1/* See LICENSE file for copyright and license details. */
2
3
4#include <sys/stat.h>
5#include <sys/sysmacros.h>
6#include <sys/types.h>
7
8#include <mntent.h>
9#include <stdio.h>
10#include <stdlib.h>
11#include <string.h>
12#include <unistd.h>
13
14#include "util.h"
15
16static void
17usage(void)
18{
19 eprintf("usage: %s [-dqx] target\n", argv0);
20}
21
22// ?man mountpoint: check if a directory is a mountpoint
23// ?man arguments: target
24// ?man determine if a directory is a mountpoint
25int
26main(int argc, char *argv[])
27{
28 int dflag = 0, qflag = 0, xflag = 0;
29 int ret = 0;
30 struct mntent *me = NULL;
31 FILE *fp;
32 struct stat st1, st2;
33
34 ARGBEGIN {
35 // ?man -d: specify directory
36 case 'd':
37 dflag = 1;
38 break;
39 // ?man -q: quiet mode; suppress output
40 case 'q':
41 qflag = 1;
42 break;
43 // ?man -x: hex format or match whole lines
44 case 'x':
45 xflag = 1;
46 break;
47 default:
48 usage();
49 } ARGEND;
50
51 if (argc < 1)
52 usage();
53
54 if (stat(argv[0], &st1) < 0) {
55 if (qflag)
56 return 1;
57 eprintf("stat %s:", argv[0]);
58 }
59
60 if (xflag) {
61 if (!S_ISBLK(st1.st_mode)) {
62 if (qflag)
63 return 1;
64 eprintf("stat: %s: not a block device\n",
65 argv[0]);
66 }
67 printf("%u:%u\n", major(st1.st_rdev),
68 minor(st1.st_rdev));
69 return 0;
70 }
71
72 if (!S_ISDIR(st1.st_mode)) {
73 if (qflag)
74 return 1;
75 eprintf("stat %s: not a directory\n", argv[0]);
76 }
77
78 if (dflag) {
79 printf("%u:%u\n", major(st1.st_dev),
80 minor(st1.st_dev));
81 return 0;
82 }
83
84 fp = setmntent("/proc/mounts", "r");
85 if (!fp) {
86 if (qflag)
87 return 1;
88 eprintf("setmntent %s:", "/proc/mounts");
89 }
90 while ((me = getmntent(fp)) != NULL) {
91 if (stat(me->mnt_dir, &st2) < 0) {
92 if (qflag)
93 return 1;
94 eprintf("stat %s:", me->mnt_dir);
95 }
96 if (st1.st_dev == st2.st_dev &&
97 st1.st_ino == st2.st_ino)
98 break;
99 }
100 endmntent(fp);
101
102 if (me == NULL)
103 ret = 1;
104
105 if (!qflag)
106 printf("%s %s a mountpoint\n", argv[0],
107 !ret ? "is" : "is not");
108
109 return ret;
110}