1 /* tinit.c
2 Initialize for reading Taylor UUCP configuration files.
3
4 Copyright (C) 1992, 1993, 1994, 1995, 2002 Ian Lance Taylor
5
6 This file is part of the Taylor UUCP uuconf library.
7
8 This library is free software; you can redistribute it and/or
9 modify it under the terms of the GNU Library General Public License
10 as published by the Free Software Foundation; either version 2 of
11 the License, or (at your option) any later version.
12
13 This library is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Library General Public License for more details.
17
18 You should have received a copy of the GNU Library General Public
19 License along with this library; if not, write to the Free Software
20 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
21
22 The author of the program may be contacted at ian@airs.com.
23 */
24
25 #include "uucnfi.h"
26
27 #if USE_RCS_ID
28 const char _uuconf_tinit_rcsid[] = "$FreeBSD$";
29 #endif
30
31 #include <errno.h>
32
33 /* Local functions. */
34
35 static int itset_default P((struct sglobal *qglobal, char ***ppzvar,
36 const char *zfile));
37 static int itdebug P((pointer pglobal, int argc, char **argv, pointer pvar,
38 pointer pinfo));
39 static int itaddfile P((pointer pglobal, int argc, char **argv, pointer pvar,
40 pointer pinfo));
41 static int itunknown P((pointer pglobal, int argc, char **argv, pointer pvar,
42 pointer pinfo));
43 static int itprogram P((pointer pglobal, int argc, char **argv, pointer pvar,
44 pointer pinfo));
45
46 static const struct cmdtab_offset asCmds[] =
47 {
48 { "nodename", UUCONF_CMDTABTYPE_STRING,
49 offsetof (struct sprocess, zlocalname), NULL },
50 { "hostname", UUCONF_CMDTABTYPE_STRING,
51 offsetof (struct sprocess, zlocalname), NULL },
52 { "uuname", UUCONF_CMDTABTYPE_STRING,
53 offsetof (struct sprocess, zlocalname), NULL },
54 { "spool", UUCONF_CMDTABTYPE_STRING,
55 offsetof (struct sprocess, zspooldir), NULL },
56 { "pubdir", UUCONF_CMDTABTYPE_STRING,
57 offsetof (struct sprocess, zpubdir), NULL },
58 { "lockdir", UUCONF_CMDTABTYPE_STRING,
59 offsetof (struct sprocess, zlockdir), NULL },
60 { "logfile", UUCONF_CMDTABTYPE_STRING,
61 offsetof (struct sprocess, zlogfile), NULL },
62 { "statfile", UUCONF_CMDTABTYPE_STRING,
63 offsetof (struct sprocess, zstatsfile), NULL },
64 { "debugfile", UUCONF_CMDTABTYPE_STRING,
65 offsetof (struct sprocess, zdebugfile), NULL },
66 { "debug", UUCONF_CMDTABTYPE_FN | 0,
67 offsetof (struct sprocess, zdebug), itdebug },
68 { "strip-login", UUCONF_CMDTABTYPE_BOOLEAN,
69 offsetof (struct sprocess, fstrip_login), NULL },
70 { "strip-proto", UUCONF_CMDTABTYPE_BOOLEAN,
71 offsetof (struct sprocess, fstrip_proto), NULL },
72 { "max-uuxqts", UUCONF_CMDTABTYPE_INT,
73 offsetof (struct sprocess, cmaxuuxqts), NULL },
74 { "run-uuxqt", UUCONF_CMDTABTYPE_STRING,
75 offsetof (struct sprocess, zrunuuxqt), NULL },
76 { "sysfile", UUCONF_CMDTABTYPE_FN | 0,
77 offsetof (struct sprocess, pzsysfiles), itaddfile },
78 { "portfile", UUCONF_CMDTABTYPE_FN | 0,
79 offsetof (struct sprocess, pzportfiles), itaddfile },
80 { "dialfile", UUCONF_CMDTABTYPE_FN | 0,
81 offsetof (struct sprocess, pzdialfiles), itaddfile },
82 { "dialcodefile", UUCONF_CMDTABTYPE_FN | 0,
83 offsetof (struct sprocess, pzdialcodefiles), itaddfile },
84 { "callfile", UUCONF_CMDTABTYPE_FN | 0,
85 offsetof (struct sprocess, pzcallfiles), itaddfile },
86 { "passwdfile", UUCONF_CMDTABTYPE_FN | 0,
87 offsetof (struct sprocess, pzpwdfiles), itaddfile },
88 { "unknown", UUCONF_CMDTABTYPE_FN, offsetof (struct sprocess, qunknown),
89 itunknown },
90 { "v2-files", UUCONF_CMDTABTYPE_BOOLEAN,
91 offsetof (struct sprocess, fv2), NULL },
92 { "hdb-files", UUCONF_CMDTABTYPE_BOOLEAN,
93 offsetof (struct sprocess, fhdb), NULL },
94 { "bnu-files", UUCONF_CMDTABTYPE_BOOLEAN,
95 offsetof (struct sprocess, fhdb), NULL },
96 { "timetable", UUCONF_CMDTABTYPE_FN | 3,
97 offsetof (struct sprocess, pztimetables), _uuconf_itimetable },
98 { NULL, 0, 0, NULL }
99 };
100
101 #define CCMDS (sizeof asCmds / sizeof asCmds[0])
102
103 /* This structure is used to pass information into the command table
104 functions. */
105
106 struct sinfo
107 {
108 /* The program name. */
109 const char *zname;
110 /* A pointer to the command table being used, passed to isystem so
111 it can call uuconf_cmd_args. */
112 struct uuconf_cmdtab *qcmds;
113 };
114
115 /* Initialize the routines which read the Taylor UUCP configuration
116 files. */
117
118 int
uuconf_taylor_init(ppglobal,zprogram,zname)119 uuconf_taylor_init (ppglobal, zprogram, zname)
120 pointer *ppglobal;
121 const char *zprogram;
122 const char *zname;
123 {
124 struct sglobal **pqglobal = (struct sglobal **) ppglobal;
125 int iret;
126 char *zcopy;
127 struct sglobal *qglobal;
128 boolean fdefault;
129 FILE *e;
130 struct sinfo si;
131
132 if (*pqglobal == NULL)
133 {
134 iret = _uuconf_iinit_global (pqglobal);
135 if (iret != UUCONF_SUCCESS)
136 return iret;
137 }
138
139 qglobal = *pqglobal;
140
141 if (zname != NULL)
142 {
143 size_t csize;
144
145 csize = strlen (zname) + 1;
146 zcopy = uuconf_malloc (qglobal->pblock, csize);
147 if (zcopy == NULL)
148 {
149 qglobal->ierrno = errno;
150 return UUCONF_MALLOC_FAILED | UUCONF_ERROR_ERRNO;
151 }
152 memcpy ((pointer) zcopy, (pointer) zname, csize);
153 fdefault = FALSE;
154 }
155 else
156 {
157 zcopy = uuconf_malloc (qglobal->pblock,
158 sizeof NEWCONFIGLIB + sizeof CONFIGFILE - 1);
159 if (zcopy == NULL)
160 {
161 qglobal->ierrno = errno;
162 return UUCONF_MALLOC_FAILED | UUCONF_ERROR_ERRNO;
163 }
164 memcpy ((pointer) zcopy, (pointer) NEWCONFIGLIB,
165 sizeof NEWCONFIGLIB - 1);
166 memcpy ((pointer) (zcopy + sizeof NEWCONFIGLIB - 1),
167 (pointer) CONFIGFILE, sizeof CONFIGFILE);
168 fdefault = TRUE;
169 }
170
171 qglobal->qprocess->zconfigfile = zcopy;
172
173 e = fopen (zcopy, "r");
174 if (e == NULL)
175 {
176 if (! fdefault)
177 {
178 qglobal->ierrno = errno;
179 qglobal->zfilename = zcopy;
180 return (UUCONF_FOPEN_FAILED
181 | UUCONF_ERROR_ERRNO
182 | UUCONF_ERROR_FILENAME);
183 }
184
185 /* There is no config file, so just use the default values. */
186 }
187 else
188 {
189 struct uuconf_cmdtab as[CCMDS];
190
191 _uuconf_ucmdtab_base (asCmds, CCMDS, (char *) qglobal->qprocess,
192 as);
193
194 if (zprogram == NULL)
195 zprogram = "uucp";
196
197 si.zname = zprogram;
198 si.qcmds = as;
199 iret = uuconf_cmd_file (qglobal, e, as, (pointer) &si, itprogram,
200 UUCONF_CMDTABFLAG_BACKSLASH,
201 qglobal->pblock);
202
203 (void) fclose (e);
204
205 if (iret != UUCONF_SUCCESS)
206 {
207 qglobal->zfilename = zcopy;
208 return iret | UUCONF_ERROR_FILENAME;
209 }
210 }
211
212 /* Get the defaults for the file names. */
213
214 iret = itset_default (qglobal, &qglobal->qprocess->pzsysfiles, SYSFILE);
215 if (iret != UUCONF_SUCCESS)
216 return iret;
217 iret = itset_default (qglobal, &qglobal->qprocess->pzportfiles, PORTFILE);
218 if (iret != UUCONF_SUCCESS)
219 return iret;
220 iret = itset_default (qglobal, &qglobal->qprocess->pzdialfiles, DIALFILE);
221 if (iret != UUCONF_SUCCESS)
222 return iret;
223 iret = itset_default (qglobal, &qglobal->qprocess->pzdialcodefiles,
224 DIALCODEFILE);
225 if (iret != UUCONF_SUCCESS)
226 return iret;
227 iret = itset_default (qglobal, &qglobal->qprocess->pzpwdfiles, PASSWDFILE);
228 if (iret != UUCONF_SUCCESS)
229 return iret;
230 iret = itset_default (qglobal, &qglobal->qprocess->pzcallfiles, CALLFILE);
231 if (iret != UUCONF_SUCCESS)
232 return iret;
233
234 return UUCONF_SUCCESS;
235 }
236
237 /* Local interface to the _uuconf_idebug_cmd function, which handles
238 the "debug" command. */
239
240 static int
itdebug(pglobal,argc,argv,pvar,pinfo)241 itdebug (pglobal, argc, argv, pvar, pinfo)
242 pointer pglobal;
243 int argc;
244 char **argv;
245 pointer pvar;
246 pointer pinfo ATTRIBUTE_UNUSED;
247 {
248 struct sglobal *qglobal = (struct sglobal *) pglobal;
249 char **pzdebug = (char **) pvar;
250
251 return _uuconf_idebug_cmd (qglobal, pzdebug, argc, argv,
252 qglobal->pblock);
253 }
254
255 /* Add new filenames to a list of files. */
256
257 /*ARGSUSED*/
258 static int
itaddfile(pglobal,argc,argv,pvar,pinfo)259 itaddfile (pglobal, argc, argv, pvar, pinfo)
260 pointer pglobal;
261 int argc;
262 char **argv;
263 pointer pvar;
264 pointer pinfo ATTRIBUTE_UNUSED;
265 {
266 struct sglobal *qglobal = (struct sglobal *) pglobal;
267 char ***ppz = (char ***) pvar;
268 int i;
269 int iret;
270
271 if (argc == 1)
272 {
273 iret = _uuconf_iadd_string (qglobal, NULL, FALSE, FALSE, ppz,
274 qglobal->pblock);
275 if (iret != UUCONF_SUCCESS)
276 return iret;
277 }
278 else
279 {
280 for (i = 1; i < argc; i++)
281 {
282 char *z;
283 boolean fallocated;
284
285 MAKE_ABSOLUTE (z, fallocated, argv[i], NEWCONFIGLIB,
286 qglobal->pblock);
287 if (z == NULL)
288 {
289 qglobal->ierrno = errno;
290 return (UUCONF_MALLOC_FAILED
291 | UUCONF_ERROR_ERRNO
292 | UUCONF_CMDTABRET_EXIT);
293 }
294 iret = _uuconf_iadd_string (qglobal, z, ! fallocated, FALSE, ppz,
295 qglobal->pblock);
296 if (iret != UUCONF_SUCCESS)
297 return iret;
298 }
299 }
300
301 return UUCONF_CMDTABRET_CONTINUE;
302 }
303
304 /* Handle an "unknown" command. We accumulate this into a linked
305 list, and only parse them later in uuconf_unknown_system_info. */
306
307 /*ARGSUSED*/
308 static int
itunknown(pglobal,argc,argv,pvar,pinfo)309 itunknown (pglobal, argc, argv, pvar, pinfo)
310 pointer pglobal;
311 int argc;
312 char **argv;
313 pointer pvar;
314 pointer pinfo ATTRIBUTE_UNUSED;
315 {
316 struct sglobal *qglobal = (struct sglobal *) pglobal;
317 struct sunknown **pq = (struct sunknown **) pvar;
318 struct sunknown *q;
319
320 q = (struct sunknown *) uuconf_malloc (qglobal->pblock,
321 sizeof (struct sunknown));
322 if (q == NULL)
323 {
324 qglobal->ierrno = errno;
325 return (UUCONF_MALLOC_FAILED
326 | UUCONF_ERROR_ERRNO
327 | UUCONF_CMDTABRET_EXIT);
328 }
329 q->qnext = NULL;
330 q->ilineno = qglobal->ilineno;
331 q->cargs = argc - 1;
332 q->pzargs = (char **) uuconf_malloc (qglobal->pblock,
333 (argc - 1) * sizeof (char *));
334 if (q->pzargs == NULL)
335 {
336 qglobal->ierrno = errno;
337 return (UUCONF_MALLOC_FAILED
338 | UUCONF_ERROR_ERRNO
339 | UUCONF_CMDTABRET_EXIT);
340 }
341 memcpy ((pointer) q->pzargs, (pointer) (argv + 1),
342 (argc - 1) * sizeof (char *));
343
344 while (*pq != NULL)
345 pq = &(*pq)->qnext;
346
347 *pq = q;
348
349 return UUCONF_CMDTABRET_KEEP;
350 }
351
352 /* If we encounter an unknown command, see if it is the program with
353 which we were invoked. If it was, pass the remaining arguments
354 back through the table. */
355
356 /*ARGSUSED*/
357 static int
itprogram(pglobal,argc,argv,pvar,pinfo)358 itprogram (pglobal, argc, argv, pvar, pinfo)
359 pointer pglobal;
360 int argc;
361 char **argv;
362 pointer pvar ATTRIBUTE_UNUSED;
363 pointer pinfo;
364 {
365 struct sglobal *qglobal = (struct sglobal *) pglobal;
366 struct sinfo *qinfo = (struct sinfo *) pinfo;
367
368 if (argc <= 1
369 || strcasecmp (qinfo->zname, argv[0]) != 0)
370 return UUCONF_CMDTABRET_CONTINUE;
371
372 return uuconf_cmd_args (pglobal, argc - 1, argv + 1, qinfo->qcmds,
373 (pointer) NULL, (uuconf_cmdtabfn) NULL, 0,
374 qglobal->pblock);
375 }
376
377 /* If a filename was not set by the configuration file, add in the
378 default value. */
379
380 static int
itset_default(qglobal,ppzvar,zfile)381 itset_default (qglobal, ppzvar, zfile)
382 struct sglobal *qglobal;
383 char ***ppzvar;
384 const char *zfile;
385 {
386 size_t clen;
387 char *zadd;
388
389 if (*ppzvar != NULL)
390 return UUCONF_SUCCESS;
391
392 clen = strlen (zfile);
393 zadd = (char *) uuconf_malloc (qglobal->pblock,
394 sizeof NEWCONFIGLIB + clen);
395 if (zadd == NULL)
396 {
397 qglobal->ierrno = errno;
398 return UUCONF_MALLOC_FAILED | UUCONF_ERROR_ERRNO;
399 }
400
401 memcpy ((pointer) zadd, (pointer) NEWCONFIGLIB, sizeof NEWCONFIGLIB - 1);
402 memcpy ((pointer) (zadd + sizeof NEWCONFIGLIB - 1), (pointer) zfile,
403 clen + 1);
404
405 return _uuconf_iadd_string (qglobal, zadd, FALSE, FALSE, ppzvar,
406 qglobal->pblock);
407 }
408
409 /* Handle the "debug" command which is documented to take multiple
410 arguments. This is also called by the ``debug'' command in a sys
411 file. It returns a CMDTABRET code. This should probably be in its
412 own file, but the only other place it is called is from tsinfo.c,
413 and any user of tsinfo.c it sure to link in this file as well. */
414
415 int
_uuconf_idebug_cmd(qglobal,pzdebug,argc,argv,pblock)416 _uuconf_idebug_cmd (qglobal, pzdebug, argc, argv, pblock)
417 struct sglobal *qglobal;
418 char **pzdebug;
419 int argc;
420 char **argv;
421 pointer pblock;
422 {
423 if (argc == 1)
424 {
425 *pzdebug = NULL;
426 return UUCONF_CMDTABRET_CONTINUE;
427 }
428 else if (argc == 2)
429 {
430 *pzdebug = argv[1];
431 return UUCONF_CMDTABRET_KEEP;
432 }
433 else
434 {
435 size_t cdebug;
436 int i;
437 char *zdebug;
438
439 cdebug = 0;
440 for (i = 1; i < argc; i++)
441 cdebug += strlen (argv[i]) + 1;
442 zdebug = (char *) uuconf_malloc (pblock, cdebug);
443 if (zdebug == NULL)
444 {
445 qglobal->ierrno = errno;
446 return (UUCONF_MALLOC_FAILED
447 | UUCONF_ERROR_ERRNO
448 | UUCONF_CMDTABRET_EXIT);
449 }
450 cdebug = 0;
451 for (i = 1; i < argc; i++)
452 {
453 size_t clen;
454
455 clen = strlen (argv[i]);
456 memcpy (zdebug + cdebug, argv[i], clen);
457 zdebug[cdebug + clen] = ' ';
458 cdebug += clen + 1;
459 }
460 zdebug[cdebug - 1] = '\0';
461 *pzdebug = zdebug;
462 return UUCONF_CMDTABRET_CONTINUE;
463 }
464 }
465