10b25da7eSHajimu UMEMOTO /* $NetBSD: services_mkdb.c,v 1.14 2008/04/28 20:24:17 martin Exp $ */ 20b25da7eSHajimu UMEMOTO 30b25da7eSHajimu UMEMOTO /*- 40b25da7eSHajimu UMEMOTO * Copyright (c) 1999 The NetBSD Foundation, Inc. 50b25da7eSHajimu UMEMOTO * All rights reserved. 60b25da7eSHajimu UMEMOTO * 70b25da7eSHajimu UMEMOTO * This code is derived from software contributed to The NetBSD Foundation 80b25da7eSHajimu UMEMOTO * by Luke Mewburn and Christos Zoulas. 90b25da7eSHajimu UMEMOTO * 100b25da7eSHajimu UMEMOTO * Redistribution and use in source and binary forms, with or without 110b25da7eSHajimu UMEMOTO * modification, are permitted provided that the following conditions 120b25da7eSHajimu UMEMOTO * are met: 130b25da7eSHajimu UMEMOTO * 1. Redistributions of source code must retain the above copyright 140b25da7eSHajimu UMEMOTO * notice, this list of conditions and the following disclaimer. 150b25da7eSHajimu UMEMOTO * 2. Redistributions in binary form must reproduce the above copyright 160b25da7eSHajimu UMEMOTO * notice, this list of conditions and the following disclaimer in the 170b25da7eSHajimu UMEMOTO * documentation and/or other materials provided with the distribution. 180b25da7eSHajimu UMEMOTO * 190b25da7eSHajimu UMEMOTO * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 200b25da7eSHajimu UMEMOTO * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 210b25da7eSHajimu UMEMOTO * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 220b25da7eSHajimu UMEMOTO * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 230b25da7eSHajimu UMEMOTO * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 240b25da7eSHajimu UMEMOTO * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 250b25da7eSHajimu UMEMOTO * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 260b25da7eSHajimu UMEMOTO * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 270b25da7eSHajimu UMEMOTO * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 280b25da7eSHajimu UMEMOTO * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 290b25da7eSHajimu UMEMOTO * POSSIBILITY OF SUCH DAMAGE. 300b25da7eSHajimu UMEMOTO */ 310b25da7eSHajimu UMEMOTO 320b25da7eSHajimu UMEMOTO #include <sys/cdefs.h> 330b25da7eSHajimu UMEMOTO __FBSDID("$FreeBSD$"); 340b25da7eSHajimu UMEMOTO 350b25da7eSHajimu UMEMOTO #include <sys/param.h> 360b25da7eSHajimu UMEMOTO #include <sys/stat.h> 370b25da7eSHajimu UMEMOTO 380b25da7eSHajimu UMEMOTO #include <assert.h> 390b25da7eSHajimu UMEMOTO #include <db.h> 400b25da7eSHajimu UMEMOTO #include <err.h> 410b25da7eSHajimu UMEMOTO #include <fcntl.h> 420b25da7eSHajimu UMEMOTO #include <netdb.h> 430b25da7eSHajimu UMEMOTO #include <stdio.h> 440b25da7eSHajimu UMEMOTO #include <stdlib.h> 450b25da7eSHajimu UMEMOTO #include <string.h> 460b25da7eSHajimu UMEMOTO #include <unistd.h> 470b25da7eSHajimu UMEMOTO #include <libutil.h> 480b25da7eSHajimu UMEMOTO #include <ctype.h> 490b25da7eSHajimu UMEMOTO #include <errno.h> 500b25da7eSHajimu UMEMOTO #include <stringlist.h> 510b25da7eSHajimu UMEMOTO 52*eccad222SEd Schouten #include "extern.h" 53*eccad222SEd Schouten 540b25da7eSHajimu UMEMOTO static char tname[MAXPATHLEN]; 550b25da7eSHajimu UMEMOTO 560b25da7eSHajimu UMEMOTO #define PMASK 0xffff 570b25da7eSHajimu UMEMOTO #define PROTOMAX 5 580b25da7eSHajimu UMEMOTO 590b25da7eSHajimu UMEMOTO extern void uniq(const char *); 600b25da7eSHajimu UMEMOTO 610b25da7eSHajimu UMEMOTO static void add(DB *, StringList *, size_t, const char *, size_t *, int); 620b25da7eSHajimu UMEMOTO static StringList ***parseservices(const char *, StringList *); 630b25da7eSHajimu UMEMOTO static void cleanup(void); 640b25da7eSHajimu UMEMOTO static void store(DB *, DBT *, DBT *, int); 650b25da7eSHajimu UMEMOTO static void killproto(DBT *); 660b25da7eSHajimu UMEMOTO static char *getstring(const char *, size_t, char **, const char *); 670b25da7eSHajimu UMEMOTO static size_t getprotoindex(StringList *, const char *); 680b25da7eSHajimu UMEMOTO static const char *getprotostr(StringList *, size_t); 690b25da7eSHajimu UMEMOTO static const char *mkaliases(StringList *, char *, size_t); 700b25da7eSHajimu UMEMOTO static void usage(void); 710b25da7eSHajimu UMEMOTO 720b25da7eSHajimu UMEMOTO const HASHINFO hinfo = { 730b25da7eSHajimu UMEMOTO .bsize = 256, 740b25da7eSHajimu UMEMOTO .ffactor = 4, 750b25da7eSHajimu UMEMOTO .nelem = 32768, 760b25da7eSHajimu UMEMOTO .cachesize = 1024, 770b25da7eSHajimu UMEMOTO .hash = NULL, 780b25da7eSHajimu UMEMOTO .lorder = 0 790b25da7eSHajimu UMEMOTO }; 800b25da7eSHajimu UMEMOTO 810b25da7eSHajimu UMEMOTO 820b25da7eSHajimu UMEMOTO int 830b25da7eSHajimu UMEMOTO main(int argc, char *argv[]) 840b25da7eSHajimu UMEMOTO { 850b25da7eSHajimu UMEMOTO DB *db; 860b25da7eSHajimu UMEMOTO int ch; 870b25da7eSHajimu UMEMOTO const char *fname = _PATH_SERVICES; 880b25da7eSHajimu UMEMOTO const char *dbname = _PATH_SERVICES_DB; 890b25da7eSHajimu UMEMOTO int warndup = 1; 900b25da7eSHajimu UMEMOTO int unique = 0; 910b25da7eSHajimu UMEMOTO int otherflag = 0; 920b25da7eSHajimu UMEMOTO size_t cnt = 0; 930b25da7eSHajimu UMEMOTO StringList *sl, ***svc; 940b25da7eSHajimu UMEMOTO size_t port, proto; 950b25da7eSHajimu UMEMOTO 960b25da7eSHajimu UMEMOTO setprogname(argv[0]); 970b25da7eSHajimu UMEMOTO 980b25da7eSHajimu UMEMOTO while ((ch = getopt(argc, argv, "qo:u")) != -1) 990b25da7eSHajimu UMEMOTO switch (ch) { 1000b25da7eSHajimu UMEMOTO case 'q': 1010b25da7eSHajimu UMEMOTO otherflag = 1; 1020b25da7eSHajimu UMEMOTO warndup = 0; 1030b25da7eSHajimu UMEMOTO break; 1040b25da7eSHajimu UMEMOTO case 'o': 1050b25da7eSHajimu UMEMOTO otherflag = 1; 1060b25da7eSHajimu UMEMOTO dbname = optarg; 1070b25da7eSHajimu UMEMOTO break; 1080b25da7eSHajimu UMEMOTO case 'u': 1090b25da7eSHajimu UMEMOTO unique++; 1100b25da7eSHajimu UMEMOTO break; 1110b25da7eSHajimu UMEMOTO case '?': 1120b25da7eSHajimu UMEMOTO default: 1130b25da7eSHajimu UMEMOTO usage(); 1140b25da7eSHajimu UMEMOTO } 1150b25da7eSHajimu UMEMOTO 1160b25da7eSHajimu UMEMOTO argc -= optind; 1170b25da7eSHajimu UMEMOTO argv += optind; 1180b25da7eSHajimu UMEMOTO 1190b25da7eSHajimu UMEMOTO if (argc > 1 || (unique && otherflag)) 1200b25da7eSHajimu UMEMOTO usage(); 1210b25da7eSHajimu UMEMOTO if (argc == 1) 1220b25da7eSHajimu UMEMOTO fname = argv[0]; 1230b25da7eSHajimu UMEMOTO 1240b25da7eSHajimu UMEMOTO if (unique) 1250b25da7eSHajimu UMEMOTO uniq(fname); 1260b25da7eSHajimu UMEMOTO 1270b25da7eSHajimu UMEMOTO svc = parseservices(fname, sl = sl_init()); 1280b25da7eSHajimu UMEMOTO 1290b25da7eSHajimu UMEMOTO if (atexit(cleanup)) 1300b25da7eSHajimu UMEMOTO err(1, "Cannot install exit handler"); 1310b25da7eSHajimu UMEMOTO 1320b25da7eSHajimu UMEMOTO (void)snprintf(tname, sizeof(tname), "%s.tmp", dbname); 1330b25da7eSHajimu UMEMOTO db = dbopen(tname, O_RDWR | O_CREAT | O_EXCL, 1340b25da7eSHajimu UMEMOTO (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH), DB_HASH, &hinfo); 1350b25da7eSHajimu UMEMOTO if (!db) 1360b25da7eSHajimu UMEMOTO err(1, "Error opening temporary database `%s'", tname); 1370b25da7eSHajimu UMEMOTO 1380b25da7eSHajimu UMEMOTO 1390b25da7eSHajimu UMEMOTO for (port = 0; port < PMASK + 1; port++) { 1400b25da7eSHajimu UMEMOTO if (svc[port] == NULL) 1410b25da7eSHajimu UMEMOTO continue; 1420b25da7eSHajimu UMEMOTO 1430b25da7eSHajimu UMEMOTO for (proto = 0; proto < PROTOMAX; proto++) { 1440b25da7eSHajimu UMEMOTO StringList *s; 1450b25da7eSHajimu UMEMOTO if ((s = svc[port][proto]) == NULL) 1460b25da7eSHajimu UMEMOTO continue; 1470b25da7eSHajimu UMEMOTO add(db, s, port, getprotostr(sl, proto), &cnt, warndup); 1480b25da7eSHajimu UMEMOTO } 1490b25da7eSHajimu UMEMOTO 1500b25da7eSHajimu UMEMOTO free(svc[port]); 1510b25da7eSHajimu UMEMOTO } 1520b25da7eSHajimu UMEMOTO 1530b25da7eSHajimu UMEMOTO free(svc); 1540b25da7eSHajimu UMEMOTO sl_free(sl, 1); 1550b25da7eSHajimu UMEMOTO 1560b25da7eSHajimu UMEMOTO if ((db->close)(db)) 1570b25da7eSHajimu UMEMOTO err(1, "Error closing temporary database `%s'", tname); 1580b25da7eSHajimu UMEMOTO 1590b25da7eSHajimu UMEMOTO if (rename(tname, dbname) == -1) 1600b25da7eSHajimu UMEMOTO err(1, "Cannot rename `%s' to `%s'", tname, dbname); 1610b25da7eSHajimu UMEMOTO 1620b25da7eSHajimu UMEMOTO return 0; 1630b25da7eSHajimu UMEMOTO } 1640b25da7eSHajimu UMEMOTO 1650b25da7eSHajimu UMEMOTO static void 1660b25da7eSHajimu UMEMOTO add(DB *db, StringList *sl, size_t port, const char *proto, size_t *cnt, 1670b25da7eSHajimu UMEMOTO int warndup) 1680b25da7eSHajimu UMEMOTO { 1690b25da7eSHajimu UMEMOTO size_t i; 1700b25da7eSHajimu UMEMOTO char keyb[BUFSIZ], datab[BUFSIZ], abuf[BUFSIZ]; 1710b25da7eSHajimu UMEMOTO DBT data, key; 1720b25da7eSHajimu UMEMOTO key.data = keyb; 1730b25da7eSHajimu UMEMOTO data.data = datab; 1740b25da7eSHajimu UMEMOTO 1750b25da7eSHajimu UMEMOTO #ifdef DEBUG 1760b25da7eSHajimu UMEMOTO (void)printf("add %s %zu %s [ ", sl->sl_str[0], port, proto); 1770b25da7eSHajimu UMEMOTO for (i = 1; i < sl->sl_cur; i++) 1780b25da7eSHajimu UMEMOTO (void)printf("%s ", sl->sl_str[i]); 1790b25da7eSHajimu UMEMOTO (void)printf("]\n"); 1800b25da7eSHajimu UMEMOTO #endif 1810b25da7eSHajimu UMEMOTO 1820b25da7eSHajimu UMEMOTO /* key `indirect key', data `full line' */ 1830b25da7eSHajimu UMEMOTO data.size = snprintf(datab, sizeof(datab), "%zu", (*cnt)++) + 1; 1840b25da7eSHajimu UMEMOTO key.size = snprintf(keyb, sizeof(keyb), "%s %zu/%s %s", 1850b25da7eSHajimu UMEMOTO sl->sl_str[0], port, proto, mkaliases(sl, abuf, sizeof(abuf))) + 1; 1860b25da7eSHajimu UMEMOTO store(db, &data, &key, warndup); 1870b25da7eSHajimu UMEMOTO 1880b25da7eSHajimu UMEMOTO /* key `\377port/proto', data = `indirect key' */ 1890b25da7eSHajimu UMEMOTO key.size = snprintf(keyb, sizeof(keyb), "\377%zu/%s", 1900b25da7eSHajimu UMEMOTO port, proto) + 1; 1910b25da7eSHajimu UMEMOTO store(db, &key, &data, warndup); 1920b25da7eSHajimu UMEMOTO 1930b25da7eSHajimu UMEMOTO /* key `\377port', data = `indirect key' */ 1940b25da7eSHajimu UMEMOTO killproto(&key); 1950b25da7eSHajimu UMEMOTO store(db, &key, &data, warndup); 1960b25da7eSHajimu UMEMOTO 1970b25da7eSHajimu UMEMOTO /* add references for service and all aliases */ 1980b25da7eSHajimu UMEMOTO for (i = 0; i < sl->sl_cur; i++) { 1990b25da7eSHajimu UMEMOTO /* key `\376service/proto', data = `indirect key' */ 2000b25da7eSHajimu UMEMOTO key.size = snprintf(keyb, sizeof(keyb), "\376%s/%s", 2010b25da7eSHajimu UMEMOTO sl->sl_str[i], proto) + 1; 2020b25da7eSHajimu UMEMOTO store(db, &key, &data, warndup); 2030b25da7eSHajimu UMEMOTO 2040b25da7eSHajimu UMEMOTO /* key `\376service', data = `indirect key' */ 2050b25da7eSHajimu UMEMOTO killproto(&key); 2060b25da7eSHajimu UMEMOTO store(db, &key, &data, warndup); 2070b25da7eSHajimu UMEMOTO } 2080b25da7eSHajimu UMEMOTO sl_free(sl, 1); 2090b25da7eSHajimu UMEMOTO } 2100b25da7eSHajimu UMEMOTO 2110b25da7eSHajimu UMEMOTO static StringList *** 2120b25da7eSHajimu UMEMOTO parseservices(const char *fname, StringList *sl) 2130b25da7eSHajimu UMEMOTO { 2140b25da7eSHajimu UMEMOTO size_t len, line, pindex; 2150b25da7eSHajimu UMEMOTO FILE *fp; 2160b25da7eSHajimu UMEMOTO StringList ***svc, *s; 2170b25da7eSHajimu UMEMOTO char *p, *ep; 2180b25da7eSHajimu UMEMOTO 2190b25da7eSHajimu UMEMOTO if ((fp = fopen(fname, "r")) == NULL) 2200b25da7eSHajimu UMEMOTO err(1, "Cannot open `%s'", fname); 2210b25da7eSHajimu UMEMOTO 2220b25da7eSHajimu UMEMOTO line = 0; 2230b25da7eSHajimu UMEMOTO if ((svc = calloc(PMASK + 1, sizeof(StringList **))) == NULL) 224449c1612SHajimu UMEMOTO err(1, "Cannot allocate %zu bytes", (size_t)(PMASK + 1)); 2250b25da7eSHajimu UMEMOTO 2260b25da7eSHajimu UMEMOTO /* XXX: change NULL to "\0\0#" when fparseln fixed */ 2270b25da7eSHajimu UMEMOTO for (; (p = fparseln(fp, &len, &line, NULL, 0)) != NULL; free(p)) { 2280b25da7eSHajimu UMEMOTO char *name, *port, *proto, *aliases, *cp, *alias; 2290b25da7eSHajimu UMEMOTO unsigned long pnum; 2300b25da7eSHajimu UMEMOTO 2310b25da7eSHajimu UMEMOTO if (len == 0) 2320b25da7eSHajimu UMEMOTO continue; 2330b25da7eSHajimu UMEMOTO 2340b25da7eSHajimu UMEMOTO for (cp = p; *cp && isspace((unsigned char)*cp); cp++) 2350b25da7eSHajimu UMEMOTO continue; 2360b25da7eSHajimu UMEMOTO 2370b25da7eSHajimu UMEMOTO if (*cp == '\0' || *cp == '#') 2380b25da7eSHajimu UMEMOTO continue; 2390b25da7eSHajimu UMEMOTO 2400b25da7eSHajimu UMEMOTO if ((name = getstring(fname, line, &cp, "name")) == NULL) 2410b25da7eSHajimu UMEMOTO continue; 2420b25da7eSHajimu UMEMOTO 2430b25da7eSHajimu UMEMOTO if ((port = getstring(fname, line, &cp, "port")) == NULL) 2440b25da7eSHajimu UMEMOTO continue; 2450b25da7eSHajimu UMEMOTO 2460b25da7eSHajimu UMEMOTO if (cp) { 2470b25da7eSHajimu UMEMOTO for (aliases = cp; *cp && *cp != '#'; cp++) 2480b25da7eSHajimu UMEMOTO continue; 2490b25da7eSHajimu UMEMOTO 2500b25da7eSHajimu UMEMOTO if (*cp) 2510b25da7eSHajimu UMEMOTO *cp = '\0'; 2520b25da7eSHajimu UMEMOTO } else 2530b25da7eSHajimu UMEMOTO aliases = NULL; 2540b25da7eSHajimu UMEMOTO 2550b25da7eSHajimu UMEMOTO proto = strchr(port, '/'); 2560b25da7eSHajimu UMEMOTO if (proto == NULL || proto[1] == '\0') { 2570b25da7eSHajimu UMEMOTO warnx("%s, %zu: no protocol found", fname, line); 2580b25da7eSHajimu UMEMOTO continue; 2590b25da7eSHajimu UMEMOTO } 2600b25da7eSHajimu UMEMOTO *proto++ = '\0'; 2610b25da7eSHajimu UMEMOTO 2620b25da7eSHajimu UMEMOTO errno = 0; 2630b25da7eSHajimu UMEMOTO pnum = strtoul(port, &ep, 0); 2640b25da7eSHajimu UMEMOTO if (*port == '\0' || *ep != '\0') { 2650b25da7eSHajimu UMEMOTO warnx("%s, %zu: invalid port `%s'", fname, line, port); 2660b25da7eSHajimu UMEMOTO continue; 2670b25da7eSHajimu UMEMOTO } 2680b25da7eSHajimu UMEMOTO if ((errno == ERANGE && pnum == ULONG_MAX) || pnum > PMASK) { 2690b25da7eSHajimu UMEMOTO warnx("%s, %zu: port too big `%s'", fname, line, port); 2700b25da7eSHajimu UMEMOTO continue; 2710b25da7eSHajimu UMEMOTO } 2720b25da7eSHajimu UMEMOTO 2730b25da7eSHajimu UMEMOTO if (svc[pnum] == NULL) { 2740b25da7eSHajimu UMEMOTO svc[pnum] = calloc(PROTOMAX, sizeof(StringList *)); 2750b25da7eSHajimu UMEMOTO if (svc[pnum] == NULL) 276449c1612SHajimu UMEMOTO err(1, "Cannot allocate %zu bytes", 277449c1612SHajimu UMEMOTO (size_t)PROTOMAX); 2780b25da7eSHajimu UMEMOTO } 2790b25da7eSHajimu UMEMOTO 2800b25da7eSHajimu UMEMOTO pindex = getprotoindex(sl, proto); 2810b25da7eSHajimu UMEMOTO if (svc[pnum][pindex] == NULL) 2820b25da7eSHajimu UMEMOTO s = svc[pnum][pindex] = sl_init(); 2830b25da7eSHajimu UMEMOTO else 2840b25da7eSHajimu UMEMOTO s = svc[pnum][pindex]; 2850b25da7eSHajimu UMEMOTO 2860b25da7eSHajimu UMEMOTO /* build list of aliases */ 2870b25da7eSHajimu UMEMOTO if (sl_find(s, name) == NULL) { 2888812e23cSHajimu UMEMOTO char *p2; 2890b25da7eSHajimu UMEMOTO 2908812e23cSHajimu UMEMOTO if ((p2 = strdup(name)) == NULL) 2910b25da7eSHajimu UMEMOTO err(1, "Cannot copy string"); 2928812e23cSHajimu UMEMOTO (void)sl_add(s, p2); 2930b25da7eSHajimu UMEMOTO } 2940b25da7eSHajimu UMEMOTO 2950b25da7eSHajimu UMEMOTO if (aliases) { 2960b25da7eSHajimu UMEMOTO while ((alias = strsep(&aliases, " \t")) != NULL) { 2970b25da7eSHajimu UMEMOTO if (alias[0] == '\0') 2980b25da7eSHajimu UMEMOTO continue; 2990b25da7eSHajimu UMEMOTO if (sl_find(s, alias) == NULL) { 3008812e23cSHajimu UMEMOTO char *p2; 3010b25da7eSHajimu UMEMOTO 3028812e23cSHajimu UMEMOTO if ((p2 = strdup(alias)) == NULL) 3030b25da7eSHajimu UMEMOTO err(1, "Cannot copy string"); 3048812e23cSHajimu UMEMOTO (void)sl_add(s, p2); 3050b25da7eSHajimu UMEMOTO } 3060b25da7eSHajimu UMEMOTO } 3070b25da7eSHajimu UMEMOTO } 3080b25da7eSHajimu UMEMOTO } 3090b25da7eSHajimu UMEMOTO (void)fclose(fp); 3100b25da7eSHajimu UMEMOTO return svc; 3110b25da7eSHajimu UMEMOTO } 3120b25da7eSHajimu UMEMOTO 3130b25da7eSHajimu UMEMOTO /* 3140b25da7eSHajimu UMEMOTO * cleanup(): Remove temporary files upon exit 3150b25da7eSHajimu UMEMOTO */ 3160b25da7eSHajimu UMEMOTO static void 3170b25da7eSHajimu UMEMOTO cleanup(void) 3180b25da7eSHajimu UMEMOTO { 3190b25da7eSHajimu UMEMOTO if (tname[0]) 3200b25da7eSHajimu UMEMOTO (void)unlink(tname); 3210b25da7eSHajimu UMEMOTO } 3220b25da7eSHajimu UMEMOTO 3230b25da7eSHajimu UMEMOTO static char * 3240b25da7eSHajimu UMEMOTO getstring(const char *fname, size_t line, char **cp, const char *tag) 3250b25da7eSHajimu UMEMOTO { 3260b25da7eSHajimu UMEMOTO char *str; 3270b25da7eSHajimu UMEMOTO 3280b25da7eSHajimu UMEMOTO while ((str = strsep(cp, " \t")) != NULL && *str == '\0') 3290b25da7eSHajimu UMEMOTO continue; 3300b25da7eSHajimu UMEMOTO 3310b25da7eSHajimu UMEMOTO if (str == NULL) 3320b25da7eSHajimu UMEMOTO warnx("%s, %zu: no %s found", fname, line, tag); 3330b25da7eSHajimu UMEMOTO 3340b25da7eSHajimu UMEMOTO return str; 3350b25da7eSHajimu UMEMOTO } 3360b25da7eSHajimu UMEMOTO 3370b25da7eSHajimu UMEMOTO static void 3380b25da7eSHajimu UMEMOTO killproto(DBT *key) 3390b25da7eSHajimu UMEMOTO { 3400b25da7eSHajimu UMEMOTO char *p, *d = key->data; 3410b25da7eSHajimu UMEMOTO 3420b25da7eSHajimu UMEMOTO if ((p = strchr(d, '/')) == NULL) 3430b25da7eSHajimu UMEMOTO abort(); 3440b25da7eSHajimu UMEMOTO *p++ = '\0'; 3450b25da7eSHajimu UMEMOTO key->size = p - d; 3460b25da7eSHajimu UMEMOTO } 3470b25da7eSHajimu UMEMOTO 3480b25da7eSHajimu UMEMOTO static void 3490b25da7eSHajimu UMEMOTO store(DB *db, DBT *key, DBT *data, int warndup) 3500b25da7eSHajimu UMEMOTO { 3510b25da7eSHajimu UMEMOTO #ifdef DEBUG 3520b25da7eSHajimu UMEMOTO int k = key->size - 1; 3530b25da7eSHajimu UMEMOTO int d = data->size - 1; 3540b25da7eSHajimu UMEMOTO (void)printf("store [%*.*s] [%*.*s]\n", 3550b25da7eSHajimu UMEMOTO k, k, (char *)key->data + 1, 3560b25da7eSHajimu UMEMOTO d, d, (char *)data->data + 1); 3570b25da7eSHajimu UMEMOTO #endif 3580b25da7eSHajimu UMEMOTO switch ((db->put)(db, key, data, R_NOOVERWRITE)) { 3590b25da7eSHajimu UMEMOTO case 0: 3600b25da7eSHajimu UMEMOTO break; 3610b25da7eSHajimu UMEMOTO case 1: 3620b25da7eSHajimu UMEMOTO if (warndup) 3630b25da7eSHajimu UMEMOTO warnx("duplicate service `%s'", 3640b25da7eSHajimu UMEMOTO &((char *)key->data)[1]); 3650b25da7eSHajimu UMEMOTO break; 3660b25da7eSHajimu UMEMOTO case -1: 3670b25da7eSHajimu UMEMOTO err(1, "put"); 3680b25da7eSHajimu UMEMOTO break; 3690b25da7eSHajimu UMEMOTO default: 3700b25da7eSHajimu UMEMOTO abort(); 3710b25da7eSHajimu UMEMOTO break; 3720b25da7eSHajimu UMEMOTO } 3730b25da7eSHajimu UMEMOTO } 3740b25da7eSHajimu UMEMOTO 3750b25da7eSHajimu UMEMOTO static size_t 3760b25da7eSHajimu UMEMOTO getprotoindex(StringList *sl, const char *str) 3770b25da7eSHajimu UMEMOTO { 3780b25da7eSHajimu UMEMOTO size_t i; 3790b25da7eSHajimu UMEMOTO char *p; 3800b25da7eSHajimu UMEMOTO 3810b25da7eSHajimu UMEMOTO for (i= 0; i < sl->sl_cur; i++) 3820b25da7eSHajimu UMEMOTO if (strcmp(sl->sl_str[i], str) == 0) 3830b25da7eSHajimu UMEMOTO return i; 3840b25da7eSHajimu UMEMOTO 3850b25da7eSHajimu UMEMOTO if (i == PROTOMAX) 3860b25da7eSHajimu UMEMOTO errx(1, "Ran out of protocols adding `%s';" 3870b25da7eSHajimu UMEMOTO " recompile with larger PROTOMAX", str); 3880b25da7eSHajimu UMEMOTO if ((p = strdup(str)) == NULL) 3890b25da7eSHajimu UMEMOTO err(1, "Cannot copy string"); 3900b25da7eSHajimu UMEMOTO (void)sl_add(sl, p); 3910b25da7eSHajimu UMEMOTO return i; 3920b25da7eSHajimu UMEMOTO } 3930b25da7eSHajimu UMEMOTO 3940b25da7eSHajimu UMEMOTO static const char * 3950b25da7eSHajimu UMEMOTO getprotostr(StringList *sl, size_t i) 3960b25da7eSHajimu UMEMOTO { 3970b25da7eSHajimu UMEMOTO assert(i < sl->sl_cur); 3980b25da7eSHajimu UMEMOTO return sl->sl_str[i]; 3990b25da7eSHajimu UMEMOTO } 4000b25da7eSHajimu UMEMOTO 4010b25da7eSHajimu UMEMOTO static const char * 4020b25da7eSHajimu UMEMOTO mkaliases(StringList *sl, char *buf, size_t len) 4030b25da7eSHajimu UMEMOTO { 4040b25da7eSHajimu UMEMOTO size_t nc, i, pos; 4050b25da7eSHajimu UMEMOTO 4060b25da7eSHajimu UMEMOTO buf[0] = 0; 4070b25da7eSHajimu UMEMOTO for (i = 1, pos = 0; i < sl->sl_cur; i++) { 4080b25da7eSHajimu UMEMOTO nc = strlcpy(buf + pos, sl->sl_str[i], len); 4090b25da7eSHajimu UMEMOTO if (nc >= len) 4100b25da7eSHajimu UMEMOTO goto out; 4110b25da7eSHajimu UMEMOTO pos += nc; 4120b25da7eSHajimu UMEMOTO len -= nc; 4130b25da7eSHajimu UMEMOTO nc = strlcpy(buf + pos, " ", len); 4140b25da7eSHajimu UMEMOTO if (nc >= len) 4150b25da7eSHajimu UMEMOTO goto out; 4160b25da7eSHajimu UMEMOTO pos += nc; 4170b25da7eSHajimu UMEMOTO len -= nc; 4180b25da7eSHajimu UMEMOTO } 4190b25da7eSHajimu UMEMOTO return buf; 4200b25da7eSHajimu UMEMOTO out: 4210b25da7eSHajimu UMEMOTO warn("aliases for `%s' truncated", sl->sl_str[0]); 4220b25da7eSHajimu UMEMOTO return buf; 4230b25da7eSHajimu UMEMOTO } 4240b25da7eSHajimu UMEMOTO 4250b25da7eSHajimu UMEMOTO static void 4260b25da7eSHajimu UMEMOTO usage(void) 4270b25da7eSHajimu UMEMOTO { 4280b25da7eSHajimu UMEMOTO (void)fprintf(stderr, "Usage:\t%s [-q] [-o <db>] [<servicefile>]\n" 4290b25da7eSHajimu UMEMOTO "\t%s -u [<servicefile>]\n", getprogname(), getprogname()); 4300b25da7eSHajimu UMEMOTO exit(1); 4310b25da7eSHajimu UMEMOTO } 432