OLD | NEW |
1 /* Taken from util-linux source. GPLv2. | 1 /* Taken from util-linux source. GPLv2. |
2 * Emits the current rootfs device. | 2 * Emits the current rootfs device. |
3 * Works by searching /dev recursively for a BLK device with the same device | 3 * Works by searching /dev recursively for a BLK device with the same device |
4 * number as '/'. | 4 * number as '/'. |
5 */ | 5 */ |
6 | 6 |
7 #include <stdio.h> | 7 #include <stdio.h> |
8 #include <err.h> | 8 #include <err.h> |
9 #include <sys/types.h> | 9 #include <sys/types.h> |
10 #include <dirent.h> | 10 #include <dirent.h> |
11 #include <sys/stat.h> | 11 #include <sys/stat.h> |
12 #include <string.h> | 12 #include <string.h> |
13 | 13 |
14 | 14 |
15 static int | 15 static int |
16 find_dev_recursive(char *dirnamebuf, int number) { | 16 find_dev_recursive(char *dirnamebuf, int number, int deviceOnly) { |
17 DIR *dp; | 17 DIR *dp; |
18 struct dirent *dir; | 18 struct dirent *dir; |
19 struct stat s; | 19 struct stat s; |
20 int dirnamelen = 0; | 20 int dirnamelen = 0; |
21 | 21 |
22 if ((dp = opendir(dirnamebuf)) == NULL) | 22 if ((dp = opendir(dirnamebuf)) == NULL) |
23 err(1, "can't read directory %s", dirnamebuf); | 23 err(1, "can't read directory %s", dirnamebuf); |
24 dirnamelen = strlen(dirnamebuf); | 24 dirnamelen = strlen(dirnamebuf); |
25 while ((dir = readdir(dp)) != NULL) { | 25 while ((dir = readdir(dp)) != NULL) { |
26 if (!strcmp(dir->d_name, ".") || !strcmp(dir->d_name, "..")) | 26 if (!strcmp(dir->d_name, ".") || !strcmp(dir->d_name, "..")) |
27 continue; | 27 continue; |
28 if (dirnamelen + 1 + strlen(dir->d_name) > PATH_MAX) | 28 if (dirnamelen + 1 + strlen(dir->d_name) > PATH_MAX) |
29 continue; | 29 continue; |
30 dirnamebuf[dirnamelen] = '/'; | 30 dirnamebuf[dirnamelen] = '/'; |
31 strcpy(dirnamebuf+dirnamelen+1, dir->d_name); | 31 strcpy(dirnamebuf+dirnamelen+1, dir->d_name); |
32 if (lstat(dirnamebuf, &s) < 0) | 32 if (lstat(dirnamebuf, &s) < 0) |
33 continue; | 33 continue; |
34 if ((s.st_mode & S_IFMT) == S_IFBLK && s.st_rdev == number) | 34 if ((s.st_mode & S_IFMT) == S_IFBLK && s.st_rdev == number){ |
| 35 if (deviceOnly) { |
| 36 int len = strlen(dirnamebuf); |
| 37 char c = 0; |
| 38 do { |
| 39 c = dirnamebuf[len-1]; |
| 40 --len; |
| 41 }while(c > 0 && c < 9 && len > 0); |
| 42 /* arm has "p" for partition */ |
| 43 if (dirnamebuf[len-1] == 'p') |
| 44 --len; |
| 45 dirnamebuf[len]='\0'; |
| 46 } |
35 return 1; | 47 return 1; |
| 48 } |
36 if ((s.st_mode & S_IFMT) == S_IFDIR && | 49 if ((s.st_mode & S_IFMT) == S_IFDIR && |
37 find_dev_recursive(dirnamebuf, number)) | 50 find_dev_recursive(dirnamebuf, number, deviceOnly)) |
38 return 1; | 51 return 1; |
39 } | 52 } |
40 dirnamebuf[dirnamelen] = 0; | 53 dirnamebuf[dirnamelen] = 0; |
41 closedir(dp); | 54 closedir(dp); |
42 return 0; | 55 return 0; |
43 } | 56 } |
44 | 57 |
| 58 void usage(){ |
| 59 printf ("rootdev \n\t-d (for device only)\n"); |
| 60 } |
| 61 |
45 int main(int argc, char *argv[]) { | 62 int main(int argc, char *argv[]) { |
46 struct stat s; | 63 struct stat s; |
47 char *file = "/"; | 64 char *file = "/"; |
48 static char name[PATH_MAX+1]; | 65 static char name[PATH_MAX+1]; |
49 | 66 int deviceOnly=0; |
50 if (argc > 1) | 67 int c; |
51 file = argv[1]; | 68 extern char *optarg; |
| 69 extern int optind, optopt; |
| 70 while ((c = getopt(argc, argv, "hd")) != -1) { |
| 71 switch(c) { |
| 72 case 'd': |
| 73 deviceOnly=1; |
| 74 break; |
| 75 case 'h': |
| 76 default: |
| 77 usage(); |
| 78 return 1; |
| 79 } |
| 80 } |
| 81 if (argc - optind >= 1) |
| 82 file = argv[optind]; |
52 | 83 |
53 if (stat(file, &s) < 0) | 84 if (stat(file, &s) < 0) |
54 err(1, "unable to stat %s", file); | 85 err(1, "unable to stat %s", file); |
55 | 86 |
56 if (!s.st_dev) | 87 if (!s.st_dev) |
57 err(1, "unknown device number 0"); | 88 err(1, "unknown device number 0"); |
58 | 89 |
59 strcpy(name, "/dev"); | 90 strcpy(name, "/dev"); |
60 | 91 |
61 if (!find_dev_recursive(name, s.st_dev)) { | 92 if (!find_dev_recursive(name, s.st_dev, deviceOnly)) { |
62 fprintf(stderr, "unable to find match\n"); | 93 fprintf(stderr, "unable to find match\n"); |
63 return 1; | 94 return 1; |
64 } | 95 } |
65 | 96 |
66 printf("%s\n", name); | 97 printf("%s\n", name); |
67 | 98 |
68 return 0; | 99 return 0; |
69 } | 100 } |
OLD | NEW |