Author: ume
Date: Sun Apr 18 04:07:32 2010
New Revision: 206784
URL: http://svn.freebsd.org/changeset/base/206784

Log:
  MFC r206155, r206267: Add capability to use a db version of
  services.  It is enabled by specifying `db' as source of
  services in /etc/nsswitch.conf.

Modified:
  stable/8/include/netdb.h
  stable/8/include/nsswitch.h
  stable/8/lib/libc/net/getservent.c
  stable/8/lib/libc/net/nsdispatch.3
  stable/8/share/man/man5/nsswitch.conf.5
  stable/8/share/man/man5/services.5
Directory Properties:
  stable/8/include/   (props changed)
  stable/8/lib/libc/   (props changed)
  stable/8/lib/libc/stdtime/   (props changed)
  stable/8/share/man/man5/   (props changed)

Modified: stable/8/include/netdb.h
==============================================================================
--- stable/8/include/netdb.h    Sun Apr 18 03:52:41 2010        (r206783)
+++ stable/8/include/netdb.h    Sun Apr 18 04:07:32 2010        (r206784)
@@ -86,6 +86,7 @@ typedef       __uint32_t      uint32_t;
 #define        _PATH_NETWORKS  "/etc/networks"
 #define        _PATH_PROTOCOLS "/etc/protocols"
 #define        _PATH_SERVICES  "/etc/services"
+#define        _PATH_SERVICES_DB "/var/db/services.db"
 
 #define        h_errno (*__h_errno())
 

Modified: stable/8/include/nsswitch.h
==============================================================================
--- stable/8/include/nsswitch.h Sun Apr 18 03:52:41 2010        (r206783)
+++ stable/8/include/nsswitch.h Sun Apr 18 04:07:32 2010        (r206784)
@@ -65,6 +65,7 @@
  * currently implemented sources
  */
 #define NSSRC_FILES    "files"         /* local files */
+#define        NSSRC_DB        "db"            /* database */
 #define        NSSRC_DNS       "dns"           /* DNS; IN for hosts, HS for 
others */
 #define        NSSRC_NIS       "nis"           /* YP/NIS */
 #define        NSSRC_COMPAT    "compat"        /* passwd,group in YP compat 
mode */

Modified: stable/8/lib/libc/net/getservent.c
==============================================================================
--- stable/8/lib/libc/net/getservent.c  Sun Apr 18 03:52:41 2010        
(r206783)
+++ stable/8/lib/libc/net/getservent.c  Sun Apr 18 04:07:32 2010        
(r206784)
@@ -37,7 +37,9 @@ __FBSDID("$FreeBSD$");
 #include <sys/types.h>
 #include <sys/socket.h>
 #include <arpa/inet.h>
+#include <db.h>
 #include <errno.h>
+#include <fcntl.h>
 #include <limits.h>
 #include <netdb.h>
 #include <nsswitch.h>
@@ -94,6 +96,19 @@ NSS_TLS_HANDLING(files);
 static int files_servent(void *, void *, va_list);
 static int files_setservent(void *, void *, va_list);
 
+/* db backend declarations */
+struct db_state
+{
+        DB *db;
+       int stayopen;
+       int keynum;
+};
+static void db_endstate(void *);
+NSS_TLS_HANDLING(db);
+
+static int db_servent(void *, void *, va_list);
+static int db_setservent(void *, void *, va_list);
+
 #ifdef YP
 /* nis backend declarations */
 static         int     nis_servent(void *, void *, va_list);
@@ -263,6 +278,8 @@ files_servent(void *retval, void *mdata,
                { NULL, 0 }
        };
        ns_dtab compat_dtab[] = {
+               { NSSRC_DB, db_servent,
+                       (void *)((struct servent_mdata *)mdata)->how },
 #ifdef YP
                { NSSRC_NIS, nis_servent,
                        (void *)((struct servent_mdata *)mdata)->how },
@@ -452,6 +469,183 @@ files_setservent(void *retval, void *mda
        return (NS_UNAVAIL);
 }
 
+/* db backend implementation */
+static void
+db_endstate(void *p)
+{
+       DB *db;
+
+       if (p == NULL)
+               return;
+
+       db = ((struct db_state *)p)->db;
+       if (db != NULL)
+               db->close(db);
+
+       free(p);
+}
+
+static int
+db_servent(void *retval, void *mdata, va_list ap)
+{
+       char buf[BUFSIZ];
+       DBT key, data, *result;
+       DB *db;
+
+       struct db_state *st;
+       int rv;
+       int stayopen;
+
+       enum nss_lookup_type how;
+       char *name;
+       char *proto;
+       int port;
+
+       struct servent *serv;
+       char *buffer;
+       size_t bufsize;
+       int *errnop;
+
+       name = NULL;
+       proto = NULL;
+       how = (enum nss_lookup_type)mdata;
+       switch (how) {
+       case nss_lt_name:
+               name = va_arg(ap, char *);
+               proto = va_arg(ap, char *);
+               break;
+       case nss_lt_id:
+               port = va_arg(ap, int);
+               proto = va_arg(ap, char *);
+               break;
+       case nss_lt_all:
+               break;
+       default:
+               return NS_NOTFOUND;
+       };
+
+       serv = va_arg(ap, struct servent *);
+       buffer  = va_arg(ap, char *);
+       bufsize = va_arg(ap, size_t);
+       errnop = va_arg(ap,int *);
+
+       *errnop = db_getstate(&st);
+       if (*errnop != 0)
+               return (NS_UNAVAIL);
+
+       if (how == nss_lt_all && st->keynum < 0)
+               return (NS_NOTFOUND);
+
+       if (st->db == NULL) {
+               st->db = dbopen(_PATH_SERVICES_DB, O_RDONLY, 0, DB_HASH, NULL);
+               if (st->db == NULL) {
+                       *errnop = errno;
+                       return (NS_UNAVAIL);
+               }
+       }
+
+       stayopen = (how == nss_lt_all) ? 1 : st->stayopen;
+       db = st->db;
+
+       do {
+               switch (how) {
+               case nss_lt_name:
+                       key.data = buf;
+                       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 ||
+                           db->get(db, &data, &key, 0) != 0) {
+                               rv = NS_NOTFOUND;
+                               goto db_fin;
+                       }
+                       result = &key;
+                       break;
+               case nss_lt_id:
+                       key.data = buf;
+                       port = htons(port);
+                       if (proto == NULL)
+                               key.size = snprintf(buf, sizeof(buf),
+                                   "\377%d", port);
+                       else
+                               key.size = snprintf(buf, sizeof(buf),
+                                   "\377%d/%s", port, proto);
+                       key.size++;
+                       if (db->get(db, &key, &data, 0) != 0 ||
+                           db->get(db, &data, &key, 0) != 0) {
+                               rv = NS_NOTFOUND;
+                               goto db_fin;
+                       }
+                       result = &key;
+                       break;
+               case nss_lt_all:
+                       key.data = buf;
+                       key.size = snprintf(buf, sizeof(buf), "%d",
+                           st->keynum++);
+                       key.size++;
+                       if (db->get(db, &key, &data, 0) != 0) {
+                               st->keynum = -1;
+                               rv = NS_NOTFOUND;
+                               goto db_fin;
+                       }
+                       result = &data;
+                       break;
+               }
+
+               rv = parse_result(serv, buffer, bufsize, result->data,
+                   result->size - 1, errnop);
+
+       } while (!(rv & NS_TERMINATE) && how == nss_lt_all);
+
+db_fin:
+       if (!stayopen && st->db != NULL) {
+               db->close(db);
+               st->db = NULL;
+       }
+
+       if (rv == NS_SUCCESS && retval != NULL)
+               *(struct servent **)retval = serv;
+
+       return (rv);
+}
+
+static int
+db_setservent(void *retval, void *mdata, va_list ap)
+{
+       DB *db;
+       struct db_state *st;
+       int rv;
+       int f;
+
+       rv = db_getstate(&st);
+       if (rv != 0)
+               return (NS_UNAVAIL);
+
+       switch ((enum constants)mdata) {
+       case SETSERVENT:
+               f = va_arg(ap, int);
+               st->stayopen |= f;
+               st->keynum = 0;
+               break;
+       case ENDSERVENT:
+               db = st->db;
+               if (db != NULL) {
+                       db->close(db);
+                       st->db = NULL;
+               }
+               st->stayopen = 0;
+               break;
+       default:
+               break;
+       };
+
+       return (NS_UNAVAIL);
+}
+
 /* nis backend implementation */
 #ifdef YP
 static         void
@@ -638,6 +832,7 @@ compat_setservent(void *retval, void *md
                { NULL, 0 }
        };
        ns_dtab compat_dtab[] = {
+               { NSSRC_DB, db_setservent, mdata },
 #ifdef YP
                { NSSRC_NIS, nis_setservent, mdata },
 #endif
@@ -924,6 +1119,7 @@ getservbyname_r(const char *name, const 
 #endif /* NS_CACHING */
        static const ns_dtab dtab[] = {
                { NSSRC_FILES, files_servent, (void *)&mdata },
+               { NSSRC_DB, db_servent, (void *)nss_lt_name },
 #ifdef YP
                { NSSRC_NIS, nis_servent, (void *)nss_lt_name },
 #endif
@@ -960,6 +1156,7 @@ getservbyport_r(int port, const char *pr
 #endif
        static const ns_dtab dtab[] = {
                { NSSRC_FILES, files_servent, (void *)&mdata },
+               { NSSRC_DB, db_servent, (void *)nss_lt_id },
 #ifdef YP
                { NSSRC_NIS, nis_servent, (void *)nss_lt_id },
 #endif
@@ -995,6 +1192,7 @@ getservent_r(struct servent *serv, char 
 #endif
        static const ns_dtab dtab[] = {
                { NSSRC_FILES, files_servent, (void *)&mdata },
+               { NSSRC_DB, db_servent, (void *)nss_lt_all },
 #ifdef YP
                { NSSRC_NIS, nis_servent, (void *)nss_lt_all },
 #endif
@@ -1027,6 +1225,7 @@ setservent(int stayopen)
 #endif
        static const ns_dtab dtab[] = {
                { NSSRC_FILES, files_setservent, (void *)SETSERVENT },
+               { NSSRC_DB, db_setservent, (void *)SETSERVENT },
 #ifdef YP
                { NSSRC_NIS, nis_setservent, (void *)SETSERVENT },
 #endif
@@ -1051,6 +1250,7 @@ endservent()
 #endif
        static const ns_dtab dtab[] = {
                { NSSRC_FILES, files_setservent, (void *)ENDSERVENT },
+               { NSSRC_DB, db_setservent, (void *)ENDSERVENT },
 #ifdef YP
                { NSSRC_NIS, nis_setservent, (void *)ENDSERVENT },
 #endif

Modified: stable/8/lib/libc/net/nsdispatch.3
==============================================================================
--- stable/8/lib/libc/net/nsdispatch.3  Sun Apr 18 03:52:41 2010        
(r206783)
+++ stable/8/lib/libc/net/nsdispatch.3  Sun Apr 18 04:07:32 2010        
(r206784)
@@ -32,7 +32,7 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd January 22, 2007
+.Dd April 4, 2010
 .Dt NSDISPATCH 3
 .Os
 .Sh NAME
@@ -176,6 +176,7 @@ While there is support for arbitrary sou
 .Bl -column NSSRC_COMPAT compat -offset indent
 .It Sy "#define        value"
 .It Dv NSSRC_FILES Ta """files""
+.It Dv NSSRC_DB Ta """db""
 .It Dv NSSRC_DNS Ta """dns""
 .It Dv NSSRC_NIS Ta """nis""
 .It Dv NSSRC_COMPAT Ta """compat""

Modified: stable/8/share/man/man5/nsswitch.conf.5
==============================================================================
--- stable/8/share/man/man5/nsswitch.conf.5     Sun Apr 18 03:52:41 2010        
(r206783)
+++ stable/8/share/man/man5/nsswitch.conf.5     Sun Apr 18 04:07:32 2010        
(r206784)
@@ -33,7 +33,7 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd December 23, 2008
+.Dd April 4, 2010
 .Dt NSSWITCH.CONF 5
 .Os
 .Sh NAME
@@ -72,6 +72,8 @@ Local files, such as
 .Pa /etc/hosts ,
 and
 .Pa /etc/passwd .
+.It db
+Local database.
 .It dns
 Internet Domain Name System.
 .Dq hosts

Modified: stable/8/share/man/man5/services.5
==============================================================================
--- stable/8/share/man/man5/services.5  Sun Apr 18 03:52:41 2010        
(r206783)
+++ stable/8/share/man/man5/services.5  Sun Apr 18 04:07:32 2010        
(r206784)
@@ -32,7 +32,7 @@
 .\"     @(#)services.5 8.1 (Berkeley) 6/5/93
 .\" $FreeBSD$
 .\"
-.Dd June 5, 1993
+.Dd April 4, 2010
 .Dt SERVICES 5
 .Os
 .Sh NAME
@@ -65,6 +65,18 @@ not interpreted by the routines which se
 Service names may contain any printable
 character other than a field delimiter, newline,
 or comment character.
+.Pp
+If 
+.Dq db
+is specified as source in the
+.Xr nsswitch.conf 5 ,
+.Pa /var/db/services.db
+is searched.
+The database in
+.Pa /var/db/services.db
+needs to be updated with
+.Xr services_mkdb 8
+after changes to the services file have been applied.
 .Sh NIS INTERACTION
 Access to the NIS
 .Pa services.byname
@@ -84,6 +96,8 @@ file resides in
 .El
 .Sh SEE ALSO
 .Xr getservent 3
+.Xr nsswitch.conf 5
+.Xr services_mkdb 8
 .Sh HISTORY
 The
 .Nm
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to