From owner-freebsd-hackers@FreeBSD.ORG Sun Aug 3 17:33:39 2003 Return-Path: Delivered-To: freebsd-hackers@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id CE12837B401 for ; Sun, 3 Aug 2003 17:33:39 -0700 (PDT) Received: from mailout.informatik.tu-muenchen.de (mailout.informatik.tu-muenchen.de [131.159.0.5]) by mx1.FreeBSD.org (Postfix) with ESMTP id 68BE643F75 for ; Sun, 3 Aug 2003 17:33:38 -0700 (PDT) (envelope-from barner@in.tum.de) Received: by zi025.glhnet.mhn.de (Postfix, from userid 1000) id 1628F38B2A; Mon, 4 Aug 2003 02:33:31 +0200 (CEST) Date: Mon, 4 Aug 2003 02:33:31 +0200 From: Simon Barner To: Terry Lambert Message-ID: <20030804003331.GA408@zi025.glhnet.mhn.de> References: <20030730224505.GD531@zi025.glhnet.mhn.de> <1059607242.64020.5.camel@mjtdev1.dand06.au.bytecraft.au.com> <3F285560.2090607@acm.org> <1059608748.64020.10.camel@mjtdev1.dand06.au.bytecraft.au.com> <002201c356fa$4a66a700$1200a8c0@gsicomp.on.ca> <20030731134343.GB1323@zi025.glhnet.mhn.de> <1059693358.64020.31.camel@mjtdev1.dand06.au.bytecraft.au.com> <20030801153142.GA487@zi025.glhnet.mhn.de> <3F2B75E2.FBC18052@mindspring.com> Mime-Version: 1.0 Content-Type: multipart/signed; micalg=pgp-sha1; protocol="application/pgp-signature"; boundary="cmJC7u66zC7hs+87" Content-Disposition: inline In-Reply-To: <3F2B75E2.FBC18052@mindspring.com> User-Agent: Mutt/1.5.4i X-Virus-Scanned: by amavisd-new at informatik.tu-muenchen.de cc: freebsd-hackers@freebsd.org cc: Heiner cc: Matthew Emmerton cc: Murray Taylor cc: kientzle@acm.org Subject: Re: [patch] Re: getfsent(3) and spaces in fstab X-BeenThere: freebsd-hackers@freebsd.org X-Mailman-Version: 2.1.1 Precedence: list List-Id: Technical Discussions relating to FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 04 Aug 2003 00:33:40 -0000 --cmJC7u66zC7hs+87 Content-Type: multipart/mixed; boundary="HlL+5n6rz5pIUxbD" Content-Disposition: inline --HlL+5n6rz5pIUxbD Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Hi Terry, > You need to add '\\' to the list of characters that can be escaped, > or you've just traded the inability to specify '\t' or ' ' for an > inability to speciy '\\'. Oh yes, I have overlook this special case. I revised my patch in order to get this right. Simon --HlL+5n6rz5pIUxbD Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="patch-fstab.c" Content-Transfer-Encoding: quoted-printable --- fstab.c.orig Fri Aug 1 17:18:00 2003 +++ fstab.c Mon Aug 4 01:46:55 2003 @@ -49,6 +49,7 @@ #include #include #include +#include #include #include #include @@ -84,6 +85,140 @@ _fs_fstab.fs_spec =3D buf; } =20 +/* + * Get next token from string *stringp, where tokens are possibly-empty + * strings separated by characters from delim. + * + * Writes NULs into the string at *stringp to end tokens. + * delim need not remain constant from call to call. + * On return, *stringp points past the last NUL written (if there might + * be further tokens), or is NULL (if there are definitely no more tokens). + * + * If *stringp is NULL, es_strsep returns NULL. + * + * In contrast to strsep(3), es_strsep will allow escaped delimiters + * within a token. These escaped characters as well as the special case + * '\\' will be converted appropriately ('\' -> ', '\\' -> '= \' + * + */ +char * +es_strsep(char **stringp, const char *delim) +{ + bool escaped=3Dfalse; + char *s, *t, *u; + int i; + + + if (*stringp =3D=3D '\0') /* empty string */ + return NULL; + s =3D *stringp; + s +=3D strspn (s, delim); /* skip delimiters */ + + if (*s =3D=3D '\0') /* string consists only of delimiters */ + return NULL; +=09 + /* + * skip a string consisting of non-delimiters, + * escapted delimiters or '\\' + */ + for (t =3D s; *t !=3D '\0'; ++t) { + if (*t =3D=3D '\\') { + if (escaped) { /* convert \\ to \ */ + --t; + u =3D t; + escaped =3D false; + while (u[0] !=3D '\0') { + u[0] =3D u[1]; + ++u; + } + } else /* start \-Sequence */ + escaped =3D true; + continue; + } + =09 + /* search for delimiter */ + for (i=3D0; delim[i] !=3D '\0'; ++i) { + if (*t =3D=3D delim[i]) + break; + } + =09 + /* un-escaped delimiter found =3D> end of token */ + if (!escaped && delim[i] !=3D '\0') + break; + =20 + /* escaped delimiter found =3D> remove / */ + if (escaped) { + --t; + u =3D t; + escaped =3D false; + while (u[0] !=3D '\0') { + u[0] =3D u[1]; + ++u; + } + } + } + + if (*t !=3D '\0') { + *t =3D '\0'; /* end current token */ + *stringp =3D t+1; /* *t !=3D '\0' =3D> *(t+1) is valid */ + } else + *stringp =3D 0; /* end of string reached */=09 +=09 + return s; /* return current token */ +} + +/* + * This function converts escaped characters: + * '\' -> '', '\\' -> '\' + *=20 + * If there are unescaped delimiters, 'false' will be return to indicate + * an error, otherwise remove_escape returns 'true'. + */ +bool remove_escapes (char **s, const char* delim) { + bool escaped=3Dfalse; + char *t, *u; + int i; +=09 + for (t =3D *s; *t !=3D '\0'; ++t) { + if (*t =3D=3D '\\') { + if (escaped) { /* convert \\ to \ */ + --t; + u =3D t; + escaped =3D false; + while (u[0] !=3D '\0') { + u[0] =3D u[1]; + ++u; + } + } else /* start \-Sequence */ + escaped =3D true; + continue; + } + =09 + /* search for delimiter */ + for (i=3D0; delim[i] !=3D '\0'; ++i) { + if (*t =3D=3D delim[i]) + break; + } + =09 + /* un-escaped delimiter found =3D> error */ + if (!escaped && delim[i] !=3D '\0') + return false; + + /* escaped delimiter found =3D> remove / */ + if (escaped) { + --t; + u =3D t; + escaped =3D false; + while (u[0] !=3D '\0') { + u[0] =3D u[1]; + ++u; + } + } + } +=09 + return true; +} + static int fstabscan() { @@ -101,9 +236,19 @@ ++LineNo; if (*line =3D=3D '#' || *line =3D=3D '\n') continue; - if (!strpbrk(p, " \t")) { + + /* escapted white-spaces only are allowed in old-style format */ + cp =3D p; + while ((cp =3D strpbrk(cp, " \t")) !=3D 0 && + cp !=3D p && cp[-1] =3D=3D '\\') + ++cp; + if (cp =3D=3D 0) { _fs_fstab.fs_spec =3D strsep(&p, ":\n"); + if (!remove_escapes (&_fs_fstab.fs_spec, " \t")) + goto bad; _fs_fstab.fs_file =3D strsep(&p, ":\n"); + if (!remove_escapes (&_fs_fstab.fs_file, " \t")) + goto bad; fixfsfile(); _fs_fstab.fs_type =3D strsep(&p, ":\n"); if (_fs_fstab.fs_type) { @@ -124,13 +269,15 @@ goto bad; } /* OLD_STYLE_FSTAB */ - while ((cp =3D strsep(&p, " \t\n")) !=3D NULL && *cp =3D=3D '\0') + while ((cp =3D es_strsep(&p, " \t\n")) !=3D NULL && *cp =3D=3D '\0') ; _fs_fstab.fs_spec =3D cp; if (!_fs_fstab.fs_spec || *_fs_fstab.fs_spec =3D=3D '#') continue; - while ((cp =3D strsep(&p, " \t\n")) !=3D NULL && *cp =3D=3D '\0') + while ((cp =3D es_strsep(&p, " \t\n")) !=3D NULL && *cp =3D=3D '\0') ; + if (cp =3D=3D 0) + goto bad; _fs_fstab.fs_file =3D cp; fixfsfile(); while ((cp =3D strsep(&p, " \t\n")) !=3D NULL && *cp =3D=3D '\0') --HlL+5n6rz5pIUxbD-- --cmJC7u66zC7hs+87 Content-Type: application/pgp-signature; name="signature.asc" Content-Description: Digital signature Content-Disposition: inline -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.2.2 (FreeBSD) iD8DBQE/LanbCkn+/eutqCoRAs7XAKCpZ+27mnva6IneR3gtL1BpkjqV/ACg4oed jyXs4Off13grX1MU/tpNx7A= =/Mku -----END PGP SIGNATURE----- --cmJC7u66zC7hs+87--