about summary refs log tree commit diff
path: root/Src/hashtable.c
diff options
context:
space:
mode:
authorTanaka Akira <akr@users.sourceforge.net>1999-10-26 15:36:10 +0000
committerTanaka Akira <akr@users.sourceforge.net>1999-10-26 15:36:10 +0000
commite0b26186f1d3c1a3a580eb7e8a8199c25536f4e6 (patch)
treee4247c2507fa1a135740a3cd02e7405cbdbfa69a /Src/hashtable.c
parent56f338eb8bfd4bcdbf14b495ff8a34425c3527d4 (diff)
downloadzsh-e0b26186f1d3c1a3a580eb7e8a8199c25536f4e6.tar.gz
zsh-e0b26186f1d3c1a3a580eb7e8a8199c25536f4e6.tar.xz
zsh-e0b26186f1d3c1a3a580eb7e8a8199c25536f4e6.zip
manual/8424
Diffstat (limited to 'Src/hashtable.c')
-rw-r--r--Src/hashtable.c109
1 files changed, 105 insertions, 4 deletions
diff --git a/Src/hashtable.c b/Src/hashtable.c
index 86258e66f..d4c832f16 100644
--- a/Src/hashtable.c
+++ b/Src/hashtable.c
@@ -1119,6 +1119,17 @@ printaliasnode(HashNode hn, int printflags)
 /* Named Directory Hash Table Functions */
 /****************************************/
 
+#ifdef HAVE_NIS_PLUS
+# include <rpcsvc/nis.h>
+#else
+# ifdef HAVE_NIS
+#  include	<rpc/types.h>
+#  include	<rpc/rpc.h>
+#  include	<rpcsvc/ypclnt.h>
+#  include	<rpcsvc/yp_prot.h>
+# endif
+#endif
+
 /* hash table containing named directories */
 
 /**/
@@ -1168,12 +1179,102 @@ emptynameddirtable(HashTable ht)
 /* Add all the usernames in the password file/database *
  * to the named directories table.                     */
 
+#ifdef HAVE_NIS_PLUS
+static int
+add_userdir(nis_name table, nis_object *object, void *userdata)
+{
+    if (object->zo_data.objdata_u.en_data.en_cols.en_cols >= 6) {
+	static char name[40], dir[PATH_MAX + 1];
+	register entry_col *ec =
+	    object->zo_data.objdata_u.en_data.en_cols.en_cols_val;
+	register int nl = minimum(ec[0].ec_value.ec_value_len, 39);
+	register int dl = minimum(ec[5].ec_value.ec_value_len, PATH_MAX);
+
+	memcpy(name, ec[0].ec_value.ec_value_val, nl);
+	name[nl] = '\0';
+	memcpy(dir, ec[5].ec_value.ec_value_val, dl);
+	dir[dl] = '\0';
+
+	adduserdir(name, dir, ND_USERNAME, 1);
+    }
+    return 0;
+}
+#else
+# ifdef HAVE_NIS
+static int
+add_userdir(int status, char *key, int keylen, char *val, int vallen, char *dummy)
+{
+    char *p, *d, *de;
+
+    if (status != YP_TRUE)
+	return 1;
+
+    if (vallen > keylen && *(p = val + keylen) == ':') {
+	*p++ = '\0';
+	if ((de = strrchr(p, ':'))) {
+	    *de = '\0';
+	    if ((d = strrchr(p, ':'))) {
+		if (*++d && val[0])
+		    adduserdir(val, d, ND_USERNAME, 1);
+	    }
+	}
+    }
+    return 0;
+}
+# endif /* HAVE_NIS */
+#endif  /* HAVE_NIS_PLUS */
+
 /**/
 static void
 fillnameddirtable(HashTable ht)
 {
-#ifdef HAVE_GETPWENT
     if (!allusersadded) {
+#if defined(HAVE_NIS) || defined(HAVE_NIS_PLUS)
+	FILE *pwf;
+	char buf[BUFSIZ], *p, *d, *de;
+	int skipping;
+
+# ifndef HAVE_NIS_PLUS
+	char domain[YPMAXDOMAIN];
+	struct ypall_callback cb;
+
+	/* Get potential matches from NIS and cull those without local accounts */
+	if (getdomainname(domain, YPMAXDOMAIN) == 0) {
+	    cb.foreach = (int (*)()) add_userdir;
+	    cb.data = NULL;
+	    yp_all(domain, PASSWD_MAP, &cb);
+    }
+# else  /* HAVE_NIS_PLUS */
+	/* Maybe we should turn this string into a #define'd constant...? */
+
+	nis_list("passwd.org_dir", EXPAND_NAME|ALL_RESULTS|FOLLOW_LINKS|FOLLOW_PATH,
+		 add_userdir, 0);
+# endif
+	/* Don't forget the non-NIS matches from the flat passwd file */
+	if ((pwf = fopen(PASSWD_FILE, "r")) != NULL) {
+	    skipping = 0;
+	    while (fgets(buf, BUFSIZ, pwf) != NULL) {
+		if (strchr(buf, '\n') != NULL) {
+		    if (!skipping) {
+			if ((p = strchr(buf, ':')) != NULL) {
+			    *p++ = '\0';
+			    if ((de = strrchr(p, ':'))) {
+				*de = '\0';
+				if ((d = strrchr(p, ':'))) {
+				    if (*++d && buf[0])
+					adduserdir(buf, d, ND_USERNAME, 1);
+				}
+			    }
+			}
+		    } else
+			skipping = 0;
+		} else
+		    skipping = 1;
+	    }
+	    fclose(pwf);
+	}
+#else  /* no NIS or NIS_PLUS */
+#ifdef HAVE_GETPWENT
 	struct passwd *pw;
  
 	setpwent();
@@ -1181,13 +1282,13 @@ fillnameddirtable(HashTable ht)
 	/* loop through the password file/database *
 	 * and add all entries returned.           */
 	while ((pw = getpwent()) && !errflag)
-	    adduserdir(ztrdup(pw->pw_name), pw->pw_dir, ND_USERNAME, 1);
+	    adduserdir(pw->pw_name, pw->pw_dir, ND_USERNAME, 1);
  
 	endpwent();
+#endif /* HAVE_GETPWENT */
+#endif
 	allusersadded = 1;
     }
-    return;
-#endif /* HAVE_GETPWENT */
 }
 
 /* Add an entry to the named directory hash *