1*cf5a6c84SAndroid Build Coastguard Worker /* mountpoint.c - Check if a directory is a mountpoint.
2*cf5a6c84SAndroid Build Coastguard Worker *
3*cf5a6c84SAndroid Build Coastguard Worker * Copyright 2012 Elie De Brauwer <[email protected]>
4*cf5a6c84SAndroid Build Coastguard Worker
5*cf5a6c84SAndroid Build Coastguard Worker USE_MOUNTPOINT(NEWTOY(mountpoint, "<1qdx[-dx]", TOYFLAG_BIN))
6*cf5a6c84SAndroid Build Coastguard Worker
7*cf5a6c84SAndroid Build Coastguard Worker config MOUNTPOINT
8*cf5a6c84SAndroid Build Coastguard Worker bool "mountpoint"
9*cf5a6c84SAndroid Build Coastguard Worker default y
10*cf5a6c84SAndroid Build Coastguard Worker help
11*cf5a6c84SAndroid Build Coastguard Worker usage: mountpoint [-qd] DIR
12*cf5a6c84SAndroid Build Coastguard Worker mountpoint [-qx] DEVICE
13*cf5a6c84SAndroid Build Coastguard Worker
14*cf5a6c84SAndroid Build Coastguard Worker Check whether the directory or device is a mountpoint.
15*cf5a6c84SAndroid Build Coastguard Worker
16*cf5a6c84SAndroid Build Coastguard Worker -q Be quiet, return zero if directory is a mountpoint
17*cf5a6c84SAndroid Build Coastguard Worker -d Print major/minor device number of the directory
18*cf5a6c84SAndroid Build Coastguard Worker -x Print major/minor device number of the block device
19*cf5a6c84SAndroid Build Coastguard Worker */
20*cf5a6c84SAndroid Build Coastguard Worker
21*cf5a6c84SAndroid Build Coastguard Worker #define FOR_mountpoint
22*cf5a6c84SAndroid Build Coastguard Worker #include "toys.h"
23*cf5a6c84SAndroid Build Coastguard Worker
die(char * gripe)24*cf5a6c84SAndroid Build Coastguard Worker static void die(char *gripe)
25*cf5a6c84SAndroid Build Coastguard Worker {
26*cf5a6c84SAndroid Build Coastguard Worker if (!FLAG(q)) printf("%s: not a %s\n", *toys.optargs, gripe);
27*cf5a6c84SAndroid Build Coastguard Worker
28*cf5a6c84SAndroid Build Coastguard Worker toys.exitval++;
29*cf5a6c84SAndroid Build Coastguard Worker xexit();
30*cf5a6c84SAndroid Build Coastguard Worker }
31*cf5a6c84SAndroid Build Coastguard Worker
mountpoint_main(void)32*cf5a6c84SAndroid Build Coastguard Worker void mountpoint_main(void)
33*cf5a6c84SAndroid Build Coastguard Worker {
34*cf5a6c84SAndroid Build Coastguard Worker struct stat st1, st2;
35*cf5a6c84SAndroid Build Coastguard Worker char *arg = *toys.optargs;
36*cf5a6c84SAndroid Build Coastguard Worker
37*cf5a6c84SAndroid Build Coastguard Worker if (lstat(arg, &st1)) (FLAG(q) ? die : perror_exit_raw)(arg);
38*cf5a6c84SAndroid Build Coastguard Worker
39*cf5a6c84SAndroid Build Coastguard Worker if (FLAG(x)) {
40*cf5a6c84SAndroid Build Coastguard Worker if (!S_ISBLK(st1.st_mode)) die("block device");
41*cf5a6c84SAndroid Build Coastguard Worker if (!FLAG(q))
42*cf5a6c84SAndroid Build Coastguard Worker printf("%u:%u\n", dev_major(st1.st_rdev), dev_minor(st1.st_rdev));
43*cf5a6c84SAndroid Build Coastguard Worker
44*cf5a6c84SAndroid Build Coastguard Worker return;
45*cf5a6c84SAndroid Build Coastguard Worker }
46*cf5a6c84SAndroid Build Coastguard Worker
47*cf5a6c84SAndroid Build Coastguard Worker // TODO: a file can be a mountpoint for --bind mounts.
48*cf5a6c84SAndroid Build Coastguard Worker if (!S_ISDIR(st1.st_mode)) die("directory");
49*cf5a6c84SAndroid Build Coastguard Worker
50*cf5a6c84SAndroid Build Coastguard Worker arg = xmprintf("%s/..", arg);
51*cf5a6c84SAndroid Build Coastguard Worker xstat(arg, &st2);
52*cf5a6c84SAndroid Build Coastguard Worker free(arg);
53*cf5a6c84SAndroid Build Coastguard Worker
54*cf5a6c84SAndroid Build Coastguard Worker // If the device is different, it's a mount point. If the device _and_
55*cf5a6c84SAndroid Build Coastguard Worker // inode are the same, it's probably "/". This misses --bind mounts from
56*cf5a6c84SAndroid Build Coastguard Worker // elsewhere in the same filesystem, but so does the other one and in the
57*cf5a6c84SAndroid Build Coastguard Worker // absence of a spec I guess that's the expected behavior?
58*cf5a6c84SAndroid Build Coastguard Worker toys.exitval = !(st1.st_dev != st2.st_dev || st1.st_ino == st2.st_ino);
59*cf5a6c84SAndroid Build Coastguard Worker if (FLAG(d)) printf("%u:%u\n", dev_major(st1.st_dev), dev_minor(st1.st_dev));
60*cf5a6c84SAndroid Build Coastguard Worker else if (!FLAG(q))
61*cf5a6c84SAndroid Build Coastguard Worker printf("%s is %sa mountpoint\n", *toys.optargs, toys.exitval ? "not " : "");
62*cf5a6c84SAndroid Build Coastguard Worker }
63