#!/bin/tcsh # ---------------------------------------------------------------------- # upgrade the AFNI binaries # # Update the package specified by "afni -ver" in the directory # specified by "which afni". Allow for overriding options of: # # -package PACKAGE # -bindir DIRECTORY # # terminate on any error, and be clear about which command failed # ---------------------------------------------------------------------- set prog = `basename $0` set hostname = afni.nimh.nih.gov set hostproto = https:// set hostsite = $hostproto$hostname # ---------------------------------------------------------------------- # history section goto POST_HIST SHOW_HIST: cat << EOF ------------------------------------------------------------------------------- history for $prog : ... : a few updates 1.0 07 Mar 2012 : existing package and install dir no longer required for -d 13 Sep 2012 : download and run the current version on the website - added option -no_recur 21 Dec 2012 : do rehash before apsearch - check download by looking for string in this file 01 Nov 2013 : Darwin defaults to 10.7 package 01 Dec 2013 : added -prog_list for Ziad 18 Dec 2013 : added check for system programs, -sys_ok and -help_system_progs 14 Jan 2014 : added more system programs 01 May 2014 : added -quick option; fixed sync of backup, was nesting 15 Jan 2015 : if bad option and current version, fail after version check 08 Apr 2015 : added -revert (zsaad and rickr) 25 Aug 2015 : update path and AFNI tab completion on initial install 2.0 08 Feb 2016 : access afni site via https protocol 2.1 16 Feb 2016 : added -ver and initial statement of version 2.2 19 Feb 2016 : minor text changes (note get_prog and appease dglen) 2.3 29 Mar 2016 : added -no_cert_verify to omit certificate verification 2.4 30 Mar 2016 : possibly udpate .bashrc after .cshrc 2.5 07 Apr 2016 : added -proto and -test_protos options 2.6 08 Apr 2016 : save -test_protos results ------------------------------------------------------------------------------- EOF exit POST_HIST: # end history section # ---------------------------------------------------------------------- set aub_version = "2.6, April 8, 2016" # ---------------------------------------------------------------------- # apply any options # initialize options to 'unset' set abin = "" set package = "" set prog_list = () # update programs or entire package set tmp_dir = ".tmp.install" # should start with '.' set make_backup = 1 # backup previous binaires set sys_ok = 0 # OK to update having system programs set system_progs = ( apt-get at cc cpp cmp diff du gcc less man md5sum od \ passwd perl python scp srm sudo vi vim wc xterm yum ) if ( $#argv == 0 ) then set help = 1 else set help = 0 endif set testing = 0 set test_protos = 0 # test download protocols set use_curl = 0 set do_apsearch = 1 # run apserach -update_all_afni_help set do_recur = 1 # download a new version of @uab, first set quick = 0 # no fancies (recur, apsearch) set revert = 0 # revert binaries to those in backup directory set cert_verify = 1 # whether to verify CA certificate via SSL/TLS set use_curl = 0 set bad_opt = '' # if bad_opt and do_recur, see if we continue set ac = 1 while ( $ac <= $#argv ) if ( "$argv[$ac]" == "-apsearch" ) then @ ac ++ if ( $ac > $#argv ) then echo "** missing parameter for option '-apsearch'" exit 1 endif set resp = `echo $argv[$ac] | cut -b1` if ( $resp == 'N' || $resp == 'n' ) set do_apsearch = 0 else if ( "$argv[$ac]" == "-bindir" ) then @ ac ++ if ( $ac > $#argv ) then echo "** missing parameter for option '-bindir'" exit 1 endif set abin = $argv[$ac] else if ( "$argv[$ac]" == "-curl" ) then set use_curl = 1 else if ( "$argv[$ac]" == "-d" || "$argv[$ac]" == "-defaults" ) then set defaults = 1 else if ( "$argv[$ac]" == "-help" ) then set help = 1 else if ( "$argv[$ac]" == "-help_sys_progs" ) then echo "" echo "system programs that would prevent an update:" echo " $system_progs" echo "" exit 0 else if ( "$argv[$ac]" == "-hist" ) then goto SHOW_HIST else if ( "$argv[$ac]" == "-revert" ) then set revert = 1 else if ( "$argv[$ac]" == "-package" ) then @ ac ++ if ( $ac > $#argv ) then echo "** missing parameter for option '-package'" exit 1 endif set package = $argv[$ac] else if ( "$argv[$ac]" == "-prog_list" ) then @ ac ++ set resp = '' while ( $ac <= $#argv ) set resp = `echo $argv[$ac] | cut -b1` if ( "$resp" == '-' ) break set prog_list = ( $prog_list $argv[$ac] ) @ ac ++ end if ( $#prog_list == 0 ) then echo "** missing parameter(s) for option '-prog_list'" exit 1 endif # decide on increment here, and continue continue else if ( "$argv[$ac]" == "-proto" ) then @ ac ++ if ( $ac > $#argv ) then echo "** missing parameter for option '-proto'" exit 1 endif if ( $argv[$ac] == http || $argv[$ac] == https ) then set hostproto = ${argv[$ac]}:// else if ( $argv[$ac] == NONE ) then set hostproto = '' else # use as is set hostproto = $argv[$ac] endif else if ( "$argv[$ac]" == "-no_cert_verify" ) then # add options to turn verification off set cert_verify = 0 else if ( "$argv[$ac]" == "-no_recur" ) then set do_recur = 0 else if ( "$argv[$ac]" == "-quick" ) then set quick = 1 else if ( "$argv[$ac]" == "-sys_ok" ) then set sys_ok = 1 else if ( "$argv[$ac]" == "-ver" ) then echo $aub_version exit 0 else if ( "$argv[$ac]" == "-test" ) then set testing = 1 else if ( "$argv[$ac]" == "-test_protos" ) then set test_protos = 1 else # allow unknown options if $do_recur, but THEY MUST BE LAST if ( $do_recur ) then # check later, if we do not actually recur echo "** unknown option $argv[$ac], but might work in newer version" set bad_opt = "$argv[$ac]" else echo "** unknown option $argv[$ac]" exit 1 endif endif @ ac ++ end set tmpsite = $hostproto$hostname if ( $tmpsite != $hostsite ) then set hostsite = $tmpsite echo "-- updating hostsite to $hostsite" endif # in quick mode, turn off fancies, even if requested 1 May, 2014 [rickr] if ( $quick ) then set do_recur = 0 set do_apsearch = 0 endif # if requested, show help and exit if ( $help ) then echo "------------------------------------------------------------" echo "$prog - upgrade AFNI binaries" echo "" echo "Update the AFNI binaries, either via '-defaults' or by the" echo "'-bindir' and/or '-package' options." echo "" echo "examples:" echo "" echo " $prog -defaults" echo " $prog -package linux_xorg7" echo " $prog -package linux_xorg7 -bindir ~/abin" echo " $prog -package linux_openmp_64 \\" echo " -programs file_tool python_scripts/*.py" echo "" echo "options:" echo "" echo " -help : show this help" echo " -help_sys_progs : list system programs that block update" echo "" echo " See -sys_ok for details." echo "" echo " -apsearch yes/no : specify getting apsearch updates" echo " -bindir ABIN : set AFNI binary directory to ABIN" echo " -curl : default to curl instead of wget" echo " -defaults : install current package into abin" echo " -d : (short for -defaults)" echo "" echo " This would be the method to 'update the package that I" echo " am currently using'." echo "" echo " The package would be decided by 'afni -ver' and the" echo " directory would come from 'which afni'. If either of" echo " these is not appropriate, the package would be determined" echo " by the OS (Linux or OSX allowed, 32 or 64-bits), and the" echo " install dir would be ~/abin." echo "" echo " If -bindir or -package cannot be determined, it must be" echo " supplied by the user." echo "" echo " 26 Sep 2012 : -update_apsearch is applied by default" echo " (if installed afni is in PATH)" echo "" echo " -no_cert_verify : do not verify the server CA certificate" echo "" echo " This option is regarding SSL/TLS Certificate Verification" echo " via some CA (certificate authority) list. It may be needed" echo " if the client CA list does not recognize the certificate" echo " provided by the afni server." echo "" echo " For curl, this appends the '--insecure' option." echo " For wget, this appends the '--no-check-certificate' option." echo "" echo " To check whether curl requires this, look for WinSSL in the" echo " output from: curl -V" echo "" echo " See https://curl.haxx.se/docs/sslcerts.html for details." echo "" echo " -no_recur : do not download and run new @uab script" echo " -package PACKAGE : install distribution package PACKAGE" echo " -prog_list PROGRAMS : install given programs, not whole PACKAGE" echo "" echo " With this option, the listed programs would be installed," echo " rather than the entire PACKAGE." echo "" echo " Note: directories are not allowed (e.g. meica.libs)" echo "" echo " For example, consider:" echo "" echo " -prog_list suma python_scripts/*.py" echo "" echo " In this case, suma and the individual python files would all" echo " end up in abin, with no directories." echo "" echo " -proto PROTOCOL : access afni host via this PROTOCOL" echo "" echo " e.g. -proto http" echo " default: https" echo "" echo " Use this option to specify the download protocol. PROTOCOL may" echo " https, http or NONE (meaning not to prefix siteaname with any)." echo "" echo " -quick : quick mode, no fancies" echo "" echo " This option blocks unwanted or unneeded actions, mostly for" echo " testing. It basically applies:" echo "" echo " -no_recur" echo " -apsearch no" echo "" echo " -sys_ok : OK to update, even if system progs found" echo "" echo " If any system program (e.g. man, sudo, xterm, yum) is found," echo " the default behavior is not to continue the update. Note" echo " that if 'afni -ver' shows a Debian package, then updates" echo " should be done via apt-get, not this program." echo "" echo " Use -sys_ok to all the update to proceed." echo "" echo " See -help_sys_progs for a list of checked system programs." echo "" echo " -test : just attempt the download and quit" echo "" echo " -test_protos : test download protocols and exit" echo "" echo " -revert : revert binaries to previous version" echo "" echo " Revert the AFNI binaries to those in directory" echo " ABIN/auto_backup.PACKAGE, where ABIN would otherwise be" echo " considered the installation directory." echo "" echo " Use this option if the last update of the binaries got" echo " you a lump of coal." echo "" echo " There should be only 1 backup to revert to. One cannot" echo " revert back 2 levels, say." echo "" echo "Note that the user must have write permissions in the ABIN" echo "directory." echo "" exit endif echo "-- running $prog version $aub_version" # note any current AFNI location which afni >& /dev/null if ( $status ) then echo "-- no current AFNI package..." set cur_afni = "" set new_install = 1 else set cur_afni = `which afni` set cur_afni = $cur_afni:h set new_install = 0 echo "-- have AFNI binaries under $cur_afni" endif # possibly apply default binary directory if ( $abin == "" ) then if ( $cur_afni == "" ) then echo "-- install dir: using default ~/abin" set abin = ~/abin else # have program, remove trailing 'afni' to get directory set abin = $cur_afni echo "-- install dir: using existing $abin" endif endif # possibly apply default package if ( $package == "" ) then if ( $cur_afni != "" ) then set package = `afni -ver | \grep binary | awk '{print $3}' | sed 's/://g'` if ( $status || "$package" == "" ) then echo "** failed setting package from 'afni -ver'" exit 1 endif else # pick package based on OS set sysname = `uname -s` set errs = 0 if ( $status ) then @ errs ++ set sysname = "" endif set cpuname = `uname -p` if ( $status ) then @ errs ++ set cpuname = "" endif if ( $errs > 0 ) then echo "** failed to note system and cpu, must specify -package" exit endif # simple cases for now, can expand later if ( $sysname == Linux ) then if ( $cpuname == x86_64 ) then set package = linux_openmp_64 else set package = linux_openmp endif else if ( $sysname == Darwin ) then # default to no.omp.glib for now set package = macosx_10.7_Intel_64 else @ errs ++ endif if ( $errs > 0 ) then echo "** unknown system $sysname/$cpuname, must specify -package" exit endif endif endif # test for existence of wget or curl which wget >& /dev/null set missing_wget = $status which curl >& /dev/null set missing_curl = $status if ( $testing ) echo "-- wget, curl status = $missing_wget, $missing_curl" if ( $missing_wget && $missing_curl ) then echo "" echo "** programs wget and curl are missing, please install *either*," echo " or look it up on the AFNI message board:" echo " $hostsite/afni/community/board" echo "" exit 1 endif # default to wget, else use curl set get_prog = ( "wget" ) if ( $use_curl || $missing_wget ) set get_prog = ( curl -O -f ) # do we verify certificates via CA list? if not, speicify if ( ! $cert_verify ) then if ( $get_prog[1] == "wget" ) then set get_prog = ( $get_prog --no-check-certificate ) else if ( $get_prog[1] == "curl" ) then set get_prog = ( $get_prog --insecure ) else echo "** cert_verify: confused about get_prog: $get_prog" exit 1 endif endif echo "-- will download from $hostsite via $get_prog" echo "" # make sure package is set to the base name if ( $package =~ *.tgz ) set package = $package:r # rcr - entire package or just prog_list (though prog_list requires package) echo "-- attempting to install package $package under" if ( $#prog_list > 0 ) echo " (including only $#prog_list programs)" echo " install dir: $abin..." # ---------------------------------------------------------------------- # if the install dir does not exist, create it if ( -d $abin ) then echo "-- have install dir" else if ( $revert == 1 ) then echo "** error: no install directory to revert from" exit 1 endif echo "++ creating install dir" mkdir -pv $abin if ( $status ) then echo "** failed to create install dir, $abin" exit endif echo "" sleep 1 endif # note appropriate backup directory set date = `date +%Y_%m_%d` set backup_dir = auto_backup.$package # ---------------------------------------------------------------------- # go to the binary directory and check that we can write cd $abin # check permissions before doing anything if ( ! -w . ) then echo "** you do not have write permissions in the install directory" echo " (install dir = `pwd`)" exit 1 endif # ---------------------------------------------------------------------- # check to see if this is someplace that we should not be writing to # - if any of these programs exist, maybe this script is not appropriate set nerr = 0 foreach cprog ( $system_progs ) if ( -e $cprog ) then if ( $nerr == 0 ) echo "** found system program '$cprog'" @ nerr ++ endif end if ( $nerr > 0 && ! $revert ) then echo "** found $nerr system program(s)" if ( $sys_ok ) then echo "continuing from -sys_ok..." echo "" else echo "" echo "** error: refusing to update potential system directory" echo " (see -sys_ok in the -help output for details)" echo "" exit 1 endif endif # ====================================================================== # begin work (most work from temp dir) # ====================================================================== # ---------------------------------------------------------------------- # remove any old package if ( ! $revert && ( -f $package.tgz || -d $package ) ) then echo deleting old package $package.tgz ... \rm -fr $package $package.tgz if ( $status ) then echo "** failed to remove old package $package" exit 1 endif endif # remove any temp install directory if ( -d $tmp_dir ) then echo deleting old temporary directory... \rm -fr $tmp_dir endif # ---------------------------------------------------------------------- # create and enter temporary working directory; test whether update is needed echo "++ working in new temp dir, $tmp_dir" mkdir $tmp_dir if ( $status ) then echo "** failed to create new or remove old temp dir, $tmp_dir" exit 1 endif cd $tmp_dir # ---------------------------------------------------------------------- # first, make sure we run the latest @update.afni.binaries: # get a new version of this script to make sure we are current... # (sneaky suggestion by Bob) # download to a temp name, though if ( $do_recur ) then set temp_prog = tmp.$prog # temp name to run with set retry = 0 # use multiple attempts to get this set bin_root = $hostsite/pub/dist/bin set get_package = $bin_root/$package/$prog echo "++ getting install prog: $get_prog $package/$prog ..." echo $get_prog $get_package $get_prog $get_package # ----- might not exist: try twice and skip if fail 26 Sep 2012 if ( $status ) then set retry = 1 else # see if we have this text (and therefore the actual program) grep 'upgrade the AFNI binaries' $prog > /dev/null if ( $status ) then set retry = 1 \rm -f $prog endif endif if ( $retry ) then set retry = 0 set ppp = linux_openmp_64 echo "** failed, trying $ppp/$prog ..." $get_prog $bin_root/$ppp/$prog if ( $status ) then set retry = 1 else # see if we have this text (and therefore the actual program) grep 'upgrade the AFNI binaries' $prog > /dev/null if ( $status ) then set retry = 1 \rm -f $prog endif endif if ( $retry ) then echo "** failed again, skipping check for new installer" goto SKIP_RECUR endif endif # ----- okay, we have a new installer to check on # see if there are any changes to apply cmp -s $prog ../$prog if ( $status ) then # use new version! echo "++ using updated $prog, instead..." echo "" # move it up to a temp name and run it (without further recursion) if ( -f ../$temp_prog ) \rm -f ../$temp_prog \mv $prog ../$temp_prog cd .. # so we don't sit in deleted directory echo "++ running: tcsh $temp_prog -no_recur $argv" tcsh $temp_prog -no_recur $argv set ss = $status if ( ! $ss ) then echo "...finished, removing temp version, $temp_prog" \rm -f $temp_prog endif exit $ss # exit with status of called program else echo "-- $prog is current, continuing with this version..." if ( "$bad_opt" != "" ) then echo "** unknown option $bad_opt" exit 1 endif endif else echo "-- skipping update of $prog" endif SKIP_RECUR: # ---------------------------------------------------------------------- # maybe we want to test protocols and exit if ( $test_protos ) then echo "" echo "++ testing protocols from temp dir, `pwd`" set plist = ( http https '' ) # protocols set slist = () # status values set ind = 1 while ( $ind <= $#plist ) set pshort = $plist[$ind] if ( $pshort == '' ) then set proto = '' else set proto = ${pshort}:// endif set tmpsite = $proto$hostname set tmpprog = $tmpsite/pub/dist/bin/$package/$prog echo $get_prog $tmpprog $get_prog $tmpprog set st = $status # make sure we have a good download, even if $status is okay if ( ! $st ) then grep 'upgrade the AFNI binaries' $prog > /dev/null set st = $status if ( $st ) then echo "** okay status but bad download" endif endif echo "" # rename old one if ( -f $prog ) \mv $prog save.$prog.$pshort set slist = ( $slist $st ) @ ind += 1 end echo "" set ind = 1 while ( $ind <= $#plist ) if ( $slist[$ind] ) then echo "failure ($slist[$ind]) for proto '$plist[$ind]'" else echo "success for proto '$plist[$ind]'" endif @ ind += 1 end echo "" exit 0 endif # ---------------------------------------------------------------------- # revert to previous version, if requrested if ( $revert ) then # revert to backup if ( ! -d ../$backup_dir ) then echo "** failed to find backup directory ../$backup_dir" exit 1 else echo "++ revert: under `pwd`, running:" echo " rsync -av ../$backup_dir/ ../" rsync -av ../$backup_dir/ ../ if ( $status ) then echo "** rsync failed" exit 1 else echo "-- binaries now replaced with those from $abin/$backup_dir" endif endif exit 0 endif # ---------------------------------------------------------------------- # just download single afni binary and compare # (if prog_list, use first prog in list) if ( $#prog_list > 0 ) then set pp = $prog_list[1]:t # directories are not allowed (harder to download) foreach ppp ( $prog_list ) set prog = $ppp:t if ( -d ../$prog ) then echo "** error: $prog is a directory" exit endif end else set pp = afni endif set get_package = $hostsite/pub/dist/bin/$package/$pp echo "++ downloading test file: $get_prog $package/$pp ..." $get_prog $get_package cmp -s $pp ../$pp if ( ! $status ) then echo "++ no update needed" cd .. \rm -fr $tmp_dir exit else if ( $#prog_list > 0 ) then echo "-- overwriting test update file, $pp" chmod a+x $pp else \rm $pp endif # if just testing, we are done if ( $testing ) then echo "++ install needed, but just testing download via '$get_prog', done" echo "(temp download in `pwd`)" exit endif echo "" echo "++ update needed, installing..." echo "" sleep 1 # ---------------------------------------------------------------------- # an update is needed, download full package # download the full binary set or list of programs if ( $#prog_list == 0 ) then echo "++ downloading full package: $get_prog $package.tgz ..." set get_package = $hostsite/pub/dist/tgz/$package.tgz $get_prog $get_package if ( $status ) then echo "** failed to download package $get_package" exit 1 endif else # prog_list, get each file if ( $#prog_list > 1 ) echo "++ downloading remaining files ..." foreach pp ( $prog_list[2-] ) set prog = $pp:t set get_package = $hostsite/pub/dist/bin/$package/$prog $get_prog $get_package set ss = $status if ( $ss ) then echo "** failed to download package file:" echo " $get_package" exit 1 endif chmod a+x $prog end endif # if no prog_list, extract package if ( $#prog_list == 0 ) then echo "++ extracting package $package..." tar xfz $package.tgz if ( $status ) then echo "** failed to extract package $package.tgz" exit 1 endif endif # ---------------------------------------------------------------------- # delete any previous auto-backup and install the new binaries # if not making a backup dir, use rsync for install # (since there might be new and unknown directories) set use_rsync = 1 # if the directory is empty, no rsync or backup set nfiles = `\ls .. | wc -l` # make a backup directory (first under 'hidden' temp dir) if ( $nfiles == 0 ) then set use_rsync = 0 # now do not need rsync echo "-- nothing to back up or sync" else if ( $make_backup ) then # create new auto-backup directory mkdir $backup_dir if ( $status ) then echo "** failed to make backup directory $backup_dir, exiting..." exit 1 endif echo "++ backing up current binaries to $backup_dir" # if prog_list, only backup those programs if ( $#prog_list ) then foreach pp ( $prog_list ) set prog = $pp:t if ( -f ../$prog ) \mv ../$prog $backup_dir end else # might nest backups here, check on remove \mv ../* $backup_dir endif # delete previous auto-backup directory if ( -d ../$backup_dir ) then echo deleting old backup directory, $backup_dir ... \rm -fr ../$backup_dir else if ( -d $backup_dir/$backup_dir ) then echo deleting previous backup directory, $backup_dir ... \rm -fr $backup_dir/$backup_dir endif \mv $backup_dir .. set use_rsync = 0 # now do not need rsync endif # abin may have sub-directories 17 Oct 2011 [rickr] # actually install the new binaries if ( $use_rsync ) then echo "++ synching new binaries..." # either sync package or files if ( $#prog_list > 0 ) then rsync -av * .. set ss = $status else rsync -a $package/ .. set ss = $status endif if ( $ss ) then echo "** failed to overwrite existing package, exiting..." exit endif else echo "++ installing new binaries..." if ( $#prog_list > 0 ) then \mv * .. set ss = $status else \mv $package/* .. set ss = $status endif if ( $ss ) then echo "** failed to overwrite existing package, exiting..." exit endif endif # if this is a new install and we are not root, update .cshrc set rcfile = ~/.cshrc if ( $new_install && -d $abin && $?USER ) then if ( $USER != root ) then if ( -f ~/.tcshrc ) then set rcfile = ~/.tcshrc else if ( -f ~/.cshrc ) then set rcfile = ~/.cshrc else set rcfile = ~/.cshrc echo ++ creating empty $rcfile echo "" > $rcfile endif grep $abin:t $rcfile >& /dev/null if ( $status ) then # finally, update .csrhc and our current path echo "++ updating path in $rcfile ..." echo 'set path = ( $path ' $abin ' ) ' >> $rcfile set path = ( $path $abin ) endif rehash set cur_afni = `which afni` set cur_afni = $cur_afni:h # --------------------------- # do this for .bashrc, too... set brcfile = ~/.bashrc # to simplify, make sure the file exists if ( ! -f $brcfile ) touch $brcfile # and possibly edit grep $abin:t $brcfile >& /dev/null if ( $status ) then # not found, so append to file echo "++ updating PATH in $brcfile ..." echo 'export PATH=$PATH:'$abin >> $brcfile endif endif endif # and possibly run apsearch if ( $do_apsearch && $cur_afni == $abin && $#prog_list == 0 ) then rehash set cmd = "apsearch -update_all_afni_help" echo "++ running $cmd ..." $cmd grep afni_help_dir $rcfile >& /dev/null if ( $status && -f $rcfile ) then cat << EOF >> $rcfile if ( -f \$HOME/.afni/help/all_progs.COMP ) then source \$HOME/.afni/help/all_progs.COMP endif EOF endif endif # maybe they need to set the DYLD_F_L_P if ( $package == macosx_10.7_Intel_64 && $#prog_list > 0 ) then echo "" echo "-- remember to set the DYLD_FALLBACK_LIBRARY_PATH, e.g." echo " setenv DYLD_FALLBACK_LIBRARY_PATH $abin" echo "" endif # finally remove any leftovers cd .. \rm -fr $tmp_dir echo "done, yay (binaries are under $abin)"