1 /* $OpenBSD: util.c,v 1.12 2003/06/28 04:55:07 deraadt 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 #include <ctype.h> 46 #include <stdio.h> 47 #include <stdlib.h> 48 #include <string.h> 49 #include <stdarg.h> 50 #include "config.h" 51 52 static void nomem(void); 53 static void vxerror(const char *, int, const char *, va_list); 54 55 /* 56 * Malloc, with abort on error. 57 */ 58 void * 59 emalloc(size_t size) 60 { 61 void *p; 62 63 if ((p = malloc(size)) == NULL) 64 nomem(); 65 memset(p, 0, size); 66 return (p); 67 } 68 69 /* 70 * Realloc, with abort on error. 71 */ 72 void * 73 erealloc(void *p, size_t size) 74 { 75 76 if ((p = realloc(p, size)) == NULL) 77 nomem(); 78 return (p); 79 } 80 81 static void 82 nomem(void) 83 { 84 85 (void)fprintf(stderr, "config: out of memory\n"); 86 exit(1); 87 } 88 89 /* 90 * Prepend the source path to a file name. 91 */ 92 char * 93 sourcepath(const char *file) 94 { 95 char *cp; 96 int len = strlen(srcdir) + 1 + strlen(file) + 1; 97 98 cp = emalloc(len); 99 (void)snprintf(cp, len, "%s/%s", srcdir, file); 100 return (cp); 101 } 102 103 static struct nvlist *nvhead; 104 105 struct nvlist * 106 newnv(const char *name, const char *str, void *ptr, int i, struct nvlist *next) 107 { 108 struct nvlist *nv; 109 110 if ((nv = nvhead) == NULL) 111 nv = emalloc(sizeof(*nv)); 112 else 113 nvhead = nv->nv_next; 114 nv->nv_next = next; 115 nv->nv_name = (char *)name; 116 if (ptr == NULL) 117 nv->nv_str = str; 118 else { 119 if (str != NULL) 120 panic("newnv"); 121 nv->nv_ptr = ptr; 122 } 123 nv->nv_int = i; 124 return (nv); 125 } 126 127 /* 128 * Free an nvlist structure (just one). 129 */ 130 void 131 nvfree(struct nvlist *nv) 132 { 133 134 nv->nv_next = nvhead; 135 nvhead = nv; 136 } 137 138 /* 139 * Free an nvlist (the whole list). 140 */ 141 void 142 nvfreel(struct nvlist *nv) 143 { 144 struct nvlist *next; 145 146 for (; nv != NULL; nv = next) { 147 next = nv->nv_next; 148 nv->nv_next = nvhead; 149 nvhead = nv; 150 } 151 } 152 153 /* 154 * External (config file) error. Complain, using current file 155 * and line number. 156 */ 157 void 158 error(const char *fmt, ...) 159 { 160 va_list ap; 161 extern const char *yyfile; 162 163 va_start(ap, fmt); 164 vxerror(yyfile, currentline(), fmt, ap); 165 va_end(ap); 166 } 167 168 /* 169 * Delayed config file error (i.e., something was wrong but we could not 170 * find out about it until later). 171 */ 172 void 173 xerror(const char *file, int line, const char *fmt, ...) 174 { 175 va_list ap; 176 177 va_start(ap, fmt); 178 vxerror(file, line, fmt, ap); 179 va_end(ap); 180 } 181 182 /* 183 * Internal form of error() and xerror(). 184 */ 185 static void 186 vxerror(const char *file, int line, const char *fmt, va_list ap) 187 { 188 189 (void)fprintf(stderr, "%s:%d: ", file, line); 190 (void)vfprintf(stderr, fmt, ap); 191 (void)putc('\n', stderr); 192 errors++; 193 } 194 195 /* 196 * Internal error, abort. 197 */ 198 __dead void 199 panic(const char *fmt, ...) 200 { 201 va_list ap; 202 203 va_start(ap, fmt); 204 (void)fprintf(stderr, "config: panic: "); 205 (void)vfprintf(stderr, fmt, ap); 206 (void)putc('\n', stderr); 207 va_end(ap); 208 exit(2); 209 } 210