blob: 053745d41b750a1d05c36b63f9952b9ecb7a2f81 [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
16find_dev_recursive(char *dirnamebuf, int number) {
17 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;
34 if ((s.st_mode & S_IFMT) == S_IFBLK && s.st_rdev == number)
35 return 1;
36 if ((s.st_mode & S_IFMT) == S_IFDIR &&
37 find_dev_recursive(dirnamebuf, number))
38 return 1;
39 }
40 dirnamebuf[dirnamelen] = 0;
41 closedir(dp);
42 return 0;
43}
44
45int main(int argc, char *argv[]) {
46 struct stat s;
47 char *file = "/";
48 static char name[PATH_MAX+1];
49
50 if (argc > 1)
51 file = argv[1];
52
53 if (stat(file, &s) < 0)
54 err(1, "unable to stat %s", file);
55
56 if (!s.st_dev)
57 err(1, "unknown device number 0");
58
59 strcpy(name, "/dev");
60
61 if (!find_dev_recursive(name, s.st_dev)) {
62 fprintf(stderr, "unable to find match\n");
63 return 1;
64 }
65
66 printf("%s\n", name);
67
68 return 0;
69}