Subject: Re: bin/24192: inetd fragments command line args to daemons
To: None <rtr@NetBSD.org>
From: Quentin Garnier <cube@NetBSD.org>
List: tech-userlevel
Date: 01/22/2004 08:52:10
On Thu, 22 Jan 2004 18:19:08 +1100 (EST)
rtr@netbsd.org wrote:

> >Synopsis:       inetd fragments command line args to daemons
[...]
> >Description:
> Command line arguments which contain whitespace but are in between 
> double quotes are broken when passed to daemons on startup.

FreeBSD had quoting in inetd.conf since 1995.  Though it's just a bit
dumb, "this""that" being parsed as two arguments.  The reason for that
behaviour is that no character is dropped, they're just skipped, thus
the end quote is necessarily the end of the argument.

Here's a patch that allows quoting pretty much the same way as in the
shell (but only with single and double quotes, no character escape).  It
uses memmove() to drop the quoting characters.

So, FreeBSD way or memmove way (I don't think there is any other simple
option)?  Neither, maybe :-)

Quentin Garnier.

Index: inetd.c
===================================================================
RCS file: /cvsroot/src/usr.sbin/inetd/inetd.c,v
retrieving revision 1.94
diff -u -r1.94 inetd.c
--- inetd.c	2003/10/21 02:43:37	1.94
+++ inetd.c	2004/01/22 07:41:13
@@ -1698,6 +1698,7 @@
 {
 	char *cp = *cpp;
 	char *start;
+	char quote;
 
 	if (*cpp == NULL)
 		return (NULL);
@@ -1717,8 +1718,21 @@
 		return (NULL);
 	}
 	start = cp;
-	while (*cp && *cp != ' ' && *cp != '\t')
-		cp++;
+	quote = '\0';
+	while (*cp && (quote || (*cp != ' ' && *cp != '\t'))) {
+		if (*cp == '\'' || *cp == '"') {
+			if (quote && *cp != quote)
+				cp++;
+			else {
+				if (quote)
+					quote = '\0';
+				else
+					quote = *cp;
+				memmove(cp, cp+1, strlen(cp));
+			}
+		} else
+			cp++;
+	}
 	if (*cp != '\0')
 		*cp++ = '\0';
 	*cpp = cp;