+/*----- Yellow pages support ----------------------------------------------*/
+
+#ifdef HAVE_YP
+
+/* --- @userdb__foreachUser@ --- *
+ *
+ * Arguments: @int st@ = YP protocol-level status code
+ * @char *k@ = address of the key for this record
+ * @int ksz@ = size of the key
+ * @char *v@ = address of the value for this record
+ * @int vsz@ = size of the value
+ * @char *data@ = pointer to some data passed to me
+ *
+ * Returns: Zero to be called again, nonzero to end the enumeration.
+ *
+ * Use: Handles an incoming user record.
+ */
+
+static int userdb__foreachUser(int st, char *k, int ksz,
+ char *v, int vsz, char *data)
+{
+ char *cv;
+ struct passwd *pw;
+
+ if (st != YP_TRUE)
+ return (-1);
+ cv = xmalloc(vsz + 1);
+ memcpy(cv, v, vsz);
+ cv[vsz] = 0;
+ T( trace(TRACE_DEBUG, "debug: nis string: `%s'", cv); )
+ pw = userdb__buildUser(cv);
+ if (pw && !userdb__byName(&userdb__users, pw->pw_name)) {
+ IF_TRACING(TRACE_DEBUG, userdb__dumpUser(pw); )
+ userdb__addToMap(&userdb__users, pw->pw_name, pw->pw_uid, pw);
+ } else
+ userdb_freeUser(pw);
+ free(cv);
+ return (0);
+}
+
+/* --- @userdb__foreachGroup@ --- *
+ *
+ * Arguments: @int st@ = YP protocol-level status code
+ * @char *k@ = address of the key for this record
+ * @int ksz@ = size of the key
+ * @char *v@ = address of the value for this record
+ * @int vsz@ = size of the value
+ * @char *data@ = pointer to some data passed to me
+ *
+ * Returns: Zero to be called again, nonzero to end the enumeration.
+ *
+ * Use: Handles an incoming user record.
+ */
+
+static int userdb__foreachGroup(int st, char *k, int ksz,
+ char *v, int vsz, char *data)
+{
+ char *cv;
+ struct group *gr;
+
+ if (st != YP_TRUE)
+ return (-1);
+ cv = xmalloc(vsz + 1);
+ memcpy(cv, v, vsz);
+ cv[vsz] = 0;
+ T( trace(TRACE_DEBUG, "debug: nis string: `%s'", cv); )
+ gr = userdb__buildGroup(cv);
+ if (gr && !userdb__byName(&userdb__groups, gr->gr_name)) {
+ IF_TRACING(TRACE_DEBUG, userdb__dumpGroup(gr); )
+ userdb__addToMap(&userdb__groups, gr->gr_name, gr->gr_gid, gr);
+ } else
+ userdb_freeGroup(gr);
+ free(cv);
+ return (0);
+}
+
+/* --- @userdb_yp@ --- *
+ *
+ * Arguments: ---
+ *
+ * Returns: ---
+ *
+ * Use: Fetches the YP database of users.
+ */
+
+void userdb_yp(void)
+{
+ /* --- Bind to a server --- */
+
+ ypstuff_bind();
+ if (!yp_domain)
+ return;
+
+ T( trace(TRACE_DEBUG, "debug: adding NIS users"); )
+
+ /* --- Fetch the users map --- */
+
+ {
+ static struct ypall_callback ucb = { userdb__foreachUser, 0 };
+ yp_all(yp_domain, "passwd.byuid", &ucb);
+ }
+
+ /* --- Fetch the groups map --- */
+
+ {
+ static struct ypall_callback gcb = { userdb__foreachGroup, 0 };
+ yp_all(yp_domain, "group.bygid", &gcb);
+ }
+}
+
+#else
+
+void userdb_yp(void) { ; }
+
+#endif
+
+/*----- Building the databases --------------------------------------------*/
+
+/* --- @userdb_local@ --- *
+ *
+ * Arguments: ---
+ *
+ * Returns: ---
+ *
+ * Use: Reads the local list of users into the maps.
+ */
+
+void userdb_local(void)
+{
+ T( trace(TRACE_DEBUG, "debug: adding local users"); )
+
+ /* --- Fetch users first --- */
+
+ {
+ struct passwd *pw;
+
+ setpwent();
+ while ((pw = getpwent()) != 0) {
+ IF_TRACING(TRACE_DEBUG, userdb__dumpUser(pw); )
+ if (!userdb__byName(&userdb__users, pw->pw_name))
+ userdb__addToMap(&userdb__users, pw->pw_name, pw->pw_uid,
+ userdb_copyUser(pw));
+ }
+ endpwent();
+ }
+
+ /* --- Then fetch groups --- */
+
+ {
+ struct group *gr;
+
+ setgrent();
+ while ((gr = getgrent()) != 0) {
+ IF_TRACING(TRACE_DEBUG, userdb__dumpGroup(gr); )
+ if (!userdb__byName(&userdb__groups, gr->gr_name))
+ userdb__addToMap(&userdb__groups, gr->gr_name, gr->gr_gid,
+ userdb_copyGroup(gr));
+ }
+ endgrent();
+ }
+}
+