bug#1205: [BusyBox] bug#1205: BusyBox] bug#1205: mount handles links differently in 0.60

Vladimir N. Oleynik dzo at simtreas.ru
Tue Aug 7 04:45:02 MDT 2001


Matt,

> > OK, the following patch should behave more like the standard mount
> > command, in that it doesn't follow symlinks when canonicalizing
> > pathnames.  I'll wait for approval, since the simplify_path
> > function is anything but.
> 
> Im tested you patch.
> If input string is "/" or "/../" or "///" your function retured empty string.

I rewrite simplify_path() wich correct this error and reduce 74 bytes size.
Work test in attach. Please compile as
$ cc -I. -Os sla.c libbb.a
(Or for test your code: witch -DMATT)


--w
vodz
-------------- next part --------------
#include "libbb/libbb.h"
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <unistd.h>

#ifdef MATT
/* Chop out LEN bytes of a string, starting at S.  */
static void strchop(char *s, size_t len)
{
       memmove(s, s + len, strlen(s + len) + 1);
}

char *simplify_path(const char *path)
{
       char *s;
       int i, j;

       if (path[0] == '/')
	       s = xstrdup(path);
       else {
	       char *cwd = xgetcwd(NULL);
	       s = concat_path_file(cwd, path);
	       free(cwd);
       }

       for (i = 0; s[i] != '\0'; i++) {
	       if (s[i] == '/') {
		       strchop(s+i+1, strspn(s+i+1, "/"));

		       if (s[i+1] == '\0')
			       s[i] = '\0';
		       else if (s[i+1] == '.') {
			       if (s[i+2] == '\0' || s[i+2] == '/') {
				       strchop(s+i+1, 1 + strspn(s+i+2, "/"));
				       i--;
			       } else if (s[i+2] == '.' && (s[i+3] == '\0' || s[i+3] == '/')) {
				       for (j = i - 1; 0 < j && s[j] != '/'; j--)
					       /* Loop.  */;
				       if (j < 0)
					       j = 0;
				       strchop(s+j+1, (i - j) + 2 + strspn(s+i+3, "/"));
				       i = j - 1;
			       }
		       }
	       }
       }

       return s;
}

#else
char *my_simplify_path(const char *path)
{
	char *s, *start, *next;

	if (path[0] == '/')
	       start = xstrdup(path);
	else {
	       s = xgetcwd(NULL);
	       start = concat_path_file(s, path);
	       free(s);
	}
	s = start;
	/* remove . and .. */
	while(*s) {
		if(*s++ == '.') {
			if(*s == '/' || *s == 0) {
				/* remove . */
				s = strcpy(s-1, s); /* maybe set // */
			}
			else if(*s == '.' && (*(s+1) == '/' || *(s+1) == 0)) {
				/* remove "dir/.." */
				next = s+1;     /* set after ".." */
				/* skip previous slashes */
				for(s -= 2; s>start && *s == '/'; s--)
					;
				/* skip previous dir */
				while(*s != '/') s--;
				/* remove previous dir */
				strcpy(s, next);  /* maybe set // */
			}
		}
	}
	/* remove duplicate slashes */
	s = start;
	while(*s) {
		if(*s++ == '/') {
			for(next = s; *next == '/'; next++)
				;
			if(next!=s)
				s = strcpy(s-1, next);
		}
	}
	/* remove trailing slash */
	s--;
	if(s < start) {
		/* all / removed to empty */
		start[0] = '/';
		start[1] = 0;
	} else if(s>start && *s == '/') /* trailing slash */
		*s = '\0';

	return start;
}
#endif

const char *applet_name = "sla";

int main(void)
{
	char buf[80];
	char *s;
	int l;

	for(;;) {
		printf("test => ");
		if(fgets(buf, 80, stdin)==NULL)
			return 0;
		l = strlen(buf);
		if(l<=1)
			return 0;
		buf[l-1]=0;
#ifdef MATT
		s = simplify_path(buf);
		printf("path => %s\n", s);
		free(s);
#else
		s = my_simplify_path(buf);
		printf("mpath=> %s\n", s);
		free(s);
#endif
	}
}


More information about the busybox mailing list