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

Contents of /trunk/src/mountinfo.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2771 - (show annotations) (download) (as text)
Wed Jul 11 17:27:46 2007 UTC (7 years, 2 months ago) by uberlord
File MIME type: text/x-csrc
File size: 6145 byte(s)
Don't unmount network filesystems in localmount or halt.sh, #175602.
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 #if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__)
12 #include <sys/param.h>
13 #include <sys/ucred.h>
14 #include <sys/mount.h>
15 #elif defined(__linux__)
16 #include <limits.h>
17 #endif
18
19 #include <errno.h>
20 #include <getopt.h>
21 #include <limits.h>
22 #include <regex.h>
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <string.h>
26
27 #include "einfo.h"
28 #include "rc.h"
29 #include "rc-misc.h"
30 #include "strlist.h"
31
32
33 #if defined(__FreeBSD__) || defined(__NetBSD__) || defined (__OpenBSD__)
34 static char **find_mounts (regex_t *node_regex, regex_t *skip_node_regex,
35 regex_t *fstype_regex, regex_t *skip_fstype_regex,
36 char **mounts, bool list_nodes, bool list_fstype)
37 {
38 struct statfs *mnts;
39 int nmnts;
40 int i;
41 char **list = NULL;
42
43 if ((nmnts = getmntinfo (&mnts, MNT_NOWAIT)) == 0)
44 eerrorx ("getmntinfo: %s", strerror (errno));
45
46 for (i = 0; i < nmnts; i++) {
47 if (node_regex &&
48 regexec (node_regex, mnts[i].f_mntfromname, 0, NULL, 0) != 0)
49 continue;
50 if (skip_node_regex &&
51 regexec (skip_node_regex, mnts[i].f_mntfromname, 0, NULL, 0) == 0)
52 continue;
53 if (fstype_regex &&
54 regexec (fstype_regex, mnts[i].f_fstypename, 0, NULL, 0) != 0)
55 continue;
56 if (skip_fstype_regex &&
57 regexec (skip_fstype_regex, mnts[i].f_fstypename, 0, NULL, 0) == 0)
58 continue;
59
60 if (mounts) {
61 bool found = false;
62 int j;
63 char *mnt;
64 STRLIST_FOREACH (mounts, mnt, j)
65 if (strcmp (mnt, mnts[i].f_mntonname) == 0) {
66 found = true;
67 break;
68 }
69 if (! found)
70 continue;
71 }
72
73 list = rc_strlist_addsortc (list, list_nodes ?
74 mnts[i].f_mntfromname :
75 list_fstype ? mnts[i].f_fstypename :
76 mnts[i].f_mntonname);
77 }
78
79 return (list);
80 }
81
82 #elif defined (__linux__)
83 static char **find_mounts (regex_t *node_regex, regex_t *skip_node_regex,
84 regex_t *fstype_regex, regex_t *skip_fstype_regex,
85 char **mounts, bool list_nodes, bool list_fstype)
86 {
87 FILE *fp;
88 char buffer[PATH_MAX * 3];
89 char *p;
90 char *from;
91 char *to;
92 char *fstype;
93 char **list = NULL;
94
95 if ((fp = fopen ("/proc/mounts", "r")) == NULL)
96 eerrorx ("getmntinfo: %s", strerror (errno));
97
98 while (fgets (buffer, sizeof (buffer), fp)) {
99 p = buffer;
100 from = strsep (&p, " ");
101 if (node_regex &&
102 regexec (node_regex, from, 0, NULL, 0) != 0)
103 continue;
104 if (skip_node_regex &&
105 regexec (skip_node_regex, from, 0, NULL, 0) == 0)
106 continue;
107
108 to = strsep (&p, " ");
109 fstype = strsep (&p, " ");
110 /* Skip the really silly rootfs */
111 if (strcmp (fstype, "rootfs") == 0)
112 continue;
113 if (fstype_regex &&
114 regexec (fstype_regex, fstype, 0, NULL, 0) != 0)
115 continue;
116 if (skip_fstype_regex &&
117 regexec (skip_fstype_regex, fstype, 0, NULL, 0) == 0)
118 continue;
119
120 if (mounts) {
121 bool found = false;
122 int j;
123 char *mnt;
124 STRLIST_FOREACH (mounts, mnt, j)
125 if (strcmp (mnt, to) == 0) {
126 found = true;
127 break;
128 }
129 if (! found)
130 continue;
131 }
132
133 list = rc_strlist_addsortc (list,
134 list_nodes ?
135 list_fstype ? fstype :
136 from : 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 { "list-nodes", 0, NULL, 'o'},
172 { "list-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 *node;
189 bool list_nodes = false;
190 bool list_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 list_nodes = true;
223 list_fstype = false;
224 break;
225 case 's':
226 list_nodes = false;
227 list_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, list_nodes, list_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, node, i) {
257 if (point_regex && regexec (point_regex, node, 0, NULL, 0) != 0)
258 continue;
259 if (skip_point_regex && regexec (skip_point_regex, node, 0, NULL, 0) == 0)
260 continue;
261 printf ("%s\n", node);
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