Merge from vendor branch TCSH:
[dragonfly.git] / contrib / amd / amd / get_args.c
1 /*
2  * Copyright (c) 1997-1999 Erez Zadok
3  * Copyright (c) 1990 Jan-Simon Pendry
4  * Copyright (c) 1990 Imperial College of Science, Technology & Medicine
5  * Copyright (c) 1990 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: get_args.c,v 1.4 1999/09/30 21:01:31 ezk Exp $
42  * $FreeBSD: src/contrib/amd/amd/get_args.c,v 1.5 1999/11/05 11:58:05 obrien Exp $
43  * $DragonFly: src/contrib/amd/amd/get_args.c,v 1.2 2003/06/17 04:23:56 dillon Exp $
44  *
45  */
46
47 /*
48  * Argument decode
49  */
50
51 #ifdef HAVE_CONFIG_H
52 # include <config.h>
53 #endif /* HAVE_CONFIG_H */
54 #include <am_defs.h>
55 #include <amd.h>
56
57 /* include auto-generated version file */
58 #include <build_version.h>
59
60 char *conf_file = "/etc/amd.conf"; /* default amd configuration file */
61 char *conf_tag = NULL;          /* default conf file tags to use */
62 int usage = 0;
63 int use_conf_file = 0;          /* default don't use amd.conf file */
64 char *mnttab_file_name = NULL;  /* symbol must be available always */
65 #if 0
66 #ifdef DEBUG
67 int debug_flags = D_AMQ         /* Register AMQ */
68                 | D_DAEMON;     /* Enter daemon mode */
69 #endif /* DEBUG */
70 #endif
71
72 /*
73  * Return the version string (dynamic buffer)
74  */
75 char *
76 get_version_string(void)
77 {
78   static char *vers = NULL;
79   char tmpbuf[1024];
80   char *wire_buf;
81   int wire_buf_len = 0;
82
83   /* first get dynamic string listing all known networks */
84   wire_buf = print_wires();
85   if (wire_buf)
86     wire_buf_len = strlen(wire_buf);
87
88   vers = xmalloc(2048 + wire_buf_len);
89   sprintf(vers, "%s\n%s\n%s\n%s\n",
90           "Copyright (c) 1997-1999 Erez Zadok",
91           "Copyright (c) 1990 Jan-Simon Pendry",
92           "Copyright (c) 1990 Imperial College of Science, Technology & Medicine",
93           "Copyright (c) 1990 The Regents of the University of California.");
94   sprintf(tmpbuf, "%s version %s (build %d).\n",
95           PACKAGE, VERSION, AMU_BUILD_VERSION);
96   strcat(vers, tmpbuf);
97   sprintf(tmpbuf, "Built by %s@%s on date %s.\n",
98           USER_NAME, HOST_NAME, CONFIG_DATE);
99   strcat(vers, tmpbuf);
100   sprintf(tmpbuf, "cpu=%s (%s-endian), arch=%s, karch=%s.\n",
101           cpu, endian, gopt.arch, gopt.karch);
102   strcat(vers, tmpbuf);
103   sprintf(tmpbuf, "full_os=%s, os=%s, osver=%s, vendor=%s.\n",
104           gopt.op_sys_full, gopt.op_sys, gopt.op_sys_ver, gopt.op_sys_vendor);
105   strcat(vers, tmpbuf);
106
107   strcat(vers, "Map support for: ");
108   mapc_showtypes(tmpbuf);
109   strcat(vers, tmpbuf);
110   strcat(vers, ".\nAMFS: ");
111   ops_showamfstypes(tmpbuf);
112   strcat(vers, tmpbuf);
113   strcat(vers, ".\nFS: ");
114   ops_showfstypes(tmpbuf);
115   strcat(vers, tmpbuf);
116
117   /* append list of networks if available */
118   if (wire_buf) {
119     strcat(vers, wire_buf);
120     XFREE(wire_buf);
121   }
122
123   return vers;
124 }
125
126
127 void
128 get_args(int argc, char *argv[])
129 {
130   int opt_ch;
131   FILE *fp = stdin;
132
133   /* if no arguments were passed, try to use /etc/amd.conf file */
134   if (argc <= 1)
135     use_conf_file = 1;
136
137   while ((opt_ch = getopt(argc, argv, "nprvSa:c:d:k:l:o:t:w:x:y:C:D:F:T:O:H")) != -1)
138     switch (opt_ch) {
139
140     case 'a':
141       if (*optarg != '/') {
142         fprintf(stderr, "%s: -a option must begin with a '/'\n",
143                 am_get_progname());
144         exit(1);
145       }
146       gopt.auto_dir = optarg;
147       break;
148
149     case 'c':
150       gopt.am_timeo = atoi(optarg);
151       if (gopt.am_timeo <= 0)
152         gopt.am_timeo = AM_TTL;
153       break;
154
155     case 'd':
156       gopt.sub_domain = optarg;
157       break;
158
159     case 'k':
160       gopt.karch = optarg;
161       break;
162
163     case 'l':
164       gopt.logfile = optarg;
165       break;
166
167     case 'n':
168       gopt.flags |= CFM_NORMALIZE_HOSTNAMES;
169       break;
170
171     case 'o':
172       gopt.op_sys_ver = optarg;
173       break;
174
175     case 'p':
176      gopt.flags |= CFM_PRINT_PID;
177       break;
178
179     case 'r':
180       gopt.flags |= CFM_RESTART_EXISTING_MOUNTS;
181       break;
182
183     case 't':
184       /* timeo.retrans */
185       {
186         char *dot = strchr(optarg, '.');
187         if (dot)
188           *dot = '\0';
189         if (*optarg) {
190           gopt.amfs_auto_timeo = atoi(optarg);
191         }
192         if (dot) {
193           gopt.amfs_auto_retrans = atoi(dot + 1);
194           *dot = '.';
195         }
196       }
197       break;
198
199     case 'v':
200       fputs(get_version_string(), stderr);
201       exit(0);
202       break;
203
204     case 'w':
205       gopt.am_timeo_w = atoi(optarg);
206       if (gopt.am_timeo_w <= 0)
207         gopt.am_timeo_w = AM_TTL_W;
208       break;
209
210     case 'x':
211       usage += switch_option(optarg);
212       break;
213
214     case 'y':
215 #ifdef HAVE_MAP_NIS
216       gopt.nis_domain = optarg;
217 #else /* not HAVE_MAP_NIS */
218       plog(XLOG_USER, "-y: option ignored.  No NIS support available.");
219 #endif /* not HAVE_MAP_NIS */
220       break;
221
222     case 'C':
223       gopt.cluster = optarg;
224       break;
225
226     case 'D':
227 #ifdef DEBUG
228       usage += debug_option(optarg);
229 #else /* not DEBUG */
230       fprintf(stderr, "%s: not compiled with DEBUG option -- sorry.\n",
231               am_get_progname());
232 #endif /* not DEBUG */
233       break;
234
235     case 'F':
236       conf_file = optarg;
237       use_conf_file = 1;
238       break;
239
240     case 'H':
241       goto show_usage;
242       break;
243
244     case 'O':
245       gopt.op_sys = optarg;
246       break;
247
248     case 'S':
249       gopt.flags &= ~CFM_PROCESS_LOCK; /* turn process locking off */
250       break;
251
252     case 'T':
253       conf_tag = optarg;
254       break;
255
256     default:
257       usage = 1;
258       break;
259     }
260
261   /*
262    * amd.conf file: if not command-line arguments were used, or if -F was
263    * specified, then use that amd.conf file.  If the file cannot be opened,
264    * abort amd.  If it can be found, open it, parse it, and then close it.
265    */
266   if (use_conf_file && conf_file) {
267     fp = fopen(conf_file, "r");
268     if (!fp) {
269       char buf[128];
270       sprintf(buf, "Amd configuration file (%s)", conf_file);
271       perror(buf);
272       exit(1);
273     }
274     yyin = fp;
275     yyparse();
276     fclose(fp);
277     if (process_last_regular_map() != 0)
278       exit(1);
279   }
280
281   /* make sure there are some default options defined */
282   if (xlog_level_init == ~0) {
283     switch_option("");
284   }
285 #ifdef DEBUG
286   usage += switch_option("debug");
287 #endif /* DEBUG */
288
289   /* log information regarding amd.conf file */
290   if (use_conf_file && conf_file)
291     plog(XLOG_INFO, "using configuration file %s", conf_file);
292
293 #ifdef HAVE_MAP_LDAP
294   /* ensure that if ldap_base is specified, that also ldap_hostports is */
295   if (gopt.ldap_hostports && !gopt.ldap_base) {
296     fprintf(stderr, "must specify both ldap_hostports and ldap_base\n");
297     exit(1);
298   }
299 #endif /* HAVE_MAP_LDAP */
300
301   if (usage)
302     goto show_usage;
303
304   while (optind <= argc - 2) {
305     char *dir = argv[optind++];
306     char *map = argv[optind++];
307     char *opts = "";
308     if (argv[optind] && *argv[optind] == '-')
309       opts = &argv[optind++][1];
310
311     root_newmap(dir, opts, map, NULL);
312   }
313
314   if (optind == argc) {
315     /*
316      * Append domain name to hostname.
317      * sub_domain overrides hostdomain
318      * if given.
319      */
320     if (gopt.sub_domain)
321       hostdomain = gopt.sub_domain;
322     if (*hostdomain == '.')
323       hostdomain++;
324     strcat(hostd, ".");
325     strcat(hostd, hostdomain);
326
327 #ifdef MOUNT_TABLE_ON_FILE
328 # ifdef DEBUG
329     if (debug_flags & D_MTAB)
330       mnttab_file_name = DEBUG_MNTTAB;
331     else
332 # endif /* DEBUG */
333       mnttab_file_name = MNTTAB_FILE_NAME;
334 #else /* not MOUNT_TABLE_ON_FILE */
335 # ifdef DEBUG
336     if (debug_flags & D_MTAB)
337       dlog("-D mtab option ignored");
338 # endif /* DEBUG */
339 #endif /* not MOUNT_TABLE_ON_FILE */
340
341     if (switch_to_logfile(gopt.logfile, orig_umask) != 0)
342       plog(XLOG_USER, "Cannot switch logfile");
343
344     /*
345      * If the kernel architecture was not specified
346      * then use the machine architecture.
347      */
348     if (gopt.karch == 0)
349       gopt.karch = gopt.arch;
350
351     if (gopt.cluster == 0)
352       gopt.cluster = hostdomain;
353
354     if (gopt.amfs_auto_timeo <= 0)
355       gopt.amfs_auto_timeo = AMFS_AUTO_TIMEO;
356     if (gopt.amfs_auto_retrans <= 0)
357       gopt.amfs_auto_retrans = AMFS_AUTO_RETRANS;
358     if (gopt.amfs_auto_retrans <= 0)
359       gopt.amfs_auto_retrans = 3;       /* XXX */
360     return;
361   }
362
363 show_usage:
364   fprintf(stderr,
365           "Usage: %s [-nprvHS] [-a mount_point] [-c cache_time] [-d domain]\n\
366 \t[-k kernel_arch] [-l logfile%s\n\
367 \t[-t timeout.retrans] [-w wait_timeout] [-C cluster_name]\n\
368 \t[-o op_sys_ver] [-O op_sys_name]\n\
369 \t[-F conf_file] [-T conf_tag]", am_get_progname(),
370 #ifdef HAVE_SYSLOG
371 # ifdef LOG_DAEMON
372           "|\"syslog[:facility]\"]"
373 # else /* not LOG_DAEMON */
374           "|\"syslog\"]"
375 # endif /* not LOG_DAEMON */
376 #else /* not HAVE_SYSLOG */
377           "]"
378 #endif /* not HAVE_SYSLOG */
379           );
380
381 #ifdef HAVE_MAP_NIS
382   fputs(" [-y nis-domain]\n", stderr);
383 #else /* not HAVE_MAP_NIS */
384   fputc('\n', stderr);
385 #endif /* HAVE_MAP_NIS */
386
387   show_opts('x', xlog_opt);
388 #ifdef DEBUG
389   show_opts('D', dbg_opt);
390 #endif /* DEBUG */
391   fprintf(stderr, "\t[directory mapname [-map_options]] ...\n");
392   exit(1);
393 }