int sba_jfs_journal_block(struct bio *sba_bio, sector_t sector)
{
	if (jour_dev) {
		if (sba_jfs_journal_request(sba_bio)) {
			int blk = SBA_SECTOR_TO_BLOCK(sector);

			if (ht_lookup(h_sba_jfs_journal, blk)) {
				return 1;
			}
			else {
				return 0;
			}
		}
		else {
			return 0;
		}
	}
	else {
		int blk = SBA_SECTOR_TO_BLOCK(sector);

		if (ht_lookup(h_sba_jfs_journal, blk)) {
			return 1;
		}
		else {
			return 0;
		}
	}
}
Beispiel #2
0
void
addpseudo(const char *name, int number, int disable)
{
	struct devbase *d;
	struct devi *i;

	d = ht_lookup(devbasetab, name);
	if (d == NULL) {
		error("undefined pseudo-device %s", name);
		return;
	}
	if (!d->d_ispseudo) {
		error("%s is a real device, not a pseudo-device", name);
		return;
	}
	if (ht_lookup(devitab, name) != NULL) {
		warnx("warning: duplicate definition of `%s', will use latest definition", name);
		d->d_umax = number;
		return;
	}
	i = newdevi(name, number - 1, d);	/* foo 16 => "foo0..foo15" */
	if (ht_insert(devitab, name, i))
		panic("addpseudo(%s)", name);
	i->i_disable = disable;
	selectbase(d, NULL);
	*nextpseudo = i;
	nextpseudo = &i->i_next;
	npseudo++;
}
Beispiel #3
0
Datei: test.c Projekt: ysl/util
int main (void)
{
  int key, val, retrive;

  ht_init(10);

  /*
   * Insert a new key
   */
  key = 8;
  val = 1;
  ht_insert(key, val);

  /*
   * Lookup
   */
  retrive = 0;
  ht_lookup(key, &retrive);
  printf("lookup for key[%d] val=[%d]\n", key, retrive);

  /*
   * Insert another key, this key will be dispatched to the same bucket.
   */
  key = 18;
  val = 2;
  ht_insert(key, val);

  /*
   * Lookup
   */
  retrive = 0;
  ht_lookup(key, &retrive);
  printf("lookup for key[%d] val=[%d]\n", key, retrive);
  ht_lookup(8, &retrive);
  printf("lookup for key[%d] val=[%d]\n", 8, retrive);

  /*
   * Insert with the same key
   */
  key = 18;
  val = 3;
  ht_insert(key, val);

  /*
   * Lookup
   */
  retrive = 0;
  ht_lookup(key, &retrive);
  printf("lookup for key[%d] val=[%d]\n", key, retrive);

  /*
   * Free object
   */
  ht_cleanup();
}
Beispiel #4
0
int eval_def_fn(const char *name, FunctionPtr fn, void *data, int args)
{
	VarFn *f;
	
	if(G_varfn_table == NULL)
	{ /* allocate new fn table */
		G_varfn_table = ht_create(500, vhash, vcomp, NULL, vdel);
		if(G_varfn_table == NULL)
			return 1; /* failed to create table */
	}
	if(ht_lookup(G_varfn_table, name, (void*)(&f)))
	{
		f = create_fn(name, fn, args, data);
		if(f == NULL)
			return 2; /* failed to create new entry */
		if(ht_insert(G_varfn_table, (void*)(f->name), (void*)f))
			return 3; /* insert failed */
	}else if(f->fn == NULL)
		return 4; /* this is a variable, NOT a function */
	else
	{
		f->fn = fn;
		f->data = data;
		f->nargs = args;
	}
	
	return 0;
}
Beispiel #5
0
void
ht_add(struct ht *ht, struct ht_entry_header **bucket, unsigned hash, struct ht_entry_header *entry)
{
    unsigned nbuckets = NBUCKETS(ht);

    if (ht->nentries > MAX_LOAD(nbuckets)) {
        /* Overloaded. Grow the table. */
        struct ht_entry_header **oldbuckets = ht->buckets;
        int newnbuckets = 2 * nbuckets;
        int i;

        ht->shift--;
        ht->buckets = malloc(newnbuckets * sizeof(struct ht_entry_header *));
        ASSERT(ht->buckets != 0, ("out of memory"));

        /* Zero the new table. */
        for (i = newnbuckets - 1; i >= 0; --i)
            ht->buckets[i] = 0;

        /* Re-hash old values. */
        rehash(ht, oldbuckets, nbuckets);
        free(oldbuckets);

        /* Make sure `bucket' is sane. */
        bucket = ht_lookup(ht, hash, HT_ENTRY_DATA(entry));
    }

    /* Link the entry into the hashtable. */
    entry->next = *bucket;
    entry->hash = hash;
    *bucket = entry;

    ++ht->nentries;
}
Beispiel #6
0
void handle_usb_unplugged(char* device){
	must_exit = 1;
	pid_t pid = fork();

	if (pid ==0){ /*child process*/			
		execl("/bin/umount", "umount", "-l", device, (char *)0);
	}else{
		waitpid(pid,0,0);
		
		MacRec *head = (MacRec *) ht_lookup(macaddrs, device);
		char* signal =  (char*) malloc(32);
		
		if (head != NULL){
			
			sprintf(signal, head->addr, 0, 17);
			strcat(signal, " deny");
			sendsignal(signal);
			MacRec *current = head;
			
			while ( (current = current->next) != NULL){
			    printf("deny --> %s\n", current->addr);
				sprintf(signal, current->addr, 0, 17);
				strcat(signal, " deny");
				sendsignal(signal);
			}
			ht_remove(macaddrs, device);
			free_macrec(head);
			free(signal);
		}
	}
}
Beispiel #7
0
static int
emitdefs(FILE *fp)
{
	struct nvlist *nv;
	char *sp;

	if (fputs("IDENT=", fp) < 0)
		return (1);
	sp = "";
	for (nv = options; nv != NULL; nv = nv->nv_next) {
		if (ht_lookup(defopttab, nv->nv_name) != NULL)
			continue;
		if (fprintf(fp, "%s-D%s", sp, nv->nv_name) < 0)
		    return 1;
		if (nv->nv_str)
		    if (fprintf(fp, "=\"%s\"", nv->nv_str) < 0)
			return 1;
		sp = " ";
	}
	if (putc('\n', fp) < 0)
		return (1);
	if (fprintf(fp, "PARAM=-DMAXUSERS=%d\n", maxusers) < 0)
		return (1);
	if (fprintf(fp, "S=\t%s\n", srcdir) < 0)
		return (1);
	if (fprintf(fp, "_mach=%s\n", machine) < 0)
		return (1);
	if (fprintf(fp, "_arch=%s\n", machinearch ? machinearch : machine) < 0)
		return (1);
	for (nv = mkoptions; nv != NULL; nv = nv->nv_next)
		if (fprintf(fp, "%s=%s\n", nv->nv_name, nv->nv_str) < 0)
			return (1);
	return (0);
}
Beispiel #8
0
/**
 * Sets the one-character shortname of the given option
 *
 * options      - The options dictionary which contains the option
 * name         - The (full) name of the option
 * shortname    - The one-character short name of the option
 *
 * NOTES:
 *  - It is not necessary to call this function unless you wish to override the default short name, which
 *    is the first letter of the long name
 *  - If an existing short name exists (including the default), it will be removed and replaced
 *  - If an identical short name exists, it will be replaced with this one, even if it is for a different
 *    option
 */
void _set_shortname(hashtable* options, const char* name, char shortname)    {
    _option* option;
    _option_wrapper* wrapper, *query_wrapper;
    char* str_shortname;
    
    if (!options) {
        return;
    }
    
    option = _query(options, name);
    if (!option)    {
        return;
    }
    
    xp_asprintf(&str_shortname, "%c", shortname);
    
    wrapper = (_option_wrapper*)malloc(sizeof(_option_wrapper));
    wrapper->key = str_shortname;
    wrapper->alias = 1;             /* We don't own the option */
    query_wrapper = wrapper;
    if (ht_lookup(options, (void*)&wrapper) != 0)    {
        /* It's not in there, just add it */
        wrapper->key = xp_strdup(str_shortname);
        ht_insert(options, (void*)wrapper);
    } else {
        /* Already in there */
        free(query_wrapper->key);
        free(query_wrapper);
    }
    
    wrapper->o = option;
}
Beispiel #9
0
void
addobject(const char *path, struct nvlist *optx, int flags)
{
	struct objects *oi;

	/*
	 * Commit this object to memory.  We will decide later whether it
	 * will be used after all.
	 */
	oi = emalloc(sizeof *oi);
	if (ht_insert(pathtab, path, oi)) {
		free(oi);
		if ((oi = ht_lookup(pathtab, path)) == NULL)
			panic("addfile: ht_lookup(%s)", path);
		error("duplicate file %s", path);
		xerror(oi->oi_srcfile, oi->oi_srcline,
		    "here is the original definition");
	}
	oi->oi_next = NULL;
	oi->oi_srcfile = yyfile;
	oi->oi_srcline = currentline();
	oi->oi_flags = flags;
	oi->oi_path = path;
	oi->oi_optx = optx;
	oi->oi_optf = NULL;
	*nextobject = oi;
	nextobject = &oi->oi_next;
}
Beispiel #10
0
/*
 * Remove an option.
 */
void
removeoption(const char *name)
{
	struct nvlist *nv, *nvt;
	char *p, *low, c;
	const char *n;

	if ((nv = ht_lookup(opttab, name)) != NULL) {
		if (options == nv) {
			options = nv->nv_next;
			nvfree(nv);
		} else {
			nvt = options;
			while (nvt->nv_next != NULL) {
				if (nvt->nv_next == nv) {
					nvt->nv_next = nvt->nv_next->nv_next;
					nvfree(nv);
					break;
				} else
					nvt = nvt->nv_next;
			}
		}
	}

	(void)ht_remove(opttab, name);

	low = emalloc(strlen(name) + 1);
	/* make lowercase, then remove from select table */
	for (n = name, p = low; (c = *n) != '\0'; n++)
		*p++ = isupper(c) ? tolower(c) : c;
	*p = 0;
	n = intern(low);
	free(low);
	(void)ht_remove(selecttab, n);
}
Beispiel #11
0
/*
 * Check to see if there is a *'d unit with a needs-count file.
 */
int
badstar(void)
{
	struct devbase *d;
	struct deva *da;
	struct devi *i;
	int errs, n;

	errs = 0;
	for (d = allbases; d != NULL; d = d->d_next) {
		for (da = d->d_ahead; da != NULL; da = da->d_bsame)
			for (i = da->d_ihead; i != NULL; i = i->i_asame) {
				if (i->i_unit == STAR)
					goto foundstar;
			}
		continue;
	foundstar:
		if (ht_lookup(needcnttab, d->d_name)) {
			(void)fprintf(stderr,
		    "config: %s's cannot be *'d until its driver is fixed\n",
			    d->d_name);
			errs++;
			continue;
		}
		for (n = 0; i != NULL; i = i->i_alias)
			if (!i->i_collapsed)
				n++;
		if (n < 1)
			panic("badstar() n<1");
	}
	return (errs);
}
Beispiel #12
0
/* This is similar to rbm_fopen */
int rbm_register(STRBUF *sb, const char *filename, int force)
{
    // Rprintf("rbm_register: registering file: %s\n", filename);

    if (ht_lookup(strbufv, filename) != NULL) {
        if (force) {
            Rprintf("rbm_register: warning: file already registered: %s\n",
                    filename);
        } else {
            Rprintf("rbm_register: error: file already registered: %s\n",
                    filename);
            return -1;
        }
    }

    /* XXX Should I provide an "isopen" function for STRBUF? */
    if (sb->open) {
        Rprintf("rbm_register: error: cannot register an open file: %s\n",
                filename);
        return -1;
    }

    ht_setvoid(strbufv, filename, sb);

    return 0;
}
Beispiel #13
0
/*
 * NAME:	conn->udp()
 * DESCRIPTION:	set the challenge for attaching a UDP channel
 */
bool conn_udp(connection *conn, char *challenge, unsigned int len)
{
    char buffer[UDPHASHSZ];
    connection **hash;

    if (len == 0 || len > BINBUF_SIZE || conn->udpbuf != (char *) NULL) {
	return FALSE;	/* invalid challenge */
    }

    if (len >= UDPHASHSZ) {
	memcpy(buffer, challenge, UDPHASHSZ);
    } else {
	memset(buffer, '\0', UDPHASHSZ);
	memcpy(buffer, challenge, len);
    }
    hash = (connection **) ht_lookup(chtab, buffer, FALSE);
    while (*hash != (connection *) NULL &&
	   memcmp((*hash)->chain.name, buffer, UDPHASHSZ) == 0) {
	if ((*hash)->bufsz == len &&
	    memcmp((*hash)->udpbuf, challenge, len) == 0) {
	    return FALSE;	/* duplicate challenge */
	}
    }

    conn->chain.next = (hte *) *hash;
    *hash = conn;
    conn->npkts = 0;
    m_static();
    conn->udpbuf = ALLOC(char, BINBUF_SIZE);
    m_dynamic();
    memset(conn->udpbuf, '\0', UDPHASHSZ);
    memcpy(conn->chain.name = conn->udpbuf, challenge, conn->bufsz = len);

    return TRUE;
}
Beispiel #14
0
/* public: variable access (set) function */
int eval_set_var(const char *name, double value)
{
	VarFn *var;
	
	if(G_varfn_table == NULL)
	{ /* allocate the var table */
		G_varfn_table = ht_create(500, vhash, vcomp, NULL, vdel);
		if(G_varfn_table == NULL)
			return 1;
	}
	/* find named var, update value or insert var/value */
	if(ht_lookup(G_varfn_table, name, (void*)&var))
	{ /* not found, insert new variable */
		var = create_var(name, value);
		if(var == NULL)
			return 2;
		if(ht_insert(G_varfn_table, (void*)(var->name), (void*)var))
			return 3;
		G_var_count++;
	}else if(var->fn != NULL)
		return 4;
	else
		var->value = value;
	
	return 0;
}
int sba_jfs_journaled_block(int blocknr)
{
	if (ht_lookup(h_jfs_journaled_blocks, blocknr)) {
		return 1;
	}

	return 0;
}
Beispiel #16
0
struct djs_elt *
djs_find_or_insert(struct disjoint_sets *djs, void *v) {
  struct djs_elt *de = (struct djs_elt *)ht_lookup(djs->ht, v);
  if(de == NULL) {
    de=djs_insert(djs,v);
  }
  return(de);
}
Beispiel #17
0
/*
 * Enable an already declared but disabled device.
 */
void
enabledev(const char *name, const char *at)
{
	struct devbase *ib, *ab;
	char atbuf[NAMESIZE];
	struct attr *attr;
	struct nvlist *nv;
	struct devi *i;
	const char *cp;
	int atunit;

	i = ht_lookup(devitab, name);
	if (i == NULL) {
		error("invalid device `%s'", name);
		return;
	}
	ib = i->i_base;

	if (split(at, strlen(at), atbuf, sizeof atbuf, &atunit)) {
		error("invalid attachment name `%s'", at);
		return;
	}
	cp = intern(atbuf);
	ab = ht_lookup(devbasetab, cp);
	if (ab == NULL) {
		error("invalid attachment device `%s'", cp);
		return;
	}
	for (nv = ab->d_attrs; nv != NULL; nv = nv->nv_next) {
		attr = nv->nv_ptr;
		if (onlist(attr->a_devs, ib))
			goto foundattachment;
	}
	error("%s's cannot attach to %s's", ib->d_name, atbuf);
	return;

foundattachment:
	while (i && i->i_atdev != ab)
		i = i->i_alias;
	if (i == NULL) {
		error("%s at %s not found", name, at);
		return;
	} else
		i->i_disable = 0; /* Enable */
}
Beispiel #18
0
/* Determine whether the str STR, of length LEN, is a defined macro.  */
int
cpp_defined (cpp_reader *pfile, const unsigned char *str, int len)
{
  cpp_hashnode *node;

  node = CPP_HASHNODE (ht_lookup (pfile->hash_table, str, len, HT_NO_INSERT));

  /* If it's of type NT_MACRO, it cannot be poisoned.  */
  return node && node->type == NT_MACRO;
}
Beispiel #19
0
static int get_value(config_t config, char *name, void **data)
{
	hashtable *ht;
	int rc;

	ht = (hashtable *)config;
	rc = ht_lookup(ht, name, data);

	return rc;
}
int sba_jfs_insert_journaled_blocks(int blocknr)
{
	if (ht_lookup(h_jfs_journaled_blocks, blocknr)) {
		sba_debug(0, "Block %d is being journaled again\n", blocknr);
		return 1;
	}

	ht_add_val(h_jfs_journaled_blocks, blocknr, 0);
	return 1;
}
Beispiel #21
0
var_t *
vtable_lookup(var_t *table, char *name)
{
	var_t lookup;
	ht_t *ht = table->v_data;

	lookup.v_name = name;

	return ht_lookup(ht, &lookup);
}
Beispiel #22
0
/*
 * We have finished reading everything.  Tack the files down: calculate
 * selection and counts as needed.  Check that the object files built
 * from the selected sources do not collide.
 */
int
fixfiles(void)
{
	struct files *fi, *ofi;
	struct nvlist *flathead, **flatp;
	int err, sel;

	err = 0;
	for (fi = allfiles; fi != NULL; fi = fi->fi_next) {
		/* Skip files that generated counted-device complaints. */
		if (fi->fi_flags & FI_HIDDEN)
			continue;

		/* Optional: see if it is to be included. */
		if (fi->fi_optx != NULL) {
			flathead = NULL;
			flatp = &flathead;
			sel = expr_eval(fi->fi_optx,
			    fi->fi_flags & FI_NEEDSCOUNT ? fixcount :
			    fi->fi_flags & FI_NEEDSFLAG ? fixfsel :
			    fixsel,
			    &flatp);
			fi->fi_optf = flathead;
			if (!sel)
				continue;
		}

		/* We like this file.  Make sure it generates a unique .o. */
		if (ht_insert(basetab, fi->fi_base, fi)) {
			if ((ofi = ht_lookup(basetab, fi->fi_base)) == NULL)
				panic("fixfiles ht_lookup(%s)", fi->fi_base);
			/*
			 * If the new file comes from a different source,
			 * allow the new one to override the old one.
			 */
			if (fi->fi_nvpath != ofi->fi_nvpath) {
				if (ht_replace(basetab, fi->fi_base, fi) != 1)
					panic("fixfiles ht_replace(%s)",
					    fi->fi_base);
				ofi->fi_flags &= ~FI_SEL;
				ofi->fi_flags |= FI_HIDDEN;
			} else {
				xerror(fi->fi_srcfile, fi->fi_srcline,
				    "object file collision on %s.o, from %s",
				    fi->fi_base, fi->fi_nvpath->nv_name);
				xerror(ofi->fi_srcfile, ofi->fi_srcline,
				    "here is the previous file: %s",
				    ofi->fi_nvpath->nv_name);
				err = 1;
			}
		}
		fi->fi_flags |= FI_SEL;
	}
	return (err);
}
Beispiel #23
0
/*
 * Look up an attribute.
 */
struct attr *
getattr(const char *name)
{
	struct attr *a;

	if ((a = ht_lookup(attrtab, name)) == NULL) {
		error("undefined attribute `%s'", name);
		a = &errattr;
	}
	return (a);
}
Beispiel #24
0
/*@dependent@*/ 
void *ht_lookup_nofail(hashtable ht, 
                             const void *key,
                             ht_constructor_cb constructor) {
  void *ret = ht_lookup(ht, key);
  if(ret == NULL) {
    ret = constructor(key);
    if(ret != NULL) {
      ht_insert(ht,ret);
    }
  }
  return(ret);
}
Beispiel #25
0
/*
 * Called from fixfiles when eval'ing a selection expression for a
 * file that will generate a .h with flags.  We will need the flat list.
 */
static int
fixfsel(const char *name, void *context)
{
	struct nvlist ***p = context;
	struct nvlist *nv;
	int sel;

	sel = ht_lookup(selecttab, name) != NULL;
	nv = newnv(name, NULL, NULL, sel, NULL);
	**p = nv;
	*p = &nv->nv_next;
	return (sel);
}
Beispiel #26
0
/*
 * Define a new instance of a specific device.
 */
static struct devi *
getdevi(const char *name)
{
	struct devi *i, *firsti;
	struct devbase *d;
	int unit;
	char base[NAMESIZE];

	if (split(name, strlen(name), base, sizeof base, &unit)) {
		error("invalid device name `%s'", name);
		return (NULL);
	}
	d = ht_lookup(devbasetab, intern(base));
	if (d == NULL) {
		error("%s: unknown device `%s'", name, base);
		return (NULL);
	}
	if (d->d_ispseudo) {
		error("%s: %s is a pseudo-device", name, base);
		return (NULL);
	}
	firsti = ht_lookup(devitab, name);
	i = newdevi(name, unit, d);
	if (firsti == NULL) {
		if (ht_insert(devitab, name, i))
			panic("getdevi(%s)", name);
		*d->d_ipp = i;
		d->d_ipp = &i->i_bsame;
	} else {
		while (firsti->i_alias)
			firsti = firsti->i_alias;
		firsti->i_alias = i;
	}
	*nextdevi = i;
	nextdevi = &i->i_next;
	ndevi++;
	return (i);
}
Beispiel #27
0
int d_lookup(const char * word, char * meaning) {
  //meaning = meaning associated with a successful lookup (look at ht_lookup)
  int bucket = hash(word);
  any a;
  
  if (a = ht_lookup(d.dict,word)) {//(clist_isempty(d.dict->items[bucket]))
    meaning = ((struct entry*)a)->desc;
    return 1;
  }    
  else {
    return 0;
  }
    
}
static int agentd_collect_interface_aliases(
                            const bn_binding_array *bindings,
                            uint32 idx,
                            const bn_binding *binding,
                            const tstring *name,
                            const tstr_array *name_components,
                            const tstring *name_last_part,
                            const tstring *value,
                            void *callback_data)
{
    int err = 0;
    ht_table *aliases = callback_data;
    tstring *ifdevname = NULL;
    void *alist_v = NULL;
    tstring *alist = NULL;
    tbool found = false;

    err = bn_binding_array_get_value_tstr_by_name_rel
        (bindings, ts_str(name), "alias/ifdevname", NULL, &ifdevname);
    bail_error_null(err, ifdevname);

    /*
     * name_last_part contains the name of the alias interface.
     * ifdevname contains the name of the original interface that was aliased.
     * Our hash table maps the latter to a list of the former.
     */

    if (ts_num_chars(ifdevname) > 0)
    {
        err = ht_lookup(aliases, ifdevname, ts_length(ifdevname), &found,
                        NULL, NULL, &alist_v);
        bail_error(err);
        if (found)
        {
            alist = alist_v;
            err = ts_append_sprintf(alist, ",%s", ts_str(name_last_part));
            bail_error(err);
        }
        else
        {
            err = ht_insert(aliases, ifdevname, ts_length(ifdevname),
                            (void *)name_last_part);
            bail_error(err);
        }
    }

 bail:
    ts_free(&ifdevname);
    return(err);
}
Beispiel #29
0
/*
 * Auxiliary function for checkfiles, called from expr_eval.
 * We are not actually interested in the expression's value.
 */
static int
checkaux(const char *name, void *context)
{
	struct files *fi = context;

	if (ht_lookup(devbasetab, name) == NULL) {
		xerror(fi->fi_srcfile, fi->fi_srcline,
		    "`%s' is not a countable device",
		    name);
		/* keep fixfiles() from complaining again */
		fi->fi_flags |= FI_HIDDEN;
	}
	return (0);
}
Beispiel #30
0
/* Find the longest match. */
static int interp(uint8 *msg, unsigned nbytes, Atom p, int pid) {
	uint8 *m;
	union ir *ir;
	struct eq *eq;
	struct shift *s;
	int res;
	uint32 v;

	/* try all or branchs */
	for(; p; p = p->or) {
		ir = &p->ir;
		eq = &ir->eq;

		/* is there an overflow? */
		if(eq->offset >= nbytes)
			continue;

		m = &msg[eq->offset];

		demand(eq->nbits % 8 == 0, bogus bit count!);
		v = 0;
		memcpy(&v, m, eq->nbits / 8);	/* will this always work? */

		if(dpf_iseq(eq->op)) {
 			v = v & eq->mask;

			if(p->ht) {
				Atom hte;

				if((hte = ht_lookup(p->ht, v))) {
					res = interp(msg, nbytes, hte->child, hte->pid);
					if(res)
						return res;
				}
			} else if(v == eq->val) {
				res = interp(msg, nbytes, p->child, p->pid);
				if(res)
					return res;
			}
		} else {
			s = &ir->shift;
			demand(dpf_isshift(s->op), bogus op);
			v = (v & s->mask) << s->shift;
			if (v < nbytes)
				if((res = interp(msg+v, nbytes-v, p->child, p->pid)))
					return res;
		}
	}
	return pid;	/* longest match */
}