mk-amd-map.c revision 38575
1/* 2 * Copyright (c) 1997-1998 Erez Zadok 3 * Copyright (c) 1990 Jan-Simon Pendry 4 * Copyright (c) 1990 Imperial College of Science, Technology & Medicine 5 * Copyright (c) 1990 The Regents of the University of California. 6 * All rights reserved. 7 * 8 * This code is derived from software contributed to Berkeley by 9 * Jan-Simon Pendry at Imperial College, London. 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions and the following disclaimer. 16 * 2. Redistributions in binary form must reproduce the above copyright 17 * notice, this list of conditions and the following disclaimer in the 18 * documentation and/or other materials provided with the distribution. 19 * 3. All advertising materials mentioning features or use of this software 20 * must display the following acknowledgement: 21 * This product includes software developed by the University of 22 * California, Berkeley and its contributors. 23 * 4. Neither the name of the University nor the names of its contributors 24 * may be used to endorse or promote products derived from this software 25 * without specific prior written permission. 26 * 27 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 28 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 29 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 30 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 31 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 32 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 33 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 34 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 35 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 36 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 37 * SUCH DAMAGE. 38 * 39 * %W% (Berkeley) %G% 40 * 41 * $Id: mk-amd-map.c,v 1.2 1998/08/23 22:52:09 obrien Exp $ 42 */ 43 44/* 45 * Convert a file map into an ndbm map 46 */ 47 48#ifdef HAVE_CONFIG_H 49# include <config.h> 50#endif /* HAVE_CONFIG_H */ 51#include <am_defs.h> 52 53/* dummy variables */ 54char hostname[MAXHOSTNAMELEN]; 55int orig_umask, foreground, debug_flags; 56pid_t mypid; 57serv_state amd_state; 58 59 60#ifdef HAVE_MAP_NDBM 61 62static int 63store_data(voidp db, char *k, char *v) 64{ 65 datum key, val; 66 67 key.dptr = k; 68 val.dptr = v; 69 key.dsize = strlen(k) + 1; 70 val.dsize = strlen(v) + 1; 71 return dbm_store((DBM *) db, key, val, DBM_INSERT); 72} 73 74 75/* 76 * Read one line from file. 77 */ 78static int 79read_line(char *buf, int size, FILE *fp) 80{ 81 int done = 0; 82 83 do { 84 while (fgets(buf, size, fp)) { 85 int len = strlen(buf); 86 87 done += len; 88 if (len > 1 && buf[len - 2] == '\\' && buf[len - 1] == '\n') { 89 int ch; 90 buf += len - 2; 91 size -= len - 2; 92 *buf = '\n'; 93 buf[1] = '\0'; 94 95 /* 96 * Skip leading white space on next line 97 */ 98 while ((ch = getc(fp)) != EOF && isascii(ch) && isspace(ch)) ; 99 (void) ungetc(ch, fp); 100 } else { 101 return done; 102 } 103 } 104 } while (size > 0 && !feof(fp)); 105 106 return done; 107} 108 109 110/* 111 * Read through a map. 112 */ 113static int 114read_file(FILE *fp, char *map, voidp db) 115{ 116 char key_val[2048]; 117 int chuck = 0; 118 int line_no = 0; 119 int errs = 0; 120 121 while (read_line(key_val, sizeof(key_val), fp)) { 122 char *kp; 123 char *cp; 124 char *hash; 125 int len = strlen(key_val); 126 127 line_no++; 128 129 /* 130 * Make sure we got the whole line 131 */ 132 if (key_val[len - 1] != '\n') { 133 fprintf(stderr, "line %d in \"%s\" is too long", line_no, map); 134 chuck = 1; 135 } else { 136 key_val[len - 1] = '\0'; 137 } 138 139 /* 140 * Strip comments 141 */ 142 hash = strchr(key_val, '#'); 143 if (hash) 144 *hash = '\0'; 145 146 /* 147 * Find start of key 148 */ 149 for (kp = key_val; *kp && isascii(*kp) && isspace((int)*kp); kp++) ; 150 151 /* 152 * Ignore blank lines 153 */ 154 if (!*kp) 155 goto again; 156 157 /* 158 * Find end of key 159 */ 160 for (cp = kp; *cp && (!isascii(*cp) || !isspace((int)*cp)); cp++) ; 161 162 /* 163 * Check whether key matches, or whether 164 * the entry is a wildcard entry. 165 */ 166 if (*cp) 167 *cp++ = '\0'; 168 while (*cp && isascii(*cp) && isspace((int)*cp)) 169 cp++; 170 if (*kp == '+') { 171 fprintf(stderr, "Can't interpolate %s\n", kp); 172 errs++; 173 } else if (*cp) { 174 if (db) { 175 if (store_data(db, kp, cp) < 0) { 176 fprintf(stderr, "Could store %s -> %s\n", kp, cp); 177 errs++; 178 } 179 } else { 180 printf("%s\t%s\n", kp, cp); 181 } 182 } else { 183 fprintf(stderr, "%s: line %d has no value field", map, line_no); 184 errs++; 185 } 186 187 again: 188 /* 189 * If the last read didn't get a whole line then 190 * throw away the remainder before continuing... 191 */ 192 if (chuck) { 193 while (fgets(key_val, sizeof(key_val), fp) && 194 !strchr(key_val, '\n')) ; 195 chuck = 0; 196 } 197 } 198 return errs; 199} 200 201 202static int 203remove_file(char *f) 204{ 205 if (unlink(f) < 0 && errno != ENOENT) 206 return -1; 207 208 return 0; 209} 210 211 212int 213main(int argc, char *argv[]) 214{ 215 FILE *mapf; 216 int mapfd = -1; 217 char *map; 218 int rc = 0; 219 DBM *mapd = NULL; 220 static char maptmp[] = "dbmXXXXXX"; 221 char maptdb[16]; 222 char *mapdb = (char *) NULL; 223 int len; 224 char *sl; 225 int printit = 0; 226 int usage = 0; 227 int ch; 228 extern int optind; 229 230 /* test options */ 231 while ((ch = getopt(argc, argv, "p")) != -1) 232 switch (ch) { 233 case 'p': 234 printit = 1; 235 break; 236 default: 237 usage++; 238 break; 239 } 240 241 if (usage || optind != (argc - 1)) { 242 fputs("Usage: mk-amd-map [-p] file-map\n", stderr); 243 exit(1); 244 } 245 map = argv[optind]; 246 247 /* test if can get to the map directory */ 248 sl = strrchr(map, '/'); 249 if (sl) { 250 *sl = '\0'; 251 if (chdir(map) < 0) { 252 fputs("Can't chdir to ", stderr); 253 perror(map); 254 exit(1); 255 } 256 map = sl + 1; 257 } 258 259 if (!printit) { 260 len = strlen(map); 261 mapdb = (char *) malloc(len + 4); 262 if (!mapdb) { 263 perror("mk-amd-map: malloc"); 264 exit(1); 265 } 266#ifdef HAVE_MKSTEMP 267 mapfd = mkstemp(maptmp); 268#else /* not HAVE_MKSTEMP */ 269 map = mktemp(maptmp); 270 if (!maptmp) { 271 fprintf(stderr, "cannot create temporary file\n"); 272 exit(1); 273 } 274 mapfd = open(map, O_RDONLY); 275#endif /* not HAVE_MKSTEMP */ 276 277 /* open DBM files */ 278 sprintf(maptdb, "%s.db", maptmp); 279 if (remove_file(maptdb) < 0) { 280 fprintf(stderr, "Can't remove existing temporary files;"); 281 perror(maptdb); 282 exit(1); 283 } 284 } 285 /* open and check if map file was opened OK */ 286 mapf = fdopen(mapfd, "r"); 287 if (mapf && !printit) 288 mapd = dbm_open(maptmp, O_RDWR|O_CREAT, 0444); 289 else 290 mapd = 0; 291 292#ifndef DEBUG 293 /* ignore ^C if debuggung is on (but why?) */ 294 signal(SIGINT, SIG_IGN); 295#endif /* not DEBUG */ 296 297 if (mapd || printit) { 298 int error = read_file(mapf, map, mapd); 299 (void) close(mapfd); 300 (void) fclose(mapf); 301 dbm_close(mapd); 302 if (printit) { 303 if (error) { 304 fprintf(stderr, "Error creating ndbm map for %s\n", map); 305 rc = 1; 306 } 307 } else { 308 309 if (error) { 310 fprintf(stderr, "Error reading source file %s\n", map); 311 rc = 1; 312 } else { 313 sprintf(mapdb, "%s.db", map); 314 if (unlink(mapdb) == 0) 315 fprintf(stderr, "WARNING: existing map \"%s.db\" destroyed\n", map); 316 if (rename(maptdb, mapdb) < 0) { 317 fprintf(stderr, "Couldn't rename %s to ", maptdb); 318 perror(mapdb); 319 /* Throw away the temporary map */ 320 unlink(maptdb); 321 rc = 1; 322 } 323 } 324 } 325 326 } else { 327 fprintf(stderr, "Can't open \"%s.db\" for ", map); 328 perror("writing"); 329 rc = 1; 330 } 331 exit(rc); 332} 333 334#else /* not HAVE_MAP_NDBM */ 335 336main() 337{ 338 fputs("mk-amd-map: This system does not support hashed database files\n", stderr); 339 exit(1); 340} 341 342#endif /* not HAVE_MAP_NDBM */ 343