Second iteration of the code. It now uses cdbr_ / cdbw_ as prefixes to avoid unnecessary conflicts with DJB's library. It includes support for services_mkdb in the new format. The interface has been adjusted slightly to directly use a fd. The format has been adjusted slightly to include a human readable description of the file's purpose for tools like file(1). Remaining requestion is what to do with old statically linked binaries. I'm not too found of keeping the legacy support in services_mkdb and the old files remain valid. Comments? Joerg
Attachment:
cdb-services.tar.gz
Description: application/tar-gz
Index: distrib/sets/lists/base/ad.mips64eb =================================================================== RCS file: /home/joerg/repo/netbsd/src/distrib/sets/lists/base/ad.mips64eb,v retrieving revision 1.11 diff -u -p -r1.11 ad.mips64eb --- distrib/sets/lists/base/ad.mips64eb 8 Mar 2010 06:40:05 -0000 1.11 +++ distrib/sets/lists/base/ad.mips64eb 8 Mar 2010 22:00:05 -0000 @@ -62,7 +62,7 @@ ./usr/lib/64/libbz2.so.1 base-compat-shlib compat,pic ./usr/lib/64/libbz2.so.1.1 base-compat-shlib compat,pic ./usr/lib/64/libc.so.12 base-compat-shlib compat,pic -./usr/lib/64/libc.so.12.171 base-compat-shlib compat,pic +./usr/lib/64/libc.so.12.172 base-compat-shlib compat,pic ./usr/lib/64/libcom_err.so.6 base-compat-shlib compat,pic ./usr/lib/64/libcom_err.so.6.0 base-compat-shlib compat,pic ./usr/lib/64/libcrypt.so.1 base-compat-shlib compat,pic @@ -294,7 +294,7 @@ ./usr/lib/o32/libbz2.so.1 base-compat-shlib compat,pic ./usr/lib/o32/libbz2.so.1.1 base-compat-shlib compat,pic ./usr/lib/o32/libc.so.12 base-compat-shlib compat,pic -./usr/lib/o32/libc.so.12.171 base-compat-shlib compat,pic +./usr/lib/o32/libc.so.12.172 base-compat-shlib compat,pic ./usr/lib/o32/libcom_err.so.6 base-compat-shlib compat,pic ./usr/lib/o32/libcom_err.so.6.0 base-compat-shlib compat,pic ./usr/lib/o32/libcrypt.so.1 base-compat-shlib compat,pic Index: distrib/sets/lists/base/ad.mips64el =================================================================== RCS file: /home/joerg/repo/netbsd/src/distrib/sets/lists/base/ad.mips64el,v retrieving revision 1.11 diff -u -p -r1.11 ad.mips64el --- distrib/sets/lists/base/ad.mips64el 8 Mar 2010 06:40:05 -0000 1.11 +++ distrib/sets/lists/base/ad.mips64el 8 Mar 2010 22:00:05 -0000 @@ -62,7 +62,7 @@ ./usr/lib/64/libbz2.so.1 base-compat-shlib compat,pic ./usr/lib/64/libbz2.so.1.1 base-compat-shlib compat,pic ./usr/lib/64/libc.so.12 base-compat-shlib compat,pic -./usr/lib/64/libc.so.12.171 base-compat-shlib compat,pic +./usr/lib/64/libc.so.12.172 base-compat-shlib compat,pic ./usr/lib/64/libcom_err.so.6 base-compat-shlib compat,pic ./usr/lib/64/libcom_err.so.6.0 base-compat-shlib compat,pic ./usr/lib/64/libcrypt.so.1 base-compat-shlib compat,pic @@ -294,7 +294,7 @@ ./usr/lib/o32/libbz2.so.1 base-compat-shlib compat,pic ./usr/lib/o32/libbz2.so.1.1 base-compat-shlib compat,pic ./usr/lib/o32/libc.so.12 base-compat-shlib compat,pic -./usr/lib/o32/libc.so.12.171 base-compat-shlib compat,pic +./usr/lib/o32/libc.so.12.172 base-compat-shlib compat,pic ./usr/lib/o32/libcom_err.so.6 base-compat-shlib compat,pic ./usr/lib/o32/libcom_err.so.6.0 base-compat-shlib compat,pic ./usr/lib/o32/libcrypt.so.1 base-compat-shlib compat,pic Index: distrib/sets/lists/base/md.amd64 =================================================================== RCS file: /home/joerg/repo/netbsd/src/distrib/sets/lists/base/md.amd64,v retrieving revision 1.85 diff -u -p -r1.85 md.amd64 --- distrib/sets/lists/base/md.amd64 8 Mar 2010 06:40:06 -0000 1.85 +++ distrib/sets/lists/base/md.amd64 8 Mar 2010 22:00:05 -0000 @@ -65,7 +65,7 @@ ./usr/lib/i386/libbz2.so.1 base-compat-shlib compat,pic ./usr/lib/i386/libbz2.so.1.1 base-compat-shlib compat,pic ./usr/lib/i386/libc.so.12 base-compat-shlib compat,pic -./usr/lib/i386/libc.so.12.171 base-compat-shlib compat,pic +./usr/lib/i386/libc.so.12.172 base-compat-shlib compat,pic ./usr/lib/i386/libcom_err.so.6 base-compat-shlib compat,pic,kerberos ./usr/lib/i386/libcom_err.so.6.0 base-compat-shlib compat,pic,kerberos ./usr/lib/i386/libcrypt.so.1 base-compat-shlib compat,pic Index: distrib/sets/lists/base/md.sparc64 =================================================================== RCS file: /home/joerg/repo/netbsd/src/distrib/sets/lists/base/md.sparc64,v retrieving revision 1.78 diff -u -p -r1.78 md.sparc64 --- distrib/sets/lists/base/md.sparc64 8 Mar 2010 06:40:06 -0000 1.78 +++ distrib/sets/lists/base/md.sparc64 8 Mar 2010 22:00:05 -0000 @@ -63,7 +63,7 @@ ./usr/lib/sparc/libbz2.so.1 base-compat-shlib compat,pic ./usr/lib/sparc/libbz2.so.1.1 base-compat-shlib compat,pic ./usr/lib/sparc/libc.so.12 base-compat-shlib compat,pic -./usr/lib/sparc/libc.so.12.171 base-compat-shlib compat,pic +./usr/lib/sparc/libc.so.12.172 base-compat-shlib compat,pic ./usr/lib/sparc/libcom_err.so.6 base-compat-shlib compat,pic ./usr/lib/sparc/libcom_err.so.6.0 base-compat-shlib compat,pic ./usr/lib/sparc/libcrypt.so.1 base-compat-shlib compat,pic Index: distrib/sets/lists/base/shl.mi =================================================================== RCS file: /home/joerg/repo/netbsd/src/distrib/sets/lists/base/shl.mi,v retrieving revision 1.525 diff -u -p -r1.525 shl.mi --- distrib/sets/lists/base/shl.mi 8 Mar 2010 12:32:17 -0000 1.525 +++ distrib/sets/lists/base/shl.mi 8 Mar 2010 22:00:06 -0000 @@ -13,7 +13,7 @@ # # Note: libtermcap and libtermlib are hardlinked and share the same version. # -./lib/libc.so.12.171 base-sys-shlib dynamicroot +./lib/libc.so.12.172 base-sys-shlib dynamicroot ./lib/libcrypt.so.1.0 base-sys-shlib dynamicroot ./lib/libcrypto.so.6.1 base-crypto-shlib crypto,dynamicroot ./lib/libdevmapper.so.1.0 base-lvm-shlib lvm,dynamicroot @@ -63,7 +63,7 @@ ./usr/lib/libbluetooth.so.4.2 base-sys-shlib ./usr/lib/libbsdmalloc.so.0.0 base-sys-shlib ./usr/lib/libbz2.so.1.1 base-sys-shlib -./usr/lib/libc.so.12.171 base-sys-shlib +./usr/lib/libc.so.12.172 base-sys-shlib ./usr/lib/libcom_err.so.6.0 base-krb5-shlib kerberos ./usr/lib/libcrypt.so.1.0 base-sys-shlib ./usr/lib/libcrypto.so.6.1 base-crypto-shlib crypto Index: distrib/sets/lists/comp/mi =================================================================== RCS file: /home/joerg/repo/netbsd/src/distrib/sets/lists/comp/mi,v retrieving revision 1.1406 diff -u -p -r1.1406 mi --- distrib/sets/lists/comp/mi 8 Mar 2010 12:32:17 -0000 1.1406 +++ distrib/sets/lists/comp/mi 8 Mar 2010 22:00:07 -0000 @@ -191,6 +191,8 @@ ./usr/include/bluetooth.h comp-c-include ./usr/include/bm.h comp-c-include ./usr/include/bzlib.h comp-c-include +./usr/include/cdbr.h comp-c-include +./usr/include/cdbw.h comp-c-include ./usr/include/cdk/alphalist.h comp-obsolete obsolete ./usr/include/cdk/binding.h comp-obsolete obsolete ./usr/include/cdk/buttonbox.h comp-obsolete obsolete @@ -5208,6 +5210,18 @@ ./usr/share/man/cat3/ccosf.0 comp-c-catman .cat ./usr/share/man/cat3/ccosh.0 comp-c-catman .cat ./usr/share/man/cat3/ccoshf.0 comp-c-catman .cat +./usr/share/man/cat3/cdbr.0 comp-c-catman .cat +./usr/share/man/cat3/cdbr_close.0 comp-c-catman .cat +./usr/share/man/cat3/cdbr_find.0 comp-c-catman .cat +./usr/share/man/cat3/cdbr_get.0 comp-c-catman .cat +./usr/share/man/cat3/cdbr_open.0 comp-c-catman .cat +./usr/share/man/cat3/cdbw.0 comp-c-catman .cat +./usr/share/man/cat3/cdbw_close.0 comp-c-catman .cat +./usr/share/man/cat3/cdbw_output.0 comp-c-catman .cat +./usr/share/man/cat3/cdbw_put.0 comp-c-catman .cat +./usr/share/man/cat3/cdbw_put_data.0 comp-c-catman .cat +./usr/share/man/cat3/cdbw_put_key.0 comp-c-catman .cat +./usr/share/man/cat3/cdbw_open.0 comp-c-catman .cat ./usr/share/man/cat3/cdk.0 comp-obsolete obsolete ./usr/share/man/cat3/cdk_alphalist.0 comp-obsolete obsolete ./usr/share/man/cat3/cdk_binding.0 comp-obsolete obsolete @@ -11023,6 +11037,18 @@ ./usr/share/man/html3/ccosf.html comp-c-htmlman html ./usr/share/man/html3/ccosh.html comp-c-htmlman html ./usr/share/man/html3/ccoshf.html comp-c-htmlman html +./usr/share/man/html3/cdbr.html comp-c-htmlman html +./usr/share/man/html3/cdbr_close.html comp-c-htmlman html +./usr/share/man/html3/cdbr_find.html comp-c-htmlman html +./usr/share/man/html3/cdbr_get.html comp-c-htmlman html +./usr/share/man/html3/cdbr_open.html comp-c-htmlman html +./usr/share/man/html3/cdbw.html comp-c-htmlman html +./usr/share/man/html3/cdbw_close.html comp-c-htmlman html +./usr/share/man/html3/cdbw_output.html comp-c-htmlman html +./usr/share/man/html3/cdbw_put.html comp-c-htmlman html +./usr/share/man/html3/cdbw_put_data.html comp-c-htmlman html +./usr/share/man/html3/cdbw_put_key.html comp-c-htmlman html +./usr/share/man/html3/cdbw_open.html comp-c-htmlman html ./usr/share/man/html3/ceil.html comp-c-htmlman html ./usr/share/man/html3/ceilf.html comp-c-htmlman html ./usr/share/man/html3/cexp.html comp-c-htmlman html @@ -13843,7 +13869,7 @@ ./usr/share/man/html3/towctrans.html comp-c-htmlman html ./usr/share/man/html3/towlower.html comp-c-htmlman html ./usr/share/man/html3/towupper.html comp-c-htmlman html -./usr/share/man/html3/tparm.html comp-c-catman html +./usr/share/man/html3/tparm.html comp-c-htmlman html ./usr/share/man/html3/tputs.html comp-c-htmlman html ./usr/share/man/html3/tree.html comp-c-htmlman html ./usr/share/man/html3/trunc.html comp-c-htmlman html @@ -16660,6 +16686,18 @@ ./usr/share/man/man3/ccosf.3 comp-c-man .man ./usr/share/man/man3/ccosh.3 comp-c-man .man ./usr/share/man/man3/ccoshf.3 comp-c-man .man +./usr/share/man/man3/cdbr.3 comp-c-man .man +./usr/share/man/man3/cdbr_close.3 comp-c-man .man +./usr/share/man/man3/cdbr_find.3 comp-c-man .man +./usr/share/man/man3/cdbr_get.3 comp-c-man .man +./usr/share/man/man3/cdbr_open.3 comp-c-man .man +./usr/share/man/man3/cdbw.3 comp-c-man .man +./usr/share/man/man3/cdbw_close.3 comp-c-man .man +./usr/share/man/man3/cdbw_output.3 comp-c-man .man +./usr/share/man/man3/cdbw_put.3 comp-c-man .man +./usr/share/man/man3/cdbw_put_data.3 comp-c-man .man +./usr/share/man/man3/cdbw_put_key.3 comp-c-man .man +./usr/share/man/man3/cdbw_open.3 comp-c-man .man ./usr/share/man/man3/cdk.3 comp-obsolete obsolete ./usr/share/man/man3/cdk_alphalist.3 comp-obsolete obsolete ./usr/share/man/man3/cdk_binding.3 comp-obsolete obsolete Index: distrib/sets/lists/man/mi =================================================================== RCS file: /home/joerg/repo/netbsd/src/distrib/sets/lists/man/mi,v retrieving revision 1.1197 diff -u -p -r1.1197 mi --- distrib/sets/lists/man/mi 8 Mar 2010 06:40:07 -0000 1.1197 +++ distrib/sets/lists/man/mi 8 Mar 2010 22:00:08 -0000 @@ -1741,6 +1741,7 @@ ./usr/share/man/cat5/bounce.0 man-postfix-catman postfix,.cat ./usr/share/man/cat5/canonical.0 man-postfix-catman postfix,.cat ./usr/share/man/cat5/ccd.conf.0 man-sysutil-catman .cat +./usr/share/man/cat5/cdb.0 man-sys-catman .cat ./usr/share/man/cat5/cidr_table.0 man-postfix-catman postfix,.cat ./usr/share/man/cat5/core.0 man-sys-catman .cat ./usr/share/man/cat5/crontab.0 man-cron-catman .cat @@ -4310,6 +4311,7 @@ ./usr/share/man/html5/bounce.html man-postfix-htmlman postfix,html ./usr/share/man/html5/canonical.html man-postfix-htmlman postfix,html ./usr/share/man/html5/ccd.conf.html man-sysutil-htmlman html +./usr/share/man/html5/cdb.html man-sys-htmlman html ./usr/share/man/html5/cidr_table.html man-postfix-htmlman postfix,html ./usr/share/man/html5/core.html man-sys-htmlman html ./usr/share/man/html5/crontab.html man-cron-htmlman html @@ -6819,6 +6821,7 @@ ./usr/share/man/man5/bounce.5 man-postfix-man postfix,.man ./usr/share/man/man5/canonical.5 man-postfix-man postfix,.man ./usr/share/man/man5/ccd.conf.5 man-sysutil-man .man +./usr/share/man/man5/cdb.5 man-sys-man .man ./usr/share/man/man5/cidr_table.5 man-postfix-man postfix,.man ./usr/share/man/man5/core.5 man-sys-man .man ./usr/share/man/man5/crontab.5 man-cron-man .man Index: include/Makefile =================================================================== RCS file: /home/joerg/repo/netbsd/src/include/Makefile,v retrieving revision 1.131 diff -u -p -r1.131 Makefile --- include/Makefile 28 May 2008 12:28:12 -0000 1.131 +++ include/Makefile 7 Mar 2010 21:23:03 -0000 @@ -8,7 +8,7 @@ NOOBJ= # defined # Missing: mp.h INCS= a.out.h aio.h ar.h assert.h atomic.h \ - bitstring.h bm.h complex.h cpio.h ctype.h \ + bitstring.h bm.h cdbr.h cdbw.h complex.h cpio.h ctype.h \ db.h dirent.h disktab.h dlfcn.h err.h errno.h fmtmsg.h fnmatch.h \ fstab.h fts.h ftw.h getopt.h glob.h grp.h ifaddrs.h iconv.h \ inttypes.h iso646.h kvm.h langinfo.h libgen.h \ Index: include/netdb.h =================================================================== RCS file: /home/joerg/repo/netbsd/src/include/netdb.h,v retrieving revision 1.62 diff -u -p -r1.62 netdb.h --- include/netdb.h 2 Oct 2009 02:45:29 -0000 1.62 +++ include/netdb.h 8 Mar 2010 20:45:55 -0000 @@ -126,7 +126,7 @@ typedef _BSD_SIZE_T_ size_t; #define _PATH_SERVICES "/etc/services" #endif #ifndef _PATH_SERVICES_DB -#define _PATH_SERVICES_DB "/var/db/services.db" +#define _PATH_SERVICES_DB "/var/db/services.cdb" #endif #endif Index: lib/libc/Makefile =================================================================== RCS file: /home/joerg/repo/netbsd/src/lib/libc/Makefile,v retrieving revision 1.140 diff -u -p -r1.140 Makefile --- lib/libc/Makefile 6 Dec 2009 12:56:59 -0000 1.140 +++ lib/libc/Makefile 7 Mar 2010 21:31:52 -0000 @@ -55,6 +55,7 @@ COMPATDIR=${.CURDIR}/compat .include "${.CURDIR}/../../common/lib/libc/Makefile.inc" .include "${.CURDIR}/atomic/Makefile.inc" +.include "${.CURDIR}/cdb/Makefile.inc" .include "${.CURDIR}/db/Makefile.inc" .include "${.CURDIR}/citrus/Makefile.inc" .include "${.CURDIR}/compat-43/Makefile.inc" Index: lib/libc/shlib_version =================================================================== RCS file: /home/joerg/repo/netbsd/src/lib/libc/shlib_version,v retrieving revision 1.215 diff -u -p -r1.215 shlib_version --- lib/libc/shlib_version 2 Oct 2009 02:45:29 -0000 1.215 +++ lib/libc/shlib_version 7 Mar 2010 22:30:32 -0000 @@ -35,4 +35,4 @@ # it's insufficient bitwidth to implement all ctype class. # see isblank's comment in ctype.h. major=12 -minor=171 +minor=172 Index: lib/libc/net/getservbyname_r.c =================================================================== RCS file: /home/joerg/repo/netbsd/src/lib/libc/net/getservbyname_r.c,v retrieving revision 1.6 diff -u -p -r1.6 getservbyname_r.c --- lib/libc/net/getservbyname_r.c 21 Mar 2007 02:35:39 -0000 1.6 +++ lib/libc/net/getservbyname_r.c 9 Mar 2010 03:02:44 -0000 @@ -40,10 +40,10 @@ __RCSID("$NetBSD: getservbyname_r.c,v 1. #include "namespace.h" #include <assert.h> +#include <cdbr.h> #include <netdb.h> #include <stdlib.h> #include <string.h> -#include <db.h> #include "servent.h" @@ -55,33 +55,62 @@ static struct servent * _servent_getbyname(struct servent_data *sd, struct servent *sp, const char *name, const char *proto) { - if (sd->db == NULL) + + if ((sd->flags & (_SV_CDB | _SV_PLAINFILE)) == 0) return NULL; - if (sd->flags & _SV_DB) { - char buf[BUFSIZ]; - DBT key, data; - DB *db = sd->db; - key.data = buf; + if (sd->flags & _SV_CDB) { + uint8_t buf[255 * 2 + 2]; + size_t namelen, protolen; + const uint8_t *data, *data_end; + const void *data_ptr; + size_t datalen; - if (proto == NULL) - key.size = snprintf(buf, sizeof(buf), "\376%s", name); - else - key.size = snprintf(buf, sizeof(buf), "\376%s/%s", - name, proto); - key.size++; - - if ((*db->get)(db, &key, &data, 0) != 0) + namelen = strlen(name); + if (namelen == 0 || namelen > 255) + return NULL; + if (proto != NULL && *proto == '\0') return NULL; + if (proto != NULL) + protolen = strlen(proto); + else + protolen = 0; + + buf[0] = namelen; + buf[1] = protolen; + memcpy(buf + 2, name, namelen); + memcpy(buf + 2 + namelen, proto, protolen); - if ((*db->get)(db, &data, &key, 0) != 0) + if (cdbr_find(sd->cdb, buf, 2 + namelen + protolen, + &data_ptr, &datalen)) return NULL; - if (sd->line) - free(sd->line); + if (datalen < namelen + protolen + 6) + return NULL; - sd->line = strdup(key.data); - return _servent_parseline(sd, sp); + data = data_ptr; + data_end = data + datalen; + if (protolen) { + if (data[2] != protolen) + return NULL; + if (memcmp(data + 3, proto, protolen + 1)) + return NULL; + } + data += 3 + data[2] + 1; + if (data > data_end) + return NULL; + while (data != data_end) { + if (*data == '\0') + return NULL; + if (data + data[0] + 2 > data_end) + return NULL; + if (data[0] == namelen && + memcmp(data + 1, name, namelen + 1) == 0) + return _servent_parsedb(sd, sp, data_ptr, + datalen); + data += data[0] + 2; + } + return NULL; } else { while (_servent_getline(sd) != -1) { char **cp; Index: lib/libc/net/getservbyport_r.c =================================================================== RCS file: /home/joerg/repo/netbsd/src/lib/libc/net/getservbyport_r.c,v retrieving revision 1.6 diff -u -p -r1.6 getservbyport_r.c --- lib/libc/net/getservbyport_r.c 21 Mar 2007 02:35:39 -0000 1.6 +++ lib/libc/net/getservbyport_r.c 9 Mar 2010 02:57:46 -0000 @@ -39,11 +39,10 @@ __RCSID("$NetBSD: getservbyport_r.c,v 1. #endif /* LIBC_SCCS and not lint */ #include "namespace.h" -#include <stdio.h> +#include <cdbr.h> #include <netdb.h> #include <string.h> #include <stdlib.h> -#include <db.h> #include "servent.h" @@ -55,34 +54,51 @@ static struct servent * _servent_getbyport(struct servent_data *sd, struct servent *sp, int port, const char *proto) { - if (sd->db == NULL) + + if ((sd->flags & (_SV_CDB | _SV_PLAINFILE)) == 0) return NULL; - if (sd->flags & _SV_DB) { - char buf[BUFSIZ]; - DBT key, data; - DB *db = sd->db; - key.data = buf; - - port = htons(port); - if (proto == NULL) - key.size = snprintf(buf, sizeof(buf), "\377%d", port); + if (sd->flags & _SV_CDB) { + uint8_t buf[255 + 4]; + size_t protolen; + const uint8_t *data, *data_end; + const void *data_ptr; + size_t datalen; + + port = be16toh(port); + + if (proto != NULL && *proto == '\0') + return NULL; + if (proto != NULL) + protolen = strlen(proto); else - key.size = snprintf(buf, sizeof(buf), "\377%d/%s", port, - proto); - key.size++; - - if ((*db->get)(db, &key, &data, 0) != 0) + protolen = 0; + if (port < 0 || port > 65536) return NULL; - if ((*db->get)(db, &data, &key, 0) != 0) + buf[0] = 0; + buf[1] = protolen; + be16enc(buf + 2, port); + memcpy(buf + 4, proto, protolen); + + if (cdbr_find(sd->cdb, buf, 4 + protolen, + &data_ptr, &datalen)) return NULL; - if (sd->line) - free(sd->line); + if (datalen < protolen + 4) + return NULL; - sd->line = strdup(key.data); - return _servent_parseline(sd, sp); + data = data_ptr; + data_end = data + datalen; + if (be16dec(data) != port) + return NULL; + if (protolen) { + if (data[2] != protolen) + return NULL; + if (memcmp(data + 3, proto, protolen + 1)) + return NULL; + } + return _servent_parsedb(sd, sp, data, datalen); } else { while (_servent_getline(sd) != -1) { if (_servent_parseline(sd, sp) == NULL) Index: lib/libc/net/getservent_r.c =================================================================== RCS file: /home/joerg/repo/netbsd/src/lib/libc/net/getservent_r.c,v retrieving revision 1.9 diff -u -p -r1.9 getservent_r.c --- lib/libc/net/getservent_r.c 6 Jan 2008 16:34:18 -0000 1.9 +++ lib/libc/net/getservent_r.c 9 Mar 2010 03:18:39 -0000 @@ -39,13 +39,13 @@ __RCSID("$NetBSD: getservent_r.c,v 1.9 2 #endif /* LIBC_SCCS and not lint */ #include "namespace.h" -#include <netdb.h> +#include <cdbr.h> #include <errno.h> +#include <fcntl.h> +#include <netdb.h> #include <stdio.h> -#include <string.h> #include <stdlib.h> -#include <fcntl.h> -#include <db.h> +#include <string.h> #include "servent.h" @@ -58,27 +58,41 @@ __weak_alias(setservent_r,_setservent_r) int _servent_open(struct servent_data *sd) { + sd->line = NULL; + sd->cdb_buf = NULL; + sd->aliases = NULL; + sd->maxaliases = 0; sd->flags |= _SV_FIRST; - if (sd->db == NULL) { - if ((sd->db = dbopen(_PATH_SERVICES_DB, O_RDONLY, 0, - DB_HASH, NULL)) != NULL) - sd->flags |= _SV_DB; - else - sd->db = fopen(_PATH_SERVICES, "r"); + if (sd->flags & (_SV_CDB | _SV_PLAINFILE)) + return 0; + + sd->cdb = cdbr_open(_PATH_SERVICES_DB, CDBR_DEFAULT); + if (sd->cdb != NULL) { + sd->flags |= _SV_CDB; + return 0; } - return sd->db ? 0 : -1; + + sd->plainfile = fopen(_PATH_SERVICES, "r"); + if (sd->plainfile != NULL) { + sd->flags |= _SV_PLAINFILE; + return 0; + } + return -1; } void _servent_close(struct servent_data *sd) { - if (sd->db) { - if (sd->flags & _SV_DB) { - DB *db = sd->db; - (*db->close)(db); - } else - (void)fclose((FILE *)sd->db); - sd->db = NULL; + if (sd->flags & _SV_CDB) { + cdbr_close(sd->cdb); + sd->cdb = NULL; + sd->flags &= ~_SV_CDB; + } + + if (sd->flags & _SV_PLAINFILE) { + (void)fclose(sd->plainfile); + sd->plainfile = NULL; + sd->flags &= ~_SV_PLAINFILE; } sd->flags &= ~_SV_STAYOPEN; } @@ -87,42 +101,25 @@ _servent_close(struct servent_data *sd) int _servent_getline(struct servent_data *sd) { - if (sd->line) { - free(sd->line); - sd->line = NULL; - } - if (sd->db == NULL) + if (sd->flags & _SV_CDB) return -1; - if (sd->flags & _SV_DB) { - DB *db = sd->db; - DBT key, data; - u_int flags = (sd->flags & _SV_FIRST) ? R_FIRST : R_NEXT; - - while ((*db->seq)(db, &key, &data, flags) == 0) { - flags = R_NEXT; - switch (((u_char *)key.data)[0]) { - case (u_char)'\377': - case (u_char)'\376': - continue; - default: - break; - } - sd->line = strdup(data.data); - break; - } - } else { - if (sd->flags & _SV_FIRST) - (void)rewind((FILE *)sd->db); - sd->line = fparseln((FILE *)sd->db, NULL, NULL, NULL, - FPARSELN_UNESCALL); + if ((sd->flags & _SV_PLAINFILE) == 0) + return -1; + + free(sd->line); + sd->line = NULL; + + if (sd->flags & _SV_FIRST) { + (void)rewind((FILE *)sd->plainfile); + sd->flags &= ~_SV_FIRST; } - sd->flags &= ~_SV_FIRST; + sd->line = fparseln(sd->plainfile, NULL, NULL, NULL, + FPARSELN_UNESCALL); return sd->line == NULL ? -1 : 0; } - struct servent * _servent_parseline(struct servent_data *sd, struct servent *sp) { @@ -156,7 +153,7 @@ _servent_parseline(struct servent_data * return NULL; } } - q = sp->s_aliases = sd->aliases; + sp->s_aliases = sd->aliases; cp = strpbrk(cp, " \t"); if (cp != NULL) *cp++ = '\0'; @@ -167,7 +164,7 @@ _servent_parseline(struct servent_data * } if (i == sd->maxaliases - 2) { sd->maxaliases *= 2; - q = realloc(q, + q = realloc(sd->aliases, sd->maxaliases * sizeof(char *)); if (q == NULL) { oerrno = errno; @@ -177,12 +174,12 @@ _servent_parseline(struct servent_data * } sp->s_aliases = sd->aliases = q; } - q[i++] = cp; + sp->s_aliases[i++] = cp; cp = strpbrk(cp, " \t"); if (cp != NULL) *cp++ = '\0'; } - q[i] = NULL; + sp->s_aliases[i] = NULL; return sp; } @@ -197,28 +194,121 @@ void endservent_r(struct servent_data *sd) { _servent_close(sd); - if (sd->aliases) { - free(sd->aliases); - sd->aliases = NULL; - sd->maxaliases = 0; - } - if (sd->line) { - free(sd->line); - sd->line = NULL; - } + free(sd->aliases); + sd->aliases = NULL; + sd->maxaliases = 0; + free(sd->line); + sd->line = NULL; + free(sd->cdb_buf); + sd->cdb_buf = NULL; } struct servent * getservent_r(struct servent *sp, struct servent_data *sd) { - if (sd->db == NULL && _servent_open(sd) == -1) + + if ((sd->flags & (_SV_CDB | _SV_PLAINFILE)) == 0 && + _servent_open(sd) == -1) return NULL; - for (;;) { - if (_servent_getline(sd) == -1) + if (sd->flags & _SV_CDB) { + const void *data; + size_t len; + + if (sd->flags & _SV_FIRST) { + sd->cdb_index = 0; + sd->flags &= ~_SV_FIRST; + } + + if (cdbr_get(sd->cdb, sd->cdb_index, &data, &len)) return NULL; - if (_servent_parseline(sd, sp) == NULL) - continue; - return sp; + ++sd->cdb_index; + return _servent_parsedb(sd, sp, data, len); } + if (sd->flags & _SV_PLAINFILE) { + for (;;) { + if (_servent_getline(sd) == -1) + return NULL; + if (_servent_parseline(sd, sp) == NULL) + continue; + return sp; + } + } + return NULL; +} + +struct servent * +_servent_parsedb(struct servent_data *sd, struct servent *sp, + const uint8_t *data, size_t len) +{ + char **q; + size_t i; + int oerrno; + + if ((sd->flags & _SV_STAYOPEN) == 0) { + free(sd->cdb_buf); + sd->cdb_buf = malloc(len); + if (sd->cdb_buf == NULL) + goto fail; + memcpy(sd->cdb_buf, data, len); + data = sd->cdb_buf; + } + + if (len < 2) + goto fail; + sp->s_port = data[1] * 256 + data[0]; + data += 2; + len -= 2; + + if (len == 0 || len < (size_t)data[0] + 2) + goto fail; + sp->s_proto = __UNCONST(data + 1); + + if (sp->s_proto[data[0]] != '\0') + goto fail; + + len -= 2 + data[0]; + data += 2 + data[0]; + + if (len == 0) + goto fail; + if (len < (size_t)data[0] + 2) + goto fail; + + sp->s_name = __UNCONST(data + 1); + len -= 2 + data[0]; + data += 2 + data[0]; + + if (sd->aliases == NULL) { + sd->maxaliases = 10; + sd->aliases = malloc(sd->maxaliases * sizeof(char *)); + if (sd->aliases == NULL) + goto fail; + } + sp->s_aliases = sd->aliases; + i = 0; + while (len) { + if (len < (size_t)data[0] + 2) + goto fail; + if (i == sd->maxaliases - 2) { + sd->maxaliases *= 2; + q = realloc(sd->aliases, + sd->maxaliases * sizeof(char *)); + if (q == NULL) + goto fail; + sp->s_aliases = sd->aliases = q; + } + sp->s_aliases[i++] = __UNCONST(data + 1); + len -= 2 + data[0]; + data += 2 + data[0]; + } + sp->s_aliases[i] = NULL; + return sp; + +fail: + oerrno = errno; + endservent_r(sd); + errno = oerrno; + return NULL; } + Index: lib/libc/net/servent.h =================================================================== RCS file: /home/joerg/repo/netbsd/src/lib/libc/net/servent.h,v retrieving revision 1.3 diff -u -p -r1.3 servent.h --- lib/libc/net/servent.h 28 Apr 2008 20:23:00 -0000 1.3 +++ lib/libc/net/servent.h 9 Mar 2010 02:49:55 -0000 @@ -32,14 +32,18 @@ #include <stdio.h> struct servent_data { - void *db; + FILE *plainfile; + struct cdbr *cdb; struct servent serv; char **aliases; size_t maxaliases; int flags; #define _SV_STAYOPEN 1 -#define _SV_DB 2 -#define _SV_FIRST 4 +#define _SV_CDB 2 +#define _SV_PLAINFILE 4 +#define _SV_FIRST 8 + uint32_t cdb_index; + uint8_t *cdb_buf; char *line; void *dummy; }; @@ -56,3 +60,5 @@ int _servent_open(struct servent_data *) void _servent_close(struct servent_data *); int _servent_getline(struct servent_data *); struct servent *_servent_parseline(struct servent_data *, struct servent *); +struct servent *_servent_parsedb(struct servent_data *, struct servent *, + const uint8_t *, size_t); Index: usr.sbin/services_mkdb/services_mkdb.c =================================================================== RCS file: /home/joerg/repo/netbsd/src/usr.sbin/services_mkdb/services_mkdb.c,v retrieving revision 1.14 diff -u -p -r1.14 services_mkdb.c --- usr.sbin/services_mkdb/services_mkdb.c 28 Apr 2008 20:24:17 -0000 1.14 +++ usr.sbin/services_mkdb/services_mkdb.c 8 Mar 2010 21:43:29 -0000 @@ -37,7 +37,7 @@ __RCSID("$NetBSD: services_mkdb.c,v 1.14 #include <sys/param.h> #include <assert.h> -#include <db.h> +#include <cdbw.h> #include <err.h> #include <fcntl.h> #include <netdb.h> @@ -57,31 +57,20 @@ static char tname[MAXPATHLEN]; extern void uniq(const char *); -static void add(DB *, StringList *, size_t, const char *, size_t *, int); +static void add(StringList *, size_t, const char *, size_t *, int); static StringList ***parseservices(const char *, StringList *); static void cleanup(void); -static void store(DB *, DBT *, DBT *, int); -static void killproto(DBT *); static char *getstring(const char *, size_t, char **, const char *); static size_t getprotoindex(StringList *, const char *); static const char *getprotostr(StringList *, size_t); -static const char *mkaliases(StringList *, char *, size_t); static void usage(void) __dead; -const HASHINFO hinfo = { - .bsize = 256, - .ffactor = 4, - .nelem = 32768, - .cachesize = 1024, - .hash = NULL, - .lorder = 0 -}; - +struct cdbw *cdbw; int main(int argc, char *argv[]) { - DB *db; + int output; int ch; const char *fname = _PATH_SERVICES; const char *dbname = _PATH_SERVICES_DB; @@ -129,11 +118,13 @@ main(int argc, char *argv[]) err(1, "Cannot install exit handler"); (void)snprintf(tname, sizeof(tname), "%s.tmp", dbname); - db = dbopen(tname, O_RDWR | O_CREAT | O_EXCL, - (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH), DB_HASH, &hinfo); - if (!db) + output = open(tname, O_WRONLY | O_CREAT | O_TRUNC, 0666); + if (output == -1) err(1, "Error opening temporary database `%s'", tname); + cdbw = cdbw_open(); + if (cdbw == NULL) + err(1, "Error opening cdb writer"); for (port = 0; port < PMASK + 1; port++) { if (svc[port] == NULL) @@ -143,7 +134,7 @@ main(int argc, char *argv[]) StringList *s; if ((s = svc[port][proto]) == NULL) continue; - add(db, s, port, getprotostr(sl, proto), &cnt, warndup); + add(s, port, getprotostr(sl, proto), &cnt, warndup); } free(svc[port]); @@ -152,7 +143,13 @@ main(int argc, char *argv[]) free(svc); sl_free(sl, 1); - if ((db->close)(db)) + if (cdbw_output(cdbw, output, "/etc/services", NULL)) { + err(1, "Error computing temporary database `%s'", tname); + } + + cdbw_close(cdbw); + + if (close(output)) err(1, "Error closing temporary database `%s'", tname); if (rename(tname, dbname) == -1) @@ -162,14 +159,14 @@ main(int argc, char *argv[]) } static void -add(DB *db, StringList *sl, size_t port, const char *proto, size_t *cnt, +add(StringList *sl, size_t port, const char *proto, size_t *cnt, int warndup) { + uint8_t key[255 * 2 + 2]; + uint8_t *data, *data_iter; + size_t len, protolen, datalen, keylen; + uint32_t idx; size_t i; - char keyb[BUFSIZ], datab[BUFSIZ], abuf[BUFSIZ]; - DBT data, key; - key.data = keyb; - data.data = datab; #ifdef DEBUG (void)printf("add %s %zu %s [ ", sl->sl_str[0], port, proto); @@ -178,32 +175,68 @@ add(DB *db, StringList *sl, size_t port, (void)printf("]\n"); #endif - /* key `indirect key', data `full line' */ - data.size = snprintf(datab, sizeof(datab), "%zu", (*cnt)++) + 1; - key.size = snprintf(keyb, sizeof(keyb), "%s %zu/%s %s", - sl->sl_str[0], port, proto, mkaliases(sl, abuf, sizeof(abuf))) + 1; - store(db, &data, &key, warndup); - - /* key `\377port/proto', data = `indirect key' */ - key.size = snprintf(keyb, sizeof(keyb), "\377%zu/%s", - port, proto) + 1; - store(db, &key, &data, warndup); - - /* key `\377port', data = `indirect key' */ - killproto(&key); - store(db, &key, &data, warndup); + protolen = strlen(proto); + if (protolen == 0 || protolen > 255) + errx(1, "Invalid protocol ``%s'', entry skipped", proto); + + datalen = 4 + protolen; + for (i = 0; i < sl->sl_cur; ++i) { + len = strlen(sl->sl_str[i]); + if (len == 0 || len > 255) + errx(1, "Service alias ``%s'' invalid", sl->sl_str[i]); + datalen += len + 2; + } + + data = malloc(datalen); + if (data == NULL) + err(1, "malloc failed"); + be16enc(data, port); + data[2] = protolen; + data_iter = data + 3; + memcpy(data_iter, proto, protolen + 1); + data_iter += protolen + 1; + for (i = 0; i < sl->sl_cur; ++i) { + len = strlen(sl->sl_str[i]); + *data_iter++ = len; + memcpy(data_iter, sl->sl_str[i], len + 1); + data_iter += len + 1; + } + + if (cdbw_put_data(cdbw, data, datalen, &idx)) + err(1, "cdbw_put_data failed"); + + free(data); + + key[0] = 0; + key[1] = protolen; + be16enc(key + 2, port); + memcpy(key + 4, proto, protolen); + keylen = 4 + protolen; + if (cdbw_put_key(cdbw, key, keylen, idx) && warndup) + warnx("duplicate service: `%ju/%s'", port, proto); + + key[1] = 0; + keylen = 4; + if (cdbw_put_key(cdbw, key, keylen, idx) && warndup) + warnx("duplicate service: `%ju'", port); /* add references for service and all aliases */ for (i = 0; i < sl->sl_cur; i++) { - /* key `\376service/proto', data = `indirect key' */ - key.size = snprintf(keyb, sizeof(keyb), "\376%s/%s", - sl->sl_str[i], proto) + 1; - store(db, &key, &data, warndup); - - /* key `\376service', data = `indirect key' */ - killproto(&key); - store(db, &key, &data, warndup); + len = strlen(sl->sl_str[i]); + key[0] = len; + key[1] = protolen; + memcpy(key + 2, sl->sl_str[i], len); + memcpy(key + 2 + len, proto, protolen); + keylen = 2 + len + protolen; + if (cdbw_put_key(cdbw, key, keylen, idx) && warndup) + warnx("duplicate service: `%s/%s'", sl->sl_str[i], proto); + + key[1] = 0; + keylen = 2 + len; + if (cdbw_put_key(cdbw, key, keylen, idx) && warndup) + warnx("duplicate service: `%s'", sl->sl_str[i]); } + sl_free(sl, 1); } @@ -276,7 +309,13 @@ parseservices(const char *fname, StringL s = svc[pnum][pindex] = sl_init(); else s = svc[pnum][pindex]; - + + if (strlen(name) > 255) { + warnx("%s, %zu: invalid name too long `%s'", fname, + line, name); + continue; + } + /* build list of aliases */ if (sl_find(s, name) == NULL) (void)sl_add(s, estrdup(name)); @@ -285,6 +324,11 @@ parseservices(const char *fname, StringL while ((alias = strsep(&aliases, " \t")) != NULL) { if (alias[0] == '\0') continue; + if (strlen(alias) > 255) { + warnx("%s, %zu: alias name too long `%s'", + fname, line, alias); + continue; + } if (sl_find(s, alias) == NULL) (void)sl_add(s, estrdup(alias)); } @@ -318,44 +362,6 @@ getstring(const char *fname, size_t line return str; } -static void -killproto(DBT *key) -{ - char *p, *d = key->data; - - if ((p = strchr(d, '/')) == NULL) - abort(); - *p++ = '\0'; - key->size = p - d; -} - -static void -store(DB *db, DBT *key, DBT *data, int warndup) -{ -#ifdef DEBUG - int k = key->size - 1; - int d = data->size - 1; - (void)printf("store [%*.*s] [%*.*s]\n", - k, k, (char *)key->data + 1, - d, d, (char *)data->data + 1); -#endif - switch ((db->put)(db, key, data, R_NOOVERWRITE)) { - case 0: - break; - case 1: - if (warndup) - warnx("duplicate service `%s'", - &((char *)key->data)[1]); - break; - case -1: - err(1, "put"); - break; - default: - abort(); - break; - } -} - static size_t getprotoindex(StringList *sl, const char *str) { @@ -379,30 +385,6 @@ getprotostr(StringList *sl, size_t i) return sl->sl_str[i]; } -static const char * -mkaliases(StringList *sl, char *buf, size_t len) -{ - size_t nc, i, pos; - - buf[0] = 0; - for (i = 1, pos = 0; i < sl->sl_cur; i++) { - nc = strlcpy(buf + pos, sl->sl_str[i], len); - if (nc >= len) - goto out; - pos += nc; - len -= nc; - nc = strlcpy(buf + pos, " ", len); - if (nc >= len) - goto out; - pos += nc; - len -= nc; - } - return buf; -out: - warn("aliases for `%s' truncated", sl->sl_str[0]); - return buf; -} - static void usage(void) { Index: usr.sbin/services_mkdb/uniq.c =================================================================== RCS file: /home/joerg/repo/netbsd/src/usr.sbin/services_mkdb/uniq.c,v retrieving revision 1.4 diff -u -p -r1.4 uniq.c --- usr.sbin/services_mkdb/uniq.c 28 Apr 2008 20:24:17 -0000 1.4 +++ usr.sbin/services_mkdb/uniq.c 3 Mar 2010 23:55:21 -0000 @@ -40,7 +40,14 @@ __RCSID("$NetBSD: uniq.c,v 1.4 2008/04/2 #include <ctype.h> #include <fcntl.h> -extern const HASHINFO hinfo; +static const HASHINFO hinfo = { + .bsize = 256, + .ffactor = 4, + .nelem = 32768, + .cachesize = 1024, + .hash = NULL, + .lorder = 0 +}; void uniq(const char *); static int comp(const char *, char **, size_t *);