xref: /openbsd/usr.sbin/config/util.c (revision c811dcf3)
1 /*	$OpenBSD: util.c,v 1.14 2014/05/18 09:29:54 espie 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  * Reallocarray, with abort on error.
73  */
74 void *
75 ereallocarray(void *p, size_t sz1, size_t sz2)
76 {
77 
78 	if ((p = reallocarray(p, sz1, sz2)) == NULL)
79 		nomem();
80 	return (p);
81 }
82 
83 /*
84  * Calloc, with abort on error.
85  */
86 void *
87 ecalloc(size_t sz1, size_t sz2)
88 {
89 	void *p;
90 
91 	if ((p = calloc(sz1, sz2)) == NULL)
92 		nomem();
93 	return (p);
94 }
95 
96 static void
97 nomem(void)
98 {
99 
100 	(void)fprintf(stderr, "config: out of memory\n");
101 	exit(1);
102 }
103 
104 /*
105  * Prepend the source path to a file name.
106  */
107 char *
108 sourcepath(const char *file)
109 {
110 	char *cp;
111 	int len = strlen(srcdir) + 1 + strlen(file) + 1;
112 
113 	cp = emalloc(len);
114 	(void)snprintf(cp, len, "%s/%s", srcdir, file);
115 	return (cp);
116 }
117 
118 static struct nvlist *nvhead;
119 
120 struct nvlist *
121 newnv(const char *name, const char *str, void *ptr, int i, struct nvlist *next)
122 {
123 	struct nvlist *nv;
124 
125 	if ((nv = nvhead) == NULL)
126 		nv = emalloc(sizeof(*nv));
127 	else
128 		nvhead = nv->nv_next;
129 	nv->nv_next = next;
130 	nv->nv_name = (char *)name;
131 	if (ptr == NULL)
132 		nv->nv_str = str;
133 	else {
134 		if (str != NULL)
135 			panic("newnv");
136 		nv->nv_ptr = ptr;
137 	}
138 	nv->nv_int = i;
139 	return (nv);
140 }
141 
142 /*
143  * Free an nvlist structure (just one).
144  */
145 void
146 nvfree(struct nvlist *nv)
147 {
148 
149 	nv->nv_next = nvhead;
150 	nvhead = nv;
151 }
152 
153 /*
154  * Free an nvlist (the whole list).
155  */
156 void
157 nvfreel(struct nvlist *nv)
158 {
159 	struct nvlist *next;
160 
161 	for (; nv != NULL; nv = next) {
162 		next = nv->nv_next;
163 		nv->nv_next = nvhead;
164 		nvhead = nv;
165 	}
166 }
167 
168 /*
169  * External (config file) error.  Complain, using current file
170  * and line number.
171  */
172 void
173 error(const char *fmt, ...)
174 {
175 	va_list ap;
176 	extern const char *yyfile;
177 
178 	va_start(ap, fmt);
179 	vxerror(yyfile, currentline(), fmt, ap);
180 	va_end(ap);
181 }
182 
183 /*
184  * Delayed config file error (i.e., something was wrong but we could not
185  * find out about it until later).
186  */
187 void
188 xerror(const char *file, int line, const char *fmt, ...)
189 {
190 	va_list ap;
191 
192 	va_start(ap, fmt);
193 	vxerror(file, line, fmt, ap);
194 	va_end(ap);
195 }
196 
197 /*
198  * Internal form of error() and xerror().
199  */
200 static void
201 vxerror(const char *file, int line, const char *fmt, va_list ap)
202 {
203 
204 	(void)fprintf(stderr, "%s:%d: ", file, line);
205 	(void)vfprintf(stderr, fmt, ap);
206 	(void)putc('\n', stderr);
207 	errors++;
208 }
209 
210 /*
211  * Internal error, abort.
212  */
213 __dead void
214 panic(const char *fmt, ...)
215 {
216 	va_list ap;
217 
218 	va_start(ap, fmt);
219 	(void)fprintf(stderr, "config: panic: ");
220 	(void)vfprintf(stderr, fmt, ap);
221 	(void)putc('\n', stderr);
222 	va_end(ap);
223 	exit(2);
224 }
225