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: |