int main (int argc, char **argv) { int c, errflg = 0; char *in, *out; int orbin, orbout; double maxpkts = VERY_LARGE_NUMBER ; int quit; char *pktmatch = strdup(".*/pf/evtinfo"), *reject = 0; int nmatch; int specified_after = 0; double after = 0.0, until = VERY_LARGE_NUMBER ; double start_time, end_time, delta_t ; double totpkts = 0, totbytes = 0; Flags flags; static int last_pktid = -1; static double last_pkttime = 0.0; char *statefile = 0; double last_burial = 0.0; double decent_interval = 300.0; int mode = PKT_NOSAMPLES; int rcode; char srcname[ORBSRCNAME_SIZE]; double pkttime = 0.0 ; int pktid; int nbytes; char *packet = 0; int packetsz = 0; Packet *unstuffed = 0; Pf *pf; Tbl *tbl; Arr *arr; char *arrkey; char *pffilename; Tbl *channels; char *net; char *sta; char *chan; char netstachan[ORBSRCNAME_SIZE]; Srcname parts; double maxtime,mintime,starttime,triggertime,duration,min_g,max_g,snr; char *datalogger; int evtfilesize,channelno,maxcts,mincts; char *errors,*evtfilename,*ft,*filter,*srcid; char *line; int i; Pf *pfnew; Dbptr db; int put_tests=0; char *chanmatch=0; Hook *hook=0; char *tdummy=0; char *match=malloc(100); memset (&flags, 0, sizeof (flags)); elog_init (argc, argv); elog_notify (0, "%s $Revision: 1.5 $ $Date: 2005/05/10 07:34:43 $\n", Program_Name); while ((c = getopt (argc, argv, "m:n:r:S:c:tvV")) != -1) { switch (c) { case 'm': match = optarg; sprintf(pktmatch,"%s/pf/evtinfo",match); break; case 'c': chanmatch = optarg; break; case 't': put_tests = 1; break; case 'n': maxpkts = atoi (optarg); break; case 'r': reject = optarg; break; case 'S': statefile = optarg; break; case 'v': flags.verbose++; break; case 'V': flags.verbose++; flags.verbose++; break; case '?': errflg++; } } if (errflg || argc - optind < 2 || argc - optind > 4) usage (); in = argv[optind++]; out = argv[optind++]; if (argc > optind) { after = str2epoch (argv[optind++]); specified_after = 1; if (argc > optind) { until = str2epoch (argv[optind++]); if (until < after) { until += after ; } } } if ((orbin = orbopen (in, "r&")) < 0) die (0, "Can't open input '%s'\n", in); if (statefile != 0) { char *s; if (exhume (statefile, &quit, RT_MAX_DIE_SECS, 0) != 0) { elog_notify (0, "read old state file\n"); } if (orbresurrect (orbin, &last_pktid, &last_pkttime) == 0) { elog_notify (0, "resurrection successful: repositioned to pktid #%d @ %s\n", last_pktid, s = strtime (last_pkttime)); free (s); } else { complain (0, "resurrection unsuccessful\n"); } } if ((orbout = orbopen (out, "w&")) < 0) { die (0, "Can't open output '%s'\n", out); } if (pktmatch) { nmatch = orbselect (orbin, pktmatch); } if (nmatch < 0) { die (1, "select '%s' returned %d\n", pktmatch, nmatch); } if (reject) { nmatch = orbreject (orbin, reject); } if (nmatch < 0) { elog_die (1, "reject '%s' returned %d\n", reject, nmatch); } else { if (flags.verbose) { elog_notify (1,"%d sources selected\n", nmatch); } } if (specified_after) { pktid = orbafter (orbin, after); if (pktid < 0) { char *s; elog_complain (1, "seek to %s failed\n", s = strtime (after)); free (s); pktid = forbtell (orbin); elog_complain (1,"pktid is still #%d\n", pktid); } else { if (flags.verbose) elog_notify (1,"new starting pktid is #%d\n", pktid); } } start_time = now (); db = dbtmp("rt1.0"); while (!quit && pkttime < until && totpkts < maxpkts) { rcode = orbreap (orbin, &pktid, srcname, &pkttime, &packet, &nbytes, &packetsz); switch (rcode) { case 0: totpkts++; totbytes += nbytes; if (flags.verbose>2) { showPkt (pktid, srcname, pkttime, packet, nbytes, stdout, mode); } if (statefile != 0 && last_pkttime - last_burial > decent_interval) { bury (); last_burial = pkttime; } if ((unstuffPkt (srcname, pkttime, packet, nbytes, &unstuffed))==Pkt_pf) { pf = unstuffed->pf; tbl= pfkeys(pf); arrkey= gettbl(tbl,0); pfget(pf,arrkey,&pfnew); datalogger= pfget_string(pfnew,"datalogger"); duration= pfget_double(pfnew,"duration"); errors= pfget_string(pfnew,"errors"); evtfilename= pfget_string(pfnew,"evtfilename"); evtfilesize= pfget_int(pfnew,"evtfilesize"); ft= pfget_string(pfnew,"ft"); starttime= pfget_double(pfnew,"time"); triggertime= pfget_double(pfnew,"triggertime"); channels=pfget_tbl(pfnew,"channels"); if (strcasecmp(ft,"no")==0 || put_tests == 1) { for (i=0; i<maxtbl(channels);i++) { line=gettbl(channels,i); sscanf(line,"%s %d %lf %d %lf %lf %d %lf", netstachan,&channelno,&maxtime,&maxcts,&max_g,&mintime,&mincts,&min_g); split_srcname(netstachan,&parts); strcpy(parts.src_suffix,"GENC"); join_srcname(&parts,netstachan); if (flags.verbose>1) printf("%s,%s\n", netstachan,tdummy=strtime(triggertime)); if (chanmatch == 0 || strmatches(parts.src_chan,chanmatch,&hook)) { if (flags.verbose) elog_notify(1,"putting detev for %s,%s\n", netstachan,tdummy=strtime(triggertime)); db=dblookup(db,0,"detev",0,"dbSCRATCH"); dbputv(db,0,"sta",parts.src_sta,"chan",parts.src_chan, "filter",K2_FILTER, "time", triggertime, "tron", starttime - triggertime, "troff", starttime - triggertime + duration, "iphase","K2", "snr",(max_g * 1000.0 - min_g * 1000.0)/2.0, 0); db2orbpkt(db,orbout); } else { if (flags.verbose>1) elog_notify(1,"ignoring %s,%s\n", netstachan,tdummy=strtime(triggertime)); } } } } last_pktid = pktid; last_pkttime = pkttime; } } if (statefile != 0) bury (); end_time = now (); delta_t = end_time - start_time; if (flags.verbose>1) { if (totpkts > 0) { elog_notify (1,"\n%.0f %.2f byte packets (%.1f kbytes) in %.3f seconds\n\t%10.3f kbytes/s\n\t%10.3f kbaud\n\t%10.3f pkts/s\n", totpkts, totbytes / totpkts, totbytes / 1024, delta_t, totbytes / delta_t / 1024, totbytes / delta_t / 1024 * 8, totpkts / delta_t); } else { elog_notify (1,"\nno packets read\n"); } } if (orbclose (orbin)) { elog_complain (1, "error closing read orb\n"); } if (orbclose (orbout)) { elog_complain (1, "error closing write orb\n"); } return 0; }
static PyObject * python_orbexhume( PyObject *self, PyObject *args ) { char *usage = "Usage: _orbexhume(filename)\n"; char *filename; int rc; if( ! PyArg_ParseTuple( args, "s", &filename ) ) { if( ! PyErr_Occurred() ) { PyErr_SetString( PyExc_RuntimeError, usage ); } return NULL; } rc = exhume( filename, 0, 0, 0 ); return Py_BuildValue( "i", rc ); }
int main( int argc, char **argv ) { int c; int errflag = 0; int orb; int stop = 0; long nrecs; char *match = ".*/pf/st"; char *from = 0; char *statefile = 0; char *pfname = "orb2rrdc"; char *orbname; char *dbcache; char *rrdtool; char command[STRSZ]; char net[STRSZ]; char sta[STRSZ]; char rrdvar[STRSZ]; char key[STRSZ]; char path[FILENAME_MAX]; Dbptr db; Dbptr dbt; Pf *pf; char *Default_network; Tbl *dlslines; Arr *Dls_vars_dsparams; Arr *Dls_vars_rras; Tbl *Dls_vars_keys; char *line; char *dls_var; char *dsparams; Tbl *rras; int i; int j; OrbreapThr *ort; int pktid; char srcname[ORBSRCNAME_SIZE]; double time = 0; char *packet = 0; int nbytes = 0; int bufsize = 0; Packet *pkt = 0; int rc; char *s; Pf *dlspf; Tbl *dlspfkeys; char *element; Tbl *parts; double val; Pf *pfval = 0; elog_init( argc, argv ); while( ( c = getopt( argc, argv, "vVd:s:p:m:f:" ) ) != -1 ) { switch( c ) { case 'd': CacheDaemon = optarg; break; case 'f': from = optarg; break; case 'm': match = optarg; break; case 'p': pfname = optarg; break; case 's': statefile = optarg; break; case 'v': Verbose++; break; case 'V': VeryVerbose++; Verbose++; break; default: elog_complain( 0, "Unknown option '%c'\n", c ); errflag++; break; } } if( errflag || argc - optind != 2 ) { usage(); } if( Verbose ) { elog_notify( 0, "Starting at %s (%s $Revision$ $Date$)\n", zepoch2str( str2epoch( "now" ), "%D %T %Z", "" ), Program_Name ); } orbname = argv[optind++]; dbcache = argv[optind++]; pfread( pfname, &pf ); rrdtool = pfget_string( pf, "rrdtool" ); if( rrdtool == NULL || ! strcmp( rrdtool, "" ) ) { elog_die( 0, "Error: no rrdtool executable name specified in parameter file\n" ); } else if( ( rrdtool[0] == '/' && ! is_present( rrdtool ) ) || ( rrdtool[0] != '/' && ! datafile( "PATH", rrdtool ) ) ) { elog_die( 0, "Error: can't find rrdtool executable by name of '%s' (check PATH environment " "variable, or absolute path name if given)\n", rrdtool ); } else if( rrdtool[0] == '/' ) { sprintf( command, "%s -", rrdtool ); } else { sprintf( command, "rrdtool -" ); } Suppress_egrep = pfget_string( pf, "suppress_egrep" ); if( Suppress_egrep != NULL && strcmp( Suppress_egrep, "" ) ) { if( ! datafile( "PATH", "egrep" ) ) { elog_complain( 0, "Ignoring suppress_egrep parameter: can't find egrep on path\n" ); } else { sprintf( command, "%s 2>&1 | egrep -v '%s'", command, Suppress_egrep ); } } if( VeryVerbose ) { elog_notify( 0, "Executing command: %s\n", command ); } Rrdfp = popen( command, "w" ); if( Rrdfp == (FILE *) NULL ) { elog_die( 0, "Failed to open socket to rrdtool command\n" ); } orb = orbopen( orbname, "r&" ); if( orb < 0 ) { elog_die( 0, "Failed to open orb '%s' for reading. Bye.\n", orbname ); } orbselect( orb, match ); if( from != NULL && statefile == NULL ) { pktid = orbposition( orb, from ); if( Verbose ) { elog_notify( 0, "Positioned to packet %d\n", pktid ); } } else if( from != NULL ) { elog_complain( 0, "Ignoring -f in favor of existing state file\n" ); } if( statefile != NULL ) { stop = 0; exhume( statefile, &stop, 15, 0 ); orbresurrect( orb, &pktid, &time ); if( Verbose ) { elog_notify( 0, "Resurrecting state to pktid %d, time %s\n", pktid, s = strtime( time ) ); free( s ); } orbseek( orb, pktid ); } dbopen( dbcache, "r+", &db ); if( db.database < 0 ) { elog_die( 0, "Failed to open cache database '%s'. Bye.\n", dbcache ); } else { db = dblookup( db, "", "rrdcache", "", "" ); if( db.table < 0 ) { elog_die( 0, "Failed to lookup 'rrdcache' table in '%s'. Bye.\n", dbcache ); } } dbcrunch( db ); dbt = dbsubset( db, "endtime == NULL", NULL ); Rrd_files = newarr( 0 ); dbquery( dbt, dbRECORD_COUNT, &nrecs ); for( dbt.record = 0; dbt.record < nrecs; dbt.record++ ) { dbgetv( dbt, 0, "net", &net, "sta", &sta, "rrdvar", &rrdvar, NULL ); dbfilename( dbt, (char *) &path ); sprintf( key, "%s:%s:%s", net, sta, rrdvar ); if( ! is_present( path ) ) { elog_complain( 0, "WARNING: rrd file '%s', listed in database, does not exist. " "Removing database entry.\n", path ); dbmark( dbt ); } else { setarr( Rrd_files, key, strdup( path ) ); if( VeryVerbose ) { elog_notify( 0, "Re-using rrd file '%s' for '%s'\n", path, key ); } } } Rrdfile_pattern = pfget_string( pf, "rrdfile_pattern" ); Status_stepsize_sec = pfget_double( pf, "status_stepsize_sec" ); Default_network = pfget_string( pf, "default_network" ); dlslines = pfget_tbl( pf, "dls_vars" ); Dls_vars_dsparams = newarr( 0 ); Dls_vars_rras = newarr( 0 ); for( i = 0; i < maxtbl( dlslines ); i++ ) { line = gettbl( dlslines, i ); strtr( line, "\t", " " ); rras = split( line, ' ' ); dls_var = shifttbl( rras ); dsparams = shifttbl( rras ); setarr( Dls_vars_dsparams, dls_var, dsparams ); setarr( Dls_vars_rras, dls_var, rras ); } ort = orbreapthr_new( orb, -1., 0 ); for( ; stop == 0; ) { orbreapthr_get( ort, &pktid, srcname, &time, &packet, &nbytes, &bufsize ); if( statefile ) { rc = bury(); if( rc < 0 ) { elog_complain( 0, "Unexpected failure of bury command! " "(are there two orb2rrdc's running with the same state" "file?)\n" ); clear_register( 1 ); } } rc = unstuffPkt( srcname, time, packet, nbytes, &pkt ); if( rc == Pkt_pf ) { if( VeryVerbose ) { /* Parameter files generally too big for elog */ fprintf( stderr, "Received a parameter-file '%s' at %s\n%s\n\n", srcname, s = strtime( time ), pf2string( pkt->pf ) ); free( s ); } else if( Verbose ) { elog_notify( 0, "Received a parameter-file '%s' at %s\n", srcname, s = strtime( time ) ); free( s ); } pfmorph( pkt->pf ); if( VeryVerbose ) { fprintf( stderr, "Morphed parameter-file '%s' to interpret 'opt':\n%s\n\n", srcname, pf2string( pkt->pf ) ); } pfget( pkt->pf, "dls", (void **) &dlspf ); dlspfkeys = pfkeys( dlspf ); Dls_vars_keys = keysarr( Dls_vars_dsparams ); for( i = 0; i < maxtbl( dlspfkeys ); i++ ) { element = gettbl( dlspfkeys, i ); if( strcontains( element, "_", 0, 0, 0 ) ) { parts = split( (s = strdup( element )), '_' ); sprintf( net, "%s", (char *) gettbl( parts, 0 ) ); sprintf( sta, "%s", (char *) gettbl( parts, 1 ) ); free( s ); freetbl( parts, 0 ); } else { sprintf( net, "%s", Default_network ); sprintf( sta, "%s", element ); } for( j = 0; j < maxtbl( Dls_vars_keys ); j++ ) { dls_var = gettbl( Dls_vars_keys, j ); sprintf( key, "%s{%s}", element, dls_var ); if( pfresolve( dlspf, key, 0, &pfval ) < 0 ) { elog_complain( 0, "Unable to extract variable '%s' " "(not present or wrong type) from element '%s' " "in packet from '%s', timestamped '%s'; Skipping\n", key, element, srcname, s = strtime( time ) ); free( s ); pfval = 0; continue; } else if( pfval != (Pf *) NULL && pfval->value.s != (char *) NULL && ! strcmp( pfval->value.s, "-" ) ) { if( VeryVerbose ) { elog_notify( 0, "Non-floating point value '-' in variable '%s', " "in packet from '%s', timestamped '%s'; Skipping data point\n", key, srcname, s = strtime( time ) ); free( s ); } continue; } else { val = pfget_double( dlspf, key ); } archive_dlsvar( db, net, sta, dls_var, (char *) getarr( Dls_vars_dsparams, dls_var ), (Tbl *) getarr( Dls_vars_rras, dls_var ), time, val ); } } freetbl( dlspfkeys, 0 ); freetbl( Dls_vars_keys, 0 ); } else if( rc == Pkt_stash ) { ; /* Do nothing */ } else { if( Verbose ) { elog_notify( 0, "Received a packet that's not a parameter file " "(type '%d' from unstuffPkt); skipping\n", rc ); } } } }
int main (int argc, char **argv) { Dbptr master_db, dbtmp; char dbname[512]; /* dbtmp name assigned by maketmpdb */ char *orbname; char *pffile=NULL; Pf *pf; /* Input pf object handle */ Arr *arr_sta; Arr *arr_a; /*Array object associative array -- purely a place holder*/ Arr *arr_phase; int i; char *statefile=NULL; Point origin; int orbin,orbout; /* We establish both a read and write connection on seperate sockets so we can use orbreap on the input */ int quit=0,last_pktid; double last_pkttime; int exhume_rcode; /* value returned by exhume*/ char *packet=0; int orid_used; Location_options o; RTlocate_Options rt_opts; ORB_Hypocenter hyp; /* This initialization is necessary for the orb_arrivals_in routine to work correctly on the first pass*/ hyp.assocs = NULL; elog_init(argc, argv); elog_notify (0, "$Revision$ $Date$") ; if(argc < 2) usage(argv[0]); orbname = argv[1]; for(i=2;i<argc;++i) { if(!strcmp(argv[i],"-pf")) { ++i; pffile = argv[i]; } else if(!strcmp(argv[i],"-S")) { ++i; statefile = argv[i]; } else { /* For this kind of program it seems wise to make it a fatal error to have the arguments botched */ elog_complain(0,"Unrecognized argument %s\n",argv[i]); usage(argv[0]); } } /* set default this way*/ if(pffile == NULL) pffile = strdup(DEFAULT_PFFILE); if(statefile == NULL) statefile = strdup(DEFAULT_STATEFILE); /* parse parameter file and form all the genloc control and internal static data structures */ i = pfread(pffile,&pf); if(i != 0) elog_die(1,"Pfread error\n"); o = parse_options_pf (pf); arr_sta = load_station_table(pf); arr_a = load_array_table(pf); arr_phase = parse_phase_parameter_file(pf); /* Note this is a slightly different use of these variables than that used by other genloc routines. Here we use it like a coordinate system origin to select range of distances to use. We actually reset these again in the location function, but check them here to make sure these variables are in the parameter space. pfget_double will cause the program to die if these aren't defined.*/ origin.lat = pfget_double(pf,"center_latitude"); origin.lon = pfget_double(pf,"center_longitude"); origin.z = 0.0; rt_opts = parse_rt_options(pf); if(dbopen(rt_opts.work_db,"r+",&master_db ) == dbINVALID) elog_die(1,"Unable to open master database %s\n", rt_opts.work_db); /* Now we open the orb server connections */ if( (orbin=orbopen(orbname,"r&")) < 0) elog_die(0,"Cannot open ring buffer %s for reading\n",orbname); if(orbselect(orbin,"/db/event|/db/origin|/db/assoc|/db/arrival") < 0) elog_die(0,"Cannot select any db records from ring buffer %s\n", orbname); /* These are the state saving routines. quit is set nonzero whenever the program catches a signal. We call bury below when this happens. exhume_state is a function because I expect it could be used again */ exhume_rcode = exhume ( statefile, 0, 0, 0 ); exhume_state(exhume_rcode); if ( orbresurrect ( orbin, &last_pktid, &last_pkttime ) == 0 ) elog_complain( 0, "resurrection successful: repositioned to pktid #%d\n", last_pktid ) ; else { orbseek (orbin, ORBOLDEST); last_pktid = orbtell(orbin); elog_complain( 0, "resurrection unsuccessful\nStarting at beginning of current orb at packet id %d\n",last_pktid ) ; } /* The following is basically a trick to create a db pointer that never references any tables. This is the preferred approach for orbpkt2db records which utilize the scratch record of this database pointer. The fact that we destroy the file this creates turns out to be a feature of datascope we can exploit here. */ if (maketmpdb ("css3.0", &dbtmp, dbname) < 0) { elog_complain(0, "maketmpdb() error.\n"); exit (1); } /* This little routine initilizes the null record for each table used here. This was necessary because we assemble records in the scratch record. This sets proper nulls in fields that are not referenced by this program. */ if(initialize_scratch_records(dbtmp) == dbINVALID) elog_complain(0,"Warning: errors initializing null records in tables. May generate invalid data in some fields\n"); /* unlink (dbname); */ if( (orbout=orbopen(orbname,"w&")) < 0) elog_die(0,"Cannot open ring buffer %s for writing\n",orbname); /* This loop is broken only by an error. We call bury after each event is processed saving the current packet id. This should effectively skip events that cause orbgenloc to die for some reason. */ while(1) { int return_code; return_code = orb_arrivals_in(orbin, dbtmp, &hyp, &last_pktid,rt_opts); if(return_code) { if(return_code < 0) elog_complain(0,"Error reading db records from orb\nCurrent event skipped\n"); else elog_complain(0,"Sequencing error reading db packets from orbassoc.\nOne or more events were probably skipped\n"); continue; } if(bury()) elog_complain(0, "bury failed writing statefile %s\n",statefile); compute_location(o,rt_opts,arr_sta,arr_a,arr_phase, pf,master_db, dbtmp, hyp, orbout); /* when last_pktid is -1 orb_arrivals_in does not do an orbseek, so we always reset it here */ last_pktid = -1; /* This is the only appropriate place to release this space. This block is malloced in orb_arrivals_in*/ free(hyp.assocs); hyp.assocs = NULL; } }
int main(int argc, char **argv) { double modified_after =now() , last_lddate, last_mtime, mtime; char *orbname = NULL; char *dbname = NULL; int orb; int naptime = -1, check_lddate_interval = -1; Dbptr db, dbt, dbs; char *prefix = NULL; struct stat filestat; int i; Tbl *tablenames, *tables_containing_dfile, *check_tables = NULL, *ignore_tables = NULL; long table_present, recc, is_view; char *tablename, *schemaname; char *filename; int counter = 0, force_check = 0; char expr[512]; char *statefilename = NULL, *pfname = "dbnew2orb"; Pf *pf = NULL; void *priv_dfile = (void *) NULL; void *private = (void *) NULL; int pmsi; /* poor man's string index, replacment for * searchtbl... */ char *pmsp; double lastburytime; Relic relic; char *s; Expression *expr_lddate; double *mtimes; double *lddates; elog_init(argc, argv); if (argc < 2) { usage(); exit(1); } for (argc--, argv++; argc > 0; argc--, argv++) { if (!strcmp(*argv, "-modified_after")) { argc--; argv++; if (argc < 1) { complain(0, "Need -modified_after argument.\n"); usage(); exit(1); } modified_after = str2epoch(*argv); } else if (!strcmp(*argv, "-prefix")) { argc--; argv++; if (argc < 1) { complain(0, "Need -prefix argument.\n"); usage(); exit(1); } prefix = *argv; } else if (!strcmp(*argv, "-pf")) { argc--; argv++; if (argc < 1) { complain(0, "Need -pf argument.\n"); usage(); exit(1); } pfname = *argv; } else if (!strcmp(*argv, "-state")) { argc--; argv++; if (argc < 1) { complain(0, "Need -state argument.\n"); usage(); exit(1); } statefilename = *argv; } else if (!strcmp(*argv, "-sleep")) { argc--; argv++; if (argc < 1) { complain(0, "Need -sleep argument.\n"); usage(); exit(1); } naptime = atoi(*argv); } else if (!strcmp(*argv, "-check_lddate_interval")) { argc--; argv++; if (argc < 1) { complain(0, "Need -check_lddate_interval argument.\n"); usage(); exit(1); } check_lddate_interval = atoi(*argv); } else if (!strcmp(*argv, "-v")) { verbose++; } else if (**argv != '-') { break; } else { complain(0, "Unrecognized argument '%s'.\n", *argv); usage(); exit(1); } } if (pfread(pfname, &pf)) { elog_die(0, "parse_pf: pfread('%s') error.\n", pfname); } if (check_lddate_interval < 1) { if (parse_param(pf, "check_lddate_interval", P_LINT, 1, &check_lddate_interval) < 0) { elog_die(1, "parse_pf: sleep check_lddate_interval needed!\n"); } else { if (check_lddate_interval < 0) { check_lddate_interval = 1; } } } if (naptime < 1) { if (parse_param(pf, "sleep", P_LINT, 1, &naptime) < 0) { elog_die(1, "parse_pf: sleep value needed!\n"); } else { if (naptime < 0) { naptime = 1; } } } if (!prefix) { if (parse_param(pf, "prefix", P_STR, 0, &prefix) < 0) { printf("NO PREFIX!\n"); prefix = NULL; } } parse_param(pf, "check_tables", P_TBL, 0, &check_tables); if (check_tables) { if (maxtbl(check_tables) < 1) { freetbl(check_tables, 0); check_tables = NULL; } } parse_param(pf, "ignore_tables", P_TBL, 0, &ignore_tables); if (ignore_tables) { if (maxtbl(ignore_tables) < 1) { freetbl(ignore_tables, 0); ignore_tables = NULL; } } /* * no good here, would erase the table above pffree(pf); */ if (argc < 1) { complain(0, "Need db argument.\n"); usage(); exit(1); } dbname = *argv; argc--; argv++; if (argc < 1) { complain(0, "Need orb argument.\n"); usage(); exit(1); } orbname = *argv; argc--; argv++; if (argc > 0) { complain(0, "Unrecognized argument '%s'.\n", *argv); usage(); exit(1); } if (dbopen(dbname, "r", &db) < 0) { elog_complain(0, "Can't open database"); exit(1); } dbquery(db, dbSCHEMA_NAME, &schemaname); orb = orbopen(orbname, "w&"); if (orb < 0) { elog_die(0, "orbopen(%s) error\n", orbname); } /* * prepare for later call to dbquery(dbFIELD_TABLES) to find only * tables containing lddate */ /* * dbtables is much better, does not require the existence of table * origin dbf = dblookup(db, 0, "origin", "lddate", "dbNULL"); * dbquery(dbf, dbFIELD_TABLES, &tablenames); */ dbex_compile(db, "max(lddate)", &expr_lddate, dbTIME); tablenames = dbtables(db, "lddate"); tables_containing_dfile = dbtables(db, "dfile"); /* waste a few bytes... */ ntables = maxtbl(tablenames); mtimes = malloc(ntables * sizeof(double)); lddates = malloc(ntables * sizeof(double)); bury_times = malloc(ntables * sizeof(double)); static_flags = malloc(ntables * sizeof(long)); if (statefilename) { if (exhume(statefilename, &Stop, 10, mortician)) { elog_notify(0, "read old state file\n"); } else { elog_complain(0, "could not read old statefile\n"); } } for (i = 0; i < ntables; i++) { /* * mtimes[i] = modified_after; lddates[i] = modified_after; */ static_flags[i] = NEW_TABLE; } for (;;) { tablenames = dbtables(db, "lddate"); for (i = 0; i < ntables; i++) { tablename = gettbl(tablenames, i); if (!tablename) { continue; } dbt = dblookup(db, 0, tablename, 0, 0); dbquery(dbt, dbTABLE_PRESENT, &table_present); if (!table_present) { continue; } dbquery(dbt, dbTABLE_IS_VIEW, &is_view); if (is_view) { continue; } /* lastid is not a good idea (my personal choice)... */ if (strcmp(tablename, "lastid") == 0) { continue; } /* remove after Dan fixed the bug with remark */ if (strcmp(tablename, "remark") == 0) { continue; } if (findtbl(tablename, tables_containing_dfile)) { continue; } if (check_tables) { if (!findtbl(tablename,check_tables)) { if (verbose > 1 && static_flags[i]==NEW_TABLE) elog_notify(0,"ignoring table %s because it's NOT in 'check_tables'\n",tablename); continue; } } if (ignore_tables) { if (findtbl(tablename,ignore_tables)) { if (verbose > 1 && static_flags[i]==NEW_TABLE) elog_notify(0,"ignoring table %s because it's in 'ignore_tables'\n",tablename); continue; } } dbquery(dbt, dbRECORD_COUNT, &recc); if (recc < 1) { continue; } if (statefilename) { if (static_flags[i] == NEW_TABLE) { relic.dp = &bury_times[i]; if (resurrect(tablename, relic, TIME_RELIC) == 0) { mtimes[i] = bury_times[i]; lddates[i] = bury_times[i]; if (verbose > 1) { elog_notify(0, "resurrection successful: check %s after %s\n", tablename, s = strtime(bury_times[i])); free(s); } } else { bury_times[i] = modified_after; mtimes[i] = modified_after; lddates[i] = modified_after; if (verbose > 1) { elog_notify(0, "resurrection unsuccessful: check %s after %s\n", tablename, s = strtime(modified_after)); free(s); } } static_flags[i] = TABLE_SEEN; } } else { if (static_flags[i] == NEW_TABLE) { bury_times[i] = modified_after; mtimes[i] = modified_after; lddates[i] = modified_after; static_flags[i] = TABLE_SEEN; } } dbquery(dbt, dbTABLE_FILENAME, &filename); if (stat(filename, &filestat) < 0) { elog_die(1, "stat(%s) error.\n", filename); } last_mtime = mtimes[i]; last_lddate = lddates[i]; mtime = filestat.st_mtime; /* * the whole mtime stuff is not soo good: mtime is * typically > lddate, so setting modified_after to * mtime will certainly ignore the last value. To get * everything, I will have to keep 2 arrays: mtimes * to detect file modifications and lddates to get * the actual entries... */ if (force_check || mtime > last_mtime) { sprintf(expr, "lddate > %f", last_lddate); dbs = dbsubset(dbt, expr, 0); dbquery(dbs, dbRECORD_COUNT, &recc); if (recc > 0) { if (dbrows2orb(dbs, orb, prefix) == 0) { /* * dbex_evalstr(dbs, * "max(lddate)", dbTIME, * &lddates[i]); */ dbex_eval(dbs, expr_lddate, 0, &lddates[i]); mtimes[i] = mtime; bury_times[i] = lddates[i]; } } dbfree(dbs); } /* * a call to dbfree(dbt) would remove it from the * list of tablenames, all later calls to tablename * would return NIL... */ if (Stop) { bury(); return (0); } } sleep(naptime); if ((counter + 1) >= check_lddate_interval) { counter = 0; force_check = 1; } else { force_check = 0; counter++; } if (statefilename) { double nowtime; nowtime = now(); if (nowtime - lastburytime > 600.0) { lastburytime = nowtime; bury(); } } } }