Date: Tue, 3 Mar 1998 16:47:21 -0800 From: Alan Batie <batie@aahz.jf.intel.com> To: bugs@FreeBSD.ORG Subject: fix for bug bin/3246 Message-ID: <19980303164721.61146@aahz.jf.intel.com>
next in thread | raw e-mail | index | archive | help
[-- Attachment #1 --]
This fixes mtree so it can cope with files with whitespace in their names:
===================================================================
RCS file: RCS/create.c,v
retrieving revision 1.1
diff -c -r1.1 create.c
*** create.c 1998/03/03 20:40:51 1.1
--- create.c 1998/03/04 00:44:57
***************
*** 59,64 ****
--- 59,66 ----
extern u_short keys;
extern char fullpath[MAXPATHLEN];
+ extern char *escape(char *);
+
static gid_t gid;
static uid_t uid;
static mode_t mode;
***************
*** 134,144 ****
struct passwd *pw;
u_long len, val;
int fd, offset;
if (iflag || S_ISDIR(p->fts_statp->st_mode))
! offset = printf("%*s%s", indent, "", p->fts_name);
else
! offset = printf("%*s %s", indent, "", p->fts_name);
if (offset > (INDENTNAMELEN + indent))
offset = MAXLINELEN;
--- 136,149 ----
struct passwd *pw;
u_long len, val;
int fd, offset;
+ char *estr;
+ estr = escape(p->fts_name);
if (iflag || S_ISDIR(p->fts_statp->st_mode))
! offset = printf("%*s%s", indent, "", estr);
else
! offset = printf("%*s %s", indent, "", estr);
! free(estr);
if (offset > (INDENTNAMELEN + indent))
offset = MAXLINELEN;
***************
*** 341,344 ****
--- 346,372 ----
*offset = INDENTNAMELEN + indent;
}
*offset += printf(" %s", buf) + 1;
+ }
+
+ char *
+ escape(char *instr)
+ {
+ int i;
+ char *estr; /* Escaped string */
+
+ /* Escaping every character would at most double string length */
+ estr = malloc((2 * strlen(instr)) + 1);
+
+ i = 0;
+ while (*instr) {
+ if (isspace(*instr)) {
+ estr[i++] = '\\';
+ }
+ estr[i++] = *instr++;
+ }
+
+ estr[i] = '\0';
+
+ /* Don't bother reallocing to optimize space: it gets freed right away */
+ return(estr);
}
===================================================================
RCS file: RCS/spec.c,v
retrieving revision 1.1
diff -c -r1.1 spec.c
*** spec.c 1998/03/03 20:40:51 1.1
--- spec.c 1998/03/04 00:45:17
***************
*** 49,54 ****
--- 49,56 ----
int lineno; /* Current spec line number. */
+ extern char *stretok(char *, const char *);
+
static void set __P((char *, NODE *));
static void unset __P((char *, NODE *));
***************
*** 99,107 ****
}
/* Grab file name, "$", "set", or "unset". */
! if ((p = strtok(p, "\n\t ")) == NULL)
err("missing field");
-
if (p[0] == '/')
switch(p[1]) {
case 's':
--- 101,108 ----
}
/* Grab file name, "$", "set", or "unset". */
! if ((p = stretok(p, "\n\t ")) == NULL)
err("missing field");
if (p[0] == '/')
switch(p[1]) {
case 's':
***************
*** 121,131 ****
if (!strcmp(p, "..")) {
/* Don't go up, if haven't gone down. */
! if (!root)
goto noparent;
if (last->type != F_DIR || last->flags & F_DONE) {
! if (last == root)
goto noparent;
last = last->parent;
}
last->flags |= F_DONE;
--- 122,134 ----
if (!strcmp(p, "..")) {
/* Don't go up, if haven't gone down. */
! if (!root) {
goto noparent;
+ }
if (last->type != F_DIR || last->flags & F_DONE) {
! if (last == root) {
goto noparent;
+ }
last = last->parent;
}
last->flags |= F_DONE;
***************
*** 171,179 ****
int value;
char *ep;
! for (; (kw = strtok(t, "= \t\n")); t = NULL) {
ip->flags |= type = parsekey(kw, &value);
! if (value && (val = strtok(NULL, " \t\n")) == NULL)
err("missing value");
switch(type) {
case F_CKSUM:
--- 174,182 ----
int value;
char *ep;
! for (; (kw = stretok(t, "= \t\n")); t = NULL) {
ip->flags |= type = parsekey(kw, &value);
! if (value && (val = stretok(NULL, " \t\n")) == NULL)
err("missing value");
switch(type) {
case F_CKSUM:
***************
*** 281,286 ****
{
register char *p;
! while ((p = strtok(t, "\n\t ")))
ip->flags &= ~parsekey(p, NULL);
}
--- 284,353 ----
{
register char *p;
! while ((p = stretok(t, "\n\t "))) {
ip->flags &= ~parsekey(p, NULL);
+ }
+ }
+
+ /*
+ * Hacked version of strtok to not look at escaped characters
+ * during test for delimiters
+ */
+ char *
+ stretok(s, delim)
+ register char *s;
+ register const char *delim;
+ {
+ register char *spanp;
+ register int c, sc;
+ char *tok;
+ static char *last;
+
+
+ if (s == NULL && (s = last) == NULL)
+ return (NULL);
+
+ /*
+ * Skip (span) leading delimiters (s += strspn(s, delim), sort of).
+ */
+ cont:
+ c = *s++;
+ if (c == '\\') {
+ strcpy(s-1, s);
+ c = *s++;
+ }
+ for (spanp = (char *)delim; (sc = *spanp++) != 0;) {
+ if (c == sc)
+ goto cont;
+ }
+
+ if (c == 0) { /* no non-delimiter characters */
+ last = NULL;
+ return (NULL);
+ }
+ tok = s - 1;
+
+ /*
+ * Scan token (scan for delimiters: s += strcspn(s, delim), sort of).
+ * Note that delim must have one NUL; we stop if we see that, too.
+ */
+ for (;;) {
+ c = *s++;
+ if (c == '\\') {
+ strcpy(s-1, s);
+ c = *s++;
+ }
+ spanp = (char *)delim;
+ do {
+ if ((sc = *spanp++) == c) {
+ if (c == 0)
+ s = NULL;
+ else
+ s[-1] = 0;
+ last = s;
+ return (tok);
+ }
+ } while (sc != 0);
+ }
+ /* NOTREACHED */
}
--
Alan Batie ------ What goes up, must come down.
batie@aahz.jf.intel.com \ / Ask any system administrator.
+1 503-264-8844 (voice) \ / --unknown
D0 D2 39 0E 02 34 D6 B4 \/ 5A 41 21 8F 23 5F 08 9D
[-- Attachment #2 --]
-----BEGIN PGP SIGNATURE-----
Version: 2.6.2
iQCVAwUBNPykmRCfrckvDwdpAQF+RQP/bw888La8+OS4RNcGN6p3sUvYoq+AN18s
M2AGa+08ZhRVL65dl0VNN0b28z1KG7NJfqgGODpft8AJs19foFzUfcb3BLquS6lu
+IchCYlUxLkNDaBS7+6FHQgHIMd7HcHQqNXmh3OZfy0LVFW04B8CX1m724i1LIlO
5uw1jxuYimA=
=3rLH
-----END PGP SIGNATURE-----
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?19980303164721.61146>
