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