Skip site navigation (1)Skip section navigation (2)
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

--J/dobhs11T7y2rNN
Content-Type: text/plain; charset=us-ascii

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

--J/dobhs11T7y2rNN
Content-Type: application/pgp-signature

-----BEGIN PGP SIGNATURE-----
Version: 2.6.2

iQCVAwUBNPykmRCfrckvDwdpAQF+RQP/bw888La8+OS4RNcGN6p3sUvYoq+AN18s
M2AGa+08ZhRVL65dl0VNN0b28z1KG7NJfqgGODpft8AJs19foFzUfcb3BLquS6lu
+IchCYlUxLkNDaBS7+6FHQgHIMd7HcHQqNXmh3OZfy0LVFW04B8CX1m724i1LIlO
5uw1jxuYimA=
=3rLH
-----END PGP SIGNATURE-----

--J/dobhs11T7y2rNN--

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



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