xref: /aosp_15_r20/external/toybox/toys/other/mountpoint.c (revision cf5a6c84e2b8763fc1a7db14496fd4742913b199)
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