int AFNI_version_check(void) { int jj , nbuf=0 , vdiff=0 ; char *vbuf=NULL ; char vv[128]="none" ; char *sname , *vvbuf ; #ifdef CYGWIN /* 30 Jun 2005 [rickr] */ return 0; #else /* if something is rotten, then toss it out */ /* (or AFNI_start_fetching_url() sets disabled if it is too soon) */ if( GLOBAL_argopt.allow_rt || disabled ) return 0 ; /* 27 Jan 2003 */ if( vc_ioc == NULL || vc_child_pid == (pid_t)(-1) ) KAPUT("bad child state"); jj = kill(vc_child_pid,0) ; /* is child alive? */ if( jj < 0 ){ IOCHAN_CLOSE(vc_ioc); vc_child_pid=(pid_t)(-1); KAPUT("child not alive"); } jj = iochan_readcheck( vc_ioc , 333 ) ; /* is iochan open yet? */ if( jj <= 0 ){ IOCHAN_CLOSE(vc_ioc); kill(vc_child_pid,SIGTERM); vc_child_pid=(pid_t)(-1); KAPUT("connection to child gone bad"); } /* if here, have data ready to read from child! */ nbuf = 0 ; vbuf = AFMALL(char, VSIZE) ; while(1){ jj = iochan_recv( vc_ioc , vbuf+nbuf , VSIZE-nbuf ) ; if( jj < 1 ) break ; nbuf += jj ; if( nbuf >= VSIZE-1 ) break ; jj = iochan_readcheck( vc_ioc , 5 ) ; if( jj < 1 ) break ; } /* now wait for child to kill itself */ waitpid(vc_child_pid,NULL,WNOHANG); vc_child_pid = (pid_t)(-1); IOCHAN_CLOSE(vc_ioc); /* no data? */ /* require enough (12 bytes) for e.g. AFNI_16.0.00 */ if( nbuf < EXPECTED_AFNI_VER_STRLEN ) { free(vbuf); vbuf = NULL; KAPUT("bad version data"); } /* unlikely */ /* extract version and data/time strings from data */ vvbuf = strstr(vbuf,"AFNI_") ; /* 29 Nov 2005: scan for version string */ if( vvbuf == NULL ) vvbuf = vbuf ; sscanf( vvbuf , "%127s" , vv ); /* get version string out of data */ vvbuf = strstr(vbuf,"motd=") ; /* 29 Nov 2005: motd string */ if( vvbuf != NULL ){ motd_new = (char *)calloc(sizeof(char),VSIZE) ; sscanf( vvbuf+5 , "%988s" , motd_new ) ; if( motd_new[0] == '\0' ){ free(motd_new); motd_new=NULL; } } free(vbuf) ; /* done with the input data from the child */ /* record the current time, so we don't check too often */ /* move to separate function 22 Mar 2016 [rickr] */ AFNI_update_vctime(vv, motd_new) ; /* 29 Nov 2005: compare motd strings (old and new) if different, save new one in GLOBAL_motd for display later */ if( motd_new != NULL ){ if( motd_old == NULL || strcmp(motd_new,motd_old) != 0 ){ GLOBAL_motd = motd_new ; } else { free(motd_new) ; motd_new = NULL ; } } if( motd_old != NULL ){ free(motd_old); motd_old=NULL; } /* compare version strings */ /* set vdiff = quarterly difference between web version and our version */ if( AFNI_version_diff(vv, AVERZHN, &vdiff) ) return 0 ; /* if at least 2 quarters old (truncates to 3+ months), warn user */ if( vdiff >= 2 ) { fprintf(stderr, "\n" "****************************************************\n" " This AFNI version is %d+ months old:\n" " Version ID = %s\n" " Latest version at %s\n" " Version ID = %s\n" "****************************************************\n" " To disable future version checks:\n" " set environment variable AFNI_VERSION_CHECK to NO\n" "****************************************************\n", (vdiff-1)*3, AVERZHN, AFNI_HOST , vv ) ; return 1 ; } return 0 ; #endif /* CYGWIN */ }
int AFNI_compile_date_check(void) { int jj , nbuf=0 , day_diff=0 ; char *vbuf=NULL , *qbuf ; int new_day =-666 , old_day =-666 ; int new_year =-666 , old_year =-666 ; char new_mon[8] = "Zork" , old_mon[8] = "Zork" ; int new_imm , old_imm ; #ifdef CYGWIN /* 30 Jun 2005 [rickr] */ return 0; #else /* if something is rotten, then toss it out */ if( GLOBAL_argopt.allow_rt || disabled ) return 0 ; /* 27 Jan 2003 */ if( vc_ioc == NULL || vc_child_pid == (pid_t)(-1) ) KAPUT("bad child state"); jj = kill(vc_child_pid,0) ; /* is child alive? */ if( jj < 0 ){ IOCHAN_CLOSE(vc_ioc); vc_child_pid=(pid_t)(-1); KAPUT("child not alive"); } jj = iochan_readcheck( vc_ioc , 333 ) ; /* is iochan open yet? */ if( jj <= 0 ){ IOCHAN_CLOSE(vc_ioc); kill(vc_child_pid,SIGTERM); vc_child_pid=(pid_t)(-1); KAPUT("connection to child gone bad"); } /* if here, have data ready to read from child! */ nbuf = 0 ; vbuf = AFMALL(char, VSIZE) ; while(1){ jj = iochan_recv( vc_ioc , vbuf+nbuf , VSIZE-nbuf ) ; if( jj < 1 ) break ; nbuf += jj ; if( nbuf >= VSIZE-1 ) break ; jj = iochan_readcheck( vc_ioc , 5 ) ; if( jj < 1 ) break ; } /* now wait for child to kill itself */ waitpid(vc_child_pid,NULL,WNOHANG); vc_child_pid = (pid_t)(-1); IOCHAN_CLOSE(vc_ioc); /* no data? */ if( nbuf < 11 ){ free(vbuf); vbuf = NULL; KAPUT("bad compile date data"); } /* unlikely */ /* extract date info from string [e.g., "16 Jun 2014"] */ qbuf = strcasestr(vbuf,"Content-Length:") ; if( qbuf != NULL ){ char *zbuf = strstr(qbuf,"\r\n\r\n") ; if( zbuf != NULL ) qbuf = zbuf + 4 ; } else { qbuf = vbuf ; } sscanf( qbuf , "%d %s %d" , &new_day , new_mon , &new_year ) ; sscanf( __DATE__ , "%s %d %d" , old_mon , &old_day , &old_year ) ; /* day/mon invert */ free(vbuf) ; /* done with the input data from the child */ /* bad results? */ if( new_day < 0 || new_mon[0] == 'Z' || new_year < 0 ) return 0 ; if( old_day < 0 || old_mon[0] == 'Z' || old_year < 0 ) return 0 ; /* compare dates */ for( jj=0 ; jj < 12 ; jj++ ) if( strcasecmp(new_mon,monlist[jj]) == 0 ) break ; if( jj < 12 ) new_imm = jj ; else return 0 ; for( jj=0 ; jj < 12 ; jj++ ) if( strcasecmp(old_mon,monlist[jj]) == 0 ) break ; if( jj < 12 ) old_imm = jj ; else return 0 ; day_diff = (new_year-old_year)*365 + (new_imm-old_imm)*31 + (new_day-old_day) ; /* record the current time, so we don't check too often */ { char *home=getenv("HOME") , mname[VSIZE]="file:" ; NI_stream ns ; if( home != NULL ) strcat(mname,home) ; strcat(mname,"/.afni.vctime") ; ns = NI_stream_open( mname , "w" ) ; if( ns != NULL ){ NI_element *nel=NI_new_data_element("AFNI_vctime",0); char rhs[32]; sprintf(rhs,"%d",(int)time(NULL)) ; NI_set_attribute( nel , "version_check_time" , rhs ) ; NI_write_element( ns , nel , NI_TEXT_MODE ) ; NI_stream_close(ns) ; } } return day_diff ; #endif /* CYGWIN */ }
int afni_io(void) { static int afni_mode = AFNI_OPEN_CONTROL_MODE ; /* status variable */ static IOCHAN * afni_ioc = NULL ; /* connection to AFNI */ int ii ; /***************************************************************/ /***** Check to see if status is OK before we proceed. *****/ /***** (if an error occurs below, afni_mode gets set to 0) *****/ if( afni_mode <= 0 ) return -1 ; /***********************************************************************/ /***** First time into this routine? Open control channel to AFNI *****/ if( afni_mode == AFNI_OPEN_CONTROL_MODE ){ char afni_iocname[128] ; /* will hold name of I/O channel */ /** Note that the control channel is always a TCP/IP channel to port #get_port_named("AFNI_PLUGOUT_TCP_0") (used to be #7955) on the AFNI host system **/ if( strcmp(afni_host,".") == 0 ) sprintf( afni_iocname , "tcp:%s:%d" , "localhost", get_port_named("AFNI_PLUGOUT_TCP_0") ); /* make name */ else sprintf( afni_iocname , "tcp:%s:%d" , afni_host, get_port_named("AFNI_PLUGOUT_TCP_0") ) ; /* make name */ afni_ioc = iochan_init( afni_iocname , "create" ) ; /* create it */ if( afni_ioc == NULL ){ fprintf(stderr, "Can't create control channel %s to AFNI!\n",afni_iocname) ; afni_mode = 0 ; return -1 ; } afni_mode = AFNI_WAIT_CONTROL_MODE ; /* waiting for AFNI connection */ if( afni_verbose ) fprintf(stderr,"AFNI control channel created\n") ; } /****************************************************/ /**** Check if AFNI control channel is connected ****/ if( afni_mode == AFNI_WAIT_CONTROL_MODE ){ ii = iochan_writecheck( afni_ioc , 5 ) ; /* wait at most 5 msec */ /** the iochan_*check() routines return -1 for an error, 0 if not ready, >0 if the I/O channel is ready. **/ if( ii < 0 ){ fprintf(stderr,"Control channel to AFNI failed!\a\n") ; IOCHAN_CLOSE(afni_ioc) ; afni_mode = 0 ; return -1 ; } else if( ii > 0 ){ afni_mode = AFNI_OPEN_DATA_MODE ; /* prepare to send data */ if( afni_verbose ) fprintf(stderr,"AFNI control channel connected\n"); } else { return 0 ; /* try again next time */ } } /**********************************************************/ /**** Send control data to AFNI, and open data channel ****/ if( afni_mode == AFNI_OPEN_DATA_MODE ){ char afni_iocname[128] ; char afni_buf[256] ; /** decide name of data channel: use shared memory (shm:) on ".", use TCP/IP (tcp:) on other computer systems; * Note that the TCP/IP port number can be anything that isn't already in use; * Note that the shm control name (here "test_plugout") is a string that will be converted to an IPC key (in function string_to_key in iochan.c). **/ if( strcmp(afni_host,".") == 0 ) strcpy( afni_iocname , "shm:test_plugout:1K+1K" ) ; else sprintf( afni_iocname , "tcp:%s:%d" , afni_host , afni_port ) ; /** write the command to AFNI into the buffer: * each command ends with a newline character, except (possibly) the last command; * the command buffer is a C string, which ends with an ASCII NUL character; * TT_XYZ_DELTA means 'send me T-T coordinates when they change'; * DSET_IJK_DELTA means 'send me IJK voxel indices when they change'; * PONAME means 'use this string for informative messages'; * IOCHAN means 'use this I/O channel from now on'. **/ if( afni_name[0] == '\0' ) strcpy(afni_name,"aManCalledHorse") ; if( afni_do_ijk ){ sprintf( afni_buf , "DSET_IJK_DELTA\n" "UNDERLAY_DELTA\n" "PONAME %s\n" "IOCHAN %s" , afni_name , afni_iocname ) ; } else { sprintf( afni_buf , "TT_XYZ_DELTA\n" "UNDERLAY_DELTA\n" "PONAME %s\n" "IOCHAN %s" , afni_name , afni_iocname ) ; } if( afni_verbose ) fprintf(stderr,"Sending control information to AFNI\n") ; /** note that the ASCII NUL at the end of the buffer is sent **/ ii = iochan_sendall( afni_ioc , afni_buf , strlen(afni_buf)+1 ) ; /** the return value is the number of bytes sent, or -1 indicating a fatal error transpired. **/ if( ii < 0 ){ fprintf(stderr,"Transmission of control data to AFNI failed!\a\n") ; IOCHAN_CLOSE(afni_ioc) ; afni_mode = 0 ; return -1 ; } else { /** wait for the acknowledgment from AFNI, then close channel **/ ii = iochan_recvall( afni_ioc , afni_buf , POACKSIZE ) ; IOCHAN_CLOSE(afni_ioc) ; if( ii < 0 || strncmp(afni_buf,"OK!",3) != 0 ){ fprintf(stderr,"AFNI didn't like control information!\a\n") ; afni_mode = 0 ; return -1 ; } /** now open data channel to AFNI **/ afni_ioc = iochan_init( afni_iocname , "create" ) ; if( afni_ioc == NULL ){ fprintf(stderr, "Can't open data channel %s to AFNI!\a\n",afni_iocname) ; afni_mode = 0 ; return -1 ; } else { afni_mode = AFNI_WAIT_DATA_MODE ; if( afni_verbose ) fprintf(stderr,"AFNI data channel created\n") ; } } } /****************************************************/ /***** See if data channel is connected to AFNI *****/ if( afni_mode == AFNI_WAIT_DATA_MODE ){ ii = iochan_goodcheck( afni_ioc , 5 ) ; /* wait at most 5 msec */ if( ii < 0 ){ fprintf(stderr, "AFNI data channel aborted before any data was sent!\a\n") ; IOCHAN_CLOSE( afni_ioc ) ; afni_mode = 0 ; return -1 ; } else if( ii > 0 ){ /* ready to go! */ afni_mode = AFNI_CONTINUE_MODE ; if( afni_verbose ) fprintf(stderr,"AFNI data channel is open\n") ; } else { return 0 ; /* try again next time */ } } /************************************************************/ /***** The "normal" state of affairs: *****/ /***** AFNI is connected. See if any data is arriving. *****/ if( afni_mode == AFNI_CONTINUE_MODE ){ char afni_buf[256] ; float xx , yy , zz ; int ix , jy , kz ; ii = iochan_readcheck( afni_ioc , 0 ) ; /* don't wait */ /** ii < 0 ==> a fatal error has happened ii == 0 ==> no data is ready ii > 0 ==> data is ready to read from the channel **/ if( ii < 0 ){ fprintf(stderr,"AFNI data channel aborted!\a\n") ; IOCHAN_CLOSE(afni_ioc) ; afni_mode = 0 ; return -1 ; } else if( ii == 0 ){ return 0 ; /* no data ==> try again next time */ } /** at this point, data is incoming from AFNI **/ ii = iochan_recv( afni_ioc , afni_buf , 256 ) ; if( ii <= 0 ){ fprintf(stderr,"AFNI data channel recv failed!\a\n") ; IOCHAN_CLOSE(afni_ioc) ; afni_mode = 0 ; return -1 ; } /** at last! "process" the data from AFNI (in this case, just print it out) **/ #if 0 if( afni_do_ijk ) ii = sscanf( afni_buf , "DSET_IJK %d %d %d" , &ix,&jy,&kz ) ; else ii = sscanf( afni_buf , "TT_XYZ %f %f %f" , &xx,&yy,&zz ) ; /** also, AFNI will wait until we send an acknowledgment; acknowledgment messages are always 4 (POACKSIZE) bytes long **/ if( ii < 3 ){ fprintf(stderr,"AFNI sent bad data: %s\a\n",afni_buf) ; PO_ACK_BAD(afni_ioc) ; } else if( afni_do_ijk ){ fprintf(stderr,"AFNI sent indices: %d %d %d\n",ix,jy,kz) ; PO_ACK_OK(afni_ioc) ; } else { fprintf(stderr,"AFNI sent coords: %9.3f %9.3f %9.3f\n",xx,yy,zz) ; PO_ACK_OK(afni_ioc) ; } #else fprintf(stderr,"AFNI sent data:\n%s\n",afni_buf) ; PO_ACK_OK(afni_ioc) ; #endif } return 0 ; }