Merge from vendor branch LESS:
[dragonfly.git] / contrib / amd / fsinfo / fsinfo.c
1 /*
2  * Copyright (c) 1997-1999 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  *      %W% (Berkeley) %G%
40  *
41  * $Id: fsinfo.c,v 1.4 1999/02/04 07:24:44 ezk Exp $
42  * $FreeBSD: src/contrib/amd/fsinfo/fsinfo.c,v 1.4 1999/09/15 05:45:15 obrien Exp $
43  * $DragonFly: src/contrib/amd/fsinfo/fsinfo.c,v 1.2 2003/06/17 04:23:57 dillon Exp $
44  *
45  */
46
47 /*
48  * fsinfo
49  */
50
51 #ifdef HAVE_CONFIG_H
52 # include <config.h>
53 #endif /* HAVE_CONFIG_H */
54 #include <am_defs.h>
55 #include <fsi_data.h>
56 #include <fsinfo.h>
57 #include <fsi_gram.h>
58
59 /* globals */
60 char **g_argv;
61 char *autodir = "/a";
62 char *progname;
63 char hostname[MAXHOSTNAMELEN + 1];
64 char *username;
65 char idvbuf[1024];
66 dict *dict_of_hosts;
67 dict *dict_of_volnames;
68 int errors;
69 int file_io_errors;
70 int parse_errors;
71 int verbose;
72 qelem *list_of_automounts;
73 qelem *list_of_hosts;
74
75 /*
76  * Output file prefixes
77  */
78 char *bootparams_pref;
79 char *dumpset_pref;
80 char *exportfs_pref;
81 char *fstab_pref;
82 char *mount_pref;
83
84
85 /*
86  * Argument cracking...
87  */
88 static void
89 fsi_get_args(int c, char *v[])
90 {
91   int ch;
92   int usage = 0;
93   char *iptr = idvbuf;
94
95   /*
96    * Determine program name
97    */
98   if (v[0]) {
99     progname = strrchr(v[0], '/');
100     if (progname && progname[1])
101       progname++;
102     else
103       progname = v[0];
104   }
105
106   if (!progname)
107     progname = "fsinfo";
108
109   while ((ch = getopt(c, v, "a:b:d:e:f:h:m:D:U:I:qv")) != -1)
110
111     switch (ch) {
112
113     case 'a':
114       autodir = optarg;
115       break;
116
117     case 'b':
118       if (bootparams_pref)
119         fatal("-b option specified twice");
120       bootparams_pref = optarg;
121       break;
122
123     case 'd':
124       if (dumpset_pref)
125         fatal("-d option specified twice");
126       dumpset_pref = optarg;
127       break;
128
129     case 'h':
130       strncpy(hostname, optarg, sizeof(hostname) - 1);
131       break;
132
133     case 'e':
134       if (exportfs_pref)
135         fatal("-e option specified twice");
136       exportfs_pref = optarg;
137       break;
138
139     case 'f':
140       if (fstab_pref)
141         fatal("-f option specified twice");
142       fstab_pref = optarg;
143       break;
144
145     case 'm':
146       if (mount_pref)
147         fatal("-m option specified twice");
148       mount_pref = optarg;
149       break;
150
151     case 'q':
152       verbose = -1;
153       break;
154
155     case 'v':
156       verbose = 1;
157       break;
158
159     case 'I':
160     case 'D':
161     case 'U':
162       sprintf(iptr, "-%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     if (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     log("g_argv[0] = %s", g_argv[0]);
190   else
191     log("g_argv[0] = (nil)");
192 }
193
194
195 /*
196  * Determine username of caller
197  */
198 static char *
199 find_username(void)
200 {
201   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
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
239   /*
240    * Get the username
241    */
242   username = find_username();
243
244   /*
245    * New hosts and automounts
246    */
247   list_of_hosts = new_que();
248   list_of_automounts = new_que();
249
250   /*
251    * New dictionaries
252    */
253   dict_of_volnames = new_dict();
254   dict_of_hosts = new_dict();
255
256   /*
257    * Parse input
258    */
259   show_area_being_processed("read config", 11);
260   if (yyparse())
261     errors = 1;
262   errors += file_io_errors + parse_errors;
263
264   if (errors == 0) {
265     /*
266      * Do semantic analysis of input
267      */
268     analyze_hosts(list_of_hosts);
269     analyze_automounts(list_of_automounts);
270   }
271
272   /*
273    * Give up if errors
274    */
275   if (errors == 0) {
276     /*
277      * Output data files
278      */
279
280     write_atab(list_of_automounts);
281     write_bootparams(list_of_hosts);
282     write_dumpset(list_of_hosts);
283     write_exportfs(list_of_hosts);
284     write_fstab(list_of_hosts);
285   }
286   col_cleanup(1);
287
288   exit(errors);
289   return errors; /* should never reach here */
290 }