1/* See LICENSE file for copyright and license details. */
2
3#include <sys/stat.h>
4#include <sys/sysmacros.h>
5#include <sys/types.h>
6
7#include <mntent.h>
8#include <stdio.h>
9#include <stdlib.h>
10#include <string.h>
11#include <unistd.h>
12
13#include "paths.h"
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 {
36 // ?man -d: specify directory
37 case 'd':
38 dflag = 1;
39 break;
40 // ?man -q: quiet mode; suppress output
41 case 'q':
42 qflag = 1;
43 break;
44 // ?man -x: hex format or match whole lines
45 case 'x':
46 xflag = 1;
47 break;
48 default:
49 usage();
50 }
51 ARGEND;
52
53 if (argc < 1)
54 usage();
55
56 if (stat(argv[0], &st1) < 0) {
57 if (qflag)
58 return 1;
59 eprintf("stat %s:", argv[0]);
60 }
61
62 if (xflag) {
63 if (!S_ISBLK(st1.st_mode)) {
64 if (qflag)
65 return 1;
66 eprintf("stat: %s: not a block device\n", argv[0]);
67 }
68 printf("%u:%u\n", major(st1.st_rdev), 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), minor(st1.st_dev));
80 return 0;
81 }
82
83 fp = setmntent(ARUU_LINUX_PATH_PROC_MOUNTS, "r");
84 if (!fp) {
85 if (qflag)
86 return 1;
87 eprintf("setmntent %s:", ARUU_LINUX_PATH_PROC_MOUNTS);
88 }
89 while ((me = getmntent(fp)) != NULL) {
90 if (stat(me->mnt_dir, &st2) < 0) {
91 if (qflag)
92 return 1;
93 eprintf("stat %s:", me->mnt_dir);
94 }
95 if (st1.st_dev == st2.st_dev && st1.st_ino == st2.st_ino)
96 break;
97 }
98 endmntent(fp);
99
100 if (me == NULL)
101 ret = 1;
102
103 if (!qflag)
104 printf("%s %s a mountpoint\n", argv[0], !ret ? "is" : "is not");
105
106 return ret;
107}