aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorvda <vda@69ca8d6d-28ef-0310-b511-8ec308f3f277>2007-04-13 23:59:52 +0000
committervda <vda@69ca8d6d-28ef-0310-b511-8ec308f3f277>2007-04-13 23:59:52 +0000
commit86b5b2210f0ea0158af81b9da1f6849ea7dcea5d (patch)
treeb7e23fd3c844849d188813323076c93105a57d4d
parentb2f7a26679f7d538944f4725e92b512745cff948 (diff)
downloadbusybox-w32-86b5b2210f0ea0158af81b9da1f6849ea7dcea5d.tar.gz
busybox-w32-86b5b2210f0ea0158af81b9da1f6849ea7dcea5d.tar.bz2
busybox-w32-86b5b2210f0ea0158af81b9da1f6849ea7dcea5d.zip
teach find_root_device to deal with /dev/ subdirs
(by "Kirill K. Smirnov" <lich@math.spbu.ru>) git-svn-id: svn://busybox.net/trunk/busybox@18435 69ca8d6d-28ef-0310-b511-8ec308f3f277
-rw-r--r--coreutils/ls.c8
-rw-r--r--coreutils/rm.c2
-rw-r--r--include/libbb.h1
-rw-r--r--libbb/concat_subpath_file.c2
-rw-r--r--libbb/find_root_device.c59
-rw-r--r--libbb/simplify_path.c11
-rw-r--r--miscutils/devfsd.c2
-rw-r--r--networking/httpd.c10
-rw-r--r--shell/ash.c3
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
18char *concat_subpath_file(const char *path, const char *f) 18char *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
12char *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 */
16enum { DEVNAME_MAX = 256 };
17struct 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
25static 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
64char *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: