/[baselayout]/trunk/src/mountinfo.c
Gentoo

Contents of /trunk/src/mountinfo.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2799 - (show annotations) (download) (as text)
Tue Jul 31 16:05:56 2007 UTC (6 years, 11 months ago) by uberlord
File MIME type: text/x-csrc
File size: 6004 byte(s)
    All our binaries are now mulicalls into rc, which makes our on disk size
    a lot smaller.
1 /*
2 mountinfo.c
3 Obtains information about mounted filesystems.
4
5 Copyright 2007 Gentoo Foundation
6 */
7
8 #define APPLET "mountinfo"
9
10 #if defined(__DragonFly__) || defined(__FreeBSD__) || \
11 defined(__NetBSD__) || defined(__OpenBSD__)
12 #define BSD
13
14 #include <sys/types.h>
15 #include <sys/param.h>
16 #include <sys/ucred.h>
17 #include <sys/mount.h>
18 #elif defined(__linux__)
19 #include <limits.h>
20 #endif
21
22 #include <errno.h>
23 #include <getopt.h>
24 #include <limits.h>
25 #include <regex.h>
26 #include <stdio.h>
27 #include <stdlib.h>
28 #include <string.h>
29
30 #include "builtins.h"
31 #include "einfo.h"
32 #include "rc.h"
33 #include "rc-misc.h"
34 #include "strlist.h"
35
36
37 #ifdef BSD
38 static char **find_mounts (regex_t *node_regex, regex_t *skip_node_regex,
39 regex_t *fstype_regex, regex_t *skip_fstype_regex,
40 char **mounts, bool node, bool fstype)
41 {
42 struct statfs *mnts;
43 int nmnts;
44 int i;
45 char **list = NULL;
46
47 if ((nmnts = getmntinfo (&mnts, MNT_NOWAIT)) == 0)
48 eerrorx ("getmntinfo: %s", strerror (errno));
49
50 for (i = 0; i < nmnts; i++) {
51 if (node_regex &&
52 regexec (node_regex, mnts[i].f_mntfromname, 0, NULL, 0) != 0)
53 continue;
54 if (skip_node_regex &&
55 regexec (skip_node_regex, mnts[i].f_mntfromname, 0, NULL, 0) == 0)
56 continue;
57 if (fstype_regex &&
58 regexec (fstype_regex, mnts[i].f_fstypename, 0, NULL, 0) != 0)
59 continue;
60 if (skip_fstype_regex &&
61 regexec (skip_fstype_regex, mnts[i].f_fstypename, 0, NULL, 0) == 0)
62 continue;
63
64 if (mounts) {
65 bool found = false;
66 int j;
67 char *mnt;
68 STRLIST_FOREACH (mounts, mnt, j)
69 if (strcmp (mnt, mnts[i].f_mntonname) == 0) {
70 found = true;
71 break;
72 }
73 if (! found)
74 continue;
75 }
76
77 list = rc_strlist_addsortc (list, node ?
78 mnts[i].f_mntfromname :
79 fstype ? mnts[i].f_fstypename :
80 mnts[i].f_mntonname);
81 }
82
83 return (list);
84 }
85
86 #elif defined (__linux__)
87 static char **find_mounts (regex_t *node_regex, regex_t *skip_node_regex,
88 regex_t *fstype_regex, regex_t *skip_fstype_regex,
89 char **mounts, bool node, bool fstype)
90 {
91 FILE *fp;
92 char buffer[PATH_MAX * 3];
93 char *p;
94 char *from;
95 char *to;
96 char *fst;
97 char **list = NULL;
98
99 if ((fp = fopen ("/proc/mounts", "r")) == NULL)
100 eerrorx ("getmntinfo: %s", strerror (errno));
101
102 while (fgets (buffer, sizeof (buffer), fp)) {
103 p = buffer;
104 from = strsep (&p, " ");
105 if (node_regex &&
106 regexec (node_regex, from, 0, NULL, 0) != 0)
107 continue;
108 if (skip_node_regex &&
109 regexec (skip_node_regex, from, 0, NULL, 0) == 0)
110 continue;
111
112 to = strsep (&p, " ");
113 fst = strsep (&p, " ");
114 /* Skip the really silly rootfs */
115 if (strcmp (fst, "rootfs") == 0)
116 continue;
117 if (fstype_regex &&
118 regexec (fstype_regex, fst, 0, NULL, 0) != 0)
119 continue;
120 if (skip_fstype_regex &&
121 regexec (skip_fstype_regex, fst, 0, NULL, 0) == 0)
122 continue;
123
124 if (mounts) {
125 bool found = false;
126 int j;
127 char *mnt;
128 STRLIST_FOREACH (mounts, mnt, j)
129 if (strcmp (mnt, to) == 0) {
130 found = true;
131 break;
132 }
133 if (! found)
134 continue;
135 }
136
137 list = rc_strlist_addsortc (list, node ? from : fstype ? fst : to);
138 }
139 fclose (fp);
140
141 return (list);
142 }
143
144 #else
145 # error "Operating system not supported!"
146 #endif
147
148 static regex_t *get_regex (char *string)
149 {
150 regex_t *reg = rc_xmalloc (sizeof (regex_t));
151 int result;
152 char buffer[256];
153
154 if ((result = regcomp (reg, string, REG_EXTENDED | REG_NOSUB)) != 0)
155 {
156 regerror (result, reg, buffer, sizeof (buffer));
157 eerrorx ("%s: invalid regex `%s'", APPLET, buffer);
158 }
159
160 return (reg);
161 }
162
163 #include "_usage.h"
164 #define getoptstring "f:F:n:N:p:P:os" getoptstring_COMMON
165 static struct option longopts[] = {
166 { "fstype-regex", 1, NULL, 'f'},
167 { "skip-fstype-regex", 1, NULL, 'F'},
168 { "node-regex", 1, NULL, 'n'},
169 { "skip-node-regex", 1, NULL, 'N'},
170 { "point-regex", 1, NULL, 'p'},
171 { "skip-point-regex", 1, NULL, 'P'},
172 { "node", 0, NULL, 'o'},
173 { "fstype", 0, NULL, 's'},
174 longopts_COMMON
175 { NULL, 0, NULL, 0}
176 };
177 #include "_usage.c"
178
179 int mountinfo (int argc, char **argv)
180 {
181 int i;
182 regex_t *fstype_regex = NULL;
183 regex_t *node_regex = NULL;
184 regex_t *point_regex = NULL;
185 regex_t *skip_fstype_regex = NULL;
186 regex_t *skip_node_regex = NULL;
187 regex_t *skip_point_regex = NULL;
188 char **nodes = NULL;
189 char *n;
190 bool node = false;
191 bool fstype = false;
192 char **mounts = NULL;
193 int opt;
194 int result;
195
196 #define DO_REG(_var) \
197 if (_var) free (_var); \
198 _var = get_regex (optarg);
199
200 while ((opt = getopt_long (argc, argv, getoptstring,
201 longopts, (int *) 0)) != -1)
202 {
203 switch (opt) {
204 case 'f':
205 DO_REG (fstype_regex);
206 break;
207 case 'F':
208 DO_REG (skip_fstype_regex);
209 break;
210 case 'n':
211 DO_REG (node_regex);
212 break;
213 case 'N':
214 DO_REG (skip_node_regex);
215 break;
216 case 'p':
217 DO_REG (point_regex);
218 break;
219 case 'P':
220 DO_REG (skip_point_regex);
221 break;
222 case 'o':
223 node = true;
224 fstype = false;
225 break;
226 case 's':
227 node = false;
228 fstype = true;
229 break;
230
231 case_RC_COMMON_GETOPT
232 }
233 }
234
235 while (optind < argc) {
236 if (argv[optind][0] != '/')
237 eerrorx ("%s: `%s' is not a mount point", argv[0], argv[optind]);
238 mounts = rc_strlist_add (mounts, argv[optind++]);
239 }
240
241 nodes = find_mounts (node_regex, skip_node_regex,
242 fstype_regex, skip_fstype_regex,
243 mounts, node, fstype);
244
245 if (node_regex)
246 regfree (node_regex);
247 if (skip_node_regex)
248 regfree (skip_node_regex);
249 if (fstype_regex)
250 regfree (fstype_regex);
251 if (skip_fstype_regex)
252 regfree (skip_fstype_regex);
253
254 rc_strlist_reverse (nodes);
255
256 result = EXIT_FAILURE;
257 STRLIST_FOREACH (nodes, n, i) {
258 if (point_regex && regexec (point_regex, n, 0, NULL, 0) != 0)
259 continue;
260 if (skip_point_regex && regexec (skip_point_regex, n, 0, NULL, 0) == 0)
261 continue;
262 printf ("%s\n", n);
263 result = EXIT_SUCCESS;
264 }
265 rc_strlist_free (nodes);
266
267 if (point_regex)
268 regfree (point_regex);
269 if (skip_point_regex)
270 regfree (skip_point_regex);
271
272 exit (result);
273 }

  ViewVC Help
Powered by ViewVC 1.1.20