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. |