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

Diff of /trunk/src/mountinfo.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

Revision 2865 Revision 2881
29#include "einfo.h" 29#include "einfo.h"
30#include "rc.h" 30#include "rc.h"
31#include "rc-misc.h" 31#include "rc-misc.h"
32#include "strlist.h" 32#include "strlist.h"
33 33
34typedef enum {
35 mount_from,
36 mount_to,
37 mount_fstype,
38 mount_options
39} mount_type;
40
41struct args {
42 regex_t *node_regex;
43 regex_t *skip_node_regex;
44 regex_t *fstype_regex;
45 regex_t *skip_fstype_regex;
46 regex_t *options_regex;
47 regex_t *skip_options_regex;
48 char **mounts;
49 mount_type mount_type;
50};
51
52static int process_mount (char ***list, struct args *args,
53 char *from, char *to, char *fstype, char *options)
54{
55 char *p;
56
57 errno = ENOENT;
58
59#ifdef __linux__
60 /* Skip the really silly rootfs */
61 if (strcmp (fstype, "rootfs") == 0)
62 return (-1);
63#endif
64
65 if (args->node_regex &&
66 regexec (args->node_regex, from, 0, NULL, 0) != 0)
67 return (1);
68 if (args->skip_node_regex &&
69 regexec (args->skip_node_regex, from, 0, NULL, 0) == 0)
70 return (1);
71
72 if (args->fstype_regex &&
73 regexec (args->fstype_regex, fstype, 0, NULL, 0) != 0)
74 return (-1);
75 if (args->skip_fstype_regex &&
76 regexec (args->skip_fstype_regex, fstype, 0, NULL, 0) == 0)
77 return (-1);
78
79 if (args->options_regex &&
80 regexec (args->options_regex, options, 0, NULL, 0) != 0)
81 return (-1);
82 if (args->skip_options_regex &&
83 regexec (args->skip_options_regex, options, 0, NULL, 0) == 0)
84 return (-1);
85
86 if (args->mounts) {
87 bool found = false;
88 int j;
89 char *mnt;
90 STRLIST_FOREACH (args->mounts, mnt, j)
91 if (strcmp (mnt, to) == 0) {
92 found = true;
93 break;
94 }
95 if (! found)
96 return (-1);
97 }
98
99 switch (args->mount_type) {
100 case mount_from:
101 p = from;
102 break;
103 case mount_to:
104 p = to;
105 break;
106 case mount_fstype:
107 p = fstype;
108 break;
109 case mount_options:
110 p = options;
111 break;
112 default:
113 p = NULL;
114 errno = EINVAL;
115 break;
116 }
117
118 if (p) {
119 errno = 0;
120 *list = rc_strlist_addsortc (*list, p);
121 return (0);
122 }
123
124 return (-1);
125}
34 126
35#ifdef BSD 127#ifdef BSD
36static char **find_mounts (regex_t *node_regex, regex_t *skip_node_regex, 128
37 regex_t *fstype_regex, regex_t *skip_fstype_regex, 129/* Translate the mounted options to english
38 char **mounts, bool node, bool fstype) 130 * This is taken directly from FreeBSD mount.c */
131static struct opt {
132 int o_opt;
133 const char *o_name;
134} optnames[] = {
135 { MNT_ASYNC, "asynchronous" },
136 { MNT_EXPORTED, "NFS exported" },
137 { MNT_LOCAL, "local" },
138 { MNT_NOATIME, "noatime" },
139 { MNT_NOEXEC, "noexec" },
140 { MNT_NOSUID, "nosuid" },
141 { MNT_NOSYMFOLLOW, "nosymfollow" },
142 { MNT_QUOTA, "with quotas" },
143 { MNT_RDONLY, "read-only" },
144 { MNT_SYNCHRONOUS, "synchronous" },
145 { MNT_UNION, "union" },
146 { MNT_NOCLUSTERR, "noclusterr" },
147 { MNT_NOCLUSTERW, "noclusterw" },
148 { MNT_SUIDDIR, "suiddir" },
149 { MNT_SOFTDEP, "soft-updates" },
150 { MNT_MULTILABEL, "multilabel" },
151 { MNT_ACLS, "acls" },
152#ifdef MNT_GJOURNAL
153 { MNT_GJOURNAL, "gjournal" },
154#endif
155 { 0, NULL }
156};
157
158static char **find_mounts (struct args *args)
39{ 159{
40 struct statfs *mnts; 160 struct statfs *mnts;
41 int nmnts; 161 int nmnts;
42 int i; 162 int i;
43 char **list = NULL; 163 char **list = NULL;
164 char *options = NULL;
165 int flags;
166 struct opt *o;
44 167
45 if ((nmnts = getmntinfo (&mnts, MNT_NOWAIT)) == 0) 168 if ((nmnts = getmntinfo (&mnts, MNT_NOWAIT)) == 0)
46 eerrorx ("getmntinfo: %s", strerror (errno)); 169 eerrorx ("getmntinfo: %s", strerror (errno));
47 170
48 for (i = 0; i < nmnts; i++) { 171 for (i = 0; i < nmnts; i++) {
49 if (node_regex && 172 flags = mnts[i].f_flags & MNT_VISFLAGMASK;
50 regexec (node_regex, mnts[i].f_mntfromname, 0, NULL, 0) != 0) 173 for (o = optnames; flags && o->o_opt; o++) {
51 continue; 174 if (flags & o->o_opt) {
52 if (skip_node_regex && 175 if (! options)
53 regexec (skip_node_regex, mnts[i].f_mntfromname, 0, NULL, 0) == 0) 176 options = rc_xstrdup (o->o_name);
54 continue; 177 else {
55 if (fstype_regex && 178 char *tmp = NULL;
56 regexec (fstype_regex, mnts[i].f_fstypename, 0, NULL, 0) != 0) 179 asprintf (&tmp, "%s, %s", options, o->o_name);
57 continue; 180 free (options);
58 if (skip_fstype_regex && 181 options = tmp;
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 } 182 }
71 if (! found) 183 }
72 continue; 184 flags &= ~o->o_opt;
73 } 185 }
74 186
75 list = rc_strlist_addsortc (list, node ? 187 process_mount (&list, args,
76 mnts[i].f_mntfromname : 188 mnts[i].f_mntfromname,
77 fstype ? mnts[i].f_fstypename :
78 mnts[i].f_mntonname); 189 mnts[i].f_mntonname,
190 mnts[i].f_fstypename,
191 options);
192
193 free (options);
194 options = NULL;
79 } 195 }
80 196
81 return (list); 197 return (list);
82} 198}
83 199
84#elif defined (__linux__) 200#elif defined (__linux__)
85static char **find_mounts (regex_t *node_regex, regex_t *skip_node_regex, 201static char **find_mounts (struct args *args)
86 regex_t *fstype_regex, regex_t *skip_fstype_regex,
87 char **mounts, bool node, bool fstype)
88{ 202{
89 FILE *fp; 203 FILE *fp;
90 char buffer[PATH_MAX * 3]; 204 char buffer[PATH_MAX * 3];
91 char *p; 205 char *p;
92 char *from; 206 char *from;
93 char *to; 207 char *to;
94 char *fst; 208 char *fst;
209 char *opts;
95 char **list = NULL; 210 char **list = NULL;
96 211
97 if ((fp = fopen ("/proc/mounts", "r")) == NULL) 212 if ((fp = fopen ("/proc/mounts", "r")) == NULL)
98 eerrorx ("getmntinfo: %s", strerror (errno)); 213 eerrorx ("getmntinfo: %s", strerror (errno));
99 214
100 while (fgets (buffer, sizeof (buffer), fp)) { 215 while (fgets (buffer, sizeof (buffer), fp)) {
101 p = buffer; 216 p = buffer;
102 from = strsep (&p, " "); 217 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, " "); 218 to = strsep (&p, " ");
111 fst = strsep (&p, " "); 219 fst = strsep (&p, " ");
112 /* Skip the really silly rootfs */ 220 opts = strsep (&p, " ");
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 221
122 if (mounts) { 222 process_mount (&list, args, from, to, fst, opts);
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 } 223 }
137 fclose (fp); 224 fclose (fp);
138 225
139 return (list); 226 return (list);
140} 227}
157 244
158 return (reg); 245 return (reg);
159} 246}
160 247
161#include "_usage.h" 248#include "_usage.h"
162#define getoptstring "f:F:n:N:op:P:qs" getoptstring_COMMON 249#define getoptstring "f:F:n:N:o:O:p:P:iqst" getoptstring_COMMON
163static struct option longopts[] = { 250static struct option longopts[] = {
164 { "fstype-regex", 1, NULL, 'f'}, 251 { "fstype-regex", 1, NULL, 'f'},
165 { "skip-fstype-regex", 1, NULL, 'F'}, 252 { "skip-fstype-regex", 1, NULL, 'F'},
166 { "node-regex", 1, NULL, 'n'}, 253 { "node-regex", 1, NULL, 'n'},
167 { "skip-node-regex", 1, NULL, 'N'}, 254 { "skip-node-regex", 1, NULL, 'N'},
255 { "options-regex", 1, NULL, 'o'},
256 { "skip-options-regex", 1, NULL, 'O'},
168 { "point-regex", 1, NULL, 'p'}, 257 { "point-regex", 1, NULL, 'p'},
169 { "skip-point-regex", 1, NULL, 'P'}, 258 { "skip-point-regex", 1, NULL, 'P'},
170 { "node", 0, NULL, 'o'}, 259 { "options", 0, NULL, 'i'},
171 { "fstype", 0, NULL, 's'}, 260 { "fstype", 0, NULL, 's'},
261 { "node", 0, NULL, 't'},
172 { "quiet", 0, NULL, 'q'}, 262 { "quiet", 0, NULL, 'q'},
173 longopts_COMMON 263 longopts_COMMON
174 { NULL, 0, NULL, 0} 264 { NULL, 0, NULL, 0}
175}; 265};
176#include "_usage.c" 266#include "_usage.c"
177 267
178int mountinfo (int argc, char **argv) 268int mountinfo (int argc, char **argv)
179{ 269{
180 int i; 270 int i;
181 regex_t *fstype_regex = NULL; 271 struct args args;
182 regex_t *node_regex = NULL;
183 regex_t *point_regex = NULL; 272 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; 273 regex_t *skip_point_regex = NULL;
187 char **nodes = NULL; 274 char **nodes = NULL;
188 char *n; 275 char *n;
189 bool node = false;
190 bool fstype = false;
191 char **mounts = NULL;
192 int opt; 276 int opt;
193 bool quiet = false; 277 bool quiet = false;
194 int result; 278 int result;
195 279
196#define DO_REG(_var) \ 280#define DO_REG(_var) \
197 if (_var) free (_var); \ 281 if (_var) free (_var); \
198 _var = get_regex (optarg); 282 _var = get_regex (optarg);
283
284 memset (&args, 0, sizeof (struct args));
285 args.mount_type = mount_to;
199 286
200 while ((opt = getopt_long (argc, argv, getoptstring, 287 while ((opt = getopt_long (argc, argv, getoptstring,
201 longopts, (int *) 0)) != -1) 288 longopts, (int *) 0)) != -1)
202 { 289 {
203 switch (opt) { 290 switch (opt) {
204 case 'f': 291 case 'f':
205 DO_REG (fstype_regex); 292 DO_REG (args.fstype_regex);
206 break; 293 break;
207 case 'F': 294 case 'F':
208 DO_REG (skip_fstype_regex); 295 DO_REG (args.skip_fstype_regex);
209 break; 296 break;
210 case 'n': 297 case 'n':
211 DO_REG (node_regex); 298 DO_REG (args.node_regex);
212 break; 299 break;
213 case 'N': 300 case 'N':
214 DO_REG (skip_node_regex); 301 DO_REG (args.skip_node_regex);
215 break; 302 break;
216 case 'o': 303 case 'o':
217 node = true; 304 DO_REG (args.options_regex);
218 fstype = false; 305 break;
306 case 'O':
307 DO_REG (args.skip_options_regex);
219 break; 308 break;
220 case 'p': 309 case 'p':
221 DO_REG (point_regex); 310 DO_REG (point_regex);
222 break; 311 break;
223 case 'P': 312 case 'P':
224 DO_REG (skip_point_regex); 313 DO_REG (skip_point_regex);
225 break; 314 break;
315 case 'i':
316 args.mount_type = mount_options;
317 break;
318 case 's':
319 args.mount_type = mount_fstype;
320 break;
321 case 't':
322 args.mount_type = mount_from;
323 break;
226 case 'q': 324 case 'q':
227 quiet = true; 325 quiet = true;
228 break;
229 case 's':
230 node = false;
231 fstype = true;
232 break; 326 break;
233 327
234 case_RC_COMMON_GETOPT 328 case_RC_COMMON_GETOPT
235 } 329 }
236 } 330 }
237 331
238 while (optind < argc) { 332 while (optind < argc) {
239 if (argv[optind][0] != '/') 333 if (argv[optind][0] != '/')
240 eerrorx ("%s: `%s' is not a mount point", argv[0], argv[optind]); 334 eerrorx ("%s: `%s' is not a mount point", argv[0], argv[optind]);
241 mounts = rc_strlist_add (mounts, argv[optind++]); 335 args.mounts = rc_strlist_add (args.mounts, argv[optind++]);
242 } 336 }
243 337
244 nodes = find_mounts (node_regex, skip_node_regex, 338 nodes = find_mounts (&args);
245 fstype_regex, skip_fstype_regex,
246 mounts, node, fstype);
247 339
248 if (node_regex)
249 regfree (node_regex);
250 if (skip_node_regex)
251 regfree (skip_node_regex);
252 if (fstype_regex) 340 if (args.fstype_regex)
253 regfree (fstype_regex); 341 regfree (args.fstype_regex);
254 if (skip_fstype_regex) 342 if (args.skip_fstype_regex)
255 regfree (skip_fstype_regex); 343 regfree (args.skip_fstype_regex);
256 344 if (args.node_regex)
345 regfree (args.node_regex);
346 if (args.skip_node_regex)
347 regfree (args.skip_node_regex);
348 if (args.options_regex)
349 regfree (args.options_regex);
350 if (args.skip_options_regex)
351 regfree (args.skip_options_regex);
352
257 rc_strlist_reverse (nodes); 353 rc_strlist_reverse (nodes);
258 354
259 result = EXIT_FAILURE; 355 result = EXIT_FAILURE;
260 STRLIST_FOREACH (nodes, n, i) { 356 STRLIST_FOREACH (nodes, n, i) {
261 if (point_regex && regexec (point_regex, n, 0, NULL, 0) != 0) 357 if (point_regex && regexec (point_regex, n, 0, NULL, 0) != 0)

Legend:
Removed from v.2865  
changed lines
  Added in v.2881

  ViewVC Help
Powered by ViewVC 1.1.20