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