]> git.ipfire.org Git - thirdparty/util-linux.git/blob - sys-utils/mountpoint.c
Merge branch 'chcpu' of git://git.kernel.org/pub/scm/linux/kernel/git/heiko/util...
[thirdparty/util-linux.git] / sys-utils / mountpoint.c
1 /*
2 * mountpoint(1) - see if a directory is a mountpoint
3 *
4 * This is libmount based reimplementation of the mountpoit(1)
5 * from sysvinit project.
6 *
7 *
8 * Copyright (C) 2011 Red Hat, Inc. All rights reserved.
9 * Written by Karel Zak <kzak@redhat.com>
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * This program is distributed in the hope that it would be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software Foundation,
23 * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 */
25
26 #include <stdio.h>
27 #include <stdlib.h>
28 #include <errno.h>
29 #include <string.h>
30 #include <getopt.h>
31 #include <unistd.h>
32 #include <sys/types.h>
33 #include <sys/stat.h>
34
35 #include <libmount.h>
36
37 #include "nls.h"
38 #include "xalloc.h"
39 #include "c.h"
40
41 static int quiet;
42
43 static char *dir_to_device(const char *spec)
44 {
45 struct libmnt_table *tb = mnt_new_table_from_file("/proc/self/mountinfo");
46 struct libmnt_fs *fs;
47 char *res = NULL;
48
49 if (!tb)
50 return NULL;
51
52 fs = mnt_table_find_target(tb, spec, MNT_ITER_BACKWARD);
53 if (fs && mnt_fs_get_target(fs))
54 res = xstrdup(mnt_fs_get_source(fs));
55
56 mnt_free_table(tb);
57 return res;
58 }
59
60 static int print_devno(const char *devname, struct stat *st)
61 {
62 struct stat stbuf;
63
64 if (!st && stat(devname, &stbuf) == 0)
65 st = &stbuf;
66 if (!st)
67 return -1;
68 if (!S_ISBLK(st->st_mode)) {
69 if (!quiet)
70 warnx(_("%s: not a block device"), devname);
71 return -1;
72 }
73 printf("%u:%u\n", major(st->st_rdev), minor(st->st_rdev));
74 return 0;
75 }
76
77 static void __attribute__((__noreturn__)) usage(FILE *out)
78 {
79 fputs(_("\nUsage:\n"), out);
80 fprintf(out,
81 _(" %1$s [-qd] /path/to/directory\n"
82 " %1$s -x /dev/device\n"), program_invocation_short_name);
83
84 fputs(_("\nOptions:\n"), out);
85 fputs(_(" -q, --quiet quiet mode - don't print anything\n"
86 " -d, --fs-devno print maj:min device number of the filesystem\n"
87 " -x, --devno print maj:min device number of the block device\n"
88 " -h, --help this help\n"), out);
89
90 fprintf(out, _("\nFor more information see mountpoint(1).\n"));
91
92 exit(out == stderr ? EXIT_FAILURE : EXIT_SUCCESS);
93 }
94
95 int main(int argc, char **argv)
96 {
97 int c, fs_devno = 0, dev_devno = 0, rc = 0;
98 char *spec;
99 struct stat st;
100
101 static const struct option longopts[] = {
102 { "quiet", 0, 0, 'q' },
103 { "fs-devno", 0, 0, 'd' },
104 { "devno", 0, 0, 'x' },
105 { "help", 0, 0, 'h' },
106 { NULL, 0, 0, 0 }
107 };
108
109 setlocale(LC_ALL, "");
110 bindtextdomain(PACKAGE, LOCALEDIR);
111 textdomain(PACKAGE);
112
113 mnt_init_debug(0);
114
115 while ((c = getopt_long(argc, argv, "qdxh", longopts, NULL)) != -1) {
116
117 switch(c) {
118 case 'q':
119 quiet = 1;
120 break;
121 case 'd':
122 fs_devno = 1;
123 break;
124 case 'x':
125 dev_devno = 1;
126 break;
127 case 'h':
128 usage(stdout);
129 break;
130 default:
131 usage(stderr);
132 break;
133 }
134 }
135
136 if (optind + 1 != argc)
137 usage(stderr);
138
139 spec = argv[optind++];
140
141 if (stat(spec, &st)) {
142 if (!quiet)
143 err(EXIT_FAILURE, "%s", spec);
144 return EXIT_FAILURE;
145 }
146 if (dev_devno)
147 rc = print_devno(spec, &st);
148 else {
149 char *src;
150
151 if (!S_ISDIR(st.st_mode)) {
152 if (!quiet)
153 errx(EXIT_FAILURE, _("%s: not a directory"), spec);
154 return EXIT_FAILURE;
155 }
156 src = dir_to_device(spec);
157 if (!src) {
158 if (!quiet)
159 printf(_("%s is not a mountpoint\n"), spec);
160 return EXIT_FAILURE;
161 }
162 if (fs_devno)
163 rc = print_devno(src, NULL);
164 else if (!quiet)
165 printf(_("%s is a mountpoint\n"), spec);
166 free(src);
167 }
168
169 return rc ? EXIT_FAILURE : EXIT_SUCCESS;
170 }