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