1 /*
2 * Copyright (c) 1997-2006 Erez Zadok
3 * Copyright (c) 1989 Jan-Simon Pendry
4 * Copyright (c) 1989 Imperial College of Science, Technology & Medicine
5 * Copyright (c) 1989 The Regents of the University of California.
6 * All rights reserved.
7 *
8 * This code is derived from software contributed to Berkeley by
9 * Jan-Simon Pendry at Imperial College, London.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
19 * 3. All advertising materials mentioning features or use of this software
20 * must display the following acknowledgment:
21 * This product includes software developed by the University of
22 * California, Berkeley and its contributors.
23 * 4. Neither the name of the University nor the names of its contributors
24 * may be used to endorse or promote products derived from this software
25 * without specific prior written permission.
26 *
27 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
28 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
29 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
30 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
31 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
32 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
33 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
34 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
35 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
36 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
37 * SUCH DAMAGE.
38 *
39 *
40 * File: am-utils/fsinfo/fsinfo.c
41 *
42 */
43
44 /*
45 * fsinfo
46 */
47
48 #ifdef HAVE_CONFIG_H
49 # include <config.h>
50 #endif /* HAVE_CONFIG_H */
51 #include <am_defs.h>
52 #include <fsi_data.h>
53 #include <fsinfo.h>
54 #include <fsi_gram.h>
55
56 /* globals */
57 char **g_argv;
58 char *autodir = "/a";
59 char *progname;
60 char hostname[MAXHOSTNAMELEN + 1];
61 char *username;
62 char idvbuf[1024];
63 dict *dict_of_hosts;
64 dict *dict_of_volnames;
65 int errors;
66 int file_io_errors;
67 int parse_errors;
68 int verbose;
69 qelem *list_of_automounts;
70 qelem *list_of_hosts;
71
72 /*
73 * Output file prefixes
74 */
75 char *bootparams_pref;
76 char *dumpset_pref;
77 char *exportfs_pref;
78 char *fstab_pref;
79 char *mount_pref;
80
81
82 /*
83 * Argument cracking...
84 */
85 static void
fsi_get_args(int c,char * v[])86 fsi_get_args(int c, char *v[])
87 {
88 int ch;
89 int usage = 0;
90 char *iptr = idvbuf;
91
92 /*
93 * Determine program name
94 */
95 if (v[0]) {
96 progname = strrchr(v[0], '/');
97 if (progname && progname[1])
98 progname++;
99 else
100 progname = v[0];
101 }
102
103 if (!progname)
104 progname = "fsinfo";
105
106 while ((ch = getopt(c, v, "a:b:d:e:f:h:m:D:U:I:qv")) != -1)
107
108 switch (ch) {
109
110 case 'a':
111 autodir = optarg;
112 break;
113
114 case 'b':
115 if (bootparams_pref)
116 fatal("-b option specified twice");
117 bootparams_pref = optarg;
118 break;
119
120 case 'd':
121 if (dumpset_pref)
122 fatal("-d option specified twice");
123 dumpset_pref = optarg;
124 break;
125
126 case 'h':
127 xstrlcpy(hostname, optarg, sizeof(hostname));
128 break;
129
130 case 'e':
131 if (exportfs_pref)
132 fatal("-e option specified twice");
133 exportfs_pref = optarg;
134 break;
135
136 case 'f':
137 if (fstab_pref)
138 fatal("-f option specified twice");
139 fstab_pref = optarg;
140 break;
141
142 case 'm':
143 if (mount_pref)
144 fatal("-m option specified twice");
145 mount_pref = optarg;
146 break;
147
148 case 'q':
149 verbose = -1;
150 break;
151
152 case 'v':
153 verbose = 1;
154 break;
155
156 case 'I':
157 case 'D':
158 case 'U':
159 /* sizeof(iptr) is actually that of idvbuf. See declaration above */
160 xsnprintf(iptr, sizeof(idvbuf), "-%c%s ", ch, optarg);
161 iptr += strlen(iptr);
162 break;
163
164 default:
165 usage++;
166 break;
167 }
168
169 if (c != optind) {
170 g_argv = v + optind - 1;
171 #ifdef yywrap
172 if (yywrap())
173 #endif /* yywrap */
174 fatal("Cannot read any input files");
175 } else {
176 usage++;
177 }
178
179 if (usage) {
180 fprintf(stderr,
181 "\
182 Usage: %s [-v] [-a autodir] [-h hostname] [-b bootparams] [-d dumpsets]\n\
183 \t[-e exports] [-f fstabs] [-m automounts]\n\
184 \t[-I dir] [-D|-U string[=string]] config ...\n", progname);
185 exit(1);
186 }
187
188 if (g_argv[0])
189 fsi_log("g_argv[0] = %s", g_argv[0]);
190 else
191 fsi_log("g_argv[0] = (nil)");
192 }
193
194
195 /*
196 * Determine username of caller
197 */
198 static char *
find_username(void)199 find_username(void)
200 {
201 const char *u = getlogin();
202
203 if (!u) {
204 struct passwd *pw = getpwuid(getuid());
205 if (pw)
206 u = pw->pw_name;
207 }
208
209 if (!u)
210 u = getenv("USER");
211 if (!u)
212 u = getenv("LOGNAME");
213 if (!u)
214 u = "root";
215
216 return strdup(u);
217 }
218
219
220 /*
221 * MAIN
222 */
223 int
main(int argc,char * argv[])224 main(int argc, char *argv[])
225 {
226 /*
227 * Process arguments
228 */
229 fsi_get_args(argc, argv);
230
231 /*
232 * If no hostname given then use the local name
233 */
234 if (!*hostname && gethostname(hostname, sizeof(hostname)) < 0) {
235 perror("gethostname");
236 exit(1);
237 }
238 hostname[sizeof(hostname) - 1] = '\0';
239
240 /*
241 * Get the username
242 */
243 username = find_username();
244
245 /*
246 * New hosts and automounts
247 */
248 list_of_hosts = new_que();
249 list_of_automounts = new_que();
250
251 /*
252 * New dictionaries
253 */
254 dict_of_volnames = new_dict();
255 dict_of_hosts = new_dict();
256
257 /*
258 * Parse input
259 */
260 show_area_being_processed("read config", 11);
261 if (yyparse())
262 errors = 1;
263 errors += file_io_errors + parse_errors;
264
265 if (errors == 0) {
266 /*
267 * Do semantic analysis of input
268 */
269 analyze_hosts(list_of_hosts);
270 analyze_automounts(list_of_automounts);
271 }
272
273 /*
274 * Give up if errors
275 */
276 if (errors == 0) {
277 /*
278 * Output data files
279 */
280
281 write_atab(list_of_automounts);
282 write_bootparams(list_of_hosts);
283 write_dumpset(list_of_hosts);
284 write_exportfs(list_of_hosts);
285 write_fstab(list_of_hosts);
286 }
287 col_cleanup(1);
288
289 exit(errors);
290 return errors; /* should never reach here */
291 }
292