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