6927821 in.ftpd is unable to list large directories when client issues 'ls'
authorMilan Jurik <Milan.Jurik@Sun.COM>
Fri, 07 May 2010 08:46:51 +0100
changeset 12333 f835be4545bb
parent 12332 f73240ab5ca7
child 12334 6920dcae2224
6927821 in.ftpd is unable to list large directories when client issues 'ls'
usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/extensions.c
usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/ftpcmd.y
usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/ftpd.c
usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/glob.c
usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/popen.c
usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/proto.h
--- a/usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/extensions.c	Thu May 06 23:21:18 2010 -0700
+++ b/usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/extensions.c	Fri May 07 08:46:51 2010 +0100
@@ -1,10 +1,7 @@
 /*
- * Copyright 2002-2003 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved.
  */
 
-#pragma ident	"%Z%%M%	%I%	%E% SMI"
-
 /****************************************************************************  
  
   Copyright (c) 1999,2000 WU-FTPD Development Group.  
@@ -837,7 +834,7 @@
 	    }
 	if (show) {
 	    globerr = NULL;
-	    filelist = ftpglob(ARG0);
+	    filelist = ftpglob(ARG0, B_TRUE);
 	    sfilelist = filelist;	/* save to free later */
 	    if (!globerr) {
 		while (filelist && *filelist) {
--- a/usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/ftpcmd.y	Thu May 06 23:21:18 2010 -0700
+++ b/usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/ftpcmd.y	Fri May 07 08:46:51 2010 +0100
@@ -1,6 +1,5 @@
 /*
- * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 1989, 2010, Oracle and/or its affiliates. All rights reserved.
  */
 
 /****************************************************************************    
@@ -1598,7 +1597,7 @@
 			(void) strlcat(t, $1 + 3, len);
 		    else if (strcmp($1, "/..") != 0)
 			(void) strlcat(t, $1, len);
-		    globlist = ftpglob(t);
+		    globlist = ftpglob(t, B_TRUE);
 		    if (globerr) {
 			reply(550, "%s", globerr);
 			$$ = NULL;
@@ -1628,7 +1627,7 @@
 	    else if (logged_in && $1 && strncmp($1, "~", 1) == 0) {
 		char **globlist;
 
-		globlist = ftpglob($1);
+		globlist = ftpglob($1, B_TRUE);
 		if (globerr) {
 		    reply(550, "%s", globerr);
 		    $$ = NULL;
--- a/usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/ftpd.c	Thu May 06 23:21:18 2010 -0700
+++ b/usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/ftpd.c	Fri May 07 08:46:51 2010 +0100
@@ -1,10 +1,7 @@
 /*
- * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 1989, 2010, Oracle and/or its affiliates. All rights reserved.
  */
 
-#pragma ident	"%Z%%M%	%I%	%E% SMI"
-
 /****************************************************************************  
  
   Copyright (c) 1999,2000,2001 WU-FTPD Development Group.  
@@ -6716,7 +6713,7 @@
 static char *onefile[] =
 {"", 0};
 
-extern char **ftpglob(register char *v);
+extern char **ftpglob(register char *v, boolean_t check_ncargs);
 extern char *globerr;
 
 void send_file_list(char *whichfiles)
@@ -6790,7 +6787,7 @@
     }
     if (strpbrk(whichfiles, "~{[*?") != NULL) {
 	globerr = NULL;
-	dirlist = ftpglob(whichfiles);
+	dirlist = ftpglob(whichfiles, B_FALSE);
 	sdirlist = dirlist;	/* save to free later */
 	if (globerr != NULL) {
 	    reply(550, "%s", globerr);
--- a/usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/glob.c	Thu May 06 23:21:18 2010 -0700
+++ b/usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/glob.c	Fri May 07 08:46:51 2010 +0100
@@ -1,10 +1,7 @@
 /*
- * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 1989, 2010, Oracle and/or its affiliates. All rights reserved.
  */
 
-#pragma ident	"%Z%%M%	%I%	%E% SMI"
-
 /****************************************************************************    
   Copyright (c) 1999,2000,2001 WU-FTPD Development Group.  
   All rights reserved.
@@ -72,15 +69,15 @@
 static char *strend(register char *);
 static void addpath(char);
 static void ginit(char **);
-static void collect(register char *);
-static void acollect(register char *);
+static void collect(register char *, boolean_t check_ncargs);
+static void acollect(register char *, boolean_t check_ncargs);
 static void sort(void);
-static void expand(char *);
-static void matchdir(char *);
+static void expand(char *, boolean_t check_ncargs);
+static void matchdir(char *, boolean_t check_ncargs);
 static int execbrc(char *, char *);
-static int match(char *, char *);
-static int amatch(char *, char *);
-static void Gcat(register char *, register char *);
+static int match(char *, char *, boolean_t check_ncargs);
+static int amatch(char *, char *, boolean_t check_ncargs);
+static void Gcat(register char *, register char *, boolean_t check_ncargs);
 static void rscan(register char **, int (*f) (register char));
 static int tglob(register char c);
 static int gethdir(char *);
@@ -109,7 +106,7 @@
 extern char _path_passwd[];
 #endif
 
-char **ftpglob(register char *v)
+char **ftpglob(register char *v, boolean_t check_ncargs)
 {
     char agpath[BUFSIZ];
     char *vv[2];
@@ -144,7 +141,7 @@
     lastgpathp = &gpath[sizeof agpath - 2];
     ginit(agargv);
     globcnt = 0;
-    collect(v);
+    collect(v, check_ncargs);
     if (globcnt == 0 && (gflag & 1)) {
 	blkfree(gargv), gargv = 0;
 	return (0);
@@ -163,24 +160,24 @@
     gnleft = NCARGS - 4;
 }
 
-static void collect(register char *as)
+static void collect(register char *as, boolean_t check_ncargs)
 {
     if (eq(as, "{") || eq(as, "{}")) {
-	Gcat(as, "");
+	Gcat(as, "", check_ncargs);
 	sort();
     }
     else
-	acollect(as);
+	acollect(as, check_ncargs);
 }
 
-static void acollect(register char *as)
+static void acollect(register char *as, boolean_t check_ncargs)
 {
     register int ogargc = gargc;
 
     gpathp = gpath;
     *gpathp = 0;
     globbed = 0;
-    expand(as);
+    expand(as, check_ncargs);
     if (gargc != ogargc)
 	sort();
 }
@@ -203,7 +200,7 @@
     sortbas = Gvp;
 }
 
-static void expand(char *as)
+static void expand(char *as, boolean_t check_ncargs)
 {
     register char *cs;
     register char *sgpathp, *oldcs;
@@ -233,9 +230,9 @@
     while (!any(*cs, globchars)) {
 	if (*cs == 0) {
 	    if (!globbed)
-		Gcat(gpath, "");
+		Gcat(gpath, "", check_ncargs);
 	    else if (stat(gpath, &stb) >= 0) {
-		Gcat(gpath, "");
+		Gcat(gpath, "", check_ncargs);
 		globcnt++;
 	    }
 	    goto endit;
@@ -252,13 +249,13 @@
 	(void) execbrc(cs, ((char *) 0));
 	return;
     }
-    matchdir(cs);
+    matchdir(cs, check_ncargs);
   endit:
     gpathp = sgpathp;
     *gpathp = 0;
 }
 
-static void matchdir(char *pattern)
+static void matchdir(char *pattern, boolean_t check_ncargs)
 {
     struct stat stb;
 
@@ -289,8 +286,8 @@
     while (!globerr && ((dp = readdir(dirp)) != NULL)) {
 	if (dp->d_ino == 0)
 	    continue;
-	if (match(dp->d_name, pattern)) {
-	    Gcat(gpath, dp->d_name);
+	if (match(dp->d_name, pattern, check_ncargs)) {
+	    Gcat(gpath, dp->d_name, check_ncargs);
 	    globcnt++;
 	}
     }
@@ -371,11 +368,11 @@
 	    *pm = savec;
 	    if (s == 0) {
 		sgpathp = gpathp;
-		expand(restbuf);
+		expand(restbuf, B_TRUE);
 		gpathp = sgpathp;
 		*gpathp = 0;
 	    }
-	    else if (amatch(s, restbuf))
+	    else if (amatch(s, restbuf, B_TRUE))
 		return (1);
 	    sort();
 	    pl = pm + 1;
@@ -394,7 +391,7 @@
     return (0);
 }
 
-static int match(char *s, char *p)
+static int match(char *s, char *p, boolean_t check_ncargs)
 {
     register int c;
     register char *sentp;
@@ -404,13 +401,13 @@
 	return (0);
     sentp = entp;
     entp = s;
-    c = amatch(s, p);
+    c = amatch(s, p, check_ncargs);
     entp = sentp;
     globbed = sglobbed;
     return (c);
 }
 
-static int amatch(char *s, char *p)
+static int amatch(char *s, char *p, boolean_t check_ncargs)
 {
     register int scc;
     int ok, lc;
@@ -460,7 +457,7 @@
 	    }
 	    s--;
 	    do {
-		if (amatch(s, p))
+		if (amatch(s, p, check_ncargs))
 		    return (1);
 	    } while (*s++);
 	    return (0);
@@ -489,11 +486,11 @@
 	    addpath('/');
 	    if (stat(gpath, &stb) == 0 && isdir(stb))
 		if (*p == 0) {
-		    Gcat(gpath, "");
+		    Gcat(gpath, "", check_ncargs);
 		    globcnt++;
 		}
 		else
-		    expand(p);
+		    expand(p, check_ncargs);
 	    gpathp = sgpathp;
 	    *gpathp = 0;
 	    return (0);
@@ -501,14 +498,13 @@
     }
 }
 
-static void Gcat(register char *s1, register char *s2)
+static void Gcat(register char *s1, register char *s2, boolean_t check_ncargs)
 {
     register size_t len = strlen(s1) + strlen(s2) + 1;
 
     if (globerr)
 	return;
-
-    if ((len + sizeof (char *)) >= gnleft) {
+    if ((check_ncargs) && ((len + sizeof (char *)) >= gnleft)) {
 	globerr = "Arguments too long";
 	return;
     }
@@ -531,7 +527,8 @@
 	sortbas = agargv;
     }
     gargc++;
-    gnleft -= len + sizeof (char *);
+    if (check_ncargs)
+	gnleft -= len + sizeof (char *);
     gargv[gargc] = 0;
     gargv[gargc - 1] = strspl(s1, s2);
 }
--- a/usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/popen.c	Thu May 06 23:21:18 2010 -0700
+++ b/usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/popen.c	Fri May 07 08:46:51 2010 +0100
@@ -1,6 +1,5 @@
 /*
- * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 1989, 2010, Oracle and/or its affiliates. All rights reserved.
  */
 
 /****************************************************************************    
@@ -125,7 +124,7 @@
     /* glob each piece */
     gargv[0] = argv[0];
     for (gargc = argc = 1; argv[argc]; argc++) {
-	if (!(pop = ftpglob(argv[argc])) || globerr != NULL) {	/* globbing failed */
+	if (!(pop = ftpglob(argv[argc], B_TRUE)) || globerr != NULL) {	/* globbing failed */
 	    if (pop) {
 		blkfree(pop);
 		free((char *) pop);
--- a/usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/proto.h	Thu May 06 23:21:18 2010 -0700
+++ b/usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/proto.h	Fri May 07 08:46:51 2010 +0100
@@ -1,10 +1,7 @@
 /*
- * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved.
  */
 
-#pragma ident	"%Z%%M%	%I%	%E% SMI"
-
 /****************************************************************************    
   Copyright (c) 1999,2000 WU-FTPD Development Group.  
   All rights reserved.
@@ -232,7 +229,7 @@
    ** glob.c
  */
 void blkfree(char **);
-char **ftpglob(register char *);
+char **ftpglob(register char *, boolean_t check_ncargs);
 char *strspl(register char *, register char *);
 char **copyblk(register char **);