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