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

Contents of /trunk/src/mountinfo.c

Parent Directory Parent Directory | Revision Log Revision Log


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

  ViewVC Help
Powered by ViewVC 1.1.20