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

Contents of /trunk/src/mountinfo.c

Parent Directory Parent Directory | Revision Log Revision Log


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

  ViewVC Help
Powered by ViewVC 1.1.20