minor fix for directory protection warning.
[unix-history] / usr / src / usr.bin / rdist / lookup.c
#ifndef lint
static char *sccsid = "@(#)lookup.c 4.3 (Berkeley) 83/10/10";
#endif
#include "defs.h"
/*
* Define a variable from a command line argument.
*/
define(name)
char *name;
{
register char *cp, *s;
register struct block *bp, *value;
if (debug)
printf("define(%s)\n", name);
cp = index(name, '=');
if (cp == NULL)
value = NULL;
else if (cp[1] == '\0') {
*cp++ = '\0';
value = NULL;
} else if (cp[1] != '(') {
*cp++ = '\0';
value = makeblock(NAME, cp);
} else {
bp = NULL;
*cp++ = '\0';
do
cp++;
while (*cp == ' ' || *cp == '\t');
for (s = cp; ; s++) {
switch (*s) {
case ')':
*s = '\0';
case '\0':
break;
case ' ':
case '\t':
*s++ = '\0';
while (*s == ' ' || *s == '\t')
s++;
if (*s == ')')
*s = '\0';
break;
default:
continue;
}
if (bp == NULL)
value = bp = makeblock(NAME, cp);
else {
bp->b_next = makeblock(NAME, cp);
bp = bp->b_next;
}
if (*s == '\0')
break;
cp = s;
}
}
bp = makeblock(VAR, name);
bp->b_args = value;
(void) lookup(bp->b_name, bp, 1);
}
static struct block *hashtab[HASHSIZE];
/*
* Lookup name in the table and return a pointer to it.
* Insert == 0 - just do lookup, return NULL if not found.
* insert == 1 - insert name with value, error if already defined.
* insert == 2 - replace name with value if not entered with insert == 1.
*/
struct block *
lookup(name, value, insert)
char *name;
struct block *value;
int insert;
{
register unsigned n;
register char *cp;
register struct block *b, *f;
if (debug)
printf("lookup(%s, %x, %d)\n", name, value, insert);
n = 0;
for (cp = name; *cp; )
n += *cp++;
n %= HASHSIZE;
for (b = hashtab[n]; b != NULL; b = b->b_next) {
if (strcmp(name, b->b_name))
continue;
if (insert) {
if (b->b_type == NAME) {
warn("%s redefined\n", name);
f = b->b_args;
b->b_args = value->b_args;
value->b_args = f;
} else if (value->b_type == VAR)
fatal("%s redefined\n", name);
}
return(b);
}
if (!insert)
fatal("%s not defined", name);
value->b_next = hashtab[n];
hashtab[n] = value;
return(value);
}
/*
* Make a block for lists of variables, commands, etc.
*/
struct block *
makeblock(type, name)
int type;
register char *name;
{
register char *cp;
register struct block *bp;
bp = ALLOC(block);
if (bp == NULL)
fatal("ran out of memory\n");
bp->b_type = type;
bp->b_next = bp->b_args = NULL;
if (type == NAME || type == VAR) {
bp->b_name = cp = malloc(strlen(name) + 1);
if (cp == NULL)
fatal("ran out of memory\n");
while (*cp++ = *name++)
;
} else
bp->b_name = NULL;
return(bp);
}