home *** CD-ROM | disk | FTP | other *** search
/ OpenStep 4.2J (Developer) / os42jdev.iso / NextDeveloper / Source / GNU / uucp / Uucp.framework / uuconf.subproj / syssub.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-10-09  |  15.7 KB  |  525 lines

  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[] = "$Id: syssub.c,v 1.14 1995/06/21 19:24:20 ian Rel $";
  30. #endif
  31.  
  32. #include <errno.h>
  33.  
  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.  
  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.  
  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.  
  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. }
  525.