#! /bin/sh # ------------------------------------------------------------- # --- init # ------------------------------------------------------------- # leave on error set -e # set program name and location: call="$0 $*" case $0 in /* ) script=$0 ;; * ) script="`/bin/pwd`/$0" ;; esac bindir=`/usr/bin/dirname ${script}` prog=`/bin/basename ${script}` # ------------------------------------------------------------- # --- help # ------------------------------------------------------------- DisplayUsage () { ${PAGER:-less} << EOF NAME $prog - General Storage System : ECMWF tape archive (ECFS) USAGE ${prog} ls [-l,--long] -l, --long : long listing including modes, times, sizes etc ${prog} get [-f,--force] [-m,--mkdir] ${prog} put [-f,--force] [-m,--mkdir] -f, --force : overwrite existing destination files if necessary; by default, an error is produced if a file on ecfs already exists (ecp -e) -m, --mkdir : create destination directories if necessary FILE SPECIFICATION A file on ecfs is specified by a standard unix file name: /ab1/TM/meteo # permanent storage 'ec:' /TMP/ab1/TM/meteo # temporary storage 'ectmp:' Special options are preceded, seperate with percent signs: umask=022%/ab1/TM/meteo FILE ACCESS PERMISSIONS Default umask: 077 = --- rwx rwx Thus new direcory : rwx rwx rwx XOR --- rwx rwx = rwx --- --- and new file : rw- rw- rw- XOR --- rwx rwx = rw- --- --- Change mask to exclude only write permissions for 'group' and 'other': umask=022 # --- -w- -w- GENERAL OPTIONS -v, --verbose : display info on progress EOF exit 0 } # err 'help text' err () { echo "$1" 1>&2 } # errit errit () { err "$prog - ERROR - from : ${call}" err "$prog - ERROR - Use '$prog --help' for more info." exit $1 } # ------------------------------------------------------------- # --- arguments # ------------------------------------------------------------- options='' task='' filespecs='' verbose='' # extract arguments for arg in "$@" ; do case ${arg} in -h | --help ) DisplayUsage ;; -v | --verbose ) verbose='T' ;; -* ) options="${options} ${arg}" ;; * ) # task or (one of the) file(s) if [ -z "${task}" ]; then task=${arg} else filespec=${arg} filespecs="${filespecs} ${filespec}" fi ;; esac done # not complete ? if [ -z "${task}" ]; then err "$prog - no arguments specified" errit 1 fi # ------------------------------------------------------------- # --- functions # ------------------------------------------------------------- # # EvalSpecials umask=022%group=ksarch%/fa/ks/TM # filespec=${FS} # # Evaluates all preceding parts ending with '%'. # Return last part in variable 'FS' . # EvalSpecials () { # seperation mark: sep='%' # loop until all % parts are removed: FS=$1 while [[ ${FS} = *%* ]]; do eval "`echo ${FS} | /usr/bin/cut -d ${sep} -f 1`" FS=`echo ${FS} | /usr/bin/cut -d ${sep} -f 2-` done } # ------------------------------------------------------------- # --- begin # ------------------------------------------------------------- test ${verbose} && echo "$prog - $0 $*" # setup script present ? case `/bin/hostname` in ecga* ) . '/usr/local/share/ecmwf/share/.kshrc' ;; ecgb* ) . "${ECFS_SYS_PATH}/.ecfs_bash_env" . "${ECFS_SYS_PATH}/.ecfs_bash_functions" . "${ECFS_SYS_PATH}/.ecfs_bash_aliases" ;; c[12]* ) ;; cc* ) PATH=$PATH:/usr/local/apps/ecfs/2.0.13rc2/bin ;; * ) err "$prog - ERROR - ecfs not supported on this host ..." errit 1 ;; esac # test task: case ${task} in # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # list file or directory # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 'list' ) # extract options els_options='' for option in ${options} ; do case ${option} in -l | --long ) els_options="${els_options} -l" ;; -* ) err "$prog - unknown option '${option}' for task '${task}'" errit 1 ;; esac done # extract source and destination filespec: filespec='' for spec in ${filespecs} ; do EvalSpecials ${spec} if [ -z "${filespec}" ]; then filespec=${FS} else err "$prog - ERROR - task '${task}' requires single file specification only." errit 1 fi done if [ -z "${filespec}" ]; then err "$prog - ERROR - tasks '${task}' requires file specification." errit 1 fi # list files: els ${els_options} ${filespec} ;; # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # copy files # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 'get' ) # extract options ecp_options='' do_mkdir='' for option in ${options} ; do case ${option} in -f | --force ) ecp_options="${ecp_options} -o" ;; -m | --mkdir ) do_mkdir='true' ;; -* ) err "$prog - unknown option '${option}' for task '${task}'" errit 1 ;; esac done # extract source and destination filespec: source_spec='' dest_spec='' for spec in ${filespecs} ; do EvalSpecials ${spec} if [ -z "${source_spec}" ]; then source_spec=${FS} elif [ -z "${dest_spec}" ]; then dest_spec=${FS} else err "$prog - ERROR - task '${task}' requires source and destination file specifications only." errit 1 fi done if [ -z "${dest_spec}" ]; then err "$prog - ERROR - task '${task}' requires source and destination file specifications." errit 1 fi # create destination directory ? # o destination is an existing file : not necessary # o destination is an existing directory : not necessary if [ ${do_mkdir} ] && [ ! -f ${dest_spec} ] && [ ! -d ${dest_spec} ]; then # destination is not an existing file or directory; # create the directory part of the destination: dest_dir=`/usr/bin/dirname ${dest_spec}` test "${dest_dir}" != "." && /bin/mkdir -p ${dest_dir} fi # copy file; suppress error messages: outfile=".gss.out.$$" if ! ( ecp ${ecp_options} ec:${source_spec} ${dest_spec} > ${outfile} 2>&1 ) ; then /bin/cat ${outfile} /bin/rm -f ${outfile} err "$prog - ERROR from ecp" errit 1 fi /bin/rm -f ${outfile} # get over the non working umask stuff -> default to 640 chmod 640 ${dest_spec} ;; 'put' ) # defaults umask=022 # no write permissions for group and other # extract options ecp_options='-e' # error if target already exists do_mkdir='' for option in ${options} ; do case ${option} in -f | --force ) ecp_options="-o" ;; -m | --mkdir ) do_mkdir='true' ;; -* ) err "$prog - unknown option '${option}' for task '${task}'" errit 1 ;; esac done # extract source and destination filespec: source_spec='' dest_spec='' for spec in ${filespecs} ; do EvalSpecials ${spec} if [ -z "${source_spec}" ]; then source_spec=${FS} elif [ -z "${dest_spec}" ]; then dest_spec=${FS} else err "$prog - ERROR - task '${task}' requires source and destination file specifications only." errit 1 fi done if [ -z "${dest_spec}" ]; then err "$prog - ERROR - task '${task}' requires source and destination file specifications." errit 1 fi # set ECFS umask - do not exit if error (cca: not available, once in the queue) set +e eumask ${umask} set -e # create destination directory ? if [ ${do_mkdir} ]; then # o destination is an existing file : not necessary # o destination is an existing directory : not necessary #if ! ${script} exist ${dest_spec} ; then # do not test if directory already exists, # this takes more time than just creation; # supress error messages about already existing directories ... dest_dir=`/usr/bin/dirname ${dest_spec}` outfile=".gss.out.$$" if ! ( emkdir -p ec:${dest_dir} > ${outfile} 2>&1 ) ; then /bin/cat ${outfile} /bin/rm -f ${outfile} err "$prog - ERROR from emkdir" errit 1 fi /bin/rm -f ${outfile} #fi fi # copy file; suppress error messages: outfile=".gss.out.$$" if ! ( ecp ${ecp_options} ${source_spec} ec:${dest_spec} > ${outfile} 2>&1 ) ; then /bin/cat ${outfile} /bin/rm -f ${outfile} err "$prog - ERROR from ecp" errit 1 fi /bin/rm -f ${outfile} # adhoc ... case "${umask}" in "022" ) echmod 644 ec:${dest_spec} ;; "002" ) echmod 664 ec:${dest_spec} ;; esac ;; # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # task ??? # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * ) err "$prog - ERROR - unsupported task '${task}'" errit 1 ;; esac # tasks # ------------------------------------------------------------- # --- end # ------------------------------------------------------------- test ${verbose} && echo "$prog - end" # ok exit 0