diff options
| author | Denis Vlasenko <vda.linux@googlemail.com> | 2007-04-13 23:59:52 +0000 |
|---|---|---|
| committer | Denis Vlasenko <vda.linux@googlemail.com> | 2007-04-13 23:59:52 +0000 |
| commit | 16abcd90aefae8bdb9f7d80a555982dba6ca59b5 (patch) | |
| tree | b7e23fd3c844849d188813323076c93105a57d4d | |
| parent | 334fa9bcb50df9a03288be252096750dcec14404 (diff) | |
| download | busybox-w32-16abcd90aefae8bdb9f7d80a555982dba6ca59b5.tar.gz busybox-w32-16abcd90aefae8bdb9f7d80a555982dba6ca59b5.tar.bz2 busybox-w32-16abcd90aefae8bdb9f7d80a555982dba6ca59b5.zip | |
teach find_root_device to deal with /dev/ subdirs
(by "Kirill K. Smirnov" <lich@math.spbu.ru>)
| -rw-r--r-- | coreutils/ls.c | 8 | ||||
| -rw-r--r-- | coreutils/rm.c | 2 | ||||
| -rw-r--r-- | include/libbb.h | 1 | ||||
| -rw-r--r-- | libbb/concat_subpath_file.c | 2 | ||||
| -rw-r--r-- | libbb/find_root_device.c | 59 | ||||
| -rw-r--r-- | libbb/simplify_path.c | 11 | ||||
| -rw-r--r-- | miscutils/devfsd.c | 2 | ||||
| -rw-r--r-- | networking/httpd.c | 10 | ||||
| -rw-r--r-- | shell/ash.c | 3 |
9 files changed, 71 insertions, 27 deletions
diff --git a/coreutils/ls.c b/coreutils/ls.c index 7bbb19d6c..b9c07adf8 100644 --- a/coreutils/ls.c +++ b/coreutils/ls.c | |||
| @@ -504,11 +504,11 @@ static struct dnode **list_dir(const char *path) | |||
| 504 | 504 | ||
| 505 | /* are we going to list the file- it may be . or .. or a hidden file */ | 505 | /* are we going to list the file- it may be . or .. or a hidden file */ |
| 506 | if (entry->d_name[0] == '.') { | 506 | if (entry->d_name[0] == '.') { |
| 507 | if ((entry->d_name[1] == 0 || ( | 507 | if ((!entry->d_name[1] || (entry->d_name[1] == '.' && !entry->d_name[2])) |
| 508 | entry->d_name[1] == '.' | 508 | && !(all_fmt & DISP_DOT) |
| 509 | && entry->d_name[2] == 0)) | 509 | ) { |
| 510 | && !(all_fmt & DISP_DOT)) | ||
| 511 | continue; | 510 | continue; |
| 511 | } | ||
| 512 | if (!(all_fmt & DISP_HIDDEN)) | 512 | if (!(all_fmt & DISP_HIDDEN)) |
| 513 | continue; | 513 | continue; |
| 514 | } | 514 | } |
diff --git a/coreutils/rm.c b/coreutils/rm.c index 61e3e7010..e29073db8 100644 --- a/coreutils/rm.c +++ b/coreutils/rm.c | |||
| @@ -40,7 +40,7 @@ int rm_main(int argc, char **argv) | |||
| 40 | do { | 40 | do { |
| 41 | const char *base = bb_get_last_path_component(*argv); | 41 | const char *base = bb_get_last_path_component(*argv); |
| 42 | 42 | ||
| 43 | if ((base[0] == '.') && (!base[1] || ((base[1] == '.') && !base[2]))) { | 43 | if (DOT_OR_DOTDOT(base)) { |
| 44 | bb_error_msg("cannot remove '.' or '..'"); | 44 | bb_error_msg("cannot remove '.' or '..'"); |
| 45 | } else if (remove_file(*argv, flags) >= 0) { | 45 | } else if (remove_file(*argv, flags) >= 0) { |
| 46 | continue; | 46 | continue; |
diff --git a/include/libbb.h b/include/libbb.h index 29ee8daae..212b048de 100644 --- a/include/libbb.h +++ b/include/libbb.h | |||
| @@ -405,6 +405,7 @@ extern char *xasprintf(const char *format, ...) __attribute__ ((format (printf, | |||
| 405 | #define NOT_LONE_DASH(s) ((s)[0] != '-' || (s)[1]) | 405 | #define NOT_LONE_DASH(s) ((s)[0] != '-' || (s)[1]) |
| 406 | #define LONE_CHAR(s,c) ((s)[0] == (c) && !(s)[1]) | 406 | #define LONE_CHAR(s,c) ((s)[0] == (c) && !(s)[1]) |
| 407 | #define NOT_LONE_CHAR(s,c) ((s)[0] != (c) || (s)[1]) | 407 | #define NOT_LONE_CHAR(s,c) ((s)[0] != (c) || (s)[1]) |
| 408 | #define DOT_OR_DOTDOT(s) ((s)[0] == '.' && (!(s)[1] || ((s)[1] == '.' && !(s)[2]))) | ||
| 408 | 409 | ||
| 409 | /* dmalloc will redefine these to it's own implementation. It is safe | 410 | /* dmalloc will redefine these to it's own implementation. It is safe |
| 410 | * to have the prototypes here unconditionally. */ | 411 | * to have the prototypes here unconditionally. */ |
diff --git a/libbb/concat_subpath_file.c b/libbb/concat_subpath_file.c index 6bbe49ab5..1c0058889 100644 --- a/libbb/concat_subpath_file.c +++ b/libbb/concat_subpath_file.c | |||
| @@ -17,7 +17,7 @@ | |||
| 17 | 17 | ||
| 18 | char *concat_subpath_file(const char *path, const char *f) | 18 | char *concat_subpath_file(const char *path, const char *f) |
| 19 | { | 19 | { |
| 20 | if (f && *f == '.' && (!f[1] || (f[1] == '.' && !f[2]))) | 20 | if (f && DOT_OR_DOTDOT(f)) |
| 21 | return NULL; | 21 | return NULL; |
| 22 | return concat_path_file(path, f); | 22 | return concat_path_file(path, f); |
| 23 | } | 23 | } |
diff --git a/libbb/find_root_device.c b/libbb/find_root_device.c index ea360eae5..7182102c7 100644 --- a/libbb/find_root_device.c +++ b/libbb/find_root_device.c | |||
| @@ -9,26 +9,65 @@ | |||
| 9 | 9 | ||
| 10 | #include "libbb.h" | 10 | #include "libbb.h" |
| 11 | 11 | ||
| 12 | char *find_block_device(const char *path) | 12 | /* Find block device /dev/XXX which contains specified file |
| 13 | * We handle /dev/dir/dir/dir too, at a cost of ~80 more bytes code */ | ||
| 14 | |||
| 15 | /* Do not reallocate all this stuff on each recursion */ | ||
| 16 | enum { DEVNAME_MAX = 256 }; | ||
| 17 | struct arena { | ||
| 18 | struct stat st; | ||
| 19 | dev_t dev; | ||
| 20 | /* Was PATH_MAX, but we recurse _/dev_. We can assume | ||
| 21 | * people are not crazy enough to have mega-deep tree there */ | ||
| 22 | char devpath[DEVNAME_MAX]; | ||
| 23 | }; | ||
| 24 | |||
| 25 | static char *find_block_device_in_dir(struct arena *ap) | ||
| 13 | { | 26 | { |
| 14 | DIR *dir; | 27 | DIR *dir; |
| 15 | struct dirent *entry; | 28 | struct dirent *entry; |
| 16 | struct stat st; | 29 | char *retpath = NULL; |
| 17 | dev_t dev; | 30 | int len, rem; |
| 18 | char *retpath=NULL; | 31 | |
| 32 | dir = opendir(ap->devpath); | ||
| 33 | if (!dir) | ||
| 34 | return NULL; | ||
| 19 | 35 | ||
| 20 | if (stat(path, &st) || !(dir = opendir("/dev"))) | 36 | len = strlen(ap->devpath); |
| 37 | rem = DEVNAME_MAX-2 - len; | ||
| 38 | if (rem <= 0) | ||
| 21 | return NULL; | 39 | return NULL; |
| 22 | dev = (st.st_mode & S_IFMT) == S_IFBLK ? st.st_rdev : st.st_dev; | 40 | ap->devpath[len++] = '/'; |
| 41 | |||
| 23 | while ((entry = readdir(dir)) != NULL) { | 42 | while ((entry = readdir(dir)) != NULL) { |
| 24 | char devpath[PATH_MAX]; | 43 | safe_strncpy(ap->devpath + len, entry->d_name, rem); |
| 25 | sprintf(devpath,"/dev/%s", entry->d_name); | 44 | if (stat(ap->devpath, &ap->st) != 0) |
| 26 | if (!stat(devpath, &st) && S_ISBLK(st.st_mode) && st.st_rdev == dev) { | 45 | continue; |
| 27 | retpath = xstrdup(devpath); | 46 | if (S_ISBLK(ap->st.st_mode) && ap->st.st_rdev == ap->dev) { |
| 47 | retpath = xstrdup(ap->devpath); | ||
| 28 | break; | 48 | break; |
| 29 | } | 49 | } |
| 50 | if (S_ISDIR(ap->st.st_mode)) { | ||
| 51 | /* Do not recurse for '.' and '..' */ | ||
| 52 | if (DOT_OR_DOTDOT(entry->d_name)) | ||
| 53 | continue; | ||
| 54 | retpath = find_block_device_in_dir(ap); | ||
| 55 | if (retpath) | ||
| 56 | break; | ||
| 57 | } | ||
| 30 | } | 58 | } |
| 31 | closedir(dir); | 59 | closedir(dir); |
| 32 | 60 | ||
| 33 | return retpath; | 61 | return retpath; |
| 34 | } | 62 | } |
| 63 | |||
| 64 | char *find_block_device(const char *path) | ||
| 65 | { | ||
| 66 | struct arena a; | ||
| 67 | |||
| 68 | if (stat(path, &a.st) != 0) | ||
| 69 | return NULL; | ||
| 70 | a.dev = S_ISBLK(a.st.st_mode) ? a.st.st_rdev : a.st.st_dev; | ||
| 71 | strcpy(a.devpath, "/dev"); | ||
| 72 | return find_block_device_in_dir(&a); | ||
| 73 | } | ||
diff --git a/libbb/simplify_path.c b/libbb/simplify_path.c index 7e68e3911..29e371df6 100644 --- a/libbb/simplify_path.c +++ b/libbb/simplify_path.c | |||
| @@ -26,13 +26,16 @@ char *bb_simplify_path(const char *path) | |||
| 26 | if (*p == '/') { | 26 | if (*p == '/') { |
| 27 | if (*s == '/') { /* skip duplicate (or initial) slash */ | 27 | if (*s == '/') { /* skip duplicate (or initial) slash */ |
| 28 | continue; | 28 | continue; |
| 29 | } else if (*s == '.') { | 29 | } |
| 30 | if (s[1] == '/' || s[1] == 0) { /* remove extra '.' */ | 30 | if (*s == '.') { |
| 31 | if (s[1] == '/' || !s[1]) { /* remove extra '.' */ | ||
| 31 | continue; | 32 | continue; |
| 32 | } else if ((s[1] == '.') && (s[2] == '/' || s[2] == 0)) { | 33 | } |
| 34 | if ((s[1] == '.') && (s[2] == '/' || !s[2])) { | ||
| 33 | ++s; | 35 | ++s; |
| 34 | if (p > start) { | 36 | if (p > start) { |
| 35 | while (*--p != '/'); /* omit previous dir */ | 37 | while (*--p != '/') /* omit previous dir */ |
| 38 | continue; | ||
| 36 | } | 39 | } |
| 37 | continue; | 40 | continue; |
| 38 | } | 41 | } |
diff --git a/miscutils/devfsd.c b/miscutils/devfsd.c index 0069b280e..d1a5163d2 100644 --- a/miscutils/devfsd.c +++ b/miscutils/devfsd.c | |||
| @@ -1369,7 +1369,7 @@ static void dir_operation(int type, const char * dir_name, int var, unsigned lon | |||
| 1369 | while ( (de = readdir (dp) ) != NULL ) | 1369 | while ( (de = readdir (dp) ) != NULL ) |
| 1370 | { | 1370 | { |
| 1371 | 1371 | ||
| 1372 | if(de->d_name && *de->d_name == '.' && (!de->d_name[1] || (de->d_name[1] == '.' && !de->d_name[2]))) | 1372 | if(de->d_name && DOT_OR_DOTDOT(de->d_name)) |
| 1373 | continue; | 1373 | continue; |
| 1374 | snprintf (path, sizeof (path), "%s/%s", dir_name, de->d_name); | 1374 | snprintf (path, sizeof (path), "%s/%s", dir_name, de->d_name); |
| 1375 | debug_msg_logger(LOG_ERR, "%s: %s", __FUNCTION__, path); | 1375 | debug_msg_logger(LOG_ERR, "%s: %s", __FUNCTION__, path); |
diff --git a/networking/httpd.c b/networking/httpd.c index d80df937a..1f7c886de 100644 --- a/networking/httpd.c +++ b/networking/httpd.c | |||
| @@ -1573,7 +1573,7 @@ static void handleIncoming(void) | |||
| 1573 | } | 1573 | } |
| 1574 | 1574 | ||
| 1575 | /* algorithm stolen from libbb bb_simplify_path(), | 1575 | /* algorithm stolen from libbb bb_simplify_path(), |
| 1576 | but don't strdup and reducing trailing slash and protect out root */ | 1576 | * but don't strdup and reducing trailing slash and protect out root */ |
| 1577 | purl = test = url; | 1577 | purl = test = url; |
| 1578 | do { | 1578 | do { |
| 1579 | if (*purl == '/') { | 1579 | if (*purl == '/') { |
| @@ -1583,18 +1583,18 @@ static void handleIncoming(void) | |||
| 1583 | } | 1583 | } |
| 1584 | if (*test == '.') { | 1584 | if (*test == '.') { |
| 1585 | /* skip extra '.' */ | 1585 | /* skip extra '.' */ |
| 1586 | if (test[1] == '/' || test[1] == 0) { | 1586 | if (test[1] == '/' || !test[1]) { |
| 1587 | continue; | 1587 | continue; |
| 1588 | } else | 1588 | } |
| 1589 | /* '..': be careful */ | 1589 | /* '..': be careful */ |
| 1590 | if (test[1] == '.' && (test[2] == '/' || test[2] == 0)) { | 1590 | if (test[1] == '.' && (test[2] == '/' || !test[2])) { |
| 1591 | ++test; | 1591 | ++test; |
| 1592 | if (purl == url) { | 1592 | if (purl == url) { |
| 1593 | /* protect out root */ | 1593 | /* protect out root */ |
| 1594 | goto BAD_REQUEST; | 1594 | goto BAD_REQUEST; |
| 1595 | } | 1595 | } |
| 1596 | while (*--purl != '/') /* omit previous dir */; | 1596 | while (*--purl != '/') /* omit previous dir */; |
| 1597 | continue; | 1597 | continue; |
| 1598 | } | 1598 | } |
| 1599 | } | 1599 | } |
| 1600 | } | 1600 | } |
diff --git a/shell/ash.c b/shell/ash.c index f8207a6cc..63f039df4 100644 --- a/shell/ash.c +++ b/shell/ash.c | |||
| @@ -2293,7 +2293,8 @@ updatepwd(const char *dir) | |||
| 2293 | break; | 2293 | break; |
| 2294 | } | 2294 | } |
| 2295 | break; | 2295 | break; |
| 2296 | } else if (p[1] == '\0') | 2296 | } |
| 2297 | if (p[1] == '\0') | ||
| 2297 | break; | 2298 | break; |
| 2298 | /* fall through */ | 2299 | /* fall through */ |
| 2299 | default: | 2300 | default: |
