Skip to content

AFNI/NIfTI Server

Sections
Personal tools
You are here: Home » AFNI » Documentation

Doxygen Source Code Documentation


Main Page   Alphabetical List   Data Structures   File List   Data Fields   Globals   Search  

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)
IOCHANvc_ioc = NULL

Define Documentation

#define AFNI_HOST   "http://afni.nimh.nih.gov/afni/"
 

Definition at line 14 of file afni_version.c.

Referenced by AFNI_version_check().

#define FAIL_MESSAGE reason   
 

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

#define KAPUT ss       return
 

25 Mar 2005: send more info in the request header *

Definition at line 207 of file afni_version.c.

Referenced by AFNI_version_check().

#define PCLAB   "Unknown"
 

#define STR_CHILD   "tcp:localhost:20279"
 

Definition at line 13 of file afni_version.c.

Referenced by AFNI_start_version_check().

#define USE_HTTP_10
 

#define VDELAY   429999
 

#define VERSION_URL   "http://afni.nimh.nih.gov/afni/AFNI.version"
 

Definition at line 12 of file afni_version.c.

Referenced by AFNI_start_version_check().

#define VSIZE   1024
 

Definition at line 15 of file afni_version.c.

Referenced by AFNI_start_version_check(), and AFNI_version_check().


Function Documentation

char* AFNI_make_update_script void   
 

Definition at line 409 of file afni_version.c.

Referenced by AFNI_startup_timeout_CB().

00409 { return NULL; }

void AFNI_start_version_check void   
 

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 }

int AFNI_version_check void   
 

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 }

void vc_exit void    [static]
 

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 */

void vexit int    sig [static]
 

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

int disabled = 0 [static]
 

Definition at line 10 of file afni_version.c.

Referenced by AFNI_start_version_check().

pid_t vc_child_pid = (pid_t)(-1) [static]
 

Definition at line 17 of file afni_version.c.

Referenced by AFNI_start_version_check(), and AFNI_version_check().

IOCHAN* vc_ioc = NULL [static]
 

Definition at line 18 of file afni_version.c.

 

Powered by Plone

This site conforms to the following standards: