possible buffer overflow; bug report 4.3BSD-tahoe/usr.sbin/3
[unix-history] / usr / src / usr.bin / rdist / lookup.c
... / ...
CommitLineData
1/*
2 * Copyright (c) 1983 Regents of the University of California.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms are permitted
6 * provided that the above copyright notice and this paragraph are
7 * duplicated in all such forms and that any documentation,
8 * advertising materials, and other materials related to such
9 * distribution and use acknowledge that the software was developed
10 * by the University of California, Berkeley. The name of the
11 * University may not be used to endorse or promote products derived
12 * from this software without specific prior written permission.
13 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
14 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
15 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
16 */
17
18#ifndef lint
19static char sccsid[] = "@(#)lookup.c 5.4 (Berkeley) %G%";
20#endif /* not lint */
21
22#include "defs.h"
23
24 /* symbol types */
25#define VAR 1
26#define CONST 2
27
28struct syment {
29 int s_type;
30 char *s_name;
31 struct namelist *s_value;
32 struct syment *s_next;
33};
34
35static struct syment *hashtab[HASHSIZE];
36
37/*
38 * Define a variable from a command line argument.
39 */
40define(name)
41 char *name;
42{
43 register char *cp, *s;
44 register struct namelist *nl;
45 struct namelist *value;
46
47 if (debug)
48 printf("define(%s)\n", name);
49
50 cp = index(name, '=');
51 if (cp == NULL)
52 value = NULL;
53 else if (cp[1] == '\0') {
54 *cp = '\0';
55 value = NULL;
56 } else if (cp[1] != '(') {
57 *cp++ = '\0';
58 value = makenl(cp);
59 } else {
60 nl = NULL;
61 *cp++ = '\0';
62 do
63 cp++;
64 while (*cp == ' ' || *cp == '\t');
65 for (s = cp; ; s++) {
66 switch (*s) {
67 case ')':
68 *s = '\0';
69 case '\0':
70 break;
71 case ' ':
72 case '\t':
73 *s++ = '\0';
74 while (*s == ' ' || *s == '\t')
75 s++;
76 if (*s == ')')
77 *s = '\0';
78 break;
79 default:
80 continue;
81 }
82 if (nl == NULL)
83 value = nl = makenl(cp);
84 else {
85 nl->n_next = makenl(cp);
86 nl = nl->n_next;
87 }
88 if (*s == '\0')
89 break;
90 cp = s;
91 }
92 }
93 (void) lookup(name, REPLACE, value);
94}
95
96/*
97 * Lookup name in the table and return a pointer to it.
98 * LOOKUP - just do lookup, return NULL if not found.
99 * INSERT - insert name with value, error if already defined.
100 * REPLACE - insert or replace name with value.
101 */
102
103struct namelist *
104lookup(name, action, value)
105 char *name;
106 int action;
107 struct namelist *value;
108{
109 register unsigned n;
110 register char *cp;
111 register struct syment *s;
112 char buf[256];
113
114 if (debug)
115 printf("lookup(%s, %d, %x)\n", name, action, value);
116
117 n = 0;
118 for (cp = name; *cp; )
119 n += *cp++;
120 n %= HASHSIZE;
121
122 for (s = hashtab[n]; s != NULL; s = s->s_next) {
123 if (strcmp(name, s->s_name))
124 continue;
125 if (action != LOOKUP) {
126 if (action != INSERT || s->s_type != CONST) {
127 (void)sprintf(buf, "%s redefined", name);
128 yyerror(buf);
129 }
130 }
131 return(s->s_value);
132 }
133
134 if (action == LOOKUP) {
135 (void)sprintf(buf, "%s undefined", name);
136 yyerror(buf);
137 return(NULL);
138 }
139
140 s = ALLOC(syment);
141 if (s == NULL)
142 fatal("ran out of memory\n");
143 s->s_next = hashtab[n];
144 hashtab[n] = s;
145 s->s_type = action == INSERT ? VAR : CONST;
146 s->s_name = name;
147 s->s_value = value;
148 return(value);
149}