mk-amd-map.c revision 38500
138494Sobrien/* 238494Sobrien * Copyright (c) 1997-1998 Erez Zadok 338494Sobrien * Copyright (c) 1990 Jan-Simon Pendry 438494Sobrien * Copyright (c) 1990 Imperial College of Science, Technology & Medicine 538494Sobrien * Copyright (c) 1990 The Regents of the University of California. 638494Sobrien * All rights reserved. 738494Sobrien * 838494Sobrien * This code is derived from software contributed to Berkeley by 938494Sobrien * Jan-Simon Pendry at Imperial College, London. 1038494Sobrien * 1138494Sobrien * Redistribution and use in source and binary forms, with or without 1238494Sobrien * modification, are permitted provided that the following conditions 1338494Sobrien * are met: 1438494Sobrien * 1. Redistributions of source code must retain the above copyright 1538494Sobrien * notice, this list of conditions and the following disclaimer. 1638494Sobrien * 2. Redistributions in binary form must reproduce the above copyright 1738494Sobrien * notice, this list of conditions and the following disclaimer in the 1838494Sobrien * documentation and/or other materials provided with the distribution. 1938494Sobrien * 3. All advertising materials mentioning features or use of this software 2038494Sobrien * must display the following acknowledgement: 2138494Sobrien * This product includes software developed by the University of 2238494Sobrien * California, Berkeley and its contributors. 2338494Sobrien * 4. Neither the name of the University nor the names of its contributors 2438494Sobrien * may be used to endorse or promote products derived from this software 2538494Sobrien * without specific prior written permission. 2638494Sobrien * 2738494Sobrien * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 2838494Sobrien * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2938494Sobrien * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 3038494Sobrien * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 3138494Sobrien * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 3238494Sobrien * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 3338494Sobrien * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 3438494Sobrien * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 3538494Sobrien * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 3638494Sobrien * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 3738494Sobrien * SUCH DAMAGE. 3838494Sobrien * 3938494Sobrien * %W% (Berkeley) %G% 4038494Sobrien * 4138500Sobrien * $Id: mk-amd-map.c,v 1.1.1.1 1998/08/23 22:07:21 obrien Exp $ 4238494Sobrien */ 4338494Sobrien 4438494Sobrien/* 4538494Sobrien * Convert a file map into an ndbm map 4638494Sobrien */ 4738494Sobrien 4838494Sobrien#ifdef HAVE_CONFIG_H 4938494Sobrien# include <config.h> 5038494Sobrien#endif /* HAVE_CONFIG_H */ 5138494Sobrien#include <am_defs.h> 5238494Sobrien 5338494Sobrien/* dummy variables */ 5438494Sobrienchar *progname; 5538494Sobrienchar hostname[MAXHOSTNAMELEN]; 5638494Sobrienint orig_umask, foreground, debug_flags; 5738494Sobrienpid_t mypid; 5838494Sobrienserv_state amd_state; 5938494Sobrien 6038494Sobrien 6138494Sobrien#ifdef HAVE_MAP_NDBM 6238494Sobrien 6338494Sobrienstatic int 6438494Sobrienstore_data(voidp db, char *k, char *v) 6538494Sobrien{ 6638494Sobrien datum key, val; 6738494Sobrien 6838494Sobrien key.dptr = k; 6938494Sobrien val.dptr = v; 7038494Sobrien key.dsize = strlen(k) + 1; 7138494Sobrien val.dsize = strlen(v) + 1; 7238494Sobrien return dbm_store((DBM *) db, key, val, DBM_INSERT); 7338494Sobrien} 7438494Sobrien 7538494Sobrien 7638494Sobrien/* 7738494Sobrien * Read one line from file. 7838494Sobrien */ 7938494Sobrienstatic int 8038494Sobrienread_line(char *buf, int size, FILE *fp) 8138494Sobrien{ 8238494Sobrien int done = 0; 8338494Sobrien 8438494Sobrien do { 8538494Sobrien while (fgets(buf, size, fp)) { 8638494Sobrien int len = strlen(buf); 8738494Sobrien 8838494Sobrien done += len; 8938494Sobrien if (len > 1 && buf[len - 2] == '\\' && buf[len - 1] == '\n') { 9038494Sobrien int ch; 9138494Sobrien buf += len - 2; 9238494Sobrien size -= len - 2; 9338494Sobrien *buf = '\n'; 9438494Sobrien buf[1] = '\0'; 9538494Sobrien 9638494Sobrien /* 9738494Sobrien * Skip leading white space on next line 9838494Sobrien */ 9938494Sobrien while ((ch = getc(fp)) != EOF && isascii(ch) && isspace(ch)) ; 10038494Sobrien (void) ungetc(ch, fp); 10138494Sobrien } else { 10238494Sobrien return done; 10338494Sobrien } 10438494Sobrien } 10538494Sobrien } while (size > 0 && !feof(fp)); 10638494Sobrien 10738494Sobrien return done; 10838494Sobrien} 10938494Sobrien 11038494Sobrien 11138494Sobrien/* 11238494Sobrien * Read through a map. 11338494Sobrien */ 11438494Sobrienstatic int 11538494Sobrienread_file(FILE *fp, char *map, voidp db) 11638494Sobrien{ 11738494Sobrien char key_val[2048]; 11838494Sobrien int chuck = 0; 11938494Sobrien int line_no = 0; 12038494Sobrien int errs = 0; 12138494Sobrien 12238494Sobrien while (read_line(key_val, sizeof(key_val), fp)) { 12338494Sobrien char *kp; 12438494Sobrien char *cp; 12538494Sobrien char *hash; 12638494Sobrien int len = strlen(key_val); 12738494Sobrien 12838494Sobrien line_no++; 12938494Sobrien 13038494Sobrien /* 13138494Sobrien * Make sure we got the whole line 13238494Sobrien */ 13338494Sobrien if (key_val[len - 1] != '\n') { 13438494Sobrien fprintf(stderr, "line %d in \"%s\" is too long", line_no, map); 13538494Sobrien chuck = 1; 13638494Sobrien } else { 13738494Sobrien key_val[len - 1] = '\0'; 13838494Sobrien } 13938494Sobrien 14038494Sobrien /* 14138494Sobrien * Strip comments 14238494Sobrien */ 14338494Sobrien hash = strchr(key_val, '#'); 14438494Sobrien if (hash) 14538494Sobrien *hash = '\0'; 14638494Sobrien 14738494Sobrien /* 14838494Sobrien * Find start of key 14938494Sobrien */ 15038494Sobrien for (kp = key_val; *kp && isascii(*kp) && isspace((int)*kp); kp++) ; 15138494Sobrien 15238494Sobrien /* 15338494Sobrien * Ignore blank lines 15438494Sobrien */ 15538494Sobrien if (!*kp) 15638494Sobrien goto again; 15738494Sobrien 15838494Sobrien /* 15938494Sobrien * Find end of key 16038494Sobrien */ 16138494Sobrien for (cp = kp; *cp && (!isascii(*cp) || !isspace((int)*cp)); cp++) ; 16238494Sobrien 16338494Sobrien /* 16438494Sobrien * Check whether key matches, or whether 16538494Sobrien * the entry is a wildcard entry. 16638494Sobrien */ 16738494Sobrien if (*cp) 16838494Sobrien *cp++ = '\0'; 16938494Sobrien while (*cp && isascii(*cp) && isspace((int)*cp)) 17038494Sobrien cp++; 17138494Sobrien if (*kp == '+') { 17238494Sobrien fprintf(stderr, "Can't interpolate %s\n", kp); 17338494Sobrien errs++; 17438494Sobrien } else if (*cp) { 17538494Sobrien if (db) { 17638494Sobrien if (store_data(db, kp, cp) < 0) { 17738494Sobrien fprintf(stderr, "Could store %s -> %s\n", kp, cp); 17838494Sobrien errs++; 17938494Sobrien } 18038494Sobrien } else { 18138494Sobrien printf("%s\t%s\n", kp, cp); 18238494Sobrien } 18338494Sobrien } else { 18438494Sobrien fprintf(stderr, "%s: line %d has no value field", map, line_no); 18538494Sobrien errs++; 18638494Sobrien } 18738494Sobrien 18838494Sobrien again: 18938494Sobrien /* 19038494Sobrien * If the last read didn't get a whole line then 19138494Sobrien * throw away the remainder before continuing... 19238494Sobrien */ 19338494Sobrien if (chuck) { 19438494Sobrien while (fgets(key_val, sizeof(key_val), fp) && 19538494Sobrien !strchr(key_val, '\n')) ; 19638494Sobrien chuck = 0; 19738494Sobrien } 19838494Sobrien } 19938494Sobrien return errs; 20038494Sobrien} 20138494Sobrien 20238494Sobrien 20338494Sobrienstatic int 20438494Sobrienremove_file(char *f) 20538494Sobrien{ 20638494Sobrien if (unlink(f) < 0 && errno != ENOENT) 20738494Sobrien return -1; 20838494Sobrien 20938494Sobrien return 0; 21038494Sobrien} 21138494Sobrien 21238494Sobrien 21338494Sobrienint 21438494Sobrienmain(int argc, char *argv[]) 21538494Sobrien{ 21638494Sobrien FILE *mapf; 21738494Sobrien int mapfd = -1; 21838494Sobrien char *map; 21938494Sobrien int rc = 0; 22038494Sobrien DBM *mapd = NULL; 22138494Sobrien static char maptmp[] = "dbmXXXXXX"; 22238494Sobrien char maptpag[16], maptdir[16]; 22338494Sobrien char *mappag = (char *) NULL, *mapdir = (char *) NULL; 22438494Sobrien int len; 22538494Sobrien char *sl; 22638494Sobrien int printit = 0; 22738494Sobrien int usage = 0; 22838494Sobrien int ch; 22938494Sobrien extern int optind; 23038494Sobrien 23138494Sobrien /* test options */ 23238500Sobrien while ((ch = getopt(argc, argv, "p")) != -1) 23338494Sobrien switch (ch) { 23438494Sobrien case 'p': 23538494Sobrien printit = 1; 23638494Sobrien break; 23738494Sobrien default: 23838494Sobrien usage++; 23938494Sobrien break; 24038494Sobrien } 24138494Sobrien 24238494Sobrien if (usage || optind != (argc - 1)) { 24338494Sobrien fputs("Usage: mk-amd-map [-p] file-map\n", stderr); 24438494Sobrien exit(1); 24538494Sobrien } 24638494Sobrien map = argv[optind]; 24738494Sobrien 24838494Sobrien /* test if can get to the map directory */ 24938494Sobrien sl = strrchr(map, '/'); 25038494Sobrien if (sl) { 25138494Sobrien *sl = '\0'; 25238494Sobrien if (chdir(map) < 0) { 25338494Sobrien fputs("Can't chdir to ", stderr); 25438494Sobrien perror(map); 25538494Sobrien exit(1); 25638494Sobrien } 25738494Sobrien map = sl + 1; 25838494Sobrien } 25938494Sobrien 26038494Sobrien if (!printit) { 26138494Sobrien len = strlen(map); 26238494Sobrien mappag = (char *) malloc(len + 5); 26338494Sobrien mapdir = (char *) malloc(len + 5); 26438494Sobrien if (!mappag || !mapdir) { 26538494Sobrien perror("mk-amd-map: malloc"); 26638494Sobrien exit(1); 26738494Sobrien } 26838494Sobrien#ifdef HAVE_MKSTEMP 26938494Sobrien mapfd = mkstemp(maptmp); 27038494Sobrien#else /* not HAVE_MKSTEMP */ 27138494Sobrien map = mktemp(maptmp); 27238494Sobrien if (!maptmp) { 27338494Sobrien fprintf(stderr, "cannot create temporary file\n"); 27438494Sobrien exit(1); 27538494Sobrien } 27638494Sobrien mapfd = open(map, O_RDONLY); 27738494Sobrien#endif /* not HAVE_MKSTEMP */ 27838494Sobrien 27938494Sobrien /* open DBM files */ 28038494Sobrien sprintf(maptpag, "%s.pag", maptmp); 28138494Sobrien sprintf(maptdir, "%s.dir", maptmp); 28238494Sobrien if (remove_file(maptpag) < 0 || remove_file(maptdir) < 0) { 28338494Sobrien fprintf(stderr, "Can't remove existing temporary files; %s and", maptpag); 28438494Sobrien perror(maptdir); 28538494Sobrien exit(1); 28638494Sobrien } 28738494Sobrien } 28838494Sobrien /* open and check if map file was opened OK */ 28938494Sobrien mapf = fdopen(mapfd, "r"); 29038494Sobrien if (mapf && !printit) 29138494Sobrien mapd = dbm_open(maptmp, O_RDWR|O_CREAT, 0444); 29238494Sobrien else 29338494Sobrien mapd = 0; 29438494Sobrien 29538494Sobrien#ifndef DEBUG 29638494Sobrien /* ignore ^C if debuggung is on (but why?) */ 29738494Sobrien signal(SIGINT, SIG_IGN); 29838494Sobrien#endif /* not DEBUG */ 29938494Sobrien 30038494Sobrien if (mapd || printit) { 30138494Sobrien int error = read_file(mapf, map, mapd); 30238494Sobrien (void) close(mapfd); 30338494Sobrien (void) fclose(mapf); 30438500Sobrien dbm_close(mapd); 30538494Sobrien if (printit) { 30638494Sobrien if (error) { 30738494Sobrien fprintf(stderr, "Error creating ndbm map for %s\n", map); 30838494Sobrien rc = 1; 30938494Sobrien } 31038494Sobrien } else { 31138494Sobrien 31238494Sobrien if (error) { 31338494Sobrien fprintf(stderr, "Error reading source file %s\n", map); 31438494Sobrien rc = 1; 31538494Sobrien } else { 31638494Sobrien sprintf(mappag, "%s.pag", map); 31738494Sobrien sprintf(mapdir, "%s.dir", map); 31838494Sobrien if (rename(maptpag, mappag) < 0) { 31938494Sobrien fprintf(stderr, "Couldn't rename %s to ", maptpag); 32038494Sobrien perror(mappag); 32138494Sobrien /* Throw away the temporary map */ 32238494Sobrien unlink(maptpag); 32338494Sobrien unlink(maptdir); 32438494Sobrien rc = 1; 32538494Sobrien 32638494Sobrien } else if (rename(maptdir, mapdir) < 0) { 32738494Sobrien fprintf(stderr, "Couldn't rename %s to ", maptdir); 32838494Sobrien perror(mapdir); 32938494Sobrien /* Put the .pag file back */ 33038494Sobrien rename(mappag, maptpag); 33138494Sobrien /* Throw away remaining part of original map */ 33238494Sobrien unlink(mapdir); 33338494Sobrien fprintf(stderr, 33438494Sobrien "WARNING: existing map \"%s.{dir,pag}\" destroyed\n", 33538494Sobrien map); 33638494Sobrien rc = 1; 33738494Sobrien } 33838494Sobrien } 33938494Sobrien } 34038494Sobrien 34138494Sobrien } else { 34238494Sobrien fprintf(stderr, "Can't open \"%s.{dir,pag}\" for ", map); 34338494Sobrien perror("writing"); 34438494Sobrien rc = 1; 34538494Sobrien } 34638494Sobrien exit(rc); 34738494Sobrien} 34838494Sobrien 34938494Sobrien#else /* not HAVE_MAP_NDBM */ 35038494Sobrien 35138494Sobrienmain() 35238494Sobrien{ 35338494Sobrien fputs("mk-amd-map: This system does not support hashed database files\n", stderr); 35438494Sobrien exit(1); 35538494Sobrien} 35638494Sobrien 35738494Sobrien#endif /* not HAVE_MAP_NDBM */ 358