Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 28 Jan 2001 10:13:49 +0100
From:      "Steve O'Hara-Smith" <steveo@eircom.net>
To:        current@freebsd.org
Subject:   /etc/shells #include syntax support patch
Message-ID:  <20010128101349.2c94539f.steveo@eircom.net>

next in thread | raw e-mail | index | archive | help
	Hi,

	Asbestos suit on, round two.

	The patch below changes getusershell to support a #include syntax
in /etc/shells. It is against RELENG_4 and may require a bit of fiddling
to apply to -current (because of nsdispatch()).

	Everything that I can find is using it (well adduser.perl has the
same support written in perl) including sendmail although I cannot see why
sendmail isn't using it's built in fallback code, but it isn't somewhere
I haven't found HASGETUSERSHELL is being set or assumed. I'm not looking
anymore.

	The changes are confined to adduser.perl, getusershell.c and shells.

	BTW: is there a reason for the avoidance of my in adduser.perl ?

Index: etc/shells
===================================================================
RCS file: /home/ncvs/src/etc/shells,v
retrieving revision 1.3.2.1
diff -u -r1.3.2.1 shells
--- etc/shells	2000/07/10 08:47:17	1.3.2.1
+++ etc/shells	2001/01/27 16:32:01
@@ -1,4 +1,4 @@
-# $FreeBSD: src/etc/shells,v 1.3.2.1 2000/07/10 08:47:17 obrien Exp $
+# $FreeBSD: src/etc/shells,v 1.3 1999/08/27 23:23:45 peter Exp $
 #
 # List of acceptable shells for chpass(1).
 # Ftpd will not allow users to connect who are not using
@@ -7,3 +7,4 @@
 /bin/sh
 /bin/csh
 /bin/tcsh
+#include /usr/local/etc/shells
Index: lib/libc/gen/getusershell.c
===================================================================
RCS file: /home/ncvs/src/lib/libc/gen/getusershell.c,v
retrieving revision 1.3
diff -u -r1.3 getusershell.c
--- lib/libc/gen/getusershell.c	1999/11/04 04:16:28	1.3
+++ lib/libc/gen/getusershell.c	2001/01/28 08:57:29
@@ -45,6 +45,7 @@
 #include <stdlib.h>
 #include <unistd.h>
 #include <paths.h>
+#include <string.h>
 
 /*
  * Local shells should NOT be added here.  They should be added in
@@ -52,8 +53,9 @@
  */
 
 static char *okshells[] = { _PATH_BSHELL, _PATH_CSHELL, NULL };
-static char **curshell, **shells, *strings;
+static char **curshell, **shells;
 static char **initshells __P((void));
+static int shellslots = 0;
 
 /*
  * Get a list of shells from _PATH_SHELLS, if it exists.
@@ -74,66 +76,87 @@
 void
 endusershell()
 {
-
-	if (shells != NULL)
+	char **sp;
+	if (shells != NULL) {
+		for (sp = shells; *sp; sp++) {
+			free (*sp);
+		}
 		free(shells);
+	}
 	shells = NULL;
-	if (strings != NULL)
-		free(strings);
-	strings = NULL;
+	shellslots = 0;
 	curshell = NULL;
 }
 
 void
 setusershell()
 {
-
 	curshell = initshells();
 }
 
 static char **
-initshells()
+readshellfile (char *path)
 {
-	register char **sp, *cp;
 	register FILE *fp;
-	struct stat statb;
+	static int sp;
+	register char *cp;
+	void *new;
+	char buf[MAXPATHLEN];
+	char *st;
+	int newslots;
 
-	if (shells != NULL)
-		free(shells);
-	shells = NULL;
-	if (strings != NULL)
-		free(strings);
-	strings = NULL;
-	if ((fp = fopen(_PATH_SHELLS, "r")) == NULL)
-		return (okshells);
-	if (fstat(fileno(fp), &statb) == -1) {
-		(void)fclose(fp);
-		return (okshells);
-	}
-	if ((strings = malloc((u_int)statb.st_size)) == NULL) {
-		(void)fclose(fp);
-		return (okshells);
+	if (shellslots == 0) {
+		sp = 0;
 	}
-	shells = calloc((unsigned)statb.st_size / 3, sizeof (char *));
-	if (shells == NULL) {
-		(void)fclose(fp);
-		free(strings);
-		strings = NULL;
-		return (okshells);
-	}
-	sp = shells;
-	cp = strings;
-	while (fgets(cp, MAXPATHLEN + 1, fp) != NULL) {
+	if ((fp = fopen(path, "r")) == NULL)
+		return (NULL);
+	while (fgets(buf, MAXPATHLEN + 1, fp) != NULL) {
+		cp = buf;
 		while (*cp != '#' && *cp != '/' && *cp != '\0')
 			cp++;
-		if (*cp == '#' || *cp == '\0')
+		if (*cp == '#' || *cp == '\0') {
+			if (!strncmp (cp, "#include", 8)) {
+				cp++;
+				while (*cp != '#' && *cp != '/' && *cp != '\0')
+					cp++;
+				if (*cp == '/') {
+					char *fn = cp;
+					while (!isspace((unsigned char)*cp) && *cp != '#' && *cp != '\0')
+						cp++;
+					*cp++ = '\0';
+					readshellfile (fn);
+				}
+			}
 			continue;
-		*sp++ = cp;
+		}
+		if (sp >= (shellslots - 1)) {
+			newslots = shellslots ? 2*shellslots : 8;
+			new = realloc ((void *)shells, newslots * sizeof (char *));
+			if (new == NULL) {
+				shells[sp] = NULL;
+				return shells;
+			}
+			shells = new;
+			shellslots = newslots;
+		}
+		st = cp;
 		while (!isspace((unsigned char)*cp) && *cp != '#' && *cp != '\0')
 			cp++;
 		*cp++ = '\0';
+		shells[sp++] = strdup (st);
 	}
-	*sp = NULL;
+	shells[sp] = NULL;
 	(void)fclose(fp);
 	return (shells);
+}
+
+static char **
+initshells()
+{
+	char **sp;
+	endusershell ();
+	if (!readshellfile (_PATH_SHELLS)) {
+		return (okshells);
+	}
+	return shells;
 }
Index: usr.sbin/adduser/adduser.perl
===================================================================
RCS file: /home/ncvs/src/usr.sbin/adduser/adduser.perl,v
retrieving revision 1.44
diff -u -r1.44 adduser.perl
--- usr.sbin/adduser/adduser.perl	1999/08/28 01:15:11	1.44
+++ usr.sbin/adduser/adduser.perl	2001/01/28 08:52:17
@@ -86,11 +86,26 @@
 
 # read shell database, see also: shells(5)
 sub shells_read {
-    local($sh);
     local($err) = 0;
+    shells_file_read ($etc_shells);
+
+    # Allow /nonexistent and /bin/date as a valid shell for system utils
+    push(@list, "/nonexistent");
+    push(@shellpref, "no") if !grep(/^no$/, @shellpref);
+    $shell{"no"} = "/nonexistent";
+
+    push(@list, "/bin/date");
+    push(@shellpref, "date") if !grep(/^date$/, @shellpref);
+    $shell{"date"} = "/bin/date";
+}
+
+sub shells_file_read {
+    my $shellsfile = shift;
+    local($sh);
+    local *S;
 
-    print "Check $etc_shells\n" if $verbose;
-    open(S, $etc_shells) || die "$etc_shells:$!\n";
+    print "Check $shellsfile\n" if $verbose;
+    open(S, $shellsfile) || die "$shellsfile:$!\n";
 
     while(<S>) {
 	if (/^\s*\//) {
@@ -102,18 +117,10 @@
 		warn "Shell: $sh not executable!\n";
 		$err++;
 	    }
-	}
+	} elsif (/\#include\s+(\S+)/) {
+            shells_file_read ($1);
+        }
     }
-
-    # Allow /nonexistent and /bin/date as a valid shell for system utils
-    push(@list, "/nonexistent");
-    push(@shellpref, "no") if !grep(/^no$/, @shellpref);
-    $shell{"no"} = "/nonexistent";
-
-    push(@list, "/bin/date");
-    push(@shellpref, "date") if !grep(/^date$/, @shellpref);
-    $shell{"date"} = "/bin/date";
-
     return $err;
 }
 


To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-current" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20010128101349.2c94539f.steveo>