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

Contents of /trunk/src/mountinfo.c

Parent Directory Parent Directory | Revision Log Revision Log


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

  ViewVC Help
Powered by ViewVC 1.1.20