1*893695ceSjsg /* $OpenBSD: stringlist.c,v 1.4 2023/01/04 13:00:11 jsg Exp $ */
2bf89e9b1Sderaadt
3bf89e9b1Sderaadt /*
4bf89e9b1Sderaadt * Copyright (c) 1994 Christos Zoulas
5bf89e9b1Sderaadt * All rights reserved.
6bf89e9b1Sderaadt *
7bf89e9b1Sderaadt * Redistribution and use in source and binary forms, with or without
8bf89e9b1Sderaadt * modification, are permitted provided that the following conditions
9bf89e9b1Sderaadt * are met:
10bf89e9b1Sderaadt * 1. Redistributions of source code must retain the above copyright
11bf89e9b1Sderaadt * notice, this list of conditions and the following disclaimer.
12bf89e9b1Sderaadt * 2. Redistributions in binary form must reproduce the above copyright
13bf89e9b1Sderaadt * notice, this list of conditions and the following disclaimer in the
14bf89e9b1Sderaadt * documentation and/or other materials provided with the distribution.
15bf89e9b1Sderaadt *
16bf89e9b1Sderaadt * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
17bf89e9b1Sderaadt * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18bf89e9b1Sderaadt * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19bf89e9b1Sderaadt * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
20bf89e9b1Sderaadt * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21bf89e9b1Sderaadt * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22bf89e9b1Sderaadt * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23bf89e9b1Sderaadt * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24bf89e9b1Sderaadt * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25bf89e9b1Sderaadt * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26bf89e9b1Sderaadt * SUCH DAMAGE.
27bf89e9b1Sderaadt */
28bf89e9b1Sderaadt
29bf89e9b1Sderaadt #include <sys/types.h>
30bf89e9b1Sderaadt #include <stdio.h>
31bf89e9b1Sderaadt #include <netgroup.h>
32bf89e9b1Sderaadt #include <string.h>
33bf89e9b1Sderaadt #include <stdlib.h>
346d347d62Sjsg #include <ctype.h>
35bf89e9b1Sderaadt #include "stringlist.h"
36bf89e9b1Sderaadt
37bf89e9b1Sderaadt static const char _ngstar[] = "*";
38bf89e9b1Sderaadt
39bf89e9b1Sderaadt static int getstring(char **, int, char **);
40bf89e9b1Sderaadt static struct netgroup *getnetgroup(char **);
41bf89e9b1Sderaadt
42bf89e9b1Sderaadt /*
43bf89e9b1Sderaadt * _ng_sl_init(): Initialize a string list
44bf89e9b1Sderaadt */
45bf89e9b1Sderaadt struct stringlist *
_ng_sl_init(void)46bf89e9b1Sderaadt _ng_sl_init(void)
47bf89e9b1Sderaadt {
48bf89e9b1Sderaadt struct stringlist *sl = malloc(sizeof(struct stringlist));
49bf89e9b1Sderaadt if (sl == NULL)
50bf89e9b1Sderaadt return NULL;
51bf89e9b1Sderaadt
52bf89e9b1Sderaadt sl->sl_cur = 0;
53bf89e9b1Sderaadt sl->sl_max = 20;
54bf89e9b1Sderaadt sl->sl_str = calloc(sl->sl_max, sizeof(char *));
55bf89e9b1Sderaadt if (sl->sl_str == NULL) {
56bf89e9b1Sderaadt free(sl);
57bf89e9b1Sderaadt return NULL;
58bf89e9b1Sderaadt }
59bf89e9b1Sderaadt return sl;
60bf89e9b1Sderaadt }
61bf89e9b1Sderaadt
62bf89e9b1Sderaadt
63bf89e9b1Sderaadt /*
64bf89e9b1Sderaadt * _ng_sl_add(): Add an item to the string list
65bf89e9b1Sderaadt */
66bf89e9b1Sderaadt int
_ng_sl_add(struct stringlist * sl,char * name)67bf89e9b1Sderaadt _ng_sl_add(struct stringlist *sl, char *name)
68bf89e9b1Sderaadt {
69bf89e9b1Sderaadt if (sl->sl_cur == sl->sl_max - 1) {
70bf89e9b1Sderaadt char **slstr;
71bf89e9b1Sderaadt
72bf89e9b1Sderaadt sl->sl_max += 20;
73bf89e9b1Sderaadt slstr = reallocarray(sl->sl_str, sl->sl_max, sizeof(char *));
74bf89e9b1Sderaadt if (slstr == NULL) {
75bf89e9b1Sderaadt free(sl->sl_str);
76bf89e9b1Sderaadt sl->sl_str = NULL;
77bf89e9b1Sderaadt return -1;
78bf89e9b1Sderaadt }
79bf89e9b1Sderaadt sl->sl_str = slstr;
80bf89e9b1Sderaadt }
81bf89e9b1Sderaadt sl->sl_str[sl->sl_cur++] = name;
82bf89e9b1Sderaadt return 0;
83bf89e9b1Sderaadt }
84bf89e9b1Sderaadt
85bf89e9b1Sderaadt
86bf89e9b1Sderaadt /*
87bf89e9b1Sderaadt * _ng_sl_free(): Free a stringlist
88bf89e9b1Sderaadt */
89bf89e9b1Sderaadt void
_ng_sl_free(struct stringlist * sl,int all)90bf89e9b1Sderaadt _ng_sl_free(struct stringlist *sl, int all)
91bf89e9b1Sderaadt {
92bf89e9b1Sderaadt size_t i;
93bf89e9b1Sderaadt
94bf89e9b1Sderaadt if (all)
95bf89e9b1Sderaadt for (i = 0; i < sl->sl_cur; i++)
96bf89e9b1Sderaadt free(sl->sl_str[i]);
97bf89e9b1Sderaadt free(sl->sl_str);
98bf89e9b1Sderaadt free(sl);
99bf89e9b1Sderaadt }
100bf89e9b1Sderaadt
101bf89e9b1Sderaadt
102bf89e9b1Sderaadt /*
103bf89e9b1Sderaadt * sl_find(): Find a name in the string list
104bf89e9b1Sderaadt */
105bf89e9b1Sderaadt char *
_ng_sl_find(struct stringlist * sl,char * name)106bf89e9b1Sderaadt _ng_sl_find(struct stringlist *sl, char *name)
107bf89e9b1Sderaadt {
108bf89e9b1Sderaadt size_t i;
109bf89e9b1Sderaadt
110bf89e9b1Sderaadt for (i = 0; i < sl->sl_cur; i++)
111bf89e9b1Sderaadt if (strcmp(sl->sl_str[i], name) == 0)
112bf89e9b1Sderaadt return sl->sl_str[i];
113bf89e9b1Sderaadt
114bf89e9b1Sderaadt return NULL;
115bf89e9b1Sderaadt }
116bf89e9b1Sderaadt
117bf89e9b1Sderaadt /*
118bf89e9b1Sderaadt * _ng_parse(): Parse a line and return: _NG_ERROR: Syntax Error _NG_NONE:
119bf89e9b1Sderaadt * line was empty or a comment _NG_GROUP: line had a netgroup definition,
120bf89e9b1Sderaadt * returned in ng _NG_NAME: line had a netgroup name, returned in name
121bf89e9b1Sderaadt *
122bf89e9b1Sderaadt * Public since used by netgroup_mkdb
123bf89e9b1Sderaadt */
124bf89e9b1Sderaadt int
_ng_parse(char ** p,char ** name,struct netgroup ** ng)125bf89e9b1Sderaadt _ng_parse(char **p, char **name, struct netgroup **ng)
126bf89e9b1Sderaadt {
127bf89e9b1Sderaadt while (**p) {
128bf89e9b1Sderaadt if (**p == '#')
129bf89e9b1Sderaadt /* comment */
130bf89e9b1Sderaadt return _NG_NONE;
131bf89e9b1Sderaadt
132bf89e9b1Sderaadt while (**p && _NG_ISSPACE(**p))
133bf89e9b1Sderaadt /* skipblank */
134bf89e9b1Sderaadt (*p)++;
135bf89e9b1Sderaadt
136bf89e9b1Sderaadt if (**p == '(') {
137bf89e9b1Sderaadt if ((*ng = getnetgroup(p)) == NULL)
138bf89e9b1Sderaadt return _NG_ERROR;
139bf89e9b1Sderaadt return _NG_GROUP;
140bf89e9b1Sderaadt } else {
141bf89e9b1Sderaadt char *np;
142bf89e9b1Sderaadt int i;
143bf89e9b1Sderaadt
144bf89e9b1Sderaadt for (np = *p; **p && !_NG_ISSPACE(**p); (*p)++)
145bf89e9b1Sderaadt continue;
146bf89e9b1Sderaadt if (np != *p) {
147bf89e9b1Sderaadt i = (*p - np) + 1;
148bf89e9b1Sderaadt *name = malloc(i);
149bf89e9b1Sderaadt if (*name == NULL)
150bf89e9b1Sderaadt return _NG_ERROR;
151bf89e9b1Sderaadt memcpy(*name, np, i);
152bf89e9b1Sderaadt (*name)[i - 1] = '\0';
153bf89e9b1Sderaadt return _NG_NAME;
154bf89e9b1Sderaadt }
155bf89e9b1Sderaadt }
156bf89e9b1Sderaadt }
157bf89e9b1Sderaadt return _NG_NONE;
158bf89e9b1Sderaadt }
159bf89e9b1Sderaadt
160bf89e9b1Sderaadt /*
161bf89e9b1Sderaadt * _ng_makekey(): Make a key from the two names given. The key is of the form
162bf89e9b1Sderaadt * <name1>.<name2> Names strings are replaced with * if they are empty;
163bf89e9b1Sderaadt */
164bf89e9b1Sderaadt char *
_ng_makekey(const char * s1,const char * s2,size_t len)165bf89e9b1Sderaadt _ng_makekey(const char *s1, const char *s2, size_t len)
166bf89e9b1Sderaadt {
167bf89e9b1Sderaadt char *buf = malloc(len);
168bf89e9b1Sderaadt int ret;
169bf89e9b1Sderaadt
170bf89e9b1Sderaadt if (buf == NULL)
171bf89e9b1Sderaadt return NULL;
172bf89e9b1Sderaadt ret = snprintf(buf, len, "%s.%s", _NG_STAR(s1), _NG_STAR(s2));
173bf89e9b1Sderaadt if (ret < 0 || ret >= len) {
174bf89e9b1Sderaadt free(buf);
175bf89e9b1Sderaadt return NULL;
176bf89e9b1Sderaadt }
177bf89e9b1Sderaadt
178bf89e9b1Sderaadt return buf;
179bf89e9b1Sderaadt }
180bf89e9b1Sderaadt
181bf89e9b1Sderaadt void
_ng_print(char * buf,size_t len,const struct netgroup * ng)182bf89e9b1Sderaadt _ng_print(char *buf, size_t len, const struct netgroup *ng)
183bf89e9b1Sderaadt {
184bf89e9b1Sderaadt (void) snprintf(buf, len, "(%s,%s,%s)", _NG_EMPTY(ng->ng_host),
185bf89e9b1Sderaadt _NG_EMPTY(ng->ng_user), _NG_EMPTY(ng->ng_domain));
186bf89e9b1Sderaadt }
187bf89e9b1Sderaadt
188bf89e9b1Sderaadt /*
189bf89e9b1Sderaadt * getnetgroup(): Parse a netgroup, and advance the pointer
190bf89e9b1Sderaadt */
191bf89e9b1Sderaadt static struct netgroup *
getnetgroup(char ** pp)192bf89e9b1Sderaadt getnetgroup(char **pp)
193bf89e9b1Sderaadt {
194bf89e9b1Sderaadt struct netgroup *ng = malloc(sizeof(struct netgroup));
195bf89e9b1Sderaadt
196bf89e9b1Sderaadt if (ng == NULL)
197bf89e9b1Sderaadt return NULL;
198bf89e9b1Sderaadt
199bf89e9b1Sderaadt (*pp)++; /* skip '(' */
200bf89e9b1Sderaadt if (!getstring(pp, ',', &ng->ng_host))
201bf89e9b1Sderaadt goto badhost;
202bf89e9b1Sderaadt
203bf89e9b1Sderaadt if (!getstring(pp, ',', &ng->ng_user))
204bf89e9b1Sderaadt goto baduser;
205bf89e9b1Sderaadt
206bf89e9b1Sderaadt if (!getstring(pp, ')', &ng->ng_domain))
207bf89e9b1Sderaadt goto baddomain;
208bf89e9b1Sderaadt
209bf89e9b1Sderaadt #ifdef DEBUG_NG
210bf89e9b1Sderaadt {
211bf89e9b1Sderaadt char buf[1024];
212bf89e9b1Sderaadt _ng_print(buf, sizeof(buf), ng);
213bf89e9b1Sderaadt fprintf(stderr, "netgroup %s\n", buf);
214bf89e9b1Sderaadt }
215bf89e9b1Sderaadt #endif
216bf89e9b1Sderaadt return ng;
217bf89e9b1Sderaadt
218bf89e9b1Sderaadt baddomain:
219bf89e9b1Sderaadt free(ng->ng_user);
220bf89e9b1Sderaadt baduser:
221bf89e9b1Sderaadt free(ng->ng_host);
222bf89e9b1Sderaadt badhost:
223bf89e9b1Sderaadt free(ng);
224bf89e9b1Sderaadt return NULL;
225bf89e9b1Sderaadt }
226bf89e9b1Sderaadt
227bf89e9b1Sderaadt /*
228bf89e9b1Sderaadt * getstring(): Get a string delimited by the character, skipping leading and
229bf89e9b1Sderaadt * trailing blanks and advancing the pointer
230bf89e9b1Sderaadt */
231bf89e9b1Sderaadt static int
getstring(char ** pp,int del,char ** str)232bf89e9b1Sderaadt getstring(char **pp, int del, char **str)
233bf89e9b1Sderaadt {
234bf89e9b1Sderaadt char *sp, *ep, *dp;
235bf89e9b1Sderaadt
236bf89e9b1Sderaadt /* skip leading blanks */
237bf89e9b1Sderaadt for (sp = *pp; *sp && _NG_ISSPACE(*sp); sp++)
238bf89e9b1Sderaadt continue;
239bf89e9b1Sderaadt
240bf89e9b1Sderaadt /* accumulate till delimiter or space */
241bf89e9b1Sderaadt for (ep = sp; *ep && *ep != del && !_NG_ISSPACE(*ep); ep++)
242bf89e9b1Sderaadt continue;
243bf89e9b1Sderaadt
244bf89e9b1Sderaadt /* hunt for the delimiter */
245bf89e9b1Sderaadt for (dp = ep; *dp && *dp != del && _NG_ISSPACE(*dp); dp++)
246bf89e9b1Sderaadt continue;
247bf89e9b1Sderaadt
248bf89e9b1Sderaadt if (*dp != del) {
249bf89e9b1Sderaadt *str = NULL;
250bf89e9b1Sderaadt return 0;
251bf89e9b1Sderaadt }
252bf89e9b1Sderaadt
253bf89e9b1Sderaadt *pp = ++dp;
254bf89e9b1Sderaadt
255bf89e9b1Sderaadt del = (ep - sp) + 1;
256bf89e9b1Sderaadt if (del > 1) {
257bf89e9b1Sderaadt dp = malloc(del);
258bf89e9b1Sderaadt if (dp == NULL)
259bf89e9b1Sderaadt return 0;
260bf89e9b1Sderaadt memcpy(dp, sp, del);
261bf89e9b1Sderaadt dp[del - 1] = '\0';
262bf89e9b1Sderaadt } else
263bf89e9b1Sderaadt dp = NULL;
264bf89e9b1Sderaadt
265bf89e9b1Sderaadt *str = dp;
266bf89e9b1Sderaadt return 1;
267bf89e9b1Sderaadt }
268