00001 #include "afni.h"
00002 #include <sys/utsname.h>
00003
00004 #define FAIL_MESSAGE(reason) \
00005 do{ fprintf(stderr,"\n" \
00006 "\n** Version check disabled: %s", \
00007 reason ) ; \
00008 disabled = 1 ; } while(0)
00009
00010 static int disabled = 0 ;
00011
00012 #define VERSION_URL "http://afni.nimh.nih.gov/afni/AFNI.version"
00013 #define STR_CHILD "tcp:localhost:20279"
00014 #define AFNI_HOST "http://afni.nimh.nih.gov/afni/"
00015 #define VSIZE 1024
00016
00017 static pid_t vc_child_pid = (pid_t)(-1) ;
00018 static IOCHAN *vc_ioc = NULL ;
00019
00020 #undef VERBOSE
00021
00022
00023
00024
00025 static void vexit( int sig )
00026 {
00027 #ifdef VERBOSE
00028 static volatile int fff=0 ;
00029 if( fff ) _exit(1) ; else fff = 1 ;
00030 fprintf(stderr,"** Version Check: child fails to complete: %d **\n",sig);
00031 #endif
00032 _exit(1);
00033 }
00034
00035
00036
00037
00038
00039
00040 static void vc_exit(void){ iochan_close(vc_ioc) ; }
00041
00042
00043
00044
00045
00046
00047 void AFNI_start_version_check(void)
00048 {
00049 pid_t child_pid ;
00050
00051 #ifdef CYGWIN
00052 FAIL_MESSAGE("not possible under Cygwin") ;
00053 return ;
00054 #else
00055
00056
00057
00058 if( AFNI_noenv("AFNI_VERSION_CHECK") ){
00059 FAIL_MESSAGE("AFNI_VERSION_CHECK forbids") ;
00060 return ;
00061 }
00062
00063 #undef VDELAY
00064 #define VDELAY 429999
00065
00066
00067 { char *home=getenv("HOME") , mname[VSIZE]="file:" ;
00068 NI_stream ns ;
00069 if( home != NULL ) strcat(mname,home) ;
00070 strcat(mname,"/.afni.vctime") ;
00071 ns = NI_stream_open( mname , "r" ) ;
00072 if( ns != NULL ){
00073 NI_element *nel = NI_read_element(ns,22) ;
00074 NI_stream_close(ns) ;
00075 if( nel != NULL ){
00076 char *rhs ;
00077 rhs = NI_get_attribute( nel , "version_check_time" ) ;
00078 if( rhs != NULL ){
00079 int last_time = strtol(rhs,NULL,10) ;
00080 int dtime = ((int)time(NULL)) - last_time ;
00081 if( dtime >= 0 && dtime < VDELAY ){
00082 NI_free_element(nel) ; disabled = 1 ; return ;
00083 }
00084 }
00085 rhs = NI_get_attribute(nel,"version_string") ;
00086 if( rhs != NULL && strcmp(rhs,VERSION) != 0 ){
00087 fprintf(stderr,
00088 "\n** Your AFNI version changed from %s to %s since last check\n",
00089 rhs , VERSION ) ;
00090 }
00091 NI_free_element(nel) ;
00092 }
00093 }
00094 }
00095
00096
00097
00098 child_pid = fork() ;
00099 if( child_pid == (pid_t)(-1) ){
00100 FAIL_MESSAGE("can't fork") ;
00101 return ;
00102 }
00103
00104 if( child_pid > 0 ){
00105
00106
00107
00108 vc_child_pid = child_pid ;
00109
00110
00111
00112 vc_ioc = iochan_init( STR_CHILD , "accept" ) ;
00113 if( vc_ioc == NULL ){
00114 kill(child_pid,SIGTERM) ;
00115 vc_child_pid = (pid_t)(-1) ;
00116 FAIL_MESSAGE("can't open connection to child") ;
00117 } else {
00118 fprintf(stderr,"\n** Version check: " VERSION_URL "\n" );
00119 atexit( vc_exit ) ;
00120 }
00121 return ;
00122
00123 } else {
00124
00125 int nbuf=0 , jj ;
00126 char *vbuf=NULL ;
00127 IOCHAN *ioc ;
00128 struct utsname ubuf ;
00129 char ua[512] ;
00130
00131 iochan_enable_perror(0) ;
00132 signal( SIGTERM , vexit ) ;
00133
00134
00135
00136 #define USE_HTTP_10
00137
00138 #ifdef USE_HTTP_10
00139 # undef PCLAB
00140 # ifdef SHOWOFF
00141 # undef SHSH
00142 # undef SHSHSH
00143 # define SHSH(x) #x
00144 # define SHSHSH(x) SHSH(x)
00145 # define PCLAB SHSHSH(SHOWOFF)
00146 # else
00147 # define PCLAB "Unknown"
00148 # endif
00149 #endif
00150
00151
00152
00153 #ifdef USE_HTTP_10
00154 ubuf.nodename[0] = ubuf.sysname[0] = ubuf.machine[0] = '\0' ;
00155 jj = uname( &ubuf ) ;
00156 if( jj >= 0 && ubuf.nodename[0] != '\0' )
00157 sprintf( ua ,
00158 "afni (avers='%s'; prec='%s' node='%s'; sys='%s'; mach='%s')" ,
00159 VERSION, PCLAB, ubuf.nodename, ubuf.sysname, ubuf.machine ) ;
00160 else
00161 sprintf( ua , "afni (avers='%s'; prec='%s')" , VERSION , PCLAB ) ;
00162
00163 set_HTTP_10( 1 ) ;
00164 set_HTTP_user_agent( ua ) ;
00165 #else
00166 set_HTTP_10( 0 ) ;
00167 #endif
00168
00169
00170
00171 nbuf = read_URL( VERSION_URL , &vbuf ) ;
00172
00173 set_HTTP_10( 0 ) ;
00174
00175
00176
00177 if( nbuf <= 0 || vbuf == NULL || vbuf[0] == '\0' ) vexit(1);
00178
00179
00180
00181 ioc = iochan_init( STR_CHILD , "create" ) ;
00182 if( ioc == NULL ) vexit(2);
00183
00184
00185
00186 jj = iochan_writecheck(ioc,-1) ;
00187 if( jj < 0 ) vexit(3);
00188
00189
00190
00191 iochan_sendall( ioc , vbuf , nbuf ) ;
00192 while( ! iochan_clearcheck(ioc,10) )
00193 iochan_sleep(10) ;
00194
00195 iochan_sleep(10); _exit(0);
00196 }
00197 #endif
00198 }
00199
00200
00201
00202 #ifdef VERBOSE
00203 # define KAPUT(ss) \
00204 do{ fprintf(stderr,"** Version Check fails: %s **\n",ss); \
00205 return ; } while(0)
00206 #else
00207 # define KAPUT(ss) return
00208 #endif
00209
00210
00211
00212
00213
00214
00215
00216
00217 int AFNI_version_check(void)
00218 {
00219 int jj , nbuf=0 ;
00220 char *vbuf=NULL ;
00221 char vv[128]="none" ;
00222 char *sname , *vvbuf ;
00223
00224 #ifdef CYGWIN
00225
00226 return 0;
00227
00228 #else
00229
00230
00231
00232 if( disabled ) return 0 ;
00233
00234 if( vc_ioc == NULL || vc_child_pid == (pid_t)(-1) ) KAPUT("bad child state");
00235
00236 jj = kill(vc_child_pid,0) ;
00237 if( jj < 0 ){
00238 IOCHAN_CLOSE(vc_ioc); vc_child_pid=(pid_t)(-1);
00239 KAPUT("child not alive");
00240 }
00241
00242 jj = iochan_readcheck( vc_ioc , 333 ) ;
00243 if( jj <= 0 ){
00244 IOCHAN_CLOSE(vc_ioc); kill(vc_child_pid,SIGTERM); vc_child_pid=(pid_t)(-1);
00245 KAPUT("connection to child gone bad");
00246 }
00247
00248
00249
00250 nbuf = 0 ;
00251 vbuf = AFMALL( char, VSIZE) ;
00252 while(1){
00253 jj = iochan_recv( vc_ioc , vbuf+nbuf , VSIZE-nbuf ) ;
00254 if( jj < 1 ) break ;
00255 nbuf += jj ;
00256 if( nbuf >= VSIZE-1 ) break ;
00257 jj = iochan_readcheck( vc_ioc , 5 ) ;
00258 if( jj < 1 ) break ;
00259 }
00260
00261
00262
00263 waitpid(vc_child_pid,NULL,WNOHANG); vc_child_pid = (pid_t)(-1);
00264 IOCHAN_CLOSE(vc_ioc);
00265
00266
00267
00268 if( nbuf <= 0 ){ free(vbuf); vbuf = NULL; KAPUT("bad version data"); }
00269
00270
00271
00272 #ifdef USE_HTTP_10
00273 vvbuf = strstr(vbuf,"\r\n\r\n") ;
00274 if( vvbuf == NULL ) vvbuf = vbuf ;
00275 else vvbuf = vvbuf + 4 ;
00276 #else
00277 vvbuf = vbuf ;
00278 #endif
00279
00280 sscanf( vvbuf , "%127s" , vv ); free(vbuf);
00281
00282
00283
00284 { char *home=getenv("HOME") , mname[VSIZE]="file:" ;
00285 NI_stream ns ;
00286 if( home != NULL ) strcat(mname,home) ;
00287 strcat(mname,"/.afni.vctime") ;
00288 ns = NI_stream_open( mname , "w" ) ;
00289 if( ns != NULL ){
00290 NI_element *nel=NI_new_data_element("AFNI_vctime",0); char rhs[32];
00291 sprintf(rhs,"%d",(int)time(NULL)) ;
00292 NI_set_attribute( nel , "version_check_time" , rhs ) ;
00293 if( strcmp(vv,"none") != 0 )
00294 NI_set_attribute( nel , "version_string" , VERSION ) ;
00295 NI_write_element( ns , nel , NI_TEXT_MODE ) ;
00296 NI_stream_close(ns) ;
00297 }
00298 }
00299
00300
00301
00302 if( strcmp(vv,VERSION) == 0 ){
00303 fprintf(stderr,"\n** Version check: you are up-to-date!\n"
00304 "** To disable future version checks:\n"
00305 "** set environment variable AFNI_VERSION_CHECK to NO.\n"
00306 "** Version checks are done about every %.1f days.\n",
00307 rint(VDELAY/86400.0) ) ;
00308 return 0 ;
00309 }
00310
00311
00312
00313 fprintf(stderr, "\n"
00314 "****************************************************\n"
00315 " This AFNI was compiled with the following settings:\n"
00316 " Version ID = %s\n"
00317 " Latest version at %s\n"
00318 " Version ID = %s\n"
00319 "****************************************************\n"
00320 " To disable future version checks:\n"
00321 " set environment variable AFNI_VERSION_CHECK to NO\n"
00322 "****************************************************\n"
00323 , VERSION, AFNI_HOST , vv ) ;
00324
00325 return 1 ;
00326
00327 #endif
00328 }
00329
00330
00331
00332
00333 #ifdef SHOWOFF
00334 # undef SHSH
00335 # undef SHSHSH
00336 # define SHSH(x) #x
00337 # define SHSHSH(x) SHSH(x)
00338
00339 # define SNAME "AFNI_UPDATER"
00340
00341 char * AFNI_make_update_script(void)
00342 {
00343 char *pg_ftp , *pg_afni , *pg_gzip , *pg_tar ;
00344 char hbuf[4096], fname[128], adir[4096], *cpt, cwd[4096] ;
00345 FILE *fp ;
00346 static char sname[4096] ;
00347
00348 pg_ftp = THD_find_executable("ftp" ); if( pg_ftp == NULL ) return NULL;
00349 pg_afni = THD_find_executable("afni"); if( pg_afni == NULL ) return NULL;
00350 pg_gzip = THD_find_executable("gzip"); if( pg_gzip == NULL ) return NULL;
00351 pg_tar = THD_find_executable("tar" ); if( pg_tar == NULL ) return NULL;
00352
00353 strcpy(adir,pg_afni) ;
00354 cpt = THD_trailname(adir,0) ;
00355 *cpt = '\0' ;
00356 if( strlen(adir) <= 0 ) return NULL ;
00357
00358 strcpy( cwd , adir ) ;
00359 strcat( cwd , "afni_qadgop" ) ;
00360 fp = fopen( cwd , "a" ) ;
00361 if( fp == NULL ) return NULL ;
00362 fclose(fp) ; remove(cwd) ;
00363
00364 getcwd( cwd , 4096 ) ;
00365 chdir( adir ) ;
00366
00367
00368
00369 gethostname( hbuf , 4096 ) ;
00370 strcpy( fname , SHSHSH(SHOWOFF) ) ; strcat( fname , ".tgz" ) ;
00371 fp = fopen( SNAME , "w" ) ; if( fp == NULL ){ chdir(cwd); return NULL; }
00372 fprintf( fp ,
00373 "#!/bin/sh\n"
00374 "echo '++ FTP-ing %s from afni.nimh.nih.gov'\n"
00375 "%s -n afni.nimh.nih.gov << EEEEE\n"
00376 "user anonymous AFNI_UPDATER@%s\n"
00377 "binary\n"
00378 "cd tgz\n"
00379 "get %s\n"
00380 "bye\n"
00381 "EEEEE\n"
00382 "echo '++ Unpacking %s'\n"
00383 "%s -dc %s | %s xf -\n"
00384 "/bin/rm -f %s\n"
00385 "echo '++ Moving files'\n"
00386 "/bin/mv -f %s/* .\n"
00387 "/bin/rm -rf %s\n"
00388 "echo '++ Finished'\n" ,
00389 fname ,
00390 pg_ftp ,
00391 hbuf ,
00392 fname ,
00393 fname ,
00394 pg_gzip, fname, pg_tar,
00395 fname ,
00396 SHSHSH(SHOWOFF) ,
00397 SHSHSH(SHOWOFF)
00398 ) ;
00399 fclose( fp ) ;
00400 chmod( SNAME , S_IRUSR | S_IWUSR | S_IXUSR ) ;
00401
00402
00403
00404 chdir(cwd) ;
00405 sprintf(sname,"%s%s",adir,SNAME) ; return sname ;
00406 }
00407
00408 #else
00409 char * AFNI_make_update_script(void){ return NULL; }
00410 #endif