blob: c3dc175d8fc99221c44f1231f5996b9bffe37d24 [file] [log] [blame]
Bill Richardson75fcf622010-03-16 13:05:12 -07001/* Taken from util-linux source. GPLv2.
2 * Emits the current rootfs device.
3 * Works by searching /dev recursively for a BLK device with the same device
4 * number as '/'.
5 */
6
7#include <stdio.h>
8#include <err.h>
9#include <sys/types.h>
10#include <dirent.h>
11#include <sys/stat.h>
12#include <string.h>
13
14
15static int
Kobi Cohen-Araziafb2fb52010-07-26 12:48:36 -060016find_dev_recursive(char *dirnamebuf, int number, int deviceOnly) {
Bill Richardson75fcf622010-03-16 13:05:12 -070017 DIR *dp;
18 struct dirent *dir;
19 struct stat s;
20 int dirnamelen = 0;
21
22 if ((dp = opendir(dirnamebuf)) == NULL)
23 err(1, "can't read directory %s", dirnamebuf);
24 dirnamelen = strlen(dirnamebuf);
25 while ((dir = readdir(dp)) != NULL) {
26 if (!strcmp(dir->d_name, ".") || !strcmp(dir->d_name, ".."))
27 continue;
28 if (dirnamelen + 1 + strlen(dir->d_name) > PATH_MAX)
29 continue;
30 dirnamebuf[dirnamelen] = '/';
31 strcpy(dirnamebuf+dirnamelen+1, dir->d_name);
32 if (lstat(dirnamebuf, &s) < 0)
33 continue;
Kobi Cohen-Araziafb2fb52010-07-26 12:48:36 -060034 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 }
Bill Richardson75fcf622010-03-16 13:05:12 -070047 return 1;
Kobi Cohen-Araziafb2fb52010-07-26 12:48:36 -060048 }
Bill Richardson75fcf622010-03-16 13:05:12 -070049 if ((s.st_mode & S_IFMT) == S_IFDIR &&
Kobi Cohen-Araziafb2fb52010-07-26 12:48:36 -060050 find_dev_recursive(dirnamebuf, number, deviceOnly))
Bill Richardson75fcf622010-03-16 13:05:12 -070051 return 1;
52 }
53 dirnamebuf[dirnamelen] = 0;
54 closedir(dp);
55 return 0;
56}
57
Kobi Cohen-Araziafb2fb52010-07-26 12:48:36 -060058void usage(){
59 printf ("rootdev \n\t-d (for device only)\n");
60}
61
Bill Richardson75fcf622010-03-16 13:05:12 -070062int main(int argc, char *argv[]) {
63 struct stat s;
64 char *file = "/";
65 static char name[PATH_MAX+1];
Kobi Cohen-Araziafb2fb52010-07-26 12:48:36 -060066 int deviceOnly=0;
67 int c;
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];
Bill Richardson75fcf622010-03-16 13:05:12 -070083
84 if (stat(file, &s) < 0)
85 err(1, "unable to stat %s", file);
Kobi Cohen-Araziafb2fb52010-07-26 12:48:36 -060086
Bill Richardson75fcf622010-03-16 13:05:12 -070087 if (!s.st_dev)
88 err(1, "unknown device number 0");
89
90 strcpy(name, "/dev");
91
Kobi Cohen-Araziafb2fb52010-07-26 12:48:36 -060092 if (!find_dev_recursive(name, s.st_dev, deviceOnly)) {
Bill Richardson75fcf622010-03-16 13:05:12 -070093 fprintf(stderr, "unable to find match\n");
94 return 1;
95 }
96
97 printf("%s\n", name);
Kobi Cohen-Araziafb2fb52010-07-26 12:48:36 -060098
Bill Richardson75fcf622010-03-16 13:05:12 -070099 return 0;
100}