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