00001 00002 /* 00003 * THIS FILE IS UNDER RCS - DO NOT MODIFY UNLESS YOU HAVE 00004 * CHECKED IT OUT USING THE COMMAND CHECKOUT. 00005 * 00006 * $Id: dave__trig_8c-source.html 2161 2006-05-19 16:55:03Z paulf $ 00007 * 00008 * Revision history: 00009 * $Log$ 00009 * Revision 1.1 2006/05/19 16:55:01 paulf 00009 * first inclusion 00009 * 00010 * Revision 1.6 2001/04/05 17:56:27 cjbryan 00011 * *** empty log message *** 00012 * 00013 * Revision 1.5 2001/03/22 16:13:28 alex 00014 * *** empty log message *** 00015 * 00016 * Revision 1.4 2001/03/21 18:50:27 alex 00017 * subnet NULL fix as per Pete. 00018 * 00019 * Revision 1.3 2001/03/21 02:20:04 alex 00020 * Alex 3/20/1 added .subnet stuff for CVO 00021 * 00022 * Revision 1.2 2000/03/31 18:26:03 lucky 00023 * *** empty log message *** 00024 * 00025 * Revision 1.1 2000/02/14 18:51:48 lucky 00026 * Initial revision 00027 * 00028 * 00029 */ 00030 00031 /************************************************************ 00032 * parse_trig.c * 00033 * * 00034 * 1/19/00 Alex: changed eventId from being an integer to * 00035 * a string. * 00036 * * 00037 * Mon Nov 2 11:02:23 MST 1998 lucky * 00038 * Y2K compliance: * 00039 * SNIPPET struct has been modified to include 8 digit * 00040 * date (YYYYMMDD), and corresponding changes have been * 00041 * made in parse_Snippet(). * 00042 * * 00043 * t_atodbl() changed to reflect YYYYMMDD. Introduced * 00044 * defines that hold string lengths in case these formats * 00045 * ever need to be changed in the future. Call to * 00046 * epocchsec15() replaced by epochsec17(). * 00047 * * 00048 ************************************************************/ 00049 00050 #include <stdio.h> 00051 #include <stdlib.h> 00052 #include <string.h> 00053 #include <time.h> 00054 00055 #ifndef EARTHWORM_H 00056 #include <earthworm.h> 00057 #endif 00058 #include <parse_trig.h> 00059 00060 00061 #define LINE_LEN 500 00062 #define BAD_TIME_VALUE 5 00063 00064 /* Function declarations */ 00065 extern int epochsec17 (double *, char *); 00066 int getNextLine (char**, char*); 00067 int t_atodbl (char*, char*, double*); 00068 00069 /* 00070 Story: 00071 parseSnippet() parses a trigger message. Inspired by, and uses, 00072 strtok. Therefore, IT IS NOT MULTI-THREAD SAFE. It must be mutex 00073 protected against concurrent calls to strtok. 00074 00075 Arguments: 00076 msg: pointer to the trigger message. 00077 pSnp: pointer to a SNIPPET structure (see parse_trig.h) 00078 nxtLine:running pointer to current line to be parsed. 00079 00080 Usage: 00081 For the first call, set nxtLine to msg. This tells parseSnippet that 00082 we're starting a new message. It will search for, and parse the event 00083 id. It will also parse the first line, and stuff the elements of the 00084 SNIPPET structure. It will then advance nxtLine to point to the next 00085 line to be parsed and return. Subsequent calls, with the adjusted 00086 value of nxtLine, will result in the next line of the message being 00087 parsed. When the last line has been parsed, a EW_FAILURE will be 00088 returned. 00089 */ 00090 00091 00092 /*********************************************************************** 00093 * parseSnippet() parses snippet parameters from next line of trigger * 00094 * message. Returns EW_FAILURE when nothing left. * 00095 * Does its own error logging via logit. * 00096 ***********************************************************************/ 00097 int parseSnippet( char* msg, SNIPPET* pSnp, char** nxtLine) 00098 { 00099 static char terminators[] = " \t\n"; /* we accept space, newline, and tab as terminators */ 00100 char* nxttok; 00101 char line[LINE_LEN]; 00102 static int startFresh=0; 00103 00104 /* if pointer to next line points to start of message, start clean 00105 *****************************************************************/ 00106 if (*nxtLine == msg) startFresh = 1; 00107 else goto GetNextStation; 00108 00109 /* if event id is negative, search for new EVENT ID 00110 **************************************************/ 00111 00112 00113 GetNextEvent: /* we jump to here when we run off the end of an event (below) */ 00114 00115 /* we're looking for a line with the form shown below: 00116 EVENT DETECTED 19970729 03:01:13.22 UTC EVENT ID: 123ABC AUTHOR: Harry SUBNET: redoubt 00117 * 00118 ************************* Y2K ************************/ 00119 00120 if ( startFresh == 1) 00121 { 00122 /* get next non-zero length line from trigger message */ 00123 while ( getNextLine(nxtLine, line) >= 0 ) /* it returns number of chars in line */ 00124 { 00125 /* skip this line if it doesn't start with EVENT */ 00126 /*** MULTI-THREAD WARNING: strtok is not safe (but it is ubiquitus) ***/ 00127 if ( strcmp( strtok( line, terminators), "EVENT" ) != 0) continue; 00128 00129 /* on this line, find "ID:" which is followed by the event id string */ 00130 while ( (nxttok = strtok( (char*)NULL, terminators)) != NULL ) /* over tokens on this line */ 00131 { 00132 if ( strcmp( nxttok, "ID:" ) != 0) continue; 00133 nxttok = strtok( (char*)NULL, terminators); /* this had better be the event id */ 00134 if (nxttok == NULL) /* oops - there was nothing after ID: */ 00135 { 00136 logit("et", "parse_trig: Bad syntax in trigger message." 00137 " Cant find EVENT ID in:\n.%s.\n", line); 00138 break; 00139 } 00140 strncpy(pSnp->eventId, nxttok, EVENTID_SIZE); 00141 pSnp->eventId[EVENTID_SIZE-1] = '\0'; /* Ensure null termination */ 00142 00143 /* Now search for author id */ 00144 nxttok = strtok( (char*)NULL, terminators); /* this had better be "AUTHOR:" */ 00145 if ( strcmp( nxttok, "AUTHOR:" ) != 0) 00146 { 00147 logit("et", "parse_trig: Bad syntax in trigger message." 00148 " Cant find AUTHOR:\n.%s.\n", line); 00149 break; 00150 } 00151 nxttok = strtok( (char*)NULL, terminators); /* this had better be author's name */ 00152 strncpy(pSnp->author, nxttok, AUTHOR_FIELD_SIZE); 00153 pSnp->author[AUTHOR_FIELD_SIZE-1] = '\0'; /* Ensure null termination */ 00154 00155 /* Now search for optional subnet */ 00156 nxttok = strtok( (char*)NULL, terminators); /* this might be "SUBNET:" */ 00157 if(nxttok == NULL) 00158 { 00159 pSnp->subnet[0] = '\0'; 00160 startFresh = 0; 00161 goto GotNextEvent; 00162 } 00163 if ( strcmp( nxttok, "SUBNET:" ) != 0) 00164 { 00165 pSnp->subnet[0] = '\0'; 00166 startFresh = 0; /* SUBNET is optional; we're happy with the titile line. Ready for rest of message */ 00167 goto GotNextEvent; 00168 } 00169 nxttok = strtok( (char*)NULL, terminators); /* this had better be subnet name */ 00170 if(nxttok != NULL) strncpy(pSnp->subnet, nxttok, MAX_SUBNET_LEN); /* as per Pete: if there's 00171 nothing there, nxttok will be NULL, which is on Solaris fatal for strncpy */ 00172 pSnp->subnet[MAX_SUBNET_LEN-1] = '\0'; /* Ensure null termination */ 00173 00174 startFresh = 0; /* we're happy with the titile line. Ready for rest of message */ 00175 goto GotNextEvent; 00176 } /* end of loop over tokens in this line */ 00177 } /* end of loop over lines in message */ 00178 return(EW_FAILURE); /* no more lines */ 00179 } /* end of search for event id */ 00180 00181 00182 00183 GotNextEvent: 00184 00185 /* So we have an event id. Now parse and return snippet parameters until a blank line 00186 *************************************************************************************/ 00187 getNextLine(nxtLine, line); /* step over the blank line */ 00188 getNextLine(nxtLine, line); /* step over the column titles line */ 00189 getNextLine(nxtLine, line); /* step over the silly dashes line */ 00190 00191 /* Read the next station line 00192 *****************************/ 00193 GetNextStation: 00194 if( getNextLine(nxtLine, line) <= 0 ) /* this should be a station trigger line */ 00195 { 00196 return(EW_FAILURE); /* no more lines */ 00197 } 00198 if ( ( nxttok=strtok(line, terminators) ) == NULL ) /* first token should be station name */ 00199 { 00200 logit("et","parse_trig: Bad syntax in trigger message:" 00201 "Strange station line - no tokens in: \n.&s.\n",line); 00202 goto GetNextEvent; 00203 } 00204 00205 /* Find SCN names 00206 ****************/ 00207 if (nxttok ==NULL) /* oops - should have been the station name */ 00208 { 00209 logit("et", "parse_trig: Bad syntax in trigger message." 00210 " Cant find statio name in:\n.%s.\n", line); 00211 goto GetNextStation; 00212 } 00213 strncpy( pSnp->sta, nxttok, 7); /* Put away the station name */ 00214 pSnp->sta[6] = '\0'; /* Ensure null termination */ 00215 00216 nxttok = strtok( (char*)NULL, terminators); /* should be the component */ 00217 if (nxttok ==NULL) /* oops - there was nothing after station name */ 00218 { 00219 logit("et", "parse_trig: Bad syntax in trigger message." 00220 " Cant find comp name in:\n.%s.\n", line); 00221 goto GetNextStation; 00222 } 00223 strncpy( pSnp->chan, nxttok, 9 ); /* Put away the component */ 00224 pSnp->chan[8] = '\0'; /* Ensure null termination */ 00225 00226 nxttok = strtok( (char*)NULL, terminators); /* should be the net */ 00227 if (nxttok ==NULL) /* oops - there was nothing after component name */ 00228 { 00229 logit("et", "parse_trig: Bad syntax in trigger message." 00230 " Cant find net name in:\n.%s.\n", line); 00231 goto GetNextStation; 00232 } 00233 strncpy( pSnp->net, nxttok, 9 ); /* put away the net */ 00234 pSnp->net[8] = '\0'; /* Ensure null termination */ 00235 00236 /* And now, find "save:" 00237 ***********************/ 00238 while ( (nxttok=strtok((char*)NULL, terminators) ) != NULL ) /* run down the tokens */ 00239 { 00240 if ( strcmp( nxttok, "save:" ) == 0 ) goto FoundSave; /* looking for 'save:' */ 00241 } 00242 logit("et","parse_trig: Bad syntax in trigger message:" 00243 "Bad station line - no save token found: \n.%s.\n",line); 00244 goto GetNextStation; 00245 FoundSave: 00246 00247 /* now find time strings 00248 ***********************/ 00249 nxttok = strtok( (char*)NULL, terminators); /* should be the save start date */ 00250 if (nxttok ==NULL) /* oops - there was nothing after save: */ 00251 { 00252 logit("et", "parse_trig: Bad syntax in trigger message." 00253 " Cant find save date in:\n.%s.\n", line); 00254 goto GetNextStation; 00255 } 00256 strcpy( pSnp->startYYYYMMDD, nxttok ); /* put away the date string */ 00257 00258 nxttok = strtok( (char*)NULL, terminators); /* sould be the save start time-of-day */ 00259 if (nxttok ==NULL) /* oops - there was nothing after save: */ 00260 { 00261 logit("et", "parse_trig: Bad syntax in trigger message." 00262 " Cant find save time of day in:\n.%s.\n", line); 00263 goto GetNextStation; 00264 } 00265 strcpy( pSnp->startHHMMSS, nxttok ); /* put away the time-of-day string */ 00266 00267 /* Convert start time to double 00268 ******************************/ 00269 if( t_atodbl(pSnp->startYYYYMMDD, pSnp->startHHMMSS, &(pSnp->starttime) ) < 0) 00270 { 00271 logit("et", "parse_trig: Bad syntax in trigger message." 00272 " Dont understand start-time in:\n.%s.\n", line); 00273 goto GetNextStation; 00274 } 00275 if ( pSnp->starttime < BAD_TIME_VALUE ) /* unreasonable time value */ 00276 { 00277 logit("et", "parse_trig: Bad syntax in trigger message." 00278 " Bad start time value in:\n.%s.\n", line); 00279 goto GetNextStation; 00280 } 00281 00282 /* find duration to save 00283 ***********************/ 00284 nxttok = strtok( (char*)NULL, terminators); /* should be the duration */ 00285 if (nxttok ==NULL) /* oops - there was nothing after save: */ 00286 { 00287 logit("et", "parse_trig: Bad syntax in trigger message." 00288 " Cant find duration in:\n.%s.\n", line); 00289 goto GetNextStation; 00290 } 00291 pSnp->duration = atol( nxttok ); 00292 if ( pSnp->duration <= 0 ) 00293 { 00294 logit("et", "parse_trig: Bad syntax in trigger message." 00295 " Bad duration value in:\n.%s.\n", line); 00296 goto GetNextStation; 00297 } 00298 00299 return(EW_SUCCESS); 00300 } 00301 /* ----------------------------------- end of parseSnippet() -------------------------------------- */ 00302 00303 /************************************************************************** 00304 * getNextLine(msg, line) moves the next line from 'msg' into 'line * 00305 * returns the number of characters in the line * 00306 * Returns negative if error. * 00307 **************************************************************************/ 00308 int getNextLine ( char** pNxtLine, char* line) 00309 { 00310 int i; 00311 char* nxtLine; 00312 00313 nxtLine=*pNxtLine; 00314 00315 for (i =0; i< LINE_LEN; i++) 00316 { 00317 line[i] = *nxtLine++; 00318 if ( (int)line[i] == 0 ) 00319 { 00320 return(-1); /* Not good */ 00321 } 00322 if (line[i] == '\n') goto normal; 00323 } 00324 logit("","getNextLine error: line too long \n"); 00325 return(-1); 00326 00327 normal: 00328 line[i+1]=0; 00329 *pNxtLine = nxtLine; 00330 return(i); 00331 00332 } 00333 /* ----------------------------------- end of getNextLine() -------------------------------------- */ 00334 00335 00336 /************************************************************************** 00337 * t_atodbl() takes date and time strings, and converts to double * 00338 * seconds since 1970. Note that the time of day string * 00339 * is of the form "hh:mm:ss.ss" * 00340 * Returns negative if error. * 00341 **************************************************************************/ 00342 00344 #define TIMESTR_LEN 17 /* whole string */ 00345 #define YMD_LEN 8 /* date part: YYYYMMDD */ 00346 #define HOUR_LEN 2 /* hours from HH:MM:SS.SS */ 00347 #define MIN_LEN 2 /* minutes from HH:MM:SS.SS */ 00348 #define SEC_LEN 5 /* seconds from HH:MM:SS.SS */ 00349 00350 int t_atodbl(char* YYYYMMDD, char* HHMMSS, double* starttime) 00351 { 00352 char timestr[TIMESTR_LEN+1]; /* need space for the null-terminator */ 00353 int ret; 00354 int tgtind, srcind; /* indices for copying fields into timestr */ 00355 00356 /************************* Y2K ************************ 00357 * 00358 * All instances of YYMMDD have been changed to YYYYMMDD 00359 * 00360 ************************* Y2K ************************/ 00361 00362 /* we want a string of the form yyyymmddhhmmss.ss */ 00363 /* 01234567890123456 */ 00364 00365 tgtind = 0; 00366 srcind = 0; 00367 00368 /* Copy in the date */ 00369 strcpy(timestr,YYYYMMDD); 00370 00371 /* Append the hour */ 00372 tgtind = tgtind + YMD_LEN; 00373 strncpy(×tr[tgtind], HHMMSS, HOUR_LEN); 00374 00375 /* Append the minute */ 00376 tgtind = tgtind + HOUR_LEN; 00377 srcind = srcind + HOUR_LEN + 1; 00378 strncpy(×tr[tgtind] ,&HHMMSS[srcind], MIN_LEN); 00379 00380 /* Append the seconds */ 00381 tgtind = tgtind + MIN_LEN; 00382 srcind = srcind + MIN_LEN + 1; 00383 strncpy(×tr[tgtind], &HHMMSS[srcind], SEC_LEN); 00384 00385 /* Null terminate the string */ 00386 tgtind = tgtind + SEC_LEN; 00387 timestr[tgtind] = '\0'; 00388 00389 00390 /* convert to double seconds */ 00391 ret = epochsec17(starttime, timestr); 00392 if (ret < 0) 00393 { 00394 logit("t","bad return from epochsec17\n"); 00395 return(-1); 00396 } 00397 return(1); 00398 } 00399 /* ----------------------------------- end of t_atodbl() ----------------------------------------- */