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