Magellan Linux

Annotation of /trunk/mkinitrd-magellan/busybox/libbb/find_root_device.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 816 - (hide annotations) (download)
Fri Apr 24 18:33:46 2009 UTC (15 years, 1 month ago) by niro
File MIME type: text/plain
File size: 1721 byte(s)
-updated to busybox-1.13.4
1 niro 532 /* vi: set sw=4 ts=4: */
2     /*
3     * Utility routines.
4     *
5     * Copyright (C) 1999-2004 by Erik Andersen <andersen@codepoet.org>
6     *
7     * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
8     */
9    
10     #include "libbb.h"
11    
12 niro 816 /* 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)
26 niro 532 {
27     DIR *dir;
28     struct dirent *entry;
29 niro 816 char *retpath = NULL;
30     int len, rem;
31 niro 532
32 niro 816 dir = opendir(ap->devpath);
33     if (!dir)
34 niro 532 return NULL;
35 niro 816
36     len = strlen(ap->devpath);
37     rem = DEVNAME_MAX-2 - len;
38     if (rem <= 0)
39     return NULL;
40     ap->devpath[len++] = '/';
41    
42 niro 532 while ((entry = readdir(dir)) != NULL) {
43 niro 816 safe_strncpy(ap->devpath + len, entry->d_name, rem);
44     /* lstat: do not follow links */
45     if (lstat(ap->devpath, &ap->st) != 0)
46     continue;
47     if (S_ISBLK(ap->st.st_mode) && ap->st.st_rdev == ap->dev) {
48     retpath = xstrdup(ap->devpath);
49 niro 532 break;
50     }
51 niro 816 if (S_ISDIR(ap->st.st_mode)) {
52     /* Do not recurse for '.' and '..' */
53     if (DOT_OR_DOTDOT(entry->d_name))
54     continue;
55     retpath = find_block_device_in_dir(ap);
56     if (retpath)
57     break;
58     }
59 niro 532 }
60     closedir(dir);
61    
62     return retpath;
63     }
64 niro 816
65     char* FAST_FUNC find_block_device(const char *path)
66     {
67     struct arena a;
68    
69     if (stat(path, &a.st) != 0)
70     return NULL;
71     a.dev = S_ISBLK(a.st.st_mode) ? a.st.st_rdev : a.st.st_dev;
72     strcpy(a.devpath, "/dev");
73     return find_block_device_in_dir(&a);
74     }