aboutsummaryrefslogtreecommitdiff
path: root/gnu/libexec/uucp/common_sources
diff options
context:
space:
mode:
Diffstat (limited to 'gnu/libexec/uucp/common_sources')
-rw-r--r--gnu/libexec/uucp/common_sources/chat.c1429
-rw-r--r--gnu/libexec/uucp/common_sources/conf.h444
-rw-r--r--gnu/libexec/uucp/common_sources/conn.c552
-rw-r--r--gnu/libexec/uucp/common_sources/conn.h312
-rw-r--r--gnu/libexec/uucp/common_sources/copy.c202
-rw-r--r--gnu/libexec/uucp/common_sources/cu.h80
-rw-r--r--gnu/libexec/uucp/common_sources/getopt.h120
-rw-r--r--gnu/libexec/uucp/common_sources/log.c699
-rw-r--r--gnu/libexec/uucp/common_sources/policy.h521
-rw-r--r--gnu/libexec/uucp/common_sources/prot.c237
-rw-r--r--gnu/libexec/uucp/common_sources/prot.h250
-rw-r--r--gnu/libexec/uucp/common_sources/sysdep.h530
-rw-r--r--gnu/libexec/uucp/common_sources/system.h950
-rw-r--r--gnu/libexec/uucp/common_sources/tcp.c470
-rw-r--r--gnu/libexec/uucp/common_sources/tli.c644
-rw-r--r--gnu/libexec/uucp/common_sources/trans.h268
-rw-r--r--gnu/libexec/uucp/common_sources/util.c144
-rw-r--r--gnu/libexec/uucp/common_sources/uuconf.h1496
-rw-r--r--gnu/libexec/uucp/common_sources/uucp.h367
-rw-r--r--gnu/libexec/uucp/common_sources/uudefs.h445
20 files changed, 10160 insertions, 0 deletions
diff --git a/gnu/libexec/uucp/common_sources/chat.c b/gnu/libexec/uucp/common_sources/chat.c
new file mode 100644
index 000000000000..8544ed2e2027
--- /dev/null
+++ b/gnu/libexec/uucp/common_sources/chat.c
@@ -0,0 +1,1429 @@
+/* chat.c
+ Chat routine for the UUCP package.
+
+ Copyright (C) 1991, 1992 Ian Lance Taylor
+
+ This file is part of the Taylor UUCP package.
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ The author of the program may be contacted at ian@airs.com or
+ c/o Infinity Development Systems, P.O. Box 520, Waltham, MA 02254.
+ */
+
+#include "uucp.h"
+
+#if USE_RCS_ID
+const char chat_rcsid[] = "$Id: chat.c,v 1.1 1993/08/05 18:22:30 conklin Exp $";
+#endif
+
+#include <ctype.h>
+#include <errno.h>
+
+#include "uudefs.h"
+#include "uuconf.h"
+#include "conn.h"
+#include "prot.h"
+#include "system.h"
+
+/* Local functions. */
+
+static int icexpect P((struct sconnection *qconn, int cstrings,
+ char **azstrings, size_t *aclens,
+ int ctimeout, boolean fstrip));
+static boolean fcsend P((struct sconnection *qconn, pointer puuconf,
+ const char *zsend,
+ const struct uuconf_system *qsys,
+ const struct uuconf_dialer *qdial,
+ const char *zphone,
+ boolean ftranslate, boolean fstrip));
+static boolean fcecho_send_strip P((struct sconnection *qconn,
+ const char *z, size_t clen));
+static boolean fcecho_send_nostrip P((struct sconnection *qconn,
+ const char *z, size_t clen));
+static boolean fcecho_send P((struct sconnection *qconn, const char *z,
+ size_t clen, boolean fstrip));
+static boolean fcphone P((struct sconnection *qconn,
+ pointer puuconf,
+ const struct uuconf_dialer *qdial,
+ const char *zphone,
+ boolean (*pfwrite) P((struct sconnection *qc,
+ const char *zwrite,
+ size_t cwrite)),
+ boolean ftranslate, boolean *pfquote));
+static boolean fctranslate P((pointer puuconf, const char *zphone,
+ const char **pzprefix,
+ const char **pzsuffix));
+static boolean fcprogram P((struct sconnection *qconn, pointer puuconf,
+ char **pzprogram,
+ const struct uuconf_system *qsys,
+ const struct uuconf_dialer *qdial,
+ const char *zphone, const char *zport,
+ long ibaud));
+
+/* Run a chat script with the other system. The chat script is a
+ series of expect send pairs. We wait for the expect string to show
+ up, and then we send the send string. The chat string for a system
+ holds the expect and send strings separated by a single space. */
+
+boolean
+fchat (qconn, puuconf, qchat, qsys, qdial, zphone, ftranslate, zport, ibaud)
+ struct sconnection *qconn;
+ pointer puuconf;
+ const struct uuconf_chat *qchat;
+ const struct uuconf_system *qsys;
+ const struct uuconf_dialer *qdial;
+ const char *zphone;
+ boolean ftranslate;
+ const char *zport;
+ long ibaud;
+{
+ int cstrings;
+ char **azstrings;
+ size_t *aclens;
+ char **pzchat;
+ char *zbuf;
+ size_t cbuflen;
+ boolean fret;
+ int i;
+
+ /* First run the program, if any. */
+ if (qchat->uuconf_pzprogram != NULL)
+ {
+ if (! fcprogram (qconn, puuconf, qchat->uuconf_pzprogram, qsys, qdial,
+ zphone, zport, ibaud))
+ return FALSE;
+ }
+
+ /* If there's no chat script, we're done. */
+ if (qchat->uuconf_pzchat == NULL)
+ return TRUE;
+
+ if (qchat->uuconf_pzfail == NULL)
+ {
+ cstrings = 1;
+ azstrings = (char **) xmalloc (sizeof (char *));
+ aclens = (size_t *) xmalloc (sizeof (size_t));
+ }
+ else
+ {
+ char **pz;
+
+ /* We leave string number 0 for the chat script. */
+ cstrings = 1;
+ for (pz = qchat->uuconf_pzfail; *pz != NULL; pz++)
+ ++cstrings;
+
+ azstrings = (char **) xmalloc (cstrings * sizeof (char *));
+ aclens = (size_t *) xmalloc (cstrings * sizeof (size_t));
+
+ /* Get the strings into the array, and handle all the escape
+ characters. */
+ for (cstrings = 1, pz = qchat->uuconf_pzfail;
+ *pz != NULL;
+ cstrings++, pz++)
+ {
+ azstrings[cstrings] = zbufcpy (*pz);
+ aclens[cstrings] = cescape (azstrings[cstrings]);
+ }
+ }
+
+ cbuflen = 0;
+ zbuf = NULL;
+ fret = TRUE;
+
+ pzchat = qchat->uuconf_pzchat;
+
+ while (*pzchat != NULL)
+ {
+ size_t clen;
+
+ /* Loop over subexpects and subsends. */
+ while (TRUE)
+ {
+ /* Copy the expect string into the buffer so that we can
+ modify it in cescape. */
+ clen = strlen (*pzchat);
+ if (clen >= cbuflen)
+ {
+ ubuffree (zbuf);
+ zbuf = zbufalc (clen + 1);
+ cbuflen = clen;
+ }
+ memcpy (zbuf, *pzchat, clen + 1);
+
+ azstrings[0] = zbuf;
+ if (azstrings[0][0] == '-')
+ ++azstrings[0];
+ aclens[0] = cescape (azstrings[0]);
+
+ if (aclens[0] == 0
+ || (aclens[0] == 2
+ && strcmp (azstrings[0], "\"\"") == 0))
+ {
+ /* There is no subexpect sequence. If there is a
+ subsend sequence we move on to it. Otherwise we let
+ this expect succeed. This is somewhat inconsistent,
+ but it seems to be the traditional approach. */
+ if (pzchat[1] == NULL || pzchat[1][0] != '-')
+ break;
+ }
+ else
+ {
+ int istr;
+
+ istr = icexpect (qconn, cstrings, azstrings, aclens,
+ qchat->uuconf_ctimeout,
+ qchat->uuconf_fstrip);
+
+ /* If we found the string, break out of the
+ subexpect/subsend loop. */
+ if (istr == 0)
+ break;
+
+ /* If we got an error, return FALSE. */
+ if (istr < -1)
+ {
+ fret = FALSE;
+ break;
+ }
+
+ /* If we found a failure string, log it and get out. */
+ if (istr > 0)
+ {
+ ulog (LOG_ERROR, "Chat script failed: Got \"%s\"",
+ qchat->uuconf_pzfail[istr - 1]);
+ fret = FALSE;
+ break;
+ }
+
+ /* We timed out; look for a send subsequence. If none,
+ the chat script has failed. */
+ if (pzchat[1] == NULL || pzchat[1][0] != '-')
+ {
+ ulog (LOG_ERROR, "Timed out in chat script");
+ fret = FALSE;
+ break;
+ }
+ }
+
+ /* Send the send subsequence without the leading '-'. A
+ \"\" will send nothing. An empty string will send a
+ carriage return. */
+ ++pzchat;
+ if (! fcsend (qconn, puuconf, *pzchat + 1, qsys, qdial, zphone,
+ ftranslate, qchat->uuconf_fstrip))
+ {
+ fret = FALSE;
+ break;
+ }
+
+ /* If there is no expect subsequence, we are done. */
+ if (pzchat[1] == NULL || pzchat[1][0] != '-')
+ break;
+
+ /* Move on to next expect subsequence. */
+ ++pzchat;
+ }
+
+ if (! fret)
+ break;
+
+ /* Move on to the send string. If there is none, we have
+ succeeded. */
+ do
+ {
+ ++pzchat;
+ }
+ while (*pzchat != NULL && (*pzchat)[0] == '-');
+
+ if (*pzchat == NULL)
+ break;
+
+ if (**pzchat != '\0')
+ {
+ if (! fcsend (qconn, puuconf, *pzchat, qsys, qdial, zphone,
+ ftranslate, qchat->uuconf_fstrip))
+ {
+ fret = FALSE;
+ break;
+ }
+ }
+
+ ++pzchat;
+ }
+
+ ubuffree (zbuf);
+ for (i = 1; i < cstrings; i++)
+ ubuffree (azstrings[i]);
+ xfree ((pointer) azstrings);
+ xfree ((pointer) aclens);
+
+ return fret;
+}
+
+/* Read characters and wait for one of a set of memory strings to come
+ in. This returns the index into the array of the string that
+ arrives, or -1 on timeout, or -2 on error. */
+
+static int
+icexpect (qconn, cstrings, azstrings, aclens, ctimeout, fstrip)
+ struct sconnection *qconn;
+ int cstrings;
+ char **azstrings;
+ size_t *aclens;
+ int ctimeout;
+ boolean fstrip;
+{
+ int i;
+ size_t cmax;
+ char *zhave;
+ size_t chave;
+ long iendtime;
+#if DEBUG > 1
+ int cchars;
+ int iolddebug;
+#endif
+
+ cmax = aclens[0];
+ for (i = 1; i < cstrings; i++)
+ if (cmax < aclens[i])
+ cmax = aclens[i];
+
+ zhave = zbufalc (cmax);
+ chave = 0;
+
+ iendtime = ixsysdep_time ((long *) NULL) + ctimeout;
+
+#if DEBUG > 1
+ cchars = 0;
+ iolddebug = iDebug;
+ if (FDEBUGGING (DEBUG_CHAT))
+ {
+ udebug_buffer ("icexpect: Looking for", azstrings[0],
+ aclens[0]);
+ ulog (LOG_DEBUG_START, "icexpect: Got \"");
+ iDebug &=~ (DEBUG_INCOMING | DEBUG_PORT);
+ }
+#endif
+
+ while (TRUE)
+ {
+ int bchar;
+
+ /* If we have no more time, get out. */
+ if (ctimeout <= 0)
+ {
+#if DEBUG > 1
+ if (FDEBUGGING (DEBUG_CHAT))
+ {
+ ulog (LOG_DEBUG_END, "\" (timed out)");
+ iDebug = iolddebug;
+ }
+#endif
+ ubuffree (zhave);
+ return -1;
+ }
+
+ /* Read one character at a time. We could use a more complex
+ algorithm to read in larger batches, but it's probably not
+ worth it. If the buffer is full, shift it left; we already
+ know that no string matches, and the buffer holds the largest
+ string, so this can't lose a match. */
+ if (chave >= cmax)
+ {
+ size_t imove;
+
+ for (imove = 0; imove < cmax - 1; imove++)
+ zhave[imove] = zhave[imove + 1];
+ --chave;
+ }
+
+ /* The timeout/error return values from breceive_char are the
+ same as for this function. */
+ bchar = breceive_char (qconn, ctimeout, TRUE);
+ if (bchar < 0)
+ {
+#if DEBUG > 1
+ if (FDEBUGGING (DEBUG_CHAT))
+ {
+ /* If there was an error, it will probably be logged in
+ the middle of our string, but this is only debugging
+ so it's not a big deal. */
+ ulog (LOG_DEBUG_END, "\" (%s)",
+ bchar == -1 ? "timed out" : "error");
+ iDebug = iolddebug;
+ }
+#endif
+ ubuffree (zhave);
+ return bchar;
+ }
+
+ /* Strip the parity bit if desired. */
+ if (fstrip)
+ bchar &= 0x7f;
+
+ zhave[chave] = (char) bchar;
+ ++chave;
+
+#if DEBUG > 1
+ if (FDEBUGGING (DEBUG_CHAT))
+ {
+ char ab[5];
+
+ ++cchars;
+ if (cchars > 60)
+ {
+ ulog (LOG_DEBUG_END, "\"");
+ ulog (LOG_DEBUG_START, "icexpect: Got \"");
+ cchars = 0;
+ }
+ (void) cdebug_char (ab, bchar);
+ ulog (LOG_DEBUG_CONTINUE, "%s", ab);
+ }
+#endif
+
+ /* See if any of the strings can be found in the buffer. Since
+ we read one character at a time, the string can only be found
+ at the end of the buffer. */
+ for (i = 0; i < cstrings; i++)
+ {
+ if (aclens[i] <= chave
+ && memcmp (zhave + chave - aclens[i], azstrings[i],
+ aclens[i]) == 0)
+ {
+#if DEBUG > 1
+ if (FDEBUGGING (DEBUG_CHAT))
+ {
+ if (i == 0)
+ ulog (LOG_DEBUG_END, "\" (found it)");
+ else
+ {
+ ulog (LOG_DEBUG_END, "\"");
+ udebug_buffer ("icexpect: Found", azstrings[i],
+ aclens[i]);
+ }
+ iDebug = iolddebug;
+ }
+#endif
+ ubuffree (zhave);
+ return i;
+ }
+ }
+
+ ctimeout = (int) (iendtime - ixsysdep_time ((long *) NULL));
+ }
+}
+
+#if DEBUG > 1
+
+/* Debugging function for fcsend. This takes the fquote variable, the
+ length of the string (0 if this an informational string which can
+ be printed directly) and the string itself. It returns the new
+ value for fquote. The fquote variable is TRUE if the debugging
+ output is in the middle of a quoted string. */
+
+static size_t cCsend_chars;
+static int iColddebug;
+
+static boolean fcsend_debug P((boolean, size_t, const char *));
+
+static boolean
+fcsend_debug (fquote, clen, zbuf)
+ boolean fquote;
+ size_t clen;
+ const char *zbuf;
+{
+ size_t cwas;
+
+ if (! FDEBUGGING (DEBUG_CHAT))
+ return TRUE;
+
+ cwas = cCsend_chars;
+ if (clen > 0)
+ cCsend_chars += clen;
+ else
+ cCsend_chars += strlen (zbuf);
+ if (cCsend_chars > 60 && cwas > 10)
+ {
+ ulog (LOG_DEBUG_END, "%s", fquote ? "\"" : "");
+ fquote = FALSE;
+ ulog (LOG_DEBUG_START, "fcsend: Writing");
+ cCsend_chars = 0;
+ }
+
+ if (clen == 0)
+ {
+ ulog (LOG_DEBUG_CONTINUE, "%s %s", fquote ? "\"" : "", zbuf);
+ return FALSE;
+ }
+ else
+ {
+ int i;
+
+ if (! fquote)
+ ulog (LOG_DEBUG_CONTINUE, " \"");
+ for (i = 0; i < clen; i++)
+ {
+ char ab[5];
+
+ (void) cdebug_char (ab, zbuf[i]);
+ ulog (LOG_DEBUG_CONTINUE, "%s", ab);
+ }
+
+ return TRUE;
+ }
+}
+
+/* Finish up the debugging information for fcsend. */
+
+static void ucsend_debug_end P((boolean, boolean));
+
+static void
+ucsend_debug_end (fquote, ferr)
+ boolean fquote;
+ boolean ferr;
+{
+ if (! FDEBUGGING (DEBUG_CHAT))
+ return;
+
+ if (fquote)
+ ulog (LOG_DEBUG_CONTINUE, "\"");
+
+ if (ferr)
+ ulog (LOG_DEBUG_CONTINUE, " (error)");
+
+ ulog (LOG_DEBUG_END, "%s", "");
+
+ iDebug = iColddebug;
+}
+
+#else /* DEBUG <= 1 */
+
+/* Use macro definitions to make fcsend look neater. */
+
+#define fcsend_debug(fquote, clen, zbuf) TRUE
+
+#define ucsend_debug_end(fquote, ferror)
+
+#endif /* DEBUG <= 1 */
+
+/* Send a string out. This has to parse escape sequences as it goes.
+ Note that it handles the dialer escape sequences (\e, \E, \D, \T)
+ although they make no sense for chatting with a system. */
+
+static boolean
+fcsend (qconn, puuconf, z, qsys, qdial, zphone, ftranslate, fstrip)
+ struct sconnection *qconn;
+ pointer puuconf;
+ const char *z;
+ const struct uuconf_system *qsys;
+ const struct uuconf_dialer *qdial;
+ const char *zphone;
+ boolean ftranslate;
+ boolean fstrip;
+{
+ boolean fnocr;
+ boolean (*pfwrite) P((struct sconnection *, const char *, size_t));
+ char *zcallout_login;
+ char *zcallout_pass;
+ boolean fquote;
+
+ if (strcmp (z, "\"\"") == 0)
+ return TRUE;
+
+ fnocr = FALSE;
+ pfwrite = fconn_write;
+ zcallout_login = NULL;
+ zcallout_pass = NULL;
+
+#if DEBUG > 1
+ if (FDEBUGGING (DEBUG_CHAT))
+ {
+ ulog (LOG_DEBUG_START, "fcsend: Writing");
+ fquote = FALSE;
+ cCsend_chars = 0;
+ iColddebug = iDebug;
+ iDebug &=~ (DEBUG_OUTGOING | DEBUG_PORT);
+ }
+#endif
+
+ while (*z != '\0')
+ {
+ const char *zlook;
+ boolean fsend;
+ char bsend;
+
+ zlook = z + strcspn ((char *) z, "\\BE");
+
+ if (zlook > z)
+ {
+ size_t c;
+
+ c = zlook - z;
+ fquote = fcsend_debug (fquote, c, z);
+ if (! (*pfwrite) (qconn, z, c))
+ {
+ ucsend_debug_end (fquote, TRUE);
+ return FALSE;
+ }
+ }
+
+ if (*zlook == '\0')
+ break;
+
+ z = zlook;
+
+ fsend = FALSE;
+ switch (*z)
+ {
+ case 'B':
+ if (strncmp (z, "BREAK", 5) == 0)
+ {
+ fquote = fcsend_debug (fquote, (size_t) 0, "break");
+ if (! fconn_break (qconn))
+ {
+ ucsend_debug_end (fquote, TRUE);
+ return FALSE;
+ }
+ fnocr = TRUE;
+ z += 5;
+ }
+ else
+ {
+ fsend = TRUE;
+ bsend = 'B';
+ ++z;
+ }
+ break;
+ case 'E':
+ if (strncmp (z, "EOT", 3) == 0)
+ {
+ fsend = TRUE;
+ bsend = '\004';
+ fnocr = TRUE;
+ z += 3;
+ }
+ else
+ {
+ fsend = TRUE;
+ bsend = 'E';
+ ++z;
+ }
+ break;
+ case '\\':
+ ++z;
+ switch (*z)
+ {
+ case '-':
+ fsend = TRUE;
+ bsend = '-';
+ break;
+ case 'b':
+ fsend = TRUE;
+ bsend = '\b';
+ break;
+ case 'c':
+ fnocr = TRUE;
+ break;
+ case 'd':
+ fquote = fcsend_debug (fquote, (size_t) 0, "sleep");
+ usysdep_sleep (2);
+ break;
+ case 'e':
+ fquote = fcsend_debug (fquote, (size_t) 0, "echo-check-off");
+ pfwrite = fconn_write;
+ break;
+ case 'E':
+ fquote = fcsend_debug (fquote, (size_t) 0, "echo-check-on");
+ if (fstrip)
+ pfwrite = fcecho_send_strip;
+ else
+ pfwrite = fcecho_send_nostrip;
+ break;
+ case 'K':
+ fquote = fcsend_debug (fquote, (size_t) 0, "break");
+ if (! fconn_break (qconn))
+ {
+ ucsend_debug_end (fquote, TRUE);
+ return FALSE;
+ }
+ break;
+ case 'n':
+ fsend = TRUE;
+ bsend = '\n';
+ break;
+ case 'N':
+ fsend = TRUE;
+ bsend = '\0';
+ break;
+ case 'p':
+ fquote = fcsend_debug (fquote, (size_t) 0, "pause");
+ usysdep_pause ();
+ break;
+ case 'r':
+ fsend = TRUE;
+ bsend = '\r';
+ break;
+ case 's':
+ fsend = TRUE;
+ bsend = ' ';
+ break;
+ case 't':
+ fsend = TRUE;
+ bsend = '\t';
+ break;
+ case '\0':
+ --z;
+ /* Fall through. */
+ case '\\':
+ fsend = TRUE;
+ bsend = '\\';
+ break;
+ case '0': case '1': case '2': case '3': case '4':
+ case '5': case '6': case '7': case '8': case '9':
+ fsend = TRUE;
+ bsend = *z - '0';
+ if (z[1] >= '0' && z[1] <= '7')
+ bsend = (char) (8 * bsend + *++z - '0');
+ if (z[1] >= '0' && z[1] <= '7')
+ bsend = (char) (8 * bsend + *++z - '0');
+ break;
+ case 'x':
+ fsend = TRUE;
+ bsend = 0;
+ while (isxdigit (BUCHAR (z[1])))
+ {
+ if (isdigit (BUCHAR (z[1])))
+ bsend = (char) (16 * bsend + *++z - '0');
+ else if (isupper (BUCHAR (z[1])))
+ bsend = (char) (16 * bsend + *++z - 'A');
+ else
+ bsend = (char) (16 * bsend + *++z - 'a');
+ }
+ break;
+ case 'L':
+ {
+ const char *zlog;
+
+ if (qsys == NULL)
+ {
+ ucsend_debug_end (fquote, TRUE);
+ ulog (LOG_ERROR, "Illegal use of \\L");
+ return FALSE;
+ }
+ zlog = qsys->uuconf_zcall_login;
+ if (zlog == NULL)
+ {
+ ucsend_debug_end (fquote, TRUE);
+ ulog (LOG_ERROR, "No login defined");
+ return FALSE;
+ }
+ if (zlog[0] == '*' && zlog[1] == '\0')
+ {
+ if (zcallout_login == NULL)
+ {
+ int iuuconf;
+
+ iuuconf = uuconf_callout (puuconf, qsys,
+ &zcallout_login,
+ &zcallout_pass);
+ if (iuuconf == UUCONF_NOT_FOUND
+ || zcallout_login == NULL)
+ {
+ ucsend_debug_end (fquote, TRUE);
+ ulog (LOG_ERROR, "No login defined");
+ return FALSE;
+ }
+ else if (iuuconf != UUCONF_SUCCESS)
+ {
+ ucsend_debug_end (fquote, TRUE);
+ ulog_uuconf (LOG_ERROR, puuconf, iuuconf);
+ return FALSE;
+ }
+ }
+ zlog = zcallout_login;
+ }
+ fquote = fcsend_debug (fquote, (size_t) 0, "login");
+ fquote = fcsend_debug (fquote, strlen (zlog), zlog);
+ if (! (*pfwrite) (qconn, zlog, strlen (zlog)))
+ {
+ ucsend_debug_end (fquote, TRUE);
+ return FALSE;
+ }
+ }
+ break;
+ case 'P':
+ {
+ const char *zpass;
+
+ if (qsys == NULL)
+ {
+ ucsend_debug_end (fquote, TRUE);
+ ulog (LOG_ERROR, "Illegal use of \\P");
+ return FALSE;
+ }
+ zpass = qsys->uuconf_zcall_password;
+ if (zpass == NULL)
+ {
+ ucsend_debug_end (fquote, TRUE);
+ ulog (LOG_ERROR, "No password defined");
+ return FALSE;
+ }
+ if (zpass[0] == '*' && zpass[1] == '\0')
+ {
+ if (zcallout_pass == NULL)
+ {
+ int iuuconf;
+
+ iuuconf = uuconf_callout (puuconf, qsys,
+ &zcallout_login,
+ &zcallout_pass);
+ if (iuuconf == UUCONF_NOT_FOUND
+ || zcallout_pass == NULL)
+ {
+ ucsend_debug_end (fquote, TRUE);
+ ulog (LOG_ERROR, "No password defined");
+ return FALSE;
+ }
+ else if (iuuconf != UUCONF_SUCCESS)
+ {
+ ucsend_debug_end (fquote, TRUE);
+ ulog_uuconf (LOG_ERROR, puuconf, iuuconf);
+ return FALSE;
+ }
+ }
+ zpass = zcallout_pass;
+ }
+ fquote = fcsend_debug (fquote, (size_t) 0, "password");
+ fquote = fcsend_debug (fquote, strlen (zpass), zpass);
+ if (! (*pfwrite) (qconn, zpass, strlen (zpass)))
+ {
+ ucsend_debug_end (fquote, TRUE);
+ return FALSE;
+ }
+ }
+ break;
+ case 'D':
+ if (qdial == NULL || zphone == NULL)
+ {
+ ucsend_debug_end (fquote, TRUE);
+ ulog (LOG_ERROR, "Illegal use of \\D");
+ return FALSE;
+ }
+ fquote = fcsend_debug (fquote, (size_t) 0, "\\D");
+ if (! fcphone (qconn, puuconf, qdial, zphone, pfwrite,
+ ftranslate, &fquote))
+ {
+ ucsend_debug_end (fquote, TRUE);
+ return FALSE;
+ }
+ break;
+ case 'T':
+ if (qdial == NULL || zphone == NULL)
+ {
+ ucsend_debug_end (fquote, TRUE);
+ ulog (LOG_ERROR, "Illegal use of \\T");
+ return FALSE;
+ }
+ fquote = fcsend_debug (fquote, (size_t) 0, "\\T");
+ if (! fcphone (qconn, puuconf, qdial, zphone, pfwrite, TRUE,
+ &fquote))
+ {
+ ucsend_debug_end (fquote, TRUE);
+ return FALSE;
+ }
+ break;
+ case 'M':
+ if (qdial == NULL)
+ {
+ ucsend_debug_end (fquote, TRUE);
+ ulog (LOG_ERROR, "Illegal use of \\M");
+ return FALSE;
+ }
+ fquote = fcsend_debug (fquote, (size_t) 0, "ignore-carrier");
+ if (! fconn_carrier (qconn, FALSE))
+ {
+ ucsend_debug_end (fquote, TRUE);
+ return FALSE;
+ }
+ break;
+ case 'm':
+ if (qdial == NULL)
+ {
+ ucsend_debug_end (fquote, TRUE);
+ ulog (LOG_ERROR, "Illegal use of \\m");
+ return FALSE;
+ }
+ if (qdial->uuconf_fcarrier)
+ {
+ fquote = fcsend_debug (fquote, (size_t) 0, "need-carrier");
+ if (! fconn_carrier (qconn, TRUE))
+ {
+ ucsend_debug_end (fquote, TRUE);
+ return FALSE;
+ }
+ }
+ break;
+ default:
+ /* This error message will screw up any debugging
+ information, but it's easily avoidable. */
+ ulog (LOG_ERROR,
+ "Unrecognized escape sequence \\%c in send string",
+ *z);
+ fsend = TRUE;
+ bsend = *z;
+ break;
+ }
+ ++z;
+ break;
+#if DEBUG > 0
+ default:
+ ulog (LOG_FATAL, "fcsend: Can't happen");
+ break;
+#endif
+ }
+
+ if (fsend)
+ {
+ fquote = fcsend_debug (fquote, (size_t) 1, &bsend);
+ if (! (*pfwrite) (qconn, &bsend, (size_t) 1))
+ {
+ ucsend_debug_end (fquote, TRUE);
+ return FALSE;
+ }
+ }
+ }
+
+ xfree ((pointer) zcallout_login);
+ xfree ((pointer) zcallout_pass);
+
+ /* Output a final carriage return, unless there was a \c. Don't
+ bother to check for an echo. */
+ if (! fnocr)
+ {
+ char b;
+
+ b = '\r';
+ fquote = fcsend_debug (fquote, (size_t) 1, &b);
+ if (! fconn_write (qconn, &b, (size_t) 1))
+ {
+ ucsend_debug_end (fquote, TRUE);
+ return FALSE;
+ }
+ }
+
+ ucsend_debug_end (fquote, FALSE);
+
+ return TRUE;
+}
+
+/* Write out a phone number with optional dialcode translation. The
+ pfquote argument is only used for debugging. */
+
+static boolean
+fcphone (qconn, puuconf, qdial, zphone, pfwrite, ftranslate, pfquote)
+ struct sconnection *qconn;
+ pointer puuconf;
+ const struct uuconf_dialer *qdial;
+ const char *zphone;
+ boolean (*pfwrite) P((struct sconnection *qc, const char *zwrite,
+ size_t cwrite));
+ boolean ftranslate;
+ boolean *pfquote;
+{
+ const char *zprefix, *zsuffix;
+
+ if (ftranslate)
+ {
+ if (! fctranslate (puuconf, zphone, &zprefix, &zsuffix))
+ return FALSE;
+ }
+ else
+ {
+ zprefix = zphone;
+ zsuffix = NULL;
+ }
+
+ while (zprefix != NULL)
+ {
+ while (TRUE)
+ {
+ const char *z;
+ const char *zstr;
+
+ z = zprefix + strcspn ((char *) zprefix, "=-");
+ if (z > zprefix)
+ {
+ size_t clen;
+
+ clen = z - zprefix;
+ *pfquote = fcsend_debug (*pfquote, clen, zprefix);
+ if (! (*pfwrite) (qconn, zprefix, clen))
+ return FALSE;
+ }
+
+ if (*z == '=')
+ zstr = qdial->uuconf_zdialtone;
+ else if (*z == '-')
+ zstr = qdial->uuconf_zpause;
+ else /* *z == '\0' */
+ break;
+
+ if (zstr != NULL)
+ {
+ *pfquote = fcsend_debug (*pfquote, strlen (zstr), zstr);
+ if (! (*pfwrite) (qconn, zstr, strlen (zstr)))
+ return FALSE;
+ }
+
+ zprefix = z + 1;
+ }
+
+ zprefix = zsuffix;
+ zsuffix = NULL;
+ }
+
+ return TRUE;
+}
+
+/* Given a phone number, run it through dial code translation
+ returning two strings. */
+
+static boolean
+fctranslate (puuconf, zphone, pzprefix, pzsuffix)
+ pointer puuconf;
+ const char *zphone;
+ const char **pzprefix;
+ const char **pzsuffix;
+{
+ int iuuconf;
+ char *zdialcode, *zto;
+ const char *zfrom;
+ char *ztrans;
+
+ *pzprefix = zphone;
+ *pzsuffix = NULL;
+
+ zdialcode = zbufalc (strlen (zphone) + 1);
+ zfrom = zphone;
+ zto = zdialcode;
+ while (*zfrom != '\0' && isalpha (BUCHAR (*zfrom)))
+ *zto++ = *zfrom++;
+ *zto = '\0';
+
+ if (*zdialcode == '\0')
+ {
+ ubuffree (zdialcode);
+ return TRUE;
+ }
+
+ iuuconf = uuconf_dialcode (puuconf, zdialcode, &ztrans);
+
+ ubuffree (zdialcode);
+
+ if (iuuconf == UUCONF_NOT_FOUND)
+ return TRUE;
+ else if (iuuconf != UUCONF_SUCCESS)
+ {
+ ulog_uuconf (LOG_ERROR, puuconf, iuuconf);
+ return FALSE;
+ }
+ else
+ {
+ /* We really should figure out a way to free up ztrans here. */
+ *pzprefix = ztrans;
+ *pzsuffix = zfrom;
+ return TRUE;
+ }
+}
+
+/* Write out a string making sure the each character is echoed back.
+ There are two versions of this function, one which strips the
+ parity bit from the characters and one which does not. This is so
+ that I can use a single function pointer in fcsend, and to avoid
+ using any static variables so that I can put chat scripts in a
+ library some day. */
+
+static boolean
+fcecho_send_strip (qconn, zwrite, cwrite)
+ struct sconnection *qconn;
+ const char *zwrite;
+ size_t cwrite;
+{
+ return fcecho_send (qconn, zwrite, cwrite, TRUE);
+}
+
+static boolean
+fcecho_send_nostrip (qconn, zwrite, cwrite)
+ struct sconnection *qconn;
+ const char *zwrite;
+ size_t cwrite;
+{
+ return fcecho_send (qconn, zwrite, cwrite, FALSE);
+}
+
+static boolean
+fcecho_send (qconn, zwrite, cwrite, fstrip)
+ struct sconnection *qconn;
+ const char *zwrite;
+ size_t cwrite;
+ boolean fstrip;
+{
+ const char *zend;
+
+ zend = zwrite + cwrite;
+
+ for (; zwrite < zend; zwrite++)
+ {
+ int b;
+ char bwrite;
+
+ bwrite = *zwrite;
+ if (! fconn_write (qconn, &bwrite, (size_t) 1))
+ return FALSE;
+ if (fstrip)
+ bwrite &= 0x7f;
+ do
+ {
+ /* We arbitrarily wait five seconds for the echo. */
+ b = breceive_char (qconn, 5, TRUE);
+ /* Now b == -1 on timeout, -2 on error. */
+ if (b < 0)
+ {
+ if (b == -1)
+ ulog (LOG_ERROR, "Character not echoed");
+ return FALSE;
+ }
+ if (fstrip)
+ b &= 0x7f;
+ }
+ while (b != BUCHAR (bwrite));
+ }
+
+ return TRUE;
+}
+
+/* Run a chat program. Expand any escape sequences and call a system
+ dependent program to run it. */
+
+static boolean
+fcprogram (qconn, puuconf, pzprogram, qsys, qdial, zphone, zport, ibaud)
+ struct sconnection *qconn;
+ pointer puuconf;
+ char **pzprogram;
+ const struct uuconf_system *qsys;
+ const struct uuconf_dialer *qdial;
+ const char *zphone;
+ const char *zport;
+ long ibaud;
+{
+ size_t cargs;
+ char **pzpass, **pzarg;
+ char **pz;
+ char *zcallout_login;
+ char *zcallout_pass;
+ boolean fret;
+
+ cargs = 1;
+ for (pz = pzprogram; *pz != NULL; pz++)
+ ++cargs;
+
+ pzpass = (char **) xmalloc (cargs * sizeof (char *));
+
+ zcallout_login = NULL;
+ zcallout_pass = NULL;
+ fret = TRUE;
+
+ /* Copy the string into memory expanding escape sequences. */
+ for (pz = pzprogram, pzarg = pzpass; *pz != NULL; pz++, pzarg++)
+ {
+ const char *zfrom;
+ size_t calc, clen;
+ char *zto;
+
+ if (strchr (*pz, '\\') == NULL)
+ {
+ *pzarg = zbufcpy (*pz);
+ continue;
+ }
+
+ *pzarg = NULL;
+ zto = NULL;
+ calc = 0;
+ clen = 0;
+
+ for (zfrom = *pz; *zfrom != '\0'; zfrom++)
+ {
+ const char *zadd = NULL;
+ size_t cadd;
+ char abadd[15];
+
+ if (*zfrom != '\\')
+ {
+ if (clen + 2 > calc)
+ {
+ char *znew;
+
+ calc = clen + 50;
+ znew = zbufalc (calc);
+ memcpy (znew, *pzarg, clen);
+ ubuffree (*pzarg);
+ *pzarg = znew;
+ zto = znew + clen;
+ }
+ *zto++ = *zfrom;
+ ++clen;
+ continue;
+ }
+
+ ++zfrom;
+ switch (*zfrom)
+ {
+ case '\0':
+ --zfrom;
+ /* Fall through. */
+ case '\\':
+ zadd = "\\";
+ break;
+ case 'L':
+ {
+ const char *zlog;
+
+ if (qsys == NULL)
+ {
+ ulog (LOG_ERROR, "chat-program: Illegal use of \\L");
+ fret = FALSE;
+ break;
+ }
+ zlog = qsys->uuconf_zcall_login;
+ if (zlog == NULL)
+ {
+ ulog (LOG_ERROR, "chat-program: No login defined");
+ fret = FALSE;
+ break;
+ }
+ if (zlog[0] == '*' && zlog[1] == '\0')
+ {
+ if (zcallout_login == NULL)
+ {
+ int iuuconf;
+
+ iuuconf = uuconf_callout (puuconf, qsys,
+ &zcallout_login,
+ &zcallout_pass);
+ if (iuuconf == UUCONF_NOT_FOUND
+ || zcallout_login == NULL)
+ {
+ ulog (LOG_ERROR,
+ "chat-program: No login defined");
+ fret = FALSE;
+ break;
+ }
+ else if (iuuconf != UUCONF_SUCCESS)
+ {
+ ulog_uuconf (LOG_ERROR, puuconf, iuuconf);
+ fret = FALSE;
+ break;
+ }
+ }
+ zlog = zcallout_login;
+ }
+ zadd = zlog;
+ }
+ break;
+ case 'P':
+ {
+ const char *zpass;
+
+ if (qsys == NULL)
+ {
+ ulog (LOG_ERROR, "chat-program: Illegal use of \\P");
+ fret = FALSE;
+ break;
+ }
+ zpass = qsys->uuconf_zcall_password;
+ if (zpass == NULL)
+ {
+ ulog (LOG_ERROR, "chat-program: No password defined");
+ fret = FALSE;
+ break;
+ }
+ if (zpass[0] == '*' && zpass[1] == '\0')
+ {
+ if (zcallout_pass == NULL)
+ {
+ int iuuconf;
+
+ iuuconf = uuconf_callout (puuconf, qsys,
+ &zcallout_login,
+ &zcallout_pass);
+ if (iuuconf == UUCONF_NOT_FOUND
+ || zcallout_pass == NULL)
+ {
+ ulog (LOG_ERROR,
+ "chat-program: No password defined");
+ fret = FALSE;
+ break;
+ }
+ else if (iuuconf != UUCONF_SUCCESS)
+ {
+ ulog_uuconf (LOG_ERROR, puuconf, iuuconf);
+ fret = FALSE;
+ break;
+ }
+ }
+ zpass = zcallout_pass;
+ }
+ zadd = zpass;
+ }
+ break;
+ case 'D':
+ if (qdial == NULL || zphone == NULL)
+ {
+ ulog (LOG_ERROR, "chat-program: Illegal use of \\D");
+ fret = FALSE;
+ break;
+ }
+ zadd = zphone;
+ break;
+ case 'T':
+ {
+ const char *zprefix, *zsuffix;
+
+ if (qdial == NULL || zphone == NULL)
+ {
+ ulog (LOG_ERROR, "chat-program: Illegal use of \\T");
+ fret = FALSE;
+ break;
+ }
+
+ if (! fctranslate (puuconf, zphone, &zprefix, &zsuffix))
+ {
+ fret = FALSE;
+ break;
+ }
+
+ if (zsuffix == NULL)
+ zadd = zprefix;
+ else
+ {
+ size_t cprefix;
+
+ cprefix = strlen (zprefix);
+ if (clen + cprefix + 1 > calc)
+ {
+ char *znew;
+
+ calc = clen + cprefix + 20;
+ znew = zbufalc (calc);
+ memcpy (znew, *pzarg, clen);
+ ubuffree (*pzarg);
+ *pzarg = znew;
+ zto = znew + clen;
+ }
+ memcpy (zto, zprefix, cprefix);
+ zto += cprefix;
+ clen += cprefix;
+ zadd = zsuffix;
+ }
+ }
+ break;
+ case 'Y':
+ if (zLdevice == NULL && zport == NULL)
+ {
+ ulog (LOG_ERROR, "chat-program: Illegal use of \\Y");
+ fret = FALSE;
+ break;
+ }
+ /* zLdevice will generally make more sense than zport, but
+ it might not be set yet. */
+ zadd = zLdevice;
+ if (zadd == NULL)
+ zadd = zport;
+ break;
+ case 'Z':
+ if (qsys == NULL)
+ {
+ ulog (LOG_ERROR, "chat-program: Illegal use of \\Z");
+ fret = FALSE;
+ break;
+ }
+ zadd = qsys->uuconf_zname;
+ break;
+ case 'S':
+ {
+ if (ibaud == 0)
+ {
+ ulog (LOG_ERROR, "chat-program: Illegal use of \\S");
+ fret = FALSE;
+ break;
+ }
+ sprintf (abadd, "%ld", ibaud);
+ zadd = abadd;
+ }
+ break;
+ default:
+ {
+ ulog (LOG_ERROR,
+ "chat-program: Unrecognized escape sequence \\%c",
+ *zfrom);
+ abadd[0] = *zfrom;
+ abadd[1] = '\0';
+ zadd = abadd;
+ }
+ break;
+ }
+
+ if (! fret)
+ break;
+
+ cadd = strlen (zadd);
+ if (clen + cadd + 1 > calc)
+ {
+ char *znew;
+
+ calc = clen + cadd + 20;
+ znew = zbufalc (calc);
+ memcpy (znew, *pzarg, clen);
+ ubuffree (*pzarg);
+ *pzarg = znew;
+ zto = znew + clen;
+ }
+ memcpy (zto, zadd, cadd + 1);
+ zto += cadd;
+ clen += cadd;
+ }
+
+ if (! fret)
+ break;
+
+ *zto++ = '\0';
+ ++clen;
+ }
+
+ *pzarg = NULL;
+
+ if (fret)
+ fret = fconn_run_chat (qconn, pzpass);
+
+ for (pz = pzpass; *pz != NULL; pz++)
+ ubuffree (*pz);
+ xfree ((pointer) pzpass);
+ xfree ((pointer) zcallout_login);
+ xfree ((pointer) zcallout_pass);
+
+ return fret;
+}
diff --git a/gnu/libexec/uucp/common_sources/conf.h b/gnu/libexec/uucp/common_sources/conf.h
new file mode 100644
index 000000000000..9053c4423e0a
--- /dev/null
+++ b/gnu/libexec/uucp/common_sources/conf.h
@@ -0,0 +1,444 @@
+/* conf.h. Generated automatically by configure. */
+/* Configuration header file for Taylor UUCP. -*- C -*- */
+
+/* Set MAIL_PROGRAM to a program which takes a mail address as an
+ argument and accepts a mail message to send to that address on
+ stdin (e.g. "/bin/mail"). */
+#define MAIL_PROGRAM "/usr/bin/mail"
+
+/* Set ECHO_PROGRAM to a program which echoes its arguments; if echo
+ is a shell builtin you can just use "echo". */
+#define ECHO_PROGRAM "echo"
+
+/* The following macros indicate what header files you have. Set the
+ macro to 1 if you have the corresponding header file, or 0 if you
+ do not. */
+#define HAVE_STDDEF_H 1 /* <stddef.h> */
+#define HAVE_STRING_H 1 /* <string.h> */
+#define HAVE_STRINGS_H 1 /* <strings.h> */
+#define HAVE_UNISTD_H 1 /* <unistd.h> */
+#define HAVE_STDLIB_H 1 /* <stdlib.h> */
+#define HAVE_LIMITS_H 1 /* <limits.h> */
+#define HAVE_TIME_H 1 /* <time.h> */
+#define HAVE_SYS_WAIT_H 1 /* <sys/wait.h> */
+#define HAVE_SYS_IOCTL_H 1 /* <sys/ioctl.h> */
+#define HAVE_DIRENT_H 1 /* <dirent.h> */
+#define HAVE_MEMORY_H 1 /* <memory.h> */
+#define HAVE_SYS_PARAM_H 1 /* <sys/param.h> */
+#define HAVE_UTIME_H 1 /* <utime.h> */
+#define HAVE_FCNTL_H 1 /* <fcntl.h> */
+#define HAVE_SYS_FILE_H 1 /* <sys/file.h> */
+#define HAVE_SYS_TIMES_H 1 /* <sys/times.h> */
+#define HAVE_LIBC_H 0 /* <libc.h> */
+#define HAVE_SYSEXITS_H 1 /* <sysexits.h> */
+#define HAVE_POLL_H 0 /* <poll.h> */
+#define HAVE_TIUSER_H 0 /* <tiuser.h> */
+#define HAVE_XTI_H 0 /* <xti.h> */
+#define HAVE_SYS_TLI_H 0 /* <sys/tli.h> */
+#define HAVE_STROPTS_H 0 /* <stropts.h> */
+#define HAVE_FTW_H 0 /* <ftw.h> */
+#define HAVE_GLOB_H 1 /* <glob.h> */
+#define HAVE_SYS_SELECT_H 0 /* <sys/select.h> */
+#define HAVE_SYS_TYPES_TCP_H 0 /* <sys/types.tcp.h> */
+
+/* If major and minor are not defined in <sys/types.h>, but are in
+ <sys/mkdev.h>, set MAJOR_IN_MKDEV to 1. If they are in
+ <sys/sysmacros.h>, set MAJOR_IN_SYSMACROS to 1. */
+#define MAJOR_IN_MKDEV 0
+#define MAJOR_IN_SYSMACROS 0
+
+/* If the macro offsetof is not defined in <stddef.h>, you may give it
+ a definition here. If you do not, the code will use a definition
+ (in uucp.h) that should be fairly portable. */
+/* #define offsetof */
+
+/* Set RETSIGTYPE to the return type of a signal handler. On newer
+ systems this will be void; some older systems use int. */
+#define RETSIGTYPE void
+
+/* Set HAVE_SYS_TIME_AND_TIME_H to 1 if <time.h> and <sys/time.h> can both
+ be included in a single source file; if you don't have either or both of
+ them, it doesn't matter what you set this to. */
+#define HAVE_SYS_TIME_AND_TIME_H 1
+
+/* Set HAVE_TERMIOS_AND_SYS_IOCTL_H to 1 if <termios.h> and <sys/ioctl.h>
+ can both be included in a single source file; if you don't have either
+ or both of them, it doesn't matter what you set this to. */
+#define HAVE_TERMIOS_AND_SYS_IOCTL_H 1
+
+/* If you are configuring by hand, you should set one of the terminal
+ driver options in policy.h. If you are autoconfiguring, the script
+ will check whether your system defines CBREAK, which is a terminal
+ setting; if your system supports CBREAK, and you don't set a terminal
+ driver in policy.h, the code will assume that you have a BSD style
+ terminal driver. */
+#define HAVE_CBREAK 1
+
+/* The package needs several standard types. If you are using the
+ configure script, it will look in standard places for these types,
+ and give default definitions for them here if it doesn't find them.
+ The default definitions should work on most systems, but you may
+ want to check them. If you are configuring by hand, you will have
+ to figure out whether the types are defined on your system, and
+ what they should be defined to.
+
+ Any type that is not defined on your system should get a macro
+ definition. The definition should be of the name of the type in
+ all capital letters. For example, #define PID_T int. If the type
+ is defined in a standard header file, the macro name should not be
+ defined. */
+
+/* The type pid_t is used to hold a process ID number. It is normally
+ defined in <sys/types.h>. This is the type returned by the
+ functions fork or getpid. Usually int will work fine. */
+#undef PID_T
+
+/* The type uid_t is used to hold a user ID number. It is normally
+ defined in <sys/types.h>. This is the type returned by the getuid
+ function. Usually int will work fine. */
+#undef UID_T
+
+/* The type gid_t is used to hold a group ID number. It is sometimes
+ defined in <sys/types.h>. This is the type returned by the getgid
+ function. Usually int will work fine. */
+#undef GID_T
+
+/* The type off_t is used to hold an offset in a file. It is sometimes
+ defined in <sys/types.h>. This is the type of the second argument to
+ the lseek function. Usually long will work fine. */
+#undef OFF_T
+
+/* Set HAVE_SIG_ATOMIC_T_IN_SIGNAL_H if the type sig_atomic_t is defined
+ in <signal.h> as required by ANSI C. */
+#define HAVE_SIG_ATOMIC_T_IN_SIGNAL_H 0
+
+/* Set HAVE_SIG_ATOMIC_T_IN_TYPES_H if the type sig_atomic_t is defined
+ in <sys/types.h>. This is ignored if HAVE_SIG_ATOMIC_T_IN_SIGNAL_H is
+ set to 1. */
+#define HAVE_SIG_ATOMIC_T_IN_TYPES_H 0
+
+/* The type sig_atomic_t is used to hold a value which may be
+ referenced in a single atomic operation. If it is not defined in
+ either <signal.h> or <sys/types.h>, you may want to give it a
+ definition here. If you don't, the code will use char. If your
+ compiler does not support sig_atomic_t, there is no type which is
+ really correct; fortunately, for this package it does not really
+ matter very much. */
+#undef SIG_ATOMIC_T
+
+/* Set HAVE_SIZE_T_IN_STDDEF_H to 1 if the type size_t is defined in
+ <stddef.h> as required by ANSI C. */
+#define HAVE_SIZE_T_IN_STDDEF_H 1
+
+/* Set HAVE_SIZE_T_IN_TYPES_H to 1 if the type size_t is defined in
+ <sys/types.h>. This is ignored if HAVE_SIZE_T_IN_STDDEF_H is set
+ to 1. */
+#define HAVE_SIZE_T_IN_TYPES_H 1
+
+/* The type size_t is used to hold the size of an object. In
+ particular, an argument of this type is passed as the size argument
+ to the malloc and realloc functions. If size_t is not defined in
+ either <stddef.h> or <sys/types.h>, you may want to give it a
+ definition here. If you don't, the code will use unsigned. */
+#undef SIZE_T
+
+/* Set HAVE_TIME_T_IN_TIME_H to 1 if the type time_t is defined in
+ <time.h>, as required by the ANSI C standard. */
+#define HAVE_TIME_T_IN_TIME_H 1
+
+/* Set HAVE_TIME_T_IN_TYPES_H to 1 if the type time_t is defined in
+ <sys/types.h>. This is ignored if HAVE_TIME_T_IN_TIME_H is set to
+ 1. */
+#define HAVE_TIME_T_IN_TYPES_H 1
+
+/* When Taylor UUCP is talking to another instance of itself, it will
+ tell the other side the size of a file before it is transferred.
+ If the package can determine how much disk space is available, it
+ will use this information to avoid filling up the disk. Define one
+ of the following macros to tell the code how to determine the
+ amount of available disk space. It is possible that none of these
+ are appropriate; it will do no harm to use none of them, but, of
+ course, nothing will then prevent the package from filling up the
+ disk. Note that this space check is only useful when talking to
+ another instance of Taylor UUCP.
+
+ STAT_STATVFS statvfs function
+ STAT_STATFS2_BSIZE two argument statfs function with f_bsize field
+ STAT_STATFS2_FSIZE two argument statfs function with f_fsize field
+ STAT_STATFS2_FS_DATA two argument statfs function with fd_req field
+ STAT_STATFS4 four argument statfs function
+ STAT_USTAT the ustat function with 512 byte blocks. */
+#define STAT_STATVFS 0
+#define STAT_STATFS2_BSIZE 0
+#define STAT_STATFS2_FSIZE 1
+#define STAT_STATFS2_FS_DATA 0
+#define STAT_STATFS4 0
+#define STAT_USTAT 0
+
+/* Set HAVE_VOID to 1 if the compiler supports declaring functions with
+ a return type of void and casting values to void. */
+#define HAVE_VOID 1
+
+/* Set HAVE_UNSIGNED_CHAR to 1 if the compiler supports the type unsigned
+ char. */
+#define HAVE_UNSIGNED_CHAR 1
+
+/* Set HAVE_ERRNO_DECLARATION to 1 if errno is declared in <errno.h>. */
+#define HAVE_ERRNO_DECLARATION 1
+
+/* There are now a number of functions to check for. For each of
+ these, the macro HAVE_FUNC should be set to 1 if your system has
+ FUNC. For example, HAVE_VFPRINTF should be set to 1 if your system
+ has vfprintf, 0 otherwise. */
+
+/* Taylor UUCP will take advantage of the following functions if they
+ are available, but knows how to deal with their absence. */
+#define HAVE_VFPRINTF 1
+#define HAVE_FTRUNCATE 1
+#define HAVE_LTRUNC 0
+#define HAVE_WAITPID 1
+#define HAVE_WAIT4 1
+#define HAVE_GLOB 1
+#define HAVE_SETREUID 1
+
+/* There are several functions which are replaced in the subdirectory
+ lib. If they are missing, the configure script will automatically
+ add them to lib/Makefile to force them to be recompiled. If you
+ are configuring by hand, you will have to do this yourself. The
+ string @LIBOBJS@ in lib/Makefile.in should be replaced by a list of
+ object files in lib/Makefile. The following comments tell you
+ which object file names to add (they are generally fairly obvious,
+ given that the file names have no more than six characters before
+ the period). */
+
+/* For each of these functions, if it does not exist, the indicated
+ object file should be added to lib/Makefile. */
+#define HAVE_BSEARCH 1 /* bsrch.o */
+#define HAVE_GETLINE 0 /* getlin.o */
+#define HAVE_MEMCHR 1 /* memchr.o */
+#define HAVE_STRDUP 1 /* strdup.o */
+#define HAVE_STRSTR 1 /* strstr.o */
+#define HAVE_STRTOL 1 /* strtol.o */
+
+/* If neither of these functions exists, you should add bzero.o to
+ lib/Makefile. */
+#define HAVE_BZERO 1
+#define HAVE_MEMSET 1
+
+/* If neither of these functions exists, you should add memcmp.o to
+ lib/Makefile. */
+#define HAVE_MEMCMP 1
+#define HAVE_BCMP 1
+
+/* If neither of these functions exists, you should add memcpy.o to
+ lib/Makefile. */
+#define HAVE_MEMCPY 1
+#define HAVE_BCOPY 1
+
+/* If neither of these functions exists, you should add strcas.o to
+ lib/Makefile. */
+#define HAVE_STRCASECMP 1
+#define HAVE_STRICMP 0
+
+/* If neither of these functions exists, you should add strncs.o to
+ lib/Makefile. */
+#define HAVE_STRNCASECMP 1
+#define HAVE_STRNICMP 0
+
+/* If neither of these functions exists, you should add strchr.o to
+ lib/Makefile. */
+#define HAVE_STRCHR 1
+#define HAVE_INDEX 1
+
+/* If neither of these functions exists, you should add strrch.o to
+ lib/Makefile. */
+#define HAVE_STRRCHR 1
+#define HAVE_RINDEX 1
+
+/* There are also Unix specific functions which are replaced in the
+ subdirectory unix. If they are missing, the configure script will
+ automatically add them to unix/Makefile to force them to be
+ recompiled. If you are configuring by hand, you will have to do
+ this yourself. The string @UNIXOBJS@ in unix/Makefile.in should be
+ replaced by a list of object files in unix/Makefile. The following
+ comments tell you which object file names to add. */
+
+/* For each of these functions, if it does not exist, the indicated
+ object file should be added to unix/Makefile. */
+#define HAVE_OPENDIR 1 /* dirent.o */
+#define HAVE_DUP2 1 /* dup2.o */
+#define HAVE_FTW 0 /* ftw.o */
+#define HAVE_REMOVE 1 /* remove.o */
+#define HAVE_RENAME 1 /* rename.o */
+#define HAVE_STRERROR 1 /* strerr.o */
+
+/* The code needs to know how to create directories. If you have the
+ mkdir function, set HAVE_MKDIR to 1 and replace @UUDIR@ in
+ Makefile.in with '# ' (the configure script will set @UUDIR@
+ according to the variable UUDIR). Otherwise, set HAVE_MKDIR to 0,
+ remove @UUDIR@ from Makefile.in, set MKDIR_PROGRAM to the name of
+ the program which will create a directory named on the command line
+ (e.g., "/bin/mkdir"), and add mkdir.o to the @UNIXOBJS@ string in
+ unix/Makefile.in. */
+#define HAVE_MKDIR 1
+#define MKDIR_PROGRAM unused
+
+/* The code also needs to know how to remove directories. If you have
+ the rmdir function, set HAVE_RMDIR to 1. Otherwise, set
+ RMDIR_PROGRAM to the name of the program which will remove a
+ directory named on the command line (e.g., "/bin/rmdir") and add
+ rmdir.o to the @UNIXOBJS@ string in unix/Makefile.in. */
+#define HAVE_RMDIR 1
+#define RMDIR_PROGRAM unused
+
+/* The code needs to know to how to get the name of the current
+ directory. If getcwd is available it will be used, otherwise if
+ getwd is available it will be used. Otherwise, set PWD_PROGRAM to
+ the name of the program which will print the name of the current
+ working directory (e.g., "/bin/pwd") and add getcwd.o to the
+ @UNIXOBJS@ string in unix/Makefile.in. */
+#define HAVE_GETCWD 1
+#define HAVE_GETWD 1
+#define PWD_PROGRAM unused
+
+/* If you have either sigsetjmp or setret, it will be used instead of
+ setjmp. These functions will only be used if your system restarts
+ system calls after interrupts (see HAVE_RESTARTABLE_SYSCALLS,
+ below). */
+#define HAVE_SIGSETJMP 0
+#define HAVE_SETRET 0
+
+/* The code needs to know what function to use to set a signal
+ handler. If will try to use each of the following functions in
+ turn. If none are available, it will use signal, which is assumed
+ to always exist. */
+#define HAVE_SIGACTION 1
+#define HAVE_SIGVEC 1
+#define HAVE_SIGSET 0
+
+/* If the code is going to use sigvec (HAVE_SIGACTION is 0 and
+ HAVE_SIGVEC is 1), then HAVE_SIGVEC_SV_FLAGS must be set to 1 if
+ the sigvec structure contains the sv_flags field, or 0 if the
+ sigvec structure contains the sv_onstack field. If the code is not
+ going to use sigvec, it doesn't matter what this is set to. */
+#define HAVE_SIGVEC_SV_FLAGS 1
+
+/* The code will try to use each of the following functions in turn
+ when blocking signals from delivery. If none are available, a
+ relatively unimportant race condition will exist. */
+#define HAVE_SIGPROCMASK 1
+#define HAVE_SIGBLOCK 1
+#define HAVE_SIGHOLD 0
+
+/* If you have either of the following functions, it will be used to
+ determine the number of file descriptors which may be open.
+ Otherwise, the code will use OPEN_MAX if defined, then NOFILE if
+ defined, then 20. */
+#define HAVE_GETDTABLESIZE 1
+#define HAVE_SYSCONF 0
+
+/* The code will use one of the following functions when detaching
+ from a terminal. One of these must exist. */
+#define HAVE_SETPGRP 0
+#define HAVE_SETSID 1
+
+/* If you do not specify the local node name in the main configuration
+ file, Taylor UUCP will try to use each of the following functions
+ in turn. If neither is available, you must specify the local node
+ name in the configuration file. */
+#define HAVE_GETHOSTNAME 1
+#define HAVE_UNAME 0
+
+/* The code will try to use each of the following functions in turn to
+ determine the current time. If none are available, it will use
+ time, which is assumed to always exist. */
+#define HAVE_GETTIMEOFDAY 1
+#define HAVE_FTIME 0
+
+/* If neither gettimeofday nor ftime is available, the code will use
+ times (if available) to measure a span of time. See also the
+ discussion of TIMES_TICK in policy.h. */
+#define HAVE_TIMES 1
+
+/* When a chat script requests a pause of less than a second with \p,
+ Taylor UUCP will try to use each of the following functions in
+ turn. If none are available, it will sleep for a full second.
+ Also, the (non-portable) tstuu program requires either select or
+ poll. */
+#define HAVE_NAPMS 0
+#define HAVE_NAP 0
+#define HAVE_USLEEP 1
+#define HAVE_POLL 0
+#define HAVE_SELECT 1
+
+/* If the getgrent function is available, it will be used to determine
+ all the groups a user belongs to when checking file access
+ permissions. */
+#define HAVE_GETGRENT 1
+
+/* If the socket function is available, TCP support code will be
+ compiled in. */
+#define HAVE_SOCKET 1
+
+/* If the t_open function is available, TLI support code will be
+ compiled in. This may require adding a library, such as -lnsl or
+ -lxti, to the Makefile variables LIBS. */
+#define HAVE_T_OPEN 0
+
+/* That's the end of the list of the functions. Now there are a few
+ last miscellaneous items. */
+
+/* On some systems the following functions are declared in such a way
+ that the code cannot make a simple extern. On other systems, these
+ functions are not declared at all, and the extern is required. If
+ a declaration of the function, as shown, compiles on your system,
+ set the value to 1. Not all functions declared externally are
+ listed here, only the ones with which I have had trouble. */
+/* extern long times (); */
+#define TIMES_DECLARATION_OK 0
+/* extern struct passwd *getpwnam (); */
+#define GETPWNAM_DECLARATION_OK 1
+/* extern struct passwd *getpwuid (); */
+#define GETPWUID_DECLARATION_OK 0
+/* extern struct group *getgrent (); */
+#define GETGRENT_DECLARATION_OK 1
+
+/* Set HAVE_BSD_PGRP to 1 if your getpgrp call takes 1 argument and
+ your setpgrp calls takes 2 arguments (on System V they generally
+ take no arguments). You can safely set this to 1 on System V,
+ provided the call will compile without any errors. */
+#define HAVE_BSD_PGRP 0
+
+/* Set HAVE_UNION_WAIT to 1 if union wait is defined in the header
+ file <sys/wait.h>. */
+#define HAVE_UNION_WAIT 1
+
+/* Set HAVE_LONG_FILE_NAMES to 1 if the system supports file names
+ longer than 14 characters. */
+#define HAVE_LONG_FILE_NAMES 1
+
+/* If slow system calls are restarted after interrupts, set
+ HAVE_RESTARTABLE_SYSCALLS to 1. This is ignored if HAVE_SIGACTION
+ is 1 or if HAVE_SIGVEC is 1 and HAVE_SIGVEC_SV_FLAGS is 1 and
+ SV_INTERRUPT is defined in <signal.h>. In both of these cases
+ system calls can be prevented from restarting. */
+#define HAVE_RESTARTABLE_SYSCALLS 1
+
+/* Some systems supposedly need the following macros to be defined.
+ These are handled by the configure script (it will turn #undef into
+ #define when appropriate, which is why the peculiar #ifndef #undef
+ construction is used). If you are configuring by hand, you may add
+ appropriate definitions here, or just add them to CFLAGS when
+ running make. */
+#ifndef _ALL_SOURCE
+#undef _ALL_SOURCE
+#endif
+#ifndef _POSIX_SOURCE
+#undef _POSIX_SOURCE
+#endif
+#ifndef _MINIX
+#undef _MINIX
+#endif
+#ifndef _POSIX_1_SOURCE
+#undef _POSIX_1_SOURCE
+#endif
diff --git a/gnu/libexec/uucp/common_sources/conn.c b/gnu/libexec/uucp/common_sources/conn.c
new file mode 100644
index 000000000000..8db53516a685
--- /dev/null
+++ b/gnu/libexec/uucp/common_sources/conn.c
@@ -0,0 +1,552 @@
+/* conn.c
+ Connection routines for the Taylor UUCP package.
+
+ Copyright (C) 1991, 1992 Ian Lance Taylor
+
+ This file is part of the Taylor UUCP package.
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ The author of the program may be contacted at ian@airs.com or
+ c/o Infinity Development Systems, P.O. Box 520, Waltham, MA 02254.
+ */
+
+#include "uucp.h"
+
+#if USE_RCS_ID
+const char conn_rcsid[] = "$Id: conn.c,v 1.1 1993/08/05 18:22:35 conklin Exp $";
+#endif
+
+#include <ctype.h>
+
+#include "uudefs.h"
+#include "uuconf.h"
+#include "conn.h"
+
+static boolean fcdo_dial P((struct sconnection *qconn, pointer puuconf,
+ struct uuconf_dialer *qdialer,
+ const char *zphone, boolean ftranslate));
+
+/* Create a new connection. This relies on system dependent functions
+ to set the qcmds and psysdep fields. If qport is NULL, it opens a
+ standard input port. */
+
+boolean
+fconn_init (qport, qconn)
+ struct uuconf_port *qport;
+ struct sconnection *qconn;
+{
+ qconn->qport = qport;
+ switch (qport == NULL ? UUCONF_PORTTYPE_STDIN : qport->uuconf_ttype)
+ {
+ case UUCONF_PORTTYPE_STDIN:
+ return fsysdep_stdin_init (qconn);
+ case UUCONF_PORTTYPE_MODEM:
+ return fsysdep_modem_init (qconn);
+ case UUCONF_PORTTYPE_DIRECT:
+ return fsysdep_direct_init (qconn);
+#if HAVE_TCP
+ case UUCONF_PORTTYPE_TCP:
+ return fsysdep_tcp_init (qconn);
+#endif
+#if HAVE_TLI
+ case UUCONF_PORTTYPE_TLI:
+ return fsysdep_tli_init (qconn);
+#endif
+ default:
+ ulog (LOG_ERROR, "Unknown port type");
+ return FALSE;
+ }
+}
+
+/* Connection dispatch routines. */
+
+/* Free a connection. */
+
+void
+uconn_free (qconn)
+ struct sconnection *qconn;
+{
+ (*qconn->qcmds->pufree) (qconn);
+}
+
+/* Lock a connection. */
+
+boolean
+fconn_lock (qconn, fin)
+ struct sconnection *qconn;
+ boolean fin;
+{
+ boolean (*pflock) P((struct sconnection *, boolean));
+
+ pflock = qconn->qcmds->pflock;
+ if (pflock == NULL)
+ return TRUE;
+ return (*pflock) (qconn, fin);
+}
+
+/* Unlock a connection. */
+
+boolean
+fconn_unlock (qconn)
+ struct sconnection *qconn;
+{
+ boolean (*pfunlock) P((struct sconnection *));
+
+ pfunlock = qconn->qcmds->pfunlock;
+ if (pfunlock == NULL)
+ return TRUE;
+ return (*pfunlock) (qconn);
+}
+
+/* Open a connection. */
+
+boolean
+fconn_open (qconn, ibaud, ihighbaud, fwait)
+ struct sconnection *qconn;
+ long ibaud;
+ long ihighbaud;
+ boolean fwait;
+{
+ boolean fret;
+
+#if DEBUG > 1
+ if (FDEBUGGING (DEBUG_PORT))
+ {
+ char abspeed[20];
+
+ if (ibaud == (long) 0)
+ strcpy (abspeed, "default speed");
+ else
+ sprintf (abspeed, "speed %ld", ibaud);
+
+ if (qconn->qport == NULL)
+ ulog (LOG_DEBUG, "fconn_open: Opening stdin port (%s)",
+ abspeed);
+ else if (qconn->qport->uuconf_zname == NULL)
+ ulog (LOG_DEBUG, "fconn_open: Opening unnamed port (%s)",
+ abspeed);
+ else
+ ulog (LOG_DEBUG, "fconn_open: Opening port %s (%s)",
+ qconn->qport->uuconf_zname, abspeed);
+ }
+#endif
+
+ /* If the system provides a range of baud rates, we select the
+ highest baud rate supported by the port. */
+ if (ihighbaud != 0 && qconn->qport != NULL)
+ {
+ struct uuconf_port *qport;
+
+ qport = qconn->qport;
+ ibaud = ihighbaud;
+ if (qport->uuconf_ttype == UUCONF_PORTTYPE_MODEM)
+ {
+ if (qport->uuconf_u.uuconf_smodem.uuconf_ilowbaud != 0)
+ {
+ if (qport->uuconf_u.uuconf_smodem.uuconf_ihighbaud < ibaud)
+ ibaud = qport->uuconf_u.uuconf_smodem.uuconf_ihighbaud;
+ }
+ else if (qport->uuconf_u.uuconf_smodem.uuconf_ibaud != 0)
+ ibaud = qport->uuconf_u.uuconf_smodem.uuconf_ibaud;
+ }
+ else if (qport->uuconf_ttype == UUCONF_PORTTYPE_DIRECT)
+ {
+ if (qport->uuconf_u.uuconf_sdirect.uuconf_ibaud != 0)
+ ibaud = qport->uuconf_u.uuconf_sdirect.uuconf_ibaud;
+ }
+ }
+
+ /* This will normally be overridden by the port specific open
+ routine. */
+ if (qconn->qport == NULL)
+ ulog_device ("stdin");
+ else
+ ulog_device (qconn->qport->uuconf_zname);
+
+ fret = (*qconn->qcmds->pfopen) (qconn, ibaud, fwait);
+
+ if (! fret)
+ ulog_device ((const char *) NULL);
+
+ return fret;
+}
+
+/* Close a connection. */
+
+boolean
+fconn_close (qconn, puuconf, qdialer, fsuccess)
+ struct sconnection *qconn;
+ pointer puuconf;
+ struct uuconf_dialer *qdialer;
+ boolean fsuccess;
+{
+ boolean fret;
+
+ DEBUG_MESSAGE0 (DEBUG_PORT, "fconn_close: Closing connection");
+
+ /* Don't report hangup signals while we're closing. */
+ fLog_sighup = FALSE;
+
+ fret = (*qconn->qcmds->pfclose) (qconn, puuconf, qdialer, fsuccess);
+
+ /* Make sure any signal reporting has been done before we set
+ fLog_sighup back to TRUE. */
+ ulog (LOG_ERROR, (const char *) NULL);
+ fLog_sighup = TRUE;
+
+ ulog_device ((const char *) NULL);
+
+ return fret;
+}
+
+/* Reset the connection. */
+
+boolean
+fconn_reset (qconn)
+ struct sconnection *qconn;
+{
+ DEBUG_MESSAGE0 (DEBUG_PORT, "fconn_reset: Resetting connection");
+
+ return (*qconn->qcmds->pfreset) (qconn);
+}
+
+/* Dial out on the connection. */
+
+boolean
+fconn_dial (qconn, puuconf, qsys, zphone, qdialer, ptdialerfound)
+ struct sconnection *qconn;
+ pointer puuconf;
+ const struct uuconf_system *qsys;
+ const char *zphone;
+ struct uuconf_dialer *qdialer;
+ enum tdialerfound *ptdialerfound;
+{
+ struct uuconf_dialer sdialer;
+ enum tdialerfound tfound;
+ boolean (*pfdial) P((struct sconnection *, pointer,
+ const struct uuconf_system *, const char *,
+ struct uuconf_dialer *, enum tdialerfound *));
+
+ if (qdialer == NULL)
+ qdialer = &sdialer;
+ if (ptdialerfound == NULL)
+ ptdialerfound = &tfound;
+
+ qdialer->uuconf_zname = NULL;
+ *ptdialerfound = DIALERFOUND_FALSE;
+
+ pfdial = qconn->qcmds->pfdial;
+ if (pfdial == NULL)
+ return TRUE;
+ return (*pfdial) (qconn, puuconf, qsys, zphone, qdialer, ptdialerfound);
+}
+
+/* Read data from the connection. */
+
+boolean
+fconn_read (qconn, zbuf, pclen, cmin, ctimeout, freport)
+ struct sconnection *qconn;
+ char *zbuf;
+ size_t *pclen;
+ size_t cmin;
+ int ctimeout;
+ boolean freport;
+{
+ boolean fret;
+
+ fret = (*qconn->qcmds->pfread) (qconn, zbuf, pclen, cmin, ctimeout,
+ freport);
+
+#if DEBUG > 1
+ if (FDEBUGGING (DEBUG_INCOMING))
+ udebug_buffer ("fconn_read: Read", zbuf, *pclen);
+ else if (FDEBUGGING (DEBUG_PORT))
+ ulog (LOG_DEBUG, "fconn_read: Read %lu", (unsigned long) *pclen);
+#endif
+
+ return fret;
+}
+
+/* Write data to the connection. */
+
+boolean
+fconn_write (qconn, zbuf, clen)
+ struct sconnection *qconn;
+ const char *zbuf;
+ size_t clen;
+{
+#if DEBUG > 1
+ if (FDEBUGGING (DEBUG_OUTGOING))
+ udebug_buffer ("fconn_write: Writing", zbuf, clen);
+ else if (FDEBUGGING (DEBUG_PORT))
+ ulog (LOG_DEBUG, "fconn_write: Writing %lu", (unsigned long) clen);
+#endif
+
+ return (*qconn->qcmds->pfwrite) (qconn, zbuf, clen);
+}
+
+/* Read and write data. */
+
+boolean
+fconn_io (qconn, zwrite, pcwrite, zread, pcread)
+ struct sconnection *qconn;
+ const char *zwrite;
+ size_t *pcwrite;
+ char *zread;
+ size_t *pcread;
+{
+ boolean fret;
+#if DEBUG > 1
+ size_t cwrite = *pcwrite;
+ size_t cread = *pcread;
+
+ if (cread == 0 || cwrite == 0)
+ ulog (LOG_FATAL, "fconn_io: cread %lu; cwrite %lu",
+ (unsigned long) cread, (unsigned long) cwrite);
+#endif
+
+#if DEBUG > 1
+ if (FDEBUGGING (DEBUG_OUTGOING))
+ udebug_buffer ("fconn_io: Writing", zwrite, cwrite);
+#endif
+
+ fret = (*qconn->qcmds->pfio) (qconn, zwrite, pcwrite, zread, pcread);
+
+ DEBUG_MESSAGE4 (DEBUG_PORT,
+ "fconn_io: Wrote %lu of %lu, read %lu of %lu",
+ (unsigned long) *pcwrite, (unsigned long) cwrite,
+ (unsigned long) *pcread, (unsigned long) cread);
+
+#if DEBUG > 1
+ if (*pcread > 0 && FDEBUGGING (DEBUG_INCOMING))
+ udebug_buffer ("fconn_io: Read", zread, *pcread);
+#endif
+
+ return fret;
+}
+
+/* Send a break character to a connection. Some port types may not
+ support break characters, in which case we just return TRUE. */
+
+boolean
+fconn_break (qconn)
+ struct sconnection *qconn;
+{
+ boolean (*pfbreak) P((struct sconnection *));
+
+ pfbreak = *qconn->qcmds->pfbreak;
+ if (pfbreak == NULL)
+ return TRUE;
+
+ DEBUG_MESSAGE0 (DEBUG_PORT, "fconn_break: Sending break character");
+
+ return (*pfbreak) (qconn);
+}
+
+/* Change the setting of a connection. Some port types may not
+ support this, in which case we just return TRUE. */
+
+boolean
+fconn_set (qconn, tparity, tstrip, txonxoff)
+ struct sconnection *qconn;
+ enum tparitysetting tparity;
+ enum tstripsetting tstrip;
+ enum txonxoffsetting txonxoff;
+{
+ boolean (*pfset) P((struct sconnection *, enum tparitysetting,
+ enum tstripsetting, enum txonxoffsetting));
+
+ pfset = qconn->qcmds->pfset;
+ if (pfset == NULL)
+ return TRUE;
+
+ DEBUG_MESSAGE3 (DEBUG_PORT,
+ "fconn_set: Changing setting to %d, %d, %d",
+ (int) tparity, (int) tstrip, (int) txonxoff);
+
+ return (*pfset) (qconn, tparity, tstrip, txonxoff);
+}
+
+/* Require or ignore carrier on a connection. */
+
+boolean
+fconn_carrier (qconn, fcarrier)
+ struct sconnection *qconn;
+ boolean fcarrier;
+{
+ boolean (*pfcarrier) P((struct sconnection *, boolean));
+
+ pfcarrier = qconn->qcmds->pfcarrier;
+ if (pfcarrier == NULL)
+ return TRUE;
+ return (*pfcarrier) (qconn, fcarrier);
+}
+
+/* Run a chat program on a connection. */
+
+boolean
+fconn_run_chat (qconn, pzprog)
+ struct sconnection *qconn;
+ char **pzprog;
+{
+ return (*qconn->qcmds->pfchat) (qconn, pzprog);
+}
+
+/* Get the baud rate of a connection. */
+
+long
+iconn_baud (qconn)
+ struct sconnection *qconn;
+{
+ long (*pibaud) P((struct sconnection *));
+
+ pibaud = qconn->qcmds->pibaud;
+ if (pibaud == NULL)
+ return 0;
+ return (*pibaud) (qconn);
+}
+
+/* Modem dialing routines. */
+
+/*ARGSUSED*/
+boolean
+fmodem_dial (qconn, puuconf, qsys, zphone, qdialer, ptdialerfound)
+ struct sconnection *qconn;
+ pointer puuconf;
+ const struct uuconf_system *qsys;
+ const char *zphone;
+ struct uuconf_dialer *qdialer;
+ enum tdialerfound *ptdialerfound;
+{
+ *ptdialerfound = DIALERFOUND_FALSE;
+
+ if (qconn->qport->uuconf_u.uuconf_smodem.uuconf_pzdialer != NULL)
+ {
+ char **pz;
+ boolean ffirst;
+
+ /* The pzdialer field is a sequence of dialer/token pairs. The
+ dialer portion names a dialer to use. The token portion is
+ what \D and \T in the chat script expand to. If there is no
+ token for the last dialer, the phone number for the system is
+ used. */
+ ffirst = TRUE;
+ pz = qconn->qport->uuconf_u.uuconf_smodem.uuconf_pzdialer;
+ while (*pz != NULL)
+ {
+ int iuuconf;
+ struct uuconf_dialer *q;
+ struct uuconf_dialer s;
+ const char *ztoken;
+ boolean ftranslate;
+
+ if (! ffirst)
+ q = &s;
+ else
+ q = qdialer;
+
+ iuuconf = uuconf_dialer_info (puuconf, *pz, q);
+ if (iuuconf == UUCONF_NOT_FOUND)
+ {
+ ulog (LOG_ERROR, "%s: Dialer not found", *pz);
+ return FALSE;
+ }
+ else if (iuuconf != UUCONF_SUCCESS)
+ {
+ ulog_uuconf (LOG_ERROR, puuconf, iuuconf);
+ return FALSE;
+ }
+
+ ++pz;
+ ztoken = *pz;
+
+ ftranslate = FALSE;
+ if (ztoken == NULL
+ || strcmp (ztoken, "\\D") == 0)
+ ztoken = zphone;
+ else if (strcmp (ztoken, "\\T") == 0)
+ {
+ ztoken = zphone;
+ ftranslate = TRUE;
+ }
+
+ if (! fcdo_dial (qconn, puuconf, q, ztoken, ftranslate))
+ {
+ (void) uuconf_dialer_free (puuconf, q);
+ if (! ffirst)
+ (void) uuconf_dialer_free (puuconf, qdialer);
+ return FALSE;
+ }
+
+ if (ffirst)
+ {
+ *ptdialerfound = DIALERFOUND_FREE;
+ ffirst = FALSE;
+ }
+ else
+ (void) uuconf_dialer_free (puuconf, q);
+
+ if (*pz != NULL)
+ ++pz;
+ }
+
+ return TRUE;
+ }
+ else if (qconn->qport->uuconf_u.uuconf_smodem.uuconf_qdialer != NULL)
+ {
+ struct uuconf_dialer *q;
+
+ q = qconn->qport->uuconf_u.uuconf_smodem.uuconf_qdialer;
+ *qdialer = *q;
+ *ptdialerfound = DIALERFOUND_TRUE;
+ return fcdo_dial (qconn, puuconf, q, zphone, FALSE);
+ }
+ else
+ {
+ ulog (LOG_ERROR, "No dialer information");
+ return FALSE;
+ }
+}
+
+/* Actually use a dialer. We set up the modem (which may include
+ opening the dialer device), run the chat script, and finish dealing
+ with the modem. */
+
+static boolean
+fcdo_dial (qconn, puuconf, qdial, zphone, ftranslate)
+ struct sconnection *qconn;
+ pointer puuconf;
+ struct uuconf_dialer *qdial;
+ const char *zphone;
+ boolean ftranslate;
+{
+ const char *zname;
+
+ if (! fsysdep_modem_begin_dial (qconn, qdial))
+ return FALSE;
+
+ if (qconn->qport == NULL)
+ zname = NULL;
+ else
+ zname = qconn->qport->uuconf_zname;
+
+ if (! fchat (qconn, puuconf, &qdial->uuconf_schat,
+ (const struct uuconf_system *) NULL, qdial,
+ zphone, ftranslate, zname, iconn_baud (qconn)))
+ return FALSE;
+
+ return fsysdep_modem_end_dial (qconn, qdial);
+}
diff --git a/gnu/libexec/uucp/common_sources/conn.h b/gnu/libexec/uucp/common_sources/conn.h
new file mode 100644
index 000000000000..59d4881b07ff
--- /dev/null
+++ b/gnu/libexec/uucp/common_sources/conn.h
@@ -0,0 +1,312 @@
+/* conn.h
+ Header file for routines which manipulate connections.
+
+ Copyright (C) 1991, 1992 Ian Lance Taylor
+
+ This file is part of the Taylor UUCP package.
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ The author of the program may be contacted at ian@airs.com or
+ c/o Infinity Development Systems, P.O. Box 520, Waltham, MA 02254.
+ */
+
+#ifndef CONN_H
+
+#define CONN_H
+
+#if ANSI_C
+/* These structures are used in prototypes but are not defined in this
+ header file. */
+struct uuconf_system;
+struct uuconf_dialer;
+struct uuconf_chat;
+#endif
+
+/* This structure represents a connection. */
+
+struct sconnection
+{
+ /* Pointer to command table for this type of connection. */
+ const struct sconncmds *qcmds;
+ /* Pointer to system dependent information. */
+ pointer psysdep;
+ /* Pointer to system independent information. */
+ struct uuconf_port *qport;
+};
+
+/* Whether fconn_dial got a dialer. */
+
+enum tdialerfound
+{
+ /* Did not find a dialer. */
+ DIALERFOUND_FALSE,
+ /* Found a dialer which does not need to be freed. */
+ DIALERFOUND_TRUE,
+ /* Found a dialer which does need to be freed. */
+ DIALERFOUND_FREE
+};
+
+/* Parity settings to pass to fconn_set. */
+
+enum tparitysetting
+{
+ /* Do not change output parity generation. */
+ PARITYSETTING_DEFAULT,
+ /* No parity (all eight output bits used). */
+ PARITYSETTING_NONE,
+ /* Even parity. */
+ PARITYSETTING_EVEN,
+ /* Odd parity. */
+ PARITYSETTING_ODD,
+ /* Mark parity. */
+ PARITYSETTING_MARK,
+ /* Space parity. */
+ PARITYSETTING_SPACE
+};
+
+/* Type of strip control argument to fconn_set. */
+
+enum tstripsetting
+{
+ /* Do not change the stripping of input characters. */
+ STRIPSETTING_DEFAULT,
+ /* Do not strip input characters to seven bits. */
+ STRIPSETTING_EIGHTBITS,
+ /* Strip input characters to seven bits. */
+ STRIPSETTING_SEVENBITS
+};
+
+/* Type of XON/XOFF control argument to fconn_set. */
+
+enum txonxoffsetting
+{
+ /* Do not change XON/XOFF handshake setting. */
+ XONXOFF_DEFAULT,
+ /* Do not do XON/XOFF handshaking. */
+ XONXOFF_OFF,
+ /* Do XON/XOFF handshaking. */
+ XONXOFF_ON
+};
+
+/* A command table holds the functions which implement actions for
+ each different kind of connection. */
+
+struct sconncmds
+{
+ /* Free up a connection. */
+ void (*pufree) P((struct sconnection *qconn));
+ /* Lock the connection. The fin argument is TRUE if the connection
+ is to be used for an incoming call. May be NULL. */
+ boolean (*pflock) P((struct sconnection *qconn, boolean fin));
+ /* Unlock the connection. May be NULL. */
+ boolean (*pfunlock) P((struct sconnection *qconn));
+ /* Open the connection. */
+ boolean (*pfopen) P((struct sconnection *qconn, long ibaud,
+ boolean fwait));
+ /* Close the connection. */
+ boolean (*pfclose) P((struct sconnection *qconn,
+ pointer puuconf,
+ struct uuconf_dialer *qdialer,
+ boolean fsuccess));
+ /* Reset the connection so that another call may be accepted. */
+ boolean (*pfreset) P((struct sconnection *qconn));
+ /* Dial a number on a connection. This set *qdialer to the dialer
+ used, if any, and sets *ptdialerfound appropriately. The qsys
+ and zphone arguments are for the chat script. This field may be
+ NULL. */
+ boolean (*pfdial) P((struct sconnection *qconn, pointer puuconf,
+ const struct uuconf_system *qsys,
+ const char *zphone,
+ struct uuconf_dialer *qdialer,
+ enum tdialerfound *ptdialerfound));
+ /* Read data from a connection, with a timeout in seconds. When
+ called *pclen is the length of the buffer; on successful return
+ *pclen is the number of bytes read into the buffer. The cmin
+ argument is the minimum number of bytes to read before returning
+ ahead of a timeout. */
+ boolean (*pfread) P((struct sconnection *qconn, char *zbuf, size_t *pclen,
+ size_t cmin, int ctimeout, boolean freport));
+ /* Write data to the connection. */
+ boolean (*pfwrite) P((struct sconnection *qconn, const char *zbuf,
+ size_t clen));
+ /* Read and write data to the connection. This reads and writes
+ data until either all passed in data has been written or the read
+ buffer has been filled. When called *pcread is the size of the
+ read buffer and *pcwrite is the number of bytes to write; on
+ successful return *pcread is the number of bytes read and
+ *pcwrite is the number of bytes written. */
+ boolean (*pfio) P((struct sconnection *qconn, const char *zwrite,
+ size_t *pcwrite, char *zread, size_t *pcread));
+ /* Send a break character. This field may be NULL. */
+ boolean (*pfbreak) P((struct sconnection *qconn));
+ /* Change the connection setting. This field may be NULL. */
+ boolean (*pfset) P((struct sconnection *qconn,
+ enum tparitysetting tparity,
+ enum tstripsetting tstrip,
+ enum txonxoffsetting txonxoff));
+ /* Require or ignore carrer. This field may be NULL. */
+ boolean (*pfcarrier) P((struct sconnection *qconn,
+ boolean fcarrier));
+ /* Run a chat program on a connection. */
+ boolean (*pfchat) P((struct sconnection *qconn, char **pzprog));
+ /* Get the baud rate of a connection. This field may be NULL. */
+ long (*pibaud) P((struct sconnection *qconn));
+};
+
+/* Connection functions. */
+
+/* Initialize a connection. This must be called before any of the
+ other connection functions are called. It initializes the fields
+ of qconn. It returns FALSE on error. */
+extern boolean fconn_init P((struct uuconf_port *qport,
+ struct sconnection *qconn));
+
+/* Free up connection data. */
+extern void uconn_free P((struct sconnection *qconn));
+
+/* Lock a connection. The fin argument is TRUE if the port is to be
+ used for an incoming call; certains type of Unix locking need this
+ information because they need to open the port. */
+extern boolean fconn_lock P((struct sconnection *qconn, boolean fin));
+
+/* Unlock a connection. */
+extern boolean fconn_unlock P((struct sconnection *qconn));
+
+/* Open a connection. If ibaud is 0, the natural baud rate of the
+ port is used. If ihighbaud is not 0, fconn_open chooses the
+ highest supported baud rate between ibaud and ihighbaud. If fwait
+ is TRUE, this should wait for an incoming call. */
+extern boolean fconn_open P((struct sconnection *qconn, long ibaud,
+ long ihighbaud, boolean fwait));
+
+/* Close a connection. The fsuccess argument is TRUE if the
+ conversation completed normally, FALSE if it is being aborted. */
+extern boolean fconn_close P((struct sconnection *qconn,
+ pointer puuconf,
+ struct uuconf_dialer *qdialer,
+ boolean fsuccess));
+
+/* Reset a connection such that another call may be accepted. */
+extern boolean fconn_reset P((struct sconnection *q));
+
+/* Dial out on a connection. The qsys and zphone arguments are for
+ the chat scripts; zphone is the phone number to dial. If qdialer
+ is not NULL, *qdialer will be set to the dialer information used if
+ any; *ptdialerfound will be set appropriately. */
+extern boolean fconn_dial P((struct sconnection *q, pointer puuconf,
+ const struct uuconf_system *qsys,
+ const char *zphone,
+ struct uuconf_dialer *qdialer,
+ enum tdialerfound *ptdialerfound));
+
+/* Read from a connection.
+ zbuf -- buffer to read bytes into
+ *pclen on call -- length of zbuf
+ *pclen on successful return -- number of bytes read
+ cmin -- minimum number of bytes to read before returning ahead of timeout
+ ctimeout -- timeout in seconds, 0 if none
+ freport -- whether to report errors. */
+extern boolean fconn_read P((struct sconnection *qconn, char *zbuf,
+ size_t *pclen, size_t cmin,
+ int ctimeout, boolean freport));
+
+/* Write to a connection. */
+extern boolean fconn_write P((struct sconnection *qconn, const char *zbuf,
+ size_t cbytes));
+
+/* Read and write to a connection. This reads and writes data until
+ either all passed-in data has been written or the read buffer is
+ full.
+ zwrite -- buffer to write bytes from
+ *pcwrite on call -- number of bytes to write
+ *pcwrite on successful return -- number of bytes written
+ zread -- buffer to read bytes into
+ *pcread on call -- size of read buffer
+ *pcread on successful return -- number of bytes read. */
+extern boolean fconn_io P((struct sconnection *qconn, const char *zwrite,
+ size_t *pcwrite, char *zread, size_t *pcread));
+
+/* Send a break character to a connection. */
+extern boolean fconn_break P((struct sconnection *qconn));
+
+/* Change the settings of a connection. This allows independent
+ control over the parity of output characters, whether to strip
+ input characters, and whether to do XON/XOFF handshaking. There is
+ no explicit control over parity checking of input characters. This
+ function returns FALSE on error. Attempts to set values not
+ supported by the hardware are silently ignored. */
+extern boolean fconn_set P((struct sconnection *qconn,
+ enum tparitysetting tparity,
+ enum tstripsetting tstrip,
+ enum txonxoffsetting txonxoff));
+
+/* Get the baud rate of a connection. */
+extern long iconn_baud P((struct sconnection *qconn));
+
+/* Do a chat script with a system. */
+extern boolean fchat P((struct sconnection *qconn, pointer puuconf,
+ const struct uuconf_chat *qchat,
+ const struct uuconf_system *qsys,
+ const struct uuconf_dialer *qdialer,
+ const char *zphone, boolean ftranslate,
+ const char *zport, long ibaud));
+
+/* Tell the connection to either require or ignore carrier as fcarrier
+ is TRUE or FALSE respectively. This is called with fcarrier TRUE
+ when \m is encountered in a chat script, and with fcarrier FALSE
+ when \M is encountered. */
+extern boolean fconn_carrier P((struct sconnection *qconn,
+ boolean fcarrier));
+
+/* Run a chat program on a connection. */
+extern boolean fconn_run_chat P((struct sconnection *qconn,
+ char **pzprog));
+
+/* Dialing out on a modem is partially system independent. This is
+ the modem dialing routine. */
+extern boolean fmodem_dial P((struct sconnection *qconn, pointer puuconf,
+ const struct uuconf_system *qsys,
+ const char *zphone,
+ struct uuconf_dialer *qdialer,
+ enum tdialerfound *ptdialerfound));
+
+/* Begin dialing out. This should open the dialer device if there is
+ one, toggle DTR if requested and possible, and tell the port to
+ ignore carrier. It should return FALSE on error. */
+extern boolean fsysdep_modem_begin_dial P((struct sconnection *qconn,
+ struct uuconf_dialer *qdial));
+
+/* Finish dialing out on a modem. This should close the dialer device
+ if there is one. If the dialer and the port both support carrier,
+ the connection should be told to pay attention to carrier. If it
+ is possible to wait for carrier to come on, and the dialer and the
+ port both the port support carrier, it should wait until carrier
+ comes on. */
+extern boolean fsysdep_modem_end_dial P((struct sconnection *qconn,
+ struct uuconf_dialer *qdial));
+
+/* System dependent initialization routines. */
+extern boolean fsysdep_stdin_init P((struct sconnection *qconn));
+extern boolean fsysdep_modem_init P((struct sconnection *qconn));
+extern boolean fsysdep_direct_init P((struct sconnection *qconn));
+#if HAVE_TCP
+extern boolean fsysdep_tcp_init P((struct sconnection *qconn));
+#endif
+#if HAVE_TLI
+extern boolean fsysdep_tli_init P((struct sconnection *qconn));
+#endif
+
+#endif /* ! defined (CONN_H) */
diff --git a/gnu/libexec/uucp/common_sources/copy.c b/gnu/libexec/uucp/common_sources/copy.c
new file mode 100644
index 000000000000..0d1a5bb2c270
--- /dev/null
+++ b/gnu/libexec/uucp/common_sources/copy.c
@@ -0,0 +1,202 @@
+/* copy.c
+ Copy one file to another for the UUCP package.
+
+ Copyright (C) 1991, 1992 Ian Lance Taylor
+
+ This file is part of the Taylor UUCP package.
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ The author of the program may be contacted at ian@airs.com or
+ c/o Infinity Development Systems, P.O. Box 520, Waltham, MA 02254.
+ */
+
+#include "uucp.h"
+
+#if USE_RCS_ID
+const char copy_rcsid[] = "$Id: copy.c,v 1.1 1993/08/05 18:22:37 conklin Exp $";
+#endif
+
+#include "uudefs.h"
+#include "system.h"
+#include "sysdep.h"
+
+#include <stdio.h>
+#include <errno.h>
+
+/* Copy one file to another. */
+
+#if USE_STDIO
+
+boolean
+fcopy_file (zfrom, zto, fpublic, fmkdirs)
+ const char *zfrom;
+ const char *zto;
+ boolean fpublic;
+ boolean fmkdirs;
+{
+ FILE *efrom;
+ boolean fret;
+
+ efrom = fopen (zfrom, BINREAD);
+ if (efrom == NULL)
+ {
+ ulog (LOG_ERROR, "fopen (%s): %s", zfrom, strerror (errno));
+ return FALSE;
+ }
+
+ fret = fcopy_open_file (efrom, zto, fpublic, fmkdirs);
+ (void) fclose (efrom);
+ return fret;
+}
+
+boolean
+fcopy_open_file (efrom, zto, fpublic, fmkdirs)
+ FILE *efrom;
+ const char *zto;
+ boolean fpublic;
+ boolean fmkdirs;
+{
+ FILE *eto;
+ char ab[8192];
+ int c;
+
+ eto = esysdep_fopen (zto, fpublic, FALSE, fmkdirs);
+ if (eto == NULL)
+ return FALSE;
+
+ while ((c = fread (ab, sizeof (char), sizeof ab, efrom)) != 0)
+ {
+ if (fwrite (ab, sizeof (char), (size_t) c, eto) != c)
+ {
+ ulog (LOG_ERROR, "fwrite: %s", strerror (errno));
+ (void) fclose (eto);
+ (void) remove (zto);
+ return FALSE;
+ }
+ }
+
+ if (fclose (eto) != 0)
+ {
+ ulog (LOG_ERROR, "fclose: %s", strerror (errno));
+ (void) remove (zto);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+#else /* ! USE_STDIO */
+
+#if HAVE_FCNTL_H
+#include <fcntl.h>
+#else
+#if HAVE_SYS_FILE_H
+#include <sys/file.h>
+#endif
+#endif
+
+#ifndef O_RDONLY
+#define O_RDONLY 0
+#define O_WRONLY 1
+#define O_RDWR 2
+#endif
+
+#ifndef O_NOCTTY
+#define O_NOCTTY 0
+#endif
+
+boolean
+fcopy_file (zfrom, zto, fpublic, fmkdirs)
+ const char *zfrom;
+ const char *zto;
+ boolean fpublic;
+ boolean fmkdirs;
+{
+ int ofrom;
+ boolean fret;
+
+ ofrom = open (zfrom, O_RDONLY | O_NOCTTY, 0);
+ if (ofrom < 0)
+ {
+ ulog (LOG_ERROR, "open (%s): %s", zfrom, strerror (errno));
+ return FALSE;
+ }
+
+ fret = fcopy_open_file (ofrom, zto, fpublic, fmkdirs);
+ (void) close (ofrom);
+ return fret;
+}
+
+boolean
+fcopy_open_file (ofrom, zto, fpublic, fmkdirs)
+ int ofrom;
+ const char *zto;
+ boolean fpublic;
+ boolean fmkdirs;
+{
+ int oto;
+ char ab[8192];
+ int c;
+
+ /* These file mode arguments are from the UNIX version of sysdep.h;
+ each system dependent header file will need their own
+ definitions. */
+ oto = creat (zto, fpublic ? IPUBLIC_FILE_MODE : IPRIVATE_FILE_MODE);
+ if (oto < 0)
+ {
+ if (errno == ENOENT && fmkdirs)
+ {
+ if (! fsysdep_make_dirs (zto, fpublic))
+ return FALSE;
+ oto = creat (zto,
+ fpublic ? IPUBLIC_FILE_MODE : IPRIVATE_FILE_MODE);
+ }
+ if (oto < 0)
+ {
+ ulog (LOG_ERROR, "open (%s): %s", zto, strerror (errno));
+ return FALSE;
+ }
+ }
+
+ while ((c = read (ofrom, ab, sizeof ab)) > 0)
+ {
+ if (write (oto, ab, (size_t) c) != c)
+ {
+ ulog (LOG_ERROR, "write: %s", strerror (errno));
+ (void) close (oto);
+ (void) remove (zto);
+ return FALSE;
+ }
+ }
+
+ if (close (oto) < 0)
+ {
+ ulog (LOG_ERROR, "close: %s", strerror (errno));
+ (void) remove (zto);
+ return FALSE;
+ }
+
+ if (c < 0)
+ {
+ ulog (LOG_ERROR, "read: %s", strerror (errno));
+ (void) remove (zto);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+#endif /* ! USE_STDIO */
diff --git a/gnu/libexec/uucp/common_sources/cu.h b/gnu/libexec/uucp/common_sources/cu.h
new file mode 100644
index 000000000000..5a514ee3bfe7
--- /dev/null
+++ b/gnu/libexec/uucp/common_sources/cu.h
@@ -0,0 +1,80 @@
+/* cu.h
+ Header file for cu.
+
+ Copyright (C) 1992 Ian Lance Taylor
+
+ This file is part of the Taylor UUCP package.
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ The author of the program may be contacted at ian@airs.com or
+ c/o Infinity Development Systems, P.O. Box 520, Waltham, MA 02254.
+ */
+
+/* The user settable variables supported by cu. */
+
+/* The escape character used to introduce a special command. The
+ escape character is the first character of this string. */
+extern const char *zCuvar_escape;
+
+/* Whether to delay for a second before printing the host name after
+ seeing an escape character. */
+extern boolean fCuvar_delay;
+
+/* The input characters which finish a line. The escape character is
+ only recognized following one of these characters. */
+extern const char *zCuvar_eol;
+
+/* Whether to transfer binary data (nonprintable characters other than
+ newline and tab) when sending a file. If this is FALSE, then
+ newline is changed to carriage return. */
+extern boolean fCuvar_binary;
+
+/* A prefix string to use before sending a binary character from a
+ file; this is only used if fCuvar_binary is TRUE. */
+extern const char *zCuvar_binary_prefix;
+
+/* Whether to check for echoes of characters sent when sending a file.
+ This is ignored if fCuvar_binary is TRUE. */
+extern boolean fCuvar_echocheck;
+
+/* A character to look for after each newline is sent when sending a
+ file. The character is the first character in this string, except
+ that a '\0' means that no echo check is done. */
+extern const char *zCuvar_echonl;
+
+/* The timeout to use when looking for an character. */
+extern int cCuvar_timeout;
+
+/* The character to use to kill a line if an echo check fails. The
+ first character in this string is sent. */
+extern const char *zCuvar_kill;
+
+/* The number of times to try resending a line if the echo check keeps
+ failing. */
+extern int cCuvar_resend;
+
+/* The string to send at the end of a file sent with ~>. */
+extern const char *zCuvar_eofwrite;
+
+/* The string to look for to finish a file received with ~<. For tip
+ this is a collection of single characters, but I don't want to do
+ that because it means that there are characters which cannot be
+ received. */
+extern const char *zCuvar_eofread;
+
+/* Whether to provide verbose information when sending or receiving a
+ file. */
+extern boolean fCuvar_verbose;
diff --git a/gnu/libexec/uucp/common_sources/getopt.h b/gnu/libexec/uucp/common_sources/getopt.h
new file mode 100644
index 000000000000..1a70e027714e
--- /dev/null
+++ b/gnu/libexec/uucp/common_sources/getopt.h
@@ -0,0 +1,120 @@
+/* Declarations for getopt.
+ Copyright (C) 1989, 1990, 1991, 1992 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by the
+ Free Software Foundation; either version 2, or (at your option) any
+ later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ This file was modified slightly by Ian Lance Taylor, November 1992,
+ for Taylor UUCP. */
+
+#ifndef _GETOPT_H
+#define _GETOPT_H 1
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Ian Lance Taylor <ian@airs.com> added the following defines for
+ Taylor UUCP. This avoids reported conflicts with system getopt
+ definitions. */
+#define getopt gnu_getopt
+#define optarg gnu_optarg
+#define optind gnu_optind
+#define opterr gnu_opterr
+
+/* For communication from `getopt' to the caller.
+ When `getopt' finds an option that takes an argument,
+ the argument value is returned here.
+ Also, when `ordering' is RETURN_IN_ORDER,
+ each non-option ARGV-element is returned here. */
+
+extern char *optarg;
+
+/* Index in ARGV of the next element to be scanned.
+ This is used for communication to and from the caller
+ and for communication between successive calls to `getopt'.
+
+ On entry to `getopt', zero means this is the first call; initialize.
+
+ When `getopt' returns EOF, this is the index of the first of the
+ non-option elements that the caller should itself scan.
+
+ Otherwise, `optind' communicates from one call to the next
+ how much of ARGV has been scanned so far. */
+
+extern int optind;
+
+/* Callers store zero here to inhibit the error message `getopt' prints
+ for unrecognized options. */
+
+extern int opterr;
+
+/* Describe the long-named options requested by the application.
+ The LONG_OPTIONS argument to getopt_long or getopt_long_only is a vector
+ of `struct option' terminated by an element containing a name which is
+ zero.
+
+ The field `has_arg' is:
+ no_argument (or 0) if the option does not take an argument,
+ required_argument (or 1) if the option requires an argument,
+ optional_argument (or 2) if the option takes an optional argument.
+
+ If the field `flag' is not NULL, it points to a variable that is set
+ to the value given in the field `val' when the option is found, but
+ left unchanged if the option is not found.
+
+ To have a long-named option do something other than set an `int' to
+ a compiled-in constant, such as set a value from `optarg', set the
+ option's `flag' field to zero and its `val' field to a nonzero
+ value (the equivalent single-letter option character, if there is
+ one). For long options that have a zero `flag' field, `getopt'
+ returns the contents of the `val' field. */
+
+struct option
+{
+ const char *name;
+ /* has_arg can't be an enum because some compilers complain about
+ type mismatches in all the code that assumes it is an int. */
+ int has_arg;
+ int *flag;
+ int val;
+};
+
+/* Names for the values of the `has_arg' field of `struct option'. */
+
+enum _argtype
+{
+ no_argument,
+ required_argument,
+ optional_argument
+};
+
+extern int getopt P((int argc, char *const *argv, const char *shortopts));
+extern int getopt_long P((int argc, char *const *argv, const char *shortopts,
+ const struct option *longopts, int *longind));
+extern int getopt_long_only P((int argc, char *const *argv,
+ const char *shortopts,
+ const struct option *longopts, int *longind));
+
+/* Internal only. Users should not call this directly. */
+extern int _getopt_internal P((int argc, char *const *argv,
+ const char *shortopts,
+ const struct option *longopts, int *longind,
+ int long_only));
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _GETOPT_H */
diff --git a/gnu/libexec/uucp/common_sources/log.c b/gnu/libexec/uucp/common_sources/log.c
new file mode 100644
index 000000000000..9528baf5ca39
--- /dev/null
+++ b/gnu/libexec/uucp/common_sources/log.c
@@ -0,0 +1,699 @@
+/* log.c
+ Routines to add entries to the log files.
+
+ Copyright (C) 1991, 1992 Ian Lance Taylor
+
+ This file is part of the Taylor UUCP package.
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ The author of the program may be contacted at ian@airs.com or
+ c/o Infinity Development Systems, P.O. Box 520, Waltham, MA 02254.
+ */
+
+#include "uucp.h"
+
+#if USE_RCS_ID
+const char log_rcsid[] = "$Id: log.c,v 1.1 1993/08/05 18:22:39 conklin Exp $";
+#endif
+
+#include <errno.h>
+
+#if ANSI_C
+#include <stdarg.h>
+#endif
+
+#if HAVE_TIME_H
+#include <time.h>
+#endif
+
+#include "uudefs.h"
+#include "uuconf.h"
+#include "system.h"
+
+/* Local functions. */
+
+static const char *zldate_and_time P((void));
+
+/* Log file name. */
+static const char *zLogfile;
+
+/* The function to call when a LOG_FATAL error occurs. */
+static void (*pfLfatal) P((void));
+
+/* Whether to go to a file. */
+static boolean fLfile;
+
+/* ID number. */
+static int iLid;
+
+/* The current user name. */
+static char *zLuser;
+
+/* The current system name. */
+static char *zLsystem;
+
+/* The current device name. */
+char *zLdevice;
+
+/* The open log file. */
+static FILE *eLlog;
+
+/* Whether we have tried to open the log file. We need this because
+ we don't want to keep trying to open the log file if we failed the
+ first time. It can't be static because under HAVE_HDB_LOGGING we
+ may have to write to various different log files. */
+static boolean fLlog_tried;
+
+#if DEBUG > 1
+/* Debugging file name. */
+static const char *zLdebugfile;
+
+/* The open debugging file. */
+static FILE *eLdebug;
+
+/* Whether we've tried to open the debugging file. */
+static boolean fLdebug_tried;
+
+/* Whether we've written out any debugging information. */
+static boolean fLdebugging;
+#endif
+
+/* Statistics file name. */
+static const char *zLstatsfile;
+
+/* The open statistics file. */
+static FILE *eLstats;
+
+/* Whether we've tried to open the statistics file. */
+static boolean fLstats_tried;
+
+/* The array of signals. The elements are only set to TRUE by the
+ default signal handler. They are only set to FALSE if we don't
+ care whether we got the signal or not. */
+volatile sig_atomic_t afSignal[INDEXSIG_COUNT];
+
+/* The array of signals to log. The elements are only set to TRUE by
+ the default signal handler. They are set to FALSE when the signal
+ is logged in ulog. This means that if a signal comes in at just
+ the right time we won't log it (or, rather, we'll log it once
+ instead of twice), but that is not a catatrophe. */
+volatile sig_atomic_t afLog_signal[INDEXSIG_COUNT];
+
+/* Flag that indicates SIGHUP is worth logging. */
+boolean fLog_sighup = TRUE;
+
+/* Signal names to use when logging signals. */
+static const char * const azSignal_names[INDEXSIG_COUNT] = INDEXSIG_NAMES;
+
+/* If not NULL, ulog calls this function before outputting anything.
+ This is used to support cu. */
+void (*pfLstart) P((void));
+
+/* If not NULL, ulog calls this function after outputting everything.
+ This is used to support cu. */
+void (*pfLend) P((void));
+
+/* Set the function to call on a LOG_FATAL error. */
+
+void
+ulog_fatal_fn (pfn)
+ void (*pfn) P((void));
+{
+ pfLfatal = pfn;
+}
+
+/* Decide whether to send log message to the file or not. */
+
+void
+ulog_to_file (puuconf, ffile)
+ pointer puuconf;
+ boolean ffile;
+{
+ int iuuconf;
+
+ iuuconf = uuconf_logfile (puuconf, &zLogfile);
+ if (iuuconf != UUCONF_SUCCESS)
+ ulog_uuconf (LOG_FATAL, puuconf, iuuconf);
+
+#if DEBUG > 1
+ iuuconf = uuconf_debugfile (puuconf, &zLdebugfile);
+ if (iuuconf != UUCONF_SUCCESS)
+ ulog_uuconf (LOG_FATAL, puuconf, iuuconf);
+#endif
+
+ iuuconf = uuconf_statsfile (puuconf, &zLstatsfile);
+ if (iuuconf != UUCONF_SUCCESS)
+ ulog_uuconf (LOG_FATAL, puuconf, iuuconf);
+
+ fLfile = ffile;
+}
+
+/* Set the ID number. This will be called by the usysdep_initialize
+ if there is something sensible to set it to. */
+
+void
+ulog_id (i)
+ int i;
+{
+ iLid = i;
+}
+
+/* Set the user we are making log entries for. The arguments will be
+ copied into memory. */
+
+void
+ulog_user (zuser)
+ const char *zuser;
+{
+ ubuffree (zLuser);
+ zLuser = zbufcpy (zuser);
+}
+
+/* Set the system name we are making log entries for. The name is copied
+ into memory. */
+
+void
+ulog_system (zsystem)
+ const char *zsystem;
+{
+ if (zsystem == NULL
+ || zLsystem == NULL
+ || strcmp (zsystem, zLsystem) != 0)
+ {
+ ubuffree (zLsystem);
+ zLsystem = zbufcpy (zsystem);
+#if HAVE_HDB_LOGGING
+ /* Under HDB logging we now must write to a different log file. */
+ ulog_close ();
+#endif /* HAVE_HDB_LOGGING */
+ }
+}
+
+/* Set the device name. This is copied into memory. */
+
+void
+ulog_device (zdevice)
+ const char *zdevice;
+{
+ ubuffree (zLdevice);
+ zLdevice = zbufcpy (zdevice);
+}
+
+/* Make a log entry. We make a token concession to non ANSI_C systems,
+ but it clearly won't always work. */
+
+#if ! ANSI_C
+#undef HAVE_VFPRINTF
+#endif
+
+/*VARARGS2*/
+#if HAVE_VFPRINTF
+void
+ulog (enum tlog ttype, const char *zmsg, ...)
+#else
+void
+ulog (ttype, zmsg, a, b, c, d, f, g, h, i, j)
+ enum tlog ttype;
+ const char *zmsg;
+#endif
+{
+#if HAVE_VFPRINTF
+ va_list parg;
+#endif
+ FILE *e, *edebug;
+ boolean fstart, fend;
+ const char *zhdr, *zstr;
+
+ /* Log any received signal. We do it this way to avoid calling ulog
+ from the signal handler. A few routines call ulog to get this
+ message out with zmsg == NULL. */
+ {
+ static boolean fdoing_sigs;
+
+ if (! fdoing_sigs)
+ {
+ int isig;
+
+ fdoing_sigs = TRUE;
+ for (isig = 0; isig < INDEXSIG_COUNT; isig++)
+ {
+ if (afLog_signal[isig])
+ {
+ afLog_signal[isig] = FALSE;
+
+ /* Apparently SunOS sends SIGINT rather than SIGHUP
+ when hanging up, so we don't log either signal if
+ fLog_sighup is FALSE. */
+ if ((isig != INDEXSIG_SIGHUP && isig != INDEXSIG_SIGINT)
+ || fLog_sighup)
+ ulog (LOG_ERROR, "Got %s signal", azSignal_names[isig]);
+ }
+ }
+ fdoing_sigs = FALSE;
+ }
+ }
+
+ if (zmsg == NULL)
+ return;
+
+#if DEBUG > 1
+ /* If we've had a debugging file open in the past, then we want to
+ write all log file entries to the debugging file even if it's
+ currently closed. */
+ if (fLfile
+ && eLdebug == NULL
+ && ! fLdebug_tried
+ && (fLdebugging || (int) ttype >= (int) LOG_DEBUG))
+ {
+ fLdebug_tried = TRUE;
+ eLdebug = esysdep_fopen (zLdebugfile, FALSE, TRUE, TRUE);
+ fLdebugging = TRUE;
+ }
+#endif /* DEBUG > 1 */
+
+ if (! fLfile)
+ e = stderr;
+#if DEBUG > 1
+ else if ((int) ttype >= (int) LOG_DEBUG)
+ {
+ e = eLdebug;
+
+ /* If we can't open the debugging file, don't output any
+ debugging messages. */
+ if (e == NULL)
+ return;
+ }
+#endif /* DEBUG > 1 */
+ else
+ {
+ if (eLlog == NULL && ! fLlog_tried)
+ {
+ fLlog_tried = TRUE;
+#if ! HAVE_HDB_LOGGING
+ eLlog = esysdep_fopen (zLogfile, TRUE, TRUE, TRUE);
+#else /* HAVE_HDB_LOGGING */
+ {
+ const char *zsys;
+ char *zfile;
+
+ /* We want to write to .Log/program/system, e.g.
+ .Log/uucico/uunet. The system name may not be set. */
+ if (zLsystem == NULL)
+ zsys = "ANY";
+ else
+ zsys = zLsystem;
+
+ zfile = zbufalc (strlen (zLogfile)
+ + strlen (abProgram)
+ + strlen (zsys)
+ + 1);
+ sprintf (zfile, zLogfile, abProgram, zsys);
+ eLlog = esysdep_fopen (zfile, TRUE, TRUE, TRUE);
+ ubuffree (zfile);
+ }
+#endif /* HAVE_HDB_LOGGING */
+
+ if (eLlog == NULL)
+ {
+ /* We can't open the log file. We don't even have a
+ safe way to report this problem, since we may not be
+ able to write to stderr (it may, for example, be
+ attached to the incoming call). */
+ if (pfLfatal != NULL)
+ (*pfLfatal) ();
+ usysdep_exit (FALSE);
+ }
+ }
+
+ e = eLlog;
+
+ /* eLlog might be NULL here because we might try to open the log
+ file recursively via esysdep_fopen. */
+ if (e == NULL)
+ return;
+ }
+
+ if (pfLstart != NULL)
+ (*pfLstart) ();
+
+ edebug = NULL;
+#if DEBUG > 1
+ if ((int) ttype < (int) LOG_DEBUG)
+ edebug = eLdebug;
+#endif
+
+ fstart = TRUE;
+ fend = TRUE;
+
+ switch (ttype)
+ {
+ case LOG_NORMAL:
+ zhdr = "";
+ break;
+ case LOG_ERROR:
+ zhdr = "ERROR: ";
+ break;
+ case LOG_FATAL:
+ zhdr = "FATAL: ";
+ break;
+#if DEBUG > 1
+ case LOG_DEBUG:
+ zhdr = "DEBUG: ";
+ break;
+ case LOG_DEBUG_START:
+ zhdr = "DEBUG: ";
+ fend = FALSE;
+ break;
+ case LOG_DEBUG_CONTINUE:
+ zhdr = NULL;
+ fstart = FALSE;
+ fend = FALSE;
+ break;
+ case LOG_DEBUG_END:
+ zhdr = NULL;
+ fstart = FALSE;
+ break;
+#endif
+ default:
+ zhdr = "???: ";
+ break;
+ }
+
+ if (fstart)
+ {
+ if (! fLfile)
+ {
+ fprintf (e, "%s: ", abProgram);
+ if (edebug != NULL)
+ fprintf (edebug, "%s: ", abProgram);
+ }
+ else
+ {
+#if HAVE_TAYLOR_LOGGING
+ fprintf (e, "%s ", abProgram);
+ if (edebug != NULL)
+ fprintf (edebug, "%s ", abProgram);
+#else /* ! HAVE_TAYLOR_LOGGING */
+ fprintf (e, "%s ", zLuser == NULL ? "uucp" : zLuser);
+ if (edebug != NULL)
+ fprintf (edebug, "%s ", zLuser == NULL ? "uucp" : zLuser);
+#endif /* HAVE_TAYLOR_LOGGING */
+
+ fprintf (e, "%s ", zLsystem == NULL ? "-" : zLsystem);
+ if (edebug != NULL)
+ fprintf (edebug, "%s ", zLsystem == NULL ? "-" : zLsystem);
+
+#if HAVE_TAYLOR_LOGGING
+ fprintf (e, "%s ", zLuser == NULL ? "-" : zLuser);
+ if (edebug != NULL)
+ fprintf (edebug, "%s ", zLuser == NULL ? "-" : zLuser);
+#endif /* HAVE_TAYLOR_LOGGING */
+
+ zstr = zldate_and_time ();
+ fprintf (e, "(%s", zstr);
+ if (edebug != NULL)
+ fprintf (edebug, "(%s", zstr);
+
+ if (iLid != 0)
+ {
+#if ! HAVE_HDB_LOGGING
+#if HAVE_TAYLOR_LOGGING
+ fprintf (e, " %d", iLid);
+ if (edebug != NULL)
+ fprintf (edebug, " %d", iLid);
+#else /* ! HAVE_TAYLOR_LOGGING */
+ fprintf (e, "-%d", iLid);
+ if (edebug != NULL)
+ fprintf (edebug, "-%d", iLid);
+#endif /* ! HAVE_TAYLOR_LOGGING */
+#else /* HAVE_HDB_LOGGING */
+
+ /* I assume that the second number here is meant to be
+ some sort of file sequence number, and that it should
+ correspond to the sequence number in the statistics
+ file. I don't have any really convenient way to do
+ this, so I won't unless somebody thinks it's very
+ important. */
+ fprintf (e, ",%d,%d", iLid, 0);
+ if (edebug != NULL)
+ fprintf (edebug, ",%d,%d", iLid, 0);
+#endif /* HAVE_HDB_LOGGING */
+ }
+
+ fprintf (e, ") ");
+ if (edebug != NULL)
+ fprintf (edebug, ") ");
+
+ fprintf (e, "%s", zhdr);
+ if (edebug != NULL)
+ fprintf (edebug, "%s", zhdr);
+ }
+ }
+
+#if HAVE_VFPRINTF
+ va_start (parg, zmsg);
+ vfprintf (e, zmsg, parg);
+ va_end (parg);
+ if (edebug != NULL)
+ {
+ va_start (parg, zmsg);
+ vfprintf (edebug, zmsg, parg);
+ va_end (parg);
+ }
+#else /* ! HAVE_VFPRINTF */
+ fprintf (e, zmsg, a, b, c, d, f, g, h, i, j);
+ if (edebug != NULL)
+ fprintf (edebug, zmsg, a, b, c, d, f, g, h, i, j);
+#endif /* ! HAVE_VFPRINTF */
+
+ if (fend)
+ {
+ fprintf (e, "\n");
+ if (edebug != NULL)
+ fprintf (edebug, "\n");
+ }
+
+ (void) fflush (e);
+ if (edebug != NULL)
+ (void) fflush (edebug);
+
+ if (pfLend != NULL)
+ (*pfLend) ();
+
+ if (ttype == LOG_FATAL)
+ {
+ if (pfLfatal != NULL)
+ (*pfLfatal) ();
+ usysdep_exit (FALSE);
+ }
+
+#if CLOSE_LOGFILES
+ ulog_close ();
+#endif
+}
+
+/* Log a uuconf error. */
+
+void
+ulog_uuconf (ttype, puuconf, iuuconf)
+ enum tlog ttype;
+ pointer puuconf;
+ int iuuconf;
+{
+ char ab[512];
+
+ (void) uuconf_error_string (puuconf, iuuconf, ab, sizeof ab);
+ ulog (ttype, "%s", ab);
+}
+
+/* Close the log file. There's nothing useful we can do with errors,
+ so we don't check for them. */
+
+void
+ulog_close ()
+{
+ /* Make sure we logged any signal we received. */
+ ulog (LOG_ERROR, (const char *) NULL);
+
+ if (eLlog != NULL)
+ {
+ (void) fclose (eLlog);
+ eLlog = NULL;
+ fLlog_tried = FALSE;
+ }
+
+#if DEBUG > 1
+ if (eLdebug != NULL)
+ {
+ (void) fclose (eLdebug);
+ eLdebug = NULL;
+ fLdebug_tried = FALSE;
+ }
+#endif
+}
+
+/* Add an entry to the statistics file. We may eventually want to put
+ failed file transfers in here, but we currently do not. */
+
+/*ARGSUSED*/
+void
+ustats (fsucceeded, zuser, zsystem, fsent, cbytes, csecs, cmicros, fmaster)
+ boolean fsucceeded;
+ const char *zuser;
+ const char *zsystem;
+ boolean fsent;
+ long cbytes;
+ long csecs;
+ long cmicros;
+ boolean fmaster;
+{
+ long cbps;
+
+ /* The seconds and microseconds are now counted independently, so
+ they may be out of synch. */
+ if (cmicros < 0)
+ {
+ csecs -= ((- cmicros) / 1000000L) + 1;
+ cmicros = 1000000L - ((- cmicros) % 1000000L);
+ }
+ if (cmicros >= 1000000L)
+ {
+ csecs += cmicros / 10000000L;
+ cmicros = cmicros % 1000000L;
+ }
+
+ /* On a system which can determine microseconds we might very well
+ have both csecs == 0 and cmicros == 0. */
+ if (csecs == 0 && cmicros < 1000)
+ cbps = 0;
+ else
+ {
+ long cmillis;
+
+ /* This computation will not overflow provided csecs < 2147483
+ and cbytes and cbps both fit in a long. */
+ cmillis = csecs * 1000 + cmicros / 1000;
+ cbps = ((cbytes / cmillis) * 1000
+ + ((cbytes % cmillis) * 1000) / cmillis);
+ }
+
+ if (eLstats == NULL)
+ {
+ if (fLstats_tried)
+ return;
+ fLstats_tried = TRUE;
+ eLstats = esysdep_fopen (zLstatsfile, TRUE, TRUE, TRUE);
+ if (eLstats == NULL)
+ return;
+ }
+
+#if HAVE_TAYLOR_LOGGING
+ fprintf (eLstats,
+ "%s %s (%s) %s%s %ld bytes in %ld.%03ld seconds (%ld bytes/sec)\n",
+ zuser, zsystem, zldate_and_time (),
+ fsucceeded ? "" : "failed after ",
+ fsent ? "sent" : "received",
+ cbytes, csecs, cmicros / 1000, cbps);
+#endif /* HAVE_TAYLOR_LOGGING */
+#if HAVE_V2_LOGGING
+ fprintf (eLstats,
+ "%s %s (%s) (%ld) %s %s %ld bytes %ld seconds\n",
+ zuser, zsystem, zldate_and_time (),
+ (long) time ((time_t *) NULL),
+ fsent ? "sent" : "received",
+ fsucceeded ? "data" : "failed after",
+ cbytes, csecs + cmicros / 500000);
+#endif /* HAVE_V2_LOGGING */
+#if HAVE_HDB_LOGGING
+ {
+ static int iseq;
+
+ /* I don't know what the 'C' means. The sequence number should
+ probably correspond to the sequence number in the log file, but
+ that is currently always 0; using this fake sequence number
+ will still at least reveal which transfers are from different
+ calls. We don't report a failed data transfer with this
+ format. */
+ if (! fsucceeded)
+ return;
+ ++iseq;
+ fprintf (eLstats,
+ "%s!%s %c (%s) (C,%d,%d) [%s] %s %ld / %ld.%03ld secs, %ld %s\n",
+ zsystem, zuser, fmaster ? 'M' : 'S', zldate_and_time (),
+ iLid, iseq, zLdevice == NULL ? "unknown" : zLdevice,
+ fsent ? "->" : "<-",
+ cbytes, csecs, cmicros / 1000, cbps,
+ "bytes/sec");
+ }
+#endif /* HAVE_HDB_LOGGING */
+
+ (void) fflush (eLstats);
+
+#if CLOSE_LOGFILES
+ ustats_close ();
+#endif
+}
+
+/* Close the statistics file. */
+
+void
+ustats_close ()
+{
+ if (eLstats != NULL)
+ {
+ if (fclose (eLstats) != 0)
+ ulog (LOG_ERROR, "fclose: %s", strerror (errno));
+ eLstats = NULL;
+ fLstats_tried = FALSE;
+ }
+}
+
+/* Return the date and time in a form used for a log entry. */
+
+static const char *
+zldate_and_time ()
+{
+ long isecs, imicros;
+ struct tm s;
+#if HAVE_TAYLOR_LOGGING
+ static char ab[sizeof "1991-12-31 12:00:00.00"];
+#endif
+#if HAVE_V2_LOGGING
+ static char ab[sizeof "12/31-12:00"];
+#endif
+#if HAVE_HDB_LOGGING
+ static char ab[sizeof "12/31-12:00:00"];
+#endif
+
+ isecs = ixsysdep_time (&imicros);
+ usysdep_localtime (isecs, &s);
+
+#if HAVE_TAYLOR_LOGGING
+ sprintf (ab, "%04d-%02d-%02d %02d:%02d:%02d.%02d",
+ s.tm_year + 1900, s.tm_mon + 1, s.tm_mday, s.tm_hour,
+ s.tm_min, s.tm_sec, (int) (imicros / 10000));
+#endif
+#if HAVE_V2_LOGGING
+ sprintf (ab, "%d/%d-%02d:%02d", s.tm_mon + 1, s.tm_mday,
+ s.tm_hour, s.tm_min);
+#endif
+#if HAVE_HDB_LOGGING
+ sprintf (ab, "%d/%d-%02d:%02d:%02d", s.tm_mon + 1, s.tm_mday,
+ s.tm_hour, s.tm_min, s.tm_sec);
+#endif
+
+ return ab;
+}
diff --git a/gnu/libexec/uucp/common_sources/policy.h b/gnu/libexec/uucp/common_sources/policy.h
new file mode 100644
index 000000000000..4c829bf42d8e
--- /dev/null
+++ b/gnu/libexec/uucp/common_sources/policy.h
@@ -0,0 +1,521 @@
+/* policy.h
+ Configuration file for policy decisions. To be edited on site.
+
+ Copyright (C) 1991, 1992 Ian Lance Taylor
+
+ This file is part of the Taylor UUCP package.
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ The author of the program may be contacted at ian@airs.com or
+ c/o Infinity Development Systems, P.O. Box 520, Waltham, MA 02254.
+ */
+
+/* This header file contains macro definitions which must be set by
+ each site before compilation. The first few are system
+ characteristics that can not be easily discovered by the
+ configuration script. Most are configuration decisions that must
+ be made by the local administrator. */
+
+/* System characteristics. */
+
+/* This code tries to use several ANSI C features, including
+ prototypes, stdarg.h, the const qualifier and the types void
+ (including void * pointers) and unsigned char. By default it will
+ use these features if the compiler defines __STDC__. If your
+ compiler supports these features but does not define __STDC__, you
+ should set ANSI_C to 1. If your compiler does not support these
+ features but defines __STDC__ (no compiler should do this, in my
+ opinion), you should set ANSI_C to 0. In most cases (or if you're
+ not sure) just leave the line below commented out. */
+/* #define ANSI_C 1 */
+
+/* Set USE_STDIO to 1 if data files should be read using the stdio
+ routines (fopen, fread, etc.) rather than the UNIX unbuffered I/O
+ calls (open, read, etc.). Unless you know your stdio is really
+ rotten, you should leave this as 1. */
+#define USE_STDIO 1
+
+/* Exactly one of the following macros must be set to 1. Many modern
+ systems support more than one of these choices through some form of
+ compilation environment, in which case the setting will depend on
+ the compilation environment you use. If you have a reasonable
+ choice between options, I suspect that TERMIO or TERMIOS will be
+ more efficient than TTY, but I have not done any head to head
+ comparisons.
+
+ If you don't set any of these macros, the code below will guess.
+ It will doubtless be wrong on some systems.
+
+ HAVE_BSD_TTY -- Use the 4.2BSD tty routines
+ HAVE_SYSV_TERMIO -- Use the System V termio routines
+ HAVE_POSIX_TERMIOS -- Use the POSIX termios routines
+ */
+#define HAVE_BSD_TTY 0
+#define HAVE_SYSV_TERMIO 0
+#define HAVE_POSIX_TERMIOS 1
+
+/* This code tries to guess which terminal driver to use if you did
+ not make a choice above. It is in this file to make it easy to
+ figure out what's happening if something goes wrong. */
+
+#if HAVE_BSD_TTY + HAVE_SYSV_TERMIO + HAVE_POSIX_TERMIOS == 0
+#if HAVE_CBREAK
+#undef HAVE_BSD_TTY
+#define HAVE_BSD_TTY 1
+#else
+#undef HAVE_SYSV_TERMIO
+#define HAVE_SYSV_TERMIO 1
+#endif
+#endif
+
+/* On some systems a write to a serial port will block even if the
+ file descriptor has been set to not block. File transfer can be
+ more efficient if the package knows that a write to the serial port
+ will not block; however, if the write does block unexpectedly then
+ data loss is possible at high speeds.
+
+ If writes to a serial port always block even when requested not to,
+ you should set HAVE_UNBLOCKED_WRITES to 0; otherwise you should set
+ it to 1. In general on System V releases without STREAMS-based
+ ttys (e.g., before SVR4) HAVE_UNBLOCKED_WRITES should be 0 and on
+ BSD or SVR4 it should be 1.
+
+ If HAVE_UNBLOCKED_WRITES is set to 1 when it should be 0 you may
+ see an unexpectedly large number of transmission errors, or, if you
+ have hardware handshaking, transfer times may be lower than
+ expected (but then, they always are). If HAVE_UNBLOCKED_WRITES is
+ set to 0 when it should be 1, file transfer will use more CPU time
+ than necessary. If you are unsure, setting HAVE_UNBLOCKED_WRITES
+ to 0 should always be safe. */
+#define HAVE_UNBLOCKED_WRITES 1
+
+/* When the code does do a blocking write, it wants to write the
+ largest amount of data which the kernel will accept as a single
+ unit. On BSD this is typically the value of OBUFSIZ in
+ <sys/tty.h>, usually 100. On System V before SVR4 this is
+ typically the size of a clist, CLSIZE in <sys/tty.h>, which is
+ usually 64. On SVR4, which uses STREAMS-based ttys, 2048 is
+ reasonable. Define SINGLE_WRITE to the correct value for your
+ system. If SINGLE_WRITE is too large, data loss may occur. If
+ SINGLE_WRITE is too small, file transfer will use more CPU time
+ than necessary. If you have no idea, 64 should work on most modern
+ systems. */
+#define SINGLE_WRITE 100
+
+/* Some tty drivers, such as those from SCO and AT&T's Unix PC, have a
+ bug in the implementation of ioctl() that causes CLOCAL to be
+ ineffective until the port is opened a second time. If
+ HAVE_CLOCAL_BUG is set to 1, code will be added to do this second
+ open on the port. Set this if you are getting messages that say
+ "Line disconnected" while in the dial chat script after only
+ writing the first few characters to the port. This bug causes the
+ resetting of CLOCAL to have no effect, so the "\m" (require
+ carrier) escape sequence won't function properly in dialer chat
+ scripts. */
+#define HAVE_CLOCAL_BUG 0
+
+/* On some systems, such as SCO Xenix, resetting DTR on a port
+ apparently prevents getty from working on the port, and thus
+ prevents anybody from dialing in. If HAVE_RESET_BUG is set to 1,
+ DTR will not be reset when a serial port is closed. */
+#define HAVE_RESET_BUG 0
+
+/* The Sony NEWS reportedly handles no parity by clearing both the odd
+ and even parity bits in the sgtty structure, unlike most BSD based
+ systems in which no parity is indicated by setting both the odd and
+ even parity bits. Setting HAVE_PARITY_BUG to 1 will handle this
+ correctly. */
+#define HAVE_PARITY_BUG 0
+
+#if HAVE_BSD_TTY
+#ifdef sony
+#undef HAVE_PARITY_BUG
+#define HAVE_PARITY_BUG 1
+#endif
+#endif
+
+/* On Ultrix 4.0, at least, setting CBREAK causes input characters to
+ be stripped, regardless of the setting of LPASS8 and LLITOUT. This
+ can be worked around by using the termio call to reset ISTRIP.
+ This probably does not apply to any other operating system.
+ Setting HAVE_STRIP_BUG to 1 will use this workaround. */
+#define HAVE_STRIP_BUG 0
+
+#if HAVE_BSD_TTY
+#ifdef ultrix
+#undef HAVE_STRIP_BUG
+#define HAVE_STRIP_BUG 1
+#endif
+#endif
+
+/* TIMES_TICK is the fraction of a second which times(2) returns (for
+ example, if times returns 100ths of a second TIMES_TICK should be
+ set to 100). On a true POSIX system (one which has the sysconf
+ function and also has _SC_CLK_TCK defined in <unistd.h>) TIMES_TICK
+ may simply be left as 0. On some systems the environment variable
+ HZ is what you want for TIMES_TICK, but on some other systems HZ
+ has the wrong value; check the man page. If you leave this set to
+ 0, the code will try to guess; it will doubtless be wrong on some
+ non-POSIX systems. If TIMES_TICK is wrong the code may report
+ incorrect file transfer times in the statistics file, but on many
+ systems times(2) will actually not be used and this value will not
+ matter at all. */
+#define TIMES_TICK 0
+
+/* If your system does not support saved set user ID, set
+ HAVE_SAVED_SETUID to 0. However, this is ignored if your system
+ has the setreuid function. Most modern Unixes have one or the
+ other. If your system has the setreuid function, don't worry about
+ this define, or about the following discussion.
+
+ If you set HAVE_SAVED_SETUID to 0, you will not be able to use uucp
+ to transfer files that the uucp user can not read. Basically, you
+ will only be able to use uucp on world-readable files. If you set
+ HAVE_SAVED_SETUID to 1, but your system does not have saved set
+ user ID, uucp will fail with an error message whenever anybody
+ other than the uucp user uses it. */
+#define HAVE_SAVED_SETUID 1
+
+/* On some systems, such as the DG Aviion and, possibly, the RS/6000,
+ the setreuid function is broken. It should be possible to use
+ setreuid to swap the real and effective user ID's, but on some
+ systems it will not change the real user ID (I believe this is due
+ to a misreading of the POSIX standard). On such a system you must
+ set HAVE_BROKEN_SETREUID to 1; if you do not, you will get error
+ messages from setreuid. Systems on which setreuid exists but is
+ broken pretty much always have saved setuid. */
+#define HAVE_BROKEN_SETREUID 0
+
+/* On the 3B2, and possibly other systems, nap takes an argument in
+ hundredths of a second rather than milliseconds. I don't know of
+ any way to test for this. Set HAVE_HUNDREDTHS_NAP to 1 if this is
+ true on your system. This does not matter if your system does not
+ have the nap function. */
+#define HAVE_HUNDREDTHS_NAP 0
+
+/* Set PS_PROGRAM to the program to run to get a process status,
+ including the arguments to pass it. This is used by ``uustat -p''.
+ Set HAVE_PS_MULTIPLE to 1 if a comma separated list of process
+ numbers may be appended (e.g. ``ps -flp1,10,100''). Otherwise ps
+ will be invoked several times, with a single process number append
+ each time. The default definitions should work on most systems,
+ although some (such as the NeXT) will complain about the 'p'
+ option; for those, use the second set of definitions. The third
+ set of definitions are appropriate for System V. To use the second
+ or third set of definitions, change the ``#if 1'' to ``#if 0'' and
+ change the appropriate ``#if 0'' to ``#if 1''. */
+#if 1
+#define PS_PROGRAM "/bin/ps -lp"
+#define HAVE_PS_MULTIPLE 0
+#endif
+#if 0
+#define PS_PROGRAM "/bin/ps -l"
+#define HAVE_PS_MULTIPLE 0
+#endif
+#if 0
+#define PS_PROGRAM "/bin/ps -flp"
+#define HAVE_PS_MULTIPLE 1
+#endif
+
+/* If you use other programs that also lock devices, such as cu or
+ uugetty, the other programs and UUCP must agree on whether a device
+ is locked. This is typically done by creating a lock file in a
+ specific directory; the lock files are generally named
+ LCK..something or LK.something. If the LOCKDIR macro is defined,
+ these lock files will be placed in the named directory; otherwise
+ they will be placed in the default spool directory. On some HDB
+ systems the lock files are placed in /etc/locks. On some they are
+ placed in /usr/spool/locks. On the NeXT they are placed in
+ /usr/spool/uucp/LCK. */
+/* #define LOCKDIR "/usr/spool/uucp" */
+/* #define LOCKDIR "/etc/locks" */
+/* #define LOCKDIR "/usr/spool/locks" */
+/* #define LOCKDIR "/usr/spool/uucp/LCK" */
+#define LOCKDIR "/var/spool/lock"
+
+/* You must also specify the format of the lock files by setting
+ exactly one of the following macros to 1. Check an existing lock
+ file to decide which of these choices is more appropriate.
+
+ The HDB style is to write the locking process ID in ASCII, passed
+ to ten characters, followed by a newline.
+
+ The V2 style is to write the locking process ID as four binary
+ bytes in the host byte order. Many BSD derived systems use this
+ type of lock file, including the NeXT.
+
+ SCO lock files are similar to HDB lock files, but always lock the
+ lowercase version of the tty (i.e., LCK..tty2a is created if you
+ are locking tty2A). They are appropriate if you are using Taylor
+ UUCP on an SCO Unix, SCO Xenix, or SCO Open Desktop system.
+
+ SVR4 lock files are also similar to HDB lock files, but they use a
+ different naming convention. The filenames are LK.xxx.yyy.zzz,
+ where xxx is the major device number of the device holding the
+ special device file, yyy is the major device number of the port
+ device itself, and zzz is the minor device number of the port
+ device.
+
+ Coherent use a completely different method of terminal locking.
+ See unix/cohtty for details. For locks other than for terminals,
+ HDB type lock files are used. */
+#define HAVE_V2_LOCKFILES 0
+#define HAVE_HDB_LOCKFILES 1
+#define HAVE_SCO_LOCKFILES 0
+#define HAVE_SVR4_LOCKFILES 0
+#define HAVE_COHERENT_LOCKFILES 0
+
+/* If your system supports Internet mail addresses (which look like
+ user@host.domain rather than system!user), HAVE_INTERNET_MAIL
+ should be set to 1. This is checked by uuxqt when sending error
+ (or success, if requested) notifications to the person who
+ submitted the job. */
+#define HAVE_INTERNET_MAIL 1
+
+/* Adminstrative decisions. */
+
+/* Set USE_RCS_ID to 1 if you want the RCS ID strings compiled into
+ the executable. Leaving them out will decrease the executable
+ size. Leaving them in will make it easier to determine which
+ version you are running. */
+#define USE_RCS_ID 1
+
+/* DEBUG controls how much debugging information is compiled into the
+ code. If DEBUG is defined as 0, no sanity checks will be done and
+ no debugging messages will be compiled in. If DEBUG is defined as
+ 1 sanity checks will be done but there will still be no debugging
+ messages. If DEBUG is 2 than debugging messages will be compiled
+ in. When initially testing, DEBUG should be 2, and you should
+ probably leave it at 2 unless a small reduction in the executable
+ file size will be very helpful. */
+#define DEBUG 2
+
+/* Set the default grade to use for a uucp command if the -g option is
+ not used. The grades, from highest to lowest, are 0 to 9, A to Z,
+ a to z. */
+#define BDEFAULT_UUCP_GRADE ('N')
+
+/* Set the default grade to use for a uux command if the -g option is
+ not used. */
+#define BDEFAULT_UUX_GRADE ('N')
+
+/* To compile in use of the new style of configuration files described
+ in the documentation, set HAVE_TAYLOR_CONFIG to 1. */
+#define HAVE_TAYLOR_CONFIG 1
+
+/* To compile in use of V2 style configuration files (L.sys, L-devices
+ and so on), set HAVE_V2_CONFIG to 1. To compile in use of HDB
+ style configuration files (Systems, Devices and so on) set
+ HAVE_HDB_CONFIG to 1. The files will be looked up in the
+ oldconfigdir directory as defined in the Makefile.
+
+ You may set any or all of HAVE_TAYLOR_CONFIG, HAVE_V2_CONFIG and
+ HAVE_HDB_CONFIG to 1 (you must set at least one of the macros).
+ When looking something up (a system, a port, etc.) the new style
+ configuration files will be read first, followed by the V2
+ configuration files, followed by the HDB configuration files. */
+#define HAVE_V2_CONFIG 1
+#define HAVE_HDB_CONFIG 1
+
+/* Exactly one of the following macros must be set to 1. The exact
+ format of the spool directories is explained in unix/spool.c.
+
+ SPOOLDIR_V2 -- Use a Version 2 (original UUCP) style spool directory
+ SPOOLDIR_BSD42 -- Use a BSD 4.2 style spool directory
+ SPOOLDIR_BSD43 -- Use a BSD 4.3 style spool directory
+ SPOOLDIR_HDB -- Use a HDB (BNU) style spool directory
+ SPOOLDIR_ULTRIX -- Use an Ultrix style spool directory
+ SPOOLDIR_SVR4 -- Use a System V Release 4 spool directory
+ SPOOLDIR_TAYLOR -- Use a new style spool directory
+
+ If you are not worried about compatibility with a currently running
+ UUCP, use SPOOLDIR_TAYLOR. */
+#define SPOOLDIR_V2 0
+#define SPOOLDIR_BSD42 0
+#define SPOOLDIR_BSD43 0
+#define SPOOLDIR_HDB 0
+#define SPOOLDIR_ULTRIX 0
+#define SPOOLDIR_SVR4 0
+#define SPOOLDIR_TAYLOR 1
+
+/* You must select which type of logging you want by setting exactly
+ one of the following to 1. These control output to the log file
+ and to the statistics file.
+
+ If you define HAVE_TAYLOR_LOGGING, each line in the log file will
+ look something like this:
+
+ uucico uunet uucp (1991-12-10 09:04:34.45 16390) Receiving uunet/D./D.uunetSwJ72
+
+ and each line in the statistics file will look something like this:
+
+ uucp uunet (1991-12-10 09:04:40.20) received 2371 bytes in 5 seconds (474 bytes/sec)
+
+ If you define HAVE_V2_LOGGING, each line in the log file will look
+ something like this:
+
+ uucico uunet uucp (12/10-09:04 16390) Receiving uunet/D./D.uunetSwJ72
+
+ and each line in the statistics file will look something like this:
+
+ uucp uunet (12/10-09:04 16390) (692373862) received data 2371 bytes 5 seconds
+
+ If you define HAVE_HDB_LOGGING, each program will by default use a
+ separate log file. For uucico talking to uunet, for example, it
+ will be /usr/spool/uucp/.Log/uucico/uunet. Each line will look
+ something like this:
+
+ uucp uunet (12/10-09:04:22,16390,1) Receiving uunet/D./D.uunetSwJ72
+
+ and each line in the statistics file will look something like this:
+
+ uunet!uucp M (12/10-09:04:22) (C,16390,1) [ttyXX] <- 2371 / 5.000 secs, 474 bytes/sec
+
+ The main reason to prefer one format over another is that you may
+ have shell scripts which expect the files to have a particular
+ format. If you have none, choose whichever format you find more
+ appealing. */
+#define HAVE_TAYLOR_LOGGING 1
+#define HAVE_V2_LOGGING 0
+#define HAVE_HDB_LOGGING 0
+
+/* If you would like the log, debugging and statistics files to be
+ closed after each message, set CLOSE_LOGFILES to 1. This will
+ permit the log files to be easily moved. If a log file does not
+ exist when a new message is written out, it will be created.
+ Setting CLOSE_LOGFILES to 1 will obviously require slightly more
+ processing time. */
+#define CLOSE_LOGFILES 0
+
+/* The name of the default spool directory. If HAVE_TAYLOR_CONFIG is
+ set to 1, this may be overridden by the ``spool'' command in the
+ configuration file. */
+#define SPOOLDIR "/var/spool/uucp"
+
+/* The name of the default public directory. If HAVE_TAYLOR_CONFIG is
+ set to 1, this may be overridden by the ``pubdir'' command in the
+ configuration file. Also, a particular system may be given a
+ specific public directory by using the ``pubdir'' command in the
+ system file. */
+#define PUBDIR "/var/spool/uucppublic"
+
+/* The default command path. This is a space separated list of
+ directories. Remote command executions requested by uux are looked
+ up using this path. If you are using HAVE_TAYLOR_CONFIG, the
+ command path may be overridden for a particular system. For most
+ systems, you should just make sure that the programs rmail and
+ rnews can be found using this path. */
+#define CMDPATH "/bin /usr/bin /usr/local/bin"
+
+/* The default amount of free space to require for systems that do not
+ specify an amount with the ``free-space'' command. This is only
+ used when talking to another instance of Taylor UUCP; if accepting
+ a file would not leave at least this many bytes free on the disk,
+ it will be refused. */
+#define DEFAULT_FREE_SPACE (50000)
+
+/* While a file is being received, Taylor UUCP will periodically check
+ to see if there is enough free space remaining on the disk. If
+ there is not enough space available on the disk (as determined by
+ DEFAULT_FREE_SPACE, above, or the ``free-space'' command for the
+ system) the communication will be aborted. The disk will be
+ checked each time FREE_SPACE_DELTA bytes are received. Lower
+ values of FREE_SPACE_DELTA are less likely to fill up the disk, but
+ will also waste more time checking the amount of free space. To
+ avoid checking the disk while the file is being received, set
+ FREE_SPACE_DELTA to 0. */
+#define FREE_SPACE_DELTA (10240)
+
+/* It is possible for an execute job to request to be executed using
+ sh(1), rather than execve(2). This is such a security risk, it is
+ being disabled by default; to allow such jobs, set the following
+ macro to 1. */
+#define ALLOW_SH_EXECUTION 0
+
+/* If a command executed on behalf of a remote system takes a filename
+ as an argument, a security breach may be possible (note that on my
+ system neither of the default commands, rmail and rnews, take
+ filename arguments). If you set ALLOW_FILENAME_ARGUMENTS to 0, all
+ arguments to a command will be checked; if any argument
+ 1) starts with ../
+ 2) contains the string /../
+ 3) begins with a / but does not name a file that may be sent or
+ received (according to the specified ``remote-send'' and
+ ``remote-receive'')
+ the command will be rejected. By default, any argument is
+ permitted. */
+#define ALLOW_FILENAME_ARGUMENTS 1
+
+#if HAVE_TAYLOR_LOGGING
+
+/* The default log file when using HAVE_TAYLOR_LOGGING. When using
+ HAVE_TAYLOR_CONFIG, this may be overridden by the ``logfile''
+ command in the configuration file. */
+#define LOGFILE "/var/spool/uucp/Log"
+
+/* The default statistics file when using HAVE_TAYLOR_LOGGING. When
+ using HAVE_TAYLOR_CONFIG, this may be overridden by the
+ ``statfile'' command in the configuration file. */
+#define STATFILE "/var/spool/uucp/Stats"
+
+/* The default debugging file when using HAVE_TAYLOR_LOGGING. When
+ using HAVE_TAYLOR_CONFIG, this may be overridden by the
+ ``debugfile'' command in the configuration file. */
+#define DEBUGFILE "/var/spool/uucp/Debug"
+
+#endif /* HAVE_TAYLOR_LOGGING */
+
+#if HAVE_V2_LOGGING
+
+/* The default log file when using HAVE_V2_LOGGING. When using
+ HAVE_TAYLOR_CONFIG, this may be overridden by the ``logfile''
+ command in the configuration file. */
+#define LOGFILE "/var/spool/uucp/LOGFILE"
+
+/* The default statistics file when using HAVE_V2_LOGGING. When using
+ HAVE_TAYLOR_CONFIG, this may be overridden by the ``statfile''
+ command in the configuration file. */
+#define STATFILE "/var/spool/uucp/SYSLOG"
+
+/* The default debugging file when using HAVE_V2_LOGGING. When using
+ HAVE_TAYLOR_CONFIG, this may be overridden by the ``debugfile''
+ command in the configuration file. */
+#define DEBUGFILE "/var/spool/uucp/DEBUG"
+
+#endif /* HAVE_V2_LOGGING */
+
+#if HAVE_HDB_LOGGING
+
+/* The default log file when using HAVE_HDB_LOGGING. When using
+ HAVE_TAYLOR_CONFIG, this may be overridden by the ``logfile''
+ command in the configuration file. The first %s in the string will
+ be replaced by the program name (e.g. uucico); the second %s will
+ be replaced by the system name (if there is no appropriate system,
+ "ANY" will be used). No other '%' character may appear in the
+ string. */
+#define LOGFILE "/var/spool/uucp/.Log/%s/%s"
+
+/* The default statistics file when using HAVE_HDB_LOGGING. When using
+ HAVE_TAYLOR_CONFIG, this may be overridden by the ``statfile''
+ command in the configuration file. */
+#define STATFILE "/var/spool/uucp/.Admin/xferstats"
+
+/* The default debugging file when using HAVE_HDB_LOGGING. When using
+ HAVE_TAYLOR_CONFIG, this may be overridden by the ``debugfile''
+ command in the configuration file. */
+#define DEBUGFILE "/var/spool/uucp/.Admin/audit.local"
+
+#endif /* HAVE_HDB_LOGGING */
diff --git a/gnu/libexec/uucp/common_sources/prot.c b/gnu/libexec/uucp/common_sources/prot.c
new file mode 100644
index 000000000000..433bf2766829
--- /dev/null
+++ b/gnu/libexec/uucp/common_sources/prot.c
@@ -0,0 +1,237 @@
+/* prot.c
+ Protocol support routines to move commands and data around.
+
+ Copyright (C) 1991, 1992 Ian Lance Taylor
+
+ This file is part of the Taylor UUCP package.
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ The author of the program may be contacted at ian@airs.com or
+ c/o Infinity Development Systems, P.O. Box 520, Waltham, MA 02254.
+ */
+
+#include "uucp.h"
+
+#if USE_RCS_ID
+const char prot_rcsid[] = "$Id: prot.c,v 1.1 1993/08/05 18:22:41 conklin Exp $";
+#endif
+
+#include <errno.h>
+
+#include "uudefs.h"
+#include "system.h"
+#include "conn.h"
+#include "prot.h"
+
+/* Variables visible to the protocol-specific routines. */
+
+/* Buffer to hold received data. */
+char abPrecbuf[CRECBUFLEN];
+
+/* Index of start of data in abPrecbuf. */
+int iPrecstart;
+
+/* Index of end of data (first byte not included in data) in abPrecbuf. */
+int iPrecend;
+
+/* We want to output and input at the same time, if supported on this
+ machine. If we have something to send, we send it all while
+ accepting a large amount of data. Once we have sent everything we
+ look at whatever we have received. If data comes in faster than we
+ can send it, we may run out of buffer space. */
+
+boolean
+fsend_data (qconn, zsend, csend, fdoread)
+ struct sconnection *qconn;
+ const char *zsend;
+ size_t csend;
+ boolean fdoread;
+{
+ if (! fdoread)
+ return fconn_write (qconn, zsend, csend);
+
+ while (csend > 0)
+ {
+ size_t crec, csent;
+
+ if (iPrecend < iPrecstart)
+ crec = iPrecstart - iPrecend - 1;
+ else
+ {
+ crec = CRECBUFLEN - iPrecend;
+ if (iPrecstart == 0)
+ --crec;
+ }
+
+ csent = csend;
+
+ if (! fconn_io (qconn, zsend, &csent, abPrecbuf + iPrecend, &crec))
+ return FALSE;
+
+ csend -= csent;
+ zsend += csent;
+
+ iPrecend = (iPrecend + crec) % CRECBUFLEN;
+ }
+
+ return TRUE;
+}
+
+/* Read data from the other system when we have nothing to send. The
+ argument cneed is the amount of data the caller wants, and ctimeout
+ is the timeout in seconds. The function sets *pcrec to the amount
+ of data which was actually received, which may be less than cneed
+ if there isn't enough room in the receive buffer. If no data is
+ received before the timeout expires, *pcrec will be returned as 0.
+ If an error occurs, the function returns FALSE. If the freport
+ argument is FALSE, no error should be reported. */
+
+boolean
+freceive_data (qconn, cneed, pcrec, ctimeout, freport)
+ struct sconnection *qconn;
+ size_t cneed;
+ size_t *pcrec;
+ int ctimeout;
+ boolean freport;
+{
+ /* Set *pcrec to the maximum amount of data we can read. fconn_read
+ expects *pcrec to be the buffer size, and sets it to the amount
+ actually received. */
+ if (iPrecend < iPrecstart)
+ *pcrec = iPrecstart - iPrecend - 1;
+ else
+ {
+ *pcrec = CRECBUFLEN - iPrecend;
+ if (iPrecstart == 0)
+ --(*pcrec);
+ }
+
+#if DEBUG > 0
+ /* If we have no room in the buffer, we're in trouble. The
+ protocols must be written to ensure that this can't happen. */
+ if (*pcrec == 0)
+ ulog (LOG_FATAL, "freceive_data: No room in buffer");
+#endif
+
+ /* If we don't have room for all the data the caller wants, we
+ simply have to expect less. We'll get the rest later. */
+ if (*pcrec < cneed)
+ cneed = *pcrec;
+
+ if (! fconn_read (qconn, abPrecbuf + iPrecend, pcrec, cneed, ctimeout,
+ freport))
+ return FALSE;
+
+ iPrecend = (iPrecend + *pcrec) % CRECBUFLEN;
+
+ return TRUE;
+}
+
+/* Read a single character. Get it out of the receive buffer if it's
+ there, otherwise ask freceive_data for at least one character.
+ This is used because as a protocol is shutting down freceive_data
+ may read ahead and eat characters that should be read outside the
+ protocol routines. We call freceive_data rather than fconn_read
+ with an argument of 1 so that we can get all the available data in
+ a single system call. The ctimeout argument is the timeout in
+ seconds; the freport argument is FALSE if no error should be
+ reported. This returns a character, or -1 on timeout or -2 on
+ error. */
+
+int
+breceive_char (qconn, ctimeout, freport)
+ struct sconnection *qconn;
+ int ctimeout;
+ boolean freport;
+{
+ char b;
+
+ if (iPrecstart == iPrecend)
+ {
+ size_t crec;
+
+ if (! freceive_data (qconn, sizeof (char), &crec, ctimeout, freport))
+ return -2;
+ if (crec == 0)
+ return -1;
+ }
+
+ b = abPrecbuf[iPrecstart];
+ iPrecstart = (iPrecstart + 1) % CRECBUFLEN;
+ return BUCHAR (b);
+}
+
+/* Send mail about a file transfer. We send to the given mailing
+ address if there is one, otherwise to the user. */
+
+boolean
+fmail_transfer (fsuccess, zuser, zmail, zwhy, zfromfile, zfromsys,
+ ztofile, ztosys, zsaved)
+ boolean fsuccess;
+ const char *zuser;
+ const char *zmail;
+ const char *zwhy;
+ const char *zfromfile;
+ const char *zfromsys;
+ const char *ztofile;
+ const char *ztosys;
+ const char *zsaved;
+{
+ const char *zsendto;
+ const char *az[20];
+ int i;
+
+ if (zmail != NULL && *zmail != '\0')
+ zsendto = zmail;
+ else
+ zsendto = zuser;
+
+ i = 0;
+ az[i++] = "The file\n\t";
+ if (zfromsys != NULL)
+ {
+ az[i++] = zfromsys;
+ az[i++] = "!";
+ }
+ az[i++] = zfromfile;
+ if (fsuccess)
+ az[i++] = "\nwas successfully transferred to\n\t";
+ else
+ az[i++] = "\ncould not be transferred to\n\t";
+ if (ztosys != NULL)
+ {
+ az[i++] = ztosys;
+ az[i++] = "!";
+ }
+ az[i++] = ztofile;
+ az[i++] = "\nas requested by\n\t";
+ az[i++] = zuser;
+ if (! fsuccess)
+ {
+ az[i++] = "\nfor the following reason:\n\t";
+ az[i++] = zwhy;
+ az[i++] = "\n";
+ }
+ if (zsaved != NULL)
+ {
+ az[i++] = zsaved;
+ az[i++] = "\n";
+ }
+
+ return fsysdep_mail (zsendto,
+ fsuccess ? "UUCP succeeded" : "UUCP failed",
+ i, az);
+}
diff --git a/gnu/libexec/uucp/common_sources/prot.h b/gnu/libexec/uucp/common_sources/prot.h
new file mode 100644
index 000000000000..4e2bb584d842
--- /dev/null
+++ b/gnu/libexec/uucp/common_sources/prot.h
@@ -0,0 +1,250 @@
+/* prot.h
+ Protocol header file.
+
+ Copyright (C) 1991, 1992 Ian Lance Taylor
+
+ This file is part of the Taylor UUCP package.
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ The author of the program may be contacted at ian@airs.com or
+ c/o Infinity Development Systems, P.O. Box 520, Waltham, MA 02254.
+ */
+
+/* We need the definition of uuconf_cmdtab to declare the protocol
+ parameter arrays. */
+#ifndef UUCONF_H
+#include "uuconf.h"
+#endif
+
+#if ANSI_C
+/* These structures are used in prototypes but are not defined in this
+ header file. */
+struct sdaemon;
+struct sconnection;
+struct stransfer;
+#endif
+
+/* The sprotocol structure holds information and functions for a specific
+ protocol (e.g. the 'g' protocol). */
+
+struct sprotocol
+{
+ /* The name of the protocol (e.g. 'g'). */
+ char bname;
+ /* Reliability requirements, an or of UUCONF_RELIABLE_xxx defines
+ from uuconf.h. */
+ int ireliable;
+ /* The maximum number of channels this protocol can support. */
+ int cchans;
+ /* Protocol parameter commands. */
+ struct uuconf_cmdtab *qcmds;
+ /* A routine to start the protocol. If *pzlog is set to be
+ non-NULL, it is an informative message to be logged; it should
+ then be passed to ubuffree. */
+ boolean (*pfstart) P((struct sdaemon *qdaemon, char **pzlog));
+ /* Shutdown the protocol. */
+ boolean (*pfshutdown) P((struct sdaemon *qdaemon));
+ /* Send a command to the other side. */
+ boolean (*pfsendcmd) P((struct sdaemon *qdaemon, const char *z,
+ int ilocal, int iremote));
+ /* Get buffer to space to fill with data. This should set *pcdata
+ to the amount of data desired. */
+ char *(*pzgetspace) P((struct sdaemon *qdaemon, size_t *pcdata));
+ /* Send data to the other side. The argument z must be a return
+ value of pzgetspace. The ipos argument is the file position, and
+ is ignored by most protocols. */
+ boolean (*pfsenddata) P((struct sdaemon *qdaemon, char *z, size_t c,
+ int ilocal, int iremote, long ipos));
+ /* Wait for data to come in and call fgot_data with it until
+ fgot_data sets *pfexit. */
+ boolean (*pfwait) P((struct sdaemon *qdaemon));
+ /* Handle any file level actions that need to be taken. If a file
+ transfer is starting rather than ending, fstart is TRUE. If the
+ file is being sent rather than received, fsend is TRUE. If
+ fstart and fsend are both TRUE, cbytes holds the size of the
+ file. If *pfhandled is set to TRUE, then the protocol routine
+ has taken care of queueing up qtrans for the next action. */
+ boolean (*pffile) P((struct sdaemon *qdaemon, struct stransfer *qtrans,
+ boolean fstart, boolean fsend, long cbytes,
+ boolean *pfhandled));
+};
+
+/* Send data to the other system. If the fread argument is TRUE, this
+ will also receive data into the receive buffer abPrecbuf; fread is
+ passed as TRUE if the protocol expects data to be coming back, to
+ make sure the input buffer does not fill up. Returns FALSE on
+ error. */
+extern boolean fsend_data P((struct sconnection *qconn,
+ const char *zsend, size_t csend,
+ boolean fdoread));
+
+/* Receive data from the other system when there is no data to send.
+ The cneed argument is the amount of data desired and the ctimeout
+ argument is the timeout in seconds. This will set *pcrec to the
+ amount of data received. It will return FALSE on error. If a
+ timeout occurs, it will return TRUE with *pcrec set to zero. */
+extern boolean freceive_data P((struct sconnection *qconn, size_t cneed,
+ size_t *pcrec, int ctimeout,
+ boolean freport));
+
+/* Get one character from the remote system, going through the
+ procotol buffering. The ctimeout argument is the timeout in
+ seconds, and the freport argument is TRUE if errors should be
+ reported (when closing a connection it is pointless to report
+ errors). This returns a character or -1 on a timeout or -2 on an
+ error. */
+extern int breceive_char P((struct sconnection *qconn,
+ int ctimeout, boolean freport));
+
+/* Compute a 32 bit CRC of a data buffer, given an initial CRC. */
+extern unsigned long icrc P((const char *z, size_t c, unsigned long ick));
+
+/* The initial CRC value to use for a new buffer. */
+#if ANSI_C
+#define ICRCINIT (0xffffffffUL)
+#else
+#define ICRCINIT ((unsigned long) 0xffffffffL)
+#endif
+
+/* The size of the receive buffer. */
+#define CRECBUFLEN (16384)
+
+/* Buffer to hold received data. */
+extern char abPrecbuf[CRECBUFLEN];
+
+/* Index of start of data in abPrecbuf. */
+extern int iPrecstart;
+
+/* Index of end of data (first byte not included in data) in abPrecbuf. */
+extern int iPrecend;
+
+/* There are a couple of variables and functions that are shared by
+ the 'i' and 'j' protocols (the 'j' protocol is just a wrapper
+ around the 'i' protocol). These belong in a separate header file,
+ protij.h, but I don't want to create one for just a couple of
+ things. */
+
+/* An escape sequence of characters for the 'j' protocol to avoid
+ (protocol parameter ``avoid''). */
+extern const char *zJavoid_parameter;
+
+/* Timeout to use when sending the 'i' protocol SYNC packet (protocol
+ parameter ``sync-timeout''). */
+extern int cIsync_timeout;
+
+/* Shared startup routine for the 'i' and 'j' protocols. */
+extern boolean fijstart P((struct sdaemon *qdaemon, char **pzlog,
+ int imaxpacksize,
+ boolean (*pfsend) P((struct sconnection *qconn,
+ const char *zsend,
+ size_t csend,
+ boolean fdoread)),
+ boolean (*pfreceive) P((struct sconnection *qconn,
+ size_t cneed,
+ size_t *pcrec,
+ int ctimeout,
+ boolean freport))));
+
+/* Prototypes for 'g' protocol functions. */
+
+extern struct uuconf_cmdtab asGproto_params[];
+extern boolean fgstart P((struct sdaemon *qdaemon, char **pzlog));
+extern boolean fbiggstart P((struct sdaemon *qdaemon, char **pzlog));
+extern boolean fgshutdown P((struct sdaemon *qdaemon));
+extern boolean fgsendcmd P((struct sdaemon *qdaemon, const char *z,
+ int ilocal, int iremote));
+extern char *zggetspace P((struct sdaemon *qdaemon, size_t *pcdata));
+extern boolean fgsenddata P((struct sdaemon *qdaemon, char *z, size_t c,
+ int ilocal, int iremote, long ipos));
+extern boolean fgwait P((struct sdaemon *qdaemon));
+
+/* Prototypes for 'f' protocol functions. */
+
+extern struct uuconf_cmdtab asFproto_params[];
+extern boolean ffstart P((struct sdaemon *qdaemon, char **pzlog));
+extern boolean ffshutdown P((struct sdaemon *qdaemon));
+extern boolean ffsendcmd P((struct sdaemon *qdaemon, const char *z,
+ int ilocal, int iremote));
+extern char *zfgetspace P((struct sdaemon *qdaemon, size_t *pcdata));
+extern boolean ffsenddata P((struct sdaemon *qdaemon, char *z, size_t c,
+ int ilocal, int iremote, long ipos));
+extern boolean ffwait P((struct sdaemon *qdaemon));
+extern boolean fffile P((struct sdaemon *qdaemon, struct stransfer *qtrans,
+ boolean fstart, boolean fsend, long cbytes,
+ boolean *pfhandled));
+
+/* Prototypes for 't' protocol functions. */
+
+extern struct uuconf_cmdtab asTproto_params[];
+extern boolean ftstart P((struct sdaemon *qdaemon, char **pzlog));
+extern boolean ftshutdown P((struct sdaemon *qdaemon));
+extern boolean ftsendcmd P((struct sdaemon *qdaemon, const char *z,
+ int ilocal, int iremote));
+extern char *ztgetspace P((struct sdaemon *qdaemon, size_t *pcdata));
+extern boolean ftsenddata P((struct sdaemon *qdaemon, char *z, size_t c,
+ int ilocal, int iremote, long ipos));
+extern boolean ftwait P((struct sdaemon *qdaemon));
+extern boolean ftfile P((struct sdaemon *qdaemon, struct stransfer *qtrans,
+ boolean fstart, boolean fsend, long cbytes,
+ boolean *pfhandled));
+
+/* Prototypes for 'e' protocol functions. */
+
+extern struct uuconf_cmdtab asEproto_params[];
+extern boolean festart P((struct sdaemon *qdaemon, char **pzlog));
+extern boolean feshutdown P((struct sdaemon *qdaemon));
+extern boolean fesendcmd P((struct sdaemon *qdaemon, const char *z,
+ int ilocal, int iremote));
+extern char *zegetspace P((struct sdaemon *qdaemon, size_t *pcdata));
+extern boolean fesenddata P((struct sdaemon *qdaemon, char *z, size_t c,
+ int ilocal, int iremote, long ipos));
+extern boolean fewait P((struct sdaemon *qdaemon));
+extern boolean fefile P((struct sdaemon *qdaemon, struct stransfer *qtrans,
+ boolean fstart, boolean fsend, long cbytes,
+ boolean *pfhandled));
+
+/* Prototypes for 'i' protocol functions. */
+
+extern struct uuconf_cmdtab asIproto_params[];
+extern boolean fistart P((struct sdaemon *qdaemon, char **pzlog));
+extern boolean fishutdown P((struct sdaemon *qdaemon));
+extern boolean fisendcmd P((struct sdaemon *qdaemon, const char *z,
+ int ilocal, int iremote));
+extern char *zigetspace P((struct sdaemon *qdaemon, size_t *pcdata));
+extern boolean fisenddata P((struct sdaemon *qdaemon, char *z, size_t c,
+ int ilocal, int iremote, long ipos));
+extern boolean fiwait P((struct sdaemon *qdaemon));
+
+/* Prototypes for 'j' protocol functions. The 'j' protocol mostly
+ uses the 'i' protocol functions, but it has a couple of functions
+ of its own. */
+extern boolean fjstart P((struct sdaemon *qdaemon, char **pzlog));
+extern boolean fjshutdown P((struct sdaemon *qdaemon));
+
+/* Prototypes for 'a' protocol functions (these use 'z' as the second
+ character because 'a' is a modified Zmodem protocol). */
+extern struct uuconf_cmdtab asZproto_params[];
+extern boolean fzstart P((struct sdaemon *qdaemon, char **pzlog));
+extern boolean fzshutdown P((struct sdaemon *qdaemon));
+extern boolean fzsendcmd P((struct sdaemon *qdaemon, const char *z,
+ int ilocal, int iremote));
+extern char *zzgetspace P((struct sdaemon *qdaemon, size_t *pcdata));
+extern boolean fzsenddata P((struct sdaemon *qdaemon, char *z, size_t c,
+ int ilocal, int iremote, long ipos));
+extern boolean fzwait P((struct sdaemon *qdaemon));
+extern boolean fzfile P((struct sdaemon *qdaemon, struct stransfer *qtrans,
+ boolean fstart, boolean fsend, long cbytes,
+ boolean *pfhandled));
diff --git a/gnu/libexec/uucp/common_sources/sysdep.h b/gnu/libexec/uucp/common_sources/sysdep.h
new file mode 100644
index 000000000000..47675ac2385d
--- /dev/null
+++ b/gnu/libexec/uucp/common_sources/sysdep.h
@@ -0,0 +1,530 @@
+/* sysh.unx -*- C -*-
+ The header file for the UNIX system dependent routines.
+
+ Copyright (C) 1991, 1992 Ian Lance Taylor
+
+ This file is part of the Taylor UUCP package.
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ The author of the program may be contacted at ian@airs.com or
+ c/o Infinity Development Systems, P.O. Box 520, Waltham, MA 02254.
+ */
+
+#ifndef SYSH_UNX_H
+
+#define SYSH_UNX_H
+
+#if ANSI_C
+/* These structures are used in prototypes but are not defined in this
+ header file. */
+struct uuconf_system;
+struct sconnection;
+#endif
+
+/* Make sure the defines do not conflict. These are in this file
+ because they are Unix dependent. */
+#if HAVE_V2_LOCKFILES + HAVE_HDB_LOCKFILES + HAVE_SCO_LOCKFILES + HAVE_SVR4_LOCKFILES + HAVE_COHERENT_LOCKFILES != 1
+ #error LOCKFILES define not set or duplicated
+#endif
+
+/* SCO and SVR4 lockfiles are basically just like HDB lockfiles. */
+#if HAVE_SCO_LOCKFILES || HAVE_SVR4_LOCKFILES
+#undef HAVE_HDB_LOCKFILES
+#define HAVE_HDB_LOCKFILES 1
+#endif
+
+#if HAVE_BSD_TTY + HAVE_SYSV_TERMIO + HAVE_POSIX_TERMIOS != 1
+ #error Terminal driver define not set or duplicated
+#endif
+
+#if SPOOLDIR_V2 + SPOOLDIR_BSD42 + SPOOLDIR_BSD43 + SPOOLDIR_HDB + SPOOLDIR_ULTRIX + SPOOLDIR_SVR4 + SPOOLDIR_TAYLOR != 1
+ #error Spool directory define not set or duplicated
+#endif
+
+/* If setreuid is broken, don't use it. */
+#if HAVE_BROKEN_SETREUID
+#undef HAVE_SETREUID
+#define HAVE_SETREUID 0
+#endif
+
+/* Get some standard types from the configuration header file. */
+#ifdef PID_T
+typedef PID_T pid_t;
+#endif
+
+#ifdef UID_T
+typedef UID_T uid_t;
+#endif
+
+#ifdef GID_T
+typedef GID_T gid_t;
+#endif
+
+#ifdef OFF_T
+typedef OFF_T off_t;
+#endif
+
+/* On Unix, binary files are the same as text files. */
+#define BINREAD "r"
+#define BINWRITE "w"
+
+/* If we have sigaction, we can force system calls to not be
+ restarted. */
+#if HAVE_SIGACTION
+#undef HAVE_RESTARTABLE_SYSCALLS
+#define HAVE_RESTARTABLE_SYSCALLS 0
+#endif
+
+/* If we have sigvec, and we have HAVE_SIGVEC_SV_FLAGS, and
+ SV_INTERRUPT is defined, we can force system calls to not be
+ restarted (signal.h is included by uucp.h before this point, so
+ SV_INTERRUPT will be defined by now if it it ever is). */
+#if HAVE_SIGVEC && HAVE_SIGVEC_SV_FLAGS
+#ifdef SV_INTERRUPT
+#undef HAVE_RESTARTABLE_SYSCALLS
+#define HAVE_RESTARTABLE_SYSCALLS 0
+#endif
+#endif
+
+/* If we were cross-configured, we will have a value of -1 for
+ HAVE_RESTARTABLE_SYSCALLS. In this case, we try to guess what the
+ correct value should be. Yuck. If we have sigvec, but neither of
+ the above cases applied (which we know because they would have
+ changed HAVE_RESTARTABLE_SYSCALLS) then we are probably on 4.2BSD
+ and system calls are automatically restarted. Otherwise, assume
+ that they are not. */
+#if HAVE_RESTARTABLE_SYSCALLS == -1
+#undef HAVE_RESTARTABLE_SYSCALLS
+#if HAVE_SIGVEC
+#define HAVE_RESTARTABLE_SYSCALLS 1
+#else
+#define HAVE_RESTARTABLE_SYSCALLS 0
+#endif
+#endif /* HAVE_RESTARTABLE_SYSCALLS == -1 */
+
+/* We don't handle sigset in combination with restartable system
+ calls, so we check for it although this combination will never
+ happen. */
+#if ! HAVE_SIGACTION && ! HAVE_SIGVEC && HAVE_SIGSET
+#if HAVE_RESTARTABLE_SYSCALLS
+#undef HAVE_SIGSET
+#define HAVE_SIGSET 0
+#endif
+#endif
+
+/* If we don't have restartable system calls, we can ignore
+ fsysdep_catch, usysdep_start_catch and usysdep_end_catch.
+ Otherwise fsysdep_catch has to do a setjmp. */
+
+#if ! HAVE_RESTARTABLE_SYSCALLS
+
+#define fsysdep_catch() (TRUE)
+#define usysdep_start_catch()
+#define usysdep_end_catch()
+#define CATCH_PROTECT
+
+#else /* HAVE_RESTARTABLE_SYSCALLS */
+
+#if HAVE_SETRET && ! HAVE_SIGSETJMP
+#include <setret.h>
+#define setjmp setret
+#define longjmp longret
+#define jmp_buf ret_buf
+#else /* ! HAVE_SETRET || HAVE_SIGSETJMP */
+#include <setjmp.h>
+#if HAVE_SIGSETJMP
+#undef setjmp
+#undef longjmp
+#undef jmp_buf
+#define setjmp(s) sigsetjmp ((s), TRUE)
+#define longjmp siglongjmp
+#define jmp_buf sigjmp_buf
+#endif /* HAVE_SIGSETJMP */
+#endif /* ! HAVE_SETRET || HAVE_SIGSETJMP */
+
+extern volatile sig_atomic_t fSjmp;
+extern volatile jmp_buf sSjmp_buf;
+
+#define fsysdep_catch() (setjmp (sSjmp_buf) == 0)
+
+#define usysdep_start_catch() (fSjmp = TRUE)
+
+#define usysdep_end_catch() (fSjmp = FALSE)
+
+#define CATCH_PROTECT volatile
+
+#endif /* HAVE_RESTARTABLE_SYSCALLS */
+
+/* Get definitions for the terminal driver. */
+
+#if HAVE_BSD_TTY
+#include <sgtty.h>
+struct sbsd_terminal
+{
+ struct sgttyb stty;
+ struct tchars stchars;
+ struct ltchars sltchars;
+};
+typedef struct sbsd_terminal sterminal;
+#define fgetterminfo(o, q) \
+ (ioctl ((o), TIOCGETP, &(q)->stty) == 0 \
+ && ioctl ((o), TIOCGETC, &(q)->stchars) == 0 \
+ && ioctl ((o), TIOCGLTC, &(q)->sltchars) == 0)
+#define fsetterminfo(o, q) \
+ (ioctl ((o), TIOCSETN, &(q)->stty) == 0 \
+ && ioctl ((o), TIOCSETC, &(q)->stchars) == 0 \
+ && ioctl ((o), TIOCSLTC, &(q)->sltchars) == 0)
+#define fsetterminfodrain(o, q) \
+ (ioctl ((o), TIOCSETP, &(q)->stty) == 0 \
+ && ioctl ((o), TIOCSETC, &(q)->stchars) == 0 \
+ && ioctl ((o), TIOCSLTC, &(q)->sltchars) == 0)
+#endif /* HAVE_BSD_TTY */
+
+#if HAVE_SYSV_TERMIO
+#include <termio.h>
+typedef struct termio sterminal;
+#define fgetterminfo(o, q) (ioctl ((o), TCGETA, (q)) == 0)
+#define fsetterminfo(o, q) (ioctl ((o), TCSETA, (q)) == 0)
+#define fsetterminfodrain(o, q) (ioctl ((o), TCSETAW, (q)) == 0)
+#endif /* HAVE_SYSV_TERMIO */
+
+#if HAVE_POSIX_TERMIOS
+#include <termios.h>
+typedef struct termios sterminal;
+#define fgetterminfo(o, q) (tcgetattr ((o), (q)) == 0)
+#define fsetterminfo(o, q) (tcsetattr ((o), TCSANOW, (q)) == 0)
+#define fsetterminfodrain(o, q) (tcsetattr ((o), TCSADRAIN, (q)) == 0)
+
+/* On some systems it is not possible to include both <sys/ioctl.h>
+ and <termios.h> in the same source files; I don't really know why.
+ On such systems, we pretend that we don't have <sys/ioctl.h>. */
+#if ! HAVE_TERMIOS_AND_SYS_IOCTL_H
+#undef HAVE_SYS_IOCTL_H
+#define HAVE_SYS_IOCTL_H 0
+#endif
+
+#endif /* HAVE_POSIX_TERMIOS */
+
+/* The root directory (this is needed by the system independent stuff
+ as the default for local-send). */
+#define ZROOTDIR "/"
+
+/* The name of the execution directory within the spool directory
+ (this is need by the system independent uuxqt.c). */
+#define XQTDIR ".Xqtdir"
+
+/* The name of the directory in which we preserve file transfers that
+ failed. */
+#define PRESERVEDIR ".Preserve"
+
+/* The length of the sequence number used in a file name. */
+#define CSEQLEN (4)
+
+/* Get some standard definitions. Avoid including the files more than
+ once--some might have been included by uucp.h. */
+#if USE_STDIO && HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#if ! USE_TYPES_H
+#include <sys/types.h>
+#endif
+#include <sys/stat.h>
+
+/* Get definitions for the file permission bits. */
+
+#ifndef S_IRWXU
+#define S_IRWXU 0700
+#endif
+#ifndef S_IRUSR
+#define S_IRUSR 0400
+#endif
+#ifndef S_IWUSR
+#define S_IWUSR 0200
+#endif
+#ifndef S_IXUSR
+#define S_IXUSR 0100
+#endif
+
+#ifndef S_IRWXG
+#define S_IRWXG 0070
+#endif
+#ifndef S_IRGRP
+#define S_IRGRP 0040
+#endif
+#ifndef S_IWGRP
+#define S_IWGRP 0020
+#endif
+#ifndef S_IXGRP
+#define S_IXGRP 0010
+#endif
+
+#ifndef S_IRWXO
+#define S_IRWXO 0007
+#endif
+#ifndef S_IROTH
+#define S_IROTH 0004
+#endif
+#ifndef S_IWOTH
+#define S_IWOTH 0002
+#endif
+#ifndef S_IXOTH
+#define S_IXOTH 0001
+#endif
+
+#ifndef S_ISDIR
+#ifdef S_IFDIR
+#define S_ISDIR(i) (((i) & S_IFMT) == S_IFDIR)
+#else /* ! defined (S_IFDIR) */
+#define S_ISDIR(i) (((i) & 0170000) == 040000)
+#endif /* ! defined (S_IFDIR) */
+#endif /* ! defined (S_ISDIR) */
+
+/* We need the access macros. */
+#ifndef R_OK
+#define R_OK 4
+#define W_OK 2
+#define X_OK 1
+#define F_OK 0
+#endif /* ! defined (R_OK) */
+
+/* We create files with these modes (should this be configurable?). */
+#define IPRIVATE_FILE_MODE (S_IRUSR | S_IWUSR)
+#define IPUBLIC_FILE_MODE (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)
+
+/* We create directories with this mode (should this be configurable?). */
+#define IDIRECTORY_MODE (S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)
+#define IPUBLIC_DIRECTORY_MODE (S_IRWXU | S_IRWXG | S_IRWXO)
+
+#if ! HAVE_OPENDIR
+
+/* Define some structures to use if we don't have opendir, etc. These
+ will only work if we have the old Unix filesystem, with a 2 byte
+ inode and a 14 byte filename. */
+
+#include <sys/dir.h>
+
+struct dirent
+{
+ char d_name[DIRSIZ + 1];
+};
+
+typedef struct
+{
+ int o;
+ struct dirent s;
+} DIR;
+
+extern DIR *opendir P((const char *zdir));
+extern struct dirent *readdir P((DIR *));
+extern int closedir P((DIR *));
+
+#endif /* ! HAVE_OPENDIR */
+
+#if ! HAVE_FTW_H
+
+/* If there is no <ftw.h>, define the ftw constants. */
+
+#define FTW_F (0)
+#define FTW_D (1)
+#define FTW_DNR (2)
+#define FTW_NS (3)
+
+#endif /* ! HAVE_FTW_H */
+
+/* This structure holds the system dependent information we keep for a
+ connection. This is used by the TCP and TLI code. */
+
+struct ssysdep_conn
+{
+ /* File descriptor. */
+ int o;
+ /* Device name. */
+ char *zdevice;
+ /* File status flags. */
+ int iflags;
+ /* File status flags for descriptor 1 (-1 if not standard input). */
+ int istdout_flags;
+ /* Hold the real descriptor when using a dialer device. */
+ int ohold;
+ /* TRUE if this is a terminal and the remaining fields are valid. */
+ boolean fterminal;
+ /* TRUE if this is a TLI descriptor. */
+ boolean ftli;
+ /* Baud rate. */
+ long ibaud;
+ /* Original terminal settings. */
+ sterminal sorig;
+ /* Current terminal settings. */
+ sterminal snew;
+#if HAVE_COHERENT_LOCKFILES
+ /* On Coherent we need to hold on to the real port name which will
+ be used to enable the port. Ick. */
+ char *zenable;
+#endif
+};
+
+/* These functions do I/O and chat scripts to a port. They are called
+ by the TCP and TLI routines. */
+extern boolean fsysdep_conn_read P((struct sconnection *qconn,
+ char *zbuf, size_t *pclen,
+ size_t cmin, int ctimeout,
+ boolean freport));
+extern boolean fsysdep_conn_write P((struct sconnection *qconn,
+ const char *zbuf, size_t clen));
+extern boolean fsysdep_conn_io P((struct sconnection *qconn,
+ const char *zwrite, size_t *pcwrite,
+ char *zread, size_t *pcread));
+extern boolean fsysdep_conn_chat P((struct sconnection *qconn,
+ char **pzprog));
+
+/* Set a signal handler. */
+extern void usset_signal P((int isig, RETSIGTYPE (*pfn) P((int)),
+ boolean fforce, boolean *pfignored));
+
+/* Default signal handler. This sets the appropriate element of the
+ afSignal array. If system calls are automatically restarted, it
+ may do a longjmp to an fsysdep_catch. */
+extern RETSIGTYPE ussignal P((int isig));
+
+/* Try to fork, repeating several times. */
+extern pid_t ixsfork P((void));
+
+/* Spawn a job. Returns the process ID of the spawned job or -1 on
+ error. The following macros may be passed in aidescs. */
+
+/* Set descriptor to /dev/null. */
+#define SPAWN_NULL (-1)
+/* Set element of aidescs to a pipe for caller to read from. */
+#define SPAWN_READ_PIPE (-2)
+/* Set element of aidescs to a pipe for caller to write to. */
+#define SPAWN_WRITE_PIPE (-3)
+
+extern pid_t ixsspawn P((const char **pazargs, int *aidescs,
+ boolean fkeepuid, boolean fkeepenv,
+ const char *zchdir, boolean fnosigs,
+ boolean fshell, const char *zpath,
+ const char *zuu_machine,
+ const char *zuu_user));
+
+/* Do a form of popen using ixsspawn. */
+extern FILE *espopen P((const char **pazargs, boolean frd,
+ pid_t *pipid));
+
+/* Wait for a particular process to finish, returning the exit status.
+ The process ID should be pid_t, but we can't put that in a
+ prototype. */
+extern int ixswait P((unsigned long ipid, const char *zreport));
+
+/* Find a spool file in the spool directory. For a local file, the
+ bgrade argument is the grade of the file. This is needed for
+ SPOOLDIR_SVR4. */
+extern char *zsfind_file P((const char *zsimple, const char *zsystem,
+ int bgrade));
+
+/* Return the grade given a sequence number. */
+extern char bsgrade P((pointer pseq));
+
+/* Lock a string. */
+extern boolean fsdo_lock P((const char *, boolean fspooldir,
+ boolean *pferr));
+
+/* Unlock a string. */
+extern boolean fsdo_unlock P((const char *, boolean fspooldir));
+
+/* Check access for a particular user name, or NULL to check access
+ for any user. */
+extern boolean fsuser_access P((const struct stat *, int imode,
+ const char *zuser));
+
+/* Stick two directories and a file name together. */
+extern char *zsappend3 P((const char *zdir1, const char *zdir2,
+ const char *zfile));
+
+/* Stick three directories and a file name together. */
+extern char *zsappend4 P((const char *zdir1, const char *zdir2,
+ const char *zdir3, const char *zfile));
+
+/* Get a temporary file name. */
+extern char *zstemp_file P((const struct uuconf_system *qsys));
+
+/* Get a command file name. */
+extern char *zscmd_file P((const struct uuconf_system *qsys, int bgrade));
+
+/* Get a jobid from a system, a file name, and a grade. */
+extern char *zsfile_to_jobid P((const struct uuconf_system *qsys,
+ const char *zfile,
+ int bgrade));
+
+/* Get a file name from a jobid. This also returns the associated system
+ in *pzsystem and the grade in *pbgrade. */
+extern char *zsjobid_to_file P((const char *zid, char **pzsystem,
+ char *pbgrade));
+
+/* See whether there is a spool directory for a system when using
+ SPOOLDIR_ULTRIX. */
+extern boolean fsultrix_has_spool P((const char *zsystem));
+
+#if HAVE_COHERENT_LOCKFILES
+/* Lock a coherent tty. */
+extern boolean lockttyexist P((const char *z));
+extern boolean fscoherent_disable_tty P((const char *zdevice,
+ char **pzenable));
+#endif
+
+/* Some replacements for standard Unix functions. */
+
+#if ! HAVE_DUP2
+extern int dup2 P((int oold, int onew));
+#endif
+
+#if ! HAVE_FTW
+extern int ftw P((const char *zdir,
+ int (*pfn) P((const char *zfile,
+ const struct stat *qstat,
+ int iflag)),
+ int cdescriptors));
+#endif
+
+#if ! HAVE_GETCWD && ! HAVE_GETWD
+extern char *getcwd P((char *zbuf, size_t cbuf));
+#endif
+
+#if ! HAVE_MKDIR
+extern int mkdir P((const char *zdir, int imode));
+#endif
+
+#if ! HAVE_RENAME
+extern int rename P((const char *zold, const char *znew));
+#endif
+
+#if ! HAVE_RMDIR
+extern int rmdir P((const char *zdir));
+#endif
+
+/* The working directory from which the program was run (this is set
+ by usysdep_initialize if called with INIT_GETCWD). */
+extern char *zScwd;
+
+/* The spool directory name. */
+extern const char *zSspooldir;
+
+/* The lock directory name. */
+extern const char *zSlockdir;
+
+/* The local UUCP name (needed for some spool directory stuff). */
+extern const char *zSlocalname;
+
+#endif /* ! defined (SYSH_UNX_H) */
diff --git a/gnu/libexec/uucp/common_sources/system.h b/gnu/libexec/uucp/common_sources/system.h
new file mode 100644
index 000000000000..aa9d2a41a45a
--- /dev/null
+++ b/gnu/libexec/uucp/common_sources/system.h
@@ -0,0 +1,950 @@
+/* system.h
+ Header file for system dependent stuff in the Taylor UUCP package.
+ This file is not itself system dependent.
+
+ Copyright (C) 1991, 1992 Ian Lance Taylor
+
+ This file is part of the Taylor UUCP package.
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ The author of the program may be contacted at ian@airs.com or
+ c/o Infinity Development Systems, P.O. Box 520, Waltham, MA 02254.
+ */
+
+#ifndef SYSTEM_H
+
+#define SYSTEM_H
+
+#if ANSI_C
+/* These structures are used in prototypes but are not defined in this
+ header file. */
+struct tm;
+struct uuconf_system;
+struct uuconf_port;
+struct sconnection;
+struct sstatus;
+struct scmd;
+#endif
+
+/* Any function which returns an error should also report an error
+ message, unless otherwise indicated.
+
+ Any function that returns a char *, rather than a const char *, is
+ returning a pointer to a buffer allocated by zbufalc which must be
+ freed using ubuffree, unless otherwise indicated. */
+
+/* The maximum length of a remote system name. */
+extern size_t cSysdep_max_name_len;
+
+/* Initialize. If something goes wrong, this routine should just
+ exit. The flag argument is 0, or a combination of any of the
+ following flags. */
+
+/* This program needs to know the current working directory. This is
+ used because on Unix it can be expensive to determine the current
+ working directory (some versions of getcwd fork a process), but in
+ most cases we don't need to know it. However, we are going to
+ chdir to the spool directory (unless INIT_CHDIR is set), so we have
+ to get the cwd now if we are ever going to get it. Both uucp and
+ uux use the function fsysdep_needs_cwd to determine whether they
+ will need the current working directory, and pass the argument to
+ usysdep_initialize appropriately. There's probably a cleaner way
+ to handle this, but this will suffice for now. */
+#define INIT_GETCWD (01)
+
+/* This program should not chdir to the spool directory. This may
+ only make sense on Unix. It is set by cu. */
+#define INIT_NOCHDIR (02)
+
+/* This program needs special access to the spool directories. That
+ means, on Unix, this program is normally installed setuid. */
+#define INIT_SUID (04)
+
+extern void usysdep_initialize P((pointer puuconf, int iflags));
+
+/* Exit the program. The fsuccess argument indicates whether to
+ return an indication of success or failure to the outer
+ environment. This routine should not return. */
+extern void usysdep_exit P((boolean fsuccess));
+
+/* Called when a non-standard configuration file is being used, to
+ avoid handing out privileged access. If it returns FALSE, default
+ configuration file will be used. This is called before the
+ usysdep_initialize function is called. */
+extern boolean fsysdep_other_config P((const char *));
+
+/* Detach from the controlling terminal. This probably only makes
+ sense on Unix. It is called by uucico to try to get the modem port
+ as a controlling terminal. It is also called by uucico before it
+ starts up uuxqt, so that uuxqt will be a complete daemon. */
+extern void usysdep_detach P((void));
+
+/* Get the local node name if it is not specified in the configuration
+ files. Returns NULL on error; otherwise the return value should
+ point to a static buffer. */
+extern const char *zsysdep_localname P((void));
+
+/* Get the login name. This is used when uucico is started up with no
+ arguments in slave mode, which causes it to assume that somebody
+ has logged in. It also used by uucp and uux for recording the user
+ name. This may not return NULL. The return value should point to
+ a static buffer. */
+extern const char *zsysdep_login_name P((void));
+
+/* Set a signal handler for a signal. If the signal occurs, the
+ appropriate element of afSignal should be set to the signal number
+ (see the declaration of afSignal in uucp.h). This routine might be
+ able to just use signal, but Unix requires more complex handling.
+ This is called before usysdep_initialize. */
+extern void usysdep_signal P((int isig));
+
+/* Catch a signal. This is actually defined as a macro in the system
+ dependent header file, and the prototype here just indicates how it
+ should be called. It is called before a routine which must exit if
+ a signal occurs, and is expected to set do a setjmp (which is why
+ it must be a macro). It is actually only called in one place in
+ the system independent code, before the call to read stdin in uux.
+ This is needed to handle 4.2 BSD restartable system calls, which
+ require a longjmp. On systems which don't need to do
+ setjmp/longjmp around system calls, this can be redefined in
+ sysdep.h to TRUE. It should return TRUE if the routine should
+ proceed, or FALSE if a signal occurred. After having this return
+ TRUE, usysdep_start_catch should be used to start catching the
+ signal; this basically tells the signal handler that it's OK to do
+ the longjmp, if fsysdep_catch did not already do so. */
+#ifndef fsysdep_catch
+extern boolean fsysdep_catch P((void));
+#endif
+
+/* Start catching a signal. This is called after fsysdep_catch to
+ tell the signal handler to go ahead and do the longjmp. This may
+ be implemented as a macro in sysdep.h. */
+#ifndef usysdep_start_catch
+extern void usysdep_start_catch P((void));
+#endif
+
+/* Stop catching a signal. This is called when it is no longer
+ necessary for fsysdep_catch to handle signals. This may be
+ implemented as a macro in sysdep.h. */
+#ifndef usysdep_end_catch
+extern void usysdep_end_catch P((void));
+#endif
+
+/* Link two files. On Unix this should attempt the link. If it
+ succeeds it should return TRUE with *pfworked set to TRUE. If the
+ link fails because it must go across a device, it should return
+ TRUE with *pfworked set to FALSE. If the link fails for some other
+ reason, it should log an error message and return FALSE. On a
+ system which does not support links to files, this should just
+ return TRUE with *pfworked set to FALSE. */
+extern boolean fsysdep_link P((const char *zfrom, const char *zto,
+ boolean *pfworked));
+
+/* Get the port name. This is used when uucico is started up in slave
+ mode to figure out which port was used to call in so that it can
+ determine any appropriate protocol parameters. This may return
+ NULL if the port cannot be determined, which will just mean that no
+ protocol parameters are applied. The name returned should be the
+ sort of name that would appear in the port file. This should set
+ *pftcp_port to TRUE if it can determine that the port is a TCP
+ connection rather than a normal serial port. The return value (if
+ not NULL) should point to a static buffer. */
+extern const char *zsysdep_port_name P((boolean *pftcp_port));
+
+/* Expand a file name on the local system. On Unix, if the zfile
+ argument begins with ~user/ it goes in that users home directory,
+ and if it begins with ~/ it goes in the public directory (the
+ public directory is passed to this routine, since each system may
+ have its own public directory). Similar conventions may be
+ desirable on other systems. This should always return an absolute
+ path name, probably in the public directory. It should return NULL
+ on error; otherwise the return value should be allocated using
+ zbufcpy or zbufalc. */
+extern char *zsysdep_local_file P((const char *zname,
+ const char *zpubdir));
+
+/* Return whether a file name is in a directory, and check for read or
+ write access. This should check whether zfile is within zdir (or
+ is zdir itself). If it is not, it should return FALSE. If zfile
+ is in zdir, then fcheck indicates whether further checking should
+ be done. If fcheck is FALSE, no further checking is done.
+ Otherwise, if freadable is TRUE the user zuser should have search
+ access to all directories from zdir down to zfile and should have
+ read access on zfile itself (if zfile does not exist, or is not a
+ regular file, this function may return FALSE but does not have to).
+ If freadable is FALSE, the user zuser should have search access to
+ all directories from zdir down to zfile and should have write
+ access on zfile (which may be a directory, or may not actually
+ exist, which is acceptable). The zuser argument may be NULL, in
+ which case the check should be made for any user, not just zuser.
+ There is no way for this function to return error. */
+extern boolean fsysdep_in_directory P((const char *zfile,
+ const char *zdir,
+ boolean fcheck,
+ boolean freadable,
+ const char *zuser));
+
+/* Return TRUE if a file exists, FALSE otherwise. There is no way to
+ return error. */
+extern boolean fsysdep_file_exists P((const char *zfile));
+
+/* Start up a program. The code expects fsysdep_run to return after
+ doing a fork, but at least for now everything will work fine if it
+ does not (on a system which does not support forking). The three
+ string arguments may be catenated together to form the program to
+ execute; I did it this way to make it easy to call execl(2), and
+ because I never needed more than two arguments. The program will
+ always be "uucico" or "uuxqt". The return value will be passed
+ directly to usysdep_exit, and should be TRUE on success, FALSE on
+ error. */
+extern boolean fsysdep_run P((const char *zprogram, const char *zarg1,
+ const char *zarg2));
+
+/* Send a mail message. This function will be passed an array of
+ strings. All necessary newlines are already included; the strings
+ should simply be concatenated together to form the mail message.
+ It should return FALSE on error, although the return value is often
+ ignored. */
+extern boolean fsysdep_mail P((const char *zto, const char *zsubject,
+ int cstrs, const char **paz));
+
+/* Get the time in seconds since some epoch. The actual epoch is
+ unimportant, so long as the time values are consistent across
+ program executions and the value is never negative. If the
+ pimicros argument is not NULL, it should be set to the number of
+ microseconds (if this is not available, *pimicros should be set to
+ zero). */
+extern long ixsysdep_time P((long *pimicros));
+
+/* Get the time in seconds and microseconds (millionths of a second)
+ since some epoch. The actual epoch is not important, and it may
+ change in between program invocations; this is provided because on
+ Unix the times function may be used. If microseconds can not be
+ determined, *pimicros can just be set to zero. */
+extern long ixsysdep_process_time P((long *pimicros));
+
+/* Parse the value returned by ixsysdep_time into a struct tm. I
+ assume that this structure is defined in <time.h>. This is
+ basically just localtime, except that the ANSI function takes a
+ time_t which may not be what is returned by ixsysdep_time. */
+extern void usysdep_localtime P((long itime, struct tm *q));
+
+/* Sleep for a number of seconds. */
+extern void usysdep_sleep P((int cseconds));
+
+/* Pause for half a second, or 1 second if subsecond sleeps are not
+ possible. */
+extern void usysdep_pause P((void));
+
+/* Lock a remote system. This should return FALSE if the system is
+ already locked (no error should be reported). */
+extern boolean fsysdep_lock_system P((const struct uuconf_system *qsys));
+
+/* Unlock a remote system. This should return FALSE on error
+ (although the return value is generally ignored). */
+extern boolean fsysdep_unlock_system P((const struct uuconf_system *qsys));
+
+/* Get the conversation sequence number for a remote system, and
+ increment it for next time. This should return -1 on error. */
+extern long ixsysdep_get_sequence P((const struct uuconf_system *qsys));
+
+/* Get the status of a remote system. This should return FALSE on
+ error. Otherwise it should set *qret to the status. If no status
+ information is available, this should set *qret to sensible values
+ and return TRUE. If pfnone is not NULL, then it should be set to
+ TRUE if no status information was available or FALSE otherwise. */
+extern boolean fsysdep_get_status P((const struct uuconf_system *qsys,
+ struct sstatus *qret,
+ boolean *pfnone));
+
+/* Set the status of a remote system. This should return FALSE on
+ error. The system will be locked before this call is made. */
+extern boolean fsysdep_set_status P((const struct uuconf_system *qsys,
+ const struct sstatus *qset));
+
+/* See whether a remote system is permitted to log in. This is just
+ to support the remote.unknown shell script for HDB. The zscript
+ argument is the script name, as return by uuconf_remote_unknown.
+ The zsystem argument is the name given by the remote system. If
+ the system is not permitted to log in, this function should log an
+ error and return FALSE. */
+extern boolean fsysdep_unknown_caller P((const char *zscript,
+ const char *zsystem));
+
+/* Check whether there is work for a remote system. It should return
+ TRUE if there is work, FALSE otherwise; there is no way to indicate
+ an error. */
+extern boolean fsysdep_has_work P((const struct uuconf_system *qsys));
+
+/* Initialize the work scan. This will be called before
+ fsysdep_get_work. The bgrade argument is the minimum grade of
+ execution files that should be considered (e.g. a bgrade of 'd'
+ will allow all grades from 'A' to 'Z' and 'a' to 'd'). This
+ function should return FALSE on error. */
+extern boolean fsysdep_get_work_init P((const struct uuconf_system *qsys,
+ int bgrade));
+
+/* Get the next command to be executed for a remote system. The
+ bgrade argument will be the same as for fsysdep_get_work_init;
+ probably only one of these functions will use it, namely the
+ function for which it is more convenient. This should return FALSE
+ on error. The structure pointed to by qcmd should be filled in.
+ The strings may point into a static buffer; they will be copied out
+ if necessary. If there is no more work, this should set qcmd->bcmd
+ to 'H' and return TRUE. This should set qcmd->pseq to something
+ which can be passed to fsysdep_did_work to remove the job from the
+ queue when it has been completed. This may set qcmd->bcmd to 'P'
+ to represent a poll file; the main code will just pass the pseq
+ element of such a structure to fsysdep_did_work if the system is
+ called. */
+extern boolean fsysdep_get_work P((const struct uuconf_system *qsys,
+ int bgrade, struct scmd *qcmd));
+
+/* Remove a job from the work queue. This must also remove the
+ temporary file used for a send command, if there is one. It should
+ return FALSE on error. */
+extern boolean fsysdep_did_work P((pointer pseq));
+
+/* Save the temporary file for a send command. This function should
+ return a string that will be put into a mail message. On success
+ this string should say something like ``The file has been saved as
+ ...''. On failure it could say something like ``The file could not
+ be saved because ...''. If there is no temporary file, or for some
+ reason it's not appropriate to include a message, this function
+ should just return NULL. This function is used when a file send
+ fails for some reason, to make sure that we don't completely lost
+ the file. */
+extern const char *zsysdep_save_temp_file P((pointer pseq));
+
+/* Cleanup anything left over by fsysdep_get_work_init and
+ fsysdep_get_work. This may be called even though
+ fsysdep_get_work_init has not been. */
+extern void usysdep_get_work_free P((const struct uuconf_system *qsys));
+
+/* Add a base name to a file if it is a directory. If zfile names a
+ directory, then return a string naming a file within the directory
+ with the base file name of zname. This should return NULL on
+ error. */
+extern char *zsysdep_add_base P((const char *zfile,
+ const char *zname));
+
+/* Get a file name from the spool directory. This should return NULL
+ on error. The pseq argument is TRUE if the file was found from
+ searching the work directory; this is, unfortunately, needed to
+ support SVR4 spool directories. */
+extern char *zsysdep_spool_file_name P((const struct uuconf_system *qsys,
+ const char *zfile,
+ pointer pseq));
+
+/* Make necessary directories. This should create all non-existent
+ directories for a file. If the fpublic argument is TRUE, anybody
+ should be permitted to create and remove files in the directory;
+ otherwise anybody can list the directory, but only the UUCP system
+ can create and remove files. It should return FALSE on error. */
+extern boolean fsysdep_make_dirs P((const char *zfile, boolean fpublic));
+
+/* Create a stdio file, setting appropriate protection. If the
+ fpublic argument is TRUE, the file is made publically accessible;
+ otherwise it is treated as a private data file. If the fappend
+ argument is TRUE, the file is opened in append mode; otherwise any
+ previously existing file of the same name is removed. If the
+ fmkdirs argument is TRUE, then any necessary directories should
+ also be created. On a system in which file protections are
+ unimportant and the necessary directories exist, this may be
+ implemented as
+
+ fopen (zfile, fappend ? "a" : "w");
+
+ */
+extern FILE *esysdep_fopen P((const char *zfile, boolean fpublic,
+ boolean fappend, boolean fmkdirs));
+
+/* Open a file, using the access permission of the user who invoked
+ the program. The frd argument is TRUE if the file should be opened
+ for reading, and the fbinary argument is TRUE if the file should be
+ opened as a binary file (this is ignored on Unix, since there all
+ files are binary files). This returns an openfile_t, not a FILE *.
+ This is supposed to be able to open a file even if it can not be
+ read by the uucp user. This is not possible on some older Unix
+ systems. */
+extern openfile_t esysdep_user_fopen P((const char *zfile,
+ boolean frd, boolean fbinary));
+
+/* Open a file to send to another system; the qsys argument is the
+ system the file is being sent to. If fcheck is TRUE, it should
+ make sure that the file is readable by zuser (if zuser is NULL the
+ file must be readable by anybody). This is to eliminate a window
+ between fsysdep_in_directory and esysdep_open_send. If an error
+ occurs, it should return EFILECLOSED. */
+extern openfile_t esysdep_open_send P((const struct uuconf_system *qsys,
+ const char *zname,
+ boolean fcheck,
+ const char *zuser));
+
+/* Return a temporary file name to receive into. This file will be
+ opened by esysdep_open_receive. The qsys argument is the system
+ the file is coming from, the zto argument is the name the file will
+ have after it has been fully received, and the ztemp argument, if
+ it is not NULL, is from the command sent by the remote system. The
+ return value must be freed using ubuffree. The function should
+ return NULL on error. */
+extern char *zsysdep_receive_temp P((const struct uuconf_system *qsys,
+ const char *zfile,
+ const char *ztemp));
+
+/* Open a file to receive from another system. The zreceive argument
+ is the return value of zsysdep_receive_temp with the same qsys,
+ zfile and ztemp arguments. If the function can determine that this
+ file has already been partially received, it should set *pcrestart
+ to the number of bytes that have been received. If the file has
+ not been partially received, *pcrestart should be set to -1. The
+ function should return EFILECLOSED on error. After the file is
+ written, fsysdep_move_file will be called to move the file to its
+ final destination, and to set the correct file mode. */
+extern openfile_t esysdep_open_receive P((const struct uuconf_system *qsys,
+ const char *zto,
+ const char *ztemp,
+ const char *zreceive,
+ long *pcrestart));
+
+/* Move a file. This is used to move a received file to its final
+ location. The zto argument is the file to create. The zorig
+ argument is the name of the file to move. If fmkdirs is TRUE, then
+ any necessary directories are created; fpublic indicates whether
+ they should be publically writeable or not. If fcheck is TRUE,
+ this should make sure the directory is writeable by the user zuser
+ (if zuser is NULL, then it must be writeable by any user); this is
+ to avoid a window of vulnerability between fsysdep_in_directory and
+ fsysdep_move_file. This function should return FALSE on error; the
+ zorig file should be removed even if an error occurs. */
+extern boolean fsysdep_move_file P((const char *zorig, const char *zto,
+ boolean fmkdirs, boolean fpublic,
+ boolean fcheck, const char *zuser));
+
+/* Change the mode of a file. The imode argument is a Unix mode.
+ This should return FALSE on error. */
+extern boolean fsysdep_change_mode P((const char *zfile,
+ unsigned int imode));
+
+/* Truncate a file which we are receiving into. This may be done by
+ closing the original file, removing it and reopening it. This
+ should return FALSE on error. */
+extern openfile_t esysdep_truncate P((openfile_t e, const char *zname));
+
+/* It is possible for the acknowledgement of a received file to be
+ lost. The sending system will then now know that the file was
+ correctly received, and will send it again. This can be a problem
+ particularly with protocols which support channels, since they may
+ send several small files in a single window, all of which may be
+ received correctly although the sending system never sees the
+ acknowledgement. If these files involve an execution, the
+ execution will happen twice, which will be bad.
+
+ This function is called when a file is completely received. It is
+ supposed to try and remember the reception, in case the connection
+ is lost. It is passed the system, the file name to receive to, and
+ the temporary file name from the sending system. It should return
+ FALSE on error. */
+extern boolean fsysdep_remember_reception P((const struct uuconf_system *qsys,
+ const char *zto,
+ const char *ztemp));
+
+/* This function is called to see if a file has already been received
+ successfully. It gets the same arguments as
+ fsysdep_remember_reception. It should return TRUE if the file was
+ already received, FALSE otherwise. There is no way to report
+ error. */
+extern boolean fsysdep_already_received P((const struct uuconf_system *qsys,
+ const char *zto,
+ const char *ztemp));
+
+/* This function is called when it is no longer necessary to remember
+ that a file has been received. This will be called when the
+ protocol knows that the receive message has been acknowledged. It
+ gets the same arguments as fsysdep_remember_reception. it should
+ return FALSE on error. */
+extern boolean fsysdep_forget_reception P((const struct uuconf_system *qsys,
+ const char *zto,
+ const char *ztemp));
+
+/* Start expanding a wildcarded file name. This should return FALSE
+ on error; otherwise subsequent calls to zsysdep_wildcard should
+ return file names. */
+extern boolean fsysdep_wildcard_start P((const char *zfile));
+
+/* Get the next wildcard name. This should return NULL when there are
+ no more names to return. The return value should be freed using
+ ubuffree. The argument should be the same as that to
+ fsysdep_wildcard_start. There is no way to return error. */
+extern char *zsysdep_wildcard P((const char *zfile));
+
+/* Finish getting wildcard names. This may be called before or after
+ zsysdep_wildcard has returned NULL. It should return FALSE on
+ error. */
+extern boolean fsysdep_wildcard_end P((void));
+
+/* Prepare to execute a bunch of file transfer requests. This should
+ make an entry in the spool directory so that the next time uucico
+ is started up it will transfer these files. The bgrade argument
+ specifies the grade of the commands. The commands themselves are
+ in the pascmds array, which has ccmds entries. The function should
+ return NULL on error, or the jobid on success. The jobid is a
+ string that may be printed or passed to fsysdep_kill_job and
+ related functions, but is otherwise uninterpreted. */
+extern char *zsysdep_spool_commands P((const struct uuconf_system *qsys,
+ int bgrade, int ccmds,
+ const struct scmd *pascmds));
+
+/* Get a file name to use for a data file to be copied to another
+ system. The ztname, zdname and zxname arguments will all either be
+ NULL or point to an array of CFILE_NAME_LEN characters in length.
+ The ztname array should be set to a temporary file name that could
+ be passed to zsysdep_spool_file_name to retrieve the return value
+ of this function; this will be appropriate for the temporary name
+ in a send request. The zdname array should be set to a data file
+ name that is appropriate for the spool directory of the other
+ system; this will be appropriate for the name of the destination
+ file in a send request of a data file for an execution of some
+ sort. The zxname array should be set to an execute file name that
+ is appropriate for the other system. The zlocalname argument is
+ the name of the local system as seen by the remote system, the
+ bgrade argument is the grade, and fxqt is TRUE if this file is
+ going to become an execution file. This should return NULL on
+ error. */
+#define CFILE_NAME_LEN (15)
+
+extern char *zsysdep_data_file_name P((const struct uuconf_system *qsys,
+ const char *zlocalname,
+ int bgrade, boolean fxqt,
+ char *ztname, char *zdname,
+ char *zxname));
+
+/* Get a name for a local execute file. This is used by uux for a
+ local command with remote files. Returns NULL on error. */
+extern char *zsysdep_xqt_file_name P((void));
+
+/* Beginning getting execute files. To get a list of execute files,
+ first fsysdep_get_xqt_init is called, then zsysdep_get_xqt is
+ called several times until it returns NULL, then finally
+ usysdep_get_xqt_free is called. */
+extern boolean fsysdep_get_xqt_init P((void));
+
+/* Get the next execute file. This should return NULL when finished
+ (with *pferr set to FALSE). On an error this should return NULL
+ with *pferr set to TRUE. This should set *pzsystem to the name of
+ the system for which the execute file was created. Both the return
+ value and *pzsystem should be freed using ubuffree. */
+extern char *zsysdep_get_xqt P((char **pzsystem,
+ boolean *pferr));
+
+/* Clean up after getting execute files. */
+extern void usysdep_get_xqt_free P((void));
+
+/* Get the absolute pathname of a command to execute. This is given
+ the legal list of commands (which may be the special case "ALL")
+ and the path. It must return an absolute pathname to the command.
+ If it gets an error it should set *pferr to TRUE and return NULL;
+ if the command is not found it should set *pferr to FALSE and
+ return NULL. */
+extern char *zsysdep_find_command P((const char *zcmd, char **pzcmds,
+ char **pzpath, boolean *pferr));
+
+/* Expand file names for uuxqt. This exists because uuxqt on Unix has
+ to expand file names which begin with a ~. It does not want to
+ expand any other type of file name, and it turns a double ~ into a
+ single one without expanding. If this returns NULL, the file does
+ not need to be changed; otherwise it returns a zbufalc'ed string.
+ There is no way to report error. */
+extern char *zsysdep_xqt_local_file P((const struct uuconf_system *qsys,
+ const char *zfile));
+
+#if ! ALLOW_FILENAME_ARGUMENTS
+/* Check an argument to an execution command to make sure that it
+ doesn't refer to a file name that may not be accessed. This should
+ check the argument to see if it is a filename. If it is, it should
+ either reject it out of hand or it should call fin_directory_list
+ on the file with both qsys->zremote_receive and qsys->zremote_send.
+ If the file is rejected, it should log an error and return FALSE.
+ Otherwise it should return TRUE. */
+extern boolean fsysdep_xqt_check_file P((const struct uuconf_system *qsys,
+ const char *zfile));
+#endif /* ! ALLOW_FILENAME_ARGUMENTS */
+
+/* Run an execute file. The arguments are:
+
+ qsys -- system for which execute file was created
+ zuser -- user who requested execution
+ pazargs -- list of arguments to command (element 0 is command)
+ zfullcmd -- command and arguments stuck together in one string
+ zinput -- file name for standard input (may be NULL)
+ zoutput -- file name for standard output (may be NULL)
+ fshell -- if TRUE, use /bin/sh to execute file
+ ilock -- return value of ixsysdep_lock_uuxqt
+ pzerror -- set to name of standard error file
+ pftemp -- set to TRUE if error is temporary, FALSE otherwise
+
+ If fshell is TRUE, the command should be executed with /bin/sh
+ (obviously, this can only really be done on Unix systems). If an
+ error occurs this should return FALSE and set *pftemp
+ appropriately. *pzerror should be freed using ubuffree. */
+extern boolean fsysdep_execute P((const struct uuconf_system *qsys,
+ const char *zuser,
+ const char **pazargs,
+ const char *zfullcmd,
+ const char *zinput,
+ const char *zoutput,
+ boolean fshell,
+ int ilock,
+ char **pzerror,
+ boolean *pftemp));
+
+/* Lock for uuxqt execution. If the cmaxuuxqts argument is not zero,
+ this should make sure that no more than cmaxuuxqts uuxqt processes
+ are running at once. Also, only one uuxqt may execute a particular
+ command (specified by the -c option) at a time. If zcmd is not
+ NULL, it is a command that must be locked. This should return a
+ nonnegative number which will be passed to other routines,
+ including fsysdep_unlock_uuxqt, or -1 on error. */
+extern int ixsysdep_lock_uuxqt P((const char *zcmd,
+ int cmaxuuxqts));
+
+/* Unlock a uuxqt process. This is passed the return value of
+ ixsysdep_lock_uuxqt, as well as the arguments passed to
+ ixsysdep_lock_uuxqt. It may return FALSE on error, but at present
+ the return value is ignored. */
+extern boolean fsysdep_unlock_uuxqt P((int iseq, const char *zcmd,
+ int cmaxuuxqts));
+
+/* See whether a particular uuxqt command is locked. This should
+ return TRUE if the command is locked (because ixsysdep_lock_uuxqt
+ was called with it as an argument), FALSE otherwise. There is no
+ way to return error. */
+extern boolean fsysdep_uuxqt_locked P((const char *zcmd));
+
+/* Lock an execute file in order to execute it. This should return
+ FALSE if the execute file is already locked. There is no way to
+ return error. */
+extern boolean fsysdep_lock_uuxqt_file P((const char *zfile));
+
+/* Unlock an execute file. This should return FALSE on error. */
+extern boolean fsysdep_unlock_uuxqt_file P((const char *zfile));
+
+/* Lock the execution directory. The ilock argument is the return
+ value of ixsysdep_lock_uuxqt. This should return FALSE if the
+ directory is already locked. There is no way to return error. */
+extern boolean fsysdep_lock_uuxqt_dir P((int ilock));
+
+/* Remove all files in the execution directory, and unlock it. This
+ should return FALSE on error. */
+extern boolean fsysdep_unlock_uuxqt_dir P((int ilock));
+
+/* Move files into or out of the execution directory. The code will
+ already have checked that all the files exist. The elements in the
+ pzfrom array will be complete filenames, and the elements in the
+ pzto array will be either NULL (in which case the file should not
+ be moved) or simple base names. If fto is TRUE, the files in
+ pzfrom should be moved to pzto; otherwise, the files in pzto should
+ be moved to pzfrom (this is used if a temporary failure occurs, in
+ which case the execution will be retried later). If pzinput and
+ *pzinput are not NULL, then it is the name of the standard input
+ file; if it is the same as any element of pzfrom, then *pzinput
+ should be set to the zbufcpy of the corresponding pzto value, if
+ any. */
+extern boolean fsysdep_move_uuxqt_files P((int cfiles,
+ const char *const *pzfrom,
+ const char *const *pzto,
+ boolean fto, int ilock,
+ char **pzinput));
+
+/* Expand a file name on the local system, defaulting to the current
+ directory. This is just like zsysdep_local_file, except that
+ relative files are placed in the working directory the program
+ started in rather than in the public directory. This should return
+ NULL on error. */
+extern char *zsysdep_local_file_cwd P((const char *zname,
+ const char *zpubdir));
+
+/* Add the working directory to a file name. The named file is
+ actually on a remote system. If the file already has a directory,
+ it should not be changed. This should return NULL on error. */
+extern char *zsysdep_add_cwd P((const char *zfile));
+
+/* See whether a file name will need the current working directory
+ when zsysdep_local_file_cwd or zsysdep_add_cwd is called on it.
+ This will be called before usysdep_initialize. It should just
+ check whether the argument is an absolute path. See the comment
+ above usysdep_initialize in this file for an explanation of why
+ things are done this way. */
+extern boolean fsysdep_needs_cwd P((const char *zfile));
+
+/* Get the base name of a file. The file will be a local file name,
+ and this function should return the base file name, ideally in a
+ form which will make sense on most systems; it will be used if the
+ destination of a uucp is a directory. */
+extern char *zsysdep_base_name P((const char *zfile));
+
+/* Return a filename within a directory. */
+extern char *zsysdep_in_dir P((const char *zdir, const char *zfile));
+
+/* Get the mode of a file. This should return a Unix style file mode.
+ It should return 0 on error. */
+extern unsigned int ixsysdep_file_mode P((const char *zfile));
+
+/* See whether the user has access to a file. This is called by uucp
+ and uux to prevent copying of a file which uucp can read but the
+ user cannot. If access is denied, this should log an error message
+ and return FALSE. */
+extern boolean fsysdep_access P((const char *zfile));
+
+/* See whether the daemon has access to a file. This is called by
+ uucp and uux when a file is queued up for transfer without being
+ copied into the spool directory. It is merely an early error
+ check, as the daemon would of course discover the error itself when
+ it tried the transfer. If access would be denied, this should log
+ an error message and return FALSE. */
+extern boolean fsysdep_daemon_access P((const char *zfile));
+
+/* Translate a destination from system!user to a place in the public
+ directory where uupick will get the file. On Unix this produces
+ system!~/receive/user/localname, and that's probably what it has to
+ produce on any other system as well. Returns NULL on a usage
+ error, or otherwise returns string allocated by zbufcpy. */
+extern char *zsysdep_uuto P((const char *zdest,
+ const char *zlocalname));
+
+/* Return TRUE if a pathname exists and is a directory. */
+extern boolean fsysdep_directory P((const char *zpath));
+
+/* Walk a directory tree. The zdir argument is the directory to walk.
+ The pufn argument is a function to call on each regular file in the
+ tree. The first argument to pufn should be the full filename; the
+ second argument to pufn should be the filename relative to zdir;
+ the third argument to pufn should be the pinfo argument to
+ usysdep_walk_tree. The usysdep_walk_tree function should return
+ FALSE on error. */
+extern boolean usysdep_walk_tree P((const char *zdir,
+ void (*pufn) P((const char *zfull,
+ const char *zrelative,
+ pointer pinfo)),
+ pointer pinfo));
+
+/* Return the jobid of a work file, given the sequence value. On
+ error this should log an error and return NULL. The jobid is a
+ string which may be printed out and read in and passed to
+ fsysdep_kill_job, etc., but is not otherwise interpreted. */
+extern char *zsysdep_jobid P((const struct uuconf_system *qsys,
+ pointer pseq));
+
+/* See whether the current user is permitted to kill jobs submitted by
+ another user. This should return TRUE if permission is granted,
+ FALSE otherwise. */
+extern boolean fsysdep_privileged P((void));
+
+/* Kill a job, given the jobid. This should remove all associated
+ files and in general eliminate the job completely. On error it
+ should log an error message and return FALSE. */
+extern boolean fsysdep_kill_job P((pointer puuconf,
+ const char *zjobid));
+
+/* Rejuvenate a job, given the jobid. If possible, this should update
+ the time associated with the job such that it will not be
+ eliminated by uustat -K or similar programs that check the creation
+ time. This should affect the return value of ixsysdep_work_time.
+ On error it should log an error message and return FALSE. */
+extern boolean fsysdep_rejuvenate_job P((pointer puuconf,
+ const char *zjobid));
+
+/* Get the time a job was queued, given the sequence number. There is
+ no way to indicate error. The return value must use the same epoch
+ as ixsysdep_time. */
+extern long ixsysdep_work_time P((const struct uuconf_system *qsys,
+ pointer pseq));
+
+/* Get the time a file was created. This is called by uustat on
+ execution files. There is no way to indicate error. The return
+ value must use the same epoch as ixsysdep_time. */
+extern long ixsysdep_file_time P((const char *zfile));
+
+/* Get the size in bytes of a file. If this file does not exist, this
+ should not give an error message, but should return -1. If some
+ other error occurs, this should return -2. */
+extern long csysdep_size P((const char *zfile));
+
+/* Return the amount of free space on the containing the given file
+ name (the file may or may not exist). If the amount of free space
+ cannot be determined, the function should return -1. */
+extern long csysdep_bytes_free P((const char *zfile));
+
+/* Start getting status information for all systems with available
+ status information. There may be status information for unknown
+ systems, which is why this series of functions is used. The phold
+ argument is used to pass information around, to possibly avoid the
+ use of static variables. On error this should log an error and
+ return FALSE. */
+extern boolean fsysdep_all_status_init P((pointer *phold));
+
+/* Get status information for the next system. This should return the
+ system name and fill in the qstat argument. The phold argument
+ will be that set by fsysdep_all_status_init. On error this should
+ log an error, set *pferr to TRUE, and return NULL. */
+extern char *zsysdep_all_status P((pointer phold, boolean *pferr,
+ struct sstatus *qstat));
+
+/* Free up anything allocated by fsysdep_all_status_init and
+ zsysdep_all_status. The phold argument is that set by
+ fsysdep_all_status_init. */
+extern void usysdep_all_status_free P((pointer phold));
+
+/* Display the process status of all processes holding lock files.
+ This is uustat -p. The return value is passed to usysdep_exit. */
+extern boolean fsysdep_lock_status P((void));
+
+/* Return TRUE if the user has legitimate access to the port. This is
+ used by cu to control whether the user can open a port directly,
+ rather than merely being able to dial out on it. Opening a port
+ directly allows the modem to be reprogrammed. */
+extern boolean fsysdep_port_access P((struct uuconf_port *qport));
+
+/* Return whether the given port could be named by the given line. On
+ Unix, the line argument would be something like "ttyd0", and this
+ function should return TRUE if the named port is "/dev/ttyd0". */
+extern boolean fsysdep_port_is_line P((struct uuconf_port *qport,
+ const char *zline));
+
+/* Set the terminal into raw mode. In this mode no input characters
+ should be treated specially, and characters should be made
+ available as they are typed. The original terminal mode should be
+ saved, so that it can be restored by fsysdep_terminal_restore. If
+ flocalecho is TRUE, then local echoing should still be done;
+ otherwise echoing should be disabled. This function returns FALSE
+ on error. */
+extern boolean fsysdep_terminal_raw P((boolean flocalecho));
+
+/* Restore the terminal back to the original setting, before
+ fsysdep_terminal_raw was called. Returns FALSE on error. */
+extern boolean fsysdep_terminal_restore P((void));
+
+/* Read a line from the terminal. The fsysdep_terminal_raw function
+ will have been called. This should print the zprompt argument
+ (unless it is NULL) and return the line, allocated by zbufcpy, or
+ NULL on error. */
+extern char *zsysdep_terminal_line P((const char *zprompt));
+
+/* Write a line to the terminal, ending with a newline. This is
+ basically just puts (zline, stdout), except that the terminal will
+ be in raw mode, so on ASCII Unix systems the line needs to end with
+ \r\n. */
+extern boolean fsysdep_terminal_puts P((const char *zline));
+
+/* If faccept is TRUE, permit the user to generate signals from the
+ terminal. If faccept is FALSE, turn signals off again. After
+ fsysdep_terminal_raw is called, signals should be off. Return
+ FALSE on error. */
+extern boolean fsysdep_terminal_signals P((boolean faccept));
+
+/* The cu program expects the system dependent code to handle the
+ details of copying data from the communications port to the
+ terminal. This should be set up by fsysdep_cu_init, and done while
+ fsysdep_cu is called. It is permissible to do it on a continual
+ basis (on Unix a subprocess handles it) so long as the copying can
+ be stopped by the fsysdep_cu_copy function.
+
+ The fsysdep_cu_init function does any system dependent
+ initialization needed for this. */
+extern boolean fsysdep_cu_init P((struct sconnection *qconn));
+
+/* Copy all data from the communications port to the terminal, and all
+ data from the terminal to the communications port. Keep this up
+ until the escape character *zCuvar_escape is seen. Set *pbcmd to
+ the character following the escape character; after the escape
+ character, zlocalname should be printed, possibly after a delay.
+ If two escape characters are entered in sequence, this function
+ should send a single escape character to the port, and not return.
+ Returns FALSE on error. */
+extern boolean fsysdep_cu P((struct sconnection *qconn,
+ char *pbcmd,
+ const char *zlocalname));
+
+/* If fcopy is TRUE, start copying data from the communications port
+ to the terminal. If fcopy is FALSE, stop copying data. This
+ function may be called several times during a cu session. It
+ should return FALSE on error. */
+extern boolean fsysdep_cu_copy P((boolean fcopy));
+
+/* Stop copying data from the communications port to the terminal, and
+ generally clean up after fsysdep_cu_init and fsysdep_cu. Returns
+ FALSE on error. */
+extern boolean fsysdep_cu_finish P((void));
+
+/* Run a shell command. If zcmd is NULL, or *zcmd == '\0', just
+ start up a shell. The second argument is one of the following
+ values. This should return FALSE on error. */
+enum tshell_cmd
+{
+ /* Attach stdin and stdout to the terminal. */
+ SHELL_NORMAL,
+ /* Attach stdout to the communications port, stdin to the terminal. */
+ SHELL_STDOUT_TO_PORT,
+ /* Attach stdin to the communications port, stdout to the terminal. */
+ SHELL_STDIN_FROM_PORT,
+ /* Attach both stdin and stdout to the communications port. */
+ SHELL_STDIO_ON_PORT
+};
+
+extern boolean fsysdep_shell P((struct sconnection *qconn,
+ const char *zcmd,
+ enum tshell_cmd tcmd));
+
+/* Change directory. If zdir is NULL, or *zdir == '\0', change to the
+ user's home directory. Return FALSE on error. */
+extern boolean fsysdep_chdir P((const char *zdir));
+
+/* Suspend the current process. This is only expected to work on Unix
+ versions that support SIGTSTP. In general, people can just shell
+ out. */
+extern boolean fsysdep_suspend P((void));
+
+/* Start getting files for uupick. The zsystem argument may be NULL
+ to get files from all systems, or it may specify a particular
+ system. The zpubdir argument is the public directory to use. This
+ returns FALSE on error. */
+extern boolean fsysdep_uupick_init P((const char *zsystem,
+ const char *zpubdir));
+
+/* Get the next file for uupick. This returns the basic file name.
+ It sets *pzfull to the full name, and *pzfrom to the name of the
+ system which sent this file over; both should be freed using
+ ubuffree. *pzfull should be passed to ubuffree after it is no
+ longer needed. The zsystem and zpubdir arguments should be the
+ same as the arguments to fsysdep_uupick_init. This returns NULL
+ when all files been returned. */
+extern char *zsysdep_uupick P((const char *zsystem, const char *zpubdir,
+ char **pzfrom, char **pzfull));
+
+/* Clean up after getting files for uupick. */
+extern boolean fsysdep_uupick_free P((const char *zsystem,
+ const char *zpubdir));
+
+/* Translate a local file name for uupick. On Unix this is just like
+ zsysdep_local_file_cwd except that a file beginning with ~/ is
+ placed in the user's home directory rather than in the public
+ directory. */
+extern char *zsysdep_uupick_local_file P((const char *zfile));
+
+/* Remove a directory and all the files in it. */
+extern boolean fsysdep_rmdir P((const char *zdir));
+
+#endif /* ! defined (SYSTEM_H) */
diff --git a/gnu/libexec/uucp/common_sources/tcp.c b/gnu/libexec/uucp/common_sources/tcp.c
new file mode 100644
index 000000000000..543e9f0d8205
--- /dev/null
+++ b/gnu/libexec/uucp/common_sources/tcp.c
@@ -0,0 +1,470 @@
+/* tcp.c
+ Code to handle TCP connections.
+
+ Copyright (C) 1991, 1992 Ian Lance Taylor
+
+ This file is part of the Taylor UUCP package.
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ The author of the program may be contacted at ian@airs.com or
+ c/o Infinity Development Systems, P.O. Box 520, Waltham, MA 02254.
+ */
+
+#include "uucp.h"
+
+#if USE_RCS_ID
+const char tcp_rcsid[] = "$Id: tcp.c,v 1.1 1993/08/05 18:22:46 conklin Exp $";
+#endif
+
+#if HAVE_TCP
+
+#include "uudefs.h"
+#include "uuconf.h"
+#include "sysdep.h"
+#include "conn.h"
+#include "system.h"
+
+#include <errno.h>
+
+#if HAVE_SYS_TYPES_TCP_H
+#include <sys/types.tcp.h>
+#endif
+#include <sys/socket.h>
+#include <netdb.h>
+#include <netinet/in.h>
+
+#if HAVE_FCNTL_H
+#include <fcntl.h>
+#else
+#if HAVE_SYS_FILE_H
+#include <sys/file.h>
+#endif
+#endif
+
+#ifndef FD_CLOEXEC
+#define FD_CLOEXEC 1
+#endif
+
+/* This code handles TCP connections. It assumes a Berkeley socket
+ interface. */
+
+/* The normal "uucp" port number. */
+#define IUUCP_PORT (540)
+
+/* Local functions. */
+static void utcp_free P((struct sconnection *qconn));
+static boolean ftcp_open P((struct sconnection *qconn, long ibaud,
+ boolean fwait));
+static boolean ftcp_close P((struct sconnection *qconn,
+ pointer puuconf,
+ struct uuconf_dialer *qdialer,
+ boolean fsuccess));
+static boolean ftcp_reset P((struct sconnection *qconn));
+static boolean ftcp_dial P((struct sconnection *qconn, pointer puuconf,
+ const struct uuconf_system *qsys,
+ const char *zphone,
+ struct uuconf_dialer *qdialer,
+ enum tdialerfound *ptdialer));
+static int itcp_port_number P((const char *zport));
+
+/* The command table for a TCP connection. */
+static const struct sconncmds stcpcmds =
+{
+ utcp_free,
+ NULL, /* pflock */
+ NULL, /* pfunlock */
+ ftcp_open,
+ ftcp_close,
+ ftcp_reset,
+ ftcp_dial,
+ fsysdep_conn_read,
+ fsysdep_conn_write,
+ fsysdep_conn_io,
+ NULL, /* pfbreak */
+ NULL, /* pfset */
+ NULL, /* pfcarrier */
+ fsysdep_conn_chat,
+ NULL /* pibaud */
+};
+
+/* Initialize a TCP connection. */
+
+boolean
+fsysdep_tcp_init (qconn)
+ struct sconnection *qconn;
+{
+ struct ssysdep_conn *q;
+
+ q = (struct ssysdep_conn *) xmalloc (sizeof (struct ssysdep_conn));
+ q->o = -1;
+ q->zdevice = NULL;
+ q->iflags = -1;
+ q->istdout_flags = -1;
+ q->fterminal = FALSE;
+ q->ftli = FALSE;
+ q->ibaud = 0;
+
+ qconn->psysdep = (pointer) q;
+ qconn->qcmds = &stcpcmds;
+ return TRUE;
+}
+
+/* Free a TCP connection. */
+
+static void
+utcp_free (qconn)
+ struct sconnection *qconn;
+{
+ xfree (qconn->psysdep);
+}
+
+/* Open a TCP connection. If the fwait argument is TRUE, we are
+ running as a server. Otherwise we are just trying to reach another
+ system. */
+
+static boolean
+ftcp_open (qconn, ibaud, fwait)
+ struct sconnection *qconn;
+ long ibaud;
+ boolean fwait;
+{
+ struct ssysdep_conn *qsysdep;
+ struct sockaddr_in s;
+ const char *zport;
+ uid_t iuid, ieuid;
+
+ ulog_device ("TCP");
+
+ qsysdep = (struct ssysdep_conn *) qconn->psysdep;
+
+ qsysdep->o = socket (AF_INET, SOCK_STREAM, 0);
+ if (qsysdep->o < 0)
+ {
+ ulog (LOG_ERROR, "socket: %s", strerror (errno));
+ return FALSE;
+ }
+
+ if (fcntl (qsysdep->o, F_SETFD,
+ fcntl (qsysdep->o, F_GETFD, 0) | FD_CLOEXEC) < 0)
+ {
+ ulog (LOG_ERROR, "fcntl (FD_CLOEXEC): %s", strerror (errno));
+ (void) close (qsysdep->o);
+ qsysdep->o = -1;
+ return FALSE;
+ }
+
+ qsysdep->iflags = fcntl (qsysdep->o, F_GETFL, 0);
+ if (qsysdep->iflags < 0)
+ {
+ ulog (LOG_ERROR, "fcntl: %s", strerror (errno));
+ (void) close (qsysdep->o);
+ qsysdep->o = -1;
+ return FALSE;
+ }
+
+ /* If we aren't waiting for a connection, we're done. */
+ if (! fwait)
+ return TRUE;
+
+ /* Run as a server and wait for a new connection. The code in
+ uucico.c has already detached us from our controlling terminal.
+ From this point on if the server gets an error we exit; we only
+ return if we have received a connection. It would be more robust
+ to respawn the server if it fails; someday. */
+ bzero ((pointer) &s, sizeof s);
+ s.sin_family = AF_INET;
+ zport = qconn->qport->uuconf_u.uuconf_stcp.uuconf_zport;
+ s.sin_port = itcp_port_number (zport);
+ s.sin_addr.s_addr = htonl (INADDR_ANY);
+
+ /* Swap to our real user ID when doing the bind call. This will
+ permit the server to use privileged TCP ports when invoked by
+ root. We only swap if our effective user ID is not root, so that
+ the program can also be made suid root in order to get privileged
+ ports when invoked by anybody. */
+ iuid = getuid ();
+ ieuid = geteuid ();
+ if (ieuid != 0)
+ {
+#if HAVE_SETREUID
+ /* Swap the effective user id and the real user id. We can then
+ swap them back again when we want to return to the uucp
+ user's permissions. */
+ if (setreuid (ieuid, iuid) < 0)
+ {
+ ulog (LOG_ERROR, "setreuid (%ld, %ld): %s",
+ (long) ieuid, (long) iuid, strerror (errno));
+ (void) close (qsysdep->o);
+ qsysdep->o = -1;
+ return FALSE;
+ }
+#else /* ! HAVE_SETREUID */
+#if HAVE_SAVED_SETUID
+ /* Set the effective user id to the real user id. Since the
+ effective user id is the saved setuid we will able to set
+ back to it later. If the real user id is root we will not be
+ able to switch back and forth, but that doesn't matter since
+ we only want to switch once. */
+ if (setuid (iuid) < 0)
+ {
+ ulog (LOG_ERROR, "setuid (%ld): %s", (long) iuid,
+ strerror (errno));
+ (void) close (qsysdep->o);
+ qsysdep->o = -1;
+ return FALSE;
+ }
+#else /* ! HAVE_SAVED_SETUID */
+ /* There's no way to switch between real permissions and
+ effective permissions. Just try the bind with the uucp
+ permissions. */
+#endif /* ! HAVE_SAVED_SETUID */
+#endif /* ! HAVE_SETREUID */
+ }
+
+ if (bind (qsysdep->o, (struct sockaddr *) &s, sizeof s) < 0)
+ ulog (LOG_FATAL, "bind: %s", strerror (errno));
+
+ /* Now swap back to the uucp user ID. */
+ if (ieuid != 0)
+ {
+#if HAVE_SETREUID
+ if (setreuid (iuid, ieuid) < 0)
+ {
+ ulog (LOG_ERROR, "setreuid (%ld, %ld): %s",
+ (long) iuid, (long) ieuid, strerror (errno));
+ (void) close (qsysdep->o);
+ qsysdep->o = -1;
+ return FALSE;
+ }
+#else /* ! HAVE_SETREUID */
+#if HAVE_SAVED_SETUID
+ /* Set ourselves back to our original effective user id. */
+ if (setuid ((uid_t) ieuid) < 0)
+ {
+ ulog (LOG_ERROR, "setuid (%ld): %s", (long) ieuid,
+ strerror (errno));
+ (void) close (qsysdep->o);
+ qsysdep->o = -1;
+ return FALSE;
+ }
+#else /* ! HAVE_SAVED_SETUID */
+ /* We didn't switch, no need to switch back. */
+#endif /* ! HAVE_SAVED_SETUID */
+#endif /* ! HAVE_SETREUID */
+ }
+
+ if (listen (qsysdep->o, 5) < 0)
+ ulog (LOG_FATAL, "listen: %s", strerror (errno));
+
+ while (! FGOT_SIGNAL ())
+ {
+ size_t clen;
+ int onew;
+ pid_t ipid;
+
+ DEBUG_MESSAGE0 (DEBUG_PORT,
+ "ftcp_open: Waiting for connections");
+
+ clen = sizeof s;
+ onew = accept (qsysdep->o, (struct sockaddr *) &s, &clen);
+ if (onew < 0)
+ ulog (LOG_FATAL, "accept: %s", strerror (errno));
+
+ DEBUG_MESSAGE0 (DEBUG_PORT,
+ "ftcp_open: Got connection; forking");
+
+ ipid = ixsfork ();
+ if (ipid < 0)
+ ulog (LOG_FATAL, "fork: %s", strerror (errno));
+ if (ipid == 0)
+ {
+ (void) close (qsysdep->o);
+ qsysdep->o = onew;
+
+ /* Now we fork and let our parent die, so that we become
+ a child of init. This lets the main server code wait
+ for its child and then continue without accumulating
+ zombie children. */
+ ipid = ixsfork ();
+ if (ipid < 0)
+ {
+ ulog (LOG_ERROR, "fork: %s", strerror (errno));
+ _exit (EXIT_FAILURE);
+ }
+
+ if (ipid != 0)
+ _exit (EXIT_SUCCESS);
+
+ ulog_id (getpid ());
+
+ return TRUE;
+ }
+
+ (void) close (onew);
+
+ /* Now wait for the child. */
+ (void) ixswait ((unsigned long) ipid, (const char *) NULL);
+ }
+
+ /* We got a signal. */
+ usysdep_exit (FALSE);
+
+ /* Avoid compiler warnings. */
+ return FALSE;
+}
+
+/* Close the port. */
+
+/*ARGSUSED*/
+static boolean
+ftcp_close (qconn, puuconf, qdialer, fsuccess)
+ struct sconnection *qconn;
+ pointer puuconf;
+ struct uuconf_dialer *qdialer;
+ boolean fsuccess;
+{
+ struct ssysdep_conn *qsysdep;
+ boolean fret;
+
+ qsysdep = (struct ssysdep_conn *) qconn->psysdep;
+ fret = TRUE;
+ if (qsysdep->o >= 0 && close (qsysdep->o) < 0)
+ {
+ ulog (LOG_ERROR, "close: %s", strerror (errno));
+ fret = FALSE;
+ }
+ qsysdep->o = -1;
+ return fret;
+}
+
+/* Reset the port. This will be called by a child which was forked
+ off in ftcp_open, above. We don't want uucico to continue looping
+ and giving login prompts, so we pretend that we received a SIGINT
+ signal. This should probably be handled more cleanly. The signal
+ will not be recorded in the log file because we don't set
+ afLog_signal[INDEXSIG_SIGINT]. */
+
+/*ARGSUSED*/
+static boolean
+ftcp_reset (qconn)
+ struct sconnection *qconn;
+{
+ afSignal[INDEXSIG_SIGINT] = TRUE;
+ return TRUE;
+}
+
+/* Dial out on a TCP port, so to speak: connect to a remote computer. */
+
+/*ARGSUSED*/
+static boolean
+ftcp_dial (qconn, puuconf, qsys, zphone, qdialer, ptdialer)
+ struct sconnection *qconn;
+ pointer puuconf;
+ const struct uuconf_system *qsys;
+ const char *zphone;
+ struct uuconf_dialer *qdialer;
+ enum tdialerfound *ptdialer;
+{
+ struct ssysdep_conn *qsysdep;
+ const char *zhost;
+ struct hostent *q;
+ struct sockaddr_in s;
+ const char *zport;
+
+ qsysdep = (struct ssysdep_conn *) qconn->psysdep;
+
+ *ptdialer = DIALERFOUND_FALSE;
+
+ zhost = zphone;
+ if (zhost == NULL)
+ {
+ if (qsys == NULL)
+ {
+ ulog (LOG_ERROR, "No address for TCP connection");
+ return FALSE;
+ }
+ zhost = qsys->uuconf_zname;
+ }
+
+ errno = 0;
+ q = gethostbyname ((char *) zhost);
+ if (q == NULL)
+ {
+ if (errno == 0)
+ ulog (LOG_ERROR, "%s: unknown host name", zhost);
+ else
+ ulog (LOG_ERROR, "gethostbyname (%s): %s", zhost, strerror (errno));
+ return FALSE;
+ }
+
+ s.sin_family = q->h_addrtype;
+ zport = qconn->qport->uuconf_u.uuconf_stcp.uuconf_zport;
+ s.sin_port = itcp_port_number (zport);
+ memcpy (&s.sin_addr.s_addr, q->h_addr, (size_t) q->h_length);
+
+ if (connect (qsysdep->o, (struct sockaddr *) &s, sizeof s) < 0)
+ {
+ ulog (LOG_ERROR, "connect: %s", strerror (errno));
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+/* Get the port number given a name. The argument will almost always
+ be "uucp" so we cache that value. The return value is always in
+ network byte order. This returns -1 on error. */
+
+static int
+itcp_port_number (zname)
+ const char *zname;
+{
+ boolean fuucp;
+ static int iuucp;
+ int i;
+ char *zend;
+ struct servent *q;
+
+ fuucp = strcmp (zname, "uucp") == 0;
+ if (fuucp && iuucp != 0)
+ return iuucp;
+
+ /* Try it as a number first. */
+ i = strtol ((char *) zname, &zend, 10);
+ if (i != 0 && *zend == '\0')
+ return htons (i);
+
+ q = getservbyname ((char *) zname, (char *) "tcp");
+ if (q == NULL)
+ {
+ /* We know that the "uucp" service should be 540, even if isn't
+ in /etc/services. */
+ if (fuucp)
+ {
+ iuucp = htons (IUUCP_PORT);
+ return iuucp;
+ }
+ ulog (LOG_ERROR, "getservbyname (%s): %s", zname, strerror (errno));
+ return -1;
+ }
+
+ if (fuucp)
+ iuucp = q->s_port;
+
+ return q->s_port;
+}
+
+#endif /* HAVE_TCP */
diff --git a/gnu/libexec/uucp/common_sources/tli.c b/gnu/libexec/uucp/common_sources/tli.c
new file mode 100644
index 000000000000..9fffdcdfebd1
--- /dev/null
+++ b/gnu/libexec/uucp/common_sources/tli.c
@@ -0,0 +1,644 @@
+/* tli.c
+ Code to handle TLI connections.
+
+ Copyright (C) 1992 Ian Lance Taylor
+
+ This file is part of the Taylor UUCP package.
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ The author of the program may be contacted at ian@airs.com or
+ c/o Infinity Development Systems, P.O. Box 520, Waltham, MA 02254.
+ */
+
+#include "uucp.h"
+
+#if USE_RCS_ID
+const char tli_rcsid[] = "$Id: tli.c,v 1.1 1993/08/05 18:22:46 conklin Exp $";
+#endif
+
+#if HAVE_TLI
+
+#include "sysdep.h"
+#include "uudefs.h"
+#include "uuconf.h"
+#include "conn.h"
+#include "system.h"
+
+#include <errno.h>
+
+#if HAVE_SYS_IOCTL_H
+#include <sys/ioctl.h>
+#endif
+
+#if HAVE_TIUSER_H
+#include <tiuser.h>
+#else
+#if HAVE_XTI_H
+#include <xti.h>
+#else
+#if HAVE_SYS_TLI_H
+#include <sys/tli.h>
+#endif
+#endif
+#endif
+
+#if HAVE_STROPTS_H
+#include <stropts.h>
+#endif
+
+#if HAVE_FCNTL_H
+#include <fcntl.h>
+#else
+#if HAVE_SYS_FILE_H
+#include <sys/file.h>
+#endif
+#endif
+
+#ifndef O_RDONLY
+#define O_RDONLY 0
+#define O_WRONLY 1
+#define O_RDWR 2
+#endif
+
+#ifndef FD_CLOEXEC
+#define FD_CLOEXEC 1
+#endif
+
+/* The arguments to t_alloca have two different names. I want the
+ SVID ones, not the XPG3 ones. */
+#ifndef T_BIND
+#define T_BIND T_BIND_STR
+#endif
+#ifndef T_CALL
+#define T_CALL T_CALL_STR
+#endif
+
+/* Hopefully these externs will not cause any trouble. This is how
+ they are shown in the SVID. */
+extern int t_errno;
+extern char *t_errlist[];
+extern int t_nerr;
+
+#ifndef t_alloc
+extern pointer t_alloc ();
+#endif
+
+/* This code handles TLI connections. It's Unix specific. It's
+ largely based on code from Unix Network Programming, by W. Richard
+ Stevens. */
+
+/* Local functions. */
+static const char *ztlierror P((void));
+static void utli_free P((struct sconnection *qconn));
+static boolean ftli_push P((struct sconnection *qconn));
+static boolean ftli_open P((struct sconnection *qconn, long ibaud,
+ boolean fwait));
+static boolean ftli_close P((struct sconnection *qconn,
+ pointer puuconf,
+ struct uuconf_dialer *qdialer,
+ boolean fsuccess));
+static boolean ftli_reset P((struct sconnection *qconn));
+static boolean ftli_dial P((struct sconnection *qconn, pointer puuconf,
+ const struct uuconf_system *qsys,
+ const char *zphone,
+ struct uuconf_dialer *qdialer,
+ enum tdialerfound *ptdialer));
+
+/* The command table for a TLI connection. */
+static const struct sconncmds stlicmds =
+{
+ utli_free,
+ NULL, /* pflock */
+ NULL, /* pfunlock */
+ ftli_open,
+ ftli_close,
+ ftli_reset,
+ ftli_dial,
+ fsysdep_conn_read,
+ fsysdep_conn_write,
+ fsysdep_conn_io,
+ NULL, /* pfbreak */
+ NULL, /* pfset */
+ NULL, /* pfcarrier */
+ fsysdep_conn_chat,
+ NULL /* pibaud */
+};
+
+/* Get a TLI error string. */
+
+static const char *
+ztlierror ()
+{
+ if (t_errno == TSYSERR)
+ return strerror (errno);
+ if (t_errno < 0 || t_errno >= t_nerr)
+ return "Unknown TLI error";
+ return t_errlist[t_errno];
+}
+
+/* Initialize a TLI connection. */
+
+boolean
+fsysdep_tli_init (qconn)
+ struct sconnection *qconn;
+{
+ struct ssysdep_conn *q;
+
+ q = (struct ssysdep_conn *) xmalloc (sizeof (struct ssysdep_conn));
+ q->o = -1;
+ q->zdevice = NULL;
+ q->iflags = -1;
+ q->istdout_flags = -1;
+ q->fterminal = FALSE;
+ q->ftli = TRUE;
+ q->ibaud = 0;
+
+ qconn->psysdep = (pointer) q;
+ qconn->qcmds = &stlicmds;
+ return TRUE;
+}
+
+/* Free a TLI connection. */
+
+static void
+utli_free (qconn)
+ struct sconnection *qconn;
+{
+ xfree (qconn->psysdep);
+}
+
+/* Push all desired modules onto a TLI stream. If the user requests a
+ STREAMS connection without giving a list of modules, we just push
+ tirdwr. If the I_PUSH ioctl is not defined on this system, we just
+ ignore any list of modules. */
+
+static boolean
+ftli_push (qconn)
+ struct sconnection *qconn;
+{
+#ifdef I_PUSH
+
+ struct ssysdep_conn *qsysdep;
+
+ qsysdep = (struct ssysdep_conn *) qconn->psysdep;
+
+ if (qconn->qport->uuconf_u.uuconf_stli.uuconf_pzpush != NULL)
+ {
+ char **pz;
+
+ for (pz = qconn->qport->uuconf_u.uuconf_stli.uuconf_pzpush;
+ *pz != NULL;
+ pz++)
+ {
+ if (ioctl (qsysdep->o, I_PUSH, *pz) < 0)
+ {
+ ulog (LOG_ERROR, "ioctl (I_PUSH, %s): %s", *pz,
+ strerror (errno));
+ return FALSE;
+ }
+ }
+ }
+ else if (qconn->qport->uuconf_u.uuconf_stli.uuconf_fstream)
+ {
+ if (ioctl (qsysdep->o, I_PUSH, "tirdwr") < 0)
+ {
+ ulog (LOG_ERROR, "ioctl (I_PUSH, tirdwr): %s",
+ strerror (errno));
+ return FALSE;
+ }
+ }
+
+ /* If we have just put the connection into stream mode, we must turn
+ off the TLI flag to avoid using TLI calls on it. */
+ if (qconn->qport->uuconf_u.uuconf_stli.uuconf_fstream)
+ qsysdep->ftli = FALSE;
+
+#endif /* defined (I_PUSH) */
+
+ return TRUE;
+}
+
+/* Open a TLI connection. If the fwait argument is TRUE, we are
+ running as a server. Otherwise we are just trying to reach another
+ system. */
+
+static boolean
+ftli_open (qconn, ibaud, fwait)
+ struct sconnection *qconn;
+ long ibaud;
+ boolean fwait;
+{
+ struct ssysdep_conn *qsysdep;
+ const char *zdevice;
+ char *zfreedev;
+ const char *zservaddr;
+ char *zfreeaddr;
+ struct t_bind *qtbind;
+ struct t_call *qtcall;
+
+ /* Unlike most other device types, we don't bother to call
+ ulog_device here, because fconn_open calls it with the name of
+ the port anyhow. */
+
+ qsysdep = (struct ssysdep_conn *) qconn->psysdep;
+
+ zdevice = qconn->qport->uuconf_u.uuconf_stli.uuconf_zdevice;
+ if (zdevice == NULL)
+ zdevice = qconn->qport->uuconf_zname;
+
+ zfreedev = NULL;
+ if (*zdevice != '/')
+ {
+ zfreedev = zbufalc (sizeof "/dev/" + strlen (zdevice));
+ sprintf (zfreedev, "/dev/%s", zdevice);
+ zdevice = zfreedev;
+ }
+
+ qsysdep->o = t_open (zdevice, O_RDWR, (struct t_info *) NULL);
+ if (qsysdep->o < 0)
+ {
+ ulog (LOG_ERROR, "t_open (%s): %s", zdevice, ztlierror ());
+ ubuffree (zfreedev);
+ return FALSE;
+ }
+
+ if (fcntl (qsysdep->o, F_SETFD,
+ fcntl (qsysdep->o, F_GETFD, 0) | FD_CLOEXEC) < 0)
+ {
+ ulog (LOG_ERROR, "fcntl (FD_CLOEXEC): %s", strerror (errno));
+ ubuffree (zfreedev);
+ (void) t_close (qsysdep->o);
+ qsysdep->o = -1;
+ return FALSE;
+ }
+
+ qsysdep->iflags = fcntl (qsysdep->o, F_GETFL, 0);
+ if (qsysdep->iflags < 0)
+ {
+ ulog (LOG_ERROR, "fcntl: %s", strerror (errno));
+ ubuffree (zfreedev);
+ (void) t_close (qsysdep->o);
+ qsysdep->o = -1;
+ return FALSE;
+ }
+
+ /* If we aren't waiting for a connection, we can bind to any local
+ address, and then we're finished. */
+ if (! fwait)
+ {
+ ubuffree (zfreedev);
+ if (t_bind (qsysdep->o, (struct t_bind *) NULL,
+ (struct t_bind *) NULL) < 0)
+ {
+ ulog (LOG_ERROR, "t_bind: %s", ztlierror ());
+ (void) t_close (qsysdep->o);
+ qsysdep->o = -1;
+ return FALSE;
+ }
+ return TRUE;
+ }
+
+ /* Run as a server and wait for a new connection. The code in
+ uucico.c has already detached us from our controlling terminal.
+ From this point on if the server gets an error we exit; we only
+ return if we have received a connection. It would be more robust
+ to respawn the server if it fails; someday. */
+ qtbind = (struct t_bind *) t_alloc (qsysdep->o, T_BIND, T_ALL);
+ if (qtbind == NULL)
+ ulog (LOG_FATAL, "t_alloc (T_BIND): %s", ztlierror ());
+
+ zservaddr = qconn->qport->uuconf_u.uuconf_stli.uuconf_zservaddr;
+ if (zservaddr == NULL)
+ ulog (LOG_FATAL, "Can't run as TLI server; no server address");
+
+ zfreeaddr = zbufcpy (zservaddr);
+ qtbind->addr.len = cescape (zfreeaddr);
+ if (qtbind->addr.len > qtbind->addr.maxlen)
+ ulog (LOG_FATAL, "%s: TLI server address too long (max %d)",
+ zservaddr, qtbind->addr.maxlen);
+ memcpy (qtbind->addr.buf, zfreeaddr, qtbind->addr.len);
+ ubuffree (zfreeaddr);
+
+ qtbind->qlen = 5;
+
+ if (t_bind (qsysdep->o, qtbind, (struct t_bind *) NULL) < 0)
+ ulog (LOG_FATAL, "t_bind (%s): %s", zservaddr, ztlierror ());
+
+ (void) t_free ((pointer) qtbind, T_BIND);
+
+ qtcall = (struct t_call *) t_alloc (qsysdep->o, T_CALL, T_ALL);
+ if (qtcall == NULL)
+ ulog (LOG_FATAL, "t_alloc (T_CALL): %s", ztlierror ());
+
+ while (! FGOT_SIGNAL ())
+ {
+ int onew;
+ pid_t ipid;
+
+ DEBUG_MESSAGE0 (DEBUG_PORT,
+ "ftli_open: Waiting for connections");
+
+ if (t_listen (qsysdep->o, qtcall) < 0)
+ ulog (LOG_FATAL, "t_listen: %s", ztlierror ());
+
+ onew = t_open (zdevice, O_RDWR, (struct t_info *) NULL);
+ if (onew < 0)
+ ulog (LOG_FATAL, "t_open (%s): %s", zdevice, ztlierror ());
+
+ if (fcntl (onew, F_SETFD,
+ fcntl (onew, F_GETFD, 0) | FD_CLOEXEC) < 0)
+ ulog (LOG_FATAL, "fcntl (FD_CLOEXEC): %s", strerror (errno));
+
+ if (t_bind (onew, (struct t_bind *) NULL, (struct t_bind *) NULL) < 0)
+ ulog (LOG_FATAL, "t_bind: %s", ztlierror ());
+
+ if (t_accept (qsysdep->o, onew, qtcall) < 0)
+ {
+ /* We may have received a disconnect. */
+ if (t_errno != TLOOK)
+ ulog (LOG_FATAL, "t_accept: %s", ztlierror ());
+ if (t_rcvdis (qsysdep->o, (struct t_discon *) NULL) < 0)
+ ulog (LOG_FATAL, "t_rcvdis: %s", ztlierror ());
+ (void) t_close (onew);
+ continue;
+ }
+
+ DEBUG_MESSAGE0 (DEBUG_PORT,
+ "ftli_open: Got connection; forking");
+
+ ipid = ixsfork ();
+ if (ipid < 0)
+ ulog (LOG_FATAL, "fork: %s", strerror (errno));
+ if (ipid == 0)
+ {
+ ulog_close ();
+
+ (void) t_close (qsysdep->o);
+ qsysdep->o = onew;
+
+ /* Push any desired modules. */
+ if (! ftli_push (qconn))
+ _exit (EXIT_FAILURE);
+
+ /* Now we fork and let our parent die, so that we become
+ a child of init. This lets the main server code wait
+ for its child and then continue without accumulating
+ zombie children. */
+ ipid = ixsfork ();
+ if (ipid < 0)
+ {
+ ulog (LOG_ERROR, "fork: %s", strerror (errno));
+ _exit (EXIT_FAILURE);
+ }
+
+ if (ipid != 0)
+ _exit (EXIT_SUCCESS);
+
+ ulog_id (getpid ());
+
+ return TRUE;
+ }
+
+ (void) t_close (onew);
+
+ /* Now wait for the child. */
+ (void) ixswait ((unsigned long) ipid, (const char *) NULL);
+ }
+
+ /* We got a signal. */
+ usysdep_exit (FALSE);
+
+ /* Avoid compiler warnings. */
+ return FALSE;
+}
+
+/* Close the port. */
+
+/*ARGSUSED*/
+static boolean
+ftli_close (qconn, puuconf, qdialer, fsuccess)
+ struct sconnection *qconn;
+ pointer puuconf;
+ struct uuconf_dialer *qdialer;
+ boolean fsuccess;
+{
+ struct ssysdep_conn *qsysdep;
+ boolean fret;
+
+ qsysdep = (struct ssysdep_conn *) qconn->psysdep;
+
+ fret = TRUE;
+ if (qsysdep->o >= 0)
+ {
+ if (qsysdep->ftli)
+ {
+ if (t_close (qsysdep->o) < 0)
+ {
+ ulog (LOG_ERROR, "t_close: %s", ztlierror ());
+ fret = FALSE;
+ }
+ }
+ else
+ {
+ if (close (qsysdep->o) < 0)
+ {
+ ulog (LOG_ERROR, "close: %s", strerror (errno));
+ fret = FALSE;
+ }
+ }
+
+ qsysdep->o = -1;
+ }
+
+ return fret;
+}
+
+/* Reset the port. This will be called by a child which was forked
+ off in ftli_open, above. We don't want uucico to continue looping
+ and giving login prompts, so we pretend that we received a SIGINT
+ signal. This should probably be handled more cleanly. The signal
+ will not be recorded in the log file because we don't set
+ afLog_signal[INDEXSIG_SIGINT]. */
+
+/*ARGSUSED*/
+static boolean
+ftli_reset (qconn)
+ struct sconnection *qconn;
+{
+ afSignal[INDEXSIG_SIGINT] = TRUE;
+ return TRUE;
+}
+
+/* Dial out on a TLI port, so to speak: connect to a remote computer. */
+
+/*ARGSUSED*/
+static boolean
+ftli_dial (qconn, puuconf, qsys, zphone, qdialer, ptdialerfound)
+ struct sconnection *qconn;
+ pointer puuconf;
+ const struct uuconf_system *qsys;
+ const char *zphone;
+ struct uuconf_dialer *qdialer;
+ enum tdialerfound *ptdialerfound;
+{
+ struct ssysdep_conn *qsysdep;
+ char **pzdialer;
+ const char *zaddr;
+ struct t_call *qtcall;
+ char *zescape;
+
+ qsysdep = (struct ssysdep_conn *) qconn->psysdep;
+
+ *ptdialerfound = DIALERFOUND_FALSE;
+
+ pzdialer = qconn->qport->uuconf_u.uuconf_stli.uuconf_pzdialer;
+ if (*pzdialer == NULL)
+ pzdialer = NULL;
+
+ /* If the first dialer is "TLI" or "TLIS", we use the first token
+ (pzdialer[1]) as the address to connect to. */
+ zaddr = zphone;
+ if (pzdialer != NULL
+ && (strcmp (pzdialer[0], "TLI") == 0
+ || strcmp (pzdialer[0], "TLIS") == 0))
+ {
+ if (pzdialer[1] == NULL)
+ ++pzdialer;
+ else
+ {
+ if (strcmp (pzdialer[1], "\\D") != 0
+ && strcmp (pzdialer[1], "\\T") != 0)
+ zaddr = pzdialer[1];
+ pzdialer += 2;
+ }
+ }
+
+ if (zaddr == NULL)
+ {
+ ulog (LOG_ERROR, "No address for TLI connection");
+ return FALSE;
+ }
+
+ qtcall = (struct t_call *) t_alloc (qsysdep->o, T_CALL, T_ADDR);
+ if (qtcall == NULL)
+ {
+ ulog (LOG_ERROR, "t_alloc (T_CALL): %s", ztlierror ());
+ return FALSE;
+ }
+
+ zescape = zbufcpy (zaddr);
+ qtcall->addr.len = cescape (zescape);
+ if (qtcall->addr.len > qtcall->addr.maxlen)
+ {
+ ulog (LOG_ERROR, "%s: TLI address too long (max %d)", zaddr,
+ qtcall->addr.maxlen);
+ ubuffree (zescape);
+ return FALSE;
+ }
+ memcpy (qtcall->addr.buf, zescape, qtcall->addr.len);
+ ubuffree (zescape);
+
+ if (t_connect (qsysdep->o, qtcall, (struct t_call *) NULL) < 0)
+ {
+ if (t_errno != TLOOK)
+ ulog (LOG_ERROR, "t_connect: %s", ztlierror ());
+ else
+ {
+ if (t_rcvdis (qsysdep->o, (struct t_discon *) NULL) < 0)
+ ulog (LOG_ERROR, "t_rcvdis: %s", ztlierror ());
+ else
+ ulog (LOG_ERROR, "Connection refused");
+ }
+ return FALSE;
+ }
+
+ /* We've connected to the remote. Push any desired modules. */
+ if (! ftli_push (qconn))
+ return FALSE;
+
+ /* Handle the rest of the dialer sequence. This is similar to
+ fmodem_dial, and they should, perhaps, be combined somehow. */
+ if (pzdialer != NULL)
+ {
+ boolean ffirst;
+
+ ffirst = TRUE;
+ while (*pzdialer != NULL)
+ {
+ int iuuconf;
+ struct uuconf_dialer *q;
+ struct uuconf_dialer s;
+ const char *ztoken;
+ boolean ftranslate;
+
+ if (! ffirst)
+ q = &s;
+ else
+ q = qdialer;
+
+ iuuconf = uuconf_dialer_info (puuconf, *pzdialer, q);
+ if (iuuconf == UUCONF_NOT_FOUND)
+ {
+ ulog (LOG_ERROR, "%s: Dialer not found", *pzdialer);
+ return FALSE;
+ }
+ else if (iuuconf != UUCONF_SUCCESS)
+ {
+ ulog_uuconf (LOG_ERROR, puuconf, iuuconf);
+ return FALSE;
+ }
+
+ ++pzdialer;
+ ztoken = *pzdialer;
+
+ ftranslate = FALSE;
+ if (ztoken == NULL
+ || strcmp (ztoken, "\\D") == 0)
+ ztoken = zphone;
+ else if (strcmp (ztoken, "\\T") == 0)
+ {
+ ztoken = zphone;
+ ftranslate = TRUE;
+ }
+
+ if (! fchat (qconn, puuconf, &q->uuconf_schat,
+ (const struct uuconf_system *) NULL, q,
+ zphone, ftranslate, qconn->qport->uuconf_zname,
+ (long) 0))
+ {
+ (void) uuconf_dialer_free (puuconf, q);
+ if (! ffirst)
+ (void) uuconf_dialer_free (puuconf, qdialer);
+ return FALSE;
+ }
+
+ if (ffirst)
+ {
+ *ptdialerfound = DIALERFOUND_FREE;
+ ffirst = FALSE;
+ }
+ else
+ (void) uuconf_dialer_free (puuconf, q);
+
+ if (*pzdialer != NULL)
+ ++pzdialer;
+ }
+ }
+
+ return TRUE;
+}
+
+#endif /* HAVE_TLI */
diff --git a/gnu/libexec/uucp/common_sources/trans.h b/gnu/libexec/uucp/common_sources/trans.h
new file mode 100644
index 000000000000..79c380ea48d8
--- /dev/null
+++ b/gnu/libexec/uucp/common_sources/trans.h
@@ -0,0 +1,268 @@
+/* trans.h
+ Header file for file and command transfer routines.
+
+ Copyright (C) 1992 Ian Lance Taylor
+
+ This file is part of the Taylor UUCP package.
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ The author of the program may be contacted at ian@airs.com or
+ c/o Infinity Development Systems, P.O. Box 520, Waltham, MA 02254.
+ */
+
+/* The maximum possible number of channels. */
+#define IMAX_CHAN (16)
+
+/* The ifeatures field of the sdaemon structure is an or of the
+ following values. These values are sent during the uucico
+ handshake, and MUST NOT CHANGE. */
+
+/* File size negotiation. */
+#define FEATURE_SIZES (01)
+
+/* File transfer restart. */
+#define FEATURE_RESTART (02)
+
+/* The E (execute) command. */
+#define FEATURE_EXEC (04)
+
+/* Version 1.03: requires decimal size in S and R command. Needless
+ to say, this should not be used by any new programs. */
+#define FEATURE_V103 (010)
+
+/* SVR4 UUCP: expects dummy string between notify field and size field
+ in send command. There is probably some meaning to this string,
+ but I don't know what it is. If I ever find out, this flag will
+ still be used to indicate it. */
+#define FEATURE_SVR4 (020)
+
+/* This structure is used to hold information concerning the
+ communication link established with the remote system. */
+
+struct sdaemon
+{
+ /* Global uuconf pointer. */
+ pointer puuconf;
+ /* Remote system information. */
+ const struct uuconf_system *qsys;
+ /* Local name being used. */
+ const char *zlocalname;
+ /* Connection structure. */
+ struct sconnection *qconn;
+ /* Protocol being used. */
+ const struct sprotocol *qproto;
+ /* The largest file size permitted for a local request. */
+ long clocal_size;
+ /* The largest file size permitted for a remote request. */
+ long cremote_size;
+ /* The largest file size that may ever be transferred. */
+ long cmax_ever;
+ /* The remote system ulimit. */
+ long cmax_receive;
+ /* Features supported by the remote side. */
+ int ifeatures;
+ /* TRUE if we should request the remote side to hang up. */
+ boolean frequest_hangup;
+ /* TRUE if the remote side requested a hangup. */
+ boolean fhangup_requested;
+ /* TRUE if we are hanging up. */
+ boolean fhangup;
+ /* TRUE if the local system is currently the master. */
+ boolean fmaster;
+ /* TRUE if the local system placed the call. */
+ boolean fcaller;
+ /* UUCONF_RELIABLE_* flags for the connection. */
+ int ireliable;
+ /* If fcaller is FALSE, the lowest grade which may be transferred
+ during this call. */
+ char bgrade;
+};
+
+/* This structure is used to hold a file or command transfer which is
+ in progress. */
+
+struct stransfer
+{
+ /* Next file transfer in queue. */
+ struct stransfer *qnext;
+ /* Previous file transfer in queue. */
+ struct stransfer *qprev;
+ /* Points to the queue this structure is on. */
+ struct stransfer **pqqueue;
+ /* The function to call to send some data. */
+ boolean (*psendfn) P((struct stransfer *qtrans, struct sdaemon *qdaemon));
+ /* The function to call when data is received. */
+ boolean (*precfn) P((struct stransfer *qtrans, struct sdaemon *qdaemon,
+ const char *zdata, size_t cdata));
+ /* Type specific information. */
+ pointer pinfo;
+ /* TRUE if we are sending the file e (this is used to avoid a call
+ to psendfn). */
+ boolean fsendfile;
+ /* TRUE if we are receiving the file e (this is used to avoid a call
+ to precfn). */
+ boolean frecfile;
+ /* The file to read or write. */
+ openfile_t e;
+ /* The position we are at in the file. */
+ long ipos;
+ /* TRUE if we are waiting for a command string. */
+ boolean fcmd;
+ /* The command string we have so far. */
+ char *zcmd;
+ /* The length of the command string we have so far. */
+ size_t ccmd;
+ /* Local destination number. */
+ int ilocal;
+ /* Remote destination number. */
+ int iremote;
+ /* The command. */
+ struct scmd s;
+ /* A message to log when work starts. */
+ char *zlog;
+ /* The process time; imicros can be negative. */
+ long isecs;
+ long imicros;
+ /* Number of bytes sent or received. */
+ long cbytes;
+};
+
+/* Reasons that a file transfer might fail. */
+
+enum tfailure
+{
+ /* No failure. */
+ FAILURE_NONE,
+ /* No permission for operation. */
+ FAILURE_PERM,
+ /* Can't open necessary file. */
+ FAILURE_OPEN,
+ /* Not enough space to receive file. */
+ FAILURE_SIZE,
+ /* File was received in a previous conversation. */
+ FAILURE_RECEIVED
+};
+
+/* The main loop which talks to the remote system, passing transfer
+ requests and file back and forth. */
+extern boolean floop P((struct sdaemon *qdaemon));
+
+/* Allocate a new transfer structure. */
+extern struct stransfer *qtransalc P((struct scmd *qcmd));
+
+/* Free a transfer structure. */
+extern void utransfree P((struct stransfer *qtrans));
+
+/* Queue up local requests. If pfany is not NULL, this sets *pfany to
+ TRUE if there are, in fact, any local requests which can be done at
+ this point. */
+extern boolean fqueue P((struct sdaemon *qdaemon, boolean *pfany));
+
+/* Clear away any queued requests. This may be called more than once
+ at the end of a call. */
+extern void uclear_queue P((struct sdaemon *qdaemon));
+
+/* Queue a new transfer request made by the local system. */
+extern boolean fqueue_local P((struct sdaemon *qdaemon,
+ struct stransfer *qtrans));
+
+/* Queue a new transfer request made by the remote system. */
+extern boolean fqueue_remote P((struct sdaemon *qdaemon,
+ struct stransfer *qtrans));
+
+/* Queue a transfer request which wants to send something. */
+extern boolean fqueue_send P((struct sdaemon *qdaemon,
+ struct stransfer *qtrans));
+
+/* Queue a transfer request which wants to receiving something. */
+extern boolean fqueue_receive P((struct sdaemon *qdaemon,
+ struct stransfer *qtrans));
+
+/* Prepare to send a file by local or remote request. */
+extern boolean flocal_send_file_init P((struct sdaemon *qdaemon,
+ struct scmd *qcmd));
+extern boolean fremote_send_file_init P((struct sdaemon *qdaemon,
+ struct scmd *qcmd,
+ int iremote));
+
+/* Prepare to receive a file by local or remote request. */
+extern boolean flocal_rec_file_init P((struct sdaemon *qdaemon,
+ struct scmd *qcmd));
+extern boolean fremote_rec_file_init P((struct sdaemon *qdaemon,
+ struct scmd *qcmd,
+ int iremote));
+
+/* Prepare to request work by local or remote request. */
+extern boolean flocal_xcmd_init P((struct sdaemon *qdaemon,
+ struct scmd *qcmd));
+extern boolean fremote_xcmd_init P((struct sdaemon *qdaemon,
+ struct scmd *qcmd,
+ int iremote));
+
+/* We have lost the connection; record any in progress file transfers
+ in the statistics file and discard any temporary files. */
+extern void ufailed P((struct sdaemon *qdaemon));
+
+/* Check that there is enough disk space for a file receive. Return
+ FALSE if there is not. */
+extern boolean frec_check_free P((struct stransfer *qtrans,
+ long cfree_space));
+
+/* Discard the temporary file being used to receive a file, if
+ appropriate. */
+extern boolean frec_discard_temp P((struct sdaemon *qdaemon,
+ struct stransfer *qtrans));
+
+/* Handle data received by a protocol. This is called by the protocol
+ specific routines as data comes in. The data is passed as two
+ buffers because that is convenient for packet based protocols, but
+ normally csecond will be 0. The ilocal argument is the local
+ channel number, and the iremote argument is the remote channel
+ number. Either may be -1, if the protocol does not have channels.
+ The ipos argument is the position in the file, if the protocol
+ knows it; for most protocols, this will be -1. The fallacked
+ argument should be set to TRUE if the remote has acknowledged all
+ outstanding data; see uwindow_acked, below, for details. This will
+ set *pfexit to TRUE if there is something for the main loop to do.
+ A file is complete is when a zero length buffer is passed (cfirst
+ == 0). A command is complete when data containing a null byte is
+ passed. This will return FALSE on error. If the protocol pfwait
+ entry point should exit and let the top level loop continue,
+ *pfexit will be set to TRUE (if pfexit is not NULL). This will not
+ set *pfexit to FALSE, so the caller must do that. */
+extern boolean fgot_data P((struct sdaemon *qdaemon,
+ const char *zfirst, size_t cfirst,
+ const char *zsecond, size_t csecond,
+ int ilocal, int iremote,
+ long ipos, boolean fallacked,
+ boolean *pfexit));
+
+/* This routine is called when an ack is sent for a file receive. */
+extern void usent_receive_ack P((struct sdaemon *qdaemon,
+ struct stransfer *qtrans));
+
+/* A protocol may call this routine to indicate the packets have been
+ acknowledged by the remote system. If the fallacked argument is
+ TRUE, then all outstanding packets have been acknowledged; for
+ convenience, this may also be indicated by passing fallacked as
+ TRUE to fgot_data, above. Otherwise this routine should be called
+ each time a complete window is acked by the remote system. The
+ transfer code uses this information to keep track of when an
+ acknowledgement of a file receive has been seen by the other side,
+ so that file receives may be handled cleanly if the connection is
+ lost. */
+extern void uwindow_acked P((struct sdaemon *qdaemon,
+ boolean fallacked));
diff --git a/gnu/libexec/uucp/common_sources/util.c b/gnu/libexec/uucp/common_sources/util.c
new file mode 100644
index 000000000000..89b3caf1d446
--- /dev/null
+++ b/gnu/libexec/uucp/common_sources/util.c
@@ -0,0 +1,144 @@
+/* util.c
+ A couple of UUCP utility functions.
+
+ Copyright (C) 1991, 1992 Ian Lance Taylor
+
+ This file is part of the Taylor UUCP package.
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ The author of the program may be contacted at ian@airs.com or
+ c/o Infinity Development Systems, P.O. Box 520, Waltham, MA 02254.
+ */
+
+#include "uucp.h"
+
+#if USE_RCS_ID
+const char util_rcsid[] = "$Id: util.c,v 1.1 1993/08/05 18:22:48 conklin Exp $";
+#endif
+
+#include <ctype.h>
+
+#include "uudefs.h"
+#include "uuconf.h"
+#include "system.h"
+
+/* Get information for an unknown system. This will leave the name
+ allocated on the heap. We could fix this by breaking the
+ abstraction and adding the name to qsys->palloc. It makes sure the
+ name is not too long, but takes no other useful action. */
+
+boolean
+funknown_system (puuconf, zsystem, qsys)
+ pointer puuconf;
+ const char *zsystem;
+ struct uuconf_system *qsys;
+{
+ char *z;
+ int iuuconf;
+
+ if (strlen (zsystem) <= cSysdep_max_name_len)
+ z = zbufcpy (zsystem);
+ else
+ {
+ char **pznames, **pz;
+ boolean ffound;
+
+ z = zbufalc (cSysdep_max_name_len + 1);
+ memcpy (z, zsystem, cSysdep_max_name_len);
+ z[cSysdep_max_name_len] = '\0';
+
+ iuuconf = uuconf_system_names (puuconf, &pznames, TRUE);
+ if (iuuconf != UUCONF_SUCCESS)
+ ulog_uuconf (LOG_FATAL, puuconf, iuuconf);
+
+ ffound = FALSE;
+ for (pz = pznames; *pz != NULL; pz++)
+ {
+ if (strcmp (*pz, z) == 0)
+ ffound = TRUE;
+ xfree ((pointer) *pz);
+ }
+ xfree ((pointer) pznames);
+
+ if (ffound)
+ {
+ ubuffree (z);
+ return FALSE;
+ }
+ }
+
+ iuuconf = uuconf_system_unknown (puuconf, qsys);
+ if (iuuconf == UUCONF_NOT_FOUND)
+ {
+ ubuffree (z);
+ return FALSE;
+ }
+ else if (iuuconf != UUCONF_SUCCESS)
+ ulog_uuconf (LOG_FATAL, puuconf, iuuconf);
+
+ for (; qsys != NULL; qsys = qsys->uuconf_qalternate)
+ qsys->uuconf_zname = z;
+
+ return TRUE;
+}
+
+/* See whether a file is in a directory list, and make sure the user
+ has appropriate access. */
+
+boolean
+fin_directory_list (zfile, pzdirs, zpubdir, fcheck, freadable, zuser)
+ const char *zfile;
+ char **pzdirs;
+ const char *zpubdir;
+ boolean fcheck;
+ boolean freadable;
+ const char *zuser;
+{
+ boolean fmatch;
+ char **pz;
+
+ fmatch = FALSE;
+
+ for (pz = pzdirs; *pz != NULL; pz++)
+ {
+ char *zuse;
+
+ if (pz[0][0] == '!')
+ {
+ zuse = zsysdep_local_file (*pz + 1, zpubdir);
+ if (zuse == NULL)
+ return FALSE;
+
+ if (fsysdep_in_directory (zfile, zuse, FALSE,
+ FALSE, (const char *) NULL))
+ fmatch = FALSE;
+ }
+ else
+ {
+ zuse = zsysdep_local_file (*pz, zpubdir);
+ if (zuse == NULL)
+ return FALSE;
+
+ if (fsysdep_in_directory (zfile, zuse, fcheck,
+ freadable, zuser))
+ fmatch = TRUE;
+ }
+
+ ubuffree (zuse);
+ }
+
+ return fmatch;
+}
diff --git a/gnu/libexec/uucp/common_sources/uuconf.h b/gnu/libexec/uucp/common_sources/uuconf.h
new file mode 100644
index 000000000000..4bf6bccbf3f2
--- /dev/null
+++ b/gnu/libexec/uucp/common_sources/uuconf.h
@@ -0,0 +1,1496 @@
+/* uuconf.h
+ Header file for UUCP configuration routines.
+
+ Copyright (C) 1992 Ian Lance Taylor
+
+ This file is part of the Taylor UUCP uuconf library.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License
+ as published by the Free Software Foundation; either version 2 of
+ the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ The use of an object file which uses material from this header
+ file, and from no other portion of the uuconf library, is
+ unrestricted, as described in paragraph 4 of section 5 of version 2
+ of the GNU Library General Public License (this sentence is merely
+ informative, and does not modify the License in any way).
+
+ The author of the program may be contacted at ian@airs.com or
+ c/o Infinity Development Systems, P.O. Box 520, Waltham, MA 02254.
+ */
+
+#ifndef UUCONF_H
+
+#define UUCONF_H
+
+#include <stdio.h>
+
+/* The macro UUCONF_ANSI_C may be used to override __STDC__. */
+#ifndef UUCONF_ANSI_C
+#ifdef __STDC__
+#define UUCONF_ANSI_C 1
+#else /* ! defined (__STDC__) */
+#define UUCONF_ANSI_C 0
+#endif /* ! defined (__STDC__) */
+#endif /* ! defined (UUCONF_ANSI_C) */
+
+#if UUCONF_ANSI_C
+#define UUCONF_CONST const
+typedef void *UUCONF_POINTER;
+#include <stddef.h>
+typedef size_t UUCONF_SIZE_T;
+#else
+#define UUCONF_CONST
+typedef char *UUCONF_POINTER;
+typedef unsigned int UUCONF_SIZE_T;
+#endif
+
+/* The field names of each of the following structures begin with
+ "uuconf_". This is to avoid any conflicts with user defined
+ macros. The first character following the "uuconf_" string
+ indicates the type of the field.
+
+ z -- a string (char *)
+ c -- a count (normally int)
+ i -- an integer value (normally int)
+ f -- a boolean value (normally int)
+ b -- a single character value (char or int)
+ t -- an enum (enum XX)
+ s -- a structure (struct XX)
+ u -- a union (union XX)
+ q -- a pointer to a structure (struct XX *)
+ p -- a pointer to something other than a string
+ */
+
+/* The information which is kept for a chat script. */
+
+struct uuconf_chat
+{
+ /* The script itself. This is a NULL terminated list of expect/send
+ pairs. The first string is an expect string. A string starting
+ with a '-' indicates subsend string; the following strings which
+ start with '-' are subexpect/subsend strings. This field may be
+ NULL, in which case there is no chat script (but pzprogram may
+ hold a program to run). */
+ char **uuconf_pzchat;
+ /* The chat program to run. This is a NULL terminated list of
+ arguments; element 0 if the program. May be NULL, in which case
+ there is no program. */
+ char **uuconf_pzprogram;
+ /* The timeout in seconds to use for expect strings in the chat
+ script. */
+ int uuconf_ctimeout;
+ /* The NULL terminated list of failure strings. If any of these
+ strings appear, the chat script is aborted. May be NULL, in
+ which case there are no failure strings. */
+ char **uuconf_pzfail;
+ /* Non-zero if incoming characters should be stripped to seven bits
+ (by anding with 0x7f). */
+ int uuconf_fstrip;
+};
+
+/* The information which is kept for a time specification. This is a
+ linked list of structures. Each element of the list represents a
+ span of time, giving a starting time and an ending time. The time
+ only depends on the day of the week, not on the day of the month or
+ of the year. The time is only specified down to the minute, not
+ down to the second or below. The list is sorted by starting time.
+
+ The starting and ending time are expressed in minutes since the
+ beginning of the week, which is considered to be 12 midnight on
+ Sunday. Thus 60 is 1 am on Sunday, 1440 (== 60 * 24) is 12
+ midnight on Monday, and the largest possible value is 10080 (== 60
+ * 24 * 7) which is 12 midnight on the following Sunday.
+
+ Each span of time has a value associated with it. This is the
+ lowest grade or the largest file size that may be transferred
+ during that time, depending on the source of the time span. When
+ time specifications overlap, the value used for the overlap is the
+ higher grade or the smaller file size. Thus specifying
+ ``call-timegrade z Any'' and ``call-timegrade Z Mo'' means that
+ only grade Z or higher may be sent on Monday, since Z is the higer
+ grade of the overlapping spans. The final array wil have no
+ overlaps.
+
+ Each span also has a retry time associated with it. This permits
+ different retry times to be used at different times of day. The
+ retry time is only relevant if the span came from a ``time'' or
+ ``timegrade'' command for a system. */
+
+struct uuconf_timespan
+{
+ /* Next element in list. */
+ struct uuconf_timespan *uuconf_qnext;
+ /* Starting minute (-1 at the end of the array). */
+ int uuconf_istart;
+ /* Ending minute. */
+ int uuconf_iend;
+ /* Value for this span (lowest grade or largest file that may be
+ transferred at this time). */
+ long uuconf_ival;
+ /* Retry time. */
+ int uuconf_cretry;
+};
+
+/* The information which is kept for protocol parameters. Protocol
+ parameter information is stored as an array of the following
+ structures. */
+
+struct uuconf_proto_param
+{
+ /* The name of the protocol to which this entry applies. This is
+ '\0' for the last element of the array. */
+ int uuconf_bproto;
+ /* Specific entries for this protocol. This points to an array
+ ending in an element with a uuconf_cargs field of 0. */
+ struct uuconf_proto_param_entry *uuconf_qentries;
+};
+
+/* Each particular protocol parameter entry is one of the following
+ structures. */
+
+struct uuconf_proto_param_entry
+{
+ /* The number of arguments to the ``protocol-parameter'' command
+ (not counting ``protocol-parameter'' itself). This is 0 for the
+ last element of the array. */
+ int uuconf_cargs;
+ /* The actual arguments to the ``protocol-parameter'' command; this
+ is an array with cargs entries. */
+ char **uuconf_pzargs;
+};
+
+/* The information which is kept for a system. The zname and zalias
+ fields will be the same for all alternates. Every other fields is
+ specific to the particular alternate in which it appears (although
+ most will be the same for all alternates). */
+
+struct uuconf_system
+{
+ /* The name of the system. */
+ char *uuconf_zname;
+ /* A list of aliases for the system. This is a NULL terminated list
+ of strings. May be NULL, in which case there are no aliases. */
+ char **uuconf_pzalias;
+ /* A linked list of alternate call in or call out information. Each
+ alternative way to call this system occupies an element of this
+ list. May be NULL, in which case there are no alternates. */
+ struct uuconf_system *uuconf_qalternate;
+ /* The name for this particular alternate. May be NULL, in which
+ case this alternate does not have a name. */
+ char *uuconf_zalternate;
+ /* If non-zero, this alternate may be used for calling out. */
+ int uuconf_fcall;
+ /* If non-zero, this alternate may be used for accepting a call. */
+ int uuconf_fcalled;
+ /* The times at which this system may be called. The ival field of
+ each uuconf_timespan structure is the lowest grade which may be
+ transferred at that time. The cretry field is the number of
+ minutes to wait before retrying the call, or 0 if it was not
+ specified. May be NULL, in which case the system may never be
+ called. */
+ struct uuconf_timespan *uuconf_qtimegrade;
+ /* The times at which to request a particular grade of the system
+ when calling it, and the grades to request. The ival field of
+ each uuconf_timespan structure is the lowest grade which the
+ other system should transfer at that time. May be NULL, in which
+ case there are no grade restrictions. */
+ struct uuconf_timespan *uuconf_qcalltimegrade;
+ /* The maximum number of times to retry calling this system. If
+ this is 0, there is no limit. */
+ int uuconf_cmax_retries;
+ /* The number of minutes to wait between successful calls to a
+ system. */
+ int uuconf_csuccess_wait;
+ /* The size restrictions by time for local requests during a locally
+ placed call. The ival field of each uuconf_timespan structure is
+ the size in bytes of the largest file which may be transferred at
+ that time. May be NULL, in which case there are no size
+ restrictions. */
+ struct uuconf_timespan *uuconf_qcall_local_size;
+ /* The size restrictions by time for remote requests during a
+ locally placed call. May be NULL. */
+ struct uuconf_timespan *uuconf_qcall_remote_size;
+ /* The size restrictions by time for local requests during a
+ remotely placed call. May be NULL. */
+ struct uuconf_timespan *uuconf_qcalled_local_size;
+ /* The size restrictions by time for remote requests during a
+ remotely placed call. May be NULL. */
+ struct uuconf_timespan *uuconf_qcalled_remote_size;
+ /* Baud rate, or speed. Zero means any baud rate. If ihighbaud is
+ non-zero, this is the low baud rate of a range. */
+ long uuconf_ibaud;
+ /* If non-zero, ibaud is the low baud rate of a range and ihighbaud
+ is the high baud rate. */
+ long uuconf_ihighbaud;
+ /* Port name to use. May be NULL. If an HDB configuration file
+ contains a modem class (alphabetic characters preceeding the baud
+ rate), the class is appended to the port name. */
+ char *uuconf_zport;
+ /* Specific port information, if the system entry includes port
+ information. May be NULL. */
+ struct uuconf_port *uuconf_qport;
+ /* Phone number to call, or address to use for a TCP connection.
+ May be NULL, in which case a dialer script may not use \D or \T
+ for this system, and a TCP port will use the system name. */
+ char *uuconf_zphone;
+ /* Chat script to use when logging in to the system. */
+ struct uuconf_chat uuconf_schat;
+ /* Login name to use for \L in the login chat script. This should
+ normally be accessed via uuconf_callout. If it is "*",
+ uuconf_callout will look it up in the call out file. This may be
+ NULL, in which case the login script may not use \L. */
+ char *uuconf_zcall_login;
+ /* Password to use for \P in the login chat script. This should
+ normally be accessed via uuconf_callout. If it is "*",
+ uuconf_callout will look it up in the call out file. This may be
+ NULL, in which case the login script may not use \P. */
+ char *uuconf_zcall_password;
+ /* The login name this system must use when calling in. This may be
+ different for different alternates. This should only be examined
+ if uuconf_fcalled is TRUE. If this is NULL or "ANY" then
+ uuconf_validate must be called to make sure that whatever login
+ name was used is permitted for this machine. */
+ char *uuconf_zcalled_login;
+ /* If non-zero, then when this system calls in the call should not
+ be allowed to proceed and the system should be called back. */
+ int uuconf_fcallback;
+ /* If non-zero, then conversation sequence numbers should be used
+ with this system. */
+ int uuconf_fsequence;
+ /* A list of protocols to use with this system. Each protocol has a
+ single character name. May be NULL, in which case any known
+ protocol may be used. */
+ char *uuconf_zprotocols;
+ /* Array of protocol parameters. Ends in an entry with a
+ uuconf_bproto field of '\0'. May be NULL. */
+ struct uuconf_proto_param *uuconf_qproto_params;
+ /* Chat script to run when called by this system. */
+ struct uuconf_chat uuconf_scalled_chat;
+ /* Debugging level to set during a conversation. May be NULL. */
+ char *uuconf_zdebug;
+ /* Maximum remote debugging level this system may request. May be
+ NULL. */
+ char *uuconf_zmax_remote_debug;
+ /* Non-zero if the remote system may request us to send files from
+ the local system to the remote. */
+ int uuconf_fsend_request;
+ /* Non-zero if the remote system may request us to receive files
+ from the remote system to the local. */
+ int uuconf_frec_request;
+ /* Non-zero if local requests are permitted when calling this
+ system. */
+ int uuconf_fcall_transfer;
+ /* Non-zero if local requests are permitted when this system calls
+ in. */
+ int uuconf_fcalled_transfer;
+ /* NULL terminated list of directories from which files may be sent
+ by local request. */
+ char **uuconf_pzlocal_send;
+ /* NULL terminated list of directories from which files may be sent
+ by remote request. */
+ char **uuconf_pzremote_send;
+ /* NULL terminated list of directories into which files may be
+ received by local request. */
+ char **uuconf_pzlocal_receive;
+ /* NULL terminated list of directories into which files may be
+ received by remote request. */
+ char **uuconf_pzremote_receive;
+ /* Path to use for command execution. This is a NULL terminated
+ list of directories. */
+ char **uuconf_pzpath;
+ /* NULL terminated List of commands that may be executed. */
+ char **uuconf_pzcmds;
+ /* Amount of free space to leave when accepting a file from this
+ system, in bytes. */
+ long uuconf_cfree_space;
+ /* NULL terminated list of systems that this system may forward
+ from. May be NULL if there are no systems from which files may
+ be forwarded. The list may include "ANY". */
+ char **uuconf_pzforward_from;
+ /* NULL terminated list of systems that this system may forward to.
+ May be NULL if there are no systems to which files may be
+ forwarded. The list may include "ANY". */
+ char **uuconf_pzforward_to;
+ /* The public directory to use for this sytem. */
+ const char *uuconf_zpubdir;
+ /* The local name to use for this remote system. May be NULL if the
+ usual local name should be used. */
+ char *uuconf_zlocalname;
+ /* Memory allocation block for the system. */
+ UUCONF_POINTER uuconf_palloc;
+};
+
+/* Types of ports. */
+
+enum uuconf_porttype
+{
+ /* Unknown port type. A port of this type should never be returned
+ by the uuconf functions. */
+ UUCONF_PORTTYPE_UNKNOWN,
+ /* Read from standard input and write to standard output. Not
+ normally used. */
+ UUCONF_PORTTYPE_STDIN,
+ /* A modem port. */
+ UUCONF_PORTTYPE_MODEM,
+ /* A direct connect port. */
+ UUCONF_PORTTYPE_DIRECT,
+ /* A TCP port. Not supported on all systems. */
+ UUCONF_PORTTYPE_TCP,
+ /* A TLI port. Not supported on all systems. */
+ UUCONF_PORTTYPE_TLI
+};
+
+/* Additional information for a stdin port (there is none). */
+
+struct uuconf_stdin_port
+{
+ int uuconf_idummy;
+};
+
+/* Additional information for a modem port. */
+
+struct uuconf_modem_port
+{
+ /* The device name. May be NULL, in which case the port name is
+ used instead. */
+ char *uuconf_zdevice;
+ /* The device name to send the dialer chat script to. May be NULL,
+ in which case the chat script is sent to the usual device. */
+ char *uuconf_zdial_device;
+ /* The default baud rate (speed). If zero, there is no default. */
+ long uuconf_ibaud;
+ /* The low baud rate, if a range is used. If zero, a range is not
+ used and ihighbaud should be ignored. */
+ long uuconf_ilowbaud;
+ /* The high baud rate, if ilowbaud is non-zero. */
+ long uuconf_ihighbaud;
+ /* Non-zero if the port supports carrier detect. */
+ int uuconf_fcarrier;
+ /* A NULL terminated sequence of dialer/token pairs (element 0 is a
+ dialer name, element 1 is a token, etc.) May be NULL, in which
+ case qdialer should not be NULL. */
+ char **uuconf_pzdialer;
+ /* Specific dialer information. Only used if pzdialer is NULL. */
+ struct uuconf_dialer *uuconf_qdialer;
+};
+
+/* Additional information for a direct connect port. */
+
+struct uuconf_direct_port
+{
+ /* The device name. May be NULL, in which case the port name is
+ used instead. */
+ char *uuconf_zdevice;
+ /* The baud rate (speed). */
+ long uuconf_ibaud;
+};
+
+/* Additional information for a TCP port. */
+
+struct uuconf_tcp_port
+{
+ /* The TCP port number to use. May be a name or a number. May be
+ NULL, in which case "uucp" is looked up using getservbyname. */
+ char *uuconf_zport;
+};
+
+/* Additional information for a TLI port. */
+
+struct uuconf_tli_port
+{
+ /* Device name to open. May be NULL, in which case the port name is
+ used. */
+ char *uuconf_zdevice;
+ /* Whether this port should be turned into a stream, permitting the
+ read and write calls instead of the t_rcv and t_send calls. */
+ int uuconf_fstream;
+ /* A NULL terminated list of modules to push after making the
+ connection. May be NULL, in which case if fstream is non-zero,
+ then "tirdwr" is pushed onto the stream, and otherwise nothing is
+ pushed. */
+ char **uuconf_pzpush;
+ /* A NULL terminated sequence of dialer/token pairs (element 0 is a
+ dialer name, element 1 is a token, etc.) May be NULL. If
+ element 0 is TLI or TLIS, element 1 is used as the address to
+ connect to; otherwise uuconf_zphone from the system information
+ is used. */
+ char **uuconf_pzdialer;
+ /* Address to use when operating as a server. This may contain
+ escape sequences. */
+ char *uuconf_zservaddr;
+};
+
+/* Information kept for a port. */
+
+struct uuconf_port
+{
+ /* The name of the port. */
+ char *uuconf_zname;
+ /* The type of the port. */
+ enum uuconf_porttype uuconf_ttype;
+ /* The list of protocols supported by the port. The name of each
+ protocol is a single character. May be NULL, in which case any
+ protocol is permitted. */
+ char *uuconf_zprotocols;
+ /* Array of protocol parameters. Ends in an entry with a
+ uuconf_bproto field of '\0'. May be NULL. */
+ struct uuconf_proto_param *uuconf_qproto_params;
+ /* The set of reliability bits. */
+ int uuconf_ireliable;
+ /* The lock file name to use. */
+ char *uuconf_zlockname;
+ /* Memory allocation block for the port. */
+ UUCONF_POINTER uuconf_palloc;
+ /* The type specific information. */
+ union
+ {
+ struct uuconf_stdin_port uuconf_sstdin;
+ struct uuconf_modem_port uuconf_smodem;
+ struct uuconf_direct_port uuconf_sdirect;
+ struct uuconf_tcp_port uuconf_stcp;
+ struct uuconf_tli_port uuconf_stli;
+ } uuconf_u;
+};
+
+/* Information kept about a dialer. */
+
+struct uuconf_dialer
+{
+ /* The name of the dialer. */
+ char *uuconf_zname;
+ /* The chat script to use when dialing out. */
+ struct uuconf_chat uuconf_schat;
+ /* The string to send when a `=' appears in the phone number. */
+ char *uuconf_zdialtone;
+ /* The string to send when a `-' appears in the phone number. */
+ char *uuconf_zpause;
+ /* Non-zero if the dialer supports carrier detect. */
+ int uuconf_fcarrier;
+ /* The number of seconds to wait for carrier after the chat script
+ is complete. Only used if fcarrier is non-zero. Only supported
+ on some systems. */
+ int uuconf_ccarrier_wait;
+ /* If non-zero, DTR should be toggled before dialing. Only
+ supported on some systems. */
+ int uuconf_fdtr_toggle;
+ /* If non-zero, sleep for 1 second after toggling DTR. Ignored if
+ fdtr_toggle is zero. */
+ int uuconf_fdtr_toggle_wait;
+ /* The chat script to use when a call is complete. */
+ struct uuconf_chat uuconf_scomplete;
+ /* The chat script to use when a call is aborted. */
+ struct uuconf_chat uuconf_sabort;
+ /* Array of protocol parameters. Ends in an entry with a
+ uuconf_bproto field of '\0'. May be NULL. */
+ struct uuconf_proto_param *uuconf_qproto_params;
+ /* The set of reliability bits. */
+ int uuconf_ireliable;
+ /* Memory allocation block for the dialer. */
+ UUCONF_POINTER uuconf_palloc;
+};
+
+/* Reliability bits for the ireliable field of ports and dialers.
+ These bits are used to decide which protocol to run. A given
+ protocol will have a set of these bits, and each of them must be
+ turned on for the port before we will permit that protocol to be
+ used. This will be overridden by the zprotocols field. */
+
+/* Whether a set of reliability bits is given. If this bit is not
+ set, then there is no reliability information. */
+#define UUCONF_RELIABLE_SPECIFIED (01)
+
+/* Set if the connection is eight bit transparent. */
+#define UUCONF_RELIABLE_EIGHT (02)
+
+/* Set if the connection is error-free. */
+#define UUCONF_RELIABLE_RELIABLE (04)
+
+/* Set if the connection is end-to-end reliable (e.g. TCP). */
+#define UUCONF_RELIABLE_ENDTOEND (010)
+
+/* Set if the connection is full-duplex; that is, no time consuming
+ line turnaround is required before sending data in the reverse
+ direction. If the connection is truly half-duplex, in the sense
+ that communication can only flow in one direction, UUCP can not be
+ used. */
+#define UUCONF_RELIABLE_FULLDUPLEX (020)
+
+/* UUCP grades range from 0 to 9, A to Z, a to z in order from highest
+ to lowest (work of higher grades is done before work of lower
+ grades). */
+
+/* The highest grade. */
+#define UUCONF_GRADE_HIGH ('0')
+
+/* The lowest grade. */
+#define UUCONF_GRADE_LOW ('z')
+
+/* Whether a character is a legal grade (requires <ctype.h>). */
+#define UUCONF_GRADE_LEGAL(b) (isalnum ((unsigned) (b)))
+
+/* Return < 0 if the first grade should be done before the second
+ grade, == 0 if they are the same, or > 0 if the first grade should
+ be done after the second grade. On an ASCII system, this can just
+ be b1 - b2. */
+#define UUCONF_GRADE_CMP(b1, b2) (uuconf_grade_cmp ((b1), (b2)))
+
+/* Most of the uuconf functions returns an error code. A value of
+ zero (UUCONF_SUCCESS) indicates success. */
+
+/* If this bit is set in the returned error code, then the
+ uuconf_errno function may be used to obtain the errno value as set
+ by the function which caused the failure. */
+#define UUCONF_ERROR_ERRNO (0x100)
+
+/* If this bit is set in the returned error code, then the
+ uuconf_filename function may be used to get the name of a file
+ associated with the error. */
+#define UUCONF_ERROR_FILENAME (0x200)
+
+/* If this bit is set in the returned error code, then the
+ uuconf_lineno function may be used to get a line number associated
+ with the error; normally if this is set UUCONF_ERROR_FILENAME will
+ also be set. */
+#define UUCONF_ERROR_LINENO (0x400)
+
+/* There are two UUCONF_CMDTABRET bits that may be set in the return
+ value of uuconf_cmd_line or uuconf_cmd_args, described below. They
+ do not indicate an error, but instead give instructions to the
+ calling function, often uuconf_cmd_file. They may also be set in
+ the return value of a user function listed in a uuconf_cmdtab
+ table, in which case they will be honored by uuconf_cmd_file. */
+
+/* This bit means that the memory occupied by the arguments passed to
+ the function should be preserved, and not overwritten or freed. It
+ refers only to the contents of the arguments; the contents of the
+ argv array itself may always be destroyed. If this bit is set in
+ the return value of uuconf_cmd_line or uuconf_cmd_args, it must be
+ honored. It will be honored by uuconf_cmd_file. This may be
+ combined with an error code or with UUCONF_CMDTABRET_EXIT, although
+ neither uuconf_cmd_file or uuconf_cmd_line will do so. */
+#define UUCONF_CMDTABRET_KEEP (0x800)
+
+/* This bit means that uuconf_cmd_file should exit, rather than go on
+ to read and process the next line. If uuconf_cmd_line or
+ uuconf_cmd_args encounter an error, the return value will have this
+ bit set along with the error code. A user function may set this
+ bit with or without an error; the return value of the user function
+ will be returned by uuconf_cmd_file, except that the
+ UUCONF_CMDTABRET_KEEP and UUCONF_CMDTABRET_EXIT bits will be
+ cleared. */
+#define UUCONF_CMDTABRET_EXIT (0x1000)
+
+/* This macro may be used to extract the specific error value. */
+#define UUCONF_ERROR_VALUE(i) ((i) & 0xff)
+
+/* UUCONF_ERROR_VALUE will return one of the following values. */
+
+/* Function succeeded. */
+#define UUCONF_SUCCESS (0)
+/* Named item not found. */
+#define UUCONF_NOT_FOUND (1)
+/* A call to fopen failed. */
+#define UUCONF_FOPEN_FAILED (2)
+/* A call to fseek failed. */
+#define UUCONF_FSEEK_FAILED (3)
+/* A call to malloc or realloc failed. */
+#define UUCONF_MALLOC_FAILED (4)
+/* Syntax error in file. */
+#define UUCONF_SYNTAX_ERROR (5)
+/* Unknown command. */
+#define UUCONF_UNKNOWN_COMMAND (6)
+
+#if UUCONF_ANSI_C
+
+/* For each type of configuration file (Taylor, V2, HDB), there are
+ separate routines to read various sorts of information. There are
+ also generic routines, which call on the appropriate type specific
+ routines. The library can be compiled to read any desired
+ combination of the configuration file types. This affects only the
+ generic routines, as it determines which type specific routines
+ they call. Thus, on a system which, for example, does not have any
+ V2 configuration files, there is no need to include the overhead of
+ the code to parse the files and the time to look for them.
+ However, a program which specifically wants to be able to parse
+ them can call the V2 specific routines.
+
+ The uuconf functions all take as an argument a pointer to uuconf
+ global information. This must be initialized by any the
+ initialization routines (the generic one and the three file type
+ specific ones) before any of the other uuconf functions may be
+ called. */
+
+/* Initialize the configuration file reading routines. The ppglobal
+ argument should point to a generic pointer (a void *, or, on older
+ compilers, a char *) which will be initialized and may then be
+ passed to the other uuconf routines. The zprogram argument is the
+ name of the program for which files should be read. A NULL is
+ taken as "uucp", and reads the standard UUCP configuration files.
+ The only other common argument is "cu", but any string is
+ permitted. The zname argument is the name of the Taylor UUCP
+ config file; if it is NULL, the default config file will be read.
+ If not reading Taylor UUCP configuration information, the argument
+ is ignored. This function must be called before any of the other
+ uuconf functions.
+
+ Note that if the zname argument is obtained from the user running
+ the program, the program should be careful to revoke any special
+ privileges it may have (e.g. on Unix call setuid (getuid ()) and
+ setgid (getgid ())). Otherwise various sorts of spoofing become
+ possible. */
+extern int uuconf_init (void **uuconf_ppglobal,
+ const char *uuconf_zprogram,
+ const char *uuconf_zname);
+
+/* Adjust the configuration file global pointer for a new thread. The
+ library is fully reentrant (with the exception of the function
+ uuconf_error_string, which calls strerror, which on some systems is
+ not reentrant), provided that each new thread that wishes to call
+ the library calls this function and uses the new global pointer
+ value. The ppglobal argument should be set to the address of the
+ global pointer set by any of the init functions; it will be
+ modified to become a new global pointer. */
+extern int uuconf_init_thread (void **uuconf_ppglobal);
+
+/* Get the names of all known systems. This sets sets *ppzsystems to
+ point to an array of system names. The list of names is NULL
+ terminated. The array is allocated using malloc, as is each
+ element of the array, and they may all be passed to free when they
+ are no longer needed. If the falias argument is 0, the list will
+ not include any aliases; otherwise, it will. */
+extern int uuconf_system_names (void *uuconf_pglobal,
+ char ***uuconf_ppzsystems,
+ int uuconf_falias);
+
+/* Get the information for the system zsystem. This sets the fields
+ in *qsys. This will work whether zsystem is the official name of
+ the system or merely an alias. */
+extern int uuconf_system_info (void *uuconf_pglobal,
+ const char *uuconf_zsystem,
+ struct uuconf_system *uuconf_qsys);
+
+/* Get information for an unknown (anonymous) system. The
+ uuconf_zname field of the returned system information will be NULL.
+ If no information is available for unknown systems, this will
+ return UUCONF_NOT_FOUND. This does not run the HDB remote.unknown
+ shell script. */
+extern int uuconf_system_unknown (void *uuconf_pglobal,
+ struct uuconf_system *uuconf_qsys);
+
+/* Get information for the local system. Normally the local system
+ name should first be looked up using uuconf_system_info. If that
+ returns UUCONF_NOT_FOUND, this function may be used to get an
+ appropriate set of defaults. The uuconf_zname field of the
+ returned system information may be NULL. */
+extern int uuconf_system_local (void *uuconf_pglobal,
+ struct uuconf_system *uuconf_qsys);
+
+/* Free the memory occupied by system information returned by
+ uuconf_system_info, uuconf_system_unknown, uuconf_system_local, or
+ any of the configuration file type specific routines described
+ below. After this is called, the contents of the structure shall
+ not be referred to. */
+extern int uuconf_system_free (void *uuconf_pglobal,
+ struct uuconf_system *uuconf_qsys);
+
+#ifdef __OPTIMIZE__
+#define uuconf_system_free(qglob, q) \
+ (uuconf_free_block ((q)->uuconf_palloc), UUCONF_SUCCESS)
+#endif
+
+/* Find a matching port. This will consider each port in turn.
+
+ If the zname argument is not NULL, the port's uuconf_zname field
+ must match it.
+
+ If the ibaud argument is not zero and the ihighbaud argument is
+ zero, the port's baud rate, if defined, must be the same (if the
+ port has a range of baud rates, ibaud must be within the range).
+ If ibaud and ihighbaud are both not zero, the port's baud rate, if
+ defined, must be between ibaud and ihighbaud inclusive (if the port
+ has a range of baud rates, the ranges must intersect). If the port
+ has no baud rate, either because it is a type of port for which
+ baud rate is not defined (e.g. a TCP port) or because the
+ uuconf_ibaud field is 0, the ibaud and ihighbaud arguments are
+ ignored.
+
+ If the pifn argument is not NULL, the port is passed to pifn, along
+ with the pinfo argument (which is otherwise ignored). If pifn
+ returns UUCONF_SUCCESS, the port matches. If pifn returns
+ UUCONF_NOT_FOUND, a new port is sought. Otherwise the return value
+ of pifn is returned from uuconf_find_port. The pifn function may
+ be used to further restrict the port, such as by modem class or
+ device name. It may also be used to lock the port, if appropriate;
+ in this case, if the lock fails, pifn may return UUCONF_NOT_FOUND
+ to force uuconf_find_port to continue searching for a port.
+
+ If the port matches, the information is set into uuconf_qport, and
+ uuconf_find_port returns UUCONF_SUCCESS. */
+extern int uuconf_find_port (void *uuconf_pglobal,
+ const char *uuconf_zname,
+ long uuconf_ibaud,
+ long uuconf_ihighbaud,
+ int (*uuconf_pifn) (struct uuconf_port *,
+ void *uuconf_pinfo),
+ void *uuconf_pinfo,
+ struct uuconf_port *uuconf_qport);
+
+/* Free the memory occupied by system information returned by
+ uuconf_find_port (or any of the configuration file specific
+ routines described below). After this is called, the contents of
+ the structure shall not be referred to. */
+extern int uuconf_port_free (void *uuconf_pglobal,
+ struct uuconf_port *uuconf_qport);
+
+#ifdef __OPTIMIZE__
+#define uuconf_port_free(qglob, q) \
+ (uuconf_free_block ((q)->uuconf_palloc), UUCONF_SUCCESS)
+#endif
+
+/* Get the names of all known dialers. This sets sets *ppzdialers to
+ point to an array of dialer names. The list of names is NULL
+ terminated. The array is allocated using malloc, as is each
+ element of the array, and they may all be passed to free when they
+ are no longer needed. */
+extern int uuconf_dialer_names (void *uuconf_pglobal,
+ char ***uuconf_ppzdialers);
+
+/* Get the information for the dialer zdialer. This sets the fields
+ in *qdialer. */
+extern int uuconf_dialer_info (void *uuconf_pglobal,
+ const char *uuconf_zdialer,
+ struct uuconf_dialer *uuconf_qdialer);
+
+/* Free the memory occupied by system information returned by
+ uuconf_dialer_info (or any of the configuration file specific
+ routines described below). After this is called, the contents of
+ the structure shall not be referred to. */
+extern int uuconf_dialer_free (void *uuconf_pglobal,
+ struct uuconf_dialer *uuconf_qsys);
+
+#ifdef __OPTIMIZE__
+#define uuconf_dialer_free(qglob, q) \
+ (uuconf_free_block ((q)->uuconf_palloc), UUCONF_SUCCESS)
+#endif
+
+/* Get the local node name. If the node name is not specified
+ (because no ``nodename'' command appeared in the config file) this
+ will return UUCONF_NOT_FOUND, and some system dependent function
+ must be used to determine the node name. Otherwise it will return
+ a pointer to a constant string, which should not be freed. */
+extern int uuconf_localname (void *uuconf_pglobal,
+ const char **pzname);
+
+/* Get the local node name that should be used, given a login name.
+ This function will check for any special local name that may be
+ associated with the login name zlogin (as set by the ``myname''
+ command in a Taylor configuration file, or the MYNAME field in a
+ Permissions entry). This will set *pzname to the node name. If no
+ node name can be determined, *pzname will be set to NULL and the
+ function will return UUCONF_NOT_FOUND; in this case some system
+ dependent function must be used to determine the node name. If the
+ function returns UUCONF_SUCCESS, *pzname will be point to an
+ malloced buffer. */
+extern int uuconf_login_localname (void *uuconf_pglobal,
+ const char *uuconf_zlogin,
+ char **pzname);
+
+/* Get the name of the UUCP spool directory. This will set *pzspool
+ to a constant string, which should not be freed. */
+extern int uuconf_spooldir (void *uuconf_pglobal,
+ const char **uuconf_pzspool);
+
+/* Get the name of the default UUCP public directory. This will set
+ *pzpub to a constant string, which should not be freed. Note that
+ particular systems may use a different public directory. */
+extern int uuconf_pubdir (void *uuconf_pglobal,
+ const char **uuconf_pzpub);
+
+/* Get the name of the UUCP lock directory. This will set *pzlock to
+ a constant string, which should not be freed. */
+extern int uuconf_lockdir (void *uuconf_pglobal,
+ const char **uuconf_pzlock);
+
+/* Get the name of the UUCP log file. This will set *pzlog to a
+ constant string, which should not be freed. */
+extern int uuconf_logfile (void *uuconf_pglobal,
+ const char **uuconf_pzlog);
+
+/* Get the name of the UUCP statistics file. This will set *pzstats
+ to a constant string, which should not be freed. */
+extern int uuconf_statsfile (void *uuconf_pglobal,
+ const char **uuconf_pzstats);
+
+/* Get the name of the UUCP debugging file. This will set *pzdebug to
+ a constant string, which should not be freed. */
+extern int uuconf_debugfile (void *uuconf_pglobal,
+ const char **uuconf_pzdebug);
+
+/* Get the default debugging level to use. This basically gets the
+ argument of the ``debug'' command from the Taylor UUCP config file.
+ It will set *pzdebug to a constant string, which should not be
+ freed. */
+extern int uuconf_debuglevel (void *uuconf_pglobal,
+ const char **uuconf_pzdebug);
+
+/* Get the maximum number of simultaneous uuxqt executions. This will
+ set *pcmaxuuxqt to the number. Zero indicates no maximum. */
+extern int uuconf_maxuuxqts (void *uuconf_pglobal,
+ int *uuconf_pcmaxuuxqt);
+
+/* Check a login name and password. This checks the Taylor UUCP
+ password file (not /etc/passwd). It will work even if
+ uuconf_taylor_init was not called. If the login name exists and
+ the password is correct, this returns UUCONF_SUCCESS. If the login
+ does not exist, or the password is wrong, this returns
+ UUCONF_NOT_FOUND. Other errors are also possible. */
+extern int uuconf_callin (void *uuconf_pglobal,
+ const char *uuconf_zlogin,
+ const char *uuconf_zpassword);
+
+/* Get the callout login name and password for a system. This will
+ set both *pzlog and *pzpass to a string allocated by malloc, or to
+ NULL if the value is not found. If neither value is found, the
+ function will return UUCONF_NOT_FOUND. */
+extern int uuconf_callout (void *uuconf_pglobal,
+ const struct uuconf_system *uuconf_qsys,
+ char **uuconf_pzlog,
+ char **uuconf_pzpass);
+
+/* See if a login name is permitted for a system. This will return
+ UUCONF_SUCCESS if it is permitted or UUCONF_NOT_FOUND if it is
+ invalid. This simply calls uuconf_taylor_validate or returns
+ UUCONF_SUCCESS, depending on the value of HAVE_TAYLOR_CONFIG. */
+extern int uuconf_validate (void *uuconf_pglobal,
+ const struct uuconf_system *uuconf_qsys,
+ const char *uuconf_zlogin);
+
+/* Get the name of the HDB remote.unknown shell script, if using
+ HAVE_HDB_CONFIG. This does not actually run the shell script. If
+ the function returns UUCONF_SUCCESS, the name will be in *pzname,
+ which will point to an malloced buffer. If it returns
+ UUCONF_NOT_FOUND, then there is no script to run. */
+extern int uuconf_remote_unknown (void *uuconf_pglobal,
+ char **pzname);
+
+/* Translate a dial code. This sets *pznum to an malloced string.
+ This will look up the entire zdial string in the dialcode file, so
+ for normal use the alphabetic prefix should be separated. */
+extern int uuconf_dialcode (void *uuconf_pglobal,
+ const char *uuconf_zdial,
+ char **uuconf_pznum);
+
+/* Compare two grades, returning < 0 if b1 should be executed before
+ b2, == 0 if they are the same, or > 0 if b1 should be executed
+ after b2. This can not fail, and does not return a standard uuconf
+ error code; it is normally called via the macro UUCONF_GRADE_CMP,
+ defined above. */
+extern int uuconf_grade_cmp (int uuconf_b1, int uuconf_b2);
+
+#else /* ! UUCONF_ANSI_C */
+
+extern int uuconf_init ();
+extern int uuconf_init_thread ();
+extern int uuconf_system_names ();
+extern int uuconf_system_info ();
+extern int uuconf_system_unknown ();
+extern int uuconf_system_local ();
+extern int uuconf_system_free ();
+extern int uuconf_find_port ();
+extern int uuconf_port_free ();
+extern int uuconf_dialer_names ();
+extern int uuconf_dialer_info ();
+extern int uuconf_dialer_free ();
+extern int uuconf_localname ();
+extern int uuconf_login_localname ();
+extern int uuconf_spooldir ();
+extern int uuconf_lockdir ();
+extern int uuconf_pubdir ();
+extern int uuconf_logfile ();
+extern int uuconf_statsfile ();
+extern int uuconf_debugfile ();
+extern int uuconf_debuglevel ();
+extern int uuconf_maxuuxqts ();
+extern int uuconf_callin ();
+extern int uuconf_callout ();
+extern int uuconf_remote_unknown ();
+extern int uuconf_validate ();
+extern int uuconf_grade_cmp ();
+
+#ifdef __OPTIMIZE__
+#define uuconf_system_free(qglob, q) \
+ (uuconf_free_block ((q)->uuconf_palloc), UUCONF_SUCCESS)
+#define uuconf_port_free(qglob, q) \
+ (uuconf_free_block ((q)->uuconf_palloc), UUCONF_SUCCESS)
+#define uuconf_dialer_free(qglob, q) \
+ (uuconf_free_block ((q)->uuconf_palloc), UUCONF_SUCCESS)
+#endif
+
+#endif /* ! UUCONF_ANSI_C */
+
+#if UUCONF_ANSI_C
+
+/* Initialize the Taylor UUCP configuration file reading routines.
+ This must be called before calling any of the Taylor UUCP
+ configuration file specific routines. The ppglobal argument should
+ point to a generic pointer. Moreover, before calling this function
+ the pointer either must be set to NULL, or must have been passed to
+ one of the other uuconf init routines. The zprogram argument is
+ the name of the program for which files should be read. If NULL,
+ it is taken as "uucp", which means to read the standard UUCP files.
+ The zname argument is the name of the config file. If it is NULL,
+ the default config file will be used.
+
+ Note that if the zname argument is obtained from the user running
+ the program, the program should be careful to revoke any special
+ privileges it may have (e.g. on Unix call setuid (getuid ()) and
+ setgid (getgid ())). Otherwise various sorts of spoofing become
+ possible. */
+extern int uuconf_taylor_init (void **uuconf_pglobal,
+ const char *uuconf_zprogram,
+ const char *uuconf_zname);
+
+/* Get the names of all systems listed in the Taylor UUCP
+ configuration files. This sets *ppzsystems to point to an array of
+ system names. The list of names is NULL terminated. The array is
+ allocated using malloc, as is each element of the array. If the
+ falias argument is 0, the list will not include any aliases;
+ otherwise, it will. */
+extern int uuconf_taylor_system_names (void *uuconf_pglobal,
+ char ***uuconf_ppzsystems,
+ int uuconf_falias);
+
+/* Get the information for system zsystem from the Taylor UUCP
+ configuration files. This will set *qsys. */
+extern int uuconf_taylor_system_info (void *uuconf_pglobal,
+ const char *uuconf_zsystem,
+ struct uuconf_system *uuconf_qsys);
+
+/* Get information for an unknown (anonymous) system. This returns
+ the values set by the ``unknown'' command in the main configuration
+ file. If the ``unknown'' command was not used, this will return
+ UUCONF_NOT_FOUND. */
+extern int uuconf_taylor_system_unknown (void *uuconf_pglobal,
+ struct uuconf_system *uuconf_qsys);
+
+/* Find a port from the Taylor UUCP configuration files. The
+ arguments and return values are identical to those of
+ uuconf_find_port. */
+extern int uuconf_taylor_find_port (void *uuconf_pglobal,
+ const char *uuconf_zname,
+ long uuconf_ibaud,
+ long uuconf_ihighbaud,
+ int (*uuconf_pifn) (struct uuconf_port *,
+ void *uuconf_pinfo),
+ void *uuconf_pinfo,
+ struct uuconf_port *uuconf_qport);
+
+/* Get the names of all dialers listed in the Taylor UUCP
+ configuration files. This sets *ppzdialers to point to an array of
+ dialer names. The list of names is NULL terminated. The array is
+ allocated using malloc, as is each element of the array. */
+extern int uuconf_taylor_dialer_names (void *uuconf_pglobal,
+ char ***uuconf_ppzdialers);
+
+/* Get the information for the dialer zdialer from the Taylor UUCP
+ configuration files. This sets the fields in *qdialer. */
+extern int uuconf_taylor_dialer_info (void *uuconf_pglobal,
+ const char *uuconf_zdialer,
+ struct uuconf_dialer *uuconf_qdialer);
+
+/* Get the local node name that should be used, given a login name,
+ considering only the ``myname'' command in the Taylor UUCP
+ configuration files. If the function returns UUCONF_SUCCESS,
+ *pzname will point to an malloced buffer. */
+extern int uuconf_taylor_login_localname (void *uuconf_pglobal,
+ const char *uuconf_zlogin,
+ char **pzname);
+
+/* Get the callout login name and password for a system from the
+ Taylor UUCP configuration files. This will set both *pzlog and
+ *pzpass to a string allocated by malloc, or to NULL if the value is
+ not found. If neither value is found, the function will return
+ UUCONF_NOT_FOUND. */
+extern int uuconf_taylor_callout (void *uuconf_pglobal,
+ const struct uuconf_system *uuconf_qsys,
+ char **uuconf_pzlog,
+ char **uuconf_pzpass);
+
+/* See if a login name is permitted for a system. This will return
+ UUCONF_SUCCESS if it is permitted or UUCONF_NOT_FOUND if it is
+ invalid. This checks whether the login name appears in a
+ called-login command with a list of system which does not include
+ the system qsys. */
+extern int uuconf_taylor_validate (void *uuconf_pglobal,
+ const struct uuconf_system *uuconf_qsys,
+ const char *uuconf_zlogin);
+
+#else /* ! UUCONF_ANSI_C */
+
+extern int uuconf_taylor_init ();
+extern int uuconf_taylor_system_names ();
+extern int uuconf_taylor_system_info ();
+extern int uuconf_taylor_system_unknown ();
+extern int uuconf_taylor_find_port ();
+extern int uuconf_taylor_dialer_names ();
+extern int uuconf_taylor_dialer_info ();
+extern int uuconf_taylor_login_localname ();
+extern int uuconf_taylor_callout ();
+extern int uuconf_taylor_validate ();
+
+#endif /* ! UUCONF_ANSI_C */
+
+#if UUCONF_ANSI_C
+
+/* Initialize the V2 configuration file reading routines. This must
+ be called before any of the other V2 routines are called. The
+ ppglobal argument should point to a generic pointer. Moreover,
+ before calling this function the pointer either must be set to
+ NULL, or must have been passed to one of the other uuconf init
+ routines. */
+extern int uuconf_v2_init (void **uuconf_ppglobal);
+
+/* Get the names of all systems listed in the V2 configuration files.
+ This sets *ppzsystems to point to an array of system names. The
+ list of names is NULL terminated. The array is allocated using
+ malloc, as is each element of the array. If the falias argument is
+ 0, the list will not include any aliases; otherwise, it will. */
+extern int uuconf_v2_system_names (void *uuconf_pglobal,
+ char ***uuconf_ppzsystems,
+ int uuconf_falias);
+
+/* Get the information for system zsystem from the V2 configuration
+ files. This will set *qsys. */
+extern int uuconf_v2_system_info (void *uuconf_pglobal,
+ const char *uuconf_zsystem,
+ struct uuconf_system *uuconf_qsys);
+
+/* Find a port from the V2 configuration files. The arguments and
+ return values are identical to those of uuconf_find_port. */
+extern int uuconf_v2_find_port (void *uuconf_pglobal,
+ const char *uuconf_zname,
+ long uuconf_ibaud,
+ long uuconf_ihighbaud,
+ int (*uuconf_pifn) (struct uuconf_port *,
+ void *uuconf_pinfo),
+ void *uuconf_pinfo,
+ struct uuconf_port *uuconf_qport);
+
+#else /* ! UUCONF_ANSI_C */
+
+extern int uuconf_v2_init ();
+extern int uuconf_v2_system_names ();
+extern int uuconf_v2_system_info ();
+extern int uuconf_v2_find_port ();
+
+#endif /* ! UUCONF_ANSI_C */
+
+#if UUCONF_ANSI_C
+
+/* Initialize the HDB configuration file reading routines. This
+ should be called before any of the other HDB routines are called.
+ The ppglobal argument should point to a generic pointer. Moreover,
+ before calling this function the pointer either must be set to
+ NULL, or must have been passed to one of the other uuconf init
+ routines. The zprogram argument is used to match against a
+ "services" string in Sysfiles. A NULL or "uucp" argument is taken
+ as "uucico". */
+extern int uuconf_hdb_init (void **uuconf_ppglobal,
+ const char *uuconf_zprogram);
+
+/* Get the names of all systems listed in the HDB configuration files.
+ This sets *ppzsystems to point to an array of system names. The
+ list of names is NULL terminated. The array is allocated using
+ malloc, as is each element of the array. If the falias argument is
+ 0, the list will not include any aliases; otherwise, it will (an
+ alias is created by using the ALIAS= keyword in the Permissions
+ file). */
+extern int uuconf_hdb_system_names (void *uuconf_pglobal,
+ char ***uuconf_ppzsystems,
+ int uuconf_falias);
+
+/* Get the information for system zsystem from the HDB configuration
+ files. This will set *qsys. */
+extern int uuconf_hdb_system_info (void *uuconf_pglobal,
+ const char *uuconf_zsystem,
+ struct uuconf_system *uuconf_qsys);
+
+
+/* Get information for an unknown (anonymous) system. If no
+ information is available for unknown systems, this will return
+ UUCONF_NOT_FOUND. This does not run the remote.unknown shell
+ script. */
+extern int uuconf_hdb_system_unknown (void *uuconf_pglobal,
+ struct uuconf_system *uuconf_qsys);
+
+/* Find a port from the HDB configuration files. The arguments and
+ return values are identical to those of uuconf_find_port. */
+extern int uuconf_hdb_find_port (void *uuconf_pglobal,
+ const char *uuconf_zname,
+ long uuconf_ibaud,
+ long uuconf_ihighbaud,
+ int (*uuconf_pifn) (struct uuconf_port *,
+ void *uuconf_pinfo),
+ void *uuconf_pinfo,
+ struct uuconf_port *uuconf_qport);
+
+/* Get the names of all dialers listed in the HDB configuration files.
+ This sets *ppzdialers to point to an array of dialer names. The
+ list of names is NULL terminated. The array is allocated using
+ malloc, as is each element of the array. */
+extern int uuconf_hdb_dialer_names (void *uuconf_pglobal,
+ char ***uuconf_ppzdialers);
+
+/* Get the information for the dialer zdialer from the HDB
+ configuration files. This sets the fields in *qdialer. */
+extern int uuconf_hdb_dialer_info (void *uuconf_pglobal,
+ const char *uuconf_zdialer,
+ struct uuconf_dialer *uuconf_qdialer);
+
+/* Get the local node name that should be used, given a login name,
+ considering only the MYNAME field in the HDB Permissions file. If
+ the function returns UUCONF_SUCCESS, *pzname will point to an
+ malloced buffer. */
+extern int uuconf_hdb_login_localname (void *uuconf_pglobal,
+ const char *uuconf_zlogin,
+ char **pzname);
+
+/* Get the name of the HDB remote.unknown shell script. This does not
+ actually run the shell script. If the function returns
+ UUCONF_SUCCESS, the name will be in *pzname, which will point to an
+ malloced buffer. */
+extern int uuconf_hdb_remote_unknown (void *uuconf_pglobal,
+ char **pzname);
+
+#else /* ! UUCONF_ANSI_C */
+
+extern int uuconf_hdb_init ();
+extern int uuconf_hdb_system_names ();
+extern int uuconf_hdb_system_info ();
+extern int uuconf_hdb_system_unknown ();
+extern int uuconf_hdb_find_port ();
+extern int uuconf_hdb_dialer_names ();
+extern int uuconf_hdb_dialer_info ();
+extern int uuconf_hdb_localname ();
+extern int uuconf_hdb_remote_unknown ();
+
+#endif /* ! UUCONF_ANSI_C */
+
+#if UUCONF_ANSI_C
+
+/* This function will set an appropriate error message into the buffer
+ zbuf, given a uuconf error code. The buffer will always be null
+ terminated, and will never be accessed beyond the length cbuf.
+ This function will return the number of characters needed for the
+ complete message, including the null byte. If this is less than
+ the cbytes argument, the buffer holds a truncated string. */
+extern int uuconf_error_string (void *uuconf_pglobal, int ierror,
+ char *zbuf, UUCONF_SIZE_T cbuf);
+
+/* If UUCONF_ERROR_ERRNO is set in a return value, this function may
+ be used to retrieve the errno value. This will be the value of
+ errno as set by the system function which failed. However, some
+ system functions, notably some stdio routines, may not set errno,
+ in which case the value will be meaningless. This function does
+ not return a uuconf error code, and it cannot fail. */
+extern int uuconf_error_errno (void *uuconf_pglobal);
+
+/* If UUCONF_ERROR_FILENAME is set in a return value, this function
+ may be used to retrieve the file name. This function does not
+ return a uuconf error code, and it cannot fail. The string that it
+ returns a pointer to is not guaranteed to remain allocated across
+ the next call to a uuconf function (other than one of the three
+ error retrieving functions). */
+extern const char *uuconf_error_filename (void *uuconf_pglobal);
+
+/* If UUCONF_ERROR_LINENO is set in a return value, this function may
+ be used to retrieve the line number. This function does not return
+ a uuconf error code, and it cannot fail. */
+extern int uuconf_error_lineno (void *uuconf_pglobal);
+
+#else /* ! UUCONF_ANSI_C */
+
+extern int uuconf_error_string ();
+extern int uuconf_error_errno ();
+extern UUCONF_CONST char *uuconf_error_filename ();
+extern int uuconf_error_lineno ();
+
+#endif /* ! UUCONF_ANSI_C */
+
+/* The uuconf package also provides a few functions which can accept
+ commands and parcel them out according to a table. These are
+ publically visible, partially in the hopes that they will be
+ useful, but mostly because the rest of the Taylor UUCP package uses
+ them. */
+
+/* The types of entries allowed in a command table (struct
+ uuconf_cmdtab). Each type defines how a particular command is
+ interpreted. Each type will either assign a value to a variable or
+ call a function. In all cases, a line of input is parsed into
+ separate fields, separated by whitespace; comments beginning with
+ '#' are discarded, except that a '#' preceeded by a backslash is
+ retained. The first field is taken as the command to execute, and
+ the remaining fields are its arguments. */
+
+/* A boolean value. Used for a command which accepts a single
+ argument, which must begin with 'y', 'Y', 't', or 'T' for true (1)
+ or 'n', 'N', 'f', or 'F' for false (0). The corresponding variable
+ must be an int. */
+#define UUCONF_CMDTABTYPE_BOOLEAN (0x12)
+
+/* An integer value. Used for a command which accepts a single
+ argument, which must be an integer. The corresponding variable
+ must be an int. */
+#define UUCONF_CMDTABTYPE_INT (0x22)
+
+/* A long value. Used for a command which accepts a single value,
+ which must be an integer. The corresponding variable must be a
+ long. */
+#define UUCONF_CMDTABTYPE_LONG (0x32)
+
+/* A string value. Used for a command which accepts a string
+ argument. If there is no argument, the variable will be set to
+ point to a zero byte. Otherwise the variable will be set to point
+ to the string. The corresponding variable must be a char *. The
+ memory pointed to by the variable after it is set must not be
+ modified. */
+#define UUCONF_CMDTABTYPE_STRING (0x40)
+
+/* A full string value. Used for a command which accepts a series of
+ string arguments separated by whitespace. The corresponding
+ variable must be a char **. It will be set to an NULL terminated
+ array of the arguments. The memory occupied by the array itself,
+ and by the strings within it, must not be modified. */
+#define UUCONF_CMDTABTYPE_FULLSTRING (0x50)
+
+/* A function. If this command is encountered, the command and its
+ arguments are passed to the corresponding function. They are
+ passed as an array of strings, in which the first string is the
+ command itself, along with a count of strings. This value may be
+ or'red with a specific number of required arguments;
+ UUCONF_CMDTABTYPE_FN | 1 accepts no additional arguments besides
+ the command itself, UUCONF_CMDTABTYPE_FN | 2 accepts 1 argument,
+ etc. UUCONF_CMDTABTYPE_FN | 0, accepts any number of additional
+ arguments. */
+#define UUCONF_CMDTABTYPE_FN (0x60)
+
+/* A prefix function. The string in the table is a prefix; if a
+ command is encountered with the same prefix, the corresponding
+ function will be called as for UUCONF_CMDTABTYPE_FN. The number of
+ arguments may be or'red in as with UUCONF_CMDTABTYPE_FN. */
+#define UUCONF_CMDTABTYPE_PREFIX (0x70)
+
+/* This macro will return the particular type of a CMDTABTYPE. */
+#define UUCONF_TTYPE_CMDTABTYPE(i) ((i) & 0x70)
+
+/* This macro will return the required number of arguments of a
+ CMDTABTYPE. If it is zero, there is no restriction. */
+#define UUCONF_CARGS_CMDTABTYPE(i) ((i) & 0x0f)
+
+/* When a function is called via UUCONF_CMDTABTYPE_FN or
+ UUCONF_CMDTABTYPE_PREFIX, it may return any uuconf error code (see
+ above). However, it will normally return one of the following:
+
+ UUCONF_CMDTABRET_CONTINUE: Take no special action. In particular,
+ the arguments passed to the function may be overwritten or freed.
+
+ UUCONF_CMDTABRET_KEEP: The memory occupied by the arguments passed
+ to the function must be preserved. Continue processing commands.
+
+ UUCONF_CMDTABRET_EXIT: If reading commands from a file, stop
+ processing. The arguments passed to the function may be
+ overwritten or freed.
+
+ UUCONF_CMDTABRET_KEEP_AND_EXIT: Stop processing any file. The
+ memory occupied by the arguments passed to the function must be
+ preserved.
+
+ These values are interpreted by uuconf_cmd_file. The
+ uuconf_cmd_line and uuconf_cmd_args functions may return
+ UUCONF_CMDTABRET_KEEP. It they get an error, they will return an
+ error code with UUCONF_CMDTABRET_EXIT set. Also, of course, they
+ may return any value that is returned by one of the user functions
+ in the uuconf_cmdtab table. */
+
+/* UUCONF_CMDTABRET_KEEP and UUCONF_CMDTABRET_EXIT are defined above,
+ with the error codes. */
+
+#define UUCONF_CMDTABRET_CONTINUE UUCONF_SUCCESS
+#define UUCONF_CMDTABRET_KEEP_AND_EXIT \
+ (UUCONF_CMDTABRET_KEEP | UUCONF_CMDTABRET_EXIT)
+
+/* When a function is called via CMDTABTYPE_FN or CMDTABTYPE_PREFIX,
+ it is passed five arguments. This is the type of a pointer to such
+ a function. The uuconf global information structure is passed in
+ for convenience in calling another uuconf function. The arguments
+ to the command are passed in (the command itself is the first
+ argument) along with a count and the value of the pvar field from
+ the uuconf_cmdtab structure in which the function pointer was
+ found. The pinfo argument to the function is taken from the
+ argument to uuconf_cmd_*. */
+
+#if UUCONF_ANSI_C
+typedef int (*uuconf_cmdtabfn) (void *uuconf_pglobal,
+ int uuconf_argc,
+ char **uuconf_argv,
+ void *uuconf_pvar,
+ void *uuconf_pinfo);
+#else
+typedef int (*uuconf_cmdtabfn) ();
+#endif
+
+/* A table of commands is an array of the following structures. The
+ final element of the table should have uuconf_zcmd == NULL. */
+
+struct uuconf_cmdtab
+{
+ /* Command name. */
+ UUCONF_CONST char *uuconf_zcmd;
+ /* Command type (one of CMDTABTYPE_*). */
+ int uuconf_itype;
+ /* If not CMDTABTYPE_FN or CMDTABTYPE_PREFIX, the address of the
+ associated variable. Otherwise, a pointer value to pass to the
+ function pifn. */
+ UUCONF_POINTER uuconf_pvar;
+ /* The function to call if CMDTABTYPE_FN or CMDTABTYPE_PREFIX. */
+ uuconf_cmdtabfn uuconf_pifn;
+};
+
+/* Bit flags to pass to uuconf_processcmds. */
+
+/* If set, case is significant when checking commands. Normally case
+ is ignored. */
+#define UUCONF_CMDTABFLAG_CASE (0x1)
+
+/* If set, a backslash at the end of a line may be used to include the
+ next physical line in the logical line. */
+#define UUCONF_CMDTABFLAG_BACKSLASH (0x2)
+
+#if UUCONF_ANSI_C
+
+/* Read commands from a file, look them up in a table, and take the
+ appropriate action. This continues reading lines from the file
+ until EOF, or until a function returns with UUCONF_CMDTABRET_EXIT
+ set, or until an error occurs. The qtab argument must point to a
+ table of struct uuconf_cmdtab; the last element in the table should
+ have uuconf_zcmd == NULL. When a UUCONF_CMDTABTYPE_FN or
+ UUCONF_CMDTABTYPE_PREFIX command is found, the pinfo argument will
+ be passed to the called function. If an a command is found that is
+ not in the table, then if pfiunknownfn is NULL the unknown command
+ is ignored; otherwise it is passed to pfiunknownfn, which should
+ return a uuconf return code which is handled as for any other
+ function (the pvar argument to pfiunknownfn will always be NULL).
+ The iflags argument is any combination of the above
+ UUCONF_CMDTABFLAG bits. The pblock argument may also be a memory
+ block, as returned by uuconf_malloc_block (described below), in
+ which case all memory preserved because of UUCONF_CMDTABRET_KEEP
+ will be added to the block so that it may be freed later; it may
+ also be NULL, in which case any such memory is permanently lost.
+
+ This function initially sets the internal line number to 0, and
+ then increments it as each line is read. It is permitted for any
+ called function to use the uuconf_lineno function to obtain it. If
+ this function is called when not at the start of a file, the value
+ returned by uuconf_lineno (which is, in any case, only valid if an
+ error code with UUCONF_ERROR_LINENO set is returned) must be
+ adjusted by the caller.
+
+ This returns a normal uuconf return value, as described above. */
+extern int uuconf_cmd_file (void *uuconf_pglobal,
+ FILE *uuconf_e,
+ const struct uuconf_cmdtab *uuconf_qtab,
+ void *uuconf_pinfo,
+ uuconf_cmdtabfn uuconf_pfiunknownfn,
+ int uuconf_iflags,
+ void *pblock);
+
+/* This utility function is just like uuconf_cmd_file, except that it
+ only operates on a single string. If a function is called via
+ qtab, its return value will be the return value of this function.
+ UUCONF_CMDTABFLAG_BACKSLASH is ignored in iflags. The string z is
+ modified in place. The return value may include the
+ UUCONF_CMDTABRET_KEEP and, on error, the UUCONF_CMDTABRET_EXIT
+ bits, which should be honored by the calling code. */
+extern int uuconf_cmd_line (void *uuconf_pglobal,
+ char *uuconf_z,
+ const struct uuconf_cmdtab *uuconf_qtab,
+ void *uuconf_pinfo,
+ uuconf_cmdtabfn uuconf_pfiunknownfn,
+ int uuconf_iflags,
+ void *pblock);
+
+/* This utility function is just like uuconf_cmd_line, except it is
+ given a list of already parsed arguments. */
+extern int uuconf_cmd_args (void *uuconf_pglobal,
+ int uuconf_cargs,
+ char **uuconf_pzargs,
+ const struct uuconf_cmdtab *uuconf_qtab,
+ void *uuconf_pinfo,
+ uuconf_cmdtabfn uuconf_pfiunknownfn,
+ int uuconf_iflags,
+ void *pblock);
+
+#else /* ! UUCONF_ANSI_C */
+
+extern int uuconf_cmd_file ();
+extern int uuconf_cmd_line ();
+extern int uuconf_cmd_args ();
+
+#endif /* ! UUCONF_ANSI_C */
+
+#if UUCONF_ANSI_C
+
+/* The uuconf_cmd_file function may allocate memory permanently, as
+ for setting a UUCONF_CMDTABTYPE_STRING value, in ways which are
+ difficult to free up. A memory block may be used to record all
+ allocated memory, so that it can all be freed up at once at some
+ later time. These functions do not take a uuconf global pointer,
+ and are independent of the rest of the uuconf library. */
+
+/* Allocate a block of memory. If this returns NULL, then malloc
+ returned NULL, and errno is whatever malloc set it to. */
+extern void *uuconf_malloc_block (void);
+
+/* Allocate memory within a memory block. If this returns NULL, then
+ malloc returned NULL, and errno is whatever malloc set it to. */
+extern void *uuconf_malloc (void *uuconf_pblock,
+ UUCONF_SIZE_T uuconf_cbytes);
+
+/* Add a block returned by the generic malloc routine to a memory
+ block. This returns zero on success, non-zero on failure. If this
+ fails (returns non-zero), then malloc returned NULL, and errno is
+ whatever malloc set it to. */
+extern int uuconf_add_block (void *uuconf_pblock, void *uuconf_padd);
+
+/* Free a value returned by uuconf_malloc from a memory block. In the
+ current implementation, this will normally not do anything, but it
+ doesn't hurt. No errors can occur. */
+extern void uuconf_free (void *uuconf_pblock, void *uuconf_pfree);
+
+/* Free an entire memory block, including all values returned by
+ uuconf_malloc from it and all values added to it with
+ uuconf_add_block. No errors can occur. */
+extern void uuconf_free_block (void *uuconf_pblock);
+
+#else /* ! UUCONF_ANSI_C */
+
+extern UUCONF_POINTER uuconf_malloc_block ();
+extern UUCONF_POINTER uuconf_malloc ();
+extern int uuconf_add_block ();
+extern /* void */ uuconf_free ();
+extern /* void */ uuconf_free_block ();
+
+#endif /* ! UUCONF_ANSI_C */
+
+#endif /* ! defined (UUCONF_H) */
diff --git a/gnu/libexec/uucp/common_sources/uucp.h b/gnu/libexec/uucp/common_sources/uucp.h
new file mode 100644
index 000000000000..8df3ec4c3e79
--- /dev/null
+++ b/gnu/libexec/uucp/common_sources/uucp.h
@@ -0,0 +1,367 @@
+/* uucp.h
+ Header file for the UUCP package.
+
+ Copyright (C) 1991, 1992 Ian Lance Taylor
+
+ This file is part of the Taylor UUCP package.
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ The author of the program may be contacted at ian@airs.com or
+ c/o Infinity Development Systems, P.O. Box 520, Waltham, MA 02254.
+ */
+
+/* Get the system configuration parameters. */
+#include "conf.h"
+#include "policy.h"
+
+/* Get a definition for ANSI_C if we weren't given one. */
+#ifndef ANSI_C
+#ifdef __STDC__
+#define ANSI_C 1
+#else /* ! defined (__STDC__) */
+#define ANSI_C 0
+#endif /* ! defined (__STDC__) */
+#endif /* ! defined (ANSI_C) */
+
+/* Pass this definition into uuconf.h. */
+#define UUCONF_ANSI_C ANSI_C
+
+/* We always include some standard header files. We need <signal.h>
+ to define sig_atomic_t. */
+#if HAVE_STDDEF_H
+#include <stddef.h>
+#endif
+#include <stdio.h>
+#include <signal.h>
+
+/* On some systems we need <sys/types.h> to get sig_atomic_t or
+ size_t or time_t. */
+#if ! HAVE_SIG_ATOMIC_T_IN_SIGNAL_H && HAVE_SIG_ATOMIC_T_IN_TYPES_H
+#define USE_TYPES_H 1
+#else
+#if ! HAVE_SIZE_T_IN_STDDEF_H && HAVE_SIZE_T_IN_TYPES_H
+#define USE_TYPES_H 1
+#else
+#if ! HAVE_TIME_T_IN_TIME_H && HAVE_TIME_T_IN_TYPES_H
+#define USE_TYPES_H 1
+#endif
+#endif
+#endif
+
+#ifndef USE_TYPES_H
+#define USE_TYPES_H 0
+#endif
+
+#if USE_TYPES_H
+#include <sys/types.h>
+#endif
+
+/* Make sure we have sig_atomic_t. */
+#if ! HAVE_SIG_ATOMIC_T_IN_SIGNAL_H && ! HAVE_SIG_ATOMIC_T_IN_TYPES_H
+#ifndef SIG_ATOMIC_T
+/* There is no portable definition for sig_atomic_t. */
+#define SIG_ATOMIC_T char
+#endif /* ! defined (SIG_ATOMIC_T) */
+typedef SIG_ATOMIC_T sig_atomic_t;
+#endif /* ! HAVE_SIG_ATOMIC_T_IN_SIGNAL_H && ! HAVE_SIG_ATOMIC_T_IN_TYPES_H */
+
+/* Make sure we have size_t. We use int as the default because the
+ main use of this type is to provide an argument to malloc and
+ realloc. On a system which does not define size_t, int is
+ certainly the correct type to use. */
+#if ! HAVE_SIZE_T_IN_STDDEF_H && ! HAVE_SIZE_T_IN_TYPES_H
+#ifndef SIZE_T
+#define SIZE_T unsigned
+#endif /* ! defined (SIZE_T) */
+typedef SIZE_T size_t;
+#endif /* ! HAVE_SIZE_T_IN_STDDEF_H && ! HAVE_SIZE_T_IN_TYPES_H */
+
+/* Make sure we have time_t. We use long as the default. We don't
+ bother to let conf.h override this, since on a system which doesn't
+ define time_t long must be correct. */
+#if ! HAVE_TIME_T_IN_TIME_H && ! HAVE_TIME_T_IN_TYPES_H
+typedef long time_t;
+#endif
+
+/* Set up some definitions for both ANSI C and Classic C.
+
+ P() -- for function prototypes (e.g. extern int foo P((int)) ).
+ pointer -- for a generic pointer (i.e. void *).
+ constpointer -- for a generic pointer to constant data.
+ BUCHAR -- to convert a character to unsigned. */
+#if ANSI_C
+#if ! HAVE_VOID || ! HAVE_UNSIGNED_CHAR
+ #error ANSI C compiler without void or unsigned char
+#endif
+#define P(x) x
+typedef void *pointer;
+typedef const void *constpointer;
+#define BUCHAR(b) ((unsigned char) (b))
+#else /* ! ANSI_C */
+/* Handle uses of const, volatile and void in Classic C. */
+#define const
+#define volatile
+#if ! HAVE_VOID
+#define void int
+#endif
+#define P(x) ()
+typedef char *pointer;
+typedef const char *constpointer;
+#if HAVE_UNSIGNED_CHAR
+#define BUCHAR(b) ((unsigned char) (b))
+#else /* ! HAVE_UNSIGNED_CHAR */
+/* This should work on most systems, but not necessarily all. */
+#define BUCHAR(b) ((b) & 0xff)
+#endif /* ! HAVE_UNSIGNED_CHAR */
+#endif /* ! ANSI_C */
+
+/* Make sure we have a definition for offsetof. */
+#ifndef offsetof
+#define offsetof(type, field) \
+ ((size_t) ((char *) &(((type *) 0)->field) - (char *) (type *) 0))
+#endif
+
+/* Only use inline with gcc. */
+#ifndef __GNUC__
+#define __inline__
+#endif
+
+/* Get the string functions, which are used throughout the code. */
+#if HAVE_MEMORY_H
+#include <memory.h>
+#else
+/* We really need a definition for memchr, and this should not
+ conflict with anything in <string.h>. I hope. */
+extern pointer memchr ();
+#endif
+
+#if HAVE_STRING_H
+#include <string.h>
+#else /* ! HAVE_STRING_H */
+#if HAVE_STRINGS_H
+#include <strings.h>
+#else /* ! HAVE_STRINGS_H */
+extern char *strcpy (), *strncpy (), *strchr (), *strrchr (), *strtok ();
+extern char *strcat (), *strerror (), *strstr ();
+extern size_t strlen (), strspn (), strcspn ();
+#if ! HAVE_MEMORY_H
+extern pointer memcpy (), memchr ();
+#endif /* ! HAVE_MEMORY_H */
+#endif /* ! HAVE_STRINGS_H */
+#endif /* ! HAVE_STRING_H */
+
+/* Get what we need from <stdlib.h>. */
+#if HAVE_STDLIB_H
+#include <stdlib.h>
+#else /* ! HAVE_STDLIB_H */
+extern pointer malloc (), realloc (), bsearch ();
+extern long strtol ();
+extern char *getenv ();
+#endif /* ! HAVE_STDLIB_H */
+
+/* NeXT uses <libc.h> to declare a bunch of functions. */
+#if HAVE_LIBC_H
+#include <libc.h>
+#endif
+
+/* Make sure we have the EXIT_ macros. */
+#ifndef EXIT_SUCCESS
+#define EXIT_SUCCESS (0)
+#endif
+#ifndef EXIT_FAILURE
+#define EXIT_FAILURE (1)
+#endif
+
+/* If we need to declare errno, do so. I don't want to always do
+ this, because some system might theoretically have a different
+ declaration for errno. On a POSIX system this is sure to work. */
+#if ! HAVE_ERRNO_DECLARATION
+extern int errno;
+#endif
+
+/* If the system has the socket call, guess that we can compile the
+ TCP code. */
+#define HAVE_TCP HAVE_SOCKET
+
+/* If the system has the t_open call, guess that we can compile the
+ TLI code. */
+#define HAVE_TLI HAVE_T_OPEN
+
+/* The boolean type holds boolean values. */
+typedef int boolean;
+#undef TRUE
+#undef FALSE
+#define TRUE (1)
+#define FALSE (0)
+
+/* The openfile_t type holds an open file. This depends on whether we
+ are using stdio or not. */
+#if USE_STDIO
+
+typedef FILE *openfile_t;
+#define EFILECLOSED ((FILE *) NULL)
+#define ffileisopen(e) ((e) != NULL)
+#define ffileeof(e) feof (e)
+#define cfileread(e, z, c) fread ((z), 1, (c), (e))
+#define ffilereaderror(e, c) ferror (e)
+#define cfilewrite(e, z, c) fwrite ((z), 1, (c), (e))
+#ifdef SEEK_SET
+#define ffileseek(e, i) (fseek ((e), (long) (i), SEEK_SET) == 0)
+#define ffilerewind(e) (fseek ((e), (long) 0, SEEK_SET) == 0)
+#else
+#define ffileseek(e, i) (fseek ((e), (long) (i), 0) == 0)
+#define ffilerewind(e) (fseek ((e), (long) 0, 0) == 0)
+#endif
+#define ffileclose(e) (fclose (e) == 0)
+
+#else /* ! USE_STDIO */
+
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+typedef int openfile_t;
+#define EFILECLOSED (-1)
+#define ffileisopen(e) ((e) >= 0)
+#define ffileeof(e) (FALSE)
+#define cfileread(e, z, c) read ((e), (z), (c))
+#define ffilereaderror(e, c) ((c) < 0)
+#define cfilewrite(e, z, c) write ((e), (z), (c))
+#ifdef SEEK_SET
+#define ffileseek(e, i) (lseek ((e), (long) i, SEEK_SET) >= 0)
+#define ffilerewind(e) (lseek ((e), (long) 0, SEEK_SET) >= 0)
+#else
+#define ffileseek(e, i) (lseek ((e), (long) i, 0) >= 0)
+#define ffilerewind(e) (lseek ((e), (long) 0, 0) >= 0)
+#endif
+#define ffileclose(e) (close (e) >= 0)
+
+#endif /* ! USE_STDIO */
+
+/* A prototype for main to avoid warnings from gcc 2.0
+ -Wmissing-prototype option. */
+extern int main P((int argc, char **argv));
+
+/* Some standard routines which we only define if they are not present
+ on the system we are compiling on. */
+
+#if ! HAVE_GETLINE
+/* Read a line from a file. */
+extern int getline P((char **pz, size_t *pc, FILE *e));
+#endif
+
+#if ! HAVE_REMOVE
+/* Erase a file. */
+#undef remove
+extern int remove P((const char *zfile));
+#endif
+
+#if ! HAVE_STRDUP
+/* Copy a string into memory. */
+extern char *strdup P((const char *z));
+#endif
+
+#if ! HAVE_STRSTR
+/* Look for one string within another. */
+extern char *strstr P((const char *zouter, const char *zinner));
+#endif
+
+#if ! HAVE_STRCASECMP
+#if HAVE_STRICMP
+#define strcasecmp stricmp
+#else /* ! HAVE_STRICMP */
+/* Rename strcasecmp to avoid ANSI C name space. */
+#define strcasecmp xstrcasecmp
+extern int strcasecmp P((const char *z1, const char *z2));
+#endif /* ! HAVE_STRICMP */
+#endif /* ! HAVE_STRCASECMP */
+
+#if ! HAVE_STRNCASECMP
+#if HAVE_STRNICMP
+#define strncasecmp strnicmp
+#else /* ! HAVE_STRNICMP */
+/* Rename strncasecmp to avoid ANSI C name space. */
+#define strncasecmp xstrncasecmp
+extern int strncasecmp P((const char *z1, const char *z2, size_t clen));
+#endif /* ! HAVE_STRNICMP */
+#endif /* ! HAVE_STRNCASECMP */
+
+#if ! HAVE_STRERROR
+/* Get a string corresponding to an error message. */
+#undef strerror
+extern char *strerror P((int ierr));
+#endif
+
+/* Get the appropriate definitions for memcmp, memcpy, memchr and
+ bzero. */
+#if ! HAVE_MEMCMP
+#if HAVE_BCMP
+#define memcmp(p1, p2, c) bcmp ((p1), (p2), (c))
+#else /* ! HAVE_BCMP */
+extern int memcmp P((constpointer p1, constpointer p2, size_t c));
+#endif /* ! HAVE_BCMP */
+#endif /* ! HAVE_MEMCMP */
+
+#if ! HAVE_MEMCPY
+#if HAVE_BCOPY
+#define memcpy(pto, pfrom, c) bcopy ((pfrom), (pto), (c))
+#else /* ! HAVE_BCOPY */
+extern pointer memcpy P((pointer pto, constpointer pfrom, size_t c));
+#endif /* ! HAVE_BCOPY */
+#endif /* ! HAVE_MEMCPY */
+
+#if ! HAVE_MEMCHR
+extern pointer memchr P((constpointer p, int b, size_t c));
+#endif
+
+#if ! HAVE_BZERO
+#if HAVE_MEMSET
+#define bzero(p, c) memset ((p), 0, (c))
+#else /* ! HAVE_MEMSET */
+extern void bzero P((pointer p, int c));
+#endif /* ! HAVE_MEMSET */
+#endif /* ! HAVE_BZERO */
+
+/* Look up a character in a string. */
+#if ! HAVE_STRCHR
+#if HAVE_INDEX
+#define strchr index
+extern char *index ();
+#else /* ! HAVE_INDEX */
+extern char *strchr P((const char *z, int b));
+#endif /* ! HAVE_INDEX */
+#endif /* ! HAVE_STRCHR */
+
+#if ! HAVE_STRRCHR
+#if HAVE_RINDEX
+#define strrchr rindex
+extern char *rindex ();
+#else /* ! HAVE_RINDEX */
+extern char *strrchr P((const char *z, int b));
+#endif /* ! HAVE_RINDEX */
+#endif /* ! HAVE_STRRCHR */
+
+/* Turn a string into a long integer. */
+#if ! HAVE_STRTOL
+extern long strtol P((const char *, char **, int));
+#endif
+
+/* Lookup a key in a sorted array. */
+#if ! HAVE_BSEARCH
+extern pointer bsearch P((constpointer pkey, constpointer parray,
+ size_t celes, size_t cbytes,
+ int (*pficmp) P((constpointer, constpointer))));
+#endif
diff --git a/gnu/libexec/uucp/common_sources/uudefs.h b/gnu/libexec/uucp/common_sources/uudefs.h
new file mode 100644
index 000000000000..47d2c89896ef
--- /dev/null
+++ b/gnu/libexec/uucp/common_sources/uudefs.h
@@ -0,0 +1,445 @@
+/* uudefs.h
+ Miscellaneous definitions for the UUCP package.
+
+ Copyright (C) 1991, 1992 Ian Lance Taylor
+
+ This file is part of the Taylor UUCP package.
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ The author of the program may be contacted at ian@airs.com or
+ c/o Infinity Development Systems, P.O. Box 520, Waltham, MA 02254.
+ */
+
+#if ANSI_C
+/* These structures are used in prototypes but are not defined in this
+ header file. */
+struct uuconf_system;
+struct uuconf_timespan;
+#endif
+
+/* The tlog enumeration holds the different types of logging. */
+enum tlog
+{
+ /* Normal log entry. */
+ LOG_NORMAL,
+ /* Error log entry. */
+ LOG_ERROR,
+ /* Fatal log entry. */
+ LOG_FATAL
+#if DEBUG > 1
+ ,
+ /* Debugging log entry. */
+ LOG_DEBUG,
+ /* Start debugging log entry. */
+ LOG_DEBUG_START,
+ /* Continue debugging log entry. */
+ LOG_DEBUG_CONTINUE,
+ /* End debugging log entry. */
+ LOG_DEBUG_END
+#endif
+};
+
+/* The tstatus_type enumeration holds the kinds of status information
+ we put in the status file. The order of entries here corresponds
+ to the order of entries in the azStatus array. */
+enum tstatus_type
+{
+ /* Conversation complete. */
+ STATUS_COMPLETE,
+ /* Port unavailable. */
+ STATUS_PORT_FAILED,
+ /* Dial failed. */
+ STATUS_DIAL_FAILED,
+ /* Login failed. */
+ STATUS_LOGIN_FAILED,
+ /* Handshake failed. */
+ STATUS_HANDSHAKE_FAILED,
+ /* Failed after logging in. */
+ STATUS_FAILED,
+ /* Talking to remote system. */
+ STATUS_TALKING,
+ /* Wrong time to call. */
+ STATUS_WRONG_TIME,
+ /* Number of status values. */
+ STATUS_VALUES
+};
+
+/* An array to convert status entries to strings. If more status entries
+ are added, this array must be extended. */
+extern const char *azStatus[];
+
+/* The sstatus structure holds the contents of a system status file. */
+struct sstatus
+{
+ /* Current status of conversation. */
+ enum tstatus_type ttype;
+ /* Number of failed retries. */
+ int cretries;
+ /* Time of last call in seconds since epoch (determined by
+ ixsysdep_time). */
+ long ilast;
+ /* Number of seconds until a retry is permitted. */
+ int cwait;
+};
+
+/* How long we have to wait for the next call, given the number of retries
+ we have already made. This should probably be configurable. */
+#define CRETRY_WAIT(c) ((c) * 10 * 60)
+
+/* The scmd structure holds a complete UUCP command. */
+struct scmd
+{
+ /* Command ('S' for send, 'R' for receive, 'X' for execute, 'E' for
+ simple execution, 'H' for hangup, 'Y' for hangup confirm, 'N' for
+ hangup deny). */
+ char bcmd;
+ /* At least one compiler needs an explicit padding byte here. */
+ char bdummy;
+ /* Sequence handle for fsysdep_did_work. */
+ pointer pseq;
+ /* File name to transfer from. */
+ const char *zfrom;
+ /* File name to transfer to. */
+ const char *zto;
+ /* User who requested transfer. */
+ const char *zuser;
+ /* Options. */
+ const char *zoptions;
+ /* Temporary file name ('S' and 'E'). */
+ const char *ztemp;
+ /* Mode to give newly created file ('S' and 'E'). */
+ unsigned int imode;
+ /* User to notify on remote system (optional; 'S' and 'E'). */
+ const char *znotify;
+ /* File size (-1 if not supplied) ('S', 'E' and 'R'). */
+ long cbytes;
+ /* Command to execute ('E'). */
+ const char *zcmd;
+ /* Position to restart from ('R'). */
+ long ipos;
+};
+
+#if DEBUG > 1
+
+/* We allow independent control over several different types of
+ debugging output, using a bit string with individual bits dedicated
+ to particular debugging types. */
+
+/* The bit string is stored in iDebug. */
+extern int iDebug;
+
+/* Debug abnormal events. */
+#define DEBUG_ABNORMAL (01)
+/* Debug chat scripts. */
+#define DEBUG_CHAT (02)
+/* Debug initial handshake. */
+#define DEBUG_HANDSHAKE (04)
+/* Debug UUCP protocol. */
+#define DEBUG_UUCP_PROTO (010)
+/* Debug protocols. */
+#define DEBUG_PROTO (020)
+/* Debug port actions. */
+#define DEBUG_PORT (040)
+/* Debug configuration files. */
+#define DEBUG_CONFIG (0100)
+/* Debug spool directory actions. */
+#define DEBUG_SPOOLDIR (0200)
+/* Debug executions. */
+#define DEBUG_EXECUTE (0400)
+/* Debug incoming data. */
+#define DEBUG_INCOMING (01000)
+/* Debug outgoing data. */
+#define DEBUG_OUTGOING (02000)
+
+/* Maximum possible value for iDebug. */
+#define DEBUG_MAX (03777)
+
+/* Intializer for array of debug names. The index of the name in the
+ array is the corresponding bit position in iDebug. We only check
+ for prefixes, so these names only need to be long enough to
+ distinguish each name from every other. The last entry must be
+ NULL. The string "all" is also recognized to turn on all
+ debugging. */
+#define DEBUG_NAMES \
+ { "a", "ch", "h", "u", "pr", "po", "co", "s", "e", "i", "o", NULL }
+
+/* The prefix to use to turn off all debugging. */
+#define DEBUG_NONE "n"
+
+/* Check whether a particular type of debugging is being done. */
+#define FDEBUGGING(i) ((iDebug & (i)) != 0)
+
+/* These macros are used to output debugging information. I use
+ several different macros depending on the number of arguments
+ because no macro can take a variable number of arguments and I
+ don't want to use double parentheses. */
+#define DEBUG_MESSAGE0(i, z) \
+ do { if (FDEBUGGING (i)) ulog (LOG_DEBUG, (z)); } while (0)
+#define DEBUG_MESSAGE1(i, z, a1) \
+ do { if (FDEBUGGING (i)) ulog (LOG_DEBUG, (z), (a1)); } while (0)
+#define DEBUG_MESSAGE2(i, z, a1, a2) \
+ do { if (FDEBUGGING (i)) ulog (LOG_DEBUG, (z), (a1), (a2)); } while (0)
+#define DEBUG_MESSAGE3(i, z, a1, a2, a3) \
+ do \
+ { \
+ if (FDEBUGGING (i)) \
+ ulog (LOG_DEBUG, (z), (a1), (a2), (a3)); \
+ } \
+ while (0)
+#define DEBUG_MESSAGE4(i, z, a1, a2, a3, a4) \
+ do \
+ { \
+ if (FDEBUGGING (i)) \
+ ulog (LOG_DEBUG, (z), (a1), (a2), (a3), (a4)); \
+ } \
+ while (0)
+
+#else /* DEBUG <= 1 */
+
+/* If debugging information is not being compiled, provide versions of
+ the debugging macros which just disappear. */
+#define DEBUG_MESSAGE0(i, z)
+#define DEBUG_MESSAGE1(i, z, a1)
+#define DEBUG_MESSAGE2(i, z, a1, a2)
+#define DEBUG_MESSAGE3(i, z, a1, a2, a3)
+#define DEBUG_MESSAGE4(i, z, a1, a2, a3, a4)
+
+#endif /* DEBUG <= 1 */
+
+/* Functions. */
+
+/* Given an unknown system name, return information for an unknown
+ system. If unknown systems are not permitted, this returns FALSE.
+ Otherwise, it translates the name as necessary for the spool
+ directory, and fills in *qsys. */
+extern boolean funknown_system P((pointer puuconf, const char *zsystem,
+ struct uuconf_system *qsys));
+
+/* See whether a file belongs in the spool directory. */
+extern boolean fspool_file P((const char *zfile));
+
+/* See if the current time matches a time span. If not, return FALSE.
+ Otherwise, return TRUE and set *pival and *pcretry to the values
+ from the matching element of the span. */
+extern boolean ftimespan_match P((const struct uuconf_timespan *qspan,
+ long *pival, int *pcretry));
+
+/* Determine the maximum size that may ever be transferred, given a
+ timesize span. If there are any time gaps larger than 1 hour not
+ described by the timesize span, this returns -1. Otherwise it
+ returns the largest size that may be transferred at some time. */
+extern long cmax_size_ever P((const struct uuconf_timespan *qtimesize));
+
+/* Send mail about a file transfer. */
+extern boolean fmail_transfer P((boolean fok, const char *zuser,
+ const char *zmail, const char *zwhy,
+ const char *zfrom, const char *zfromsys,
+ const char *zto, const char *ztosys,
+ const char *zsaved));
+
+/* See whether a file is in one of a list of directories. The zpubdir
+ argument is used to pass the directory names to zsysdep_local_file.
+ If fcheck is FALSE, this does not check accessibility. Otherwise,
+ if freadable is TRUE, the user zuser must have read access to the
+ file and all appropriate directories; if freadable is FALSE zuser
+ must have write access to the appropriate directories. The zuser
+ argument may be NULL, in which case all users must have the
+ appropriate access (this is used for a remote request). */
+extern boolean fin_directory_list P((const char *zfile,
+ char **pzdirs,
+ const char *zpubdir,
+ boolean fcheck,
+ boolean freadable,
+ const char *zuser));
+
+/* Parse a command string. */
+extern boolean fparse_cmd P((char *zcmd, struct scmd *qcmd));
+
+/* Make a log entry. */
+#ifdef __GNUC__
+#define GNUC_VERSION __GNUC__
+#else
+#define GNUC_VERSION 0
+#endif
+
+#if ANSI_C && HAVE_VFPRINTF
+extern void ulog P((enum tlog ttype, const char *zfmt, ...))
+#if GNUC_VERSION > 1
+ __attribute__ ((format (printf, 2, 3)))
+#endif
+ ;
+#else
+extern void ulog ();
+#endif
+
+#undef GNUC_VERSION
+
+/* Report an error returned by one of the uuconf routines. */
+extern void ulog_uuconf P((enum tlog ttype, pointer puuconf,
+ int iuuconf));
+
+/* Set the function to call if a fatal error occurs. */
+extern void ulog_fatal_fn P((void (*pfn) P((void))));
+
+/* If ffile is TRUE, send log entries to the log file rather than to
+ stderr. */
+extern void ulog_to_file P((pointer puuconf, boolean ffile));
+
+/* Set the ID number used by the logging functions. */
+extern void ulog_id P((int iid));
+
+/* Set the system name used by the logging functions. */
+extern void ulog_system P((const char *zsystem));
+
+/* Set the system and user name used by the logging functions. */
+extern void ulog_user P((const char *zuser));
+
+/* Set the device name used by the logging functions. */
+extern void ulog_device P((const char *zdevice));
+
+/* Close the log file. */
+extern void ulog_close P((void));
+
+/* Make an entry in the statistics file. */
+extern void ustats P((boolean fsucceeded, const char *zuser,
+ const char *zsystem, boolean fsent,
+ long cbytes, long csecs, long cmicros,
+ boolean fmaster));
+
+/* Close the statistics file. */
+extern void ustats_close P((void));
+
+#if DEBUG > 1
+/* A debugging routine to output a buffer. This outputs zhdr, the
+ buffer length clen, and the contents of the buffer in quotation
+ marks. */
+extern void udebug_buffer P((const char *zhdr, const char *zbuf,
+ size_t clen));
+
+/* A debugging routine to make a readable version of a character.
+ This takes a buffer at least 5 bytes long, and returns the length
+ of the string it put into it (not counting the null byte). */
+extern size_t cdebug_char P((char *z, int ichar));
+
+/* Parse a debugging option string. This can either be a number or a
+ comma separated list of debugging names. This returns a value for
+ iDebug. */
+extern int idebug_parse P((const char *));
+
+#endif /* DEBUG <= 1 */
+
+/* Copy one file to another. */
+extern boolean fcopy_file P((const char *zfrom, const char *zto,
+ boolean fpublic, boolean fmkdirs));
+
+/* Copy an open file to another. */
+extern boolean fcopy_open_file P((openfile_t efrom, const char *zto,
+ boolean fpublic, boolean fmkdirs));
+
+/* Translate escape sequences in a buffer, leaving the result in the
+ same buffer and returning the length. */
+extern size_t cescape P((char *zbuf));
+
+/* Get a buffer to hold a string of a given size. The buffer should
+ be freed with ubuffree. */
+extern char *zbufalc P((size_t csize));
+
+/* Call zbufalc to allocate a buffer and copy a string into it. */
+extern char *zbufcpy P((const char *z));
+
+/* Free up a buffer returned by zbufalc or zbufcpy. */
+extern void ubuffree P((char *z));
+
+/* Allocate memory without fail. */
+extern pointer xmalloc P((size_t));
+
+/* Realloc memory without fail. */
+extern pointer xrealloc P((pointer, size_t));
+
+/* Free memory (accepts NULL pointers, which some libraries erroneously
+ do not). */
+extern void xfree P((pointer));
+
+/* Global variables. */
+
+/* The name of the program being run. This is statically initialized,
+ although it should perhaps be set from argv[0]. */
+extern char abProgram[];
+
+/* When a signal occurs, the signal handlers sets the appropriate
+ element of the arrays afSignal and afLog_signal to TRUE. The
+ afSignal array is used to check whether a signal occurred. The
+ afLog_signal array tells ulog to log the signal; ulog will clear
+ the element after logging it, which means that if a signal comes in
+ at just the right moment it will not be logged. It will always be
+ recorded in afSignal, though. At the moment we handle 5 signals:
+ SIGHUP, SIGINT, SIGQUIT, SIGTERM and SIGPIPE (the Unix code also
+ handles SIGALRM). If we want to handle more, the afSignal array
+ must be extended; I see little point to handling any of the other
+ ANSI C or POSIX signals, as they are either unlikely to occur
+ (SIGABRT, SIGUSR1) or nearly impossible to handle cleanly (SIGILL,
+ SIGSEGV). SIGHUP is only logged if fLog_sighup is TRUE. */
+#define INDEXSIG_SIGHUP (0)
+#define INDEXSIG_SIGINT (1)
+#define INDEXSIG_SIGQUIT (2)
+#define INDEXSIG_SIGTERM (3)
+#define INDEXSIG_SIGPIPE (4)
+#define INDEXSIG_COUNT (5)
+
+extern volatile sig_atomic_t afSignal[INDEXSIG_COUNT];
+extern volatile sig_atomic_t afLog_signal[INDEXSIG_COUNT];
+extern boolean fLog_sighup;
+
+/* The names of the signals to use in error messages, as an
+ initializer for an array. */
+#define INDEXSIG_NAMES \
+ { "hangup", "interrupt", "quit", "termination", "SIGPIPE" }
+
+/* Check to see whether we've received a signal. It would be nice if
+ we could use a single variable for this, but we sometimes want to
+ clear our knowledge of a signal and that would cause race
+ conditions (clearing a single element of the array is not a race
+ assuming that we don't care about a particular signal, even if it
+ occurs after we've examined the array). */
+#define FGOT_SIGNAL() \
+ (afSignal[INDEXSIG_SIGHUP] || afSignal[INDEXSIG_SIGINT] \
+ || afSignal[INDEXSIG_SIGQUIT] || afSignal[INDEXSIG_SIGTERM] \
+ || afSignal[INDEXSIG_SIGPIPE])
+
+/* If we get a SIGINT in uucico, we continue the current communication
+ session but don't start any new ones. This macros checks for any
+ signal other than SIGINT, which means we should get out
+ immediately. */
+#define FGOT_QUIT_SIGNAL() \
+ (afSignal[INDEXSIG_SIGHUP] || afSignal[INDEXSIG_SIGQUIT] \
+ || afSignal[INDEXSIG_SIGTERM] || afSignal[INDEXSIG_SIGPIPE])
+
+/* File being sent. */
+extern openfile_t eSendfile;
+
+/* File being received. */
+extern openfile_t eRecfile;
+
+/* Device name to log. This is set by fconn_open. It may be NULL. */
+extern char *zLdevice;
+
+/* If not NULL, ulog calls this function before outputting anything.
+ This is used to support cu. */
+extern void (*pfLstart) P((void));
+
+/* If not NULL, ulog calls this function after outputting everything.
+ This is used to support cu. */
+extern void (*pfLend) P((void));