]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - gnu/libexec/uucp/libuuconf/syssub.c
$Id$ -> $FreeBSD$
[FreeBSD/FreeBSD.git] / gnu / libexec / uucp / libuuconf / syssub.c
1 /* syssub.c
2    System information subroutines.
3
4    Copyright (C) 1992, 1993, 1995 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 or
23    c/o Cygnus Support, 48 Grove Street, Somerville, MA 02144.
24    */
25
26 #include "uucnfi.h"
27
28 #if USE_RCS_ID
29 const char _uuconf_syssub_rcsid[] = "$FreeBSD$";
30 #endif
31
32 #include <errno.h>
33 \f
34 /* This macro operates on every string (char *) field in struct
35    uuconf_system.  */
36 #define SYSTEM_STRINGS(OP) \
37   do \
38     { \
39       OP (uuconf_zname); \
40       OP (uuconf_zalternate); \
41       OP (uuconf_zdebug); \
42       OP (uuconf_zmax_remote_debug); \
43       OP (uuconf_zphone); \
44       OP (uuconf_zcall_login); \
45       OP (uuconf_zcall_password); \
46       OP (uuconf_zcalled_login); \
47       OP (uuconf_zprotocols); \
48       OP (uuconf_zpubdir); \
49       OP (uuconf_zlocalname); \
50     } \
51   while (0)
52
53 /* This macro operates on every string array (char **) field in struct
54    uuconf_system.  */
55 #define SYSTEM_STRING_ARRAYS(OP) \
56   do \
57     { \
58       OP (uuconf_pzalias); \
59       OP (uuconf_pzlocal_send); \
60       OP (uuconf_pzremote_send); \
61       OP (uuconf_pzlocal_receive); \
62       OP (uuconf_pzremote_receive); \
63       OP (uuconf_pzpath); \
64       OP (uuconf_pzcmds); \
65       OP (uuconf_pzforward_from); \
66       OP (uuconf_pzforward_to); \
67       OP (uuconf_schat.uuconf_pzchat); \
68       OP (uuconf_schat.uuconf_pzprogram); \
69       OP (uuconf_schat.uuconf_pzfail); \
70       OP (uuconf_scalled_chat.uuconf_pzchat); \
71       OP (uuconf_scalled_chat.uuconf_pzprogram); \
72       OP (uuconf_scalled_chat.uuconf_pzfail); \
73     } \
74   while (0)
75
76 /* This macro operations on every timespan pointer (struct
77    uuconf_timespan *) in struct uuconf_system.  */
78 #define SYSTEM_TIMESPANS(OP) \
79   do \
80     { \
81       OP (uuconf_qtimegrade); \
82       OP (uuconf_qcalltimegrade); \
83       OP (uuconf_qcalledtimegrade); \
84       OP (uuconf_qcall_local_size); \
85       OP (uuconf_qcall_remote_size); \
86       OP (uuconf_qcalled_local_size); \
87       OP (uuconf_qcalled_remote_size); \
88     } \
89   while (0)
90
91 /* This macro operates on every boolean value (of type int, although
92    some type int are not boolean) field in uuconf_system.  */
93 #define SYSTEM_BOOLEANS(OP) \
94   do \
95     { \
96       OP (uuconf_fcall); \
97       OP (uuconf_fcalled); \
98       OP (uuconf_fcallback); \
99       OP (uuconf_fsequence); \
100       OP (uuconf_fsend_request); \
101       OP (uuconf_frec_request); \
102       OP (uuconf_fcall_transfer); \
103       OP (uuconf_fcalled_transfer); \
104       OP (uuconf_schat.uuconf_fstrip); \
105       OP (uuconf_scalled_chat.uuconf_fstrip); \
106     } \
107   while (0)
108
109 /* This macro operates on every generic integer (type int or long) in
110    uuconf_system.  */
111 #define SYSTEM_INTEGERS(OP) \
112   do \
113     { \
114       OP (uuconf_cmax_retries); \
115       OP (uuconf_csuccess_wait); \
116       OP (uuconf_ibaud); \
117       OP (uuconf_ihighbaud); \
118       OP (uuconf_cfree_space); \
119       OP (uuconf_schat.uuconf_ctimeout); \
120       OP (uuconf_scalled_chat.uuconf_ctimeout); \
121     } \
122   while (0)
123
124 /* There is no macro for uuconf_qalternate, uuconf_zport,
125    uuconf_qport, uuconf_qproto_params, or uuconf_palloc.  */
126 \f
127 /* Clear the contents of a struct uuconf_system.  */
128
129 void
130 _uuconf_uclear_system (q)
131      struct uuconf_system *q;
132 {
133 #define CLEAR(x) q->x = (char *) &_uuconf_unset
134   SYSTEM_STRINGS (CLEAR);
135 #undef CLEAR
136 #define CLEAR(x) q->x = (char **) &_uuconf_unset
137   SYSTEM_STRING_ARRAYS (CLEAR);
138 #undef CLEAR
139 #define CLEAR(x) q->x = (struct uuconf_timespan *) &_uuconf_unset
140   SYSTEM_TIMESPANS (CLEAR);
141 #undef CLEAR
142 #define CLEAR(x) q->x = -1
143   SYSTEM_BOOLEANS (CLEAR);
144   SYSTEM_INTEGERS (CLEAR);
145 #undef CLEAR
146   q->uuconf_qalternate = NULL;
147   q->uuconf_zport = (char *) &_uuconf_unset;
148   q->uuconf_qport = (struct uuconf_port *) &_uuconf_unset;
149   q->uuconf_qproto_params = (struct uuconf_proto_param *) &_uuconf_unset;
150   q->uuconf_palloc = NULL;
151 }
152 \f
153 /* Default the contents of one struct uuconf_system to the contents of
154    another.  This default alternate by alternate.  Any additional
155    alternates in q default to the last alternate of qdefault.  If the
156    faddalternates arguments is TRUE, additional alternates or qdefault
157    are added to q; these alternates are copies of the first alternate
158    of q, and defaults are set from the additional alternates of
159    qdefault.  */
160
161 int
162 _uuconf_isystem_default (qglobal, qset, qdefault, faddalternates)
163      struct sglobal *qglobal;
164      struct uuconf_system *qset;
165      struct uuconf_system *qdefault;
166      boolean faddalternates;
167 {
168   struct uuconf_system *qalt;
169
170   if (qset->uuconf_palloc != qdefault->uuconf_palloc)
171     qset->uuconf_palloc =
172       _uuconf_pmalloc_block_merge (qset->uuconf_palloc,
173                                    qdefault->uuconf_palloc);
174
175   /* If we are adding alternates from the default, make sure we have
176      at least as many alternates in qset as we do in qdefault.  Each
177      new alternate we create gets initialized to the first alternate
178      of the system.  */
179   if (faddalternates)
180     {
181       struct uuconf_system **pq, *qdef;
182
183       for (qdef = qdefault, pq = &qset;
184            qdef != NULL;
185            qdef = qdef->uuconf_qalternate, pq = &(*pq)->uuconf_qalternate)
186         {
187           if (*pq == NULL)
188             {
189               *pq = ((struct uuconf_system *)
190                      uuconf_malloc (qset->uuconf_palloc,
191                                     sizeof (struct uuconf_system)));
192               if (*pq == NULL)
193                 {
194                   qglobal->ierrno = errno;
195                   return UUCONF_MALLOC_FAILED | UUCONF_ERROR_ERRNO;
196                 }
197               **pq = *qset;
198               (*pq)->uuconf_qalternate = NULL;
199             }
200         }
201     }
202
203   for (qalt = qset; qalt != NULL; qalt = qalt->uuconf_qalternate)
204     {
205 #define DEFAULT(x) \
206   if (qalt->x == (char *) &_uuconf_unset) qalt->x = qdefault->x
207       SYSTEM_STRINGS (DEFAULT);
208 #undef DEFAULT
209 #define DEFAULT(x) \
210   if (qalt->x == (char **) &_uuconf_unset) qalt->x = qdefault->x
211       SYSTEM_STRING_ARRAYS (DEFAULT);
212 #undef DEFAULT
213 #define DEFAULT(x) \
214   if (qalt->x == (struct uuconf_timespan *) &_uuconf_unset) \
215     qalt->x = qdefault->x
216       SYSTEM_TIMESPANS (DEFAULT);
217 #undef DEFAULT
218 #define DEFAULT(x) if (qalt->x < 0) qalt->x = qdefault->x
219       SYSTEM_BOOLEANS (DEFAULT);
220       SYSTEM_INTEGERS (DEFAULT);
221 #undef DEFAULT
222
223       /* We only copy over zport if both zport and qport are NULL,
224          because otherwise a default zport would override a specific
225          qport.  */
226       if (qalt->uuconf_zport == (char *) &_uuconf_unset
227           && qalt->uuconf_qport == (struct uuconf_port *) &_uuconf_unset)
228         qalt->uuconf_zport = qdefault->uuconf_zport;
229       if (qalt->uuconf_qport == (struct uuconf_port *) &_uuconf_unset)
230         qalt->uuconf_qport = qdefault->uuconf_qport;
231
232       if (qalt->uuconf_qproto_params
233           == (struct uuconf_proto_param *) &_uuconf_unset)
234         qalt->uuconf_qproto_params = qdefault->uuconf_qproto_params;
235       else if (qdefault->uuconf_qproto_params != NULL)
236         {
237           int cnew, ca;
238           struct uuconf_proto_param *qd, *qa;
239
240           /* Merge in the default protocol parameters, so that a
241              system with 'g' protocol parameters won't lose the
242              default 'i' protocol parameters.  */
243           ca = 0;
244           cnew = 0;
245           for (qd = qdefault->uuconf_qproto_params;
246                qd->uuconf_bproto != '\0';
247                qd++)
248             {
249               int c;
250
251               c = 0;
252               for (qa = qalt->uuconf_qproto_params;
253                    (qa->uuconf_bproto != '\0'
254                     && qa->uuconf_bproto != qd->uuconf_bproto);
255                    qa++)
256                 ++c;
257               if (qa->uuconf_bproto == '\0')
258                 {
259                   ++cnew;
260                   ca = c;
261                 }
262             }
263
264           if (cnew > 0)
265             {
266               struct uuconf_proto_param *qnew;
267
268               qnew = ((struct uuconf_proto_param *)
269                       uuconf_malloc (qset->uuconf_palloc,
270                                      ((ca + cnew + 1)
271                                       * sizeof (struct uuconf_proto_param))));
272               if (qnew == NULL)
273                 {
274                   qglobal->ierrno = errno;
275                   return UUCONF_MALLOC_FAILED | UUCONF_ERROR_ERRNO;
276                 }
277               memcpy ((pointer) qnew, (pointer) qalt->uuconf_qproto_params,
278                       ca * sizeof (struct uuconf_proto_param));
279               cnew = 0;
280               for (qd = qdefault->uuconf_qproto_params;
281                    qd->uuconf_bproto != '\0';
282                    qd++)
283                 {
284                   for (qa = qalt->uuconf_qproto_params;
285                        (qa->uuconf_bproto != '\0'
286                         && qa->uuconf_bproto != qd->uuconf_bproto);
287                        qa++)
288                     ;
289                   if (qa->uuconf_bproto == '\0')
290                     {
291                       qnew[ca + cnew] = *qd;
292                       ++cnew;
293                     }
294                 }
295               qnew[ca + cnew].uuconf_bproto = '\0';
296               uuconf_free (qset->uuconf_palloc, qalt->uuconf_qproto_params);
297               qalt->uuconf_qproto_params = qnew;
298             }
299         }
300
301       if (qdefault->uuconf_qalternate != NULL)
302         qdefault = qdefault->uuconf_qalternate;
303     }
304
305   return UUCONF_SUCCESS;
306 }
307 \f
308 /* Put in the basic defaults.  This ensures that the fields are valid
309    on every uuconf_system structure.  */
310
311 int
312 _uuconf_isystem_basic_default (qglobal, q)
313      struct sglobal *qglobal;
314      register struct uuconf_system *q;
315 {
316   int iret;
317
318   iret = UUCONF_SUCCESS;
319
320   for (; q != NULL && iret == UUCONF_SUCCESS; q = q->uuconf_qalternate)
321     {
322       /* The default of 26 allowable retries is traditional.  */
323       if (q->uuconf_cmax_retries < 0)
324         q->uuconf_cmax_retries = 26;
325       if (q->uuconf_schat.uuconf_pzchat == (char **) &_uuconf_unset)
326         {
327           q->uuconf_schat.uuconf_pzchat = NULL;
328           iret = _uuconf_iadd_string (qglobal, (char *) "\"\"", FALSE,
329                                       FALSE,
330                                       &q->uuconf_schat.uuconf_pzchat,
331                                       q->uuconf_palloc);
332           if (iret != UUCONF_SUCCESS)
333             return iret;
334           iret = _uuconf_iadd_string (qglobal, (char *) "\\r\\c", FALSE,
335                                       FALSE,
336                                       &q->uuconf_schat.uuconf_pzchat,
337                                       q->uuconf_palloc);
338           if (iret != UUCONF_SUCCESS)
339             return iret;
340           iret = _uuconf_iadd_string (qglobal, (char *) "ogin:", FALSE,
341                                       FALSE,
342                                       &q->uuconf_schat.uuconf_pzchat,
343                                       q->uuconf_palloc);
344           if (iret != UUCONF_SUCCESS)
345             return iret;
346           iret = _uuconf_iadd_string (qglobal, (char *) "-BREAK", FALSE,
347                                       FALSE,
348                                       &q->uuconf_schat.uuconf_pzchat,
349                                       q->uuconf_palloc);
350           if (iret != UUCONF_SUCCESS)
351             return iret;
352           iret = _uuconf_iadd_string (qglobal, (char *) "-ogin:", FALSE,
353                                       FALSE,
354                                       &q->uuconf_schat.uuconf_pzchat,
355                                       q->uuconf_palloc);
356           if (iret != UUCONF_SUCCESS)
357             return iret;
358           iret = _uuconf_iadd_string (qglobal, (char *) "-BREAK", FALSE,
359                                       FALSE,
360                                       &q->uuconf_schat.uuconf_pzchat,
361                                       q->uuconf_palloc);
362           if (iret != UUCONF_SUCCESS)
363             return iret;
364           iret = _uuconf_iadd_string (qglobal, (char *) "-ogin:", FALSE,
365                                       FALSE,
366                                       &q->uuconf_schat.uuconf_pzchat,
367                                       q->uuconf_palloc);
368           if (iret != UUCONF_SUCCESS)
369             return iret;
370           iret = _uuconf_iadd_string (qglobal, (char *) "\\L", FALSE,
371                                       FALSE,
372                                       &q->uuconf_schat.uuconf_pzchat,
373                                       q->uuconf_palloc);
374           if (iret != UUCONF_SUCCESS)
375             return iret;
376           iret = _uuconf_iadd_string (qglobal, (char *) "word:", FALSE,
377                                       FALSE,
378                                       &q->uuconf_schat.uuconf_pzchat,
379                                       q->uuconf_palloc);
380           if (iret != UUCONF_SUCCESS)
381             return iret;
382           iret = _uuconf_iadd_string (qglobal, (char *) "\\P", FALSE,
383                                       FALSE,
384                                       &q->uuconf_schat.uuconf_pzchat,
385                                       q->uuconf_palloc);
386           if (iret != UUCONF_SUCCESS)
387             return iret;
388         }
389       if (q->uuconf_schat.uuconf_ctimeout < 0)
390         q->uuconf_schat.uuconf_ctimeout = 10;
391       if (q->uuconf_schat.uuconf_fstrip < 0)
392         q->uuconf_schat.uuconf_fstrip = TRUE;
393       if (q->uuconf_scalled_chat.uuconf_ctimeout < 0)
394         q->uuconf_scalled_chat.uuconf_ctimeout = 60;
395       if (q->uuconf_scalled_chat.uuconf_fstrip < 0)
396         q->uuconf_scalled_chat.uuconf_fstrip = TRUE;
397       if (q->uuconf_fsend_request < 0)
398         q->uuconf_fsend_request = TRUE;
399       if (q->uuconf_frec_request < 0)
400         q->uuconf_frec_request = TRUE;
401       if (q->uuconf_fcall_transfer < 0)
402         q->uuconf_fcall_transfer = TRUE;
403       if (q->uuconf_fcalled_transfer < 0)
404         q->uuconf_fcalled_transfer = TRUE;
405       if (q->uuconf_pzlocal_send == (char **) &_uuconf_unset)
406         {
407           q->uuconf_pzlocal_send = NULL;
408           iret = _uuconf_iadd_string (qglobal, (char *) ZROOTDIR, FALSE,
409                                       FALSE, &q->uuconf_pzlocal_send,
410                                       q->uuconf_palloc);
411           if (iret != UUCONF_SUCCESS)
412             return iret;
413         }
414       if (q->uuconf_pzremote_send == (char **) &_uuconf_unset)
415         {
416           q->uuconf_pzremote_send = NULL;
417           iret = _uuconf_iadd_string (qglobal, (char *) "~", FALSE, FALSE,
418                                       &q->uuconf_pzremote_send,
419                                       q->uuconf_palloc);
420           if (iret != UUCONF_SUCCESS)
421             return iret;
422         }
423       if (q->uuconf_pzlocal_receive == (char **) &_uuconf_unset)
424         {
425           q->uuconf_pzlocal_receive = NULL;
426           iret = _uuconf_iadd_string (qglobal, (char *) "~", FALSE, FALSE,
427                                       &q->uuconf_pzlocal_receive,
428                                       q->uuconf_palloc);
429           if (iret != UUCONF_SUCCESS)
430             return iret;
431         }
432       if (q->uuconf_pzremote_receive == (char **) &_uuconf_unset)
433         {
434           q->uuconf_pzremote_receive = NULL;
435           iret = _uuconf_iadd_string (qglobal, (char *) "~", FALSE, FALSE,
436                                       &q->uuconf_pzremote_receive,
437                                       q->uuconf_palloc);
438           if (iret != UUCONF_SUCCESS)
439             return iret;
440         }
441
442       if (q->uuconf_pzpath == (char **) &_uuconf_unset)
443         {
444           char *zdup;
445           char **pz;
446           size_t csplit;
447           int c;
448
449           zdup = (char *) uuconf_malloc (q->uuconf_palloc, sizeof CMDPATH);
450           if (zdup == NULL)
451             {
452               qglobal->ierrno = errno;
453               return UUCONF_MALLOC_FAILED | UUCONF_ERROR_ERRNO;
454             }
455                   
456           memcpy ((pointer) zdup, (pointer) CMDPATH, sizeof CMDPATH);
457           pz = NULL;
458           csplit = 0;
459           if ((c = _uuconf_istrsplit (zdup, '\0', &pz, &csplit)) < 0)
460             {
461               qglobal->ierrno = errno;
462               return UUCONF_MALLOC_FAILED | UUCONF_ERROR_ERRNO;
463             }
464           q->uuconf_pzpath = (char **) uuconf_malloc (q->uuconf_palloc,
465                                                       ((c + 1)
466                                                        * sizeof (char *)));
467           if (q->uuconf_pzpath == NULL)
468             {
469               qglobal->ierrno = errno;
470               return UUCONF_MALLOC_FAILED | UUCONF_ERROR_ERRNO;
471             }
472           memcpy ((pointer) q->uuconf_pzpath, (pointer) pz,
473                   c * sizeof (char *));
474           q->uuconf_pzpath[c] = NULL;
475           free ((pointer) pz);
476         }
477
478       if (q->uuconf_pzcmds == (char **) &_uuconf_unset)
479         {
480           q->uuconf_pzcmds = ((char **)
481                               uuconf_malloc (q->uuconf_palloc,
482                                              3 * sizeof (const char *)));
483           if (q->uuconf_pzcmds == NULL)
484             {
485               qglobal->ierrno = errno;
486               return UUCONF_MALLOC_FAILED | UUCONF_ERROR_ERRNO;
487             }
488           q->uuconf_pzcmds[0] = (char *) "rnews";
489           q->uuconf_pzcmds[1] = (char *) "rmail";
490           q->uuconf_pzcmds[2] = NULL;
491         }
492
493       if (q->uuconf_cfree_space < 0)
494         q->uuconf_cfree_space = DEFAULT_FREE_SPACE;
495
496       if (q->uuconf_zpubdir == (const char *) &_uuconf_unset)
497         q->uuconf_zpubdir = qglobal->qprocess->zpubdir;
498
499 #define SET(x) if (q->x == (char *) &_uuconf_unset) q->x = NULL
500       SYSTEM_STRINGS(SET);
501 #undef SET
502 #define SET(x) if (q->x == (char **) &_uuconf_unset) q->x = NULL
503       SYSTEM_STRING_ARRAYS(SET);
504 #undef SET
505 #define SET(x) \
506   if (q->x == (struct uuconf_timespan *) &_uuconf_unset) q->x = NULL
507       SYSTEM_TIMESPANS (SET);
508 #undef SET
509 #define SET(x) if (q->x < 0) q->x = 0
510       SYSTEM_BOOLEANS (SET);
511       SYSTEM_INTEGERS (SET);
512 #undef SET
513
514       if (q->uuconf_zport == (char *) &_uuconf_unset)
515         q->uuconf_zport = NULL;
516       if (q->uuconf_qport == (struct uuconf_port *) &_uuconf_unset)
517         q->uuconf_qport = NULL;
518       if (q->uuconf_qproto_params
519           == (struct uuconf_proto_param *) &_uuconf_unset)
520         q->uuconf_qproto_params = NULL;
521     }
522
523   return iret;
524 }