Beispiel #1
1
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;
}
Beispiel #2
0
static PyObject *
python_orbbury( PyObject *self, PyObject *args ) {
	char	*usage = "Usage: _orbbury(orb, pktid, pkttime)\n";
	Orb_relic *or;
	int	orbfd;
	int	pktid;
	double	pkttime;
	int	rc;

	if( ! PyArg_ParseTuple( args, "iid", &orbfd, &pktid, &pkttime ) ) {

		if( ! PyErr_Occurred() ) {

			PyErr_SetString( PyExc_RuntimeError, usage );
		}

		return NULL;
	}

	or = get_Orb_relic( orbfd );

	or->pktid = pktid;
	or->pkttime = pkttime;

	rc = bury();

	return Py_BuildValue( "i", rc );
}
//
// Check the status of this child by explicitly probing it.
// Caller must hold master lock.
//
bool Child::checkStatus(int options)
{
	assert(state() == alive);
	secdebug("unixchild", "checking %p (pid %d)", this, this->pid());
	int status;
  again:
	switch (IFDEBUG(pid_t pid =) ::wait4(this->pid(), &status, options, NULL)) {
	case pid_t(-1):
		switch (errno) {
		case EINTR:
			goto again;		// retry
		case ECHILD:
			secdebug("unixchild", "%p (pid=%d) unknown to kernel", this, this->pid());
			mState = invalid;
			mChildren().erase(this->pid());
			return false;
		default:
			UnixError::throwMe();
		}
		break;	// placebo
	case 0:
		return false;	// child not ready (do nothing)
	default:
		assert(pid == this->pid());
		bury(status);
		return true;
	}
}
Beispiel #4
0
int
cypher(void)
{
	int n;
	int junk;
	int lflag;
	char buffer[10];

	lflag = -1;
	while (wordtype[wordnumber] == ADJS)
		wordnumber++;
	while (wordnumber <= wordcount) {
		switch (wordvalue[wordnumber]) {
		case UP:
			if (location[position].access || wiz || tempwiz) {
				if (!location[position].access)
					puts("Zap!  A gust of wind lifts you up.");
				if (!battlestar_move(location[position].up, AHEAD))
					return (-1);
			} else {
				puts("There is no way up");
				return (-1);
			}
			lflag = 0;
			break;

		case DOWN:
			if (!battlestar_move(location[position].down, AHEAD))
				return (-1);
			lflag = 0;
			break;

		case LEFT:
			if (!battlestar_move(left, LEFT))
				return (-1);
			lflag = 0;
			break;

		case RIGHT:
			if (!battlestar_move(right, RIGHT))
				return (-1);
			lflag = 0;
			break;

		case AHEAD:
			if (!battlestar_move(ahead, AHEAD))
				return (-1);
			lflag = 0;
			break;

		case BACK:
			if (!battlestar_move(back, BACK))
				return (-1);
			lflag = 0;
			break;

		case SHOOT:
			if (wordnumber < wordcount &&
			    wordvalue[wordnumber + 1] == EVERYTHING) {
				for (n = 0; n < NUMOFOBJECTS; n++)
					if (testbit(location[position].objects,
					    n) && objsht[n]) {
						wordvalue[wordnumber + 1] = n;
						wordnumber = shoot();
					}
				wordnumber++;
				wordnumber++;
			} else
				shoot();
			break;

		case TAKE:
			if (wordnumber < wordcount &&
			    wordvalue[wordnumber + 1] == EVERYTHING) {
				for (n = 0; n < NUMOFOBJECTS; n++)
					if (testbit(location[position].objects,
					    n) && objsht[n]) {
						wordvalue[wordnumber + 1] = n;
						wordnumber =
							take(location[position].objects);
					}
				wordnumber++;
				wordnumber++;
			} else
				take(location[position].objects);
			break;

		case DROP:
			if (wordnumber < wordcount &&
			    wordvalue[wordnumber + 1] == EVERYTHING) {
				for (n = 0; n < NUMOFOBJECTS; n++)
					if (testbit(inven, n)) {
						wordvalue[wordnumber + 1] = n;
						wordnumber = drop("Dropped");
					}
				wordnumber++;
				wordnumber++;
			} else
				drop("Dropped");
			break;

		case KICK:
		case THROW:
			if (wordnumber < wordcount &&
			    wordvalue[wordnumber + 1] == EVERYTHING) {
				for (n = 0; n < NUMOFOBJECTS; n++) {
					if ((testbit(inven, n) ||
					     testbit(location[position].objects, n)) && objsht[n]) {
						wordvalue[wordnumber + 1] = n;
						wordnumber = throw(wordvalue[wordnumber] ==
							KICK ? "Kicked" : "Thrown");
					}
				}
				wordnumber += 2;
			} else
				throw(wordvalue[wordnumber] == KICK ? "Kicked" : "Thrown");
			break;

		case TAKEOFF:
			if (wordnumber < wordcount &&
			    wordvalue[wordnumber + 1] == EVERYTHING) {
				for (n = 0; n < NUMOFOBJECTS; n++)
					if (testbit(wear, n)) {
						wordvalue[wordnumber + 1] = n;
						wordnumber = takeoff();
					}
				wordnumber += 2;
			} else
				takeoff();
			break;

		case DRAW:
			if (wordnumber < wordcount &&
			    wordvalue[wordnumber + 1] == EVERYTHING) {
				for (n = 0; n < NUMOFOBJECTS; n++)
					if (testbit(wear, n)) {
						wordvalue[wordnumber + 1] = n;
						wordnumber = draw();
					}
				wordnumber += 2;
			} else
				draw();
			break;

		case PUTON:
			if (wordnumber < wordcount &&
			    wordvalue[wordnumber + 1] == EVERYTHING) {
				for (n = 0; n < NUMOFOBJECTS; n++)
					if (testbit(location[position].objects,
					    n) && objsht[n]) {
						wordvalue[wordnumber + 1] = n;
						wordnumber = puton();
					}
				wordnumber += 2;
			} else
				puton();
			break;

		case WEARIT:
			if (wordnumber < wordcount &&
			    wordvalue[wordnumber + 1] == EVERYTHING) {
				for (n = 0; n < NUMOFOBJECTS; n++)
					if (testbit(inven, n)) {
						wordvalue[wordnumber + 1] = n;
						wordnumber = wearit();
					}
				wordnumber += 2;
			} else
				wearit();
			break;

		case EAT:
			if (wordnumber < wordcount &&
			    wordvalue[wordnumber + 1] == EVERYTHING) {
				for (n = 0; n < NUMOFOBJECTS; n++)
					if (testbit(inven, n)) {
						wordvalue[wordnumber + 1] = n;
						wordnumber = eat();
					}
				wordnumber += 2;
			} else
				eat();
			break;

		case PUT:
			put();
			break;

		case INVEN:
			if (ucard(inven)) {
				puts("You are holding:\n");
				for (n = 0; n < NUMOFOBJECTS; n++)
					if (testbit(inven, n))
						printf("\t%s\n", objsht[n]);
				printf("\n= %d kilogram%s (%d%%)\n", carrying,
				       (carrying == 1 ? "." : "s."),
				       (WEIGHT ? carrying * 100 / WEIGHT : -1));
				printf("Your arms are %d%% full.\n",
				       encumber * 100 / CUMBER);
			} else
				puts("You aren't carrying anything.");

			if (ucard(wear)) {
				puts("\nYou are wearing:\n");
				for (n = 0; n < NUMOFOBJECTS; n++)
					if (testbit(wear, n))
						printf("\t%s\n", objsht[n]);
			} else
				puts("\nYou are stark naked.");
			if (card(injuries, NUMOFINJURIES)) {
				puts("\nYou have suffered:\n");
				for (n = 0; n < NUMOFINJURIES; n++)
					if (injuries[n])
						printf("\t%s\n", ouch[n]);
				printf("\nYou can still carry up to %d kilogram%s\n",
				    WEIGHT, (WEIGHT == 1 ? "." : "s."));
			} else
				puts("\nYou are in perfect health.");
			break;

		case USE:
			lflag = use();
			break;

		case LOOK:
			if (!notes[CANTSEE] || testbit(inven, LAMPON) ||
			    testbit(location[position].objects, LAMPON) ||
			    matchlight) {
				beenthere[position] = 2;
				writedes();
				printobjs();
				if (matchlight) {
					puts("\nYour match splutters out.");
					matchlight = 0;
				}
			} else
				puts("I can't see anything.");
			return (-1);
			break;

		case SU:
			if (wiz || tempwiz) {
				printf("\nRoom (was %d) = ", position);
				fgets(buffer, 10, stdin);
				if (*buffer != '\n')
					sscanf(buffer, "%d", &position);
				printf("Time (was %d) = ", gtime);
				fgets(buffer, 10, stdin);
				if (*buffer != '\n')
					sscanf(buffer, "%d", &gtime);
				printf("Fuel (was %d) = ", fuel);
				fgets(buffer, 10, stdin);
				if (*buffer != '\n')
					sscanf(buffer, "%d", &fuel);
				printf("Torps (was %d) = ", torps);
				fgets(buffer, 10, stdin);
				if (*buffer != '\n')
					sscanf(buffer, "%d", &torps);
				printf("CUMBER (was %d) = ", CUMBER);
				fgets(buffer, 10, stdin);
				if (*buffer != '\n')
					sscanf(buffer, "%d", &CUMBER);
				printf("WEIGHT (was %d) = ", WEIGHT);
				fgets(buffer, 10, stdin);
				if (*buffer != '\n')
					sscanf(buffer, "%d", &WEIGHT);
				printf("Clock (was %d) = ", gclock);
				fgets(buffer, 10, stdin);
				if (*buffer != '\n')
					sscanf(buffer, "%d", &gclock);
				printf("Wizard (was %d, %d) = ", wiz, tempwiz);
				fgets(buffer, 10, stdin);
				if (*buffer != '\n') {
					sscanf(buffer, "%d", &junk);
					if (!junk)
						tempwiz = wiz = 0;
				}
				printf("\nDONE.\n");
				return (0);
			} else
				puts("You aren't a wizard.");
			break;

		case SCORE:
			printf("\tPLEASURE\tPOWER\t\tEGO\n");
			printf("\t%3d\t\t%3d\t\t%3d\n\n", pleasure, power, ego);
			printf("This gives you the rating of %s in %d turns.\n",
			    rate(), gtime);
			printf("You have visited %d out of %d rooms this run (%d%%).\n",
			    card(beenthere, NUMOFROOMS), NUMOFROOMS,
			    card(beenthere, NUMOFROOMS) * 100 / NUMOFROOMS);
			break;

		case KNIFE:
		case KILL:
			murder();
			break;

		case UNDRESS:
		case RAVAGE:
			ravage();
			break;

		case SAVE:
			save();
			break;

		case FOLLOW:
			lflag = follow();
			break;

		case GIVE:
			give();
			break;

		case KISS:
			kiss();
			break;

		case LOVE:
			love();
			break;

		case RIDE:
			lflag = ride();
			break;

		case DRIVE:
			lflag = drive();
			break;

		case LIGHT:
			light();
			break;

		case LAUNCH:
			if (!launch())
				return (-1);
			else
				lflag = 0;
			break;

		case LANDIT:
			if (!land())
				return (-1);
			else
				lflag = 0;
			break;

		case TIME:
			chime();
			break;

		case SLEEP:
			zzz();
			break;

		case DIG:
			dig();
			break;

		case JUMP:
			lflag = jump();
			break;

		case BURY:
			bury();
			break;

		case SWIM:
			puts("Surf's up!");
			break;

		case DRINK:
			drink();
			break;

		case QUIT:
			die(0);

		default:
			puts("How's that?");
			return (-1);
			break;
		}
		if (wordnumber < wordcount && *words[wordnumber++] == ',')
			continue;
		else
			return (lflag);
	}
	return (lflag);
}
Beispiel #5
0
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;
	}
}
Beispiel #7
0
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();
			}
		}
	}
}
Beispiel #8
0
/**
 * @brief Checks if the current process has a pending signal.
 * 
 * @returns The number of the signal that is pending. If no signal is pending,
 *          SIGNULL is returned.
 */
PUBLIC int issig(void)
{
	/* Find a pending signal that is not being ignored. */
	for (int i = 1; i < NR_SIGNALS; i++)
	{
		/* Skip. */
		if (!(curr_proc->received & (1 << i)))
			continue;
		
		/*
		 * SIGCHLD is somewhat special. If the current process
		 * has set SIG_IGN to handle SIGCHLD, the child processes
		 * should not become zombie  processes. However, if
		 * the current process is catching SIGCHLD or handling it
		 * with the default handler (SIG_DFL), child processes do
		 * become zombie processes and they are buried in wait().
		 */
		if (i == SIGCHLD)
		{
			/* The current process has set SIG_IGN to handle SIGCHLD. */
			if (curr_proc->handlers[SIGCHLD] == SIG_IGN)
			{
				curr_proc->received &= ~(1 << i);
			
				/* Bury zombie child processes. */
				for (struct process *p = FIRST_PROC; p <= LAST_PROC; p++)
				{
					if ((p->father == curr_proc) && (p->state==PROC_ZOMBIE))
						bury(p);
				}
				
				/*
				 * The current process still have child processes,
				 * so try to find another signal that is pending
				 * and not being ignored.
				 */
				if (curr_proc->nchildren)
					continue;
				
				return (SIGNULL);
			}
			
			/* 
			 * Clear the signal flag for SIGCHLD since the current
			 * process is not catching this signal and the default
			 * action is to ignore it.
			 */
			else if (curr_proc->handlers[SIGCHLD] == SIG_DFL)
			{
				curr_proc->received &= ~(1 << i);
				return (SIGNULL);
			}
			
			return (SIGCHLD);
		}
		
		/*
		 * Check if the default action for this signal
		 * is to stop execution. If so, we do it now.
		 */
		if (curr_proc->handlers[i] == SIG_DFL)
		{
			if (sigdfl[i] == (sighandler_t)&stop)
			{
				curr_proc->received &= ~(1 << i);
				stop();
				return (SIGNULL);
			}
		}
		
		return (i);
	}
	
	return (SIGNULL);
}
Beispiel #9
0
/* returns 0 if error or no more commands to do,
 *         1 if there are more commands remaining on the current input line
 */
int
cypher(void)
{
	int     n;
	int     junk;
	int     lflag = -1;
	char   *filename, *rfilename;
	size_t  filename_len;

	while (wordnumber <= wordcount) {
		if (wordtype[wordnumber] != VERB &&
		    !(wordtype[wordnumber] == OBJECT &&
		    wordvalue[wordnumber] == KNIFE)) {
			printf("%s: How's that?\n",
			    (wordnumber == wordcount) ? words[wordnumber - 1] : words[wordnumber]);
			return (0);
		}

		switch (wordvalue[wordnumber]) {

		case AUXVERB:
			/* Take the following word as the verb */
			wordnumber++;
			return(cypher());
			break;

		case UP:
			if (location[position].access || wiz || tempwiz) {
				if (!location[position].access)
					puts("Zap!  A gust of wind lifts you up.");
				if (!moveplayer(location[position].up, AHEAD))
					return (0);
			} else {
				puts("There is no way up.");
				return (0);
			}
			lflag = 0;
			break;

		case DOWN:
			if (!moveplayer(location[position].down, AHEAD))
				return (0);
			lflag = 0;
			break;

		case LEFT:
			if (!moveplayer(left, LEFT))
				return (0);
			lflag = 0;
			break;

		case RIGHT:
			if (!moveplayer(right, RIGHT))
				return (0);
			lflag = 0;
			break;

		case AHEAD:
			if (!moveplayer(ahead, AHEAD))
				return (0);
			lflag = 0;
			break;

		case BACK:
			if (!moveplayer(back, BACK))
				return (0);
			lflag = 0;
			break;

		case SHOOT:
			verb_with_all(location[position].objects, OBJ_PERSON,
			    shoot, "shoot at");
			break;

		case TAKE:
			if (wordnumber < wordcount && wordvalue[wordnumber + 1] == EVERYTHING) {
				int things;
				things = 0;
				for (n = 0; n < NUMOFOBJECTS; n++)
					if (TestBit(location[position].objects, n) && objsht[n]) {
						things++;
						wordvalue[wordnumber + 1] = n;
/* Some objects (type NOUNS) have special treatment in take().  For these
 * we must set the type to NOUNS.  However for SWORD and BODY all it does
 * is find which of many objects is meant, so we need do nothing here.
 * BATHGOD must become NORMGOD as well.  NOUNS with no special case must be
 * included here to get the right error.  DOOR cannot occur as an object so
 * need not be included.
 */
						switch (n) {
						case BATHGOD:
							wordvalue[wordnumber + 1] = NORMGOD;
							/* FALLTHROUGH */
						case NORMGOD:
						case AMULET:
						case MEDALION:
						case TALISMAN:
						case MAN:
						case TIMER:
						case NATIVE:
							wordtype[wordnumber + 1] = NOUNS;
							break;
						default:
							wordtype[wordnumber + 1] = OBJECT;
						}
						wordnumber = take(location[position].objects);
						wordnumber += 2;
					}
				if (!things)
					puts("Nothing to take!");
			} else
				take(location[position].objects);
			break;

		case DROP:
			if (wordnumber < wordcount && wordvalue[wordnumber + 1] == EVERYTHING) {
				int things;
				things = 0;
				for (n = 0; n < NUMOFOBJECTS; n++)
					if (TestBit(inven, n)) {
						things++;
						wordvalue[wordnumber + 1] = n;
						wordnumber = drop("Dropped");
					}
				wordnumber++;
				wordnumber++;
				if (!things)
					puts("Nothing to drop!");
			} else
				drop("Dropped");
			break;


		case KICK:
		case THROW:
			if (wordnumber < wordcount && wordvalue[wordnumber + 1] == EVERYTHING) {
				int things, wv;
				things = 0;
				wv = wordvalue[wordnumber];
				for (n = 0; n < NUMOFOBJECTS; n++)
					if (TestBit(inven, n) ||
					  (TestBit(location[position].objects, n) && objsht[n])) {
						things++;
						wordvalue[wordnumber + 1] = n;
						wordnumber = throw(wordvalue[wordnumber] == KICK ? "Kicked" : "Thrown");
					}
				wordnumber += 2;
				if (!things)
					printf("Nothing to %s!\n", wv == KICK ? "kick" : "throw");
			} else
				throw(wordvalue[wordnumber] == KICK ? "Kicked" : "Thrown");
			break;

		case TAKEOFF:
			verb_with_all(wear, 0, takeoff, "take off");
			break;

		case DRAW:
			verb_with_all(wear, 0, draw, "draw");
			break;

		case PUTON:
			verb_with_all(location[position].objects, 0, puton, "put on");
			break;

		case WEARIT:
			verb_with_all(inven, 0, wearit, "wear");
			break;

		case EAT:
			verb_with_all(inven, 0, eat, "eat");
			break;

		case PUT:
			put();
			break;

		case INVEN:
			if (ucard(inven)) {
				puts("You are holding:\n");
				for (n = 0; n < NUMOFOBJECTS; n++)
					if (TestBit(inven, n))
						printf("\t%s\n", objsht[n]);
				printf("\n= %d kilogram%s ", carrying,
				    (carrying == 1 ?  "." : "s."));
				if (WEIGHT)
					printf("(%d%%)\n", carrying * 100 / WEIGHT);
				else
					printf("(can't lift any weight%s)\n",
					    (carrying ? " or move with what you have" : ""));
				if (CUMBER)
					printf("Your arms are %d%% full.\n",
					    encumber * 100 / CUMBER);
				else
					printf("You can't pick anything up.\n");
			} else
				puts("You aren't carrying anything.");

			if (ucard(wear)) {
				puts("\nYou are wearing:\n");
				for (n = 0; n < NUMOFOBJECTS; n++)
					if (TestBit(wear, n))
						printf("\t%s\n", objsht[n]);
			} else
				puts("\nYou are stark naked.");
			if (card(injuries, NUMOFINJURIES)) {
				puts("\nYou have suffered:\n");
				for (n = 0; n < NUMOFINJURIES; n++)
					if (injuries[n])
						printf("\t%s\n", ouch[n]);
				printf("\nYou can still carry up to %d kilogram%s\n", WEIGHT, (WEIGHT == 1 ? "." : "s."));
			} else
				puts("\nYou are in perfect health.");
			break;

		case USE:
			lflag = use();
			break;

		case OPEN:
			dooropen();
			break;

		case LOOK:
			if (!notes[CANTSEE] || TestBit(inven, LAMPON) ||
			    TestBit(location[position].objects, LAMPON)
			    || matchlight) {
				beenthere[position] = 2;
				writedes();
				printobjs();
				if (matchlight) {
					puts("\nYour match splutters out.");
					matchlight = 0;
				}
			} else
				puts("I can't see anything.");
			return (0);	/* No commands after a look */
			break;

		case SU:
			if (wiz || tempwiz) {
				getnum(&position, "\nRoom (was %d) = ", position);
				getnum(&ourtime, "Time (was %d) = ", ourtime);
				getnum(&fuel, "Fuel (was %d) = ", fuel);
				getnum(&torps, "Torps (was %d) = ", torps);
				getnum(&CUMBER, "CUMBER (was %d) = ", CUMBER);
				getnum(&WEIGHT, "WEIGHT (was %d) = ", WEIGHT);
				getnum(&ourclock, "Clock (was %d) = ", ourclock);
				if (getnum(&junk, "Wizard (was %d, %d) = ", wiz, tempwiz) != -1 && !junk)
					tempwiz = wiz = 0;
				printf("\nDONE.\n");
				return (0);	/* No commands after a SU */
			} else
				puts("You aren't a wizard.");
			break;

		case SCORE:
			printf("\tPLEASURE\tPOWER\t\tEGO\n");
			printf("\t%3d\t\t%3d\t\t%3d\n\n", pleasure, power, ego);
			printf("This gives you the rating of %s in %d turns.\n", rate(), ourtime);
			printf("You have visited %d out of %d rooms this run (%d%%).\n", card(beenthere, NUMOFROOMS), NUMOFROOMS, card(beenthere, NUMOFROOMS) * 100 / NUMOFROOMS);
			break;

		/* case KNIFE: */
		case KILL:
			murder();
			break;

		case UNDRESS:
			undress();
			break;

		case RAVAGE:
			ravage();
			break;

		case SAVE:
			printf("\nSave file name (default %s):  ",
			    DEFAULT_SAVE_FILE);
			filename = fgetln(stdin, &filename_len);
			if (filename_len == 0
			    || (filename_len == 1 && filename[0] == '\n'))
				rfilename = save_file_name(DEFAULT_SAVE_FILE,
				    strlen(DEFAULT_SAVE_FILE));
			else {
				if (filename[filename_len - 1] == '\n')
					filename_len--;
				rfilename = save_file_name(filename,
				    filename_len);
			}
			save(rfilename);
			free(rfilename);
			break;

		case VERBOSE:
			verbose = 1;
			printf("[Maximum verbosity]\n");
			break;

		case BRIEF:
			verbose = 0;
			printf("[Standard verbosity]\n");
			break;

		case FOLLOW:
			lflag = follow();
			break;

		case GIVE:
			give();
			break;

		case KISS:
			kiss();
			break;

		case LOVE:
			love();
			break;

		case RIDE:
			lflag = ride();
			break;

		case DRIVE:
			lflag = drive();
			break;

		case LIGHT:
			light();
			break;

		case LAUNCH:
			if (!launch())
				return (0);
			else
				lflag = 0;
			break;

		case LANDIT:
			if (!land())
				return (0);
			else
				lflag = 0;
			break;

		case TIME:
			chime();
			break;

		case SLEEP:
			zzz();
			break;

		case DIG:
			dig();
			break;

		case JUMP:
			lflag = jump();
			break;

		case BURY:
			bury();
			break;

		case SWIM:
			puts("Surf's up!");
			break;

		case DRINK:
			drink();
			break;

		case QUIT:
			die(0);

		default:
			puts("How's that?");
			return (0);
			break;

		}
		if (!lflag)
			newlocation();
		if (wordnumber < wordcount && !stop_cypher &&
		    (*words[wordnumber] == ',' || *words[wordnumber] == '.')) {
			wordnumber++;
			return (1);
		} else
			return (0);
	}
	return (0);
}