xref: /openbsd-src/usr.sbin/config/util.c (revision 91f110e064cd7c194e59e019b83bb7496c1c84d4)
1 /*	$OpenBSD: util.c,v 1.13 2011/10/02 22:20:50 edd Exp $	*/
2 /*	$NetBSD: util.c,v 1.5 1996/08/31 20:58:29 mycroft Exp $	*/
3 
4 /*
5  * Copyright (c) 1992, 1993
6  *	The Regents of the University of California.  All rights reserved.
7  *
8  * This software was developed by the Computer Systems Engineering group
9  * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
10  * contributed to Berkeley.
11  *
12  * All advertising materials mentioning features or use of this software
13  * must display the following acknowledgement:
14  *	This product includes software developed by the University of
15  *	California, Lawrence Berkeley Laboratories.
16  *
17  * Redistribution and use in source and binary forms, with or without
18  * modification, are permitted provided that the following conditions
19  * are met:
20  * 1. Redistributions of source code must retain the above copyright
21  *    notice, this list of conditions and the following disclaimer.
22  * 2. Redistributions in binary form must reproduce the above copyright
23  *    notice, this list of conditions and the following disclaimer in the
24  *    documentation and/or other materials provided with the distribution.
25  * 3. Neither the name of the University nor the names of its contributors
26  *    may be used to endorse or promote products derived from this software
27  *    without specific prior written permission.
28  *
29  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
30  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
31  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
32  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
33  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
34  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
35  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
36  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
37  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
38  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
39  * SUCH DAMAGE.
40  *
41  *	from: @(#)util.c	8.1 (Berkeley) 6/6/93
42  */
43 
44 #include <sys/types.h>
45 
46 #include <ctype.h>
47 #include <stdarg.h>
48 #include <stdio.h>
49 #include <stdlib.h>
50 #include <string.h>
51 
52 #include "config.h"
53 
54 static void nomem(void);
55 static void vxerror(const char *, int, const char *, va_list);
56 
57 /*
58  * Malloc, with abort on error.
59  */
60 void *
61 emalloc(size_t size)
62 {
63 	void *p;
64 
65 	if ((p = malloc(size)) == NULL)
66 		nomem();
67 	memset(p, 0, size);
68 	return (p);
69 }
70 
71 /*
72  * Realloc, with abort on error.
73  */
74 void *
75 erealloc(void *p, size_t size)
76 {
77 
78 	if ((p = realloc(p, size)) == NULL)
79 		nomem();
80 	return (p);
81 }
82 
83 static void
84 nomem(void)
85 {
86 
87 	(void)fprintf(stderr, "config: out of memory\n");
88 	exit(1);
89 }
90 
91 /*
92  * Prepend the source path to a file name.
93  */
94 char *
95 sourcepath(const char *file)
96 {
97 	char *cp;
98 	int len = strlen(srcdir) + 1 + strlen(file) + 1;
99 
100 	cp = emalloc(len);
101 	(void)snprintf(cp, len, "%s/%s", srcdir, file);
102 	return (cp);
103 }
104 
105 static struct nvlist *nvhead;
106 
107 struct nvlist *
108 newnv(const char *name, const char *str, void *ptr, int i, struct nvlist *next)
109 {
110 	struct nvlist *nv;
111 
112 	if ((nv = nvhead) == NULL)
113 		nv = emalloc(sizeof(*nv));
114 	else
115 		nvhead = nv->nv_next;
116 	nv->nv_next = next;
117 	nv->nv_name = (char *)name;
118 	if (ptr == NULL)
119 		nv->nv_str = str;
120 	else {
121 		if (str != NULL)
122 			panic("newnv");
123 		nv->nv_ptr = ptr;
124 	}
125 	nv->nv_int = i;
126 	return (nv);
127 }
128 
129 /*
130  * Free an nvlist structure (just one).
131  */
132 void
133 nvfree(struct nvlist *nv)
134 {
135 
136 	nv->nv_next = nvhead;
137 	nvhead = nv;
138 }
139 
140 /*
141  * Free an nvlist (the whole list).
142  */
143 void
144 nvfreel(struct nvlist *nv)
145 {
146 	struct nvlist *next;
147 
148 	for (; nv != NULL; nv = next) {
149 		next = nv->nv_next;
150 		nv->nv_next = nvhead;
151 		nvhead = nv;
152 	}
153 }
154 
155 /*
156  * External (config file) error.  Complain, using current file
157  * and line number.
158  */
159 void
160 error(const char *fmt, ...)
161 {
162 	va_list ap;
163 	extern const char *yyfile;
164 
165 	va_start(ap, fmt);
166 	vxerror(yyfile, currentline(), fmt, ap);
167 	va_end(ap);
168 }
169 
170 /*
171  * Delayed config file error (i.e., something was wrong but we could not
172  * find out about it until later).
173  */
174 void
175 xerror(const char *file, int line, const char *fmt, ...)
176 {
177 	va_list ap;
178 
179 	va_start(ap, fmt);
180 	vxerror(file, line, fmt, ap);
181 	va_end(ap);
182 }
183 
184 /*
185  * Internal form of error() and xerror().
186  */
187 static void
188 vxerror(const char *file, int line, const char *fmt, va_list ap)
189 {
190 
191 	(void)fprintf(stderr, "%s:%d: ", file, line);
192 	(void)vfprintf(stderr, fmt, ap);
193 	(void)putc('\n', stderr);
194 	errors++;
195 }
196 
197 /*
198  * Internal error, abort.
199  */
200 __dead void
201 panic(const char *fmt, ...)
202 {
203 	va_list ap;
204 
205 	va_start(ap, fmt);
206 	(void)fprintf(stderr, "config: panic: ");
207 	(void)vfprintf(stderr, fmt, ap);
208 	(void)putc('\n', stderr);
209 	va_end(ap);
210 	exit(2);
211 }
212