[9] | 1 | /* printroot - print root device on stdout Author: Bruce Evans */
|
---|
| 2 |
|
---|
| 3 | /* This program figures out what the root device is by doing a stat on it, and
|
---|
| 4 | * then searching /dev until it finds an entry with the same device number.
|
---|
| 5 | * A typical use (probably the only use) is in /etc/rc for initializing
|
---|
| 6 | * /etc/mtab, as follows:
|
---|
| 7 | *
|
---|
| 8 | * /usr/bin/printroot >/etc/mtab
|
---|
| 9 | *
|
---|
| 10 | * 9 Dec 1989 - clean up for 1.5 - full prototypes (BDE)
|
---|
| 11 | * 15 Oct 1989 - avoid ACK cc bugs (BDE):
|
---|
| 12 | * - sizeof "foo" is 2 (from wrong type char *) instead of 4
|
---|
| 13 | * - char foo[10] = "bar"; allocates 4 bytes instead of 10
|
---|
| 14 | * 1 Oct 1989 - Minor changes by Andy Tanenbaum
|
---|
| 15 | * 5 Oct 1992 - Use readdir (kjb)
|
---|
| 16 | * 26 Nov 1994 - Flag -r: print just the root device (kjb)
|
---|
| 17 | */
|
---|
| 18 |
|
---|
| 19 | #include <sys/types.h>
|
---|
| 20 | #include <sys/stat.h>
|
---|
| 21 | #include <fcntl.h>
|
---|
| 22 | #include <limits.h>
|
---|
| 23 | #include <stdlib.h>
|
---|
| 24 | #include <string.h>
|
---|
| 25 | #include <unistd.h>
|
---|
| 26 | #include <minix/minlib.h>
|
---|
| 27 | #include <dirent.h>
|
---|
| 28 |
|
---|
| 29 | static char DEV_PATH[] = "/dev/"; /* #define would step on sizeof bug */
|
---|
| 30 | static char MESSAGE[] = " / "; /* ditto */
|
---|
| 31 | #define UNKNOWN_DEV "/dev/unknown"
|
---|
| 32 | #define ROOT "/"
|
---|
| 33 | int rflag;
|
---|
| 34 |
|
---|
| 35 | _PROTOTYPE(int main, (int argc, char **argv));
|
---|
| 36 | _PROTOTYPE(void done, (char *name, int status));
|
---|
| 37 |
|
---|
| 38 | int main(argc, argv)
|
---|
| 39 | int argc;
|
---|
| 40 | char **argv;
|
---|
| 41 | {
|
---|
| 42 | DIR *dp;
|
---|
| 43 | struct dirent *entry;
|
---|
| 44 | struct stat filestat, rootstat;
|
---|
| 45 | static char namebuf[sizeof DEV_PATH + NAME_MAX];
|
---|
| 46 |
|
---|
| 47 | rflag = (argc > 1 && strcmp(argv[1], "-r") == 0);
|
---|
| 48 |
|
---|
| 49 | if (stat(ROOT, &rootstat) == 0 && (dp = opendir(DEV_PATH)) != (DIR *) NULL) {
|
---|
| 50 | while ((entry = readdir(dp)) != (struct dirent *) NULL) {
|
---|
| 51 | strcpy(namebuf, DEV_PATH);
|
---|
| 52 | strcat(namebuf, entry->d_name);
|
---|
| 53 | if (stat(namebuf, &filestat) != 0) continue;
|
---|
| 54 | if ((filestat.st_mode & S_IFMT) != S_IFBLK) continue;
|
---|
| 55 | if (filestat.st_rdev != rootstat.st_dev) continue;
|
---|
| 56 | done(namebuf, 0);
|
---|
| 57 | }
|
---|
| 58 | }
|
---|
| 59 | done(UNKNOWN_DEV, 1);
|
---|
| 60 | return(0); /* not reached */
|
---|
| 61 | }
|
---|
| 62 |
|
---|
| 63 | void done(name, status)
|
---|
| 64 | char *name;
|
---|
| 65 | int status;
|
---|
| 66 | {
|
---|
| 67 | int v;
|
---|
| 68 |
|
---|
| 69 | write(1, name, strlen(name));
|
---|
| 70 | if (rflag) {
|
---|
| 71 | write(1, "\n", 1);
|
---|
| 72 | exit(status);
|
---|
| 73 | }
|
---|
| 74 | write(1, MESSAGE, sizeof MESSAGE - 1);
|
---|
| 75 | v = fsversion(name, "printroot"); /* determine file system version */
|
---|
| 76 | if (v == 1)
|
---|
| 77 | write(1, "1 rw\n", 5);
|
---|
| 78 | else if (v == 2)
|
---|
| 79 | write(1, "2 rw\n", 5);
|
---|
| 80 | else if (v == 3)
|
---|
| 81 | write(1, "3 rw\n", 5);
|
---|
| 82 | else
|
---|
| 83 | write(1, "0 rw\n", 5);
|
---|
| 84 | exit(status);
|
---|
| 85 | }
|
---|