Esempio n. 1
0
/*------------------------------------------------------------------------
 *  wakeup  -  Called by clock interrupt handler to awaken processes
 *------------------------------------------------------------------------
 */
void	wakeup(void)
{
	/* Awaken all processes that have no more time to sleep */

	while (nonempty(sleepq) && (firstkey(sleepq) <= 0)) {
		ready(dequeue(sleepq), RESCHED_NO);
	}
	
	if ( (slnonempty = nonempty(sleepq)) == TRUE ) {
		sltop = &queuetab[firstkey(sleepq)].qkey;
	}
	resched();
	return;
}
Esempio n. 2
0
File: sem.c Progetto: ksherlock/gno
/* delete a semaphore by releasing its table entry */
SYSCALL KERNsdelete(int *ERRNO, int sem)
{
int mpid;
struct sentry *sptr;	/* address of sem to free */

    disableps();
    if (isbadsem(sem) || (sptr = &_semaph[sem])->sstate == SFREE) {
	enableps();
	*ERRNO = EINVAL;
        return SYSERR;
    }
    sptr->sstate = SFREE;
    if (nonempty(sptr->squeue)) {
	while ((mpid = _getfirst(sptr->squeue)) != SYSERR) {
		/* _ready(kp->procTable[mpid].flpid,RESCHNO); */
		if (kp->procTable[mpid].processState != procUNUSED)
			kp->procTable[mpid].processState = procREADY;
	}
        Qdispose(sptr->squeue);
        enableps();
        _resched();
        return OK;
    }
    Qdispose(sptr->squeue);
    enableps();
    return OK;
}
Esempio n. 3
0
/**
 * Deallocate a semaphore.
 * Reset the semaphore count, releasing any threads
 * in the waiting queue.  Deallocate entry in global
 * semaphore table.
 * @param sem  target semaphore
 * @return OK on success, SYSERR on failure
 */
syscall semfree(semaphore sem)
{
    register struct sement *semptr;
    irqmask im;
    tid_typ tid;

    im = disable();
    if (isbadsem(sem))
    {
        restore(im);
        return SYSERR;
    }

    semptr = &semtab[sem];
    while (nonempty(semptr->queue))
    {
        tid = dequeue(semptr->queue);   /* free waiting threads */
        ready(tid, RESCHED_NO);
    }

    semptr->count = 0;
    semptr->state = SFREE;
    restore(im);
    return OK;
}
Esempio n. 4
0
main()
{
  char *region[10] ;
  int i ;
  void *map_info ;
  int rs[] = {255, 255, 176, 255,   0, 196,   0, 135,   0,   0} ;
  int gs[] = {  0, 165,  48, 255, 255, 196, 196, 206,   0,   0} ;
  int bs[] = {  0,   0,  96,   0,   0,   0,   0, 235, 255,   0} ;

  decode_query_string(10,"region1", &region[0],
		      "region2", &region[1],
		      "region3", &region[2],
		      "region4", &region[3],
		      "region5", &region[4],
		      "region6", &region[5],
		      "region7", &region[6],
		      "region8", &region[7],
		      "region9", &region[8],
		      "region10", &region[9]) ;

  map_info = map_initialize("/herbaria/FLORA/cgi/maps", "vpt", ABSOLUTE) ;
  map_assign_absolute_colors(map_info, 10, rs, gs, bs) ;

  for (i =0 ; i < 10 ; i++) 
    if (nonempty(region[i]) && !strcmp(region[i], "yes"))
      map_set_region_color_by_num(map_info, i, i+1) ;

  map_output_redirect(map_info, NULL) ;
}
Esempio n. 5
0
/**
 * Wakeup and ready all threads that have no more time to sleep
 */
void wakeup(void)
{
    while (nonempty(sleepq) && (firstkey(sleepq) <= 0))
    {
        ready(dequeue(sleepq), RESCHED_NO);
    }
}
Esempio n. 6
0
interrupt clkhandler(void)
{
    /* Reset the timer to fire again */
    clkupdate(platform.clkfreq / CLKTICKS_PER_SEC);

    /* Another clock tick passes. */
    clkticks++;

    /* Update global second counter. */
    if (clkticks >= CLKTICKS_PER_SEC)
    {
        clktime++;
        clkticks = 0;
    }

    /* If sleepq is not empty, decrement first key.   */
    /* If key reaches zero, call wakeup.              */
    if (nonempty(sleepq) && (--firstkey(sleepq) <= 0))
    {
        wakeup(); // This no longer does a resched() call since we need to
                  // clear our interrupts before doing a resched()
    }

    #ifdef FLUKE_ARM
    /* Acknowledge and clear the interrupt */
    timer0->int_clr = 1;
    irq_handled();
    #endif

    resched();
}
Esempio n. 7
0
void regular_expression::free_buf()
{
  if (nonempty(&m_regex_buf, sizeof(m_regex_buf))) {
    regfree(&m_regex_buf);
    memset(&m_regex_buf, 0, sizeof(m_regex_buf));
  }
}
Esempio n. 8
0
// Try, very hard, to put everything in the multicol into two columns
// so that the total height is at most htavail.
void multicol::compose(int defonly)
{
	int i;
	stream cd;
	if (!nonempty()) {
		setheight(0);
		return;
	}
	scratch.freeall();		// fill scratch with everything destined
					// for either column
	for (cd = definite; cd.more(); cd.advance())
		scratch.append(cd.current());
	if (!defonly)
		for (cd = *(currpage->stage); cd.more(); cd.advance())
			if (cd.current()->numcol() == 2)
				scratch.append(cd.current());
	scratch.restoreall();		// in particular, floatables' goals
	int rawht = scratch.rawht();
	int halfheight = (int)(coltol*rawht);
					// choose a goal height
	int maxht = defonly ? halfheight : htavail;
secondtry:
	for (i = 0; i < 2; i++)
		column[i].freeall();
	leftblocked = 0;
	cd = scratch;
	while (cd.more()) {
		queue ministage;	// for the minimally acceptable chunks
		ministage.freeall();	// that are to be added to either column
		while (cd.more() && !cd.current()->issentinel()) {
			ministage.enqueue(cd.current());
			cd.advance();
		}
		choosecol(&ministage, maxht);
		if (cd.more() && cd.current()->issentinel())
			cd.advance();	// past sentinel
	}
	if (height() > htavail && maxht != htavail) {
					// We tried to balance the columns, but
					// the result was too tall.  Go back
					// and try again with the less ambitious
					// goal of fitting the space available.
		maxht = htavail;
		goto secondtry;
	}
	for (i = 0; i < 2; i++) {
		movefloats(&(column[i]), ((double) column[i].rawht())/currpage->pagesize);
		trimspace(&(column[i]));
	}
	if (dbg & 32) {
		printf("#multicol::compose: htavail %d maxht %d dv %d\n",
			htavail, maxht, height());
		dump();
	}
	if (defonly)
		stretch(height());
}
Esempio n. 9
0
void
singsub(char **s)
{
    LinkList foo;

    foo = newlinklist();
    addlinknode(foo, *s);
    prefork(foo, 4);
    if (errflag)
	return;
    *s = (char *) ugetnode(foo);
    DPUTS(nonempty(foo), "BUG: singsub() produced more than one word!");
}
Esempio n. 10
0
File: cond.c Progetto: AMDmi3/zsh
static void cond_subst(char **strp, int glob_ok)
{
    if (glob_ok &&
	checkglobqual(*strp, strlen(*strp), 1, NULL)) {
	LinkList args = newlinklist();
	addlinknode(args, *strp);
	prefork(args, 0, NULL);
	while (!errflag && args && nonempty(args) &&
	       has_token((char *)peekfirst(args)))
	    zglob(args, firstnode(args), 0);
	*strp = sepjoin(hlinklist2array(args, 0), NULL, 1);
    } else
	singsub(strp);
}
Esempio n. 11
0
main()
{
  int i ;
  char *regions, *species, *genus, *infra, *inspec, *s ;
  char plainname[128], italname[128] ;
  int rs[] = {255, 255, 176, 255,   0, 196,   0, 135,   0,   0} ;
  int gs[] = {  0, 165,  48, 255, 255, 196, 196, 206,   0,   0} ;
  int bs[] = {  0,   0,  96,   0,   0,   0,   0, 235, 255,   0} ;
  void *map_info ;

  return_header("text/html") ;

  decode_query_string(1, "reg", &regions,
		      "spec", &species,
		      "gen", &genus,
		      "infra", &infra,
		      "inspec", &inspec) ;

  if (nonempty(inspec)) {
    sprintf(plainname, "%s %s %s %s", genus, species, inspec, infra) ;
    sprintf(italname, "<i>%s %s</i> %s <i>%s</i>", 
	    genus, species, inspec, infra) ;
  }
  else {
    sprintf(plainname, "%s %s", genus, species) ;
    sprintf(italname, "<i>%s %s</i>", genus, species) ;
  }

  map_info = map_initialize("/herbaria/FLORA/cgi/maps", "vpt", ABSOLUTE) ;
  map_assign_absolute_colors(map_info, 10, rs, gs, bs) ;
  s = strtok(regions, ",") ;
  while (s != NULL) {
    map_set_region_color_by_num(map_info, atoi(s)-1, atoi(s)) ;
    s = strtok(NULL, ",") ;
  }

  printf("<title>Distribution of %s in Texas</title>\n", plainname) ;
  printf("<h1>Distribution of %s in Texas:</h1>\n", italname) ;

  map_output_img(map_info, 0, NULL, "left", NULL) ;
  printf("<p>\n") ;
  for (i=0 ; i < 10 ; i++) {
    map_output_absolute_color_block(map_info, i+1) ;
    printf("<a href=\"/FLORA/tracy/%s%d.htm\">%s</a><br>",
	   i+1 == 10 ? "taesre" : "taesreg", i+1, names[i]) ;
  }
}
Esempio n. 12
0
/**
 * Reschedule processor to highest priority ready thread.
 * Upon entry, thrcurrent gives current thread id.
 * Threadtab[thrcurrent].pstate gives correct NEXT state
 * for current thread if other than THRREADY.
 * @return OK when the thread is context switched back
 */
int resched(void)
{
    uchar asid;                 /* address space identifier */
    struct thrent *throld;      /* old thread entry */
    struct thrent *thrnew;      /* new thread entry */

    if (resdefer > 0)
    {                           /* if deferred, increase count & return */
        resdefer++;
        return (OK);
    }

    throld = &thrtab[thrcurrent];

    throld->intmask = disable();

    if (THRCURR == throld->state)
    {
        if (nonempty(readylist) && (throld->prio > firstkey(readylist)))
        {
            restore(throld->intmask);
            return OK;
        }
        throld->state = THRREADY;
        insert(thrcurrent, readylist, throld->prio);
    }

    /* get highest priority thread from ready list */
    thrcurrent = dequeue(readylist);
    thrnew = &thrtab[thrcurrent];
    thrnew->state = THRCURR;

    /* change address space identifier to thread id */
    asid = thrcurrent & 0xff;
#if 0
  // XXX Fix this later?
  asm("mtc0 %0, $10": :"r"(asid));
#endif

    restore(thrnew->intmask);
    ctxsw(&throld->stkptr, &thrnew->stkptr);

    /* old thread returns here when resumed */
    restore(throld->intmask);
    return OK;
}
Esempio n. 13
0
/*------------------------------------------------------------------------
 * ldelete  --  delete a lock by releasing its table entry
 *------------------------------------------------------------------------
 */
int ldelete (int lockdescriptor)
{

	STATWORD ps;
	int	pid;
	int temp,temp1;
	
	struct lentry *lptr;
	disable(ps);	
	
	if (isbadlock(lockdescriptor) || locks[lockdescriptor].lstate==DELETED || locks[lockdescriptor].lstate==LFREE) {	
		restore(ps);	
		return(SYSERR);	
	}	

	lptr = &locks[lockdescriptor];
	lptr->lstate = DELETED;	
	lptr->ltype = NONE;	
	lptr->lreaders= 0;	

	if (nonempty(lptr->lqhead)) {	
		while( (pid=getfirst(lptr->lqhead)) != EMPTY)		 
			{		   
				proctab[pid].plockwaitret = DELETED;		
				proctab[pid].locktype[lockdescriptor] = DELETED;	
				dequeue(pid);		  
				ready(pid,RESCHNO);	
	
				//kprintf("\n\t\t[LDELETE.C: 37] Proc '%s' deleted from waitqueue of Lock %d\n",proctab[pid].pname,lockdescriptor);		
			}		
			resched();
		}	


	for(pid=1;pid<NPROC;pid++)	{	
		if(locks[lockdescriptor].lprocs[pid] == READ || locks[lockdescriptor].lprocs[pid] == WRITE)		
			{		
				locks[lockdescriptor].lprocs[pid] = DELETED;	
			}	
	}	

	restore(ps);	
	return(OK);


}
int ldelete(int lock_value)
{
        STATWORD ps;
        int     pid, i;
        struct  lentry  *lptr;
		int lock_index;
		int lock_version;
		
        disable(ps);
		lock_index = lock_value/MAXVERSION;
		lock_version = lock_value%MAXVERSION;
		lptr=&locks[lock_index];
		
        if (locks[lock_index].lstate==LFREE) 
			{
            restore(ps);
            return(SYSERR);
        	}
		
		if(locks[lock_index].version != lock_version)
			{
            restore(ps);
            return(SYSERR);
        	}

        locks[lock_index].lstate = LFREE;
        if(nonempty(lptr->lqhead)) 
			{
            while( (pid=getfirst(lptr->lqhead)) != EMPTY)
                {
                proctab[pid].plwaitret = DELETED;
                ready(pid,RESCHNO);
                }
                resched();
        	}
		locks[lock_index].nreaders = 0;
		locks[lock_index].nwriters = 0;

		for(i = 0; i < NPROC; i++)
			lockholdtab[i][lock_index] = 0;

        restore(ps);
        return(OK);
}
Esempio n. 15
0
/*------------------------------------------------------------------------
 *  unsleep  -  Remove a process from the sleep queue prematurely by
 *			adjusting the delay of successive processes
 *------------------------------------------------------------------------
 */
syscall	unsleep(
	  pid32		pid		/* ID of process to remove	*/
        )
{
	intmask	mask;			/* saved interrupt mask		*/
        struct	procent	*prptr;		/* ptr to process' table entry	*/

        pid32	pidnext;		/* ID of process on sleep queue	*/
					/* that follows the process that*/
					/* is being removed		*/

	mask = disable();

	if (isbadpid(pid)) {
		restore(mask);
		return SYSERR;
	}

	/* Verify that candidate process is on the sleep queue */

	prptr = &proctab[pid];
	if ((prptr->prstate!=PR_SLEEP) && (prptr->prstate!=PR_RECTIM)) {
		restore(mask);
		return SYSERR;
	}

	/* Increment delay of next process if such a process exists */

	pidnext = queuetab[pid].qnext;
	if (pidnext < NPROC) {
		queuetab[pidnext].qkey += queuetab[pid].qkey;
	}

	if ( nonempty(sleepq) ) {
		sltop = &queuetab[firstid(sleepq)].qkey;
		slnonempty = TRUE;
	} else {
		slnonempty = FALSE;
	}
	getitem(pid);			/* unlink process from queue */
	restore(mask);
	return OK;
}
Esempio n. 16
0
static int locale_read_data(Context *c) {
        int r;

        context_free_locale(c);

        r = parse_env_file("/etc/locale.conf", NEWLINE,
                           "LANG",              &c->locale[LOCALE_LANG],
                           "LANGUAGE",          &c->locale[LOCALE_LANGUAGE],
                           "LC_CTYPE",          &c->locale[LOCALE_LC_CTYPE],
                           "LC_NUMERIC",        &c->locale[LOCALE_LC_NUMERIC],
                           "LC_TIME",           &c->locale[LOCALE_LC_TIME],
                           "LC_COLLATE",        &c->locale[LOCALE_LC_COLLATE],
                           "LC_MONETARY",       &c->locale[LOCALE_LC_MONETARY],
                           "LC_MESSAGES",       &c->locale[LOCALE_LC_MESSAGES],
                           "LC_PAPER",          &c->locale[LOCALE_LC_PAPER],
                           "LC_NAME",           &c->locale[LOCALE_LC_NAME],
                           "LC_ADDRESS",        &c->locale[LOCALE_LC_ADDRESS],
                           "LC_TELEPHONE",      &c->locale[LOCALE_LC_TELEPHONE],
                           "LC_MEASUREMENT",    &c->locale[LOCALE_LC_MEASUREMENT],
                           "LC_IDENTIFICATION", &c->locale[LOCALE_LC_IDENTIFICATION],
                           NULL);

        if (r == -ENOENT) {
                int p;

                /* Fill in what we got passed from systemd. */
                for (p = 0; p < _LOCALE_MAX; p++) {
                        assert(names[p]);

                        r = free_and_strdup(&c->locale[p],
                                            nonempty(getenv(names[p])));
                        if (r < 0)
                                return r;
                }

                r = 0;
        }

        locale_simplify(c);
        return r;
}
int ldelete(int ldes)
{
	STATWORD ps;
	
	struct lentry *lptr;
	int pid, lockID;
	
	disable(ps);
	lockID = getLockID(ldes);
	
	if( isbadlock(lockID) || (lptr=&locktab[lockID])->lstate == LOCKFREE )
	{
		restore(ps);
		return(SYSERR);
	}
	
	//lptr = &locktab[ldes];
	lptr->lstate = LOCKFREE;
	lptr->locked = 0;
	lptr->acquiredby[currpid]=-1;
	lptr->lockType = DELETED;
	lptr->lprio=-1;
	
	
	if( nonempty(lptr->lhead) )
	{
		while( (pid=getlast(lptr->lhead)) != EMPTY )
		{
			proctab[pid].waitPriority = -1;
			proctab[pid].lockID = -1;
			proctab[pid].procLockType[lockID] = DELETED;
			proctab[pid].pwaitret = DELETED;
			
			ready(pid, RESCHNO);
		}
		resched();
	}
	
	restore(ps);
	return(OK);
}
Esempio n. 18
0
interrupt clkhandler(void)
{
    //DEBUG
    //kprintf("Timer went off\n");

    /* Reset the timer to fire again */
    clkupdate(platform.clkfreq / CLKTICKS_PER_SEC);

    /* Another clock tick passes. */
    clkticks++;
    msclkticks++;

    /* Update global second counter. */
    if (clkticks >= CLKTICKS_PER_SEC)
    {
        clktime++;
        clkticks = 0;
    }

    /* Update global countdown for round robien reschedule */
    if (msclkticks >= (CLKTICKS_PER_SEC/1000))
    {
	rescheduleMSLeft -= 1;
	msclkticks = 0;
    }

    /* If sleepq is not empty, decrement first key.   */
    /* If key reaches zero, call wakeup.              */
    if (nonempty(sleepq) && (--firstkey(sleepq) <= 0))
    {
        wakeup(); // This no longer does a resched() call since we need to
                  // clear our interrupts before doing a resched()
    }

    /* Acknowledge and clear the interrupt */
    timer0->int_clr = 1;
    irq_handled();

    resched();
}
Esempio n. 19
0
int ldelete (int lockdescriptor)
{
        STATWORD ps;
        int     pid;
        struct  lentry  *lptr;

        disable(ps);
        if (isbadlock(lockdescriptor%100) || lockarr[lockdescriptor%100].lstate==LFREE) {
                restore(ps);
                return(SYSERR);
        }
        lptr = &lockarr[lockdescriptor%100];
        lptr->lstate = LFREE;
        if (nonempty(lptr->lqhead)) {
                while( (pid=getfirst(lptr->lqhead)) != EMPTY)
                  {
                    proctab[pid].pwaitret = DELETED;
                    ready(pid,RESCHNO);
                  }
                resched();
        }
        restore(ps);
        return(OK);
}
Esempio n. 20
0
/*------------------------------------------------------------------------
 * sdelete  --  delete a semaphore by releasing its table entry
 *------------------------------------------------------------------------
 */
SYSCALL sdelete(int sem)
{
	STATWORD ps;    
	int	pid;
	struct	sentry	*sptr;

	disable(ps);
	if (isbadsem(sem) || semaph[sem].sstate==SFREE) {
		restore(ps);
		return(SYSERR);
	}
	sptr = &semaph[sem];
	sptr->sstate = SFREE;
	if (nonempty(sptr->sqhead)) {
		while( (pid=getfirst(sptr->sqhead)) != EMPTY)
		  {
		    proctab[pid].pwaitret = DELETED;
		    ready(pid,RESCHNO);
		  }
		resched();
	}
	restore(ps);
	return(OK);
}
Esempio n. 21
0
int
multsub(char **s, char ***a, int *isarr, char *sep)
{
    LinkList foo;
    int l;
    char **r, **p;

    foo = newlinklist();
    addlinknode(foo, *s);
    prefork(foo, 0);
    if (errflag) {
	if (isarr)
	    *isarr = 0;
	return 0;
    }
    if ((l = countlinknodes(foo)) > 1) {
	p = r = ncalloc((l + 1) * sizeof(char*));
	while (nonempty(foo))
	    *p++ = (char *)ugetnode(foo);
	*p = NULL;
	if (a) {
	    *a = r;
	    *isarr = 1;
	    return 0;
	}
	*s = sepjoin(r, NULL);
	return 0;
    }
    if (l)
	*s = (char *) ugetnode(foo);
    else
	*s = dupstring("");
    if (isarr)
	*isarr = 0;
    return !l;
}
Esempio n. 22
0
static int
rm(State_t* state, register FTSENT* ent)
{
	register char*	path;
	register int	n;
	int		v;
	struct stat	st;

	if (ent->fts_info == FTS_NS || ent->fts_info == FTS_ERR || ent->fts_info == FTS_SLNONE)
	{
		if (!state->force)
			error(2, "%s: not found", ent->fts_path);
	}
	else if (state->fs3d && iview(ent->fts_statp))
		fts_set(NiL, ent, FTS_SKIP);
	else switch (ent->fts_info)
	{
	case FTS_DNR:
	case FTS_DNX:
		if (state->unconditional)
		{
			if (!beenhere(ent))
				break;
			if (!chmod(ent->fts_name, (ent->fts_statp->st_mode & S_IPERM)|S_IRWXU))
			{
				fts_set(NiL, ent, FTS_AGAIN);
				break;
			}
			error_info.errors++;
		}
		else if (!state->force)
			error(2, "%s: cannot %s directory", ent->fts_path, (ent->fts_info & FTS_NR) ? "read" : "search");
		else
			error_info.errors++;
		fts_set(NiL, ent, FTS_SKIP);
		nonempty(ent);
		break;
	case FTS_D:
	case FTS_DC:
		path = ent->fts_name;
		if (path[0] == '.' && (!path[1] || path[1] == '.' && !path[2]) && (ent->fts_level > 0 || path[1]))
		{
			fts_set(NiL, ent, FTS_SKIP);
			if (!state->force)
				error(2, "%s: cannot remove", ent->fts_path);
			else
				error_info.errors++;
			break;
		}
		if (!state->recursive)
		{
			fts_set(NiL, ent, FTS_SKIP);
			error(2, "%s: directory", ent->fts_path);
			break;
		}
		if (!beenhere(ent))
		{
			if (state->unconditional && (ent->fts_statp->st_mode & S_IRWXU) != S_IRWXU)
				chmod(path, (ent->fts_statp->st_mode & S_IPERM)|S_IRWXU);
			if (ent->fts_level > 0)
			{
				char*	s;

				if (ent->fts_accpath == ent->fts_name || !(s = strrchr(ent->fts_accpath, '/')))
					v = !stat(".", &st);
				else
				{
					path = ent->fts_accpath;
					*s = 0;
					v = !stat(path, &st);
					*s = '/';
				}
				if (v)
					v = st.st_nlink <= 2 || st.st_ino == ent->fts_parent->fts_statp->st_ino && st.st_dev == ent->fts_parent->fts_statp->st_dev || strchr(astconf("PATH_ATTRIBUTES", path, NiL), 'l');
			}
			else
				v = 1;
			if (v)
			{
				if (state->interactive)
				{
					if ((v = astquery(-1, "remove directory %s? ", ent->fts_path)) < 0 || sh_checksig(state->context))
						return -1;
					if (v > 0)
					{
						fts_set(NiL, ent, FTS_SKIP);
						nonempty(ent);
					}
				}
				if (ent->fts_info == FTS_D)
					break;
			}
			else
			{
				ent->fts_info = FTS_DC;
				error(1, "%s: hard link to directory", ent->fts_path);
			}
		}
		else if (ent->fts_info == FTS_D)
			break;
		/*FALLTHROUGH*/
	case FTS_DP:
		if (isempty(ent) || state->directory)
		{
			path = ent->fts_name;
			if (path[0] != '.' || path[1])
			{
				path = ent->fts_accpath;
				if (state->verbose)
					sfputr(sfstdout, ent->fts_path, '\n');
				if ((ent->fts_info == FTS_DC || state->directory) ? remove(path) : rmdir(path))
					switch (errno)
					{
					case ENOENT:
						break;
					case EEXIST:
#if defined(ENOTEMPTY) && (ENOTEMPTY) != (EEXIST)
					case ENOTEMPTY:
#endif
						if (ent->fts_info == FTS_DP && !beenhere(ent))
						{
							retry(ent);
							fts_set(NiL, ent, FTS_AGAIN);
							break;
						}
						/*FALLTHROUGH*/
					default:
						nonempty(ent);
						if (!state->force)
							error(ERROR_SYSTEM|2, "%s: directory not removed", ent->fts_path);
						else
							error_info.errors++;
						break;
					}
			}
			else if (!state->force)
				error(2, "%s: cannot remove", ent->fts_path);
			else
				error_info.errors++;
		}
		else
		{
			nonempty(ent);
			if (!state->force)
				error(2, "%s: directory not removed", ent->fts_path);
			else
				error_info.errors++;
		}
		break;
	default:
		path = ent->fts_accpath;
		if (state->verbose)
			sfputr(sfstdout, ent->fts_path, '\n');
		if (state->interactive)
		{
			if ((v = astquery(-1, "remove %s? ", ent->fts_path)) < 0 || sh_checksig(state->context))
				return -1;
			if (v > 0)
			{
				nonempty(ent);
				break;
			}
		}
		else if (!state->force && state->terminal && eaccess(path, W_OK))
		{
			if ((v = astquery(-1, "override protection %s for %s? ",
#ifdef ETXTBSY
				errno == ETXTBSY ? "``running program''" : 
#endif
				ent->fts_statp->st_uid != state->uid ? "``not owner''" :
				fmtmode(ent->fts_statp->st_mode & S_IPERM, 0) + 1, ent->fts_path)) < 0 ||
			    sh_checksig(state->context))
				return -1;
			if (v > 0)
			{
				nonempty(ent);
				break;
			}
		}
#if _lib_fsync
		if (state->clobber && S_ISREG(ent->fts_statp->st_mode) && ent->fts_statp->st_size > 0)
		{
			if ((n = open(path, O_WRONLY)) < 0)
				error(ERROR_SYSTEM|2, "%s: cannot clear data", ent->fts_path);
			else
			{
				off_t		c = ent->fts_statp->st_size;

				for (;;)
				{
					if (write(n, state->buf, sizeof(state->buf)) != sizeof(state->buf))
					{
						error(ERROR_SYSTEM|2, "%s: data clear error", ent->fts_path);
						break;
					}
					if (c <= sizeof(state->buf))
						break;
					c -= sizeof(state->buf);
				}
				fsync(n);
				close(n);
			}
		}
#endif
		if (remove(path))
		{
			nonempty(ent);
			switch (errno)
			{
			case ENOENT:
				break;
			default:
				if (!state->force || state->interactive)
					error(ERROR_SYSTEM|2, "%s: not removed", ent->fts_path);
				else
					error_info.errors++;
				break;
			}
		}
		break;
	}
	return 0;
}
Esempio n. 23
0
File: zselect.c Progetto: AMDmi3/zsh
static int
bin_zselect(char *nam, char **args, UNUSED(Options ops), UNUSED(int func))
{
#ifdef HAVE_SELECT
    int i, fd, fdsetind = 0, fdmax = 0, fdcount;
    fd_set fdset[3];
    const char fdchar[3] = "rwe";
    struct timeval tv, *tvptr = NULL;
    char *outarray = "reply", **outdata, **outptr;
    char *outhash = NULL;
    LinkList fdlist;

    for (i = 0; i < 3; i++)
	FD_ZERO(fdset+i);

    for (; *args; args++) {
	char *argptr = *args, *endptr;
	zlong tempnum;
	if (*argptr == '-') {
	    for (argptr++; *argptr; argptr++) {
		switch (*argptr) {
		    /*
		     * Array name for reply, if not $reply.
		     * This gets set to e.g. `-r 0 -w 1' if 0 is ready
		     * for reading and 1 is ready for writing.
		     */
		case 'a':
		case 'A':
		    i = *argptr;
		    if (argptr[1])
			argptr++;
		    else if (args[1]) {
			argptr = *++args;
		    } else {
			zwarnnam(nam, "argument expected after -%c", *argptr);
			return 1;
		    }
		    if (idigit(*argptr) || !isident(argptr)) {
			zwarnnam(nam, "invalid array name: %s", argptr);
			return 1;
		    }
		    if (i == 'a')
			outarray = argptr;
		    else
			outhash = argptr;
		    /* set argptr to next to last char because of increment */
		    while (argptr[1])
			argptr++;
		    break;

		    /* Following numbers indicate fd's for reading */
		case 'r':
		    fdsetind = 0;
		    break;

		    /* Following numbers indicate fd's for writing */
		case 'w':
		    fdsetind = 1;
		    break;

		    /* Following numbers indicate fd's for errors */
		case 'e':
		    fdsetind = 2;
		    break;

		    /*
		     * Get a timeout value in hundredths of a second
		     * (same units as KEYTIMEOUT).  0 means just poll.
		     * If not given, blocks indefinitely.
		     */
		case 't':
		    if (argptr[1])
			argptr++;
		    else if (args[1]) {
			argptr = *++args;
		    } else {
			zwarnnam(nam, "argument expected after -%c", *argptr);
			return 1;
		    }
		    if (!idigit(*argptr)) {
			zwarnnam(nam, "number expected after -t");
			return 1;
		    }
		    tempnum = zstrtol(argptr, &endptr, 10);
		    if (*endptr) {
			zwarnnam(nam, "garbage after -t argument: %s",
				 endptr);
			return 1;
		    }
		    /* timevalue now active */
		    tvptr = &tv;
		    tv.tv_sec = (long)(tempnum / 100);
		    tv.tv_usec = (long)(tempnum % 100) * 10000L;

		    /* remember argptr is incremented at end of loop */
		    argptr = endptr - 1;
		    break;

		    /* Digits following option without arguments are fd's. */
		default:
		    if (handle_digits(nam, argptr, fdset+fdsetind,
				      &fdmax))
			return 1;
		}
	    }
	} else if (handle_digits(nam, argptr, fdset+fdsetind, &fdmax))
	    return 1;
    }

    errno = 0;
    do {
	i = select(fdmax, (SELECT_ARG_2_T)fdset, (SELECT_ARG_2_T)(fdset+1),
		   (SELECT_ARG_2_T)(fdset+2), tvptr);
    } while (i < 0 && errno == EINTR && !errflag);

    if (i <= 0) {
	if (i < 0)
	    zwarnnam(nam, "error on select: %e", errno);
	/* else no fd's set.  Presumably a timeout. */
	return 1;
    }

    /*
     * Make a linked list of all file descriptors which are ready.
     * These go into an array preceded by -r, -w or -e for read, write,
     * error as appropriate.  Typically there will only be one set
     * so this looks rather like overkill.
     */
    fdlist = znewlinklist();
    for (i = 0; i < 3; i++) {
	int doneit = 0;
	for (fd = 0; fd < fdmax; fd++) {
	    if (FD_ISSET(fd, fdset+i)) {
		char buf[BDIGBUFSIZE];
		if (outhash) {
		    /*
		     * Key/value pairs; keys are fd's (as strings),
		     * value is a (possibly improper) subset of "rwe".
		     */
		    LinkNode nptr;
		    int found = 0;

		    convbase(buf, fd, 10);
		    for (nptr = firstnode(fdlist); nptr; 
			 nptr = nextnode(nextnode(nptr))) {
			if (!strcmp((char *)getdata(nptr), buf)) {
			    /* Already there, add new character. */
			    void **dataptr = getaddrdata(nextnode(nptr));
			    char *data = (char *)*dataptr, *ptr;
			    found = 1;
			    if (!strchr(data, fdchar[i])) {
				strcpy(buf, data);
				for (ptr = buf; *ptr; ptr++)
				    ;
				*ptr++ = fdchar[i];
				*ptr = '\0';
				zsfree(data);
				*dataptr = ztrdup(buf);
			    }
			    break;
			}
		    }
		    if (!found) {
			/* Add new key/value pair. */
			zaddlinknode(fdlist, ztrdup(buf));
			buf[0] = fdchar[i];
			buf[1] = '\0';
			zaddlinknode(fdlist, ztrdup(buf));
		    }
		} else {
		    /* List of fd's preceded by -r, -w, -e. */
		    if (!doneit) {
			buf[0] = '-';
			buf[1] = fdchar[i];
			buf[2] = 0;
			zaddlinknode(fdlist, ztrdup(buf));
			doneit = 1;
		    }
		    convbase(buf, fd, 10);
		    zaddlinknode(fdlist, ztrdup(buf));
		}
	    }
	}
    }

    /* convert list to array */
    fdcount = countlinknodes(fdlist);
    outptr = outdata = (char **)zalloc((fdcount+1)*sizeof(char *));
    while (nonempty(fdlist))
	*outptr++ = getlinknode(fdlist);
    *outptr = NULL;
    /* and store in array parameter */
    if (outhash)
	sethparam(outhash, outdata);
    else
	setaparam(outarray, outdata);
    freelinklist(fdlist, NULL);

    return 0;
#else
    /* TODO: use poll */
    zerrnam(nam, "your system does not implement the select system call.");
    return 2;
#endif
}
/*-----------------------------------------------------------------------
 * resched  --  reschedule processor to highest priority ready process
 *
 * Notes:	Upon entry, currpid gives current process id.
 *		Proctab[currpid].pstate gives correct NEXT state for
 *			current process if other than PRREADY.
 *------------------------------------------------------------------------
 */
int resched()
{
	register struct	pentry	*optr;	/* pointer to old process entry */
	register struct	pentry	*nptr;	/* pointer to new process entry */
	int itemA, itemB, itemC,proc;
	int num, i;
	//STATWORD ps;
	optr = &proctab[currpid];
	
	if(sched_type==RANDOMSCHED)
	{
		/*if(count_random==0)
		{
			count_random++;
			enqueue(dequeue(0),queueC_tail);
		}*/
		
		if((!nonempty(queueC_head)) && (!nonempty(queueC_head)) && (!nonempty(queueC_head)))
		{
			return OK;
		}
		
		proctab[currpid].quantumLeft = preempt;	//quantum used in last execution
		if(switched_to_randomsched==1)
		{
			switched_to_randomsched=0;
			proctab[currpid].procCpuTicks += (proctab[currpid].assignedQuantum - preempt);
		}
		else
		{
			proctab[currpid].procCpuTicks += (QUANTUM - preempt);
		}
		//proctab[currpid].procCpuTicks += (QUANTUM - preempt);
		
		/*Make current process as ready*/
		if (optr->pstate == PRCURR) 
		{
			//kprintf("\nen inside ");

			optr->pstate = PRREADY;
			if(((optr->pprio)>=66) && ((optr->pprio)<=99))
			{
				//kprintf("\nReady Queue A, %s", optr->pname);
				enqueue(currpid, queueA_tail);
			}
		
			else if(optr->pprio>=33 && optr->pprio<=65)
			{
				//kprintf("\nReady Queue b, %s", optr->pname);
				enqueue(currpid, queueB_tail);
			}
		
			else if(optr->pprio>=0 && optr->pprio<=32)
			{
				//kprintf("\nReady Queue c, %s", optr->pname);
				enqueue(currpid, queueC_tail);
				//enqueue(0,queueC_tail);
			}
		}
		
		//srand(1);
		generate_random:
			num = rand();
			//kprintf("\n rand 1: %d", num);
			num = (num%97);
			//kprintf("\n normalized rand 1: %d", num);
		
		
		if(num>=50)
		{
		
			if(nonempty(queueA_head))
			{	
				itemA = getfirst(queueA_head);
				//kprintf("\nresched Queue A, %d",itemA);

				nptr = &proctab[ (currpid = itemA)];//getfirst(queueA_head)) ];
				nptr->pstate = PRCURR;		/* mark it currently running	*/
				#ifdef	RTCLOCK
					preempt = QUANTUM;		/* reset preemption counter	*/
				#endif
		
				ctxsw((int)&optr->pesp, (int)optr->pirmask, (int)&nptr->pesp, (int)nptr->pirmask);
		
				/* The OLD process returns here when resumed. */
				return OK;

			}
			else
				goto generate_random;//resched();
		}
		
		else if(num>20 && num <50)
		{
		
			if(nonempty(queueB_head))
			{
				itemB = getfirst(queueB_head);
				//kprintf("\nresched Queue B, %d, %s",itemB, proctab[itemB].pname);

				nptr = &proctab[ (currpid = itemB)];//getfirst(queueB_head)) ];
				nptr->pstate = PRCURR;		/* mark it currently running	*/
				#ifdef	RTCLOCK
					preempt = QUANTUM;		/* reset preemption counter	*/
				#endif
		
				ctxsw((int)&optr->pesp, (int)optr->pirmask, (int)&nptr->pesp, (int)nptr->pirmask);
		
				/* The OLD process returns here when resumed. */
				return OK;

			}
			else
				goto generate_random;//resched();
		}
		
		else if(num<=20)
		{
			
			if(nonempty(queueC_head))
			{
				itemC = getfirst(queueC_head);
				//kprintf("\nresched Queue C, %d, %s",itemC, proctab[itemC].pname);

				nptr = &proctab[ (currpid = itemC)];//getfirst(queueC_head)) ];
				nptr->pstate = PRCURR;		/* mark it currently running	*/
				#ifdef	RTCLOCK
					preempt = QUANTUM;		/* reset preemption counter	*/
				#endif
		
				ctxsw((int)&optr->pesp, (int)optr->pirmask, (int)&nptr->pesp, (int)nptr->pirmask);
		
				/* The OLD process returns here when resumed. */
				return OK;

			}
			else
				goto generate_random;//resched();
		}
	}



	
	
	else if(sched_type == LINUXSCHED)
	{
		//int usedPreempt = preempt;
		int highProc;
		int oldPriority = proctab[currpid].pprio;	//save the current process' priority so that the effect of chprio() or change in priority to the quantum
													// or goodness is reflected in new epoch
		//int procGoodness = 0;
		int startNewEpoch = 1;
		//disable(ps);
		proctab[currpid].quantumLeft = preempt;
		if(switched_to_linuxsched==1)
		{
			proctab[currpid].runnableProc = 1;
			switched_to_linuxsched=0;
			proctab[currpid].procCpuTicks += (QUANTUM - preempt);
			proctab[currpid].assignedQuantum = proctab[currpid].assignedQuantum -(QUANTUM - preempt);
		}
		else
		{
			proctab[currpid].procCpuTicks += (proctab[currpid].assignedQuantum - preempt);
			proctab[currpid].assignedQuantum = proctab[currpid].quantumLeft;
		}
		
		
		if(optr->pstate == PRCURR)
		{
			optr->pstate = PRREADY;
			insert(currpid, rdyhead, proctab[currpid].procGoodness);
		}
		
		
			highProc = rdytail;

			while(q[highProc].qprev!=rdyhead  && q[highProc].qprev>=0 && q[highProc].qprev<NPROC)				//q[temp].qnext!=rdytail && q[temp].qnext>=0 && q[temp].qnext<NPROC
			{
				//kprintf("\t pbdsf%s",proctab[q[highProc].qprev].pname);
				
				
				if((proctab[q[highProc].qprev].runnableProc == 1) && (proctab[q[highProc].qprev].assignedQuantum > 0 ) )	//q[highProc].qnext!=0 && 
				{
					//kprintf("\n bacha hai : %d, %s",q[highProc].qprev, proctab[q[highProc].qprev].pname);
					startNewEpoch = 0;
					break;
				}
						
				highProc = q[highProc].qprev;
			}

		
		
		if(startNewEpoch == 1)
		{
			//kprintf("\nNew Epoch started---*******");
			for(i=0; i<NPROC; i++)
			{
				if(proctab[i].pstate != PRFREE)
				{
					oldPriority = proctab[i].pprio;	//prevent priority change effect in calculation of quantum
					//proctab[i].runnableProc = 1;
					
					//calculate quantum of each process either sleeping/waiting or ready
					if(proctab[i].runnableProc == 1)
					{
						if(proctab[i].assignedQuantum > 0)
						{
							proctab[i].assignedQuantum = (oldPriority + (proctab[i].assignedQuantum /2));
							
							proctab[i].procGoodness = (oldPriority + proctab[i].quantumLeft);
							//kprintf("\nNew quantum and goodness %d, %d, %s",proctab[i].assignedQuantum, proctab[i].procGoodness, proctab[i].pname);
						}
						else
						{
							proctab[i].assignedQuantum = oldPriority;
							
							proctab[i].procGoodness = 0;//(oldPriority);
							//kprintf("\nused up quantum %d, %d, %s",proctab[i].assignedQuantum, proctab[i].procGoodness, proctab[i].pname);
						}
					}
					proctab[i].runnableProc = 1;
					//kprintf("\nFinal values of quantum and goodness %d, %d, %s",proctab[i].assignedQuantum, proctab[i].procGoodness, proctab[i].pname);
					
					dequeue(i);
					insert(i, rdyhead, proctab[i].procGoodness);
					
					
				}
			}
			
			
		}
		
		//goodness is to be calculated for process in same epoch also ? -> no
	
		highProc = rdytail;
		
		
		while(q[highProc].qprev!=rdyhead && q[highProc].qprev>=0 && q[highProc].qprev<NPROC)
		{
			
			/*kprintf("\n Highest proc based on goodness %d, %d, %d", q[highProc].qprev, proctab[q[highProc].qprev].procGoodness, proctab[q[highProc].qprev].assignedQuantum);
			if(proctab[q[highProc].qprev].pstate == PRREADY)
			{
				kprintf("\nstate: PRREADY, %d", proctab[q[highProc].qprev].runnableProc);
				
			}*/
			if( (proctab[q[highProc].qprev].runnableProc == 1) && (proctab[q[highProc].qprev].assignedQuantum > 0 ) )//&& (proctab[q[highProc].qprev].pstate==PRREADY) && q[highProc].qprev!=0 )
			{
				//kprintf(" \ninside----------- %d", currpid);
				currpid = dequeue(q[highProc].qprev);
				//kprintf(" \nnew pid----------- %d", currpid);
				//if(currpid != 0)
				//{
					nptr = &proctab[currpid];
					nptr->pstate = PRCURR;		/* mark it currently running	*/
				#ifdef	RTCLOCK
					preempt = nptr->assignedQuantum;		/* reset preemption counter	*/
				#endif
	
					ctxsw((int)&optr->pesp, (int)optr->pirmask, (int)&nptr->pesp, (int)nptr->pirmask);
		
					/* The OLD process returns here when resumed. */
					return ;// OK;
					break;
				}
			
			else if( (q[rdyhead].qnext == 0) && (q[rdytail].qprev== 0))
				{
					//proctab[currpid].assignedQuantum = QUANTUM;
			//	kprintf(" \ninside----------- %d", currpid);
					nptr = &proctab[(currpid=0)];
					nptr->pstate = PRCURR;		/* mark it currently running	*/
				#ifdef	RTCLOCK
					preempt = QUANTUM;		/* reset preemption counter	*/
				#endif
					ctxsw((int)&optr->pesp, (int)optr->pirmask, (int)&nptr->pesp, (int)nptr->pirmask);
		
					/* The OLD process returns here when resumed. */
					return;// OK;
					break;
				}
				highProc = q[highProc].qprev;
			}
	
	}

	
	
	

	else if(sched_type!=RANDOMSCHED && sched_type!=LINUXSCHED)
	{

		/* no switch needed if current process priority higher than next*/
	
	
		if ( ( optr->pstate == PRCURR) && (lastkey(rdytail)<optr->pprio)) 
		{
			return(OK);
		}
	
		/* force context switch */

		if (optr->pstate == PRCURR) {
			optr->pstate = PRREADY;
			insert(currpid,rdyhead,optr->pprio);
		}

		proctab[currpid].quantumLeft = preempt;
		proctab[currpid].procCpuTicks += (QUANTUM - preempt);
		/* remove highest priority process at end of ready list */

		nptr = &proctab[ (currpid = getlast(rdytail)) ];
		nptr->pstate = PRCURR;		/* mark it currently running	*/
	#ifdef	RTCLOCK
		preempt = QUANTUM;		/* reset preemption counter	*/
	#endif
	
		ctxsw((int)&optr->pesp, (int)optr->pirmask, (int)&nptr->pesp, (int)nptr->pirmask);
	
		/* The OLD process returns here when resumed. */
		return OK;
	}
}
Esempio n. 25
0
main()
{
  char *rle_fname, *colors_in, *array_in, *s, rle_fname_full[80] ;
  char *scale_in, *top_in, *bottom_in, *left_in, *right_in ;
  int num_colors, *r_level, *g_level, *b_level ;
  int *r_array, *g_array, *b_array ;
  int i, nregs, step ;

  /* hex digits here are number plus 'A' */

  decode_query_string(8,"fname", &rle_fname, "colors", &colors_in, 
		      "array",&array_in, "scale", &scale_in,
		      "top", &top_in, "bot", &bottom_in,
		      "left", &left_in, "right", &right_in) ;

  num_colors = ((int)strlen(colors_in) / 6)+1 ;
  r_level = (int *)malloc(sizeof(int) * num_colors) ;
  g_level = (int *)malloc(sizeof(int) * num_colors) ;
  b_level = (int *)malloc(sizeof(int) * num_colors) ;

  r_level[0] = g_level[0] = b_level[0] = 255 ;

  for (s=colors_in, i=1 ; *s != '\0' ; i++, s+=6) {
    r_level[i] = hexdigit(s[0])*16 + hexdigit(s[1]) ;
    g_level[i] = hexdigit(s[2])*16 + hexdigit(s[3]) ;
    b_level[i] = hexdigit(s[4])*16 + hexdigit(s[5]) ;
  }

  nregs = strlen(array_in) ;
  r_array = (int *)malloc(sizeof(int) * nregs) ;
  g_array = (int *)malloc(sizeof(int) * nregs) ;
  b_array = (int *)malloc(sizeof(int) * nregs) ;

  for (i=0 ; i < nregs ; i++) {
    if (array_in[i] >= '0' && array_in[i] <= '9') 
      step = array_in[i] - '0' ;
    else if (array_in[i] >= 'a' && array_in[i] <= 'z') 
      step = array_in[i] - 'a' + 10 ;
    else if (array_in[i] >= 'A' && array_in[i] <= 'Z') 
      step = array_in[i] - 'Z' + 36 ;
    else step = 0 ;
    r_array[i] = r_level[step] ;
    g_array[i] = g_level[step] ;
    b_array[i] = b_level[step] ;
  }

  printf("Content-type: image/gif\n\n") ;
  fflush(stdout) ;

  if (nonempty(scale_in) ||
      (nonempty(top_in) && nonempty(bottom_in) &&
       nonempty(left_in) && nonempty(right_in))) {
    void *image ;
    image = rle22mem(rle_fname, nregs, r_array, g_array, b_array) ;

    if (nonempty(top_in)) 
      rle2clip_mem(image, atoi(left_in), atoi(right_in), 
		   atoi(top_in), atoi(bottom_in)) ;

    if (nonempty(scale_in)) 
      rle2scale_mem(image, atof(scale_in)) ;

    rle2output_mem(image, 0) ;
  }
  else
    rle22gif(rle_fname, nregs, 0, r_array, g_array, b_array) ;
 
}
Esempio n. 26
0
main()
{
  void *qd, *map_info ;

  char *all_in ;
  char *fam_in ; 
  char *gen_in ;
  char *spec_in ; 
  char *mode_in ;
  char *mode_str ;

  char *herb_in, *coll_in, *loc_in, *cult_in ;

  char query_str[1024] ;

  char fam_name_html[80] ;
  char genus_name_html[80] ;
  char spec_name_html[80] ;

  int i ;
  int num_hits ;
  int request_level ;
  int item_num ;
  int first ;

  char header_string[1024] ;
  char *title_string ;

  int redblue_colorsteps[] = {162, 54, 0, 0, 0} ;
  int green_colorsteps[] = {255, 255, 217, 140, 86} ;

  return_header("text/html") ;

  printf("<script>") ;
  printf("if (top.display_mode.substring(top.display_mode.length-4,top.display_mode.length) == 'icty')") ;
  printf("top.change_mode(top.display_mode);") ;
  printf("</script>") ;

  decode_query_string(9, "all", &all_in, "fam", &fam_in, "gen", &gen_in,
		      "spec", &spec_in, "mode", &mode_in, 
		      "herb", &herb_in, "coll", &coll_in,
		      "cult", &cult_in, "loc", &loc_in) ;

  if (nonempty(mode_in) && !strcmp(mode_in, "taxa"))
    mode_str = "qqtax" ;
  else mode_str = "qqspc" ;

  if (nonempty(all_in))
    request_level = 0 ;
  else if (nonempty(fam_in)) {
    if (nonempty(gen_in)) {
      if (nonempty(spec_in)) {
	char *s ;
	while ((s = strchr(spec_in, '-')) != NULL)
	  strcpy(s, s+1) ;
	
	request_level = 3 ;
      }
      else request_level = 2 ;
    }
    else request_level = 1 ;
  }

  if (nonempty(mode_str))
    sprintf(query_str, "%s&", mode_str) ;
  else sprintf(query_str, "") ;
  
  switch(request_level) {
  case 3:
    sprintf(query_str+strlen(query_str), 
	    "qqfam%s&qqgen%s&qqspe%s&", fam_in, gen_in, spec_in) ;
    break ;
  case 2:
    sprintf(query_str+strlen(query_str), 
	    "qqfam%s&qqgen%s&", fam_in, gen_in) ;
    break ;
  case 1:
    sprintf(query_str+strlen(query_str), 
	    "qqfam%s&", fam_in) ;
    break ;
  case 0:
    /* don't need to do anything */
    break ;
  }
  
  if (nonempty(cult_in)) 
    sprintf(query_str+strlen(query_str), "qqcul%s&", cult_in) ;

  if (nonempty(loc_in)) {
    char *t ;
    sprintf(query_str+strlen(query_str), "(") ;
    t = loc_in ;
    while (*t != '\0') {
      sprintf(query_str+strlen(query_str), "qqloc%c%c%c", t[0],t[1],t[2]) ; 
      t+=3 ;
      if (*t != '\0') 
	sprintf(query_str+strlen(query_str), "|") ;
    }
    sprintf(query_str+strlen(query_str), ")&") ;
  }
  
  if (nonempty(herb_in)) {
    char *temp, *tok ;

    temp = strdup(herb_in) ;
    tok = strtok(temp, " ") ;
    sprintf(query_str+strlen(query_str), "(") ;
    do {
      sprintf(query_str+strlen(query_str), "qqhrb%s", tok) ;
      tok = strtok(NULL, " ") ;
      if (tok != NULL) sprintf(query_str+strlen(query_str), "|") ;
    } while (tok != NULL) ;
    sprintf(query_str+strlen(query_str), ")&") ;
    free(temp) ;
  }

  *strrchr(query_str, '&') = '\0' ;
  
  mg_bool_query(query_str, HSB_DATA_PATH, "tracyspecs_map", 
		&qd) ;
  
  num_hits = mg_get_num_returned(qd) ;


  if (num_hits == 0) {
    printf("<h1>No specimens match criteria</h1>") ;
    printf("Sorry! The database does not contain any items ") ;
    printf("meeting the criteria you have selected.\n") ;
  }
  else {
    map_info = map_initialize(HSB_MAP_PATH, "tx", GRADED_VALUE);
    map_assign_graded_colors(map_info, 5, redblue_colorsteps,
			     green_colorsteps, redblue_colorsteps) ;

    if (nonempty(loc_in)) {
      char loc[4], *t ;
      map_disable_all_regions(map_info) ;
      t = loc_in ;
      while (*t != '\0') {
	strncpy(loc, t, 3) ;
	loc[3] = '\0' ;
	map_enable_region_by_name(map_info, "ut_abbr", loc) ;
	t += 3 ;
      }
    }
    
    first = 1 ;
    do {
      item_num = mg_get_doc_num(qd) ;
      if (request_level > 0 && first) {
	/* grab one of the returned items to get all the names */
	void *line_producer = NULL;
	mg_setup_doc_line_producer(qd, item_num, &line_producer) ;
	while (mg_dlp_more_lines(line_producer)) {
	  char s[256] ;
	  mg_dlp_next_line(line_producer, s) ;
	  if (s[0] != '\0') {
	    
	    if (!strncmp(s, "qqfah", 5)) {
	      strcpy(fam_name_html, s+6) ;
	    }
	    else if (!strncmp(s, "qqgeh", 5)) {
	      strcpy(genus_name_html, s+6) ;
	    }
	    else if (!strncmp(s, "qqsph", 5)) {
	      strcpy(spec_name_html, s+6) ;
	    }
	  }
	}
	first = 0 ;
      }
      add_to_county_bins(map_info, item_num) ;
    } while (mg_goto_next_doc(qd)) ;

    printf("<body bgcolor=\"#ffffff\">") ;

    printf("<h1>") ;
    if (!strcmp(mode_str, "qqtax"))
      printf("Species") ;
    else printf("Specimen") ;
    printf(" Distribution Map</h1>\n") ;

    printf("<b>Selection criteria:</b>:<br>") ;

    if (nonempty(cult_in)) 
      printf("Mapping only items taken from %s material <br>\n",
	     !strcmp(cult_in, "yes") ? "cultivated" : "non-cultivated") ;

    printf("Herbaria: <b>") ;
    if (nonempty(herb_in)) {
      printf("%s", herb_in) ;
    }
    else printf("all") ;
    printf("</b><br>\n") ;
    
    printf("Items: <b>") ;
    switch (request_level) {
    case 0:
      printf("all") ;
      break ;
    case 1:
      printf("family %s", fam_name_html) ;
      break ;
    case 2:
      printf("genus %s", genus_name_html) ;
      break ;
    case 3:
      printf("species %s", spec_name_html) ;
      break ;
    }
    printf("</b><p>\n") ;

    printf("<font size=+1>") ;

    printf("<b>Color Key (number of %s county) :<br>\n",
	   !strcmp(mode_str, "qqtax") ? "species in" : "specimens from") ;

    map_output_graded_color_key(map_info) ;
    printf("</b>\n") ;
    
    printf("<form method=get action=\"%s/specsfrommap.html\">", 
	   HSB_MAIN_URL) ;

    map_output_form_elem(map_info, NULL, NULL, NULL) ;

    printf("</form>\n") ;
    printf("</font>") ;
  }
}
Esempio n. 27
0
LinkNode
stringsubst(LinkList list, LinkNode node, int ssub)
{
    int qt;
    char *str3 = (char *)getdata(node);
    char *str  = str3;

    while (!errflag && *str) {
	if ((qt = *str == Qstring) || *str == String)
	    if (str[1] == Inpar) {
		str++;
		goto comsub;
	    } else if (str[1] == Inbrack) {
		/* $[...] */
		char *str2 = str;
		str2++;
		if (skipparens(Inbrack, Outbrack, &str2)) {
		    zerr("closing bracket missing", NULL, 0);
		    return NULL;
		}
		str2[-1] = *str = '\0';
		str = arithsubst(str + 2, &str3, str2);
		setdata(node, (void *) str3);
		continue;
	    } else {
		node = paramsubst(list, node, &str, qt, ssub);
		if (errflag || !node)
		    return NULL;
		str3 = (char *)getdata(node);
		continue;
	    }
	else if ((qt = *str == Qtick) || *str == Tick)
	  comsub: {
	    LinkList pl;
	    char *s, *str2 = str;
	    char endchar;
	    int l1, l2;

	    if (*str == Inpar) {
		endchar = Outpar;
		str[-1] = '\0';
		if (skipparens(Inpar, Outpar, &str))
		    DPUTS(1, "Oops. parse error in command substitution");
		str--;
	    } else {
		endchar = *str;
		*str = '\0';

		while (*++str != endchar)
		    DPUTS(!*str, "Oops. parse error in command substitution");
	    }
	    *str++ = '\0';
	    if (endchar == Outpar && str2[1] == '(' && str[-2] == ')') {
		/* Math substitution of the form $((...)) */
		str = arithsubst(str2 + 1, &str3, str);
		setdata(node, (void *) str3);
		continue;
	    }

	    /* It is a command substitution, which will be parsed again   *
	     * by the lexer, so we untokenize it first, but we cannot use *
	     * untokenize() since in the case of `...` some Bnulls should *
	     * be left unchanged.  Note that the lexer doesn't tokenize   *
	     * the body of a command substitution so if there are some    *
	     * tokens here they are from a ${(e)~...} substitution.       */
	    for (str = str2; *++str; )
		if (itok(*str) && *str != Nularg &&
		    !(endchar != Outpar && *str == Bnull &&
		      (str[1] == '$' || str[1] == '\\' || str[1] == '`' ||
		       (qt && str[1] == '"'))))
		    *str = ztokens[*str - Pound];
	    str++;
	    if (!(pl = getoutput(str2 + 1, qt || ssub))) {
		zerr("parse error in command substitution", NULL, 0);
		return NULL;
	    }
	    if (endchar == Outpar)
		str2--;
	    if (!(s = (char *) ugetnode(pl))) {
		str = strcpy(str2, str);
		continue;
	    }
	    if (!qt && ssub && isset(GLOBSUBST))
		tokenize(s);
	    l1 = str2 - str3;
	    l2 = strlen(s);
	    if (nonempty(pl)) {
		LinkNode n = lastnode(pl);
		str2 = (char *) ncalloc(l1 + l2 + 1);
		strcpy(str2, str3);
		strcpy(str2 + l1, s);
		setdata(node, str2);
		insertlinklist(pl, node, list);
		s = (char *) getdata(node = n);
		l1 = 0;
		l2 = strlen(s);
	    }
	    str2 = (char *) ncalloc(l1 + l2 + strlen(str) + 1);
	    if (l1)
		strcpy(str2, str3);
	    strcpy(str2 + l1, s);
	    str = strcpy(str2 + l1 + l2, str);
	    str3 = str2;
	    setdata(node, str3);
	    continue;
	}
	str++;
    }
    return errflag ? NULL : node;
}
Esempio n. 28
0
int main(int argc, char *argv[]) 
{
  char *all_in, *group_in, *subclass_in, *order_in ;
  char *family_in, *genus_in, *species_in, *tri_in, *show_infras ;
  char *loc_in, *x_in, *y_in ;
  request_level_t request_level ;
  char name_html[128], *name_plain ;
  char qstr[512] ;
  void *qd ;
  taxon *root ;
  taxon *group_p, *subc_p, *ord_p, *fam_p, *gen_p, *spec_p, *tri_p, *quad_p ;
  int has_orders, has_subclasses ;
  int is_ext = !strcmp(argv[0], "b98_list_ext") ? 1 : 0 ;

  /* get CGI vars */
  decode_query_string(11, "all", &all_in,
		      "group", &group_in, "subclass", &subclass_in,
		      "order", &order_in, "family", &family_in,
		      "genus", &genus_in, "species", &species_in,
		      "tri", &tri_in,
		      "loc", &loc_in, "x", &x_in, "y", &y_in) ;

  /* process mouse click */
  
  if (nonempty(x_in)) {
    loc_in = map_convert_xy_to_name(atoi(x_in), atoi(y_in),
				    MAP_DIR, MAP_NAME, "abbr") ;
    if (!nonempty(loc_in)) return_nothing() ;
  }

  /* determine "request level" of request */

  if (nonempty(all_in))
    request_level = ALL ;
  else if (nonempty(group_in))
    request_level = GROUP ;
  else if (nonempty(subclass_in))
    request_level = SUBCLASS ;
  else if (nonempty(order_in))
    request_level = ORDER ;
  else if (nonempty(family_in))
    request_level = FAMILY ;
  else if (nonempty(genus_in)) {
    if (nonempty(species_in)) 
      if (nonempty(tri_in))
	request_level = TRI ;
      else request_level = SPECIES ;
    else request_level = GENUS ;
  }
  else request_level = ERROR ;

  /* build MG query string */

  switch(request_level) {
  case ALL:
    sprintf(qstr, "qqall") ; break;
  case GROUP:
    sprintf(qstr, "qqgrp%s", group_in) ; break ;
  case SUBCLASS:
    sprintf(qstr, "qqsbc%s", subclass_in) ; break ;
  case ORDER:
    sprintf(qstr, "qqord%s", order_in) ; break ;
  case FAMILY:
    sprintf(qstr, "qqfam%s", family_in) ; break ;
  case GENUS:
    sprintf(qstr, "qqgen%s", genus_in) ; break ;
  case SPECIES: case TRI:
    /* eliminate dashes in species names */
    {
      char *temp_s, *dash_loc ;
      temp_s = strdup(species_in) ;
      if ((dash_loc = strchr(temp_s, '-')) != NULL)
	strcpy(dash_loc, dash_loc+1) ;
      sprintf(qstr, "qqgen%s&qqspe%s", genus_in, temp_s) ;
      free(temp_s) ;
      if (request_level == TRI) {
	temp_s = strdup(tri_in) ;
	if ((dash_loc = strchr(temp_s, '-')) != NULL)
	  strcpy(dash_loc, dash_loc+1) ;
	sprintf(qstr+strlen(qstr), "&qqtri%s", temp_s) ;
	free(temp_s) ;
      }
    } break ;
  }

  if (nonempty(loc_in))
    sprintf(qstr+strlen(qstr), "&qqloc%s", loc_in) ;

  /* execute MG query */
  mg_bool_query(qstr, MG_COLL_DIR, MG_COLL_NAME, &qd) ;

  /* process MG query results */

  if (mg_get_num_returned(qd) == 0) return_nothing() ;

  root = NULL ;

  {
    char s[256] ;
    void *lp=NULL ;
    int docnum ;
    
    do {
      clear_name_vars() ;
      docnum = mg_get_doc_num(qd) ;
      mg_setup_doc_line_producer(qd, docnum, &lp) ;
      while (mg_dlp_more_lines(lp)) {
	if (!strncmp(s, "qqgrp", 5))
	  strcpy(group_out, s+5) ;
	else if (!strncmp(s, "qqsbc", 5))
	  strcpy(subclass_out, s+5) ;
	else if (!strncmp(s, "qqord", 5))
	  strcpy(order_out, s+5) ;
	else if (!strncmp(s, "qqfam", 5))
	  strcpy(family_out, s+5) ;
	else if (!strncmp(s, "qqgen", 5))
	  strcpy(genus_out, s+5) ; 
	else if (!strncmp(s, "qqhyb", 5))
	  hybrid = (!strncmp(s+5, "yes", 3) ? 1 : 0) ;
	else if (!strncmp(s, "qqspr", 5))
	  strcpy(species_out, s+5) ;
	else if (!strncmp(s, "qqtrs", 5))
	  strcpy(trirank_out, s+5) ;
	else if (!strncmp(s, "qqtrr", 5))
	  strcpy(tri_out, s+5) ;
	else if (!strncmp(s, "qqqus", 5))
	  strcpy(quadrank_out, s+5) ;
	else if (!strncmp(s, "qqqur", 5))
	  strcpy(quad_out, s+5) ;
	mg_dlp_next_line(lp, s) ;
      }
      switch (group_out[0]) {
      case 'P': 
	group_p = insert_taxon_item(&root, "1Pteridophytes", NULL, 1) ;
	break ;
      case 'G': 
	group_p = insert_taxon_item(&root, "2Gymnosperms", NULL, 1) ;
	break ;
      case 'M': 
	group_p = insert_taxon_item(&root, "3Monocots", NULL, 1) ;
	break ;
      case 'D': 
	group_p = insert_taxon_item(&root, "4Dicots", NULL, 1) ;
	break ;
      }
      subc_p = insert_taxon_child(group_p, subclass_out, NULL, 1) ;
      ord_p = insert_taxon_child(subc_p, order_out, NULL, 1) ;
      fam_p = insert_taxon_child(ord_p, family_out, NULL, 1) ;
      gen_p = insert_taxon_child(fam_p, genus_out, NULL, 1) ;
      spec_p = insert_taxon_child(gen_p, species_out, 
				  new_int(hybrid), 1) ;
      if (nonempty(tri_out)) {
	tri_p = insert_taxon_child(spec_p, tri_out, 
				   new_int(!strcmp(trirank_out, "var") ?
					   1 : 0), 1) ;
	if (nonempty(quad_out)) {
	  quad_p = insert_taxon_child(tri_p, quad_out, 
				      new_int(!strcmp(quadrank_out, "var") ?
						      1 : 0), 1) ;
	}
      }
    } while (mg_goto_next_doc(qd)) ;
  }

  /* generate HTML page */

  /* HTTP header */
  return_header("text/html") ;

  build_name(name_html, request_level, 0) ;
  name_plain = strip_tags(name_html) ;

  puts("<html>") ;
  puts("<head>") ;
  printf("<title>BONAP Distribution Data: ") ;
  if (request_level == SPECIES || request_level == TRI)
    printf("subspecies/varieties ") ;
  else printf("taxa ") ;
  printf("of %s", name_plain) ;
  if (nonempty(loc_in))
    printf(" in %s", 
	   map_convert_region_name(MAP_DIR, MAP_NAME, 
				   "abbr", "name", loc_in)) ;
  else
    puts(" in the US") ;
  puts("</title>") ;
  puts("</head>") ;
  puts("<body bgcolor=\"#ffffff\">") ;

  if (is_ext) ext_header() ;

  printf("<h1>") ;
  if (request_level == SPECIES || request_level == TRI)
    printf("Subspecies/varieties ") ;
  else printf("Taxa ") ;
  printf("of %s", name_html) ;
  if (nonempty(loc_in))
    printf(" in %s", 
	   map_convert_region_name(MAP_DIR, MAP_NAME, 
				   "abbr", "name", loc_in)) ;
  else
    puts(" in the US") ;
  printf("</h1>") ;

  if (request_level > GROUP) {
    if (request_level <= GENUS) name_html[0] = toupper(name_html[0]) ;
    printf("%s is a member of the %s group",
	   name_html,
	   (root->name)+1) ;
    if (request_level > SUBCLASS) 
      if (strcmp(root->nextlevel->name, "none")) 
	printf(", subclass %s", root->nextlevel->name) ;
    if (request_level > ORDER)
      if (strcmp(root->nextlevel->nextlevel->name, "none"))
	printf(", order %s", root->nextlevel->nextlevel->name) ;
    if (request_level > FAMILY)
      printf(", family %s", root->nextlevel->nextlevel->nextlevel->name) ;
    /* Don't really need to mention genus because it's obvious
       from the species name */
    /*
    if (request_level > GENUS)
      printf(", genus <i>%s</i>",
	     root->nextlevel->nextlevel->nextlevel->nextlevel->name) ;
	     */
    puts(".<p>") ;
  }

  if (request_level <= ALL) 
    puts("<ul>") ;
  group_p = root ;
  while (group_p != NULL) {
    if (request_level <= ALL)
      printf("%s<br>\n", (group_p->name)+1) ;

    subc_p = group_p->nextlevel ;
    has_subclasses = (strcmp(subc_p->name, "none") != 0) ;

    if (request_level <= GROUP)
      if (has_subclasses) puts("<ul>") ;
    while (subc_p != NULL) {
      strcpy(subclass_out, subc_p->name) ;
      if (request_level <= GROUP && has_subclasses) {
	build_name(name_html, SUBCLASS, 1) ;
	printf("<b>%s</b>", name_html) ;

	puts("<br>") ;
      }
      ord_p = subc_p->nextlevel ;
      has_orders = (strcmp(ord_p->name, "none") != 0) ;
      if (request_level <= SUBCLASS)
	if (has_orders) puts("<ul>") ;
      while (ord_p != NULL) {
	strcpy(order_out, ord_p->name) ;
	if (request_level <= SUBCLASS && has_orders) {
	  build_name(name_html, ORDER, 1) ;
	  printf("<b>%s</b><br>\n", name_html) ;
	}
	fam_p = ord_p->nextlevel ;
	if (request_level <= ORDER)
	  puts("<ul>") ;
	while (fam_p != NULL) {
	  strcpy(family_out, fam_p->name) ;
	  if (request_level <= ORDER) {
	    build_name(name_html, FAMILY, 1) ;
	    printf("<b>%s</b><br>\n", name_html) ;
	  }
	  gen_p = fam_p->nextlevel ;
	  if (request_level <= FAMILY)
	    puts("<ul>") ;
	  while (gen_p != NULL) {
	    strcpy(genus_out, gen_p->name) ;
	    if (request_level <= FAMILY) {
	      build_name(name_html, GENUS, 1) ;
	      printf("<b>%s</b> ", name_html) ;
	      printf("<a href=\"%s?colldir=%s&collname=%s&"
		     "query=%s\">(checklist entries)</a>",
		     RULED_HTML_QUERY_URL,
		     CHECKLIST_COLL_DIR, CHECKLIST_COLL_NAME,
		     gen_p->name) ;
	      printf(" <a href=\"%s?genus=%s\">(map)</a>",
		     is_ext ? B98_MAP_EXT_URL : B98_MAP_URL,
		     genus_out) ;
	      puts("<br>") ;
	    }
	    spec_p = gen_p->nextlevel ;
	    if (request_level <= GENUS)
	      puts("<ul>") ;
	    while (spec_p != NULL) {
	      strcpy(species_out, spec_p->name) ;
	      hybrid = *((int *)(spec_p->other_data)) ;
	      if (request_level <= GENUS) {
		build_name(name_html, SPECIES, 1) ;
		printf("<b>%s</b>", name_html) ;
		printf(" <a href=\"%s?colldir=%s&collname=%s&"
		       "query=%s%%26%s\">(checklist entry)</a>",
		       RULED_HTML_QUERY_URL,
		       CHECKLIST_COLL_DIR, CHECKLIST_COLL_NAME,
		       gen_p->name, spec_p->name) ;
		printf(" <a href=\"%s?genus=%s&species=%s\">(species "
		       "map)</a>",
		       is_ext ? B98_MAP_EXT_URL : B98_MAP_URL,
		       genus_out, species_out) ;
		if (spec_p->nextlevel != NULL) 
		  printf(" <a href=\"%s?genus=%s&species=%s&show_infras=yes\">"
			 "(infras map)</a>",
			 is_ext ? B98_MAP_EXT_URL : B98_MAP_URL,
			 genus_out, species_out) ;
		printf("<br>\n") ;
	      }
	      if (spec_p->nextlevel != NULL) puts("<ul>") ;
	      tri_p = spec_p->nextlevel ;
	      while (tri_p != NULL) {
		strcpy(tri_out, tri_p->name) ;
		strcpy(trirank_out,
		       *((int *)(tri_p->other_data)) ? "var" : "ssp") ;
		build_name(name_html, TRI, 1) ;
		printf("<b>%s</b>", name_html) ;
		printf(" <a href=\"%s?genus=%s&species=%s&tri=%s\">"
		       "(infra map)</a>",
		       is_ext ? B98_MAP_EXT_URL : B98_MAP_URL,
		       genus_out, species_out, tri_out) ;
		if (tri_p->nextlevel != NULL) 
		  printf(" <a href=\"%s?genus=%s&species=%s&tri=%s"
			 "&show_infras=yes\">(subinfras map)</a>",
			 is_ext ? B98_MAP_EXT_URL : B98_MAP_URL,
			 genus_out, species_out, tri_out) ;
		puts("<br>") ;
		if (tri_p->nextlevel != NULL) puts("<ul>") ;
		quad_p = tri_p->nextlevel ;
		while (quad_p != NULL) {
		  strcpy(quad_out, quad_p->name) ;
		  strcpy(quadrank_out,
			 *((int *)(quad_p->other_data)) ? "var" : "ssp") ;
		  build_name(name_html, QUAD, 1) ;
		  printf("<b>%s</b>", name_html) ;
		  printf(" <a href=\"%s?genus=%s&species=%s&tri=%s&quad=%s\">"
			 "(subinfra map)</a>",
			 is_ext ? B98_MAP_EXT_URL : B98_MAP_URL,
			 genus_out, species_out, tri_out, quad_out) ;
		  puts("<br>") ;
		  step_taxon(quad_p) ;
		}
		if (tri_p->nextlevel != NULL) puts("</ul>") ;
		step_taxon(tri_p) ;
	      }
	      if (spec_p->nextlevel != NULL) puts("</ul>") ;
	      step_taxon(spec_p) ;
	    }
	    if (request_level <= GENUS)
	      puts("</ul>") ;
	    step_taxon(gen_p) ;
	  }
	  if (request_level <= FAMILY)
	    puts("</ul>") ;
	  step_taxon(fam_p) ;
	}
	if (request_level <= ORDER)
	  puts("</ul>") ;
	step_taxon(ord_p) ;
      }
      if (request_level <= SUBCLASS)
	if (has_orders) puts("</ul>") ;
      step_taxon(subc_p) ;
    }
    if (request_level <= GROUP)
      if (has_subclasses) puts("</ul>") ;
    step_taxon(group_p) ;
  }

  if (request_level <= ALL)
    puts("</ul>") ;

  puts("</body>"
       "</html>") ;
}
Esempio n. 29
0
main()
{
  char *all_in = NULL ;
  char *grp_in = NULL ;
  char *fam_in = NULL ;
  char *gen_in = NULL ;
  char *spec_in = NULL ;
  char *x_in = NULL, *y_in = NULL ;
  char *loc_in = NULL ;
  char *loc_name = NULL ;
  char query_str[512] ;
  void *qd, *lp=NULL ;
  taxon *root, *grp_p, *fam_p, *gen_p, *spe_p, *inf_p ;
  char grp_out[32], fam_out[32], gen_out[32], spec_out[32] ;

  decode_query_string(8, "all", &all_in,
		      "grp", &grp_in,
		      "fam", &fam_in,
		      "gen", &gen_in,
		      "spec", &spec_in,
		      "x", &x_in, "y", &y_in, "loc", &loc_in) ;

  if (nonempty(x_in)) {
    loc_in = map_convert_xy_to_name(atoi(x_in),atoi(y_in), 
				    "/bwg/FLORA/cgi/maps", "ca_pswrs",
				    "abbr") ;
    if (loc_in == NULL) {
      return_nothing() ;
      exit(1) ;
    }
  }
  if (nonempty(loc_in)) 
    loc_name = 
      map_convert_region_name("/bwg/FLORA/cgi/maps", "ca_pswrs",
			      "abbr", "name", loc_in) ;
    

  if (!mg_db_available("/bwg/FLORA/calflora/mgdata", "calmap")) {
    return_header("text/html") ;
    sorry() ;
    exit(1) ;
  }

  if (nonempty(all_in))
    sprintf(query_str, "qqall") ;
  else if (nonempty(grp_in))
    sprintf(query_str, "qqgro%s", grp_in) ;
  else if (nonempty(fam_in))
    sprintf(query_str, "qqfam%s", fam_in) ;
  else if (nonempty(gen_in)) {
    if (nonempty(spec_in))
      sprintf(query_str, "qqgen%s&qqspe%s", gen_in, spec_in) ;
    else sprintf(query_str, "qqgen%s", gen_in) ;
  }
  else {
    return_header("text/html") ;
    printf("<title>Sorry!</title>") ;
    printf("<h1>Sorry!</h1>") ;
    printf("Your list query to the CalFlora plant ") ;
    printf("distributions database was improperly formed.") ;
    printf("Please check that the URL ") ;
    printf("is properly formed, and contact Erich Schneider ") ;
    printf("<a href=\"mailto:[email protected]\">(<b>[email protected]") ;
    printf("</b>)</a> if you have further problems.") ;
    exit(1) ;
  }

  if (nonempty(loc_in))
    sprintf(query_str+strlen(query_str), 
	    "&(qqcpl%s|qqupl%s|qqijl%s)", loc_in, loc_in, loc_in) ;

  mg_bool_query(query_str, "/herbaria/FLORA/calflora/mgdata", "calmap",&qd);

  if (mg_get_num_returned(qd) == 0) {
    if (nonempty(x_in)) {
      return_nothing() ;
      exit(1) ;
    }
    else {
      return_header("text/html") ;
      printf("<title>Sorry!</title>") ;
      printf("<h1>Sorry!</h1>") ;
      printf("Your request did not correspond to any items in the CalFlora ") ;
      printf("plant distributions database. Please check that the URL ") ;
      printf("is properly formed, and contact Erich Schneider ") ;
      printf("<a href=\"mailto:[email protected]\">(<b>[email protected]") ;
      printf("</b>)</a> if you have further problems.") ;
      exit(0) ;
    }
  }


  root = NULL ;
  do {
    int first=1 ;
    char *grp, fam[32], gen[32], spec[32], infra[32], source[64] ;
    char name[256], rank ;
    item_data_t *item_data ;
    
    mg_setup_doc_line_producer(qd, mg_get_doc_num(qd), &lp) ;
    while (mg_dlp_more_lines(lp)) {
      char s[256] ;
      mg_dlp_next_line(lp, s) ;
      if (first) {
	if (!strncmp(s, "qqgro", 5)) strcpy(grp_out, s+5) ;
	else if (!strncmp(s, "qqfam", 5)) strcpy(fam_out, s+5) ;
	else if (!strncmp(s, "qqgen", 5)) strcpy(gen_out, s+5) ;
	else if (!strncmp(s, "qqspe", 5)) 
	  strcpy(spec_out, strchr(s, ' ')+1) ;
      }

      if (!strncmp(s, "qqgro", 5)) {
	if (!strcmp(s+5, "Pteridophyte")) grp = "1Pteridophytes";
	else if (!strcmp(s+5, "Gymnosperm")) grp="2Gymnosperms";
	else if (!strcmp(s+5, "Dicot")) grp="3Dicots";
	else if (!strcmp(s+5, "Monocot")) grp="4Monocots";
      }
      else if (!strncmp(s, "qqfam", 5)) 
	strcpy(fam, s+5) ;
      else if (!strncmp(s, "qqgen", 5)) 
	strcpy(gen, s+5) ;
      else if (!strncmp(s, "qqspe", 5)) 
	strcpy(spec, strchr(s, ' ')+1) ;
      else if (!strncmp(s, "qqtri", 5)) 
	strcpy(infra, s+5) ;
      else if (!strncmp(s, "qqnam", 5))
	strcpy(name, s+6) ;
      else if (!strncmp(s, "qqsrc", 5)) 
	strcpy(source, s+6) ;
      else if (!strncmp(s, "qqrnk", 5)) 
	rank = s[5] ;
    }
    grp_p = insert_taxon_item(&root, grp, NULL, 0) ;
    fam_p = insert_taxon_child(grp_p, fam, NULL, 0) ;
    gen_p = insert_taxon_child(fam_p, gen, NULL, 0) ;
    spe_p = insert_taxon_child(gen_p, spec, NULL, 0) ;

    item_data = (item_data_t *)malloc(sizeof(item_data_t)) ;
    item_data->name = strdup(name) ;
    if (strcmp(source, "No distribution source referenced"))
      item_data->has_dist = 1 ;
    else item_data->has_dist = 0 ;


    if (rank == 'b') {
      inf_p = insert_taxon_child(spe_p, infra, item_data, 1) ;
    }
    else {
      spe_p->other_data = item_data ;
    }

    first = 0 ;
  } while (mg_goto_next_doc(qd)) ;

  return_header("text/html") ;

  header() ;

  puts("<h1>") ;
  if (nonempty(all_in)) {
    printf("Plants ") ;
    if (nonempty(loc_name))
      printf("of %s", loc_name) ;
    else printf("of California") ;
  }
  else if (nonempty(grp_in)) {
    printf("%ss ", grp_out) ;
    if (nonempty(loc_name))
      printf("of %s", loc_name) ;
    else printf("of California") ;
  }
  else if (nonempty(fam_in)) {
    printf("Plants of family %s ", fam_out) ;
    if (nonempty(loc_name))
      printf("in %s", loc_name) ;
    else printf("in California") ;
  }
  else if (nonempty(gen_in)) {
    if (!nonempty(spec_in))
      printf("Plants of genus <i>%s</i> ", gen_out) ;
    else printf("Varieties/subspecies of <i>%s %s</i> ", gen_out, spec_out) ;
    if (nonempty(loc_name))
      printf("in %s", loc_name) ;
    else printf("in California") ;
  }
  puts("</h1>") ;

  printf("Links in the list below go to diversity maps of the item ") ;
  printf("in question, or to distribution maps if the item is a ") ;
  printf("bottom-level species (indicated by the presence of an ") ;
  printf("authority). Species containing varieities or subspecies ") ;
  printf("which have distribution data in their own right have links ") ;
  printf("both to diversity maps of their infraspecific taxa as well ") ;
  printf("as to a map of their own distribution. A map of ") ;
  printf("<a href=\"/FLORA/cgi/calmap?all=yes&div=yes\">") ;
  printf("all California plants</a> in the database is also available.") ;
  printf("<p>") ;


  for (grp_p = root ; grp_p != NULL ; step_taxon(grp_p)) {
    printf("<a href=\"/FLORA/cgi/calmap?div=yes&grp=") ;
    switch(grp_p->name[0]) {
    case '1': printf("pteridophyte") ; break ;
    case '2': printf("gymnosperm") ; break ;
    case '3': printf("dicot") ; break ;
    case '4': printf("monocot") ; break ;
    }
    printf("\">") ;
    printf("%s", grp_p->name+1) ;
    printf("</a>") ;
    puts("<br><ul>") ;
    for (fam_p = grp_p->nextlevel ; fam_p != NULL ; step_taxon(fam_p)) {
      printf("Family ") ;
      printf("<a href=\"/FLORA/cgi/calmap?div=yes&fam=%s\">",
	     fam_p->name) ;
      printf("%s", fam_p->name) ;
      printf("</a>") ;
      puts("<br><ul>") ;
      for (gen_p = fam_p->nextlevel ; gen_p != NULL ; step_taxon(gen_p)) {
	printf("Genus ") ;
	printf("<a href=\"/FLORA/cgi/calmap?div=yes&gen=%s\">",
	       gen_p->name) ;
	printf("<i>%s</i>", gen_p->name) ;
	printf("</a>") ;
	printf("<br><ul>") ;
	for (spe_p = gen_p->nextlevel ; spe_p != NULL ; step_taxon(spe_p)) {
	  int spec_has_own_identity = 0 ;
	  int spec_has_infras = 0 ;
	  int spec_has_distribution = 0 ;

	  if (spe_p->other_data != NULL)
	    spec_has_own_identity = 1 ;
	  if (spe_p->nextlevel != NULL) spec_has_infras = 1 ;
	  if (spec_has_own_identity &&
	      ((item_data_t *)spe_p->other_data)->has_dist)
	    spec_has_distribution = 1;

	  if (spec_has_distribution || spec_has_infras) {
	    printf("<a href=\"/FLORA/cgi/calmap?") ;
	    if (spec_has_infras) 
	      printf("div=yes&") ;
	    printf("gen=%s&spec=%s\">", gen_p->name, spe_p->name) ;
	  }

	  if (spec_has_own_identity) {
	    printf("%s", ((item_data_t *)spe_p->other_data)->name) ;
	  }
	  else {
	    printf("<i>%s %s</i>", gen_p->name, spe_p->name) ;
	  }
	  if (spec_has_distribution || spec_has_infras) printf("</a>") ;
	  if (spec_has_distribution && spec_has_infras) {
	    printf(" <a href=\"/FLORA/cgi/calmap?") ;
	    printf("gen=%s&spec=%s\">(species distribution)</a>",
		   gen_p->name, spe_p->name) ;
	  }
	  if (!spec_has_distribution && !spec_has_infras)
	    printf(" (No distribution data in database)") ;

	  puts("<br>") ;
	  if (spec_has_infras) {
	    puts("<ul>") ;
	    for (inf_p = spe_p->nextlevel ; inf_p != NULL ; 
		 step_taxon(inf_p)) {
	      if (((item_data_t *)inf_p->other_data)->has_dist) {
		printf("<a href=\"/FLORA/cgi/calmap?") ;
		printf("gen=%s&spec=%s&inf=%s\">", 
		       gen_p->name, spe_p->name, inf_p->name) ;
	      }
	      printf("%s", ((item_data_t *)inf_p->other_data)->name) ;
	      if (((item_data_t *)inf_p->other_data)->has_dist) 
		printf("</a>") ;
	      else printf(" (No distribution data in database)") ;
	      puts("<br>") ;
	    }
	    puts("</ul>") ;
	  }
	}
	puts("</ul>") ;
      }
      puts("</ul>") ;
    }
    puts("</ul>") ;
  }

  footer() ;

}
Esempio n. 30
0
main()
{
  char *fam_in, *gen_in, *spec_in, *nkcode_in, *tkcode_in, *x_in, *y_in ;
  char *ncode_in, *tcode_in, *gcode_in, *fcode_in, *ntype_in ;
  char *all_in, *tri_in, *quad_in, *cutoff_in ;
  int need_name ;
  char name_html[128] ;
  int i, cutoff_level ;
  void *qd ;
  int num_hits ;
  char *loc_in=NULL, *county_in=NULL ;
  int request_level ;
  char qstr[256] ;

  if (!mg_db_available("/bwg/FLORA/tracy/mgdata","tracyspecs")) {
    return_header("text/html") ;
    puts("<title>Sorry!</title>") ;
    puts("<h1>Sorry!</h1>") ;
    puts("The database of specimens used to generate lists, which is ") ;
    puts("required to process ") ;
    puts("your query, is currently being rebuilt. Please try again ") ;
    puts("in a little while.") ;
    exit(0) ;
  }

  decode_query_string(14, "ncode", &ncode_in,  /* bonap name code */ 
		      "tcode", &tcode_in,  /* bonap taxon code */
		      "gcode", &gcode_in,  /* ncode of genus */
		      "fcode", &fcode_in,  /* ncode of family */
		      "ntype", &ntype_in,  /* native/bonap_n/bonap_t */
		      "all", &all_in,
		      "fam", &fam_in, 
		      "gen", &gen_in,
		      "spec", &spec_in, 
		      "infra", &tri_in,
		      "infra2", &quad_in,
		      "cutoff", &cutoff_in, /* clip level of map */
		      "x", &x_in, "y", &y_in) ;
  
  if (nonempty(x_in)) {
    loc_in = map_convert_xy_to_name(atoi(x_in), atoi(y_in),
				    "/herbaria/FLORA/cgi/maps","tx",
				    "ut_abbr") ;
    if (loc_in == NULL) {
      return_nothing() ;
      exit() ;
    }
    county_in = map_convert_xy_to_name(atoi(x_in), atoi(y_in),
				    "/herbaria/FLORA/cgi/maps","tx",
				    "cname") ;
  }

  need_name = 0 ;

  if (nonempty(ncode_in) || nonempty(tcode_in) ||
      nonempty(gcode_in) || nonempty(fcode_in)) {
    char *code, *prefix ;
    if (nonempty(ncode_in)) {
      code = ncode_in ;
      prefix = "qqbnn" ;
    }
    else if (nonempty(tcode_in)) {
      code = tcode_in ; 
      prefix = "qqbtn" ;
    }
    else if (nonempty(gcode_in)){
      code = gcode_in ;
      prefix = "qqgco" ;
    }
    else if (nonempty(fcode_in)) {
      code = fcode_in ;
      prefix = "qqfco" ;
    }
    get_bonap_info_by_code(code, name_html, &request_level) ;
    strcpy(qstr, prefix) ;
    for (i=0 ; code[i] != '\0' ; i++) 
      sprintf(qstr+strlen(qstr), "%c", code[i]+'A'-'0') ;
  }
  else /* no bonap code, doing it by name */ {
    /* determine request level */
    if (nonempty(all_in)) {
      request_level = 0 ;
      sprintf(qstr, "qqspc") ;
    }
    else if (nonempty(fam_in)) {
      request_level = 1 ;
      sprintf(qstr, "qqfam%s", fam_in) ;
    }
    else if (nonempty(gen_in)) {
      if (nonempty(spec_in)) {
	if (nonempty(tri_in)) {
	  if (nonempty(quad_in)) {
	    request_level = 5 ;
	    sprintf(qstr, "qqgen%s&qqspe%s&qqtri%s&qqqua%s",
		    fam_in, gen_in, tri_in, quad_in) ;
	  }
	  else {
	    request_level = 4 ;
	    sprintf(qstr, "qqgen%s&qqspe%s&qqtri%s",
		    fam_in, gen_in, tri_in) ;
	  }
	}
	else {
	  request_level = 3 ;
	  sprintf(qstr, "qqgen%s&qqspe%s", gen_in, spec_in) ;
	}
      }
      else {
	request_level = 2 ;
	sprintf(qstr, "qqgen%s", gen_in) ;
      }
    }
    else {
      return_header("text/html") ;
      puts("<title>Sorry!</title>") ;
      puts("<h1>Sorry!</h1>") ;
      puts("The URL you requested is malformed. When querying by name,") ;
      puts("you must provide one of the following:") ;
      puts("<ul>") ;
      puts("<li>A request for all specimens") ;
      puts("<li>A family") ;
      puts("<li>A genus") ;
      puts("<li>A genus and species") ;
      puts("<li>A genus, species, and tri-level infra") ;
      puts("<li>A genus, species, tri- and quad-level infras") ;
      puts("</ul>") ;
      puts("Please check the URL structure and try again.") ;
      exit(1) ;
    }

    if (request_level > 0) {
      if (nonempty(ntype_in) && strcmp(ntype_in, "native")) {
	char ncode[10], tcode[10], *prefix, *code ;
	get_bonap_info_by_qstr(qstr, name_html, ncode, tcode) ;
	prefix = !strcmp(ntype_in, "bonap_n") ? "qqbnn" : "qqbtn" ;
	code = !strcmp(ntype_in, "bonap_n") ? ncode : tcode ;
	switch(request_level) {
	case 1: 
	  sprintf(qstr, "qqfco%s", tcode) ; break ;
	case 2:
	  sprintf(qstr, "qqgco%s", tcode) ; break ;
	case 3:
	  sprintf(qstr, "(%s%s|qqsco%s", prefix, code, tcode) ; break ;
	case 4:
	  sprintf(qstr, "(%s%s|qqtco%s", prefix, code, tcode) ; break ;
	case 5:
	  sprintf(qstr, "%s%s", prefix, code) ; break ;
	}
      }
      else need_name = 1 ;
    }
  }

  /* after all this drill "name_html" should contain the html form
     of the thing being queried for or need_name != 0 */

  if (nonempty(cutoff_in)) {
    if (!strcmp(cutoff_in, "fam") && request_level <= 1) {
      cutoff_level = 1 ;
      sprintf(qstr+strlen(qstr), "&qqfrp") ;
    }
    else if (!strcmp(cutoff_in, "gen") && request_level <= 2) {
      cutoff_level = 2 ;
      sprintf(qstr+strlen(qstr), "&qqgrp") ;
    }
    else if (!strcmp(cutoff_in, "spec") && request_level <= 3) {
      sprintf(qstr+strlen(qstr), "&qqtax") ;
      cutoff_level = 3 ;
    }
    else {
      return_header("text/html") ;
      puts("<title>Sorry!</title>") ;
      puts("<h1>Sorry!</h1>") ;
      puts("The URL you requested is malformed. When supplying a cutoff,") ;
      puts("the cutoff must be at a taxonomic level less than or equal to ") ;
      puts("the level of the query (for example, you cannot have a cutoff ") ;
      puts("of \"family\" when listing a genus). Please check the URL ") ;
      puts("and try again.") ;
      exit(1) ;
    }
  }
  else cutoff_level = 0 ;
  
  if (nonempty(loc_in)) 
    sprintf(qstr+strlen(qstr), "&qqloc%s", loc_in) ;

  mg_bool_query(qstr,"/bwg/FLORA/tracy/mgdata", "tracyspecs", 
		&qd) ;

  num_hits = mg_get_num_returned(qd) ;

  if (num_hits == 0) {
    if (nonempty(loc_in)) return_nothing() ;
    else {
      return_header("text/html") ;
      puts("<title>Sorry!</title>") ;
      puts("<h1>Sorry!</h1>") ;
      puts("There are no items in the database which corresponded to your ") ;
      puts("query.") ;
    }
  }
  else {
    void *dlp=NULL ;
    char s[256] ;
    char stored_fam[80], stored_gen[80], stored_spec[80] ;
    char stored_tri[80], stored_quad[80] ;
    int new_fam, new_gen, new_spec ;
    int printing_genera, printing_species, printing_specimens ;

    if (need_name) {
      void *lp=NULL ;
      char tri_html[80], quad_html[80] ;
      mg_setup_doc_line_producer(qd, mg_get_doc_num(qd), &lp) ;
      while (mg_dlp_more_lines(lp)) {
	char s[256] ;
	mg_dlp_next_line(lp, s) ;
	if (request_level == 1) {
	  if (!strncmp(s, "qqfah ", 6))
	    strcpy(name_html, s+6) ;
	}
	else if (request_level == 2) {
	  if (!strncmp(s, "qqgeh ", 6))
	    strcpy(name_html, s+6) ;
	}
	else {
	  if (!strncmp(s, "qqsph ", 6))
	    strcpy(name_html, s+6) ;
	  else if (!strncmp(s, "qqiah ", 6))
	    strcpy(tri_html, s+6) ;
	  else if (!strncmp(s, "qqibh ", 6))
	    strcpy(quad_html, s+6) ;
	}
      }
      if (request_level >= 4)
	sprintf(name_html+strlen(name_html), " %s", tri_html) ;
      if (request_level == 5)
	sprintf(name_html+strlen(name_html), " %s", quad_html) ;
    }

    if (cutoff_level != 0) {
      printing_specimens = 0 ;
      stored_fam[0] = stored_gen[0] = stored_spec[0] = '\0' ;
      printing_genera = (cutoff_level >= 2) ;
      printing_species = (cutoff_level == 3) ;
    }
    else {
      printing_specimens = 1 ;
      printing_genera=printing_species = 0 ;
    }

    /* header stuff */

    return_header("text/html") ;
    printf("<body bgcolor=\"#ffffff\">\n") ;

    puts("<title>Flora of Texas Consortium - Texas Plant") ;
    puts("Distributions</title>") ;

    puts("<h1>Flora of Texas Consortium - Texas Plant Distributions</h1>") ;

    puts("<b>Currently listing: ") ;
    switch (request_level) {
    case 0: 
      switch (cutoff_level) {
      case 0: puts("all specimens") ; break ;
      case 1: puts("all families") ; break ;
      case 2: puts("all genera") ; break ;
      case 3: puts("all species") ; break ;
      }
      break ;
    case 1:
      switch (cutoff_level) {
      case 0: puts("specimens of family") ; break ;
      case 2: puts("genera of family") ; break ;
      case 3: puts("species of family") ; break ;
      }
      break ;
    case 2: 
      switch(cutoff_level) {
      case 0: puts("specimens of genus") ; break ;
      case 3: puts("species of genus") ; break ;
      }
      break ;
    default:
      puts("specimens of ") ; break ;
    }
    if (request_level > 0) puts(name_html) ;
    if (nonempty(county_in)) printf(" from %s County", county_in) ;
    puts("</b><p>") ;
    if (nonempty(ntype_in) && !strcmp(ntype_in, "bonap_t")) {
      puts("Items whose names are defined as synonymous to ") ;
      puts("the name requested are included in this list.<p>") ;
    }

    if (printing_genera) puts("<ul>") ;
    if (printing_species) puts("<ul>") ;

    do {
      char auth_name[80], herb_abbr[5], acc_num[16] ;
      char coll_name[80] ;
      char spec_loc[4] ;
      int cultivated ;

      auth_name[0] = '\0' ;
      coll_name[0] = '\0' ;
      stored_tri[0] = stored_quad[0] = '\0' ;

      mg_setup_doc_line_producer(qd, mg_get_doc_num(qd), &dlp) ;
      while (mg_dlp_more_lines(dlp)) {
	mg_dlp_next_line(dlp, s) ;

	if (!strncmp(s, "qqfah", 5)) {
	  if (strcmp(s+6, stored_fam)) {
	    new_fam=1 ;
	    strcpy(stored_fam, s+6) ;
	  }
	  else new_fam = 0 ;
	}

	if (!strncmp(s, "qqgeh", 5)) {
	  if (strcmp(s+6, stored_gen)) {
	    new_gen=1 ;
	    strcpy(stored_gen, s+6) ;
	  }
	  else new_gen = 0 ;
	}

	if (!strncmp(s, "qqsph", 5)) {
	  if (strcmp(s+6, stored_spec)) {
	    new_spec=1 ;
	    strcpy(stored_spec, s+6) ;
	  }
	  else new_spec = 0 ;
	}

	if (!strncmp(s, "qqiah", 5)) 
	  strcpy(stored_tri, s+6) ;
	if (!strncmp(s, "qqibh", 5))
	  strcpy(stored_quad, s+6) ;

	if (printing_specimens) {
	  if (!strncmp(s, "qqaut", 5)) 
	    strcpy(auth_name, s+6) ;
	  else if (!strncmp(s, "qqhrb", 5)) 
	    strcpy(herb_abbr, s+5) ;
	  else if (!strncmp(s, "qqacc", 5)) {
	    strcpy(acc_num, s+5) ;
	    for (i=0 ; acc_num[i] != '\0' ; i++) acc_num[i] += '0'-'A' ;
	  }
	  else if (!strncmp(s, "qqcnm", 5)) 
	    strcpy(coll_name, s+6) ;
	  else if (!strncmp(s, "qqcul", 5)) 
	    cultivated = !strncmp(s+5, "yes", 3) ;
	  else if (!nonempty(loc_in) && !strncmp(s, "qqloc", 5))
	    strcpy(spec_loc, s+5) ;
	}

      }

      if (printing_specimens) {
	printf("%s %s ", herb_abbr, acc_num, auth_name) ;
	if (nonempty(auth_name)) printf(" %s", auth_name) ;
	else {
	  fputs(stored_spec, stdout) ;
	  if (nonempty(stored_tri))
	    printf(" %s", stored_tri) ;
	  if (nonempty(stored_quad))
	    printf(" %s", stored_quad) ;
	}

	printf(", collected by %s", coll_name) ;
	if (cultivated) printf(" from cultivated material") ;
	if (!nonempty(loc_in))
	  printf(", %s county ", 
		 map_convert_region_name("/bwg/FLORA/cgi/maps", "tx",
					 "ut_abbr", "cname", spec_loc)) ;
	puts("<br>") ;
      }
      else {
	if (new_fam) {
	  if (printing_specimens) puts("</ul>") ;
	  if (printing_species) puts("</ul>") ;
	  if (printing_genera) puts("</ul>") ;

	  printf("Family %s<br>", stored_fam) ;
	}
	if (printing_genera && new_gen) {
	  if (new_fam)
	    puts("<ul>") ;
	  else {
	    if (printing_specimens) puts("</ul>") ;
	    if (printing_species) puts("</ul>") ;
	  }
	  printf("Genus %s", stored_gen) ;
	  puts("<br>") ;
	}
	if (printing_species && new_spec) {
	  if (new_gen) printf("<ul>") ;
	  else {
	    if (printing_specimens) puts("</ul>") ;
	  }
	  printf("%s<br>", stored_spec) ;
	}
      }

    } while (mg_goto_next_doc(qd)) ;
    if (printing_specimens) puts("</ul>") ;
    if (printing_species) puts("</ul>") ;
    if (printing_genera) puts("</ul>") ;

    /* footer stuff */

    puts("<hr>") ;
    puts("This page was constructed by a program written by ") ;
    puts("<a href=\"mailto:[email protected]\">") ;
    puts("Erich Schneider</a> of the ") ;
    puts("<a href=\"http://www.csdl.tamu.edu\">") ;
    puts("Center for the Study of Digital Libraries</a> ") ;
    puts("working for the ") ;
    puts("<a href=\"http://www.csdl.tamu.edu/FLORA/tamuherb.htm\">") ;
    puts("Texas A&amp;M Bioinformatics Working Group</a>.") ;
  }
}