gss_cart 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479
  1. #! /bin/sh
  2. # -------------------------------------------------------------
  3. # --- init
  4. # -------------------------------------------------------------
  5. # leave on error
  6. set -e
  7. # set program name and location:
  8. call="$0 $*"
  9. case $0 in
  10. /* ) script=$0 ;;
  11. * ) script="`/bin/pwd`/$0" ;;
  12. esac
  13. bindir=`/usr/bin/dirname ${script}`
  14. prog=`/bin/basename ${script}`
  15. # -------------------------------------------------------------
  16. # --- help
  17. # -------------------------------------------------------------
  18. DisplayUsage ()
  19. {
  20. ${PAGER:-less} << EOF
  21. NAME
  22. $prog - General Storage System : CINECA cartridge archive (cart)
  23. USAGE
  24. ${prog} ls [-l,--long] <ecfsfilespec>
  25. -l, --long : long listing including modes, times, sizes etc
  26. ${prog} get [-f,--force] [-m,--mkdir] <source-ecfsfilespec> <dest-filespec>
  27. ${prog} put [-f,--force] [-m,--mkdir] <source-ecfsfilespec> <dest-filespec>
  28. -f, --force : overwrite existing destination files if necessary;
  29. by default, an error is produced if a file on the cartridge
  30. already exists
  31. -m, --mkdir : create destination directories if necessary
  32. FILE SPECIFICATION
  33. A file on the cartridge is specified by a volume and a file name.
  34. Specify them as if the volume is the (only) directory in a path name:
  35. myvolume/myfile.txt
  36. GENERAL OPTIONS
  37. -v, --verbose : display info on progress
  38. ORIGINAL COMMANDS
  39. From www.cineca.it > Docs > HPC UserGuide 2010 > 1.5 Production Environment and Tools
  40. |------------------------------------------------------------------------------|
  41. |Command |Action |
  42. |------------------------------------------------------------------------------|
  43. |cart_new <vol_name> |create a new volume <vol_name> |
  44. | | |
  45. |cart_dir |show all the defined volumes from the user |
  46. |cart_dir <vol_name> |show the files stored on the volume <vol_name> |
  47. | | |
  48. |cart_put <vol_name> <file> |save <file> in the volume <vol_name> |
  49. | | |
  50. |cart_get <vol_name> <file> |retrieve the <file> from the volume <vol_name> |
  51. | | |
  52. |cart_del <vol_name> <file> |delete the <file> from the volume <vol_name> |
  53. |cart_del <vol_name> |delete the volume <vol_name> (the volume is empty)|
  54. |------------------------------------------------------------------------------|
  55. EOF
  56. exit 0
  57. }
  58. # err 'help text'
  59. err ()
  60. {
  61. echo "$1" 1>&2
  62. }
  63. # errit <exit-status>
  64. errit ()
  65. {
  66. err "$prog - ERROR - from : ${call}"
  67. err "$prog - ERROR - Use '$prog --help' for more info."
  68. exit $1
  69. }
  70. # -------------------------------------------------------------
  71. # --- arguments
  72. # -------------------------------------------------------------
  73. options=''
  74. task=''
  75. filespecs=''
  76. verbose=''
  77. # extract arguments
  78. for arg in "$@" ; do
  79. case ${arg} in
  80. -h | --help ) DisplayUsage ;;
  81. -v | --verbose ) verbose='T' ;;
  82. -* ) options="${options} ${arg}" ;;
  83. * ) # task or (one of the) file(s)
  84. if [ -z "${task}" ]; then
  85. task=${arg}
  86. else
  87. filespec=${arg}
  88. filespecs="${filespecs} ${filespec}"
  89. fi
  90. ;;
  91. esac
  92. done
  93. # not complete ?
  94. if [ -z "${task}" ]; then
  95. err "$prog - no arguments specified"
  96. errit 1
  97. fi
  98. # -------------------------------------------------------------
  99. # --- begin
  100. # -------------------------------------------------------------
  101. test ${verbose} && echo "$prog - $0 $*"
  102. # test task:
  103. case ${task} in
  104. # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  105. # list file or directory
  106. # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  107. 'list' )
  108. # extract options
  109. list_long='no'
  110. for option in ${options} ; do
  111. case ${option} in
  112. -l | --long ) list_long='yes' ;;
  113. -* )
  114. err "$prog - unknown option '${option}' for task '${task}'"
  115. errit 1
  116. ;;
  117. esac
  118. done
  119. # extract source and destination filespec:
  120. filespec=''
  121. for spec in ${filespecs} ; do
  122. if [ -z "${filespec}" ]; then
  123. filespec=${spec}
  124. else
  125. err "$prog - ERROR - task '${task}' requires single file specification only."
  126. errit 1
  127. fi
  128. done
  129. if [ -z "${filespec}" ]; then
  130. err "$prog - ERROR - tasks '${task}' requires file specification."
  131. errit 1
  132. fi
  133. # split at '/' , count words:
  134. nword=`echo ${filespec} | tr '/' ' ' | wc -w`
  135. if [ ${nword} -eq 0 ]; then
  136. filevolume=''
  137. filename=''
  138. elif [ ${nword} -eq 1 ]; then
  139. filevolume=${filespec}
  140. filename=''
  141. elif [ ${nword} -eq 2 ]; then
  142. filevolume=`echo ${filespec} | cut -d '/' -f 1`
  143. filename=`echo ${filespec} | cut -d '/' -f 2`
  144. else
  145. err "$prog - ERROR - file specification should be [<volume>/]<name> ."
  146. errit 1
  147. fi
  148. # list files:
  149. if [ "${list_long}" = "yes" ]; then
  150. # single file only ?
  151. if [ -n "${filename}" ]; then
  152. # list volume, skip total number of files, extract line with requested file:
  153. cart_dir ${filevolume} | grep -v 'total:' | grep " ${filename} "
  154. else
  155. # list volume, skip total number of files:
  156. cart_dir ${filevolume} | grep -v 'total:'
  157. fi
  158. else
  159. # single file only ?
  160. if [ -n "${filename}" ]; then
  161. # list volume, skip total number of files, only the file name, extract line with requested file:
  162. cart_dir ${filevolume} | grep -v 'total:' | cut -d ' ' -f 2 | grep "^${filename}$"
  163. else
  164. # list volume, skip total number of files, only the file name:
  165. cart_dir ${filevolume} | grep -v 'total:' | cut -d ' ' -f 2
  166. fi
  167. fi
  168. ;;
  169. # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  170. # copy files
  171. # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  172. 'get' )
  173. # extract options
  174. #do_force=''
  175. do_mkdir=''
  176. for option in ${options} ; do
  177. case ${option} in
  178. -f | --force ) ;; # do_force='true' ;; # ignore, cart_get always overwrites
  179. -m | --mkdir ) do_mkdir='true' ;;
  180. -* )
  181. err "$prog - unknown option '${option}' for task '${task}'"
  182. errit 1
  183. ;;
  184. esac
  185. done
  186. # extract source and destination filespec:
  187. source_spec=''
  188. dest_spec=''
  189. for spec in ${filespecs} ; do
  190. if [ -z "${source_spec}" ]; then
  191. source_spec=${spec}
  192. elif [ -z "${dest_spec}" ]; then
  193. dest_spec=${spec}
  194. else
  195. err "$prog - ERROR - task '${task}' requires source and destination file specifications only."
  196. errit 1
  197. fi
  198. done
  199. if [ -z "${dest_spec}" ]; then
  200. err "$prog - ERROR - task '${task}' requires source and destination file specifications."
  201. errit 1
  202. fi
  203. # destination directory:
  204. dest_dir=`/usr/bin/dirname ${dest_spec}`
  205. dest_file=`basename ${dest_spec}`
  206. # create destination directory ?
  207. # o destination is an existing file : not necessary
  208. # o destination is an existing directory : not necessary
  209. if [ ${do_mkdir} ] && [ ! -f ${dest_spec} ] && [ ! -d ${dest_spec} ]; then
  210. # destination is not an existing file or directory;
  211. # create the directory part of the destination:
  212. test "${dest_dir}" != "." && /bin/mkdir -p ${dest_dir}
  213. fi
  214. ## remove existing target ?
  215. #if [ ${do_force} ] && [ -f ${dest_spec} ]; then
  216. # # info ...
  217. # test "${verbose}" && echo "$prog - remove existing ${dest_spec} ..."
  218. # # remove target:
  219. # /bin/rm -f ${dest_spec}
  220. #fi
  221. # split at '/' , count words:
  222. nword=`echo ${source_spec} | tr '/' ' ' | wc -w`
  223. if [ ${nword} -eq 2 ]; then
  224. source_volume=`echo ${source_spec} | cut -d '/' -f 1`
  225. source_file=`echo ${source_spec} | cut -d '/' -f 2`
  226. else
  227. err "$prog - ERROR - file specification should be <volume>/<name> ."
  228. errit 1
  229. fi
  230. # save current working dir:
  231. cwd=`pwd`
  232. # goto destination directory:
  233. test "${verbose}" && echo "$prog - goto ${dest_dir} ..."
  234. cd ${dest_dir}
  235. # full command:
  236. cart_cmnd="cart_get ${source_volume} ${source_file}"
  237. # info ..
  238. test "${verbose}" && echo "$prog - execute : ${cart_cmnd}"
  239. # copy file; suppress error messages:
  240. outfile=".gss.out.$$"
  241. if ! ( ${cart_cmnd} > ${outfile} 2>&1 ) ; then
  242. /bin/cat ${outfile}
  243. /bin/rm -f ${outfile}
  244. err "$prog - ERROR from cart_get"
  245. errit 1
  246. fi
  247. /bin/rm -f ${outfile}
  248. # rename ?
  249. if [ "${source_file}" != "${dest_file}" ]; then
  250. # info ..
  251. test "${verbose}" && echo "$prog - rename to : ${dest_file}"
  252. # rename:
  253. /bin/mv ${source_file} ${dest_file}
  254. fi
  255. # back:
  256. cd ${cwd}
  257. ;;
  258. 'put' )
  259. # extract options
  260. do_force=''
  261. do_mkdir=''
  262. for option in ${options} ; do
  263. case ${option} in
  264. -f | --force ) do_force="true" ;;
  265. -m | --mkdir ) do_mkdir='true' ;;
  266. -* )
  267. err "$prog - unknown option '${option}' for task '${task}'"
  268. errit 1
  269. ;;
  270. esac
  271. done
  272. # extract source and destination filespec:
  273. source_spec=''
  274. dest_spec=''
  275. for spec in ${filespecs} ; do
  276. if [ -z "${source_spec}" ]; then
  277. source_spec=${spec}
  278. elif [ -z "${dest_spec}" ]; then
  279. dest_spec=${spec}
  280. else
  281. err "$prog - ERROR - task '${task}' requires source and destination file specifications only."
  282. errit 1
  283. fi
  284. done
  285. if [ -z "${dest_spec}" ]; then
  286. err "$prog - ERROR - task '${task}' requires source and destination file specifications."
  287. errit 1
  288. fi
  289. # split at '/' , count words:
  290. nword=`echo ${dest_spec} | tr '/' ' ' | wc -w`
  291. if [ ${nword} -eq 2 ]; then
  292. dest_volume=`echo ${dest_spec} | cut -d '/' -f 1`
  293. dest_file=`echo ${dest_spec} | cut -d '/' -f 2`
  294. else
  295. err "$prog - ERROR - cart file specification should be <volume>/<name> ."
  296. errit 1
  297. fi
  298. # create destination directory ?
  299. if [ ${do_mkdir} ]; then
  300. # full command:
  301. cart_cmnd="cart_new ${dest_volume}"
  302. # info ...
  303. test "${verbose}" && echo "$prog - execute : ${cart_cmnd}"
  304. # execute:
  305. outfile=".gss.out.$$"
  306. if ! ( ${cart_cmnd} > ${outfile} 2>&1 ) ; then
  307. /bin/cat ${outfile}
  308. /bin/rm -f ${outfile}
  309. err "$prog - ERROR from: ${cart_cmnd}"
  310. errit 1
  311. fi
  312. /bin/rm -f ${outfile}
  313. fi
  314. # rename ?
  315. source_file=`basename ${source_spec}`
  316. if [ "${dest_file}" != "${source_file}" ]; then
  317. # check ...
  318. if [ -f ${dest_file} ]; then
  319. echo "$prog - ERROR - destination has another name than source, but could not create a temporary symbolic link"
  320. echo "$prog - ERROR - since file in current directory has the same name already"
  321. errit 1
  322. fi
  323. # info ...
  324. test "${verbose}" && echo "$prog - create ${dest_file} -> ${source_spec}"
  325. # create a symbolic link
  326. ln -s ${source_spec} ${dest_file}
  327. # new name:
  328. source_spec="${dest_file}"
  329. # flag to remove the link afterwards:
  330. tmplink="${dest_file}"
  331. else
  332. # dummy ..
  333. tmplink=''
  334. fi
  335. # full command:
  336. cart_cmnd="cart_put ${dest_volume} ${source_spec}"
  337. # info ...
  338. test "${verbose}" && echo "$prog - execute : ${cart_cmnd}"
  339. # copy file; suppress error messages:
  340. outfile=".gss.out.$$"
  341. if ! ( ${cart_cmnd} > ${outfile} 2>&1 ) ; then
  342. # trap error on existing file ...
  343. if [ "`head -n 1 ${outfile}`" = "This filename already exist in this volume!" ]; then
  344. test "${verbose}" && echo "$prog - destination file already exists ..."
  345. if [ -n "${do_force}" ]; then
  346. test "${verbose}" && echo "$prog - remove existing destination file ..."
  347. cart_cmnd_del="cart_del ${dest_volume} ${source_spec}"
  348. if ! ( ${cart_cmnd_del} > ${outfile} 2>&1 ) ; then
  349. /bin/cat ${outfile}
  350. /bin/rm -f ${outfile}
  351. test -n "${tmplink}" && /bin/rm -f ${tmplink}
  352. err "$prog - ERROR from : ${cart_cmnd_del}"
  353. err "$prog - ERROR (delete existing file)"
  354. errit 1
  355. fi
  356. test "${verbose}" && echo "$prog - copy again ..."
  357. if ! ( ${cart_cmnd} > ${outfile} 2>&1 ) ; then
  358. /bin/cat ${outfile}
  359. /bin/rm -f ${outfile}
  360. test -n "${tmplink}" && /bin/rm -f ${tmplink}
  361. err "$prog - ERROR from : ${cart_cmnd}"
  362. err "$prog - ERROR (after deleting existing file)"
  363. errit 1
  364. fi
  365. else
  366. err "$prog - ERROR - target file exist : ${dest_spec}"
  367. err "$prog - ERROR - specifiy --force to have existing files removed"
  368. /bin/rm -f ${outfile}
  369. test -n "${tmplink}" && /bin/rm -f ${tmplink}
  370. errit 1
  371. fi
  372. else
  373. /bin/cat ${outfile}
  374. /bin/rm -f ${outfile}
  375. test -n "${tmplink}" && /bin/rm -f ${tmplink}
  376. err "$prog - ERROR from : ${cart_cmnd}"
  377. errit 1
  378. fi
  379. fi
  380. /bin/rm -f ${outfile}
  381. # cleanup ?
  382. if [ -n "${tmplink}" ]; then
  383. # info ...
  384. test "${verbose}" && echo "$prog - remove temporary link ${tmplink} ..."
  385. # remove:
  386. /bin/rm -f ${tmplink}
  387. fi
  388. ;;
  389. # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  390. # task ???
  391. # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  392. * )
  393. err "$prog - ERROR - unsupported task '${task}'"
  394. errit 1
  395. ;;
  396. esac # tasks
  397. # -------------------------------------------------------------
  398. # --- end
  399. # -------------------------------------------------------------
  400. test ${verbose} && echo "$prog - end"
  401. # ok
  402. exit 0