Doxygen Source Code Documentation
afni_version.c File Reference
#include "afni.h"#include <sys/utsname.h>Go to the source code of this file.
Defines | |
| #define | FAIL_MESSAGE(reason) |
| #define | VERSION_URL "http://afni.nimh.nih.gov/afni/AFNI.version" |
| #define | STR_CHILD "tcp:localhost:20279" |
| #define | AFNI_HOST "http://afni.nimh.nih.gov/afni/" |
| #define | VSIZE 1024 |
| #define | VDELAY 429999 |
| #define | USE_HTTP_10 |
| #define | PCLAB "Unknown" |
| #define | KAPUT(ss) return |
Functions | |
| void | vexit (int sig) |
| void | vc_exit (void) |
| void | AFNI_start_version_check (void) |
| int | AFNI_version_check (void) |
| char * | AFNI_make_update_script (void) |
Variables | |
| int | disabled = 0 |
| pid_t | vc_child_pid = (pid_t)(-1) |
| IOCHAN * | vc_ioc = NULL |
Define Documentation
|
|
Definition at line 14 of file afni_version.c. Referenced by AFNI_version_check(). |
|
|
Value: do{ fprintf(stderr,"\n" \ "\n** Version check disabled: %s", \ reason ) ; \ disabled = 1 ; } while(0) Definition at line 4 of file afni_version.c. Referenced by AFNI_start_version_check(). |
|
|
25 Mar 2005: send more info in the request header * Definition at line 207 of file afni_version.c. Referenced by AFNI_version_check(). |
|
|
|
|
|
Definition at line 13 of file afni_version.c. Referenced by AFNI_start_version_check(). |
|
|
|
|
|
|
|
|
Definition at line 12 of file afni_version.c. Referenced by AFNI_start_version_check(). |
|
|
Definition at line 15 of file afni_version.c. Referenced by AFNI_start_version_check(), and AFNI_version_check(). |
Function Documentation
|
|
Definition at line 409 of file afni_version.c. Referenced by AFNI_startup_timeout_CB().
00409 { return NULL; }
|
|
|
Start the Web fetch to check the AFNI version in a child process. To complete things, call AFNI_version_check() somewhat later. -------------------------------------------------------------------------- Definition at line 47 of file afni_version.c. References AFNI_noenv(), atexit(), disabled, FAIL_MESSAGE, getenv(), iochan_clearcheck(), iochan_enable_perror(), iochan_init(), iochan_sendall(), iochan_sleep(), iochan_writecheck(), NI_free_element(), NI_get_attribute(), NI_read_element(), NI_stream_close(), NI_stream_open(), read_URL(), set_HTTP_10(), set_HTTP_user_agent(), STR_CHILD, vc_child_pid, vc_exit(), VERSION_URL, vexit(), and VSIZE. Referenced by main().
00048 {
00049 pid_t child_pid ;
00050
00051 #ifdef CYGWIN /* 18 Dec 2002 */
00052 FAIL_MESSAGE("not possible under Cygwin") ;
00053 return ;
00054 #else
00055
00056 /*-- decide if we are to do anything --*/
00057
00058 if( AFNI_noenv("AFNI_VERSION_CHECK") ){ /* never check */
00059 FAIL_MESSAGE("AFNI_VERSION_CHECK forbids") ;
00060 return ;
00061 }
00062
00063 #undef VDELAY
00064 #define VDELAY 429999 /* 429999 s = 5 days */
00065 /* check if we did this in the last VDELAY seconds */
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 ){ /* don't check */
00082 NI_free_element(nel) ; disabled = 1 ; return ;
00083 }
00084 }
00085 rhs = NI_get_attribute(nel,"version_string") ; /* 27 Jan 2003 */
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 /*-- OK, start the child process --*/
00097
00098 child_pid = fork() ;
00099 if( child_pid == (pid_t)(-1) ){ /* bad */
00100 FAIL_MESSAGE("can't fork") ;
00101 return ;
00102 }
00103
00104 if( child_pid > 0 ){ /* I'm the parent */
00105
00106 /*-- save PID of child for later use --*/
00107
00108 vc_child_pid = child_pid ;
00109
00110 /*-- open a shared mem segment to talk to child --*/
00111
00112 vc_ioc = iochan_init( STR_CHILD , "accept" ) ;
00113 if( vc_ioc == NULL ){
00114 kill(child_pid,SIGTERM) ; /* cf. Abraham and Isaac */
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" ); /* 13 Jan 2003 */
00119 atexit( vc_exit ) ; /* 12 Dec 2002 */
00120 }
00121 return ;
00122
00123 } else { /* I'm the child */
00124 /* (never returns) */
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) ; /* don't print TCP/IP error messages */
00132 signal( SIGTERM , vexit ) ; /* if parent kills us, call vexit() */
00133
00134 /*-- get information from the AFNI server --*/
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 /** 25 Mar 2005: send more info in the request header **/
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 /* send the request */
00170
00171 nbuf = read_URL( VERSION_URL , &vbuf ) ; /* may take a while */
00172
00173 set_HTTP_10( 0 ) ;
00174
00175 /*-- if this failed, quit --*/
00176
00177 if( nbuf <= 0 || vbuf == NULL || vbuf[0] == '\0' ) vexit(1);
00178
00179 /*-- talk to parent process thru shared memory --*/
00180
00181 ioc = iochan_init( STR_CHILD , "create" ) ;
00182 if( ioc == NULL ) vexit(2);
00183
00184 /*-- wait until ioc is ready for writing --*/
00185
00186 jj = iochan_writecheck(ioc,-1) ;
00187 if( jj < 0 ) vexit(3);
00188
00189 /*-- send the info in vbuf --*/
00190
00191 iochan_sendall( ioc , vbuf , nbuf ) ;
00192 while( ! iochan_clearcheck(ioc,10) ) /* loop until cleared */
00193 iochan_sleep(10) ; /* by parent process */
00194
00195 iochan_sleep(10); /* a little extra napping */ _exit(0);
00196 }
00197 #endif /* not CYGWIN */
00198 }
|
|
|
Complete the version check by seeing if the child process has any data to report from the AFNI web site. Returns 1 if the version at the AFNI site doesn't match the version of this program; returns 0 if they match, or it can't tell. Also prints stuff out. -------------------------------------------------------------------------- Definition at line 217 of file afni_version.c. References AFMALL, AFNI_HOST, free, getenv(), IOCHAN_CLOSE, iochan_readcheck(), iochan_recv(), KAPUT, NI_new_data_element(), NI_set_attribute(), NI_stream_close(), NI_stream_open(), NI_TEXT_MODE, NI_write_element(), vc_child_pid, and VSIZE. Referenced by AFNI_startup_timeout_CB().
00218 {
00219 int jj , nbuf=0 ;
00220 char *vbuf=NULL ;
00221 char vv[128]="none" ;
00222 char *sname , *vvbuf ;
00223
00224 #ifdef CYGWIN /* 30 Jun 2005 [rickr] */
00225
00226 return 0;
00227
00228 #else
00229
00230 /* if something is rotten, then toss it out */
00231
00232 if( disabled ) return 0 ; /* 27 Jan 2003 */
00233
00234 if( vc_ioc == NULL || vc_child_pid == (pid_t)(-1) ) KAPUT("bad child state");
00235
00236 jj = kill(vc_child_pid,0) ; /* is child alive? */
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 ) ; /* is iochan open yet? */
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 /* if here, have data ready to read from child! */
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 /* now wait for child to kill itself */
00262
00263 waitpid(vc_child_pid,NULL,WNOHANG); vc_child_pid = (pid_t)(-1);
00264 IOCHAN_CLOSE(vc_ioc);
00265
00266 /* no data? */
00267
00268 if( nbuf <= 0 ){ free(vbuf); vbuf = NULL; KAPUT("bad version data"); } /* unlikely */
00269
00270 /* extract version and data/time strings from data */
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 /* record the current time, so we don't check too often */
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 ) /* 27 Jan 2003 */
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 /* compare version strings */
00301
00302 if( strcmp(vv,VERSION) == 0 ){ /* versions match */
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 /* print a message about version mismatch */
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 /* CYGWIN */
00328 }
|
|
|
This is called at main AFNI process exit, to destroy vc_ioc if it is still open. -------------------------------------------------------------------------- Definition at line 40 of file afni_version.c. References iochan_close(). Referenced by AFNI_start_version_check().
00040 { iochan_close(vc_ioc) ; } /* 12 Dec 2002 */
|
|
|
This is only called from within the child process. Definition at line 25 of file afni_version.c. Referenced by AFNI_start_version_check().
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 }
|
Variable Documentation
|
|
Definition at line 10 of file afni_version.c. Referenced by AFNI_start_version_check(). |
|
|
Definition at line 17 of file afni_version.c. Referenced by AFNI_start_version_check(), and AFNI_version_check(). |
|
|
Definition at line 18 of file afni_version.c. |