diff options
| author | mycroft <mycroft@NetBSD.org> | 1995-03-01 00:00:00 +0000 |
|---|---|---|
| committer | mycroft <mycroft@NetBSD.org> | 1995-03-01 00:00:00 +0000 |
| commit | 4c34be6b52a699cc7287e3b937a69ca90fd2ced9 (patch) | |
| tree | 0b0c2cc7c7d71419513e6302a3adf0b1829bf333 /gnu/libexec | |
| parent | 5c42185b5c628c038e11439c03ffcad1b27f6ec5 (diff) | |
Clean up deleted files.
Diffstat (limited to 'gnu/libexec')
57 files changed, 0 insertions, 49449 deletions
diff --git a/gnu/libexec/uucp/config.c b/gnu/libexec/uucp/config.c deleted file mode 100644 index aee11f8e3cc..00000000000 --- a/gnu/libexec/uucp/config.c +++ /dev/null @@ -1,1044 +0,0 @@ -/* config.c - Read the configuration 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 AIRS, P.O. Box 520, Waltham, MA 02254. - - $Log: config.c,v $ - Revision 1.1.1.1 1993/03/21 09:45:37 cgd - initial import of 386bsd-0.1 sources - - Revision 1.29 1992/03/28 22:06:38 ian - Michael I Bushnell: renamed enum tstatus to avoid header file conflict - - Revision 1.28 1992/03/28 21:47:55 ian - David J. MacKenzie: allow backslash to quote newline in config files - - Revision 1.27 1992/03/28 04:26:12 ian - David J. MacKenzie: cMaxuuxqts is independent of HAVE_TAYLOR_CONFIG - - Revision 1.26 1992/03/18 23:12:37 ian - Handle CMDTABTYPE_FULLSTRING correctly if there are no arguments - - Revision 1.25 1992/03/17 01:03:03 ian - Miscellaneous cleanup - - Revision 1.24 1992/03/12 19:54:43 ian - Debugging based on types rather than number - - Revision 1.23 1992/03/11 22:06:37 ian - Marty Shannon: added max-uuxqts command - - Revision 1.22 1992/03/09 05:08:16 ian - Added status for wrong time to call, not used if system can't be called - - Revision 1.21 1992/03/04 21:39:04 ian - Local variables in igradecmp have to be integers - - Revision 1.20 1992/03/03 06:06:48 ian - T. William Wells: don't complain about missing configuration files - - Revision 1.19 1992/02/29 01:06:59 ian - Chip Salzenberg: recheck file permissions before sending - - Revision 1.18 1992/02/24 04:58:47 ian - Only permit files to be received into directories that are world-writeable - - Revision 1.17 1992/02/08 03:54:18 ian - Include <string.h> only in <uucp.h>, added 1992 copyright - - Revision 1.16 1992/01/15 07:06:29 ian - Set configuration directory in Makefile rather than sysdep.h - - Revision 1.15 1992/01/14 04:04:17 ian - Chip Salzenberg: strcmp is a macro on AIX - - Revision 1.14 1991/12/29 04:04:18 ian - Added a bunch of extern definitions - - Revision 1.13 1991/12/29 01:54:46 ian - Terry Gardner: allow a # character to be quoted in a configuration file - - Revision 1.12 1991/12/22 20:57:57 ian - Added externs for strcasecmp or strncasecmp - - Revision 1.11 1991/12/18 03:54:14 ian - Made error messages to terminal appear more normal - - Revision 1.10 1991/12/15 03:42:33 ian - Added tprocess_chat_cmd for all chat commands, and added CMDTABTYPE_PREFIX - - Revision 1.9 1991/12/13 22:43:06 ian - Don't continually allocate and free the list of arguments - - Revision 1.8 1991/12/09 18:39:46 ian - Richard Todd: the pushed back line is specific to a particular multi file - - Revision 1.7 1991/12/09 16:59:48 ian - Richard Todd: don't warn if special "#" command is unrecognized - - Revision 1.6 1991/12/07 18:05:20 ian - Franc,ois Pinard: no limit to number of arguments - - Revision 1.5 1991/12/03 02:38:26 ian - Don't treat numbers with leading zeroes as octal - - Revision 1.4 1991/12/01 19:35:38 ian - David Nugent: read V2 and BNU files by default even with TAYLOR_CONFIG - - Revision 1.3 1991/11/26 02:04:49 ian - Bob Denny: add explicit extern for strcmp and strcasecmp - - Revision 1.2 1991/09/19 02:38:21 ian - Chip Salzenberg: V2 and BNU dialcodes files are relative to CONFIGLIB - - Revision 1.1 1991/09/10 19:38:34 ian - Initial revision - - */ - -#include "uucp.h" - -#if USE_RCS_ID -char config_rcsid[] = "$Id: config.c,v 1.1.1.1 1993/03/21 09:45:37 cgd Exp $"; -#endif - -#include <ctype.h> -#include <errno.h> - -#include "system.h" -#include "sysdep.h" - -/* Some systems make strcmp a macro, which screws us up since we want - to declare it since we will take its address later. */ -#undef strcmp -#undef strncmp - -/* External functions. */ -extern int strcmp (), strncmp (), strcasecmp (), strncasecmp (); -extern int fclose (); - -/* Local functions. */ - -static void umulti_pushback P((struct smulti_file *, char *)); - -/* Status strings. These must match enum tstatus_type. */ - -const char *azStatus[] = -{ - "Conversation complete", - "Port unavailable", - "Dial failed", - "Login failed", - "Handshake failed", - "Call failed", - "Talking", - "Wrong time to call" -}; - -/* Local node name. */ -const char *zLocalname; - -/* Spool directory. */ -const char *zSpooldir = SPOOLDIR; - -#if DEBUG > 1 -/* Debugging level. */ -int iDebug = 0; - -/* Debugging file name. */ -const char *zDebugfile = DEBUGFILE; -#endif - -/* Public directory. */ -const char *zPubdir = PUBDIR; - -/* Log file name. */ -const char *zLogfile = LOGFILE; - -/* Statistics file name. */ -const char *zStatfile = STATFILE; - -/* Dialcode file names. */ -char *zDialcodefile; - -/* The maximum number of uuxqt processes which may be running at one - time. If this is zero, there is no limit. */ -int cMaxuuxqts; - -#if HAVE_TAYLOR_CONFIG - -/* System file names. */ -char *zSysfile; - -/* Port file names. */ -char *zPortfile; - -/* Dialer file names. */ -char *zDialfile; - -/* Call out login and password file names. */ -char *zCallfile; - -/* Call in login and password file names. */ -char *zPwdfile; - -/* Command table used to parse the configuration file. */ - -static enum tcmdtabret tcadd P((int argc, char **argv, pointer pvar, - const char *zerr)); - -const struct scmdtab asCmds[] = -{ - /* System name. */ - { "nodename", CMDTABTYPE_STRING, (pointer) &zLocalname, NULL }, - { "hostname", CMDTABTYPE_STRING, (pointer) &zLocalname, NULL }, - { "uuname", CMDTABTYPE_STRING, (pointer) &zLocalname, NULL }, - /* Spool directory. */ - { "spool", CMDTABTYPE_STRING, (pointer) &zSpooldir, NULL }, - /* System information files. */ - { "sysfile", CMDTABTYPE_FN | 0, (pointer) &zSysfile, tcadd }, - /* Port files. */ - { "portfile", CMDTABTYPE_FN | 0, (pointer) &zPortfile, tcadd }, - /* Dial files. */ - { "dialfile", CMDTABTYPE_FN | 0, (pointer) &zDialfile, tcadd }, - /* Dialcode files. */ - { "dialcodefile", CMDTABTYPE_FN | 0, (pointer) &zDialcodefile, tcadd }, - /* Public directory. */ - { "pubdir", CMDTABTYPE_STRING, (pointer) &zPubdir, NULL }, - /* Call out login name and password files. */ - { "callfile", CMDTABTYPE_FN | 0, (pointer) &zCallfile, tcadd }, - /* Call in login name and password files. */ - { "passwdfile", CMDTABTYPE_FN | 0, (pointer) &zPwdfile, tcadd }, - /* Log file. */ - { "logfile", CMDTABTYPE_STRING, (pointer) &zLogfile, NULL }, - /* Statistics file. */ - { "statfile", CMDTABTYPE_STRING, (pointer) &zStatfile, NULL }, -#if DEBUG > 1 - /* Debugging file. */ - { "debugfile", CMDTABTYPE_STRING, (pointer) &zDebugfile, NULL }, - /* Debugging level. */ - { "debug", CMDTABTYPE_FN | 0, (pointer) &iDebug, tidebug_parse }, -#endif - /* Command for unknown system. */ - { "unknown", CMDTABTYPE_FN, NULL, tiunknown }, - /* Maximum number of uuxqt processes. */ - { "max-uuxqts", CMDTABTYPE_INT, (pointer) &cMaxuuxqts, NULL }, -#if HAVE_V2_CONFIG - { "v2-files", CMDTABTYPE_BOOLEAN, (pointer) &fV2, NULL }, -#endif -#if HAVE_BNU_CONFIG - { "bnu-files", CMDTABTYPE_BOOLEAN, (pointer) &fBnu, NULL }, -#endif - /* End marker. */ - { NULL, 0, NULL, NULL } -}; - -/* Add strings to a string variable, separating with spaces. */ - -/*ARGSUSED*/ -static enum tcmdtabret -tcadd (argc, argv, pvar, zerr) - int argc; - char **argv; - pointer pvar; - const char *zerr; -{ - int i; - - for (i = 1; i < argc; i++) - uadd_string ((char **) pvar, argv[i], ' '); - return CMDTABRET_FREE; -} - -#endif /* HAVE_TAYLOR_CONFIG */ - -/* Process commands from a stdio file according to a command table. - The character '#' introduces a comment. Exactly one of e and - qmulti must be NULL. If we get the first line of a multi file, we - attempt to process the command "#"; this command will not arise - from a normal command file, and lets the caller take special action - at the start of a new file. If we are reading with zmulti_gets, we - ignore the zerr argument and instead use the name of the file. */ - -void -uprocesscmds (e, qmulti, qcmds, zerr, iflags) - FILE *e; - struct smulti_file *qmulti; - const struct scmdtab *qcmds; - const char *zerr; - int iflags; -{ - while (TRUE) - { - static char **pzargs; - static int calloc_args; - char *zget, *z; - int cargs; - enum tcmdtabret t; - char **pzhold_args; - int chold_alloc_args; - - if (e != NULL) - zget = zfgets (e, (iflags & CMDFLAG_BACKSLASH) != 0); - else - { - boolean ffirst; - - zget = zmulti_gets (qmulti, &ffirst, &zerr, - (iflags & CMDFLAG_BACKSLASH) != 0); - if (zget != NULL && ffirst) - { - char *zargs; - - zargs = (char *) "#"; - t = tprocess_one_cmd (1, &zargs, qcmds, zerr, - iflags &~ CMDFLAG_WARNUNRECOG); - if (t == CMDTABRET_EXIT || t == CMDTABRET_FREE_AND_EXIT) - { - umulti_pushback (qmulti, zget); - return; - } - } - } - - if (zget == NULL) - return; - - /* Any # character not preceeded by a backslash starts a - comment. */ - z = zget; - while ((z = strchr (z, '#')) != NULL) - { - if (z == zget || *(z - 1) != '\\') - { - *z = '\0'; - break; - } - /* Remove the backslash. */ - xmemmove (z - 1, z, strlen (z) + 1); - } - - z = zget; - cargs = 0; - while (TRUE) - { - while (*z != '\0' && isspace (BUCHAR (*z))) - z++; - - if (*z == '\0') - break; - - if (cargs >= calloc_args) - { - calloc_args += 10; - pzargs = (char **) xrealloc ((pointer) pzargs, - calloc_args * sizeof (char *)); - } - - pzargs[cargs] = z; - ++cargs; - - while (*z != '\0' && ! isspace (BUCHAR (*z))) - z++; - - if (*z == '\0') - break; - - *z++ = '\0'; - } - - if (cargs <= 0) - { - xfree ((pointer) zget); - continue; - } - - /* Save off the static variables to allow this function to - be called recursively. */ - pzhold_args = pzargs; - chold_alloc_args = calloc_args; - pzargs = NULL; - calloc_args = 0; - - t = tprocess_one_cmd (cargs, pzhold_args, qcmds, zerr, iflags); - - if (pzargs != NULL) - xfree ((pointer) pzargs); - pzargs = pzhold_args; - calloc_args = chold_alloc_args; - - if (t == CMDTABRET_FREE || t == CMDTABRET_FREE_AND_EXIT) - xfree ((pointer) zget); - if (t == CMDTABRET_EXIT || t == CMDTABRET_FREE_AND_EXIT) - return; - } -} - -/* Process a single command. */ - -enum tcmdtabret -tprocess_one_cmd (cargs, azargs, qcmds, zerr, iflags) - int cargs; - char **azargs; - const struct scmdtab *qcmds; - const char *zerr; - int iflags; -{ - const struct scmdtab *q; - int (*pfcmp) P((const char *, const char *)); - - if ((iflags & CMDFLAG_CASESIGNIFICANT) != 0) - pfcmp = strcmp; - else - pfcmp = strcasecmp; - - for (q = qcmds; q->zcmd != NULL; q++) - { - int itype; - int callowed; - - itype = TTYPE_CMDTABTYPE (q->itype); - if (itype != CMDTABTYPE_PREFIX) - { - if ((*pfcmp) (q->zcmd, azargs[0]) != 0) - continue; - } - else - { - int clen; - - clen = strlen (q->zcmd); - if ((iflags & CMDFLAG_CASESIGNIFICANT) != 0) - { - if (strncmp (q->zcmd, azargs[0], clen) != 0) - continue; - } - else - { - if (strncasecmp (q->zcmd, azargs[0], clen) != 0) - continue; - } - } - - callowed = CARGS_CMDTABTYPE (q->itype); - if (callowed != 0 && callowed != cargs) - { - if (zerr != NULL) - ulog (LOG_ERROR, "%s: %s: Wrong number of arguments", - zerr, q->zcmd); - return CMDTABRET_FREE; - } - else if (itype == TTYPE_CMDTABTYPE (CMDTABTYPE_STRING)) - { - if (cargs != 1 && cargs != 2) - { - if (zerr != NULL) - ulog (LOG_ERROR, "%s: %s: Wrong number of arguments", - zerr, q->zcmd); - return CMDTABRET_FREE; - } - if (cargs == 1) - *(const char **) q->pvar = ""; - else - *(const char **) q->pvar = azargs[1]; - return CMDTABRET_CONTINUE; - } - else if (itype == TTYPE_CMDTABTYPE (CMDTABTYPE_INT) - || itype == TTYPE_CMDTABTYPE (CMDTABTYPE_LONG)) - { - long i; - char *zend; - - i = strtol (azargs[1], &zend, 10); - if (*zend != '\0') - { - if (zerr != NULL) - ulog (LOG_ERROR, "%s: %s: Bad number", zerr, - q->zcmd); - return CMDTABRET_FREE; - } - if (itype == TTYPE_CMDTABTYPE (CMDTABTYPE_INT)) - * (int *) q->pvar = (int) i; - else - * (long *) q->pvar = i; - - return CMDTABRET_FREE; - } - else if (itype == TTYPE_CMDTABTYPE (CMDTABTYPE_BOOLEAN)) - { - char b; - - b = azargs[1][0]; - if (b == 'y' || b == 'Y' || b == 't' || b == 'T') - * (boolean *) q->pvar = TRUE; - else if (b == 'n' || b == 'N' || b == 'f' || b == 'F') - * (boolean *) q->pvar = FALSE; - else if (zerr != NULL) - ulog (LOG_ERROR, "%s: %s: Bad boolean", zerr, - q->zcmd); - return CMDTABRET_FREE; - } - else if (itype == TTYPE_CMDTABTYPE (CMDTABTYPE_FULLSTRING)) - { - int i, clen; - char *zset; - - /* Use all the arguments separated by a ' ' - character. */ - - clen = 1; - for (i = 1; i < cargs; i++) - clen += strlen (azargs[i]) + 1; - - zset = (char *) xmalloc (clen); - *zset = '\0'; - for (i = 1; i < cargs - 1; i++) - { - strcat (zset, azargs[i]); - strcat (zset, " "); - } - if (i < cargs) - strcat (zset, azargs[i]); - - * (const char **) q->pvar = zset; - - return CMDTABRET_FREE; - } - else if (itype == TTYPE_CMDTABTYPE (CMDTABTYPE_FN) - || itype == TTYPE_CMDTABTYPE (CMDTABTYPE_PREFIX)) - return (*q->ptfn) (cargs, azargs, q->pvar, zerr); - else - { -#if DEBUG > 0 - ulog (LOG_FATAL, "tprocess_one_cmd: Can't happen (0x%x)", - itype); -#endif - return CMDTABRET_FREE; - } - } - - if ((iflags & CMDFLAG_WARNUNRECOG) != 0 - && zerr != NULL) - ulog (LOG_ERROR, "%s: Unrecognized command %s", zerr, azargs[0]); - - return CMDTABRET_FREE; -} - -/* Read the configuration file. If we can't open the configuration file, - and we're trying to read the default, don't report an error. This - permits people to not have a configuration file at all if they are - satisfied with the compiled in defaults. */ - -void -uread_config (zname) - const char *zname; -{ -#if HAVE_TAYLOR_CONFIG - - FILE *e; - char *zdefault; - - zdefault = (char *) alloca (sizeof NEWCONFIGLIB + sizeof CONFIGFILE); - sprintf (zdefault, "%s%s", NEWCONFIGLIB, CONFIGFILE); - - /* On UNIX we will be probably be running suid to uucp. We don't want - to let somebody run us and specify some arbitrary file as the - configuration file, since that might let them examine files they - have no access to. */ - if (zname != NULL - && strcmp (zname, zdefault) != 0 - && ! fsysdep_other_config (zname)) - { - ulog (LOG_ERROR, "Can't read %s; using %s", zname, zdefault); - zname = zdefault; - } - - if (zname == NULL) - zname = zdefault; - - e = fopen (zname, "r"); - if (e == NULL) - { - if (strcmp (zname, zdefault) != 0) - { - fprintf (stderr, "%s: %s: %s\n", abProgram, zname, - strerror (errno)); - /* We haven't yet called usysdep_initialize, so it should be - safe to just exit. */ - exit (EXIT_FAILURE); - } - /* Just use defaults. */ - } - else - { - uiunknown_start (); - uprocesscmds (e, (struct smulti_file *) NULL, asCmds, zname, - CMDFLAG_BACKSLASH); - (void) fclose (e); - uiunknown_end (); - } - -#else /* ! HAVE_TAYLOR_CONFIG */ - - uiunknown_start (); - uiunknown_end (); - -#endif /* ! HAVE_TAYLOR_CONFIG */ - - if (zLocalname == NULL) - { - zLocalname = zsysdep_local_name (); - if (zLocalname == NULL) - { - fprintf (stderr, "%s: Can't get local node name\n", abProgram); - exit (EXIT_FAILURE); - } - } - - uisetup_localsys (); - -#if HAVE_TAYLOR_CONFIG - - /* Get the defaults for the file names. */ - -#define SETDEFAULT(z, zfile) \ - if (z == NULL) \ - { \ - z = (char *) xmalloc (sizeof NEWCONFIGLIB + sizeof zfile - 1); \ - strcpy (z, NEWCONFIGLIB); \ - strcat (z, zfile); \ - if (! fsysdep_file_exists (z)) \ - { \ - xfree ((pointer) z); \ - z = NULL; \ - } \ - } - - SETDEFAULT (zSysfile, SYSFILE); - SETDEFAULT (zPortfile, PORTFILE); - SETDEFAULT (zDialfile, DIALFILE); - SETDEFAULT (zDialcodefile, DIALCODEFILE); - SETDEFAULT (zPwdfile, PASSWDFILE); - SETDEFAULT (zCallfile, CALLFILE); - -#endif /* HAVE_TAYLOR_CONFIG */ - -#if HAVE_BNU_CONFIG - /* If we are supposed to read standard BNU files, read Sysfiles to - get any nonstandard file names. */ - if (fBnu) - ubnu_read_sysfiles (); -#endif /* HAVE_BNU_CONFIG */ - - /* The format of the dialcodes file is the same for all systems, so - if additional configuration are being used we add the files in - here to save having to do it when the dialcodes file is read. */ - -#if HAVE_V2_CONFIG - if (fV2) - { - char *z; - - z = (char *) alloca (sizeof OLDCONFIGLIB + sizeof V2_DIALCODES); - sprintf (z, "%s%s", OLDCONFIGLIB, V2_DIALCODES); - uadd_string (&zDialcodefile, z, ' '); - } -#endif /* HAVE_V2_CONFIG */ - -#if HAVE_BNU_CONFIG - if (fBnu) - { - char *z; - - z = (char *) alloca (sizeof OLDCONFIGLIB + sizeof BNU_DIALCODES); - sprintf (z, "%s%s", OLDCONFIGLIB, BNU_DIALCODES); - uadd_string (&zDialcodefile, z, ' '); - } -#endif /* HAVE_BNU_CONFIG */ -} - -/* Add a string to a list of strings separated by a separator - character. */ - -void -uadd_string (pz, z, bsep) - char **pz; - const char *z; - int bsep; -{ - if (*pz == NULL) - *pz = xstrdup (z); - else - { - int clen; - - clen = strlen (*pz); - *pz = (char *) xrealloc ((pointer) *pz, clen + strlen (z) + 2); - (*pz)[clen] = (char) bsep; - strcpy (*pz + clen + 1, z); - } -} - -#if DEBUG > 1 - -/* Parse a debugging string. This may be a simple number, which sets - the given number of bits in iDebug, or it may be a series of single - letters. */ - -static const char * const azDebug_names[] = DEBUG_NAMES; - -int -idebug_parse (z) - const char *z; -{ - char *zend; - int i, iret; - char *zcopy, *ztok; - - i = (int) strtol (z, &zend, 0); - if (*zend == '\0') - { - if (i > 15) - i = 15; - else if (i < 0) - i = 0; - return (1 << i) - 1; - } - - zcopy = (char *) alloca (strlen (z) + 1); - strcpy (zcopy, z); - - iret = 0; - - for (ztok = strtok (zcopy, ","); - ztok != NULL; - ztok = strtok ((char *) NULL, ",")) - { - if (strcasecmp (ztok, "all") == 0) - { - iret = DEBUG_MAX; - break; - } - for (i = 0; azDebug_names[i] != NULL; i++) - { - if (strncasecmp (ztok, azDebug_names[i], - strlen (azDebug_names[i])) == 0) - { - iret |= 1 << i; - break; - } - } - if (azDebug_names[i] == NULL) - ulog (LOG_ERROR, "Unrecognized debugging option \"%s\"", - ztok); - } - - return iret; -} - -/* Parse a debugging string in a configuration file. The pvar - arguments points to the field to set. */ - -/*ARGSUSED*/ -enum tcmdtabret -tidebug_parse (argc, argv, pvar, zerr) - int argc; - char **argv; - pointer pvar; - const char *zerr; -{ - int *pidebug = (int *) pvar; - int i; - - if (argc == 2 && - strncasecmp (argv[1], DEBUG_NONE, strlen (DEBUG_NONE)) == 0) - { - *pidebug = 0; - return CMDTABRET_FREE; - } - - for (i = 1; i < argc; i++) - *pidebug |= idebug_parse (argv[i]); - - return CMDTABRET_FREE; -} - -#endif /* DEBUG > 1 */ - -/* Given a file name that may actually be several file names each - separated with a single space character, we want to be able to read - lines from them as though they were catenated to form a single - file. This set of routines allows us to do that easily, although - only for one set of files at a time. One line can be pushed back, - which can be convenient for the first line of a file. */ - -struct smulti_file -{ - /* Names of next files to open. */ - char *z; - /* String to free up when done. */ - char *zfree; - /* Current file. */ - FILE *e; - /* Current file name. */ - char *zname; - /* Next line to return. */ - char *znext; -}; - -struct smulti_file * -qmulti_open (znames) - const char *znames; -{ - struct smulti_file *qret; - - qret = (struct smulti_file *) xmalloc (sizeof (struct smulti_file)); - qret->z = qret->zfree = xstrdup (znames); - qret->zname = NULL; - qret->e = NULL; - qret->znext = NULL; - - return qret; -} - -/* Read the next line from a multiply opened set of files. */ - -char * -zmulti_gets (q, pffirst, pzname, fbackslash) - struct smulti_file *q; - boolean *pffirst; - const char **pzname; - boolean fbackslash; -{ - if (pffirst != NULL) - *pffirst = FALSE; - - if (q->znext != NULL) - { - char *z; - - z = q->znext; - q->znext = NULL; - return z; - } - - while (TRUE) - { - char *z; - - if (q->e != NULL) - { - char *zret; - - zret = zfgets (q->e, fbackslash); - if (zret != NULL) - { - if (pzname != NULL) - *pzname = q->zname; - return zret; - } - - if (fclose (q->e) != 0) - { - ulog (LOG_ERROR, "fclose: %s", strerror (errno)); - q->e = NULL; - return NULL; - } - - q->e = NULL; - } - - if (*q->z == '\0') - return NULL; - - z = q->z; - q->z += strcspn (z, " "); - if (*q->z != '\0') - *q->z++ = '\0'; - - q->e = fopen (z, "r"); - if (q->e == NULL) - { - ulog (LOG_ERROR, "fopen (%s): %s", z, strerror (errno)); - return NULL; - } - - if (pffirst != NULL) - *pffirst = TRUE; - q->zname = z; - } -} - -/* Push back a line so that it is read by the next call to - zmulti_gets. This is sometimes used on the first line of a file in - uprocesscmds. */ - -static void -umulti_pushback (q, z) - struct smulti_file *q; - char *z; -{ -#if DEBUG > 0 - if (q->znext != NULL) - ulog (LOG_FATAL, "umulti_pushback: Can't happen"); -#endif - q->znext = z; -} - -/* Close the multiple file, even though a read is in progress. If - zmulti_gets returns NULL, the files will have been closed. */ - -boolean -fmulti_close (q) - struct smulti_file *q; -{ - boolean fret; - - fret = TRUE; - - if (q->e != NULL) - { - if (fclose (q->e) != 0) - { - ulog (LOG_ERROR, "fclose: %s", strerror (errno)); - fret = FALSE; - } - } - - xfree ((pointer) q->zfree); - xfree ((pointer) q); - - return fret; -} - -/* See whether a file is in a directory list, and make sure the user - has appropriate access. */ - -boolean -fin_directory_list (qsys, zfile, zdirs, fcheck, freadable, zuser) - const struct ssysteminfo *qsys; - const char *zfile; - const char *zdirs; - boolean fcheck; - boolean freadable; - const char *zuser; -{ - char *zcopy; - boolean fmatch; - - zcopy = (char *) alloca (strlen (zdirs) + 1); - strcpy (zcopy, zdirs); - - fmatch = FALSE; - - while (*zcopy != '\0') - { - char *z; - - z = zcopy + strcspn (zcopy, " "); - if (*z == '\0') - --z; - else - *z = '\0'; - - if (*zcopy == '!') - { - if (fsysdep_in_directory (qsys, zfile, zcopy + 1, FALSE, - FALSE, (const char *) NULL)) - fmatch = FALSE; - } - else - { - if (fsysdep_in_directory (qsys, zfile, zcopy, fcheck, - freadable, zuser)) - fmatch = TRUE; - } - - zcopy = z + 1; - } - - return fmatch; -} - -/* See whether a file is a spool file. Spool file names are specially - crafted to hand around to other UUCP packages. They always begin - with 'C', 'D' or 'X', and the second character is always a period. - The remaining characters are any character that could appear in a - system name. */ - -boolean -fspool_file (zfile) - const char *zfile; -{ - const char *z; - - if (*zfile != 'C' && *zfile != 'D' && *zfile != 'X') - return FALSE; - if (zfile[1] != '.') - return FALSE; - for (z = zfile + 2; *z != '\0'; z++) - if (! isalnum (BUCHAR (*z)) && *z != '_' && *z != '-' && *z != '.') - return FALSE; - return TRUE; -} - -/* Compare two grades, returning < 0 if the first should be executed - before the second, == 0 if they are the same, and > 0 if the first - should be executed after the second. This code assumes that the - upper case letters appear in sequence and the lower case letters - appear in sequence. */ - -int -igradecmp (barg1, barg2) - int barg1; - int barg2; -{ - int b1, b2; - - /* Make sure the arguments are unsigned. */ - b1 = (int) BUCHAR (barg1); - b2 = (int) BUCHAR (barg2); - - if (isdigit (b1)) - { - if (isdigit (b2)) - return b1 - b2; - else - return -1; - } - else if (isupper (b1)) - { - if (isdigit (b2)) - return 1; - else if (isupper (b2)) - return b1 - b2; - else - return -1; - } - else - { - if (! islower (b2)) - return 1; - else - return b1 - b2; - } -} diff --git a/gnu/libexec/uucp/config.status b/gnu/libexec/uucp/config.status deleted file mode 100644 index fd56c992df5..00000000000 --- a/gnu/libexec/uucp/config.status +++ /dev/null @@ -1,11 +0,0 @@ -DEFS="" -LIBS="" -INSTALL="/usr/bin/install -c" -INSTALLDATA="/usr/bin/install -c -m 644" -CC="gcc -O" -CFLAGS="-g" -LDFLAGS="" -LN_S="ln -s" -ALLOCA="" -UUDIR="# " - diff --git a/gnu/libexec/uucp/configure b/gnu/libexec/uucp/configure deleted file mode 100644 index 9dcf886067e..00000000000 --- a/gnu/libexec/uucp/configure +++ /dev/null @@ -1,936 +0,0 @@ -: -# Guess values for system-dependent variables and create Makefiles. -# Generated automatically by autoconf. -# Copyright (C) 1991 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, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -# Usage: configure [--srcdir=DIR] [--host=HOST] [--gas] [--nfp] [TARGET] -# All args except --srcdir=DIR are ignored. - -trap 'rm -f conftest conftest.c; exit 1' 1 3 15 - -set +u # Make sure unset variables are ok. - -for arg in $*; do - # Handle --srcdir with a space before the argument. - if test x$next_srcdir = xyes; then srcdir=$arg; next_srcdir= - # Handle --host with a space before the argument. - elif test x$next_host = xyes; then next_host= - else - case $arg in - +srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=* | --s=*) - srcdir=`echo $arg | sed 's/[+-]s[a-z]*=//'` ;; - +srcdir | --srcdir | --srcdi | --srcd | --src | --sr | --s) - next_srcdir=yes ;; - +host=* | --host=* | --hos=* | --ho=* | --h=*) ;; - +host | --host | --hos | --ho | --h) - next_host=yes ;; - +gas | --gas | --ga | --g) ;; - +nfp | --nfp | --nf | --n) ;; - *) ;; - esac - fi -done - -INCLUDEDIR=${INCLUDEDIR-/usr/include} - -rm -f conftest conftest.c -compile='$CC $DEFS conftest.c -o conftest $LIBS >/dev/null 2>&1' - -# A filename unique to this package, relative to the directory that -# configure is in, which we can look for to find out if srcdir is correct. -unique_file=uucico.c - -# Makefile rules whose targets are searched for in VPATH need to use $<. -# However, old makes do not support it, so we use a combination -# construction in Makefile.in: `$file<'. -# If srcdir is `.', we use sed to change that to `file' for old makes. -# Otherwise, we use sed to change it to `$<'. -# vpsub is the sed program, which changes `$file<' to one or the other. -vpsub='s,\$\([-./a-zA-Z0-9_][-./a-zA-Z0-9_]*\)<,\1,g' -# Find the source files, if location was not specified. -if test x$srcdir = x; then - srcdirdefaulted=yes; srcdir=. - if test ! -r $unique_file; then srcdir=`pwd`/..; fi -fi -if test $srcdir != .; then - VPATH='VPATH = $(srcdir)' - vpsub='s,\$\([-./a-zA-Z0-9_][-./a-zA-Z0-9_]*\)<,\$<,g' -fi - -if test ! -r $srcdir/$unique_file; then - if test x$srcdirdefaulted = xyes; then - echo "configure: Can not find sources in \`.' or \`..'." 1>&2 - else - echo "configure: Can not find sources in \`${srcdir}'." 1>&2 - fi - exit 1 -fi - -# The Bourne shell writes "command not found" to /dev/tty, so if we get -# a usage message on stderr, we have the program. -# -# ksh and zsh write "command not found" to stderr, but test -n does not -# want any output if there is no program. So we use the `type' builtin -# instead for them (and bash). -if test "$RANDOM" = "$RANDOM"; then - checkfor='test -n "`$checkprog $checkargs 2>&1`"' -else - checkfor='type $checkprog >/dev/null' -fi - - -exec 6>conf.h -trap 'rm -f conftest conftest.c conf.h; exit 1' 1 3 15 -echo 1>&6 "/* conf.h */" - -echo 1>&6 "/* Configuration header file for Taylor UUCP. - Generated on `date`. */ -" -echo checking for install -# Make sure to not get the incompatible SysV /etc/install. -if test -z "$INSTALL" || test -z "$INSTALLDATA"; then - saveifs="$IFS"; IFS="$IFS:" - for dir in $PATH; do - test -z "$dir" && dir=. - if test $dir != /etc && test -f $dir/install; then - test -z "$INSTALL" && INSTALL="$dir/install -c" - test -z "$INSTALLDATA" && INSTALLDATA="$dir/install -c -m 644" - break - fi - done - IFS="$saveifs" -fi -INSTALL=${INSTALL-cp} -INSTALLDATA=${INSTALLDATA-cp} - -echo checking for gcc -checkprog=gcc checkargs='' -test -z "$CC" && eval $checkfor && CC='gcc -O' -CC=${CC-cc} - -CFLAGS=${CFLAGS--g} -echo checking for mail program -echo 1>&6 "/* 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. */ -#define MAIL_PROGRAM `if test -s /usr/ucb/mail; then echo '"/usr/ucb/mail"'; else if test -s /bin/mail; then echo '"/bin/mail"'; else echo 'undefined'; fi; fi`" -echo checking for echo program -echo 1>&6 " -/* Set ECHO_PROGRAM to a program which echoes its arguments; if echo - is a shell builtin you can just use \"echo\". */ -#define ECHO_PROGRAM `if test -s /bin/echo; then echo '"/bin/echo"'; else echo '"echo"'; fi`" -echo checking for symbolic links -if ln -s X NoSucHFile 2>/dev/null; then - LN_S='ln -s' -else - LN_S='ln' -fi -rm -f NoSucHFile - -echo 1>&6 " -/* 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. */" -for hdr in string.h strings.h unistd.h stdlib.h limits.h time.h -do -havehdr=HAVE_`echo ${hdr} | tr "[a-z]./" "[A-Z]__"` -echo checking for ${hdr} -echo 1>&6 "#define ${havehdr} `if test -f $INCLUDEDIR/${hdr}; then echo 1; else echo 0; fi` /* <${hdr}> */" -done -for hdr in sys/wait.h sys/ioctl.h dirent.h memory.h sys/param.h -do -havehdr=HAVE_`echo ${hdr} | tr "[a-z]./" "[A-Z]__"` -echo checking for ${hdr} -echo 1>&6 "#define ${havehdr} `if test -f $INCLUDEDIR/${hdr}; then echo 1; else echo 0; fi` /* <${hdr}> */" -done -for hdr in utime.h fcntl.h sys/file.h libc.h sysexits.h -do -havehdr=HAVE_`echo ${hdr} | tr "[a-z]./" "[A-Z]__"` -echo checking for ${hdr} -echo 1>&6 "#define ${havehdr} `if test -f $INCLUDEDIR/${hdr}; then echo 1; else echo 0; fi` /* <${hdr}> */" -done -for hdr in poll.h stropts.h -do -havehdr=HAVE_`echo ${hdr} | tr "[a-z]./" "[A-Z]__"` -echo checking for ${hdr} -echo 1>&6 "#define ${havehdr} `if test -f $INCLUDEDIR/${hdr}; then echo 1; else echo 0; fi` /* <${hdr}> */" -done - -echo 1>&6 "" -echo checking for signal handler type -pattern='void[ ]*(\*signal[ ]*(' -echo 1>&6 "/* Set SIGtype to the return type of a signal handler. On newer systems - this will be void; some older systems use int. */ -#define SIGtype `if grep "$pattern" $INCLUDEDIR/signal.h >/dev/null 2>&1 || - grep "$pattern" $INCLUDEDIR/sys/signal.h >/dev/null 2>&1; then - echo void - else - echo int - fi`" - -echo checking for time_t in time.h -echo "#include <time.h> -main() { exit(0); } t() { time_t i; }" > conftest.c -eval $compile -echo 1>&6 " -/* Set HAVE_TIME_T to 1 if time_t is defined in <time.h>, as required by - the ANSI C standard. */ -#define HAVE_TIME_T `(if test -s conftest && ./conftest 2>/dev/null; then echo 1; else echo 0; fi) 2>/dev/null`" -rm -f conftest conftest.c - -echo checking for time_t in sys/types.h -echo "#include <sys/types.h> -main() { exit(0); } t() { time_t i; }" > conftest.c -eval $compile -echo 1>&6 " -/* Set HAVE_SYS_TIME_T to 1 if time_t is defined in <sys/types.h>; this - is only checked if HAVE_TIME_T is 0. */ -#define HAVE_SYS_TIME_T `(if test -s conftest && ./conftest 2>/dev/null; then echo 1; else echo 0; fi) 2>/dev/null`" -rm -f conftest conftest.c - -echo 1>&6 "" -echo checking for time.h and sys/time.h being included together -echo "#include <sys/time.h> -#include <time.h> -main () { exit (0); }" > conftest.c -eval $compile -echo 1>&6 "/* 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 `(if test -f $INCLUDEDIR/time.h -a -f $INCLUDEDIR/sys/time.h -a -s conftest && ./conftest 2>/dev/null; then echo 1; else echo 0; fi) 2>/dev/null`" -rm -f conftest conftest.c - -echo 1>&6 "" -echo checking for termios.h and sys/ioctl.h being included together -echo "#include <termios.h> -#include <sys/ioctl.h> -main () { exit (0); }" > conftest.c -eval $compile -echo 1>&6 "/* 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 `(if test -f $INCLUDEDIR/termios.h -a -f $INCLUDEDIR/sys/ioctl.h -a -s conftest && ./conftest 2>/dev/null; then echo 1; else echo 0; fi) 2>/dev/null`" -rm -f conftest conftest.c - -echo 1>&6 "" -echo checking for CBREAK -echo "#include <sgtty.h> -main() { exit(0); } t() { int i = CBREAK; }" > conftest.c -eval $compile -echo 1>&6 "/* 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 `(if test -s conftest && ./conftest 2>/dev/null; then echo 1; else echo 0; fi) 2>/dev/null`" -rm -f conftest conftest.c - -echo 1>&6 " -/* 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. - - Each of the types should be defined using #define. For example, - #define pid_t int - */" -echo 1>&6 " -/* 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. */" -echo checking for pid_t in sys/types.h -echo "#include <sys/types.h> -main() { exit(0); } t() {pid_t x; }" >conftest.c -eval $compile -if test -s conftest && ./conftest 2>/dev/null; then - echo 1>&6 "/* A definition of pid_t was found on your system. */" -else - echo 1>&6 "#define pid_t int" -fi -rm -f conftest conftest.c - -echo 1>&6 " -/* 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. */" -echo checking for uid_t in sys/types.h -echo "#include <sys/types.h> -main() { exit(0); } t() {uid_t x; }" >conftest.c -eval $compile -if test -s conftest && ./conftest 2>/dev/null; then - echo 1>&6 "/* A definition of uid_t was found on your system. */" -else - echo 1>&6 "#define uid_t int" -fi -rm -f conftest conftest.c - -echo 1>&6 " -/* 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. */" -echo checking for gid_t in sys/types.h -echo "#include <sys/types.h> -main() { exit(0); } t() {gid_t x; }" >conftest.c -eval $compile -if test -s conftest && ./conftest 2>/dev/null; then - echo 1>&6 "/* A definition of gid_t was found on your system. */" -else - echo 1>&6 "#define gid_t int" -fi -rm -f conftest conftest.c - -echo 1>&6 " -/* 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. */" -echo checking for off_t in sys/types.h -echo "#include <sys/types.h> -main() { exit(0); } t() {off_t x; }" >conftest.c -eval $compile -if test -s conftest && ./conftest 2>/dev/null; then - echo 1>&6 "/* A definition of off_t was found on your system. */" -else - echo 1>&6 "#define off_t long" -fi -rm -f conftest conftest.c - - -echo checking for sig_atomic_t in signal.h -echo "#include <signal.h> -main() { exit(0); } t() { sig_atomic_t x; }" > conftest.c -eval $compile -echo 1>&6 " -/* 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 `(if test -s conftest && ./conftest 2>/dev/null; then echo 1; else echo 0; fi) 2>/dev/null`" -rm -f conftest conftest.c - -echo checking for sig_atomic_t in sys/types.h -echo "#include <sys/types.h> -main() { exit(0); } t() { sig_atomic_t x; }" > conftest.c -eval $compile -echo 1>&6 " -/* 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 `(if test -s conftest && ./conftest 2>/dev/null; then echo 1; else echo 0; fi) 2>/dev/null`" -rm -f conftest conftest.c - -echo 1>&6 " -/* 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. */" - -echo checking how to get filesystem info -echo 1>&6 " -/* 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. - - FS_STATVFS the statvfs function - FS_USG_STATFS the four argument statfs function - FS_MNTENT the two argument statfs function with the f_bsize field - FS_STATFS the two argument statfs function with the f_fsize field - FS_GETMNT the two argument statfs function with the fd_req field - FS_USTAT the ustat function with 512 byte blocks. */" -if test -f $INCLUDEDIR/sys/statvfs.h -a -f $INCLUDEDIR/sys/fstyp.h; then - echo 1>&6 "#define FS_STATVFS " -elif test -f $INCLUDEDIR/sys/statfs.h -a -f $INCLUDEDIR/sys/fstyp.h; then - echo 1>&6 "#define FS_USG_STATFS " -elif test -f $INCLUDEDIR/mntent.h; then - echo 1>&6 "#define FS_MNTENT " -elif test -f $INCLUDEDIR/sys/mount.h -a -f $INCLUDEDIR/sys/fs_types.h; then - echo 1>&6 "#define FS_GETMNT " -elif grep MOUNT_UFS $INCLUDEDIR/sys/mount.h >/dev/null 2>&1; then - echo 1>&6 "#define FS_STATFS " -else - echo checking for ustat -echo " -main() { exit(0); } t() { ustat(); }" > conftest.c -eval $compile -if test -s conftest && ./conftest 2>/dev/null; then - echo 1>&6 "#define FS_USTAT " -fi -rm -f conftest conftest.c - -fi - -echo checking for void -echo "void main() { (void) exit (0); }" > conftest.c -eval $compile -echo 1>&6 " -/* 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 `(if test -s conftest && ./conftest 2>/dev/null; then echo 1; else echo 0; fi) 2>/dev/null`" -rm -f conftest.c conftest - -echo checking for unsigned char -echo "main () { unsigned char i = (unsigned char) -1; exit (0); }" > conftest.c -eval $compile -echo 1>&6 " -/* Set HAVE_UNSIGNED_CHAR to 1 if the compiler supports the type unsigned - char. */ -#define HAVE_UNSIGNED_CHAR `(if test -s conftest && ./conftest 2>/dev/null; then echo 1; else echo 0; fi) 2>/dev/null`" -rm -f conftest.c conftest - -echo checking for "int.*errno" in "errno.h" -echo 1>&6 " -/* Set HAVE_ERRNO_DECLARATION to 1 if errno is declared in <errno.h>. */ -#define HAVE_ERRNO_DECLARATION `if grep 'int.*errno' $INCLUDEDIR/errno.h >/dev/null 2>&1; then echo 1; else echo 0; fi`" - -echo checking for combined use of O_NONBLOCK and O_NDELAY -echo "#include <fcntl.h> -#ifndef O_NDELAY -#ifdef FNDELAY -#define O_NDELAY FNDELAY -#else -#define O_NDELAY 0 -#endif -#endif -#ifndef O_NONBLOCK -#ifdef FNBLOCK -#define O_NONBLOCK FNBLOCK -#else -#define O_NONBLOCK 0 -#endif -#endif -main () { exit (fcntl (open ("'"conftest.c"'", O_RDONLY), - F_SETFL, - O_NONBLOCK | O_NDELAY)); }" > conftest.c -eval $compile -echo 1>&6 " -/* Set COMBINED_UNBLOCK to 1 if the flags O_NONBLOCK and O_NDELAY can - both be specified at once on a file descriptor. If your system - does not support both flags, it doesn't matter what you set this - to. */ -#define COMBINED_UNBLOCK `(if test -s conftest && ./conftest 2>/dev/null; then echo 1; else echo 0; fi) 2>/dev/null`" - -echo checking for alloca -echo "#ifdef __GNUC__ -#define alloca __builtin_alloca -#else /* ! defined(__GNUC__) */ -#ifdef sparc -#include <alloca.h> -#else /* ! defined (sparc) */ -#ifdef _AIX - #pragma alloca -#else /* ! defined (_AIX) */ -char *alloca (); -#endif /* ! defined (_AIX) */ -#endif /* ! defined (sparc) */ -#endif /* ! defined (__GNUC__) */ -main() { exit(0); } t() { char *p = (char *) alloca(1); }" > conftest.c -eval $compile -if test -s conftest && ./conftest 2>/dev/null; then : -else - OLIBS=$LIBS - if test -f /usr/ucblib/libucb.a; then - LIBS="$LIBS -L/usr/ucblib -lucb" # SVR4 - elif test -f /lib/libPW.a; then - LIBS="$LIBS -lPW" # SVR2 and SVR3 - else - ALLOCA=alloca.o - fi - if test "$OLIBS" != "$LIBS"; then - eval $compile - if test -s conftest && ./conftest 2>/dev/null; then : - else - LIBS=$OLIBS - ALLOCA=alloca.o - fi - fi -fi - -echo 1>&6 " -/* 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_STRERROR should be set to 1 if your system has strerror, - 0 otherwise. */" - -echo 1>&6 " -/* Taylor UUCP provides its own versions of the following functions, - or knows how to work around their absence. */" - -for func in memset memcmp memchr memcpy bcopy bcmp bzero -do -havefunc=HAVE_`echo ${func} | tr "[a-z]" "[A-Z]"` -echo checking for ${func} -echo "main() { exit (0); } t() { ${func}(); }" > conftest.c -eval $compile -echo 1>&6 "#define ${havefunc} `(if test -s conftest && ./conftest 2>/dev/null; then echo 1; else echo 0; fi) 2>/dev/null`" -rm -f conftest conftest.c -done - -echo checking for memmove -echo "main () { exit (0); } t() { memmove(); }" > conftest.c -eval $compile -havememmove=`(if test -s conftest && ./conftest 2>/dev/null; then echo 1; else echo 0; fi) 2>/dev/null` -rm -f conftest conftest.c -if test "${havememmove}" != "1"; then - echo 1>&6 "#define HAVE_MEMMOVE 0" -else - echo "main() - { - register int x1, x2, x3; - char s[2]; - - x1 = 1; - x2 = 2; - x3 = 3; - memmove(s, "'""'", 1); - exit((x1 != 1) || (x2 != 2) || (x3 != 3)); - }" > conftest.c - cc -o conftest conftest.c >/dev/null 2>/dev/null - if test ! -s ./conftest; then - echo 1>&6 "#define HAVE_MEMMOVE 1" - elif ./conftest 2>/dev/null; then - echo 1>&6 "#define HAVE_MEMMOVE 1" - else - echo 1>&6 "#define HAVE_MEMMOVE 0 /* Your memmove seems to be buggy. */" - fi - rm -f conftest conftest.c -fi - -for func in strchr strrchr index rindex strerror strtol strstr -do -havefunc=HAVE_`echo ${func} | tr "[a-z]" "[A-Z]"` -echo checking for ${func} -echo "main() { exit (0); } t() { ${func}(); }" > conftest.c -eval $compile -echo 1>&6 "#define ${havefunc} `(if test -s conftest && ./conftest 2>/dev/null; then echo 1; else echo 0; fi) 2>/dev/null`" -rm -f conftest conftest.c -done -for func in strdup strcasecmp stricmp strlwr bsearch vfprintf -do -havefunc=HAVE_`echo ${func} | tr "[a-z]" "[A-Z]"` -echo checking for ${func} -echo "main() { exit (0); } t() { ${func}(); }" > conftest.c -eval $compile -echo 1>&6 "#define ${havefunc} `(if test -s conftest && ./conftest 2>/dev/null; then echo 1; else echo 0; fi) 2>/dev/null`" -rm -f conftest conftest.c -done -for func in remove ftruncate ltrunc rename opendir dup2 waitpid wait4 -do -havefunc=HAVE_`echo ${func} | tr "[a-z]" "[A-Z]"` -echo checking for ${func} -echo "main() { exit (0); } t() { ${func}(); }" > conftest.c -eval $compile -echo 1>&6 "#define ${havefunc} `(if test -s conftest && ./conftest 2>/dev/null; then echo 1; else echo 0; fi) 2>/dev/null`" -rm -f conftest conftest.c -done - -echo 1>&6 " -/* 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). */" -for func in sigsetjmp setret -do -havefunc=HAVE_`echo ${func} | tr "[a-z]" "[A-Z]"` -echo checking for ${func} -echo "main() { exit (0); } t() { ${func}(); }" > conftest.c -eval $compile -echo 1>&6 "#define ${havefunc} `(if test -s conftest && ./conftest 2>/dev/null; then echo 1; else echo 0; fi) 2>/dev/null`" -rm -f conftest conftest.c -done - -echo 1>&6 " -/* 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. */" -for func in sigaction sigvec sigset -do -havefunc=HAVE_`echo ${func} | tr "[a-z]" "[A-Z]"` -echo checking for ${func} -echo "main() { exit (0); } t() { ${func}(); }" > conftest.c -eval $compile -echo 1>&6 "#define ${havefunc} `(if test -s conftest && ./conftest 2>/dev/null; then echo 1; else echo 0; fi) 2>/dev/null`" -rm -f conftest conftest.c -done - -echo 1>&6 " -/* 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. */" -for func in sigprocmask sigblock sighold -do -havefunc=HAVE_`echo ${func} | tr "[a-z]" "[A-Z]"` -echo checking for ${func} -echo "main() { exit (0); } t() { ${func}(); }" > conftest.c -eval $compile -echo 1>&6 "#define ${havefunc} `(if test -s conftest && ./conftest 2>/dev/null; then echo 1; else echo 0; fi) 2>/dev/null`" -rm -f conftest conftest.c -done - -echo 1>&6 " -/* 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. */" -for func in getdtablesize sysconf -do -havefunc=HAVE_`echo ${func} | tr "[a-z]" "[A-Z]"` -echo checking for ${func} -echo "main() { exit (0); } t() { ${func}(); }" > conftest.c -eval $compile -echo 1>&6 "#define ${havefunc} `(if test -s conftest && ./conftest 2>/dev/null; then echo 1; else echo 0; fi) 2>/dev/null`" -rm -f conftest conftest.c -done - -echo 1>&6 " -/* The code will use one of the following functions when detaching - from a terminal. One of these must exist. */" -for func in setpgrp setsid -do -havefunc=HAVE_`echo ${func} | tr "[a-z]" "[A-Z]"` -echo checking for ${func} -echo "main() { exit (0); } t() { ${func}(); }" > conftest.c -eval $compile -echo 1>&6 "#define ${havefunc} `(if test -s conftest && ./conftest 2>/dev/null; then echo 1; else echo 0; fi) 2>/dev/null`" -rm -f conftest conftest.c -done - -echo 1>&6 " -/* 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. */" -for func in gethostname uname -do -havefunc=HAVE_`echo ${func} | tr "[a-z]" "[A-Z]"` -echo checking for ${func} -echo "main() { exit (0); } t() { ${func}(); }" > conftest.c -eval $compile -echo 1>&6 "#define ${havefunc} `(if test -s conftest && ./conftest 2>/dev/null; then echo 1; else echo 0; fi) 2>/dev/null`" -rm -f conftest conftest.c -done - -echo 1>&6 " -/* 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 assume to always exist. */" -for func in gettimeofday -do -havefunc=HAVE_`echo ${func} | tr "[a-z]" "[A-Z]"` -echo checking for ${func} -echo "main() { exit (0); } t() { ${func}(); }" > conftest.c -eval $compile -echo 1>&6 "#define ${havefunc} `(if test -s conftest && ./conftest 2>/dev/null; then echo 1; else echo 0; fi) 2>/dev/null`" -rm -f conftest conftest.c -done - -echo checking for ftime -echo "main () { exit (0); } t() { ftime(); }" > conftest.c -eval $compile -haveftime=`(if test -s conftest && ./conftest 2>/dev/null; then echo 1; else echo 0; fi) 2>/dev/null` -rm -f conftest conftest.c -if test "${haveftime}" != "1"; then - echo 1>&6 "#define HAVE_FTIME 0" -else - echo "#include <sys/types.h> - #include <sys/timeb.h> - main () - { - struct timeb s, slast; - int c = 0; - ftime (&slast); - while (c < 10) - { - ftime (&s); - if (s.time < slast.time - || (s.time == slast.time && s.millitm < slast.millitm)) - exit (1); - if (s.time != slast.time) - ++c; - slast.time = s.time; - slast.millitm = s.millitm; - } - exit (0); - }" > conftest.c - eval $compile - if test -s ./conftest && ./conftest 2>/dev/null; then - echo 1>&6 "#define HAVE_FTIME 1" - else - echo 1>&6 "#define HAVE_FTIME 0 /* Your ftime seems to be buggy. */" - fi - rm -f conftest conftest.c -fi - -echo 1>&6 " -/* 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. */" -for func in times -do -havefunc=HAVE_`echo ${func} | tr "[a-z]" "[A-Z]"` -echo checking for ${func} -echo "main() { exit (0); } t() { ${func}(); }" > conftest.c -eval $compile -echo 1>&6 "#define ${havefunc} `(if test -s conftest && ./conftest 2>/dev/null; then echo 1; else echo 0; fi) 2>/dev/null`" -rm -f conftest conftest.c -done - -echo 1>&6 " -/* 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. */" -for func in napms nap usleep poll select -do -havefunc=HAVE_`echo ${func} | tr "[a-z]" "[A-Z]"` -echo checking for ${func} -echo "main() { exit (0); } t() { ${func}(); }" > conftest.c -eval $compile -echo 1>&6 "#define ${havefunc} `(if test -s conftest && ./conftest 2>/dev/null; then echo 1; else echo 0; fi) 2>/dev/null`" -rm -f conftest conftest.c -done -echo '#include <stdio.h> -#include "conf.h" -main () -{ -#if ! HAVE_NAPMS -#if ! HAVE_NAP -#if ! HAVE_USLEEP -#if ! HAVE_POLL -#if ! HAVE_SELECT - fprintf (stderr, "WARNING: No way to sleep for less than one second\n"); - fprintf (stderr, " \\p in chat scripts will sleep for a full second\n"); -#endif -#endif -#endif -#endif -#endif -}' > conftest.c -eval $compile -if test -s ./conftest; then - ./conftest -fi -rm -f conftest conftest.c - -echo 1>&6 " -/* If the getgrent function is available, it will be used to determine - all the groups a user belongs to when checking file access - permissions. */" -for func in getgrent -do -havefunc=HAVE_`echo ${func} | tr "[a-z]" "[A-Z]"` -echo checking for ${func} -echo "main() { exit (0); } t() { ${func}(); }" > conftest.c -eval $compile -echo 1>&6 "#define ${havefunc} `(if test -s conftest && ./conftest 2>/dev/null; then echo 1; else echo 0; fi) 2>/dev/null`" -rm -f conftest conftest.c -done - -echo 1>&6 " -/* If the socket function is available, TCP support code will be - compiled in. */" -for func in socket -do -havefunc=HAVE_`echo ${func} | tr "[a-z]" "[A-Z]"` -echo checking for ${func} -echo "main() { exit (0); } t() { ${func}(); }" > conftest.c -eval $compile -echo 1>&6 "#define ${havefunc} `(if test -s conftest && ./conftest 2>/dev/null; then echo 1; else echo 0; fi) 2>/dev/null`" -rm -f conftest conftest.c -done - -echo 1>&6 " -/* 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. */" -echo checking for getcwd -echo "main() { exit (0); } t() { getcwd(); }" >conftest.c -eval $compile -havegetcwd=`(if test -s conftest && ./conftest 2>/dev/null; then echo 1; else echo 0; fi) 2>/dev/null` -echo 1>&6 "#define HAVE_GETCWD ${havegetcwd}" -echo checking for getwd -echo "main() { exit (0); } t() { getwd(); }" >conftest.c -eval $compile -havegetwd=`(if test -s conftest && ./conftest 2>/dev/null; then echo 1; else echo 0; fi) 2>/dev/null` -echo 1>&6 "#define HAVE_GETWD ${havegetwd}" -if test "${havegetcwd}" != 1 -a "${havegetwd}" != 1; then - echo 1>&6 "#define PWD_PROGRAM `if test -s /bin/pwd; then echo '"/bin/pwd"'; else echo unknown; fi`" -else - echo 1>&6 "#define PWD_PROGRAM unused" -fi - -echo 1>&6 " -/* 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, and set MKDIR_PROGRAM to the name - of the program which will create a directory named on the command - line. */" -echo checking for mkdir -echo "main() { exit (0); } t() { mkdir(); }" > conftest.c -eval $compile -havemkdir=`(if test -s conftest && ./conftest 2>/dev/null; then echo 1; else echo 0; fi) 2>/dev/null` -echo 1>&6 "#define HAVE_MKDIR ${havemkdir}" -if test "${havemkdir}" = "1"; then - UUDIR='# ' - echo 1>&6 "#define MKDIR_PROGRAM unused" -else - UUDIR= - echo 1>&6 "#define MKDIR_PROGRAM `if test -f /bin/mkdir; then echo '"/bin/mkdir"'; else echo unknown; fi`" -fi -rm -f conftest conftest.c - -echo 1>&6 " -/* That's the end of the list of the functions. Now there are a few - last miscellaneous items. */" - -echo checking whether times can be declared as long -echo "#include <sys/types.h> -`if test -f $INCLUDEDIR/sys/times.h; then echo '#include <sys/times.h>'; fi` -main () { exit(0); } extern long times ();" > conftest.c -eval $compile -echo 1>&6 " -/* On some systems times is declared in <sys/times.h> as returning - int, so the code cannot safely declare it as returning long. On - the other hand, on some systems times will not work unless it is - declared as returning long. Set TIMES_DECLARATION_OK to 1 if times - can be safely declared as returning long. If you will not be using - times, it doesn't matter what you set this to. */ -#define TIMES_DECLARATION_OK `(if test -s conftest && ./conftest 2>/dev/null; then echo 1; else echo 0; fi) 2>/dev/null`" -rm -f conftest conftest.c - -echo checking for BSD setpgrp -echo "`if test -f $INCLUDEDIR/unistd.h; then echo '#include <unistd.h>'; fi` -main() { exit(0); } t() { getpgrp (0); setpgrp (0, 0); }" > conftest.c -eval $compile -echo 1>&6 " -/* Set HAVE_BSD_PGRP to 1 if your getpgrp call takes 1 argument and - your setpgrp calls takes 2 argument (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 `(if test -s conftest && ./conftest 2>/dev/null; then echo 1; else echo 0; fi) 2>/dev/null`" -rm -f conftest conftest.c - - -echo checking for union wait -echo "#include <sys/wait.h> -main() { exit(0); } t() { union wait u; wait (&u); }" > conftest.c -eval $compile -echo 1>&6 " -/* Set HAVE_UNION_WAIT to 1 if union wait is defined in the header - file <sys/wait.h>. */ -#define HAVE_UNION_WAIT `(if test -s conftest && ./conftest 2>/dev/null; then echo 1; else echo 0; fi) 2>/dev/null`" -rm -f conftest conftest.c - - -echo 1>&6 " -/* Define UTIME_NULL_MISSING if utime with a NULL second argument does not - set the file times to the current time. */" -echo checking utime with null argument -rm -f uttest; > uttest -# Sequent interprets utime(file, 0) to mean use start of epoch. Wrong. -echo '#include <sys/types.h> -#include <sys/stat.h> -main() { -struct stat s, t; -exit(!(stat ("uttest", &s) == 0 && utime("uttest", (long *)0) == 0 -&& stat("uttest", &t) == 0 && t.st_mtime >= s.st_mtime -&& t.st_mtime - s.st_mtime < 120)); -}' > conftest.c -eval $compile -./conftest 2>/dev/null || echo 1>&6 "#define UTIME_NULL_MISSING " -rm -f conftest conftest.c uttest core - - -echo checking for long file names -(echo "1" > 123456789012345) 2>/dev/null -(echo "2" > 123456789012346) 2>/dev/null -long=`cat 123456789012345 2>/dev/null` -echo 1>&6 " -/* Set HAVE_LONG_NAMES to 1 if the system supports file names longer - than 14 characters. */ -#define HAVE_LONG_NAMES `if test -f 123456789012345 -a "${long}" = "1"; then echo 1; else echo 0; fi 2>/dev/null`" -rm -f 123456789012345 123456789012346 2>/dev/null - -echo checking for restartable system calls -echo "#include <signal.h> -ucatch (isig) { } -main () { int i = fork (); - if (i == 0) { sleep (3); kill (getppid (), SIGINT); sleep (3); exit (0); } - signal (SIGINT, ucatch); - exit (wait (&i) == -1); }" > conftest.c -eval $compile -echo 1>&6 " -/* 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 SV_INTERRUPT is defined in - <signal.h>. In both of these cases system calls can be prevented - from restarting. */ -#define HAVE_RESTARTABLE_SYSCALLS `(if test -s conftest && ./conftest 2>/dev/null; then echo 1; else echo 0; fi) 2>/dev/null`" -rm -f conftest conftest.c - -trap 'for dir in .; do rm -f $dir/Makefile; done; rm -f config.status conf.h; exit 1' 1 3 15 - -for dir in .; do - test -d $dir || mkdir $dir - echo creating $dir/Makefile - echo '# Generated automatically from Makefile.in by configure.' > $dir/Makefile - sed -e " -$vpsub -s,@srcdir@,$srcdir, -s,@VPATH@,$VPATH, -s,@DEFS@,$DEFS, -s,@LIBS@,$LIBS, -s,@INSTALL@,$INSTALL, -s,@INSTALLDATA@,$INSTALLDATA, -s,@CC@,$CC, -s,@CFLAGS@,$CFLAGS, -s,@LDFLAGS@,$LDFLAGS, -s,@LN_S@,$LN_S, -s,@ALLOCA@,$ALLOCA, -s,@UUDIR@,$UUDIR, -" $srcdir/$dir/Makefile.in >> $dir/Makefile -done - -echo creating config.status -echo "\ -DEFS=\"$DEFS\" -LIBS=\"$LIBS\" -INSTALL=\"$INSTALL\" -INSTALLDATA=\"$INSTALLDATA\" -CC=\"$CC\" -CFLAGS=\"$CFLAGS\" -LDFLAGS=\"$LDFLAGS\" -LN_S=\"$LN_S\" -ALLOCA=\"$ALLOCA\" -UUDIR=\"$UUDIR\" -" > config.status - diff --git a/gnu/libexec/uucp/configure.in b/gnu/libexec/uucp/configure.in deleted file mode 100644 index c1efdce1706..00000000000 --- a/gnu/libexec/uucp/configure.in +++ /dev/null @@ -1,589 +0,0 @@ -dnl Taylor UUCP configuration file -dnl This should be processed with autoconf to produce a configure script. -dnl Copyright (c) 1992 Ian Lance Taylor -dnl -M_INIT(uucico.c) -M_HEADER_FILE(conf.h) -ILT_HEADER_COMMENT([/* Configuration header file for Taylor UUCP. - Generated on `date`. */ -]) -dnl -M_PROG_INSTALL -M_PROG_GCC -CFLAGS=${CFLAGS--g} -M_SUBST(CFLAGS)dnl -M_SUBST(LDFLAGS)dnl -dnl -echo checking for mail program -M_DEFINE([MAIL_PROGRAM], -[`if test -s /usr/ucb/mail; then echo '"/usr/ucb/mail"'; else if test -s /bin/mail; then echo '"/bin/mail"'; else echo 'undefined'; fi; fi`], -[/* 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. */]) -echo checking for echo program -M_DEFINE([ECHO_PROGRAM], -[`if test -s /bin/echo; then echo '"/bin/echo"'; else echo '"echo"'; fi`], -[ -/* Set ECHO_PROGRAM to a program which echoes its arguments; if echo - is a shell builtin you can just use \"echo\". */]) -dnl this is just used to set LN_S in the Makefile -echo checking for symbolic links -if ln -s X NoSucHFile 2>/dev/null; then - LN_S='ln -s' -else - LN_S='ln' -fi -rm -f NoSucHFile -M_SUBST(LN_S)dnl - -ILT_HEADER_COMMENT([ -/* 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. */]) -ILT_HEADER_CHECK(string.h strings.h unistd.h stdlib.h limits.h time.h) -ILT_HEADER_CHECK(sys/wait.h sys/ioctl.h dirent.h memory.h sys/param.h) -ILT_HEADER_CHECK(utime.h fcntl.h sys/file.h libc.h sysexits.h) -ILT_HEADER_CHECK(poll.h stropts.h) - -ILT_HEADER_COMMENT() -ILT_SIGTYPE -ILT_LIBTHING_CHECK([time_t in time.h], -[#include <time.h>], [time_t i;], [HAVE_TIME_T], -[ -/* Set HAVE_TIME_T to 1 if time_t is defined in <time.h>, as required by - the ANSI C standard. */]) -ILT_LIBTHING_CHECK([time_t in sys/types.h], -[#include <sys/types.h>], [time_t i;], [HAVE_SYS_TIME_T], -[ -/* Set HAVE_SYS_TIME_T to 1 if time_t is defined in <sys/types.h>; this - is only checked if HAVE_TIME_T is 0. */]) -ILT_HEADER_COMMENT() -echo checking for time.h and sys/time.h being included together -echo "#include <sys/time.h> -#include <time.h> -main () { exit (0); }" > conftest.c -eval $compile -M_DEFINE([HAVE_SYS_TIME_AND_TIME_H], -[`(if test -f $INCLUDEDIR/time.h -a -f $INCLUDEDIR/sys/time.h -a -s conftest && ./conftest 2>/dev/null; then echo 1; else echo 0; fi) 2>/dev/null`], -[/* 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. */]) -rm -f conftest conftest.c - -ILT_HEADER_COMMENT() -echo checking for termios.h and sys/ioctl.h being included together -echo "#include <termios.h> -#include <sys/ioctl.h> -main () { exit (0); }" > conftest.c -eval $compile -M_DEFINE([HAVE_TERMIOS_AND_SYS_IOCTL_H], -[`(if test -f $INCLUDEDIR/termios.h -a -f $INCLUDEDIR/sys/ioctl.h -a -s conftest && ./conftest 2>/dev/null; then echo 1; else echo 0; fi) 2>/dev/null`], -[/* 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. */]) -rm -f conftest conftest.c - -ILT_HEADER_COMMENT() -ILT_LIBTHING_CHECK([CBREAK], [#include <sgtty.h>], [int i = CBREAK;], -[HAVE_CBREAK], -[/* 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. */]) -ILT_HEADER_COMMENT([ -/* 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. - - Each of the types should be defined using #define. For example, - #define pid_t int - */]) -ILT_HEADER_COMMENT([ -/* 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. */]) -ILT_LIBTHING_CHOICE([pid_t in sys/types.h], -[#include <sys/types.h>], [pid_t x;], -ILT_HEADER_COMMENT([/* A definition of pid_t was found on your system. */]), -M_DEFINE(pid_t, int)) -ILT_HEADER_COMMENT([ -/* 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. */]) -ILT_LIBTHING_CHOICE([uid_t in sys/types.h], -[#include <sys/types.h>], [uid_t x;], -ILT_HEADER_COMMENT([/* A definition of uid_t was found on your system. */]), -M_DEFINE(uid_t, int)) -ILT_HEADER_COMMENT([ -/* 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. */]) -ILT_LIBTHING_CHOICE([gid_t in sys/types.h], -[#include <sys/types.h>], [gid_t x;], -ILT_HEADER_COMMENT([/* A definition of gid_t was found on your system. */]), -M_DEFINE(gid_t, int)) -ILT_HEADER_COMMENT([ -/* 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. */]) -ILT_LIBTHING_CHOICE([off_t in sys/types.h], -[#include <sys/types.h>], [off_t x;], -ILT_HEADER_COMMENT([/* A definition of off_t was found on your system. */]), -M_DEFINE(off_t, long)) - -dnl On SCO 3.2.2 sig_atomic_t is in <sys/types.h> but not <signal.h>. -ILT_LIBTHING_CHECK([sig_atomic_t in signal.h], -[#include <signal.h>], [sig_atomic_t x;], -[HAVE_SIG_ATOMIC_T_IN_SIGNAL_H], -[ -/* Set HAVE_SIG_ATOMIC_T_IN_SIGNAL_H if the type sig_atomic_t is defined - in <signal.h> as required by ANSI C. */]) -ILT_LIBTHING_CHECK([sig_atomic_t in sys/types.h], -[#include <sys/types.h>], [sig_atomic_t x;], -[HAVE_SIG_ATOMIC_T_IN_TYPES_H], -[ -/* 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. */]) -ILT_HEADER_COMMENT([ -/* 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. */]) - -dnl The filesystem info code is from David MacKenzie's fileutils 3.1 -dnl package. -echo checking how to get filesystem info -ILT_HEADER_COMMENT([ -/* 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. - - FS_STATVFS the statvfs function - FS_USG_STATFS the four argument statfs function - FS_MNTENT the two argument statfs function with the f_bsize field - FS_STATFS the two argument statfs function with the f_fsize field - FS_GETMNT the two argument statfs function with the fd_req field - FS_USTAT the ustat function with 512 byte blocks. */]) -if test -f $INCLUDEDIR/sys/statvfs.h -a -f $INCLUDEDIR/sys/fstyp.h; then - M_DEFINE(FS_STATVFS) -elif test -f $INCLUDEDIR/sys/statfs.h -a -f $INCLUDEDIR/sys/fstyp.h; then - M_DEFINE(FS_USG_STATFS) -elif test -f $INCLUDEDIR/mntent.h; then - M_DEFINE(FS_MNTENT) -elif test -f $INCLUDEDIR/sys/mount.h -a -f $INCLUDEDIR/sys/fs_types.h; then - M_DEFINE(FS_GETMNT) -elif grep MOUNT_UFS $INCLUDEDIR/sys/mount.h >/dev/null 2>&1; then - M_DEFINE(FS_STATFS) -else - M_LIBTHING_PRESENT([ustat], , [ustat();], M_DEFINE(FS_USTAT)) -fi - -echo checking for void -echo "void main() { (void) exit (0); }" > conftest.c -eval $compile -M_DEFINE([HAVE_VOID], -[`(if test -s conftest && ./conftest 2>/dev/null; then echo 1; else echo 0; fi) 2>/dev/null`], -[ -/* Set HAVE_VOID to 1 if the compiler supports declaring functions with - a return type of void and casting values to void. */]) -rm -f conftest.c conftest - -echo checking for unsigned char -echo "main () { unsigned char i = (unsigned char) -1; exit (0); }" > conftest.c -eval $compile -M_DEFINE([HAVE_UNSIGNED_CHAR], -[`(if test -s conftest && ./conftest 2>/dev/null; then echo 1; else echo 0; fi) 2>/dev/null`], -[ -/* Set HAVE_UNSIGNED_CHAR to 1 if the compiler supports the type unsigned - char. */]) -rm -f conftest.c conftest - -ILT_IDENT_CHECK([int.*errno], [errno.h], [HAVE_ERRNO_DECLARATION], -[ -/* Set HAVE_ERRNO_DECLARATION to 1 if errno is declared in <errno.h>. */]) - -echo checking for combined use of O_NONBLOCK and O_NDELAY -echo "#include <fcntl.h> -#ifndef O_NDELAY -#ifdef FNDELAY -#define O_NDELAY FNDELAY -#else -#define O_NDELAY 0 -#endif -#endif -#ifndef O_NONBLOCK -#ifdef FNBLOCK -#define O_NONBLOCK FNBLOCK -#else -#define O_NONBLOCK 0 -#endif -#endif -main () { exit (fcntl (open ("'"conftest.c"'", O_RDONLY), - F_SETFL, - O_NONBLOCK | O_NDELAY)); }" > conftest.c -eval $compile -M_DEFINE([COMBINED_UNBLOCK], -[`(if test -s conftest && ./conftest 2>/dev/null; then echo 1; else echo 0; fi) 2>/dev/null`], -[ -/* Set COMBINED_UNBLOCK to 1 if the flags O_NONBLOCK and O_NDELAY can - both be specified at once on a file descriptor. If your system - does not support both flags, it doesn't matter what you set this - to. */]) - -dnl Do some complicated tests for alloca. If we fail to find it, we -dnl look in a couple of libraries and try again. -echo checking for alloca -echo "#ifdef __GNUC__ -#define alloca __builtin_alloca -#else /* ! defined(__GNUC__) */ -#ifdef sparc -#include <alloca.h> -#else /* ! defined (sparc) */ -#ifdef _AIX - #pragma alloca -#else /* ! defined (_AIX) */ -char *alloca (); -#endif /* ! defined (_AIX) */ -#endif /* ! defined (sparc) */ -#endif /* ! defined (__GNUC__) */ -main() { exit(0); } t() { char *p = (char *) alloca(1); }" > conftest.c -eval $compile -if test -s conftest && ./conftest 2>/dev/null; then : -else - OLIBS=$LIBS - if test -f /usr/ucblib/libucb.a; then - LIBS="$LIBS -L/usr/ucblib -lucb" # SVR4 - elif test -f /lib/libPW.a; then - LIBS="$LIBS -lPW" # SVR2 and SVR3 - else - ALLOCA=alloca.o - fi - if test "$OLIBS" != "$LIBS"; then - eval $compile - if test -s conftest && ./conftest 2>/dev/null; then : - else - LIBS=$OLIBS - ALLOCA=alloca.o - fi - fi -fi -M_SUBST(ALLOCA)dnl - -ILT_HEADER_COMMENT([ -/* 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_STRERROR should be set to 1 if your system has strerror, - 0 otherwise. */]) - -ILT_HEADER_COMMENT([ -/* Taylor UUCP provides its own versions of the following functions, - or knows how to work around their absence. */]) -undefine([index]) -ILT_FUNC_CHECK(memset memcmp memchr memcpy bcopy bcmp bzero) - -echo checking for memmove -echo "main () { exit (0); } t() { memmove(); }" > conftest.c -eval $compile -havememmove=`(if test -s conftest && ./conftest 2>/dev/null; then echo 1; else echo 0; fi) 2>/dev/null` -rm -f conftest conftest.c -if test "${havememmove}" != "1"; then - M_DEFINE(HAVE_MEMMOVE, 0) -else - dnl now check for the SCO buggy memmove. This test case is from - dnl Chip Salzenberg - changequote(,)dnl - echo "main() - { - register int x1, x2, x3; - char s[2]; - - x1 = 1; - x2 = 2; - x3 = 3; - memmove(s, "'""'", 1); - exit((x1 != 1) || (x2 != 2) || (x3 != 3)); - }" > conftest.c - changequote([,])dnl - dnl The test case must be compiled with cc without optimization - cc -o conftest conftest.c >/dev/null 2>/dev/null - if test ! -s ./conftest; then - dnl $CC worked but cc didn't; it's probably OK - M_DEFINE(HAVE_MEMMOVE, 1) - elif ./conftest 2>/dev/null; then - M_DEFINE(HAVE_MEMMOVE, 1) - else - M_DEFINE(HAVE_MEMMOVE, [0 /* Your memmove seems to be buggy. */]) - fi - rm -f conftest conftest.c -fi - -ILT_FUNC_CHECK(strchr strrchr index rindex strerror strtol strstr) -ILT_FUNC_CHECK(strdup strcasecmp stricmp strlwr bsearch vfprintf) -ILT_FUNC_CHECK(remove ftruncate ltrunc rename opendir dup2 waitpid wait4) - -ILT_HEADER_COMMENT([ -/* 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). */]) -ILT_FUNC_CHECK(sigsetjmp setret) - -ILT_HEADER_COMMENT([ -/* 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. */]) -ILT_FUNC_CHECK(sigaction sigvec sigset) - -ILT_HEADER_COMMENT([ -/* 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. */]) -ILT_FUNC_CHECK(sigprocmask sigblock sighold) - -ILT_HEADER_COMMENT([ -/* 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. */]) -ILT_FUNC_CHECK(getdtablesize sysconf) - -ILT_HEADER_COMMENT([ -/* The code will use one of the following functions when detaching - from a terminal. One of these must exist. */]) -ILT_FUNC_CHECK(setpgrp setsid) - -ILT_HEADER_COMMENT([ -/* 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. */]) -ILT_FUNC_CHECK(gethostname uname) - -ILT_HEADER_COMMENT([ -/* 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 assume to always exist. */]) -ILT_FUNC_CHECK(gettimeofday) - -echo checking for ftime -echo "main () { exit (0); } t() { ftime(); }" > conftest.c -eval $compile -haveftime=`(if test -s conftest && ./conftest 2>/dev/null; then echo 1; else echo 0; fi) 2>/dev/null` -rm -f conftest conftest.c -if test "${haveftime}" != "1"; then - M_DEFINE(HAVE_FTIME, 0) -else - dnl now check for the SCO buggy ftime - echo "#include <sys/types.h> - #include <sys/timeb.h> - main () - { - struct timeb s, slast; - int c = 0; - ftime (&slast); - while (c < 10) - { - ftime (&s); - if (s.time < slast.time - || (s.time == slast.time && s.millitm < slast.millitm)) - exit (1); - if (s.time != slast.time) - ++c; - slast.time = s.time; - slast.millitm = s.millitm; - } - exit (0); - }" > conftest.c - eval $compile - if test -s ./conftest && ./conftest 2>/dev/null; then - M_DEFINE(HAVE_FTIME, 1) - else - M_DEFINE(HAVE_FTIME, [0 /* Your ftime seems to be buggy. */]) - fi - rm -f conftest conftest.c -fi - -ILT_HEADER_COMMENT([ -/* 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. */]) -ILT_FUNC_CHECK(times) - -ILT_HEADER_COMMENT([ -/* 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. */]) -ILT_FUNC_CHECK(napms nap usleep poll select) -echo '#include <stdio.h> -#include "conf.h" -main () -{ -#if ! HAVE_NAPMS -#if ! HAVE_NAP -#if ! HAVE_USLEEP -#if ! HAVE_POLL -#if ! HAVE_SELECT - fprintf (stderr, "WARNING: No way to sleep for less than one second\n"); - fprintf (stderr, " \\p in chat scripts will sleep for a full second\n"); -#endif -#endif -#endif -#endif -#endif -}' > conftest.c -eval $compile -if test -s ./conftest; then - ./conftest -fi -rm -f conftest conftest.c - -ILT_HEADER_COMMENT([ -/* If the getgrent function is available, it will be used to determine - all the groups a user belongs to when checking file access - permissions. */]) -ILT_FUNC_CHECK(getgrent) - -ILT_HEADER_COMMENT([ -/* If the socket function is available, TCP support code will be - compiled in. */]) -ILT_FUNC_CHECK(socket) - -ILT_HEADER_COMMENT([ -/* 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. */]) -echo checking for getcwd -echo "main() { exit (0); } t() { getcwd(); }" >conftest.c -eval $compile -havegetcwd=`(if test -s conftest && ./conftest 2>/dev/null; then echo 1; else echo 0; fi) 2>/dev/null` -M_DEFINE([HAVE_GETCWD], [${havegetcwd}]) -echo checking for getwd -echo "main() { exit (0); } t() { getwd(); }" >conftest.c -eval $compile -havegetwd=`(if test -s conftest && ./conftest 2>/dev/null; then echo 1; else echo 0; fi) 2>/dev/null` -M_DEFINE([HAVE_GETWD], [${havegetwd}]) -if test "${havegetcwd}" != 1 -a "${havegetwd}" != 1; then - M_DEFINE([PWD_PROGRAM], - [`if test -s /bin/pwd; then echo '"/bin/pwd"'; else echo unknown; fi`]) -else - M_DEFINE([PWD_PROGRAM], [unused]) -fi - -ILT_HEADER_COMMENT([ -/* 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, and set MKDIR_PROGRAM to the name - of the program which will create a directory named on the command - line. */]) -echo checking for mkdir -echo "main() { exit (0); } t() { mkdir(); }" > conftest.c -eval $compile -havemkdir=`(if test -s conftest && ./conftest 2>/dev/null; then echo 1; else echo 0; fi) 2>/dev/null` -M_DEFINE([HAVE_MKDIR], [${havemkdir}]) -if test "${havemkdir}" = "1"; then - UUDIR='# ' - M_DEFINE([MKDIR_PROGRAM], [unused]) -else - UUDIR= - M_DEFINE([MKDIR_PROGRAM], - [`if test -f /bin/mkdir; then echo '"/bin/mkdir"'; else echo unknown; fi`]) -fi -M_SUBST(UUDIR)dnl -rm -f conftest conftest.c - -ILT_HEADER_COMMENT([ -/* That's the end of the list of the functions. Now there are a few - last miscellaneous items. */]) - -echo checking whether times can be declared as long -echo "#include <sys/types.h> -`if test -f $INCLUDEDIR/sys/times.h; then echo '#include <sys/times.h>'; fi` -main () { exit(0); } extern long times ();" > conftest.c -eval $compile -M_DEFINE([TIMES_DECLARATION_OK], -[`(if test -s conftest && ./conftest 2>/dev/null; then echo 1; else echo 0; fi) 2>/dev/null`], -[ -/* On some systems times is declared in <sys/times.h> as returning - int, so the code cannot safely declare it as returning long. On - the other hand, on some systems times will not work unless it is - declared as returning long. Set TIMES_DECLARATION_OK to 1 if times - can be safely declared as returning long. If you will not be using - times, it doesn't matter what you set this to. */]) -rm -f conftest conftest.c - -ILT_LIBTHING_CHECK([BSD setpgrp], -[`if test -f $INCLUDEDIR/unistd.h; then echo '#include <unistd.h>'; fi`], -[getpgrp (0); setpgrp (0, 0);], [HAVE_BSD_PGRP], -[ -/* Set HAVE_BSD_PGRP to 1 if your getpgrp call takes 1 argument and - your setpgrp calls takes 2 argument (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. */]) - -ILT_LIBTHING_CHECK([union wait], [#include <sys/wait.h>], -[union wait u; wait (&u);], [HAVE_UNION_WAIT], -[ -/* Set HAVE_UNION_WAIT to 1 if union wait is defined in the header - file <sys/wait.h>. */]) - -ILT_HEADER_COMMENT([ -/* Define UTIME_NULL_MISSING if utime with a NULL second argument does not - set the file times to the current time. */]) -M_UTIME_NULL - -echo checking for long file names -(echo "1" > 123456789012345) 2>/dev/null -(echo "2" > 123456789012346) 2>/dev/null -long=`cat 123456789012345 2>/dev/null` -M_DEFINE([HAVE_LONG_NAMES], -[`if test -f 123456789012345 -a "${long}" = "1"; then echo 1; else echo 0; fi 2>/dev/null`], -[ -/* Set HAVE_LONG_NAMES to 1 if the system supports file names longer - than 14 characters. */]) -rm -f 123456789012345 123456789012346 2>/dev/null - -echo checking for restartable system calls -dnl Remember that exit (0) is true, so this exits with true when the wait -dnl call returns something other than -1, i.e. the pid of the child, -dnl which means that the wait was restarted after the signal. -echo "#include <signal.h> -ucatch (isig) { } -main () { int i = fork (); - if (i == 0) { sleep (3); kill (getppid (), SIGINT); sleep (3); exit (0); } - signal (SIGINT, ucatch); - exit (wait (&i) == -1); }" > conftest.c -eval $compile -M_DEFINE([HAVE_RESTARTABLE_SYSCALLS], -[`(if test -s conftest && ./conftest 2>/dev/null; then echo 1; else echo 0; fi) 2>/dev/null`], -[ -/* 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 SV_INTERRUPT is defined in - <signal.h>. In both of these cases system calls can be prevented - from restarting. */]) -rm -f conftest conftest.c - -M_OUTPUT(.) diff --git a/gnu/libexec/uucp/copy.c b/gnu/libexec/uucp/copy.c deleted file mode 100644 index 3976a84fec6..00000000000 --- a/gnu/libexec/uucp/copy.c +++ /dev/null @@ -1,207 +0,0 @@ -/* 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 AIRS, P.O. Box 520, Waltham, MA 02254. - - $Log: copy.c,v $ - Revision 1.1.1.1 1993/03/21 09:45:37 cgd - initial import of 386bsd-0.1 sources - - Revision 1.7 1992/02/24 20:07:43 ian - John Theus: some systems don't have <fcntl.h> - - Revision 1.6 1992/02/08 03:54:18 ian - Include <string.h> only in <uucp.h>, added 1992 copyright - - Revision 1.5 1991/12/29 04:04:18 ian - Added a bunch of extern definitions - - Revision 1.4 1991/12/11 03:59:19 ian - Create directories when necessary; don't just assume they exist - - Revision 1.3 1991/12/01 02:23:12 ian - Niels Baggesen: don't multiply include <unistd.h> - - Revision 1.2 1991/09/19 03:23:34 ian - Chip Salzenberg: append to private debugging file, don't overwrite it - - Revision 1.1 1991/09/10 19:39:38 ian - Initial revision - - */ - -#include "uucp.h" - -#if USE_RCS_ID -char copy_rcsid[] = "$Id: copy.c,v 1.1.1.1 1993/03/21 09:45:37 cgd Exp $"; -#endif - -#include <stdio.h> -#include <errno.h> - -#include "system.h" -#include "sysdep.h" - -/* External functions. */ -extern int fclose (); - -/* 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; - FILE *eto; - char ab[8192]; - int c; - - efrom = fopen (zfrom, BINREAD); - if (efrom == NULL) - { - ulog (LOG_ERROR, "fopen (%s): %s", zfrom, strerror (errno)); - return FALSE; - } - eto = esysdep_fopen (zto, fpublic, FALSE, fmkdirs); - if (eto == NULL) - { - (void) fclose (efrom); - return FALSE; - } - - while ((c = fread (ab, sizeof (char), sizeof ab, efrom)) != 0) - { - if (fwrite (ab, sizeof (char), c, eto) != c) - { - ulog (LOG_ERROR, "fwrite: %s", strerror (errno)); - (void) fclose (efrom); - (void) fclose (eto); - (void) remove (zto); - return FALSE; - } - } - - (void) fclose (efrom); - - 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 - -boolean -fcopy_file (zfrom, zto, fpublic, fmkdirs) - const char *zfrom; - const char *zto; - boolean fpublic; - boolean fmkdirs; -{ - int ofrom; - int oto; - char ab[8192]; - int c; - - ofrom = open (zfrom, O_RDONLY, 0); - if (ofrom < 0) - { - ulog (LOG_ERROR, "open (%s): %s", zfrom, strerror (errno)); - return FALSE; - } - - /* 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)); - (void) close (ofrom); - return FALSE; - } - } - - while ((c = read (ofrom, ab, sizeof ab)) > 0) - { - if (write (oto, ab, c) != c) - { - ulog (LOG_ERROR, "write: %s", strerror (errno)); - (void) close (ofrom); - (void) close (oto); - (void) remove (zto); - return FALSE; - } - } - - (void) close (ofrom); - - 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/file.c b/gnu/libexec/uucp/file.c deleted file mode 100644 index 5fc34456ac0..00000000000 --- a/gnu/libexec/uucp/file.c +++ /dev/null @@ -1,589 +0,0 @@ -/* file.c - Generic routines to handle 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 AIRS, P.O. Box 520, Waltham, MA 02254. - - $Log: file.c,v $ - Revision 1.1.1.1 1993/03/21 09:45:37 cgd - initial import of 386bsd-0.1 sources - - Revision 1.16 1992/03/30 04:07:13 ian - Dirk Musstopf: remove temporary file if receive fails - - Revision 1.15 1992/03/17 00:31:33 ian - Changed iRecmode to unsigned int - - Revision 1.14 1992/03/11 01:18:15 ian - Niels Baggesen: drop the connection on a write failure - - Revision 1.13 1992/03/11 00:18:50 ian - Save temporary file if file send fails - - Revision 1.12 1992/02/29 01:06:59 ian - Chip Salzenberg: recheck file permissions before sending - - Revision 1.11 1992/02/19 19:36:07 ian - Rearranged time functions - - Revision 1.10 1992/02/08 03:54:18 ian - Include <string.h> only in <uucp.h>, added 1992 copyright - - Revision 1.9 1992/01/18 22:48:53 ian - Reworked sending of mail and general handling of failed transfers - - Revision 1.8 1991/12/21 23:10:43 ian - Terry Gardner: record failed file transfers in statistics file - - Revision 1.7 1991/12/17 07:09:58 ian - Record statistics in fractions of a second - - Revision 1.6 1991/12/10 19:29:02 ian - Move statistics file stuff from file.c to log.c - - Revision 1.5 1991/11/10 19:24:22 ian - Added pffile protocol entry point for file level control - - Revision 1.4 1991/11/08 04:30:50 ian - Hannu Strang: flush statistics file after each line - - Revision 1.3 1991/11/07 19:42:16 ian - Chip Salzenberg: declare inline functions consistently - - Revision 1.2 1991/09/19 03:23:34 ian - Chip Salzenberg: append to private debugging file, don't overwrite it - - Revision 1.1 1991/09/10 19:40:31 ian - Initial revision - - */ - -#include "uucp.h" - -#if USE_RCS_ID -char file_rcsid[] = "$Id: file.c,v 1.1.1.1 1993/03/21 09:45:37 cgd Exp $"; -#endif - -#include <errno.h> - -#include "system.h" - -/* Current file being sent. */ -openfile_t eSendfile = EFILECLOSED; - -/* Current file being received. */ -openfile_t eRecfile = EFILECLOSED; - -/* This file has to keep several strings. I don't want to pay for the - overhead (small as it is) of calling malloc for each one, and I also - don't want to truncate the strings. So I use a structure which holds - strings up to a certain length, and call malloc for longer strings. - NULL strings are indistinguishable from empty strings, which turns - out not to matter. */ - -#define CSTRLEN (30) - -struct sstring -{ - char ab[CSTRLEN]; - char *zalloc; -}; - -/* Local functions. */ - -__inline__ static boolean ffsetstring P((struct sstring *, const char *)); -__inline__ static const char *zfgetstring P((const struct sstring *)); -__inline__ static void uffreestring P((struct sstring *)); - -__inline__ -static boolean ffsetstring (q, z) - struct sstring *q; - const char *z; -{ - if (z == NULL) - q->ab[0] = '\0'; - else if (strlen (z) < CSTRLEN) - strcpy (q->ab, z); - else - { - q->zalloc = strdup (z); - if (q->zalloc == NULL) - { - ulog (LOG_ERROR, "Not enough memory to store command"); - return FALSE; - } - } - return TRUE; -} - -__inline__ -static const char *zfgetstring (q) - const struct sstring *q; -{ - if (q->zalloc != NULL) - return q->zalloc; - else - return q->ab; -} - -__inline__ static void -uffreestring (q) - struct sstring *q; -{ - xfree ((pointer) q->zalloc); - q->zalloc = NULL; -} - -/* Information we keep for the file being sent. We have to be able to - send mail to the user when the transfer is finished, we have to be - able to report error messages sensibly, and we have to be able to - clear this send request out of the work queue if we initiated the - send. */ - -/* Work queue sequence number. */ -static pointer pSendseq; -/* File name being transferred from. */ -static struct sstring sSendfrom; -/* File name being transferred to. */ -static struct sstring sSendto; -/* System being transferred to. */ -static struct sstring sSendtosys; -/* Requesting user name. */ -static struct sstring sSenduser; -/* User to send mail to. */ -static struct sstring sSendmail; -/* Start time. */ -static long iSendstart_secs; -static long iSendstart_micros; -/* Indicate whether we had an error during the transfer. */ -static boolean fSenderror; - -/* Store information about a file being sent. */ - -boolean -fstore_sendfile (e, pseq, zfrom, zto, ztosys, zuser, zmail) - openfile_t e; - pointer pseq; - const char *zfrom; - const char *zto; - const char *ztosys; - const char *zuser; - const char *zmail; -{ -#if DEBUG > 0 - if (ffileisopen (eSendfile)) - ulog (LOG_FATAL, "fstore_sendfile: In progress"); -#endif - - if (! ffsetstring (&sSendfrom, zfrom) - || ! ffsetstring (&sSendto, zto) - || ! ffsetstring (&sSendtosys, ztosys) - || ! ffsetstring (&sSenduser, zuser) - || ! ffsetstring (&sSendmail, zmail)) - { - (void) ffileclose (e); - return FALSE; - } - - eSendfile = e; - pSendseq = pseq; - iSendstart_secs = isysdep_process_time (&iSendstart_micros); - - fSenderror = FALSE; - - return TRUE; -} - -/* Finish up after sending a file. The freceived argument indicates - whether the other file received it successfully. The cbytes - argument is the number of bytes that were sent (for the statistics - entry). The zwhy argument holds a reason for failure if freceived - is FALSE. The fnever argument is TRUE if the file was not received - correctly and, moreover, will never be received correctly. */ - -boolean -fsent_file (freceived, cbytes, zwhy, fnever) - boolean freceived; - long cbytes; - const char *zwhy; - boolean fnever; -{ - boolean f; - long isecs, imicros; - - f = TRUE; - - if (fSenderror) - freceived = FALSE; - - if (ffileisopen (eSendfile)) - (void) ffileclose (eSendfile); - - isecs = isysdep_process_time (&imicros); - imicros -= iSendstart_micros; - if (imicros < 0) - { - imicros += 1000000; - isecs--; - } - isecs -= iSendstart_secs; - - ustats (freceived, zfgetstring (&sSenduser), zfgetstring (&sSendtosys), - TRUE, cbytes, isecs, imicros); - - if (freceived) - { - const char *zmail; - - zmail = zfgetstring (&sSendmail); - if (*zmail != '\0') - { - if (! fmail_transfer (TRUE, zfgetstring (&sSenduser), - zmail, zwhy, - zfgetstring (&sSendfrom), - zLocalname, - zfgetstring (&sSendto), - zfgetstring (&sSendtosys), - (const char *) NULL)) - f = FALSE; - } - - if (pSendseq != NULL) - { - if (! fsysdep_did_work (pSendseq)) - f = FALSE; - pSendseq = NULL; - } - } - else - { - /* If the transfer failed, we only try to save the file and send - mail if it was requested locally (in which case pSendseq != - NULL) and it will never succeed. We send mail to sSendmail - if defined, otherwise to sSenduser. I hope this is - reasonable. */ - if (pSendseq != NULL && fnever) - { - if (! fmail_transfer (FALSE, - zfgetstring (&sSenduser), - zfgetstring (&sSendmail), - zwhy, - zfgetstring (&sSendfrom), - zLocalname, - zfgetstring (&sSendto), - zfgetstring (&sSendtosys), - zsysdep_save_temp_file (pSendseq))) - f = FALSE; - - if (! fsysdep_did_work (pSendseq)) - f = FALSE; - pSendseq = NULL; - } - } - - eSendfile = EFILECLOSED; - uffreestring (&sSendfrom); - uffreestring (&sSendto); - uffreestring (&sSendtosys); - uffreestring (&sSenduser); - uffreestring (&sSendmail); - - return f; -} - -/* Some error occurred while sending a file. Mark an error and let - fsent_file handle everything else. This used to differentiate - between temporary and permanent errors, but I've decided that all - transmission errors are temporary. */ - -void -usendfile_error () -{ - fSenderror = TRUE; -} - -/* Information we keep for the file being received. We have to be - able to move the file into its final location with the correct - mode, we have to be able to send mail to the user when the transfer - is finished, we have to be able to report error messages sensibly, - and we have to be able to clear this receive request out of the - work queue if we initiated the receive. */ - -/* Work queue sequence number. */ -static pointer pRecseq; -/* File name being transferred from. */ -static struct sstring sRecfrom; -/* File name being transferred to. */ -static struct sstring sRecto; -/* System being transferred from. */ -static struct sstring sRecfromsys; -/* Requesting user name. */ -static struct sstring sRecuser; -/* Final file mode. */ -static unsigned int iRecmode; -/* User to send mail to. */ -static struct sstring sRecmail; -/* Temporary file name (as returned by esysdep_open_receive). */ -static struct sstring sRectemp; -/* Start time. */ -static long iRecstart_secs; -static long iRecstart_micros; -/* Indicate whether we had an error during the transfer. */ -static boolean fRecerror; - -/* Store information about a file being received. */ - -boolean -fstore_recfile (e, pseq, zfrom, zto, zfromsys, zuser, imode, zmail, ztemp) - openfile_t e; - pointer pseq; - const char *zfrom; - const char *zto; - const char *zfromsys; - const char *zuser; - unsigned int imode; - const char *zmail; - const char *ztemp; -{ -#if DEBUG > 0 - if (ffileisopen (eRecfile)) - ulog (LOG_FATAL, "fstore_recfile: In progress"); -#endif - - if (! ffsetstring (&sRecfrom, zfrom) - || ! ffsetstring (&sRecto, zto) - || ! ffsetstring (&sRecfromsys, zfromsys) - || ! ffsetstring (&sRecuser, zuser) - || ! ffsetstring (&sRecmail, zmail) - || ! ffsetstring (&sRectemp, ztemp)) - { - (void) ffileclose (e); - (void) remove (ztemp); - return FALSE; - } - - eRecfile = e; - pRecseq = pseq; - iRecmode = imode; - iRecstart_secs = isysdep_process_time (&iRecstart_micros); - - fRecerror = FALSE; - - return TRUE; -} - -/* Finish up after receiving a file. The argument indicates whether - the data was received correctly. We do not confirm the file - reception to the other system unless this function returns TRUE. - This may be called when no file receive is in progress if a fatal - program error occurs. The zwhy and fnever arguments are valid if - fsent is FALSE; fnever is TRUE if the file receive can never - succeed. */ - -boolean -freceived_file (fsent, cbytes, zwhy, fnever) - boolean fsent; - long cbytes; - const char *zwhy; - boolean fnever; -{ - long isecs, imicros; - - if (fRecerror) - fsent = FALSE; - - if (ffileisopen (eRecfile)) - { - if (! ffileclose (eRecfile)) - { - if (fsent) - { - zwhy = strerror (errno); - fnever = FALSE; - ulog (LOG_ERROR, "close: %s", zwhy); - } - fsent = FALSE; - } - } - - if (fsent) - { - if (! fsysdep_move_file (zfgetstring (&sRectemp), - zfgetstring (&sRecto), - iRecmode, TRUE, - (pRecseq != NULL - ? zfgetstring (&sRecuser) - : (const char *) NULL))) - { - zwhy = "could not move to final location"; - fnever = TRUE; - fsent = FALSE; - } - } - else - (void) remove (zfgetstring (&sRectemp)); - - isecs = isysdep_process_time (&imicros); - imicros -= iRecstart_micros; - if (imicros < 0) - { - imicros += 1000000; - isecs--; - } - isecs -= iRecstart_secs; - - ustats (fsent, zfgetstring (&sRecuser), zfgetstring (&sRecfromsys), - FALSE, cbytes, isecs, imicros); - - if (fsent) - { - const char *zmail; - - zmail = zfgetstring (&sRecmail); - if (*zmail != '\0') - (void) fmail_transfer (TRUE, zfgetstring (&sRecuser), - zmail, zwhy, - zfgetstring (&sRecfrom), - zfgetstring (&sRecfromsys), - zfgetstring (&sRecto), - zLocalname, (const char *) NULL); - - if (pRecseq != NULL) - { - if (! fsysdep_did_work (pRecseq)) - fsent = FALSE; - pRecseq = NULL; - } - } - else - { - /* If the transfer failed, we send mail if it was requested - locally and if it can never succeed. */ - if (pRecseq != NULL && fnever) - { - (void) fmail_transfer (FALSE, - zfgetstring (&sRecuser), - zfgetstring (&sRecmail), - zwhy, - zfgetstring (&sRecfrom), - zfgetstring (&sRecfromsys), - zfgetstring (&sRecto), - zLocalname, (const char *) NULL); - if (! fsysdep_did_work (pRecseq)) - fsent = FALSE; - pRecseq = NULL; - } - } - - eRecfile = EFILECLOSED; - uffreestring (&sRecfrom); - uffreestring (&sRecto); - uffreestring (&sRecfromsys); - uffreestring (&sRecuser); - uffreestring (&sRecmail); - uffreestring (&sRectemp); - - return fsent; -} - -/* Some error occurred while receiving a file. Note that we had an - error, so that when we close up we know that something went wrong. - We leave the file open because it's easier to handle everything in - freceived_file. This used to differentiate between permanent - errors and temporary errors, but I've decided that all errors that - occur while the file is being transferred are temporary. */ - -void -urecfile_error () -{ - fRecerror = TRUE; -} - -/* There was some sort of protocol error while receiving the file, - so we want to try it again. We must truncate the file. */ - -boolean -frecfile_rewind () -{ - eRecfile = esysdep_truncate (eRecfile, zfgetstring (&sRectemp)); - if (! ffileisopen (eRecfile)) - { - urecfile_error (); - return FALSE; - } - return TRUE; -} - -/* 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"; - 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"; - 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/getopt.c b/gnu/libexec/uucp/getopt.c deleted file mode 100644 index 71f5cb6e86a..00000000000 --- a/gnu/libexec/uucp/getopt.c +++ /dev/null @@ -1,682 +0,0 @@ -/* Getopt for GNU. - NOTE: getopt is now part of the C library, so if you don't know what - "Keep this file name-space clean" means, talk to roland@gnu.ai.mit.edu - before changing it! - - Copyright (C) 1987, 88, 89, 90, 91, 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, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ - -#ifndef lint -static char rcsid[] = "$Id: getopt.c,v 1.2 1993/08/02 17:25:05 mycroft Exp $"; -#endif /* not lint */ - -/* AIX requires this to be the first thing in the file. */ -#ifdef __GNUC__ -#define alloca __builtin_alloca -#else /* not __GNUC__ */ -#ifdef sparc -#include <alloca.h> -#else -#ifdef _AIX - #pragma alloca -#else -char *alloca (); -#endif -#endif /* sparc */ -#endif /* not __GNUC__ */ - -#ifdef LIBC -/* For when compiled as part of the GNU C library. */ -#include <ansidecl.h> -#endif - -#include <stdio.h> - -/* This needs to come after some library #include - to get __GNU_LIBRARY__ defined. */ -#ifdef __GNU_LIBRARY__ -#undef alloca -#include <stdlib.h> -#include <string.h> -#else /* Not GNU C library. */ -#define __alloca alloca -#endif /* GNU C library. */ - - -#ifndef __STDC__ -#define const -#endif - -/* If GETOPT_COMPAT is defined, `+' as well as `--' can introduce a - long-named option. Because this is not POSIX.2 compliant, it is - being phased out. */ -#define GETOPT_COMPAT - -/* This version of `getopt' appears to the caller like standard Unix `getopt' - but it behaves differently for the user, since it allows the user - to intersperse the options with the other arguments. - - As `getopt' works, it permutes the elements of ARGV so that, - when it is done, all the options precede everything else. Thus - all application programs are extended to handle flexible argument order. - - Setting the environment variable POSIXLY_CORRECT disables permutation. - Then the behavior is completely standard. - - GNU application programs can use a third alternative mode in which - they can distinguish the relative order of options and other arguments. */ - -#include "getopt.h" - -/* 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. */ - -char *optarg = 0; - -/* 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. */ - -int optind = 0; - -/* The next char to be scanned in the option-element - in which the last option character we returned was found. - This allows us to pick up the scan where we left off. - - If this is zero, or a null string, it means resume the scan - by advancing to the next ARGV-element. */ - -static char *nextchar; - -/* Callers store zero here to inhibit the error message - for unrecognized options. */ - -int opterr = 1; - -/* Describe how to deal with options that follow non-option ARGV-elements. - - If the caller did not specify anything, - the default is REQUIRE_ORDER if the environment variable - POSIXLY_CORRECT is defined, PERMUTE otherwise. - - REQUIRE_ORDER means don't recognize them as options; - stop option processing when the first non-option is seen. - This is what Unix does. - This mode of operation is selected by either setting the environment - variable POSIXLY_CORRECT, or using `+' as the first character - of the list of option characters. - - PERMUTE is the default. We permute the contents of ARGV as we scan, - so that eventually all the non-options are at the end. This allows options - to be given in any order, even with programs that were not written to - expect this. - - RETURN_IN_ORDER is an option available to programs that were written - to expect options and other ARGV-elements in any order and that care about - the ordering of the two. We describe each non-option ARGV-element - as if it were the argument of an option with character code 1. - Using `-' as the first character of the list of option characters - selects this mode of operation. - - The special argument `--' forces an end of option-scanning regardless - of the value of `ordering'. In the case of RETURN_IN_ORDER, only - `--' can cause `getopt' to return EOF with `optind' != ARGC. */ - -static enum -{ - REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER -} ordering; - -#ifdef __GNU_LIBRARY__ -#include <string.h> -#define my_index strchr -#define my_bcopy(src, dst, n) memcpy ((dst), (src), (n)) -#else - -/* Avoid depending on library functions or files - whose names are inconsistent. */ - -char *getenv (); - -static char * -my_index (string, chr) - char *string; - int chr; -{ - while (*string) - { - if (*string == chr) - return string; - string++; - } - return 0; -} - -static void -my_bcopy (from, to, size) - char *from, *to; - int size; -{ - int i; - for (i = 0; i < size; i++) - to[i] = from[i]; -} -#endif /* GNU C library. */ - -/* Handle permutation of arguments. */ - -/* Describe the part of ARGV that contains non-options that have - been skipped. `first_nonopt' is the index in ARGV of the first of them; - `last_nonopt' is the index after the last of them. */ - -static int first_nonopt; -static int last_nonopt; - -/* Exchange two adjacent subsequences of ARGV. - One subsequence is elements [first_nonopt,last_nonopt) - which contains all the non-options that have been skipped so far. - The other is elements [last_nonopt,optind), which contains all - the options processed since those non-options were skipped. - - `first_nonopt' and `last_nonopt' are relocated so that they describe - the new indices of the non-options in ARGV after they are moved. */ - -static void -exchange (argv) - char **argv; -{ - int nonopts_size = (last_nonopt - first_nonopt) * sizeof (char *); - char **temp = (char **) __alloca (nonopts_size); - - /* Interchange the two blocks of data in ARGV. */ - - my_bcopy (&argv[first_nonopt], temp, nonopts_size); - my_bcopy (&argv[last_nonopt], &argv[first_nonopt], - (optind - last_nonopt) * sizeof (char *)); - my_bcopy (temp, &argv[first_nonopt + optind - last_nonopt], nonopts_size); - - /* Update records for the slots the non-options now occupy. */ - - first_nonopt += (optind - last_nonopt); - last_nonopt = optind; -} - -/* Scan elements of ARGV (whose length is ARGC) for option characters - given in OPTSTRING. - - If an element of ARGV starts with '-', and is not exactly "-" or "--", - then it is an option element. The characters of this element - (aside from the initial '-') are option characters. If `getopt' - is called repeatedly, it returns successively each of the option characters - from each of the option elements. - - If `getopt' finds another option character, it returns that character, - updating `optind' and `nextchar' so that the next call to `getopt' can - resume the scan with the following option character or ARGV-element. - - If there are no more option characters, `getopt' returns `EOF'. - Then `optind' is the index in ARGV of the first ARGV-element - that is not an option. (The ARGV-elements have been permuted - so that those that are not options now come last.) - - OPTSTRING is a string containing the legitimate option characters. - If an option character is seen that is not listed in OPTSTRING, - return '?' after printing an error message. If you set `opterr' to - zero, the error message is suppressed but we still return '?'. - - If a char in OPTSTRING is followed by a colon, that means it wants an arg, - so the following text in the same ARGV-element, or the text of the following - ARGV-element, is returned in `optarg'. Two colons mean an option that - wants an optional arg; if there is text in the current ARGV-element, - it is returned in `optarg', otherwise `optarg' is set to zero. - - If OPTSTRING starts with `-' or `+', it requests different methods of - handling the non-option ARGV-elements. - See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above. - - Long-named options begin with `--' instead of `-'. - Their names may be abbreviated as long as the abbreviation is unique - or is an exact match for some defined option. If they have an - argument, it follows the option name in the same ARGV-element, separated - from the option name by a `=', or else the in next ARGV-element. - When `getopt' finds a long-named option, it returns 0 if that option's - `flag' field is nonzero, the value of the option's `val' field - if the `flag' field is zero. - - The elements of ARGV aren't really const, because we permute them. - But we pretend they're const in the prototype to be compatible - with other systems. - - LONGOPTS is a vector of `struct option' terminated by an - element containing a name which is zero. - - LONGIND returns the index in LONGOPT of the long-named option found. - It is only valid when a long-named option has been found by the most - recent call. - - If LONG_ONLY is nonzero, '-' as well as '--' can introduce - long-named options. */ - -int -_getopt_internal (argc, argv, optstring, longopts, longind, long_only) - int argc; - char *const *argv; - const char *optstring; - const struct option *longopts; - int *longind; - int long_only; -{ - int option_index; - - optarg = 0; - - /* Initialize the internal data when the first call is made. - Start processing options with ARGV-element 1 (since ARGV-element 0 - is the program name); the sequence of previously skipped - non-option ARGV-elements is empty. */ - - if (optind == 0) - { - first_nonopt = last_nonopt = optind = 1; - - nextchar = NULL; - - /* Determine how to handle the ordering of options and nonoptions. */ - - if (optstring[0] == '-') - { - ordering = RETURN_IN_ORDER; - ++optstring; - } - else if (optstring[0] == '+') - { - ordering = REQUIRE_ORDER; - ++optstring; - } - else if (getenv ("POSIXLY_CORRECT") != NULL) - ordering = REQUIRE_ORDER; - else - ordering = PERMUTE; - } - - if (nextchar == NULL || *nextchar == '\0') - { - if (ordering == PERMUTE) - { - /* If we have just processed some options following some non-options, - exchange them so that the options come first. */ - - if (first_nonopt != last_nonopt && last_nonopt != optind) - exchange ((char **) argv); - else if (last_nonopt != optind) - first_nonopt = optind; - - /* Now skip any additional non-options - and extend the range of non-options previously skipped. */ - - while (optind < argc - && (argv[optind][0] != '-' || argv[optind][1] == '\0') -#ifdef GETOPT_COMPAT - && (longopts == NULL - || argv[optind][0] != '+' || argv[optind][1] == '\0') -#endif /* GETOPT_COMPAT */ - ) - optind++; - last_nonopt = optind; - } - - /* Special ARGV-element `--' means premature end of options. - Skip it like a null option, - then exchange with previous non-options as if it were an option, - then skip everything else like a non-option. */ - - if (optind != argc && !strcmp (argv[optind], "--")) - { - optind++; - - if (first_nonopt != last_nonopt && last_nonopt != optind) - exchange ((char **) argv); - else if (first_nonopt == last_nonopt) - first_nonopt = optind; - last_nonopt = argc; - - optind = argc; - } - - /* If we have done all the ARGV-elements, stop the scan - and back over any non-options that we skipped and permuted. */ - - if (optind == argc) - { - /* Set the next-arg-index to point at the non-options - that we previously skipped, so the caller will digest them. */ - if (first_nonopt != last_nonopt) - optind = first_nonopt; - return EOF; - } - - /* If we have come to a non-option and did not permute it, - either stop the scan or describe it to the caller and pass it by. */ - - if ((argv[optind][0] != '-' || argv[optind][1] == '\0') -#ifdef GETOPT_COMPAT - && (longopts == NULL - || argv[optind][0] != '+' || argv[optind][1] == '\0') -#endif /* GETOPT_COMPAT */ - ) - { - if (ordering == REQUIRE_ORDER) - return EOF; - optarg = argv[optind++]; - return 1; - } - - /* We have found another option-ARGV-element. - Start decoding its characters. */ - - nextchar = (argv[optind] + 1 - + (longopts != NULL && argv[optind][1] == '-')); - } - - if (longopts != NULL - && ((argv[optind][0] == '-' - && (argv[optind][1] == '-' || long_only)) -#ifdef GETOPT_COMPAT - || argv[optind][0] == '+' -#endif /* GETOPT_COMPAT */ - )) - { - const struct option *p; - char *s = nextchar; - int exact = 0; - int ambig = 0; - const struct option *pfound = NULL; - int indfound; - - while (*s && *s != '=') - s++; - - /* Test all options for either exact match or abbreviated matches. */ - for (p = longopts, option_index = 0; p->name; - p++, option_index++) - if (!strncmp (p->name, nextchar, s - nextchar)) - { - if (s - nextchar == strlen (p->name)) - { - /* Exact match found. */ - pfound = p; - indfound = option_index; - exact = 1; - break; - } - else if (pfound == NULL) - { - /* First nonexact match found. */ - pfound = p; - indfound = option_index; - } - else - /* Second nonexact match found. */ - ambig = 1; - } - - if (ambig && !exact) - { - if (opterr) - fprintf (stderr, "%s: option `%s' is ambiguous\n", - argv[0], argv[optind]); - nextchar += strlen (nextchar); - optind++; - return '?'; - } - - if (pfound != NULL) - { - option_index = indfound; - optind++; - if (*s) - { - /* Don't test has_arg with >, because some C compilers don't - allow it to be used on enums. */ - if (pfound->has_arg) - optarg = s + 1; - else - { - if (opterr) - { - if (argv[optind - 1][1] == '-') - /* --option */ - fprintf (stderr, - "%s: option `--%s' doesn't allow an argument\n", - argv[0], pfound->name); - else - /* +option or -option */ - fprintf (stderr, - "%s: option `%c%s' doesn't allow an argument\n", - argv[0], argv[optind - 1][0], pfound->name); - } - nextchar += strlen (nextchar); - return '?'; - } - } - else if (pfound->has_arg == 1) - { - if (optind < argc) - optarg = argv[optind++]; - else - { - if (opterr) - fprintf (stderr, "%s: option `%s' requires an argument\n", - argv[0], argv[optind - 1]); - nextchar += strlen (nextchar); - return '?'; - } - } - nextchar += strlen (nextchar); - if (longind != NULL) - *longind = option_index; - if (pfound->flag) - { - *(pfound->flag) = pfound->val; - return 0; - } - return pfound->val; - } - /* Can't find it as a long option. If this is not getopt_long_only, - or the option starts with '--' or is not a valid short - option, then it's an error. - Otherwise interpret it as a short option. */ - if (!long_only || argv[optind][1] == '-' -#ifdef GETOPT_COMPAT - || argv[optind][0] == '+' -#endif /* GETOPT_COMPAT */ - || my_index (optstring, *nextchar) == NULL) - { - if (opterr) - { - if (argv[optind][1] == '-') - /* --option */ - fprintf (stderr, "%s: unrecognized option `--%s'\n", - argv[0], nextchar); - else - /* +option or -option */ - fprintf (stderr, "%s: unrecognized option `%c%s'\n", - argv[0], argv[optind][0], nextchar); - } - nextchar += strlen (nextchar); - optind++; - return '?'; - } - } - - /* Look at and handle the next option-character. */ - - { - char c = *nextchar++; - char *temp = my_index (optstring, c); - - /* Increment `optind' when we start to process its last character. */ - if (*nextchar == '\0') - optind++; - - if (temp == NULL || c == ':') - { - if (opterr) - { - if (c < 040 || c >= 0177) - fprintf (stderr, "%s: unrecognized option, character code 0%o\n", - argv[0], c); - else - fprintf (stderr, "%s: unrecognized option `-%c'\n", argv[0], c); - } - return '?'; - } - if (temp[1] == ':') - { - if (temp[2] == ':') - { - /* This is an option that accepts an argument optionally. */ - if (*nextchar != '\0') - { - optarg = nextchar; - optind++; - } - else - optarg = 0; - nextchar = NULL; - } - else - { - /* This is an option that requires an argument. */ - if (*nextchar != 0) - { - optarg = nextchar; - /* If we end this ARGV-element by taking the rest as an arg, - we must advance to the next element now. */ - optind++; - } - else if (optind == argc) - { - if (opterr) - fprintf (stderr, "%s: option `-%c' requires an argument\n", - argv[0], c); - c = '?'; - } - else - /* We already incremented `optind' once; - increment it again when taking next ARGV-elt as argument. */ - optarg = argv[optind++]; - nextchar = NULL; - } - } - return c; - } -} - -int -getopt (argc, argv, optstring) - int argc; - char *const *argv; - const char *optstring; -{ - return _getopt_internal (argc, argv, optstring, - (const struct option *) 0, - (int *) 0, - 0); -} - -#ifdef TEST - -/* Compile with -DTEST to make an executable for use in testing - the above definition of `getopt'. */ - -int -main (argc, argv) - int argc; - char **argv; -{ - int c; - int digit_optind = 0; - - while (1) - { - int this_option_optind = optind ? optind : 1; - - c = getopt (argc, argv, "abc:d:0123456789"); - if (c == EOF) - break; - - switch (c) - { - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - if (digit_optind != 0 && digit_optind != this_option_optind) - printf ("digits occur in two different argv-elements.\n"); - digit_optind = this_option_optind; - printf ("option %c\n", c); - break; - - case 'a': - printf ("option a\n"); - break; - - case 'b': - printf ("option b\n"); - break; - - case 'c': - printf ("option c with value `%s'\n", optarg); - break; - - case '?': - break; - - default: - printf ("?? getopt returned character code 0%o ??\n", c); - } - } - - if (optind < argc) - { - printf ("non-option ARGV-elements: "); - while (optind < argc) - printf ("%s ", argv[optind++]); - printf ("\n"); - } - - exit (0); -} - -#endif /* TEST */ diff --git a/gnu/libexec/uucp/getopt.h b/gnu/libexec/uucp/getopt.h deleted file mode 100644 index a31e4e82123..00000000000 --- a/gnu/libexec/uucp/getopt.h +++ /dev/null @@ -1,124 +0,0 @@ -/* 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, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - $Id: getopt.h,v 1.2 1993/08/02 17:25:06 mycroft Exp $ -*/ - -#ifndef _GETOPT_H_ -#define _GETOPT_H_ - -/* 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 -{ -#ifdef __STDC__ - const char *name; -#else - char *name; -#endif - /* 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 -}; - -#ifdef __STDC__ -extern int getopt (int argc, char *const *argv, const char *shortopts); -extern int getopt_long (int argc, char *const *argv, const char *shortopts, - const struct option *longopts, int *longind); -extern int getopt_long_only (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 (int argc, char *const *argv, - const char *shortopts, - const struct option *longopts, int *longind, - int long_only); -#else /* not __STDC__ */ -extern int getopt (); -extern int getopt_long (); -extern int getopt_long_only (); - -extern int _getopt_internal (); -#endif /* not __STDC__ */ - -#endif /* _GETOPT_H_ */ diff --git a/gnu/libexec/uucp/log.c b/gnu/libexec/uucp/log.c deleted file mode 100644 index 435a4930975..00000000000 --- a/gnu/libexec/uucp/log.c +++ /dev/null @@ -1,740 +0,0 @@ -/* 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 AIRS, P.O. Box 520, Waltham, MA 02254. - - $Log: log.c,v $ - Revision 1.1.1.1 1993/03/21 09:45:37 cgd - initial import of 386bsd-0.1 sources - - Revision 1.29 1992/04/01 21:58:35 ian - Added CLOSE_LOGFILES configuration parameter - - Revision 1.28 1992/03/28 19:40:26 ian - Close log and statistics file at each master/slave role switch - - Revision 1.27 1992/03/15 04:51:17 ian - Keep an array of signals we've received rather than a single variable - - Revision 1.26 1992/03/12 19:54:43 ian - Debugging based on types rather than number - - Revision 1.25 1992/03/08 16:42:41 ian - Ted Lindgreen: report port and login name in log file - - Revision 1.24 1992/03/04 00:36:44 ian - Michael Richardson: better chat script debugging - - Revision 1.23 1992/02/27 05:40:54 ian - T. William Wells: detach from controlling terminal, handle signals safely - - Revision 1.22 1992/02/19 19:36:07 ian - Rearranged time functions - - Revision 1.21 1992/02/18 04:33:38 ian - Don't use headers when outputting to terminal - - Revision 1.20 1992/02/14 07:51:49 ian - Michael Nolan: don't refer to eLdebug if DEBUG is 0 - - Revision 1.19 1992/02/08 20:33:57 ian - Handle all possible signals raised by abort - - Revision 1.18 1992/02/08 03:54:18 ian - Include <string.h> only in <uucp.h>, added 1992 copyright - - Revision 1.17 1992/02/01 00:51:28 ian - Michael Nolan: call abort if SIGABRT is not defined - - Revision 1.16 1992/01/28 04:51:34 ian - Marty Shannon: don't report failed transfers with BNU logging - - Revision 1.15 1992/01/16 18:07:18 ian - Niels Baggesen: add FAILED to end of xferstats line if appropriate - - Revision 1.14 1992/01/12 19:32:29 ian - Handle HAVE_BNU_LOGGING with no %s in zLogfile - - Revision 1.13 1992/01/05 04:41:48 ian - Tweaked HAVE_V2_LOGGING output slightly - - Revision 1.12 1991/12/29 05:00:27 ian - Was not allocating enough space in zldate_and_time - - Revision 1.11 1991/12/29 04:04:18 ian - Added a bunch of extern definitions - - Revision 1.10 1991/12/29 02:59:50 ian - Lele Gaifax: put full year in log file - - Revision 1.9 1991/12/21 23:10:43 ian - Terry Gardner: record failed file transfers in statistics file - - Revision 1.8 1991/12/18 03:54:14 ian - Made error messages to terminal appear more normal - - Revision 1.7 1991/12/18 03:14:52 ian - Use a fixed number of fields in log messages - - Revision 1.6 1991/12/17 07:09:58 ian - Record statistics in fractions of a second - - Revision 1.5 1991/12/13 04:02:23 ian - David Nugent: move ERROR: from start of line to after date and time - - Revision 1.4 1991/12/11 04:21:37 ian - Arne Ludwig: merge in Arne Ludwig's patches for V2 and BNU style logging - - Revision 1.3 1991/11/07 20:32:04 ian - Chip Salzenberg: allow ANSI_C to be defined in conf.h - - Revision 1.2 1991/09/19 03:23:34 ian - Chip Salzenberg: append to private debugging file, don't overwrite it - - Revision 1.1 1991/09/10 19:40:31 ian - Initial revision - - */ - -#include "uucp.h" - -#if USE_RCS_ID -char log_rcsid[] = "$Id: log.c,v 1.1.1.1 1993/03/21 09:45:37 cgd Exp $"; -#endif - -#include <errno.h> - -#if ANSI_C -#include <stdarg.h> -#endif - -#if HAVE_TIME_H -#include <time.h> -#endif - -#if ! HAVE_TIME_T -#if HAVE_SYS_TIME_T -#include <sys/types.h> -#endif /* HAVE_SYS_TIME_T */ -#endif /* ! HAVE_TIME_T */ - -#include "system.h" - -/* External functions. */ -extern int fflush (), fclose (); -#if HAVE_VFPRINTF -extern int vfprintf (); -#endif - -/* Static functions. */ - -static const char *zldate_and_time P((void)); - -/* The function to call when a LOG_FATAL error occurs. */ -static void (*fLfatal) 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_BNU_LOGGING we - may have to write to various different log files. */ -static boolean fLlog_tried; - -#if DEBUG > 1 -/* 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 - -/* 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]; - -/* Signal names to use when logging signals. */ -static const char * const azSignal_names[INDEXSIG_COUNT] = INDEXSIG_NAMES; - -/* Set the function to call on a LOG_FATAL error. */ - -void -ulog_fatal_fn (pfn) - void (*pfn) P((void)); -{ - fLfatal = pfn; -} - -/* Decide whether to send log message to the file or not. */ - -void -ulog_to_file (ffile) - boolean ffile; -{ - 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; -{ - if (zuser == NULL - || zLuser == NULL - || strcmp (zuser, zLuser) != 0) - { - xfree ((pointer) zLuser); - if (zuser == NULL) - zLuser = NULL; - else - zLuser = xstrdup (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) - { - xfree ((pointer) zLsystem); - if (zsystem == NULL) - zLsystem = NULL; - else - zLsystem = xstrdup (zsystem); -#if HAVE_BNU_LOGGING - /* Under BNU logging we now must write to a different log file. */ - if (eLlog != NULL) - { - (void) fclose (eLlog); - eLlog = NULL; - fLlog_tried = FALSE; - } -#endif /* HAVE_BNU_LOGGING */ - } -} - -/* Set the device name. This is copied into memory. */ - -void -ulog_device (zdevice) - const char *zdevice; -{ - if (zdevice == NULL - || zLdevice == NULL - || strcmp (zdevice, zLdevice) != 0) - { - xfree ((pointer) zLdevice); - if (zdevice == NULL) - zLdevice = NULL; - else - zLdevice = xstrdup (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; - 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 (zDebugfile, 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_BNU_LOGGING - eLlog = esysdep_fopen (zLogfile, TRUE, TRUE, TRUE); -#else /* HAVE_BNU_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 = (char *) alloca (strlen (zLogfile) - + strlen (abProgram) - + strlen (zsys) - + 1); - sprintf (zfile, zLogfile, abProgram, zsys); - eLlog = esysdep_fopen (zfile, TRUE, TRUE, TRUE); - } -#endif /* HAVE_BNU_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 (fLfatal != NULL) - (*fLfatal) (); - 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; - } - - 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_BNU_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_BNU_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_BNU_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 (ttype == LOG_FATAL) - { - if (fLfatal != NULL) - (*fLfatal) (); - usysdep_exit (FALSE); - } - -#if CLOSE_LOGFILES - ulog_close (); -#endif -} - -/* 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. */ - -void -ustats (fsucceeded, zuser, zsystem, fsent, cbytes, csecs, cmicros) - boolean fsucceeded; - const char *zuser; - const char *zsystem; - boolean fsent; - long cbytes; - long csecs; - long cmicros; -{ - long cbps; - - /* On a system which can determine microseconds we might very well - have both csecs == 0 and cmicros == 0. */ - if (csecs == 0 && cmicros == 0) - cbps = 0; - else - cbps = (1000 * cbytes) / (csecs * 1000 + cmicros / 1000); - - if (eLstats == NULL) - { - if (fLstats_tried) - return; - fLstats_tried = TRUE; - eLstats = esysdep_fopen (zStatfile, 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_BNU_LOGGING - { - static int iseq; - - /* I don't know what the 'M' or the 'C' mean. This format expects - us to get the time in fractions of a second; on Unix we could - use times to do this, and we probably should. 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 M (%s) (C,%d,%d) [%s] %s %ld / %ld.%03ld secs, %ld %s\n", - zsystem, zuser, zldate_and_time (), iLid, iseq, - zLdevice == NULL ? "unknown" : zLdevice, - fsent ? "->" : "<-", - cbytes, csecs, cmicros / 1000, cbps, - "bytes/sec"); - } -#endif /* HAVE_BNU_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_BNU_LOGGING - static char ab[sizeof "12/31-12:00:00"]; -#endif - - isecs = isysdep_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_BNU_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/parse.c b/gnu/libexec/uucp/parse.c deleted file mode 100644 index 632947edcfd..00000000000 --- a/gnu/libexec/uucp/parse.c +++ /dev/null @@ -1,162 +0,0 @@ -/* parse.c - Parse a UUCP command string. - - 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 AIRS, P.O. Box 520, Waltham, MA 02254. - - $Log: parse.c,v $ - Revision 1.1.1.1 1993/03/21 09:45:37 cgd - initial import of 386bsd-0.1 sources - - Revision 1.3 1992/02/08 03:54:18 ian - Include <string.h> only in <uucp.h>, added 1992 copyright - - Revision 1.2 1991/11/11 02:10:39 ian - Forget to set pseq field to NULL - - Revision 1.1 1991/09/10 19:40:31 ian - Initial revision - - */ - -#include "uucp.h" - -#if USE_RCS_ID -char parse_rcsid[] = "$Id: parse.c,v 1.1.1.1 1993/03/21 09:45:37 cgd Exp $"; -#endif - -/* Parse a UUCP command string into an scmd structure. This is called - by the 'g' protocol and the UNIX command file reading routines. It - destroys the string it is passed, and the scmd string pointers are - left pointing into it. It returns TRUE if the string is - successfully parsed, FALSE otherwise. */ - -boolean -fparse_cmd (zcmd, qcmd) - char *zcmd; - struct scmd *qcmd; -{ - char *z; - - z = strtok (zcmd, " \t\n"); - if (z == NULL) - return FALSE; - - qcmd->bcmd = *z; - if (qcmd->bcmd != 'S' - && qcmd->bcmd != 'R' - && qcmd->bcmd != 'X' - && qcmd->bcmd != 'H') - return FALSE; - - qcmd->pseq = NULL; - - /* Handle hangup commands specially. If it's just "H", return - the command 'H' to indicate a hangup request. If it's "HY" - return 'Y' and if it's "HN" return 'N'. */ - - if (qcmd->bcmd == 'H') - { - if (z[1] == '\0') - return TRUE; - else if (z[1] == 'Y') - { - qcmd->bcmd = 'Y'; - return TRUE; - } - else if (z[1] == 'N') - { - qcmd->bcmd = 'N'; - return TRUE; - } - else - return FALSE; - } - - if (z[1] != '\0') - return FALSE; - - z = strtok ((char *) NULL, " \t\n"); - if (z == NULL) - return FALSE; - qcmd->zfrom = z; - - z = strtok ((char *) NULL, " \t\n"); - if (z == NULL) - return FALSE; - qcmd->zto = z; - - z = strtok ((char *) NULL, " \t\n"); - if (z == NULL) - return FALSE; - qcmd->zuser = z; - - z = strtok ((char *) NULL, " \t\n"); - if (z == NULL || *z != '-') - return FALSE; - qcmd->zoptions = z + 1; - - z = strtok ((char *) NULL, " \t\n"); - if (z != NULL) - qcmd->ztemp = z; - else if (qcmd->bcmd == 'S') - return FALSE; - else - qcmd->ztemp = ""; - - z = strtok ((char *) NULL, " \t\n"); - if (z != NULL) - { - char *zend; - - qcmd->imode = (int) strtol (z, &zend, 8); - if (*zend != '\0') - return FALSE; - } - else if (qcmd->bcmd == 'S') - return FALSE; - else - qcmd->imode = 0666; - - z = strtok ((char *) NULL, " \t\n"); - if (z != NULL) - qcmd->znotify = z; - else - qcmd->znotify = ""; - - /* If the notify string is "", there may be a number of bytes. */ - qcmd->cbytes = -1; - if (strcmp (qcmd->znotify, "\"\"") == 0) - { - z = strtok ((char *) NULL, " \t\n"); - if (z != NULL) - { - char *zend; - - qcmd->znotify = ""; - qcmd->cbytes = strtol (z, &zend, 10); - if (*zend != '\0') - return FALSE; - } - } - - return TRUE; -} diff --git a/gnu/libexec/uucp/policy.h b/gnu/libexec/uucp/policy.h deleted file mode 100644 index 74c0d085d60..00000000000 --- a/gnu/libexec/uucp/policy.h +++ /dev/null @@ -1,419 +0,0 @@ -/* 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 AIRS, P.O. Box 520, Waltham, MA 02254. - - $Id: policy.h,v 1.2 1993/08/02 17:25:07 mycroft Exp $ -*/ - -/* 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 1 -#define HAVE_SYSV_TERMIO 0 -#define HAVE_POSIX_TERMIOS 0 - -/* 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 HAVE_UNBLOCKED_WRITES should be 0 - and on BSD 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 this is typically the size - of a clist, CLSIZE in <sys/tty.h>, which is usually 64. 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 - -/* Set TIMES_TICK to 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 TIMES_TICK may simply be - defined as CLK_TCK. 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 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 60 - -/* 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 may complain about the 'p' option. The second set of - definitions are appropriate for System V. To use the second set of - definitions, change the ``#if 1'' to ``#if 0''. */ -#if 1 -#define PS_PROGRAM "/bin/ps -lp" -#define HAVE_PS_MULTIPLE 0 -#else -#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 file is named LCK.. followed by the - name of the device (UUCP and some versions of cu also lock systems - this way). 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 BNU systems the lock files - are placed in /etc/locks. On some they are placed in - /usr/spool/locks. */ -/* #define LOCKDIR "/etc/locks" */ -#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 BNU 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. - - SCO lock files are similar to BNU 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 BNU 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. */ -#define HAVE_V2_LOCKFILES 0 -#define HAVE_BNU_LOCKFILES 1 -#define HAVE_SCO_LOCKFILES 0 -#define HAVE_SVR4_LOCKFILES 0 - -/* If your system supports Internet mail addresses, 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') - -/* The maximum number of times to retry calling a system which is not - answering. If this many calls to the system have failed, the - system will not be called again until the status file has been - removed (on a Unix system the status file is in the .Status - subdirectory of the main spool directory, and has the same name as - the system name). If this is set to 0 the system may be called - regardless of how many previous calls have failed. */ -#define CMAXRETRIES 26 - -/* 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 BNU - style configuration files (Systems, Devices and so on) set - HAVE_BNU_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_BNU_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 BNU configuration files. */ -#define HAVE_V2_CONFIG 0 -#define HAVE_BNU_CONFIG 0 - -/* Exactly one of the following macros must be set to 1. The exact - format of the spool directories is explained in sys3.unx. - - 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_BNU -- Use a BNU (HDB) style spool directory - SPOOLDIR_ULTRIX -- Use an Ultrix style 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_BNU 0 -#define SPOOLDIR_ULTRIX 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_BNU_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_BNU_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) - -/* 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_BNU_LOGGING - -/* The default log file when using HAVE_BNU_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_BNU_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_BNU_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_BNU_LOGGING */ diff --git a/gnu/libexec/uucp/port.c b/gnu/libexec/uucp/port.c deleted file mode 100644 index 65ae2acb6e8..00000000000 --- a/gnu/libexec/uucp/port.c +++ /dev/null @@ -1,602 +0,0 @@ -/* port.c - Port manipulation 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 AIRS, P.O. Box 520, Waltham, MA 02254. - - $Log: port.c,v $ - Revision 1.1.1.1 1993/03/21 09:45:37 cgd - initial import of 386bsd-0.1 sources - - Revision 1.17 1992/04/01 22:31:05 ian - Initialize stdin port - - Revision 1.16 1992/03/28 19:57:22 ian - David J. MacKenzie: send port device for /Y rather than port name - - Revision 1.15 1992/03/17 01:03:03 ian - Miscellaneous cleanup - - Revision 1.14 1992/03/15 06:58:12 ian - Show fport_read and fport_write calls under DEBUG_PORT - - Revision 1.13 1992/03/12 19:54:43 ian - Debugging based on types rather than number - - Revision 1.12 1992/03/04 00:36:44 ian - Michael Richardson: better chat script debugging - - Revision 1.11 1992/02/08 19:34:07 ian - Cast result of alloca - - Revision 1.10 1992/02/08 03:54:18 ian - Include <string.h> only in <uucp.h>, added 1992 copyright - - Revision 1.9 1991/12/28 04:20:36 ian - Cleaned up debugging code - - Revision 1.8 1991/12/20 02:18:35 ian - Complete diagnostics for fport_io - - Revision 1.7 1991/12/15 03:42:33 ian - Added tprocess_chat_cmd for all chat commands, and added CMDTABTYPE_PREFIX - - Revision 1.6 1991/12/10 19:45:05 ian - Added ulog_device to record device name for log file - - Revision 1.5 1991/11/14 03:20:13 ian - Added seven-bit and reliable commands to help when selecting protocols - - Revision 1.4 1991/11/13 20:38:00 ian - Added TCP port type for connections over TCP - - Revision 1.3 1991/11/11 23:47:24 ian - Added chat-program to run a program to do a chat script - - Revision 1.2 1991/11/11 00:39:45 ian - Open port in seven bit mode, added fport_set to change to eight bit - - Revision 1.1 1991/09/10 19:40:31 ian - Initial revision - - */ - -#include "uucp.h" - -#if USE_RCS_ID -char port_rcsid[] = "$Id: port.c,v 1.1.1.1 1993/03/21 09:45:37 cgd Exp $"; -#endif - -#include <ctype.h> - -#include "port.h" - -#if DEBUG > 1 - -/* A debugging routine used when displaying buffers. */ - -int -cdebug_char (z, ichar) - char *z; - int ichar; -{ - char b; - - if (isprint (BUCHAR (ichar)) - && ichar != '\"' - && ichar != '\\') - { - *z++ = (char) ichar; - *z = '\0'; - return 1; - } - - *z++ = '\\'; - - switch (ichar) - { - case '\n': - b = 'n'; - break; - case '\r': - b = 'r'; - break; - case '\"': - b = '\"'; - break; - case '\\': - b = '\\'; - break; - default: - sprintf (z, "%03o", (unsigned int) BUCHAR (ichar)); - return strlen (z) + 1; - } - - *z++ = b; - *z = '\0'; - return 2; -} - -/* Display a buffer when debugging. */ - -void -udebug_buffer (zhdr, zbuf, clen) - const char *zhdr; - const char *zbuf; - int clen; -{ - char *z, *zalc; - int i; - - z = zalc = (char *) xmalloc (clen * 4 + 1); - for (i = 0; i < clen && i < 80; i++) - z += cdebug_char (z, zbuf[i]); - if (i < clen) - { - *z++ = '.'; - *z++ = '.'; - *z++ = '.'; - } - *z = '\0'; - - ulog (LOG_DEBUG, "%s %d \"%s\"", zhdr, clen, zalc); - xfree ((pointer) zalc); -} - -#endif /* DEBUG > 1 */ - -/* The open port. */ - -struct sport *qPort; - -/* The port dispatch table. The order of entries in this table must - be the same as the tporttype enumeration. */ - -const struct sportcmds asPortcmds[] = -{ - { fsysdep_stdin_lock, fsysdep_stdin_open, fsysdep_stdin_close, - fsysdep_stdin_reset, NULL, fsysdep_stdin_read, - fsysdep_stdin_write, fsysdep_stdin_io, fsysdep_stdin_break, - fsysdep_stdin_set, fsysdep_stdin_chat, isysdep_stdin_baud }, - { fsysdep_modem_lock, fsysdep_modem_open, fsysdep_modem_close, - fsysdep_modem_reset, fmodem_dial, fsysdep_modem_read, - fsysdep_modem_write, fsysdep_modem_io, fsysdep_modem_break, - fsysdep_modem_set, fsysdep_modem_chat, isysdep_modem_baud }, - { fsysdep_direct_lock, fsysdep_direct_open, fsysdep_direct_close, - fsysdep_direct_reset, NULL, fsysdep_direct_read, - fsysdep_direct_write, fsysdep_direct_io, fsysdep_direct_break, - fsysdep_direct_set, fsysdep_direct_chat, isysdep_direct_baud }, -#if HAVE_TCP - { ftcp_lock, ftcp_open, ftcp_close, - ftcp_reset, ftcp_dial, fsysdep_tcp_read, - fsysdep_tcp_write, fsysdep_tcp_io, NULL, - NULL, fsysdep_tcp_chat, itcp_baud }, -#endif /* HAVE_TCP */ -}; - -/* Port dispatch routines. These could probably become macros, - although the port argument would have to be evaluated twice. */ - -/* Lock a port. */ - -boolean -fport_lock (qport, fin) - struct sport *qport; - boolean fin; -{ - return (*asPortcmds[(int) qport->ttype].pflock) (qport, fin); -} - -/* The port structure we use when opening standard input as a port. */ - -static struct sport sPstdin = -{ - "stdin", - PORTTYPE_STDIN, - NULL, - 0, - NULL, - 0, - NULL -}; - -/* Open a port. */ - -boolean -fport_open (qport, ibaud, ihighbaud, fwait) - struct sport *qport; - 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 (qport == NULL) - ulog (LOG_DEBUG, "fport_open: Opening stdin port (%s)", - abspeed); - else if (qport->zname == NULL) - ulog (LOG_DEBUG, "fport_open: Opening unnamed port (%s)", - abspeed); - else - ulog (LOG_DEBUG, "fport_open: Opening port %s (%s)", - qport->zname, abspeed); - } -#endif - - if (qport == NULL) - { - qport = &sPstdin; - SYSDEP_STDIN_INIT (&qport->u.sstdin.s); - } - qPort = NULL; - - /* If the system provides a range of baud rates, we select the - highest baud rate supported by the port. */ - if (ihighbaud != 0) - { - ibaud = ihighbaud; - if (qport->ttype == PORTTYPE_MODEM) - { - if (qport->u.smodem.ihighbaud != 0) - { - if (qport->u.smodem.ihighbaud < ihighbaud) - ibaud = qport->u.smodem.ihighbaud; - } - else if (qport->u.smodem.ibaud != 0) - ibaud = qport->u.smodem.ibaud; - } - else if (qport->ttype == PORTTYPE_DIRECT) - { - if (qport->u.sdirect.ibaud != 0) - ibaud = qport->u.sdirect.ibaud; - } - } - - /* This will normally be overridden by the port specific open - routine. */ - ulog_device (qport->zname); - - fret = (*asPortcmds[(int) qport->ttype].pfopen) (qport, ibaud, fwait); - if (fret) - qPort = qport; - else - ulog_device ((const char *) NULL); - return fret; -} - -/* Close and unlock the port. */ - -boolean -fport_close (fsuccess) - boolean fsuccess; -{ - boolean fret; - - if (qPort == NULL) - return TRUE; - - DEBUG_MESSAGE0 (DEBUG_PORT, "fport_close: Closing port"); - - fret = (*asPortcmds[(int) qPort->ttype].pfclose) (qPort, fsuccess); - qPort = NULL; - ulog_device ((const char *) NULL); - return fret; -} - -/* Reset the port. */ - -boolean -fport_reset () -{ - DEBUG_MESSAGE0 (DEBUG_PORT, "fport_reset: Resetting port"); - - return (*asPortcmds[(int) qPort->ttype].pfreset) (qPort); -} - -/* Dial out on the port. */ - -boolean -fport_dial (qsys, pcproto_params, pqproto_params, pireliable) - const struct ssysteminfo *qsys; - int *pcproto_params; - struct sproto_param **pqproto_params; - int *pireliable; -{ - boolean (*pfdial) P((struct sport *, const struct ssysteminfo *, - int *, struct sproto_param **, int *)); - - pfdial = asPortcmds[(int) qPort->ttype].pfdial; - if (pfdial == NULL) - { - *pcproto_params = 0; - *pqproto_params = NULL; - *pireliable = 0; - return TRUE; - } - return (*pfdial) (qPort, qsys, pcproto_params, pqproto_params, - pireliable); -} - -/* Read data from the port. */ - -boolean -fport_read (zbuf, pclen, cmin, ctimeout, freport) - char *zbuf; - int *pclen; - int cmin; - int ctimeout; - boolean freport; -{ - boolean fret; - - fret = (*asPortcmds[(int) qPort->ttype].pfread) (qPort, zbuf, pclen, - cmin, ctimeout, - freport); -#if DEBUG > 1 - if (FDEBUGGING (DEBUG_INCOMING)) - udebug_buffer ("fport_read: Read", zbuf, *pclen); - else if (FDEBUGGING (DEBUG_PORT)) - ulog (LOG_DEBUG, "fport_read: Read %d", *pclen); -#endif - - return fret; -} - -/* Write data to the port. */ - -boolean -fport_write (zbuf, clen) - const char *zbuf; - int clen; -{ -#if DEBUG > 1 - if (FDEBUGGING (DEBUG_OUTGOING)) - udebug_buffer ("fport_write: Writing", zbuf, clen); - else if (FDEBUGGING (DEBUG_PORT)) - ulog (LOG_DEBUG, "fport_write: Writing %d", clen); -#endif - - return (*asPortcmds[(int) qPort->ttype].pfwrite) (qPort, zbuf, clen); -} - -/* Read and write data. */ - -boolean -fport_io (zwrite, pcwrite, zread, pcread) - const char *zwrite; - int *pcwrite; - char *zread; - int *pcread; -{ - boolean fret; -#if DEBUG > 1 - int cwrite = *pcwrite; - int cread = *pcread; - - if (cread <= 0 || cwrite <= 0) - ulog (LOG_FATAL, "fport_io: cread %d; cwrite %d", cread, cwrite); -#endif - -#if DEBUG > 1 - if (FDEBUGGING (DEBUG_OUTGOING)) - udebug_buffer ("fport_io: Writing", zwrite, cwrite); -#endif - - fret = (*asPortcmds[(int) qPort->ttype].pfio) (qPort, zwrite, pcwrite, - zread, pcread); - - DEBUG_MESSAGE4 (DEBUG_PORT, - "fport_io: Wrote %d of %d, read %d of %d", - *pcwrite, cwrite, *pcread, cread); - -#if DEBUG > 1 - if (*pcread > 0 && FDEBUGGING (DEBUG_INCOMING)) - udebug_buffer ("fport_io: Read", zread, *pcread); -#endif - - return fret; -} - -/* Send a break character to a port. Some port types may not support - break characters, in which case we just return TRUE. */ - -boolean -fport_break () -{ - boolean (*pfbreak) P((struct sport *)); - - DEBUG_MESSAGE0 (DEBUG_PORT, "fport_break: Sending break character"); - - pfbreak = asPortcmds[(int) qPort->ttype].pfbreak; - if (pfbreak == NULL) - return TRUE; - return (*pfbreak) (qPort); -} - -/* Change the setting of a port. Some port types may not support - this, in which case we just return TRUE. */ - -boolean -fport_set (tset) - enum tportsetting tset; -{ - boolean (*pfset) P((struct sport *, enum tportsetting)); - - DEBUG_MESSAGE1 (DEBUG_PORT, - "fport_set: Changing setting to %d", (int) tset); - - pfset = asPortcmds[(int) qPort->ttype].pfset; - if (pfset == NULL) - return TRUE; - return (*pfset) (qPort, tset); -} - -/* Run a chat program on a port. */ - -boolean -fport_run_chat (zprog) - const char *zprog; -{ - return (*asPortcmds[(int) qPort->ttype].pfchat) (qPort, zprog); -} - -/* Get the baud rate of a port. */ - -long -iport_baud () -{ - return (*asPortcmds[(int) qPort->ttype].pibaud) (qPort); -} - -/* Modem dialing routines. */ - -static boolean fpdo_dial P((struct sdialer *qdial, const char *zphone, - boolean ftranslate)); - -boolean -fmodem_dial (qport, qsys, pcproto_params, pqproto_params, pireliable) - struct sport *qport; - const struct ssysteminfo *qsys; - int *pcproto_params; - struct sproto_param **pqproto_params; - int *pireliable; -{ - if (qport->u.smodem.zdialer != NULL) - { - char *zcopy, *zdialer; - boolean ffirst; - - /* The zdialer string 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; - *pcproto_params = 0; - *pqproto_params = NULL; - *pireliable = 0; - - zcopy = (char *) alloca (strlen (qport->u.smodem.zdialer) + 1); - strcpy (zcopy, qport->u.smodem.zdialer); - - zdialer = strtok (zcopy, " \t"); - while (zdialer != NULL) - { - struct sdialer s; - char *ztoken; - boolean ftranslate, ftoken; - - if (! fread_dialer_info (zdialer, &s)) - return FALSE; - - ztoken = strtok ((char *) NULL, " \t"); - ftoken = ztoken != NULL; - - ftranslate = FALSE; - if (ztoken == NULL - || strcmp (ztoken, "\\D") == 0) - ztoken = qsys->zphone; - else if (strcmp (ztoken, "\\T") == 0) - { - ztoken = qsys->zphone; - ftranslate = TRUE; - } - - /* Perhaps we should accumulate the protocol parameters. */ - if (ffirst) - { - *pcproto_params = s.cproto_params; - *pqproto_params = s.qproto_params; - *pireliable = s.ireliable; - ffirst = FALSE; - } - - if (! fpdo_dial (&s, ztoken, ftranslate)) - return FALSE; - - if (! ftoken) - zdialer = NULL; - else - zdialer = strtok ((char *) NULL, " \t"); - } - - return TRUE; - } - else if (qport->u.smodem.qdialer != NULL) - { - *pcproto_params = qport->u.smodem.qdialer->cproto_params; - *pqproto_params = qport->u.smodem.qdialer->qproto_params; - *pireliable = qport->u.smodem.qdialer->ireliable; - return fpdo_dial (qport->u.smodem.qdialer, qsys->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 -fpdo_dial (qdial, zphone, ftranslate) - struct sdialer *qdial; - const char *zphone; - boolean ftranslate; -{ - if (! fsysdep_modem_begin_dial (qPort, qdial)) - return FALSE; - - if (! fchat (&qdial->schat, (const struct ssysteminfo *) NULL, qdial, - zphone, ftranslate, qPort->zname, iport_baud ())) - return FALSE; - - return fsysdep_modem_end_dial (qPort, qdial); -} - -/* Permit no carrier from a port. */ - -boolean -fport_no_carrier () -{ - return fsysdep_modem_no_carrier (qPort); -} - -/* Require carrier from a port. */ - -boolean -fport_need_carrier () -{ - return fsysdep_modem_need_carrier (qPort); -} diff --git a/gnu/libexec/uucp/port.h b/gnu/libexec/uucp/port.h deleted file mode 100644 index 00e940116f8..00000000000 --- a/gnu/libexec/uucp/port.h +++ /dev/null @@ -1,509 +0,0 @@ -/* port.h - Header file for routines which manipulate ports. - - 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 AIRS, P.O. Box 520, Waltham, MA 02254. - - $Id: port.h,v 1.2 1993/08/02 17:25:09 mycroft Exp $ -*/ - -#ifndef PORT_H - -#define PORT_H - -#include "sysdep.h" - -/* Information kept about using stdin as a port. */ - -struct sstdin_port -{ - struct ssysdep_stdin_port s; -}; - -/* The smodem_port structure holds the information we keep about a modem - port. */ - -struct smodem_port -{ - /* The device name. If NULL, use the port name instead. */ - const char *zdevice; - /* The device name to output dialer instructions to. If NULL, use - the normal port. */ - const char *zdial_device; - /* The default baud rate. */ - long ibaud; - /* The low baud rate, if a range is used. */ - long ilowbaud; - /* The high baud rate, if a range is used. */ - long ihighbaud; - /* Whether to wait for carrier detect after dialing. */ - boolean fcarrier; - /* The name of the dialer to use. */ - const char *zdialer; - /* Specific dialer information, if zdialer is NULL. */ - struct sdialer *qdialer; - /* System dependent modem port stuff. */ - struct ssysdep_modem_port s; -}; - -/* Information kept about a direct port. */ - -struct sdirect_port -{ - /* The device to use (if NULL, use the port name). */ - const char *zdevice; - /* The baud rate to communicate at. */ - long ibaud; - /* System dependent direct port stuff. */ - struct ssysdep_direct_port s; -}; - -#if HAVE_TCP - -/* Information kept about a TCP port. */ - -struct stcp_port -{ - /* The file descriptor. */ - int o; - /* The TCP port number to use. */ - const char *zport; -}; - -#endif /* HAVE_TCP */ - -/* Types of ports. The order of this enumeration must be the same - as the initializer for asPortcmds and azPtype_names. */ - -enum tporttype -{ - PORTTYPE_STDIN, - PORTTYPE_MODEM, - PORTTYPE_DIRECT -#if HAVE_TCP - , PORTTYPE_TCP -#endif -}; - -/* Port settings. Currently we only have seven bit and eight bit - ports. The only real difference between these is that seven bit - ports can do XON/XOFF. */ - -enum tportsetting -{ - PORTSETTING_EIGHT, - PORTSETTING_SEVEN -}; - -/* Reliability bits. 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. Of course, this can always be overridden by - using the ``protocols'' command in the system file. Reliability - bits can be specified by both ports and dialers. */ - -/* Whether a set of reliability bits is given (0 means no - information). */ -#define RELIABLE_SPECIFIED (01) - -/* Whether the connection is eight bit transparent. */ -#define RELIABLE_EIGHT (02) - -/* Whether the connection is error-free. */ -#define RELIABLE_RELIABLE (04) - -/* Whether the connection is end-to-end reliable (e.g. TCP). */ -#define RELIABLE_ENDTOEND (010) - -/* Information kept about a port. */ - -struct sport -{ - /* The name of the port. */ - const char *zname; - /* The type of the port. */ - enum tporttype ttype; - /* The protocol string for the port. */ - const char *zprotocols; - /* The number of protocol parameter entries. */ - int cproto_params; - /* The protocol parameter string. */ - struct sproto_param *qproto_params; - /* The set of reliability bits. */ - int ireliable; - /* The lock file name to use. */ - const char *zlockname; - /* The type specific information. */ - union - { - struct sstdin_port sstdin; - struct smodem_port smodem; - struct sdirect_port sdirect; -#if HAVE_TCP - struct stcp_port stcp; -#endif - } u; -}; - -/* Information kept about a dialer. */ - -struct sdialer -{ - /* The name. */ - const char *zname; - /* Chat script. */ - struct schat_info schat; - /* The ``wait for dialtone'' string. */ - const char *zdialtone; - /* The ``pause'' string. */ - const char *zpause; - /* Whether the dialer supports carrier. */ - boolean fcarrier; - /* How many seconds to wait for carrier (if fcarrier TRUE). */ - int ccarrier_wait; - /* Whether to toggle DTR. */ - boolean fdtr_toggle; - /* Whether to wait after toggling DTR. */ - boolean fdtr_toggle_wait; - /* The chat script to use when a call is complete. */ - struct schat_info scomplete; - /* The chat script to use when a call is aborted. */ - struct schat_info sabort; - /* Number of protocol parameters. */ - int cproto_params; - /* The protocol parameters. */ - struct sproto_param *qproto_params; - /* The set of reliability bits. */ - int ireliable; -}; - -/* A command table holds the functions which implement actions for - each different kind of port. */ - -struct sportcmds -{ - /* Lock the port. The fin argument is TRUE if the port is to be - used for an incoming call, FALSE for an outgoing call. */ - boolean (*pflock) P((struct sport *qport, boolean fin)); - /* Open the port. */ - boolean (*pfopen) P((struct sport *qport, long ibaud, - boolean fwait)); - /* Close the port. */ - boolean (*pfclose) P((struct sport *qport, boolean fsuccess)); - /* Reset the port so that another call may be accepted. */ - boolean (*pfreset) P((struct sport *qport)); - /* Dial a number on a port (may be NULL). This set *pcproto_params - and *pqproto_params to the protocol parameters of the dialer, if - any, and *pireliable to the reliable code of the dialer (a hack - to avoid reading dialer information twice). */ - boolean (*pfdial) P((struct sport *qport, const struct ssysteminfo *qsys, - int *pcproto_params, - struct sproto_param **pqproto_params, - int *pireliable)); - /* Read data from the port, 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 sport *qport, char *zbuf, int *pclen, - int cmin, int ctimeout, boolean freport)); - /* Write data to the port. */ - boolean (*pfwrite) P((struct sport *qport, const char *zbuf, - int clen)); - /* Read and write data to the port. 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 sport *qport, const char *zwrite, - int *pcwrite, char *zread, int *pcread)); - /* Send a break character. This may be NULL. */ - boolean (*pfbreak) P((struct sport *qport)); - /* Change the port setting. This may be NULL. */ - boolean (*pfset) P((struct sport *qport, enum tportsetting tset)); - /* Run a chat program on a port. */ - boolean (*pfchat) P((struct sport *qport, const char *zprog)); - /* Get the baud rate of a port. */ - long (*pibaud) P((struct sport *qport)); -}; - -/* Only one port can be open during an execution of uucico, and we - keep it in this global variable. */ - -extern struct sport *qPort; - -/* The table of port functions. The order of entries in this table - must match the tporttype enumeration. */ - -extern const struct sportcmds asPortcmds[]; - -/* Port functions. */ - -/* Process a port command. The pvar argument should point to a pointer - to type struct sport. */ -extern enum tcmdtabret tprocess_port_cmd P((int cargs, char **azargs, - pointer pvar, const char *zerr)); - -/* Read dialer information. */ -extern boolean fread_dialer_info P((const char *zdialer, - struct sdialer *qdialer)); - -#if HAVE_V2_CONFIG -/* Read information from the V2 configuration files. */ - -extern boolean fv2_find_port P((const char *zname, long ibaud, - long ihighbaud, struct sport *qport, - boolean (*pflock) P((struct sport *, - boolean fin)), - boolean *pffound)); -#endif /* HAVE_V2_CONFIG */ - -#if HAVE_BNU_CONFIG -/* Read information from the BNU configuration files. */ - -extern boolean fbnu_find_port P((const char *zname, long ibaud, - long ihighbaud, struct sport *qport, - boolean (*pflock) P((struct sport *, - boolean fin)), - boolean *pffound)); -extern boolean fbnu_read_dialer_info P((const char *zdialer, - struct sdialer *qdialer)); -#endif /* HAVE_BNU_CONFIG */ - -/* Lock a port. 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 fport_lock P((struct sport *qport, boolean fin)); - -/* Find and lock a port. If the port name is NULL, the matching is - done only on the baud rate. If the baud rate is 0, the matching is - done only on the port name. Otherwise the port must match both - name and baud rate. If ihighbaud is not 0, the baud rate of the - port must fall between ibaud and ihighbaud. */ -extern boolean ffind_port P((const char *zname, long ibaud, - long ihighbaud, struct sport *qport, - boolean (*pflock) P((struct sport *, - boolean fin)), - boolean freport)); - -/* Open a port. If ibaud is 0, the natural baud rate of the port is - used. If ihighbaud is not 0, fport_open figures out what baud rate - to use based on the port's baud rate. */ -extern boolean fport_open P((struct sport *qport, long ibaud, - long ihighbaud, boolean fwait)); - -/* Close and unlock a port. The fsuccess argument is TRUE if the - conversation on the port was completed normally, FALSE if it is - being aborted. */ -extern boolean fport_close P((boolean fsuccess)); - -/* Reset a port such that another call may be accepted. */ -extern boolean fport_reset P((void)); - -/* Dial out on a port. This is permitted to return a set of protocol - parameters and reliability bits for the dialer (yes, it's a hack; - this permits protocol parameters to set for particular modems). */ -extern boolean fport_dial P((const struct ssysteminfo *qsys, - int *pcproto_params, - struct sproto_param **pqproto_params, - int *pireliable)); - -/* Read from a port. - 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 fport_read P((char *zbuf, int *pclen, int cmin, - int ctimeout, boolean freport)); - -/* Write to a port. */ -extern boolean fport_write P((const char *zbuf, int cbytes)); - -/* Read and write to a port. 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 fport_io P((const char *zwrite, int *pcwrite, - char *zread, int *pcread)); - -/* Send a break character to a port. */ -extern boolean fport_break P((void)); - -/* Change the settings of a port. */ -extern boolean fport_set P((enum tportsetting tset)); - -/* Get the baud rate of a port. */ -extern long iport_baud P((void)); - -/* Do a chat script with a system. */ -extern boolean fchat P((const struct schat_info *qchat, - const struct ssysteminfo *qsys, - const struct sdialer *qdial, - const char *zphone, boolean ftranslate, - const char *zport, long ibaud)); - -/* Allow no carrier during a chat script. */ -extern boolean fport_no_carrier P((void)); - -/* Require carrier during a chat script. */ -extern boolean fport_need_carrier P((void)); - -/* Run a chat program on a port. */ -extern boolean fport_run_chat P((const char *zprog)); - -/* Modem routines used when dialing. */ - -/* 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 sport *qport, - struct sdialer *qdial)); - -/* Tell the modem to ignore carrier. This is called when \M is - encountered in a dialer chat script. It should return FALSE on - error. */ -extern boolean fsysdep_modem_no_carrier P((struct sport *qport)); - -/* Tell the modem that carrier is required. This is called when \m is - encountered in a dialer chat script. It should return FALSE on - error. */ -extern boolean fsysdep_modem_need_carrier P((struct sport *qport)); - -/* 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 port 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 sport *qport, - struct sdialer *qdial)); - -/* Port routines for stdin ports. */ - -extern boolean fsysdep_stdin_lock P((struct sport *qport, boolean fin)); -extern boolean fsysdep_stdin_open P((struct sport *qport, long ibaud, - boolean fwait)); -extern boolean fsysdep_stdin_close P((struct sport *qport, - boolean fsuccess)); -extern boolean fsysdep_stdin_reset P((struct sport *qport)); -extern boolean fsysdep_stdin_read P((struct sport *qport, char *zread, - int *pcread, int cmin, - int ctimeout, boolean freport)); -extern boolean fsysdep_stdin_write P((struct sport *qport, - const char *zwrite, int cwrite)); -extern boolean fsysdep_stdin_io P((struct sport *qport, - const char *zwrite, int *pcwrite, - char *zread, int *pcread)); -extern boolean fsysdep_stdin_break P((struct sport *qport)); -extern boolean fsysdep_stdin_set P((struct sport *qport, - enum tportsetting tset)); -extern boolean fsysdep_stdin_chat P((struct sport *qport, - const char *zprog)); -extern long isysdep_stdin_baud P((struct sport *qport)); - -/* Port routines for modem ports. */ - -extern boolean fsysdep_modem_lock P((struct sport *qport, boolean fin)); -extern boolean fsysdep_modem_open P((struct sport *qport, long ibaud, - boolean fwait)); -extern boolean fsysdep_modem_close P((struct sport *qport, - boolean fsuccess)); -extern boolean fsysdep_modem_reset P((struct sport *qport)); -extern boolean fmodem_dial P((struct sport *qport, - const struct ssysteminfo *qsys, - int *pcproto_params, - struct sproto_param **pqproto_params, - int *pireliable)); -extern boolean fsysdep_modem_read P((struct sport *qport, char *zread, - int *pcread, int cmin, - int ctimeout, boolean freport)); -extern boolean fsysdep_modem_write P((struct sport *qport, - const char *zwrite, int cwrite)); -extern boolean fsysdep_modem_io P((struct sport *qport, - const char *zwrite, int *pcwrite, - char *zread, int *pcread)); -extern boolean fsysdep_modem_break P((struct sport *qport)); -extern boolean fsysdep_modem_set P((struct sport *qport, - enum tportsetting tset)); -extern boolean fsysdep_modem_chat P((struct sport *qport, - const char *zprog)); -extern long isysdep_modem_baud P((struct sport *qport)); - -/* Port routines for direct connections. */ - -extern boolean fsysdep_direct_lock P((struct sport *qport, boolean fin)); -extern boolean fsysdep_direct_open P((struct sport *qport, long ibaud, - boolean fwait)); -extern boolean fsysdep_direct_close P((struct sport *qport, - boolean fsuccess)); -extern boolean fsysdep_direct_reset P((struct sport *qport)); -extern boolean fsysdep_direct_read P((struct sport *qport, char *zread, - int *pcread, int cmin, - int ctimeout, boolean freport)); -extern boolean fsysdep_direct_write P((struct sport *qport, - const char *zwrite, int cwrite)); -extern boolean fsysdep_direct_io P((struct sport *qport, - const char *zwrite, int *pcwrite, - char *zread, int *pcread)); -extern boolean fsysdep_direct_break P((struct sport *qport)); -extern boolean fsysdep_direct_set P((struct sport *qport, - enum tportsetting tset)); -extern boolean fsysdep_direct_chat P((struct sport *qport, - const char *zprog)); -extern long isysdep_direct_baud P((struct sport *qport)); - -#if HAVE_TCP - -/* Port routines for TCP ports. */ - -extern boolean ftcp_lock P((struct sport *qport, boolean fin)); -extern boolean ftcp_open P((struct sport *qport, long ibaud, - boolean fwait)); -extern boolean ftcp_close P((struct sport *qport, boolean fsuccess)); -extern boolean ftcp_reset P((struct sport *qport)); -extern boolean ftcp_dial P((struct sport *qport, - const struct ssysteminfo *qsys, - int *pcproto_params, - struct sproto_param **pqproto_params, - int *pireliable)); -extern boolean fsysdep_tcp_read P((struct sport *qport, char *zread, - int *pcread, int cmin, - int ctimeout, boolean freport)); -extern boolean fsysdep_tcp_write P((struct sport *qport, - const char *zwrite, int cwrite)); -extern boolean fsysdep_tcp_io P((struct sport *qport, - const char *zwrite, int *pcwrite, - char *zread, int *pcread)); -extern boolean fsysdep_tcp_chat P((struct sport *qport, - const char *zprog)); -extern long itcp_baud P((struct sport *qport)); - -#endif /* HAVE_TCP */ - -#endif diff --git a/gnu/libexec/uucp/prot.c b/gnu/libexec/uucp/prot.c deleted file mode 100644 index 155a9cb459d..00000000000 --- a/gnu/libexec/uucp/prot.c +++ /dev/null @@ -1,1255 +0,0 @@ -/* 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 AIRS, P.O. Box 520, Waltham, MA 02254. - - $Log: prot.c,v $ - Revision 1.1.1.1 1993/03/21 09:45:37 cgd - initial import of 386bsd-0.1 sources - - Revision 1.21 1992/04/02 22:51:09 ian - Add gcc 2.0 format checking to ulog, and fixed discovered problems - - Revision 1.20 1992/03/30 04:49:10 ian - Niels Baggesen: added debugging types abnormal and uucp-proto - - Revision 1.19 1992/03/30 04:07:13 ian - Dirk Musstopf: remove temporary file if receive fails - - Revision 1.18 1992/03/13 22:59:25 ian - Have breceive_char go through freceive_data - - Revision 1.17 1992/03/12 19:56:10 ian - Debugging based on types rather than number - - Revision 1.16 1992/03/11 01:18:15 ian - Niels Baggesen: drop the connection on a write failure - - Revision 1.15 1992/03/11 00:18:50 ian - Save temporary file if file send fails - - Revision 1.14 1992/02/09 05:21:55 ian - Bob Denny: call fmail_transfer before fsysdep_did_work - - Revision 1.13 1992/02/08 19:41:24 ian - Simplify pffile calls for ancient stupid compilers - - Revision 1.12 1992/02/08 03:54:18 ian - Include <string.h> only in <uucp.h>, added 1992 copyright - - Revision 1.11 1992/01/18 22:48:53 ian - Reworked sending of mail and general handling of failed transfers - - Revision 1.10 1992/01/16 18:16:58 ian - Niels Baggesen: add some debugging messages - - Revision 1.9 1991/12/31 19:34:19 ian - Added number of bytes to pffile protocol entry point - - Revision 1.8 1991/12/30 04:28:30 ian - John Theus: check for EOF to work around bug in fread - - Revision 1.7 1991/12/21 23:10:43 ian - Terry Gardner: record failed file transfers in statistics file - - Revision 1.6 1991/12/13 04:33:38 ian - Franc,ois Pinard: don't bother to warn if the final HY doesn't come in - - Revision 1.5 1991/11/15 21:00:59 ian - Efficiency hacks for 'f' and 't' protocols - - Revision 1.4 1991/11/11 19:32:03 ian - Added breceive_char to read characters through protocol buffering - - Revision 1.3 1991/11/11 04:21:16 ian - Added 'f' protocol - - Revision 1.2 1991/11/10 19:24:22 ian - Added pffile protocol entry point for file level control - - Revision 1.1 1991/11/09 18:51:50 ian - Initial revision - - */ - -#include "uucp.h" - -#if USE_RCS_ID -char prot_rcsid[] = "$Id: prot.c,v 1.1.1.1 1993/03/21 09:45:37 cgd Exp $"; -#endif - -#include <errno.h> - -#include "system.h" -#include "port.h" -#include "prot.h" - -/* This file implements the generic UUCP protocol for making and - confirming file transfer requests. This involves sending ASCII - strings back and forth between the communicating daemons. It would - be possible to use a different scheme when designing a new - protocol, but this scheme is used by all traditional UUCP - protocols. */ - -/* Local functions. */ - -static boolean fpsendfile_confirm P((void)); -static boolean fprecfile_confirm P((void)); -static boolean fploop P((void)); -static void upadd_cmd P((const char *z, int clen, boolean flast)); - -/* Variables visible to the protocol-specific routines. */ - -/* Protocol structure. */ -const struct sprotocol *qProto; - -/* 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; - -/* Whether an unexpected shutdown is OK now; this is used to avoid - giving a warning for systems that hang up in a hurry. */ -boolean fPerror_ok; - -/* Amount of data sent for current send file; -1 means there is no - current send file. */ -static long cPsent_bytes = -1; - -/* Amount of data received for current receive file; -1 means there is - no current receive file. */ -static long cPreceived_bytes = -1; - -/* Send a file. If we are the master, we must send a command to - transfer the file and wait for a confirmation that we can begin - sending the file. If we are the slave, the master has sent us a - command and is waiting for a reply; we must confirm that we will - send the file. Either way, we begin transferring data. - - This function returns FALSE if there is a communication failure. - It returns TRUE otherwise, even if the file transfer failed. */ - -boolean -fsend_file (fmaster, e, qcmd, zmail, ztosys, fnew) - boolean fmaster; - openfile_t e; - const struct scmd *qcmd; - const char *zmail; - const char *ztosys; - boolean fnew; -{ - if (fmaster) - { - int clen; - char *zsend; - const char *zrec; - - /* Send the string - S zfrom zto zuser zoptions ztemp imode znotify - to the remote system. We put a '-' in front of the (possibly - empty) options and a '0' in front of the mode. The remote - system will ignore ztemp, but it is supposed to be sent anyhow. - If fnew is TRUE, we also send the size; in this case if ztemp - is empty we must send it as "". */ - clen = (strlen (qcmd->zfrom) + strlen (qcmd->zto) - + strlen (qcmd->zuser) + strlen (qcmd->zoptions) - + strlen (qcmd->ztemp) + strlen (qcmd->znotify) - + 50); - zsend = (char *) alloca (clen); - if (! fnew) - sprintf (zsend, "S %s %s %s -%s %s 0%o %s", qcmd->zfrom, qcmd->zto, - qcmd->zuser, qcmd->zoptions, qcmd->ztemp, qcmd->imode, - qcmd->znotify); - else - { - const char *znotify; - - if (qcmd->znotify[0] != '\0') - znotify = qcmd->znotify; - else - znotify = "\"\""; - sprintf (zsend, "S %s %s %s -%s %s 0%o %s %ld", qcmd->zfrom, - qcmd->zto, qcmd->zuser, qcmd->zoptions, qcmd->ztemp, - qcmd->imode, znotify, qcmd->cbytes); - } - - if (! (qProto->pfsendcmd) (zsend)) - { - (void) ffileclose (e); - return FALSE; - } - - /* Now we must await a reply. */ - - zrec = zgetcmd (); - if (zrec == NULL) - { - (void) ffileclose (e); - return FALSE; - } - - if (zrec[0] != 'S' - || (zrec[1] != 'Y' && zrec[1] != 'N')) - { - ulog (LOG_ERROR, "Bad response to send request"); - (void) ffileclose (e); - return FALSE; - } - - if (zrec[1] == 'N') - { - const char *zerr; - boolean fnever; - - fnever = TRUE; - if (zrec[2] == '2') - zerr = "permission denied"; - else if (zrec[2] == '4') - { - zerr = "remote cannot create work files"; - fnever = FALSE; - } - else if (zrec[2] == '6') - { - zerr = "too large for receiver now"; - fnever = FALSE; - } - else if (zrec[2] == '7') - { - /* The file is too large to ever send. */ - zerr = "too large for receiver"; - } - else - { - char *zset; - - zset = (char *) alloca (sizeof "unknown reason: " - + strlen (zrec)); - sprintf (zset, "unknown reason: %s", zrec); - zerr = zset; - } - - ulog (LOG_ERROR, "Can't send %s: %s", qcmd->zfrom, zerr); - (void) ffileclose (e); - if (fnever) - { - (void) fmail_transfer (FALSE, qcmd->zuser, zmail, zerr, - qcmd->zfrom, zLocalname, - qcmd->zto, ztosys, - zsysdep_save_temp_file (qcmd->pseq)); - (void) fsysdep_did_work (qcmd->pseq); - } - return TRUE; - } - } - else - { - char absend[20]; - - /* We are the slave; confirm that we will send the file. We - send the file mode in the confirmation string. */ - - sprintf (absend, "RY 0%o", qcmd->imode); - - if (! (qProto->pfsendcmd) (absend)) - { - (void) ffileclose (e); - return FALSE; - } - } - - /* Record the file we are sending, and let the protocol take over. */ - - if (! fstore_sendfile (e, qcmd->pseq, qcmd->zfrom, qcmd->zto, ztosys, - qcmd->zuser, zmail)) - return FALSE; - - cPsent_bytes = 0; - - /* Tell the protocol that we are starting to send a file. */ - if (qProto->pffile != NULL) - { - boolean (*pffile) P((boolean, boolean, boolean *, long)); - - /* Simplify expression for ancient compilers. */ - pffile = qProto->pffile; - if (! pffile (TRUE, TRUE, (boolean *) NULL, qcmd->cbytes)) - return FALSE; - } - - return fploop (); -} - -/* Confirm that a file has been received correctly by the other side. - Return FALSE for a communication error. We expect the receiving - system to send back CY; if an error occurred while moving the - received file into its final location, the receiving system will - send back CN5. */ - -static boolean -fpsendfile_confirm () -{ - const char *zrec; - long cbytes; - const char *zerr; - - zrec = zgetcmd (); - if (zrec == NULL) - return FALSE; - - cbytes = cPsent_bytes; - cPsent_bytes = -1; - - if (zrec[0] != 'C' - || (zrec[1] != 'Y' && zrec[1] != 'N')) - { - zerr = "Bad confirmation for sent file"; - ulog (LOG_ERROR, zerr); - (void) fsent_file (FALSE, cbytes, zerr, FALSE); - } - else if (zrec[1] == 'N') - { - if (zrec[2] == '5') - zerr = "File could not be stored in final location"; - else - { - char *zset; - - zset = (char *) alloca (sizeof "File send failed: " + strlen (zrec)); - sprintf (zset, "File send failed: %s", zrec); - zerr = zset; - } - ulog (LOG_ERROR, zerr); - (void) fsent_file (FALSE, cbytes, zerr, TRUE); - } - else - (void) fsent_file (TRUE, cbytes, (const char *) NULL, FALSE); - - return TRUE; -} - -/* Receive a file. If we are the master, we must set up a file - request and wait for the other side to confirm it. If we are the - slave, we must confirm a request made by the other side. We then - start receiving the file. - - This function must return FALSE if there is a communication error - and TRUE otherwise. We return TRUE even if the file transfer - fails. */ - -boolean -freceive_file (fmaster, e, qcmd, zmail, zfromsys, fnew) - boolean fmaster; - openfile_t e; - const struct scmd *qcmd; - const char *zmail; - const char *zfromsys; - boolean fnew; -{ - unsigned int imode; - - if (fmaster) - { - int clen; - char *zsend; - const char *zrec; - - /* We send the string - R from to user options - We put a dash in front of options. If we are talking to a - counterpart, we also send the maximum size file we are - prepared to accept, as returned by esysdep_open_receive. */ - - clen = (strlen (qcmd->zfrom) + strlen (qcmd->zto) - + strlen (qcmd->zuser) + strlen (qcmd->zoptions) + 30); - zsend = (char *) alloca (clen); - - if (! fnew) - sprintf (zsend, "R %s %s %s -%s", qcmd->zfrom, qcmd->zto, - qcmd->zuser, qcmd->zoptions); - else - sprintf (zsend, "R %s %s %s -%s %ld", qcmd->zfrom, qcmd->zto, - qcmd->zuser, qcmd->zoptions, qcmd->cbytes); - - if (! (qProto->pfsendcmd) (zsend)) - { - (void) ffileclose (e); - (void) remove (qcmd->ztemp); - return FALSE; - } - - /* Wait for a reply. */ - - zrec = zgetcmd (); - if (zrec == NULL) - { - (void) ffileclose (e); - (void) remove (qcmd->ztemp); - return FALSE; - } - - if (zrec[0] != 'R' - || (zrec[1] != 'Y' && zrec[1] != 'N')) - { - ulog (LOG_ERROR, "Bad response to receive request"); - (void) ffileclose (e); - (void) remove (qcmd->ztemp); - return FALSE; - } - - if (zrec[1] == 'N') - { - const char *zerr; - - if (zrec[2] == '2') - zerr = "no such file"; - else if (zrec[2] == '6') - { - /* We sent over the maximum file size we were prepared - to receive, and the remote system is telling us that - the file is larger than that. Try again later. It - would be better if we could know whether there will - ever be enough room. */ - ulog (LOG_ERROR, "Can't receive %s: too large", - qcmd->zfrom); - (void) ffileclose (e); - (void) remove (qcmd->ztemp); - return TRUE; - } - else - { - char *zset; - - zset = (char *) alloca (sizeof "unknown reason: " - + strlen (zrec)); - sprintf (zset, "unknown reason: %s", zrec); - zerr = zset; - } - ulog (LOG_ERROR, "Can't receive %s: %s", qcmd->zfrom, zerr); - (void) ffileclose (e); - (void) remove (qcmd->ztemp); - (void) fmail_transfer (FALSE, qcmd->zuser, zmail, zerr, - qcmd->zfrom, zfromsys, - qcmd->zto, zLocalname, - (const char *) NULL); - (void) fsysdep_did_work (qcmd->pseq); - return TRUE; - } - - /* The mode should have been sent as "RY 0%o". If it wasn't, - we use 0666. */ - imode = (unsigned int) strtol (zrec + 2, (char **) NULL, 8); - if (imode == 0) - imode = 0666; - } - else - { - /* Tell the other system to go ahead and send. */ - - if (! (qProto->pfsendcmd) ("SY")) - { - (void) ffileclose (e); - (void) remove (qcmd->ztemp); - return FALSE; - } - imode = qcmd->imode; - } - - if (! fstore_recfile (e, qcmd->pseq, qcmd->zfrom, qcmd->zto, zfromsys, - qcmd->zuser, imode, zmail, qcmd->ztemp)) - return FALSE; - - cPreceived_bytes = 0; - - /* Tell the protocol that we are starting to receive a file. */ - if (qProto->pffile != NULL) - { - boolean (*pffile) P((boolean, boolean, boolean *, long)); - - /* Simplify expression for ancient compilers. */ - pffile = qProto->pffile; - if (! pffile (TRUE, FALSE, (boolean *) NULL, (long) -1)) - return FALSE; - } - - return fploop (); -} - -/* Confirm that a file was received correctly. */ - -static boolean -fprecfile_confirm () -{ - long cbytes; - - cbytes = cPreceived_bytes; - cPreceived_bytes = -1; - - if (freceived_file (TRUE, cbytes, (const char *) NULL, FALSE)) - return (qProto->pfsendcmd) ("CY"); - else - return (qProto->pfsendcmd) ("CN5"); -} - -/* Send a transfer request. This is only called by the master. It - ignored the pseq entry in the scmd structure. */ - -boolean -fxcmd (qcmd, pfnever) - const struct scmd *qcmd; - boolean *pfnever; -{ - int clen; - char *zsend; - const char *zrec; - - *pfnever = FALSE; - - /* We send the string - X from to user options - We put a dash in front of options. */ - - clen = (strlen (qcmd->zfrom) + strlen (qcmd->zto) - + strlen (qcmd->zuser) + strlen (qcmd->zoptions) + 7); - zsend = (char *) alloca (clen); - - sprintf (zsend, "X %s %s %s -%s", qcmd->zfrom, qcmd->zto, - qcmd->zuser, qcmd->zoptions); - - if (! (qProto->pfsendcmd) (zsend)) - return FALSE; - - /* Wait for a reply. */ - - zrec = zgetcmd (); - if (zrec == NULL) - return FALSE; - - if (zrec[0] != 'X' - || (zrec[1] != 'Y' && zrec[1] != 'N')) - { - ulog (LOG_ERROR, "Bad response to wildcard request"); - return FALSE; - } - - if (zrec[1] == 'N') - { - ulog (LOG_ERROR, "Work request denied"); - *pfnever = TRUE; - return TRUE; - } - - return TRUE; -} - -/* Confirm a transfer request. */ - -boolean -fxcmd_confirm () -{ - return (qProto->pfsendcmd) ("XY"); -} - -/* Signal a file transfer failure to the other side. This is only called - by the slave. */ - -boolean -ftransfer_fail (bcmd, twhy) - int bcmd; - enum tfailure twhy; -{ - const char *z; - - switch (bcmd) - { - case 'S': - switch (twhy) - { - case FAILURE_PERM: - z = "SN2"; - break; - case FAILURE_OPEN: - z = "SN4"; - break; - case FAILURE_SIZE: - z = "SN6"; - break; - default: - z = "SN"; - break; - } - break; - case 'R': - switch (twhy) - { - case FAILURE_PERM: - case FAILURE_OPEN: - z = "RN2"; - break; - case FAILURE_SIZE: - z = "RN6"; - break; - default: - z = "RN"; - break; - } - break; - case 'X': - z = "XN"; - break; - default: -#if DEBUG > 0 - ulog (LOG_ERROR, "ftransfer_fail: Can't happen"); -#endif - return FALSE; - } - - return (qProto->pfsendcmd) (z); -} - -/* Get and parse a command from the other system. Handle hangups - specially. */ - -boolean -fgetcmd (fmaster, qcmd) - boolean fmaster; - struct scmd *qcmd; -{ - static char *z; - static int c; - - while (TRUE) - { - const char *zcmd; - int clen; - - zcmd = zgetcmd (); - if (zcmd == NULL) - return FALSE; - - clen = strlen (zcmd); - if (clen + 1 > c) - { - c = clen + 1; - z = (char *) xrealloc ((pointer) z, c); - } - strcpy (z, zcmd); - - if (! fparse_cmd (z, qcmd)) - continue; - - /* Handle hangup commands specially. If it's just 'H', return - it. If it's 'N', the other side is denying a hangup request - which we can just ignore (since the top level code assumes - that hangup requests are denied). If it's 'Y', the other - side is confirming a hangup request. In this case we confirm - with an "HY", wait for yet another "HY" from the other side, - and then finally shut down the protocol (I don't know why it - works this way, but it does). We then return a 'Y' command - to the top level code. */ - - if (qcmd->bcmd == 'N') - { -#if DEBUG > 0 - if (fmaster) - ulog (LOG_ERROR, "Got hangup reply as master"); -#endif - continue; - } - - if (qcmd->bcmd == 'Y') - { -#if DEBUG > 0 - if (fmaster) - ulog (LOG_ERROR, "Got hangup reply as master"); -#endif - /* Don't check errors rigorously here, since the other side - might jump the gun and hang up. */ - - if (! (qProto->pfsendcmd) ("HY")) - return TRUE; - fPerror_ok = TRUE; - zcmd = zgetcmd (); - fPerror_ok = FALSE; - if (zcmd == NULL) - return TRUE; -#if DEBUG > 1 - if (strcmp (zcmd, "HY") != 0) - DEBUG_MESSAGE1 (DEBUG_UUCP_PROTO | DEBUG_ABNORMAL, - "fgetcmd: Got \"%s\" when expecting \"HY\"", - zcmd); -#endif - (void) (qProto->pfshutdown) (); - return TRUE; - } - - return TRUE; - } - - /*NOTREACHED*/ -} - -/* Hangup. */ - -boolean -fhangup_request () -{ - return (qProto->pfsendcmd) ("H"); -} - -/* Reply to a hangup request. This is only called by the slave. If - fconfirm is TRUE, we are closing down the protocol. We send an HY - message. The master responds with an HY message. We send another - HY message, and then shut down the protocol. */ - -boolean -fhangup_reply (fconfirm) - boolean fconfirm; -{ - if (! fconfirm) - return (qProto->pfsendcmd) ("HN"); - else - { - const char *z; - - if (! (qProto->pfsendcmd) ("HY")) - return FALSE; - - z = zgetcmd (); - if (z == NULL) - return FALSE; - if (strcmp (z, "HY") != 0) - ulog (LOG_ERROR, "Got \"%s\" when expecting \"HY\"", z); - else - { - if (! (qProto->pfsendcmd) ("HY")) - return FALSE; - } - - return (qProto->pfshutdown) (); - } -} - -/* Loop sending and/or receiving data. If there is a file to send, - this will send it until the entire file has been sent or a command - has been received from the remote system or a complete file has - been received from the remote system. Otherwise this will simply - call the protocol to wait until a complete file or command has been - received from the remote system. */ - -static boolean -fploop () -{ - boolean fexit; - - DEBUG_MESSAGE0 (DEBUG_UUCP_PROTO, "fploop: Main protocol loop"); - - if (ffileisopen (eSendfile)) - { - int iend; - - iend = iPrecend; - - while (TRUE) - { - /* We keep sending out packets until we have something - in the receive buffer. */ - while (iend == iPrecend) - { - char *zdata; - int cdata; - - /* Get a packet and fill it with data. */ - - zdata = (qProto->pzgetspace) (&cdata); - if (zdata == NULL) - return FALSE; - - if (ffileeof (eSendfile)) - cdata = 0; - else - { - cdata = cfileread (eSendfile, zdata, cdata); - if (ffilereaderror (eSendfile, cdata)) - { - /* The protocol gives us no way to report a file - sending error, so we just drop the connection. - What else can we do? */ - ulog (LOG_ERROR, "read: %s", strerror (errno)); - usendfile_error (); - return FALSE; - } - } - - if (! (qProto->pfsenddata) (zdata, cdata)) - return FALSE; - - cPsent_bytes += cdata; - - /* If we have reached the end of the file, tell the - protocol that the file is finished (the protocol - could also detect this by looking for zero passed as - the data length to the send data routine, but would - have no convenient way to tell us to redo the file - send). If we are not supposed to redo the file - transfer, wait for confirmation and return out to get - the next file. */ - - if (cdata == 0) - { - if (qProto->pffile != NULL) - { - boolean fredo; - boolean (*pffile) P((boolean, boolean, boolean *, - long)); - - /* Simplify expression for ancient compilers. */ - pffile = qProto->pffile; - if (! pffile (FALSE, TRUE, &fredo, (long) -1)) - return FALSE; - - if (fredo) - { - ulog (LOG_NORMAL, "Resending file"); - if (! ffilerewind (eSendfile)) - { - ulog (LOG_ERROR, "rewind: %s", - strerror (errno)); - usendfile_error (); - return FALSE; - } - continue; - } - } - - return fpsendfile_confirm (); - } - } - - /* Process the data in the receive buffer, and decide - whether it's time to get out. */ - if (! (qProto->pfprocess) (&fexit)) - return FALSE; - if (fexit) - return TRUE; - - iend = iPrecend; - } - } - -#if DEBUG > 0 - /* If there is no file to send, there really should be a file to - receive. */ - - if (! ffileisopen(eRecfile)) - ulog (LOG_FATAL, "fploop: No send or receive file"); -#endif - - /* We have no file to send. Wait for data to come in. */ - - return (qProto->pfwait) (); -} - -/* This function is called by the protocol routines when data has - arrived. Some protocols may know whether the data is for a command - or a file; for others, if a receive file is open it is for the file - and is otherwise for a command. This function will set *pfexit to - TRUE if it has received a complete file (assumed to be true if - cdata is zero) or a complete command (assumed to be true if the - argument data contains a null byte). It will return FALSE on - error. */ - -boolean -fgot_data (zdata, cdata, fcmd, ffile, pfexit) - const char *zdata; - int cdata; - boolean fcmd; - boolean ffile; - boolean *pfexit; -{ - *pfexit = FALSE; - - if (! fcmd && ! ffile) - { - if (ffileisopen (eRecfile)) - ffile = TRUE; - else - fcmd = TRUE; - } - -#if DEBUG > 0 - if (ffile && ! ffileisopen (eRecfile)) - ulog (LOG_FATAL, "fgot_data: No file to receive into"); -#endif - - if (ffile) - { - if (cdata == 0) - { - /* The file transfer is complete. If the protocol has a - file level routine, call it to see whether we have to - receive the file again. */ - if (qProto->pffile != NULL) - { - boolean fredo; - boolean (*pffile) P((boolean, boolean, boolean *, long)); - - /* Simplify expression for ancient compilers. */ - pffile = qProto->pffile; - if (! pffile (FALSE, FALSE, &fredo, (long) -1)) - return FALSE; - - if (fredo) - { - ulog (LOG_NORMAL, "File being resent"); - if (! frecfile_rewind ()) - return FALSE; - return TRUE; - } - } - - if (! fprecfile_confirm ()) - return FALSE; - *pfexit = TRUE; - return TRUE; - } - else - { - int cwrote; - - /* Cast zdata to avoid warnings because of erroneous - prototypes on Ultrix. */ - cwrote = cfilewrite (eRecfile, (char *) zdata, cdata); - if (cwrote != cdata) - { - const char *zerr; - - if (cwrote < 0) - zerr = strerror (errno); - else - zerr = "could not write all data"; - ulog (LOG_ERROR, "write: %s", zerr); - urecfile_error (); - - /* Any write error is almost certainly a temporary - condition, or else UUCP would not be functioning at - all. If we continue to accept the file, we will wind - up rejecting it at the end (what else could we do?) - and the remote system will throw away the request. - We're better off just dropping the connection, which - is what happens when we return FALSE, and trying - again later. */ - return FALSE; - } - - cPreceived_bytes += cdata; - - return TRUE; - } - } - else - { - const char *z; - - /* We want to add this data to the current command string. If - there is no null character in the data, this string will be - continued by the next packet. Otherwise this must be the - last string in the command, and we don't care about what - comes after the null byte. */ - - z = (const char *) memchr ((constpointer) zdata, '\0', cdata); - if (z == NULL) - upadd_cmd (zdata, cdata, FALSE); - else - { - upadd_cmd (zdata, z - zdata, TRUE); - *pfexit = TRUE; - } - - return TRUE; - } -} - -/* This function is called by fgot_data when a command string is - received. We must queue up received commands since we don't know - when we'll be able to get to them (for example, the - acknowledgements for the last few packets of a sent file may - contain the string indicating whether the file was received - correctly). */ - -struct spcmdqueue -{ - struct spcmdqueue *qnext; - int csize; - int clen; - char *z; -}; - -static struct spcmdqueue *qPcmd_queue; -static struct spcmdqueue *qPcmd_free; - -static void -upadd_cmd (z, clen, flast) - const char *z; - int clen; - boolean flast; -{ - struct spcmdqueue *q; - - q = qPcmd_free; - if (q == NULL) - { - q = (struct spcmdqueue *) xmalloc (sizeof (struct spcmdqueue)); - q->qnext = NULL; - q->csize = 0; - q->clen = 0; - q->z = NULL; - qPcmd_free = q; - } - - if (q->clen + clen + 1 > q->csize) - { - q->csize = q->clen + clen + 1; - q->z = (char *) xrealloc ((pointer) q->z, q->csize); - } - - memcpy (q->z + q->clen, z, clen); - q->clen += clen; - q->z[q->clen] = '\0'; - - /* If the last string in this command, add it to the queue of - finished commands. */ - - if (flast) - { - struct spcmdqueue **pq; - - for (pq = &qPcmd_queue; *pq != NULL; pq = &(*pq)->qnext) - ; - *pq = q; - qPcmd_free = q->qnext; - q->qnext = NULL; - } -} - -/* Get a command string. We just have to wait until the receive - packet function gives us something in qPcmd_queue. The return - value of this may be treated as a static buffer; it will last - at least until the next packet is received. */ - -const char * -zgetcmd () -{ - struct spcmdqueue *q; - - /* Wait until a command comes in. */ - while (qPcmd_queue == NULL) - { - DEBUG_MESSAGE0 (DEBUG_UUCP_PROTO, "zgetcmd: Waiting for packet"); - - if (! (qProto->pfwait) ()) - return NULL; - } - - q = qPcmd_queue; - qPcmd_queue = q->qnext; - - q->clen = 0; - - /* We must not replace qPcmd_free, because it may already be - receiving a new command string. */ - if (qPcmd_free == NULL) - { - q->qnext = NULL; - qPcmd_free = q; - } - else - { - q->qnext = qPcmd_free->qnext; - qPcmd_free->qnext = q; - } - - DEBUG_MESSAGE1 (DEBUG_UUCP_PROTO, "zgetcmd: Got command \"%s\"", q->z); - - return q->z; -} - -/* 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 (zsend, csend, fdoread) - const char *zsend; - int csend; - boolean fdoread; -{ - if (! fdoread) - return fport_write (zsend, csend); - - while (csend > 0) - { - char *zrec; - int crec, csent; - - if (iPrecend < iPrecstart) - { - zrec = abPrecbuf + iPrecend; - crec = iPrecstart - iPrecend - 1; - } - else if (iPrecend < CRECBUFLEN) - { - zrec = abPrecbuf + iPrecend; - crec = CRECBUFLEN - iPrecend; - } - else - { - zrec = abPrecbuf; - crec = iPrecstart - 1; - } - - csent = csend; - - if (! fport_io (zsend, &csent, zrec, &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 (cneed, pcrec, ctimeout, freport) - int cneed; - int *pcrec; - int ctimeout; - boolean freport; -{ - /* Set *pcrec to the maximum amount of data we can read. fport_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 (! fport_read (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 fport_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 (ctimeout, freport) - int ctimeout; - boolean freport; -{ - char b; - - if (iPrecstart == iPrecend) - { - int crec; - - if (! freceive_data (1, &crec, ctimeout, freport)) - return -2; - if (crec == 0) - return -1; - } - - b = abPrecbuf[iPrecstart]; - iPrecstart = (iPrecstart + 1) % CRECBUFLEN; - return BUCHAR (b); -} - -/* This routine is called when an error occurred and we are crashing - out of the connection. It is only used to report statistics on - failed transfers to the statistics file. Note that the number of - bytes we report as having been sent has little or nothing to do - with the number of bytes the remote site actually received. */ - -void -ustats_failed () -{ - long cbytes; - - if (cPsent_bytes != -1) - { - cbytes = cPsent_bytes; - cPsent_bytes = -1; - (void) fsent_file (FALSE, cbytes, "connection failure", FALSE); - } - - if (cPreceived_bytes != -1) - { - cbytes = cPreceived_bytes; - cPreceived_bytes = -1; - (void) freceived_file (FALSE, cbytes, "connection failure", FALSE); - } -} diff --git a/gnu/libexec/uucp/prot.h b/gnu/libexec/uucp/prot.h deleted file mode 100644 index ffcc75103b0..00000000000 --- a/gnu/libexec/uucp/prot.h +++ /dev/null @@ -1,266 +0,0 @@ -/* 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 AIRS, P.O. Box 520, Waltham, MA 02254. - - $Id: prot.h,v 1.2 1993/08/02 17:25:12 mycroft Exp $ -*/ - -/* 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; - /* Whether the protocol is full-duplex or not; a full-duplex protocol - can transfer files in both directions at once. */ - boolean ffullduplex; - /* Reliability requirements, an or of RELIABLE_xxx defines from - port.h. */ - int ireliable; - /* Protocol parameter commands. */ - struct scmdtab *qcmds; - /* A routine to start the protocol; the argument is whether the caller - is the master or the slave. Returns TRUE if the protocol has been - succesfully started, FALSE otherwise. */ - boolean (*pfstart) P((boolean fmaster)); - /* Shutdown the protocol. */ - boolean (*pfshutdown) P((void)); - /* Send a command to the other side. */ - boolean (*pfsendcmd) P((const char *z)); - /* Get buffer to space to fill with data. This should set *pcdata - to the amount of data desired. */ - char *(*pzgetspace) P((int *pcdata)); - /* Send data to the other side. The first argument must be a return - value of pzgetspace. */ - boolean (*pfsenddata) P((char *z, int c)); - /* Process received data in abPrecbuf, calling fgot_data as - necessary. If fgot_data sets *pfexit, it should get passed back - out. */ - boolean (*pfprocess) P((boolean *pfexit)); - /* Wait for data to come in and call fgot_data with it until - fgot_data sets *pfexit. */ - boolean (*pfwait) P((void)); - /* Handle any file level actions that need to be taken. If fstart - is TRUE, a file transfer is beginning. If fstart is FALSE a file - transfer is ending, and *pfredo should be set to TRUE if the file - transfer needs to be redone. If fstart and fsend are both TRUE, - cbytes holds the size of the file or -1 if it is unknown. */ - boolean (*pffile) P((boolean fstart, boolean fsend, boolean *pfredo, - long cbytes)); -}; - -/* Send a file. - fmaster -- whether this job is the master - e -- open file (send if fmaster, receive if ! fmaster) - qcmd -- command to execute - zmail -- user to notify on source system. - ztosys -- system the file is being sent to - fnew -- whether the system is running our code or not - - If this is called with fmaster TRUE, it is responsible for - informing the slave that it wants to send a file; the slave will - eventually call freceive_file. The file should then be - transferred. When the transfer is complete, then if fmaster is - TRUE and zmail is not NULL, mail should be sent to the user zmail; - if fmaster is FALSE and qcmd->znotify is not NULL, mail should be - sent to the user qcmd->znotify. After the file transfer is - complete, the work queue entry should be removed by calling - fsysdep_did_work (pseq). Most of the latter stuff is handled by - fsent_file. */ -extern boolean fsend_file P((boolean fmaster, openfile_t e, - const struct scmd *qcmd, const char *zmail, - const char *ztosys, boolean fnew)); - -/* Receive a file. - fmaster -- whether this job is the master - e -- open file (receive if fmaster, send if ! fmaster) - qcmd -- command to execute - zmail -- user to notify on destination system. - zfromsys -- system the file is from - fnew -- whether the system is running our code or not - - The field qcmd->znotify will not be meaningful. - - If this is called with fmaster TRUE, it is responsible for - informing the slave that it wants to receive a file; the slave will - eventually call pfsend. The file should then be transferred. When - the transfer is complete, if fmaster is TRUE and zmail is not NULL, - mail should be sent to the user zmail. After the file transfer is - complete, the work queue entry should be removed by calling - fsysdep_did_work (pseq). Most of the latter work is done by - freceived_file. */ -extern boolean freceive_file P((boolean fmaster, openfile_t e, - const struct scmd *qcmd, const char *zmail, - const char *zfromsys, boolean fnew)); - -/* Request a transfer. This is only called by the master. - qcmd -- command (only pseq, zfrom, zto, zuser, zoptions valid) - - This function should tell the slave that the master wants to - execute a transfer. The slave may queue up work to do. The return - value is FALSE if some error occurred. This always does its work - immediately, so it does not use qcmd->pseq. It sets *pfnever to - TRUE if the request was denied. */ -extern boolean fxcmd P((const struct scmd *qcmd, boolean *pfnever)); - -/* Confirm a transfer. This is only called by the slave. This is - called after a transfer request has been received to confirm that - it was successful. If it was not successful, pffail will be - called with a first argument of 'X'. */ -extern boolean fxcmd_confirm P((void)); - -/* Fail. This is called by the slave if it is unable to execute some - request by the master. The argument bcmd is the request which - failed ('S' or 'R'). The argument twhy indicates the reason. The - return value is FALSE if some error occurred. */ -extern boolean ftransfer_fail P((int bcmd, enum tfailure twhy)); - -/* Get a command from the master. The strings in the command argument - are set to point into a static buffer. If fmaster is TRUE, this - should not wait if there is no command pending; if fmaster is FALSE - it should wait until a command is received. The field qcmd->pseq - will be set to NULL. */ -extern boolean fgetcmd P((boolean fmaster, struct scmd *qcmd)); - -/* Get a command string from the other system, where the nature of a - command string is defined by the protocol. The return value is - fragile, and must be saved if any other protocol related calls are - made. */ -extern const char *zgetcmd P((void)); - -/* Hangup. This is only called by the master, and indicates that the - master is ready to relinquish control; after calling it, the master - becomes the slave. If the original slave has no work to do, it - confirms the hangup (the new slave will wind up getting a 'Y' - command from fgetcmd). If the the original slave has work to do, - it becomes the master (it also denies the hangup, but this is not - seen outside the protocol code). The return value of fhangup is - FALSE if some error occurred. */ -extern boolean fhangup_request P((void)); - -/* Hangup reply. This is only called by the slave if the master has - sent a hangup request. If fconfirm is TRUE, the slave is - confirming the hangup, in which case the protocol should be shut - down. If fconfirm is FALSE, the slave will become the master. The - return value is FALSE if some error occurred. */ -extern boolean fhangup_reply P((boolean fconfirm)); - -/* Handle data received by a protocol. This is called by the protocol - specific routines as data comes in. The protocol specific routines - may know that the data is destined for a command or a file, in - which case they should pass fcmd and ffile appropriately. - Otherwise they may both be passed as FALSE, in which case if a file - recieve is in progress the data will be sent to the file, otherwise - to a command. This will set *pfexit to TRUE if the file or command - is finished. A file is finished when a zero length buffer is - passed. A command is finished when a string containing a null byte - is passed. This will return FALSE on error. */ -extern boolean fgot_data P((const char *zdata, int cdata, - boolean fcmd, boolean ffile, - boolean *pfexit)); - -/* 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((const char *zsend, int 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((int cneed, int *pcrec, int ctimeout, - boolean freport)); - -/* Protocol in use. */ -extern const struct sprotocol *qProto; - -/* 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; - -/* Whether an unexpected shutdown is OK now; this is used to avoid - giving a warning for systems that hang up in a hurry. */ -extern boolean fPerror_ok; - -/* Prototypes for 'g' protocol functions. */ - -extern struct scmdtab asGproto_params[]; -extern boolean fgstart P((boolean fmaster)); -extern boolean fgshutdown P((void)); -extern boolean fgsendcmd P((const char *z)); -extern char *zggetspace P((int *pcdata)); -extern boolean fgsenddata P((char *z, int c)); -extern boolean fgprocess P((boolean *pfexit)); -extern boolean fgwait P((void)); - -/* Prototypes for 'f' protocol functions. */ - -extern struct scmdtab asFproto_params[]; -extern boolean ffstart P((boolean fmaster)); -extern boolean ffshutdown P((void)); -extern boolean ffsendcmd P((const char *z)); -extern char *zfgetspace P((int *pcdata)); -extern boolean ffsenddata P((char *z, int c)); -extern boolean ffprocess P((boolean *pfexit)); -extern boolean ffwait P((void)); -extern boolean fffile P((boolean fstart, boolean fsend, boolean *pfredo, - long cbytes)); - -/* Prototypes for 't' protocol functions. */ - -extern struct scmdtab asTproto_params[]; -extern boolean ftstart P((boolean fmaster)); -extern boolean ftshutdown P((void)); -extern boolean ftsendcmd P((const char *z)); -extern char *ztgetspace P((int *pcdata)); -extern boolean ftsenddata P((char *z, int c)); -extern boolean ftprocess P((boolean *pfexit)); -extern boolean ftwait P((void)); -extern boolean ftfile P((boolean fstart, boolean fsend, boolean *pfredo, - long cbytes)); - -/* Prototypes for 'e' protocol functions. */ - -extern struct scmdtab asEproto_params[]; -extern boolean festart P((boolean fmaster)); -extern boolean feshutdown P((void)); -extern boolean fesendcmd P((const char *z)); -extern char *zegetspace P((int *pcdata)); -extern boolean fesenddata P((char *z, int c)); -extern boolean feprocess P((boolean *pfexit)); -extern boolean fewait P((void)); -extern boolean fefile P((boolean fstart, boolean fsend, boolean *pfredo, - long cbytes)); diff --git a/gnu/libexec/uucp/prote.c b/gnu/libexec/uucp/prote.c deleted file mode 100644 index 45fbdc4a1d9..00000000000 --- a/gnu/libexec/uucp/prote.c +++ /dev/null @@ -1,401 +0,0 @@ -/* prote.c - The 'e' protocol. - - 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 AIRS, P.O. Box 520, Waltham, MA 02254. - - $Log: prote.c,v $ - Revision 1.1.1.1 1993/03/21 09:45:37 cgd - initial import of 386bsd-0.1 sources - - Revision 1.7 1992/03/30 04:49:10 ian - Niels Baggesen: added debugging types abnormal and uucp-proto - - Revision 1.6 1992/03/17 01:03:03 ian - Miscellaneous cleanup - - Revision 1.5 1992/03/13 22:59:25 ian - Have breceive_char go through freceive_data - - Revision 1.4 1992/03/12 19:56:10 ian - Debugging based on types rather than number - - Revision 1.3 1992/02/08 03:54:18 ian - Include <string.h> only in <uucp.h>, added 1992 copyright - - Revision 1.2 1992/01/16 18:16:58 ian - Niels Baggesen: add some debugging messages - - Revision 1.1 1991/12/31 19:43:30 ian - Initial revision - - */ - -#include "uucp.h" - -#if USE_RCS_ID -char prote_rcsid[] = "$Id: prote.c,v 1.1.1.1 1993/03/21 09:45:37 cgd Exp $"; -#endif - -#include "prot.h" -#include "port.h" -#include "system.h" - -/* This implementation is based on my implementation of the 't' - protocol, which is fairly similar. The main difference between the - protocols seems to be that 't' breaks the file into packets and - transmits the size of the packet with each packet, whereas 'e' - sends the size of the entire file and then sends all the data in a - single enormous packet. - - The 'e' protocol does no error checking whatsoever and thus - requires an end-to-end verified eight bit communication line, such - as is provided by TCP. Using it with a modem is inadvisable, since - errors can occur between the modem and the computer. */ - -/* The buffer size we use. */ -#define CEBUFSIZE (CRECBUFLEN / 2) - -/* The size of the initial file size message. */ -#define CEFRAMELEN (20) - -/* A pointer to the buffer we will use. */ -static char *zEbuf; - -/* True if we are receiving a file. */ -static boolean fEfile; - -/* The number of bytes we have left to send or receive. */ -static long cEbytes; - -/* The timeout we use. */ -static int cEtimeout = 120; - -struct scmdtab asEproto_params[] = -{ - { "timeout", CMDTABTYPE_INT, (pointer) &cEtimeout, NULL }, - { NULL, 0, NULL, NULL } -}; - -/* Local function. */ - -static boolean feprocess_data P((boolean *pfexit, int *pcneed)); - -/* Start the protocol. */ - -/*ARGSUSED*/ -boolean -festart (fmaster) - boolean fmaster; -{ - if (! fport_set (PORTSETTING_EIGHT)) - return FALSE; - zEbuf = (char *) xmalloc (CEBUFSIZE); - fEfile = FALSE; - usysdep_sleep (2); - return TRUE; -} - -/* Stop the protocol. */ - -boolean -feshutdown () -{ - xfree ((pointer) zEbuf); - zEbuf = NULL; - return TRUE; -} - -/* Send a command string. We send everything up to and including the - null byte. */ - -boolean -fesendcmd (z) - const char *z; -{ - DEBUG_MESSAGE1 (DEBUG_UUCP_PROTO, "fesendcmd: Sending command \"%s\"", z); - - return fsend_data (z, strlen (z) + 1, TRUE); -} - -/* Get space to be filled with data. We provide a buffer which has - 20 bytes at the start available to hold the length. */ - -char * -zegetspace (pclen) - int *pclen; -{ - *pclen = CEBUFSIZE; - return zEbuf; -} - -/* Send out some data. We are allowed to modify the 20 bytes - preceding the buffer. This allows us to send the entire block with - header bytes in a single call. */ - -boolean -fesenddata (zdata, cdata) - char *zdata; - int cdata; -{ -#if DEBUG > 0 - /* Keep track of the number of bytes we send out to make sure it all - adds up. */ - cEbytes -= cdata; - if (cEbytes < 0) - { - ulog (LOG_ERROR, "Protocol 'e' internal error"); - return FALSE; - } -#endif - - /* We pass FALSE to fsend_data since we don't expect the other side - to be sending us anything just now. */ - return fsend_data (zdata, cdata, FALSE); -} - -/* Process any data in the receive buffer. */ - -boolean -feprocess (pfexit) - boolean *pfexit; -{ - return feprocess_data (pfexit, (int *) NULL); -} - -/* Process data and return the amount we need in *pfneed. */ - -static boolean -feprocess_data (pfexit, pcneed) - boolean *pfexit; - int *pcneed; -{ - int cinbuf, cfirst, clen; - - *pfexit = FALSE; - - cinbuf = iPrecend - iPrecstart; - if (cinbuf < 0) - cinbuf += CRECBUFLEN; - - if (! fEfile) - { - /* We are not receiving a file. Commands continue up to a null - byte. */ - while (cinbuf > 0) - { - char *pnull; - - cfirst = CRECBUFLEN - iPrecstart; - if (cfirst > cinbuf) - cfirst = cinbuf; - - pnull = memchr (abPrecbuf + iPrecstart, '\0', cfirst); - if (pnull != NULL) - cfirst = pnull - (abPrecbuf + iPrecstart) + 1; - - DEBUG_MESSAGE1 (DEBUG_PROTO, - "feprocess_data: Got %d command bytes", - cfirst); - - if (! fgot_data (abPrecbuf + iPrecstart, cfirst, TRUE, FALSE, - pfexit)) - return FALSE; - - iPrecstart = (iPrecstart + cfirst) % CRECBUFLEN; - - if (*pfexit) - return TRUE; - - cinbuf = iPrecend - iPrecstart; - if (cinbuf < 0) - cinbuf += CRECBUFLEN; - } - - if (pcneed != NULL) - *pcneed = 1; - - return TRUE; - } - - /* Here we are receiving a file. We want cEbytes in total. If we - don't have cEbytes yet, we have to get it first. */ - - if (cEbytes == -1) - { - char ab[CEFRAMELEN + 1]; - - if (cinbuf < CEFRAMELEN) - { - if (pcneed != NULL) - *pcneed = CEFRAMELEN - cinbuf; - return TRUE; - } - - cfirst = CRECBUFLEN - iPrecstart; - if (cfirst >= CEFRAMELEN) - memcpy (ab, abPrecbuf + iPrecstart, CEFRAMELEN); - else - { - memcpy (ab, abPrecbuf + iPrecstart, cfirst); - memcpy (ab + cfirst, abPrecbuf, CEFRAMELEN - cfirst); - } - - ab[CEFRAMELEN] = '\0'; - cEbytes = strtol (ab, (char **) NULL, 10); - - iPrecstart = (iPrecstart + CEFRAMELEN) % CRECBUFLEN; - - cinbuf = iPrecend - iPrecstart; - if (cinbuf < 0) - cinbuf += CRECBUFLEN; - } - - /* Here we can read real data for the file. */ - - while (cinbuf > 0) - { - clen = cinbuf; - if ((long) clen > cEbytes) - clen = (int) cEbytes; - - cfirst = CRECBUFLEN - iPrecstart; - if (cfirst > clen) - cfirst = clen; - - DEBUG_MESSAGE1 (DEBUG_PROTO, - "feprocess_data: Got %d data bytes", - cfirst); - - if (! fgot_data (abPrecbuf + iPrecstart, cfirst, FALSE, TRUE, - pfexit)) - return FALSE; - if (cfirst < clen) - { - if (! fgot_data (abPrecbuf, clen - cfirst, FALSE, TRUE, - pfexit)) - return FALSE; - } - - iPrecstart = (iPrecstart + clen) % CRECBUFLEN; - cEbytes -= clen; - - if (cEbytes == 0) - { - if (! fgot_data (abPrecbuf, 0, FALSE, TRUE, pfexit)) - return FALSE; - if (*pfexit) - return TRUE; - } - - cinbuf -= clen; - } - - if (pcneed != NULL) - { - if (cEbytes > CRECBUFLEN / 2) - *pcneed = CRECBUFLEN / 2; - else - *pcneed = (int) cEbytes; - } - - return TRUE; -} - -/* Wait for data to come in and process it until we've reached the end - of a command or a file. */ - -boolean -fewait () -{ - while (TRUE) - { - boolean fexit; - int cneed, crec; - - if (! feprocess_data (&fexit, &cneed)) - return FALSE; - if (fexit) - return TRUE; - - if (! freceive_data (cneed, &crec, cEtimeout, TRUE)) - return FALSE; - - if (crec == 0) - { - ulog (LOG_ERROR, "Timed out waiting for data"); - return FALSE; - } - } -} - -/* File level routine, to handle transferring the amount of data and - to set fEfile correctly. */ - -boolean -fefile (fstart, fsend, pfredo, cbytes) - boolean fstart; - boolean fsend; - boolean *pfredo; - long cbytes; -{ - if (pfredo != NULL) - *pfredo = FALSE; - - if (fstart) - { - if (fsend) - { - char ab[CEFRAMELEN]; - - DEBUG_MESSAGE1 (DEBUG_PROTO, - "Protocol 'e' starting to send %ld bytes", - cbytes); - - bzero (ab, CEFRAMELEN); - sprintf (ab, "%ld", cbytes); - if (! fsend_data (ab, CEFRAMELEN, TRUE)) - return FALSE; - cEbytes = cbytes; - } - else - { - cEbytes = -1; - fEfile = TRUE; - } - } - else - { - if (! fsend) - fEfile = FALSE; -#if DEBUG > 0 - if (cEbytes != 0) - { - ulog (LOG_ERROR, - "Protocol 'e' internal error: %ld bytes left over", - cEbytes); - return FALSE; - } -#endif - } - - return TRUE; -} diff --git a/gnu/libexec/uucp/protf.c b/gnu/libexec/uucp/protf.c deleted file mode 100644 index bb234a5a7f1..00000000000 --- a/gnu/libexec/uucp/protf.c +++ /dev/null @@ -1,673 +0,0 @@ -/* protf.c - The 'f' protocol. - - 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 AIRS, P.O. Box 520, Waltham, MA 02254. - - $Log: protf.c,v $ - Revision 1.1.1.1 1993/03/21 09:45:37 cgd - initial import of 386bsd-0.1 sources - - Revision 1.15 1992/03/30 04:49:10 ian - Niels Baggesen: added debugging types abnormal and uucp-proto - - Revision 1.14 1992/03/17 01:03:03 ian - Miscellaneous cleanup - - Revision 1.13 1992/03/13 22:59:25 ian - Have breceive_char go through freceive_data - - Revision 1.12 1992/03/12 19:56:10 ian - Debugging based on types rather than number - - Revision 1.11 1992/02/08 03:54:18 ian - Include <string.h> only in <uucp.h>, added 1992 copyright - - Revision 1.10 1992/01/16 18:16:58 ian - Niels Baggesen: add some debugging messages - - Revision 1.9 1992/01/14 04:35:23 ian - Chip Salzenberg: implement this patch correctly - - Revision 1.8 1992/01/14 04:21:59 ian - Chip Salzenberg: avoid use before set warning - - Revision 1.7 1991/12/31 19:34:19 ian - Added number of bytes to pffile protocol entry point - - Revision 1.6 1991/12/20 03:02:01 ian - Oleg Tabarovsky: added statistical messages to 'g' and 'f' protocols - - Revision 1.5 1991/12/20 00:01:54 ian - Franc,ois Pinard: don't crash 'f' protocol because of an illegal byte - - Revision 1.4 1991/11/16 00:31:01 ian - Increased default 't' and 'f' protocol timeouts - - Revision 1.3 1991/11/15 23:32:15 ian - Don't use 1 second timeouts--loses data on System V - - Revision 1.2 1991/11/15 21:00:59 ian - Efficiency hacks for 'f' and 't' protocols - - Revision 1.1 1991/11/11 04:21:16 ian - Initial revision - - */ - -#include "uucp.h" - -#if USE_RCS_ID -char protf_rcsid[] = "$Id: protf.c,v 1.1.1.1 1993/03/21 09:45:37 cgd Exp $"; -#endif - -#include <ctype.h> -#include <errno.h> - -#include "prot.h" -#include "port.h" -#include "system.h" - -/* This implementation is based on code by Piet Beertema, CWI, - Amsterdam, Sep 1984. - - This code implements the 'f' protocol, which requires a - flow-controlled error-free seven-bit data path. It does check for - errors, but only at the end of each file transmission, so a noisy - line without error correcting modems will be unusable. - - The conversion to seven bit data is done as follows, where b - represents the character to convert: - - 0 <= b <= 037: 0172, b + 0100 (0100 to 0137) - 040 <= b <= 0171: b ( 040 to 0171) - 0172 <= b <= 0177: 0173, b - 0100 ( 072 to 077) - 0200 <= b <= 0237: 0174, b - 0100 (0100 to 0137) - 0240 <= b <= 0371: 0175, b - 0200 ( 040 to 0171) - 0372 <= b <= 0377: 0176, b - 0300 ( 072 to 077) - - This causes all output bytes to be in the range 040 to 0176; these - are the printable ASCII characters. */ - -/* Internal functions. */ -static boolean ffprocess_data P((boolean *pfexit, int *pcneed)); - -/* The size of the buffer we allocate to store outgoing data in. */ -#define CFBUFSIZE (256) - -/* The timeout to wait for data to arrive before giving up. */ -static int cFtimeout = 120; - -/* The maximum number of retries. */ -static int cFmaxretries = 2; - -/* The buffer we allocate for outgoing data. */ -static char *zFbuf; - -/* TRUE if we are receiving a file rather than a command. */ -static boolean fFfile; - -/* The checksum so far. */ -static unsigned int iFcheck; - -/* The last special byte (0172 to 0176) or 0 if none. */ -static char bFspecial; - -/* The number of times we have retried this file. */ -static int cFretries; - -struct scmdtab asFproto_params[] = -{ - { "timeout", CMDTABTYPE_INT, (pointer) &cFtimeout, NULL }, - { "retries", CMDTABTYPE_INT, (pointer) &cFmaxretries, NULL }, - { NULL, 0, NULL, NULL } -}; - -/* Statistics. */ - -/* The number of data bytes sent in files. */ -static long cFsent_data; - -/* The number of actual bytes sent in files. */ -static long cFsent_bytes; - -/* The number of data bytes received in files. */ -static long cFrec_data; - -/* The number of actual bytes received in files. */ -static long cFrec_bytes; - -/* The number of file retries when sending. */ -static long cFsend_retries; - -/* The number of file retries when receiving. */ -static long cFrec_retries; - -/* Start the protocol. */ - -/*ARGSUSED*/ -boolean -ffstart (fmaster) - boolean fmaster; -{ - cFsent_data = 0; - cFsent_bytes = 0; - cFrec_data = 0; - cFrec_bytes = 0; - cFsend_retries = 0; - cFrec_retries = 0; - - /* Allow XON/XOFF to work. */ - if (! fport_set (PORTSETTING_SEVEN)) - return FALSE; - - /* We sleep to allow the other side to reset the terminal; this is - what Mr. Beertema's code does. */ - usysdep_sleep (2); - - return TRUE; -} - -/* Shutdown the protocol. */ - -boolean -ffshutdown () -{ - xfree ((pointer) zFbuf); - zFbuf = NULL; - ulog (LOG_NORMAL, - "Protocol 'f': sent %ld bytes for %ld, received %ld bytes for %ld", - cFsent_bytes, cFsent_data, cFrec_bytes, cFrec_data); - if (cFsend_retries != 0 || cFrec_retries != 0) - ulog (LOG_NORMAL, "Protocol 'f' file retries: %ld sending, %ld receiving", - cFsend_retries, cFrec_retries); - return TRUE; -} - -/* Send a command string. We just send the string followed by a carriage - return. */ - -boolean -ffsendcmd (z) - const char *z; -{ - int clen; - char *zalc; - - DEBUG_MESSAGE1 (DEBUG_UUCP_PROTO, "ffsendcmd: Sending command \"%s\"", z); - - clen = strlen (z); - zalc = (char *) alloca (clen + 2); - sprintf (zalc, "%s\r", z); - return fsend_data (zalc, clen + 1, TRUE); -} - -/* Get space to be filled with data. We allocate the space from the - heap. */ - -char * -zfgetspace (pclen) - int *pclen; -{ - *pclen = CFBUFSIZE; - if (zFbuf == NULL) - zFbuf = (char *) xmalloc (CFBUFSIZE); - return zFbuf; -} - -/* Send out a data packet. We have to encode the data into seven bits - and accumulate a checksum. */ - -boolean -ffsenddata (zdata, cdata) - char *zdata; - int cdata; -{ - char ab[CFBUFSIZE * 2]; - char *ze; - register unsigned int itmpchk; - - cFsent_data += cdata; - - ze = ab; - itmpchk = iFcheck; - while (cdata-- > 0) - { - register int b; - - /* Rotate the checksum left. */ - if ((itmpchk & 0x8000) == 0) - itmpchk <<= 1; - else - { - itmpchk <<= 1; - ++itmpchk; - } - - /* Add the next byte into the checksum. */ - b = *zdata++ & 0xff; - itmpchk += b; - - /* Encode the byte. */ - if (b <= 0177) - { - if (b <= 037) - { - *ze++ = '\172'; - *ze++ = (char) (b + 0100); - } - else if (b <= 0171) - *ze++ = (char) b; - else - { - *ze++ = '\173'; - *ze++ = (char) (b - 0100); - } - } - else - { - if (b <= 0237) - { - *ze++ = '\174'; - *ze++ = (char) (b - 0100); - } - else if (b <= 0371) - { - *ze++ = '\175'; - *ze++ = (char) (b - 0200); - } - else - { - *ze++ = '\176'; - *ze++ = (char) (b - 0300); - } - } - } - - iFcheck = itmpchk; - - cFsent_bytes += ze - ab; - - /* Passing FALSE tells fsend_data not to bother looking for incoming - information, since we really don't expect any. */ - return fsend_data (ab, ze - ab, FALSE); -} - -/* Process any data in the receive buffer. */ - -boolean -ffprocess (pfexit) - boolean *pfexit; -{ - return ffprocess_data (pfexit, (int *) NULL); -} - -/* Process data and return the amount of data we are looking for in - *pcneed. The 'f' protocol doesn't really reveal this, but when - transferring file we know that we need at least seven characters - for the checksum. */ - -static boolean -ffprocess_data (pfexit, pcneed) - boolean *pfexit; - int *pcneed; -{ - int i; - register unsigned int itmpchk; - - if (pcneed != NULL) - *pcneed = 1; - - if (! fFfile) - { - /* A command continues until a '\r' character, which we turn - into '\0' before calling fgot_data. */ - - while (iPrecstart != iPrecend) - { - for (i = iPrecstart; i < CRECBUFLEN && i != iPrecend; i++) - { - if (abPrecbuf[i] == '\r') - { - int istart; - - abPrecbuf[i] = '\0'; - istart = iPrecstart; - iPrecstart = (i + 1) % CRECBUFLEN; - return fgot_data (abPrecbuf + istart, i - istart + 1, - TRUE, FALSE, pfexit); - } - } - - if (! fgot_data (abPrecbuf + iPrecstart, i - iPrecstart, - TRUE, FALSE, pfexit)) - return FALSE; - - iPrecstart = i % CRECBUFLEN; - } - - *pfexit = FALSE; - return TRUE; - } - - /* Here the data is destined for a file, and we must decode it. */ - - itmpchk = iFcheck; - - while (iPrecstart != iPrecend) - { - char *zstart, *zto, *zfrom; - int c; - - zto = zfrom = zstart = abPrecbuf + iPrecstart; - - c = iPrecend - iPrecstart; - if (c < 0) - c = CRECBUFLEN - iPrecstart; - - while (c-- != 0) - { - int b; - - b = *zfrom++ & 0xff; - if (b < 040 || b > 0176) - { - ulog (LOG_ERROR, "Illegal byte %d", b); - continue; - } - - /* Characters >= 0172 are always special characters. The - only legal pair of consecutive special characters - are 0176 0176 which immediately precede the four - digit checksum. */ - - if (b >= 0172) - { - if (bFspecial != 0) - { - if (bFspecial != 0176 || b != 0176) - { - ulog (LOG_ERROR, "Illegal bytes %d %d", - bFspecial, b); - bFspecial = 0; - continue; - } - - /* Pass any initial data. */ - if (zto != zstart) - { - /* Don't count the checksum in the received bytes. */ - cFrec_bytes += zfrom - zstart - 2; - cFrec_data += zto - zstart; - if (! fgot_data (zstart, zto - zstart, FALSE, - TRUE, pfexit)) - return FALSE; - } - - /* The next characters we want to read are the - checksum, so skip the second 0176. */ - iPrecstart = (iPrecstart + zfrom - zstart) % CRECBUFLEN; - - iFcheck = itmpchk; - - /* Tell fgot_data that we've read the entire file by - passing 0 length data. This will set *pfexit to - TRUE and call fffile to verify the checksum. */ - return fgot_data ((char *) NULL, 0, FALSE, TRUE, pfexit); - } - - /* Here we have encountered a special character that - does not follow another special character. */ - bFspecial = (char) b; - } - else - { - int bnext; - - /* Here we have encountered a nonspecial character. */ - - switch (bFspecial) - { - default: - bnext = b; - break; - case 0172: - bnext = b - 0100; - break; - case 0173: - case 0174: - bnext = b + 0100; - break; - case 0175: - bnext = b + 0200; - break; - case 0176: - bnext = b + 0300; - break; - } - - *zto++ = (char) bnext; - bFspecial = 0; - - /* Rotate the checksum left. */ - if ((itmpchk & 0x8000) == 0) - itmpchk <<= 1; - else - { - itmpchk <<= 1; - ++itmpchk; - } - - /* Add the next byte into the checksum. */ - itmpchk += bnext; - } - } - - if (zto != zstart) - { - DEBUG_MESSAGE1 (DEBUG_PROTO, - "ffprocess: Calling fgot_data with %d bytes", - zto - zstart); - - cFrec_data += zto - zstart; - if (! fgot_data (zstart, zto - zstart, FALSE, TRUE, pfexit)) - return FALSE; - } - - cFrec_bytes += zfrom - zstart; - - iPrecstart = (iPrecstart + zfrom - zstart) % CRECBUFLEN; - } - - iFcheck = itmpchk; - - if (pcneed != NULL) - { - /* At this point we may have seen the first 0176 in the checksum - but not the second. The checksum is at least seven - characters long (0176 0176 a b c d \r). This won't help - much, but reading seven characters is a lot better than - reading two, which is what I saw in a 2400 baud log file. */ - if (bFspecial == 0176) - *pcneed = 6; - else - *pcneed = 7; - } - - *pfexit = FALSE; - return TRUE; -} - -/* Wait for data to come in and process it until we've finished a - command or a file. */ - -boolean -ffwait () -{ - while (TRUE) - { - boolean fexit; - int cneed, crec; - - if (! ffprocess_data (&fexit, &cneed)) - return FALSE; - if (fexit) - return TRUE; - - /* We only ask for one character at a time. This could wind up - being quite inefficient, since we might only get one - character back from each read. We really want to do - something like get all available characters, then sleep for - half a second and get all available characters again, and - keep this up until we don't get anything after sleeping. */ - - if (! freceive_data (cneed, &crec, cFtimeout, TRUE)) - return FALSE; - - if (crec == 0) - { - ulog (LOG_ERROR, "Timed out waiting for data"); - return FALSE; - } - } -} - -/* File level operations. Reset the checksums when starting to send - or receive a file, and output the checksum when we've finished - sending a file. */ - -/*ARGSUSED*/ -boolean -fffile (fstart, fsend, pfredo, cbytes) - boolean fstart; - boolean fsend; - boolean *pfredo; - long cbytes; -{ - if (fstart) - { - iFcheck = 0xffff; - cFretries = 0; - if (! fsend) - { - bFspecial = 0; - fFfile = TRUE; - } - return TRUE; - } - else - { - const char *z; - - *pfredo = FALSE; - - if (fsend) - { - char ab[8]; - - /* Send the final checksum. */ - - sprintf (ab, "\176\176%04x\r", iFcheck & 0xffff); - if (! fsend_data (ab, 7, TRUE)) - return FALSE; - - /* Now look for the acknowledgement. */ - z = zgetcmd (); - if (z == NULL) - return FALSE; - - /* An R means to retry sending the file. */ - if (*z == 'R') - { - ++cFretries; - if (cFretries > cFmaxretries) - { - ulog (LOG_ERROR, "Too many retries"); - return FALSE; - } - *pfredo = TRUE; - iFcheck = 0xffff; - ++cFsend_retries; - return TRUE; - } - - if (*z == 'G') - return TRUE; - - DEBUG_MESSAGE1 (DEBUG_PROTO, "fffile: Got \"%s\"", z); - - ulog (LOG_ERROR, "File send failed"); - return FALSE; - } - else - { - unsigned int icheck; - - /* We next expect to receive a command. */ - fFfile = FALSE; - - /* Get the checksum. */ - z = zgetcmd (); - if (z == NULL) - return FALSE; - - if (strlen (z) != 4 - || ! isxdigit (z[0]) - || ! isxdigit (z[1]) - || ! isxdigit (z[2]) - || ! isxdigit (z[3])) - { - ulog (LOG_ERROR, "Bad checksum format"); - return FALSE; - } - - icheck = strtol (z, (char **) NULL, 16); - - if (icheck != (iFcheck & 0xffff)) - { - DEBUG_MESSAGE2 (DEBUG_PROTO | DEBUG_ABNORMAL, - "Checksum failed; calculated 0x%x, got 0x%x", - iFcheck & 0xffff, icheck); - - ++cFretries; - if (cFretries > cFmaxretries) - { - ulog (LOG_ERROR, "Too many retries"); - (void) ffsendcmd ("Q"); - return FALSE; - } - - *pfredo = TRUE; - iFcheck = 0xffff; - bFspecial = 0; - fFfile = TRUE; - ++cFrec_retries; - - /* Send an R to tell the other side to resend the file. */ - return ffsendcmd ("R"); - } - - /* Send a G to tell the other side the file was received - correctly. */ - return ffsendcmd ("G"); - } - } -} diff --git a/gnu/libexec/uucp/protg.c b/gnu/libexec/uucp/protg.c deleted file mode 100644 index 5e8c0b79442..00000000000 --- a/gnu/libexec/uucp/protg.c +++ /dev/null @@ -1,1932 +0,0 @@ -/* protg.c - The 'g' protocol. - - 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 AIRS, P.O. Box 520, Waltham, MA 02254. - - $Log: protg.c,v $ - Revision 1.1.1.1 1993/03/21 09:45:37 cgd - initial import of 386bsd-0.1 sources - - Revision 1.31 1992/03/31 19:39:08 ian - Niels Baggesen: packet to retransmit did not get reset correctly - - Revision 1.30 1992/03/30 04:49:10 ian - Niels Baggesen: added debugging types abnormal and uucp-proto - - Revision 1.29 1992/03/16 18:57:38 ian - Niels Baggesen: improved debugging information - - Revision 1.28 1992/03/13 22:59:25 ian - Have breceive_char go through freceive_data - - Revision 1.27 1992/03/12 19:56:10 ian - Debugging based on types rather than number - - Revision 1.26 1992/03/03 21:18:31 ian - Aleksey P. Rudnev: added remote-window and packsize 'g' protocol parameters - - Revision 1.25 1992/02/25 18:47:38 ian - Bob Denny: reset timeouts only when data is recognized - - Revision 1.24 1992/02/19 19:36:07 ian - Rearranged time functions - - Revision 1.23 1992/02/08 03:54:18 ian - Include <string.h> only in <uucp.h>, added 1992 copyright - - Revision 1.22 1992/02/01 00:56:20 ian - Chip Salzenberg: change default window size to 7 - - Revision 1.21 1992/01/28 16:06:24 ian - Correct previous patch - - Revision 1.20 1992/01/28 03:30:14 ian - John Antypas: bad boundary condition for command in small packet - - Revision 1.19 1992/01/19 23:01:21 ian - Dave Platt: send small packets to hold a small amount of data - - Revision 1.18 1992/01/16 23:46:40 ian - Zero out unused bytes in short packets - - Revision 1.17 1992/01/16 18:16:14 ian - Corrected misspelling in debugging message - - Revision 1.16 1992/01/07 17:11:15 ian - Discount out of order packets in the error count - - Revision 1.15 1992/01/04 22:15:41 ian - Mark Mallett: wait for INITx from master before sending our INITx - - Revision 1.14 1992/01/02 05:01:28 ian - Count rejections separately from resent packets - - Revision 1.13 1991/12/31 21:17:32 ian - Franc,ois Pinard: forgot to initialize cGdelayed_packets - - Revision 1.12 1991/12/30 04:07:13 ian - Don't send RR packets when a failure occurs - - Revision 1.11 1991/12/28 03:49:23 ian - Added HAVE_MEMFNS and HAVE_BFNS; changed uses of memset to bzero - - Revision 1.10 1991/12/27 06:01:55 ian - Check for configurable maximum number of errors - - Revision 1.9 1991/12/20 03:02:01 ian - Oleg Tabarovsky: added statistical messages to 'g' and 'f' protocols - - Revision 1.8 1991/12/17 22:13:14 ian - David Nugent: zero out garbage before sending data - - Revision 1.7 1991/12/11 15:02:45 ian - Tweaked initialization sequence slightly for better packet loss response - - Revision 1.6 1991/11/15 21:33:36 ian - Remove unreached line - - Revision 1.5 1991/11/15 21:00:59 ian - Efficiency hacks for 'f' and 't' protocols - - Revision 1.4 1991/11/11 00:39:45 ian - Open port in seven bit mode, added fport_set to change to eight bit - - Revision 1.3 1991/11/09 18:53:07 ian - Reworked protocol interface - - Revision 1.2 1991/11/08 04:07:04 ian - Brian Campbell: made cGsent_bytes and cGreceived_bytes long, not int - - Revision 1.1 1991/09/10 19:40:31 ian - Initial revision - - */ - -#include "uucp.h" - -#if USE_RCS_ID -char protg_rcsid[] = "$Id: protg.c,v 1.1.1.1 1993/03/21 09:45:37 cgd Exp $"; -#endif - -#include <ctype.h> -#include <errno.h> - -#include "prot.h" -#include "system.h" -#include "port.h" - -/* Each 'g' protocol packet begins with six bytes. They are: - - <DLE><k><c0><c1><C><x> - - <DLE> is the ASCII DLE character (^P or '\020'). - if 1 <= <k> <= 8, the packet is followed by 2 ** (k + 4) bytes of data; - if <k> == 9, these six bytes are a complete control packet; - other value of <k> are illegal. - <c0> is the low byte of a checksum. - <c1> is the high byte of a checksum. - <C> is a control byte (see below). - <x> is <k> ^ <c0> ^ <c1> ^ <C>. - - The control byte <C> is divided into three bitfields: - - t t x x x y y y - - The two bit field tt is the packet type. - The three bit field xxx is the control type for a control packet, or - the sequence number for a data packet. - The three bit field yyy is a value for a control packet, or the - sequence number of the last packet received for a data packet. - - For all successfully recieved packets, the control byte is stored - into iGpacket_control. */ - -/* Names for the bytes in the frame header. */ - -#define IFRAME_DLE (0) -#define IFRAME_K (1) -#define IFRAME_CHECKLOW (2) -#define IFRAME_CHECKHIGH (3) -#define IFRAME_CONTROL (4) -#define IFRAME_XOR (5) - -/* Length of the frame header. */ -#define CFRAMELEN (6) - -/* Macros to break apart the control bytes. */ - -#define CONTROL_TT(b) ((int)(((b) >> 6) & 03)) -#define CONTROL_XXX(b) ((int)(((b) >> 3) & 07)) -#define CONTROL_YYY(b) ((int)((b) & 07)) - -/* DLE value. */ -#define DLE ('\020') - -/* Get the length of a packet given a pointer to the header. */ -#define CPACKLEN(z) (1 << ((z)[IFRAME_K] + 4)) - -/* <k> field value for a control message. */ -#define KCONTROL (9) - -/* Get the next sequence number given a sequence number. */ -#define INEXTSEQ(i) ((i + 1) & 07) - -/* Compute i1 - i2 modulo 8. */ -#define CSEQDIFF(i1, i2) (((i1) + 8 - (i2)) & 07) - -/* Packet types. These are from the tt field. - CONTROL -- control packet - ALTCHAN -- alternate channel; not used by UUCP - DATA -- full data segment - SHORTDATA -- less than full data segment (all the bytes specified by - the packet length <k> are always transferred). Let <u> be the number - of bytes in the data segment not to be used. If <u> <= 0x7f, the first - byte of the data segment is <u> and the data follows. If <u> > 0x7f, - the first byte of the data segment is 0x80 | (<u> & 0x7f), the second - byte of the data segment is <u> >> 7, and the data follows. The - maximum possible data segment size is 2**12, so this handles all - possible cases. */ - -#define CONTROL (0) -#define ALTCHAN (1) -#define DATA (2) -#define SHORTDATA (3) - -/* Control types. These are from the xxx field if the type (tt field) - is CONTROL. - - CLOSE -- close the connection - RJ -- reject; packet yyy last to be received correctly - SRJ -- selective reject; reject only packet yyy (not used by UUCP) - RR -- receiver ready; packet yyy received correctly - INITC -- third step of initialization; yyy holds window size - INITB -- second step of initialization; yyy holds maximum <k> value - 1 - INITA -- first step of initialization; yyy holds window size. - - The yyy value for RR is the same as the yyy value for an ordinary - data packet. */ - -#define CLOSE (1) -#define RJ (2) -#define SRJ (3) -#define RR (4) -#define INITC (5) -#define INITB (6) -#define INITA (7) - -/* Maximum amount of data in a single packet. This is set by the <k> - field in the header; the amount of data in a packet is - 2 ** (<k> + 4). <k> ranges from 1 to 8. */ - -#define CMAXDATAINDEX (8) - -#define CMAXDATA (1 << (CMAXDATAINDEX + 4)) - -/* Maximum window size. */ - -#define CMAXWINDOW (7) - -/* Defaults for the protocol parameters. These may all be changed by - using the ``protocol-parameter g'' command, so there is no - particular reason to change the values given here. */ - -/* The desired window size. This is what we tell the other system to - use. It must be between 1 and 7, and there's no reason to use less - than 7. Protocol parameter ``window''. */ -#define IWINDOW (7) - -/* The desired packet size. Many implementations only support 64 byte - packets. Protocol parameter ``packet-size''. */ -#define IPACKSIZE (64) - -/* The number of times to retry the exchange of INIT packets when - starting the protocol. Protocol parameter ``startup-retries''. */ -#define CSTARTUP_RETRIES (8) - -/* The timeout to use when waiting for an INIT packet when starting up - the protocol. Protocol parameter ``init-timeout''. */ -#define CEXCHANGE_INIT_TIMEOUT (10) - -/* The number of times to retry sending and waiting for a single INIT - packet when starting the protocol. This controls a single INIT - packet, while CSTARTUP_RETRIES controls how many times to try the - entire INIT sequence. Protocol parameter ``init-retries''. */ -#define CEXCHANGE_INIT_RETRIES (4) - -/* The timeout to use when waiting for a packet. Protocol parameter - ``timeout''. */ -#define CTIMEOUT (10) - -/* The number of times to retry waiting for a packet. Each time the - timeout fails we send a copy of our last data packet or a reject - message for the packet we expect from the other side, depending on - whether we are waiting for an acknowledgement or a data packet. - This is the number of times we try doing that and then waiting - again. Protocol parameter ``retries''. */ -#define CRETRIES (6) - -/* If we see more than this much unrecognized data, we drop the - connection. This must be larger than a single packet size, which - means it must be larger than 4096 (the largest possible packet - size). Protocol parameter ``garbage''. */ -#define CGARBAGE (10000) - -/* If we see more than this many protocol errors, we drop the - connection. Protocol parameter ``errors''. */ -#define CERRORS (100) - -/* If this value is non-zero, it will be used as the remote window - size regardless of what the other side requested. This can be - useful for dealing with some particularly flawed packages. This - default value should always be 0, and protocol parameter - ``remote-window'' should be used for the affected systems. */ -#define IREMOTE_WINDOW (0) - -/* If this value is non-zero, it will be used as the packet size to - send to the remote system regardless of what it requested. It's - difficult to imagine any circumstances where you would want to set - this. Protocol parameter ``remote-packet-size''. */ -#define IREMOTE_PACKSIZE (0) - -/* Local variables. */ - -/* Next sequence number to send. */ -static int iGsendseq; - -/* Last sequence number that has been acked. */ -static int iGremote_ack; - -/* Last sequence number to be retransmitted. */ -static int iGretransmit_seq; - -/* Last sequence number we have received. */ -static int iGrecseq; - -/* Last sequence number we have acked. */ -static int iGlocal_ack; - -/* Window size to request (protocol parameter ``window''). */ -static int iGrequest_winsize = IWINDOW; - -/* Packet size to request (protocol parameter ``packet-size''). */ -static int iGrequest_packsize = IPACKSIZE; - -/* Remote window size (set during handshake). */ -static int iGremote_winsize; - -/* Forced remote window size (protocol parameter ``remote-window''). */ -static int iGforced_remote_winsize = IREMOTE_WINDOW; - -/* Remote segment size (set during handshake). This is one less than - the value in a packet header. */ -static int iGremote_segsize; - -/* Remote packet size (set based on iGremote_segsize). */ -static int iGremote_packsize; - -/* Forced remote packet size (protocol parameter - ``remote-packet-size''). */ -static int iGforced_remote_packsize = IREMOTE_PACKSIZE; - -/* Recieved control byte. */ -static int iGpacket_control; - -/* Number of times to retry the initial handshake. Protocol parameter - ``startup-retries''. */ -static int cGstartup_retries = CSTARTUP_RETRIES; - -/* Number of times to retry sending an initial control packet. - Protocol parameter ``init-retries''. */ -static int cGexchange_init_retries = CEXCHANGE_INIT_RETRIES; - -/* Timeout (seconds) for receiving an initial control packet. - Protocol parameter ``init-timeout''. */ -static int cGexchange_init_timeout = CEXCHANGE_INIT_TIMEOUT; - -/* Timeout (seconds) for receiving a data packet. Protocol parameter - ``timeout''. */ -static int cGtimeout = CTIMEOUT; - -/* Maximum number of timeouts when receiving a data packet or - acknowledgement. Protocol parameter ``retries''. */ -static int cGretries = CRETRIES; - -/* Amount of garbage data we are prepared to see before giving up. - Protocol parameter ``garbage''. */ -static int cGgarbage_data = CGARBAGE; - -/* Maximum number of errors we are prepared to see before giving up. - Protocol parameter ``errors''. */ -static int cGmax_errors = CERRORS; - -/* Protocol parameter commands. */ - -struct scmdtab asGproto_params[] = -{ - { "window", CMDTABTYPE_INT, (pointer) &iGrequest_winsize, NULL }, - { "packet-size", CMDTABTYPE_INT, (pointer) &iGrequest_packsize, NULL }, - { "startup-retries", CMDTABTYPE_INT, (pointer) &cGstartup_retries, NULL }, - { "init-timeout", CMDTABTYPE_INT, (pointer) &cGexchange_init_timeout, - NULL }, - { "init-retries", CMDTABTYPE_INT, (pointer) &cGexchange_init_retries, - NULL }, - { "timeout", CMDTABTYPE_INT, (pointer) &cGtimeout, NULL }, - { "retries", CMDTABTYPE_INT, (pointer) &cGretries, NULL }, - { "garbage", CMDTABTYPE_INT, (pointer) &cGgarbage_data, NULL }, - { "errors", CMDTABTYPE_INT, (pointer) &cGmax_errors, NULL }, - { "remote-window", CMDTABTYPE_INT, (pointer) &iGforced_remote_winsize, - NULL }, - { "remote-packet-size", CMDTABTYPE_INT, (pointer) &iGforced_remote_packsize, - NULL }, - { NULL, 0, NULL, NULL } -}; - -/* Statistics. */ - -/* Number of packets we have sent. */ -static long cGsent_packets; - -/* Number of packets we have resent (these are not included in - cGsent_packets). */ -static long cGresent_packets; - -/* Number of packets we have delayed sending (these should not be - counted in cGresent_packets). */ -static long cGdelayed_packets; - -/* Number of packets we have received. */ -static long cGrec_packets; - -/* Number of packets rejected because the header was bad. */ -static long cGbad_hdr; - -/* Number of packets rejected because the checksum was bad. */ -static long cGbad_checksum; - -/* Number of packets received out of order. */ -static long cGbad_order; - -/* Number of packets rejected by receiver (number of RJ packets - received). */ -static long cGremote_rejects; - -#if DEBUG > 1 -/* Control packet names used for debugging. */ -static const char * const azGcontrol[] = -{"?0?", "CLOSE", "RJ", "SRJ", "RR", "INITC", "INITB", "INITA"}; -#endif - -/* Local functions. */ - -static boolean fgexchange_init P((boolean fmaster, int ictl, int ival, - int *piset)); -static boolean fgsend_control P((int ictl, int ival)); -static void ugadjust_ack P((int iseq)); -static boolean fgwait_for_packet P((boolean freturncontrol, int ctimeout, - int cretries)); -static boolean fgsend_acks P((void)); -static boolean fggot_ack P((int iack)); -static boolean fgprocess_data P((boolean fdoacks, boolean freturncontrol, - boolean *pfexit, int *pcneed, - boolean *pffound)); -static boolean fginit_sendbuffers P((boolean fallocate)); -static boolean fgcheck_errors P((void)); -static int igchecksum P((const char *zdata, int clen)); -static int igchecksum2 P((const char *zfirst, int cfirst, - const char *zsecond, int csecond)); - -/* Start the protocol. This requires a three way handshake. Both sides - must send and receive an INITA packet, an INITB packet, and an INITC - packet. The INITA and INITC packets contain the window size, and the - INITB packet contains the packet size. */ - -boolean -fgstart (fmaster) - boolean fmaster; -{ - int iseg; - int i; - boolean fgota, fgotb; - - /* The 'g' protocol requires a full eight bit interface. */ - if (! fport_set (PORTSETTING_EIGHT)) - return FALSE; - - iGsendseq = 1; - iGremote_ack = 0; - iGretransmit_seq = -1; - iGrecseq = 0; - iGlocal_ack = 0; - cGsent_packets = 0; - cGresent_packets = 0; - cGdelayed_packets = 0; - cGrec_packets = 0; - cGbad_hdr = 0; - cGbad_checksum = 0; - cGbad_order = 0; - cGremote_rejects = 0; - - /* We must determine the segment size based on the packet size - which may have been modified by a protocol parameter command. - A segment size of 2^n is passed as n - 5. */ - - i = iGrequest_packsize; - iseg = -1; - while (i > 0) - { - ++iseg; - i >>= 1; - } - iseg -= 5; - if (iseg < 0 || iseg > 7) - { - ulog (LOG_ERROR, "Illegal packet size %d for 'g' protocol", - iGrequest_packsize); - iseg = 1; - } - - fgota = FALSE; - fgotb = FALSE; - for (i = 0; i < cGstartup_retries; i++) - { - if (fgota) - { - if (! fgsend_control (INITA, iGrequest_winsize)) - return FALSE; - } - else - { - if (! fgexchange_init (fmaster, INITA, iGrequest_winsize, - &iGremote_winsize)) - continue; - } - fgota = TRUE; - - if (fgotb) - { - if (! fgsend_control (INITB, iseg)) - return FALSE; - } - else - { - if (! fgexchange_init (fmaster, INITB, iseg, - &iGremote_segsize)) - continue; - } - fgotb = TRUE; - - if (! fgexchange_init (fmaster, INITC, iGrequest_winsize, - &iGremote_winsize)) - continue; - - /* We have succesfully connected. Determine the remote packet - size. */ - - iGremote_packsize = 1 << (iGremote_segsize + 5); - - /* If the user requested us to force specific remote window and - packet sizes, do so now. */ - - if (iGforced_remote_winsize > 0 - && iGforced_remote_winsize <= CMAXWINDOW) - iGremote_winsize = iGforced_remote_winsize; - - if (iGforced_remote_packsize >= 32 - && iGforced_remote_packsize <= 4096) - { - /* Force the value to a power of two. */ - i = iGforced_remote_packsize; - iseg = -1; - while (i > 0) - { - ++iseg; - i >>= 1; - } - iGremote_packsize = 1 << iseg; - } - - /* Set up packet buffers to use. We don't do this until we know - the maximum packet size we are going to send. */ - if (! fginit_sendbuffers (TRUE)) - return FALSE; - - DEBUG_MESSAGE2 (DEBUG_PROTO, - "fgstart: Protocol started; packsize %d, winsize %d", - iGremote_packsize, iGremote_winsize); - - return TRUE; - } - - DEBUG_MESSAGE0 (DEBUG_PROTO | DEBUG_ABNORMAL, - "fgstart: Protocol startup failed"); - - return FALSE; -} - -/* Exchange initialization messages with the other system. - - A problem: - - We send INITA; it gets received - We receive INITA - We send INITB; it gets garbled - We receive INITB - - We have seen and sent INITB, so we start to send INITC. The other - side as sent INITB but not seen it, so it times out and resends - INITB. We will continue sending INITC and the other side will - continue sending INITB until both sides give up and start again - with INITA. - - It might seem as though if we are sending INITC and receive INITB, - we should resend our INITB, but this could cause infinite echoing - of INITB on a long-latency line. Rather than risk that, I have - implemented a fast drop-back procedure. If we are sending INITB and - receive INITC, the other side has gotten ahead of us. We immediately - fail and begin again with INITA. For the other side, if we are - sending INITC and see INITA, we also immediately fail back to INITA. - - Unfortunately, this doesn't work for the other case, in which we - are sending INITB but the other side has not yet seen INITA. As - far as I can see, if this happens we just have to wait until we - time out and resend INITA. */ - -/*ARGSUSED*/ -static boolean -fgexchange_init (fmaster, ictl, ival, piset) - boolean fmaster; - int ictl; - int ival; - int *piset; -{ - int i; - - /* The three-way handshake should be independent of who initializes - it, but it seems that some versions of uucico assume that the - master sends first and the slave responds. This only matters if - we are the slave and the first packet is garbled. If we send a - packet, the other side will assume that we must have seen the - packet they sent and will never time out and send it again. - Therefore, if we are the slave we don't send a packet the first - time through the loop. This can still fail, but should usually - work, and, after all, if the initialization packets are received - correctly there will be no problem no matter what we do. */ - - for (i = 0; i < cGexchange_init_retries; i++) - { - long itime; - int ctimeout; - - if (fmaster || i > 0) - { - if (! fgsend_control (ictl, ival)) - return FALSE; - } - - itime = isysdep_time ((long *) NULL); - ctimeout = cGexchange_init_timeout; - - do - { - long inewtime; - - /* We pass 0 as the retry count to fgwait_for_packet because - we want to handle retries here and because if it retried - it would send a packet, which would be bad. */ - - if (! fgwait_for_packet (TRUE, ctimeout, 0)) - break; - - if (CONTROL_TT (iGpacket_control) == CONTROL) - { - if (CONTROL_XXX (iGpacket_control) == ictl) - { - *piset = CONTROL_YYY (iGpacket_control); - - /* If we didn't already send our initialization - packet, send it now. */ - if (! fmaster && i == 0) - { - if (! fgsend_control (ictl, ival)) - return FALSE; - } - - return TRUE; - } - - /* If the other side is farther along than we are, - we have lost a packet. Fail immediately back to - INITA (but don't fail if we are already doing INITA, - since that would count against cStart_retries more - than it should). */ - if (CONTROL_XXX (iGpacket_control) < ictl && ictl != INITA) - return FALSE; - - /* If we are sending INITC and we receive an INITA, the other - side has failed back (we know this because we have - seen an INITB from them). Fail back ourselves to - start the whole handshake over again. */ - if (CONTROL_XXX (iGpacket_control) == INITA && ictl == INITC) - return FALSE; - } - - inewtime = isysdep_time ((long *) NULL); - ctimeout -= inewtime - itime; - } - while (ctimeout > 0); - } - - return FALSE; -} - -/* Shut down the protocol. */ - -boolean -fgshutdown () -{ - (void) fgsend_control (CLOSE, 0); - (void) fgsend_control (CLOSE, 0); - (void) fginit_sendbuffers (FALSE); - - /* The count of sent packets may not be accurate, because some of - them may have not been sent yet if the connection failed in the - middle (the ones that counted for cGdelayed_packets). I don't - think it's worth being precise. */ - ulog (LOG_NORMAL, - "Protocol 'g' packets: sent %ld, resent %ld, received %ld", - cGsent_packets, cGresent_packets - cGdelayed_packets, - cGrec_packets); - if (cGbad_hdr != 0 - || cGbad_checksum != 0 - || cGbad_order != 0 - || cGremote_rejects != 0) - ulog (LOG_NORMAL, - "Errors: header %ld, checksum %ld, order %ld, remote rejects %ld", - cGbad_hdr, cGbad_checksum, cGbad_order, cGremote_rejects); - - /* Reset all the parameters to their default values, so that the - protocol parameters used for this connection do not affect the - next one. */ - iGrequest_winsize = IWINDOW; - iGrequest_packsize = IPACKSIZE; - cGstartup_retries = CSTARTUP_RETRIES; - cGexchange_init_timeout = CEXCHANGE_INIT_TIMEOUT; - cGexchange_init_retries = CEXCHANGE_INIT_RETRIES; - cGtimeout = CTIMEOUT; - cGretries = CRETRIES; - cGgarbage_data = CGARBAGE; - cGmax_errors = CERRORS; - iGforced_remote_winsize = IREMOTE_WINDOW; - iGforced_remote_packsize = IREMOTE_PACKSIZE; - - return TRUE; -} - -/* Send a command string. We send packets containing the string until - the entire string has been sent. Each packet is full. */ - -boolean -fgsendcmd (z) - const char *z; -{ - int clen; - boolean fagain; - - DEBUG_MESSAGE1 (DEBUG_UUCP_PROTO, "fgsendcmd: Sending command \"%s\"", z); - - clen = strlen (z); - - do - { - char *zpacket; - int cdummy; - - zpacket = zggetspace (&cdummy); - - if (clen < iGremote_packsize) - { - int csize; - - /* If the remote packet size is larger than 64 (the default, - which may indicate an older UUCP package), try to fit - this command into a smaller packet. We still always send - a complete packet, though. */ - - if (iGremote_packsize <= 64) - csize = iGremote_packsize; - else - { - csize = 32; - while (csize <= clen) - csize <<= 1; - } - - strcpy (zpacket, z); - bzero (zpacket + clen, csize - clen); - fagain = FALSE; - - if (! fgsenddata (zpacket, csize)) - return FALSE; - } - else - { - memcpy (zpacket, z, iGremote_packsize); - z += iGremote_packsize; - clen -= iGremote_packsize; - fagain = TRUE; - - if (! fgsenddata (zpacket, iGremote_packsize)) - return FALSE; - } - } - while (fagain); - - return TRUE; -} - -/* We keep an array of buffers to retransmit as necessary. Rather - than waste static space on large buffer sizes, we allocate the - buffers once we know how large the other system expects them to be. - The sequence numbers used in the 'g' protocol are only three bits - long, so we allocate eight buffers and maintain a correspondence - between buffer index and sequence number. This always wastes some - buffer space, but it's easy to implement. */ - -#define CSENDBUFFERS (CMAXWINDOW + 1) - -static char *azGsendbuffers[CSENDBUFFERS]; - -static boolean -fginit_sendbuffers (fallocate) - boolean fallocate; -{ - int i; - - /* Free up any remaining old buffers. */ - - for (i = 0; i < CSENDBUFFERS; i++) - { - xfree ((pointer) azGsendbuffers[i]); - if (fallocate) - { - azGsendbuffers[i] = (char *) malloc (CFRAMELEN + iGremote_packsize); - if (azGsendbuffers[i] == NULL) - return FALSE; - bzero (azGsendbuffers[i], CFRAMELEN + iGremote_packsize); - } - else - azGsendbuffers[i] = NULL; - } - return TRUE; -} - -/* Allocate a packet to send out. The return value of this function - must be filled in and passed to fgsenddata, or discarded. This - will ensure that the buffers and iGsendseq stay in synch. Set - *pclen to the amount of data to place in the buffer. */ - -char * -zggetspace (pclen) - int *pclen; -{ - *pclen = iGremote_packsize; - return azGsendbuffers[iGsendseq] + CFRAMELEN; -} - -/* Send out a data packet. This computes the checksum, sets up the - header, and sends the packet out. The argument should point to the - return value of zggetspace. */ - -boolean -fgsenddata (zdata, cdata) - char *zdata; - int cdata; -{ - char *z; - int itt, iseg, csize; - unsigned short icheck; - - /* Set the initial length bytes. See the description at the definition - of SHORTDATA, above. */ - - itt = DATA; - csize = iGremote_packsize; - iseg = iGremote_segsize + 1; - -#if DEBUG > 0 - if (cdata > iGremote_packsize) - ulog (LOG_FATAL, "fgsend_packet: Packet size too large"); -#endif - - if (cdata < iGremote_packsize) - { - /* If the remote packet size is larger than 64, the default, we - can assume they can handle a smaller packet as well, which - will be more efficient to send. */ - if (iGremote_packsize > 64) - { - /* The packet size is 1 << (iseg + 4). */ - iseg = 1; - csize = 32; - while (csize < cdata) - { - csize <<= 1; - ++iseg; - } - } - - if (csize != cdata) - { - int cshort; - - /* We have to move the data within the packet, - unfortunately. It's tough to see any way around this - without going to some sort of iovec structure. It only - happens once per file transfer. It would also be nice if - we computed the checksum as we move. We zero out the - unused bytes, since it makes people happy. */ - - itt = SHORTDATA; - cshort = csize - cdata; - if (cshort <= 127) - { - xmemmove (zdata + 1, zdata, cdata); - zdata[0] = (char) cshort; - bzero (zdata + cdata + 1, cshort - 1); - } - else - { - xmemmove (zdata + 2, zdata, cdata); - zdata[0] = (char) (0x80 | (cshort & 0x7f)); - zdata[1] = (char) (cshort >> 7); - bzero (zdata + cdata + 2, cshort - 2); - } - } - } - - z = zdata - CFRAMELEN; - - z[IFRAME_DLE] = DLE; - z[IFRAME_K] = (char) iseg; - - icheck = (unsigned short) igchecksum (zdata, csize); - - /* We're just about ready to go. Wait until there is room in the - receiver's window for us to send the packet. We do this now so - that we send the correct value for the last packet received. - Note that if iGsendseq == iGremote_ack, this means that the - sequence numbers are actually 8 apart, since the packet could not - have been acknowledged before it was sent; this can happen when - the window size is 7. */ - while (iGsendseq == iGremote_ack - || CSEQDIFF (iGsendseq, iGremote_ack) > iGremote_winsize) - { - if (! fgwait_for_packet (TRUE, cGtimeout, cGretries)) - return FALSE; - } - - /* Ack all packets up to the next one, since the UUCP protocol - requires that all packets be acked in order. */ - while (CSEQDIFF (iGrecseq, iGlocal_ack) > 1) - { - iGlocal_ack = INEXTSEQ (iGlocal_ack); - if (! fgsend_control (RR, iGlocal_ack)) - return FALSE; - } - iGlocal_ack = iGrecseq; - - z[IFRAME_CONTROL] = (char) ((itt << 6) | (iGsendseq << 3) | iGrecseq); - - iGsendseq = INEXTSEQ (iGsendseq); - - icheck = ((unsigned short) - ((0xaaaa - (icheck ^ (z[IFRAME_CONTROL] & 0xff))) & 0xffff)); - z[IFRAME_CHECKLOW] = (char) (icheck & 0xff); - z[IFRAME_CHECKHIGH] = (char) (icheck >> 8); - - z[IFRAME_XOR] = (char) (z[IFRAME_K] ^ z[IFRAME_CHECKLOW] - ^ z[IFRAME_CHECKHIGH] ^ z[IFRAME_CONTROL]); - - /* If we've retransmitted a packet, but it hasn't been acked yet, - and this isn't the next packet after the retransmitted one (note - that iGsendseq has already been incremented at this point) then - don't send this packet yet. The other side is probably not ready - for it yet. Instead, code in fgprocess_data will send the - outstanding packets when an ack is received. */ - - ++cGsent_packets; - - if (iGretransmit_seq != -1 - && INEXTSEQ (INEXTSEQ (iGretransmit_seq)) != iGsendseq) - { - ++cGdelayed_packets; - return TRUE; - } - - iGretransmit_seq = -1; - - DEBUG_MESSAGE2 (DEBUG_PROTO, - "fgsenddata: Sending packet %d (%d bytes)", - CONTROL_XXX (z[IFRAME_CONTROL]), cdata); - - return fsend_data (z, CFRAMELEN + csize, TRUE); -} - -/* Recompute the control byte and checksum of a packet so that it - includes the correct packet acknowledgement. This is called - when a packet is retransmitted to make sure the retransmission - does not confuse the other side. */ - -static void -ugadjust_ack (iseq) - int iseq; -{ - char *z; - unsigned short icheck; - - z = azGsendbuffers[iseq]; - - /* If the received packet number is the same, there is nothing - to do. */ - if (CONTROL_YYY (z[IFRAME_CONTROL]) == iGrecseq) - return; - - /* Get the old checksum. */ - icheck = (unsigned short) (((z[IFRAME_CHECKHIGH] & 0xff) << 8) - | (z[IFRAME_CHECKLOW] & 0xff)); - icheck = ((unsigned short) - (((0xaaaa - icheck) ^ (z[IFRAME_CONTROL] & 0xff)) & 0xffff)); - - /* Update the control byte. */ - z[IFRAME_CONTROL] = (char) ((z[IFRAME_CONTROL] &~ 07) | iGrecseq); - - /* Create the new checksum. */ - icheck = ((unsigned short) - ((0xaaaa - (icheck ^ (z[IFRAME_CONTROL] & 0xff))) & 0xffff)); - z[IFRAME_CHECKLOW] = (char) (icheck & 0xff); - z[IFRAME_CHECKHIGH] = (char) (icheck >> 8); - - /* Update the XOR byte. */ - z[IFRAME_XOR] = (char) (z[IFRAME_K] ^ z[IFRAME_CHECKLOW] - ^ z[IFRAME_CHECKHIGH] ^ z[IFRAME_CONTROL]); -} - -/* Send a control packet. These are fairly simple to construct. It - seems reasonable to me that we should be able to send a control - packet at any time, even if the receive window is closed. In - particular, we don't want to delay when sending a CLOSE control - message. If I'm wrong, it can be changed easily enough. */ - -static boolean -fgsend_control (ixxx, iyyy) - int ixxx; - int iyyy; -{ - char ab[CFRAMELEN]; - int ictl; - unsigned short icheck; - - DEBUG_MESSAGE2 (DEBUG_PROTO, - "fgsend_control: Sending control %s %d", - azGcontrol[ixxx], iyyy); - - ab[IFRAME_DLE] = DLE; - ab[IFRAME_K] = KCONTROL; - - ictl = (CONTROL << 6) | (ixxx << 3) | iyyy; - icheck = (unsigned short) (0xaaaa - ictl); - ab[IFRAME_CHECKLOW] = (char) (icheck & 0xff); - ab[IFRAME_CHECKHIGH] = (char) (icheck >> 8); - - ab[IFRAME_CONTROL] = (char) ictl; - - ab[IFRAME_XOR] = (char) (ab[IFRAME_K] ^ ab[IFRAME_CHECKLOW] - ^ ab[IFRAME_CHECKHIGH] ^ ab[IFRAME_CONTROL]); - - return fsend_data (ab, CFRAMELEN, TRUE); -} - -/* Process existing data. Set *pfexit to TRUE if a file or a command - has been completely received. Return FALSE on error. */ - -boolean -fgprocess (pfexit) - boolean *pfexit; -{ - /* Don't ack incoming data (since this is called when a file is - being sent and the acks can be merged onto the outgoing data), - don't return after receiving a control packet, and don't bother - to report how much more data is needed or whether any packets - were found. */ - return fgprocess_data (FALSE, FALSE, pfexit, (int *) NULL, - (boolean *) NULL); -} - -/* Wait for data to come in. This continues processing until a - complete file or command has been received. */ - -boolean -fgwait () -{ - return fgwait_for_packet (FALSE, cGtimeout, cGretries); -} - -/* Get a packet. This is called when we have nothing to send, but - want to wait for a packet to come in. If freturncontrol is TRUE, - this will return after getting any control packet. Otherwise, it - will continue to receive packets until a complete file or a - complete command has been received. The timeout and the number of - retries are specified as arguments. The function returns FALSE if - an error occurs or if cretries timeouts of ctimeout seconds were - exceeded. */ - -static boolean -fgwait_for_packet (freturncontrol, ctimeout, cretries) - boolean freturncontrol; - int ctimeout; - int cretries; -{ - int ctimeouts; - int cgarbage; - int cshort; - - ctimeouts = 0; - cgarbage = 0; - cshort = 0; - - while (TRUE) - { - boolean fexit; - int cneed; - boolean ffound; - int crec; - - if (! fgprocess_data (TRUE, freturncontrol, &fexit, &cneed, &ffound)) - return FALSE; - - if (fexit) - return TRUE; - - DEBUG_MESSAGE1 (DEBUG_PROTO, - "fgwait_for_packet: Need %d bytes", cneed); - - if (ffound) - { - ctimeouts = 0; - cgarbage = 0; - } - else - { - if (cgarbage > cGgarbage_data) - { - ulog (LOG_ERROR, "Too much unrecognized data"); - return FALSE; - } - } - - if (! freceive_data (cneed, &crec, ctimeout, TRUE)) - return FALSE; - - cgarbage += crec; - - if (crec != 0) - { - /* If we don't get enough data twice in a row, we may have - dropped some data and still be looking for the end of a - large packet. Incrementing iPrecstart will force - fgprocess_data to skip that packet and look through the - rest of the data. In some situations, this will be a - mistake. */ - if (crec >= cneed) - cshort = 0; - else - { - ++cshort; - if (cshort > 1) - { - iPrecstart = (iPrecstart + 1) % CRECBUFLEN; - cshort = 0; - } - } - } - else - { - /* The read timed out. If we're looking for a control - packet, assume we're looking for an ack and send the last - unacknowledged packet again. Otherwise, send an RJ with - the last packet we received correctly. */ - - ++ctimeouts; - if (ctimeouts > cretries) - { - if (cretries > 0) - ulog (LOG_ERROR, "Timed out waiting for packet"); - return FALSE; - } - - if (freturncontrol - && INEXTSEQ (iGremote_ack) != iGsendseq) - { - int inext; - - inext = INEXTSEQ (iGremote_ack); - - DEBUG_MESSAGE1 (DEBUG_PROTO | DEBUG_ABNORMAL, - "fgwait_for_packet: Resending packet %d", - inext); - - ugadjust_ack (inext); - ++cGresent_packets; - if (! fsend_data (azGsendbuffers[inext], - CFRAMELEN + CPACKLEN (azGsendbuffers[inext]), - TRUE)) - return FALSE; - iGretransmit_seq = inext; - } - else - { - /* Send all pending acks first, to avoid confusing - the other side. */ - if (iGlocal_ack != iGrecseq) - { - if (! fgsend_acks ()) - return FALSE; - } - if (! fgsend_control (RJ, iGrecseq)) - return FALSE; - } - } - } -} - -/* Send acks for all packets we haven't acked yet. */ - -static boolean -fgsend_acks () -{ - while (iGlocal_ack != iGrecseq) - { - iGlocal_ack = INEXTSEQ (iGlocal_ack); - if (! fgsend_control (RR, iGlocal_ack)) - return FALSE; - } - return TRUE; -} - -/* Handle an ack of a packet. According to Hanrahan's paper, this - acknowledges all previous packets. If this is an ack for a - retransmitted packet, continue by resending up to two more packets - following the retransmitted one. This should recover quickly from - a line glitch, while avoiding the problem of continual - retransmission. */ - -static boolean -fggot_ack (iack) - int iack; -{ - int inext; - - iGremote_ack = iack; - - if (iack != iGretransmit_seq) - return TRUE; - - inext = INEXTSEQ (iGretransmit_seq); - if (inext == iGsendseq) - iGretransmit_seq = -1; - else - { - DEBUG_MESSAGE1 (DEBUG_PROTO, - "fggot_ack: Sending packet %d", inext); - - ugadjust_ack (inext); - ++cGresent_packets; - if (! fsend_data (azGsendbuffers[inext], - CFRAMELEN + CPACKLEN (azGsendbuffers[inext]), - TRUE)) - return FALSE; - inext = INEXTSEQ (inext); - if (inext == iGsendseq) - iGretransmit_seq = -1; - else - { - DEBUG_MESSAGE1 (DEBUG_PROTO, - "fggot_ack: Sending packet %d", inext); - - ugadjust_ack (inext); - ++cGresent_packets; - if (! fsend_data (azGsendbuffers[inext], - CFRAMELEN + CPACKLEN (azGsendbuffers[inext]), - TRUE)) - return FALSE; - iGretransmit_seq = inext; - } - } - - return TRUE; -} - -/* See if we've received more than the permitted number of errors. If - we receive a bad packet, we can expect a window full (less one) of - out of order packets to follow, so we discount cGbad_order - accordingly. */ - -static boolean -fgcheck_errors () -{ - int corder; - - if (cGmax_errors < 0) - return TRUE; - - corder = (cGbad_order - - ((cGbad_hdr + cGbad_checksum) * (iGremote_winsize - 1))); - if (corder < 0) - corder = 0; - - if ((cGbad_hdr + cGbad_checksum + corder + cGremote_rejects) - > cGmax_errors) - { - ulog (LOG_ERROR, "Too many 'g' protocol errors"); - return FALSE; - } - - return TRUE; -} - -/* Process the receive buffer into a data packet, if possible. All - control packets are handled here. When a data packet is received, - fgprocess_data calls fgot_data with the data; if that sets its - pfexit argument to TRUE fgprocess_data will set *pfexit to TRUE and - return TRUE. Otherwise if the freturncontrol argument is TRUE - fgprocess_data will set *pfexit to FALSE and return TRUE. - Otherwise fgprocess_data will continue trying to process data. If - some error occurs, fgprocess_data will return FALSE. If there is - not enough data to form a complete packet, then *pfexit will be set - to FALSE, *pcneed will be set to the number of bytes needed to form - a complete packet (unless pcneed is NULL) and fgprocess_data will - return TRUE. If this function found a data packet, and pffound is - not NULL, it will set *pffound to TRUE; this can be used to tell - valid data from an endless stream of garbage and control packets. - If fdoacks is TRUE, received packets will be acknowledged; - otherwise they must be acknowledged later. */ - -static boolean -fgprocess_data (fdoacks, freturncontrol, pfexit, pcneed, pffound) - boolean fdoacks; - boolean freturncontrol; - boolean *pfexit; - int *pcneed; - boolean *pffound; -{ - *pfexit = FALSE; - if (pffound != NULL) - *pffound = FALSE; - - while (iPrecstart != iPrecend) - { - char ab[CFRAMELEN]; - int i, iget, cwant; - unsigned short ihdrcheck, idatcheck; - const char *zfirst, *zsecond; - int cfirst, csecond; - - /* Look for the DLE which must start a packet. */ - - if (abPrecbuf[iPrecstart] != DLE) - { - char *zdle; - - cfirst = iPrecend - iPrecstart; - if (cfirst < 0) - cfirst = CRECBUFLEN - iPrecstart; - - zdle = memchr (abPrecbuf + iPrecstart, DLE, cfirst); - - if (zdle == NULL) - { - iPrecstart = (iPrecstart + cfirst) % CRECBUFLEN; - continue; - } - - /* We don't need % CRECBUFLEN here because zdle - (abPrecbuf - + iPrecstart) < cfirst <= CRECBUFLEN - iPrecstart. */ - iPrecstart += zdle - (abPrecbuf + iPrecstart); - } - - /* Get the first six bytes into ab. */ - - for (i = 0, iget = iPrecstart; - i < CFRAMELEN && iget != iPrecend; - i++, iget = (iget + 1) % CRECBUFLEN) - ab[i] = abPrecbuf[iget]; - - /* If there aren't six bytes, there is no packet. */ - - if (i < CFRAMELEN) - { - if (pcneed != NULL) - *pcneed = CFRAMELEN - i; - return TRUE; - } - - /* Make sure these six bytes start a packet. The check on - IFRAME_DLE is basically a debugging check, since the above - code should have ensured that it will never fail. If this is - not the start of a packet, bump iPrecstart and loop around to - look for another DLE. */ - - if (ab[IFRAME_DLE] != DLE - || ab[IFRAME_K] < 1 - || ab[IFRAME_K] > 9 - || ab[IFRAME_XOR] != (ab[IFRAME_K] ^ ab[IFRAME_CHECKLOW] - ^ ab[IFRAME_CHECKHIGH] ^ ab[IFRAME_CONTROL]) - || CONTROL_TT (ab[IFRAME_CONTROL]) == ALTCHAN) - { - ++cGbad_hdr; - - DEBUG_MESSAGE4 - (DEBUG_PROTO | DEBUG_ABNORMAL, - "fgprocess_data: Bad header: K %d TT %d XOR byte %d calc %d", - ab[IFRAME_K] & 0xff, - CONTROL_TT (ab[IFRAME_CONTROL]), - ab[IFRAME_XOR] & 0xff, - (ab[IFRAME_K] ^ ab[IFRAME_CHECKLOW] - ^ ab[IFRAME_CHECKHIGH] ^ ab[IFRAME_CONTROL]) & 0xff); - - if (! fgcheck_errors ()) - return FALSE; - - iPrecstart = (iPrecstart + 1) % CRECBUFLEN; - continue; - } - - /* The zfirst and cfirst pair point to the first set of data for - this packet; the zsecond and csecond point to the second set, - in case the packet wraps around the end of the buffer. */ - zfirst = abPrecbuf + iPrecstart + CFRAMELEN; - cfirst = 0; - zsecond = NULL; - csecond = 0; - - if (ab[IFRAME_K] == KCONTROL) - { - /* This is a control packet. It should not have any data. */ - - if (CONTROL_TT (ab[IFRAME_CONTROL]) != CONTROL) - { - ++cGbad_hdr; - - DEBUG_MESSAGE0 - (DEBUG_PROTO | DEBUG_ABNORMAL, - "fgprocess_data: Bad header: control packet with data"); - - if (! fgcheck_errors ()) - return FALSE; - - iPrecstart = (iPrecstart + 1) % CRECBUFLEN; - continue; - } - - idatcheck = (unsigned short) (0xaaaa - ab[IFRAME_CONTROL]); - cwant = 0; - } - else - { - int cinbuf; - unsigned short icheck; - - /* This is a data packet. It should not be type CONTROL. */ - - if (CONTROL_TT (ab[IFRAME_CONTROL]) == CONTROL) - { - ++cGbad_hdr; - - DEBUG_MESSAGE0 - (DEBUG_PROTO | DEBUG_ABNORMAL, - "fgprocess_data: Bad header: data packet is type CONTROL"); - - if (! fgcheck_errors ()) - return FALSE; - - iPrecstart = (iPrecstart + 1) % CRECBUFLEN; - continue; - } - - cinbuf = iPrecend - iPrecstart; - if (cinbuf < 0) - cinbuf += CRECBUFLEN; - cinbuf -= CFRAMELEN; - - /* Make sure we have enough data. If we don't, wait for - more. */ - - cwant = CPACKLEN (ab); - if (cinbuf < cwant) - { - if (pcneed != NULL) - *pcneed = cwant - cinbuf; - return TRUE; - } - - /* Set up the data pointers and compute the checksum. */ - - if (iPrecend >= iPrecstart) - cfirst = cwant; - else - { - cfirst = CRECBUFLEN - (iPrecstart + CFRAMELEN); - if (cfirst >= cwant) - cfirst = cwant; - else if (cfirst > 0) - { - zsecond = abPrecbuf; - csecond = cwant - cfirst; - } - else - { - /* Here cfirst is non-positive, so subtracting from - abPrecbuf will actually skip the appropriate number - of bytes at the start of abPrecbuf. */ - zfirst = abPrecbuf - cfirst; - cfirst = cwant; - } - } - - if (csecond == 0) - icheck = (unsigned short) igchecksum (zfirst, cfirst); - else - icheck = (unsigned short) igchecksum2 (zfirst, cfirst, - zsecond, csecond); - - idatcheck = ((unsigned short) - (((0xaaaa - (icheck ^ (ab[IFRAME_CONTROL] & 0xff))) - & 0xffff))); - } - - ihdrcheck = (unsigned short) (((ab[IFRAME_CHECKHIGH] & 0xff) << 8) - | (ab[IFRAME_CHECKLOW] & 0xff)); - - if (ihdrcheck != idatcheck) - { - DEBUG_MESSAGE2 - (DEBUG_PROTO | DEBUG_ABNORMAL, - "fgprocess_data: Bad checksum: header 0x%x, data 0x%x", - ihdrcheck, idatcheck); - - ++cGbad_checksum; - if (! fgcheck_errors ()) - return FALSE; - - /* If the checksum failed for a data packet, then if it was - the one we were expecting send an RJ, otherwise ignore - it. Previously if this code got the wrong packet number - it would send an RR, but that may confuse some Telebit - modems and it doesn't help in any case since the receiver - will probably just ignore the RR as a duplicate (that's - basically what this code does). If we totally missed the - packet we will time out and send an RJ in the function - fgwait_for_packet above. */ - - if (CONTROL_TT (ab[IFRAME_CONTROL]) != CONTROL) - { - /* Make sure we've acked everything up to this point. */ - if (iGrecseq != iGlocal_ack) - { - if (! fgsend_acks ()) - return FALSE; - } - - /* If this is the packet we wanted, tell the sender that - it failed. */ - if (CONTROL_XXX (ab[IFRAME_CONTROL]) == INEXTSEQ (iGrecseq)) - { - if (! fgsend_control (RJ, iGrecseq)) - return FALSE; - } - } - - /* We can't skip the packet data after this, because if we - have lost incoming bytes the next DLE will be somewhere - in what we thought was the packet data. */ - - iPrecstart = (iPrecstart + 1) % CRECBUFLEN; - continue; - } - - /* We have a packet; remove the processed bytes from the receive - buffer. */ - iPrecstart = (iPrecstart + cwant + CFRAMELEN) % CRECBUFLEN; - - /* Store the control byte for the handshake routines. */ - iGpacket_control = ab[IFRAME_CONTROL] & 0xff; - - /* Update the received sequence number from the yyy field of a - data packet or an RR control packet. If we've been delaying - sending packets until we received an ack, this may send out - some packets. */ - if (CONTROL_TT (ab[IFRAME_CONTROL]) != CONTROL - || CONTROL_XXX (ab[IFRAME_CONTROL]) == RR) - { - if (! fggot_ack (CONTROL_YYY (ab[IFRAME_CONTROL]))) - return FALSE; - } - - /* If this isn't a control message, make sure we have received - the expected packet sequence number, acknowledge the packet - if it's the right one, and process the data. */ - - if (CONTROL_TT (ab[IFRAME_CONTROL]) != CONTROL) - { - if (CONTROL_XXX (ab[IFRAME_CONTROL]) != INEXTSEQ (iGrecseq)) - { - /* We got the wrong packet number. */ - DEBUG_MESSAGE2 (DEBUG_PROTO | DEBUG_ABNORMAL, - "fgprocess_data: Got packet %d; expected %d", - CONTROL_XXX (ab[IFRAME_CONTROL]), - INEXTSEQ (iGrecseq)); - - ++cGbad_order; - if (! fgcheck_errors ()) - return FALSE; - - /* This code used to send an RR to encourage the other - side to get back in synch, but that may confuse some - Telebit modems and does little good in any case, - since the other side will probably just ignore it - anyhow (that's what this code does). */ - - continue; - } - - /* We got the packet we expected. */ - - ++cGrec_packets; - - iGrecseq = INEXTSEQ (iGrecseq); - - DEBUG_MESSAGE1 (DEBUG_PROTO, - "fgprocess_data: Got packet %d", iGrecseq); - - /* Tell the caller that we found something. */ - if (pffound != NULL) - *pffound = TRUE; - - /* If we are supposed to do acknowledgements here, send back - an RR packet. */ - - if (fdoacks) - { - if (! fgsend_acks ()) - return FALSE; - } - - /* If this is a short data packet, adjust the data pointers - and lengths. */ - - if (CONTROL_TT (ab[IFRAME_CONTROL]) == SHORTDATA) - { - int cshort, cmove; - - if ((zfirst[0] & 0x80) == 0) - { - cshort = zfirst[0] & 0xff; - cmove = 1; - } - else - { - int cbyte2; - - if (cfirst > 1) - cbyte2 = zfirst[1] & 0xff; - else - cbyte2 = zsecond[0] & 0xff; - cshort = (zfirst[0] & 0x7f) + (cbyte2 << 7); - cmove = 2; - } - - DEBUG_MESSAGE1 (DEBUG_PROTO, - "fgprocess_data: Packet short by %d", - cshort); - - /* Adjust the start of the buffer for the bytes used - by the count. */ - if (cfirst > cmove) - { - zfirst += cmove; - cfirst -= cmove; - } - else - { - zfirst = zsecond + (cmove - cfirst); - cfirst = csecond - (cmove - cfirst); - csecond = 0; - } - - /* Adjust the length of the buffer for the bytes we are - not supposed to consider. */ - cshort -= cmove; - if (csecond >= cshort) - csecond -= cshort; - else - { - cfirst -= cshort - csecond; - csecond = 0; - } - -#if DEBUG > 0 - /* This should not happen, but just in case. */ - if (cfirst < 0) - cfirst = 0; -#endif - } - - /* If *pfexit gets set by the first batch of data, and there - is still more data, it must be the case that we are - accumulating a command and encountered a null byte, so we - can ignore the second batch of data. */ - - if (! fgot_data (zfirst, cfirst, FALSE, FALSE, pfexit)) - return FALSE; - if (csecond > 0 && ! *pfexit) - { - if (! fgot_data (zsecond, csecond, FALSE, FALSE, pfexit)) - return FALSE; - } - - /* If fgot_data told us that we were finished, get out. */ - if (*pfexit) - return TRUE; - - /* If we've been asked to return control packets, get out - now. */ - if (freturncontrol) - { - *pfexit = TRUE; - return TRUE; - } - - continue; - } - - /* Handle control messages here. */ - -#if DEBUG > 1 - if (FDEBUGGING (DEBUG_PROTO) - || (FDEBUGGING (DEBUG_ABNORMAL) - && CONTROL_XXX (ab[IFRAME_CONTROL]) != RR)) - ulog (LOG_DEBUG, "fgprocess_data: Got control %s %d", - azGcontrol[CONTROL_XXX (ab[IFRAME_CONTROL])], - CONTROL_YYY (ab[IFRAME_CONTROL])); -#endif - - switch (CONTROL_XXX (ab[IFRAME_CONTROL])) - { - case CLOSE: - /* The other side has closed the connection. */ - if (fPerror_ok) - (void) fgshutdown (); - else - { - ulog (LOG_ERROR, "Received unexpected CLOSE packet"); - (void) fgsend_control (CLOSE, 0); - } - return FALSE; - case RJ: - /* The other side dropped a packet. Begin retransmission with - the packet following the one acknowledged. We don't - retransmit the packets immediately, but instead wait - for the first one to be acked. This prevents us from - sending an entire window several times if we get several - RJ packets. */ - iGremote_ack = CONTROL_YYY (ab[IFRAME_CONTROL]); - iGretransmit_seq = INEXTSEQ (iGremote_ack); - if (iGretransmit_seq == iGsendseq) - iGretransmit_seq = -1; - else - { - char *zpack; - - DEBUG_MESSAGE2 - (DEBUG_PROTO | DEBUG_ABNORMAL, - "fgprocess_data: Remote reject: next %d resending %d", - iGsendseq, iGretransmit_seq); - - ugadjust_ack (iGretransmit_seq); - ++cGresent_packets; - ++cGremote_rejects; - if (! fgcheck_errors ()) - return FALSE; - zpack = azGsendbuffers[iGretransmit_seq]; - if (! fsend_data (zpack, CFRAMELEN + CPACKLEN (zpack), TRUE)) - return FALSE; - } - break; - case SRJ: - /* Selectively reject a particular packet. This is not used - by UUCP, but it's easy to support. */ - DEBUG_MESSAGE1 (DEBUG_PROTO | DEBUG_ABNORMAL, - "fgprocess_data: Selective reject of %d", - CONTROL_YYY (ab[IFRAME_CONTROL])); - { - char *zpack; - - ugadjust_ack (CONTROL_YYY (ab[IFRAME_CONTROL])); - ++cGresent_packets; - ++cGremote_rejects; - zpack = azGsendbuffers[CONTROL_YYY (ab[IFRAME_CONTROL])]; - if (! fsend_data (zpack, CFRAMELEN + CPACKLEN (zpack), TRUE)) - return FALSE; - } - break; - case RR: - /* Acknowledge receipt of a packet. This was already handled - above. */ - break; - case INITC: - case INITB: - case INITA: - /* Ignore attempts to reinitialize. */ - break; - } - - /* If we've been asked to return control packets, get out. */ - if (freturncontrol) - { - *pfexit = TRUE; - return TRUE; - } - - /* Loop around to look for the next packet, if any. */ - } - - /* There is no data left in the receive buffer. */ - - if (pcneed != NULL) - *pcneed = CFRAMELEN; - return TRUE; -} - -/* Compute the 'g' protocol checksum. This is unfortunately rather - awkward. This is the most time consuming code in the entire - program. It's also not a great checksum, since it can be fooled - by some single bit errors. */ - -static int -igchecksum (z, c) - register const char *z; - register int c; -{ - register unsigned int ichk1, ichk2; - - ichk1 = 0xffff; - ichk2 = 0; - - do - { - register unsigned int b; - - /* Rotate ichk1 left. */ - if ((ichk1 & 0x8000) == 0) - ichk1 <<= 1; - else - { - ichk1 <<= 1; - ++ichk1; - } - - /* Add the next character to ichk1. */ - b = *z++ & 0xff; - ichk1 += b; - - /* Add ichk1 xor the character position in the buffer counting from - the back to ichk2. */ - ichk2 += ichk1 ^ c; - - /* If the character was zero, or adding it to ichk1 caused an - overflow, xor ichk2 to ichk1. */ - if (b == 0 || (ichk1 & 0xffff) < b) - ichk1 ^= ichk2; - } - while (--c > 0); - - return ichk1 & 0xffff; -} - -/* We use a separate function compute the checksum if the block is - split around the end of the receive buffer since it occurs much - less frequently and the checksum is already high up in the - profiles. These functions are almost identical, and this one - actually only has a few more instructions in the inner loop. */ - -static int -igchecksum2 (zfirst, cfirst, zsecond, csecond) - const char *zfirst; - int cfirst; - const char *zsecond; - int csecond; -{ - register unsigned int ichk1, ichk2; - register const char *z; - register int c; - - z = zfirst; - c = cfirst + csecond; - - ichk1 = 0xffff; - ichk2 = 0; - - do - { - register unsigned int b; - - /* Rotate ichk1 left. */ - if ((ichk1 & 0x8000) == 0) - ichk1 <<= 1; - else - { - ichk1 <<= 1; - ++ichk1; - } - - /* Add the next character to ichk1. */ - b = *z++ & 0xff; - ichk1 += b; - - /* If the first buffer has been finished, switch to the second. */ - --cfirst; - if (cfirst == 0) - z = zsecond; - - /* Add ichk1 xor the character position in the buffer counting from - the back to ichk2. */ - ichk2 += ichk1 ^ c; - - /* If the character was zero, or adding it to ichk1 caused an - overflow, xor ichk2 to ichk1. */ - if (b == 0 || (ichk1 & 0xffff) < b) - ichk1 ^= ichk2; - } - while (--c > 0); - - return ichk1 & 0xffff; -} diff --git a/gnu/libexec/uucp/prott.c b/gnu/libexec/uucp/prott.c deleted file mode 100644 index 8b6a72c2eec..00000000000 --- a/gnu/libexec/uucp/prott.c +++ /dev/null @@ -1,375 +0,0 @@ -/* prott.c - The 't' protocol. - - 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 AIRS, P.O. Box 520, Waltham, MA 02254. - - $Log: prott.c,v $ - Revision 1.1.1.1 1993/03/21 09:45:37 cgd - initial import of 386bsd-0.1 sources - - Revision 1.16 1992/03/30 04:49:10 ian - Niels Baggesen: added debugging types abnormal and uucp-proto - - Revision 1.15 1992/03/17 01:03:03 ian - Miscellaneous cleanup - - Revision 1.14 1992/03/13 22:59:25 ian - Have breceive_char go through freceive_data - - Revision 1.13 1992/03/12 19:56:10 ian - Debugging based on types rather than number - - Revision 1.12 1992/02/08 19:55:32 ian - Shifts of integers by more than 15 are not portable - - Revision 1.11 1992/02/08 03:54:18 ian - Include <string.h> only in <uucp.h>, added 1992 copyright - - Revision 1.10 1992/01/16 18:16:58 ian - Niels Baggesen: add some debugging messages - - Revision 1.9 1991/12/31 19:34:19 ian - Added number of bytes to pffile protocol entry point - - Revision 1.8 1991/12/28 03:49:23 ian - Added HAVE_MEMFNS and HAVE_BFNS; changed uses of memset to bzero - - Revision 1.7 1991/12/17 22:13:14 ian - David Nugent: zero out garbage before sending data - - Revision 1.6 1991/11/16 00:31:01 ian - Increased default 't' and 'f' protocol timeouts - - Revision 1.5 1991/11/15 23:27:21 ian - Include system.h in prott.c and protf.c - - Revision 1.4 1991/11/15 23:20:59 ian - Changed sleep to usysdep_sleep - - Revision 1.3 1991/11/15 21:00:59 ian - Efficiency hacks for 'f' and 't' protocols - - Revision 1.2 1991/11/13 20:44:20 ian - Learned author - - Revision 1.1 1991/11/12 18:26:03 ian - Initial revision - - */ - -#include "uucp.h" - -#if USE_RCS_ID -char prott_rcsid[] = "$Id: prott.c,v 1.1.1.1 1993/03/21 09:45:37 cgd Exp $"; -#endif - - -#include "prot.h" -#include "port.h" -#include "system.h" - -/* This implementation is based on code written by Rick Adams. - - This code implements the 't' protocol, which does no error checking - whatsoever and thus requires an end-to-end verified eight bit - communication line, such as is provided by TCP. Using it with a - modem is unadvisable, since errors can occur between the modem and - the computer. */ - -/* The buffer size we use. */ -#define CTBUFSIZE (1024) - -/* The offset in the buffer to the data. */ -#define CTFRAMELEN (4) - -/* Commands are sent in multiples of this size. */ -#define CTPACKSIZE (512) - -/* A pointer to the buffer we will use. */ -static char *zTbuf; - -/* True if we are receiving a file. */ -static boolean fTfile; - -/* The timeout we use. */ -static int cTtimeout = 120; - -struct scmdtab asTproto_params[] = -{ - { "timeout", CMDTABTYPE_INT, (pointer) &cTtimeout, NULL }, - { NULL, 0, NULL, NULL } -}; - -/* Local function. */ - -static boolean ftprocess_data P((boolean *pfexit, int *pcneed)); - -/* Start the protocol. */ - -/*ARGSUSED*/ -boolean -ftstart (fmaster) - boolean fmaster; -{ - if (! fport_set (PORTSETTING_EIGHT)) - return FALSE; - zTbuf = (char *) xmalloc (CTBUFSIZE + CTFRAMELEN); - /* The first two bytes of the buffer are always zero. */ - zTbuf[0] = 0; - zTbuf[1] = 0; - fTfile = FALSE; - usysdep_sleep (2); - return TRUE; -} - -/* Stop the protocol. */ - -boolean -ftshutdown () -{ - xfree ((pointer) zTbuf); - zTbuf = NULL; - return TRUE; -} - -/* Send a command string. We send everything up to and including the - null byte. The number of bytes we send must be a multiple of - TPACKSIZE. */ - -boolean -ftsendcmd (z) - const char *z; -{ - int clen; - char *zalc; - - DEBUG_MESSAGE1 (DEBUG_UUCP_PROTO, "ftsendcmd: Sending command \"%s\"", z); - - clen = strlen (z); - - /* We need to send the smallest multiple of CTPACKSIZE which is - greater than clen (not equal to clen, since we need room for the - null byte). */ - clen = ((clen / CTPACKSIZE) + 1) * CTPACKSIZE; - - zalc = (char *) alloca (clen); - bzero (zalc, clen); - strcpy (zalc, z); - - return fsend_data (zalc, clen, TRUE); -} - -/* Get space to be filled with data. We provide a buffer which has - four bytes at the start available to hold the length. */ - -char * -ztgetspace (pclen) - int *pclen; -{ - *pclen = CTBUFSIZE; - return zTbuf + CTFRAMELEN; -} - -/* Send out some data. We are allowed to modify the four bytes - preceding the buffer. This allows us to send the entire block with - header bytes in a single call. */ - -boolean -ftsenddata (zdata, cdata) - char *zdata; - int cdata; -{ - /* Here we do htonl by hand, since it doesn't exist everywhere. We - know that the amount of data cannot be greater than CTBUFSIZE, so - the first two bytes of this value will always be 0. They were - set to 0 in ftstart so we don't touch them here. This is useful - because we cannot portably right shift by 24 or 16, since we - might be dealing with sixteen bit integers. */ - zdata[-2] = (char) ((cdata >> 8) & 0xff); - zdata[-1] = (char) (cdata & 0xff); - - /* We pass FALSE to fsend_data since we don't expect the other side - to be sending us anything just now. */ - return fsend_data (zdata - CTFRAMELEN, cdata + CTFRAMELEN, FALSE); -} - -/* Process any data in the receive buffer. */ - -boolean -ftprocess (pfexit) - boolean *pfexit; -{ - return ftprocess_data (pfexit, (int *) NULL); -} - -/* Process data and return the amount we need in *pfneed. */ - -static boolean -ftprocess_data (pfexit, pcneed) - boolean *pfexit; - int *pcneed; -{ - int cinbuf, cfirst, clen; - - *pfexit = FALSE; - - cinbuf = iPrecend - iPrecstart; - if (cinbuf < 0) - cinbuf += CRECBUFLEN; - - if (! fTfile) - { - /* We are not receiving a file. Commands are read in chunks of - CTPACKSIZE. */ - while (cinbuf >= CTPACKSIZE) - { - cfirst = CRECBUFLEN - iPrecstart; - if (cfirst > CTPACKSIZE) - cfirst = CTPACKSIZE; - - DEBUG_MESSAGE1 (DEBUG_PROTO, - "ftprocess_data: Got %d command bytes", - cfirst); - - if (! fgot_data (abPrecbuf + iPrecstart, cfirst, TRUE, FALSE, - pfexit)) - return FALSE; - if (cfirst < CTPACKSIZE && ! *pfexit) - { - if (! fgot_data (abPrecbuf, CTPACKSIZE - cfirst, TRUE, FALSE, - pfexit)) - return FALSE; - } - - iPrecstart = (iPrecstart + CTPACKSIZE) % CRECBUFLEN; - - if (*pfexit) - return TRUE; - - cinbuf -= CTPACKSIZE; - } - - if (pcneed != NULL) - *pcneed = CTPACKSIZE - cinbuf; - - return TRUE; - } - - /* Here we are receiving a file. The data comes in blocks. The - first four bytes contain the length, followed by that amount of - data. */ - - while (cinbuf >= CTFRAMELEN) - { - /* The length is stored in network byte order, MSB first. */ - - clen = (((((((abPrecbuf[iPrecstart] & 0xff) << 8) - + (abPrecbuf[(iPrecstart + 1) % CRECBUFLEN] & 0xff)) << 8) - + (abPrecbuf[(iPrecstart + 2) % CRECBUFLEN] & 0xff)) << 8) - + (abPrecbuf[(iPrecstart + 3) % CRECBUFLEN] & 0xff)); - - if (cinbuf < clen + CTFRAMELEN) - { - if (pcneed != NULL) - *pcneed = clen + CTFRAMELEN - cinbuf; - return TRUE; - } - - iPrecstart = (iPrecstart + CTFRAMELEN) % CRECBUFLEN; - - cfirst = CRECBUFLEN - iPrecstart; - if (cfirst > clen) - cfirst = clen; - - DEBUG_MESSAGE1 (DEBUG_PROTO, - "ftprocess_data: Got %d data bytes", - cfirst); - - if (! fgot_data (abPrecbuf + iPrecstart, cfirst, FALSE, TRUE, - pfexit)) - return FALSE; - if (cfirst < clen) - { - if (! fgot_data (abPrecbuf, clen - cfirst, FALSE, TRUE, - pfexit)) - return FALSE; - } - - iPrecstart = (iPrecstart + clen) % CRECBUFLEN; - - if (*pfexit) - return TRUE; - - cinbuf -= clen + CTFRAMELEN; - } - - if (pcneed != NULL) - *pcneed = CTFRAMELEN - cinbuf; - - return TRUE; -} - -/* Wait for data to come in and process it until we've reached the end - of a command or a file. */ - -boolean -ftwait () -{ - while (TRUE) - { - boolean fexit; - int cneed, crec; - - if (! ftprocess_data (&fexit, &cneed)) - return FALSE; - if (fexit) - return TRUE; - - if (! freceive_data (cneed, &crec, cTtimeout, TRUE)) - return FALSE; - - if (crec == 0) - { - ulog (LOG_ERROR, "Timed out waiting for data"); - return FALSE; - } - } -} - -/* File level routine, to set fTfile correctly. */ - -/*ARGSUSED*/ -boolean -ftfile (fstart, fsend, pfredo, cbytes) - boolean fstart; - boolean fsend; - boolean *pfredo; - long cbytes; -{ - if (pfredo != NULL) - *pfredo = FALSE; - - if (! fsend) - fTfile = fstart; - - return TRUE; -} diff --git a/gnu/libexec/uucp/prtinf.c b/gnu/libexec/uucp/prtinf.c deleted file mode 100644 index f6dce5528d1..00000000000 --- a/gnu/libexec/uucp/prtinf.c +++ /dev/null @@ -1,1072 +0,0 @@ -/* prtinf.c - Routines to gather information about ports and dialers from - configuration 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 AIRS, P.O. Box 520, Waltham, MA 02254. - - $Log: prtinf.c,v $ - Revision 1.1.1.1 1993/03/21 09:45:37 cgd - initial import of 386bsd-0.1 sources - - Revision 1.20 1992/04/02 22:51:09 ian - Add gcc 2.0 format checking to ulog, and fixed discovered problems - - Revision 1.19 1992/03/28 21:47:55 ian - David J. MacKenzie: allow backslash to quote newline in config files - - Revision 1.18 1992/03/10 21:47:39 ian - Added protocol command for ports - - Revision 1.17 1992/03/08 04:56:21 ian - Peter da Silva: added ``lockname'' command for ports - - Revision 1.16 1992/03/03 06:06:48 ian - T. William Wells: don't complain about missing configuration files - - Revision 1.15 1992/02/08 03:54:18 ian - Include <string.h> only in <uucp.h>, added 1992 copyright - - Revision 1.14 1992/01/14 04:04:17 ian - Chip Salzenberg: strcmp is a macro on AIX - - Revision 1.13 1992/01/11 17:11:11 ian - Hannu Strang: avoid compiler bug by not using -> in address constant - - Revision 1.12 1991/12/22 20:57:57 ian - Added externs for strcasecmp or strncasecmp - - Revision 1.11 1991/12/17 23:14:08 ian - T. William Wells: allow dialer complete and abort to be chat scripts - - Revision 1.10 1991/12/17 17:08:02 ian - Marc Unangst: allow true and false for boolean strings as documented - - Revision 1.9 1991/12/15 03:42:33 ian - Added tprocess_chat_cmd for all chat commands, and added CMDTABTYPE_PREFIX - - Revision 1.8 1991/12/09 18:26:33 ian - Richard Todd: handle "#" command generated by multiple dialer files - - Revision 1.7 1991/12/02 21:25:36 ian - Niels Baggesen: protocol-parameter for ports and dialers didn't work - - Revision 1.6 1991/11/30 22:55:03 ian - Marty Shannon: blew up if more than one port in port file! - - Revision 1.5 1991/11/14 03:20:13 ian - Added seven-bit and reliable commands to help when selecting protocols - - Revision 1.4 1991/11/13 20:38:00 ian - Added TCP port type for connections over TCP - - Revision 1.3 1991/11/11 23:47:24 ian - Added chat-program to run a program to do a chat script - - Revision 1.2 1991/11/11 16:59:05 ian - Eliminate fread_port_info, allow NULL pflock arg to ffind_port - - Revision 1.1 1991/09/10 19:40:31 ian - Initial revision - - */ - -#include "uucp.h" - -#if USE_RCS_ID -char prtinf_rcsid[] = "$Id: prtinf.c,v 1.1.1.1 1993/03/21 09:45:37 cgd Exp $"; -#endif - -#include <ctype.h> - -#include "port.h" - -/* External functions. */ -extern int strcasecmp (); - -/* Ports are defined in a file. This file has to be both flexible and - easy to use. The format is described in a separate documentation - file. */ - -#if HAVE_TAYLOR_CONFIG - -/* The string names of the port types. This array corresponds to the - tporttype enumeration. */ - -static const char *azPtype_names[] = -{ - "stdin", - "modem", - "direct", -#if HAVE_TCP - "tcp", -#endif -}; - -#define CPORT_TYPES (sizeof azPtype_names / sizeof azPtype_names[0]) - -/* The port structure used by the command tables. */ - -static struct sport sPort; - -/* The generic port command table. */ - -static enum tcmdtabret tpexit P((int argc, char **argv, pointer pvar, - const char *zerr)); -static enum tcmdtabret tpdup_type P((int argc, char **argv, - pointer pvar, const char *zerr)); -static enum tcmdtabret tpproto_param P((int argc, char **argv, - pointer pvar, const char *zerr)); -static enum tcmdtabret tpseven_bit P((int argc, char **argv, - pointer pvar, const char *zerr)); -static enum tcmdtabret tpreliable P((int argc, char **argv, - pointer pvar, const char *zerr)); - -static struct scmdtab asPort_cmds[] = -{ - { "type", CMDTABTYPE_FN | 2, NULL, tpdup_type }, - { "protocol", CMDTABTYPE_STRING, (pointer) &sPort.zprotocols, NULL }, - { "protocol-parameter", CMDTABTYPE_FN | 0, NULL, tpproto_param }, - { "seven-bit", CMDTABTYPE_FN | 2, (pointer) &sPort.ireliable, - tpseven_bit }, - { "reliable", CMDTABTYPE_FN | 2, (pointer) &sPort.ireliable, - tpreliable }, - { "lockname", CMDTABTYPE_STRING, (pointer) &sPort.zlockname, NULL }, - { NULL, 0, NULL, NULL } -}; - -#define CPORT_CMDS (sizeof asPort_cmds / sizeof asPort_cmds[0]) - -/* The stdin port command table. */ - -static struct scmdtab asPstdin_cmds[] = -{ -#ifdef SYSDEP_STDIN_CMDS - SYSDEP_STDIN_CMDS (sPort.u.sstdin.s), -#endif - { NULL, 0, NULL, NULL } -}; - -#define CSTDIN_CMDS (sizeof asPstdin_cmds / sizeof asPstdin_cmds[0]) - -/* The modem port command table. */ - -static enum tcmdtabret tpdialer P((int argc, char **argv, pointer pvar, - const char *zerr)); -static enum tcmdtabret tpbaud_range P((int argc, char **argv, - pointer pvar, - const char *zerr)); - -static struct scmdtab asPmodem_cmds[] = -{ - { "device", CMDTABTYPE_STRING, (pointer) &sPort.u.smodem.zdevice, NULL }, - { "baud", CMDTABTYPE_LONG, (pointer) &sPort.u.smodem.ibaud, NULL }, - { "speed", CMDTABTYPE_LONG, (pointer) &sPort.u.smodem.ibaud, NULL }, - { "baud-range", CMDTABTYPE_FN | 3, NULL, tpbaud_range }, - { "speed-range", CMDTABTYPE_FN | 3, NULL, tpbaud_range }, - { "carrier", CMDTABTYPE_BOOLEAN, (pointer) &sPort.u.smodem.fcarrier, NULL }, - { "dial-device", CMDTABTYPE_STRING, (pointer) &sPort.u.smodem.zdial_device, - NULL }, - { "dialer", CMDTABTYPE_FN | 0, (pointer) &sPort.u.smodem.qdialer, - tpdialer }, - { "dialer-sequence", CMDTABTYPE_FULLSTRING, - (pointer) &sPort.u.smodem.zdialer, NULL }, -#ifdef SYSDEP_MODEM_CMDS - SYSDEP_MODEM_CMDS (sPort.u.smodem.s); -#endif - { NULL, 0, NULL, NULL } -}; - -#define CMODEM_CMDS (sizeof asPmodem_cmds / sizeof asPmodem_cmds[0]) - -/* The direct port command table. */ - -static struct scmdtab asPdirect_cmds[] = -{ - { "device", CMDTABTYPE_STRING, (pointer) &sPort.u.sdirect.zdevice, NULL }, - { "baud", CMDTABTYPE_LONG, (pointer) &sPort.u.sdirect.ibaud, NULL }, - { "speed", CMDTABTYPE_LONG, (pointer) &sPort.u.sdirect.ibaud, NULL }, -#ifdef SYSDEP_DIRECT_CMDS - SYSDEP_DIRECT_CMDS (sPort.u.sdirect.s); -#endif - { NULL, 0, NULL, NULL } -}; - -#define CDIRECT_CMDS (sizeof asPdirect_cmds / sizeof asPdirect_cmds[0]) - -#if HAVE_TCP - -/* The TCP port command table. */ - -static struct scmdtab asPtcp_cmds[] = -{ - { "service", CMDTABTYPE_STRING, (pointer) &sPort.u.stcp.zport, NULL }, - { NULL, 0, NULL, NULL } -}; - -#define CTCP_CMDS (sizeof asPtcp_cmds / sizeof asPtcp_cmds[0]) - -#else /* ! HAVE_TCP */ - -#define CTCP_CMDS (0) - -#endif /* ! HAVE_TCP */ - -/* A little routine to exit when another port command is seen. This - will cause confusion if somebody types ``port port foo'' in the - system file. */ - -/*ARGSUSED*/ -static enum tcmdtabret -tpexit (argc, argv, pvar, zerr) - int argc; - char **argv; - pointer pvar; - const char *zerr; -{ - return CMDTABRET_EXIT; -} - -/* A little routine to give a warning about duplicate type commands. */ - -/*ARGSUSED*/ -static enum tcmdtabret -tpdup_type (argc, argv, pvar, zerr) - int argc; - char **argv; - pointer pvar; - const char *zerr; -{ - ulog (LOG_ERROR, "%s: type: Ignoring extraneous command", zerr); - return CMDTABRET_FREE; -} - -/* Handle protocol parameter settings for ports. */ - -/*ARGSUSED*/ -static enum tcmdtabret -tpproto_param (argc, argv, pvar, zerr) - int argc; - char **argv; - pointer pvar; - const char *zerr; -{ - return tadd_proto_param (&sPort.cproto_params, &sPort.qproto_params, - zerr, argc - 1, argv + 1); -} - -/* Handle the ``seven-bit'' command for ports or dialers. */ - -/*ARGSUSED*/ -static enum tcmdtabret -tpseven_bit (argc, argv, pvar, zerr) - int argc; - char **argv; - pointer pvar; - const char *zerr; -{ - char b; - boolean fset; - int *pi = (int *) pvar; - - b = argv[1][0]; - if (b == 'y' || b == 'Y' || b == 't' || b == 'T') - fset = TRUE; - else if (b == 'n' || b == 'N' || b == 'f' || b == 'F') - fset = FALSE; - else - { - ulog (LOG_ERROR, "%s: %s: %s: Bad boolean", zerr, argv[0], argv[1]); - return CMDTABRET_FREE; - } - - *pi |= RELIABLE_SPECIFIED; - if (fset) - *pi |= RELIABLE_EIGHT; - else - *pi &=~ RELIABLE_EIGHT; - - return CMDTABRET_FREE; -} - -/* Handle the ``reliable'' command for ports or dialers. */ - -/*ARGSUSED*/ -static enum tcmdtabret -tpreliable (argc, argv, pvar, zerr) - int argc; - char **argv; - pointer pvar; - const char *zerr; -{ - char b; - boolean fset; - int *pi = (int *) pvar; - - b = argv[1][0]; - if (b == 'y' || b == 'Y' || b == 't' || b == 'T') - fset = TRUE; - else if (b == 'n' || b == 'N' || b == 'f' || b == 'F') - fset = FALSE; - else - { - ulog (LOG_ERROR, "%s: %s: %s: Bad boolean", zerr, argv[0], argv[1]); - return CMDTABRET_FREE; - } - - *pi |= RELIABLE_SPECIFIED; - if (fset) - *pi |= RELIABLE_RELIABLE; - else - *pi &=~ RELIABLE_RELIABLE; - - return CMDTABRET_FREE; -} - -/* Handle the ``baud-range'' command for a modem port. */ - -/*ARGSUSED*/ -static enum tcmdtabret -tpbaud_range (argc, argv, pvar, zerr) - int argc; - char **argv; - pointer pvar; - const char *zerr; -{ - /* This should do more error checking. */ - sPort.u.smodem.ilowbaud = atol (argv[1]); - sPort.u.smodem.ihighbaud = atol (argv[2]); - return CMDTABRET_FREE; -} - -/* Process a port command found while reading the system information - file. */ - -enum tcmdtabret -tprocess_port_cmd (argc, argv, pvar, zerr) - int argc; - char **argv; - pointer pvar; - const char *zerr; -{ - struct sport **pqport = (struct sport **) pvar; - enum tcmdtabret tret; - const struct scmdtab *qcmds; - int i; - - if (*pqport == NULL) - { - enum tporttype ttype; - struct sport *qnew; - boolean fgottype; - - if (strcasecmp (argv[0], "type") != 0) - { - ttype = PORTTYPE_MODEM; - fgottype = FALSE; - } - else - { - if (argc != 2) - { - ulog (LOG_ERROR, "%s: port type: Wrong number of arguments", - zerr); - return CMDTABRET_FREE; - } - - for (i = 0; i < CPORT_TYPES; i++) - if (strcasecmp (argv[1], azPtype_names[i]) == 0) - break; - - if (i >= CPORT_TYPES) - { - ulog (LOG_ERROR, "%s: Unknown port type", zerr); - return CMDTABRET_FREE; - } - - ttype = (enum tporttype) i; - fgottype = TRUE; - } - - qnew = (struct sport *) xmalloc (sizeof (struct sport)); - qnew->zname = NULL; - qnew->ttype = ttype; - qnew->zprotocols = NULL; - qnew->cproto_params = 0; - qnew->qproto_params = NULL; - qnew->zlockname = NULL; - - /* Note that we do not set RELIABLE_SPECIFIED; this just sets - defaults, so that ``seven-bit true'' does not imply - ``reliable false''. */ - qnew->ireliable = RELIABLE_RELIABLE | RELIABLE_EIGHT; - - switch (ttype) - { - case PORTTYPE_STDIN: -#ifdef SYSDEP_STDIN_INIT - SYSDEP_STDIN_INIT (&qnew->u.sstdin.s); -#endif - break; - case PORTTYPE_MODEM: - qnew->u.smodem.zdevice = NULL; - qnew->u.smodem.zdial_device = NULL; - qnew->u.smodem.ibaud = 0L; - qnew->u.smodem.ilowbaud = 0L; - qnew->u.smodem.ihighbaud = 0L; - qnew->u.smodem.fcarrier = TRUE; - qnew->u.smodem.zdialer = NULL; - qnew->u.smodem.qdialer = NULL; -#ifdef SYSDEP_MODEM_INIT - SYSDEP_MODEM_INIT (&qnew->u.smodem.s); -#endif - break; - case PORTTYPE_DIRECT: - qnew->u.sdirect.zdevice = NULL; - qnew->u.sdirect.ibaud = -1; -#ifdef SYSDEP_DIRECT_INIT - SYSDEP_DIRECT_INIT (&qnew->u.sdirect.s); -#endif - break; -#if HAVE_TCP - case PORTTYPE_TCP: - qnew->u.stcp.o = -1; - qnew->u.stcp.zport = "uucp"; - break; -#endif /* HAVE_TCP */ - } - - *pqport = qnew; - - if (fgottype) - return CMDTABRET_FREE; - } - - /* See if this command is one of the generic ones. */ - for (i = 0; i < CPORT_CMDS - 1; i++) - { - if (strcasecmp (argv[0], asPort_cmds[i].zcmd) == 0) - { - sPort = **pqport; - tret = tprocess_one_cmd (argc, argv, asPort_cmds, zerr, 0); - **pqport = sPort; - return tret; - } - } - - /* Now check the port commands for specific types. */ - switch ((*pqport)->ttype) - { - case PORTTYPE_STDIN: - qcmds = asPstdin_cmds; - break; - case PORTTYPE_MODEM: - qcmds = asPmodem_cmds; - break; - case PORTTYPE_DIRECT: - qcmds = asPdirect_cmds; - break; -#if HAVE_TCP - case PORTTYPE_TCP: - qcmds = asPtcp_cmds; - break; -#endif /* HAVE_TCP */ - default: -#if DEBUG > 0 - ulog (LOG_FATAL, "tprocess_port_cmd: Can't happen"); -#endif - return CMDTABRET_FREE; - } - - sPort = **pqport; - tret = tprocess_one_cmd (argc, argv, qcmds, zerr, - CMDFLAG_WARNUNRECOG); - **pqport = sPort; - return tret; -} - -/* Fill in an scmdtab structure to pass every possible port command - to tprocess_port_cmd. The argument must be large enough. */ - -static void uport_cmdtab P((struct scmdtab *qcmds, struct sport **pqnew)); - -static void -uport_cmdtab (qcmds, pqnew) - struct scmdtab *qcmds; - struct sport **pqnew; -{ - int i; - int ibase; - - ibase = 0; - for (i = 0; i < CPORT_CMDS - 1; i++) - { - qcmds[ibase + i].zcmd = asPort_cmds[i].zcmd; - qcmds[ibase + i].itype = CMDTABTYPE_FN | 0; - qcmds[ibase + i].pvar = (pointer) pqnew; - qcmds[ibase + i].ptfn = tprocess_port_cmd; - } - ibase += CPORT_CMDS - 1; - for (i = 0; i < CSTDIN_CMDS - 1; i++) - { - qcmds[ibase + i].zcmd = asPstdin_cmds[i].zcmd; - qcmds[ibase + i].itype = CMDTABTYPE_FN | 0; - qcmds[ibase + i].pvar = (pointer) pqnew; - qcmds[ibase + i].ptfn = tprocess_port_cmd; - } - ibase += CSTDIN_CMDS - 1; - for (i = 0; i < CMODEM_CMDS - 1; i++) - { - qcmds[ibase + i].zcmd = asPmodem_cmds[i].zcmd; - qcmds[ibase + i].itype = CMDTABTYPE_FN | 0; - qcmds[ibase + i].pvar = (pointer) pqnew; - qcmds[ibase + i].ptfn = tprocess_port_cmd; - } - ibase += CMODEM_CMDS - 1; - for (i = 0; i < CDIRECT_CMDS - 1; i++) - { - qcmds[ibase + i].zcmd = asPdirect_cmds[i].zcmd; - qcmds[ibase + i].itype = CMDTABTYPE_FN | 0; - qcmds[ibase + i].pvar = (pointer) pqnew; - qcmds[ibase + i].ptfn = tprocess_port_cmd; - } - ibase += CDIRECT_CMDS - 1; -#if HAVE_TCP - for (i = 0; i < CTCP_CMDS - 1; i++) - { - qcmds[ibase + i].zcmd = asPtcp_cmds[i].zcmd; - qcmds[ibase + i].itype = CMDTABTYPE_FN | 0; - qcmds[ibase + i].pvar = (pointer) pqnew; - qcmds[ibase + i].ptfn = tprocess_port_cmd; - } - ibase += CTCP_CMDS - 1; -#endif /* HAVE_TCP */ - qcmds[ibase].zcmd = NULL; -} - -#endif /* HAVE_TAYLOR_CONFIG */ - -#if HAVE_TAYLOR_CONFIG - -/* Save a port name so that we can use it when looking for a port - with a particular baud rate. */ - -static enum tcmdtabret tpport_for_baud P((int argc, char **argv, - pointer pvar, const char *zerr)); - -static const char *zport_for_baud_name; - -/*ARGSUSED*/ -static enum tcmdtabret -tpport_for_baud (argc, argv, pvar, zerr) - int argc; - char **argv; - pointer pvar; - const char *zerr; -{ - zport_for_baud_name = argv[1]; - return CMDTABRET_EXIT; -} - -#endif /* HAVE_TAYLOR_CONFIG */ - -/* Find and lock a port. The arguments specify a port name and a baud - rate, and the port found must match both. If the name passed in is - NULL, all ports match. If the baud rate passed in is 0, all ports - match. The lock routine is passed in so that it doesn't have to be - linked in by programs which don't need this call (yes, it's a - hack). The freport argument is actually only used for testing - purposes. */ - -boolean -ffind_port (zfind, ibaud, ihighbaud, qport, pflock, freport) - const char *zfind; - long ibaud; - long ihighbaud; - struct sport *qport; - boolean (*pflock) P((struct sport *, boolean fin)); - boolean freport; -{ - boolean ffound; - - if (ihighbaud == 0) - ihighbaud = ibaud; - - ffound = FALSE; - -#if HAVE_TAYLOR_CONFIG - if (zPortfile == NULL) - { - boolean fmore; - - /* Only warn about a missing file if we're not going to read the - V2 or BNU files. */ - fmore = FALSE; -#if HAVE_V2_CONFIG - if (fV2) - fmore = TRUE; -#endif -#if HAVE_BNU_CONFIG - if (fBnu) - fmore = TRUE; -#endif - if (! fmore) - { - ulog (LOG_ERROR, "%s%s: file not found", NEWCONFIGLIB, - PORTFILE); - return FALSE; - } - } - else - { - struct smulti_file *qmulti; - struct scmdtab ascmds[CPORT_CMDS + CSTDIN_CMDS + CMODEM_CMDS + - CDIRECT_CMDS + CTCP_CMDS + 1]; - struct sport *qnew; - const char *zname; - - qmulti = qmulti_open (zPortfile); - if (qmulti != NULL) - { - /* Set up such that each command is routed to - tprocess_port_cmd. Route "port" to tpport_for_baud, - which will record the name of the port. */ - qnew = NULL; - - ascmds[0].zcmd = "port"; - ascmds[0].itype = CMDTABTYPE_FN | 2; - ascmds[0].pvar = NULL; - ascmds[0].ptfn = tpport_for_baud; - uport_cmdtab (ascmds + 1, &qnew); - - /* Look for the first command in the file (which should be - ``port'') to get the name of the first port. */ - - zport_for_baud_name = NULL; - - uprocesscmds ((FILE *) NULL, qmulti, ascmds, - (const char *) NULL, CMDFLAG_BACKSLASH); - - if (qnew != NULL) - { - (void) fmulti_close (qmulti); - ulog (LOG_ERROR, "First command in port file is not `port'"); - return FALSE; - } - - /* Look through the files until we can't find any more. */ - - zname = zport_for_baud_name; - while (zname != NULL) - { - zport_for_baud_name = NULL; - uprocesscmds ((FILE *) NULL, qmulti, ascmds, - (const char *) NULL, CMDFLAG_BACKSLASH); - - if (qnew != NULL - && (zfind == NULL - || strcmp (zfind, zname) == 0) - && (ibaud == 0 - || (qnew->ttype == PORTTYPE_MODEM - && ((qnew->u.smodem.ibaud == 0 - && qnew->u.smodem.ilowbaud == 0 - && qnew->u.smodem.ihighbaud == 0) - || (qnew->u.smodem.ibaud >= ibaud - && qnew->u.smodem.ibaud <= ihighbaud) - || (qnew->u.smodem.ilowbaud <= ihighbaud - && qnew->u.smodem.ihighbaud >= ibaud))) - || (qnew->ttype == PORTTYPE_DIRECT - && (qnew->u.sdirect.ibaud == 0 - || qnew->u.sdirect.ibaud == ibaud)))) - { - ffound = TRUE; - qnew->zname = zname; - if (pflock == NULL - || (*pflock) (qnew, FALSE)) - { - *qport = *qnew; - xfree ((pointer) qnew); - (void) fmulti_close (qmulti); - return TRUE; - } - } - - xfree ((pointer) qnew); - qnew = NULL; - - zname = zport_for_baud_name; - } - - (void) fmulti_close (qmulti); - } - } -#endif /* HAVE_TAYLOR_CONFIG */ - -#if HAVE_V2_CONFIG - if (fV2) - { - if (fv2_find_port (zfind, ibaud, ihighbaud, qport, pflock, &ffound)) - return TRUE; - } -#endif /* HAVE_V2_CONFIG */ - -#if HAVE_BNU_CONFIG - if (fBnu) - { - if (fbnu_find_port (zfind, ibaud, ihighbaud, qport, pflock, &ffound)) - return TRUE; - } -#endif /* HAVE_BNU_CONFIG */ - - if (freport) - { - if (ffound) - ulog (LOG_ERROR, "All matching ports in use"); - else - ulog (LOG_ERROR, "No matching ports defined"); - } - - return FALSE; -} - -#if HAVE_TAYLOR_CONFIG - -/* Read dialer commands. */ - -static struct sdialer sPdialer; - -/* The dialer command table. */ - -static enum tcmdtabret tpdtr_toggle P((int argc, char **argv, pointer pvar, - const char *zerr)); -static enum tcmdtabret tpcomplete P((int argc, char **argv, pointer pvar, - const char *zerr)); -static enum tcmdtabret tpdialer_proto_param P((int argc, char **argv, - pointer pvar, - const char *zerr)); - -static struct scmdtab asPdialer_cmds[] = -{ - { "dialer", CMDTABTYPE_FN | 2, NULL, tpexit }, - { "#", CMDTABTYPE_FN | 0, NULL, tpexit }, - { "chat", CMDTABTYPE_PREFIX | 0, (pointer) &sPdialer.schat, - tprocess_chat_cmd }, - { "dialtone", CMDTABTYPE_STRING, (pointer) &sPdialer.zdialtone, NULL }, - { "pause", CMDTABTYPE_STRING, (pointer) &sPdialer.zpause, NULL }, - { "carrier", CMDTABTYPE_BOOLEAN, (pointer) &sPdialer.fcarrier, NULL }, - { "carrier-wait", CMDTABTYPE_INT, (pointer) &sPdialer.ccarrier_wait, NULL }, - { "dtr-toggle", CMDTABTYPE_FN | 0, NULL, tpdtr_toggle }, - { "complete", CMDTABTYPE_FN | 2, (pointer) &sPdialer.scomplete, - tpcomplete }, - { "complete-chat", CMDTABTYPE_PREFIX, (pointer) &sPdialer.scomplete, - tprocess_chat_cmd }, - { "abort", CMDTABTYPE_FN | 2, (pointer) &sPdialer.sabort, tpcomplete }, - { "abort-chat", CMDTABTYPE_PREFIX, (pointer) &sPdialer.sabort, - tprocess_chat_cmd }, - { "protocol-parameter", CMDTABTYPE_FN | 0, NULL, tpdialer_proto_param }, - { "seven-bit", CMDTABTYPE_FN | 2, (pointer) &sPdialer.ireliable, - tpseven_bit }, - { "reliable", CMDTABTYPE_FN | 2, (pointer) &sPdialer.ireliable, - tpreliable }, - { NULL, 0, NULL, NULL } -}; - -#define CDIALER_CMDS (sizeof asPdialer_cmds / sizeof asPdialer_cmds[0]) - -/* Handle the dtr-toggle command. */ - -/*ARGSUSED*/ -static enum tcmdtabret -tpdtr_toggle (argc, argv, pvar, zerr) - int argc; - char **argv; - pointer pvar; - const char *zerr; -{ - char b; - - if (argc < 2 || argc > 3) - { - ulog (LOG_ERROR, "%s: %s: Wrong number of arguments", zerr, argv[0]); - return CMDTABRET_FREE; - } - - b = argv[1][0]; - if (b == 'y' || b == 'Y' || b == 't' || b == 'T') - sPdialer.fdtr_toggle = TRUE; - else if (b == 'n' || b == 'N' || b == 'f' || b == 'F') - sPdialer.fdtr_toggle = FALSE; - else - { - ulog (LOG_ERROR, "%s: %s: Bad boolean", zerr, argv[0]); - return CMDTABRET_FREE; - } - - if (argc == 3) - { - b = argv[2][0]; - if (b == 'y' || b == 'Y' || b == 't' || b == 'T') - sPdialer.fdtr_toggle_wait = TRUE; - else if (b == 'n' || b == 'N' || b == 'f' || b == 'F') - sPdialer.fdtr_toggle_wait = FALSE; - else - { - ulog (LOG_ERROR, "%s: %s: Bad boolean", zerr, argv[0]); - return CMDTABRET_FREE; - } - } - - return CMDTABRET_FREE; -} - -/* Handle the complete and abort commands. These just turn a string - into a trivial chat script. */ - -/*ARGSUSED*/ -static enum tcmdtabret -tpcomplete (argc, argv, pvar, zerr) - int argc; - char **argv; - pointer pvar; - const char *zerr; -{ - struct schat_info *qchat = (struct schat_info *) pvar; - - qchat->zchat = (char *) xmalloc (strlen (argv[1]) + sizeof "\"\" "); - sprintf (qchat->zchat, "\"\" %s", argv[1]); - return CMDTABRET_FREE; -} - -/* Handle protocol parameters for dialers. */ - -/*ARGSUSED*/ -static enum tcmdtabret -tpdialer_proto_param (argc, argv, pvar, zerr) - int argc; - char **argv; - pointer pvar; - const char *zerr; -{ - return tadd_proto_param (&sPdialer.cproto_params, &sPdialer.qproto_params, - zerr, argc - 1, argv + 1); -} - -/* Process one dialer command. */ - -static enum tcmdtabret tprocess_dialer_cmd P((int argc, char **argv, - pointer pvar, - const char *zerr)); - -static enum tcmdtabret -tprocess_dialer_cmd (argc, argv, pvar, zerr) - int argc; - char **argv; - pointer pvar; - const char *zerr; -{ - struct sdialer **pq = (struct sdialer **) pvar; - enum tcmdtabret tret; - - if (*pq == NULL) - { - struct sdialer *qnew; - - qnew = (struct sdialer *) xmalloc (sizeof (struct sdialer)); - qnew->zname = NULL; - INIT_CHAT (&qnew->schat); - qnew->zdialtone = ","; - qnew->zpause = ","; - qnew->fcarrier = TRUE; - qnew->ccarrier_wait = 60; - qnew->fdtr_toggle = FALSE; - qnew->fdtr_toggle_wait = FALSE; - INIT_CHAT (&qnew->scomplete); - INIT_CHAT (&qnew->sabort); - qnew->cproto_params = 0; - qnew->qproto_params = NULL; - - /* Note that we do not set RELIABLE_SPECIFIED; this just sets - defaults, so that ``seven-bit true'' does not imply - ``reliable false''. */ - qnew->ireliable = RELIABLE_RELIABLE | RELIABLE_EIGHT; - - *pq = qnew; - } - - sPdialer = **pq; - tret = tprocess_one_cmd (argc, argv, asPdialer_cmds, zerr, - CMDFLAG_WARNUNRECOG); - **pq = sPdialer; - return tret; -} - -/* Handle a dialer command seen in the port file. */ - -static enum tcmdtabret -tpdialer (argc, argv, pvar, zerr) - int argc; - char **argv; - pointer pvar; - const char *zerr; -{ - if (argc < 2) - { - ulog (LOG_ERROR, "%s: %s: Wrong number of arguments", zerr, argv[0]); - return CMDTABRET_FREE; - } - - if (argc > 2) - return tprocess_dialer_cmd (argc - 1, argv + 1, pvar, zerr); - - sPort.u.smodem.zdialer = argv[1]; - - return CMDTABRET_CONTINUE; -} - -/* Read the information for a particular item. */ - -struct splook -{ - const char *zlook; - boolean ffound; -}; - -/* Look for a particular dialer. */ - -static enum tcmdtabret tplook P((int argc, char **argv, pointer pvar, - const char *zerr)); - -/*ARGSUSED*/ -static enum tcmdtabret -tplook (argc, argv, pvar, zerr) - int argc; - char **argv; - pointer pvar; - const char *zerr; -{ - struct splook *q = (struct splook *) pvar; - - if (strcmp (q->zlook, argv[1]) == 0) - { - q->ffound = TRUE; - return CMDTABRET_FREE_AND_EXIT; - } - return CMDTABRET_FREE; -} - -#endif /* HAVE_TAYLOR_CONFIG */ - -/* Read information about a specific dialer. */ - -boolean -fread_dialer_info (zdialer, qdialer) - const char *zdialer; - struct sdialer *qdialer; -{ -#if HAVE_TAYLOR_CONFIG - - /* If we haven't got a dialer file, then only complain if we aren't - going to try the BNU dialer file. */ - if (zDialfile == NULL) - { -#if HAVE_BNU_CONFIG - if (! fBnu) -#endif - { - ulog (LOG_ERROR, "%s%s: file not found", NEWCONFIGLIB, DIALFILE); - return FALSE; - } - } - else - { - struct smulti_file *qmulti; - struct scmdtab as[2]; - struct splook s; - struct sdialer *qnew; - struct scmdtab ascmds[CDIALER_CMDS]; - int i; - - qmulti = qmulti_open (zDialfile); - if (qmulti != NULL) - { - s.zlook = zdialer; - s.ffound = FALSE; - - as[0].zcmd = "dialer"; - as[0].itype = CMDTABTYPE_FN | 2; - as[0].pvar = (pointer) &s; - as[0].ptfn = tplook; - - as[1].zcmd = NULL; - - uprocesscmds ((FILE *) NULL, qmulti, as, (const char *) NULL, - CMDFLAG_BACKSLASH); - - if (s.ffound) - { - qnew = NULL; - - for (i = 0; i < CDIALER_CMDS; i++) - { - ascmds[i].zcmd = asPdialer_cmds[i].zcmd; - if (TTYPE_CMDTABTYPE (asPdialer_cmds[i].itype) - == CMDTABTYPE_PREFIX) - ascmds[i].itype = CMDTABTYPE_PREFIX | 0; - else - ascmds[i].itype = CMDTABTYPE_FN | 0; - ascmds[i].pvar = (pointer) &qnew; - ascmds[i].ptfn = tprocess_dialer_cmd; - } - - uprocesscmds ((FILE *) NULL, qmulti, ascmds, - (const char *) NULL, - CMDFLAG_WARNUNRECOG | CMDFLAG_BACKSLASH); - - (void) fmulti_close (qmulti); - - if (qnew == NULL) - { - ulog (LOG_ERROR, "No information for dialer %s", zdialer); - return FALSE; - } - - *qdialer = *qnew; - xfree ((pointer) qnew); - - return TRUE; - } - - (void) fmulti_close (qmulti); - } - } -#endif /* HAVE_TAYLOR_CONFIG */ - -#if HAVE_BNU_CONFIG - if (fBnu) - { - if (fbnu_read_dialer_info (zdialer, qdialer)) - return TRUE; - } -#endif /* HAVE_BNU_CONFIG */ - - ulog (LOG_ERROR, "%s: No such dialer", zdialer); - return FALSE; -} diff --git a/gnu/libexec/uucp/sys1.unx b/gnu/libexec/uucp/sys1.unx deleted file mode 100644 index 2a8fa1f862e..00000000000 --- a/gnu/libexec/uucp/sys1.unx +++ /dev/null @@ -1,2543 +0,0 @@ -/* sys1.unx - The basic system dependent routines for UNIX. - - 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 AIRS, P.O. Box 520, Waltham, MA 02254. - - $Log: sys1.unx,v $ - Revision 1.1.1.1 1993/03/21 09:45:37 cgd - initial import of 386bsd-0.1 sources - -# Revision 1.2 92/05/13 05:42:07 rich -# ported to 386bsd -# -# Revision 1.1 1992/05/10 17:36:33 rich -# Initial revision -# - Revision 1.68 1992/04/03 05:37:11 ian - Minor cleanups for gcc 2.1 - - Revision 1.67 1992/03/31 23:53:34 ian - Use $PWD to get the current directory if it's defined and correct - - Revision 1.66 1992/03/31 23:42:59 ian - Brian W. Antoine: use name from getpwnam rather than getlogin - - Revision 1.65 1992/03/26 17:17:25 ian - Gerben Wierda: various cleanups - - Revision 1.64 1992/03/18 06:00:25 ian - Open the controlling terminal in non delay mode - - Revision 1.63 1992/03/17 15:35:28 ian - Log signals when they happen, even if we continue looping - - Revision 1.62 1992/03/17 01:28:18 ian - Undefine remove in uucp.h if ! HAVE_REMOVE - - Revision 1.61 1992/03/16 22:40:01 ian - Undefine remove before function definition - - Revision 1.60 1992/03/16 22:22:35 ian - Adjusted external declarations - - Revision 1.59 1992/03/16 22:01:58 ian - Don't declare sigemptyset - - Revision 1.58 1992/03/16 01:23:08 ian - Make blocking writes optional - - Revision 1.57 1992/03/15 04:51:17 ian - Keep an array of signals we've received rather than a single variable - - Revision 1.56 1992/03/15 01:54:46 ian - All execs are now done in isspawn, all waits are done in iswait - - Revision 1.55 1992/03/12 19:54:43 ian - Debugging based on types rather than number - - Revision 1.54 1992/03/11 02:09:57 ian - Franc,ois Pinard: retry fork several times before giving up - - Revision 1.53 1992/03/11 00:18:50 ian - Save temporary file if file send fails - - Revision 1.52 1992/03/08 02:06:28 ian - Let setpgrp fail silently - - Revision 1.51 1992/03/04 01:40:51 ian - Thomas Fischer: tweaked a bit for the NeXT - - Revision 1.50 1992/03/03 21:01:20 ian - Use strict timeout in fsserial_read, eliminate all race conditions - - Revision 1.49 1992/02/29 01:06:59 ian - Chip Salzenberg: recheck file permissions before sending - - Revision 1.48 1992/02/28 05:06:15 ian - T. William Wells: fsysdep_catch must be a macro - - Revision 1.47 1992/02/27 19:51:09 ian - Added some new extern definitions - - Revision 1.46 1992/02/27 05:40:54 ian - T. William Wells: detach from controlling terminal, handle signals safely - - Revision 1.45 1992/02/24 20:07:43 ian - John Theus: some systems don't have <fcntl.h> - - Revision 1.44 1992/02/24 04:58:47 ian - Only permit files to be received into directories that are world-writeable - - Revision 1.43 1992/02/23 03:26:51 ian - Overhaul to use automatic configure shell script - - Revision 1.42 1992/02/19 19:36:07 ian - Rearranged time functions - - Revision 1.41 1992/02/09 05:10:50 ian - Added HAVE_MKDIR configuration parameter and mkdir emulation - - Revision 1.40 1992/02/09 03:14:48 ian - Added HAVE_OLD_DIRECTORIES for systems without readdir routines - - Revision 1.39 1992/02/09 02:41:58 ian - Added HAVE_DUP2 configuration parameter and dup2 emulation function - - Revision 1.38 1992/02/08 23:38:17 ian - Put utsname on stack rather than making it static - - Revision 1.37 1992/02/08 23:34:41 ian - If we have neither getcwd nor getwd, fork /bin/pwd to get the cwd - - Revision 1.36 1992/02/08 22:33:32 ian - Only get the current working directory if it's going to be needed - - Revision 1.35 1992/02/08 03:54:18 ian - Include <string.h> only in <uucp.h>, added 1992 copyright - - Revision 1.34 1992/01/29 04:27:11 ian - Jay Vassos-Libove: removed some conflicting declarations - - Revision 1.33 1992/01/22 05:08:21 ian - Call execl with correct first argument - - Revision 1.32 1992/01/21 19:39:12 ian - Chip Salzenberg: uucp and uux start uucico for right system, not any - - Revision 1.31 1992/01/21 00:30:48 ian - Don't try to create a directory with no name - - Revision 1.30 1992/01/16 03:38:20 ian - Put \n at end of fsysdep_run error message - - Revision 1.29 1992/01/15 21:06:11 ian - Mike Park: some systems can't include <sys/time.h> and <time.h> together - - Revision 1.28 1992/01/13 19:38:16 ian - Chip Salzenberg: can't declare execl, since it is varadic - - Revision 1.27 1992/01/13 06:11:39 ian - David Nugent: can't declare open or fcntl - - Revision 1.26 1992/01/11 17:30:10 ian - John Antypas: use memcpy instead of relying on structure assignment - - Revision 1.25 1992/01/04 23:23:57 ian - usysdep_localtime can't use usysdep_full_time if HAVE_TIMES - - Revision 1.24 1992/01/04 22:56:22 ian - Added extern definition - - Revision 1.23 1991/12/29 15:45:46 ian - Don't take the address of a cast value - - Revision 1.22 1991/12/29 04:04:18 ian - Added a bunch of extern definitions - - Revision 1.21 1991/12/29 02:59:50 ian - Lele Gaifax: put full year in log file - - Revision 1.20 1991/12/28 17:08:47 ian - John Theus: offer HAVE_GETWD as an alternative to using getcwd - - Revision 1.19 1991/12/28 07:01:15 ian - Added HAVE_FTIME configuration option - - Revision 1.18 1991/12/22 22:14:19 ian - Monty Solomon: added HAVE_UNISTD_H configuration parameter - - Revision 1.17 1991/12/21 21:34:14 ian - Moved fsysdep_file_exists from sys5.unx to sys1.unx - - Revision 1.16 1991/12/21 21:04:42 ian - Use real program name in fsysdep_run error messages - - Revision 1.15 1991/12/17 07:09:58 ian - Record statistics in fractions of a second - - Revision 1.14 1991/12/12 18:35:47 ian - Do locking with link to avoid races and to permit running as root - - Revision 1.13 1991/12/12 17:39:40 ian - Set the GID as well as the UID for extra safety - - Revision 1.12 1991/12/11 03:59:19 ian - Create directories when necessary; don't just assume they exist - - Revision 1.11 1991/12/06 22:50:01 ian - Franc,ois Pinard: getcwd may legitimately fail in usysdep_initialize - - Revision 1.10 1991/12/01 02:23:12 ian - Niels Baggesen: don't multiply include <unistd.h> - - Revision 1.9 1991/11/21 20:59:32 ian - Brian Campbell: ttyname takes an argument - - Revision 1.8 1991/11/14 19:11:25 ian - Add extern for ttyname - - Revision 1.7 1991/11/14 03:40:10 ian - Try to figure out whether stdin is a TCP port - - Revision 1.6 1991/11/11 18:55:52 ian - Get protocol parameters from port and dialer for incoming calls - - Revision 1.5 1991/09/19 17:49:39 ian - Chip Salzenberg: the log file has been closed before calling fsysdep_run - - Revision 1.4 1991/09/19 15:46:48 ian - Chip Salzenberg: Make sure getlogin () uid matches process uid - - Revision 1.3 1991/09/19 03:23:34 ian - Chip Salzenberg: append to private debugging file, don't overwrite it - - Revision 1.2 1991/09/11 02:33:14 ian - Added ffork argument to fsysdep_run - - Revision 1.1 1991/09/10 19:45:50 ian - Initial revision - - */ - -#include "uucp.h" - -#if USE_RCS_ID -char sys1_unx_rcsid[] = "$Id: sys1.unx,v 1.1.1.1 1993/03/21 09:45:37 cgd Exp $"; -#endif - -#include <errno.h> - -#if USE_STDIO && HAVE_UNISTD_H -#include <unistd.h> -#endif - -#include "system.h" -#include "sysdep.h" - -#include <pwd.h> - -#if HAVE_GETGRENT -#include <grp.h> -extern struct group *getgrent (); -#endif - -#if HAVE_LIMITS_H -#include <limits.h> -#endif - -#if HAVE_SYS_PARAM_H -#include <sys/param.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 O_APPEND -#ifdef FAPPEND -#define O_APPEND FAPPEND -#endif -#endif - -#ifndef O_NOCTTY -#define O_NOCTTY 0 -#endif - -#if ! HAVE_GETHOSTNAME && HAVE_UNAME -#include <sys/utsname.h> -extern int uname (); -#endif - -#if HAVE_TIME_H && (HAVE_SYS_TIME_AND_TIME_H || ! HAVE_GETTIMEOFDAY) -#include <time.h> -#endif - -#if HAVE_SYS_IOCTL_H -#include <sys/ioctl.h> -#endif - -/* If we have getcwd, forget about getwd. */ - -#if HAVE_GETCWD -#undef HAVE_GETWD -#define HAVE_GETWD 0 -#endif - -#if HAVE_GETWD -/* If we didn't get MAXPATHLEN, make it up. */ -#ifndef MAXPATHLEN -#define MAXPATHLEN 1024 -#endif -extern char *getwd (); -#endif /* HAVE_GETWD */ - -/* Prefer gettimeofday to ftime to times. */ - -#if HAVE_GETTIMEOFDAY || HAVE_FTIME -#undef HAVE_TIMES -#define HAVE_TIMES 0 -#endif - -#if HAVE_GETTIMEOFDAY -#undef HAVE_FTIME -#define HAVE_FTIME 0 -#endif - -#if HAVE_GETTIMEOFDAY -#include <sys/time.h> -extern int gettimeofday (); -#endif - -#if HAVE_FTIME -#include <sys/timeb.h> -extern int ftime (); -#endif - -#if HAVE_TIMES -#include <sys/times.h> -#if TIMES_DECLARATION_OK -/* We use a macro to protect this because times really returns clock_t - and on some systems, such as Ultrix 4.0, clock_t is int. We don't - leave it out entirely because on some systems, such as System III, - the declaration is necessary for correct compilation. */ -extern long times (); -#endif - -#if TIMES_TICK == 0 -/* We don't have a value for TIMES_TICK. Look for one. */ -#ifdef CLK_TCK -#undef TIMES_TICK -#define TIMES_TICK CLK_TCK -#else /* ! defined (CLK_TCK) */ -#ifdef HZ -#undef TIMES_TICK -#define TIMES_TICK HZ -#endif /* defined (HZ) */ -#endif /* ! defined (CLK_TCK) */ -#endif /* TIMES_TICK == 0 */ - -#endif /* HAVE_TIMES */ - -/* 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 need wait status information. */ - -#if HAVE_SYS_WAIT_H -#include <sys/wait.h> -#endif - -/* We use a typedef wait_status for wait and related functions to put - results into. We define the POSIX examination functions we need if - they are not already defined (if they aren't defined, I assume that - we have a standard wait status). */ - -#if HAVE_UNION_WAIT -typedef union wait wait_status; -#ifndef WIFEXITED -#define WIFEXITED(u) ((u).w_termsig == 0) -#endif -#ifndef WEXITSTATUS -#define WEXITSTATUS(u) ((u).w_retcode) -#endif -#ifndef WTERMSIG -#define WTERMSIG(u) ((u).w_termsig) -#endif -#else /* ! HAVE_UNION_WAIT */ -typedef int wait_status; -#ifndef WIFEXITED -#define WIFEXITED(i) (((i) & 0xff) == 0) -#endif -#ifndef WEXITSTATUS -#define WEXITSTATUS(i) (((i) >> 8) & 0xff) -#endif -#ifndef WTERMSIG -#define WTERMSIG(i) ((i) & 0x7f) -#endif -#endif /* ! HAVE_UNION_WAIT */ - -/* External variables. */ -extern char **environ; - -/* External functions. */ -#ifndef __386BSD__ -extern int kill (); -#endif __386BSD__ -extern int chdir (), access (), stat (), unlink (), execve (); -extern int close (), pipe (), dup2 (); -extern int fputs (); -extern void _exit (); -extern time_t time (); -extern char *getlogin (), *ttyname (); -extern pid_t getpid (), getppid (), fork (), getpgrp (); -extern uid_t getuid (), geteuid (), getgid (), getegid (); -extern struct tm *localtime (); -#ifndef __386BSD__ -extern struct passwd *getpwuid (); -#endif __386BSD__ -extern struct passwd *getpwnam (); -#if HAVE_GETHOSTNAME -extern int gethostname (); -#endif -#if HAVE_GETCWD -extern char *getcwd (); -#else -#if ! HAVE_GETWD -static char *getcwd P((char *zbuf, int cbuf)); -#endif /* ! HAVE_GETWD */ -#endif /* ! HAVE_GETCWD */ -#if HAVE_GETDTABLESIZE -extern int getdtablesize (); -#endif -#if HAVE_SYSCONF -extern long sysconf (); -#endif -#if HAVE_SETPGRP -#ifndef __386BSD__ -extern int setpgrp (); -#endif __386BSD__ -#endif -#if HAVE_SETSID -#ifndef __386BSD__ -extern int setsid (); -#endif __386BSD__ -#endif -#if HAVE_SIGACTION -extern int sigaction (); -#endif -#if HAVE_SIGVEC -extern int sigvec (); -#endif -#if HAVE_TCP -extern int getsockname (); -#endif - -/* Initialize the system dependent routines. We will probably be running - suid to uucp, so we make sure that nothing is obviously wrong. We - save the login name since we will be losing the real uid. */ -static char *zSlogin; - -/* We save the current directory since we will do a chdir to the - spool directory. */ -char *zScwd; - -/* The maximum length of a system name is controlled by the type of spool - directory we use. */ - -#if SPOOLDIR_V2 | SPOOLDIR_BSD42 | SPOOLDIR_BSD43 | SPOOLDIR_ULTRIX -int cSysdep_max_name_len = 7; -#endif /* SPOOLDIR_V2 | SPOOLDIR_BSD42 | SPOOLDIR_BSD43 | SPOOLDIR_ULTRIX */ -#if SPOOLDIR_BNU -int cSysdep_max_name_len = 14; -#endif /* SPOOLDIR_BNU */ -#if SPOOLDIR_TAYLOR -#if HAVE_LONG_NAMES -int cSysdep_max_name_len = 255; -#else /* ! HAVE_LONG_NAMES */ -int cSysdep_max_name_len = 14; -#endif /* ! HAVE_LONG_NAMES */ -#endif /* SPOOLDIR_TAYLOR */ - -/* The number of available file descriptors. */ - -static int cSdescriptors; - -/* Local functions. */ - -static void xmkdir P((const char *zdir)); -static void usmake_spool_dir P((void)); - -void -usysdep_initialize (fdaemon, fgetcwd) - boolean fdaemon; - boolean fgetcwd; -{ - int o; - char *z; - struct passwd *q; - - ulog_id (getpid ()); - -#if HAVE_GETDTABLESIZE - cSdescriptors = getdtablesize (); -#else -#if HAVE_SYSCONF - cSdescriptors = sysconf (_SC_OPEN_MAX); -#else -#ifdef OPEN_MAX - cSdescriptors = OPEN_MAX; -#else -#ifdef NOFILE - cSdescriptors = NOFILE; -#else - cSdescriptors = 20; -#endif /* ! defined (NOFILE) */ -#endif /* ! defined (OPEN_MAX) */ -#endif /* ! HAVE_SYSCONF */ -#endif /* ! HAVE_GETDTABLESIZE */ - - /* Close everything but stdin, stdout and stderr. */ - - for (o = 3; o < cSdescriptors; o++) - (void) close (o); - - /* Make sure stdin, stdout and stderr are open. Otherwise, newly - opened files will appear to be them and confusion will result. */ - if (fcntl (0, F_GETFD, 0) == -1 - && open ("/dev/null", O_RDONLY, 0) != 0) - exit (EXIT_FAILURE); - if (fcntl (1, F_GETFD, 0) == -1 - && open ("/dev/null", O_WRONLY, 0) != 1) - exit (EXIT_FAILURE); - if (fcntl (2, F_GETFD, 0) == -1 - && open ("/dev/null", O_WRONLY, 0) != 2) - exit (EXIT_FAILURE); - - /* We always set our file modes to exactly what we want. */ - umask (0); - - /* Get the login name, making sure that it matches the uid. Many - systems truncate the getlogin return value to 8 characters, but - keep the full name in the password file, so we prefer the name in - the password file. */ - z = getlogin (); - if (z == NULL) - q = NULL; - else - { - q = getpwnam (z); - if (q != NULL) - z = q->pw_name; - } - if (q == NULL || q->pw_uid != getuid ()) - { - q = getpwuid (getuid ()); - if (q == NULL) - ulog (LOG_FATAL, "Can't get login name"); - z = q->pw_name; - } - zSlogin = xstrdup (z); - - if (fdaemon) - { - /* Set our uid to our effective uid. There is no point in - remembering who originally ran the program. This won't work - on System V, but there's nothing to be done about that and it - doesn't make all that much difference. */ - (void) setuid (geteuid ()); - (void) setgid (getegid ()); - } - - if (fgetcwd) - { - const char *zenv; - struct stat senv, sdot; - - /* Get the current working directory. We have to get it now, - since we're about to do a chdir. We use PWD if it's defined - and if it really names the working directory, since if it's - not the same as whatever getcwd returns it's probably more - appropriate. */ - zenv = getenv ("PWD"); - if (zenv != NULL - && stat (zenv, &senv) == 0 - && stat (".", &sdot) == 0 - && senv.st_ino == sdot.st_ino - && senv.st_dev == sdot.st_dev) - zScwd = xstrdup (zenv); - else - { - -#if HAVE_GETCWD || ! HAVE_GETWD - { - int c; - - c = 128; - while (TRUE) - { - zScwd = (char *) xmalloc (c); - if (getcwd (zScwd, c) != NULL) - break; - if (errno != ERANGE) - ulog (LOG_FATAL, "getcwd: %s", strerror (errno)); - xfree ((pointer) zScwd); - c <<= 1; - } - } -#endif /* HAVE_GETCWD */ - -#if HAVE_GETWD - zScwd = (char *) xmalloc (MAXPATHLEN); - /* The getwd function puts in an error message in the - buffer, rather than setting errno. */ - if (getwd (zScwd) == NULL) - ulog (LOG_FATAL, "getwd: %s", zScwd); -#endif /* HAVE_GETWD */ - - zScwd = (char *) xrealloc ((pointer) zScwd, strlen (zScwd) + 1); - } - } - - /* Connect to the spool directory, and create it if is doesn't - exist. */ - if (chdir (zSpooldir) < 0) - { - if (errno != ENOENT) - ulog (LOG_FATAL, "chdir (%s): %s", zSpooldir, - strerror (errno)); - usmake_spool_dir (); - } -} - -/* Exit the program. */ - -void -usysdep_exit (fsuccess) - boolean fsuccess; -{ - exit (fsuccess ? EXIT_SUCCESS : EXIT_FAILURE); -} - -/* This is called when a non-standard configuration file is used, to - make sure the program doesn't hand out privileged file access. - This means that to test non-standard configuration files, you - should be logged in as uucp. This is called before - usysdep_initialize. It ensures that someone can't simply use an - alternate configuration file to steal UUCP transfers from other - systems. This will still permit people to set up their own - configuration file and pretend to be whatever system they choose. - The only real security is to use a high level of protection on the - modem ports. */ - -/*ARGSUSED*/ -boolean fsysdep_other_config (z) - const char *z; -{ - (void) setuid (getuid ()); - (void) setgid (getgid ()); - return TRUE; -} - -/* Detach from the controlling terminal. This is called by uucico if - it is calling out to another system, so that it can receive SIGHUP - signals from the port it calls out on. It is also called by uucico - just before it starts uuxqt, so that uuxqt is completely - independent of the terminal. */ - -#ifdef TIOCNOTTY -#define HAVE_TIOCNOTTY 1 -#else -#define HAVE_TIOCNOTTY 0 -#endif - -void -usysdep_detach () -{ - int o; - -#if ! HAVE_BSD_PGRP || ! HAVE_TIOCNOTTY - - pid_t igrp; - - /* First make sure we are not a process group leader. If we have - TIOCNOTTY, this doesn't matter, since TIOCNOTTY sets our process - group to 0 anyhow. */ - -#if HAVE_BSD_PGRP - igrp = getpgrp (0); -#else - igrp = getpgrp (); -#endif - - if (igrp == getpid ()) - { - boolean fignored; - pid_t ipid; - - /* Ignore SIGHUP, since our process group leader is about to - die. */ - usset_signal (SIGHUP, SIG_IGN, FALSE, &fignored); - - ipid = isfork (); - if (ipid < 0) - ulog (LOG_FATAL, "fork: %s", strerror (errno)); - - if (ipid != 0) - _exit (EXIT_SUCCESS); - - /* We'll always wind up as a child of process number 1, right? - Right? We have to wait for our parent to die before - reenabling SIGHUP. */ - while (getppid () != 1) - sleep (1); - - /* Restore SIGHUP catcher if it wasn't being ignored. */ - if (! fignored) - usset_signal (SIGHUP, ussignal, TRUE, (boolean *) NULL); - } - -#endif /* ! HAVE_BSD_PGRP || ! HAVE_TIOCNOTTY */ - - /* Close all open files. */ - - ulog_close (); - - for (o = 0; o < cSdescriptors; o++) - (void) close (o); - - /* Reopen stdin, stdout and stderr. */ - - if (open ("/dev/null", O_RDONLY) != 0 - || open ("/dev/null", O_WRONLY) != 1 - || open ("/dev/null", O_WRONLY) != 2) - ulog (LOG_FATAL, "open (/dev/null): %s", strerror (errno)); - -#if HAVE_BSD_PGRP - -#if HAVE_TIOCNOTTY - /* Lose our controlling terminal. */ - -#ifndef O_NDELAY -#define O_NDELAY FNDELAY -#endif - - o = open ("/dev/tty", O_RDWR | O_NDELAY, 0); - if (o >= 0) - { - (void) ioctl (o, TIOCNOTTY, (char *) NULL); - (void) close (o); - } -#endif /* HAVE_TIOCNOTTY */ - - /* Make sure our process group ID is set to 0. On BSD TIOCNOTTY - should already have set it 0, so this will do no harm. On System - V we presumably did not execute the TIOCNOTTY call, but the - System V setpgrp will detach the controlling terminal anyhow. - This lets us use the same code on both BSD and System V, provided - it compiles correctly, which life easier for the configure - script. We don't output an error if we got EPERM because some - BSD variants don't permit this usage of setpgrp (which means they - don't provide any way to pick up a new controlling terminal). */ - - if (setpgrp (0, 0) < 0) - { - if (errno != EPERM) - ulog (LOG_ERROR, "setpgrp: %s", strerror (errno)); - } - -#else /* ! HAVE_BSD_PGRP */ - -#if HAVE_SETSID - - /* Under POSIX the setsid call creates a new session for which we - are the process group leader. It also detaches us from our - controlling terminal. I'm using the BSD setpgrp call first - because they should be equivalent for my purposes, but it turns - out that on Ultrix 4.0 setsid prevents us from ever acquiring - another controlling terminal (it does not change our process - group, and Ultrix 4.0 prevents us from setting our process group - to 0). */ - - if (setsid () < 0) - ulog (LOG_ERROR, "setsid: %s", strerror (errno)); - -#else /* ! HAVE_SETSID */ - -#if HAVE_SETPGRP - - /* Now we assume we have the System V setpgrp, which takes no - arguments, and we couldn't compile the HAVE_BSD_PGRP code above - because there was a prototype somewhere in scope. On System V - setpgrp makes us the leader of a new process group and also - detaches the controlling terminal. */ - - if (setpgrp () < 0) - ulog (LOG_ERROR, "setpgrp: %s", strerror (errno)); - -#else /* ! HAVE_SETPGRP */ - - #error Must detach from controlling terminal - -#endif /* HAVE_SETPGRP */ -#endif /* ! HAVE_SETSID */ -#endif /* ! HAVE_BSD_PGRP */ - - /* At this point we have completely detached from our controlling - terminal. The next terminal device we open will probably become - our controlling terminal. */ -} - -/* Get the node name to use if it was not specified in the configuration - file. */ - -const char * -zsysdep_local_name () -{ -#if HAVE_GETHOSTNAME - char ab[256]; - - if (gethostname (ab, sizeof ab) < 0) - { - ulog (LOG_ERROR, "gethostname: %s", strerror (errno)); - return NULL; - } - ab[sizeof ab - 1] = '\0'; - ab[strcspn (ab, ".")] = '\0'; - return xstrdup (ab); -#else /* ! HAVE_GETHOSTNAME */ -#if HAVE_UNAME - struct utsname s; - - if (uname (&s) < 0) - { - ulog (LOG_ERROR, "uname: %s", strerror (errno)); - return NULL; - } - return xstrdup (s.nodename); -#else /* ! HAVE_UNAME */ - return NULL; -#endif /* ! HAVE_UNAME */ -#endif /* ! HAVE_GETHOSTNAME */ -} - -/* Get the login name. We actually get the login name in - usysdep_initialize, because after that we will lost the real uid. */ - -const char * -zsysdep_login_name () -{ - return zSlogin; -} - -/* Get the port name of standard input. I assume that Unix systems - generally support ttyname. If they don't, this function can just - return NULL. It uses getsockname to see whether standard input is - a TCP connection. */ - -const char * -zsysdep_port_name (ftcp_port) - boolean *ftcp_port; -{ - const char *z; - - *ftcp_port = FALSE; - -#if HAVE_TCP - { - int clen; - - clen = 0; - if (getsockname (0, (struct sockaddr *) NULL, &clen) == 0) - *ftcp_port = TRUE; - } -#endif /* HAVE_TCP */ - - z = ttyname (0); - if (z == NULL) - return NULL; - if (strncmp (z, "/dev/", 5) == 0) - return z + 5; - else - return z; -} - -/* Signal handling routines. When we catch a signal, we want to set - the appropriate elements of afSignal and afLog_signal to TRUE. If - we are on a system which restarts system calls, we may also want to - longjmp out. On a system which does not restart system calls, - these signal handling routines are well-defined by ANSI C. */ - -#if HAVE_RESTARTABLE_SYSCALLS -volatile sig_atomic_t fSjmp; -volatile jmp_buf sSjmp_buf; -#endif /* HAVE_RESTARTABLE_SYSCALLS */ - -/* The SVR3 sigset function can be called just like signal, unless - system calls are restarted which is extremely unlikely; we prevent - this case in sysh.unx. */ -#if HAVE_SIGSET && ! HAVE_SIGACTION && ! HAVE_SIGVEC -#define signal sigset -#endif - -/* Catch a signal. Reinstall the signal handler if necessary, set the - appropriate variables, and do a longjmp if necessary. */ - -SIGtype -ussignal (isig) - int isig; -{ - int iindex; - -#if ! HAVE_SIGACTION && ! HAVE_SIGVEC && ! HAVE_SIGSET - (void) signal (isig, ussignal); -#endif - - switch (isig) - { - default: iindex = INDEXSIG_SIGHUP; break; -#ifdef SIGINT - case SIGINT: iindex = INDEXSIG_SIGINT; break; -#endif -#ifdef SIGQUIT - case SIGQUIT: iindex = INDEXSIG_SIGQUIT; break; -#endif -#ifdef SIGTERM - case SIGTERM: iindex = INDEXSIG_SIGTERM; break; -#endif -#ifdef SIGPIPE - case SIGPIPE: iindex = INDEXSIG_SIGPIPE; break; -#endif - } - - afSignal[iindex] = TRUE; - afLog_signal[iindex] = TRUE; - -#if HAVE_RESTARTABLE_SYSCALLS - if (fSjmp) - longjmp (sSjmp_buf, 1); -#endif /* HAVE_RESTARTABLE_SYSCALLS */ -} - -/* Prepare to catch a signal. This is basically the ANSI C routine - signal, but it uses sigaction or sigvec instead if they are - available. If fforce is FALSE, we do not set the signal if it is - currently being ignored. If pfignored is not NULL and fforce is - FALSE, then *pfignored will be set to TRUE if the signal was - previously being ignored (if fforce is TRUE the value of *pfignored - is meaningless). If we can't change the signal handler we give a - fatal error. */ - -void -usset_signal (isig, pfn, fforce, pfignored) - int isig; - SIGtype (*pfn) P((int)); - boolean fforce; - boolean *pfignored; -{ -#if HAVE_SIGACTION - - struct sigaction s; - - if (! fforce) - { - sigemptyset (&s.sa_mask); - if (sigaction (isig, (struct sigaction *) NULL, &s) != 0) - ulog (LOG_FATAL, "sigaction (%d): %s", isig, strerror (errno)); - - if (s.sa_handler == SIG_IGN) - { - if (pfignored != NULL) - *pfignored = TRUE; - return; - } - - if (pfignored != NULL) - *pfignored = FALSE; - } - - s.sa_handler = pfn; - sigemptyset (&s.sa_mask); - s.sa_flags = 0; - - if (sigaction (isig, &s, (struct sigaction *) NULL) != 0) - ulog (LOG_FATAL, "sigaction (%d): %s", isig, strerror (errno)); - -#else /* ! HAVE_SIGACTION */ -#if HAVE_SIGVEC - - struct sigvec s; - - if (! fforce) - { - if (sigvec (isig, (struct sigvec *) NULL, &s) != 0) - ulog (LOG_FATAL, "sigvec (%d): %s", isig, strerror (errno)); - - if (s.sv_handler == SIG_IGN) - { - if (pfignored != NULL) - *pfignored = TRUE; - return; - } - - if (pfignored != NULL) - *pfignored = FALSE; - } - - s.sv_handler = pfn; - s.sv_mask = 0; -#ifdef SV_INTERRUPT - s.sv_flags = SV_INTERRUPT; -#else - s.sv_flags = 0; -#endif - - if (sigvec (isig, &s, (struct sigvec *) NULL) != 0) - ulog (LOG_FATAL, "sigvec (%d): %s", isig, strerror (errno)); - -#else /* ! HAVE_SIGVEC */ - - if (! fforce) - { - if (signal (isig, SIG_IGN) == SIG_IGN) - { - if (pfignored != NULL) - *pfignored = TRUE; - return; - } - - if (pfignored != NULL) - *pfignored = FALSE; - } - - (void) signal (isig, pfn); - -#endif /* ! HAVE_SIGVEC */ -#endif /* ! HAVE_SIGACTION */ -} - -/* The routine called by the system independent code, which always - uses the same signal handler. */ - -void -usysdep_signal (isig) - int isig; -{ - usset_signal (isig, ussignal, FALSE, (boolean *) NULL); -} - -/* Get the time in seconds since the epoch, with optional - microseconds. We use usysdep_process_time to get the microseconds - if it will work (it won't is it uses times, since that returns a - time based only on the process). */ - -long -isysdep_time (pimicros) - long *pimicros; -{ -#if HAVE_GETTIMEOFDAY || HAVE_FTIME - return isysdep_process_time (pimicros); -#else - if (pimicros != NULL) - *pimicros = 0; - return time ((time_t *) NULL); -#endif -} - -/* Get the time in seconds and microseconds; this need only work - within the process when called from the system independent code. - It is also called by isysdep_time, above. */ - -long -isysdep_process_time (pimicros) - long *pimicros; -{ -#if HAVE_GETTIMEOFDAY - struct timeval stime; - struct timezone stz; - - (void) gettimeofday (&stime, &stz); - if (pimicros != NULL) - *pimicros = stime.tv_usec; - return stime.tv_sec; -#endif /* HAVE_GETTIMEOFDAY */ - -#if HAVE_FTIME - struct timeb stime; - - (void) ftime (&stime); - if (pimicros != NULL) - *pimicros = stime.millitm * 1000; - return stime.time; -#endif /* HAVE_FTIME */ - -#if HAVE_TIMES - struct tms s; - long i; - static int itick; - - if (itick == 0) - { -#if TIMES_TICK != 0 - itick = TIMES_TICK; -#else /* TIMES_TICK == 0 */ - const char *z; - - z = getenv ("HZ"); - if (z != NULL) - itick = atoi (z); - - /* If we really couldn't get anything, just use 60. */ - if (itick == 0) - itick = 60; -#endif /* TIMES_TICK == 0 */ - } - - i = (long) times (&s); - if (pimicros != NULL) - *pimicros = (i % (long) itick) * ((long) 1000000 / (long) itick); - return i / (long) itick; -#endif /* HAVE_TIMES */ - -#if ! HAVE_GETTIMEOFDAY && ! HAVE_FTIME && ! HAVE_TIMES - if (pimicros != NULL) - *pimicros = 0; - return time ((time_t *) NULL); -#endif /* ! HAVE_GETTIMEOFDAY && ! HAVE_FTIME && ! HAVE_TIMES */ -} - -/* Fill in a struct tm. */ - -void -usysdep_localtime (itime, q) - long itime; - struct tm *q; -{ - time_t i; - - i = (time_t) itime; - memcpy (q, localtime (&i), sizeof (struct tm)); -} - -/* Sleep for a number of seconds. */ - -void -usysdep_sleep (c) - int c; -{ - sleep (c); -} - -/* Check whether a file exists. */ - -boolean -fsysdep_file_exists (zfile) - const char *zfile; -{ - struct stat s; - - return stat (zfile, &s) == 0; -} - -/* Open a stdio file with appropriate permissions. */ - -FILE * -esysdep_fopen (zfile, fpublic, fappend, fmkdirs) - const char *zfile; - boolean fpublic; - boolean fappend; - boolean fmkdirs; -{ - int imode; - int o; - FILE *e; - - if (fpublic) - imode = IPUBLIC_FILE_MODE; - else - imode = IPRIVATE_FILE_MODE; - - if (! fappend) - o = creat (zfile, imode); - else - { -#ifdef O_CREAT - o = open (zfile, O_WRONLY | O_APPEND | O_CREAT | O_NOCTTY, imode); -#else - o = open (zfile, O_WRONLY | O_NOCTTY); - if (o < 0 && errno == ENOENT) - o = creat (zfile, imode); -#endif /* ! defined (O_CREAT) */ - } - - if (o < 0) - { - if (errno == ENOENT && fmkdirs) - { - if (! fsysdep_make_dirs (zfile, fpublic)) - return NULL; - if (! fappend) - o = creat (zfile, imode); - else - { -#ifdef O_CREAT - o = open (zfile, O_WRONLY | O_APPEND | O_CREAT, imode); -#else - o = creat (zfile, imode); -#endif - } - } - if (o < 0) - { - ulog (LOG_ERROR, "open (%s): %s", zfile, strerror (errno)); - return NULL; - } - } - -#ifndef O_CREAT -#ifdef O_APPEND - if (fappend) - { - if (fcntl (o, F_SETFL, O_APPEND) != 0) - { - ulog (LOG_ERROR, "fcntl (%s, O_APPEND): %s", zfile, - strerror (errno)); - (void) close (o); - return NULL; - } - } -#endif /* defined (O_APPEND) */ -#endif /* ! defined (O_CREAT) */ - - if (fappend) - e = fdopen (o, (char *) "a"); - else - e = fdopen (o, (char *) "w"); - - if (e == NULL) - { - ulog (LOG_ERROR, "fdopen: %s", strerror (errno)); - (void) close (o); - } - - return e; -} - -/* See whether a directory exists. */ - -boolean -fsdirectory_exists (z) - const char *z; -{ - struct stat s; - - if (stat (z, &s) < 0) - return FALSE; - return S_ISDIR (s.st_mode); -} - -/* Create any directories needed for a file name. */ - -boolean -fsysdep_make_dirs (zfile, fpublic) - const char *zfile; - boolean fpublic; -{ - char *zcopy, *z; - int imode; - - zcopy = (char *) alloca (strlen (zfile) + 1); - strcpy (zcopy, zfile); - - if (fpublic) - imode = IPUBLIC_DIRECTORY_MODE; - else - imode = IDIRECTORY_MODE; - - for (z = zcopy; *z != '\0'; z++) - { - if (*z == '/' && z != zcopy) - { - *z = '\0'; - if (! fsdirectory_exists (zcopy)) - { - if (mkdir (zcopy, imode) != 0) - { - ulog (LOG_ERROR, "mkdir (%s): %s", zcopy, - strerror (errno)); - return FALSE; - } - } - *z = '/'; - } - } - - return TRUE; -} - -/* Tilde expand a file or directory name. */ - -/*ARGSUSED*/ -const char * -zstilde_expand (qsys, zfile) - const struct ssysteminfo *qsys; - const char *zfile; -{ - static int calc; - static char *zalc; - const char *zdir; - int clen; - - if (zfile[0] != '~') - return zfile; - else if (zfile[1] == '\0' || zfile[1] == '/') - { - const char *zpub; - - if (qsys->zpubdir == NULL) - zpub = zPubdir; - else - zpub = qsys->zpubdir; - if (zfile[1] == '\0') - return zpub; - else - { - zdir = zpub; - zfile += 2; - } - } - else - { - int cuserlen; - char *zcopy; - struct passwd *q; - - ++zfile; - cuserlen = strcspn (zfile, "/"); - zcopy = (char *) alloca (cuserlen + 1); - strncpy (zcopy, zfile, cuserlen); - zcopy[cuserlen] = '\0'; - - q = getpwnam (zcopy); - if (q == NULL) - { - ulog (LOG_ERROR, "User %s not found", zcopy); - return NULL; - } - - if (zfile[cuserlen] == '\0') - return q->pw_dir; - else - { - zdir = q->pw_dir; - zfile += cuserlen + 1; - } - } - - clen = strlen (zdir) + strlen (zfile) + 2; - if (clen > calc) - { - zalc = (char *) xrealloc ((pointer) zalc, clen); - calc = clen; - } - - sprintf (zalc, "%s/%s", zdir, zfile); - return zalc; -} - -/* Do access(2) on a stat structure, except that the user name is - provided. If the user name in zuser is NULL, require the file to - be accessible to the world. Return TRUE if access is permitted, - FALSE otherwise. This does not log an error message. */ - -boolean -fsuser_access (q, imode, zuser) - const struct stat *q; - int imode; - const char *zuser; -{ - static char *zuser_hold; - static uid_t iuid_hold; - static gid_t igid_hold; - static int cgroups_hold; - static gid_t *paigroups_hold; - int ir, iw, ix, iand; - - if (imode == F_OK) - return TRUE; - - if (zuser != NULL) - { - /* We keep static variables around for the last user we did, to - avoid looking up a user multiple times. */ - if (zuser_hold == NULL || strcmp (zuser_hold, zuser) != 0) - { - struct passwd *qpwd; - - if (zuser_hold != NULL) - { - xfree ((pointer) zuser_hold); - zuser_hold = NULL; - cgroups_hold = 0; - xfree ((pointer) paigroups_hold); - paigroups_hold = NULL; - } - - qpwd = getpwnam ((char *) zuser); - if (qpwd == NULL) - { - /* Check this as a remote request. */ - zuser = NULL; - } - else - { -#if HAVE_GETGRENT - struct group *qg; -#endif - - zuser_hold = xstrdup (zuser); - - iuid_hold = qpwd->pw_uid; - igid_hold = qpwd->pw_gid; - -#if HAVE_GETGRENT - /* Get the list of groups for this user. This is - definitely more appropriate for BSD than for System - V. It may just be a waste of time, and perhaps it - should be configurable. */ - setgrent (); - while ((qg = getgrent ()) != NULL) - { - const char **pz; - - if (qg->gr_gid == igid_hold) - continue; - for (pz = (const char **) qg->gr_mem; *pz != NULL; pz++) - { - if ((*pz)[0] == *zuser - && strcmp (*pz, zuser) == 0) - { - paigroups_hold = ((gid_t *) - (xrealloc - ((pointer) paigroups_hold, - ((cgroups_hold + 1) - * sizeof (gid_t))))); - paigroups_hold[cgroups_hold] = qg->gr_gid; - ++cgroups_hold; - break; - } - } - } - endgrent (); -#endif - } - } - } - - - /* Now do the actual access check. */ - - if (zuser != NULL) - { - /* The superuser can do anything. */ - if (iuid_hold == 0) - return TRUE; - - /* If this is the uid we're running under, there's no point to - checking access further, because when we actually try the - operation the system will do the checking for us. */ - if (iuid_hold == geteuid ()) - return TRUE; - } - - ir = S_IROTH; - iw = S_IWOTH; - ix = S_IXOTH; - - if (zuser != NULL) - { - if (iuid_hold == q->st_uid) - { - ir = S_IRUSR; - iw = S_IWUSR; - ix = S_IXUSR; - } - else - { - boolean fgroup; - - fgroup = FALSE; - if (igid_hold == q->st_gid) - fgroup = TRUE; - else - { - int i; - - for (i = 0; i < cgroups_hold; i++) - { - if (paigroups_hold[i] == q->st_gid) - { - fgroup = TRUE; - break; - } - } - } - - if (fgroup) - { - ir = S_IRGRP; - iw = S_IWGRP; - ix = S_IXGRP; - } - } - } - - iand = 0; - if ((imode & R_OK) != 0) - iand |= ir; - if ((imode & W_OK) != 0) - iand |= iw; - if ((imode & X_OK) != 0) - iand |= ix; - - return (q->st_mode & iand) == iand; -} - -/* See whether a file is in a directory, and optionally check access. */ - -boolean -fsysdep_in_directory (qsys, zfile, zdir, fcheck, freadable, zuser) - const struct ssysteminfo *qsys; - const char *zfile; - const char *zdir; - boolean fcheck; - boolean freadable; - const char *zuser; -{ - int c; - char *zcopy, *zslash; - struct stat s; - - if (*zdir == '~') - { - zdir = zstilde_expand (qsys, zdir); - if (zdir == NULL) - return FALSE; - } - c = strlen (zdir); - if (zdir[c - 1] == '/') - c--; - if (strncmp (zfile, zdir, c) != 0 - || (zfile[c] != '/' && zfile[c] != '\0')) - return FALSE; - if (strstr (zfile + c, "/../") != NULL) - return FALSE; - - /* If we're not checking access, get out now. */ - - if (! fcheck) - return TRUE; - - zcopy = (char *) alloca (strlen (zfile) + 1); - strcpy (zcopy, zfile); - - /* Start checking directories after zdir. Otherwise, we would - require that all directories down to /usr/spool/uucppublic be - publically searchable; they probably are but it should not be - requirement. */ - - zslash = zcopy + c; - do - { - char b; - struct stat shold; - - b = *zslash; - *zslash = '\0'; - - shold = s; - if (stat (zcopy, &s) != 0) - { - if (errno != ENOENT) - { - ulog (LOG_ERROR, "stat (%s): %s", zcopy, strerror (errno)); - return FALSE; - } - - /* If this is the top directory, any problems will be caught - later when we try to open it. */ - if (zslash == zcopy + c) - return TRUE; - - /* Go back and check the last directory for read or write - access. */ - s = shold; - break; - } - - /* If this is not a directory, get out of the loop. */ - if (! S_ISDIR (s.st_mode)) - break; - - /* Make sure the directory is searchable. */ - if (! fsuser_access (&s, X_OK, zuser)) - { - ulog (LOG_ERROR, "%s: %s", zcopy, strerror (EACCES)); - return FALSE; - } - - /* If we've reached the end of the string, get out. */ - if (b == '\0') - break; - - *zslash = b; - } - while ((zslash = strchr (zslash + 1, '/')) != NULL); - - /* At this point s holds a stat on the last component of the path. - We must check it for readability or writeability. */ - - if (! fsuser_access (&s, freadable ? R_OK : W_OK, zuser)) - { - ulog (LOG_ERROR, "%s: %s", zcopy, strerror (EACCES)); - return FALSE; - } - - return TRUE; -} - -/* Start up a new program and end the current one. We always go - through isspawn, and never exec directly. We don't have to worry - about SIGHUP because the current process is either not a process - group leader (uucp, uux) or it does not have a controlling terminal - (uucico). */ - -boolean -fsysdep_run (ffork, zprogram, zarg1, zarg2) - boolean ffork; - const char *zprogram; - const char *zarg1; - const char *zarg2; -{ - char *zlib; - const char *azargs[4]; - int aidescs[3]; - pid_t ipid; - - zlib = (char *) alloca (sizeof LIBDIR + sizeof "/" + strlen (zprogram)); - sprintf (zlib, "%s/%s", LIBDIR, zprogram); - - azargs[0] = zlib; - azargs[1] = zarg1; - azargs[2] = zarg2; - azargs[3] = NULL; - - aidescs[0] = SPAWN_NULL; - aidescs[1] = SPAWN_NULL; - aidescs[2] = SPAWN_NULL; - - /* We pass fshell as TRUE, which permits uucico and uuxqt to be - replaced by shell scripts. */ - ipid = isspawn (azargs, aidescs, FALSE, FALSE, (const char *) NULL, - FALSE, TRUE, (const char *) NULL, - (const char *) NULL, (const char *) NULL); - if (ipid < 0) - { - ulog (LOG_ERROR, "isspawn: %s", strerror (errno)); - return FALSE; - } - - if (ffork) - return TRUE; - - exit (EXIT_SUCCESS); -} - -/* Mail a message to a user. */ - -boolean -fsysdep_mail (zto, zsubject, cstrs, paz) - const char *zto; - const char *zsubject; - int cstrs; - const char **paz; -{ - const char *az[3]; - FILE *e; - pid_t ipid; - time_t itime; - int i; - - az[0] = MAIL_PROGRAM; - az[1] = zto; - az[2] = NULL; - - e = espopen (az, FALSE, &ipid); - if (e == NULL) - { - ulog (LOG_ERROR, "espopen (%s): %s", MAIL_PROGRAM, - strerror (errno)); - return FALSE; - } - - fprintf (e, "Subject: %s\n", zsubject); - fprintf (e, "To: %s\n", zto); - - /* We should probably put in a Date: header as well. */ - - fprintf (e, "\n"); - - (void) time (&itime); - /* Remember that ctime includes a \n, so this skips a line. */ - fprintf (e, "Message from UUCP on %s %s\n", zLocalname, - ctime (&itime)); - - for (i = 0; i < cstrs; i++) - fputs (paz[i], e); - - (void) fclose (e); - - return iswait ((unsigned long) ipid, MAIL_PROGRAM) == 0; -} - -/* Make a directory with error checking. */ - -static void -xmkdir (zdir) - const char *zdir; -{ - if (mkdir ((char *) zdir, IDIRECTORY_MODE) < 0) - ulog (LOG_FATAL, "mkdir (%s): %s", zdir, strerror (errno)); -} - -/* Make the spool directory. */ - -static void -usmake_spool_dir () -{ - xmkdir (zSpooldir); - - if (chdir (zSpooldir) < 0) - ulog (LOG_FATAL, "chdir (%s): %s", zSpooldir, strerror (errno)); - -#if SPOOLDIR_BSD42 | SPOOLDIR_BSD43 - xmkdir ("C."); - xmkdir ("D."); -#if SPOOLDIR_BSD43 - xmkdir ("X."); -#endif /* SPOOLDIR_BSD43 */ - { - char ab[sizeof "D.1234567X"]; - - sprintf (ab, "D.%.7s", zLocalname); - xmkdir (ab); -#if SPOOLDIR_BSD43 - strcat (ab, "X"); - xmkdir (ab); -#endif /* SPOOLDIR_BSD43 */ - } -#endif /* SPOOLDIR_BSD42 | SPOOLDIR_BSD43 */ - -#if SPOOLDIR_ULTRIX - xmkdir ("sys"); - xmkdir ("sys/DEFAULT"); - xmkdir ("sys/DEFAULT/C."); - xmkdir ("sys/DEFAULT/D."); - xmkdir ("sys/DEFAULT/X."); - { - char ab[sizeof "sys/DEFAULT/D.1234567X"]; - - sprintf (ab, "sys/DEFAULT/D.%.7s", zLocalname); - xmkdir (ab); - strcat (ab, "X"); - xmkdir (ab); - } -#endif /* SPOOLDIR_ULTRIX */ - -#if SPOOLDIR_BSD43 | SPOOLDIR_ULTRIX | SPOOLDIR_TAYLOR - xmkdir (".Temp"); -#endif /* SPOOLDIR_BSD43 | SPOOLDIR_ULTRIX | SPOOLDIR_TAYLOR */ - - xmkdir (".Status"); - xmkdir (".Sequence"); - xmkdir (XQTDIR); - xmkdir (PRESERVEDIR); -} - -/* Retry fork several times before giving up. */ - -pid_t -isfork () -{ - int i; - pid_t iret; - - for (i = 0; i < 10; i++) - { - iret = fork (); - if (iret >= 0 || errno != EAGAIN) - return iret; - sleep (5); - } - - return iret; -} - -/* Spawn a child in a fairly secure fashion. This returns the process - ID of the child or -1 on error. It takes far too many arguments: - - pazargs -- arguments (element 0 is command) - aidescs -- file descriptors for stdin, stdout and stderr - fkeepuid -- TRUE if euid should be left unchanged - fkeepenv -- TRUE if environment should be left unmodified - zchdir -- directory to chdir to - fnosigs -- TRUE if child should ignore SIGHUP, SIGINT and SIGQUIT - fshell -- TRUE if should try /bin/sh if execve gets ENOEXEC - zpath -- value for environment variable PATH - zuu_machine -- value for environment variable UU_MACHINE - zuu_user -- value for environment variable UU_USER - - The aidescs array is three elements long. 0 is stdin, 1 is stdout - and 2 is stderr. The array may contain either file descriptor - numbers to dup appropriately, or one of the following: - - SPAWN_NULL -- set descriptor to /dev/null - SPAWN_READ_PIPE -- set aidescs element to pipe for parent to read - SPAWN_WRITE_PIPE -- set aidescs element to pipe for parent to write - - If fkeepenv is FALSE, a standard environment is created. The - environment arguments (zpath, zuu_machine and zuu_user) are only - used if fkeepenv is FALSE; any of them may be NULL. */ - -pid_t -isspawn (pazargs, aidescs, fkeepuid, fkeepenv, zchdir, fnosigs, fshell, - zpath, zuu_machine, zuu_user) - const char **pazargs; - int aidescs[3]; - boolean fkeepuid; - boolean fkeepenv; - const char *zchdir; - boolean fnosigs; - boolean fshell; - const char *zpath; - const char *zuu_machine; - const char *zuu_user; -{ - char *zshcmd = NULL; - int i; - char *azenv[9]; - char **pazenv; - boolean ferr; - int ierr = 0; - int onull; - int aichild_descs[3]; - int cpar_close; - int aipar_close[4]; - int cchild_close; - int aichild_close[3]; - pid_t iret = 0; - const char *zcmd; - - /* If we might have to use the shell, allocate enough space for the - quoted command before forking. Otherwise the allocation might - modify the data segment and we could not safely use vfork. */ - if (fshell) - { - int clen; - - clen = 0; - for (i = 0; pazargs[i] != NULL; i++) - clen += strlen (pazargs[i]); - zshcmd = (char *) alloca (2 * clen + i); - } - - /* Set up a standard environment. This is again done before forking - because it might modify the data segment. */ - - if (fkeepenv) - pazenv = environ; - else - { - const char *zterm, *ztz; - char *zspace; - int ienv; - - if (zpath == NULL) - zpath = CMDPATH; - - azenv[0] = (char *) alloca (sizeof "PATH=" + strlen (zpath)); - sprintf (azenv[0], "PATH=%s", zpath); - zspace = azenv[0] + sizeof "PATH=" - 1; - while ((zspace = strchr (zspace, ' ')) != NULL) - *zspace = ':'; - - azenv[1] = (char *) alloca (sizeof "HOME=" + strlen (zSpooldir)); - sprintf (azenv[1], "HOME=%s", zSpooldir); - - zterm = getenv ("TERM"); - if (zterm == NULL) - zterm = "unknown"; - azenv[2] = (char *) alloca (sizeof "TERM=" + strlen (zterm)); - sprintf (azenv[2], "TERM=%s", zterm); - - azenv[3] = (char *) "SHELL=/bin/sh"; - - azenv[4] = (char *) alloca (sizeof "USER=" + strlen (OWNER)); - sprintf (azenv[4], "USER=%s", OWNER); - - ienv = 5; - - ztz = getenv ("TZ"); - if (ztz != NULL) - { - azenv[ienv] = (char *) alloca (sizeof "TZ=" + strlen (ztz)); - sprintf (azenv[ienv], "TZ=%s", ztz); - ++ienv; - } - - if (zuu_machine != NULL) - { - azenv[ienv] = (char *) alloca (sizeof "UU_MACHINE=" - + strlen (zuu_machine)); - sprintf (azenv[ienv], "UU_MACHINE=%s", zuu_machine); - ++ienv; - } - - if (zuu_user != NULL) - { - azenv[ienv] = (char *) alloca (sizeof "UU_USER=" - + strlen (zuu_user)); - sprintf (azenv[ienv], "UU_USER=%s", zuu_user); - ++ienv; - } - - azenv[ienv] = NULL; - pazenv = azenv; - } - - /* Set up any needed pipes. */ - - ferr = FALSE; - onull = -1; - cpar_close = 0; - cchild_close = 0; - - for (i = 0; i < 3; i++) - { - if (aidescs[i] == SPAWN_NULL) - { - if (onull < 0) - { - onull = open ("/dev/null", O_RDWR); - if (onull < 0) - { - ierr = errno; - ferr = TRUE; - break; - } - aipar_close[cpar_close] = onull; - ++cpar_close; - } - aichild_descs[i] = onull; - } - else if (aidescs[i] != SPAWN_READ_PIPE - && aidescs[i] != SPAWN_WRITE_PIPE) - aichild_descs[i] = aidescs[i]; - else - { - int aipipe[2]; - - if (pipe (aipipe) < 0) - { - ierr = errno; - ferr = TRUE; - break; - } - - if (aidescs[i] == SPAWN_READ_PIPE) - { - aidescs[i] = aipipe[0]; - aichild_close[cchild_close] = aipipe[0]; - aichild_descs[i] = aipipe[1]; - aipar_close[cpar_close] = aipipe[1]; - } - else - { - aidescs[i] = aipipe[1]; - aichild_close[cchild_close] = aipipe[1]; - aichild_descs[i] = aipipe[0]; - aipar_close[cpar_close] = aipipe[0]; - } - - ++cpar_close; - ++cchild_close; - } - } - -#if DEBUG > 1 - if (! ferr && FDEBUGGING (DEBUG_EXECUTE)) - { - ulog (LOG_DEBUG_START, "Forking %s", pazargs[0]); - for (i = 1; pazargs[i] != NULL; i++) - ulog (LOG_DEBUG_CONTINUE, " %s", pazargs[i]); - ulog (LOG_DEBUG_END, "%s", ""); - } -#endif - - if (! ferr) - { - /* This should really be vfork if available. */ - iret = isfork (); - if (iret < 0) - { - ferr = TRUE; - ierr = errno; - } - } - - if (ferr) - { - for (i = 0; i < cpar_close; i++) - (void) close (aipar_close[i]); - for (i = 0; i < cchild_close; i++) - (void) close (aichild_close[i]); - errno = ierr; - return -1; - } - - /* Here the fork has succeeded and all the pipes have been done. */ - - if (iret != 0) - { - /* The parent. Close the child's ends of the pipes and return - the process ID. */ - for (i = 0; i < cpar_close; i++) - (void) close (aipar_close[i]); - return iret; - } - - /* The child. */ - -#ifdef STDIN_FILENO -#if STDIN_FILENO != 0 || STDOUT_FILENO != 1 || STDERR_FILENO != 2 - #error The following code makes invalid assumptions -#endif -#endif - - for (i = 0; i < 3; i++) - if (aichild_descs[i] != i) - (void) dup2 (aichild_descs[i], i); - - for (i = 3; i < cSdescriptors; i++) - (void) close (i); - - zcmd = pazargs[0]; - pazargs[0] = strrchr (zcmd, '/'); - if (pazargs[0] == NULL) - pazargs[0] = zcmd; - else - ++pazargs[0]; - - if (! fkeepuid) - { - (void) setuid (getuid ()); - (void) setgid (getgid ()); - } - - if (zchdir != NULL) - (void) chdir (zchdir); - - if (fnosigs) - { -#ifdef SIGHUP - (void) signal (SIGHUP, SIG_IGN); -#endif -#ifdef SIGINT - (void) signal (SIGINT, SIG_IGN); -#endif -#ifdef SIGQUIT - (void) signal (SIGQUIT, SIG_IGN); -#endif - } - - (void) execve ((char *) zcmd, (char **) pazargs, pazenv); - - /* The exec failed. If permitted, try using /bin/sh to execute a - shell script. */ - - if (errno == ENOEXEC && fshell) - { - char *zto; - const char *azshargs[4]; - - pazargs[0] = zcmd; - zto = zshcmd; - for (i = 0; pazargs[i] != NULL; i++) - { - const char *zfrom; - - for (zfrom = pazargs[i]; *zfrom != '\0'; zfrom++) - { - /* Some versions of /bin/sh appear to have a bug such - that quoting a '/' sometimes causes an error. I - don't know exactly when this happens (I can recreate - it on Ultrix 4.0), but in any case it is harmless to - not quote a '/'. */ - if (*zfrom != '/') - *zto++ = '\\'; - *zto++ = *zfrom; - } - *zto++ = ' '; - } - *(zto - 1) = '\0'; - - azshargs[0] = "sh"; - azshargs[1] = "-c"; - azshargs[2] = zshcmd; - azshargs[3] = NULL; - - (void) execve ((char *) "/bin/sh", (char **) azshargs, pazenv); - } - - _exit (EXIT_FAILURE); - - /* Avoid compiler warning. */ - return -1; -} - -/* A version of popen that goes through isspawn. This actually takes - an array of arguments rather than a string, and takes a boolean - read/write value rather than a string. It sets *pipid to the - process ID of the child. */ - -FILE * -espopen (pazargs, frd, pipid) - const char **pazargs; - boolean frd; - pid_t *pipid; -{ - int aidescs[3]; - pid_t ipid; - FILE *eret; - - if (frd) - { - aidescs[0] = SPAWN_NULL; - aidescs[1] = SPAWN_READ_PIPE; - } - else - { - aidescs[0] = SPAWN_WRITE_PIPE; - aidescs[1] = SPAWN_NULL; - } - aidescs[2] = SPAWN_NULL; - - ipid = isspawn (pazargs, aidescs, FALSE, FALSE, - (const char *) NULL, FALSE, TRUE, - (const char *) NULL, (const char *) NULL, - (const char *) NULL); - if (ipid < 0) - return NULL; - - if (frd) - eret = fdopen (aidescs[1], (char *) "r"); - else - eret = fdopen (aidescs[0], (char *) "w"); - - if (eret == NULL) - { - int ierr; - - ierr = errno; - (void) close (frd ? aidescs[1] : aidescs[0]); - (void) kill (ipid, SIGKILL); - (void) iswait ((unsigned long) ipid, (const char *) NULL); - errno = ierr; - return NULL; - } - - *pipid = ipid; - - return eret; -} - -/* Wait for a particular process to finish. The ipid argument should - be pid_t, but then we couldn't have a prototype. If the zreport - argument is not NULL, then a wait error will be logged, and if the - exit status is non-zero it will be logged with zreport as the - header of the log message. If the zreport argument is NULL, no - errors will be logged. This function returns the exit status if - the process exited normally, or -1 on error or if the process was - killed by a signal (I don't just always return the exit status - because then the calling code would have to prepared to handle - union wait status vs. int status, and none of the callers care - which signal killed the program anyhow). - - This functions keeps waiting until the process finished, even if it - is interrupted by a signal. I think this is right for all uses. - The controversial one would be when called from uuxqt to wait for a - requested process. Hitting uuxqt with SIGKILL will approximate the - actions taken if we return from here with an error anyhow. If we - do get a signal, we call ulog with a NULL argument to get it in the - log file at about the right time. */ - -int -iswait (ipid, zreport) - unsigned long ipid; - const char *zreport; -{ - wait_status istat; - -#if HAVE_WAITPID - while (waitpid ((pid_t) ipid, &istat, 0) < 0) - { - if (errno != EINTR) - { - if (zreport != NULL) - ulog (LOG_ERROR, "waitpid: %s", strerror (errno)); - return -1; - } - ulog (LOG_ERROR, (const char *) NULL); - } -#else /* ! HAVE_WAITPID */ -#if HAVE_WAIT4 - while (wait4 ((pid_t) ipid, &istat, 0, (struct rusage *) NULL) < 0) - { - if (errno != EINTR) - { - if (zreport != NULL) - ulog (LOG_ERROR, "wait4: %s", strerror (errno)); - return -1; - } - ulog (LOG_ERROR, (const char *) NULL); - } -#else /* ! HAVE_WAIT4 */ - pid_t igot; - - /* We could theoretically get the wrong child here if we're in some - kind of weird pipeline, so we don't give any error messages for - it. */ - while ((igot = wait (&istat)) != (pid_t) ipid) - { - if (igot < 0) - { - if (errno != EINTR) - { - if (zreport != NULL) - ulog (LOG_ERROR, "wait: %s", strerror (errno)); - return -1; - } - ulog (LOG_ERROR, (const char *) NULL); - } - } -#endif /* ! HAVE_WAIT4 */ -#endif /* ! HAVE_WAITPID */ - - DEBUG_MESSAGE2 (DEBUG_EXECUTE, "%s %d", - WIFEXITED (istat) ? "Exit status" : "Signal", - WIFEXITED (istat) ? WEXITSTATUS (istat) : WTERMSIG (istat)); - - if (WIFEXITED (istat) && WEXITSTATUS (istat) == 0) - return 0; - - if (zreport != NULL) - { - if (! WIFEXITED (istat)) - ulog (LOG_ERROR, "%s: Got signal %d", zreport, WTERMSIG (istat)); - else - ulog (LOG_ERROR, "%s: Exit status %d", zreport, - WEXITSTATUS (istat)); - } - - if (WIFEXITED (istat)) - return WEXITSTATUS (istat); - else - return -1; -} - -#if ! HAVE_REMOVE - -/* Remove a file. */ - -int -remove (z) - const char *z; -{ - return unlink (z); -} - -#endif /* ! HAVE_REMOVE */ - -#if ! HAVE_STRERROR - -/* Some systems don't have a strerror definition, so we provide one. - This function is, of course, system dependent. */ - -char * -strerror (ierr) - int ierr; -{ - extern int sys_nerr; - extern char *sys_errlist[]; - - if (ierr >= 0 && ierr < sys_nerr) - return sys_errlist[ierr]; - return (char *) "unknown error"; -} - -#endif /* ! HAVE_STRERROR */ - -#if ! HAVE_GETCWD && ! HAVE_GETWD - -/* Implement a simple getcwd that just calls /bin/pwd. I probably - should include Roland McGrath's getcwd implementation here, since - it doesn't fork, but it requires readdir support that I don't feel - like contemplating just now. */ - -static char * -getcwd (zbuf, cbuf) - char *zbuf; - int cbuf; -{ - const char *azargs[2]; - FILE *e; - pid_t ipid; - int cread; - int ierr; - - azargs[0] = PWD_PROGRAM; - azargs[1] = NULL; - e = espopen (azargs, TRUE, &ipid); - if (e == NULL) - return NULL; - - ierr = 0; - - cread = fread (zbuf, sizeof (char), cbuf, e); - if (cread == 0) - ierr = errno; - - (void) fclose (e); - - if (iswait ((unsigned long) ipid, (const char *) NULL) != 0) - { - ierr = EACCES; - cread = 0; - } - - if (cread != 0) - { - if (zbuf[cread - 1] == '\n') - zbuf[cread - 1] = '\0'; - else - { - ierr = ERANGE; - cread = 0; - } - } - - if (cread == 0) - { - errno = ierr; - return NULL; - } - - return zbuf; -} - -#endif /* ! HAVE_GETCWD && ! HAVE_GETWD */ - -#if ! HAVE_DUP2 - -/* Emulate the dup2 call. I basically took this from the emacs 18.57 - distribution, although I cleaned it up a bit and made it POSIX - compliant. */ - -int -dup2 (oold, onew) - int oold; - int onew; -{ - if (oold == onew) - return onew; - (void) close (onew); - -#ifdef F_DUPFD - return fcntl (oold, F_DUPFD, onew); -#else - { - int onext, oret, isave; - - onext = dup (oold); - if (onext == onew) - return onext; - if (onext < 0) - return -1; - oret = dup2 (oold, onew); - isave = errno; - (void) close (onext); - errno = isave; - return oret; - } -#endif -} - -#endif /* ! HAVE_DUP2 */ - -#if ! HAVE_OPENDIR - -/* Simple emulations of opendir/readdir/closedir for systems which - have the original format of Unix directories. It's probably better - to get Doug Gwyn's public domain set of emulation functions. */ - -DIR * -opendir (zdir) - const char *zdir; -{ - int o; - struct stat s; - DIR *qret; - - o = open (zdir, O_RDONLY | O_NOCTTY, 0); - if (o == -1) - return NULL; - if (fstat (o, &s) < 0) - { - (void) close (o); - return NULL; - } - if (! S_ISDIR (s.st_mode)) - { - (void) close (o); - errno = ENOTDIR; - return NULL; - } - qret = (DIR *) xmalloc (sizeof (DIR)); - qret->o = o; - return qret; -} - -struct dirent * -readdir (q) - DIR *q; -{ - struct direct sdir; - int cgot; - - do - { - cgot = read (q->o, &sdir, sizeof (struct direct)); - if (cgot <= 0) - return NULL; - if (cgot != sizeof (struct direct)) - { - errno = ENOENT; - return NULL; - } - } - while (sdir.d_ino == 0); - - strncpy (q->s.d_name, sdir.d_name, DIRSIZ); - q->s.d_name[DIRSIZ] = '\0'; - return &q->s; -} - -int -closedir (q) - DIR *q; -{ - int iret, isave; - - iret = close (q->o); - isave = errno; - xfree (q); - errno = isave; - return iret; -} - -#endif /* ! HAVE_OPENDIR */ - -#if ! HAVE_MKDIR - -/* We don't have the mkdir system call, so we invoke the suid program - uudir to create the directory with the correct owner. */ - -int -mkdir (zdir, imode) - const char *zdir; - int imode; -{ - const char *azargs[2]; - int aidescs[3]; - pid_t ipid; - - /* /bin/mkdir will create the directory with mode 777, so we set our - umask to get the mode we want. */ - (void) umask ((~ imode) & (S_IRWXU | S_IRWXG | S_IRWXO)); - - azargs[0] = UUDIR_PROGRAM; - azargs[1] = NULL; - aidescs[0] = SPAWN_NULL; - aidescs[1] = SPAWN_NULL; - aidescs[2] = SPAWN_NULL; - - ipid = isspawn (azargs, aidescs, FALSE, FALSE, (const char *) NULL, - TRUE, FALSE, (const char *) NULL, - (const char *) NULL, (const char *) NULL); - - (void) umask (0); - - if (ipid < 0) - return -1; - - if (iswait ((unsigned long) ipid, (const char *) NULL) != 0) - { - /* Make up an errno value. */ - errno = EACCES; - return -1; - } - - return 0; -} - -#endif /* ! HAVE_MKDIR */ - -/* - Local variables: - mode:c - End: - */ diff --git a/gnu/libexec/uucp/sys2.unx b/gnu/libexec/uucp/sys2.unx deleted file mode 100644 index 95f4b60841f..00000000000 --- a/gnu/libexec/uucp/sys2.unx +++ /dev/null @@ -1,2746 +0,0 @@ -/* sys2.unx - The system dependent communication routines for UNIX. - - 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 AIRS, P.O. Box 520, Waltham, MA 02254. - - $Log: sys2.unx,v $ - Revision 1.1.1.1 1993/03/21 09:45:37 cgd - initial import of 386bsd-0.1 sources - - Revision 1.72 1992/04/03 17:43:39 ian - Petri Helenius: don't clobber undefined bits in termio or termios - - Revision 1.71 1992/04/01 21:52:04 ian - T. William Wells: handle a system without <poll.h> or <stropts.h> - - Revision 1.70 1992/03/30 15:29:58 ian - Added HAVE_SVR4_LOCKFILES - - Revision 1.69 1992/03/29 22:25:27 ian - Always block and unblock read and write descriptors together - - Revision 1.68 1992/03/28 04:12:17 ian - Gerben Wierda: minor cleanups - - Revision 1.67 1992/03/28 03:06:04 ian - Don't use TIOCEXCL locking - - Revision 1.66 1992/03/28 02:47:30 ian - Rework HAVE_UNBLOCKED_WRITES to work even if writes are unblocked - - Revision 1.65 1992/03/17 15:35:28 ian - Log signals when they happen, even if we continue looping - - Revision 1.64 1992/03/17 05:01:33 ian - Don't block when opening the write descriptor - - Revision 1.63 1992/03/17 01:03:03 ian - Miscellaneous cleanup - - Revision 1.62 1992/03/16 01:23:08 ian - Make blocking writes optional - - Revision 1.61 1992/03/15 07:15:42 ian - T. William Wells: don't use unblocked writes - - Revision 1.60 1992/03/15 04:51:17 ian - Keep an array of signals we've received rather than a single variable - - Revision 1.59 1992/03/15 01:54:46 ian - All execs are now done in isspawn, all waits are done in iswait - - Revision 1.58 1992/03/12 21:50:50 ian - Moved local header includes above sleep routine determination - - Revision 1.57 1992/03/12 19:54:43 ian - Debugging based on types rather than number - - Revision 1.56 1992/03/11 02:09:57 ian - Franc,ois Pinard: retry fork several times before giving up - - Revision 1.55 1992/03/09 22:11:46 ian - Franc,ois Pinard: sleep for a second after closing a serial port - - Revision 1.54 1992/03/09 22:07:36 ian - Wait for terminal output to drain at various points - - Revision 1.53 1992/03/08 16:56:51 ian - Ted Lindgreen: if CRTSCTS is defined, don't turn on IXOFF - - Revision 1.52 1992/03/08 04:56:21 ian - Peter da Silva: added ``lockname'' command for ports - - Revision 1.51 1992/03/08 01:56:01 ian - Include <sys/ioctl.h> if we have it - - Revision 1.50 1992/03/08 01:37:45 ian - Suppurt TIOCEXCL locking - - Revision 1.49 1992/03/07 16:25:21 ian - Preserve unknown bits in c_cflag - - Revision 1.48 1992/03/04 23:43:39 ian - Petri Helenius: didn't remove lock file if open failed - - Revision 1.47 1992/03/04 01:40:51 ian - Thomas Fischer: tweaked a bit for the NeXT - - Revision 1.46 1992/03/03 21:01:20 ian - Use strict timeout in fsserial_read, eliminate all race conditions - - Revision 1.45 1992/03/03 04:25:00 ian - T. William Wells: don't arbitrarily extend read timeout - - Revision 1.44 1992/03/02 04:53:07 ian - Marc Unangst: added HAVE_SCO_LOCKFILES configuration parameter - - Revision 1.43 1992/02/28 05:06:15 ian - T. William Wells: fsysdep_catch must be a macro - - Revision 1.42 1992/02/27 05:40:54 ian - T. William Wells: detach from controlling terminal, handle signals safely - - Revision 1.41 1992/02/24 21:22:47 ian - The poll function takes milliseconds, not microseconds (my error) - - Revision 1.40 1992/02/24 21:18:17 ian - Roberto Biancardi: use poll for sleeping if we haven't got anything else - - Revision 1.39 1992/02/24 20:07:43 ian - John Theus: some systems don't have <fcntl.h> - - Revision 1.38 1992/02/23 03:26:51 ian - Overhaul to use automatic configure shell script - - Revision 1.37 1992/02/17 22:08:50 ian - Bob Denny: log chat script messages as LOG_NORMAL, not LOG_ERROR - - Revision 1.36 1992/02/08 20:02:36 ian - Added HAVE_SETRET configuration option for systems without setjmp - - Revision 1.35 1992/02/08 03:54:18 ian - Include <string.h> only in <uucp.h>, added 1992 copyright - - Revision 1.34 1992/01/16 16:32:44 ian - Mike Park: ioctl is sometimes declared varadic, so we can't declare it - - Revision 1.33 1992/01/15 21:06:11 ian - Mike Park: some systems can't include <sys/time.h> and <time.h> together - - Revision 1.32 1992/01/15 20:40:04 ian - Mike Park: some systems don't have <limits.h> - - Revision 1.31 1992/01/15 19:40:35 ian - Mike Park: handle HAVE_UNION_WAIT correctly and completely - - Revision 1.30 1992/01/14 04:18:47 ian - Chip Salzenberg: added HAVE_USLEEP configuration parameter - - Revision 1.29 1992/01/13 06:11:39 ian - David Nugent: can't declare open or fcntl - - Revision 1.28 1991/12/31 04:16:19 ian - Chip Salzenberg: don't turn on IXON and IXOFF at the start - - Revision 1.27 1991/12/29 04:04:18 ian - Added a bunch of extern definitions - - Revision 1.26 1991/12/29 00:55:23 ian - Monty Solomon: added HAVE_UNION_WAIT - - Revision 1.25 1991/12/22 22:14:19 ian - Monty Solomon: added HAVE_UNISTD_H configuration parameter - - Revision 1.24 1991/12/20 02:23:10 ian - Don't change port settings if we don't have to - - Revision 1.23 1991/12/19 04:25:57 ian - Terry Gardner: configuration parameter to not use both NONBLOCK and NDELAY - - Revision 1.22 1991/12/17 23:14:08 ian - T. William Wells: allow dialer complete and abort to be chat scripts - - Revision 1.21 1991/12/17 22:31:15 ian - Start in RAW mode, to avoid dropping characters when we switch to it - - Revision 1.20 1991/12/17 05:24:01 ian - David Nugent: flush pending input in fsserial_open - - Revision 1.19 1991/12/15 04:28:23 ian - Don't turn on ISTRIP initially - - Revision 1.18 1991/12/10 19:45:05 ian - Added ulog_device to record device name for log file - - Revision 1.17 1991/12/01 02:23:12 ian - Niels Baggesen: don't multiply include <unistd.h> - - Revision 1.16 1991/11/26 01:50:30 ian - Set fread_blocking and fwrite_blocking correctly for TCP routines - - Revision 1.15 1991/11/26 01:45:42 ian - Marty Shannon: configuration option to not include <sys/wait.h> - - Revision 1.14 1991/11/22 06:05:57 ian - Gregory Gulik: fix wait status macro definitions - - Revision 1.13 1991/11/21 20:58:18 ian - Brian Campbell: for HAVE_SIGSETJMP use sigjmp_buf, not jmp_buf - - Revision 1.12 1991/11/15 23:13:53 ian - Fixed termio(s) version of fsserial_set - - Revision 1.11 1991/11/13 20:38:00 ian - Added TCP port type for connections over TCP - - Revision 1.10 1991/11/12 19:07:27 ian - Be careful to only call fsetterminfo on a terminal - - Revision 1.9 1991/11/11 23:47:24 ian - Added chat-program to run a program to do a chat script - - Revision 1.8 1991/11/11 00:39:45 ian - Open port in seven bit mode, added fport_set to change to eight bit - - Revision 1.7 1991/11/08 22:52:34 ian - Brian Campbell: only include <sys/time.h> and <sys/ioctl.h> when needed - - Revision 1.6 1991/11/08 22:11:45 ian - Brian Campbell: allow sigsetjmp as configuration option - - Revision 1.5 1991/11/07 22:52:11 ian - Chip Salzenberg: force stdin and stdout to stay open in case of spawning - - Revision 1.4 1991/11/07 21:43:59 ian - Chip Salzenberg: set terminal modes directly, don't or them in - - Revision 1.3 1991/11/07 19:42:16 ian - Chip Salzenberg: declare inline functions consistently - - Revision 1.2 1991/11/07 19:32:28 ian - Chip Salzenberg: allow LOCKDIR, and check that locking process exists - - Revision 1.1 1991/09/10 19:45:50 ian - Initial revision - - */ - -#include "uucp.h" - -#if USE_RCS_ID -char sys2_unx_rcsid[] = "$Id: sys2.unx,v 1.1.1.1 1993/03/21 09:45:37 cgd Exp $"; -#endif - -#include <errno.h> - -#if HAVE_LIMITS_H -#include <limits.h> -#endif - -#if USE_STDIO && HAVE_UNISTD_H -#include <unistd.h> -#endif - -#include "system.h" -#include "sysdep.h" -#include "port.h" - -/* Pick a timing routine to use. I somewhat arbitrarily picked usleep - above nap above napms above poll above select. */ - -#if HAVE_USLEEP || HAVE_NAP || HAVE_NAPMS || HAVE_POLL -#define USE_SELECT_TIMER 0 -#else -#define USE_SELECT_TIMER HAVE_SELECT -#endif - -#if HAVE_USLEEP || HAVE_NAP || HAVE_NAPMS -#undef HAVE_POLL -#define HAVE_POLL 0 -#endif - -#if HAVE_USLEEP || HAVE_NAP -#undef HAVE_NAPMS -#define HAVE_NAPMS 0 -#endif - -#if HAVE_USLEEP -#undef HAVE_NAP -#define HAVE_NAP 0 -#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 - -#if HAVE_SYS_IOCTL_H -#include <sys/ioctl.h> -#endif - -#if USE_SELECT_TIMER || HAVE_BSD_TTY -#include <sys/time.h> -#endif - -#if HAVE_POLL -#if HAVE_STROPTS_H -#include <stropts.h> -#endif -#if HAVE_POLL_H -#include <poll.h> -#endif -#if ! HAVE_STROPTS_H && ! HAVE_POLL_H -/* We need a definition for struct pollfd, although it doesn't matter - what it contains. It's used in usysdep_pause. */ -struct pollfd -{ - int idummy; -}; -#endif /* ! HAVE_STROPTS_H && ! HAVE_POLL_H */ -#endif /* HAVE_POLL */ - -#if HAVE_TIME_H -#if HAVE_SYS_TIME_AND_TIME_H || (! USE_SELECT_TIMER && ! HAVE_BSD_TTY) -#include <time.h> -#endif -#endif - -/* Get definitions for both O_NONBLOCK and O_NDELAY. */ - -#ifndef O_NDELAY -#ifdef FNDELAY -#define O_NDELAY FNDELAY -#else /* ! defined (FNDELAY) */ -#define O_NDELAY 0 -#endif /* ! defined (FNDELAY) */ -#endif /* ! defined (O_NDELAY) */ - -#ifndef O_NONBLOCK -#ifdef FNBLOCK -#define O_NONBLOCK FNBLOCK -#else /* ! defined (FNBLOCK) */ -#define O_NONBLOCK 0 -#endif /* ! defined (FNBLOCK) */ -#endif /* ! defined (O_NONBLOCK) */ - -#if O_NDELAY == 0 && O_NONBLOCK == 0 - #error No way to do nonblocking I/O -#endif - -/* If we can define them both together, do so. This is because some - ancient drivers on some systems appear to look for one but not the - other. Otherwise just use O_NONBLOCK. */ -#if COMBINED_UNBLOCK -#define FILE_UNBLOCKED (O_NDELAY | O_NONBLOCK) -#else -#define FILE_UNBLOCKED O_NONBLOCK -#endif - -/* Get definitions for both EAGAIN and EWOULDBLOCK. */ - -#ifndef EAGAIN -#ifndef EWOULDBLOCK -#define EAGAIN (-1) -#define EWOULDBLOCK (-1) -#else /* defined (EWOULDBLOCK) */ -#define EAGAIN EWOULDBLOCK -#endif /* defined (EWOULDBLOCK) */ -#else /* defined (EAGAIN) */ -#ifndef EWOULDBLOCK -#define EWOULDBLOCK EAGAIN -#endif /* ! defined (EWOULDBLOCK) */ -#endif /* defined (EAGAIN) */ - -/* Make sure we have a definition for MAX_INPUT. */ - -#ifndef MAX_INPUT -#define MAX_INPUT (256) -#endif - -/* Make sure we have definitions for major and minor. */ - -#ifndef major -#define major(i) (((i) >> 8) & 0xff) -#endif -#ifndef minor -#define minor(i) ((i) & 0xff) -#endif - -/* If we have the TIOCSINUSE ioctl call, we use it to lock a terminal. - Otherwise, if we have the TIOCEXCL ioctl call, we have to open the - terminal before we know that it is unlocked. */ -#ifdef TIOCSINUSE -#define HAVE_TIOCSINUSE 1 -#else -#ifdef TIOCEXCL -#define HAVE_TIOCEXCL 1 -#endif -#endif - -/* Determine bits to clear for the various terminal control fields for - HAVE_SYSV_TERMIO and HAVE_POSIX_TERMIOS. */ - -#if HAVE_SYSV_TERMIO -#define ICLEAR_IFLAG (IGNBRK | BRKINT | IGNPAR | PARMRK | INPCK \ - | ISTRIP | INLCR | IGNCR | ICRNL | IUCLC \ - | IXON | IXANY | IXOFF) -#define ICLEAR_OFLAG (OPOST | OLCUC | ONLCR | OCRNL | ONOCR | ONLRET \ - | OFILL | OFDEL | NLDLY | CRDLY | TABDLY | BSDLY \ - | VTDLY | FFDLY) -#define ICLEAR_CFLAG (CBAUD | CLOCAL | CSIZE | PARENB | PARODD) -#define ISET_CFLAG (CS8 | CREAD | HUPCL) -#define ICLEAR_LFLAG (ISIG | ICANON | XCASE | ECHO | ECHOE | ECHOK \ - | ECHONL | NOFLSH) -#endif -#if HAVE_POSIX_TERMIOS -#define ICLEAR_IFLAG (BRKINT | ICRNL | IGNBRK | IGNCR | IGNPAR \ - | INLCR | INPCK | ISTRIP | IXOFF | IXON \ - | PARMRK) -#define ICLEAR_OFLAG (OPOST) -#define ICLEAR_CFLAG (CLOCAL | CSIZE | PARENB | PARODD) -#define ISET_CFLAG (CS8 | CREAD | HUPCL) -#define ICLEAR_LFLAG (ECHO | ECHOE | ECHOK | ECHONL | ICANON | IEXTEN \ - | ISIG | NOFLSH | TOSTOP) -#endif - -/* External functions. */ -extern char *strlwr (); -extern int close (), pipe (), dup2 (), read (), write (); -extern int fclose (); -extern void _exit (); -#if USE_SELECT_TIMER || HAVE_BSD_TTY -extern int select (); -#endif -#if HAVE_NAP -extern int nap (); -#endif -#if HAVE_NAPMS -extern int napms (); -#endif -#if HAVE_POLL -extern int poll (); -#endif - -/* Local functions. */ - -static SIGtype usalarm P((int isig)); -static boolean fsserial_lockfile P((boolean flok, const struct sport *, - const char *zdevice)); -static boolean fsserial_lock P((const struct sport *qport, - struct ssysdep_serial_port *q, - boolean fin, const char *zdevice)); -static boolean fsserial_open P((const char *z, long ibaud, boolean fwait, - struct ssysdep_serial_port *q)); -__inline__ static boolean fsblock P((struct ssysdep_serial_port *q, - boolean fblock)); -static boolean fsserial_close P((struct ssysdep_serial_port *q)); -static boolean fsserial_reset P((struct ssysdep_serial_port *q)); -static boolean fsserial_read P((struct ssysdep_serial_port *q, - char *zbuf, int *pclen, int cmin, - int ctimeout, boolean freport, - boolean fpty)); -static boolean fsserial_write P((struct ssysdep_serial_port *q, - const char *zwrite, int cwrite)); -static boolean fsserial_io P((struct ssysdep_serial_port *q, - const char *zwrite, int *pcwrite, - char *zread, int *pcread)); -static boolean fsserial_break P((struct ssysdep_serial_port *q)); -static boolean fsserial_set P((struct ssysdep_serial_port *q, - enum tportsetting tset)); -static boolean fsrun_chat P((int oread, int owrite, const char *zprog)); - -/* This code handles SIGALRM. See the discussion above fsserial_read. - Normally we ignore SIGALRM, but the handler will temporarily be set - to this function, which should set fSalarm and then either longjmp - or schedule another SIGALRM. fSalarm is never referred to outside - of this file, but we don't make it static to try to fool compilers - which don't understand volatile. */ - -volatile sig_atomic_t fSalarm; - -static SIGtype -usalarm (isig) - int isig; -{ -#if ! HAVE_SIGACTION && ! HAVE_SIGVEC && ! HAVE_SIGSET - (void) signal (isig, usalarm); -#endif - - fSalarm = TRUE; - -#if HAVE_RESTARTABLE_SYSCALLS - longjmp (sSjmp_buf, 1); -#else - alarm (1); -#endif -} - -/* We need a simple routine to block SIGINT, SIGQUIT, SIGTERM and - SIGPIPE and another to restore the original state. When these - functions are called (in fsysdep_modem_close) SIGHUP is being - ignored. The routines are isblocksigs, which returns a value of - type HELD_SIG_MASK and usunblocksigs which takes a single argument - of type HELD_SIG_MASK. */ - -#if HAVE_SIGPROCMASK - -/* Use the POSIX sigprocmask call. */ - -extern int sigprocmask (); - -#define HELD_SIG_MASK sigset_t - -static sigset_t isblocksigs P((void)); - -static sigset_t -isblocksigs () -{ - sigset_t sblock, sold; - - sigemptyset (&sblock); - sigaddset (&sblock, SIGINT); - sigaddset (&sblock, SIGQUIT); - sigaddset (&sblock, SIGTERM); - sigaddset (&sblock, SIGPIPE); - sigprocmask (SIG_BLOCK, &sblock, &sold); - return sold; -} - -#define usunblocksigs(s) \ - ((void) sigprocmask (SIG_SETMASK, &(s), (sigset_t *) NULL)) - -#else /* ! HAVE_SIGPROCMASK */ -#if HAVE_SIGBLOCK - -/* Use the BSD sigblock and sigsetmask calls. */ - -extern int sigblock (), sigsetmask (); - -#define HELD_SIG_MASK int - -#ifndef sigmask -#define sigmask(i) (1 << ((i) - 1)) -#endif - -#define isblocksigs() \ - sigblock (sigmask (SIGINT) | sigmask (SIGQUIT) \ - | sigmask (SIGTERM) | sigmask (SIGPIPE)) - -#define usunblocksigs(i) ((void) sigsetmask (i)) - -#else /* ! HAVE_SIGBLOCK */ - -#if HAVE_SIGHOLD - -/* Use the SVR3 sighold and sigrelse calls. */ - -extern int sighold (), sigrelse (); - -#define HELD_SIG_MASK int - -static int isblocksigs P((void)); - -static int -isblocksigs () -{ - sighold (SIGINT); - sighold (SIGQUIT); - sighold (SIGTERM); - sighold (SIGPIPE); - return 0; -} - -static void usunblocksigs P((int)); - -/*ARGSUSED*/ -static void -usunblocksigs (i) - int i; -{ - sigrelse (SIGINT); - sigrelse (SIGQUIT); - sigrelse (SIGTERM); - sigrelse (SIGPIPE); -} - -#else /* ! HAVE_SIGHOLD */ - -/* We have no way to block signals. This system will suffer from a - race condition in fsysdep_modem_close. */ - -#define HELD_SIG_MASK int - -#define isblocksigs() 0 - -#define usunblocksigs(i) - -#endif /* ! HAVE_SIGHOLD */ -#endif /* ! HAVE_SIGBLOCK */ -#endif /* ! HAVE_SIGPROCMASK */ - -/* Pause for half a second. This doesn't really belong in this file, - but all the timing routines are here. */ - -void -usysdep_pause () -{ -#if HAVE_NAPMS - napms (500); -#endif /* HAVE_NAPMS */ -#if HAVE_NAP - nap (500L); -#endif /* HAVE_NAP */ -#if HAVE_USLEEP - usleep (500 * (long) 1000); -#endif /* HAVE_USLEEP */ -#if HAVE_POLL - struct pollfd sdummy; - - /* We need to pass an unused pollfd structure because poll checks - the address before checking the number of elements. */ - poll (&sdummy, 0, 500); -#endif /* HAVE_POLL */ -#if USE_SELECT_TIMER - struct timeval s; - - s.tv_sec = 0; - s.tv_usec = 500 * (long) 1000; - select (0, (int *) NULL, (int *) NULL, (int *) NULL, &s); -#endif /* USE_SELECT_TIMER */ -#if ! HAVE_NAPMS && ! HAVE_NAP && ! HAVE_USLEEP -#if ! USE_SELECT_TIMER && ! HAVE_POLL - sleep (1); -#endif /* ! USE_SELECT_TIMER && ! HAVE_POLL */ -#endif /* ! HAVE_NAPMS && ! HAVE_NAP && ! HAVE_USLEEP */ -} - -/* This routine is used for both locking and unlocking. It is the - only routine which knows how to translate a device name into the - name of a lock file. If it can't figure out a name, it does - nothing and returns TRUE. */ - -static boolean -fsserial_lockfile (flok, qport, zdevice) - boolean flok; - const struct sport *qport; - const char *zdevice; -{ - const char *z; - - z = qport->zlockname; - if (z == NULL) - { - char *zalc; - - z = zdevice; - if (z == NULL) - { - z = qport->zname; - if (z == NULL) - return TRUE; - } - -#if ! HAVE_SVR4_LOCKFILES - if (strncmp (z, "/dev/", sizeof "/dev/" - 1) == 0) - z += sizeof "/dev/" - 1; - zalc = (char *) alloca (strlen (z) + sizeof "LCK.."); - sprintf (zalc, "LCK..%s", z); -#if HAVE_SCO_LOCKFILES - strlwr (zalc + sizeof "LCK.." - 1); -#endif -#else /* HAVE_SVR4_LOCKFILES */ - { - struct stat s; - - if (*z != '/') - { - zalc = (char *) alloca (sizeof "/dev/" + strlen (z)); - sprintf (zalc, "/dev/%s", z); - z = zalc; - } - if (stat (z, &s) != 0) - { - ulog (LOG_ERROR, "stat (%s): %s", z, strerror (errno)); - return FALSE; - } - zalc = (char *) alloca (sizeof "LK.123.123.123"); - sprintf (zalc, "LK.%03d.%03d.%03d", major (s.st_dev), - major (s.st_rdev), minor (s.st_rdev)); - } -#endif /* HAVE_SVR4_LOCKFILES */ - - z = zalc; - } - - if (flok) - return fsdo_lock (z, FALSE); - else - return fsdo_unlock (z, FALSE); -} - -/* If we can mark a modem line in use, then when we lock a port we - must open it and mark it in use. We can't wait until the actual - open because we can't fail out if it is locked then. */ - -static boolean -fsserial_lock (qport, q, fin, zdevice) - const struct sport *qport; - struct ssysdep_serial_port *q; - boolean fin; - const char *zdevice; -{ - if (! fsserial_lockfile (TRUE, qport, zdevice)) - return FALSE; - -#if HAVE_TIOCSINUSE || HAVE_TIOCEXCL - /* Open the line and, if possible, mark it in use. */ - { - const char *z; - int oread, iflag; - - z = zdevice; - if (z == NULL) - { - z = qport->zname; - if (z == NULL) - return TRUE; - } - - if (fin) - iflag = 0; - else - iflag = FILE_UNBLOCKED; - - if (*z != '/') - { - char *zcopy; - - zcopy = (char *) alloca (sizeof "/dev/" + strlen (z)); - sprintf (zcopy, "/dev/%s", z); - z = zcopy; - } - - oread = open (z, O_RDWR | iflag); - if (oread < 0) - { - if (errno != EBUSY) - ulog (LOG_ERROR, "open (%s): %s", z, strerror (errno)); - (void) fsserial_lockfile (FALSE, qport, zdevice); - return FALSE; - } - -#if HAVE_TIOCSINUSE - /* If we can't mark it in use, return FALSE to indicate that the - lock failed. */ - if (ioctl (oread, TIOCSINUSE, 0) < 0) - { - if (errno != EALREADY) - ulog (LOG_ERROR, "ioctl (TIOCSINUSE): %s", strerror (errno)); - (void) close (oread); - (void) fsserial_lockfile (FALSE, qport, zdevice); - return FALSE; - } -#endif - -#ifdef TIOCSCTTY - /* On BSD 4.4, make it our controlling terminal. */ - (void) ioctl (oread, TIOCSCTTY, 0); -#endif - - q->oread = q->owrite = oread; - } -#endif /* HAVE_TIOCSINUSE || HAVE_TIOCEXCL */ - - return TRUE; -} - -/* We don't need to lock a stdin port. */ - -/*ARGSUSED*/ -boolean -fsysdep_stdin_lock (qport, fin) - struct sport *qport; - boolean fin; -{ - return TRUE; -} - -/* Lock a modem port. */ - -boolean -fsysdep_modem_lock (qport, fin) - struct sport *qport; - boolean fin; -{ - return fsserial_lock (qport, &qport->u.smodem.s.s, fin, - qport->u.smodem.zdevice); -} - -/* Lock a direct port. */ - -boolean -fsysdep_direct_lock (qport, fin) - struct sport *qport; - boolean fin; -{ - return fsserial_lock (qport, &qport->u.sdirect.s.s, fin, - qport->u.sdirect.zdevice); -} - -/* Open a serial line. This sets the terminal settings. We begin in - seven bit mode and let the protocol change if necessary. */ - -static struct sbaud_table -{ -#if HAVE_POSIX_TERMIOS - speed_t icode; -#else - int icode; -#endif - long ibaud; -} asSbaud_table[] = -{ - { B50, 50 }, - { B75, 75 }, - { B110, 110 }, - { B134, 134 }, - { B150, 150 }, - { B200, 200 }, - { B300, 300 }, - { B600, 600 }, - { B1200, 1200 }, - { B1800, 1800 }, - { B2400, 2400 }, - { B4800, 4800 }, - { B9600, 9600 }, -#ifdef B19200 - { B19200, 19200 }, -#else /* ! defined (B19200) */ -#ifdef EXTA - { EXTA, 19200 }, -#endif /* EXTA */ -#endif /* ! defined (B19200) */ -#ifdef B38400 - { B38400, 38400 } -#else /* ! defined (B38400) */ -#ifdef EXTB - { EXTB, 38400 } -#endif /* EXTB */ -#endif /* ! defined (B38400) */ -}; - -#define CBAUD_TABLE (sizeof asSbaud_table / sizeof asSbaud_table[0]) - -#if HAVE_SYSV_TERMIO || HAVE_POSIX_TERMIOS -/* Hold the MIN value for the terminal to avoid setting it - unnecessarily. */ -static int cSmin; -#endif /* HAVE_SYSV_TERMIO || HAVE_POSIX_TERMIOS */ - -static boolean -fsserial_open (z, ibaud, fwait, q) - const char *z; - long ibaud; - boolean fwait; - struct ssysdep_serial_port *q; -{ -#if HAVE_POSIX_TERMIOS - speed_t ib; -#else - int ib; -#endif - - if (z == NULL) - { - const char *zport; - boolean fdummy; - - zport = zsysdep_port_name (&fdummy); - if (zport != NULL) - ulog_device (zport); - } - else - { - if (strncmp (z, "/dev/", sizeof "/dev/" - 1) == 0) - ulog_device (z + sizeof "/dev/" - 1); - else - ulog_device (z); - } - - ib = B0; - - if (ibaud != 0) - { - int i; - - for (i = 0; i < CBAUD_TABLE; i++) - if (asSbaud_table[i].ibaud == ibaud) - break; - if (i >= CBAUD_TABLE) - { - ulog (LOG_ERROR, "Unsupported baud rate %ld", ibaud); - if (q->oread != -1) - { - (void) close (q->oread); - if (q->oread != q->owrite) - (void) close (q->owrite); - } - return FALSE; - } - ib = asSbaud_table[i].icode; - } - - /* The port may have already been opened by the locking routine. */ - if (q->oread == -1) - { - int oread, owrite; - - if (z == NULL) - { - oread = 0; - owrite = 1; - } - else - { - int iflag; - - if (fwait) - iflag = 0; - else - iflag = FILE_UNBLOCKED; - - if (*z != '/') - { - char *zcopy; - - zcopy = (char *) alloca (sizeof "/dev/" + strlen (z)); - sprintf (zcopy, "/dev/%s", z); - z = zcopy; - } - - oread = open (z, O_RDWR | iflag); - if (oread < 0) - { - ulog (LOG_ERROR, "open (%s): %s", z, strerror (errno)); - return FALSE; - } - -#ifdef TIOCSCTTY - /* On BSD 4.4, make it our controlling terminal. */ - (void) ioctl (oread, TIOCSCTTY, 0); -#endif - - owrite = oread; - } - - q->oread = oread; - q->owrite = owrite; - } - - /* Make sure the ports are blocking. */ - - if (fcntl (q->oread, F_SETFL, 0) < 0 - || (q->oread != q->owrite - && fcntl (q->owrite, F_SETFL, 0) < 0)) - { - ulog (LOG_ERROR, "fcntl: %s", strerror (errno)); - (void) close (q->oread); - if (q->oread != q->owrite) - (void) close (q->owrite); - return FALSE; - } - - q->fread_blocking = TRUE; - - if (! fgetterminfo (q->oread, &q->sorig)) - { - q->fterminal = FALSE; - return TRUE; - } - - q->fterminal = TRUE; - - q->snew = q->sorig; - -#if HAVE_BSD_TTY - - q->snew.sg_flags = RAW | ANYP; - if (ibaud == 0) - ib = q->snew.sg_ospeed; - else - { - q->snew.sg_ispeed = ib; - q->snew.sg_ospeed = ib; - } - -#ifdef TIOCHPCL - /* When the file is closed, hang up the line. This is a safety - measure in case the program crashes. */ - (void) ioctl (q->oread, TIOCHPCL, 0); -#endif - -#ifdef TIOCFLUSH - { - int iparam; - - /* Flush pending input. */ -#ifdef FREAD - iparam = FREAD; -#else - iparam = 0; -#endif - (void) ioctl (q->oread, TIOCFLUSH, &iparam); - } -#endif /* TIOCFLUSH */ - -#endif /* HAVE_BSD_TTY */ - -#if HAVE_SYSV_TERMIO - - if (ibaud == 0) - ib = q->snew.c_cflag & CBAUD; - - q->snew.c_iflag &=~ ICLEAR_IFLAG; - q->snew.c_oflag &=~ ICLEAR_OFLAG; - q->snew.c_cflag &=~ ICLEAR_CFLAG; - q->snew.c_cflag |= (ib | ISET_CFLAG); - q->snew.c_lflag &=~ ICLEAR_LFLAG; - cSmin = 6; - q->snew.c_cc[VMIN] = cSmin; - q->snew.c_cc[VTIME] = 0; - -#ifdef TCFLSH - /* Flush pending input. */ - (void) ioctl (q->oread, TCFLSH, 0); -#endif - -#endif /* HAVE_SYSV_TERMIO */ - -#if HAVE_POSIX_TERMIOS - - if (ibaud == 0) - ib = cfgetospeed (&q->snew); - - q->snew.c_iflag &=~ ICLEAR_IFLAG; - q->snew.c_oflag &=~ ICLEAR_OFLAG; - q->snew.c_cflag &=~ ICLEAR_CFLAG; - q->snew.c_cflag |= ISET_CFLAG; - q->snew.c_lflag &=~ ICLEAR_LFLAG; - cSmin = 6; - q->snew.c_cc[VMIN] = cSmin; - q->snew.c_cc[VTIME] = 0; - - (void) cfsetospeed (&q->snew, ib); - (void) cfsetispeed (&q->snew, ib); - - /* Flush pending input. */ - (void) tcflush (q->oread, TCIFLUSH); - -#endif /* HAVE_POSIX_TERMIOS */ - - if (! fsetterminfo (q->oread, &q->snew)) - { - ulog (LOG_ERROR, "Can't set terminal settings: %s", strerror (errno)); - (void) close (q->oread); - if (q->oread != q->owrite) - (void) close (q->owrite); - return FALSE; - } - - if (ibaud != 0) - q->ibaud = ibaud; - else - { - int i; - - q->ibaud = 1200; - for (i = 0; i < CBAUD_TABLE; i++) - { - if (asSbaud_table[i].icode == ib) - { - q->ibaud = asSbaud_table[i].ibaud; - break; - } - } - - DEBUG_MESSAGE1 (DEBUG_PORT, - "fsserial_open: Baud rate is %ld", q->ibaud); - } - - return TRUE; -} - -/* Open a stdin port. */ - -boolean -fsysdep_stdin_open (qport, ibaud, fwait) - struct sport *qport; - long ibaud; - boolean fwait; -{ - return fsserial_open ((const char *) NULL, ibaud, fwait, - &qport->u.sstdin.s.s); -} - -/* Open a modem port. */ - -boolean -fsysdep_modem_open (qport, ibaud, fwait) - struct sport *qport; - long ibaud; - boolean fwait; -{ - const char *z; - boolean fret; - - z = qport->u.smodem.zdevice; - if (z == NULL) - { - z = qport->zname; - if (z == NULL) - { - ulog (LOG_ERROR, "Port has no name or device"); - return FALSE; - } - } - if (ibaud == 0) - ibaud = qport->u.smodem.ibaud; - fret = fsserial_open (z, ibaud, fwait, &qport->u.smodem.s.s); - if (! fret) - (void) fsserial_lockfile (FALSE, qport, qport->u.smodem.zdevice); - return fret; -} - -/* Open a direct port. */ - -boolean -fsysdep_direct_open (qport, ibaud, fwait) - struct sport *qport; - long ibaud; - boolean fwait; -{ - const char *z; - boolean fret; - - z = qport->u.sdirect.zdevice; - if (z == NULL) - { - z = qport->zname; - if (z == NULL) - { - ulog (LOG_ERROR, "Port has no name or device"); - return FALSE; - } - } - if (ibaud == 0) - ibaud = qport->u.sdirect.ibaud; - fret = fsserial_open (z, ibaud, fwait, &qport->u.sdirect.s.s); - if (! fret) - (void) fsserial_lockfile (FALSE, qport, qport->u.sdirect.zdevice); - return fret; -} - -/* Change the blocking status of the port. We keep track of the - current blocking status to avoid calling fcntl unnecessarily; fcntl - turns out to be surprisingly expensive, at least on Ultrix. We - used to keep track of the blocking status of the read port and the - write port independently. Unfortunately, this is nonportable, - because on BSD, and probably some other systems, unblocking a - terminal applies to all descriptors to that terminal. Now, if - oread != owrite, we set both. */ - -__inline__ -static boolean -fsblock (qs, fblock) - struct ssysdep_serial_port *qs; - boolean fblock; -{ - if (fblock ? ! qs->fread_blocking : qs->fread_blocking) - { - int iset; - - if (fblock) - iset = 0; - else - iset = FILE_UNBLOCKED; - if (fcntl (qs->oread, F_SETFL, iset) < 0 - || (qs->oread != qs->owrite - && fcntl (qs->owrite, F_SETFL, iset) < 0)) - { - ulog (LOG_ERROR, "fcntl: %s", strerror (errno)); - return FALSE; - } - qs->fread_blocking = fblock; - } - return TRUE; -} - -/* Close a serial port. */ - -static boolean -fsserial_close (q) - struct ssysdep_serial_port *q; -{ - if (q->oread >= 0) - { - /* Use a 30 second timeout to avoid hanging while draining - output. */ - if (q->fterminal) - { - fSalarm = FALSE; - - if (fsysdep_catch ()) - { - usysdep_start_catch (); - usset_signal (SIGALRM, usalarm, TRUE, (boolean *) NULL); - (void) alarm (30); - - (void) fsetterminfodrain (q->oread, &q->sorig); - } - - usset_signal (SIGALRM, SIG_IGN, TRUE, (boolean *) NULL); - (void) alarm (0); - usysdep_end_catch (); - - /* If we timed out, use the non draining call. Hopefully - this can't hang. */ - if (fSalarm) - (void) fsetterminfo (q->oread, &q->sorig); - } - - (void) close (q->oread); - if (q->oread != q->owrite) - (void) close (q->owrite); - q->oread = q->owrite = -1; - - /* Sleep for a second to give the terminal a chance to settle, - in case we are about to call out again. */ - sleep (1); - } - - return TRUE; -} - -/* Close a stdin port. */ - -/*ARGSUSED*/ -boolean -fsysdep_stdin_close (qport, fsuccess) - struct sport *qport; - boolean fsuccess; -{ - return fsserial_close (&qport->u.sstdin.s.s); -} - -/* Close a modem port. */ - -boolean -fsysdep_modem_close (qport, fsuccess) - struct sport *qport; - boolean fsuccess; -{ - boolean fret; - struct sdialer *qdial; - struct sdialer sdial; - - fret = TRUE; - qdial = NULL; - - /* We're no longer interested in carrier. */ - (void) fsysdep_modem_no_carrier (qport); - - if (qport->u.smodem.zdialer != NULL) - { - char *zcopy; - - zcopy = (char *) alloca (strlen (qport->u.smodem.zdialer) + 1); - strcpy (zcopy, qport->u.smodem.zdialer); - zcopy[strcspn (zcopy, " \t")] = '\0'; - if (! fread_dialer_info (zcopy, &sdial)) - fret = FALSE; - else - qdial = &sdial; - } - else - qdial = qport->u.smodem.qdialer; - - if (qdial != NULL) - { - boolean fsighup_ignored; - HELD_SIG_MASK smask; - int i; - sig_atomic_t afhold[INDEXSIG_COUNT]; - const struct schat_info *qchat; - - /* The port I/O routines check whether any signal has been - received, and abort if one has. While we are closing down - the modem, we don't care if we received a signal in the past, - but we do care if we receive a new signal (otherwise it would - be difficult to kill a uucico which was closing down a - modem). We never care if we get SIGHUP at this point. So we - turn off SIGHUP, remember what signals we've already seen, - and clear our notion of what signals we've seen. We have to - block the signals while we remember and clear the array, - since we might otherwise miss a signal which occurred between - the copy and the clear (old systems can't block signals; they - will just have to suffer the race). */ - - usset_signal (SIGHUP, SIG_IGN, FALSE, &fsighup_ignored); - smask = isblocksigs (); - for (i = 0; i < INDEXSIG_COUNT; i++) - { - afhold[i] = afSignal[i]; - afSignal[i] = FALSE; - } - usunblocksigs (smask); - - if (fsuccess) - qchat = &qdial->scomplete; - else - qchat = &qdial->sabort; - if (! fchat (qchat, (const struct ssysteminfo *) NULL, - (const struct sdialer *) NULL, (const char *) NULL, - FALSE, qport->zname, qport->u.smodem.s.s.ibaud)) - fret = FALSE; - - /* Restore the old signal array and the SIGHUP handler. It is - not necessary to block signals here, since all we are doing - is exactly what the signal handler itself would do if the - signal occurred. */ - for (i = 0; i < INDEXSIG_COUNT; i++) - if (afhold[i]) - afSignal[i] = TRUE; - if (! fsighup_ignored) - usset_signal (SIGHUP, ussignal, TRUE, (boolean *) NULL); - } - - if (! fsserial_close (&qport->u.smodem.s.s)) - fret = FALSE; - - if (! fsserial_lockfile (FALSE, qport, qport->u.smodem.zdevice)) - fret = FALSE; - - return fret; -} - -/* Close a direct port. */ - -/*ARGSUSED*/ -boolean -fsysdep_direct_close (qport, fsuccess) - struct sport *qport; - boolean fsuccess; -{ - boolean fret; - - fret = fsserial_close (&qport->u.sdirect.s.s); - - if (! fsserial_lockfile (FALSE, qport, qport->u.sdirect.zdevice)) - fret = FALSE; - - return fret; -} - -/* Reset a serial port by hanging up. */ - -#if ! HAVE_POSIX_TERMIOS - -static boolean -fsserial_reset (q) - struct ssysdep_serial_port *q; -{ - sterminal sbaud; - - if (! q->fterminal) - return TRUE; - - sbaud = q->snew; - -#if HAVE_BSD_TTY - sbaud.sg_ispeed = B0; - sbaud.sg_ospeed = B0; -#else /* ! HAVE_BSD_TTY */ - sbaud.c_cflag = (sbaud.c_cflag &~ CBAUD) | B0; -#endif /* ! HAVE_BSD_TTY */ - - if (! fsetterminfodrain (q->oread, &sbaud)) - ulog (LOG_FATAL, "Can't hangup terminal: %s", strerror (errno)); - - /* Give the terminal a chance to settle. */ - sleep (1); - - if (! fsetterminfo (q->oread, &q->snew)) - ulog (LOG_FATAL, "Can't reopen terminal: %s", strerror (errno)); - - return TRUE; -} - -#else /* HAVE_POSIX_TERMIOS */ - -static boolean -fsserial_reset (q) - struct ssysdep_serial_port *q; -{ - sterminal sbaud; - speed_t iin, iout; - - if (! q->fterminal) - return TRUE; - - iin = cfgetispeed (&q->snew); - iout = cfgetospeed (&q->snew); - - sbaud = q->snew; - - if (cfsetospeed (&sbaud, B0) != 0 - || ! fsetterminfodrain (q->oread, &sbaud)) - ulog (LOG_FATAL, "Can't hangup terminal: %s", strerror (errno)); - - /* Give the terminal a chance to settle. */ - sleep (1); - - if (cfsetispeed (&q->snew, iin) != 0 - || cfsetospeed (&q->snew, iout) != 0 - || ! fsetterminfo (q->oread, &q->snew)) - ulog (LOG_FATAL, "Can't reopen terminal: %s", strerror (errno)); - - return TRUE; -} - -#endif /* HAVE_POSIX_TERMIOS */ - -/* Reset a stdin port. */ - -boolean -fsysdep_stdin_reset (qport) - struct sport *qport; -{ - return fsserial_reset (&qport->u.sstdin.s.s); -} - -/* Reset a modem port. */ - -boolean -fsysdep_modem_reset (qport) - struct sport *qport; -{ - return fsserial_reset (&qport->u.smodem.s.s); -} - -/* Reset a direct port. */ - -boolean -fsysdep_direct_reset (qport) - struct sport *qport; -{ - return fsserial_reset (&qport->u.sdirect.s.s); -} - -/* Begin dialing out on a modem port. This opens the dialer device if - there is one. */ - -boolean -fsysdep_modem_begin_dial (qport, qdial) - struct sport *qport; - struct sdialer *qdial; -{ -#ifdef TIOCMODEM - /* If we can tell the modem to obey modem control, do so. */ - { - int iperm; - - iperm = 0; - (void) ioctl (qport->u.smodem.s.s.oread, TIOCMODEM, &iperm); - } -#endif /* TIOCMODEM */ - -#ifdef TIOCCDTR - /* If we supposed to toggle DTR, do so. */ - - if (qdial->fdtr_toggle) - { - (void) ioctl (qport->u.smodem.s.s.oread, TIOCCDTR, 0); - (void) ioctl (qport->u.smodem.s.s.oread, TIOCSDTR, 0); - - if (qdial->fdtr_toggle_wait) - sleep (1); - } -#endif /* TIOCCDTR */ - - if (! fsysdep_modem_no_carrier (qport)) - return FALSE; - - /* Open the dial device if there is one. */ - if (qport->u.smodem.zdial_device != NULL) - { - const char *z; - int oread; - - qport->u.smodem.s.s.oholdread = qport->u.smodem.s.s.oread; - qport->u.smodem.s.s.oholdwrite = qport->u.smodem.s.s.owrite; - - z = qport->u.smodem.zdial_device; - if (*z != '/') - { - char *zcopy; - - zcopy = (char *) alloca (sizeof "/dev/" + strlen (z)); - sprintf (zcopy, "/dev/%s", z); - z = zcopy; - } - - oread = open (z, O_RDWR); - if (oread < 0) - { - ulog (LOG_ERROR, "open (%s): %s", z, strerror (errno)); - return FALSE; - } - - qport->u.smodem.s.s.oread = qport->u.smodem.s.s.owrite = oread; - } - - return TRUE; -} - -/* Tell the port to not require carrier. I don't know how to do this - on a BSD system that doesn't support TIOCNCAR, if there are any - such systems. */ - -boolean -fsysdep_modem_no_carrier (qport) - struct sport *qport; -{ - if (! qport->u.smodem.s.s.fterminal) - return TRUE; - -#ifdef TIOCNCAR - /* Tell the modem to ignore carrier. */ - if (ioctl (qport->u.smodem.s.s.oread, TIOCNCAR, 0) < 0) - { - ulog (LOG_ERROR, "ioctl (TIOCNCAR): %s", strerror (errno)); - return FALSE; - } -#endif /* TIOCNCAR */ - -#if HAVE_SYSV_TERMIO || HAVE_POSIX_TERMIOS - /* Put the modem into local mode (ignore carrier) to start the chat - script. */ - qport->u.smodem.s.s.snew.c_cflag |= CLOCAL; - if (! fsetterminfo (qport->u.smodem.s.s.oread, - &qport->u.smodem.s.s.snew)) - { - ulog (LOG_ERROR, "Can't set CLOCAL: %s", strerror (errno)); - return FALSE; - } -#endif /* HAVE_SYSV_TERMIO || HAVE_POSIX_TERMIOS */ - - return TRUE; -} - -/* Tell the port to require carrier. If the port does not support - carrier, we do nothing. We do not need to worry whether the - dialer supports carrier, since this will only be called when - explicitly requested by a dialer chat script. */ - -boolean -fsysdep_modem_need_carrier (qport) - struct sport *qport; -{ - if (! qport->u.smodem.s.s.fterminal) - return TRUE; - - if (qport->u.smodem.fcarrier) - { -#ifdef TIOCCAR - /* Tell the modem to pay attention to carrier. */ - if (ioctl (qport->u.smodem.s.s.oread, TIOCCAR, 0) < 0) - { - ulog (LOG_ERROR, "ioctl (TIOCCAR): %s", strerror (errno)); - return FALSE; - } -#endif /* TIOCCAR */ - -#if HAVE_SYSV_TERMIO || HAVE_POSIX_TERMIOS - /* Put the modem into nonlocal mode. */ - qport->u.smodem.s.s.snew.c_cflag &=~ CLOCAL; - if (! fsetterminfo (qport->u.smodem.s.s.oread, - &qport->u.smodem.s.s.snew)) - { - ulog (LOG_ERROR, "Can't clear CLOCAL: %s", strerror (errno)); - return FALSE; - } -#endif /* HAVE_SYSV_TERMIO || HAVE_POSIX_TERMIOS */ - } - - return TRUE; -} - -/* Finish dialing out on a modem by closing any dialer device and waiting - for carrier. */ - -boolean -fsysdep_modem_end_dial (qport, qdial) - struct sport *qport; - struct sdialer *qdial; -{ - if (qport->u.smodem.zdial_device != NULL) - { - (void) close (qport->u.smodem.s.s.oread); - qport->u.smodem.s.s.oread = qport->u.smodem.s.s.oholdread; - qport->u.smodem.s.s.owrite = qport->u.smodem.s.s.oholdwrite; - } - - if (qport->u.smodem.fcarrier && qdial->fcarrier) - { - /* Tell the port that we need carrier. */ - - if (! fsysdep_modem_need_carrier (qport)) - return FALSE; - -#ifdef TIOCWONLINE - - /* We know how to wait for carrier, so do so. */ - - /* If we already got a signal, just quit now. */ - if (FGOT_QUIT_SIGNAL ()) - return FALSE; - - /* This bit of code handles signals just like fsserial_read - does. See that function for a longer explanation. */ - - /* Use fsysdep_catch to handle a longjmp from the signal - handler. */ - - fSalarm = FALSE; - - if (fsysdep_catch ()) - { - /* Start catching SIGALRM; normally we ignore it. */ - usysdep_start_catch (); - usset_signal (SIGALRM, usalarm, TRUE, (boolean *) NULL); - (void) alarm (qdial->ccarrier_wait); - - /* We really don't care if we get an error, since that will - probably just mean that TIOCWONLINE isn't supported in - which case there's nothing we can do anyhow. If we get - SIGINT we want to keep waiting for carrier, because - SIGINT just means don't start any new sessions. We don't - handle SIGINT correctly if we do a longjmp in the signal - handler; too bad. */ - while (ioctl (qport->u.smodem.s.s.oread, TIOCWONLINE, 0) < 0 - && errno == EINTR) - { - /* Log the signal. */ - ulog (LOG_ERROR, (const char *) NULL); - if (FGOT_QUIT_SIGNAL () || fSalarm) - break; - } - } - - /* Turn off the pending SIGALRM and ignore SIGALARM again. */ - usset_signal (SIGALRM, SIG_IGN, TRUE, (boolean *) NULL); - (void) alarm (0); - usysdep_end_catch (); - - /* If we got a random signal, just return FALSE. */ - if (FGOT_QUIT_SIGNAL ()) - return FALSE; - - /* If we timed out, give an error. */ - if (fSalarm) - { - ulog (LOG_ERROR, "Timed out waiting for carrier"); - return FALSE; - } - -#endif /* TIOCWONLINE */ - } - - return TRUE; -} - -/* Read data from a serial port, with a timeout. - - This function should return when we have read cmin characters or - the timeout has occurred. We have to work a bit to get UNIX to do - this efficiently. The simple implementation schedules a SIGALRM - signal and then calls read; if there is a single character - available, the call to read will return immediately, so there must - be a loop which terminates when the SIGALRM is delivered or the - correct number of characters has been read. This can be very - inefficient with a fast CPU or a low baud rate (or both!), since - each call to read may return only one or two characters. - - Under POSIX or System V, we can specify a minimum number of - characters to read, so there is no serious trouble. - - Under BSD, we figure out how many characters we have left to read, - how long it will take for them to arrive at the current baud rate, - and sleep that long. - - Doing this with a timeout and avoiding all possible race conditions - get very hairy, though. Basically, we're going to schedule a - SIGALRM for when the timeout expires. I don't really want to do a - longjmp in the SIGALRM handler, though, because that may lose data. - Therefore, I have the signal handler set a variable. However, this - means that there will be a span of time between the time the code - checks the variable and the time it calls the read system call; if - the SIGALRM occurs during that time, the read might hang forever. - To avoid this, the SIGALRM handler not only sets a global variable, - it also schedules another SIGALRM for one second in the future - (POSIX specifies that a signal handler is permitted to safely call - alarm). To avoid getting a continual sequence of SIGALRM - interrupts, we change the signal handler to ignore SIGALRM when - we're about to exit the function. This means that every time we - execute fsserial_read we make at least five system calls. It's the - best I've been able to come up with, though. - - When fsserial_read finishes, there will be no SIGALRM scheduled and - SIGALRM will be ignored. */ - -static boolean -fsserial_read (q, zbuf, pclen, cmin, ctimeout, freport, fpty) - struct ssysdep_serial_port *q; - char *zbuf; - int *pclen; - int cmin; - int ctimeout; - boolean freport; - boolean fpty; -{ - CATCH_PROTECT int cwant; - boolean fret; - - cwant = *pclen; - *pclen = 0; - - /* Guard against a bad timeout. We return TRUE when a timeout - expires. It is possible to get a negative timeout here because - the calling code does not check user supplied timeouts for - plausibility. */ - if (ctimeout <= 0) - return TRUE; - - /* We want to do a blocking read. */ - if (! fsblock (q, TRUE)) - return FALSE; - - fSalarm = FALSE; - - /* We're going to set up an alarm signal to last for the entire - read. If the read system call cannot be interrupted, the signal - handler will do a longjmp causing fsysdep_catch (a macro) to - return FALSE. We handle that here. If read can be interrupted, - fsysdep_catch will be defined to TRUE. */ - - if (fsysdep_catch ()) - { - /* Prepare to catch SIGALRM and schedule the signal. */ - usysdep_start_catch (); - usset_signal (SIGALRM, usalarm, TRUE, (boolean *) NULL); - alarm (ctimeout); - } - else - { - /* We caught a signal. We don't actually have to do anything, - as all the appropriate checks are made at the start of the - following loop. */ - } - - fret = FALSE; - - while (TRUE) - { - int cgot; - -#if HAVE_SYSV_TERMIO || HAVE_POSIX_TERMIOS - /* If we can tell the terminal not to return until we have a - certain number of characters, do so. */ - if (q->fterminal) - { - int csetmin; - - /* I'm not that confident about setting MIN to values larger - than 127, although up to 255 would probably work. */ - if (cmin < 127) - csetmin = cmin; - else - csetmin = 127; - - if (csetmin != cSmin) - { - q->snew.c_cc[VMIN] = csetmin; - if (! fsetterminfo (q->oread, &q->snew)) - { - int ierr; - - /* We turn off the signal before reporting the error - to minimize any problems with interrupted system - calls. */ - ierr = errno; - usset_signal (SIGALRM, SIG_IGN, TRUE, (boolean *) NULL); - alarm (0); - usysdep_end_catch (); - ulog (LOG_ERROR, "Can't set MIN for terminal: %s", - strerror (ierr)); - return FALSE; - } - cSmin = csetmin; - } - } -#endif /* HAVE_SYSV_TERMIO || HAVE_POSIX_TERMIOS */ - - /* If we've received a signal, get out now. */ - if (FGOT_QUIT_SIGNAL ()) - break; - - /* If we've already gotten a SIGALRM, get out with whatever - we've accumulated. */ - - if (fSalarm) - { - fret = TRUE; - break; - } - - /* Right here is the race condition which we avoid by having the - SIGALRM handler schedule another SIGALRM. */ - - cgot = read (q->oread, zbuf, cwant); - - /* If the read returned an error, check for signals. */ - if (cgot < 0) - { - if (errno == EINTR) - { - /* Log the signal. */ - ulog (LOG_ERROR, (const char *) NULL); - } - if (fSalarm) - { - fret = TRUE; - break; - } - if (FGOT_QUIT_SIGNAL ()) - break; - } - - /* If read returned an error, get out. We just ignore EINTR - here, since it must be from some signal we don't care about. - If the read returned 0 then the line must have been hung up - (normally we would have received SIGHUP, but we can't count - on that). We turn off the signals before calling ulog to - reduce problems with interrupted system calls. */ - if (cgot <= 0) - { - if (cgot < 0 && errno == EINTR) - cgot = 0; - else - { - int ierr; - - ierr = errno; - - usset_signal (SIGALRM, SIG_IGN, TRUE, (boolean *) NULL); - alarm (0); - usysdep_end_catch (); - - if (freport) - { - if (cgot == 0) - ulog (LOG_ERROR, "Line disconnected"); - else - ulog (LOG_ERROR, "read: %s", strerror (ierr)); - } - - return FALSE; - } - } - - cwant -= cgot; - cmin -= cgot; - zbuf += cgot; - *pclen += cgot; - - /* If we have enough data, get out now. */ - - if (cmin <= 0) - { - fret = TRUE; - break; - } - -#if HAVE_BSD_TTY - /* We still want more data, so sleep long enough for the rest of - it to arrive. We don't this for System V or POSIX because - setting MIN is good enough (we can't sleep longer than it - takes to get MAX_INPUT characters anyhow). - - The baud rate is approximately 10 times the number of - characters which will arrive in one second, so the number of - milliseconds to sleep == - characters * (milliseconds / character) == - characters * (1000 * (seconds / character)) == - characters * (1000 * (1 / (baud / 10))) == - characters * (10000 / baud) - - We arbitrarily reduce the sleep amount by 10 milliseconds to - attempt to account for the amount of time it takes to set up - the sleep. This is how long it takes to get half a character - at 19200 baud. We then don't bother to sleep for less than - 10 milliseconds. We don't sleep if the read was interrupted. - - We use select to sleep. It would be easy to use poll as - well, but it's unlikely that any system with BSD ttys would - have poll but not select. Using select avoids hassles with - the pending SIGALRM; if it hits the select will be - interrupted, and otherwise the select will not affect it. */ - -#if ! HAVE_SELECT - #error This code requires select; feel free to extend it -#endif - - if (q->fterminal && ! fpty && cmin > 1 && cgot > 0) - { - int csleepchars; - int isleep; - - /* We don't try to read all the way up to MAX_INPUT, - since that might drop a character. */ - - if (cmin <= MAX_INPUT - 10) - csleepchars = cmin; - else - csleepchars = MAX_INPUT - 10; - - isleep = (int) (((long) csleepchars * 10000L) / q->ibaud); - isleep -= 10; - - if (isleep > 10) - { - struct timeval s; - - s.tv_sec = isleep / 1000; - s.tv_usec = (isleep % 1000) * 1000; - - /* Some versions of select take a pointer to an int, - while some take a pointer to an fd_set. I just cast - the arguments to a generic pointer, and assume that - any machine which distinguishes int * from fd_set * - (I would be amazed if there are any such machines) - have an appropriate prototype somewhere or other. */ - (void) select (0, (pointer) NULL, (pointer) NULL, - (pointer) NULL, &s); - - /* Here either the select finished sleeping or we got a - SIGALRM. If the latter occurred, fSalarm was set to - TRUE; it will be checked at the top of the loop. */ - } - } -#endif /* HAVE_BSD_TTY */ - } - - /* Turn off the pending SIGALRM and return. */ - - usset_signal (SIGALRM, SIG_IGN, TRUE, (boolean *) NULL); - alarm (0); - usysdep_end_catch (); - - return fret; -} - -/* Read from a stdin port. */ - -boolean -fsysdep_stdin_read (qport, zbuf, pclen, cmin, ctimeout, freport) - struct sport *qport; - char *zbuf; - int *pclen; - int cmin; - int ctimeout; - boolean freport; -{ - return fsserial_read (&qport->u.sstdin.s.s, zbuf, pclen, cmin, ctimeout, - freport, qport->u.sstdin.s.fpty); -} - -/* Read from a modem port. */ - -boolean -fsysdep_modem_read (qport, zbuf, pclen, cmin, ctimeout, freport) - struct sport *qport; - char *zbuf; - int *pclen; - int cmin; - int ctimeout; - boolean freport; -{ - return fsserial_read (&qport->u.smodem.s.s, zbuf, pclen, cmin, ctimeout, - freport, FALSE); -} - -/* Read from a direct port. */ - -boolean -fsysdep_direct_read (qport, zbuf, pclen, cmin, ctimeout, freport) - struct sport *qport; - char *zbuf; - int *pclen; - int cmin; - int ctimeout; - boolean freport; -{ - return fsserial_read (&qport->u.sdirect.s.s, zbuf, pclen, cmin, ctimeout, - freport, FALSE); -} - -/* Write data to a serial port. */ - -static boolean -fsserial_write (q, zwrite, cwrite) - struct ssysdep_serial_port *q; - const char *zwrite; - int cwrite; -{ - int czero; - - /* We want blocking writes here. */ - if (! fsblock (q, TRUE)) - return FALSE; - - czero = 0; - - while (cwrite > 0) - { - int cdid; - - /* If we've received a signal, don't continue. */ - if (FGOT_QUIT_SIGNAL ()) - return FALSE; - - /* Loop until we don't get an interrupt. */ - while ((cdid = write (q->owrite, zwrite, cwrite)) < 0 - && errno == EINTR) - { - /* Log the signal. */ - ulog (LOG_ERROR, (const char *) NULL); - if (FGOT_QUIT_SIGNAL ()) - return FALSE; - } - - if (cdid < 0) - { - if (errno != EWOULDBLOCK && errno != EAGAIN) - { - ulog (LOG_ERROR, "write: %s", strerror (errno)); - return FALSE; - } - cdid = 0; - } - - if (cdid == 0) - { - /* On some systems write will return 0 if carrier is lost. - If we fail to write anything ten times in a row, we - assume that this has happened. This is hacked in like - this because there seems to be no reliable way to tell - exactly why the write returned 0. */ - ++czero; - if (czero >= 10) - { - ulog (LOG_ERROR, "Line disconnected"); - return FALSE; - } - } - else - { - czero = 0; - - cwrite -= cdid; - zwrite += cdid; - } - } - - return TRUE; -} - -/* Write to a stdin port. */ - -boolean -fsysdep_stdin_write (qport, zwrite, cwrite) - struct sport *qport; - const char *zwrite; - int cwrite; -{ - return fsserial_write (&qport->u.sstdin.s.s, zwrite, cwrite); -} - -/* Write to a modem port. */ - -boolean -fsysdep_modem_write (qport, zwrite, cwrite) - struct sport *qport; - const char *zwrite; - int cwrite; -{ - return fsserial_write (&qport->u.smodem.s.s, zwrite, cwrite); -} - -/* Write to a direct port. */ - -boolean -fsysdep_direct_write (qport, zwrite, cwrite) - struct sport *qport; - const char *zwrite; - int cwrite; -{ - return fsserial_write (&qport->u.sdirect.s.s, zwrite, cwrite); -} - -/* The fsysdep_io routine is supposed to both read and write data - until it has either filled its read buffer or written out all the - data it was given. This lets us write out large packets without - losing incoming data. */ - -static boolean -fsserial_io (q, zwrite, pcwrite, zread, pcread) - struct ssysdep_serial_port *q; - const char *zwrite; - int *pcwrite; - char *zread; - int *pcread; -{ - int cwrite, cread, czero; - - cwrite = *pcwrite; - *pcwrite = 0; - cread = *pcread; - *pcread = 0; - - czero = 0; - - while (TRUE) - { - int cgot, cdo, cdid; - - /* If we've received a signal, don't continue. */ - if (FGOT_QUIT_SIGNAL ()) - return FALSE; - - /* This used to always use nonblocking writes, but it turns out - that some systems don't support them on terminals. - - The current algorithm is: - loop: - unblocked read - if read buffer full, return - if nothing to write, return - if HAVE_UNBLOCKED_WRITES - write all data - else - write up to SINGLE_WRITE bytes - if all data written, return - if no data written - blocked write of up to SINGLE_WRITE bytes - - This algorithm should work whether the system supports - unblocked writes on terminals or not. If the system supports - unblocked writes but HAVE_UNBLOCKED_WRITES is 0, then it will - call write more often than it needs to. If the system does - not support unblocked writes but HAVE_UNBLOCKED_WRITES is 1, - then the write may hang so long that incoming data is lost. - This is actually possible at high baud rates on any system - when a blocking write is done; there is no solution, except - hardware handshaking. */ - - /* Do an unblocked read. */ - - if (! fsblock (q, FALSE)) - return FALSE; - - /* Loop until we get something (error or data) other than an - acceptable EINTR. */ - while ((cgot = read (q->oread, zread, cread)) < 0 - && errno == EINTR) - { - /* Log the signal. */ - ulog (LOG_ERROR, (const char *) NULL); - if (FGOT_QUIT_SIGNAL ()) - return FALSE; - } - - if (cgot < 0) - { - if (errno != EAGAIN && errno != EWOULDBLOCK) - { - ulog (LOG_ERROR, "read: %s", strerror (errno)); - return FALSE; - } - cgot = 0; - } - - cread -= cgot; - zread += cgot; - *pcread += cgot; - - /* If we've filled the read buffer, or we have nothing left to - write, return out. */ - - if (cread <= 0 || cwrite <= 0) - return TRUE; - - /* The port is currently unblocked. Do a write. */ - - cdo = cwrite; - -#if ! HAVE_UNBLOCKED_WRITES - if (cdo > SINGLE_WRITE) - cdo = SINGLE_WRITE; -#endif - - /* Loop until we get something besides EINTR. */ - while ((cdid = write (q->owrite, zwrite, cdo)) < 0 - && errno == EINTR) - { - /* Log the signal. */ - ulog (LOG_ERROR, (const char *) NULL); - if (FGOT_QUIT_SIGNAL ()) - return FALSE; - } - - if (cdid < 0) - { - if (errno != EWOULDBLOCK && errno != EAGAIN) - { - ulog (LOG_ERROR, "write: %s", strerror (errno)); - return FALSE; - } - cdid = 0; - } - - if (cdid > 0) - { - /* We wrote some data. If we wrote everything, return out. - Otherwise loop around and do another read. */ - cwrite -= cdid; - zwrite += cdid; - *pcwrite += cdid; - - if (cwrite <= 0) - return TRUE; - - czero = 0; - } - else - { - /* We didn't write any data. Do a blocking write. */ - - if (! fsblock (q, TRUE)) - return FALSE; - - cdo = cwrite; - if (cdo > SINGLE_WRITE) - cdo = SINGLE_WRITE; - - DEBUG_MESSAGE1 (DEBUG_PORT, - "fsserial_io: Blocking write of %d", cdo); - - /* Loop until we get something besides EINTR. */ - while ((cdid = write (q->owrite, zwrite, cdo)) < 0 - && errno == EINTR) - { - /* Log the signal. */ - ulog (LOG_ERROR, (const char *) NULL); - if (FGOT_QUIT_SIGNAL ()) - return FALSE; - } - - if (cdid < 0) - { - ulog (LOG_ERROR, "write: %s", strerror (errno)); - return FALSE; - } - - if (cdid == 0) - { - /* On some systems write will return 0 if carrier is - lost. If we fail to write anything ten times in a - row, we assume that this has happened. This is - hacked in like this because there seems to be no - reliable way to tell exactly why the write returned - 0. */ - ++czero; - if (czero >= 10) - { - ulog (LOG_ERROR, "Line disconnected"); - return FALSE; - } - } - else - { - cwrite -= cdid; - zwrite += cdid; - *pcwrite += cdid; - czero = 0; - } - } - } -} - -/* I/O to a stdin port. */ - -boolean -fsysdep_stdin_io (qport, zwrite, pcwrite, zread, pcread) - struct sport *qport; - const char *zwrite; - int *pcwrite; - char *zread; - int *pcread; -{ - return fsserial_io (&qport->u.sstdin.s.s, zwrite, pcwrite, zread, pcread); -} - -/* I/O to a modem port. */ - -boolean -fsysdep_modem_io (qport, zwrite, pcwrite, zread, pcread) - struct sport *qport; - const char *zwrite; - int *pcwrite; - char *zread; - int *pcread; -{ - return fsserial_io (&qport->u.smodem.s.s, zwrite, pcwrite, zread, pcread); -} - -/* I/O to a direct port. */ - -boolean -fsysdep_direct_io (qport, zwrite, pcwrite, zread, pcread) - struct sport *qport; - const char *zwrite; - int *pcwrite; - char *zread; - int *pcread; -{ - return fsserial_io (&qport->u.sdirect.s.s, zwrite, pcwrite, zread, pcread); -} - -/* Send a break character to a serial port. */ - -static boolean -fsserial_break (q) - struct ssysdep_serial_port *q; -{ -#if HAVE_BSD_TTY - ioctl (q->owrite, TIOCSBRK, 0); - sleep (1); - ioctl (q->owrite, TIOCCBRK, 0); - return TRUE; -#endif /* HAVE_BSD_TTY */ -#if HAVE_SYSV_TERMIO - ioctl (q->owrite, TCSBRK, 0); - return TRUE; -#endif /* HAVE_SYSV_TERMIO */ -#if HAVE_POSIX_TERMIOS - return tcsendbreak (q->owrite, 0) == 0; -#endif /* HAVE_POSIX_TERMIOS */ -} - -/* Send a break character to a stdin port. */ - -boolean -fsysdep_stdin_break (qport) - struct sport *qport; -{ - return fsserial_break (&qport->u.sstdin.s.s); -} - -/* Send a break character to a modem port. */ - -boolean -fsysdep_modem_break (qport) - struct sport *qport; -{ - return fsserial_break (&qport->u.smodem.s.s); -} - -/* Send a break character to a direct port. */ - -boolean -fsysdep_direct_break (qport) - struct sport *qport; -{ - return fsserial_break (&qport->u.sdirect.s.s); -} - -/* Change the setting of a serial port. */ - -static boolean -fsserial_set (q, tset) - struct ssysdep_serial_port *q; - enum tportsetting tset; -{ - if (! q->fterminal) - return TRUE; - - switch (tset) - { - case PORTSETTING_EIGHT: -#if HAVE_BSD_TTY - if (q->snew.sg_flags == (RAW | ANYP)) - return TRUE; - q->snew.sg_flags = RAW | ANYP; -#endif -#if HAVE_SYSV_TERMIO || HAVE_POSIX_TERMIOS - if ((q->snew.c_iflag & ICLEAR_IFLAG) == 0) - return TRUE; - q->snew.c_iflag &=~ ICLEAR_IFLAG; -#endif - if (! fsetterminfodrain (q->oread, &q->snew)) - { - ulog (LOG_ERROR, "Can't go to raw mode: %s", strerror (errno)); - return FALSE; - } - return TRUE; - - case PORTSETTING_SEVEN: -#if HAVE_BSD_TTY - if (q->snew.sg_flags == (CBREAK | ANYP | TANDEM)) - return TRUE; - q->snew.sg_flags = CBREAK | ANYP | TANDEM; -#endif /* HAVE_BSD_TTY */ -#if HAVE_SYSV_TERMIO | HAVE_POSIX_TERMIOS - { - int iwant; - -#ifdef CRTSCTS - /* It would be nice to do this is in a more portable fashion, - but in any case this is apparently correct for SunOS. If - we are doing hardware flow control, we don't also send - start and stop characters; however, we do recognize - incoming start and stop characters. */ - if ((q->snew.c_cflag & CRTSCTS) != 0) - iwant = ISTRIP | IXON; - else - iwant = ISTRIP | IXON | IXOFF; -#else /* ! defined (CRTSCTS) */ - iwant = ISTRIP | IXON | IXOFF; -#endif /* ! defined (CRTSCTS) */ - - if ((q->snew.c_iflag & ICLEAR_IFLAG) == iwant) - return TRUE; - - q->snew.c_iflag &=~ ICLEAR_IFLAG; - q->snew.c_iflag |= iwant; - } -#endif /* HAVE_SYSV_TERMIO | HAVE_POSIX_TERMIOS */ - - if (! fsetterminfodrain (q->oread, &q->snew)) - { - ulog (LOG_ERROR, "Can't go to seven bit mode: %s", - strerror (errno)); - return FALSE; - } - return TRUE; - - default: -#if DEBUG > 0 - ulog (LOG_FATAL, "fsserial_set: Can't happen"); -#endif - return FALSE; - } -} - -/* Change settings of a stdin port. */ - -boolean -fsysdep_stdin_set (qport, tset) - struct sport *qport; - enum tportsetting tset; -{ - return fsserial_set (&qport->u.sstdin.s.s, tset); -} - -/* Change settings of a modem port. */ - -boolean -fsysdep_modem_set (qport, tset) - struct sport *qport; - enum tportsetting tset; -{ - return fsserial_set (&qport->u.smodem.s.s, tset); -} - -/* Change settings of a direct port. */ - -boolean -fsysdep_direct_set (qport, tset) - struct sport *qport; - enum tportsetting tset; -{ - return fsserial_set (&qport->u.sdirect.s.s, tset); -} - -/* Run a chat program. */ - -static boolean -fsrun_chat (oread, owrite, zprog) - int oread; - int owrite; - const char *zprog; -{ - int cargs; - const char **azargs; - char *zcopy, *zarg; - int aidescs[3]; - FILE *e; - pid_t ipid; - char *z; - - /* Get the arguments into an array to pass to isspawn. */ - zcopy = (char *) alloca (strlen (zprog) + 1); - strcpy (zcopy, zprog); - cargs = 0; - for (zarg = strtok (zcopy, " \t"); - zarg != NULL; - zarg = strtok ((char *) NULL, " \t")) - ++cargs; - - azargs = (const char **) alloca ((cargs + 1) * sizeof (const char *)); - - strcpy (zcopy, zprog); - cargs = 0; - for (zarg = strtok (zcopy, " \t"); - zarg != NULL; - zarg = strtok ((char *) NULL, " \t")) - { - azargs[cargs] = zarg; - ++cargs; - } - azargs[cargs] = NULL; - - aidescs[0] = oread; - aidescs[1] = owrite; - aidescs[2] = SPAWN_READ_PIPE; - - /* Pass fkeepuid, fkeepenv and fshell as TRUE. This puts the - responsibility of maintaing security on the chat program. */ - ipid = isspawn (azargs, aidescs, TRUE, TRUE, (const char *) NULL, - FALSE, TRUE, (const char *) NULL, - (const char *) NULL, (const char *) NULL); - if (ipid < 0) - { - ulog (LOG_ERROR, "isspawn (%s): %s", azargs[0], strerror (errno)); - return FALSE; - } - - e = fdopen (aidescs[2], (char *) "r"); - if (e == NULL) - { - ulog (LOG_ERROR, "fdopen: %s", strerror (errno)); - (void) close (aidescs[2]); - (void) kill (ipid, SIGKILL); - (void) iswait ((unsigned long) ipid, (const char *) NULL); - return FALSE; - } - - /* The FILE e now is attached to stderr of the program. Forward - every line the program outputs to the log file. */ - while ((z = zfgets (e, FALSE)) != NULL) - { - int clen; - - clen = strlen (z); - if (z[clen - 1] == '\n') - z[clen - 1] = '\0'; - if (*z != '\0') - ulog (LOG_NORMAL, "chat: %s", z); - xfree ((pointer) z); - } - - (void) fclose (e); - - return iswait ((unsigned long) ipid, "Chat program") == 0; -} - -/* Run a chat program on a stdin port. */ - -boolean -fsysdep_stdin_chat (qport, zprog) - struct sport *qport; - const char *zprog; -{ - return fsrun_chat (qport->u.sstdin.s.s.oread, - qport->u.sstdin.s.s.owrite, - zprog); -} - -/* Run a chat program on a modem port. */ - -boolean -fsysdep_modem_chat (qport, zprog) - struct sport *qport; - const char *zprog; -{ - return fsrun_chat (qport->u.smodem.s.s.oread, - qport->u.smodem.s.s.owrite, - zprog); -} - -/* Run a chat program on a direct port. */ - -boolean -fsysdep_direct_chat (qport, zprog) - struct sport *qport; - const char *zprog; -{ - return fsrun_chat (qport->u.sdirect.s.s.oread, - qport->u.sdirect.s.s.owrite, - zprog); -} - -#if HAVE_TCP - -/* Run a chat program on a TCP port. */ - -boolean -fsysdep_tcp_chat (qport, zprog) - struct sport *qport; - const char *zprog; -{ - return fsrun_chat (qport->u.stcp.o, qport->u.stcp.o, zprog); -} - -#endif /* HAVE_TCP */ - -/* Functions to return baud rates. */ - -/* Return baud rate of a stdin port. */ - -long -isysdep_stdin_baud (qport) - struct sport *qport; -{ - return qport->u.sstdin.s.s.ibaud; -} - -/* Return baud rate of a modem port. */ - -long -isysdep_modem_baud (qport) - struct sport *qport; -{ - return qport->u.smodem.s.s.ibaud; -} - -/* Return baud rate of a direct port. */ - -long -isysdep_direct_baud (qport) - struct sport *qport; -{ - return qport->u.sdirect.s.s.ibaud; -} - -#if HAVE_TCP - -/* Some system dependent routines for TCP ports. These work by - setting up an ssysdep_serial_port structure to fake out the serial - port routines. I'm doing it this way to avoid having to write the - complicated timeout code twice, and because the serial port code - will work fine. It does mean that if the serial port code changes - this code will have to be considered. */ - -/* Read data from a TCP port. */ - -boolean -fsysdep_tcp_read (qport, zread, pclen, cmin, ctimeout, freport) - struct sport *qport; - char *zread; - int *pclen; - int cmin; - int ctimeout; - boolean freport; -{ - struct ssysdep_serial_port s; - - s.oread = s.owrite = qport->u.stcp.o; - s.fread_blocking = TRUE; - s.fterminal = FALSE; - return fsserial_read (&s, zread, pclen, cmin, ctimeout, freport, FALSE); -} - -/* Write data to a TCP port. */ - -boolean -fsysdep_tcp_write (qport, zwrite, cwrite) - struct sport *qport; - const char *zwrite; - int cwrite; -{ - struct ssysdep_serial_port s; - - s.oread = s.owrite = qport->u.stcp.o; - s.fread_blocking = TRUE; - s.fterminal = FALSE; - return fsserial_write (&s, zwrite, cwrite); -} - -/* Read and write data to and from a TCP port. We actually don't - bother to really implement this, since the system will buffer up - plenty of TCP data (only 256 bytes are buffered for a terminal, - so losing data becomes a real possibility). */ - -boolean -fsysdep_tcp_io (qport, zwrite, pcwrite, zread, pcread) - struct sport *qport; - const char *zwrite; - int *pcwrite; - char *zread; - int *pcread; -{ - struct ssysdep_serial_port s; - - s.oread = s.owrite = qport->u.stcp.o; - s.fread_blocking = TRUE; - s.fterminal = FALSE; - *pcread = 0; - return fsserial_write (&s, zwrite, *pcwrite); -} - -#endif /* HAVE_TCP */ - -/* - Local variables: - mode:c - End: - */ diff --git a/gnu/libexec/uucp/sys3.unx b/gnu/libexec/uucp/sys3.unx deleted file mode 100644 index 9ef70d643b8..00000000000 --- a/gnu/libexec/uucp/sys3.unx +++ /dev/null @@ -1,2650 +0,0 @@ -/* sys3.unx - The system dependent spool directory subroutines for Unix. - - 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 AIRS, P.O. Box 520, Waltham, MA 02254. - - $Log: sys3.unx,v $ - Revision 1.1.1.1 1993/03/21 09:45:37 cgd - initial import of 386bsd-0.1 sources - -# Revision 1.2 92/05/13 05:42:07 rich -# ported to 386bsd -# -# Revision 1.1 1992/05/10 18:00:16 rich -# Initial revision -# - Revision 1.48 1992/04/01 22:36:48 ian - David J. MacKenzie: some USG_STATFS systems use 512 despite f_bsize - - Revision 1.47 1992/03/30 15:03:07 ian - Niels Baggesen: USG statfs has an f_bsize field - - Revision 1.46 1992/03/28 22:06:38 ian - Michael I Bushnell: renamed enum tstatus to avoid header file conflict - - Revision 1.45 1992/03/26 20:20:28 ian - Reduce race condition in fsdo_lock - - Revision 1.44 1992/03/15 01:54:46 ian - All execs are now done in isspawn, all waits are done in iswait - - Revision 1.43 1992/03/12 19:54:43 ian - Debugging based on types rather than number - - Revision 1.42 1992/03/10 20:45:58 ian - Check size of destination file system as well as temporary system - - Revision 1.41 1992/03/09 19:42:43 ian - Ted Lindgreen: don't send mail for nonexistent file - - Revision 1.40 1992/03/04 01:40:51 ian - Thomas Fischer: tweaked a bit for the NeXT - - Revision 1.39 1992/02/29 04:07:08 ian - Added -j option to uucp and uux - - Revision 1.38 1992/02/29 01:06:59 ian - Chip Salzenberg: recheck file permissions before sending - - Revision 1.37 1992/02/28 15:57:58 ian - Give error if esysdep_open_send is given a directory - - Revision 1.36 1992/02/24 22:05:30 ian - Roberto Biancardi: support F_CHSIZE and F_FREESP in esysdep_truncate - - Revision 1.35 1992/02/24 20:07:43 ian - John Theus: some systems don't have <fcntl.h> - - Revision 1.34 1992/02/23 03:26:51 ian - Overhaul to use automatic configure shell script - - Revision 1.33 1992/02/20 04:18:59 ian - Added uustat - - Revision 1.32 1992/02/08 03:54:18 ian - Include <string.h> only in <uucp.h>, added 1992 copyright - - Revision 1.31 1992/02/02 20:42:40 ian - Niels Baggesen: case enum to int before comparison - - Revision 1.30 1992/02/01 00:54:31 ian - Michael Nolan: cast alloca return value - - Revision 1.29 1992/01/29 04:27:11 ian - Jay Vassos-Libove: removed some conflicting declarations - - Revision 1.28 1992/01/28 04:34:10 ian - Marty Shannon: handle trailing '/' to indicate directory - - Revision 1.27 1992/01/14 04:51:48 ian - David Nugent: don't declare chmod - - Revision 1.26 1992/01/14 04:25:20 ian - Chip Salzenberg: avoid use before set warning - - Revision 1.25 1992/01/14 03:46:55 ian - Chip Salzenberg: handle invalid status values in status files - - Revision 1.24 1992/01/13 06:11:39 ian - David Nugent: can't declare open or fcntl - - Revision 1.23 1992/01/05 03:18:54 ian - Avoid redefining SEEK_SET - - Revision 1.22 1992/01/04 22:56:22 ian - Added extern definition - - Revision 1.21 1992/01/03 05:44:35 ian - Remove temporary file if link fails in fsdo_lock - - Revision 1.20 1991/12/29 04:04:18 ian - Added a bunch of extern definitions - - Revision 1.19 1991/12/22 22:14:19 ian - Monty Solomon: added HAVE_UNISTD_H configuration parameter - - Revision 1.18 1991/12/22 20:50:47 ian - Franc,ois Pinard: fixed bug in fsysdep_get_status - - Revision 1.17 1991/12/12 18:35:47 ian - Do locking with link to avoid races and to permit running as root - - Revision 1.16 1991/12/12 17:45:34 ian - fcopy_file now creates the file with IPRIVATE_MODE - - Revision 1.15 1991/12/11 03:59:19 ian - Create directories when necessary; don't just assume they exist - - Revision 1.14 1991/12/09 19:07:07 ian - Richard Todd: add HAVE_V2_LOCKFILES--binary number in lock file - - Revision 1.13 1991/12/03 02:59:46 ian - Using LOCKDIR clobbered a byte on the stack - - Revision 1.12 1991/12/01 02:23:12 ian - Niels Baggesen: don't multiply include <unistd.h> - - Revision 1.11 1991/12/01 01:12:40 ian - Marty Shannon: accept truncated status file; also eliminated scanf calls - - Revision 1.10 1991/11/30 23:28:26 ian - Marty Shannon: some systems need a fake version of the rename system call - - Revision 1.9 1991/11/21 21:43:42 ian - Eliminate unused MIN_FREE_BYTES - - Revision 1.8 1991/11/21 21:07:46 ian - Brian Campbell: offer ltrunc as an alternative to ftruncate - - Revision 1.7 1991/11/10 21:32:16 ian - Fixed ftruncate call - - Revision 1.6 1991/11/10 19:24:22 ian - Added pffile protocol entry point for file level control - - Revision 1.5 1991/11/07 19:32:28 ian - Chip Salzenberg: allow LOCKDIR, and check that locking process exists - - Revision 1.4 1991/09/19 17:28:01 ian - Chip Salzenberg: make sure spool directory files are not world readable - - Revision 1.3 1991/09/19 03:23:34 ian - Chip Salzenberg: append to private debugging file, don't overwrite it - - Revision 1.2 1991/09/19 03:06:04 ian - Chip Salzenberg: put BNU temporary files in system's directory - - Revision 1.1 1991/09/10 19:45:50 ian - Initial revision - - */ - -#include "uucp.h" - -#if USE_RCS_ID -char sys3_unx_rcsid[] = "$Id: sys3.unx,v 1.1.1.1 1993/03/21 09:45:37 cgd Exp $"; -#endif - -#include <ctype.h> -#include <errno.h> - -#if USE_STDIO && HAVE_UNISTD_H -#include <unistd.h> -#endif - -#include "system.h" -#include "sysdep.h" - -#include <pwd.h> - -#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 - -/* Get the right header files for statfs and friends. This stuff is - from David MacKenzie's df program. */ - -#ifdef FS_STATVFS -#include <sys/statvfs.h> -extern int statvfs (); -#endif - -#ifdef FS_USG_STATFS -#include <sys/statfs.h> -extern int statfs (); -#endif - -#ifdef FS_MNTENT -#include <sys/vfs.h> -extern int statfs (); -#endif - -#ifdef FS_GETMNT -#include <sys/param.h> -#include <sys/mount.h> -extern int statfs (); -#endif - -#ifdef FS_STATFS -#include <sys/mount.h> -extern int statfs (); -#endif - -#ifdef FS_USTAT -#include <ustat.h> -extern int ustat (); -#endif - -/* We need a definition for SEEK_SET. */ - -#ifndef SEEK_SET -#define SEEK_SET 0 -#endif - -/* External functions. */ -extern int close (), link (), read (), write (); -#ifndef __386BSD__ -extern int kill (); -#endif __386BSD__ -extern int fstat (), stat (); -extern int fclose (), fseek (), pclose (); -extern pid_t getpid (); -extern off_t lseek (); -extern char *strrchr (); - -#if HAVE_FTRUNCATE -extern int ftruncate (); -#endif - -#if HAVE_RENAME -extern int rename (); -#else -static int rename P((const char *zfrom, const char *zto)); -#endif - -/* There are several types of files that go in the spool directory, - and they go into various different subdirectories. When using - SPOOLDIR_TAYLOR, there is a subdirectory for each system for which - communication occurs; these system names have been made canonical - via fread_system_info or ztranslate_name, so they will fit any - name length restrictions (namely 14 characters on System V). - Whenever the system name LOCAL appears below, it means whatever - the local system name is. - - Command files - These contain instructions for uucico indicating what files to transfer - to and from what systems. Each line of a work file is a command - beginning with S, R or X. - #if ! SPOOLDIR_TAYLOR - They are named C.ssssssgqqqq, where ssssss is the system name to - transfer to or from, g is the grade and qqqq is the sequence number. - #if SPOOLDIR_V2 - They are put in the spool directory. - #elif SPOOLDIR_BSD42 | SPOOLDIR_BSD43 - They are put in the directory C. - #elif SPOOLDIR_BNU - They are put in a directory named for the system for which they were - created. - #elif SPOOLDIR_ULTRIX - If the directory sys/ssssss exists, they are put in the directory - sys/ssssss/C; otherwise, they are put in the directory sys/DEFAULT/C. - #endif - #else SPOOLDIR_TAYLOR - They are named C.gqqqq, where g is the grade and qqqq is the sequence - number, and are placed in the directory ssssss/C. where ssssss is - the system name to transfer to or from. - #endif - - Data files - There are files to be transferred to other systems. Some files to - be transferred may not be in the spool directory, depending on how - uucp was invoked. Data files are named in work files, so it is - never necessary to look at them directly (except to remove old ones); - it is only necessary to create them. These means that the many - variations in naming are inconsequential. - #if ! SPOOLDIR_TAYLOR - They are named D.ssssssgqqqq where ssssss is a system name (which - may be LOCAL for locally initiated transfers or a remote system for - remotely initiated transfers, except that BNU appears to use the - system the file is being transferred to), g is the grade and qqqq - is the sequence number. Some systems use a trailing subjob ID - number, but we currently do not. The grade is not important, and - some systems do not use it. If the data file is to become an - execution file on another system the grade (if present) will be - 'X'. Otherwise Ultrix appears to use 'b'; the uux included with - gnuucp 1.0 appears to use 'S'; SCO does not appear to use a grade, - although it does use a subjob ID number. - #if SPOOLDIR_V2 - They are put in the spool directory. - #elif SPOOLDIR_BSD42 - If the name begins with D.LOCAL, the file is put in the directory - D.LOCAL. Otherwise the file is put in the directory D.. - #elif SPOOLDIR_BSD43 - If the name begins with D.LOCALX, the file is put in the directory - D.LOCALX. Otherwise if the name begins with D.LOCAL, the file is - put in the directory D.LOCAL Otherwise the file is put in the - directory D.. - #elif SPOOLDIR_BNU - They are put in a directory named for the system for which they - were created. - #elif SPOOLDIR_ULTRIX - Say the file is being transferred to system REMOTE. If the - directory sys/REMOTE exists, then if the file begins with D.LOCALX - it is put in sys/REMOTE/D.LOCALX, if the file begins with D.LOCAL - it is put in sys/REMOTE/D.LOCAL, and otherwise it is put in - sys/REMOTE/D.. If the directory sys/REMOTE does not exist, the - same applies except that DEFAULT is used instead of REMOTE. - #endif - #else SPOOLDIR_TAYLOR - If the file is to become an executable file on another system it is - named D.Xqqqq, otherwise it is named D.qqqq where in both cases - qqqq is a sequence number. If the corresponding C. file is in - directory ssssss/C., a D.X file is placed in ssssss/D.X and a D. - file is placed in ssssss/D.. - #endif - - Execute files - These are files that specify programs to be executed. They are - created by uux, perhaps as run on another system. These names are - important, because a file transfer done to an execute file name - causes an execution to occur. The name is X.ssssssgqqqq, where - ssssss is the requesting system, g is the grade, and qqqq is a - sequence number. - #if SPOOLDIR_V2 | SPOOLDIR_BSD42 - These files are placed in the spool directory. - #elif SPOOLDIR_BSD43 - These files are placed in the directory X.. - #elif SPOOLDIR_BNU - These files are put in a directory named for the system for which - the files were created. - #elif SPOOLDIR_ULTRIX - If there is a spool directory (sys/ssssss) for the requesting - system, the files are placed in sys/ssssss/X.; otherwise, the files - are placed in sys/DEFAULT/X.. - #elif SPOOLDIR_TAYLOR - The system name is automatically truncated to seven characters when - a file is created. The files are placed in the subdirectory X. of - a directory named for the system for which the files were created. - #endif - - Temporary receive files - These are used when receiving files from another system. They are - later renamed to the final name. The actual name is unimportant, - although it generally begins with TM.. - #if SPOOLDIR_V2 | SPOOLDIR_BSD42 - These files are placed in the spool directory. - #elif SPOOLDIR_BSD43 | SPOOLDIR_ULTRIX | SPOOLDIR_TAYLOR - These files are placed in the directory .Temp. - #elif SPOOLDIR_BNU - These files are placed in a directory named for the system for - which they were created. - #endif - - Lock files - These files are used to lock systems, devices and special files. - The file LCK..ssssss is used to lock a system, where ssssss is the - system name. The file LCK..dev is used to lock a device, where dev - is the device name. The file LCK.file is used to lock a file, - where file is LOG for the log file, SQ for the system sequence - number file, or SEQF for the work queue sequence number file. At - least under Ultrix, the file LCK.XQT is used to lock uuxqt - execution. Some systems supposedly use LCK.SEQL for something. On - some systems, the contents of the lock file is the ASCII process - id; on others, it is the process id as four data bytes. As far as - I can tell, the only lock file I really have to get right is the - one locking a device, so that cu won't use it; if somebody tries to - run old UUCP and this at the same time, they will probably have - trouble unless they make sure the locking is correct for their - system. Not that there is any easy way to make that check, - unfortunately. Supposedly all normal systems put the LCK files in - the spool directory, and this package will do that also. - - System status files - These are used to record when the last call was made to the system - and what the status is. They are used to prevent frequent recalls - to a system which is not responding. I will not attempt to - recreate the format of these exactly, since they are not all that - important. They will be put in the directory .Status, as in BNU, - and they use the system name as the name of the file. - - Log files - These are used to record what UUCP has done. I will not attempt to - recreate the format of these at all. They will be stored in the - directory .Log/uucico (or .Log/uucp, .Log/uux, .Log/uuxqt) and - named for the relevant system. This is the format used by BNU. - - Statistics files - I don't really know the format of these. They are apparently used - to keep track of what jobs have been run by UUCP, but at least on - Ultrix they don't seem to be used very consistently. - - Sequence file - This is used to generate a unique sequence number. It contains an - ASCII number. - #if SPOOLDIR_V2 | SPOOLDIR_BSD42 | SPOOLDIR_BSD43 - The file is named SEQF and is kept in the spool directory. - #elif SPOOLDIR_BNU - A separate sequence file is kept for each system in the directory - .Sequence with the name of the system. - #elif SPOOLDIR_ULTRIX - Each system with a file sys/ssssss has a sequence file in - sys/ssssss/.SEQF. Other systems use sys/DEFAULT/.SEQF. - #else SPOOLDIR_TAYLOR - A sequence file named SEQF is kept in the directory ssssss for each - system. - #endif - - Audit files - Debugging messages are stored in these when running as a slave. We - use the file AUDIT in the spool directory. */ - -/* Local functions. */ - -static char *zsstatic_size P((int c)); -#if SPOOLDIR_TAYLOR -static const char *zsappend3 P((const char *zdir1, const char *zdir2, - const char *zfile)); -#endif -#if SPOOLDIR_ULTRIX -static const char *zsappend4 P((const char *zdir1, const char *zdir2, - const char *zdir3, const char *zfile)); -#endif -static const char *zsfind_file P((const char *zsimple, - const char *zsystem)); -static boolean fscmd_seq P((const char *zsystem, char *zseq)); -static const char *zsfile_name P((int btype, const char *zsystem, - int bgrade, char *ztname, - char *zdname, char *zxname)); - -/* A few routines to manipulate strings with directories. */ - -#define CSTATICLEN (50) -static char abSstatic[CSTATICLEN]; -static char *zSstatic_alloc; -static int cSstatic_alloc; - -/* Return a pointer to a static buffer of a certain size. */ - -static char * -zsstatic_size (c) - int c; -{ - if (c <= CSTATICLEN) - return abSstatic; - if (cSstatic_alloc < c) - { - xfree ((pointer) zSstatic_alloc); - zSstatic_alloc = (char *) xmalloc (c); - cSstatic_alloc = c; - } - return zSstatic_alloc; -} - -/* Copy a string into a static buffer. */ - -const char * -zscopy (z) - const char *z; -{ - char *zret; - - zret = zsstatic_size (strlen (z) + 1); - strcpy (zret, z); - return (const char *) zret; -} - -/* Stick a directory and file name together. Return a static buffer - holding the combined name. This is called by Unix system dependent - routines outside this file. */ - -const char * -zsappend (zdir, zfile) - const char *zdir; - const char *zfile; -{ - char *zret; - - zret = zsstatic_size (strlen (zdir) + strlen (zfile) + sizeof "/"); - sprintf (zret, "%s/%s", zdir, zfile); - return (const char *) zret; -} - -#if SPOOLDIR_TAYLOR - -/* Stick two directories and a file name together. Return a static - buffer holding the combined name. */ - -static const char * -zsappend3 (zdir1, zdir2, zfile) - const char *zdir1; - const char *zdir2; - const char *zfile; -{ - char *zret; - - zret = zsstatic_size (strlen (zdir1) + strlen (zdir2) - + strlen (zfile) + sizeof "//"); - sprintf (zret, "%s/%s/%s", zdir1, zdir2, zfile); - return (const char *) zret; -} - -#endif /* SPOOLDIR_TAYLOR */ - -#if SPOOLDIR_ULTRIX - -/* Stick three directories and a file name together. Return a static - buffer holding the combined name. */ - -static const char * -zsappend4 (zdir1, zdir2, zdir3, zfile) - const char *zdir1; - const char *zdir2; - const char *zdir3; - const char *zfile; -{ - char *zret; - - zret = zsstatic_size (strlen (zdir1) + strlen (zdir2) + strlen (zdir3) - + strlen (zfile) + sizeof "///"); - sprintf (zret, "%s/%s/%s/%s", zdir1, zdir2, zdir3, zfile); - return (const char *) zret; -} - -/* See whether an ULTRIX spool directory exists for a system. For system - ssssss, the spool directory is called sys/ssssss. */ - -boolean -fsultrix_has_spool (zsystem) - const char *zsystem; -{ - char *z; - - z = (char *) alloca (sizeof "sys/" + strlen (zsystem)); - sprintf (z, "sys/%s", zsystem); - return fsdirectory_exists (z); -} - -#endif /* SPOOLDIR_ULTRIX */ - -/* Create a spool directory for a system. This is only relevant for - SPOOLDIR_BNU or SPOOLDIR_TAYLOR. The system specific directories - for Ultrix are meant to be created by hand. */ - -#if SPOOLDIR_TAYLOR | SPOOLDIR_BNU - -static boolean fsmkdir P((const char *zdir)); - -static boolean -fsmkdir (zdir) - const char *zdir; -{ - if (mkdir ((char *) zdir, IDIRECTORY_MODE) < 0) - { - ulog (LOG_ERROR, "mkdir (%s): %s", zdir, strerror (errno)); - return FALSE; - } - return TRUE; -} - -#endif /* SPOOLDIR_TAYLOR | SPOOLDIR_BNU */ - -boolean -fsysdep_make_spool_dir (qsys) - const struct ssysteminfo *qsys; -{ - const char *zsystem; - - zsystem = qsys->zname; - -#if SPOOLDIR_BNU - if (fsdirectory_exists (zsystem)) - return TRUE; - if (! fsmkdir (zsystem)) - return FALSE; -#endif /* SPOOLDIR_BNU */ - -#if SPOOLDIR_TAYLOR - if (fsdirectory_exists (zsystem)) - return TRUE; - if (! fsmkdir (zsystem) - || ! fsmkdir (zsappend (zsystem, "C.")) - || ! fsmkdir (zsappend (zsystem, "D.")) - || ! fsmkdir (zsappend (zsystem, "D.X")) - || ! fsmkdir (zsappend (zsystem, "X."))) - return FALSE; -#endif /* SPOOLDIR_TAYLOR */ - - return TRUE; -} - -/* Given the name of a file as specified in a UUCP command, and the - system for which this file has been created, return where to find - it in the spool directory. The file will begin with C. (a command - file), D. (a data file) or X. (an execution file). The return - value of this function will point to a static buffer. */ - -static const char * -zsfind_file (zsimple, zsystem) - const char *zsimple; - const char *zsystem; -{ - if (zsimple[1] != '.' - || (*zsimple != 'C' - && *zsimple != 'D' - && *zsimple != 'X')) - { - ulog (LOG_ERROR, "Unrecognized file name %s", zsimple); - return NULL; - } - - switch (*zsimple) - { - case 'C': -#if SPOOLDIR_V2 - return zscopy (zsimple); -#endif /* SPOOLDIR_V2 */ -#if SPOOLDIR_BSD42 | SPOOLDIR_BSD43 - return zsappend ("C.", zsimple); -#endif /* SPOOLDIR_BSD42 | SPOOLDIR_BSD43 */ -#if SPOOLDIR_BNU - return zsappend (zsystem, zsimple); -#endif /* SPOOLDIR_BNU */ -#if SPOOLDIR_ULTRIX - if (fsultrix_has_spool (zsystem)) - return zsappend4 ("sys", zsystem, "C.", zsimple); - else - return zsappend4 ("sys", "DEFAULT", "C.", zsimple); -#endif -#if SPOOLDIR_TAYLOR - return zsappend3 (zsystem, "C.", zsimple); -#endif - - case 'D': -#if SPOOLDIR_V2 - return zscopy (zsimple); -#endif /* SPOOLDIR_V2 */ -#if SPOOLDIR_BSD42 | SPOOLDIR_BSD43 - { - int c; - boolean ftruncated; - char *zalloc; - - /* D.LOCAL in D.LOCAL/, others in D./. If BSD43, D.LOCALX in - D.LOCALX/. */ - ftruncated = TRUE; - if (strncmp (zsimple + 2, zLocalname, strlen (zLocalname)) == 0) - { - c = strlen (zLocalname); - ftruncated = FALSE; - } - else if (strncmp (zsimple + 2, zLocalname, 7) == 0) - c = 7; - else if (strncmp (zsimple + 2, zLocalname, 6) == 0) - c = 6; - else - c = 0; -#if SPOOLDIR_BSD43 - if (c > 0 && zsimple[c + 2] == 'X') - c++; -#endif /* SPOOLDIR_BSD43 */ - if (c > 0) - { - zalloc = (char *) alloca (c + 3); - strncpy (zalloc, zsimple, c + 2); - zalloc[c + 2] = '\0'; - - /* If we truncated the system name, and there is no existing - directory with the truncated name, then just use D.. */ - if (ftruncated && ! fsdirectory_exists (zalloc)) - return zsappend ("D.", zsimple); - - return zsappend (zalloc, zsimple); - } - else - return zsappend ("D.", zsimple); - } -#endif /* SPOOLDIR_BSD42 | SPOOLDIR_BSD43 */ -#if SPOOLDIR_BNU - return zsappend (zsystem, zsimple); -#endif /* SPOOLDIR_BNU */ -#if SPOOLDIR_ULTRIX - { - int c; - boolean ftruncated; - char *zalloc; - const char *zdir; - - /* D.LOCALX in D.LOCALX/, D.LOCAL in D.LOCAL/, others in D./. */ - - ftruncated = TRUE; - if (strncmp (zsimple + 2, zLocalname, strlen (zLocalname)) == 0) - { - c = strlen (zLocalname); - ftruncated = FALSE; - } - else if (strncmp (zsimple + 2, zLocalname, 7) == 0) - c = 7; - else if (strncmp (zsimple + 2, zLocalname, 6) == 0) - c = 6; - else - c = 0; - if (c > 0 && zsimple[c + 2] == 'X') - c++; - if (c > 0) - { - zalloc = (char *) alloca (c + 3); - strncpy (zalloc, zsimple, c + 2); - zalloc[c + 2] = '\0'; - zdir = zalloc; - - /* If we truncated the name, and there is no directory for - the truncated name, then don't use it. */ - if (ftruncated) - { - char *zlook; - - zlook = (char *) alloca (c + 20 + strlen (zsystem)); - if (fsultrix_has_spool (zsystem)) - sprintf (zlook, "sys/%s/%s", zsystem, zdir); - else - sprintf (zlook, "sys/DEFAULT/%s", zdir); - if (! fsdirectory_exists (zlook)) - zdir = "D."; - } - } - else - zdir = "D."; - - if (fsultrix_has_spool (zsystem)) - return zsappend4 ("sys", zsystem, zdir, zsimple); - else - return zsappend4 ("sys", "DEFAULT", zdir, zsimple); - } -#endif /* SPOOLDIR_ULTRIX */ -#if SPOOLDIR_TAYLOR - if (zsimple[2] == 'X') - return zsappend3 (zsystem, "D.X", zsimple); - else - return zsappend3 (zsystem, "D.", zsimple); -#endif /* SPOOLDIR_TAYLOR */ - - /* Files beginning with X. are execute files. It is important - for security reasons that we know the system which created - the X. file. This is easy under SPOOLDIR_BNU or - SPOOLDIR_TAYLOR, because the file will be in a directory - named for the system. Under other schemes, we must get the - system name from the X. file name. To prevent security - violations, we set the system name directly here; this will - cause problems if the maximum file name length is too short, - but hopefully no problem will occur since any System V - systems will be using either BNU or TAYLOR. */ - - case 'X': -#if ! SPOOLDIR_BNU && ! SPOOLDIR_TAYLOR - if (strncmp (zsimple + 2, zsystem, strlen (zsimple) - 7) != 0) - { - char *zcopy; - - zcopy = (char *) alloca (strlen (zsystem) + 8); - sprintf (zcopy, "X.%s%s", zsystem, - zsimple + strlen (zsimple) - 5); - zsimple = zcopy; - } -#endif /* ! SPOOLDIR_BNU && ! SPOOLDIR_TAYLOR */ - -#if SPOOLDIR_V2 | SPOOLDIR_BSD42 - return zscopy (zsimple); -#endif -#if SPOOLDIR_BSD43 - return zsappend ("X.", zsimple); -#endif -#if SPOOLDIR_BNU - return zsappend (zsystem, zsimple); -#endif -#if SPOOLDIR_ULTRIX - if (fsultrix_has_spool (zsystem)) - return zsappend4 ("sys", zsystem, "X.", zsimple); - else - return zsappend4 ("sys", "DEFAULT", "X.", zsimple); -#endif -#if SPOOLDIR_TAYLOR - return zsappend3 (zsystem, "X.", zsimple); -#endif - - default: -#if DEBUG > 0 - ulog (LOG_FATAL, "zsfind_file: Can't happen"); -#endif /* DEBUG */ - return NULL; - } - /*NOTREACHED*/ -} - -/* Get the status of a system. */ - -/*ARGSUSED*/ -boolean -fsysdep_get_status (qsys, qret) - const struct ssysteminfo *qsys; - struct sstatus *qret; -{ - const char *zname; - FILE *e; - char *zline; - char *zend, *znext; - boolean fbad; - int istat; - - zname = zsappend (".Status", qsys->zname); - e = fopen (zname, "r"); - if (e == NULL) - { - if (errno != ENOENT) - { - ulog (LOG_ERROR, "fopen (%s): %s", zname, strerror (errno)); - return FALSE; - } - zline = NULL; - } - else - { - zline = zfgets (e, FALSE); - (void) fclose (e); - } - - if (zline == NULL) - { - /* There is either no status file for this system, or it's been - truncated, so fake a good status. */ - qret->ttype = STATUS_COMPLETE; - qret->cretries = 0; - qret->ilast = 0; - qret->cwait = 0; - return TRUE; - } - - /* It turns out that scanf is not used much in this program, so for - the benefit of small computers we avoid linking it in. This is - basically - - sscanf (zline, "%d %d %ld %d", &qret->ttype, &qret->cretries, - &qret->ilast, &qret->cwait); - - except that it's done with strtol. */ - - fbad = FALSE; - istat = (int) strtol (zline, &zend, 10); - if (zend == zline) - fbad = TRUE; - - /* On some systems it may be appropriate to map system dependent status - values on to our status values. Perhaps someday. */ - - if (istat < 0 || istat >= (int) STATUS_VALUES) - istat = (int) STATUS_COMPLETE; - qret->ttype = (enum tstatus_type) istat; - znext = zend; - qret->cretries = (int) strtol (znext, &zend, 10); - if (zend == znext) - fbad = TRUE; - znext = zend; - qret->ilast = strtol (znext, &zend, 10); - if (zend == znext) - fbad = TRUE; - znext = zend; - qret->cwait = (int) strtol (znext, &zend, 10); - if (zend == znext) - fbad = TRUE; - - xfree ((pointer) zline); - - if (fbad) - { - ulog (LOG_ERROR, "Bad format of status file for %s", qsys->zname); - return FALSE; - } - - return TRUE; -} - -/* Set the status of a remote system. We assume the system is locked - when this is called. */ - -/*ARGSUSED*/ -boolean -fsysdep_set_status (qsys, qset) - const struct ssysteminfo *qsys; - const struct sstatus *qset; -{ - const char *zname; - FILE *e; - int istat; - - zname = zsappend (".Status", qsys->zname); - - e = esysdep_fopen (zname, TRUE, FALSE, TRUE); - if (e == NULL) - return FALSE; - istat = (int) qset->ttype; - - /* On some systems it may be appropriate to map istat onto a system - dependent number. Perhaps someday. */ - - fprintf (e, "%d %d %ld %d %s %s\n", istat, qset->cretries, - qset->ilast, qset->cwait, azStatus[(int) qset->ttype], - qsys->zname); - if (fclose (e) != 0) - { - ulog (LOG_ERROR, "fclose: %s", strerror (errno)); - return FALSE; - } - - return TRUE; -} - -/* Get the real name of a spool file. */ - -const char * -zsysdep_spool_file_name (qsys, zfile) - const struct ssysteminfo *qsys; - const char *zfile; -{ - return zsfind_file (zfile, qsys->zname); -} - -/* Expand a file name on the local system. The qsys argument is only - used to determine which public directory to use. */ - -const char * -zsysdep_real_file_name (qsys, zfile, zname) - const struct ssysteminfo *qsys; - const char *zfile; - const char *zname; -{ - const char *ztry; - char *zlook; - - if (zfile[0] == '/') - ztry = zfile; - else if (zfile[0] == '~') - { - const char *z; - char *zcopy; - - z = zstilde_expand (qsys, zfile); - zcopy = (char *) alloca (strlen (z) + 1); - strcpy (zcopy, z); - ztry = zcopy; - } - else - { - const char *zpub, *z; - char *zcopy; - - /* Put the file in the public directory. */ - if (qsys == NULL || qsys->zpubdir == NULL) - zpub = zPubdir; - else - zpub = qsys->zpubdir; - z = zsappend (zpub, zfile); - zcopy = (char *) alloca (strlen (z) + 1); - strcpy (zcopy, z); - ztry = zcopy; - } - - /* If we don't have a file name to use within a directory, or we - haven't named a directory, we use what we've got so far. If the - name ends in a '/', it is assumed to name a directory. */ - - if (zname == NULL) - return zscopy (ztry); - - if (ztry[strlen (ztry) - 1] != '/') - { - if (! fsdirectory_exists (ztry)) - return zscopy (ztry); - } - else - { - char *zcopy; - int clen; - - clen = strlen (ztry); - zcopy = (char *) alloca (clen + 1); - strcpy (zcopy, ztry); - zcopy[clen - 1] = '\0'; - ztry = zcopy; - } - - /* Get a name out of zname and tag it on. */ - - zlook = strrchr (zname, '/'); - if (zlook != NULL) - zname = zlook + 1; - - return zsappend (ztry, zname); -} - -/* Return a file name within a directory. */ - -const char * -zsysdep_in_dir (zdir, zfile) - const char *zdir; - const char *zfile; -{ - if (fsdirectory_exists (zdir)) - return zsappend (zdir, zfile); - else - return zdir; -} - -/* Open a file to send to another system, and return the mode and - the size. */ - -/*ARGSUSED*/ -openfile_t -esysdep_open_send (qsys, zfile, fcheck, zuser, pimode, pcbytes, pfgone) - const struct ssysteminfo *qsys; - const char *zfile; - boolean fcheck; - const char *zuser; - unsigned int *pimode; - long *pcbytes; - boolean *pfgone; -{ - struct stat s; - openfile_t e; - int o; - - if (pfgone != NULL) - *pfgone = FALSE; - - if (fsdirectory_exists (zfile)) - { - ulog (LOG_ERROR, "%s: is a directory", zfile); - return EFILECLOSED; - } -#if USE_STDIO - e = fopen (zfile, BINREAD); - if (e == NULL) - { - ulog (LOG_ERROR, "fopen (%s): %s", zfile, strerror (errno)); - if (pfgone != NULL && errno == ENOENT) - *pfgone = TRUE; - return NULL; - } - o = fileno (e); -#else - e = open (zfile, O_RDONLY, 0); - if (e == -1) - { - ulog (LOG_ERROR, "open (%s): %s", zfile, strerror (errno)); - if (pfgone != NULL && errno == ENOENT) - *pfgone = TRUE; - return -1; - } - o = e; -#endif - - if (fstat (o, &s) == -1) - { - ulog (LOG_ERROR, "fstat: %s", strerror (errno)); - s.st_mode = 0666; - } - - /* We have to recheck the file permission, although we probably - checked it already, because otherwise there would be a window in - which somebody could change the contents of a symbolic link to - point to some file which was only readable by uucp. */ - if (fcheck) - { - if (! fsuser_access (&s, R_OK, zuser)) - { - ulog (LOG_ERROR, "%s: %s", zfile, strerror (EACCES)); - (void) ffileclose (e); - return EFILECLOSED; - } - } - - *pimode = s.st_mode & 0777; - *pcbytes = s.st_size; - return e; -} - -/* Get a temporary file name. */ - -/*ARGSUSED*/ -const char * -zstemp_file (qsys) - const struct ssysteminfo *qsys; -{ - static int icount; - char *zret; - -#if SPOOLDIR_V2 | SPOOLDIR_BSD42 - { - static char ab[sizeof "TM.12345.123"]; - - sprintf (ab, "TM.%05d.%03d", getpid (), icount); - zret = ab; - } -#endif -#if SPOOLDIR_BSD43 | SPOOLDIR_ULTRIX | SPOOLDIR_TAYLOR - { - static char ab[sizeof ".Temp/TM.12345.123"]; - - sprintf (ab, ".Temp/TM.%05d.%03d", getpid (), icount); - zret = ab; - } -#endif -#if SPOOLDIR_BNU - { - static char *z; - static int calc; - int cneed; - - cneed = strlen (qsys->zname) + sizeof "/TM.12345.123"; - if (cneed > calc) - { - xfree ((pointer) z); - z = (char *) xmalloc (cneed); - calc = cneed; - } - sprintf (z, "%s/TM.%05d.%03d", qsys->zname, getpid (), icount); - zret = z; - } -#endif - - ++icount; - - return zret; -} - -/* Open a temporary file to receive into. This should, perhaps, check - that we have write permission on the receiving directory, but it - doesn't. It is supposed to set *pcbytes to the size of the largest - file that can be accepted. */ - -/*ARGSUSED*/ -openfile_t -esysdep_open_receive (qsys, zto, pztemp, pcbytes) - const struct ssysteminfo *qsys; - const char *zto; - const char **pztemp; - long *pcbytes; -{ - const char *z; - int o; - openfile_t e; - long c1, c2; - char *zcopy, *zslash; - - z = zstemp_file (qsys); - - o = creat (z, IPRIVATE_FILE_MODE); - - if (o == -1) - { - if (errno == ENOENT) - { - if (! fsysdep_make_dirs (z, FALSE)) - return EFILECLOSED; - o = creat (z, IPRIVATE_FILE_MODE); - } - if (o == -1) - { - ulog (LOG_ERROR, "creat (%s): %s", z, strerror (errno)); - return EFILECLOSED; - } - } - -#if USE_STDIO - e = fdopen (o, (char *) BINWRITE); - - if (e == NULL) - { - ulog (LOG_ERROR, "fdopen (%s): %s", z, strerror (errno)); - (void) close (o); - (void) remove (z); - return NULL; - } -#else - e = o; -#endif - - *pztemp = z; - - /* Try to determine the amount of free space available for the - temporary file and for the final destination. This code is - mostly from David MacKenzie's df program. */ - - c1 = (long) -1; - c2 = (long) -1; - - zcopy = (char *) alloca (strlen (zto) + 1); - strcpy (zcopy, zto); - zslash = strrchr (zcopy, '/'); - if (zslash != NULL) - *zslash = '\0'; - else - { - zcopy[0] = '.'; - zcopy[1] = '\0'; - } - - { -#ifdef FS_STATVFS - struct statvfs s; - - if (statvfs (z, &s) >= 0) - c1 = (long) s.f_bavail * (long) s.f_frsize; - if (statvfs (zcopy, &s) >= 0) - c2 = (long) s.f_bavail * (long) s.f_frsize; -#endif -#ifdef FS_USG_STATFS - struct statfs s; - - /* This structure has an f_bsize field, but on many systems - f_bfree is measured in 512 byte blocks. On some systems, - f_bfree is measured in f_bsize byte blocks. Rather than - overestimate the amount of free space, this code assumes that - f_bfree is measuring 512 byte blocks. */ - - if (statfs (z, &s, sizeof s, 0) >= 0) - c1 = (long) s.f_bfree * (long) 512; - if (statfs (zcopy, &s, sizeof s, 0) >= 0) - c2 = (long) s.f_bfree * (long) 512; -#endif -#ifdef FS_MNTENT - struct statfs s; - - if (statfs (z, &s) == 0) - c1 = (long) s.f_bavail * (long) s.f_bsize; - if (statfs (zcopy, &s) == 0) - c2 = (long) s.f_bavail * (long) s.f_bsize; -#endif -#ifdef FS_GETMNT - struct fs_data s; - - if (statfs (z, &s) == 1) - c1 = (long) s.fd_req.bfreen * (long) 1024; - if (statfs (zcopy, &s) == 1) - c2 = (long) s.fd_req.bfreen * (long) 1024; -#endif -#ifdef FS_STATFS - struct statfs s; - - if (statfs (z, &s) >= 0) - c1 = (long) s.f_bavail * (long) s.f_fsize; - if (statfs (zcopy, &s) >= 0) - c2 = (long) s.f_bavail * (long) s.f_fsize; -#endif -#ifdef FS_USTAT - struct stat sstat; - struct ustat s; - - if (fstat (o, &sstat) == 0 - && ustat (sstat.st_dev, &s) == 0) - c1 = (long) s.f_tfree * (long) 512; - if (stat (zcopy, &sstat) == 0 - && ustat (sstat.st_dev, &s) == 0) - c2 = (long) s.f_tfree * (long) 512; -#endif - } - - if (c1 == (long) -1) - *pcbytes = c2; - else if (c2 == (long) -1) - *pcbytes = c1; - else if (c1 < c2) - *pcbytes = c1; - else - *pcbytes = c2; - - return e; -} - -/* After the temporary file has been completely written out, the file - is closed and this routine is called to move it into its final - location. If we fail, we must remove the temporary file. */ - -boolean -fsysdep_move_file (zorig, zto, imode, fcheck, zuser) - const char *zorig; - const char *zto; - unsigned int imode; - boolean fcheck; - const char *zuser; -{ - DEBUG_MESSAGE2 (DEBUG_SPOOLDIR, - "fsysdep_move_file: Moving %s to %s", zorig, zto); - - /* Unless and until we add an option to change the ownership of the - file, the only information we want from the mode is whether the - file is executable or not. It would be dumb to create a file - with mode 0600, for example, since the owner will be uucp and the - recipient will not be able to read it. If we do not have an - absolute path to the file, which means that it is being moved - somewhere in the spool directory, we don't change the mode; in - general, the files in the spool directory should not be - publically readable. */ - - if (*zto != '/') - imode = 0; - - if (imode != 0) - { - if ((imode & 0111) != 0) - imode = S_IRWXU | S_IRWXG | S_IRWXO; - else - imode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH; - } - - /* Optionally make sure that zuser has write access on the - directory. We only check files that are not in the spool - directory. */ - if (fcheck && *zto == '/') - { - char *zcopy; - char *zslash; - struct stat s; - - zcopy = (char *) alloca (strlen (zto) + 1); - strcpy (zcopy, zto); - zslash = strrchr (zcopy, '/'); - if (zslash == zcopy) - zslash[1] = '\0'; - else - *zslash = '\0'; - - if (stat (zcopy, &s) != 0) - { - ulog (LOG_ERROR, "stat (%s): %s", zcopy, strerror (errno)); - (void) remove (zorig); - return FALSE; - } - if (! fsuser_access (&s, W_OK, zuser)) - { - ulog (LOG_ERROR, "%s: %s", zcopy, strerror (EACCES)); - (void) remove (zorig); - return FALSE; - } - - /* A malicious user now has a few milliseconds to change a - symbolic link to a directory uucp has write permission on but - the user does not (the obvious choice being /usr/lib/uucp). - The only certain method I can come up with to close this race - is to fork an suid process which takes on the users identity - and does the actual copy. This is sufficiently high overhead - that I'm not going to do it. */ - } - - /* We try to use rename to move the file. */ - - if (rename (zorig, zto) == 0) - { - /* We must set the correct file mode, but don't worry if it doesn't - work. There should be an option for setting the owner, as - well. */ - if (imode != 0) - (void) chmod (zto, imode); - return TRUE; - } - - /* If this file is in the spool directory, make sure all directories - exist. */ - if (*zto != '/' && errno == ENOENT) - { - if (! fsysdep_make_dirs (zto, FALSE)) - { - (void) remove (zorig); - return FALSE; - } - if (rename (zorig, zto) == 0) - { - if (imode != 0) - (void) chmod (zto, imode); - return TRUE; - } - } - - /* If we can't link across devices, we must copy the file by hand. */ - if (errno != EXDEV) - { - ulog (LOG_ERROR, "rename (%s, %s): %s", zorig, zto, - strerror (errno)); - (void) remove (zorig); - return FALSE; - } - - /* If the destination file is not in the spool directory, any - necessary directories should already have been made. */ - if (! fcopy_file (zorig, zto, FALSE, *zto != '/')) - { - (void) remove (zorig); - return FALSE; - } - - if (remove (zorig) < 0) - ulog (LOG_ERROR, "remove (%s): %s", zorig, strerror (errno)); - - if (imode != 0) - (void) chmod (zto, imode); - - return TRUE; -} - -/* Truncate a file to zero length. If this fails, it closes and - removes the file. We support a number of different means of - truncation, which is probably a waste of time since this function - is currently only called when the 'f' protocol resends a file. */ - -#if HAVE_FTRUNCATE -#undef HAVE_LTRUNC -#define HAVE_LTRUNC 0 -#endif - -#if ! HAVE_FTRUNCATE && ! HAVE_LTRUNC -#ifdef F_CHSIZE -#define HAVE_F_CHSIZE 1 -#else /* ! defined (F_CHSIZE) */ -#ifdef F_FREESP -#define HAVE_F_FREESP 1 -#endif /* defined (F_FREESP) */ -#endif /* ! defined (F_CHSIZE) */ -#endif /* ! HAVE_FTRUNCATE && ! HAVE_LTRUNC */ - -openfile_t -esysdep_truncate (e, zname) - openfile_t e; - const char *zname; -{ - int o; - -#if HAVE_FTRUNCATE || HAVE_LTRUNC || HAVE_F_CHSIZE || HAVE_F_FREESP - int itrunc; - - if (! ffilerewind (e)) - { - ulog (LOG_ERROR, "rewind: %s", strerror (errno)); - (void) ffileclose (e); - (void) remove (zname); - return EFILECLOSED; - } - -#if USE_STDIO - o = fileno (e); -#else - o = e; -#endif - -#if HAVE_FTRUNCATE - itrunc = ftruncate (o, 0); -#endif -#if HAVE_LTRUNC - itrunc = ltrunc (o, (long) 0, SEEK_SET); -#endif -#if HAVE_F_CHSIZE - itrunc = fcntl (o, F_CHSIZE, (off_t) 0); -#endif -#if HAVE_F_FREESP - /* This selection is based on an implementation of ftruncate by - kucharsk@Solbourne.com (William Kucharski). */ - { - struct flock fl; - - fl.l_whence = 0; - fl.l_len = 0; - fl.l_start = 0; - fl.l_type = F_WRLCK; - - itrunc = fcntl (o, F_FREESP, &fl); - } -#endif - - if (itrunc != 0) - { -#if HAVE_FTRUNCATE - ulog (LOG_ERROR, "ftruncate: %s", strerror (errno)); -#endif -#ifdef HAVE_LTRUNC - ulog (LOG_ERROR, "ltrunc: %s", strerror (errno)); -#endif -#ifdef HAVE_F_CHSIZE - ulog (LOG_ERROR, "fcntl (F_CHSIZE): %s", strerror (errno)); -#endif -#ifdef HAVE_F_FREESP - ulog (LOG_ERROR, "fcntl (F_FREESP): %s", strerror (errno)); -#endif - - (void) ffileclose (e); - (void) remove (zname); - return EFILECLOSED; - } - - return e; -#else /* ! (HAVE_FTRUNCATE || HAVE_LTRUNC) */ - (void) ffileclose (e); - (void) remove (zname); - - o = creat (zname, IPRIVATE_FILE_MODE); - - if (o == -1) - { - ulog (LOG_ERROR, "open (%s): %s", zname, strerror (errno)); - return EFILECLOSED; - } - -#if USE_STDIO - e = fdopen (o, (char *) BINWRITE); - - if (e == NULL) - { - ulog (LOG_ERROR, "fdopen (%s): %s", zname, strerror (errno)); - (void) close (o); - (void) remove (zname); - return NULL; - } -#else /* ! USE_STDIO */ - e = o; -#endif /* ! USE_STDIO */ - - return e; -#endif /* ! HAVE_FTRUNCATE */ -} - -/* Lock something. If the fspooldir argument is TRUE, the argument is - a file name relative to the spool directory; otherwise the argument - is a simple file name which should be created in the system lock - directory (under BNU this is /etc/locks). */ - -/*ARGSUSED*/ -boolean -fsdo_lock (zlock, fspooldir) - const char *zlock; - boolean fspooldir; -{ - const char *zpath, *zslash; - int cslash; - char *ztempfile; - char abtempfile[20]; - int o; - pid_t ime; -#if HAVE_V2_LOCKFILES - int i; -#else - char ab[12]; -#endif - int cwrote; - const char *zerr; - boolean fret; - -#ifdef LOCKDIR - if (fspooldir) - zpath = zlock; - else - { - char *zalc; - - zalc = (char *) alloca (sizeof LOCKDIR + strlen (zlock) + 1); - sprintf (zalc, "%s/%s", LOCKDIR, zlock); - zpath = zalc; - } -#else /* ! defined (LOCKDIR) */ - zpath = zlock; -#endif - - ime = getpid (); - - /* We do the actual lock by creating a file and then linking it to - the final file name we want. This avoids race conditions due to - one process checking the file before we have finished writing it, - and also works even if we are somehow running as root. - - First, create the file in the right directory (we must create the - file in the same directory since otherwise we might attempt a - cross-device link). */ - zslash = strrchr (zpath, '/'); - if (zslash == NULL) - cslash = 0; - else - cslash = zslash - zpath + 1; - - ztempfile = (char *) alloca (cslash + sizeof "TMP1234567890"); - strncpy (ztempfile, zpath, cslash); - sprintf (abtempfile, "TMP%010d", (int) ime); - ztempfile[cslash] = '\0'; - strcat (ztempfile, abtempfile); - - o = creat (ztempfile, IPUBLIC_FILE_MODE); - if (o < 0) - { - if (errno == ENOENT) - { - if (! fsysdep_make_dirs (ztempfile, FALSE)) - return FALSE; - o = creat (ztempfile, IPUBLIC_FILE_MODE); - } - if (o < 0) - { - ulog (LOG_ERROR, "open (%s): %s", ztempfile, strerror (errno)); - return FALSE; - } - } - -#if HAVE_V2_LOCKFILES - i = ime; - cwrote = write (o, &i, sizeof i); -#else - sprintf (ab, "%10d\n", (int) ime); - cwrote = write (o, ab, strlen (ab)); -#endif - - zerr = NULL; - if (cwrote < 0) - zerr = "write"; - if (close (o) < 0) - zerr = "close"; - if (zerr != NULL) - { - ulog (LOG_ERROR, "%s (%s): %s", zerr, ztempfile, strerror (errno)); - (void) remove (ztempfile); - return FALSE; - } - - /* Now try to link the file we just created to the lock file that we - want. If it fails, try reading the existing file to make sure - the process that created it still exists. We do this in a loop - to make it easy to retry if the old locking process no longer - exists. */ - - fret = TRUE; - o = -1; - zerr = NULL; - - while (link (ztempfile, zpath) != 0) - { - int cgot; - int ipid; - - fret = FALSE; - - if (errno != EEXIST) - { - ulog (LOG_ERROR, "link (%s, %s): %s", ztempfile, zpath, - strerror (errno)); - break; - } - - o = open (zpath, O_RDWR, 0); - if (o < 0) - { - zerr = "open"; - break; - } - - /* The race starts here. See below for a discussion. */ - -#if HAVE_V2_LOCKFILES - cgot = read (o, &i, sizeof i); -#else - cgot = read (o, ab, sizeof ab - 1); -#endif - - if (cgot < 0) - { - zerr = "read"; - break; - } - -#if HAVE_V2_LOCKFILES - ipid = i; -#else - ab[cgot] = '\0'; - ipid = atoi (ab); -#endif - - /* If the process still exists, we will get EPERM rather than - ESRCH. We then return FALSE to indicate that we cannot make - the lock. */ - if (kill (ipid, 0) == 0 || errno == EPERM) - break; - - /* On NFS, the link might have actually succeeded even though we - got a failure return. This can happen if the original - acknowledgement was lost or delayed and the operation was - retried. In this case the pid will be our own. This - introduces a rather improbable race condition: if a stale - lock was left with our process ID in it, and another process - just did the above kill but has not yet changed the lock file - to hold its own process ID, we could start up and make it all - the way to here and think we have the lock. I'm not going to - worry about this possibility. */ - if (ipid == ime) - { - fret = TRUE; - break; - } - - ulog (LOG_ERROR, "Found stale lock %s held by process %d", - zpath, ipid); - - /* This is a stale lock, created by a process that no longer - exists. - - Now we could remove the file, but that would be a race - condition. If we were interrupted any time after we did the - read until we did the remove, another process could get in, - open the file, find that it was a stale lock, remove the file - and create a new one. When we woke up we would remove the - file the other process just created. - - These files are being generated partially for the benefit of - cu, and it would be nice to avoid the race however cu avoids - it, so that the programs remain compatible. Unfortunately, - nobody seems to know how cu avoids the race, or even if it - tries to avoid it at all. - - There are a few ways to avoid the race. We could use kernel - locking primitives, but they may not be available. We could - link to a special file name, but if that file were left lying - around then no stale lock could ever be broken (Henry Spencer - would think this was a good thing). - - Instead I've implemented the following procedure: seek to the - start of the file, write our pid into it, sleep for five - seconds, and then make sure our pid is still there. Anybody - who checks the file while we're asleep will find our pid - there and fail the lock. The only race will come from - another process which has done the read by the time we do our - write. That process will then have five seconds to do its - own write. When we wake up, we'll notice that our pid is no - longer in the file, and retry the lock from the beginning. - - This relies on the atomicity of write(2). If it possible for - the writes of two processes to be interleaved, the two - processes could livelock. POSIX unfortunately leaves this - case explicitly undefined; however, given that the write is - of less than a disk block, it's difficult to imagine an - interleave occurring. - - Note that this is still a race. If it takes the second - process more than five seconds to do the kill, the lseek, and - the write, both processes will think they have the lock. - Perhaps the length of time to sleep should be configurable. - Even better, perhaps I should add a configuration option to - use a permanent lock file, which eliminates any race and - forces the installer to be aware of the existence of the - permanent lock file. - - For the benefit of cu, we stat the file after the sleep, to - make sure some cu program hasn't deleted it for us. */ - - if (lseek (o, (off_t) 0, SEEK_SET) != 0) - { - zerr = "lseek"; - break; - } - -#if HAVE_V2_LOCKFILES - i = ime; - cwrote = write (o, &i, sizeof i); -#else - sprintf (ab, "%10d\n", (int) ime); - cwrote = write (o, ab, strlen (ab)); -#endif - - if (cwrote < 0) - { - zerr = "write"; - break; - } - - (void) sleep (5); - - if (lseek (o, (off_t) 0, SEEK_SET) != 0) - { - zerr = "lseek"; - break; - } - -#if HAVE_V2_LOCKFILES - cgot = read (o, &i, sizeof i); -#else - cgot = read (o, ab, sizeof ab - 1); -#endif - - if (cgot < 0) - { - zerr = "read"; - break; - } - -#if HAVE_V2_LOCKFILES - ipid = i; -#else - ab[cgot] = '\0'; - ipid = atoi (ab); -#endif - - if (ipid == ime) - { - struct stat sfile, sdescriptor; - - /* It looks like we have the lock. Do the final stat - check. */ - - if (stat (zpath, &sfile) != 0) - { - if (errno != ENOENT) - { - zerr = "stat"; - break; - } - /* Loop around and try again. */ - } - else - { - if (fstat (o, &sdescriptor) < 0) - { - zerr = "fstat"; - break; - } - - if (sfile.st_ino == sdescriptor.st_ino - && sfile.st_dev == sdescriptor.st_dev) - { - /* Close the file before assuming we've succeeded to - pick up any trailing errors. */ - if (close (o) < 0) - { - zerr = "close"; - break; - } - - o = -1; - - /* We have the lock. */ - fret = TRUE; - break; - } - } - } - - /* Loop around and try the lock again. We keep doing this until - the lock file holds a pid that exists. */ - - (void) close (o); - o = -1; - fret = TRUE; - } - - if (zerr != NULL) - ulog (LOG_ERROR, "%s (%s): %s", zerr, zpath, strerror (errno)); - - if (o >= 0) - (void) close (o); - - /* It would be nice if we could leave the temporary file around for - future calls, but considering that we create lock files in - various different directories it's probably more trouble than - it's worth. */ - if (remove (ztempfile) != 0) - ulog (LOG_ERROR, "remove (%s): %s", ztempfile, strerror (errno)); - - return fret; -} - -/* Unlock something. The fspooldir argument is as in fsdo_lock. */ - -boolean -fsdo_unlock (zlock, fspooldir) - const char *zlock; - boolean fspooldir; -{ - const char *zpath; - -#ifdef LOCKDIR - if (fspooldir) - zpath = zlock; - else - { - char *zalc; - - zalc = (char *) alloca (sizeof LOCKDIR + strlen (zlock) + 1); - sprintf (zalc, "%s/%s", LOCKDIR, zlock); - zpath = zalc; - } -#else /* ! defined (LOCKDIR) */ - zpath = zlock; -#endif - - if (remove (zpath) == 0 - || errno == ENOENT) - return TRUE; - else - { - ulog (LOG_ERROR, "remove (%s): %s", zpath, strerror (errno)); - return FALSE; - } -} - -/* Lock a remote system. */ - -/*ARGSUSED*/ -boolean -fsysdep_lock_system (qsys) - const struct ssysteminfo *qsys; -{ - char *z; - - z = (char *) alloca (strlen (qsys->zname) + sizeof "LCK.."); - sprintf (z, "LCK..%.8s", qsys->zname); - return fsdo_lock (z, FALSE); -} - -/* Unlock a remote system. */ - -/*ARGSUSED*/ -boolean -fsysdep_unlock_system (qsys) - const struct ssysteminfo *qsys; -{ - char *z; - - z = (char *) alloca (strlen (qsys->zname) + sizeof "LCK.."); - sprintf (z, "LCK..%.8s", qsys->zname); - return fsdo_unlock (z, FALSE); -} - -/* Get a new command sequence number (this is not a sequence number to - be used for communicating with another system, but a sequence - number to be used when generating the name of a command file). - The sequence number is placed into zseq, which should be five - characters long. */ - -#define CSEQLEN (4) - -static boolean -fscmd_seq (zsystem, zseq) - const char *zsystem; - char *zseq; -{ - int ctries; - const char *zfile; - int o; - int i; - - /* Lock the sequence file. This may not be correct for all systems, - but it only matters if the system UUCP and this UUCP are running - at the same time. */ - - ctries = 0; - while (! fsdo_lock ("LCK..SEQ", TRUE)) - { - ++ctries; - if (ctries > 10) - { - ulog (LOG_ERROR, "Can't lock sequence file"); - return FALSE; - } - sleep (1); - } - -#if SPOOLDIR_V2 | SPOOLDIR_BSD42 | SPOOLDIR_BSD43 - zfile = "SEQF"; -#endif -#if SPOOLDIR_BNU - { - char *zalc; - - zalc = (char *) alloca (strlen (zsystem) + sizeof ".Sequence/"); - sprintf (zalc, ".Sequence/%s", zsystem); - zfile = zalc; - } -#endif -#if SPOOLDIR_ULTRIX - if (fsultrix_has_spool (zsystem)) - { - char *zalc; - - zalc = (char *) alloca (strlen (zsystem) + sizeof "sys//.SEQF"); - sprintf (zalc, "sys/%s/.SEQF", zsystem); - zfile = zalc; - } - else - zfile = "sys/DEFAULT/.SEQF"; -#endif /* SPOOLDIR_ULTRIX */ -#if SPOOLDIR_TAYLOR - { - char *zalc; - - zalc = (char *) alloca (strlen (zsystem) + sizeof "/SEQF"); - sprintf (zalc, "%s/SEQF", zsystem); - zfile = zalc; - } -#endif /* SPOOLDIR_TAYLOR */ - -#ifdef O_CREAT - o = open (zfile, O_RDWR | O_CREAT, IPUBLIC_FILE_MODE); -#else - o = open (zfile, O_RDWR); - if (o < 0 && errno == ENOENT) - { - o = creat (zfile, IPUBLIC_FILE_MODE); - if (o >= 0) - { - (void) close (o); - o = open (zfile, O_RDWR); - } - } -#endif - - if (o < 0) - { - if (errno == ENOENT) - { - if (! fsysdep_make_dirs (zfile, FALSE)) - { - (void) fsdo_unlock ("LCK..SEQ", TRUE); - return FALSE; - } -#ifdef O_CREAT - o = open (zfile, O_RDWR | O_CREAT, IPUBLIC_FILE_MODE); -#else - o = creat (zfile, IPUBLIC_FILE_MODE); - if (o >= 0) - { - (void) close (o); - o = open (zfile, O_RDWR); - } -#endif - } - if (o < 0) - { - ulog (LOG_ERROR, "open (%s): %s", zfile, strerror (errno)); - (void) fsdo_unlock ("LCK..SEQ", TRUE); - return FALSE; - } - } - - if (read (o, zseq, CSEQLEN) != CSEQLEN) - strcpy (zseq, "0000"); - zseq[CSEQLEN] = '\0'; - - /* We must add one to the sequence number and return the new value. - On Ultrix, arbitrary characters are allowed in the sequence number. - On other systems, the sequence number apparently must be in hex. */ - -#if SPOOLDIR_V2 | SPOOLDIR_BSD42 | SPOOLDIR_BSD43 | SPOOLDIR_BNU - i = strtol (zseq, (char **) NULL, 16); - ++i; - if (i > 0xffff) - i = 0; - /* The sprintf argument has CSEQLEN built into it. */ - sprintf (zseq, "%04x", (unsigned int) i); -#endif /* SPOOLDIR_V2 | SPOOLDIR_BSD42 | SPOOLDIR_BSD43 | SPOOLDIR_BNU */ -#if SPOOLDIR_ULTRIX | SPOOLDIR_TAYLOR - for (i = CSEQLEN - 1; i >= 0; i--) - { - if (zseq[i] == 'z') - { - zseq[i] = '0'; - continue; - } - - if (zseq[i] == '9') - zseq[i] = 'A'; - else if (zseq[i] == 'Z') - zseq[i] = 'a'; - else if ((zseq[i] >= '0' && zseq[i] < '9') - || (zseq[i] >= 'A' && zseq[i] < 'Z') - || (zseq[i] >= 'a' && zseq[i] < 'z')) - ++zseq[i]; - else - { - /* A bad character was found; reset the entire sequence - number. */ - ulog (LOG_ERROR, - "Bad sequence number %s for system %s", - zseq, zsystem); - strcpy (zseq, "0000"); - } - - break; - } -#endif /* SPOOLDIR_ULTRIX | SPOOLDIR_TAYLOR */ - - if (lseek (o, (off_t) 0, SEEK_SET) < 0 - || write (o, zseq, CSEQLEN) != CSEQLEN - || close (o) < 0) - { - ulog (LOG_ERROR, "lseek or write or close: %s", strerror (errno)); - (void) close (o); - (void) fsdo_unlock ("LCK..SEQ", TRUE); - return FALSE; - } - - (void) fsdo_unlock ("LCK..SEQ", TRUE); - - return TRUE; -} - -/* Get the name of a command or data file for a remote system. The - btype argument should be C for a command file or D for a data file. - If the grade of a data file is X, it is assumed that this is going - to become an execute file on some other system. The zsystem - argument is the system that the file will be transferred to. The - ztname argument will be set to a file name that could be passed to - zsysdep_spool_file_name. The zdname argument, if not NULL, will be - set to a data file name appropriate for the remote system. The - zxname argument, if not NULL, will be set to the name of an execute - file on the remote system. None of the names will be more than 14 - characters long. */ - -static const char * -zsfile_name (btype, zsystem, bgrade, ztname, zdname, zxname) - int btype; - const char *zsystem; - int bgrade; - char *ztname; - char *zdname; - char *zxname; -{ - char abseq[CSEQLEN + 1]; - char absimple[11 + CSEQLEN]; - const char *zname; - struct stat s; - - do - { - if (! fscmd_seq (zsystem, abseq)) - return NULL; - - if (btype == 'C') - { -#if ! SPOOLDIR_TAYLOR - sprintf (absimple, "C.%.7s%c%s", zsystem, bgrade, abseq); -#else - sprintf (absimple, "C.%c%s", bgrade, abseq); -#endif - } - else if (btype == 'D') - { -#if ! SPOOLDIR_TAYLOR - /* Note that a data file uses the local system's name. */ - sprintf (absimple, "D.%.7s%c%s", zLocalname, bgrade, abseq); -#else - if (bgrade == 'X') - sprintf (absimple, "D.X%s", abseq); - else - sprintf (absimple, "D.%s", abseq); -#endif - } -#if DEBUG > 0 - else - ulog (LOG_FATAL, "zsfile_name: Can't happen (%d)", btype); -#endif - - zname = zsfind_file (absimple, zsystem); - if (zname == NULL) - return NULL; - } - while (stat (zname, &s) == 0); - - if (ztname != NULL) - strcpy (ztname, absimple); - - if (zdname != NULL) - sprintf (zdname, "D.%.7s%c%s", zLocalname, bgrade, abseq); - - if (zxname != NULL) - sprintf (zxname, "X.%.7s%c%s", zLocalname, bgrade, abseq); - - return zname; -} - -/* Given a set of commands to execute for a remote system, create a - command file holding them. This creates a single command file - holding all the commands passed in. It returns a jobid. */ - -const char * -zsysdep_spool_commands (qsys, bgrade, ccmds, pascmds) - const struct ssysteminfo *qsys; - int bgrade; - int ccmds; - const struct scmd *pascmds; -{ - const char *z; - FILE *e; - int i; - const struct scmd *q; - const char *zjobid; - -#if DEBUG > 0 - if (! FGRADE_LEGAL (bgrade)) - ulog (LOG_FATAL, "Bad grade %d", bgrade); -#endif - - z = zsfile_name ('C', qsys->zname, bgrade, (char *) NULL, (char *) NULL, - (char *) NULL); - if (z == NULL) - return NULL; - - e = esysdep_fopen (z, FALSE, FALSE, TRUE); - if (e == NULL) - return NULL; - - for (i = 0, q = pascmds; i < ccmds; i++, q++) - { - switch (q->bcmd) - { - case 'S': - fprintf (e, "S %s %s %s -%s %s 0%o %s\n", q->zfrom, q->zto, - q->zuser, q->zoptions, q->ztemp, q->imode, - q->znotify); - break; - case 'R': - fprintf (e, "R %s %s %s -%s\n", q->zfrom, q->zto, q->zuser, - q->zoptions); - break; - case 'X': - fprintf (e, "X %s %s %s -%s\n", q->zfrom, q->zto, q->zuser, - q->zoptions); - break; - default: - ulog (LOG_ERROR, - "zsysdep_spool_commands: Unrecognized type %d", - q->bcmd); - (void) fclose (e); - (void) remove (z); - return NULL; - } - } - - if (fclose (e) != 0) - { - ulog (LOG_ERROR, "fclose: %s", strerror (errno)); - (void) remove (z); - return NULL; - } - - zjobid = zsfile_to_jobid (qsys, z); - if (zjobid == NULL) - (void) remove (z); - return zjobid; -} - -/* Return a name to use for a data file to be copied to another - system. The name returned will be for a real file. The ztname - argument, if not NULL, will be set to a name that could be passed - to zsysdep_spool_file_name to get back the return value of this - function. The zdname argument, if not NULL, will be set to a name - that the file could be given on another system. The zxname - argument, if not NULL, will be set to a name for an execute file on - another system. */ - -const char * -zsysdep_data_file_name (qsys, bgrade, ztname, zdname, zxname) - const struct ssysteminfo *qsys; - int bgrade; - char *ztname; - char *zdname; - char *zxname; -{ - return zsfile_name ('D', qsys->zname, bgrade, ztname, zdname, zxname); -} - -/* Return a name for an execute file to be created locally. This is - used by uux to execute a command locally with remote files. */ - -const char * -zsysdep_xqt_file_name () -{ - char abseq[CSEQLEN + 1]; - char absx[11 + CSEQLEN]; - const char *zname; - struct stat s; - - while (TRUE) - { - if (! fscmd_seq (zLocalname, abseq)) - return NULL; - - sprintf (absx, "X.%.7sX%s", zLocalname, abseq); - - zname = zsfind_file (absx, zLocalname); - if (zname == NULL) - return NULL; - if (stat (zname, &s) != 0) - break; - } - - return zname; -} - -/* Start getting a wildcarded file spec. We use the shell to expand - the wildcard. */ - -static char *zSwildcard_alloc; -static char *zSwildcard; - -boolean -fsysdep_wildcard_start (qsys, zfile) - const struct ssysteminfo *qsys; - const char *zfile; -{ - char *zcmd; - const char *azargs[4]; - FILE *e; - pid_t ipid; - - zSwildcard_alloc = NULL; - zSwildcard = NULL; - - if (*zfile == '~') - { - zfile = zstilde_expand (qsys, zfile); - if (zfile == NULL) - return FALSE; - } - - if (*zfile != '/') - { - ulog (LOG_ERROR, "Relative path not permitted in wildcard"); - return FALSE; - } - - zcmd = (char *) alloca (sizeof ECHO_PROGRAM + sizeof " " + strlen (zfile)); - sprintf (zcmd, "%s %s", ECHO_PROGRAM, zfile); - - azargs[0] = "/bin/sh"; - azargs[1] = "-c"; - azargs[2] = zcmd; - azargs[3] = NULL; - - e = espopen (azargs, TRUE, &ipid); - if (e == NULL) - { - ulog (LOG_ERROR, "espopen: %s", strerror (errno)); - return FALSE; - } - - zSwildcard_alloc = zfgets (e, FALSE); - - if (iswait ((unsigned long) ipid, ECHO_PROGRAM) != 0) - { - xfree ((pointer) zSwildcard_alloc); - return FALSE; - } - - if (zSwildcard_alloc == NULL) - return FALSE; - - DEBUG_MESSAGE1 (DEBUG_EXECUTE, - "fsysdep_wildcard_start: got \"%s\"", - zSwildcard_alloc); - - zSwildcard = zSwildcard_alloc; - - return TRUE; -} - -/* Get the next wildcard spec. */ - -/*ARGSUSED*/ -const char * -zsysdep_wildcard (qsys, zfile) - const struct ssysteminfo *qsys; - const char *zfile; -{ - char *zret; - - if (zSwildcard_alloc == NULL || zSwildcard == NULL) - return NULL; - - zret = zSwildcard; - - while (*zSwildcard != '\0' && ! isspace (BUCHAR (*zSwildcard))) - ++zSwildcard; - - if (*zSwildcard == '\0') - zSwildcard = NULL; - else - { - *zSwildcard = '\0'; - ++zSwildcard; - while (*zSwildcard != '\0' && isspace (BUCHAR (*zSwildcard))) - ++zSwildcard; - if (*zSwildcard == '\0') - zSwildcard = NULL; - } - - return zret; -} - -/* Finish up getting wildcard specs. */ - -boolean -fsysdep_wildcard_end () -{ - xfree ((pointer) zSwildcard_alloc); - zSwildcard_alloc = NULL; - zSwildcard = NULL; - return TRUE; -} - -/* Get the current conversation sequence number for a remote system, - and increment it for next time. The conversation sequence number - is kept in a file named .SQ in the spool directory for that system. - This is not compatible with other versions of UUCP, but it makes - more sense to me. The sequence file is only used if specified in - the information for that system. In V2, the file - /usr/lib/uucp/SQFILE is searched for each system to get a - conversation sequence number. */ - -long -isysdep_get_sequence (qsys) - const struct ssysteminfo *qsys; -{ - FILE *e; - const char *zname; - struct stat s; - long iseq; - - /* This will only be called when the system is locked anyhow, so there - is no need to use a separate lock for the conversation sequence - file. */ - - zname = zsappend (".Sequence", qsys->zname); - - iseq = 0; - if (stat (zname, &s) == 0) - { - boolean fok; - char *zline; - - /* The file should only be readable and writable by uucp. */ - - if ((s.st_mode & (S_IRWXG | S_IRWXO)) != 0) - { - ulog (LOG_ERROR, - "Bad file protection for conversation sequence file"); - return -1; - } - - /* The file already exists, so we don't have to worry about - its protection. */ - e = fopen (zname, "r+"); - if (e == NULL) - { - ulog (LOG_ERROR, "fopen (%s): %s", zname, strerror (errno)); - return -1; - } - - zline = zfgets (e, FALSE); - - fok = TRUE; - if (zline == NULL) - fok = FALSE; - else - { - char *zend; - - iseq = strtol (zline, &zend, 10); - if (zend == zline) - fok = FALSE; - xfree ((pointer) zline); - } - - if (! fok) - { - ulog (LOG_ERROR, "Bad format for conversation sequence file"); - return -1; - } - - rewind (e); - } - else - { - e = esysdep_fopen (zname, FALSE, FALSE, TRUE); - if (e == NULL) - return -1; - } - - ++iseq; - - fprintf (e, "%ld", iseq); - - if (fclose (e) != 0) - { - ulog (LOG_ERROR, "fclose: %s", strerror (errno)); - return -1; - } - - return iseq; -} - -/* Get the Unix file mode of a file. */ - -unsigned int -isysdep_file_mode (zfile) - const char *zfile; -{ - struct stat s; - - if (stat (zfile, &s) != 0) - { - ulog (LOG_ERROR, "stat (%s): %s", zfile, strerror (errno)); - return 0; - } - -#if S_IRWXU != 0700 - #error Files modes need to be translated -#endif - - /* We can't return 0, since that indicate an error. */ - if ((s.st_mode & 0777) == 0) - return 0400; - - return s.st_mode & 0777; -} - -/* Translate a file name and an associated system into a job id. - These job ids are used by uustat. We use the system name attached - to the grade and sequence number. */ - -const char * -zsfile_to_jobid (qsys, zfile) - const struct ssysteminfo *qsys; - const char *zfile; -{ - char *zid; - - zid = (char *) alloca (strlen (qsys->zname) + CSEQLEN + 2); - sprintf (zid, "%s%s", qsys->zname, - zfile + strlen (zfile) - CSEQLEN - 1); - - return zscopy (zid); -} - -/* Turn a job id back into a file name. */ - -const char * -zsjobid_to_file (zid, pzsystem) - const char *zid; - const char **pzsystem; -{ - int clen; - char abend[CSEQLEN + 2]; - static char *zsys; - static int csyslen; - char abname[CSEQLEN + 11]; - - clen = strlen (zid); - strcpy (abend, zid + clen - CSEQLEN - 1); - - if (clen - CSEQLEN > csyslen) - { - zsys = (char *) xrealloc ((pointer) zsys, clen - CSEQLEN); - csyslen = clen - CSEQLEN; - } - - strncpy (zsys, zid, clen - CSEQLEN - 1); - zsys[clen - CSEQLEN - 1] = '\0'; - if (pzsystem != NULL) - *pzsystem = zsys; - - /* This must correspond to zsfile_name. */ -#if ! SPOOLDIR_TAYLOR - sprintf (abname, "C.%.7s%s", zsys, abend); -#else - sprintf (abname, "C.%s", abend); -#endif - - return zsfind_file (abname, zsys); -} - -#if ! HAVE_RENAME - -/* This is currently the only file which calls rename, so I've put my - fake rename function in here. */ - -static int -rename (zfrom, zto) - const char *zfrom; - const char *zto; -{ - /* Try to make the link without removing the old file first. */ - if (link (zfrom, zto) == -1) - { - if (errno != EEXIST) - return -1; - - /* Assume that this will never be called with zfrom the same as - zto. If it could be, this is wrong. */ - (void) remove (zto); - - if (link (zfrom, zto) == -1) - return -1; - } - - return remove (zfrom); -} - -#endif /* ! HAVE_RENAME */ - -/* - Local variables: - mode:c - End: - */ diff --git a/gnu/libexec/uucp/sys4.unx b/gnu/libexec/uucp/sys4.unx deleted file mode 100644 index 88820ccb4e1..00000000000 --- a/gnu/libexec/uucp/sys4.unx +++ /dev/null @@ -1,769 +0,0 @@ -/* sys4.unx - The system dependent routines to read command files for Unix. - These routines are used by uucico to get the commands it should - execute. - - 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 AIRS, P.O. Box 520, Waltham, MA 02254. - - $Log: sys4.unx,v $ - Revision 1.1.1.1 1993/03/21 09:45:37 cgd - initial import of 386bsd-0.1 sources - - Revision 1.17 1992/03/12 19:56:10 ian - Debugging based on types rather than number - - Revision 1.16 1992/03/11 00:18:50 ian - Save temporary file if file send fails - - Revision 1.15 1992/03/04 21:34:12 ian - Johan Vromans: set *pbgrade correctly in fsysdep_has_work - - Revision 1.14 1992/03/04 02:13:23 ian - Bob Denny: warn if we can't open a command file - - Revision 1.13 1992/02/23 03:26:51 ian - Overhaul to use automatic configure shell script - - Revision 1.12 1992/02/20 04:18:59 ian - Added uustat - - Revision 1.11 1992/02/09 03:14:48 ian - Added HAVE_OLD_DIRECTORIES for systems without readdir routines - - Revision 1.10 1992/02/08 20:11:47 ian - Work data was freed up incorrectly if a file transfer failed in the middle - - Revision 1.9 1992/02/08 03:54:18 ian - Include <string.h> only in <uucp.h>, added 1992 copyright - - Revision 1.8 1992/01/29 18:28:34 ian - Patrick Smith: fixed casts in iswork_cmp - - Revision 1.7 1991/12/29 04:04:18 ian - Added a bunch of extern definitions - - Revision 1.6 1991/12/20 00:10:39 ian - Sort the earlier files so that bsearch can work correctly - - Revision 1.5 1991/12/19 01:09:38 ian - David Nugent: rescan work directory before quitting - - Revision 1.4 1991/11/16 00:45:50 ian - If fsysdep_work frees qSwork_file, it must set it to NULL - - Revision 1.3 1991/11/15 21:58:02 ian - Move ssline definition out of ssfile - - Revision 1.2 1991/11/08 04:47:19 ian - Hannu Strang: don't check system name for BNU work files - - Revision 1.1 1991/09/10 19:45:50 ian - Initial revision - - */ - -#include "uucp.h" - -#if USE_RCS_ID -char sys4_unx_rcsid[] = "$Id: sys4.unx,v 1.1.1.1 1993/03/21 09:45:37 cgd Exp $"; -#endif - -#include <ctype.h> -#include <errno.h> - -#include "system.h" -#include "sysdep.h" - -#if HAVE_OPENDIR -#if HAVE_DIRENT_H -#include <dirent.h> -#else /* ! HAVE_DIRENT_H */ -#include <sys/dir.h> -#define dirent direct -#endif /* ! HAVE_DIRENT_H */ -#endif /* HAVE_OPENDIR */ - -/* External functions. */ -extern int fclose (); - -/* Local functions. */ - -static const char *zswork_directory P((const char *zsystem)); -static boolean fswork_file P((const char *zsystem, const char *zfile, - char *pbgrade)); - -/* These functions can support multiple actions going on at once. - This allows the UUCP package to send and receive multiple files at - the same time. This is a very flexible feature, but I'm not sure - it will actually be used all that much. - - The ssfile structure holds a command file name and all the lines - read in from that command file. The union within the ssline - structure initially holds a line from the file and then holds a - pointer back to the ssfile structure; a pointer to this union is - used as a sequence pointer. The ztemp entry of the ssline - structure holds the name of a temporary file to delete, if any. */ - -#define CFILELINES (10) - -struct ssline -{ - char *zline; - struct ssfile *qfile; - char *ztemp; -}; - -struct ssfile -{ - char *zfile; - int clines; - int cdid; - struct ssline aslines[CFILELINES]; -}; - -/* Static variables for the work scan. */ - -static char **azSwork_files; -static int cSwork_files; -static int iSwork_file; -static struct ssfile *qSwork_file; - -/* Given a system name, return a directory to search for work. */ - -static const char * -zswork_directory (zsystem) - const char *zsystem; -{ -#if SPOOLDIR_V2 - return "."; -#endif /* SPOOLDIR_V2 */ -#if SPOOLDIR_BSD42 | SPOOLDIR_BSD43 - return "C."; -#endif /* SPOOLDIR_BSD42 | SPOOLDIR_BSD43 */ -#if SPOOLDIR_BNU - return zsystem; -#endif /* SPOOLDIR_BNU */ -#if SPOOLDIR_ULTRIX - static int c; - static char *z; - int cwant; - - cwant = strlen (zsystem); - if (cwant < sizeof "DEFAULT" - 1) - cwant = sizeof "DEFAULT" - 1; - cwant += sizeof "sys//C."; - if (c < cwant) - { - xfree ((pointer) z); - z = (char *) xmalloc (cwant); - c = cwant; - } - - if (fsultrix_has_spool (zsystem)) - sprintf (z, "sys/%s/C.", zsystem); - else - strcpy (z, "sys/DEFAULT/C."); - return z; -#endif /* SPOOLDIR_ULTRIX */ -#if SPOOLDIR_TAYLOR - static int c; - static char *z; - int cwant; - - cwant = strlen (zsystem) + sizeof "/C."; - if (c < cwant) - { - xfree ((pointer) z); - z = (char *) xmalloc (cwant); - c = cwant; - } - sprintf (z, "%s/C.", zsystem); - return z; -#endif /* SPOOLDIR_TAYLOR */ -} - -/* See whether a file name from the directory returned by - zswork_directory is really a command for a particular system. - Return the command grade. */ - -/*ARGSUSED*/ -static boolean -fswork_file (zsystem, zfile, pbgrade) - const char *zsystem; - const char *zfile; - char *pbgrade; -{ -#if SPOOLDIR_V2 || SPOOLDIR_BSD42 || SPOOLDIR_BSD43 || SPOOLDIR_ULTRIX - int cfilesys, csys; - - /* The file name should be C.ssssssgqqqq, where g is exactly one - letter and qqqq is exactly four numbers. The system name may be - truncated to six or seven characters. The system name of the - file must match the system name we're looking for, since there - could be work files for several systems in one directory. */ - if (zfile[0] != 'C' || zfile[1] != '.') - return FALSE; - csys = strlen (zsystem); - cfilesys = strlen (zfile) - 7; - if (csys != cfilesys - && (csys < 6 || (cfilesys != 6 && cfilesys != 7))) - return FALSE; - *pbgrade = zfile[cfilesys + 2]; - return strncmp (zfile + 2, zsystem, cfilesys) == 0; -#endif /* V2 || BSD42 || BSD43 || ULTRIX */ -#if SPOOLDIR_BNU - int clen; - - /* The file name should be C.ssssssgqqqq where g is exactly one - letter and qqqq is exactly four numbers or letters. We don't - check the system name, because it is guaranteed by the directory - we are looking in and AIX uucp sets it to the local system rather - than the remote one. */ - if (zfile[0] != 'C' || zfile[1] != '.') - return FALSE; - clen = strlen (zfile); - if (clen < 7) - return FALSE; - *pbgrade = zfile[clen - 5]; - return TRUE; -#endif /* SPOOLDIR_BNU */ -#if SPOOLDIR_TAYLOR - /* We don't keep the system name in the file name, since that - forces truncation. Our file names are always C.gqqqq. */ - *pbgrade = zfile[2]; - return (zfile[0] == 'C' - && zfile[1] == '.' - && strlen (zfile) == 7); -#endif /* SPOOLDIR_TAYLOR */ -} - -/* A comparison function to look through the list of file names. */ - -static int iswork_cmp P((constpointer pkey, constpointer pdatum)); - -static int -iswork_cmp (pkey, pdatum) - constpointer pkey; - constpointer pdatum; -{ - const char * const *pzkey = (const char * const *) pkey; - const char * const *pzdatum = (const char * const *) pdatum; - - return strcmp (*pzkey, *pzdatum); -} - -/* See whether there is any work to do for a particular system. If - any work is found, *pbgrade is set to highest grade found. */ - -/*ARGSUSED*/ -boolean -fsysdep_has_work (qsys, pbgrade) - const struct ssysteminfo *qsys; - char *pbgrade; -{ - boolean fret; - const char *zdir; - DIR *qdir; - struct dirent *qentry; - - fret = FALSE; - *pbgrade = BGRADE_LOW; - - if (azSwork_files != NULL && iSwork_file < cSwork_files) - { - int i; - - fret = TRUE; - for (i = iSwork_file; i < cSwork_files; i++) - { - char bgrade; - - (void) fswork_file (qsys->zname, azSwork_files[i], &bgrade); - if (igradecmp (bgrade, *pbgrade) < 0) - *pbgrade = bgrade; - } - } - - zdir = zswork_directory (qsys->zname); - if (zdir == NULL) - return FALSE; - - qdir = opendir ((char *) zdir); - if (qdir == NULL) - return FALSE; - while ((qentry = readdir (qdir)) != NULL) - { - char bgrade; - char *zname; - - /* If this is a work file and we haven't seen it before, return - TRUE. Also, determine the grade to return. */ - zname = qentry->d_name; - if (fswork_file (qsys->zname, qentry->d_name, &bgrade) - && (azSwork_files == NULL - || bsearch ((pointer) &zname, - (pointer) azSwork_files, - cSwork_files, sizeof (char *), - iswork_cmp) == NULL)) - { - fret = TRUE; - if (igradecmp (bgrade, *pbgrade) < 0) - *pbgrade = bgrade; - } - } - closedir (qdir); - return fret; -} - -/* Initialize the work scan. We have to read all the files in the - work directory, so that we can sort them by work grade. The bgrade - argument is the minimum grade to consider. We don't want to return - files that we have already considered; usysdep_get_work_free will - clear the data out when we are done with the system. This returns - FALSE on error. */ - -#define CWORKFILES (10) - -/*ARGSUSED*/ -boolean -fsysdep_get_work_init (qsys, bgrade) - const struct ssysteminfo *qsys; - int bgrade; -{ - const char *zdir; - DIR *qdir; - struct dirent *qentry; - int chad; - int callocated; - - zdir = zswork_directory (qsys->zname); - if (zdir == NULL) - return FALSE; - - qdir = opendir ((char *) zdir); - if (qdir == NULL) - { - if (errno != ENOENT) - ulog (LOG_ERROR, "opendir (%s): %s", zdir, strerror (errno)); - return FALSE; - } - - chad = cSwork_files; - callocated = cSwork_files; - - /* Sort the files we already know about so that we can check the new - ones with bsearch. It would be faster to use a hash table, and - the code should be probably be changed. The sort done at the end - of this function does not suffice because it only includes the - files added last time, and does not sort the entire array. Some - (bad) qsort implementations are very slow when given a sorted - array, which causes particularly bad effects here. */ - if (chad > 0) - qsort ((pointer) azSwork_files, chad, sizeof (char *), iswork_cmp); - - while ((qentry = readdir (qdir)) != NULL) - { - char bfilegrade; - char *zname; - - zname = qentry->d_name; - if (fswork_file (qsys->zname, qentry->d_name, &bfilegrade) - && (azSwork_files == NULL - || bsearch ((pointer) &zname, - (pointer) azSwork_files, - chad, sizeof (char *), - iswork_cmp) == NULL)) - { - if (igradecmp (bgrade, bfilegrade) < 0) - continue; - - DEBUG_MESSAGE1 (DEBUG_SPOOLDIR, - "fsysdep_get_work_init: Found %s", - qentry->d_name); - - if (cSwork_files >= callocated) - { - callocated += CWORKFILES; - azSwork_files = - (char **) xrealloc ((pointer) azSwork_files, - callocated * sizeof (char *)); - } - - azSwork_files[cSwork_files] = xstrdup (qentry->d_name); - ++cSwork_files; - } - } - - closedir (qdir); - - /* Sorting the files alphabetically will get the grades in the - right order, since all the file prefixes are the same. */ - - if (cSwork_files > chad) - qsort ((pointer) (azSwork_files + chad), cSwork_files - chad, - sizeof (char *), iswork_cmp); - - return TRUE; -} - -/* Get the next work entry for a system. This must parse the next - line in the next work file. The type of command is set into - qcmd->bcmd; if there are no more commands we call - fsysdep_get_work_init to rescan, in case any came in since the last - call. If there are still no commands, qcmd->bcmd is set to 'H'. - Each field in the structure is set to point to a spot in an - malloced string. The only time we use the grade here is when - calling fsysdep_get_work_init to rescan. */ - -boolean -fsysdep_get_work (qsys, bgrade, qcmd) - const struct ssysteminfo *qsys; - int bgrade; - struct scmd *qcmd; -{ - const char *zdir; - - if (qSwork_file != NULL && qSwork_file->cdid >= qSwork_file->clines) - qSwork_file = NULL; - - if (azSwork_files == NULL) - { - qcmd->bcmd = 'H'; - return TRUE; - } - - zdir = NULL; - - /* This loop continues until a line is returned. */ - while (TRUE) - { - /* This loop continues until a file is opened and read in. */ - while (qSwork_file == NULL) - { - FILE *e; - struct ssfile *qfile; - int iline, callocated; - char *zline; - const char *zname; - - /* Read all the lines of a command file into memory. */ - - do - { - if (iSwork_file >= cSwork_files) - { - /* Rescan the work directory. */ - if (! fsysdep_get_work_init (qsys, bgrade)) - return FALSE; - if (iSwork_file >= cSwork_files) - { - qcmd->bcmd = 'H'; - return TRUE; - } - } - - if (zdir == NULL) - { - zdir = zswork_directory (qsys->zname); - if (zdir == NULL) - return FALSE; - } - - zname = zsappend (zdir, azSwork_files[iSwork_file]); - - ++iSwork_file; - - if (zname == NULL) - return FALSE; - - e = fopen (zname, "r"); - if (e == NULL) - ulog (LOG_ERROR, "fopen (%s): %s", zname, - strerror (errno)); - } - while (e == NULL); - - qfile = (struct ssfile *) xmalloc (sizeof (struct ssfile)); - callocated = CFILELINES; - iline = 0; - - while ((zline = zfgets (e, FALSE)) != NULL) - { - if (iline >= callocated) - { - /* The sizeof (struct ssfile) includes CFILELINES - entries already, so using callocated * sizeof - (struct ssline) will give us callocated * - CFILELINES entries. */ - qfile = - ((struct ssfile *) - xrealloc ((pointer) qfile, - (sizeof (struct ssfile) + - (callocated * sizeof (struct ssline))))); - callocated += CFILELINES; - } - qfile->aslines[iline].zline = zline; - qfile->aslines[iline].qfile = NULL; - qfile->aslines[iline].ztemp = NULL; - iline++; - } - - if (fclose (e) != 0) - ulog (LOG_ERROR, "fclose: %s", strerror (errno)); - - if (iline == 0) - { - /* There was nothing in the file; remove it and look - for the next one. */ - xfree ((pointer) qfile); - if (remove (zname) != 0) - ulog (LOG_ERROR, "remove (%s): %s", zname, - strerror (errno)); - } - else - { - qfile->zfile = xstrdup (zname); - qfile->clines = iline; - qfile->cdid = 0; - qSwork_file = qfile; - } - } - - /* This loop continues until all the lines from the current file - are used up, or a line is returned. */ - while (TRUE) - { - int iline; - - if (qSwork_file->cdid >= qSwork_file->clines) - { - /* We don't want to free qSwork_file here, since it must - remain until all the lines have been completed. It - is freed in fsysdep_did_work. */ - qSwork_file = NULL; - /* Go back to the main loop which finds another file. */ - break; - } - - iline = qSwork_file->cdid; - ++qSwork_file->cdid; - - /* Now parse the line into a command. */ - - if (! fparse_cmd (qSwork_file->aslines[iline].zline, qcmd)) - { - ulog (LOG_ERROR, "Bad line in command file %s", - qSwork_file->zfile); - xfree ((pointer) qSwork_file->aslines[iline].zline); - qSwork_file->aslines[iline].zline = NULL; - continue; - } - - if (qcmd->bcmd == 'S') - { - const char *zreal; - - zreal = zsysdep_spool_file_name (qsys, qcmd->ztemp); - if (zreal == NULL) - { - xfree ((pointer) qSwork_file->aslines[iline].zline); - qSwork_file->aslines[iline].zline = NULL; - return FALSE; - } - - qSwork_file->aslines[iline].ztemp = xstrdup (zreal); - } - - qSwork_file->aslines[iline].qfile = qSwork_file; - qcmd->pseq = (pointer)(&qSwork_file->aslines[iline]); - - return TRUE; - } - } -} - -/* When a command has been complete, fsysdep_did_work is called. The - sequence entry was set above to be the address of an aslines - structure whose pfile entry points to the ssfile corresponding to - this file. We can then check whether all the lines have been - completed (they will have been if the pfile entry is NULL) and - remove the file if they have been. This means that we only remove - a command file if we manage to complete every transfer it specifies - in a single UUCP session. I don't know if this is how regular UUCP - works. */ - -boolean -fsysdep_did_work (pseq) - pointer pseq; -{ - struct ssfile *qfile; - struct ssline *qline; - int i; - - qline = (struct ssline *) pseq; - - xfree ((pointer) qline->zline); - qline->zline = NULL; - - qfile = qline->qfile; - qline->qfile = NULL; - - /* Remove the temporary file, if there is one. It really doesn't - matter if this fails, and not checking the return value lets us - attempt to remove D.0 or whatever an unused temporary file is - called without complaining. */ - if (qline->ztemp != NULL) - (void) remove (qline->ztemp); - - /* If not all the lines have been returned from bsysdep_get_work, - we can't remove the file yet. */ - if (qfile->cdid < qfile->clines) - return TRUE; - - /* See whether all the commands have been completed. */ - for (i = 0; i < qfile->clines; i++) - if (qfile->aslines[i].qfile != NULL) - return TRUE; - - /* All commands have finished. */ - if (remove (qfile->zfile) != 0) - { - ulog (LOG_ERROR, "remove (%s): %s", qfile->zfile, - strerror (errno)); - return FALSE; - } - - xfree ((pointer) qfile->zfile); - xfree ((pointer) qfile); - - if (qfile == qSwork_file) - qSwork_file = NULL; - - return TRUE; -} - -/* Free up the results of a work scan, when we're done with this - system. */ - -/*ARGSUSED*/ -void -usysdep_get_work_free (qsys) - const struct ssysteminfo *qsys; -{ - if (azSwork_files != NULL) - { - int i; - - for (i = 0; i < cSwork_files; i++) - xfree ((pointer) azSwork_files[i]); - xfree ((pointer) azSwork_files); - azSwork_files = NULL; - cSwork_files = 0; - iSwork_file = 0; - } - if (qSwork_file != NULL) - { - int i; - - xfree ((pointer) qSwork_file->zfile); - for (i = 0; i < qSwork_file->cdid; i++) - { - xfree ((pointer) qSwork_file->aslines[i].zline); - xfree ((pointer) qSwork_file->aslines[i].ztemp); - } - for (i = qSwork_file->cdid; i < qSwork_file->clines; i++) - xfree ((pointer) qSwork_file->aslines[i].zline); - xfree ((pointer) qSwork_file); - qSwork_file = NULL; - } -} - -/* Save the temporary file used by a send command, and return an - informative message to mail to the requestor. This is called when - a file transfer failed, to make sure that the potentially valuable - file is not completely lost. */ - -const char * -zsysdep_save_temp_file (pseq) - pointer pseq; -{ - struct ssline *qline = (struct ssline *) pseq; - char *zto, *zslash; - int cwant; - static char *zbuf; - static int cbuf; - - if (! fsysdep_file_exists (qline->ztemp)) - return NULL; - - zslash = strrchr (qline->ztemp, '/'); - if (zslash == NULL) - zslash = qline->ztemp; - else - ++zslash; - - zto = (char *) alloca (sizeof PRESERVEDIR + 1 + strlen (zslash)); - sprintf (zto, "%s/%s", PRESERVEDIR, zslash); - - /* We must make sure that the PRESERVEDIR directory exists, since - fsysdep_move_file won't create it for us. */ - - if (! fsdirectory_exists (PRESERVEDIR)) - { - if (mkdir (PRESERVEDIR, IDIRECTORY_MODE) != 0) - { - ulog (LOG_ERROR, "mkdir (%s): %s", PRESERVEDIR, - strerror (errno)); - return "Could not create preservation directory"; - } - } - - if (! fsysdep_move_file (qline->ztemp, zto, 0, FALSE, - (const char *) NULL)) - return "Could not move file to preservation directory"; - - cwant = sizeof "File saved as\n\t" + strlen (zSpooldir) + 1 + strlen (zto); - if (cwant > cbuf) - { - zbuf = (char *) xrealloc ((pointer) zbuf, cwant); - cbuf = cwant; - } - - sprintf (zbuf, "File saved as\n\t%s/%s", zSpooldir, zto); - return zbuf; -} - -/* Get the jobid of a work file. This is needed by uustat. */ - -const char * -zsysdep_jobid (qsys, pseq) - const struct ssysteminfo *qsys; - pointer pseq; -{ - return zsfile_to_jobid (qsys, ((struct ssline *) pseq)->qfile->zfile); -} - -/* - Local variables: - mode:c - End: - */ diff --git a/gnu/libexec/uucp/sys5.unx b/gnu/libexec/uucp/sys5.unx deleted file mode 100644 index a3bf8453a7e..00000000000 --- a/gnu/libexec/uucp/sys5.unx +++ /dev/null @@ -1,877 +0,0 @@ -/* sys5.unx - The system dependent routines to read execute files for Unix, - and to execute programs. These routines are used by uuxqt. - - 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 AIRS, P.O. Box 520, Waltham, MA 02254. - - $Log: sys5.unx,v $ - Revision 1.1.1.1 1993/03/21 09:45:37 cgd - initial import of 386bsd-0.1 sources - - Revision 1.40 1992/03/17 03:15:40 ian - Pass command to fsysdep_execute as first element of argument array - - Revision 1.39 1992/03/16 19:44:45 ian - Cast result of alloca - - Revision 1.38 1992/03/15 01:54:46 ian - All execs are now done in isspawn, all waits are done in iswait - - Revision 1.37 1992/03/12 19:54:43 ian - Debugging based on types rather than number - - Revision 1.36 1992/03/11 22:06:37 ian - Marty Shannon: added max-uuxqts command - - Revision 1.35 1992/03/11 17:04:53 ian - Jon Zeeff: retry execution later if temporary failure - - Revision 1.34 1992/03/11 02:09:57 ian - Franc,ois Pinard: retry fork several times before giving up - - Revision 1.33 1992/02/29 01:06:59 ian - Chip Salzenberg: recheck file permissions before sending - - Revision 1.32 1992/02/27 05:40:54 ian - T. William Wells: detach from controlling terminal, handle signals safely - - Revision 1.31 1992/02/25 15:58:29 ian - Bob Denny: don't warn when trying to open a non-directory - - Revision 1.30 1992/02/24 20:07:43 ian - John Theus: some systems don't have <fcntl.h> - - Revision 1.29 1992/02/24 04:58:47 ian - Only permit files to be received into directories that are world-writeable - - Revision 1.28 1992/02/23 19:50:50 ian - Handle READ and WRITE in Permissions correctly - - Revision 1.27 1992/02/23 03:26:51 ian - Overhaul to use automatic configure shell script - - Revision 1.26 1992/02/18 04:40:06 ian - Michael Nolan: allow full command path from remote, not just basename - - Revision 1.25 1992/02/09 03:14:48 ian - Added HAVE_OLD_DIRECTORIES for systems without readdir routines - - Revision 1.24 1992/02/08 03:54:18 ian - Include <string.h> only in <uucp.h>, added 1992 copyright - - Revision 1.23 1992/01/15 19:42:42 ian - No longer need to define wait status macros here - - Revision 1.22 1992/01/15 19:40:35 ian - Mike Park: handle HAVE_UNION_WAIT correctly and completely - - Revision 1.21 1992/01/13 06:11:39 ian - David Nugent: can't declare open or fcntl - - Revision 1.20 1992/01/04 21:43:24 ian - Chip Salzenberg: added ALLOW_FILENAME_ARGUMENTS to permit them - - Revision 1.19 1992/01/04 04:12:54 ian - David J. Fiander: make sure execution arguments are not bad file names - - Revision 1.18 1991/12/29 04:04:18 ian - Added a bunch of extern definitions - - Revision 1.17 1991/12/29 00:55:23 ian - Monty Solomon: added HAVE_UNION_WAIT - - Revision 1.16 1991/12/22 22:14:19 ian - Monty Solomon: added HAVE_UNISTD_H configuration parameter - - Revision 1.15 1991/12/21 21:34:14 ian - Moved fsysdep_file_exists from sys5.unx to sys1.unx - - Revision 1.14 1991/12/15 01:58:49 ian - Oleg Tabarovsky: don't abandon processing because of an opendir error - - Revision 1.13 1991/12/11 04:17:39 ian - Call fsysdep_make_dirs correctly if chdir (XQTDIR) fails - - Revision 1.12 1991/12/11 03:59:19 ian - Create directories when necessary; don't just assume they exist - - Revision 1.11 1991/12/07 03:41:44 ian - David J. Fiander: if execve fails, fall back on /bin/sh - - Revision 1.10 1991/12/01 02:23:12 ian - Niels Baggesen: don't multiply include <unistd.h> - - Revision 1.9 1991/11/26 01:45:42 ian - Marty Shannon: configuration option to not include <sys/wait.h> - - Revision 1.8 1991/11/22 06:05:57 ian - Gregory Gulik: fix wait status macro definitions - - Revision 1.7 1991/11/16 00:35:43 ian - Case constant arguments to opendir - - Revision 1.6 1991/11/07 20:52:33 ian - Chip Salzenberg: pass command as single argument to /bin/sh - - Revision 1.5 1991/11/07 19:32:28 ian - Chip Salzenberg: allow LOCKDIR, and check that locking process exists - - Revision 1.4 1991/09/19 16:15:58 ian - Chip Salzenberg: configuration option for permitting execution via sh - - Revision 1.3 1991/09/19 15:51:01 ian - Chip Salzenberg: pass TZ environment variable to execution process - - Revision 1.2 1991/09/19 03:06:04 ian - Chip Salzenberg: put BNU temporary files in system's directory - - Revision 1.1 1991/09/10 19:45:50 ian - Initial revision - - */ - -#include "uucp.h" - -#if USE_RCS_ID -char sys5_unx_rcsid[] = "$Id: sys5.unx,v 1.1.1.1 1993/03/21 09:45:37 cgd Exp $"; -#endif - -#include <ctype.h> -#include <errno.h> - -#if USE_STDIO && HAVE_UNISTD_H -#include <unistd.h> -#endif - -#include "system.h" -#include "sysdep.h" - -#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 - -#if HAVE_OPENDIR -#if HAVE_DIRENT_H -#include <dirent.h> -#else /* ! HAVE_DIRENT_H */ -#include <sys/dir.h> -#define dirent direct -#endif /* ! HAVE_DIRENT_H */ -#endif /* HAVE_OPENDIR */ - -/* We need F_OK. */ - -#ifndef F_OK -#define F_OK (0) -#endif - -/* Get a value for EX_TEMPFAIL. */ - -#if HAVE_SYSEXITS_H -#include <sysexits.h> -#endif - -#ifndef EX_TEMPFAIL -#define EX_TEMPFAIL 75 -#endif - -/* External functions. */ -extern int access (), close (), dup2 (), chdir (); -extern void _exit (); - -/* Under the V2 or BSD42 spool directory scheme, all execute files are - in the main spool directory. Under the BSD43 scheme, they are all - in the directory X.. Under the BNU scheme, they are in directories - named after systems. Under the ULTRIX scheme, they are in X. - subdirectories of subdirectories of sys. Under the TAYLOR scheme, - they are all in the subdirectory X. of a directory named after - the system. - - This means that for BNU, ULTRIX or TAYLOR, we have to search - directories of directories. */ - -#if SPOOLDIR_V2 | SPOOLDIR_BSD42 -#define ZDIR "." -#define SUBDIRS 0 -#endif -#if SPOOLDIR_BNU | SPOOLDIR_TAYLOR -#define ZDIR "." -#define SUBDIRS 1 -#endif -#if SPOOLDIR_ULTRIX -#define ZDIR "sys" -#define SUBDIRS 1 -#endif -#if SPOOLDIR_BSD43 -#define ZDIR "X." -#define SUBDIRS 0 -#endif - -/* Static variables for the execute file scan. */ - -static DIR *qSxqt_topdir; -#if ! SUBDIRS -static const char *zSdir; -#else /* SUBDIRS */ -static char *zSdir; -static DIR *qSxqt_dir; -static char *zSsystem; -#endif /* SUBDIRS */ - -/* Initialize the scan for execute files. The function - usysdep_get_xqt_free will clear the data out when we are done with - the system. This returns FALSE on error. */ - -/*ARGSUSED*/ -boolean -fsysdep_get_xqt_init () -{ - usysdep_get_xqt_free (); - - qSxqt_topdir = opendir ((char *) ZDIR); - if (qSxqt_topdir == NULL) - { - if (errno == ENOENT) - return TRUE; - ulog (LOG_ERROR, "opendir (%s): %s", ZDIR, strerror (errno)); - return FALSE; - } - - return TRUE; -} - -/* Return the name of the next execute file to read and process. If - this returns NULL, *pferr must be checked. If will be TRUE on - error, FALSE if there are no more files. On a successful return - *pzsystem will be set to the system for which the execute file was - created. */ - -const char * -zsysdep_get_xqt (pzsystem, pferr) - const char **pzsystem; - boolean *pferr; -{ - *pferr = FALSE; - - if (qSxqt_topdir == NULL) - return NULL; - - /* This loop continues until we find a file. */ - while (TRUE) - { - DIR *qdir; - struct dirent *q; - -#if ! SUBDIRS - zSdir = ZDIR; - qdir = qSxqt_topdir; -#else /* SUBDIRS */ - /* This loop continues until we find a subdirectory to read. */ - while (qSxqt_dir == NULL) - { - struct dirent *qtop; - char *zset; - - qtop = readdir (qSxqt_topdir); - if (qtop == NULL) - { - (void) closedir (qSxqt_topdir); - qSxqt_topdir = NULL; - return NULL; - } - - /* No system name may start with a dot (this is enforced by - tisystem in sysinf.c). This allows us to quickly skip - impossible directories. */ - if (qtop->d_name[0] == '.') - continue; - - DEBUG_MESSAGE1 (DEBUG_SPOOLDIR, - "zsysdep_get_xqt: Found %s in top directory", - qtop->d_name); - -#if SPOOLDIR_BNU - zset = qtop->d_name; -#endif -#if SPOOLDIR_ULTRIX - zset = (char *) alloca (strlen (qtop->d_name) + sizeof "sys//X."); - sprintf (zset, "sys/%s/X.", qtop->d_name); -#endif -#if SPOOLDIR_TAYLOR - zset = (char *) alloca (strlen (qtop->d_name) + sizeof "/X."); - sprintf (zset, "%s/X.", qtop->d_name); -#endif - - xfree ((pointer) zSdir); - zSdir = xstrdup (zset); - - xfree ((pointer) zSsystem); - zSsystem = xstrdup (qtop->d_name); - - qSxqt_dir = opendir (zSdir); - - if (qSxqt_dir == NULL - && errno != ENOTDIR - && errno != ENOENT) - ulog (LOG_ERROR, "opendir (%s): %s", zSdir, strerror (errno)); - } - - qdir = qSxqt_dir; -#endif /* SUBDIRS */ - - q = readdir (qdir); - -#if DEBUG > 1 - if (q != NULL) - DEBUG_MESSAGE2 (DEBUG_SPOOLDIR, - "zsysdep_get_xqt: Found %s in subdirectory %s", - q->d_name, zSdir); -#endif - - /* If we've found an execute file, return it. We have to get - the system name, which is easy for BNU or TAYLOR. For other - spool directory schemes, we have to pull it out of the X. - file name; this would be insecure, except that zsfind_file - clobbers the file name to include the real system name. */ - - if (q != NULL - && q->d_name[0] == 'X' - && q->d_name[1] == '.') - { - const char *zret; - -#if SPOOLDIR_BNU | SPOOLDIR_TAYLOR - *pzsystem = zSsystem; -#else - { - static char *zsys = NULL; - static int csys = 0; - int clen; - - clen = strlen (q->d_name) - 7; - if (clen + 1 > csys) - { - zsys = (char *) xrealloc ((pointer) zsys, clen + 1); - csys = clen + 1; - } - strncpy (zsys, q->d_name + 2, clen); - zsys[clen] = '\0'; - - *pzsystem = zsys; - } -#endif - - /* Set *pferr to TRUE in case zsappend returns NULL. */ - *pferr = TRUE; - - zret = zsappend (zSdir, q->d_name); - -#if DEBUG > 1 - if (zret != NULL) - DEBUG_MESSAGE2 (DEBUG_SPOOLDIR, - "zsysdep_get_xqt: Returning %s (system %s)", - zret, *pzsystem); -#endif - - return zret; - } - - /* If we've reached the end of the directory, then if we are - using subdirectories loop around to read the next one, - otherwise we are finished. */ - - if (q == NULL) - { - (void) closedir (qdir); -#if SUBDIRS - qSxqt_dir = NULL; - continue; -#else - qSxqt_topdir = NULL; - return NULL; -#endif - } - } -} - -/* Free up the results of an execute file scan, when we're done with - this system. */ - -/*ARGSUSED*/ -void -usysdep_get_xqt_free () -{ - if (qSxqt_topdir != NULL) - { - (void) closedir (qSxqt_topdir); - qSxqt_topdir = NULL; - } -#if SUBDIRS - if (qSxqt_dir != NULL) - { - (void) closedir (qSxqt_dir); - qSxqt_dir = NULL; - } - xfree ((pointer) zSdir); - zSdir = NULL; - xfree ((pointer) zSsystem); - zSsystem = NULL; -#endif -} - -/* Get the full pathname of the command to execute, given the list of - permitted commands and the allowed path. */ - -const char * -zsysdep_find_command (zcmd, zcmds, zpath, pferr) - const char *zcmd; - const char *zcmds; - const char *zpath; - boolean *pferr; -{ - char *zcopy, *ztok; - - *pferr = TRUE; - - if (strcmp (zcmds, "ALL") != 0) - { - zcopy = (char *) alloca (strlen (zcmds) + 1); - strcpy (zcopy, zcmds); - for (ztok = strtok (zcopy, " "); - ztok != NULL; - ztok = strtok ((char *) NULL, " ")) - { - char *zslash; - - zslash = strrchr (ztok, '/'); - if (zslash != NULL) - ++zslash; - else - zslash = ztok; - if (strcmp (zslash, zcmd) == 0 - || strcmp (ztok, zcmd) == 0) - { - if (*ztok == '/') - { - /* Hack to get two arguments for zsappend. */ - zslash[-1] = '\0'; - return zsappend (ztok, zslash); - } - break; - } - } - - /* If we didn't find this command, get out. */ - if (ztok == NULL) - { - *pferr = FALSE; - return NULL; - } - } - - /* We didn't find an absolute pathname, so we must look through - the path. */ - zcopy = (char *) alloca (strlen (zpath) + 1); - strcpy (zcopy, zpath); - for (ztok = strtok (zcopy, " "); - ztok != NULL; - ztok = strtok ((char *) NULL, " ")) - { - const char *zname; - - zname = zsappend (ztok, zcmd); - if (zname == NULL) - return NULL; - if (access (zname, F_OK) == 0) - return zname; - } - - *pferr = FALSE; - return NULL; -} - -#if ! ALLOW_FILENAME_ARGUMENTS - -/* Check to see whether an argument specifies a file name; if it does, - make sure that the file may legally be sent and/or received. For - Unix, we do not permit any occurrence of "/../" in the name, nor - may it start with "../". Otherwise, if it starts with "/" we check - against the list of permitted files. */ - -boolean -fsysdep_xqt_check_file (qsys, zfile) - const struct ssysteminfo *qsys; - const char *zfile; -{ - if (strncmp (zfile, "../", sizeof "../" - 1) == 0 - || strstr (zfile, "/../") != NULL - || (*zfile == '/' - && (! fin_directory_list (qsys, zfile, qsys->zremote_send, TRUE, - FALSE, (const char *) NULL) - || (qsys->zcalled_remote_send != NULL - && ! fin_directory_list (qsys, zfile, - qsys->zcalled_remote_send, - TRUE, FALSE, - (const char *) NULL)) - || ! fin_directory_list (qsys, zfile, qsys->zremote_receive, - TRUE, FALSE, (const char *) NULL) - || (qsys->zcalled_remote_receive != NULL - && ! fin_directory_list (qsys, zfile, - qsys->zcalled_remote_receive, - TRUE, FALSE, - (const char *) NULL))))) - { - ulog (LOG_ERROR, "Not permitted to refer to file \"%s\"", zfile); - return FALSE; - } - - return TRUE; -} - -#endif /* ! ALLOW_FILENAME_ARGUMENTS */ - -/* Invoke the command specified by an execute file. */ - -/*ARGSUSED*/ -boolean -fsysdep_execute (qsys, zuser, pazargs, zfullcmd, zinput, zoutput, - fshell, pzerror, pftemp) - const struct ssysteminfo *qsys; - const char *zuser; - const char **pazargs; - const char *zfullcmd; - const char *zinput; - const char *zoutput; - boolean fshell; - const char **pzerror; - boolean *pftemp; -{ - int aidescs[3]; - boolean ferr; - pid_t ipid; - int ierr; - int istat; -#if ALLOW_SH_EXECUTION - const char *azshargs[4]; -#endif - - *pzerror = NULL; - *pftemp = FALSE; - - aidescs[0] = SPAWN_NULL; - aidescs[1] = SPAWN_NULL; - aidescs[2] = SPAWN_NULL; - - ferr = FALSE; - - if (zinput != NULL) - { - aidescs[0] = open (zinput, O_RDONLY, 0); - if (aidescs[0] < 0) - { - ulog (LOG_ERROR, "open (%s): %s", zinput, strerror (errno)); - ferr = TRUE; - } - } - - if (! ferr && zoutput != NULL) - { - aidescs[1] = creat (zoutput, IPRIVATE_FILE_MODE); - if (aidescs[1] < 0) - { - ulog (LOG_ERROR, "creat (%s): %s", zoutput, strerror (errno)); - *pftemp = TRUE; - ferr = TRUE; - } - } - - if (! ferr) - { - *pzerror = zstemp_file (qsys); - aidescs[2] = creat (*pzerror, IPRIVATE_FILE_MODE); - if (aidescs[2] < 0) - { - if (errno == ENOENT) - { - if (! fsysdep_make_dirs (*pzerror, FALSE)) - { - *pftemp = TRUE; - ferr = TRUE; - } - else - aidescs[2] = creat (*pzerror, IPRIVATE_FILE_MODE); - } - if (! ferr && aidescs[2] < 0) - { - ulog (LOG_ERROR, "creat (%s): %s", *pzerror, strerror (errno)); - *pftemp = TRUE; - ferr = TRUE; - } - } - } - - if (! fsdirectory_exists (XQTDIR)) - { - char *zcopy; - - /* The fsysdep_make_dirs function needs a trailing slash, - because it only works on file names. */ - zcopy = (char *) alloca (strlen (XQTDIR) + 2); - sprintf (zcopy, "%s/", XQTDIR); - if (! fsysdep_make_dirs (zcopy, FALSE)) - ferr = TRUE; - } - - if (ferr) - { - if (aidescs[0] != SPAWN_NULL) - (void) close (aidescs[0]); - if (aidescs[1] != SPAWN_NULL) - (void) close (aidescs[1]); - if (aidescs[2] != SPAWN_NULL) - (void) close (aidescs[2]); - return FALSE; - } - -#if ALLOW_SH_EXECUTION - if (fshell) - { - azshargs[0] = "/bin/sh"; - azshargs[1] = "-c"; - azshargs[2] = zfullcmd; - azshargs[3] = NULL; - pazargs = azshargs; - } -#else - fshell = FALSE; -#endif - - /* Pass zchdir as XQTDIR, fnosigs as TRUE, fshell as TRUE if we - aren't already using the shell. */ - ipid = isspawn (pazargs, aidescs, FALSE, FALSE, XQTDIR, TRUE, - ! fshell, qsys->zpath, qsys->zname, zuser); - - ierr = errno; - - if (aidescs[0] != SPAWN_NULL) - (void) close (aidescs[0]); - if (aidescs[1] != SPAWN_NULL) - (void) close (aidescs[1]); - if (aidescs[2] != SPAWN_NULL) - (void) close (aidescs[2]); - - if (ipid < 0) - { - ulog (LOG_ERROR, "isspawn: %s", strerror (ierr)); - *pftemp = TRUE; - return FALSE; - } - - istat = iswait ((unsigned long) ipid, "Execution"); - - if (istat == EX_TEMPFAIL) - *pftemp = TRUE; - - return istat == 0; -} - -/* Lock a uuxqt process. */ - -int -isysdep_lock_uuxqt (zcmd) - const char *zcmd; -{ - char ab[14]; - int i; - - if (cMaxuuxqts <= 0) - i = 0; - else - { - int c; - - c = cMaxuuxqts; - if (c >= 10000) - c = 9999; - for (i = 0; i < c; i++) - { - sprintf (ab, "LCK.XQT.%d", i); - if (fsdo_lock (ab, TRUE)) - break; - } - if (i >= c) - return -1; - } - - if (zcmd != NULL) - { - char abcmd[14]; - - sprintf (abcmd, "LXQ.%.9s", zcmd); - abcmd[strcspn (abcmd, " \t/")] = '\0'; - if (! fsdo_lock (abcmd, TRUE)) - { - if (cMaxuuxqts > 0) - (void) fsdo_unlock (ab, TRUE); - return -1; - } - } - - return i; -} - -/* Unlock a uuxqt process. */ - -boolean -fsysdep_unlock_uuxqt (iseq, zcmd) - int iseq; - const char *zcmd; -{ - char ab[14]; - boolean fret; - - fret = TRUE; - - if (cMaxuuxqts > 0) - { - sprintf (ab, "LCK.XQT.%d", iseq); - if (! fsdo_unlock (ab, TRUE)) - fret = FALSE; - } - - if (zcmd != NULL) - { - sprintf (ab, "LXQ.%.9s", zcmd); - ab[strcspn (ab, " \t/")] = '\0'; - if (! fsdo_unlock (ab, TRUE)) - fret = FALSE; - } - - return fret; -} - -/* See whether a particular uuxqt command is locked (this depends on - the implementation of fsdo_lock). */ - -boolean -fsysdep_uuxqt_locked (zcmd) - const char *zcmd; -{ - char ab[14]; - - sprintf (ab, "LXQ.%.9s", zcmd); - return access (ab, F_OK) == 0; -} - -/* Lock a particular execute file. */ - -boolean -fsysdep_lock_uuxqt_file (zfile) - const char *zfile; -{ - char *zcopy, *z; - - zcopy = (char *) alloca (strlen (zfile) + 1); - strcpy (zcopy, zfile); - - z = strrchr (zcopy, '/'); - if (z == NULL) - *zcopy = 'L'; - else - *(z + 1) = 'L'; - - return fsdo_lock (zcopy, TRUE); -} - -/* Unlock a particular execute file. */ - -boolean -fsysdep_unlock_uuxqt_file (zfile) - const char *zfile; -{ - char *zcopy, *z; - - zcopy = (char *) alloca (strlen (zfile) + 1); - strcpy (zcopy, zfile); - - z = strrchr (zcopy, '/'); - if (z == NULL) - *zcopy = 'L'; - else - *(z + 1) = 'L'; - - return fsdo_unlock (zcopy, TRUE); -} - -/* Lock the execute directory. */ - -boolean -fsysdep_lock_uuxqt_dir () -{ - return fsdo_lock ("LCK..XQTDIR", TRUE); -} - -/* Unlock the execute directory and clear it out. */ - -boolean -fsysdep_unlock_uuxqt_dir () -{ - DIR *qdir; - - qdir = opendir ((char *) XQTDIR); - if (qdir != NULL) - { - struct dirent *qentry; - - while ((qentry = readdir (qdir)) != NULL) - { - const char *z; - - if (strcmp (qentry->d_name, ".") == 0 - || strcmp (qentry->d_name, "..") == 0) - continue; - z = zsappend (XQTDIR, qentry->d_name); - if (z != NULL) - (void) remove (z); - } - - closedir (qdir); - } - - return fsdo_unlock ("LCK..XQTDIR", TRUE); -} - -/* - Local variables: - mode:c - End: - */ diff --git a/gnu/libexec/uucp/sys6.unx b/gnu/libexec/uucp/sys6.unx deleted file mode 100644 index d4f9a20bc78..00000000000 --- a/gnu/libexec/uucp/sys6.unx +++ /dev/null @@ -1,234 +0,0 @@ -/* sys6.unx - System dependent routines to deal with local file names. - - 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 AIRS, P.O. Box 520, Waltham, MA 02254. - - $Log: sys6.unx,v $ - Revision 1.1.1.1 1993/03/21 09:45:37 cgd - initial import of 386bsd-0.1 sources - - Revision 1.9 1992/02/27 19:51:55 ian - Added extern for stat - - Revision 1.8 1992/02/08 22:33:32 ian - Only get the current working directory if it's going to be needed - - Revision 1.7 1992/02/08 03:54:18 ian - Include <string.h> only in <uucp.h>, added 1992 copyright - - Revision 1.6 1992/02/02 20:34:36 ian - Niels Baggesen: must check user permissions on access to local files - - Revision 1.5 1991/12/22 22:14:19 ian - Monty Solomon: added HAVE_UNISTD_H configuration parameter - - Revision 1.4 1991/12/14 16:09:07 ian - Added -l option to uux to link files into the spool directory - - Revision 1.3 1991/12/06 22:50:01 ian - Franc,ois Pinard: getcwd may legitimately fail in usysdep_initialize - - Revision 1.2 1991/11/13 23:08:40 ian - Expand remote pathnames in uucp and uux; fix up uux special cases - - Revision 1.1 1991/09/10 19:45:50 ian - Initial revision - - */ - -#include "uucp.h" - -#if USE_RCS_ID -char sys6_unx_rcsid[] = "$Id: sys6.unx,v 1.1.1.1 1993/03/21 09:45:37 cgd Exp $"; -#endif - -#include <errno.h> - -#if USE_STDIO && HAVE_UNISTD_H -#include <unistd.h> -#endif - -#include "system.h" -#include "sysdep.h" - -/* We need R_OK. */ -#ifndef R_OK -#define R_OK 4 -#endif - -/* We need some mode access macros. */ -#ifndef S_IRUSR -#define S_IRUSR (0400) -#define S_IRGRP (0040) -#define S_IROTH (0004) -#endif /* ! defined (S_IRUSR) */ - -/* External functions. */ -extern int access (), link (), stat (); -extern uid_t getuid (), getgid (), geteuid (), getegid (); - -/* See whether running this file through zsysdep_add_cwd would require - knowing the current working directory. This is used to avoid - determining the cwd if it will not be needed. */ - -boolean -fsysdep_needs_cwd (zfile) - const char *zfile; -{ - return *zfile != '/' && *zfile != '~'; -} - -/* Add the current working directory to a file name, if no directory - has been specified. We do ~ expansion here. */ - -const char * -zsysdep_add_cwd (zfile, flocal) - const char *zfile; - boolean flocal; -{ - if (*zfile == '/') - return zfile; - if (*zfile == '~') - { - if (flocal) - return zstilde_expand (&sLocalsys, zfile); - else - return zfile; - } - -#if DEBUG > 0 - if (zScwd == NULL) - ulog (LOG_FATAL, "zsysdep_add_cwd: No cwd"); -#endif - - return zsappend (zScwd, zfile); -} - -/* Get the base name of a file name. */ - -const char * -zsysdep_base_name (zfile) - const char *zfile; -{ - const char *z; - - z = strrchr (zfile, '/'); - if (z != NULL) - return z + 1; - return zfile; -} - -/* See if the user has access to a file, to prevent the setuid uucp - and uux programs handing out unauthorized access. */ - -boolean -fsysdep_access (zfile) - const char *zfile; -{ - if (access (zfile, R_OK) == 0) - return TRUE; - ulog (LOG_ERROR, "%s: %s", zfile, strerror (errno)); - return FALSE; -} - -/* See if the daemon has access to a file. This is called if a file - is not being transferred to the spool directory, since if the - daemon does not have access the later transfer will fail. We - assume that the daemon will have the same euid (or egid) as the one - we are running under. If our uid (gid) and euid (egid) are the - same, we assume that we have access. Note that is not important - for security, since the check will be (implicitly) done again when - the daemon tries to transfer the file. This routine should work - whether the UUCP programs are installed setuid or setgid. */ - -boolean -fsysdep_daemon_access (zfile) - const char *zfile; -{ - struct stat s; - uid_t ieuid, iuid, iegid, igid; - boolean fok; - - ieuid = geteuid (); - if (ieuid == 0) - return TRUE; - iuid = getuid (); - iegid = getegid (); - igid = getgid (); - - /* If our effective uid and gid are the same as our real uid and - gid, we assume the daemon will have access to the file. */ - if (ieuid == iuid && iegid == igid) - return TRUE; - - if (stat (zfile, &s) != 0) - { - ulog (LOG_ERROR, "stat (%s): %s", zfile, strerror (errno)); - return FALSE; - } - - /* If our euid is not our uid, but it is the file's uid, see if the - owner has read access. Otherwise, if our egid is not our gid, - but it is the file's gid, see if the group has read access. - Otherwise, see if the world has read access. We know from the - above check that at least one of our euid and egid are different, - so that is the only one we want to check. This check could fail - if the UUCP programs were both setuid and setgid, but why would - they be? */ - if (ieuid != iuid && ieuid == s.st_uid) - fok = (s.st_mode & S_IRUSR) != 0; - else if (iegid != igid && iegid == s.st_gid) - fok = (s.st_mode & S_IRGRP) != 0; - else - fok = (s.st_mode & S_IROTH) != 0; - - if (! fok) - { - ulog (LOG_ERROR, "%s: cannot be read by daemon", zfile); - return FALSE; - } - - return TRUE; -} - -/* Link two files. This in here because it's only called by uux. */ - -boolean -fsysdep_link (zfrom, zto, pfworked) - const char *zfrom; - const char *zto; - boolean *pfworked; -{ - if (link (zfrom, zto) == 0) - { - *pfworked = TRUE; - return TRUE; - } - *pfworked = FALSE; - return errno == EXDEV; -} - -/* - Local variables: - mode:c - End: - */ diff --git a/gnu/libexec/uucp/sys7.unx b/gnu/libexec/uucp/sys7.unx deleted file mode 100644 index 0a83cf1c0f2..00000000000 --- a/gnu/libexec/uucp/sys7.unx +++ /dev/null @@ -1,606 +0,0 @@ -/* sys7.unx - System dependent routines for uustat. - - 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 AIRS, P.O. Box 520, Waltham, MA 02254. - - $Log: sys7.unx,v $ - Revision 1.1.1.1 1993/03/21 09:45:37 cgd - initial import of 386bsd-0.1 sources - - Revision 1.11 1992/03/28 04:19:39 ian - Niels Baggesen, Gerben Wierda: minor patches - - Revision 1.10 1992/03/16 22:22:35 ian - Adjusted external declarations - - Revision 1.9 1992/03/15 01:54:46 ian - All execs are now done in isspawn, all waits are done in iswait - - Revision 1.8 1992/03/12 19:54:43 ian - Debugging based on types rather than number - - Revision 1.7 1992/03/11 22:21:19 ian - Permit uucp user to delete jobs - - Revision 1.6 1992/02/27 19:53:26 ian - Added some extern definitions - - Revision 1.5 1992/02/24 20:07:43 ian - John Theus: some systems don't have <fcntl.h> - - Revision 1.4 1992/02/23 16:21:26 ian - Handle systems on which NULL second argument to utime fails - - Revision 1.3 1992/02/23 03:26:51 ian - Overhaul to use automatic configure shell script - - Revision 1.2 1992/02/20 04:40:07 ian - Make sure only the submitter or the superuser can cancel a request - - Revision 1.1 1992/02/20 04:18:59 ian - Initial revision - - */ - -#include "uucp.h" - -#if USE_RCS_ID -char sys7_unx_rcsid[] = "$Id: sys7.unx,v 1.1.1.1 1993/03/21 09:45:37 cgd Exp $"; -#endif - -#include <errno.h> - -#if USE_STDIO && HAVE_UNISTD_H -#include <unistd.h> -#endif - -#include "system.h" -#include "sysdep.h" - -#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 - -#if HAVE_OPENDIR -#if HAVE_DIRENT_H -#include <dirent.h> -#else /* ! HAVE_DIRENT_H */ -#include <sys/dir.h> -#define dirent direct -#endif /* ! HAVE_DIRENT_H */ -#endif /* HAVE_OPENDIR */ - -#ifdef UTIME_NULL_MISSING -#if HAVE_TIME_H -#include <time.h> -#endif -#endif - -#if HAVE_UTIME_H -#include <utime.h> -#endif - -/* External functions. */ -extern int fclose (), fflush (); -extern int read (), close (), utime (), stat (); -extern uid_t getuid (), geteuid (); - -/* Local functions. */ - -static boolean fskill_or_rejuv P((const char *zid, boolean fkill)); - -/* Set file access time to the present. On most systems this can be a - macro, but some apparently do not support utime correctly. */ - -#ifndef UTIME_NULL_MISSING - -#define ussettime(z) utime((z), (struct utimbuf *) NULL) - -#else /* defined (UTIME_NULL_MISSING) */ - -static int -ussettime(z) - const char *z; -{ - time_t inow; - - inow = time ((time_t *) NULL); - - { -#if HAVE_UTIME_H - struct utimbuf s; - - s.actime = inow; - s.modtime = inow; - return utime (z, &s); -#else - time_t ai[2]; - - ai[0] = inow; - ai[1] = inow; - return utime (z, ai); -#endif - } -} - -#endif /* defined (UTIME_NULL_MISSING) */ - -/* Kill a job, given the jobid. */ - -boolean -fsysdep_kill_job (zid) - const char *zid; -{ - return fskill_or_rejuv (zid, TRUE); -} - -/* Rejuvenate a job, given the jobid. */ - -boolean -fsysdep_rejuvenate_job (zid) - const char *zid; -{ - return fskill_or_rejuv (zid, FALSE); -} - -/* Kill or rejuvenate a job, given the jobid. */ - -static boolean -fskill_or_rejuv (zid, fkill) - const char *zid; - boolean fkill; -{ - const char *zfile; - const char *zsys; - char *zcopy; - struct ssysteminfo ssys; - const struct ssysteminfo *qsys; - FILE *e; - boolean fret; - char *zline; - int isys; - - zfile = zsjobid_to_file (zid, &zsys); - zcopy = (char *) alloca (strlen (zfile) + 1); - strcpy (zcopy, zfile); - zfile = zcopy; - zcopy = (char *) alloca (strlen (zsys) + 1); - strcpy (zcopy, zsys); - zsys = zcopy; - - if (fread_system_info (zsys, &ssys)) - qsys = &ssys; - else - { - if (! fUnknown_ok) - { - ulog (LOG_ERROR, "%s: Bad job id", zid); - return FALSE; - } - sUnknown.zname = zsys; - qsys = &sUnknown; - } - - e = fopen (zfile, "r"); - if (e == NULL) - { - if (errno == ENOENT) - ulog (LOG_ERROR, "%s: Job not found", zid); - else - ulog (LOG_ERROR, "fopen (%s): %s", zfile, strerror (errno)); - return FALSE; - } - - /* Now we have to read through the file to identify any temporary - files. */ - - fret = TRUE; - while ((zline = zfgets (e, FALSE)) != NULL) - { - struct scmd s; - - if (! fparse_cmd (zline, &s)) - { - ulog (LOG_ERROR, "Bad line in command file %s", zfile); - fret = FALSE; - xfree ((pointer) zline); - continue; - } - - /* You are only permitted to delete a job if you submitted it or - if you are root or uucp. We check for uucp by seeing if the - real user ID and the effective user ID are the same; this - works because we should be suid to uucp, so our effective - user ID will always be uucp while our real user ID will be - whoever ran the program. */ - if (strcmp (s.zuser, zsysdep_login_name ()) != 0 - && getuid () != 0 - && getuid () != geteuid ()) - { - ulog (LOG_ERROR, "%s: Not submitted by you", zid); - xfree ((pointer) zline); - return FALSE; - } - - if (s.bcmd == 'S') - { - const char *ztemp; - - ztemp = zsysdep_spool_file_name (qsys, s.ztemp); - if (ztemp == NULL) - fret = FALSE; - else - { - if (fkill) - isys = remove (ztemp); - else - isys = ussettime (ztemp); - - if (isys != 0 && errno != ENOENT) - { - ulog (LOG_ERROR, "%s (%s): %s", - fkill ? "remove" : "utime", ztemp, - strerror (errno)); - fret = FALSE; - } - } - } - - xfree ((pointer) zline); - } - - (void) fclose (e); - - if (fkill) - isys = remove (zfile); - else - isys = ussettime (zfile); - - if (isys != 0 && errno != ENOENT) - { - ulog (LOG_ERROR, "%s (%s): %s", fkill ? "remove" : "utime", - zfile, strerror (errno)); - fret = FALSE; - } - - return fret; -} - -/* Get the time a work job was queued. */ - -long -isysdep_work_time (qsys, pseq) - const struct ssysteminfo *qsys; - pointer pseq; -{ - return isysdep_file_time (zsjobid_to_file (zsysdep_jobid (qsys, pseq), - (const char **) NULL)); -} - -/* Get the time a file was created (actually, the time it was last - modified). */ - -long -isysdep_file_time (zfile) - const char *zfile; -{ - struct stat s; - - if (stat (zfile, &s) < 0) - { - if (errno != ENOENT) - ulog (LOG_ERROR, "stat (%s): %s", zfile, strerror (errno)); - return isysdep_time ((long *) NULL); - } - - return (long) s.st_mtime; -} - -/* Get the size in bytes of a file. */ - -long -csysdep_size (zfile) - const char *zfile; -{ - struct stat s; - - if (stat (zfile, &s) < 0) - { - if (errno != ENOENT) - ulog (LOG_ERROR, "stat (%s): %s", zfile, strerror (errno)); - return 0; - } - - return s.st_size; -} - -/* Start getting the status files. */ - -boolean -fsysdep_all_status_init (phold) - pointer *phold; -{ - DIR *qdir; - - qdir = opendir ((char *) ".Status"); - if (qdir == NULL) - { - ulog (LOG_ERROR, "opendir (.Status): %s", strerror (errno)); - return FALSE; - } - - *phold = (pointer) qdir; - return TRUE; -} - -/* Get the next status file. */ - -const char * -zsysdep_all_status (phold, pferr, qstat) - pointer phold; - boolean *pferr; - struct sstatus *qstat; -{ - DIR *qdir = (DIR *) phold; - struct dirent *qentry; - - while (TRUE) - { - errno = 0; - qentry = readdir (qdir); - if (qentry == NULL) - { - if (errno == 0) - *pferr = FALSE; - else - { - ulog (LOG_ERROR, "readdir: %s", strerror (errno)); - *pferr = TRUE; - } - return NULL; - } - - if (qentry->d_name[0] != '.') - { - struct ssysteminfo ssys; - - /* Hack seriously; fsysdep_get_status only looks at the - zname element of the qsys argument, so if we fake that we - can read the status file. This should really be done - differently. */ - ssys.zname = qentry->d_name; - if (fsysdep_get_status (&ssys, qstat)) - return zscopy (qentry->d_name); - - /* If fsysdep_get_status fails, it will output an error - message. We just continue with the next entry, so that - most of the status files will be displayed. */ - } - } -} - -/* Finish getting the status file. */ - -void -usysdep_all_status_free (phold) - pointer phold; -{ - DIR *qdir = (DIR *) phold; - - (void) closedir (qdir); -} - -/* Get the status of all processes holding lock files. We do this by - invoking ps after we've figured out the process entries to use. */ - -boolean -fsysdep_lock_status () -{ - const char *zdir; - DIR *qdir; - struct dirent *qentry; - int calc; - int *pai; - int cgot; - int aidescs[3]; - char *zcopy, *ztok; - int cargs, iarg; - char **pazargs; - -#ifdef LOCKDIR - zdir = LOCKDIR; -#else - zdir = "."; -#endif - - qdir = opendir ((char *) zdir); - if (qdir == NULL) - { - ulog (LOG_ERROR, "opendir (%s): %s", zdir, strerror (errno)); - return FALSE; - } - - /* We look for entries that start with "LCK.." and ignore everything - else. This won't find all possible lock files, but it should - find all the locks on terminals and systems. */ - - calc = 0; - pai = NULL; - cgot = 0; - while ((qentry = readdir (qdir)) != NULL) - { - const char *zname; - int o; -#if HAVE_V2_LOCKFILES - int i; -#else - char ab[12]; -#endif - int cread; - int ierr; - int ipid; - - if (strncmp (qentry->d_name, "LCK..", sizeof "LCK.." - 1) != 0) - continue; - - zname = zsappend (zdir, qentry->d_name); - o = open (zname, O_RDONLY, 0); - if (o < 0) - { - if (errno != ENOENT) - ulog (LOG_ERROR, "open (%s): %s", zname, strerror (errno)); - continue; - } - -#if HAVE_V2_LOCKFILES - cread = read (o, &i, sizeof i); -#else - cread = read (o, ab, sizeof ab - 1); -#endif - - ierr = errno; - (void) close (o); - - if (cread < 0) - { - ulog (LOG_ERROR, "read %s: %s", zname, strerror (ierr)); - continue; - } - -#if HAVE_V2_LOCKFILES - ipid = i; -#else - ab[cread] = '\0'; - ipid = atoi (ab); -#endif - - printf ("%s: %d\n", qentry->d_name, ipid); - - if (cgot >= calc) - { - calc += 10; - pai = (int *) xrealloc ((pointer) pai, calc * sizeof (int)); - } - - pai[cgot] = ipid; - ++cgot; - } - - if (cgot == 0) - return TRUE; - - aidescs[0] = SPAWN_NULL; - aidescs[1] = 1; - aidescs[2] = 2; - - /* Parse PS_PROGRAM into an array of arguments. */ - zcopy = (char *) alloca (sizeof PS_PROGRAM); - strcpy (zcopy, PS_PROGRAM); - - cargs = 0; - for (ztok = strtok (zcopy, " \t"); - ztok != NULL; - ztok = strtok ((char *) NULL, " \t")) - ++cargs; - - pazargs = (char **) alloca ((cargs + 1) * sizeof (char *)); - - strcpy (zcopy, PS_PROGRAM); - for (ztok = strtok (zcopy, " \t"), iarg = 0; - ztok != NULL; - ztok = strtok ((char *) NULL, " \t"), ++iarg) - pazargs[iarg] = ztok; - pazargs[iarg] = NULL; - -#if ! HAVE_PS_MULTIPLE - /* We have to invoke ps multiple times. */ - { - int i; - char *zlast, *zset; - - zlast = pazargs[cargs - 1]; - zset = (char *) alloca (strlen (zlast) + 20); - for (i = 0; i < cgot; i++) - { - pid_t ipid; - - sprintf (zset, "%s%d", zlast, pai[i]); - pazargs[cargs - 1] = zset; - - ipid = isspawn ((const char **) pazargs, aidescs, FALSE, FALSE, - (const char *) NULL, FALSE, TRUE, - (const char *) NULL, (const char *) NULL, - (const char *) NULL); - if (ipid < 0) - ulog (LOG_ERROR, "isspawn: %s", strerror (errno)); - else - (void) iswait ((unsigned long) ipid, PS_PROGRAM); - } - } -#else - { - char *zlast; - int i; - pid_t ipid; - - zlast = (char *) alloca (strlen (pazargs[cargs - 1]) + cgot * 20 + 1); - strcpy (zlast, pazargs[cargs - 1]); - for (i = 0; i < cgot; i++) - { - char ab[20]; - - sprintf (ab, "%d", pai[i]); - strcat (zlast, ab); - if (i + 1 < cgot) - strcat (zlast, ","); - } - pazargs[cargs - 1] = zlast; - - ipid = isspawn ((const char **) pazargs, aidescs, FALSE, FALSE, - (const char *) NULL, FALSE, TRUE, - (const char *) NULL, (const char *) NULL, - (const char *) NULL); - if (ipid < 0) - ulog (LOG_ERROR, "isspawn: %s", strerror (errno)); - else - (void) iswait ((unsigned long) ipid, PS_PROGRAM); - } -#endif - - return TRUE; -} - -/* - Local variables: - mode:c - End: - */ diff --git a/gnu/libexec/uucp/sysh.unx b/gnu/libexec/uucp/sysh.unx deleted file mode 100644 index f7c07bb4d76..00000000000 --- a/gnu/libexec/uucp/sysh.unx +++ /dev/null @@ -1,606 +0,0 @@ -/* sysh.unx - 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 AIRS, P.O. Box 520, Waltham, MA 02254. - - $Log: sysh.unx,v $ - Revision 1.1.1.1 1993/03/21 09:45:37 cgd - initial import of 386bsd-0.1 sources - - Revision 1.53 1992/03/30 15:29:58 ian - Added HAVE_SVR4_LOCKFILES - - Revision 1.52 1992/03/16 01:23:08 ian - Make blocking writes optional - - Revision 1.51 1992/03/15 07:15:42 ian - T. William Wells: don't use unblocked writes - - Revision 1.50 1992/03/15 04:51:17 ian - Keep an array of signals we've received rather than a single variable - - Revision 1.49 1992/03/15 01:54:46 ian - All execs are now done in isspawn, all waits are done in iswait - - Revision 1.48 1992/03/12 21:52:21 ian - Corrected readdir prototype - - Revision 1.47 1992/03/11 22:06:37 ian - Marty Shannon: added max-uuxqts command - - Revision 1.46 1992/03/11 02:09:57 ian - Franc,ois Pinard: retry fork several times before giving up - - Revision 1.45 1992/03/11 00:18:50 ian - Save temporary file if file send fails - - Revision 1.44 1992/03/10 17:39:57 ian - Some systems don't permit both <termios.h> and <sys/ioctl.h> to be included - - Revision 1.43 1992/03/09 22:07:36 ian - Wait for terminal output to drain at various points - - Revision 1.42 1992/03/03 21:01:20 ian - Use strict timeout in fsserial_read, eliminate all race conditions - - Revision 1.41 1992/03/02 04:53:07 ian - Marc Unangst: added HAVE_SCO_LOCKFILES configuration parameter - - Revision 1.40 1992/02/29 01:06:59 ian - Chip Salzenberg: recheck file permissions before sending - - Revision 1.39 1992/02/28 05:06:15 ian - T. William Wells: fsysdep_catch must be a macro - - Revision 1.38 1992/02/27 05:40:54 ian - T. William Wells: detach from controlling terminal, handle signals safely - - Revision 1.37 1992/02/23 03:26:51 ian - Overhaul to use automatic configure shell script - - Revision 1.36 1992/02/20 04:18:59 ian - Added uustat - - Revision 1.35 1992/02/09 05:10:50 ian - Added HAVE_MKDIR configuration parameter and mkdir emulation - - Revision 1.34 1992/02/09 03:14:48 ian - Added HAVE_OLD_DIRECTORIES for systems without readdir routines - - Revision 1.33 1992/02/09 02:41:58 ian - Added HAVE_DUP2 configuration parameter and dup2 emulation function - - Revision 1.32 1992/02/08 23:34:41 ian - If we have neither getcwd nor getwd, fork /bin/pwd to get the cwd - - Revision 1.31 1992/02/08 20:02:36 ian - Added HAVE_SETRET configuration option for systems without setjmp - - Revision 1.30 1992/02/08 03:54:18 ian - Include <string.h> only in <uucp.h>, added 1992 copyright - - Revision 1.29 1992/01/15 21:06:11 ian - Mike Park: some systems can't include <sys/time.h> and <time.h> together - - Revision 1.28 1992/01/15 19:40:35 ian - Mike Park: handle HAVE_UNION_WAIT correctly and completely - - Revision 1.27 1992/01/15 07:06:29 ian - Set configuration directory in Makefile rather than sysdep.h - - Revision 1.26 1992/01/14 04:18:47 ian - Chip Salzenberg: added HAVE_USLEEP configuration parameter - - Revision 1.25 1992/01/13 19:59:29 ian - Define LIBDIR in Makefile rather than in sysh.unx - - Revision 1.24 1992/01/13 05:55:59 ian - Touched up a few comments - - Revision 1.23 1992/01/13 05:53:04 ian - Mike Park: added HAVE_WAITPID and HAVE_WAIT4 configuration parameters - - Revision 1.22 1992/01/11 17:11:11 ian - Hannu Strang: avoid compiler bug by not using -> in address constant - - Revision 1.21 1992/01/04 21:43:24 ian - Chip Salzenberg: added ALLOW_FILENAME_ARGUMENTS to permit them - - Revision 1.20 1991/12/29 00:55:23 ian - Monty Solomon: added HAVE_UNION_WAIT - - Revision 1.19 1991/12/28 17:08:47 ian - John Theus: offer HAVE_GETWD as an alternative to using getcwd - - Revision 1.18 1991/12/28 07:01:15 ian - Added HAVE_FTIME configuration option - - Revision 1.17 1991/12/22 22:14:19 ian - Monty Solomon: added HAVE_UNISTD_H configuration parameter - - Revision 1.16 1991/12/19 04:25:57 ian - Terry Gardner: configuration parameter to not use both NONBLOCK and NDELAY - - Revision 1.15 1991/12/17 07:09:58 ian - Record statistics in fractions of a second - - Revision 1.14 1991/12/11 04:21:37 ian - Arne Ludwig: merge in Arne Ludwig's patches for V2 and BNU style logging - - Revision 1.13 1991/12/09 19:07:07 ian - Richard Todd: add HAVE_V2_LOCKFILES--binary number in lock file - - Revision 1.12 1991/11/30 23:28:26 ian - Marty Shannon: some systems need a fake version of the rename system call - - Revision 1.11 1991/11/26 01:45:42 ian - Marty Shannon: configuration option to not include <sys/wait.h> - - Revision 1.10 1991/11/24 04:15:13 ian - Removed extraneous comment left by last revision - - Revision 1.9 1991/11/21 21:49:38 ian - Brian Campbell: define all macros to avoid compiler warnings - - Revision 1.8 1991/11/21 21:07:46 ian - Brian Campbell: offer ltrunc as an alternative to ftruncate - - Revision 1.7 1991/11/10 19:24:22 ian - Added pffile protocol entry point for file level control - - Revision 1.6 1991/11/08 22:52:34 ian - Brian Campbell: only include <sys/time.h> and <sys/ioctl.h> when needed - - Revision 1.5 1991/11/08 22:11:45 ian - Brian Campbell: allow sigsetjmp as configuration option - - Revision 1.4 1991/11/07 19:32:28 ian - Chip Salzenberg: allow LOCKDIR, and check that locking process exists - - Revision 1.3 1991/09/19 16:15:58 ian - Chip Salzenberg: configuration option for permitting execution via sh - - Revision 1.2 1991/09/19 03:06:04 ian - Chip Salzenberg: put BNU temporary files in system's directory - - Revision 1.1 1991/09/10 19:45:50 ian - Initial revision - - */ - -#ifndef SYSH_UNX_H - -#define SYSH_UNX_H - -/* We're might redefine fsysdep_catch, so make sure we've gotten the - prototype already. */ - -#ifndef SYSTEM_H -#include "system.h" -#endif - -/* Make sure the defines do not conflict. These are in this file - because they are Unix dependent. */ - -#if HAVE_V2_LOCKFILES + HAVE_BNU_LOCKFILES + HAVE_SCO_LOCKFILES + HAVE_SVR4_LOCKFILES != 1 - #error LOCKFILES define not set or duplicated -#endif - -/* SCO and SVR4 lockfiles are basically just like BNU lockfiles. */ -#if HAVE_SCO_LOCKFILES || HAVE_SVR4_LOCKFILES -#undef HAVE_BNU_LOCKFILES -#define HAVE_BNU_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_BNU + SPOOLDIR_ULTRIX + SPOOLDIR_TAYLOR != 1 - #error Spool directory define not set or duplicated -#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 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 -#ifdef SV_INTERRUPT -#undef HAVE_RESTARTABLE_SYSCALLS -#define HAVE_RESTARTABLE_SYSCALLS 0 -#endif -#endif - -/* 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> -typedef struct sgttyb sterminal; -#define fgetterminfo(o, q) (ioctl ((o), TIOCGETP, (q)) == 0) -#define fsetterminfo(o, q) (ioctl ((o), TIOCSETN, (q)) == 0) -#define fsetterminfodrain(o, q) (ioctl ((o), TIOCSETP, (q)) == 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" - -#if HAVE_TAYLOR_CONFIG - -/* The names of the configuration files. These are appended to - NEWCONFIGLIB which is defined in Makefile. */ -#define CONFIGFILE "/config" -#define SYSFILE "/sys" -#define PORTFILE "/port" -#define DIALFILE "/dial" -#define CALLFILE "/call" -#define PASSWDFILE "/passwd" -#define DIALCODEFILE "/dialcode" - -#endif /* HAVE_TAYLOR_CONFIG */ - -#if HAVE_V2_CONFIG - -/* The names of the various V2 configuration files. These are - appended to OLDCONFIGLIB which is defined in Makefile. */ -#define V2_SYSTEMS "/L.sys" -#define V2_DEVICES "/L-devices" -#define V2_USERFILE "/USERFILE" -#define V2_CMDS "/L.cmds" -#define V2_DIALCODES "/L-dialcodes" - -#endif /* HAVE_V2_CONFIG */ - -#if HAVE_BNU_CONFIG - -/* The names of the BNU configuration files. These are appended to - OLDCONFIGLIB which is defined in Makefile. */ -#define BNU_SYSFILES "/Sysfiles" -#define BNU_SYSTEMS "/Systems" -#define BNU_PERMISSIONS "/Permissions" -#define BNU_DIALERS "/Dialers" -#define BNU_DEVICES "/Devices" -#define BNU_PERMISSIONS "/Permissions" -#define BNU_DIALCODES "/Dialcodes" -#define BNU_MAXUUXQTS "/Maxuuxqts" - -#endif /* HAVE_BNU_CONFIG */ - -/* Get some standard definitions. */ - -#include <sys/types.h> -#include <sys/stat.h> - -/* Get definitions for the file permission bits. */ - -#ifndef S_IRUSR - -#define S_IRWXU 0700 -#define S_IRUSR 0400 -#define S_IWUSR 0200 -#define S_IXUSR 0100 - -#define S_IRWXG 0070 -#define S_IRGRP 0040 -#define S_IWGRP 0020 -#define S_IXGRP 0010 - -#define S_IRWXO 0007 -#define S_IROTH 0004 -#define S_IWOTH 0002 -#define S_IXOTH 0001 - -#endif /* ! defined (S_IRUSR) */ - -#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 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 */ - -/* Information we need for a UNIX serial port. */ - -struct ssysdep_serial_port -{ - /* File descriptor to read from. */ - int oread; - /* Whether the read descriptor is blocking. */ - boolean fread_blocking; - /* File descriptor to write to. */ - int owrite; - /* Whether the write descriptor is blocking. */ - boolean fwrite_blocking; - /* Whether setting the read descriptor to blocking affects the write - descriptor and vice-versa. */ - boolean fblock_both; - /* Hold the real read descriptor when using a dialer device. */ - int oholdread; - /* Hold the real write descriptor when using a dialer device. */ - int oholdwrite; - /* TRUE if this is a terminal and the remaining fields are valid. */ - boolean fterminal; - /* Baud rate. */ - long ibaud; - /* Original terminal settings. */ - sterminal sorig; - /* New terminal settings (raw mode, etc.). */ - sterminal snew; -}; - -/* Information we need for a UNIX stdin port. */ - -struct ssysdep_stdin_port -{ - struct ssysdep_serial_port s; - boolean fpty; -}; - -/* For debugging it is helpful to know whether we are connected - through a pty; the fsserial_read routine uses this information to - know whether to sleep or not. */ -#define SYSDEP_STDIN_CMDS(s) \ - { "pty", CMDTABTYPE_BOOLEAN, (pointer) &(s).fpty, NULL } - -#define SYSDEP_STDIN_INIT(q) ((q)->fpty = FALSE, (q)->s.oread = -1) - -/* Information we need for a UNIX modem port. */ - -struct ssysdep_modem_port -{ - struct ssysdep_serial_port s; -}; - -#define SYSDEP_MODEM_INIT(q) ((q)->s.oread = -1) - -/* Information we need for a UNIX direct port. */ - -struct ssysdep_direct_port -{ - struct ssysdep_serial_port s; -}; - -#define SYSDEP_DIRECT_INIT(q) ((q)->s.oread = -1) - -/* Set a signal handler. */ -extern void usset_signal P((int isig, SIGtype (*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 SIGtype ussignal P((int isig)); - -/* Try to fork, repeating several times. */ -extern pid_t isfork 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 isspawn 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 isspawn. */ -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 iswait P((unsigned long ipid, const char *zreport)); - -/* Lock a string. */ -extern boolean fsdo_lock P((const char *, boolean fspooldir)); - -/* Unlock a string. */ -extern boolean fsdo_unlock P((const char *, boolean fspooldir)); - -/* See whether a directory exists. */ -extern boolean fsdirectory_exists P((const char *)); - -/* Expand a leading tilde to the public directory or a user's home - directory. Each system may have a different public directory, so - the system information must be passed in. */ -extern const char *zstilde_expand P((const struct ssysteminfo *qsys, - const char *zfile)); - -/* 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)); - -/* Copy a string to the common static buffer. */ -extern const char *zscopy P((const char *z)); - -/* Prepend a directory to a file name, returning the common static - buffer. */ -extern const char *zsappend P((const char *zdir, const char *zfile)); - -/* Get a temporary file name. */ -extern const char *zstemp_file P((const struct ssysteminfo *qsys)); - -/* Get a jobid from a system and file name. */ -extern const char *zsfile_to_jobid P((const struct ssysteminfo *qsys, - const char *zfile)); - -/* Get a file name from a jobid. This also returns the associated system - in *pzsystem. */ -extern const char *zsjobid_to_file P((const char *zid, - const char **pzsystem)); - -#if SPOOLDIR_ULTRIX -/* See whether there is a spool directory for a system. */ -extern boolean fsultrix_has_spool P((const char *zsystem)); -#endif /* SPOOLDIR_ULTRIX */ - -/* The working directory from which the program was run (this is set - by usysdep_initialize if called with fgetcwd TRUE). */ -extern char *zScwd; - -/* - Local variables: - mode:c - End: - */ -#endif /* ! defined (SYSH_UNX_H) */ diff --git a/gnu/libexec/uucp/sysinf.c b/gnu/libexec/uucp/sysinf.c deleted file mode 100644 index 647d56be147..00000000000 --- a/gnu/libexec/uucp/sysinf.c +++ /dev/null @@ -1,1797 +0,0 @@ -/* sysinf.c - Functions to read system information 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 AIRS, P.O. Box 520, Waltham, MA 02254. - - $Log: sysinf.c,v $ - Revision 1.1.1.1 1993/03/21 09:45:37 cgd - initial import of 386bsd-0.1 sources - - Revision 1.24 1992/04/02 22:51:09 ian - Add gcc 2.0 format checking to ulog, and fixed discovered problems - - Revision 1.23 1992/03/30 04:49:10 ian - Niels Baggesen: added debugging types abnormal and uucp-proto - - Revision 1.22 1992/03/28 21:47:55 ian - David J. MacKenzie: allow backslash to quote newline in config files - - Revision 1.21 1992/03/28 20:31:55 ian - Franc,ois Pinard: allow a name to be given to an alternate - - Revision 1.20 1992/03/24 17:18:33 ian - Fixed handling of alternates in file-wide defaults - - Revision 1.19 1992/03/16 04:30:57 ian - Permit a retry time for the time and timegrade commands - - Revision 1.18 1992/03/13 16:17:42 ian - Chip Salzenberg: set default login chat script timeout to 10 seconds - - Revision 1.17 1992/03/12 19:54:43 ian - Debugging based on types rather than number - - Revision 1.16 1992/03/09 20:14:37 ian - Ted Lindgreen: added max-remote-debug command - - Revision 1.15 1992/03/07 02:56:30 ian - Rewrote time routines - - Revision 1.14 1992/03/03 06:06:48 ian - T. William Wells: don't complain about missing configuration files - - Revision 1.13 1992/02/23 19:50:50 ian - Handle READ and WRITE in Permissions correctly - - Revision 1.12 1992/02/08 03:54:18 ian - Include <string.h> only in <uucp.h>, added 1992 copyright - - Revision 1.11 1992/01/13 05:17:30 ian - Mike Park: wrong number of arguments to ulog call - - Revision 1.10 1992/01/07 15:23:50 ian - Niels Baggesen: allocate number of protocol parameters correctly - - Revision 1.9 1991/12/28 03:49:23 ian - Added HAVE_MEMFNS and HAVE_BFNS; changed uses of memset to bzero - - Revision 1.8 1991/12/23 05:15:54 ian - David Nugent: set debugging level for a specific system - - Revision 1.7 1991/12/17 17:08:02 ian - Marc Unangst: allow true and false for boolean strings as documented - - Revision 1.6 1991/12/15 04:17:11 ian - Added chat-seven-bit command to control parity bit stripping - - Revision 1.5 1991/12/15 03:42:33 ian - Added tprocess_chat_cmd for all chat commands, and added CMDTABTYPE_PREFIX - - Revision 1.4 1991/11/13 20:38:00 ian - Added TCP port type for connections over TCP - - Revision 1.3 1991/11/12 19:47:04 ian - Add called-chat set of commands to run a chat script on an incoming call - - Revision 1.2 1991/11/11 23:47:24 ian - Added chat-program to run a program to do a chat script - - Revision 1.1 1991/09/10 19:40:31 ian - Initial revision - - */ - -#include "uucp.h" - -#if USE_RCS_ID -char sysinf_rcsid[] = "$Id: sysinf.c,v 1.1.1.1 1993/03/21 09:45:37 cgd Exp $"; -#endif - -#include <ctype.h> -#include <errno.h> - -#include "port.h" -#include "system.h" -#include "uutime.h" - -/* Whether we accept calls from unknown systems. */ -boolean fUnknown_ok = FALSE; - -/* Information we hold for an unknown system. */ -struct ssysteminfo sUnknown; - -/* Information we hold for the local system. */ -struct ssysteminfo sLocalsys; - -#if HAVE_TAYLOR_CONFIG - -/* I don't find the system file format used by either V2 or BNU UUCP - very intuitive, so I've developed my own format. This replaces the - files L.sys and USERFILE for V2, and Systems and Permissions for - BNU. The complete format is described in a separate document. */ - -/* Some local functions. */ -static void uiset_clear P((boolean falternate)); - -/* Set when we read the first line of a new file, to indicate that a - new set of defaults should be gathered. */ -static boolean fIfirst; - -/* This structure holds system information as it is gathered. */ -static struct ssysteminfo sIhold; - -/* Default information. */ -static struct ssysteminfo sIdefault; - -/* The name of the next system. */ -static char *zInext_system; - -/* The list of alternates to draw from. */ -static struct ssysteminfo *qIalternates; - -/* Whether to use default alternates. */ -static boolean fIdefault_alternates; - -/* There are several commands for which we want to take the default if - provided, but we don't want to add to the default. For example, - each system can have multiple time specifications (using different - grades), which is implemented by adding each new time specification - to the previous ones. We want to allow default time specifications. - However, if a system has time specifications, we don't want to add - its time specifications to the default ones. We handle this with a - set of boolean variables which we set to tell the adding functions - to ignore any existing entry; when an entry has been added, the - boolean variable is cleared. */ -static boolean fIclear_alias; -static boolean fIclear_alternate; -static boolean fIclear_time; -static boolean fIclear_calltimegrade; -static boolean fIclear_call_local_size; -static boolean fIclear_call_remote_size; -static boolean fIclear_called_local_size; -static boolean fIclear_called_remote_size; -static boolean fIclear_port; -static boolean fIclear_chat_fail; -static boolean fIclear_proto_param; -static boolean fIclear_called_chat_fail; - -/* Local functions needed to parse the system information file. */ - -#define CMDTABFN(z) \ - static enum tcmdtabret z P((int, char **, pointer, const char *)) - -CMDTABFN (ticlear); -CMDTABFN (tisystem); -CMDTABFN (tialias); -CMDTABFN (tialternate); -CMDTABFN (titime); -CMDTABFN (titimegrade); -CMDTABFN (ticall_local_size); -CMDTABFN (ticall_remote_size); -CMDTABFN (ticalled_local_size); -CMDTABFN (ticalled_remote_size); -CMDTABFN (titimetable); -CMDTABFN (tiport); -CMDTABFN (tichat); -CMDTABFN (ticalled_login); -CMDTABFN (tiproto_param); -CMDTABFN (tirequest); -CMDTABFN (titransfer); - -#undef CMDTABFN - -/* The commands accepted from the system information file. */ - -static const struct scmdtab asIcmds[] = -{ - { "#", CMDTABTYPE_FN | 1, NULL, ticlear }, - { "system", CMDTABTYPE_FN | 2, NULL, tisystem }, - { "alias", CMDTABTYPE_FN | 2, NULL, tialias }, - { "alternate", CMDTABTYPE_FN | 0, NULL, tialternate }, - { "default-alternates", CMDTABTYPE_BOOLEAN, - (pointer) &fIdefault_alternates, NULL }, - { "time", CMDTABTYPE_FN | 0, NULL, titime }, - { "timegrade", CMDTABTYPE_FN | 0, (pointer) &sIhold.ztime, titimegrade }, - { "call-timegrade", CMDTABTYPE_FN | 3, (pointer) &sIhold.zcalltimegrade, - titimegrade }, - { "call-local-size", CMDTABTYPE_FN | 3, NULL, ticall_local_size }, - { "call-remote-size", CMDTABTYPE_FN | 3, NULL, ticall_remote_size }, - { "called-local-size", CMDTABTYPE_FN | 3, NULL, ticalled_local_size }, - { "called-remote-size", CMDTABTYPE_FN | 3, NULL, ticalled_remote_size }, - { "timetable", CMDTABTYPE_FN | 3, NULL, titimetable }, - { "baud", CMDTABTYPE_LONG, (pointer) &sIhold.ibaud, NULL }, - { "speed", CMDTABTYPE_LONG, (pointer) &sIhold.ibaud, NULL }, - { "port", CMDTABTYPE_FN | 0, NULL, tiport }, - { "phone", CMDTABTYPE_STRING, (pointer) &sIhold.zphone, NULL }, - { "address", CMDTABTYPE_STRING, (pointer) &sIhold.zphone, NULL }, - { "chat", CMDTABTYPE_PREFIX | 0, (pointer) &sIhold.schat, tichat }, - { "call-login", CMDTABTYPE_STRING, (pointer) &sIhold.zcall_login, NULL }, - { "call-password", CMDTABTYPE_STRING, (pointer) &sIhold.zcall_password, - NULL }, - { "called-login", CMDTABTYPE_FN | 0, NULL, ticalled_login }, - { "callback", CMDTABTYPE_BOOLEAN, (pointer) &sIhold.fcallback, NULL }, - { "sequence", CMDTABTYPE_BOOLEAN, (pointer) &sIhold.fsequence, NULL }, - { "protocol", CMDTABTYPE_STRING, (pointer) &sIhold.zprotocols, NULL }, - { "protocol-parameter", CMDTABTYPE_FN | 0, NULL, tiproto_param }, - { "called-chat", CMDTABTYPE_PREFIX | 0, (pointer) &sIhold.scalled_chat, - tichat }, -#if DEBUG > 1 - { "debug", CMDTABTYPE_FN | 0, (pointer) &sIhold.idebug, tidebug_parse }, - { "max-remote-debug", CMDTABTYPE_FN | 0, - (pointer) &sIhold.imax_remote_debug, tidebug_parse }, -#endif - { "call-request", CMDTABTYPE_BOOLEAN, (pointer) &sIhold.fcall_request, - NULL }, - { "called-request", CMDTABTYPE_BOOLEAN, (pointer) &sIhold.fcalled_request, - NULL }, - { "request", CMDTABTYPE_FN | 2, NULL, tirequest }, - { "call-transfer", CMDTABTYPE_BOOLEAN, (pointer) &sIhold.fcall_transfer, - NULL }, - { "called-transfer", CMDTABTYPE_BOOLEAN, - (pointer) &sIhold.fcalled_transfer, NULL }, - { "transfer", CMDTABTYPE_FN | 2, NULL, titransfer }, - { "local-send", CMDTABTYPE_FULLSTRING, (pointer) &sIhold.zlocal_send, - NULL }, - { "remote-send", CMDTABTYPE_FULLSTRING, (pointer) &sIhold.zremote_send, - NULL }, - { "local-receive", CMDTABTYPE_FULLSTRING, - (pointer) &sIhold.zlocal_receive, NULL }, - { "remote-receive", CMDTABTYPE_FULLSTRING, - (pointer) &sIhold.zremote_receive, NULL }, - { "command-path", CMDTABTYPE_FULLSTRING, (pointer) &sIhold.zpath, NULL }, - { "commands", CMDTABTYPE_FULLSTRING, (pointer) &sIhold.zcmds, NULL }, - { "free-space", CMDTABTYPE_LONG, (pointer) &sIhold.cfree_space, NULL }, - { "forwardto", CMDTABTYPE_FULLSTRING, (pointer) &sIhold.zforwardto, NULL }, - { "forward-to", CMDTABTYPE_FULLSTRING, (pointer) &sIhold.zforwardto, NULL }, - { "pubdir", CMDTABTYPE_STRING, (pointer) &sIhold.zpubdir, NULL }, - { "myname", CMDTABTYPE_STRING, (pointer) &sIhold.zlocalname, NULL }, - { NULL, 0, NULL, NULL } -}; - -/* This is called for the first line of each file. It clears the - defaults, so that each file has a different set. */ - -/*ARGSUSED*/ -static enum tcmdtabret -ticlear (argc, argv, pvar, zerr) - int argc; - char **argv; - pointer pvar; - const char *zerr; -{ - fIfirst = TRUE; - return CMDTABRET_FREE_AND_EXIT; -} - -/* Process the system command. We store away the system name and exit - out of processing commands to let the main loop handle it. */ - -/*ARGSUSED*/ -static enum tcmdtabret -tisystem (argc, argv, pvar, zerr) - int argc; - char **argv; - pointer pvar; - const char *zerr; -{ - const char *z; - - /* System names may only contain alphanumeric characters, - underscores, dashes and dots, and they may not begin with a dot, - at least for now. */ - for (z = argv[1]; *z != '\0'; z++) - { - if (! isalnum (BUCHAR (*z)) - && *z != '_' - && *z != '-' - && (*z != '.' || z == argv[1])) - { - ulog (LOG_ERROR, "%s: %s %s: Illegal character in system name", - zerr, argv[0], argv[1]); - return CMDTABRET_FREE; - } - } - - if (strlen (argv[1]) > cSysdep_max_name_len) - { - ulog (LOG_ERROR, "System name \"%s\" too long (max %d)", argv[1], - cSysdep_max_name_len); - return CMDTABRET_FREE; - } - - zInext_system = argv[1]; - - DEBUG_MESSAGE1 (DEBUG_CONFIG, - "tisystem: Reading system %s", zInext_system); - - return CMDTABRET_EXIT; -} - -/* Process the alias command. */ - -/*ARGSUSED*/ -static enum tcmdtabret -tialias (argc, argv, pvar, zerr) - int argc; - char **argv; - pointer pvar; - const char *zerr; -{ - if (fIclear_alias) - { - sIhold.zalias = NULL; - fIclear_alias = FALSE; - } - uadd_string (&sIhold.zalias, argv[1], ' '); - return CMDTABRET_FREE; -} - -/* Process the alternate command. The current information is in - sIhold. We link this onto a chain of alternates starting at - sIalternate. We then set up sIhold with the defaults for the next - alternate. qIalternates holds the list of alternates for the - file-wide defaults, and we use to set up sIhold. We also call - uiset_clear to set all the fIclear_* variables so that commands - like ``time'' know that they should ignore any existing entry. */ - -static struct ssysteminfo sIalternate; - -/*ARGSUSED*/ -static enum tcmdtabret -tialternate (argc, argv, pvar, zerr) - int argc; - char **argv; - pointer pvar; - const char *zerr; -{ - if (fIclear_alternate) - { - sIalternate = sIhold; - fIclear_alternate = FALSE; - } - else - { - struct ssysteminfo *qnew; - struct ssysteminfo **pq; - - qnew = (struct ssysteminfo *) xmalloc (sizeof (struct ssysteminfo)); - *qnew = sIhold; - for (pq = &sIalternate.qalternate; *pq != NULL; pq = &(*pq)->qalternate) - ; - *pq = qnew; - sIhold = sIalternate; - sIhold.qalternate = NULL; - } - - /* Clear the name of the next alternate. */ - sIhold.zalternate = NULL; - - /* Now, if there is a default alternate to base this on, we must - override everything not changed before the first ``alternate'' - command to the default alternate. */ - if (fIdefault_alternates - && qIalternates != NULL) - { - if (qIalternates->zalternate != NULL) - sIhold.zalternate = qIalternates->zalternate; - -#define TEST(x) \ - if (sIhold.x == sIdefault.x) \ - sIhold.x = qIalternates->x; - - TEST (ztime); - TEST (zcalltimegrade); - TEST (zcall_local_size); - TEST (zcall_remote_size); - TEST (zcalled_local_size); - TEST (zcalled_remote_size); - TEST (ibaud); - TEST (zport); - TEST (qport); - TEST (zphone); - TEST (schat.zchat); - TEST (schat.zprogram); - TEST (schat.ctimeout); - TEST (schat.zfail); - TEST (zcall_login); - TEST (zcalled_login); - TEST (fcallback); - TEST (zprotocols); - TEST (cproto_params); - TEST (qproto_params); - TEST (scalled_chat.zchat); - TEST (scalled_chat.zprogram); - TEST (scalled_chat.ctimeout); - TEST (scalled_chat.zfail); -#if DEBUG > 1 - TEST (idebug); - TEST (imax_remote_debug); -#endif - TEST (fcall_request); - TEST (fcalled_request); - TEST (fcall_transfer); - TEST (fcalled_transfer); - TEST (zlocal_send); - TEST (zcalled_local_send); - TEST (zremote_send); - TEST (zcalled_remote_send); - TEST (zlocal_receive); - TEST (zcalled_local_receive); - TEST (zremote_receive); - TEST (zcalled_remote_receive); - TEST (zpath); - TEST (zcmds); - TEST (cfree_space); - TEST (zforwardto); - TEST (zpubdir); - TEST (zlocalname); - -#undef TEST - - qIalternates = qIalternates->qalternate; - } - - /* If there is a name for this alternate, put it in. */ - if (argc > 1) - sIhold.zalternate = xstrdup (argv[1]); - - uiset_clear (TRUE); - - return CMDTABRET_FREE; -} - -/* Process the time command. */ - -/*ARGSUSED*/ -static enum tcmdtabret -titime (argc, argv, pvar, zerr) - int argc; - char **argv; - pointer pvar; - const char *zerr; -{ - char *pznew[4]; - char ab[2]; - - pznew[0] = argv[0]; - ab[0] = 'z'; - ab[1] = '\0'; - pznew[1] = ab; - pznew[2] = argv[1]; - if (argc > 2) - pznew[3] = argv[2]; - - return titimegrade (argc + 1, pznew, (pointer) &sIhold.ztime, zerr); -} - -/* Process the timegrade and the call-timegrade commands. */ - -static enum tcmdtabret -titimegrade (argc, argv, pvar, zerr) - int argc; - char **argv; - pointer pvar; - const char *zerr; -{ - char **pztime = (char **) pvar; - int clen; - char *z; - - if (argc < 3 || argc > 4) - { - ulog (LOG_ERROR, "%s: %s: Wrong number of arguments", zerr, argv[0]); - return CMDTABRET_FREE; - } - - if (argv[1][1] != '\0' || ! FGRADE_LEGAL (argv[1][0])) - { - ulog (LOG_ERROR, "%s: %s: Illegal grade '%s'", zerr, argv[0], - argv[1]); - return CMDTABRET_FREE; - } - - /* We should probably check whether the time string is legal. A - timegrade string is a single character grade, then a time string, - then an optional semicolon and a retry time. */ - - clen = strlen (argv[2]) + 2; - if (argc > 3) - clen += strlen (argv[3]) + 1; - z = (char *) alloca (clen); - *z = argv[1][0]; - strcpy (z + 1, argv[2]); - if (argc > 3) - { - strcat (z, ";"); - strcat (z, argv[3]); - } - - if (pztime == &sIhold.ztime) - { - if (fIclear_time) - { - *pztime = NULL; - fIclear_time = FALSE; - } - } - else - { - if (fIclear_calltimegrade) - { - *pztime = NULL; - fIclear_calltimegrade = FALSE; - } - } - - uadd_string (pztime, z, ' '); - - return CMDTABRET_FREE; -} - -/* Add a size command. */ - -static enum tcmdtabret tiadd_size P((int argc, char **argv, - const char *zerr, boolean *pf, - char **pz)); - -static enum tcmdtabret -tiadd_size (argc, argv, zerr, pf, pz) - int argc; - char **argv; - const char *zerr; - boolean *pf; - char **pz; -{ - long cbytes; - char *zend; - char *zarg; - - cbytes = strtol (argv[1], &zend, 10); - if (*zend != '\0') - { - ulog (LOG_ERROR, "%s: %s: Bad number", zerr, argv[0]); - return CMDTABRET_FREE; - } - - /* We should check the legality of the time string here. */ - - if (*pf) - { - *pz = NULL; - *pf = FALSE; - } - - zarg = (char *) alloca (strlen (argv[2]) + 20); - sprintf (zarg, "%ld %s", cbytes, argv[2]); - - uadd_string (pz, zarg, ' '); - - return CMDTABRET_FREE; -} - -/* Process the call-local-size command. */ - -/*ARGSUSED*/ -static enum tcmdtabret -ticall_local_size (argc, argv, pvar, zerr) - int argc; - char **argv; - pointer pvar; - const char *zerr; -{ - return tiadd_size (argc, argv, zerr, &fIclear_call_local_size, - &sIhold.zcall_local_size); -} - -/* Process the call-remote-size command. */ - -/*ARGSUSED*/ -static enum tcmdtabret -ticall_remote_size (argc, argv, pvar, zerr) - int argc; - char **argv; - pointer pvar; - const char *zerr; -{ - return tiadd_size (argc, argv, zerr, &fIclear_call_remote_size, - &sIhold.zcall_remote_size); -} - -/* Process the called-local-size command. */ - -/*ARGSUSED*/ -static enum tcmdtabret -ticalled_local_size (argc, argv, pvar, zerr) - int argc; - char **argv; - pointer pvar; - const char *zerr; -{ - return tiadd_size (argc, argv, zerr, &fIclear_called_local_size, - &sIhold.zcalled_local_size); -} - -/* Process the called-remote-size command. */ - -/*ARGSUSED*/ -static enum tcmdtabret -ticalled_remote_size (argc, argv, pvar, zerr) - int argc; - char **argv; - pointer pvar; - const char *zerr; -{ - return tiadd_size (argc, argv, zerr, &fIclear_called_remote_size, - &sIhold.zcalled_remote_size); -} - -/* Process the timetable command. */ - -/*ARGSUSED*/ -static enum tcmdtabret -titimetable (argc, argv, pvar, zerr) - int argc; - char **argv; - pointer pvar; - const char *zerr; -{ - uaddtimetable (argv[1], argv[2]); - return CMDTABRET_CONTINUE; -} - -/* Process the port command. */ - -/*ARGSUSED*/ -static enum tcmdtabret -tiport (argc, argv, pvar, zerr) - int argc; - char **argv; - pointer pvar; - const char *zerr; -{ - if (argc < 2) - { - ulog (LOG_ERROR, "%s: %s: Wrong number of arguments", zerr, argv[0]); - return CMDTABRET_FREE; - } - - if (fIclear_port) - { - sIhold.zport = NULL; - sIhold.qport = NULL; - fIclear_port = FALSE; - } - - if (argc > 2) - { - enum tcmdtabret tret; - - if (sIhold.zport != NULL) - { - ulog (LOG_ERROR, - "%s: %s: Ignoring port specification following port name", - zerr, argv[0]); - return CMDTABRET_FREE; - } - tret = tprocess_port_cmd (argc - 1, argv + 1, (pointer) &sIhold.qport, - zerr); - if (sIhold.qport != NULL && sIhold.qport->zname == NULL) - { - char *zname; - - if (sIhold.zname == NULL) - sIhold.qport->zname = "default system file port"; - else - { - zname = (char *) alloca (strlen (sIhold.zname) - + sizeof "system port"); - sprintf (zname, "system %s port", sIhold.zname); - sIhold.qport->zname = xstrdup (zname); - } - } - -#if DEBUG > 1 - if (sIhold.qport != NULL) - DEBUG_MESSAGE2 (DEBUG_CONFIG, - "tiport: Command %s to port %s", argv[1], - sIhold.qport->zname); -#endif - - return tret; - } - else - { - if (sIhold.qport != NULL) - { - ulog (LOG_ERROR, - "%s: %s: Ignoring port name following port specification", - zerr, argv[0]); - return CMDTABRET_FREE; - } - - sIhold.zport = argv[1]; - - return CMDTABRET_CONTINUE; - } -} - -/* Process one of the chat commands. We have a special version for - systems just so that we clear out the chat failure strings. It - would be nice if there were a cleaner way to do this. */ - -static enum tcmdtabret -tichat (argc, argv, pvar, zerr) - int argc; - char **argv; - pointer pvar; - const char *zerr; -{ - if (strcmp (argv[0], "chat-fail") == 0) - { - if (fIclear_chat_fail) - { - sIhold.schat.zfail = NULL; - fIclear_chat_fail = FALSE; - } - } - else if (strcmp (argv[0], "called-chat-fail") == 0) - { - if (fIclear_called_chat_fail) - { - sIhold.scalled_chat.zfail = NULL; - fIclear_called_chat_fail = FALSE; - } - } - - return tprocess_chat_cmd (argc, argv, pvar, zerr); -} - -/* Process the called-login command. */ - -/*ARGSUSED*/ -static enum tcmdtabret -ticalled_login (argc, argv, pvar, zerr) - int argc; - char **argv; - pointer pvar; - const char *zerr; -{ - if (argc < 2) - { - ulog (LOG_ERROR, "%s: %s: Wrong number of arguments", zerr, argv[0]); - return CMDTABRET_FREE; - } - - sIhold.zcalled_login = argv[1]; - - if (argc > 2) - uadd_validate (argv[1], argc - 2, (const char **) argv + 2); - - return CMDTABRET_CONTINUE; -} - -/* Process the protocol parameter command. */ - -/*ARGSUSED*/ -static enum tcmdtabret -tiproto_param (argc, argv, pvar, zerr) - int argc; - char **argv; - pointer pvar; - const char *zerr; -{ - if (fIclear_proto_param) - { - sIhold.cproto_params = 0; - sIhold.qproto_params = NULL; - fIclear_proto_param = FALSE; - } - - return tadd_proto_param (&sIhold.cproto_params, &sIhold.qproto_params, - zerr, argc - 1, argv + 1); -} - -/* Process the request command. */ - -/*ARGSUSED*/ -static enum tcmdtabret -tirequest (argc, argv, pvar, zerr) - int argc; - char **argv; - pointer pvar; - const char *zerr; -{ - char b; - boolean fset; - - b = argv[1][0]; - if (b == 'y' || b == 'Y' || b == 't' || b == 'T') - fset = TRUE; - else if (b == 'n' || b == 'N' || b == 'f' || b == 'F') - fset = FALSE; - else - { - ulog (LOG_ERROR, "%s: %s: %s: Bad boolean", zerr, argv[0], argv[1]); - return CMDTABRET_FREE; - } - - sIhold.fcall_request = fset; - sIhold.fcalled_request = fset; - - return CMDTABRET_FREE; -} - -/* Process the transfer command. */ - -/*ARGSUSED*/ -static enum tcmdtabret -titransfer (argc, argv, pvar, zerr) - int argc; - char **argv; - pointer pvar; - const char *zerr; -{ - char b; - boolean fset; - - b = argv[1][0]; - if (b == 'y' || b == 'Y' || b == 't' || b == 'T') - fset = TRUE; - else if (b == 'n' || b == 'N' || b == 'f' || b == 'F') - fset = FALSE; - else - { - ulog (LOG_ERROR, "%s: %s: %s: Bad boolean", zerr, argv[0], argv[1]); - return CMDTABRET_FREE; - } - - sIhold.fcall_transfer = fset; - sIhold.fcalled_transfer = fset; - - return CMDTABRET_FREE; -} - -/* Mark all the contents of sIhold to be cleared before they are set. - If the falternate argument is TRUE, then only prepare to clear - those contents that should be cleared for an alternate. */ - -static void -uiset_clear (falternate) - boolean falternate; -{ - if (! falternate) - { - fIclear_alias = TRUE; - fIclear_alternate = TRUE; - } - fIclear_time = TRUE; - fIclear_calltimegrade = TRUE; - fIclear_call_local_size = TRUE; - fIclear_call_remote_size = TRUE; - fIclear_called_local_size = TRUE; - fIclear_called_remote_size = TRUE; - fIclear_port = TRUE; - fIclear_chat_fail = TRUE; - fIclear_proto_param = TRUE; - fIclear_called_chat_fail = TRUE; -} - -#endif /* HAVE_TAYLOR_CONFIG */ - -/* Set up the default values advertised in the documentation. */ - -void -uset_system_defaults (qsys) - struct ssysteminfo *qsys; -{ - qsys->zname = NULL; - qsys->zalias = NULL; - qsys->qalternate = NULL; - qsys->zalternate = NULL; - qsys->ztime = xmalloc (1 + sizeof "Never"); - sprintf (qsys->ztime, "%cNever", BGRADE_LOW); - qsys->zcalltimegrade = NULL; - qsys->zcall_local_size = NULL; - qsys->zcall_remote_size = NULL; - qsys->zcalled_local_size = NULL; - qsys->zcalled_remote_size = NULL; - qsys->ibaud = 0L; - qsys->ihighbaud = 0L; - qsys->zport = NULL; - qsys->zphone = NULL; - qsys->qport = NULL; - INIT_CHAT (&qsys->schat); - qsys->schat.zchat = - (char *) "\"\" \\r\\c ogin:-BREAK-ogin:-BREAK-ogin: \\L word: \\P"; - qsys->schat.ctimeout = 10; - qsys->zcall_login = NULL; - qsys->zcall_password = NULL; - qsys->zcalled_login = NULL; - qsys->fcallback = FALSE; - qsys->fsequence = FALSE; - qsys->zprotocols = NULL; - qsys->cproto_params = 0; - qsys->qproto_params = NULL; - INIT_CHAT (&qsys->scalled_chat); -#if DEBUG > 1 - qsys->idebug = 0; - qsys->imax_remote_debug = DEBUG_ABNORMAL | DEBUG_CHAT | DEBUG_HANDSHAKE; -#endif - qsys->fcall_request = TRUE; - qsys->fcalled_request = TRUE; - qsys->fcall_transfer = TRUE; - qsys->fcalled_transfer = TRUE; - qsys->zlocal_send = ZROOTDIR; - qsys->zcalled_local_send = NULL; - qsys->zremote_send = "~"; - qsys->zcalled_remote_send = NULL; - qsys->zlocal_receive = "~"; - qsys->zcalled_local_receive = NULL; - qsys->zremote_receive = "~"; - qsys->zcalled_remote_receive = NULL; - qsys->zpath = CMDPATH; - qsys->zcmds = "rnews rmail"; - qsys->cfree_space = DEFAULT_FREE_SPACE; - qsys->zforwardto = NULL; - qsys->zpubdir = NULL; - qsys->zlocalname = NULL; -} - -/* Variables to store the loaded system information. */ - -static boolean fIhave_systems; -static int cIsystems; -static struct ssysteminfo *pasIsystems; - -/* Read information about all systems. */ - -static void uiread_systems P((void)); - -static void -uiread_systems () -{ - if (fIhave_systems) - return; - - fIhave_systems = TRUE; - -#if HAVE_TAYLOR_CONFIG - if (zSysfile == NULL) - { - boolean fmore; - - /* Only warn about a missing file if we aren't going to read the - V2 or BNU files. */ - fmore = FALSE; -#if HAVE_V2_CONFIG - if (fV2) - fmore = TRUE; -#endif -#if HAVE_BNU_CONFIG - if (fBnu) - fmore = TRUE; -#endif - if (! fmore) - { - ulog (LOG_ERROR, "%s%s: file not found", NEWCONFIGLIB, - SYSFILE); - return; - } - } - else - { - struct smulti_file *qmulti; - int calc; - boolean fdefaults, fsystem; - struct ssysteminfo *qalternates; - - qmulti = qmulti_open (zSysfile); - if (qmulti != NULL) - { - calc = 0; - fdefaults = FALSE; - fsystem = FALSE; - qalternates = NULL; - - fIfirst = FALSE; - zInext_system = NULL; - - while (TRUE) - { - qIalternates = qalternates; - fIdefault_alternates = TRUE; - - /* Read commands. This will exit when it encounters the - start of a file (which it will when we first start - reading) and when it reads a ``system'' command. */ - uprocesscmds ((FILE *) NULL, qmulti, asIcmds, - (const char *) NULL, - CMDFLAG_WARNUNRECOG | CMDFLAG_BACKSLASH); - - /* The handling of alternates can get complex. Before - we start reading a system, fIclear_alternate is set - to TRUE (this is done in uiset_clear). After we have - finished reading a system, then if fIclear_alternate - is still TRUE then no ``alternate'' command was used - and the system information is in sIhold. Otherwise, - if fIclear_alternate is FALSE, an ``alternate'' - command was used and we must call tialternate one - more time; after this final call to tialternate, the - system information will be in sIalternate. - - The final call to tialternate is needed because each - occurrence of the ``alternate'' command links the - previous alternate into sIalternate and sets up - sIhold with the defaults for the next alternate. The - final call will link the last alternate into - sIalternate. */ - - if (fdefaults) - { - /* We were reading default information. Save it. */ - if (fIclear_alternate) - sIdefault = sIhold; - else - { - (void) tialternate (0, (char **) NULL, - (pointer) NULL, "alternate"); - sIdefault = sIalternate; - } - qalternates = sIdefault.qalternate; - sIdefault.qalternate = NULL; - fdefaults = FALSE; - } - else if (fsystem) - { - /* We just either finished a file or encountered a - ``system'' command after we had started reading a - system. Finish up the information for the system - we were reading. */ - if (cIsystems >= calc) - { - calc += 10; - pasIsystems = - ((struct ssysteminfo *) - xrealloc ((pointer) pasIsystems, - calc * sizeof (struct ssysteminfo))); - } - - /* We must now attach any remaining default - alternates. */ - if (fIdefault_alternates) - { - while (qIalternates != NULL) - (void) tialternate (0, (char **) NULL, - (pointer) NULL, "alternate"); - } - - if (fIclear_alternate) - pasIsystems[cIsystems] = sIhold; - else - { - (void) tialternate (0, (char **) NULL, - (pointer) NULL, "alternate"); - pasIsystems[cIsystems] = sIalternate; - } - - ++cIsystems; - - fsystem = FALSE; - } - - if (fIfirst) - { - /* We just started reading a new file. Reset the - default information. The next time around the - loop we will read the default information. */ - uset_system_defaults (&sIhold); - uiset_clear (FALSE); - qalternates = NULL; - fdefaults = TRUE; - fIfirst = FALSE; - } - else if (zInext_system != NULL) - { - /* We just encountered a ``system'' command. Save - the name, reset the system information to the - defaults, and go on to read the system - information. */ - sIhold = sIdefault; - sIhold.zname = zInext_system; - uiset_clear (FALSE); - fsystem = TRUE; - zInext_system = NULL; - } - else - { - /* We have reached the end of the files to read. */ - break; - } - } - - (void) fmulti_close (qmulti); - } - } -#endif /* HAVE_TAYLOR_CONFIG */ - -#if HAVE_V2_CONFIG - if (fV2) - { - int cv2; - struct ssysteminfo *pasv2; - - uv2_read_systems (&cv2, &pasv2); - if (cv2 > 0) - { - pasIsystems = - ((struct ssysteminfo *) - xrealloc ((pointer) pasIsystems, - (cIsystems + cv2) * sizeof (struct ssysteminfo))); - memcpy (pasIsystems + cIsystems, pasv2, - cv2 * sizeof (struct ssysteminfo)); - cIsystems += cv2; - } - } -#endif /* HAVE_V2_CONFIG */ - -#if HAVE_BNU_CONFIG - if (fBnu) - { - int cbnu; - struct ssysteminfo *pasbnu; - - ubnu_read_systems (&cbnu, &pasbnu); - if (cbnu > 0) - { - pasIsystems = - ((struct ssysteminfo *) - xrealloc ((pointer) pasIsystems, - (cIsystems + cbnu) * sizeof (struct ssysteminfo))); - memcpy (pasIsystems + cIsystems, pasbnu, - cbnu * sizeof (struct ssysteminfo)); - cIsystems += cbnu; - } - } -#endif /* HAVE_BNU_CONFIG */ -} - -/* Get information about all systems. */ - -void -uread_all_system_info (pc, ppas) - int *pc; - struct ssysteminfo **ppas; -{ - if (! fIhave_systems) - uiread_systems (); - - *pc = cIsystems; - *ppas = pasIsystems; -} - -/* Get information about a specific system. */ - -boolean -fread_system_info (zsystem, qsys) - const char *zsystem; - struct ssysteminfo *qsys; -{ - int i; - - DEBUG_MESSAGE1 (DEBUG_CONFIG, - "fread_system_info: Reading information for system %s", - zsystem); - - if (! fIhave_systems) - uiread_systems (); - - for (i = 0; i < cIsystems; i++) - { - char *z; - - if (strcmp (zsystem, pasIsystems[i].zname) == 0) - { - *qsys = pasIsystems[i]; - - DEBUG_MESSAGE1 (DEBUG_CONFIG, - "fread_system_info: Got information for system %s", - qsys->zname); - - return TRUE; - } - - z = pasIsystems[i].zalias; - if (z == NULL) - continue; - while (TRUE) - { - char *znext; - - znext = z + strcspn (z, " "); - if (strncmp (zsystem, z, znext - z) == 0) - { - *qsys = pasIsystems[i]; - - DEBUG_MESSAGE1 (DEBUG_CONFIG, - "fread_system_info: Got system %s", - qsys->zname); - - return TRUE; - } - z = znext; - if (*z == ' ') - ++z; - else - break; - } - } - - DEBUG_MESSAGE1 (DEBUG_CONFIG, - "fread_system_info: Could not find system %s", - zsystem); - - return FALSE; -} - -/* Prepare to read commands defining unknown systems. */ - -void -uiunknown_start () -{ -#if HAVE_TAYLOR_CONFIG - uset_system_defaults (&sIhold); - uiset_clear (FALSE); -#else /* ! HAVE_TAYLOR_CONFIG */ - uset_system_defaults (&sUnknown); -#endif /* ! HAVE_TAYLOR_CONFIG */ -} - -#if HAVE_TAYLOR_CONFIG - -/* Process a command defining unknown systems. This is actually - called from the main configuration file, not the system file. */ - -enum tcmdtabret -tiunknown (argc, argv, pvar, zerr) - int argc; - char **argv; - pointer pvar; - const char *zerr; -{ - fUnknown_ok = TRUE; - return tprocess_one_cmd (argc - 1, argv + 1, asIcmds, zerr, - CMDFLAG_WARNUNRECOG); -} - -#endif /* HAVE_TAYLOR_CONFIG */ - -/* Finish up after all commands defining unknwon systems. */ - -void -uiunknown_end () -{ -#if HAVE_TAYLOR_CONFIG - if (fUnknown_ok) - { - /* Add the final alternate. */ - if (fIclear_alternate) - sUnknown = sIhold; - else - { - (void) tialternate (0, (char **) NULL, (pointer) NULL, "alternate"); - sUnknown = sIalternate; - } - } -#endif /* HAVE_TAYLOR_CONFIG */ -} - -/* Initialize the local system information. Perhaps it would be - desirable to allow the user to customize this as well. This is - called after the configuration file has been read in and the system - name has been determined. Only a few elements of this structure - are ever actually used, probably just zname and zremote_receive. */ - -void -uisetup_localsys () -{ - uset_system_defaults (&sLocalsys); - sLocalsys.zname = zLocalname; -} - -/* Translate a system name into something we can use locally. This should - be more intelligent than it is. Right now we just truncate the name; - if this matches the name of another system, we reject the call. */ - -const char * -ztranslate_system (zsystem) - const char *zsystem; -{ - char *z; - struct ssysteminfo s; - - if (strlen (zsystem) <= cSysdep_max_name_len) - return zsystem; - z = (char *) xmalloc (cSysdep_max_name_len + 1); - strncpy (z, zsystem, cSysdep_max_name_len); - z[cSysdep_max_name_len] = '\0'; - if (fread_system_info (z, &s)) - { - xfree ((pointer) z); - return NULL; - } - return z; -} - -#if HAVE_TAYLOR_CONFIG - -/* Get the login name and password for a system out of the call file. - The call file is simple a sequence of lines. The first word on - each line is the system name, the second word is the login name, - and the third word is the password. We read it using uprocesscmds, - since it's easy. */ - -struct silogpass -{ - char **pzlog; - char **pzpass; -}; - -static enum tcmdtabret tilog_pass P((int argc, char **argv, pointer pvar, - const char *zerr)); - -/*ARGSUSED*/ -static enum tcmdtabret -tilog_pass (argc, argv, pvar, zerr) - int argc; - char **argv; - pointer pvar; - const char *zerr; -{ - struct silogpass *q = (struct silogpass *) pvar; - - *q->pzlog = xstrdup (argv[1]); - *q->pzpass = xstrdup (argv[2]); - return CMDTABRET_FREE_AND_EXIT; -} - -#endif /* HAVE_TAYLOR_CONFIG */ - -/* Get the login name and password to use for a system. */ - -boolean -fcallout_login (qsys, pzlog, pzpass) - const struct ssysteminfo *qsys; - char **pzlog; - char **pzpass; -{ - *pzlog = NULL; - *pzpass = NULL; - -#if HAVE_TAYLOR_CONFIG - { - struct smulti_file *qmulti; - struct scmdtab as[2]; - struct silogpass s; - - qmulti = qmulti_open (zCallfile); - if (qmulti == NULL) - return FALSE; - - s.pzlog = pzlog; - s.pzpass = pzpass; - - as[0].zcmd = qsys->zname; - as[0].itype = CMDTABTYPE_FN | 3; - as[0].pvar = (pointer)&s; - as[0].ptfn = tilog_pass; - - as[1].zcmd = NULL; - - uprocesscmds ((FILE *) NULL, qmulti, as, (const char *) NULL, - CMDFLAG_BACKSLASH); - - (void) fmulti_close (qmulti); - } -#endif /* HAVE_TAYLOR_CONFIG */ - - if (*pzlog == NULL) - { - ulog (LOG_ERROR, "No call out login for system %s", qsys->zname); - return FALSE; - } - - return TRUE; -} - -#if HAVE_TAYLOR_CONFIG - -/* Check whether a login name and password gathered by the UUCP program - itself are correct. */ - -static enum tcmdtabret ticheck_login P((int argc, char **argv, - pointer pvar, const char *zerr)); - -/*ARGSUSED*/ -static enum tcmdtabret -ticheck_login (argc, argv, pvar, zerr) - int argc; - char **argv; - pointer pvar; - const char *zerr; -{ - char **pz = (char **) pvar; - - *pz = xstrdup (argv[1]); - return CMDTABRET_FREE_AND_EXIT; -} - -#endif /* HAVE_TAYLOR_CONFIG */ - -boolean -fcheck_login (zuser, zpass) - const char *zuser; - const char *zpass; -{ -#if HAVE_TAYLOR_CONFIG - struct smulti_file *qmulti; - struct scmdtab as[2]; - char *zfilepass; - boolean fok; - - if (zPwdfile == NULL) - { - ulog (LOG_ERROR, "%s%s: file not found", NEWCONFIGLIB, - PASSWDFILE); - return FALSE; - } - - qmulti = qmulti_open (zPwdfile); - if (qmulti == NULL) - return FALSE; - - zfilepass = NULL; - - as[0].zcmd = zuser; - as[0].itype = CMDTABTYPE_FN | 2; - as[0].pvar = (pointer)&zfilepass; - as[0].ptfn = ticheck_login; - - as[1].zcmd = NULL; - - uprocesscmds ((FILE *) NULL, qmulti, as, (const char *) NULL, - CMDFLAG_CASESIGNIFICANT | CMDFLAG_BACKSLASH); - - (void) fmulti_close (qmulti); - - fok = zfilepass != NULL && strcmp (zfilepass, zpass) == 0; - - if (zfilepass != NULL) - { - bzero (zfilepass, strlen (zfilepass)); - xfree ((pointer) zfilepass); - } - - if (! fok) - ulog (LOG_ERROR, "Bad login"); - - return fok; - -#else /* HAVE_TAYLOR_CONFIG */ - - ulog (LOG_ERROR, "Not compiled to accept logins"); - return FALSE; - -#endif /* HAVE_TAYLOR_CONFIG */ -} - -#if HAVE_TAYLOR_CONFIG - -/* Process a chat command. These are done as prefix commands. We set - it up such that argv[0] will contain the string "chat" and we must - look after that point to see what command to execute. */ - -static struct schat_info sChat; - -static enum tcmdtabret tcchat_fail P((int argc, char **argv, - pointer pvar, - const char *zerr)); - -static const struct scmdtab asChatcmds[] = -{ - { "chat", CMDTABTYPE_FULLSTRING, (pointer) &sChat.zchat, NULL }, - { "chat-program", CMDTABTYPE_FULLSTRING, (pointer) &sChat.zprogram, - NULL }, - { "chat-timeout", CMDTABTYPE_INT, (pointer) &sChat.ctimeout, NULL }, - { "chat-fail", CMDTABTYPE_FN | 2, NULL, tcchat_fail }, - { "chat-seven-bit", CMDTABTYPE_BOOLEAN, (pointer) &sChat.fstrip, NULL }, - { NULL, 0, NULL, NULL } -}; - -enum tcmdtabret -tprocess_chat_cmd (argc, argv, pvar, zerr) - int argc; - char **argv; - pointer pvar; - const char *zerr; -{ - struct schat_info *qchat = (struct schat_info *) pvar; - char *zchat; - enum tcmdtabret t; - - zchat = strstr (argv[0], "chat"); - -#if DEBUG > 0 - if (zchat == NULL) - ulog (LOG_FATAL, "tprocess_chat_cmd: Can't happen"); -#endif - - argv[0] = zchat; - - sChat = *qchat; - t = tprocess_one_cmd (argc, argv, asChatcmds, zerr, - CMDFLAG_WARNUNRECOG); - *qchat = sChat; - - return t; -} - -/* Add a new chat failure string. */ - -static enum tcmdtabret -tcchat_fail (argc, argv, pvar, zerr) - int argc; - char **argv; - pointer pvar; - const char *zerr; -{ - uadd_string (&sChat.zfail, argv[1], ' '); - return CMDTABRET_FREE; -} - -#endif /* HAVE_TAYLOR_CONFIG */ - -#if HAVE_TAYLOR_CONFIG - -/* Add a protocol parameter entry. The pc parameter points to the - number of protocol parameter entries, and the pq parameter points - to the array of protocol parameters. */ - -enum tcmdtabret -tadd_proto_param (pc, pq, zerr, cargs, azargs) - int *pc; - struct sproto_param **pq; - const char *zerr; - int cargs; - char **azargs; -{ - int i; - struct sproto_param *q; - int ientry; - int icopy; - - if (cargs < 1) - { - ulog (LOG_ERROR, "%s: protocol-parameter: Not enough arguments", zerr); - return CMDTABRET_FREE; - } - if (azargs[0][1] != '\0') - { - ulog (LOG_ERROR, - "%s: protocol-parameter: Protocol names are single characters", - zerr); - return CMDTABRET_FREE; - } - - q = NULL; - ientry = 0; - - for (i = 0; i < *pc; i++) - { - if ((*pq)[i].bproto == azargs[0][0]) - { - q = &(*pq)[i]; - ientry = q->centries; - ++q->centries; - q->qentries = - ((struct sproto_param_entry *) - xrealloc ((pointer) q->qentries, - (q->centries * sizeof (struct sproto_param_entry)))); - break; - } - } - - if (i >= *pc) - { - ++(*pc); - *pq = ((struct sproto_param *) - xrealloc ((pointer) *pq, - (*pc * sizeof (struct sproto_param)))); - q = &(*pq)[*pc - 1]; - q->bproto = azargs[0][0]; - q->centries = 1; - q->qentries = ((struct sproto_param_entry *) - xmalloc (sizeof (struct sproto_param_entry))); - ientry = 0; - } - - q->qentries[ientry].cargs = cargs - 1; - q->qentries[ientry].azargs = - (char **) xmalloc ((cargs - 1) * sizeof (char *)); - for (icopy = 0; icopy < cargs - 1; icopy++) - q->qentries[ientry].azargs[icopy] = azargs[icopy + 1]; - - return CMDTABRET_CONTINUE; -} - -#endif /* HAVE_TAYLOR_CONFIG */ - -/* Apply some protocol parameters, given the current protocol. */ - -void -uapply_proto_params (bproto, qcmds, c, pas) - int bproto; - struct scmdtab *qcmds; - int c; - struct sproto_param *pas; -{ - int i; - struct sproto_param *q; - - for (i = 0, q = pas; - i < c; - i++, q++) - { - if (q->bproto == (char) bproto) - { - char ab[sizeof "g protocol parameters"]; - struct sproto_param_entry *qentry; - int ientry; - - sprintf (ab, "%c protocol parameters", bproto); - q = &pas[i]; - for (ientry = 0, qentry = &q->qentries[0]; - ientry < q->centries; - ientry++, qentry++) - (void) tprocess_one_cmd (qentry->cargs, qentry->azargs, - qcmds, ab, CMDFLAG_WARNUNRECOG); - return; - } - } -} - -/* Maintain a list of systems which are permitted to log in using a - particular login name. This is the VALIDATE entry from the BNU - Permissions file. */ - -static struct svalidate -{ - struct svalidate *qnext; - const char *zlogname; - int cmachines; - const char *azmachines[1]; -} *qIvalidate; - -/* Add an entry to the validation list. This assumes that it does not - have to copy the login name or the machine names. It does copy the - array of machines names. */ - -void -uadd_validate (zlogname, cmachines, pazmachines) - const char *zlogname; - int cmachines; - const char **pazmachines; -{ - struct svalidate **pq, *q; - - for (pq = &qIvalidate; *pq != NULL; pq = &(*pq)->qnext) - { - if (strcmp ((*pq)->zlogname, zlogname) == 0) - { - *pq = ((struct svalidate *) - xrealloc ((pointer) *pq, - sizeof (struct svalidate) - + (((*pq)->cmachines + cmachines - 1) - * sizeof (const char *)))); - memcpy ((*pq)->azmachines + (*pq)->cmachines, pazmachines, - cmachines * sizeof (const char *)); - (*pq)->cmachines += cmachines; - return; - } - } - - q = (struct svalidate *) xmalloc (sizeof (struct svalidate) - + ((cmachines - 1) - * sizeof (const char *))); - q->qnext = qIvalidate; - q->zlogname = zlogname; - memcpy (q->azmachines, pazmachines, - cmachines * sizeof (const char *)); - q->cmachines = cmachines; - qIvalidate = q; -} - -/* Check whether a particular login name/machine name is valid. */ - -boolean -fcheck_validate (zlogname, zmachine) - const char *zlogname; - const char *zmachine; -{ - struct svalidate *q; - - for (q = qIvalidate; q != NULL; q = q->qnext) - { - if (strcmp (q->zlogname, zlogname) == 0) - { - int i; - - for (i = 0; i < q->cmachines; i++) - if (strcmp (q->azmachines[i], zmachine) == 0) - return TRUE; - - return FALSE; - } - } - - return TRUE; -} - -/* The variables which hold the array of timetables. */ - -int cTtable; -struct stimetable *pasTtable; - -/* Initialize the table of timetables as advertised in the - documentation. */ - -void -uinittimetables () -{ - pasTtable = (struct stimetable *) xmalloc (3 * sizeof (struct stimetable)); - pasTtable[0].zname = "Evening"; - pasTtable[0].ztime = "Wk1705-0755,Sa,Su"; - pasTtable[1].zname = "Night"; - pasTtable[1].ztime = "Wk2305-0755,Sa,Su2305-1655"; - pasTtable[2].zname = "NonPeak"; - pasTtable[2].ztime = "Wk1805-0655,Sa,Su"; - cTtable = 3; -} - -/* Add a new timetable entry. This assumes it can take control of the - strings it is passed, so they must not be on the stack and if they - have been allocated they must not be freed. */ - -void -uaddtimetable (zname, ztime) - const char *zname; - const char *ztime; -{ - if (pasTtable == NULL) - uinittimetables (); - - pasTtable = ((struct stimetable *) - xrealloc ((pointer) pasTtable, - (cTtable + 1) * sizeof (struct stimetable))); - pasTtable[cTtable].zname = zname; - pasTtable[cTtable].ztime = ztime; - ++cTtable; -} diff --git a/gnu/libexec/uucp/system.h b/gnu/libexec/uucp/system.h deleted file mode 100644 index ccc5ae2c014..00000000000 --- a/gnu/libexec/uucp/system.h +++ /dev/null @@ -1,668 +0,0 @@ -/* 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 AIRS, P.O. Box 520, Waltham, MA 02254. - - $Id: system.h,v 1.2 1993/08/02 17:25:13 mycroft Exp $ -*/ - -#ifndef SYSTEM_H - -#define SYSTEM_H - -/* Any function which returns an error should also report an error - message. - - Many of the function may share a common static buffer; this is - noted in the description of the function. */ - -/* The maximum length of a remote system name. */ -extern int cSysdep_max_name_len; - -/* Initialize. If something goes wrong, this routine should just - exit. The fdaemon argument is TRUE if called from uucico or uuxqt. - The fgetcwd argument is TRUE if the current working directory is - needed. 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, 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. */ -extern void usysdep_initialize P((boolean fdaemon, boolean fgetcwd)); - -/* 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, the - 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 - file. This is called before the usysdep_initialize function is - called. It should return NULL on error. The return value should - point to a static buffer. */ -extern const char *zsysdep_local_name 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 4.3 BSD 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. */ -extern boolean fsysdep_catch P((void)); - -/* Start catching a signal. This is called after fsysdep_catch to - tell the signal handler to go ahead and do the longjmp. */ -extern void usysdep_start_catch P((void)); - -/* Stop catching a signal. This is called when it is no longer - necessary for fsysdep_catch to handle signals. */ -extern void usysdep_end_catch P((void)); - -/* 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 print 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. */ -extern const char *zsysdep_port_name P((boolean *pftcp_port)); - -/* Make a spool directory for a system. This will be called each time - the system might be accessed. It should return FALSE on error. */ -extern boolean fsysdep_make_spool_dir P((const struct ssysteminfo *qsys)); - -/* 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. The qsys - argument should be used to expand ~ into the public directory. */ -extern boolean fsysdep_in_directory P((const struct ssysteminfo *qsys, - 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)); - -/* Exit the current program and start a new one. If the ffork - argument is TRUE, the new program should be started up and the - current program should continue (but in all current cases, it will - immediately exit anyhow); if the ffork argument is FALSE, the new - program should replace the current program. 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((boolean ffork, 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 calls - to the program, 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 isysdep_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 isysdep_process_time P((long *pimicros)); - -/* Parse the value returned by isysdep_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 isysdep_time. The - typedef is a hack to avoid the problem of mentioning a structure - for the first time in a prototype while remaining compatible with - standard C. The type tm_ptr is never again referred to. */ -typedef struct tm *tm_ptr; -extern void usysdep_localtime P((long itime, tm_ptr q)); - -/* Sleep for a number of seconds. */ -extern void usysdep_sleep P((int cseconds)); - -/* Pause for half a second. */ -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 ssysteminfo *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 ssysteminfo *qsys)); - -/* Get the conversation sequence number for a remote system, and - increment it for next time. This should return -1 on error. */ -extern long isysdep_get_sequence P((const struct ssysteminfo *qsys)); - -/* Get the status of a remote system. This should return FALSE on - error. Otherwise it should set *qret to the status. */ -extern boolean fsysdep_get_status P((const struct ssysteminfo *qsys, - struct sstatus *qret)); - -/* 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 ssysteminfo *qsys, - const struct sstatus *qset)); - -/* Check whether there is work for a remote system. This should set - *pbgrade to the highest grade of work waiting to execute. 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 ssysteminfo *qsys, - char *pbgrade)); - -/* 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'). It should - return FALSE on error. */ -extern boolean fsysdep_get_work_init P((const struct ssysteminfo *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. */ -extern boolean fsysdep_get_work P((const struct ssysteminfo *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 ssysteminfo *qsys)); - -/* Get the real file name for a file. The file may or may not exist - on the system. If the zname argument is not NULL, then the zfile - argument may be a directory; if it is, zname should be used for the - name of the file within the directory. The zname argument may not - be simple (it may be in the format of another OS) so care should be - taken with it. On Unix, if the zfile argument begins with ~user/ - it goes in that users home directory, and if it begins with ~/ - (~uucp/) it goes in the public directory (note that each system may - have its own public directory); similar conventions may be - desirable on other systems. The return value may point to a common - static buffer. This should return NULL on error. */ -extern const char *zsysdep_real_file_name P((const struct ssysteminfo *, - const char *zfile, - const char *zname)); - -/* Get a file name from the spool directory. This should return - NULL on error. The return value may point to a common static - buffer. */ -extern const char *zsysdep_spool_file_name P((const struct ssysteminfo *, - const char *zfile)); - -/* 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, and the file - is kept private to the UUCP system. 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 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. The function - should set *pimode to the mode that should be sent over (this - should be a UNIX style file mode number). It should set *pcbytes - to the number of bytes contained in the file. If an error occurs, - it should return EFILECLOSED and, if pfgone is not NULL, it should - *pfgone to TRUE if the file no longer exists or FALSE if there was - some other error. */ -extern openfile_t esysdep_open_send P((const struct ssysteminfo *qsys, - const char *zname, - boolean fcheck, - const char *zuser, - unsigned int *pimode, - long *pcbytes, - boolean *pfgone)); - -/* Open a file to receive from another system. Receiving a file is - done in two steps. First esysdep_open_receive is called. This - should open a temporary file and return the file name in *pztemp. - It may ignore qsys (the system the file is coming from) and zto - (the file to be created) although they are passed in case they are - useful. The file mode is not available at this point. The *pztemp - return value may point to a common static buffer. The amount of - free space should be returned in *pcbytes; ideally it should be the - lesser of the amount of free space on the file system of the - temporary file and the amount of free space on the file system of - the final destination. If the amount of free space is not - available, *pcbytes 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 ssysteminfo *qsys, - const char *zto, - const char **pztemp, - long *pcbytes)); - -/* Move a file. This is used to move a received file to its final - location. It is also used by uuxqt to move files in and out of the - execute directory. The zto argument is the file to create. The - zorig argument is the name of the file to move. The imode argument - is the Unix file mode to use for the final file; if it is zero, it - should be ignored and the file should be kept private to the UUCP - system. 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, - unsigned int imode, boolean fcheck, - const char *zuser)); - -/* 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)); - -/* Start expanding a wildcarded file name. This should return FALSE - on error; otherwise subsequent calls to zsysdep_wildcard should - return file names. The argument may have leading ~ characters. */ -extern boolean fsysdep_wildcard_start P((const struct ssysteminfo *qsys, - const char *zfile)); - -/* Get the next wildcard name. This should return NULL when there are - no more names to return. The return value may point to a common - static buffer. The argument should be the same as that to - fsysdep_wildcard_start. There is no way to return error. */ -extern const char *zsysdep_wildcard P((const struct ssysteminfo *qsys, - 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 const char *zsysdep_spool_commands P((const struct ssysteminfo *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. A file which will become an execute file will use a grade - of 'X' (actually this is just convention, but it affects where the - file will be placed in the spool directory on Unix). 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. This should return NULL on error. The return - value may point to a common static buffer. */ - -#define CFILE_NAME_LEN (15) - -extern const char *zsysdep_data_file_name P((const struct ssysteminfo *qsys, - int bgrade, 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. It should return NULL on error. - The return value may point to a common static buffer. */ -extern const 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. */ -extern const char *zsysdep_get_xqt P((const 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. Otherwise, the return value may point to a common - static buffer. */ -extern const char *zsysdep_find_command P((const char *zcmd, - const char *zcmds, - const char *zpath, - boolean *pferr)); - -#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 ssysteminfo *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 - 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. */ -extern boolean fsysdep_execute P((const struct ssysteminfo *qsys, - const char *zuser, - const char **pazargs, - const char *zfullcmd, - const char *zinput, - const char *zoutput, - boolean fshell, - const char **pzerror, - boolean *pftemp)); - -/* Lock a particular uuxqt command (e.g. rmail). This should return - FALSE if the command is already locked. This is used to make sure - only one uuxqt process is handling a particular command. There is - no way to return error. */ - -/* Lock for uuxqt execution. If the global variable cMaxuuxqts 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 nonegative number which will be passed to - fsysdep_unlock_uuxqt, or -1 on error. */ -extern int isysdep_lock_uuxqt P((const char *zcmd)); - -/* Unlock a uuxqt process. This is passed the return value of - isysdep_lock_uuxqt, as well as the zcmd argument passed to - isysdep_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)); - -/* See whether a particular uuxqt command is locked. This should - return TRUE if the command is locked (because isysdep_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. This should return FALSE if the - directory is already locked. There is no way to return error. */ -extern boolean fsysdep_lock_uuxqt_dir P((void)); - -/* Remove all files in the execution directory, and unlock it. This - should return FALSE on error. */ -extern boolean fsysdep_unlock_uuxqt_dir P((void)); - -/* Add the working directory to a file name. If the file already has - a directory, it should not be changed. The return value may point - to a common static buffer. If the flocal argument is TRUE, then - this is a local file (so, for example, a leading ~ should be - expanded as appropriate); otherwise the file is on a remote system. - This should return NULL on error. */ -extern const char *zsysdep_add_cwd P((const char *zfile, - boolean flocal)); - -/* See whether a file name will need the current working directory - when 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 const char *zsysdep_base_name P((const char *zfile)); - -/* Return a filename within a directory. The zdir argument may name a - file, in which case it should be returned. If it names a - directory, this function should get the filename from the zfile - argument and return that filename within the directory. */ -extern const 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 isysdep_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)); - -/* 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. The - return value may point to a common statis buffer. */ -extern const char *zsysdep_jobid P((const struct ssysteminfo *qsys, - pointer pseq)); - -/* 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((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 uuclean or similar programs that check the creation - time. This should affect the return value of isysdep_work_time. - On error it should log an error message and return FALSE. */ -extern boolean fsysdep_rejuvenate_job P((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 isysdep_time. */ -extern long isysdep_work_time P((const struct ssysteminfo *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 isysdep_time. */ -extern long isysdep_file_time P((const char *zfile)); - -/* Get the size in bytes of a file. There is no way to indicate - error. This is only used by uustat. */ -extern long csysdep_size 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 const 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)); - -#endif /* ! defined (SYSTEM_H) */ diff --git a/gnu/libexec/uucp/tcp.c b/gnu/libexec/uucp/tcp.c deleted file mode 100644 index ea1a7eb4b34..00000000000 --- a/gnu/libexec/uucp/tcp.c +++ /dev/null @@ -1,363 +0,0 @@ -/* 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 AIRS, P.O. Box 520, Waltham, MA 02254. - - $Log: tcp.c,v $ - Revision 1.1.1.1 1993/03/21 09:45:37 cgd - initial import of 386bsd-0.1 sources - - Revision 1.16 1992/03/30 15:37:22 ian - Petri Helenius: TCP server never started uuxqt - - Revision 1.15 1992/03/17 02:44:08 ian - Declare _exit - - Revision 1.14 1992/03/17 00:34:10 ian - Cast argument to bzero - - Revision 1.13 1992/03/15 04:51:17 ian - Keep an array of signals we've received rather than a single variable - - Revision 1.12 1992/03/15 01:54:46 ian - All execs are now done in isspawn, all waits are done in iswait - - Revision 1.11 1992/03/12 19:56:10 ian - Debugging based on types rather than number - - Revision 1.10 1992/03/11 02:09:57 ian - Franc,ois Pinard: retry fork several times before giving up - - Revision 1.9 1992/03/10 22:57:03 ian - Petri Helenius: have server fork twice to avoid zombies - - Revision 1.8 1992/02/08 03:54:18 ian - Include <string.h> only in <uucp.h>, added 1992 copyright - - Revision 1.7 1991/12/28 03:49:23 ian - Added HAVE_MEMFNS and HAVE_BFNS; changed uses of memset to bzero - - Revision 1.6 1991/12/26 22:54:32 ian - Monty Solomon: cast arguments to avoid prototype errors - - Revision 1.5 1991/12/22 22:14:19 ian - Monty Solomon: added HAVE_UNISTD_H configuration parameter - - Revision 1.4 1991/12/10 19:45:05 ian - Added ulog_device to record device name for log file - - Revision 1.3 1991/11/24 20:06:08 ian - Michael Haberler: itcp_port_number of a number wasn't calling htons - - Revision 1.2 1991/11/14 03:20:13 ian - Added seven-bit and reliable commands to help when selecting protocols - - Revision 1.1 1991/11/13 20:38:00 ian - Initial revision - - */ - -#include "uucp.h" - -#if USE_RCS_ID -char tcp_rcsid[] = "$Id: tcp.c,v 1.1.1.1 1993/03/21 09:45:37 cgd Exp $"; -#endif - -#if HAVE_TCP - -#include <errno.h> - -#if USE_STDIO && HAVE_UNISTD_H -#include <unistd.h> -#endif - -#include <sys/types.h> -#include <sys/socket.h> -#include <netdb.h> -#include <netinet/in.h> - -#include "sysdep.h" -#include "port.h" -#include "system.h" - -/* External functions. */ -extern int close (); -extern int socket (), bind (), listen (), accept (), connect (); -extern void _exit (); - -/* This code handles TCP connections by providing a set of routines - that are called by the port routines. It assumes a Berkeley socket - interface. */ - -/* The normal "uucp" port number. */ -#define IUUCP_PORT (540) - -/* Local function to get the port number from a name. */ -static int itcp_port_number P((const char *zport)); - -/* Lock a port. There is no need to lock a TCP port. */ - -boolean -ftcp_lock (qport, fin) - struct sport *qport; - boolean fin; -{ - return TRUE; -} - -/* Open a port. If the fwait argument is TRUE, we are running as a - server. Otherwise we are just trying to reach another system. */ - -boolean -ftcp_open (qport, ibaud, fwait) - struct sport *qport; - long ibaud; - boolean fwait; -{ - struct sockaddr_in s; - - ulog_device ("TCP"); - - qport->u.stcp.o = socket (AF_INET, SOCK_STREAM, 0); - if (qport->u.stcp.o == -1) - { - ulog (LOG_ERROR, "socket: %s", strerror (errno)); - 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; - s.sin_port = itcp_port_number (qport->u.stcp.zport); - s.sin_addr.s_addr = htonl (INADDR_ANY); - - if (bind (qport->u.stcp.o, (struct sockaddr *) &s, sizeof s) == -1) - { - ulog (LOG_ERROR, "bind: %s", strerror (errno)); - usysdep_exit (FALSE); - } - if (listen (qport->u.stcp.o, 5) == -1) - { - ulog (LOG_ERROR, "listen: %s", strerror (errno)); - usysdep_exit (FALSE); - } - - while (! FGOT_SIGNAL ()) - { - int clen; - int onew; - pid_t ipid; - - DEBUG_MESSAGE0 (DEBUG_PORT, - "ftcp_open: Waiting for connections"); - - clen = sizeof s; - onew = accept (qport->u.stcp.o, (struct sockaddr *) &s, &clen); - if (onew == -1) - { - ulog (LOG_ERROR, "accept: %s", strerror (errno)); - usysdep_exit (FALSE); - } - - DEBUG_MESSAGE0 (DEBUG_PORT, - "ftcp_open: Got connection; forking"); - - ipid = isfork (); - if (ipid < 0) - { - ulog (LOG_ERROR, "fork: %s", strerror (errno)); - usysdep_exit (FALSE); - } - if (ipid == 0) - { - (void) close (qport->u.stcp.o); - qport->u.stcp.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 = isfork (); - if (ipid < 0) - { - ulog (LOG_ERROR, "fork: %s", strerror (errno)); - _exit (EXIT_FAILURE); - } - - if (ipid != 0) - _exit (EXIT_SUCCESS); - - return TRUE; - } - - (void) close (onew); - - /* Now wait for the child. */ - (void) iswait ((unsigned long) ipid, (const char *) NULL); - } - - /* We got a signal. */ - usysdep_exit (FALSE); - - /* Avoid compiler warnings. */ - return FALSE; -} - -/* Close the port. */ - -boolean -ftcp_close (qport, fsuccess) - struct sport *qport; - boolean fsuccess; -{ - if (close (qport->u.stcp.o) == -1) - { - ulog (LOG_ERROR, "close: %s", strerror (errno)); - return FALSE; - } - return TRUE; -} - -/* 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. */ - -boolean -ftcp_reset (qport) - struct sport *qport; -{ - afSignal[INDEXSIG_SIGINT] = TRUE; - return TRUE; -} - -/* Dial out on a TCP port, so to speak: connect to a remote computer. */ - -boolean -ftcp_dial (qport, qsys, pcproto_params, pqproto_params, pireliable) - struct sport *qport; - const struct ssysteminfo *qsys; - int *pcproto_params; - struct sproto_param **pqproto_params; - int *pireliable; -{ - const char *zhost; - struct sockaddr_in s; - struct hostent *q; - - /* There are no dialer protocol parameters, but a TCP connection is - fully reliable. */ - *pcproto_params = 0; - *pqproto_params = NULL; - *pireliable = (RELIABLE_SPECIFIED | RELIABLE_ENDTOEND - | RELIABLE_RELIABLE | RELIABLE_EIGHT); - - zhost = qsys->zphone; - if (zhost == NULL) - zhost = qsys->zname; - - /* Cast argument to avoid prototype error on NeXT. */ - q = gethostbyname ((char *) zhost); - if (q == NULL) - { - ulog (LOG_ERROR, "gethostbyname (%s): %s", zhost, strerror (errno)); - return FALSE; - } - - s.sin_family = q->h_addrtype; - s.sin_port = itcp_port_number (qport->u.stcp.zport); - memcpy (&s.sin_addr.s_addr, q->h_addr, q->h_length); - - if (connect (qport->u.stcp.o, (struct sockaddr *) &s, sizeof s) == -1) - { - ulog (LOG_ERROR, "connect: %s", strerror (errno)); - return FALSE; - } - - return TRUE; -} - -/* Return the baud rate. */ - -long -itcp_baud (qport) - struct sport *qport; -{ - return 0; -} - -/* 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 (zname, &zend, 10); - if (i != 0 && *zend == '\0') - return htons (i); - - /* Cast arguments to avoid prototype errors on NeXT. */ - 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/time.c b/gnu/libexec/uucp/time.c deleted file mode 100644 index 7ff051203e1..00000000000 --- a/gnu/libexec/uucp/time.c +++ /dev/null @@ -1,705 +0,0 @@ -/* time.c - Routines to deal with UUCP time strings. - - 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 AIRS, P.O. Box 520, Waltham, MA 02254. - - $Log: time.c,v $ - Revision 1.1.1.1 1993/03/21 09:45:37 cgd - initial import of 386bsd-0.1 sources - - Revision 1.12 1992/03/17 00:32:40 ian - Cast argument to qttime_parse - - Revision 1.11 1992/03/09 05:08:16 ian - Added status for wrong time to call, not used if system can't be called - - Revision 1.10 1992/03/08 01:52:34 ian - Removed extraneous semicolons - - Revision 1.9 1992/03/07 02:56:30 ian - Rewrote time routines - - Revision 1.8 1992/02/08 03:54:18 ian - Include <string.h> only in <uucp.h>, added 1992 copyright - - Revision 1.7 1992/01/11 17:30:10 ian - John Antypas: use memcpy instead of relying on structure assignment - - Revision 1.6 1991/12/29 04:04:18 ian - Added a bunch of extern definitions - - Revision 1.5 1991/12/22 20:57:57 ian - Added externs for strcasecmp or strncasecmp - - Revision 1.4 1991/09/19 02:22:44 ian - Chip Salzenberg's patch to allow ";retrytime" at the end of a time string - - Revision 1.3 1991/09/12 05:04:44 ian - Wrong sense of comparison in btime_low_grade - - Revision 1.2 1991/09/11 16:59:00 ian - fcheck_time and btime_low_grade looped endlessly on unusual grades - - Revision 1.1 1991/09/10 19:40:31 ian - Initial revision - - */ - -#include "uucp.h" - -#if USE_RCS_ID -char time_rcsid[] = "$Id: time.c,v 1.1.1.1 1993/03/21 09:45:37 cgd Exp $"; -#endif - -#include <ctype.h> - -#if HAVE_TIME_H -#include <time.h> -#endif - -#if ! HAVE_TIME_T -#if HAVE_SYS_TIME_T -#include <sys/types.h> -#endif /* HAVE_SYS_TIME_T */ -#endif /* ! HAVE_TIME_T */ - -#include "uutime.h" - -/* External functions. */ -extern int strncasecmp (); -extern time_t time (); -extern struct tm *localtime (); - -/* Local functions. */ - -static struct sspan *qtnew P((struct sspan *qnext, long ival, - int istart, int iend, int cretry)); -static struct sspan *qtadd_span P((struct sspan *qlist, long ival, - int istart, int iend, - boolean (*picmp) P((long, long)), - int cretry)); -static struct sspan *qttime_parse P((const char *ztime, - struct sspan *qlist, long ival, - boolean (*picmp) P((long, long)), - int cretry)); - -/* A helper function to create a new time span with the specified - arguments. */ - -static struct sspan * -qtnew (qnext, ival, istart, iend, cretry) - struct sspan *qnext; - long ival; - int istart; - int iend; - int cretry; -{ - struct sspan *q; - - q = (struct sspan *) xmalloc (sizeof (struct sspan)); - q->qnext = qnext; - q->ival = ival; - q->istart = istart; - q->iend = iend; - q->cretry = cretry; - return q; -} - -/* A simple function to free a list of time spans. */ - -void -utimespan_free (q) - struct sspan *q; -{ - while (q != NULL) - { - struct sspan *qnext; - - qnext = q->qnext; - xfree ((pointer) q); - q = qnext; - } -} - -/* Add a time span to an existing list of time spans. We keep the - list sorted by time to make this operation easier. This modifies - the existing list, and returns the modified version. It takes a - comparison function which should return < 0 if the first argument - should take precedence over the second argument and == 0 if they - are the same (for grades this is igradecmp; for sizes it is minus - (the binary operator)). */ - -static struct sspan * -qtadd_span (qlist, ival, istart, iend, picmp, cretry) - struct sspan *qlist; - long ival; - int istart; - int iend; - boolean (*picmp) P((long, long)); - int cretry; -{ - struct sspan **pq; - - /* istart < iend */ - for (pq = &qlist; *pq != NULL; pq = &(*pq)->qnext) - { - int icmp; - - /* Invariant: PREV (*pq) == NULL || PREV (*pq)->iend <= istart */ - /* istart < iend && (*pq)->istart < (*pq)->iend */ - - if (iend <= (*pq)->istart) - { - /* istart < iend <= (*pq)->istart < (*pq)->iend */ - /* No overlap, and we're at the right spot. See if we can - combine these spans. */ - if (iend == (*pq)->istart - && cretry == (*pq)->cretry - && (*picmp) (ival, (*pq)->ival) == 0) - { - (*pq)->istart = istart; - return qlist; - } - /* We couldn't combine them. */ - break; - } - - if ((*pq)->iend <= istart) - { - /* (*pq)->istart < (*pq)->iend <= istart < iend */ - /* No overlap. Try attaching this span. */ - if ((*pq)->iend == istart - && (*pq)->cretry == cretry - && ((*pq)->qnext == NULL - || iend <= (*pq)->qnext->istart) - && (*picmp) (ival, (*pq)->ival) == 0) - { - (*pq)->iend = iend; - return qlist; - } - /* Couldn't attach; keep looking for the right spot. We - might be able to combine part of the new span onto an - existing span, but it's probably not worth it. */ - continue; - } - - /* istart < iend - && (*pq)->istart < (*pq)->iend - && istart < (*pq)->iend - && (*pq)->istart < iend */ - /* Overlap. */ - - icmp = (*picmp) (ival, (*pq)->ival); - - if (icmp == 0) - { - /* Just expand the old span to include the new span. */ - if (istart < (*pq)->istart) - (*pq)->istart = istart; - if ((*pq)->iend < iend) - (*pq)->iend = iend; - } - else if (icmp < 0) - { - /* Replace the old span with the new span. */ - if ((*pq)->istart < istart) - { - /* Save the initial portion of the old span. */ - *pq = qtnew (*pq, (*pq)->ival, (*pq)->istart, istart, - (*pq)->cretry); - pq = &(*pq)->qnext; - } - if (iend < (*pq)->iend) - { - /* Save the final portion of the old span. */ - (*pq)->qnext = qtnew ((*pq)->qnext, (*pq)->ival, iend, - (*pq)->iend, (*pq)->cretry); - } - (*pq)->ival = ival; - (*pq)->istart = istart; - (*pq)->iend = iend; - (*pq)->cretry = cretry; - } - else - { - /* Leave the old span untouched. */ - if (istart < (*pq)->istart) - { - /* Put in the initial portion of the new span. */ - *pq = qtnew (*pq, ival, istart, (*pq)->istart, cretry); - pq = &(*pq)->qnext; - } - if ((*pq)->iend < iend) - { - /* Put in the final portion of the new span. */ - (*pq)->qnext = qtnew ((*pq)->qnext, ival, (*pq)->iend, - iend, cretry); - } - } - - return qlist; - } - - /* This is the spot for the new span, and there's no overlap. */ - - *pq = qtnew (*pq, ival, istart, iend, cretry); - - return qlist; -} - -/* An array of weekday abbreviations. The code below assumes that - each one starts with a lower case letter. */ - -static const struct -{ - const char *zname; - int imin; - int imax; -} asTdays[] = -{ - { "any", 0, 6 }, - { "wk", 1, 5 }, - { "su", 0, 0 }, - { "mo", 1, 1 }, - { "tu", 2, 2 }, - { "we", 3, 3 }, - { "th", 4, 4 }, - { "fr", 5, 5 }, - { "sa", 6, 6 }, - { "never", -1, -2 }, - { NULL, 0, 0 } -}; - -/* Parse a time string and add it to a span list. This function is - given the value and comparison function to use. The time string - continues to a null byte, a space or a semicolon. This returns the - new span list, or NULL on error. If no time matches, it will wind - up returning qlist, which may itself be NULL. */ - -static struct sspan * -qttime_parse (ztime, qlist, ival, picmp, cretry) - const char *ztime; - struct sspan *qlist; - long ival; - int (*picmp) P((long, long)); - int cretry; -{ - const char *zend; - char bfirst; - int i; - - zend = ztime + strcspn (ztime, "; "); - - if (pasTtable == NULL) - uinittimetables (); - - /* Expand the string using a timetable. */ - bfirst = tolower (BUCHAR (*ztime)); - for (i = 0; i < cTtable; i++) - { - if (bfirst == tolower (BUCHAR (pasTtable[i].zname[0])) - && strncasecmp (ztime, pasTtable[i].zname, zend - ztime) == 0) - { - ztime = pasTtable[i].ztime; - zend = ztime + strlen (ztime); - /* Now search the table for this string. */ - i = -1; - } - } - - /* Look through the portions of the time string separated by a - comma or a vertical bar. */ - - for (; ztime < zend; ztime += strcspn (ztime, ",|")) - { - int iday; - boolean afday[7]; - const char *z; - int istart, iend; - - if (*ztime == ',' || *ztime == '|') - ++ztime; - - for (iday = 0; iday < 7; iday++) - afday[iday] = FALSE; - - /* Get the days. */ - - z = ztime; - do - { - bfirst = tolower (BUCHAR (*z)); - for (iday = 0; asTdays[iday].zname != NULL; iday++) - { - int clen; - - if (bfirst != asTdays[iday].zname[0]) - continue; - - clen = strlen (asTdays[iday].zname); - if (strncasecmp (z, asTdays[iday].zname, clen) == 0) - { - int iset; - - for (iset = asTdays[iday].imin; - iset <= asTdays[iday].imax; - iset++) - afday[iset] = TRUE; - z += clen; - break; - } - } - if (asTdays[iday].zname == NULL) - { - ulog (LOG_ERROR, "%s: unparseable time string", ztime); - return NULL; - } - } - while (isalpha (BUCHAR (*z))); - - /* Get the hours. */ - - if (! isdigit (BUCHAR (*z))) - { - istart = 0; - iend = 24 * 60; - } - else - { - char *zendnum; - - istart = (int) strtol (z, &zendnum, 10); - if (*zendnum != '-' || ! isdigit (BUCHAR (zendnum[1]))) - { - ulog (LOG_ERROR, "%s: unparseable time string", ztime); - return NULL; - } - z = zendnum + 1; - iend = (int) strtol (z, &zendnum, 10); - if (*zendnum != '\0' - && *zendnum != ' ' - && *zendnum != ';' - && *zendnum != ',' - && *zendnum != '|') - { - ulog (LOG_ERROR, "%s: unparseable time string", ztime); - return NULL; - } - - istart = (istart / 100) * 60 + istart % 100; - iend = (iend / 100) * 60 + iend % 100; - } - - /* Add the times we've found onto the list. */ - - for (iday = 0; iday < 7; iday++) - { - if (afday[iday]) - { - int iminute; - - iminute = iday * 24 * 60; - if (istart < iend) - qlist = qtadd_span (qlist, ival, iminute + istart, - iminute + iend, picmp, cretry); - else - { - /* Wrap around midnight. */ - qlist = qtadd_span (qlist, ival, iminute, - iminute + iend, picmp, cretry); - qlist = qtadd_span (qlist, ival, iminute + istart, - iminute + 24 * 60, picmp, - cretry); - } - } - } - } - - return qlist; -} - -/* See if the current time matches a time span. If it does, return - TRUE, set *pival to the value for the matching span, and set - *pcretry to the retry for the matching span. Otherwise return - FALSE. */ - -boolean -ftimespan_match (qspan, pival, pcretry) - const struct sspan *qspan; - long *pival; - int *pcretry; -{ - time_t inow; - struct tm *qtm; - int itm; - const struct sspan *q; - - time (&inow); - qtm = localtime (&inow); - - /* Get the number of minutes since Sunday for the time. */ - itm = qtm->tm_wday * 24 * 60 + qtm->tm_hour * 60 + qtm->tm_min; - - for (q = qspan; q != NULL; q = q->qnext) - { - if (q->istart <= itm && itm <= q->iend) - { - if (pival != NULL) - *pival = q->ival; - if (pcretry != NULL) - *pcretry = q->cretry; - return TRUE; - } - } - - return FALSE; -} - -/* Compare two work grades. */ - -static int itgradecmp P((long, long)); - -static int -itgradecmp (i1, i2) - long i1; - long i2; -{ - return igradecmp ((int) i1, (int) i2); -} - -/* Parse a time grade string into a time span. A time grade string is - a series of single character work grades followed by time strings. - The time string may end with a semicolon and a retry time. Each - grade/time/retry tuple is separated by a single space. This - function returns a time span, or NULL if no time matches or an - error occurs. */ - -struct sspan * -qtimegrade_parse (ztimegrade) - const char *ztimegrade; -{ - struct sspan *qret; - - if (ztimegrade == NULL) - return NULL; - - qret = NULL; - - while (TRUE) - { - const char *zretry; - int cretry; - struct sspan *qnext; - - zretry = ztimegrade + strcspn (ztimegrade, "; "); - if (*zretry == ';') - cretry = atoi (zretry + 1); - else - cretry = 0; - - qnext = qttime_parse (ztimegrade + 1, qret, (long) *ztimegrade, - itgradecmp, cretry); - if (qnext != NULL) - qret = qnext; - - ztimegrade += strcspn (ztimegrade, " "); - - if (*ztimegrade == '\0') - break; - - ++ztimegrade; - } - - return qret; -} - -/* Compare sizes when putting them into a timestring. */ - -static int itsizecmp P((long, long)); - -static int -itsizecmp (i1, i2) - long i1; - long i2; -{ - /* We can't just return i1 - i2 because that would be a long. */ - if (i1 < i2) - return -1; - else if (i1 == i2) - return 0; - else - return 1; -} - -/* Parse a time size string into a span. A time size string is a - size, a space, a time string, a space, repeated. There is no retry - time associated with a time size string. */ - -struct sspan * -qtimesize_parse (ztimesize) - const char *ztimesize; -{ - struct sspan *qret; - - if (ztimesize == NULL) - return NULL; - - qret = NULL; - - while (TRUE) - { - long isize; - char *zend; - struct sspan *qnext; - - isize = strtol (ztimesize, &zend, 10); - -#if DEBUG > 0 - if (*zend != ' ') - ulog (LOG_FATAL, "qtimesize_parse: Can't happen"); -#endif - - ++zend; - - qnext = qttime_parse (zend, qret, isize, itsizecmp, 0); - if (qnext != NULL) - qret = qnext; - - ztimesize = zend + strcspn (zend, " "); - - if (*ztimesize == '\0') - break; - - ++ztimesize; - } - - return qret; -} - -/* Determine the grade of work we are permitted to do at the current - time, given a time/grade string. Return a null byte if no grades - are legal. */ - -char -btimegrade (ztimegrade) - const char *ztimegrade; -{ - struct sspan *qspan; - boolean fmatch; - long ival; - - qspan = qtimegrade_parse (ztimegrade); - if (qspan == NULL) - return '\0'; - - fmatch = ftimespan_match (qspan, &ival, (int *) NULL); - - utimespan_free (qspan); - - if (! fmatch) - return '\0'; - - return (int) ival; -} - -/* Determine the maximum size that may be transferred at the present - time, according to a time size string. This returns -1 if there - are no restrictions. */ - -long -cmax_size_now (ztimesize) - const char *ztimesize; -{ - struct sspan *qspan; - boolean fmatch; - long ival; - - qspan = qtimesize_parse (ztimesize); - if (qspan == NULL) - return -1; - - fmatch = ftimespan_match (qspan, &ival, (int *) NULL); - - utimespan_free (qspan); - - if (! fmatch) - return -1; - - return ival; -} - -/* Determine the maximum size that may ever be transferred, according - to a time size string. This returns -1 if there is no limit. */ - -long -cmax_size_ever (ztimesize) - const char *ztimesize; -{ - struct sspan *qspan; - long imax; - struct sspan *q; - - qspan = qtimesize_parse (ztimesize); - if (qspan == NULL) - return -1; - - /* Look through the list of spans. If there is any gap larger than - 1 hour, we assume there are no restrictions. Otherwise we keep - track of the largest value we see. I picked 1 hour arbitrarily, - on the theory that a 1 hour span to transfer large files might - actually occur, and is probably not an accident. */ - - if (qspan->istart >= 60) - { - utimespan_free (qspan); - return -1; - } - - imax = -1; - - for (q = qspan; q != NULL; q = q->qnext) - { - if (q->qnext == NULL) - { - if (q->iend <= 6 * 24 * 60 + 23 * 60) - { - utimespan_free (qspan); - return -1; - } - } - else - { - if (q->iend + 60 <= q->qnext->istart) - { - utimespan_free (qspan); - return -1; - } - } - - if (imax < q->ival) - imax = q->ival; - } - - utimespan_free (qspan); - - return imax; -} diff --git a/gnu/libexec/uucp/util.c b/gnu/libexec/uucp/util.c deleted file mode 100644 index b77e81bad76..00000000000 --- a/gnu/libexec/uucp/util.c +++ /dev/null @@ -1,684 +0,0 @@ -/* util.c - Utilities 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 AIRS, P.O. Box 520, Waltham, MA 02254. - - $Log: util.c,v $ - Revision 1.1.1.1 1993/03/21 09:45:37 cgd - initial import of 386bsd-0.1 sources - - Revision 1.11 1992/03/12 19:56:10 ian - Debugging based on types rather than number - - Revision 1.10 1992/03/02 04:53:07 ian - Marc Unangst: added HAVE_SCO_LOCKFILES configuration parameter - - Revision 1.9 1992/02/23 03:26:51 ian - Overhaul to use automatic configure shell script - - Revision 1.8 1992/02/08 03:54:18 ian - Include <string.h> only in <uucp.h>, added 1992 copyright - - Revision 1.7 1992/01/19 18:29:05 ian - Added HAVE_BSEARCH configuration parameter - - Revision 1.6 1992/01/15 20:40:04 ian - Mike Park: some systems don't have <limits.h> - - Revision 1.5 1991/12/28 06:10:50 ian - Added HAVE_STRCHR and HAVE_INDEX to conf.h - - Revision 1.4 1991/12/28 03:49:23 ian - Added HAVE_MEMFNS and HAVE_BFNS; changed uses of memset to bzero - - Revision 1.3 1991/12/11 19:35:48 ian - Mark Powell: put in my own version of strtol - - Revision 1.2 1991/11/21 21:20:41 ian - Brian Campbell: offer str{n}icmp as an alternative to str{n}casecmp - - Revision 1.1 1991/09/10 19:40:31 ian - Initial revision - - */ - -#include "uucp.h" - -#if USE_RCS_ID -char util_rcsid[] = "$Id: util.c,v 1.1.1.1 1993/03/21 09:45:37 cgd Exp $"; -#endif - -#include <stdio.h> -#include <ctype.h> -#include <errno.h> - -#if HAVE_LIMITS_H -#include <limits.h> -#endif - -/* Allocate a block of memory without fail. */ - -pointer -xmalloc (c) - int c; -{ - pointer pret; - - pret = malloc (c); - if (pret == NULL && c != 0) - ulog (LOG_FATAL, "Out of memory"); - return pret; -} - -/* Realloc a block of memory without fail. Supposedly some versions of - realloc can't handle a NULL first argument, so we check for that - here. */ - -pointer -xrealloc (p, c) - pointer p; - int c; -{ - pointer pret; - - if (p == NULL) - return xmalloc (c); - pret = realloc (p, c); - if (pret == NULL && c != 0) - ulog (LOG_FATAL, "Out of memory"); - return pret; -} - -/* Some versions of free (like the one in SCO Unix 3.2.2) don't handle - null pointers correctly, so we go through our own routine. */ - -void -xfree (p) - pointer p; -{ - if (p != NULL) - free (p); -} - -/* Read a string of arbitrary length from a stdio file, returning an - malloced memory area. */ - -#define CFGETSDEFAULT (63) - -char * -zfgets (e, fbackslash) - FILE *e; - boolean fbackslash; -{ - char *zret, *z, *zend; - int clen; - int ichar; - - clen = CFGETSDEFAULT; - - /* Allocate one extra byte for the '\0'. */ - zret = (char *) xmalloc (clen + 1); - - z = zret; - zend = zret + clen; - while ((ichar = getc (e)) != EOF) - { - if (z >= zend) - { - char *znew; - - clen += CFGETSDEFAULT; - - /* Allocate one extra byte for the '\0'. */ - znew = (char *) xrealloc ((pointer) zret, clen + 1); - z = znew + (z - zret); - zret = znew; - zend = zret + clen; - } - - *z++ = (char) ichar; - if (ichar == '\n') - { - if (! fbackslash || z - zret < 2 || z[-2] != '\\') - break; - z -= 2; - } - } - - if (z == zret) - { - xfree ((pointer) zret); - return NULL; - } - - *z = '\0'; - - return zret; -} - -#if ! HAVE_STRDUP - -/* Duplicate a string in memory. */ - -char * -strdup (z) - const char *z; -{ - char *zret; - - zret = malloc (strlen (z) + 1); - if (zret != NULL) - strcpy (zret, z); - return zret; -} - -#endif /* ! HAVE_STRDUP */ - -/* Duplicate a string in memory with no errors. */ - -char * -xstrdup (z) - const char *z; -{ - char *zret; - - zret = strdup (z); - if (zret == NULL) - ulog (LOG_FATAL, "Out of memory"); - return zret; -} - -#if ! HAVE_STRSTR - -/* Look for one string inside another. */ - -char * -strstr (zhold, zwithin) - const char *zhold; - const char *zwithin; -{ - register char b; - register char bwithin; - - if ((bwithin = *zwithin++) == '\0') - return (char *) zhold; - - while ((b = *zhold++) != '\0') - { - if (bwithin == b) - { - register const char *zout, *zin; - - zout = zhold; - zin = zwithin; - do - { - if (*zin == '\0') - return (char *) (zhold - 1); - } - while (*zout++ == *zin++); - } - } - - return (char *) NULL; -} - -#endif /* ! HAVE_STRSTR */ - -#if ! HAVE_STRCASECMP && ! HAVE_STRICMP - -/* Do a case insensitive string comparison. */ - -int -strcasecmp (z1, z2) - const char *z1; - const char *z2; -{ - char b1, b2; - - while ((b1 = *z1++) != '\0') - { - b2 = *z2++; - if (b2 == '\0') - return 1; - if (b1 != b2) - { - if (isupper (BUCHAR (b1))) - b1 = tolower (BUCHAR (b1)); - if (isupper (BUCHAR (b2))) - b2 = tolower (BUCHAR (b2)); - if (b1 != b2) - return b1 - b2; - } - } - if (*z2 == '\0') - return 0; - else - return -1; -} - -int -strncasecmp (z1, z2, c) - const char *z1; - const char *z2; - int c; -{ - char b1, b2; - - if (c <= 0) - return 0; - while ((b1 = *z1++) != '\0') - { - b2 = *z2++; - if (b2 == '\0') - return 1; - if (b1 != b2) - { - if (isupper (BUCHAR (b1))) - b1 = tolower (BUCHAR (b1)); - if (isupper (BUCHAR (b2))) - b2 = tolower (BUCHAR (b2)); - if (b1 != b2) - return b1 - b2; - } - --c; - if (c <= 0) - return 0; - } - if (*z2 == '\0') - return 0; - else - return -1; -} - -#endif /* ! HAVE_STRCASECMP && ! HAVE_STRICMP */ - -#if ! HAVE_MEMCHR - -/* Find a single byte in a memory block. */ - -pointer -memchr (parg, b, c) - constpointer parg; - int b; - int c; -{ - const char *p = (const char *) parg; - - b = BUCHAR (b); - while (c-- != 0) - if (BUCHAR (*p++) == b) - return (pointer) --p; - return NULL; -} - -#endif /* ! HAVE_MEMCHR */ - -#if ! HAVE_MEMCMP && ! HAVE_BCMP - -/* Compare two memory blocks. */ - -int -memcmp (p1arg, p2arg, c) - constpointer p1arg; - constpointer p2arg; - int c; -{ - const char *p1 = (const char *) p1arg; - const char *p2 = (const char *) p2arg; - - while (c-- != 0) - if (*p1++ != *p2++) - return BUCHAR (*--p1) - BUCHAR (*--p2); - return 0; -} - -#endif /* ! HAVE_MEMCMP && ! HAVE_BCMP */ - -#if ! HAVE_MEMCPY && ! HAVE_BCOPY - -/* Copy one memory block to another. */ - -pointer -memcpy (ptoarg, pfromarg, c) - pointer ptoarg; - constpointer pfromarg; - int c; -{ - char *pto = (char *) ptoarg; - const char *pfrom = (const char *) pfromarg; - - while (c-- != 0) - *pto++ = *pfrom++; - return ptoarg; -} - -#endif /* ! HAVE_MEMCPY && ! HAVE_BCOPY */ - -#if ! HAVE_BZERO && ! HAVE_MEMSET - -/* Zero out a block of memory. */ - -void -bzero (parg, c) - pointer parg; - int c; -{ - char *p = (char *) parg; - - while (c-- != 0) - *p++ = 0; -} - -#endif /* ! HAVE_BZERO && ! HAVE_MEMSET */ - -#if ! HAVE_MEMMOVE - -/* Move a memory block safely despite overlap. This function is - almost impossible to write in strictly conforming C, because it - wants to compare pointers to different objects, but this - implementation will suffice for all normal systems. I hope. */ - -pointer -xmemmove (pto, pfrom, c) - pointer pto; - constpointer pfrom; - int c; -{ - char *zto = (char *) pto; - const char *zfrom = (const char *) pfrom; - - if (zto <= zfrom || zto >= zfrom + c) - { - while (c-- != 0) - *zto++ = *zfrom++; - } - else - { - zto += c; - zfrom += c; - while (c-- != 0) - *--zto = *--zfrom; - } - - return pto; -} - -#endif /* ! HAVE_MEMMOVE */ - -#if ! HAVE_STRCHR && ! HAVE_INDEX - -/* I doubt there are any systems for which this is true, but who - knows? Provide my own version of strchr. */ - -/* Look for a character in a string. This is supposed to work for a - null byte, although we never actually call it with one. */ - -char * -strchr (z, b) - const char *z; - int b; -{ - b = (char) b; - while (*z != b) - if (*z++ == '\0') - return NULL; - return (char *) z; -} - -#endif /* ! HAVE_STRCHR && ! HAVE_INDEX */ - -#if ! HAVE_STRRCHR && ! HAVE_RINDEX - -/* Look for the last occurrence of a character in a string. This is - supposed to work for a null byte, although we never actually call - it with one. */ - -char * -strrchr (z, b) - const char *z; - int b; -{ - char *zret; - - b = (char) b; - zret = NULL; - do - { - if (*z == b) - zret = (char *) z; - } - while (*z++ != '\0'); - return zret; -} - -#endif /* ! HAVE_STRRCHR && ! HAVE_RINDEX */ - -#if ! HAVE_STRLWR - -/* Convert a string to lower case. */ - -char * -strlwr (zarg) - char *zarg; -{ - char *z = zarg; - - while (*z != '\0') - { - if (isupper (*z)) - *z = tolower (*z); - ++z; - } - - return zarg; -} - -#endif /* ! HAVE_STRLWR */ - -#if ! HAVE_STRTOL - -/* My own version of strtol. This assumes that the upper case - characters appear in sequence and that the lower case characters - appear in sequence. It also assumes that unsigned arithmetic is - performed correctly, but that's probably a safe assumption. This - code needs only a couple of changes to also work as strtoul. */ - -/* We need definitions for LONG_MAX and LONG_MIN; the limits that - appear here are those guaranteed by the C standard. The value for - LONG_MIN is one greater than that applicable to most computers. */ - -#ifndef LONG_MAX -#define LONG_MAX (2147483647) -#endif -#ifndef LONG_MIN -#define LONG_MIN (- 2147483647) -#endif - -long -strtol (zarg, pzend, ibase) - const char *zarg; - char **pzend; - int ibase; -{ - const char *z, *zsubj; - boolean fsign; - unsigned long ival; - boolean foverflow; - - z = zarg; - - while (isspace (BUCHAR (*z))) - ++z; - - fsign = FALSE; - if (*z == '+') - ++z; - else if (*z == '-') - { - ++z; - fsign = TRUE; - } - - if (ibase == 0) - { - if (*z == '0') - { - if (z[1] == 'x' || z[1] == 'X') - { - z += 2; - ibase = 16; - } - else - ibase = 8; - } - else - ibase = 10; - } - else - { - if (ibase == 16 - && *z == '0' - && (z[1] == 'x' || z[1] == 'X')) - z += 2; - } - - ival = 0; - foverflow = FALSE; - zsubj = z; - - while (TRUE) - { - int inext; - unsigned long itmp; - - if (isdigit (BUCHAR (*z))) - inext = *z - '0'; - else if (isupper (BUCHAR (*z))) - inext = *z - 'A' + 10; - else if (islower (BUCHAR (*z))) - inext = *z - 'a' + 10; - else - break; - - if (inext >= ibase) - break; - - itmp = ival * ibase + inext; - - /* Operations on unsigned values are performed using modulos - arithmetic. Therefore any overflow will result in a smaller - number. Note that we can't simply return out on overflow, - because we still have to determine the end of the subject - sequence. */ - if (itmp < ival) - foverflow = TRUE; - - ival = itmp; - ++z; - } - - if (z == zsubj) - { - if (pzend != NULL) - *pzend = (char *) zarg; - return 0; - } - - if (pzend != NULL) - *pzend = (char *) z; - - /* Now checked for overflow as a signed type. If this were strtoul, - we would just leave out this check. Converting LONG_MIN, a - negative number, to unsigned long means adding it to ULONG_MAX + - 1, which can not overflow since long and unsigned long are the - same size. Negating an unsigned long, say i, means performing - the operation (ULONG_MAX + 1) - i, which clearly can not - overflow. The result is thus (ULONG_MAX + 1) - ((ULONG_MAX + 1) - + LONG_MIN) == - LONG_MIN, which is the magnitude we are looking - for. */ - if (fsign - ? ival > (unsigned long) LONG_MAX - : ival > - (unsigned long) LONG_MIN) - foverflow = TRUE; - - /* If this were strtoul, we would return ULONG_MAX on overflow - regardless of the value of fsign. */ - if (foverflow) - { - errno = ERANGE; - if (fsign) - return LONG_MIN; - else - return LONG_MAX; - } - - if (fsign) - ival = - ival; - - /* If this were strtoul, we would not case the value before - returning. */ - return (long) ival; -} - -#endif /* ! HAVE_STRTOL */ - -#if ! HAVE_BSEARCH - -/* Search for a key in a sorted array. The third and fourth arguments - should be size_t, but int will suffice for my uses and spare me - from defining size_t portably. */ - -pointer -bsearch (pkey, parray, celes, cbytes, pficmp) - constpointer pkey; - constpointer parray; - int celes; - int cbytes; - int (*pficmp) P((constpointer, constpointer)); -{ - const char *zarray = (const char *) parray; - int ilow, ihigh, itrial; - - ilow = 0; - ihigh = celes; - while (ilow < ihigh) - { - const char *zcheck; - int icmp; - - itrial = (ilow + ihigh) >> 1; - /* Here ilow <= itrial < ihigh */ - zcheck = zarray + itrial * cbytes; - icmp = (*pficmp) (pkey, (constpointer) zcheck); - if (icmp < 0) - ihigh = itrial; - else if (icmp > 0) - ilow = itrial + 1; - else - return (pointer) zcheck; - } - - return NULL; -} - -#endif /* ! HAVE_BSEARCH */ diff --git a/gnu/libexec/uucp/uuchk.c b/gnu/libexec/uucp/uuchk.c deleted file mode 100644 index 3df8b4cf725..00000000000 --- a/gnu/libexec/uucp/uuchk.c +++ /dev/null @@ -1,908 +0,0 @@ -/* uuchk.c - Display what we think the permissions of systems are. - - 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 AIRS, P.O. Box 520, Waltham, MA 02254. - - $Log: uuchk.c,v $ - Revision 1.1.1.1 1993/03/21 09:45:37 cgd - initial import of 386bsd-0.1 sources - - Revision 1.28 1992/03/28 20:31:55 ian - Franc,ois Pinard: allow a name to be given to an alternate - - Revision 1.27 1992/03/12 19:54:43 ian - Debugging based on types rather than number - - Revision 1.26 1992/03/10 21:47:39 ian - Added protocol command for ports - - Revision 1.25 1992/03/09 18:10:26 ian - Zacharias Beckman: put acceptable commands and path on different lines - - Revision 1.24 1992/03/07 02:56:30 ian - Rewrote time routines - - Revision 1.23 1992/02/27 05:40:54 ian - T. William Wells: detach from controlling terminal, handle signals safely - - Revision 1.22 1992/02/23 19:50:50 ian - Handle READ and WRITE in Permissions correctly - - Revision 1.21 1992/02/23 03:26:51 ian - Overhaul to use automatic configure shell script - - Revision 1.20 1992/02/08 22:33:32 ian - Only get the current working directory if it's going to be needed - - Revision 1.19 1992/02/08 20:33:57 ian - Handle all possible signals raised by abort - - Revision 1.18 1992/02/08 03:54:18 ian - Include <string.h> only in <uucp.h>, added 1992 copyright - - Revision 1.17 1992/01/15 07:06:29 ian - Set configuration directory in Makefile rather than sysdep.h - - Revision 1.16 1992/01/14 04:04:17 ian - Chip Salzenberg: strcmp is a macro on AIX - - Revision 1.15 1992/01/05 03:09:17 ian - Changed abProgram and abVersion to non const to avoid compiler bug - - Revision 1.14 1991/12/23 05:15:54 ian - David Nugent: set debugging level for a specific system - - Revision 1.13 1991/12/22 22:14:53 ian - Added externs for strcasecmp or strncasecmp - - Revision 1.12 1991/12/18 03:54:14 ian - Made error messages to terminal appear more normal - - Revision 1.11 1991/12/17 23:14:08 ian - T. William Wells: allow dialer complete and abort to be chat scripts - - Revision 1.10 1991/12/15 04:17:11 ian - Added chat-seven-bit command to control parity bit stripping - - Revision 1.9 1991/12/15 03:42:33 ian - Added tprocess_chat_cmd for all chat commands, and added CMDTABTYPE_PREFIX - - Revision 1.8 1991/12/01 14:45:53 ian - Bob Izenberg: report dialer/token pairs correctly - - Revision 1.7 1991/11/21 22:17:06 ian - Add version string, print version when printing usage - - Revision 1.6 1991/11/13 20:38:00 ian - Added TCP port type for connections over TCP - - Revision 1.5 1991/11/12 19:47:04 ian - Add called-chat set of commands to run a chat script on an incoming call - - Revision 1.4 1991/11/11 23:47:24 ian - Added chat-program to run a program to do a chat script - - Revision 1.3 1991/11/11 16:19:21 ian - Added message for no protocol specified - - Revision 1.2 1991/09/19 02:22:44 ian - Chip Salzenberg's patch to allow ";retrytime" at the end of a time string - - Revision 1.1 1991/09/10 19:40:31 ian - Initial revision - - */ - -#include "uucp.h" - -#if USE_RCS_ID -char uuchk_rcsid[] = "$Id: uuchk.c,v 1.1.1.1 1993/03/21 09:45:37 cgd Exp $"; -#endif - -#include "getopt.h" - -#include "port.h" -#include "system.h" -#include "sysdep.h" -#include "uutime.h" - -/* External functions. */ -extern int strcasecmp (); - -/* Program name. */ -char abProgram[] = "uuchk"; - -/* Local functions. */ - -static void ukusage P((void)); -static void ukshow P((const struct ssysteminfo *qsys)); -static boolean fkshow_port P((struct sport *qport, boolean fin)); -static void ukshow_dialer P((struct sdialer *qdial)); -static void ukshow_chat P((const struct schat_info *qchat, - const char *zhdr)); -static void ukshow_size P((const char *z, boolean fcall, boolean flocal)); -static void ukshow_proto_params P((int c, struct sproto_param *pas, - int cindent)); -static void ukshow_time P((const struct sspan *)); -static struct sspan *qcompress_span P((struct sspan *)); - -/* Local variables. */ -static boolean fKgot_port; - -/* Long getopt options. */ - -static const struct option asKlongopts[] = { { NULL, 0, NULL, 0 } }; - -const struct option *_getopt_long_options = asKlongopts; - -int -main (argc, argv) - int argc; - char **argv; -{ - int iopt; - /* The configuration file name. */ - const char *zconfig = NULL; - int c; - struct ssysteminfo *pas; - int i; - - while ((iopt = getopt (argc, argv, "I:x:")) != EOF) - { - switch (iopt) - { - case 'I': - /* Set the configuration file name. */ - zconfig = optarg; - break; - - case 'x': -#if DEBUG > 1 - /* Set the debugging level. */ - iDebug |= idebug_parse (optarg); -#endif - break; - - case 0: - /* Long option found and flag set. */ - break; - - default: - ukusage (); - break; - } - } - - if (optind != argc) - ukusage (); - - uread_config (zconfig); - - usysdep_initialize (FALSE, FALSE); - - uread_all_system_info (&c, &pas); - - for (i = 0; i < c; i++) - { - ukshow (&pas[i]); - if (i < c - 1) - printf ("\n"); - } - - ulog_close (); - - usysdep_exit (TRUE); - - /* Avoid errors about not returning a value. */ - return 0; -} - -/* Print a usage message and die. */ - -static void -ukusage () -{ - fprintf (stderr, - "Taylor UUCP version %s, copyright (C) 1991, 1992 Ian Lance Taylor\n", - abVersion); - fprintf (stderr, - "Usage: uuchk [-I file] [-x debug]\n"); - fprintf (stderr, - " -x debug: Set debugging level (0 for none, 9 is max)\n"); -#if HAVE_TAYLOR_CONFIG - fprintf (stderr, - " -I file: Set configuration file to use (default %s%s)\n", - NEWCONFIGLIB, CONFIGFILE); -#endif /* HAVE_TAYLOR_CONFIG */ - exit (EXIT_FAILURE); -} - -/* Dump out the information for a system. */ - -static void -ukshow (qsys) - const struct ssysteminfo *qsys; -{ - int i; - const struct ssysteminfo *qlast; - - printf ("System: %s", qsys->zname); - if (qsys->zalias != NULL) - printf (" (%s)", qsys->zalias); - printf ("\n"); - - qlast = NULL; - for (i = 0; qsys != NULL; qlast = qsys, qsys = qsys->qalternate, i++) - { - boolean fcall, fcalled; - struct sspan *qtime, *qspan; - - if (i != 0 || qsys->qalternate != NULL) - { - printf ("Alternate %d", i); - if (qsys->zalternate != NULL) - printf (" (%s)", qsys->zalternate); - printf ("\n"); - } - - /* See if this alternate could be used when calling out. */ - - fcall = (i == 0 - || qsys->ztime != qlast->ztime - || qsys->zport != qlast->zport - || qsys->qport != qlast->qport - || qsys->ibaud != qlast->ibaud - || qsys->zphone != qlast->zphone - || qsys->schat.zprogram != qlast->schat.zprogram - || qsys->schat.zchat != qlast->schat.zchat); - - if (! fcall) - qtime = NULL; - else - { - qtime = qtimegrade_parse (qsys->ztime); - if (qtime == NULL) - fcall = FALSE; - } - - /* If this is the first alternate, it can be used to accept - a call. Otherwise it can be used if it specifies a different - login name than the previous alternate. */ - fcalled = (i == 0 - || (qlast != NULL - && qsys->zcalled_login != NULL - && (qlast->zcalled_login == NULL - || strcmp (qsys->zcalled_login, - qlast->zcalled_login) != 0))); - - if (! fcall && ! fcalled) - { - printf (" This alternate is never used\n"); - continue; - } - - if (fcalled) - { - if (qsys->zcalled_login != NULL - && strcmp (qsys->zcalled_login, "ANY") != 0) - { - if (i == 0 && qsys->qalternate == NULL) - printf (" Caller must log in as %s\n", qsys->zcalled_login); - else - printf (" When called using login name %s\n", - qsys->zcalled_login); - } - else - printf (" When called using any login name\n"); - - if (qsys->zlocalname != NULL) - printf (" Will use %s as name of local system\n", - qsys->zlocalname); - } - - if (fcalled && qsys->fcallback) - { - printf (" If called, will call back\n"); - fcalled = FALSE; - } - - if (fcall) - { - if (i == 0 && qsys->qalternate == NULL) - printf (" Call out"); - else - printf (" This alternate applies when calling"); - - if (qsys->zport != NULL || qsys->qport != NULL) - { - printf (" using "); - if (qsys->zport != NULL) - printf ("port %s", qsys->zport); - else - printf ("a specially defined port"); - if (qsys->ibaud != 0) - { - printf (" at speed %ld", qsys->ibaud); - if (qsys->ihighbaud != 0) - printf (" to %ld", qsys->ihighbaud); - } - printf ("\n"); - } - else if (qsys->ibaud != 0) - { - printf (" at speed %ld", qsys->ibaud); - if (qsys->ihighbaud != 0) - printf (" to %ld", qsys->ihighbaud); - printf ("\n"); - } - else - printf (" using any port\n"); - - if (qsys->qport != NULL) - { - printf (" The port is defined as:\n"); - (void) fkshow_port (qsys->qport, FALSE); - } - else - { - struct sport sdummy; - - printf (" The possible ports are:\n"); - fKgot_port = FALSE; - (void) ffind_port (qsys->zport, qsys->ibaud, - qsys->ihighbaud, &sdummy, - fkshow_port, FALSE); - if (! fKgot_port) - printf (" *** There are no matching ports\n"); - } - - if (qsys->zphone != NULL) - { -#if HAVE_TCP - if ((qsys->zport != NULL - && strcmp (qsys->zport, "TCP") == 0) - || (qsys->qport != NULL - && qsys->qport->ttype == PORTTYPE_TCP)) - printf (" Remote address %s\n", qsys->zphone); - else -#endif /* HAVE_TCP */ - printf (" Phone number %s\n", qsys->zphone); - } - - ukshow_chat (&qsys->schat, " Chat"); - - if (qsys->zcall_login != NULL) - { - if (strcmp (qsys->zcall_login, "*") != 0) - printf (" Login name %s\n", qsys->zcall_login); - else - { - char *zlogin, *zpass; - - if (! fcallout_login (qsys, &zlogin, &zpass)) - printf (" Can not determine login name\n"); - else - { - printf (" Login name %s\n", zlogin); - xfree ((pointer) zlogin); - xfree ((pointer) zpass); - } - } - } - - if (qsys->zcall_password != NULL) - { - if (strcmp (qsys->zcall_password, "*") != 0) - printf (" Password %s\n", qsys->zcall_password); - else - { - char *zlogin, *zpass; - - if (! fcallout_login (qsys, &zlogin, &zpass)) - printf (" Can not determine password\n"); - else - { - printf (" Password %s\n", zpass); - xfree ((pointer) zlogin); - xfree ((pointer) zpass); - } - } - } - - qtime = qcompress_span (qtime); - - for (qspan = qtime; qspan != NULL; qspan = qspan->qnext) - { - printf (" "); - ukshow_time (qspan); - printf (" may call if "); - if ((char) qspan->ival == BGRADE_LOW) - printf ("any work"); - else - printf ("work grade %c or higher", (char) qspan->ival); - if (qspan->cretry != 0) - printf (" (retry %d)", qspan->cretry); - printf ("\n"); - } - - utimespan_free (qtime); - - if (qsys->zcalltimegrade != NULL) - { - boolean fprint, fother; - - qtime = qtimegrade_parse (qsys->zcalltimegrade); - qtime = qcompress_span (qtime); - fprint = FALSE; - fother = FALSE; - if (qtime->istart != 0) - fother = TRUE; - for (qspan = qtime; qspan != NULL; qspan = qspan->qnext) - { - if ((char) qspan->ival == BGRADE_LOW) - { - fother = TRUE; - continue; - } - fprint = TRUE; - printf (" "); - ukshow_time (qspan); - printf (" may accept work grade %c or higher\n", - (char) qspan->ival); - if (qspan->qnext == NULL) - { - if (qspan->iend != 7 * 24 * 60) - fother = TRUE; - } - else - { - if (qspan->iend != qspan->qnext->istart) - fother = TRUE; - } - } - if (fprint && fother) - printf (" (At other times may accept any work)\n"); - - utimespan_free (qtime); - } - } - - if (qsys->fsequence) - printf (" Sequence numbers are used\n"); - - if (fcalled) - ukshow_chat (&qsys->scalled_chat, " When called, chat"); - -#if DEBUG > 1 - if (qsys->idebug != 0) - printf (" Debugging level 0%o\n", (unsigned int) qsys->idebug); - if (qsys->imax_remote_debug != 0) - printf (" Max remote debugging level 0%o\n", - (unsigned int) qsys->imax_remote_debug); -#endif - - if (fcall) - { - ukshow_size (qsys->zcall_local_size, TRUE, TRUE); - ukshow_size (qsys->zcall_remote_size, TRUE, FALSE); - } - if (fcalled) - { - ukshow_size (qsys->zcalled_local_size, FALSE, TRUE); - ukshow_size (qsys->zcalled_remote_size, FALSE, TRUE); - } - - if (fcall) - { - printf (" %sllow remote requests when calling\n", - qsys->fcall_request ? "A" : "Do not a"); - printf (" May %smake local requests when calling\n", - qsys->fcall_transfer ? "" : "not "); - } - - if (fcalled) - { - printf (" %sllow remote requests when called\n", - qsys->fcalled_request ? "A" : "Do not a"); - printf (" May %smake local requests when called\n", - qsys->fcalled_transfer ? "" : "not "); - } - - if (qsys->fcall_transfer || qsys->fcalled_transfer) - { - if (qsys->zcalled_local_send == NULL) - printf (" May send by local request: %s\n", qsys->zlocal_send); - else - { - if (fcall && qsys->fcall_transfer) - printf (" May send by local request when calling: %s\n", - qsys->zlocal_send); - if (fcalled && qsys->fcalled_transfer) - printf (" May send by local request when called: %s\n", - qsys->zcalled_local_send); - } - } - if (qsys->fcall_request || qsys->fcalled_request) - { - if (qsys->zcalled_remote_send == NULL) - printf (" May send by remote request: %s\n", qsys->zremote_send); - else - { - if (fcall && qsys->fcall_request) - printf (" May send by remote request when calling: %s\n", - qsys->zremote_send); - if (fcalled && qsys->fcalled_request) - printf (" May send by remote request when called: %s\n", - qsys->zcalled_remote_send); - } - } - if (qsys->fcall_transfer || qsys->fcalled_transfer) - { - if (qsys->zcalled_local_receive == NULL) - printf (" May accept by local request: %s\n", - qsys->zlocal_receive); - else - { - if (fcall && qsys->fcall_transfer) - printf (" May accept by local request when calling: %s\n", - qsys->zlocal_receive); - if (fcalled && qsys->fcalled_transfer) - printf (" May accept by local request when called: %s\n", - qsys->zcalled_local_receive); - } - } - if (qsys->fcall_request || qsys->fcalled_request) - { - if (qsys->zcalled_remote_receive == NULL) - printf (" May accept by remote request: %s\n", - qsys->zremote_receive); - else - { - if (fcall && qsys->fcall_request) - printf (" May accept by remote request when calling: %s\n", - qsys->zremote_receive); - if (fcalled && qsys->fcalled_request) - printf (" May accept by remote request when called: %s\n", - qsys->zcalled_remote_receive); - } - } - - printf (" May execute %s\n", qsys->zcmds); - printf (" Execution path %s\n", qsys->zpath); - - if (qsys->cfree_space != 0) - printf (" Will leave %ld bytes available\n", qsys->cfree_space); - - if (qsys->zpubdir != NULL) - printf (" Public directory is %s\n", qsys->zpubdir); - - if (qsys->zprotocols != NULL) - printf (" Will use protocols %s\n", qsys->zprotocols); - else - printf (" Will use any known protocol\n"); - - if (qsys->cproto_params != 0) - ukshow_proto_params (qsys->cproto_params, qsys->qproto_params, 1); - } -} - -/* Show information about a port. */ - -/*ARGSUSED*/ -static boolean -fkshow_port (qport, fin) - struct sport *qport; - boolean fin; -{ - fKgot_port = TRUE; - - printf (" Port name %s\n", qport->zname); - switch (qport->ttype) - { - case PORTTYPE_STDIN: - printf (" Port type stdin\n"); - break; - case PORTTYPE_DIRECT: - printf (" Port type direct\n"); - if (qport->u.sdirect.zdevice != NULL) - printf (" Device %s\n", qport->u.sdirect.zdevice); - printf (" Speed %ld\n", qport->u.sdirect.ibaud); - break; - case PORTTYPE_MODEM: - printf (" Port type modem\n"); - if (qport->u.smodem.zdevice != NULL) - printf (" Device %s\n", qport->u.smodem.zdevice); - if (qport->u.smodem.zdial_device != NULL) - printf (" Dial device %s\n", qport->u.smodem.zdial_device); - printf (" Speed %ld\n", qport->u.smodem.ibaud); - if (qport->u.smodem.ilowbaud != qport->u.smodem.ihighbaud) - printf (" Speed range %ld to %ld\n", qport->u.smodem.ilowbaud, - qport->u.smodem.ihighbaud); - printf (" Carrier %savailable\n", - qport->u.smodem.fcarrier ? "" : "not "); - if (qport->u.smodem.qdialer != NULL) - { - printf (" Specially defined dialer\n"); - ukshow_dialer (qport->u.smodem.qdialer); - } - else if (qport->u.smodem.zdialer != NULL) - { - const char *zc; - struct sdialer sdial; - - /* This might be a single dialer name, or it might be a - sequence of dialer/token pairs. */ - - zc = qport->u.smodem.zdialer; - if (zc[strcspn (zc, " \t")] == '\0') - { - if (! fread_dialer_info (qport->u.smodem.zdialer, &sdial)) - printf (" *** No dialer %s\n", qport->u.smodem.zdialer); - else - { - printf (" Dialer %s\n", qport->u.smodem.zdialer); - ukshow_dialer (&sdial); - } - } - else - { - char *z, *zdialer; - - printf (" Dialer sequence %s\n", zc); - - z = (char *) alloca (strlen (zc) + 1); - strcpy (z, zc); - - zdialer = strtok (z, " \t"); - while (zdialer != NULL) - { - char *ztoken; - - if (! fread_dialer_info (zdialer, &sdial)) - printf (" *** No dialer %s\n", zdialer); - else - { - printf (" Dialer %s\n", zdialer); - ukshow_dialer (&sdial); - } - - ztoken = strtok ((char *) NULL, " \t"); - if (ztoken == NULL) - zdialer = NULL; - else - zdialer = strtok ((char *) NULL, " \t"); - } - } - } - else - printf (" *** No dialer information\n"); - break; -#if HAVE_TCP - case PORTTYPE_TCP: - printf (" Port type tcp\n"); - printf (" TCP service %s\n", qport->u.stcp.zport); - break; -#endif /* HAVE_TCP */ - default: - printf (" CAN'T HAPPEN\n"); - break; - } - - if (qport->zprotocols != NULL) - printf (" Will use protocols %s\n", qport->zprotocols); - - if (qport->cproto_params != 0) - ukshow_proto_params (qport->cproto_params, qport->qproto_params, 3); - - /* Return FALSE to force ffind_port to continue searching. */ - return FALSE; -} - -/* Show information about a dialer. */ - -static void -ukshow_dialer (q) - struct sdialer *q; -{ - ukshow_chat (&q->schat, " Chat"); - if (q->zdialtone != NULL) - printf (" Wait for dialtone %s\n", q->zdialtone); - if (q->zpause != NULL) - printf (" Pause while dialing %s\n", q->zpause); - printf (" Carrier %savailable\n", q->fcarrier ? "" : "not "); - if (q->fcarrier) - printf (" Wait %d seconds for carrier\n", q->ccarrier_wait); - if (q->fdtr_toggle) - { - printf (" Toggle DTR"); - if (q->fdtr_toggle_wait) - printf (" and wait"); - printf ("\n"); - } - ukshow_chat (&q->scomplete, " When complete chat"); - ukshow_chat (&q->sabort, " When aborting chat"); - if (q->cproto_params != 0) - ukshow_proto_params (q->cproto_params, q->qproto_params, 4); -} - -/* Show a chat script. */ - -static void -ukshow_chat (qchat, zhdr) - const struct schat_info *qchat; - const char *zhdr; -{ - if (qchat->zprogram != NULL) - printf ("%s program %s\n", zhdr, qchat->zprogram); - - if (qchat->zchat != NULL) - { - printf ("%s script %s\n", zhdr, qchat->zchat); - printf ("%s script timeout %d\n", zhdr, qchat->ctimeout); - if (qchat->zfail != NULL) - printf ("%s failure strings %s\n", zhdr, qchat->zfail); - if (qchat->fstrip) - printf ("%s script incoming bytes stripped to seven bits\n", zhdr); - } -} - -/* Show a size/time restriction. */ - -static void -ukshow_size (zstring, fcall, flocal) - const char *zstring; - boolean fcall; - boolean flocal; -{ - struct sspan *qspan, *q; - boolean fother; - - qspan = qcompress_span (qtimesize_parse (zstring)); - if (qspan == NULL) - return; - - printf (" If call%s the following applies to a %s request:\n", - fcall ? "ing" : "ed", flocal ? "local" : "remote"); - - fother = FALSE; - if (qspan->istart >= 60) - fother = TRUE; - - for (q = qspan; q != NULL; q = q->qnext) - { - printf (" "); - ukshow_time (q); - printf (" may transfer files %ld bytes or smaller\n", q->ival); - if (q->qnext == NULL) - { - if (q->iend <= 6 * 24 * 60 + 23 * 60) - fother = TRUE; - } - else - { - if (q->iend + 60 <= q->qnext->istart) - fother = TRUE; - } - } - - if (fother) - printf (" (At other times may send files of any size)\n"); - - utimespan_free (qspan); -} - -/* Show protocol parameters. */ - -static void -ukshow_proto_params (c, pas, cindent) - int c; - struct sproto_param *pas; - int cindent; -{ - int ip; - - for (ip = 0; ip < c; ip++) - { - int ie, isp; - - for (isp = 0; isp < cindent; isp++) - printf (" "); - printf ("For protocol %c will use the following parameters\n", - pas[ip].bproto); - for (ie = 0; ie < pas[ip].centries; ie++) - { - int ia; - struct sproto_param_entry *qe; - - qe = &pas[ip].qentries[ie]; - for (isp = 0; isp < cindent; isp++) - printf (" "); - for (ia = 0; ia < qe->cargs; ia++) - printf (" %s", qe->azargs[ia]); - printf ("\n"); - } - } -} - -/* Display a time span. */ - -static void -ukshow_time (q) - const struct sspan *q; -{ - int idaystart, idayend; - int ihourstart, ihourend; - int iminutestart, iminuteend; - const char * const zdays = "Sun\0Mon\0Tue\0Wed\0Thu\0Fri\0Sat\0Sun"; - - if (q->istart == 0 && q->iend == 7 * 24 * 60) - { - printf ("At any time"); - return; - } - - idaystart = q->istart / (24 * 60); - ihourstart = (q->istart % (24 * 60)) / 60; - iminutestart = q->istart % 60; - idayend = q->iend / (24 * 60); - ihourend = (q->iend % (24 * 60)) / 60; - iminuteend = q->iend % 60; - - if (idaystart == idayend) - printf ("%s from %02d:%02d to %02d:%02d", zdays + idaystart * 4, - ihourstart, iminutestart, ihourend, iminuteend); - else - printf ("From %s %02d:%02d to %s %02d:%02d", - zdays + idaystart * 4, ihourstart, iminutestart, - zdays + idayend * 4, ihourend, iminuteend); -} - -/* Compress a time span by merging any two adjacent spans with - identical values. This isn't necessary for uucico, but it looks - nicer when printed out. */ - -static struct sspan * -qcompress_span (qlist) - struct sspan *qlist; -{ - struct sspan **pq; - - pq = &qlist; - while (*pq != NULL) - { - if ((*pq)->qnext != NULL - && (*pq)->iend == (*pq)->qnext->istart - && (*pq)->ival == (*pq)->qnext->ival) - { - struct sspan *qfree; - - qfree = (*pq)->qnext; - (*pq)->qnext = qfree->qnext; - (*pq)->iend = qfree->iend; - xfree ((pointer) qfree); - } - else - pq = &(*pq)->qnext; - } - - return qlist; -} diff --git a/gnu/libexec/uucp/uucico.8 b/gnu/libexec/uucp/uucico.8 deleted file mode 100644 index dc4c44e44a6..00000000000 --- a/gnu/libexec/uucp/uucico.8 +++ /dev/null @@ -1,242 +0,0 @@ -''' $Id: uucico.8,v 1.1.1.1 1993/03/21 09:45:37 cgd Exp $ -''' $Log: uucico.8,v $ -''' Revision 1.1.1.1 1993/03/21 09:45:37 cgd -''' initial import of 386bsd-0.1 sources -''' -''' Revision 1.7 1992/04/01 21:11:19 ian -''' Cleaned up a bit, updated -x switch -''' -''' Revision 1.6 1992/03/28 04:34:11 ian -''' David J. MacKenzie: change .TP5 to .TP 5; also updated to 1.03 -''' -''' Revision 1.5 1992/03/08 17:08:20 ian -''' Ted Lindgreen: ignore -u option -''' -''' Revision 1.4 1992/02/27 05:40:54 ian -''' T. William Wells: detach from controlling terminal, handle signals safely -''' -''' Revision 1.3 1992/01/20 23:52:23 ian -''' Change to version 1.02 -''' -''' Revision 1.2 1991/12/18 05:12:00 ian -''' Added -l option to uucico to prompt for login name once and then exit -''' -''' Revision 1.1 1991/12/14 19:05:30 ian -''' Initial revision -''' -''' -.TH uucico 8 "Taylor UUCP 1.03" -.SH NAME -uucico \- UUCP file transfer daemon -.SH SYNOPSIS -.B uucico -[ options ] -.SH DESCRIPTION -The -.I uucico -daemon processes file transfer requests queued by -.I uucp -(1) and -.I uux -(1). It is started when -.I uucp -or -.I uux -is run (unless they are given the -.B \-r -option). It is also typically started periodically using -entries in the -.I crontab -table(s). - -When invoked with the -.B \-r1 -option or the -.B \-s -or -.B \-S -option, the daemon will place a call to a remote system, running in -master mode. -Otherwise the daemon will start in slave mode, accepting a -call from a remote system. Typically a special login name will be set -up for UUCP which automatically invokes -.I uucico -when a call is made. - -When -.I uucico -terminates, it invokes the -.I uuxqt -(8) daemon, unless the -.B \-q -option is given; -.I uuxqt -(8) executes any work orders created by -.I uux -(1) on a remote system, and any work orders created locally which have -received remote files for which they were waiting. - -If a call fails, -.I uucico -will normally refuse to retry the -call until a certain (configurable) amount of time -has passed. This may be overriden by the -.B -f -or the -.B -S -option. - -The -.B \-l -or -.B \-e -option may be used to force -.I uucico -to produce its own prompts of "login: " and "Password:". When another -daemon calls in, it will see these prompts and log in as usual; the -login name and password will be checked against a separate list kept -specially for -.I uucico -rather than the -.I /etc/passwd -file. The -.B \-l -option will prompt once and then exit. The -.B \-e -option will prompt again after the first session is over; in this mode -.I uucico -will permanently control a port. - -If -.I uucico -receives a SIGQUIT, SIGTERM or SIGPIPE signal, it will cleanly abort -any current conversation with a remote system and exit. If it -receives a SIGHUP signal it will abort any current conversation, but -will continue to place calls to (if invoked with -.B \-r1) -and accept calls from (if invoked with -.B \-e) -other systems. If it receives a -SIGINT signal it will finish the current conversation, but will not -place or accept any more calls. -.SH OPTIONS -The following options may be given to -.I uucico. -.TP 5 -.B \-r1 -Start in master mode (call out to a system); implied by -.B \-s -or -.B \-S. If no system is specified, -call any system for which work is -waiting to be done. -.TP 5 -.B \-r0 -Start in slave mode. This is the default. -.TP 5 -.B \-s system -Call the named system. -.TP 5 -.B \-S system -Call the named system, ignoring any required wait. -.TP 5 -.B \-f -Ignore any required wait for any systems to be called. -.TP 5 -.B \-l -Prompt for login name and password using "login: " and "Password:". -This allows -.I uucico -to be easily run from -.I inetd -(8). The login name and password are checked against the UUCP -password file, which has no connection to the file -.I /etc/passwd. -.TP 5 -.B \-p port -Specify a port to call out on or to listen to. In slave mode, this -implies -.B \-e. -.TP 5 -.B \-e -Enter endless loop of login/password prompts and slave mode daemon -execution. The program will not stop by itself; you must use -.I kill -(1) to shut it down. -.TP 5 -.B \-w -After calling out (to a particular system when -.B \-s -or -.B \-S -is specifed, or to all systems which have work when -.B \-r1 -is specifed), begin an endless loop as with -.B \-e. -.TP 5 -.B \-q -Do not start the -.I uuxqt -(8) daemon when finished. -.TP 5 -.B \-D -Do not detach from the controlling terminal. Normally -.I uucico -detaches from the terminal before each call out to another system and -before invoking -.I uuxqt. -This option prevents this. -.TP 5 -.B \-x type, \-X type -Turn on particular debugging types. The following types are -recognized: abnormal, chat, handshake, uucp-proto, proto, port, -config, spooldir, execute, incoming, outgoing. - -Multiple types may be given, separated by commas, and the -.B \-x -option may appear multiple times. A number may also be given, which -will turn on that many types from the foregoing list; for example, -.B \-x 2 -is equivalent to -.B \-x abnormal,chat. - -The debugging output is sent to the debugging file, usually one of -/usr/spool/uucp/Debug, /usr/spool/uucp/DEBUG, or -/usr/spool/uucp/.Admin/audit.local. -.TP 5 -.B \-I file -Set configuration file to use. This option may not be available, -depending upon how -.I uucico -was compiled. -.TP 5 -.B \-u login -This option is ignored. It is only included because some versions of -uucpd invoke -.I uucico -with it. -.SH FILES -The file names may be changed at compilation time or by the -configuration file, so these are only approximations. - -.br -/usr/lib/uucp/config - Configuration file. -.br -/usr/lib/uucp/passwd - Default UUCP password file. -.br -/usr/spool/uucp - -UUCP spool directory. -.br -/usr/spool/uucp/Log - -UUCP log file. -.br -/usr/spool/uucppublic - -Default UUCP public directory. -.br -/usr/spool/uucp/Debug - -Debugging file. -.SH SEE ALSO -kill(1), uucp(1), uux(1), uuxqt(8) -.SH AUTHOR -Ian Lance Taylor -(ian@airs.com or uunet!airs!ian) diff --git a/gnu/libexec/uucp/uucico.c b/gnu/libexec/uucp/uucico.c deleted file mode 100644 index dd60ee8a715..00000000000 --- a/gnu/libexec/uucp/uucico.c +++ /dev/null @@ -1,3496 +0,0 @@ -/* uucico.c - This is the main UUCP communication program. - - 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 AIRS, P.O. Box 520, Waltham, MA 02254. - - $Log: uucico.c,v $ - Revision 1.1.1.1 1993/03/21 09:45:37 cgd - initial import of 386bsd-0.1 sources - - Revision 1.92 1992/04/06 21:10:14 ian - Marc Boucher: set *pqsys to NULL in faccept_call - - Revision 1.91 1992/03/30 04:07:13 ian - Dirk Musstopf: remove temporary file if receive fails - - Revision 1.90 1992/03/28 22:06:38 ian - Michael I Bushnell: renamed enum tstatus to avoid header file conflict - - Revision 1.89 1992/03/28 20:52:11 ian - Petri Helenius: must dump controlling terminal when going to next alternate - - Revision 1.88 1992/03/28 20:31:55 ian - Franc,ois Pinard: allow a name to be given to an alternate - - Revision 1.87 1992/03/28 19:40:26 ian - Close log and statistics file at each master/slave role switch - - Revision 1.86 1992/03/28 04:45:31 ian - Mark E. Mallett: minor cleanup - - Revision 1.85 1992/03/17 18:42:21 ian - T. William Wells: set current time in status file when call completes - - Revision 1.84 1992/03/17 01:03:03 ian - Miscellaneous cleanup - - Revision 1.83 1992/03/16 05:16:03 ian - Recognize SVR4 -U flag - - Revision 1.82 1992/03/16 04:38:00 ian - Turn off DEBUG_PORT for handshake debugging - - Revision 1.81 1992/03/15 04:51:17 ian - Keep an array of signals we've received rather than a single variable - - Revision 1.80 1992/03/12 19:54:43 ian - Debugging based on types rather than number - - Revision 1.79 1992/03/11 19:53:55 ian - Improved chat script debugging - - Revision 1.78 1992/03/11 00:18:50 ian - Save temporary file if file send fails - - Revision 1.77 1992/03/10 23:01:20 ian - Don't run uuxqt if we got a SIGTERM - - Revision 1.76 1992/03/10 21:47:39 ian - Added protocol command for ports - - Revision 1.75 1992/03/09 20:14:37 ian - Ted Lindgreen: added max-remote-debug command - - Revision 1.74 1992/03/09 19:52:50 ian - Ted Lindgreen: strip parity from initial handshake strings - - Revision 1.73 1992/03/09 19:42:43 ian - Ted Lindgreen: don't send mail for nonexistent file - - Revision 1.72 1992/03/09 05:37:10 ian - Only look for hangup string in debugging mode - - Revision 1.71 1992/03/09 05:29:20 ian - Ted Lindgreen: report requested grade on an incoming call - - Revision 1.70 1992/03/09 05:08:16 ian - Added status for wrong time to call, not used if system can't be called - - Revision 1.69 1992/03/08 17:45:41 ian - Ted Lindgreen: start uuxqt for only one system if appropriate - - Revision 1.68 1992/03/08 17:08:20 ian - Ted Lindgreen: ignore -u option - - Revision 1.67 1992/03/08 16:42:41 ian - Ted Lindgreen: report port and login name in log file - - Revision 1.66 1992/03/07 02:56:30 ian - Rewrote time routines - - Revision 1.65 1992/03/04 15:05:51 ian - Michael Haberler: some systems send \n after Shere - - Revision 1.64 1992/03/04 00:36:44 ian - Michael Richardson: better chat script debugging - - Revision 1.63 1992/03/03 21:01:20 ian - Use strict timeout in fsserial_read, eliminate all race conditions - - Revision 1.62 1992/03/03 06:06:48 ian - T. William Wells: don't complain about missing configuration files - - Revision 1.61 1992/02/29 04:07:08 ian - Added -j option to uucp and uux - - Revision 1.60 1992/02/29 01:06:59 ian - Chip Salzenberg: recheck file permissions before sending - - Revision 1.59 1992/02/27 05:40:54 ian - T. William Wells: detach from controlling terminal, handle signals safely - - Revision 1.58 1992/02/24 22:38:45 ian - Don't treat an extra argument as a port - - Revision 1.57 1992/02/24 04:58:47 ian - Only permit files to be received into directories that are world-writeable - - Revision 1.56 1992/02/23 19:50:50 ian - Handle READ and WRITE in Permissions correctly - - Revision 1.55 1992/02/23 03:26:51 ian - Overhaul to use automatic configure shell script - - Revision 1.54 1992/02/20 22:57:19 ian - Chip Salzenberg: some systems truncate the Shere= machine name - - Revision 1.53 1992/02/19 19:36:07 ian - Rearranged time functions - - Revision 1.52 1992/02/14 21:32:50 ian - Niels Baggesen: under HAVE_BNU_LOGGING, don't lost system name when dieing - - Revision 1.51 1992/02/09 05:21:55 ian - Bob Denny: call fmail_transfer before fsysdep_did_work - - Revision 1.50 1992/02/08 22:33:32 ian - Only get the current working directory if it's going to be needed - - Revision 1.49 1992/02/08 20:33:57 ian - Handle all possible signals raised by abort - - Revision 1.48 1992/02/08 03:54:18 ian - Include <string.h> only in <uucp.h>, added 1992 copyright - - Revision 1.47 1992/02/07 17:08:15 ian - Bob Denny: retry time not reached is not an error - - Revision 1.46 1992/01/29 18:37:27 ian - Patrick Smith: only wait a short time for the hangup message - - Revision 1.45 1992/01/28 04:34:10 ian - Marty Shannon: -f uucp flag not handled correctly - - Revision 1.44 1992/01/28 03:50:42 ian - Chip Salzenberg: set .Status correctly if wrong time to call - - Revision 1.43 1992/01/21 19:39:12 ian - Chip Salzenberg: uucp and uux start uucico for right system, not any - - Revision 1.42 1992/01/20 16:44:54 ian - Marty Shannon: update .Status file if it's the wrong time to call - - Revision 1.41 1992/01/19 02:27:00 ian - Marty Shannon: update .Status file on incoming calls - - Revision 1.40 1992/01/18 22:48:53 ian - Reworked sending of mail and general handling of failed transfers - - Revision 1.39 1992/01/15 07:06:29 ian - Set configuration directory in Makefile rather than sysdep.h - - Revision 1.38 1992/01/14 04:38:43 ian - Chip Salzenberg: only declare sportinfo if it will be used - - Revision 1.37 1992/01/12 19:53:05 ian - John Antypas: pass in sportinfo structure for fdo_call to use - - Revision 1.36 1992/01/05 03:09:17 ian - Changed abProgram and abVersion to non const to avoid compiler bug - - Revision 1.35 1992/01/04 21:53:36 ian - Start up uuxqt even if a call fails - - Revision 1.34 1991/12/31 19:43:13 ian - Added 'e' protocol - - Revision 1.33 1991/12/28 04:33:09 ian - Set fmasterdone correctly in slave mode - - Revision 1.32 1991/12/23 05:15:54 ian - David Nugent: set debugging level for a specific system - - Revision 1.31 1991/12/21 23:10:43 ian - Terry Gardner: record failed file transfers in statistics file - - Revision 1.30 1991/12/21 22:17:20 ian - Change protocol ordering to 't', 'g', 'f' - - Revision 1.29 1991/12/21 22:07:47 ian - John Theus: don't warn if port file does not exist - - Revision 1.28 1991/12/20 04:30:24 ian - Terry Gardner: record conversation time in log file - - Revision 1.27 1991/12/20 00:42:24 ian - Clear user name from error message given by getting next command - - Revision 1.26 1991/12/18 05:12:00 ian - Added -l option to uucico to prompt for login name once and then exit - - Revision 1.25 1991/12/18 03:54:14 ian - Made error messages to terminal appear more normal - - Revision 1.24 1991/12/17 04:55:01 ian - David Nugent: ignore SIGHUP in uucico and uuxqt - - Revision 1.23 1991/12/15 03:42:33 ian - Added tprocess_chat_cmd for all chat commands, and added CMDTABTYPE_PREFIX - - Revision 1.22 1991/12/11 03:59:19 ian - Create directories when necessary; don't just assume they exist - - Revision 1.21 1991/11/21 22:17:06 ian - Add version string, print version when printing usage - - Revision 1.20 1991/11/16 00:33:28 ian - Remove ?: operator between string literal and variable - - Revision 1.19 1991/11/14 03:40:10 ian - Try to figure out whether stdin is a TCP port - - Revision 1.18 1991/11/14 03:20:13 ian - Added seven-bit and reliable commands to help when selecting protocols - - Revision 1.17 1991/11/13 23:08:40 ian - Expand remote pathnames in uucp and uux; fix up uux special cases - - Revision 1.16 1991/11/12 19:47:04 ian - Add called-chat set of commands to run a chat script on an incoming call - - Revision 1.15 1991/11/12 18:25:33 ian - Added 't' protocol - - Revision 1.14 1991/11/11 23:47:24 ian - Added chat-program to run a program to do a chat script - - Revision 1.13 1991/11/11 19:32:03 ian - Added breceive_char to read characters through protocol buffering - - Revision 1.12 1991/11/11 18:55:52 ian - Get protocol parameters from port and dialer for incoming calls - - Revision 1.11 1991/11/11 16:59:05 ian - Eliminate fread_port_info, allow NULL pflock arg to ffind_port - - Revision 1.10 1991/11/11 04:21:16 ian - Added 'f' protocol - - Revision 1.9 1991/11/10 19:24:22 ian - Added pffile protocol entry point for file level control - - Revision 1.8 1991/11/09 18:53:07 ian - Reworked protocol interface - - Revision 1.7 1991/11/07 18:15:38 ian - Chip Salzenberg: move CMAXRETRIES to conf.h for easy configuration - - Revision 1.6 1991/09/19 03:06:04 ian - Chip Salzenberg: put BNU temporary files in system's directory - - Revision 1.5 1991/09/19 02:30:37 ian - From Chip Salzenberg: check whether signal is ignored differently - - Revision 1.4 1991/09/19 02:22:44 ian - Chip Salzenberg's patch to allow ";retrytime" at the end of a time string - - Revision 1.3 1991/09/12 05:04:26 ian - Changed sense of \0 return from btime_low_grade on calltimegrade - - Revision 1.2 1991/09/11 02:33:14 ian - Added ffork argument to fsysdep_run - - Revision 1.1 1991/09/10 19:40:31 ian - Initial revision - - */ - -#include "uucp.h" - -#if USE_RCS_ID -char uucico_rcsid[] = "$Id: uucico.c,v 1.1.1.1 1993/03/21 09:45:37 cgd Exp $"; -#endif - -#include <ctype.h> - -#include "getopt.h" - -#include "port.h" -#include "prot.h" -#include "system.h" -#include "uutime.h" - -/* The program name. */ -char abProgram[] = "uucico"; - -/* Define the known protocols. - bname, ffullduplex, qcmds, pfstart, pfshutdown, pfsendcmd, pzgetspace, - pfsenddata, pfprocess, pfwait, pffile */ - -static struct sprotocol asProtocols[] = -{ - { 't', FALSE, RELIABLE_ENDTOEND | RELIABLE_RELIABLE | RELIABLE_EIGHT, - asTproto_params, ftstart, ftshutdown, ftsendcmd, ztgetspace, - ftsenddata, ftprocess, ftwait, ftfile }, - { 'e', FALSE, RELIABLE_ENDTOEND | RELIABLE_RELIABLE | RELIABLE_EIGHT, - asEproto_params, festart, feshutdown, fesendcmd, zegetspace, - fesenddata, feprocess, fewait, fefile }, - { 'g', FALSE, RELIABLE_EIGHT, - asGproto_params, fgstart, fgshutdown, fgsendcmd, zggetspace, - fgsenddata, fgprocess, fgwait, NULL }, - { 'f', FALSE, RELIABLE_RELIABLE, - asFproto_params, ffstart, ffshutdown, ffsendcmd, zfgetspace, - ffsenddata, ffprocess, ffwait, fffile }, -}; - -#define CPROTOCOLS (sizeof asProtocols / sizeof asProtocols[0]) - -/* Locked system. */ - -static boolean fLocked_system; -static struct ssysteminfo sLocked_system; - -/* Local functions. */ - -static void uusage P((void)); -static void uabort P((void)); -static boolean fcall P((const struct ssysteminfo *qsys, - struct sport *qport, - boolean fforce, int bgrade, - boolean fnodetach)); -static boolean fdo_call P((const struct ssysteminfo *qsys, - struct sport *qport, - struct sstatus *qstat, int cretry, - boolean *pfcalled, struct sport *quse)); -static boolean fcall_failed P((const struct ssysteminfo *qsys, - enum tstatus_type twhy, - struct sstatus *qstat, int cretry)); -static boolean flogin_prompt P((struct sport *qport)); -static boolean faccept_call P((const char *zlogin, struct sport *qport, - const struct ssysteminfo **pqsys)); -static boolean fuucp P((boolean fmaster, const struct ssysteminfo *qsys, - int bgrade, boolean fnew, long cmax_receive)); -static boolean fdo_xcmd P((const struct ssysteminfo *qsys, - boolean fcaller, - const struct scmd *qcmd)); -static boolean fok_to_send P((const char *zfrom, boolean flocal, - boolean fcaller, boolean fspool, - const struct ssysteminfo *qsys, - const char *zuser)); -static boolean fok_to_receive P((const char *zto, boolean flocal, - boolean fcaller, - const struct ssysteminfo *qsys, - const char *zuser)); -static boolean frequest_ok P((boolean flocal, boolean fcaller, - const struct ssysteminfo *qsys, - const char *zuser)); -static boolean fsend_uucp_cmd P((const char *z)); -static const char *zget_uucp_cmd P((boolean frequired)); -static const char *zget_typed_line P((void)); - -/* Long getopt options. */ - -static const struct option asLongopts[] = { { NULL, 0, NULL, 0 } }; - -const struct option *_getopt_long_options = asLongopts; - -int -main (argc, argv) - int argc; - char **argv; -{ - /* getopt return value */ - int iopt; - /* Don't detach from controlling terminal. */ - boolean fnodetach = FALSE; - /* Configuration file name */ - const char *zconfig = NULL; - /* System to call */ - const char *zsystem = NULL; - /* Port to use; in master mode, call out on this port. In slave mode, - accept logins on this port. If port not specified, then in master - mode figure it out for each system, and in slave mode use stdin and - stdout. */ - const char *zport = NULL; - /* Port information for the port name in zport. */ - struct sport sportinfo; - /* Pointer to port to use, or NULL if unknown. */ - struct sport *qport; - /* Whether to start uuxqt when done. */ - boolean fuuxqt = TRUE; - /* Whether to force a call despite status of previous call */ - boolean fforce = FALSE; - /* Whether we are the master */ - boolean fmaster = FALSE; - /* Whether to give a single login prompt. */ - boolean flogin = FALSE; - /* Whether to do an endless loop of accepting calls */ - boolean floop = FALSE; - /* Whether to wait for an inbound call after doing an outbound call */ - boolean fwait = FALSE; - boolean fret = TRUE; -#if DEBUG > 1 - int iholddebug; -#endif - - while ((iopt = getopt (argc, argv, - "DefI:lp:qr:s:S:u:x:X:w")) != EOF) - { - switch (iopt) - { - case 'D': - /* Don't detach from controlling terminal. */ - fnodetach = TRUE; - break; - - case 'e': - /* Do an endless loop of accepting calls. */ - floop = TRUE; - break; - - case 'f': - /* Force a call even if it hasn't been long enough since the last - failed call. */ - fforce = TRUE; - break; - - case 'I': - /* Set configuration file name (default is in sysdep.h). */ - zconfig = optarg; - break; - - case 'l': - /* Prompt for login name and password. */ - flogin = TRUE; - break; - - case 'p': - /* Port to use */ - zport = optarg; - break; - - case 'q': - /* Don't start uuxqt. */ - fuuxqt = FALSE; - break; - - case 'r': - /* Set mode: -r1 for master, -r0 for slave (default) */ - if (optarg[0] == '1' && optarg[1] == '\0') - fmaster = TRUE; - else if (optarg[0] == '0' && optarg[1] == '\0') - fmaster = FALSE; - else - uusage (); - break; - - case 's': - /* Set system name */ - zsystem = optarg; - fmaster = TRUE; - break; - - case 'S': - /* Set system name and force call like -f */ - zsystem = optarg; - fforce = TRUE; - fmaster = TRUE; - break; - - case 'u': - /* Some versions of uucpd invoke uucico with a -u argument - specifying the login name. I'm told it is safe to ignore - this value, although perhaps we should use it rather than - zsysdep_login_name (). */ - break; - - case 'x': - case 'X': -#if DEBUG > 1 - /* Set debugging level */ - iDebug |= idebug_parse (optarg); -#endif - break; - - case 'w': - /* Call out and then wait for a call in */ - fwait = TRUE; - break; - - case 0: - /* Long option found, and flag value set. */ - break; - - default: - uusage (); - break; - } - } - - if (optind != argc) - uusage (); - - if (fwait && zport == NULL) - { - fprintf (stderr, "%s: -w requires -e\n", abProgram); - uusage (); - } - - uread_config (zconfig); - -#ifdef SIGINT - usysdep_signal (SIGINT); -#endif -#ifdef SIGHUP - usysdep_signal (SIGHUP); -#endif -#ifdef SIGQUIT - usysdep_signal (SIGQUIT); -#endif -#ifdef SIGTERM - usysdep_signal (SIGTERM); -#endif -#ifdef SIGPIPE - usysdep_signal (SIGPIPE); -#endif - - usysdep_initialize (TRUE, FALSE); - - ulog_to_file (TRUE); - ulog_fatal_fn (uabort); - - /* If a port was named, get its information. */ - if (zport == NULL) - qport = NULL; - else - { - if (! ffind_port (zport, (long) 0, (long) 0, &sportinfo, - (boolean (*) P((struct sport *, boolean))) NULL, - FALSE)) - { - ulog (LOG_ERROR, "%s: No such port", zport); - ulog_close (); - usysdep_exit (FALSE); - } - qport = &sportinfo; - } - - if (fmaster) - { - /* If a system was named, call it up. Otherwise check all the - known systems, and call all the ones which have work to do. */ - if (zsystem != NULL) - { - if (! fread_system_info (zsystem, &sLocked_system)) - ulog (LOG_FATAL, "Unknown system %s", zsystem); - - /* Detach from the controlling terminal for the call. This - probably makes sense only on Unix. We want the modem - line to become the controlling terminal. */ - if (! fnodetach && - (qport == NULL || qport->ttype != PORTTYPE_STDIN)) - usysdep_detach (); - - ulog_system (sLocked_system.zname); - -#if DEBUG > 1 - iholddebug = iDebug; - iDebug |= sLocked_system.idebug; -#endif - - if (! fsysdep_lock_system (&sLocked_system)) - { - ulog (LOG_ERROR, "System already locked"); - fret = FALSE; - } - else - { - fLocked_system = TRUE; - fret = fcall (&sLocked_system, qport, fforce, BGRADE_HIGH, - fnodetach); - (void) fsysdep_unlock_system (&sLocked_system); - fLocked_system = FALSE; - } - -#if DEBUG > 1 - iDebug = iholddebug; -#endif - - ulog_system ((const char *) NULL); - } - else - { - int csystems; - struct ssysteminfo *pas; - int i; - char bgrade; - boolean fdidone; - - fret = TRUE; - fdidone = FALSE; - uread_all_system_info (&csystems, &pas); - for (i = 0; i < csystems && ! FGOT_SIGNAL (); i++) - { - if (fsysdep_has_work (&pas[i], &bgrade)) - { - fdidone = TRUE; - - /* Detach from the controlling terminal. On Unix - this means that we will wind up forking a new - process for each system we call. */ - if (! fnodetach - && (qport == NULL - || qport->ttype != PORTTYPE_STDIN)) - usysdep_detach (); - - ulog_system (pas[i].zname); - -#if DEBUG > 1 - iholddebug = iDebug; - iDebug |= pas[i].idebug; -#endif - - if (! fsysdep_lock_system (&pas[i])) - { - ulog (LOG_ERROR, "System already locked"); - fret = FALSE; - } - else - { - sLocked_system = pas[i]; - fLocked_system = TRUE; - if (! fcall (&pas[i], qport, fforce, bgrade, - fnodetach)) - fret = FALSE; - - /* Now ignore any SIGHUP that we got. */ - afSignal[INDEXSIG_SIGHUP] = FALSE; - - (void) fsysdep_unlock_system (&pas[i]); - fLocked_system = FALSE; - } - -#if DEBUG > 1 - iDebug = iholddebug; -#endif - - ulog_system ((const char *) NULL); - } - } - - if (! fdidone) - ulog (LOG_NORMAL, "No work"); - } - - /* If requested, wait for calls after dialing out. */ - if (fwait) - { - floop = TRUE; - fmaster = FALSE; - } - } - - if (! fmaster) - { - /* If a port was specified by name, we go into endless loop - mode. In this mode, we wait for calls and prompt them with - "login:" and "Password:", so that they think we are a regular - UNIX system. If we aren't in endless loop mode, we have been - called by some other system. If flogin is TRUE, we prompt - with "login:" and "Password:" a single time. */ - - fret = TRUE; - zsystem = NULL; - - if (qport != NULL) - { - /* Detach from the controlling terminal, so that the port we - are about to use becomes our controlling terminal. */ - if (! fnodetach && qport->ttype != PORTTYPE_STDIN) - usysdep_detach (); - - floop = TRUE; - if (! fport_lock (qport, TRUE)) - { - ulog (LOG_ERROR, "Port %s is locked", qport->zname); - fret = FALSE; - } - } - - if (fret) - { - if (! fport_open (qport, (long) 0, (long) 0, TRUE)) - fret = FALSE; - } - - if (fret) - { - if (floop) - { - while (! FGOT_SIGNAL () && flogin_prompt (qport)) - { - /* Now ignore any SIGHUP that we got. */ - afSignal[INDEXSIG_SIGHUP] = FALSE; - - if (fLocked_system) - { - (void) fsysdep_unlock_system (&sLocked_system); - fLocked_system = FALSE; - } - if (! fport_reset ()) - break; - } - fret = FALSE; - } - else - { - if (flogin) - fret = flogin_prompt (qport); - else - { - const struct ssysteminfo *qsys; - -#if DEBUG > 1 - iholddebug = iDebug; -#endif - fret = faccept_call (zsysdep_login_name (), qport, - &qsys); - if (qsys != NULL) - zsystem = qsys->zname; -#if DEBUG > 1 - iDebug = iholddebug; -#endif - } - } - - (void) fport_close (fret); - - if (fLocked_system) - { - (void) fsysdep_unlock_system (&sLocked_system); - fLocked_system = FALSE; - } - } - } - - ulog_close (); - ustats_close (); - - /* If we got a SIGTERM, perhaps because the system is going down, - don't run uuxqt. We go ahead and run it for any other signal, - since I think they indicate more temporary conditions. */ - if (afSignal[INDEXSIG_SIGTERM]) - fuuxqt = FALSE; - - if (fuuxqt) - { - /* Detach from the controlling terminal before starting up uuxqt, - so that it runs as a true daemon. */ - if (! fnodetach) - usysdep_detach (); - if (zsystem == NULL) - fret = fsysdep_run (FALSE, "uuxqt", (const char *) NULL, - (const char *) NULL); - else - fret = fsysdep_run (FALSE, "uuxqt", "-s", zsystem); - } - - usysdep_exit (fret); - - /* Avoid complaints about not returning. */ - return 0; -} - -/* Print out a usage message. */ - -static void -uusage () -{ - fprintf (stderr, - "Taylor UUCP version %s, copyright (C) 1991, 1992 Ian Lance Taylor\n", - abVersion); - fprintf (stderr, - "Usage: uucico [options]\n"); - fprintf (stderr, - " -s,-S system: Call system (-S implies -f)\n"); - fprintf (stderr, - " -f: Force call despite system status\n"); - fprintf (stderr, - " -r state: 1 for master, 0 for slave (default)\n"); - fprintf (stderr, - " -p port: Specify port (implies -e)\n"); - fprintf (stderr, - " -l: prompt for login name and password\n"); - fprintf (stderr, - " -e: Endless loop of login prompts and daemon execution\n"); - fprintf (stderr, - " -w: After calling out, wait for incoming calls\n"); - fprintf (stderr, - " -q: Don't start uuxqt when done\n"); - fprintf (stderr, - " -x,-X debug: Set debugging level\n"); -#if HAVE_TAYLOR_CONFIG - fprintf (stderr, - " -I file: Set configuration file to use (default %s%s)\n", - NEWCONFIGLIB, CONFIGFILE); -#endif /* HAVE_TAYLOR_CONFIG */ - - exit (EXIT_FAILURE); -} - -/* This function is called when a LOG_FATAL error occurs. */ - -static void -uabort () -{ - ustats_failed (); - -#if ! HAVE_BNU_LOGGING - /* When using BNU logging, it's a pain to have no system name. */ - ulog_system ((const char *) NULL); -#endif - - ulog_user ((const char *) NULL); - - if (qPort != NULL) - (void) fport_close (FALSE); - - if (fLocked_system) - { - (void) fsysdep_unlock_system (&sLocked_system); - fLocked_system = FALSE; - } - - ulog_close (); - ustats_close (); - - usysdep_exit (FALSE); -} - -/* Call another system, trying all the possible sets of calling - instructions. The fprepare_call function should already have been - called. The qsys argument is the system to call. The qport - argument is the port to use, and may be NULL. If the fforce - argument is TRUE, a call is forced even if not enough time has - passed since the last failed call. The bgrade argument is the - highest grade of work to be done for the system. The qstat - argument holds the status of the system. */ - -static boolean fcall (qsys, qport, fforce, bgrade, fnodetach) - const struct ssysteminfo *qsys; - struct sport *qport; - boolean fforce; - int bgrade; - boolean fnodetach; -{ - boolean fbadtime, fnevertime; - const struct ssysteminfo *qorigsys; - struct sstatus sstat; - - qorigsys = qsys; - if (! fsysdep_get_status (qorigsys, &sstat)) - return FALSE; - - /* Make sure it's been long enough since the last failed call. */ - if (! fforce) - { -#ifdef CMAXRETRIES -#if CMAXRETRIES > 0 - if (sstat.cretries >= CMAXRETRIES) - { - ulog (LOG_ERROR, "Too many retries"); - return FALSE; - } -#endif /* CMAXRETRIES > 0 */ -#endif /* defined (CMAXRETRIES) */ - - if (sstat.ttype != STATUS_COMPLETE - && sstat.ilast + sstat.cwait > isysdep_time ((long *) NULL)) - { - ulog (LOG_NORMAL, "Retry time not reached"); - return FALSE; - } - } - - fbadtime = TRUE; - fnevertime = TRUE; - - do - { - struct sspan *qtime; - const struct ssysteminfo *qnext; - - qtime = qtimegrade_parse (qsys->ztime); - if (qtime != NULL) - { - long ival; - int cretry; - boolean fmatch; - - fnevertime = FALSE; - - /* The value returned in ival by fspan_match is the lowest - grade which may be done at this time. */ - - fmatch = (ftimespan_match (qtime, &ival, &cretry) - && igradecmp (bgrade, (int) ival) <= 0); - - utimespan_free (qtime); - - if (fmatch) - { - boolean fret, fcalled; - struct sport sportinfo; - - if (FGOT_SIGNAL ()) - return FALSE; - - fbadtime = FALSE; - - fret = fdo_call (qsys, qport, &sstat, cretry, &fcalled, - &sportinfo); - (void) fport_close (fret); - - if (fret) - return TRUE; - if (fcalled) - return FALSE; - - /* Now we have to dump that port so that we can aquire a - new one. */ - if (! fnodetach) - usysdep_detach (); - } - } - - /* Look for the next alternate with different calling - instructions. */ - qnext = qsys; - do - { - qnext = qnext->qalternate; - } - while (qnext != NULL - && qsys->ztime == qnext->ztime - && qsys->zport == qnext->zport - && qsys->qport == qnext->qport - && qsys->ibaud == qnext->ibaud - && qsys->zphone == qnext->zphone - && qsys->schat.zprogram == qnext->schat.zprogram - && qsys->schat.zchat == qnext->schat.zchat); - - qsys = qnext; - } - while (qsys != NULL); - - if (fbadtime) - { - ulog (LOG_ERROR, "Wrong time to call"); - - /* Update the status, unless the system can never be called. If - the system can never be called, there is little point to - putting in a ``wrong time to call'' message. We don't change - the number of retries, although we do set the wait until the - next retry to 0. */ - if (! fnevertime) - { - sstat.ttype = STATUS_WRONG_TIME; - sstat.ilast = isysdep_time ((long *) NULL); - sstat.cwait = 0; - (void) fsysdep_set_status (qorigsys, &sstat); - } - } - - return FALSE; -} - -/* Do the actual work of calling another system, such as dialing and - logging in. The qsys argument is the system to call, the qport - argument is the port to use, and the qstat argument holds the - current status of the ssystem. If we log in successfully, set - *pfcalled to TRUE; this is used to distinguish a failed dial from a - failure during the call. The quse argument is passed in because - this function does not call fport_close, so if it reads in a port - structure to open it must not keep it on the stack. */ - -static boolean fdo_call (qsys, qport, qstat, cretry, pfcalled, quse) - const struct ssysteminfo *qsys; - struct sport *qport; - struct sstatus *qstat; - int cretry; - boolean *pfcalled; - struct sport *quse; -{ - const char *zstr; - boolean fnew; - int cdial_proto_params; - struct sproto_param *qdial_proto_params; - int idial_reliable; - long istart_time; - - *pfcalled = FALSE; - - /* If no port was specified on the command line, use any port - defined for the system. To select the system port: 1) see if - port information was specified directly; 2) see if a port was - named; 3) get an available port given the baud rate. We don't - change the system status if a port is unavailable; i.e. we don't - force the system to wait for the retry time. */ - - if (qport == NULL) - qport = qsys->qport; - if (qport != NULL) - { - if (! fport_lock (qport, FALSE)) - { - ulog (LOG_ERROR, "Port \"%s\" already locked", qport->zname); - return FALSE; - } - } - else - { - if (! ffind_port (qsys->zport, qsys->ibaud, qsys->ihighbaud, - quse, fport_lock, TRUE)) - return FALSE; - qport = quse; - /* The port is locked by ffind_port. */ - } - - /* Now try to call the system. */ - - if (! fport_open (qport, qsys->ibaud, qsys->ihighbaud, FALSE)) - { - (void) fcall_failed (qsys, STATUS_PORT_FAILED, qstat, cretry); - return FALSE; - } - - if (qsys->zalternate == NULL) - ulog (LOG_NORMAL, "Calling system %s (port %s)", qsys->zname, - zLdevice == NULL ? "unknown" : zLdevice); - else - ulog (LOG_NORMAL, "Calling system %s (alternate %s, port %s)", - qsys->zname, qsys->zalternate, - zLdevice == NULL ? "unknown" : zLdevice); - - cdial_proto_params = 0; - qdial_proto_params = NULL; - if (! fport_dial (qsys, &cdial_proto_params, &qdial_proto_params, - &idial_reliable)) - { - (void) fcall_failed (qsys, STATUS_DIAL_FAILED, qstat, cretry); - return FALSE; - } - - if (! fchat (&qsys->schat, qsys, (const struct sdialer *) NULL, - (const char *) NULL, FALSE, qPort->zname, iport_baud ())) - { - (void) fcall_failed (qsys, STATUS_LOGIN_FAILED, qstat, cretry); - return FALSE; - } - - qstat->ttype = STATUS_TALKING; - qstat->ilast = isysdep_time ((long *) NULL); - qstat->cretries = 0; - qstat->cwait = 0; - if (! fsysdep_set_status (qsys, qstat)) - return FALSE; - - ulog (LOG_NORMAL, "Login successful"); - - *pfcalled = TRUE; - istart_time = isysdep_time ((long *) NULL); - - /* We should now see "Shere" from the other system. Apparently - some systems send "Shere=foo" where foo is the remote name. */ - - zstr = zget_uucp_cmd (TRUE); - if (zstr == NULL) - { - (void) fcall_failed (qsys, STATUS_HANDSHAKE_FAILED, qstat, cretry); - return FALSE; - } - - if (strncmp (zstr, "Shere", 5) != 0) - { - (void) fcall_failed (qsys, STATUS_HANDSHAKE_FAILED, qstat, cretry); - ulog (LOG_ERROR, "Bad initialization string"); - return FALSE; - } - - if (zstr[5] == '=') - { - const char *zheresys; - int icmp; - - /* Some UUCP packages only provide seven characters in the Shere - machine name. */ - zheresys = zstr + 6; - if (strlen (zheresys) == 7) - icmp = strncmp (zheresys, qsys->zname, 7); - else - icmp = strcmp (zheresys, qsys->zname); - if (icmp != 0) - { - (void) fcall_failed (qsys, STATUS_HANDSHAKE_FAILED, qstat, - cretry); - ulog (LOG_ERROR, "Called wrong system (%s)", zheresys); - return FALSE; - } - } -#if DEBUG > 1 - else if (zstr[5] != '\0') - DEBUG_MESSAGE1 (DEBUG_HANDSHAKE, - "fdo_call: Strange Shere: %s", zstr); -#endif - - /* We now send "S" name switches, where name is our UUCP name. If - we are using sequence numbers with this system, we send a -Q - argument with the sequence number. If the call-timegrade command - was used, we send a -p argument and a -vgrade= argument with the - grade to send us (we send both argument to make it more likely - that one is recognized). We always send a -N (for new) switch to - indicate that we are prepared to accept file sizes. */ - { - char bgrade; - const char *zuse_local; - char *zsend; - - /* Determine the grade we should request of the other system. A - '\0' means that no restrictions have been made. */ - bgrade = btimegrade (qsys->zcalltimegrade); - - if (qsys->zlocalname != NULL) - zuse_local = qsys->zlocalname; - else - zuse_local = zLocalname; - - zsend = (char *) alloca (strlen (zuse_local) + 70); - if (! qsys->fsequence) - { - if (bgrade == '\0') - sprintf (zsend, "S%s -N", zuse_local); - else - sprintf (zsend, "S%s -p%c -vgrade=%c -N", zuse_local, bgrade, - bgrade); - } - else - { - long iseq; - - iseq = isysdep_get_sequence (qsys); - if (iseq < 0) - { - (void) fcall_failed (qsys, STATUS_HANDSHAKE_FAILED, qstat, - cretry); - return FALSE; - } - if (bgrade == '\0') - sprintf (zsend, "S%s -Q%ld -N", zuse_local, iseq); - else - sprintf (zsend, "S%s -Q%ld -p%c -vgrade=%c -N", zuse_local, iseq, - bgrade, bgrade); - } - - if (! fsend_uucp_cmd (zsend)) - { - (void) fcall_failed (qsys, STATUS_HANDSHAKE_FAILED, qstat, - cretry); - return FALSE; - } - } - - /* Now we should see ROK or Rreason where reason gives a cryptic - reason for failure. If we are talking to a counterpart, we will - get back ROKN. */ - zstr = zget_uucp_cmd (TRUE); - if (zstr == NULL) - { - (void) fcall_failed (qsys, STATUS_HANDSHAKE_FAILED, qstat, cretry); - return FALSE; - } - - if (zstr[0] != 'R') - { - (void) fcall_failed (qsys, STATUS_HANDSHAKE_FAILED, qstat, cretry); - ulog (LOG_ERROR, "Bad reponse to handshake string (%s)", - zstr); - return FALSE; - } - - if (strcmp (zstr + 1, "OKN") == 0) - fnew = TRUE; - else if (strcmp (zstr + 1, "OK") == 0) - fnew = FALSE; - else if (strcmp (zstr + 1, "CB") == 0) - { - ulog (LOG_NORMAL, "Remote system will call back"); - qstat->ttype = STATUS_COMPLETE; - (void) fsysdep_set_status (qsys, qstat); - return TRUE; - } - else - { - (void) fcall_failed (qsys, STATUS_HANDSHAKE_FAILED, qstat, cretry); - ulog (LOG_ERROR, "Handshake failed (%s)", zstr + 1); - return FALSE; - } - - /* The slave should now send \020Pprotos\0 where protos is a list of - supported protocols. Each protocol is a single character. */ - - zstr = zget_uucp_cmd (TRUE); - if (zstr == NULL) - { - (void) fcall_failed (qsys, STATUS_HANDSHAKE_FAILED, qstat, cretry); - return FALSE; - } - - if (zstr[0] != 'P') - { - (void) fcall_failed (qsys, STATUS_HANDSHAKE_FAILED, qstat, cretry); - ulog (LOG_ERROR, "Bad protocol handshake (%s)", zstr); - return FALSE; - } - - /* Now decide which protocol to use. The system and the port may - have their own list of protocols. */ - { - int i; - char ab[5]; - - i = CPROTOCOLS; - if (qsys->zprotocols != NULL || qPort->zprotocols != NULL) - { - const char *zproto; - - if (qsys->zprotocols != NULL) - zproto = qsys->zprotocols; - else - zproto = qPort->zprotocols; - for (; *zproto != '\0'; zproto++) - { - if (strchr (zstr + 1, *zproto) != NULL) - { - for (i = 0; i < CPROTOCOLS; i++) - if (asProtocols[i].bname == *zproto) - break; - if (i < CPROTOCOLS) - break; - } - } - } - else - { - int ir; - - /* If neither the system nor the port specified a list of - protocols, we want only protocols that match the known - reliability of the dialer and the port. If we have no - reliability information, we default to a reliable eight bit - connection. */ - - ir = 0; - if ((qPort->ireliable & RELIABLE_SPECIFIED) != 0) - ir = qPort->ireliable; - if ((idial_reliable & RELIABLE_SPECIFIED) != 0) - { - if (ir != 0) - ir &= idial_reliable; - else - ir = idial_reliable; - } - if (ir == 0) - ir = RELIABLE_RELIABLE | RELIABLE_EIGHT | RELIABLE_SPECIFIED; - - for (i = 0; i < CPROTOCOLS; i++) - { - int ipr; - - ipr = asProtocols[i].ireliable; - if ((ipr & ir) != ipr) - continue; - if (strchr (zstr + 1, asProtocols[i].bname) != NULL) - break; - } - } - - if (i >= CPROTOCOLS) - { - (void) fsend_uucp_cmd ("UN"); - (void) fcall_failed (qsys, STATUS_HANDSHAKE_FAILED, qstat, cretry); - ulog (LOG_ERROR, "No mutually supported protocols"); - return FALSE; - } - - qProto = &asProtocols[i]; - - sprintf (ab, "U%c", qProto->bname); - if (! fsend_uucp_cmd (ab)) - { - (void) fcall_failed (qsys, STATUS_HANDSHAKE_FAILED, qstat, cretry); - return FALSE; - } - } - - /* Run any protocol parameter commands. */ - - if (qProto->qcmds != NULL) - { - if (qsys->cproto_params != 0) - uapply_proto_params (qProto->bname, qProto->qcmds, - qsys->cproto_params, qsys->qproto_params); - if (qPort->cproto_params != 0) - uapply_proto_params (qProto->bname, qProto->qcmds, - qPort->cproto_params, qPort->qproto_params); - if (cdial_proto_params != 0) - uapply_proto_params (qProto->bname, qProto->qcmds, - cdial_proto_params, qdial_proto_params); - } - - /* Turn on the selected protocol. */ - - if (! (*qProto->pfstart) (TRUE)) - { - (void) fcall_failed (qsys, STATUS_HANDSHAKE_FAILED, qstat, - cretry); - return FALSE; - } - - /* Now we have succesfully logged in as the master. */ - - ulog (LOG_NORMAL, "Handshake successful"); - - { - boolean fret; - long iend_time; - - fret = fuucp (TRUE, qsys, '\0', fnew, (long) -1); - ulog_user ((const char *) NULL); - usysdep_get_work_free (qsys); - - /* If we jumped out due to an error, shutdown the protocol. */ - if (! fret) - { - (void) (*qProto->pfshutdown) (); - ustats_failed (); - } - - /* Now send the hangup message. As the caller, we send six O's - and expect to receive seven O's. We send the six O's twice - to help the other side. We don't worry about errors here. */ - if (fsend_uucp_cmd ("OOOOOO") - && fsend_uucp_cmd ("OOOOOO")) - { - /* We don't even look for the hangup string from the other - side unless we're in debugging mode. */ -#if DEBUG > 1 - if (fret && FDEBUGGING (DEBUG_HANDSHAKE)) - { - zstr = zget_uucp_cmd (FALSE); - if (zstr != NULL) - { - /* The Ultrix UUCP only sends six O's, although I - think it should send seven. Because of this, we - only check for six. */ - if (strstr (zstr, "OOOOOO") == NULL) - ulog (LOG_DEBUG, "No hangup from remote"); - } - } -#endif - } - - iend_time = isysdep_time ((long *) NULL); - - ulog (LOG_NORMAL, "Call complete (%ld seconds)", - iend_time - istart_time); - - if (! fret) - { - (void) fcall_failed (qsys, STATUS_FAILED, qstat, cretry); - return FALSE; - } - else - { - qstat->ttype = STATUS_COMPLETE; - qstat->ilast = iend_time; - (void) fsysdep_set_status (qsys, qstat); - return TRUE; - } - } -} - -/* A small helper routine to write out the system status when something - goes wrong. */ - -static boolean -fcall_failed (qsys, twhy, qstat, cretry) - const struct ssysteminfo *qsys; - enum tstatus_type twhy; - struct sstatus *qstat; - int cretry; -{ - DEBUG_MESSAGE2 (DEBUG_HANDSHAKE, - "fcall_failed: Cause %d (%s)", (int) twhy, - azStatus[(int) twhy]); - - qstat->ttype = twhy; - qstat->cretries++; - qstat->ilast = isysdep_time ((long *) NULL); - if (cretry == 0) - qstat->cwait = CRETRY_WAIT (qstat->cretries); - else - qstat->cwait = cretry * 60; - return fsysdep_set_status (qsys, qstat); -} - -/* Prompt for a login name and a password, and run as the slave. */ - -static boolean flogin_prompt (qport) - struct sport *qport; -{ - const char *zuser, *zpass; - - DEBUG_MESSAGE0 (DEBUG_HANDSHAKE, "flogin_prompt: Waiting for login"); - - do - { - if (! fport_write ("login: ", sizeof "login: " - 1)) - return FALSE; - zuser = zget_typed_line (); - } - while (zuser != NULL && *zuser == '\0'); - - if (zuser != NULL) - { - char *zhold; - - zhold = (char *) alloca (strlen (zuser) + 1); - strcpy (zhold, zuser); - - if (! fport_write ("Password:", sizeof "Password:" - 1)) - return FALSE; - - zpass = zget_typed_line (); - if (zpass != NULL) - { - if (fcheck_login (zhold, zpass)) - { -#if DEBUG > 1 - int iholddebug; -#endif - - /* We ignore the return value of faccept_call because we - really don't care whether the call succeeded or not. - We are going to reset the port anyhow. */ -#if DEBUG > 1 - iholddebug = iDebug; -#endif - (void) faccept_call (zhold, qport, - (const struct ssysteminfo **) NULL); -#if DEBUG > 1 - iDebug = iholddebug; -#endif - } - } - } - - return TRUE; -} - -/* Accept a call from a remote system. If pqsys is not NULL, *pqsys - will be set to the system that called in if known. */ - -static boolean -faccept_call (zlogin, qport, pqsys) - const char *zlogin; - struct sport *qport; - const struct ssysteminfo **pqsys; -{ - long istart_time; - int cdial_proto_params; - struct sproto_param *qdial_proto_params; - int idial_reliable; - boolean ftcp_port; - const char *zport; - char *zsend, *zspace; - const char *zstr; - struct ssysteminfo ssys; - const struct ssysteminfo *qsys; - boolean fnew; - char bgrade; - const char *zuse_local; - struct sstatus sstat; - long cmax_receive; - boolean frestart; -#if HAVE_TAYLOR_CONFIG - struct sport sportinfo; -#endif - - if (pqsys != NULL) - *pqsys = NULL; - - ulog (LOG_NORMAL, "Incoming call (login %s port %s)", - zlogin == NULL ? "unknown" : zlogin, - zLdevice == NULL ? "unknown" : zLdevice); - - istart_time = isysdep_time ((long *) NULL); - - /* Figure out protocol parameters determined by the port. If no - port was specified we're reading standard input, so try to get - the port name and read information from the port file. We only - use the port information to get protocol parameters; we don't - want to start treating the port as though it were a modem, for - example. */ - - if (qport != NULL) - { - zport = qport->zname; - ftcp_port = FALSE; - } - else - { - zport = zsysdep_port_name (&ftcp_port); - - /* We want to get the protocol parameters for the port. If we - aren't using HAVE_TAYLOR_CONFIG, that information isn't - stored anyhow, so we don't bother to look it up. */ - -#if HAVE_TAYLOR_CONFIG - - if (zport != NULL && zPortfile != NULL) - { - if (ffind_port (zport, (long) 0, (long) 0, &sportinfo, - (boolean (*) P((struct sport *, boolean))) NULL, - FALSE)) - qport = &sportinfo; - } - -#endif /* HAVE_TAYLOR_CONFIG */ - - if (zport == NULL) - zport = "unknown"; - } - - /* If we've managed to figure out that this is a modem port, now try - to get protocol parameters from the dialer. */ - - cdial_proto_params = 0; - qdial_proto_params = NULL; - idial_reliable = 0; - if (qport != NULL) - { - if (qport->ttype == PORTTYPE_MODEM) - { - if (qport->u.smodem.zdialer != NULL) - { - char *zcopy; - char *zdial; - struct sdialer sdialerinfo; - - /* We use the first dialer in the sequence. */ - zcopy = (char *) alloca (strlen (qport->u.smodem.zdialer) - + 1); - strcpy (zcopy, qport->u.smodem.zdialer); - - zdial = strtok (zcopy, " \t"); - if (fread_dialer_info (zdial, &sdialerinfo)) - { - cdial_proto_params = sdialerinfo.cproto_params; - qdial_proto_params = sdialerinfo.qproto_params; - idial_reliable = sdialerinfo.ireliable; - } - } - else if (qport->u.smodem.qdialer != NULL) - { - cdial_proto_params = qport->u.smodem.qdialer->cproto_params; - qdial_proto_params = qport->u.smodem.qdialer->qproto_params; - idial_reliable = qport->u.smodem.qdialer->ireliable; - } - } -#if HAVE_TCP - else if (qport->ttype == PORTTYPE_TCP) - ftcp_port = TRUE; -#endif - } - - /* If it's a TCP port, it's fully reliable. Even if HAVE_TCP is not - supported, zsysdep_port_name may be able to figure this out (not - on Unix, though). */ - if (ftcp_port) - idial_reliable = (RELIABLE_SPECIFIED | RELIABLE_ENDTOEND - | RELIABLE_RELIABLE | RELIABLE_EIGHT); - - /* We have to check to see whether some system uses this login name - to indicate a different local name. Obviously, this means that - any system which uses this login name must expect the alternate - system name. */ - zuse_local = NULL; - if (fUnknown_ok) - { - for (qsys = &sUnknown; qsys != NULL; qsys = qsys->qalternate) - { - if (qsys->zlocalname != NULL - && qsys->zcalled_login != NULL - && strcmp (qsys->zcalled_login, zlogin) == 0) - { - zuse_local = qsys->zlocalname; - break; - } - } - } - if (zuse_local == NULL) - { - struct ssysteminfo *pas; - int isys, csystems; - - zuse_local = zLocalname; - - uread_all_system_info (&csystems, &pas); - for (isys = 0; isys < csystems; isys++) - { - for (qsys = &pas[isys]; qsys != NULL; qsys = qsys->qalternate) - { - if (qsys->zlocalname != NULL - && qsys->zcalled_login != NULL - && strcmp (qsys->zcalled_login, zlogin) == 0) - { - zuse_local = qsys->zlocalname; - break; - } - } - if (qsys != NULL) - break; - } - } - - /* Tell the remote system who we are. */ - zsend = (char *) alloca (strlen (zuse_local) + 10); - sprintf (zsend, "Shere=%s", zuse_local); - if (! fsend_uucp_cmd (zsend)) - return FALSE; - - zstr = zget_uucp_cmd (TRUE); - if (zstr == NULL) - return FALSE; - - if (zstr[0] != 'S') - { - ulog (LOG_ERROR, "Bad introduction string"); - return FALSE; - } - ++zstr; - - zspace = strchr (zstr, ' '); - if (zspace != NULL) - *zspace = '\0'; - if (fread_system_info (zstr, &ssys)) - qsys = &ssys; - else - { - /* We have no information on this system. */ - if (! fUnknown_ok) - { - (void) fsend_uucp_cmd ("RYou are unknown to me"); - ulog (LOG_ERROR, "Call from unknown system %s", zstr); - return FALSE; - } - - /* We have to translate the name to a canonical form for the - benefit of systems which only allow short system names. */ - sUnknown.zname = ztranslate_system (zstr); - if (sUnknown.zname == NULL) - { - (void) fsend_uucp_cmd ("RYou are unknown to me"); - return FALSE; - } - - qsys = &sUnknown; - } - - if (pqsys != NULL) - *pqsys = qsys; - - if (! fcheck_validate (zlogin, qsys->zname)) - { - (void) fsend_uucp_cmd ("RLOGIN"); - ulog (LOG_ERROR, "System %s used wrong login name %s", - zstr, zlogin); - return FALSE; - } - - if (qsys->zcalled_login != NULL) - { - const struct ssysteminfo *qany; - - /* Choose an alternate system definition based on the - login name. */ - qany = NULL; - for (; qsys != NULL; qsys = qsys->qalternate) - { - if (qsys->zcalled_login != NULL) - { - if (qany == NULL - && strcmp (qsys->zcalled_login, "ANY") == 0) - qany = qsys; - else if (strcmp (qsys->zcalled_login, zlogin) == 0) - break; - } - } - - if (qsys == NULL) - { - if (qany == NULL) - { - (void) fsend_uucp_cmd ("RLOGIN"); - ulog (LOG_ERROR, "System %s used wrong login name %s", - zstr, zlogin); - return FALSE; - } - qsys = qany; - } - } - - ulog_system (qsys->zname); - -#if DEBUG > 1 - iDebug |= qsys->idebug; -#endif - - /* See if we are supposed to call the system back. This will queue - up an empty command. It would be better to actually call back - directly at this point as well. */ - if (qsys->fcallback) - { - (void) fsend_uucp_cmd ("RCB"); - ulog (LOG_NORMAL, "Will call back"); - (void) zsysdep_spool_commands (qsys, BGRADE_HIGH, 0, - (const struct scmd *) NULL); - return TRUE; - } - - /* We only permit one call at a time from a remote system. Lock it. */ - if (! fsysdep_lock_system (qsys)) - { - (void) fsend_uucp_cmd ("RLCK"); - ulog (LOG_ERROR, "System already locked"); - return FALSE; - } - sLocked_system = *qsys; - fLocked_system = TRUE; - - /* Set the system status. We don't really care if we can't get the - earlier status. We also don't want to kill the conversation just - because we can't output the .Status file, so we ignore any - errors. */ - if (! fsysdep_get_status (qsys, &sstat)) - { - sstat.cretries = 0; - sstat.cwait = 0; - } - - sstat.ttype = STATUS_TALKING; - sstat.ilast = isysdep_time ((long *) NULL); - (void) fsysdep_set_status (qsys, &sstat); - - /* Check the arguments of the remote system. We accept -x# to set - our debugging level and -Q# for a sequence number. We may insist - on a sequence number. The -p and -vgrade= arguments are taken to - specify the lowest job grade that we should transfer; I think - this is the traditional meaning, but I don't know. The -N switch - means that we are talking to another instance of ourselves. The - -U switch specifies the ulimit of the remote system, which we - treat as the maximum file size that may be sent. The -R switch - means that the remote system supports file restart; we don't. */ - - fnew = FALSE; - bgrade = BGRADE_LOW; - cmax_receive = (long) -1; - frestart = FALSE; - - if (zspace == NULL) - { - if (qsys->fsequence) - { - (void) fsend_uucp_cmd ("RBADSEQ"); - ulog (LOG_ERROR, "No sequence number (call rejected)"); - sstat.ttype = STATUS_FAILED; - (void) fsysdep_set_status (qsys, &sstat); - return FALSE; - } - } - else - { - ++zspace; - while (isspace (BUCHAR (*zspace))) - ++zspace; - - while (*zspace != '\0') - { - boolean frecognized; - char *znext; - - frecognized = FALSE; - if (*zspace == '-') - { - switch (zspace[1]) - { - case 'x': - frecognized = TRUE; -#if DEBUG > 1 - { - int iwant; - - iwant = atoi (zspace + 2); - if (! fnew) - iwant = (1 << iwant) - 1; - iwant &= qsys->imax_remote_debug; - if ((iDebug | iwant) != iDebug) - { - iDebug |= iwant; - ulog (LOG_NORMAL, "Setting debugging mode to 0%o", - iDebug); - } - } -#endif - break; - case 'Q': - frecognized = TRUE; - { - long iseq; - - if (! qsys->fsequence) - break; - iseq = atol (zspace + 2); - if (iseq != isysdep_get_sequence (qsys)) - { - (void) fsend_uucp_cmd ("RBADSEQ"); - ulog (LOG_ERROR, "Out of sequence call rejected"); - sstat.ttype = STATUS_FAILED; - (void) fsysdep_set_status (qsys, &sstat); - return FALSE; - } - } - break; - case 'p': - /* We don't accept a space between the -p and the - grade, although we should. */ - frecognized = TRUE; - if (FGRADE_LEGAL (zspace[2])) - bgrade = zspace[2]; - break; - case 'v': - if (strncmp (zspace + 1, "vgrade=", - sizeof "vgrade=" - 1) == 0) - { - frecognized = TRUE; - if (FGRADE_LEGAL (zspace[sizeof "vgrade="])) - bgrade = zspace[sizeof "vgrade="]; - } - break; - case 'N': - frecognized = TRUE; - fnew = TRUE; - break; - case 'U': - frecognized = TRUE; - { - long c; - - c = strtol (zspace + 2, (char **) NULL, 0); - if (c > 0) - cmax_receive = c * (long) 512; - } - break; - case 'R': - frecognized = TRUE; - frestart = TRUE; - break; - default: - break; - } - } - - znext = zspace; - while (*znext != '\0' && ! isspace (BUCHAR (*znext))) - ++znext; - - if (! frecognized) - { - int clen; - char *zcopy; - - /* We could just use %.*s for this, but it's probably - not portable. */ - clen = znext - zspace; - zcopy = (char *) alloca (clen + 1); - strncpy (zcopy, zspace, clen); - zcopy[clen] = '\0'; - ulog (LOG_NORMAL, "Unrecognized argument %s", zcopy); - } - - zspace = znext; - while (isspace (BUCHAR (*zspace))) - ++zspace; - } - } - - /* We recognized the system, and the sequence number (if any) was - OK. Send an ROK, and send a list of protocols. If we got the -N - switch, send ROKN to confirm it. */ - - if (! fsend_uucp_cmd (fnew ? "ROKN" : "ROK")) - { - sstat.ttype = STATUS_FAILED; - (void) fsysdep_set_status (qsys, &sstat); - return FALSE; - } - - { - int i; - - if (qsys->zprotocols != NULL || - (qport != NULL && qport->zprotocols != NULL)) - { - const char *zprotos; - - if (qsys->zprotocols != NULL) - zprotos = qsys->zprotocols; - else - zprotos = qport->zprotocols; - zsend = (char *) alloca (strlen (zprotos) + 2); - sprintf (zsend, "P%s", zprotos); - } - else - { - char *zset; - int ir; - - zsend = (char *) alloca (CPROTOCOLS + 2); - zset = zsend; - *zset++ = 'P'; - - /* If the system did not specify a list of protocols, we want - only protocols that match the known reliability of the - dialer and the port. If we have no information, we default - to a reliable eight bit connection. */ - - ir = 0; - if (qport != NULL - && (qport->ireliable & RELIABLE_SPECIFIED) != 0) - ir = qport->ireliable; - if ((idial_reliable & RELIABLE_SPECIFIED) != 0) - { - if (ir != 0) - ir &= idial_reliable; - else - ir = idial_reliable; - } - if (ir == 0) - ir = RELIABLE_RELIABLE | RELIABLE_EIGHT | RELIABLE_SPECIFIED; - - for (i = 0; i < CPROTOCOLS; i++) - { - int ipr; - - ipr = asProtocols[i].ireliable; - if ((ipr & ir) != ipr) - continue; - *zset++ = asProtocols[i].bname; - } - *zset = '\0'; - } - - if (! fsend_uucp_cmd (zsend)) - { - sstat.ttype = STATUS_FAILED; - (void) fsysdep_set_status (qsys, &sstat); - return FALSE; - } - - /* The master will now send back the selected protocol. */ - zstr = zget_uucp_cmd (TRUE); - if (zstr == NULL) - { - sstat.ttype = STATUS_FAILED; - (void) fsysdep_set_status (qsys, &sstat); - return FALSE; - } - - if (zstr[0] != 'U' || zstr[2] != '\0') - { - ulog (LOG_ERROR, "Bad protocol response string"); - sstat.ttype = STATUS_FAILED; - (void) fsysdep_set_status (qsys, &sstat); - return FALSE; - } - - if (zstr[1] == 'N') - { - ulog (LOG_ERROR, "No supported protocol"); - sstat.ttype = STATUS_FAILED; - (void) fsysdep_set_status (qsys, &sstat); - return FALSE; - } - - for (i = 0; i < CPROTOCOLS; i++) - if (asProtocols[i].bname == zstr[1]) - break; - - if (i >= CPROTOCOLS) - { - ulog (LOG_ERROR, "No supported protocol"); - sstat.ttype = STATUS_FAILED; - (void) fsysdep_set_status (qsys, &sstat); - return FALSE; - } - - qProto = &asProtocols[i]; - } - - /* Run the chat script for when a call is received. */ - - if (! fchat (&qsys->scalled_chat, qsys, (const struct sdialer *) NULL, - (const char *) NULL, FALSE, zport, iport_baud ())) - { - sstat.ttype = STATUS_FAILED; - sstat.ilast = isysdep_time ((long *) NULL); - (void) fsysdep_set_status (qsys, &sstat); - return FALSE; - } - - /* Run any protocol parameter commands. There should be a way to - read the dialer information if there is any to permit modem - specific protocol parameters, but for now there isn't. */ - - if (qProto->qcmds != NULL) - { - if (qsys->cproto_params != 0) - uapply_proto_params (qProto->bname, qProto->qcmds, - qsys->cproto_params, qsys->qproto_params); - if (qport != NULL - && qport->cproto_params != 0) - uapply_proto_params (qProto->bname, qProto->qcmds, - qport->cproto_params, qport->qproto_params); - if (cdial_proto_params != 0) - uapply_proto_params (qProto->bname, qProto->qcmds, - cdial_proto_params, qdial_proto_params); - } - - /* Turn on the selected protocol. */ - - if (! (*qProto->pfstart)(FALSE)) - { - sstat.ttype = STATUS_FAILED; - sstat.ilast = isysdep_time ((long *) NULL); - (void) fsysdep_set_status (qsys, &sstat); - return FALSE; - } - - /* If we using HAVE_BNU_LOGGING, then the previous ``incoming call'' - message went to the general log, since we didn't know the system - name at that point. In that case, we repeat the port and login - names. */ -#if HAVE_BNU_LOGGING - if (bgrade == BGRADE_LOW) - ulog (LOG_NORMAL, "Handshake successful (login %s port %s)", - zlogin == NULL ? "unknown" : zlogin, - zLdevice == NULL ? "unknown" : zLdevice); - else - ulog (LOG_NORMAL, "Handshake successful (login %s port %s grade %c)", - zlogin == NULL ? "unknown" : zlogin, - zLdevice == NULL ? "unknown" : zLdevice, - bgrade); -#else /* ! HAVE_BNU_LOGGING */ - if (bgrade == BGRADE_LOW) - ulog (LOG_NORMAL, "Handshake successful"); - else - ulog (LOG_NORMAL, "Handshake successful (grade %c)", bgrade); -#endif /* ! HAVE_BNU_LOGGING */ - - { - boolean fret; - long iend_time; - - fret = fuucp (FALSE, qsys, bgrade, fnew, cmax_receive); - ulog_user ((const char *) NULL); - usysdep_get_work_free (qsys); - - /* If we bombed out due to an error, shut down the protocol. */ - if (! fret) - { - (void) (*qProto->pfshutdown) (); - ustats_failed (); - } - - /* Hangup. As the answerer, we send seven O's and expect to see - six. */ - if (fsend_uucp_cmd ("OOOOOOO") - && fsend_uucp_cmd ("OOOOOOO")) - { - /* We don't even look for the hangup string from the other - side unless we're in debugging mode. */ -#if DEBUG > 1 - if (fret && FDEBUGGING (DEBUG_HANDSHAKE)) - { - zstr = zget_uucp_cmd (FALSE); - if (zstr != NULL) - { - if (strstr (zstr, "OOOOOO") == NULL) - ulog (LOG_DEBUG, "No hangup from remote"); - } - } -#endif - } - - iend_time = isysdep_time ((long *) NULL); - - ulog (LOG_NORMAL, "Call complete (%ld seconds)", - iend_time - istart_time); - if (fret) - sstat.ttype = STATUS_COMPLETE; - else - sstat.ttype = STATUS_FAILED; - sstat.ilast = iend_time; - (void) fsysdep_set_status (qsys, &sstat); - return fret; - } -} - -/* This function runs the main UUCP protocol. It is called when the - two systems have succesfully connected. It transfers files back - and forth until neither system has any more work to do. The - traditional UUCP protocol has a master which sends files to the - slave or requests files from the slave (a single file is requested - with the R command; a wildcarded file name is requested with the X - command). The slave simply obeys the commands of the master. When - the master has done all its work, it requests a hangup. If the - slave has work to do it refuses the hangup and becomes the new - master. - - This is essentially a half-duplex connection, in that files are - only transferred in one direction at a time. This is not - unreasonable, since generally one site is receiving a lot of news - from the other site, and I believe that Telebit modems are - basically half-duplex in that it takes a comparatively long time to - turn the line around. However, it is possible to design a - full-duplex protocol which would be useful in some situtations when - using V.32 (or a network) and this function attempts to support - this possibility. - - Traditionally the work to be done is kept in a set of files whose - names begin with C.[system][grade][pid], where system is the remote - system name, grade is the grade of transfer, and pid makes the file - name unique. Each line in these files is a command, and each line - can be treated independently. We let the system dependent layer - handle all of this. This will let us use some other scheme on - systems in which the fourteen character filename length limit - restricts the name of the remote system to seven characters (the - usual restriction cited is six characters; I do not yet know where - this comes from). - - Here are the types of commands, along with the definitions of the - variables they use in the fuucp function. - - 'S' -- Send a file from master to slave. - zfrom -- master file name - zto -- slave file name - zuser -- user who requested the transfer - zoptions -- list of options - ztemp -- temporary file name on master (used unless option c) - imode -- mode to give file - znotify -- user to notify (if option n) - - The options are: - C -- file copied to spool (use ztemp rather than zfrom) - c -- file not copied to spool (use zfrom rather than ztemp) - d -- create directories if necessary - f -- do not create directories - m -- notify originator (in zuser) when complete - n -- notify recipient (in znotify) when complete - - I assume that the n option is implemented by the remote system. - - 'R' -- Retrieve a file from slave to master. - zfrom -- slave file name - zto -- master file name - zuser -- user who requested the transfer - zoptions -- list of options - - The options are the same as in case 'S', except that option n is - not supported. If zto is a directory, we must create a file in - that directory using the last component of zfrom. - - 'X' -- Execute wildcard transfer from slave to master. - zfrom -- wildcard file name - zto -- local file (hopefully a directory) - zuser -- user who requested the transfer - zoptions -- list of options - - The options are presumably the same as in case 'R'. It may be - permissible to have no zuser or zoptions. The zto name will have - local! prepended to it already (where local is the local system - name). - - This command is merely sent over to the remote system, where it - is executed. When the remote system becomes the master, it sends - the files back. - - 'H' -- Hangup - This is used by the master to indicate a transfer of control. If - slave has nothing to do, it responds with HY and the conversation - is finished. Otherwise, the slave becomes the master, and - vice-versa. */ - -static boolean -fuucp (fmaster, qsys, bgrade, fnew, cmax_receive) - boolean fmaster; - const struct ssysteminfo *qsys; - int bgrade; - boolean fnew; - long cmax_receive; -{ - boolean fcaller, fmasterdone, fnowork; - const char *zlocal_size, *zremote_size; - long clocal_size, cremote_size, cmax_ever; - - fcaller = fmaster; - - fmasterdone = FALSE; - if (! qProto->ffullduplex && ! fmaster) - fmasterdone = TRUE; - - /* Make sure we have a spool directory for this system. */ - if (! fsysdep_make_spool_dir (qsys)) - return FALSE; - - /* If we are not the caller, the grade will be passed in as an - argument. If we are the caller, we compute the grade in this - function so that we can recompute if time has passed. */ - - if (fcaller) - bgrade = btimegrade (qsys->ztime); - - if (bgrade == '\0') - fnowork = TRUE; - else - { - if (! fsysdep_get_work_init (qsys, bgrade)) - return FALSE; - fnowork = FALSE; - } - - /* Determine the maximum sizes we can send and receive. */ - - if (fcaller) - { - zlocal_size = qsys->zcall_local_size; - zremote_size = qsys->zcall_remote_size; - } - else - { - zlocal_size = qsys->zcalled_local_size; - zremote_size = qsys->zcalled_remote_size; - } - - clocal_size = cmax_size_now (zlocal_size); - cremote_size = cmax_size_now (zremote_size); - cmax_ever = (long) -2; - - /* Loop while we have local commands to execute and while we receive - remote commands. */ - - while (TRUE) - { -#if ! HAVE_ALLOCA - /* This only works if we know that no caller of this function is - holding an alloca'ed pointer. */ - (void) alloca (0); -#endif - -#if DEBUG > 1 - /* If we're doing any debugging, close the log and debugging - files regularly. This will let people copy them off and - remove them while the conversation is in progresss. */ - if (iDebug != 0) - { - ulog_close (); - ustats_close (); - } -#endif - - /* We send a command to the remote system if - we are the master or - this is full duplex protocol which is ready for a command and - we haven't finished executing commands. */ - if (fmaster || - (qProto->ffullduplex && ! fmasterdone)) - { - struct scmd s; - const char *zmail, *zuse; - boolean fspool, fnever; - openfile_t e = EFILECLOSED; - boolean fgone; - - /* Get the next work line for this system. All the arguments - are left pointing into a static buffer, so they must be - copied out before the next call. */ - ulog_user ((const char *) NULL); - if (fnowork) - s.bcmd = 'H'; - else - { - s.zuser = NULL; - if (! fsysdep_get_work (qsys, bgrade, &s)) - return FALSE; - ulog_user (s.zuser); - } - - switch (s.bcmd) - { - case 'S': - /* Send a file. */ - - fspool = fspool_file (s.zfrom); - - if (! fspool) - { - zuse = zsysdep_real_file_name (qsys, s.zfrom, - (const char *) NULL); - if (zuse == NULL) - { - (void) fmail_transfer (FALSE, s.zuser, - (const char *) NULL, - "cannot form file name", - s.zfrom, zLocalname, - s.zto, qsys->zname, - (const char *) NULL); - (void) fsysdep_did_work (s.pseq); - break; - } - - /* The 'C' option means that the file has been - copied to the spool directory. */ - if (strchr (s.zoptions, 'C') != NULL) - fspool = TRUE; - - if (! fok_to_send (zuse, TRUE, fcaller, fspool, qsys, - s.zuser)) - { - ulog (LOG_ERROR, "Not permitted to send %s", zuse); - (void) fmail_transfer (FALSE, s.zuser, - (const char *) NULL, - "not permitted to send", - s.zfrom, zLocalname, - s.zto, qsys->zname, - (const char *) NULL); - (void) fsysdep_did_work (s.pseq); - break; - } - - /* If we're copying the real file, use its mode - directly rather than the mode copied into the - command file. */ - if (! fspool) - e = esysdep_open_send (qsys, zuse, TRUE, s.zuser, - &s.imode, &s.cbytes, &fgone); - } - - if (fspool) - { - unsigned int idummy; - - zuse = zsysdep_spool_file_name (qsys, s.ztemp); - if (zuse == NULL) - { - (void) fmail_transfer (FALSE, s.zuser, - (const char *) NULL, - "cannot form file name", - s.zfrom, zLocalname, - s.zto, qsys->zname, - (const char *) NULL); - (void) fsysdep_did_work (s.pseq); - break; - } - e = esysdep_open_send (qsys, zuse, FALSE, - (const char *) NULL, &idummy, - &s.cbytes, &fgone); - } - - if (! ffileisopen (e)) - { - /* If the file does not exist, fgone will be set to - TRUE. In this case we might have sent the file - the last time we talked to the remote system, - because we might have been interrupted in the - middle of a command file. To avoid confusion, we - don't send a mail message. */ - if (! fgone) - (void) fmail_transfer (FALSE, s.zuser, - (const char *) NULL, - "cannot open file", - s.zfrom, zLocalname, - s.zto, qsys->zname, - (const char *) NULL); - (void) fsysdep_did_work (s.pseq); - break; - } - - if (s.cbytes != -1) - { - boolean fsmall; - const char *zerr; - - fsmall = FALSE; - fnever = FALSE; - zerr = NULL; - - if (cmax_receive != -1 && cmax_receive < s.cbytes) - { - fsmall = TRUE; - fnever = TRUE; - zerr = "too large for receiver"; - } - else if (clocal_size != -1 && clocal_size < s.cbytes) - { - fsmall = TRUE; - - if (cmax_ever == -2) - { - long c1, c2; - - c1 = cmax_size_ever (qsys->zcall_local_size); - c2 = cmax_size_ever (qsys->zcalled_local_size); - if (c1 > c2) - cmax_ever = c1; - else - cmax_ever = c2; - } - - if (cmax_ever == -1 || cmax_ever >= s.cbytes) - zerr = "too large to send now"; - else - { - fnever = TRUE; - zerr = "too large to send"; - } - } - - if (fsmall) - { - ulog (LOG_ERROR, "File %s is %s", s.zfrom, zerr); - - if (fnever) - { - const char *zsaved; - - zsaved = zsysdep_save_temp_file (s.pseq); - (void) fmail_transfer (FALSE, s.zuser, - (const char *) NULL, - zerr, - s.zfrom, zLocalname, - s.zto, qsys->zname, - zsaved); - (void) fsysdep_did_work (s.pseq); - } - - (void) ffileclose (e); - break; - } - } - - ulog (LOG_NORMAL, "Sending %s", s.zfrom); - - /* The send file function is responsible for notifying - the user upon success (if option m) or failure, and - for closing the file. This allows it to not complete - immediately. */ - if (strchr (s.zoptions, 'm') == NULL) - zmail = NULL; - else - zmail = s.zuser; - - if (! fsend_file (TRUE, e, &s, zmail, qsys->zname, fnew)) - return FALSE; - - break; - - case 'R': - /* Receive a file. */ - - if (fspool_file (s.zto)) - { - /* Normal users are not allowed to receive files in - the spool directory, and to make it particularly - difficult we require a special option '9'. This - is used only by uux when a file must be requested - from one system and then sent to another. */ - if (s.zto[0] != 'D' - || strchr (s.zoptions, '9') == NULL) - { - ulog (LOG_ERROR, "Not permitted to receive %s", - s.zto); - (void) fmail_transfer (FALSE, s.zuser, - (const char *) NULL, - "not permitted to receive", - s.zfrom, qsys->zname, - s.zto, zLocalname, - (const char *) NULL); - (void) fsysdep_did_work (s.pseq); - break; - } - - zuse = zsysdep_spool_file_name (qsys, s.zto); - if (zuse == NULL) - { - (void) fmail_transfer (FALSE, s.zuser, - (const char *) NULL, - "cannot form file name", - s.zfrom, qsys->zname, - s.zto, zLocalname, - (const char *) NULL); - (void) fsysdep_did_work (s.pseq); - break; - } - } - else - { - zuse = zsysdep_real_file_name (qsys, s.zto, s.zfrom); - if (zuse == NULL) - { - (void) fmail_transfer (FALSE, s.zuser, - (const char *) NULL, - "cannot form file name", - s.zfrom, qsys->zname, - s.zto, zLocalname, - (const char *) NULL); - (void) fsysdep_did_work (s.pseq); - break; - } - - /* Check permissions. */ - if (! fok_to_receive (zuse, TRUE, fcaller, qsys, s.zuser)) - { - ulog (LOG_ERROR, "Not permitted to receive %s", - s.zto); - (void) fmail_transfer (FALSE, s.zuser, - (const char *) NULL, - "not permitted to receive", - s.zfrom, qsys->zname, - s.zto, zLocalname, - (const char *) NULL); - (void) fsysdep_did_work (s.pseq); - break; - } - - /* The 'f' option means that directories should not - be created if they do not already exist. */ - if (strchr (s.zoptions, 'f') == NULL) - { - if (! fsysdep_make_dirs (zuse, TRUE)) - { - (void) fmail_transfer (FALSE, s.zuser, - (const char *) NULL, - "cannot create directories", - s.zfrom, qsys->zname, - s.zto, zLocalname, - (const char *) NULL); - (void) fsysdep_did_work (s.pseq); - break; - } - } - } - - e = esysdep_open_receive (qsys, zuse, &s.ztemp, &s.cbytes); - if (! ffileisopen (e)) - { - (void) fmail_transfer (FALSE, s.zuser, - (const char *) NULL, - "cannot open file", - s.zfrom, qsys->zname, - s.zto, zLocalname, - (const char *) NULL); - (void) fsysdep_did_work (s.pseq); - break; - } - - /* Here s.cbytes represents the amount of free space we - have. We want to adjust it by the amount of free - space permitted for this system. If there is a - maximum transfer size, we may want to use that as an - amount of free space. */ - if (s.cbytes != -1) - { - s.cbytes -= qsys->cfree_space; - if (s.cbytes < 0) - s.cbytes = 0; - } - - if (clocal_size != -1 - && (s.cbytes == -1 || clocal_size < s.cbytes)) - s.cbytes = clocal_size; - - ulog (LOG_NORMAL, "Receiving %s", zuse); - s.zto = zuse; - - /* As with the send routine, this function is - responsible for mailing a message to the user on - failure or on success if the m option is set, and is - also responsible for closing the file. */ - if (strchr (s.zoptions, 'm') == NULL) - zmail = NULL; - else - zmail = s.zuser; - - /* The imode argument (passed as 0666) will be corrected - with information from the remote system. */ - s.imode = 0666; - - if (! freceive_file (TRUE, e, &s, zmail, qsys->zname, fnew)) - return FALSE; - - break; - - case 'X': - /* Request a file copy. This is used to request a file - to be sent to another machine, as well as to get a - wildcarded filespec. */ - ulog (LOG_NORMAL, "Requesting work: %s to %s", s.zfrom, - s.zto); - - if (! fxcmd (&s, &fnever)) - return FALSE; - - if (fnever) - (void) fmail_transfer (FALSE, s.zuser, - (const char *) NULL, - "wildcard request denied", - s.zfrom, qsys->zname, - s.zto, zLocalname, - (const char *) NULL); - (void) fsysdep_did_work (s.pseq); - break; - - case 'H': - /* There is nothing left to do; hang up. If we are not the - master, take no action (this allows for two-way - protocols. */ - - fmasterdone = TRUE; - if (fmaster) - { - if (! fhangup_request ()) - { - ulog (LOG_ERROR, "Hangup failed"); - return FALSE; - } - - fmaster = FALSE; - - /* Close the log file at every master/slave switch. - This will cut down on the amount of time we have - an old log file open. */ - ulog_close (); - ustats_close (); - } - break; - - default: - ulog (LOG_ERROR, "Unknown command '%c'", s.bcmd); - break; - } - } - - /* We look for a command from the other system if we are the - slave or this is a full-duplex protocol and the slave still - has work to do. */ - if (! fmaster || qProto->ffullduplex) - { - struct scmd s; - const char *zuse, *zmail; - openfile_t e; - char bhave_grade; - long cbytes; - - /* We are the slave. Get the next command from the other - system. */ - ulog_user ((const char *) NULL); - if (! fgetcmd (fmaster, &s)) - return FALSE; - - if (s.bcmd != 'H' && s.bcmd != 'Y') - ulog_user (s.zuser); - - switch (s.bcmd) - { - case 'S': - /* The master wants to send a file to us. */ - - if (fspool_file (s.zto)) - { - zuse = zsysdep_spool_file_name (qsys, s.zto); - /* We don't accept remote command files. */ - if (zuse == NULL || s.zto[0] == 'C') - { - if (! ftransfer_fail ('S', FAILURE_PERM)) - return FALSE; - break; - } - } - else - { - zuse = zsysdep_real_file_name (qsys, s.zto, s.zfrom); - if (zuse == NULL) - { - if (! ftransfer_fail ('S', FAILURE_PERM)) - return FALSE; - break; - } - - /* Check permissions. */ - if (! fok_to_receive (zuse, FALSE, fcaller, qsys, - s.zuser)) - { - ulog (LOG_ERROR, "Not permitted to receive %s", zuse); - if (! ftransfer_fail ('S', FAILURE_PERM)) - return FALSE; - break; - } - - if (strchr (s.zoptions, 'f') == NULL) - { - if (! fsysdep_make_dirs (zuse, TRUE)) - { - if (! ftransfer_fail ('S', FAILURE_PERM)) - return FALSE; - break; - } - } - } - - e = esysdep_open_receive (qsys, zuse, &s.ztemp, &cbytes); - if (! ffileisopen (e)) - { - if (! ftransfer_fail ('S', FAILURE_OPEN)) - return FALSE; - break; - } - - /* Adjust the number of bytes we are prepared to receive - according to the amount of free space we are supposed - to leave available and the maximum file size we are - permitted to transfer. */ - if (cbytes != -1) - { - cbytes -= qsys->cfree_space; - if (cbytes < 0) - cbytes = 0; - } - - if (cremote_size != -1 - && (cbytes == -1 || cremote_size < cbytes)) - cbytes = cremote_size; - - /* If the number of bytes we are prepared to receive - is less than the file size, we must fail. */ - - if (s.cbytes != -1 - && cbytes != -1 - && cbytes < s.cbytes) - { - ulog (LOG_ERROR, "%s is too big to receive", zuse); - (void) ffileclose (e); - (void) remove (s.ztemp); - if (! ftransfer_fail ('S', FAILURE_SIZE)) - return FALSE; - break; - } - - ulog (LOG_NORMAL, "Receiving %s", zuse); - s.zto = zuse; - - if (strchr (s.zoptions, 'n') == NULL) - zmail = NULL; - else - zmail = s.znotify; - s.pseq = NULL; - if (! freceive_file (FALSE, e, &s, zmail, qsys->zname, fnew)) - return FALSE; - - break; - - case 'R': - /* The master wants to get a file from us. */ - - if (fspool_file (s.zfrom)) - { - ulog (LOG_ERROR, "No permission to send %s", s.zfrom); - if (! ftransfer_fail ('R', FAILURE_PERM)) - return FALSE; - break; - } - - zuse = zsysdep_real_file_name (qsys, s.zfrom, - (const char *) NULL); - if (zuse == NULL) - { - if (! ftransfer_fail ('R', FAILURE_PERM)) - return FALSE; - break; - } - - if (! fok_to_send (zuse, FALSE, fcaller, FALSE, qsys, - s.zuser)) - { - ulog (LOG_ERROR, "No permission to send %s", zuse); - if (! ftransfer_fail ('R', FAILURE_PERM)) - return FALSE; - break; - } - - e = esysdep_open_send (qsys, zuse, TRUE, (const char *) NULL, - &s.imode, &cbytes, (boolean *) NULL); - if (! ffileisopen (e)) - { - if (! ftransfer_fail ('R', FAILURE_OPEN)) - return FALSE; - break; - } - - /* If the file is larger than the amount of space - the other side reported, we can't send it. */ - if (cbytes != -1 - && ((s.cbytes != -1 && s.cbytes < cbytes) - || (cremote_size != -1 && cremote_size < cbytes) - || (cmax_receive != -1 && cmax_receive < cbytes))) - { - ulog (LOG_ERROR, "%s is too large to send", zuse); - if (! ftransfer_fail ('R', FAILURE_SIZE)) - return FALSE; - (void) ffileclose (e); - break; - } - - ulog (LOG_NORMAL, "Sending %s", zuse); - - /* Pass in the real size of the file. */ - s.cbytes = cbytes; - - if (! fsend_file (FALSE, e, &s, (const char *) NULL, - qsys->zname, fnew)) - return FALSE; - - break; - - case 'X': - /* This is an execution request. We are being asked to - send one or more files to a destination on either the - local or a remote system. We do this by spooling up - commands for the destination system. */ - ulog (LOG_NORMAL, "Work requested: %s to %s", s.zfrom, - s.zto); - - if (fdo_xcmd (qsys, fcaller, &s)) - { - if (! fxcmd_confirm ()) - return FALSE; - } - else - { - if (! ftransfer_fail ('X', FAILURE_PERM)) - return FALSE; - } - - break; - - case 'H': - /* The master wants to hang up. If we have something to - do, become the master. Otherwise, agree to hang up. - We recheck the grades allowed at this time, since a - lot of time may have passed. */ - if (fcaller) - bgrade = btimegrade (qsys->ztime); - if (bgrade != '\0' - && fsysdep_has_work (qsys, &bhave_grade) - && igradecmp (bgrade, bhave_grade) >= 0) - { - if (fmasterdone) - { - if (! fsysdep_get_work_init (qsys, bgrade)) - return FALSE; - fnowork = FALSE; - } - - fmasterdone = FALSE; - - if (! fhangup_reply (FALSE)) - return FALSE; - fmaster = TRUE; - - /* Recalculate the maximum sizes we can send, since - the time might have changed significantly. */ - clocal_size = cmax_size_now (zlocal_size); - cremote_size = cmax_size_now (zremote_size); - - /* Close the log file at every switch of master and - slave. */ - ulog_close (); - ustats_close (); - } - else - { - /* The hangup_reply function will shut down the - protocol. */ - return fhangup_reply (TRUE); - } - break; - - case 'Y': - /* This is returned when a hangup has been confirmed and - the protocol has been shut down. */ - return TRUE; - - default: - ulog (LOG_ERROR, "Unknown command %c", s.bcmd); - break; - } - } - } -} - -/* Do an 'X' request for another system. The other system has - basically requested us to execute a uucp command for them. */ - -static boolean -fdo_xcmd (qsys, fcaller, q) - const struct ssysteminfo *qsys; - boolean fcaller; - const struct scmd *q; -{ - const char *zexclam; - const char *zdestfile; - char *zcopy; - struct ssysteminfo sdestsys; - const struct ssysteminfo *qdestsys; - char *zuser = NULL; - char aboptions[5]; - char *zoptions = NULL; - boolean fmkdirs; - const char *zfile; - - zexclam = strchr (q->zto, '!'); - if (zexclam == NULL - || zexclam == q->zto - || strncmp (zLocalname, q->zto, zexclam - q->zto) == 0) - { - /* The files are supposed to be copied to the - local system. */ - qdestsys = NULL; - if (zexclam == NULL) - zdestfile = q->zto; - else - zdestfile = zexclam + 1; - } - else - { - int clen; - - clen = zexclam - q->zto; - zcopy = (char *) alloca (clen + 1); - strncpy (zcopy, q->zto, clen); - zcopy[clen] = '\0'; - - if (! fread_system_info (zcopy, &sdestsys)) - { - if (! fUnknown_ok) - { - ulog (LOG_ERROR, "Destination system %s unknown", - zcopy); - return FALSE; - } - sdestsys = sUnknown; - sdestsys.zname = zcopy; - } - qdestsys = &sdestsys; - zdestfile = zexclam + 1; - } - - if (qdestsys != NULL) - { - zuser = (char *) alloca (strlen (qdestsys->zname) - + strlen (q->zuser) + sizeof "!"); - sprintf (zuser, "%s!%s", qdestsys->zname, - q->zuser); - zoptions = aboptions; - *zoptions++ = 'C'; - if (strchr (q->zoptions, 'd') != NULL) - *zoptions++ = 'd'; - if (strchr (q->zoptions, 'm') != NULL) - *zoptions++ = 'm'; - *zoptions = '\0'; - fmkdirs = TRUE; - } - else - fmkdirs = strchr (q->zoptions, 'f') != NULL; - - /* Now we have to process each source file. The - source specification may or may use wildcards. */ - if (! fsysdep_wildcard_start (qsys, q->zfrom)) - return FALSE; - - while ((zfile = zsysdep_wildcard (qsys, q->zfrom)) != NULL) - { - const char *zsend; - const char *zto; - char abtname[CFILE_NAME_LEN]; - - zcopy = (char *) alloca (strlen (zfile) + 1); - strcpy (zcopy, zfile); - zfile = zcopy; - - /* Make sure the remote system is permitted to read the - specified file. */ - zsend = qsys->zremote_send; - if (! fcaller && qsys->zcalled_remote_send != NULL) - zsend = qsys->zcalled_remote_send; - - if (! fin_directory_list (qsys, zfile, zsend, TRUE, TRUE, - (const char *) NULL)) - { - ulog (LOG_ERROR, "Not permitted to send %s", zfile); - (void) fsysdep_wildcard_end (); - return FALSE; - } - - if (qdestsys != NULL) - { - /* We really should get the original grade here. */ - zto = zsysdep_data_file_name (qdestsys, BDEFAULT_UUCP_GRADE, - abtname, (char *) NULL, - (char *) NULL); - } - else - { - const char *zrec; - - zto = zsysdep_real_file_name (qsys, zexclam + 1, zfile); - if (zto == NULL) - { - (void) fsysdep_wildcard_end (); - return FALSE; - } - /* We only accept a local destination if the remote system - has the right to create files there. */ - zrec = qsys->zremote_receive; - if (! fcaller && qsys->zcalled_remote_receive != NULL) - zrec = qsys->zcalled_remote_receive; - - if (! fin_directory_list (qsys, zto, zrec, TRUE, FALSE, - (const char *) NULL)) - { - ulog (LOG_ERROR, "Not permitted to receive %s", zto); - (void) fsysdep_wildcard_end (); - return FALSE; - } - } - - /* Copy the file either to the final destination or to the - spool directory. */ - if (! fcopy_file (zfile, zto, qdestsys == NULL, fmkdirs)) - { - (void) fsysdep_wildcard_end (); - return FALSE; - } - - /* If there is a destination system, queue it up. */ - if (qdestsys != NULL) - { - struct scmd ssend; - - ssend.bcmd = 'S'; - ssend.pseq = NULL; - ssend.zfrom = zfile; - ssend.zto = zdestfile; - ssend.zuser = zuser; - ssend.zoptions = aboptions; - ssend.ztemp = abtname; - ssend.imode = isysdep_file_mode (zfile); - if (ssend.imode == 0) - { - (void) fsysdep_wildcard_end (); - return FALSE; - } - ssend.znotify = ""; - ssend.cbytes = -1; - - if (zsysdep_spool_commands (qdestsys, BDEFAULT_UUCP_GRADE, - 1, &ssend) == NULL) - { - (void) fsysdep_wildcard_end (); - return FALSE; - } - } - } - - if (! fsysdep_wildcard_end ()) - return FALSE; - - return TRUE; -} - -/* See whether it's OK to send a file to another system, according to - the permissions recorded for that system. If the file is not in - the spool directory, this also makes sure that the user has - permission to access the file and all its containing directories. - - zfile -- file to send - flocal -- TRUE if the send was requested locally - fcaller -- TRUE if the local system called the other system - fspool -- TRUE if file was copied to spool directory - qsys -- remote system information - zuser -- user who requested the action */ - -static boolean -fok_to_send (zfile, flocal, fcaller, fspool, qsys, zuser) - const char *zfile; - boolean flocal; - boolean fcaller; - boolean fspool; - const struct ssysteminfo *qsys; - const char *zuser; -{ - const char *z; - - if (! frequest_ok (flocal, fcaller, qsys, zuser)) - return FALSE; - - if (flocal) - { - z = qsys->zlocal_send; - if (! fcaller && qsys->zcalled_local_send != NULL) - z = qsys->zcalled_local_send; - } - else - { - z = qsys->zremote_send; - if (! fcaller && qsys->zcalled_remote_send != NULL) - z = qsys->zcalled_remote_send; - } - - /* If fspool is TRUE, we don't want to check file accessibility. If - this was not a local request, we pass a NULL down as the user - name, since zuser has no meaning on this system. */ - return fin_directory_list (qsys, zfile, z, ! fspool, TRUE, - flocal ? zuser : (const char *) NULL); -} - -/* See whether it's OK to receive a file from another system. */ - -/*ARGSUSED*/ -static boolean -fok_to_receive (zto, flocal, fcaller, qsys, zuser) - const char *zto; - boolean flocal; - boolean fcaller; - const struct ssysteminfo *qsys; - const char *zuser; -{ - const char *z; - - if (! frequest_ok (flocal, fcaller, qsys, zuser)) - return FALSE; - - if (flocal) - { - z = qsys->zlocal_receive; - if (! fcaller && qsys->zcalled_local_receive != NULL) - z = qsys->zcalled_local_receive; - } - else - { - z = qsys->zremote_receive; - if (! fcaller && qsys->zcalled_remote_receive != NULL) - z = qsys->zcalled_remote_receive; - } - - return fin_directory_list (qsys, zto, z, TRUE, FALSE, - flocal ? zuser : (const char *) NULL); -} - -/* See whether a request is OK. This depends on which system placed - the call and which system made the request. */ - -/*ARGSUSED*/ -static boolean -frequest_ok (flocal, fcaller, qsys, zuser) - boolean flocal; - boolean fcaller; - const struct ssysteminfo *qsys; - const char *zuser; -{ - if (flocal) - { - if (fcaller) - return qsys->fcall_transfer; - else - return qsys->fcalled_transfer; - } - else - { - if (fcaller) - return qsys->fcall_request; - else - return qsys->fcalled_request; - } -} - -/* Send a string to the other system beginning with a DLE - character and terminated with a null byte. This is only - used when no protocol is in force. */ - -static boolean -fsend_uucp_cmd (z) - const char *z; -{ - char *zalc; - int cwrite; - - cwrite = strlen (z) + 2; - - zalc = (char *) alloca (cwrite); - sprintf (zalc, "\020%s", z); - - return fport_write (zalc, cwrite); -} - -/* Get a UUCP command beginning with a DLE character and ending with a - null byte. This is only used when no protocol is in force. This - implementation has the potential of being seriously slow. It also - doesn't have any real error recovery. The frequired argument is - passed as TRUE if we need the string; we don't care that much if - we're closing down the connection anyhow. */ - -#define CTIMEOUT (120) -#define CSHORTTIMEOUT (10) -#define CINCREMENT (10) - -static const char * -zget_uucp_cmd (frequired) - boolean frequired; -{ - static char *zalc; - static int calc; - int cgot; - long iendtime; - int ctimeout; -#if DEBUG > 1 - int cchars; - int iolddebug; -#endif - - iendtime = isysdep_time ((long *) NULL); - if (frequired) - iendtime += CTIMEOUT; - else - iendtime += CSHORTTIMEOUT; - -#if DEBUG > 1 - cchars = 0; - iolddebug = iDebug; - if (FDEBUGGING (DEBUG_HANDSHAKE)) - { - ulog (LOG_DEBUG_START, "zget_uucp_cmd: Got \""); - iDebug &=~ (DEBUG_INCOMING | DEBUG_PORT); - } -#endif - - cgot = -1; - while ((ctimeout = (int) (iendtime - isysdep_time ((long *) NULL))) > 0) - { - int b; - - b = breceive_char (ctimeout, frequired); - /* Now b == -1 on timeout, -2 on error. */ - if (b < 0) - { -#if DEBUG > 1 - if (FDEBUGGING (DEBUG_HANDSHAKE)) - { - ulog (LOG_DEBUG_END, "\" (%s)", - b == -1 ? "timeout" : "error"); - iDebug = iolddebug; - } -#endif - if (b == -1 && frequired) - ulog (LOG_ERROR, "Timeout"); - return NULL; - } - - /* Apparently some systems use parity on these strings, so we - strip the parity bit. This may need to be configurable at - some point, although only if system names can have eight bit - characters. */ - if (! isprint (BUCHAR (b))) - b &= 0x7f; - -#if DEBUG > 1 - if (FDEBUGGING (DEBUG_HANDSHAKE)) - { - char ab[5]; - - ++cchars; - if (cchars > 60) - { - ulog (LOG_DEBUG_END, "\""); - ulog (LOG_DEBUG_START, "zget_uucp_cmd: Got \""); - cchars = 0; - } - (void) cdebug_char (ab, b); - ulog (LOG_DEBUG_CONTINUE, "%s", ab); - } -#endif - - if (cgot < 0) - { - if (b != '\020') - continue; - cgot = 0; - continue; - } - - /* If we see another DLE, something has gone wrong; continue - as though this were the first one we saw. */ - if (b == '\020') - { - cgot = 0; - continue; - } - - /* Some systems send a trailing \n on the Shere line. As far as - I can tell this line can never contain a \n, so this - modification should be safe enough. */ - if (b == '\r' || b == '\n') - b = '\0'; - - if (cgot >= calc) - { - calc += CINCREMENT; - zalc = (char *) xrealloc ((pointer) zalc, calc); - } - - zalc[cgot] = (char) b; - ++cgot; - - if (b == '\0') - { -#if DEBUG > 1 - if (FDEBUGGING (DEBUG_HANDSHAKE)) - { - ulog (LOG_DEBUG_END, "\""); - iDebug = iolddebug; - } -#endif - return zalc; - } - } - -#if DEBUG > 1 - if (FDEBUGGING (DEBUG_HANDSHAKE)) - { - ulog (LOG_DEBUG_END, "\" (timeout)"); - iDebug = iolddebug; - } -#endif - - if (frequired) - ulog (LOG_ERROR, "Timeout"); - return NULL; -} - -/* Read a sequence of characters up to a newline or carriage return, and - return the line without the line terminating character. */ - -static const char * -zget_typed_line () -{ - static char *zalc; - static int calc; - int cgot; - -#if DEBUG > 1 - int cchars; - int iolddebug; - - cchars = 0; - iolddebug = iDebug; - if (FDEBUGGING (DEBUG_CHAT)) - { - ulog (LOG_DEBUG_START, "zget_typed_line: Got \""); - iDebug &=~ (DEBUG_INCOMING | DEBUG_PORT); - } -#endif - - cgot = 0; - while (TRUE) - { - int b; - - b = breceive_char (CTIMEOUT, FALSE); - - /* Now b == -1 on timeout, -2 on error. */ - - if (b == -2 || FGOT_SIGNAL ()) - { -#if DEBUG > 1 - if (FDEBUGGING (DEBUG_CHAT)) - { - ulog (LOG_DEBUG_END, "\" (error)"); - iDebug = iolddebug; - } -#endif - return NULL; - } - - if (b == -1) - continue; - -#if DEBUG > 1 - if (FDEBUGGING (DEBUG_CHAT)) - { - char ab[5]; - - ++cchars; - if (cchars > 60) - { - ulog (LOG_DEBUG_END, "\""); - ulog (LOG_DEBUG_START, "zget_typed_line: Got \""); - cchars = 0; - } - (void) cdebug_char (ab, b); - ulog (LOG_DEBUG_CONTINUE, "%s", ab); - } -#endif - - if (cgot >= calc) - { - calc += CINCREMENT; - zalc = (char *) xrealloc ((pointer) zalc, calc); - } - - if (b == '\r' || b == '\n') - b = '\0'; - - zalc[cgot] = (char) b; - ++cgot; - - if (b == '\0') - { -#if DEBUG > 1 - if (FDEBUGGING (DEBUG_CHAT)) - { - ulog (LOG_DEBUG_END, "\""); - iDebug = iolddebug; - } -#endif - return zalc; - } - } -} diff --git a/gnu/libexec/uucp/uucp.1 b/gnu/libexec/uucp/uucp.1 deleted file mode 100644 index 40431801af3..00000000000 --- a/gnu/libexec/uucp/uucp.1 +++ /dev/null @@ -1,183 +0,0 @@ -''' $Id: uucp.1,v 1.1.1.1 1993/03/21 09:45:37 cgd Exp $ -''' $Log: uucp.1,v $ -''' Revision 1.1.1.1 1993/03/21 09:45:37 cgd -''' initial import of 386bsd-0.1 sources -''' -''' Revision 1.5 1992/04/01 21:11:19 ian -''' Cleaned up a bit, updated -x switch -''' -''' Revision 1.4 1992/03/28 04:34:11 ian -''' David J. MacKenzie: change .TP5 to .TP 5; also updated to 1.03 -''' -''' Revision 1.3 1992/02/29 04:07:08 ian -''' Added -j option to uucp and uux -''' -''' Revision 1.2 1992/01/20 23:52:23 ian -''' Change to version 1.02 -''' -''' Revision 1.1 1991/12/14 19:05:20 ian -''' Initial revision -''' -''' -.TH uucp 1 "Taylor UUCP 1.03" -.SH NAME -uucp \- Unix to Unix copy -.SH SYNOPSIS -.B uucp -[ options ] source-file destination-file -.PP -.B uucp -[ options ] source-file... destination-directory -.SH DESCRIPTION -The -.I uucp -command copies files between systems. Each -.I file -argument is either a pathname on the local machine or is of the form -.IP -system!path -.LP -which is interpreted as being on a remote system. -In the first form, the contents of the first file are copied to the -second. In the second form, each source file is copied into the -destination directory. - -Any pathname that does not begin with / or ~ will be appended to the -current directory; this resulting path may not exist on a remote -system. A pathname beginning with a simple ~ starts at the UUCP -public directory; a pathname beginning with ~name starts at the home -directory of the named user. The ~ is interpreted on the appropriate -system. Note that some shells will interpret a simple ~ to the local -home directory before -.I uucp -sees it; to avoid this the ~ must be quoted. - -Shell metacharacters ? * [ ] are interpreted on the appropriate -system, assuming they are quoted to prevent the shell from -interpreting them first. - -The copy does not take place immediately, but is queued up for the -.I uucico -(8) daemon; the daemon is started immediately unless the -.B \-r -switch is given. In any case, the next time the remote system is called the -file(s) will be copied. -.SH OPTIONS -The following options may be given to -.I uucp. -.TP 5 -.B \-c -Do not copy local source files to the spool directory. If they are -removed before being processed by the -.I uucico -(8) daemon, the copy will fail. The files must be readable by the -.I uucico -(8) daemon, and by the invoking user. -.TP 5 -.B \-C -Copy local source files to the spool directory. This is the default. -.TP 5 -.B \-d -Create all necessary directories when doing the copy. This is the -default. -.TP 5 -.B \-f -If any necessary directories do not exist for the destination path, -abort the copy. -.TP 5 -.B \-g grade -Set the grade of the file transfer command. Jobs of a higher grade -are executed first. Grades run 0 ... 9 A ... Z a ... z from high to -low. -.TP 5 -.B \-m -Report completion or failure of the file transfer by -.I mail -(1). -.TP 5 -.B \-n user -Report completion or failure of the file transfer by -.I mail -(1) to the named -user on the remote system. -.TP 5 -.B \-r -Do not start -.I uucico -(8) daemon immediately; merely queue up the file transfer for later -execution. -.TP 5 -.B \-j -Print jobid on standard output. The job may be -later cancelled by passing the jobid to the -.B \-k -switch of -.I uustat -(1). -It is possible for some complex operations to produce more than one -jobid, in which case each will be printed on a separate line. For -example -.EX -uucp sys1!~user1/file1 sys2!~user2/file2 /usr/spool/uucppublic -.EE -will generate two separate jobs, one for the system -.I sys1 -and one for the system -.I sys2. -.TP 5 -.B \-x type -Turn on particular debugging types. The following types are -recognized: abnormal, chat, handshake, uucp-proto, proto, port, -config, spooldir, execute, incoming, outgoing. Only abnormal, config, -spooldir and execute are meaningful for -.I uucp. - -Multiple types may be given, separated by commas, and the -.B \-x -option may appear multiple times. A number may also be given, which -will turn on that many types from the foregoing list; for example, -.B \-x 2 -is equivalent to -.B \-x abnormal,chat. -.TP 5 -.B \-I file -Set configuration file to use. This option may not be available, -depending upon how -.I uucp -was compiled. -.SH FILES -The file names may be changed at compilation time or by the -configuration file, so these are only approximations. - -.br -/usr/lib/uucp/config - Configuration file. -.br -/usr/spool/uucp - -UUCP spool directory. -.br -/usr/spool/uucp/Log - -UUCP log file. -.br -/usr/spool/uucppublic - -Default UUCP public directory. -.SH SEE ALSO -mail(1), uux(1), uustat(1), uucico(8) -.SH BUGS -Files can not be copied across multiple systems. - -Some of the options are dependent on the capabilities of the -.I uucico -(8) daemon on the remote system. - -The -.I \-n -and -.I \-m -switches do not work when transferring a file from one remote system -to another. - -File modes are not preserved, except for the execute bit. The -resulting file is owned by the uucp user. -.SH AUTHOR -Ian Lance Taylor -(ian@airs.com or uunet!airs!ian) diff --git a/gnu/libexec/uucp/uucp.c b/gnu/libexec/uucp/uucp.c deleted file mode 100644 index efee28de102..00000000000 --- a/gnu/libexec/uucp/uucp.c +++ /dev/null @@ -1,809 +0,0 @@ -/* uucp.c - Prepare to copy a file to or from a remote system. - - 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 AIRS, P.O. Box 520, Waltham, MA 02254. - - $Log: uucp.c,v $ - Revision 1.1.1.1 1993/03/21 09:45:37 cgd - initial import of 386bsd-0.1 sources - - Revision 1.25 1992/03/15 04:51:17 ian - Keep an array of signals we've received rather than a single variable - - Revision 1.24 1992/03/12 21:55:09 ian - Use fake local name when generating an execution request - - Revision 1.23 1992/03/12 19:54:43 ian - Debugging based on types rather than number - - Revision 1.22 1992/02/29 04:07:08 ian - Added -j option to uucp and uux - - Revision 1.21 1992/02/29 01:06:59 ian - Chip Salzenberg: recheck file permissions before sending - - Revision 1.20 1992/02/27 05:40:54 ian - T. William Wells: detach from controlling terminal, handle signals safely - - Revision 1.19 1992/02/24 04:58:47 ian - Only permit files to be received into directories that are world-writeable - - Revision 1.18 1992/02/23 03:26:51 ian - Overhaul to use automatic configure shell script - - Revision 1.17 1992/02/14 05:17:09 ian - Niels Baggesen: have to copy abtname into memory - - Revision 1.16 1992/02/08 22:33:32 ian - Only get the current working directory if it's going to be needed - - Revision 1.15 1992/02/08 20:33:57 ian - Handle all possible signals raised by abort - - Revision 1.14 1992/02/08 03:54:18 ian - Include <string.h> only in <uucp.h>, added 1992 copyright - - Revision 1.13 1992/02/02 20:56:25 ian - Do local copy to zsysdep_real_file_name, not zsysdep_in_dir - - Revision 1.12 1992/02/02 20:34:36 ian - Niels Baggesen: must check user permissions on access to local files - - Revision 1.11 1992/01/21 19:39:12 ian - Chip Salzenberg: uucp and uux start uucico for right system, not any - - Revision 1.10 1992/01/15 07:06:29 ian - Set configuration directory in Makefile rather than sysdep.h - - Revision 1.9 1992/01/05 03:09:17 ian - Changed abProgram and abVersion to non const to avoid compiler bug - - Revision 1.8 1991/12/21 21:09:01 ian - Use ulog to report illegal grade error message - - Revision 1.7 1991/12/18 03:54:14 ian - Made error messages to terminal appear more normal - - Revision 1.6 1991/12/11 03:59:19 ian - Create directories when necessary; don't just assume they exist - - Revision 1.5 1991/11/21 22:17:06 ian - Add version string, print version when printing usage - - Revision 1.4 1991/11/13 23:08:40 ian - Expand remote pathnames in uucp and uux; fix up uux special cases - - Revision 1.3 1991/09/19 02:30:37 ian - From Chip Salzenberg: check whether signal is ignored differently - - Revision 1.2 1991/09/11 02:33:14 ian - Added ffork argument to fsysdep_run - - Revision 1.1 1991/09/10 19:40:31 ian - Initial revision - - */ - -#include "uucp.h" - -#if USE_RCS_ID -char uucp_rcsid[] = "$Id: uucp.c,v 1.1.1.1 1993/03/21 09:45:37 cgd Exp $"; -#endif - -#include <ctype.h> -#include <errno.h> - -#include "getopt.h" - -#include "system.h" -#include "sysdep.h" - -/* The program name. */ -char abProgram[] = "uucp"; - -/* Long getopt options. */ - -static const struct option asClongopts[] = { { NULL, 0, NULL, 0 } }; - -const struct option *_getopt_long_options = asClongopts; - -/* Local functions. */ - -static void ucusage P((void)); -static void ucadd_cmd P((const struct ssysteminfo *qsys, - const struct scmd *qcmd)); -static void ucspool_cmds P((int bgrade, boolean fjobid)); -static const char *zcone_system P((boolean *pfany)); -static void ucrecord_file P((const char *zfile)); -static void ucabort P((void)); - -int -main (argc, argv) - int argc; - char **argv; -{ - int iopt; - /* -c,-C: if true, copy to spool directory. */ - boolean fcopy = TRUE; - /* -d,-f: if true, create directories if they don't exist. */ - boolean fmkdirs = TRUE; - /* -g: job grade. */ - char bgrade = BDEFAULT_UUCP_GRADE; - /* -I: configuration file name. */ - const char *zconfig = NULL; - /* -j: output job id. */ - boolean fjobid = FALSE; - /* -m: mail to requesting user. */ - boolean fmail = FALSE; - /* -n: notify remote user. */ - const char *znotify = ""; - /* -r: don't start uucico when finished. */ - boolean fuucico = TRUE; - /* -s: report status to named file. */ - const char *zstatus_file = NULL; - /* -W: expand local file names only. */ - boolean fexpand = TRUE; - int i; - boolean fgetcwd; - char *zexclam; - char *zdestfile; - const char *zconst; - struct ssysteminfo sdestsys; - const struct ssysteminfo *qdestsys; - boolean flocaldest; - const char *zuser; - char absend_options[5]; - char abrec_options[3]; - char *zoptions; - boolean fexit; - - while ((iopt = getopt (argc, argv, "cCdfg:I:jmn:rs:Wx:")) != EOF) - { - switch (iopt) - { - case 'c': - /* Do not copy local files to spool directory. */ - fcopy = FALSE; - break; - - case 'C': - /* Copy local files to spool directory. */ - fcopy = TRUE; - break; - - case 'd': - /* Create directories if necessary. */ - fmkdirs = TRUE; - break; - - case 'f': - /* Do not create directories if they don't exist. */ - fmkdirs = FALSE; - break; - - case 'g': - /* Set job grade. */ - bgrade = optarg[0]; - break; - - case 'I': - /* Name configuration file. */ - zconfig = optarg; - break; - - case 'j': - /* Output job id. */ - fjobid = TRUE; - break; - - case 'm': - /* Mail to requesting user. */ - fmail = TRUE; - break; - - case 'n': - /* Notify remote user. */ - znotify = optarg; - break; - - case 'r': - /* Don't start uucico when finished. */ - fuucico = FALSE; - break; - - case 's': - /* Report status to named file. */ - zstatus_file = optarg; - break; - - case 'W': - /* Expand only local file names. */ - fexpand = FALSE; - break; - - case 'x': -#if DEBUG > 1 - /* Set debugging level. */ - iDebug |= idebug_parse (optarg); -#endif - break; - - case 0: - /* Long option found and flag set. */ - break; - - default: - ucusage (); - break; - } - } - - if (! FGRADE_LEGAL (bgrade)) - { - /* We use LOG_NORMAL rather than LOG_ERROR because this is going - to stderr rather than to the log file, and we don't need the - ERROR header string. */ - ulog (LOG_NORMAL, "Ignoring illegal grade"); - bgrade = BDEFAULT_UUCP_GRADE; - } - - if (argc - optind < 2) - ucusage (); - - uread_config (zconfig); - - /* See if we are going to need to know the current directory. We - just check each argument to see whether it's an absolute - pathname. We actually aren't going to need the cwd if fexpand is - FALSE and the file is remote, but so what. */ - fgetcwd = FALSE; - for (i = optind; i < argc; i++) - { - zexclam = strrchr (argv[i], '!'); - if (zexclam == NULL) - zexclam = argv[i]; - else - ++zexclam; - if (fsysdep_needs_cwd (zexclam)) - { - fgetcwd = TRUE; - break; - } - } - -#ifdef SIGINT - usysdep_signal (SIGINT); -#endif -#ifdef SIGHUP - usysdep_signal (SIGHUP); -#endif -#ifdef SIGQUIT - usysdep_signal (SIGQUIT); -#endif -#ifdef SIGTERM - usysdep_signal (SIGTERM); -#endif -#ifdef SIGPIPE - usysdep_signal (SIGPIPE); -#endif - - usysdep_initialize (FALSE, fgetcwd); - - ulog_fatal_fn (ucabort); - - zuser = zsysdep_login_name (); - - /* Set up the options. */ - - zoptions = absend_options; - if (fcopy) - *zoptions++ = 'C'; - else - *zoptions++ = 'c'; - if (fmkdirs) - *zoptions++ = 'd'; - else - *zoptions++ = 'f'; - if (fmail) - *zoptions++ = 'm'; - if (*znotify != '\0') - *zoptions++ = 'n'; - *zoptions = '\0'; - - zoptions = abrec_options; - if (fmkdirs) - *zoptions++ = 'd'; - else - *zoptions++ = 'f'; - if (fmail) - *zoptions++ = 'm'; - *zoptions = '\0'; - - zexclam = strchr (argv[argc - 1], '!'); - if (zexclam == NULL) - { - zdestfile = argv[argc - 1]; - qdestsys = &sLocalsys; - flocaldest = TRUE; - } - else - { - int clen; - char *zcopy; - - clen = zexclam - argv[argc - 1]; - zcopy = (char *) alloca (clen + 1); - strncpy (zcopy, argv[argc - 1], clen); - zcopy[clen] = '\0'; - - zdestfile = zexclam + 1; - - if (*zcopy == '\0' || strcmp (zcopy, zLocalname) == 0) - { - qdestsys = &sLocalsys; - flocaldest = TRUE; - } - else - { - if (fread_system_info (zcopy, &sdestsys)) - qdestsys = &sdestsys; - else - { - if (! fUnknown_ok) - ulog (LOG_FATAL, "System %s unknown", zcopy); - qdestsys = &sUnknown; - sUnknown.zname = zcopy; - } - - flocaldest = FALSE; - - if (! fsysdep_make_spool_dir (qdestsys)) - { - ulog_close (); - usysdep_exit (FALSE); - } - } - } - - /* If the destination file is not an absolute path, expand it - with the current directory. */ - if (fexpand || flocaldest) - { - zconst = zsysdep_add_cwd (zdestfile, flocaldest); - if (zconst == NULL) - { - ulog_close (); - usysdep_exit (FALSE); - } - zdestfile = xstrdup (zconst); - } - - /* Check that we have permission to receive into the desired - directory. If we don't have permission, uucico will fail. */ - - if (flocaldest) - { - if (! fin_directory_list (&sLocalsys, zdestfile, - sLocalsys.zlocal_receive, - TRUE, FALSE, zuser)) - ulog (LOG_FATAL, "Not permitted to receive to %s", zdestfile); - } - - /* Process each file. */ - - for (i = optind; i < argc - 1 && ! FGOT_SIGNAL (); i++) - { - struct scmd s; - - zexclam = strchr (argv[i], '!'); - - if (zexclam == NULL) - { - char *zfrom; - - /* This is a local file. Make sure we get it out of the - original directory. We don't support local wildcards - yet (if ever). */ - zconst = zsysdep_add_cwd (argv[i], TRUE); - if (zconst == NULL) - ucabort (); - zfrom = xstrdup (zconst); - - /* Make sure the user has access to this file, since we are - running setuid. */ - if (! fsysdep_access (zfrom)) - ucabort (); - - if (flocaldest) - { - char *zto; - - /* Copy one local file to another. */ - - zconst = zsysdep_real_file_name (&sLocalsys, zdestfile, - argv[i]); - if (zconst == NULL) - ucabort (); - zto = xstrdup (zconst); - - if (! fcopy_file (zfrom, zto, FALSE, fmkdirs)) - ucabort (); - - xfree ((pointer) zto); - } - else - { - char abtname[CFILE_NAME_LEN]; - unsigned int imode; - - /* Copy a local file to a remote file. We may have to - copy the local file to the spool directory. */ - - imode = isysdep_file_mode (zfrom); - if (imode == 0) - ucabort (); - - if (! fcopy) - { - /* Make sure the daemon will be permitted to send - this file. */ - if (! fsysdep_daemon_access (zfrom)) - ucabort (); - if (! fin_directory_list (&sLocalsys, zfrom, - sLocalsys.zlocal_send, - TRUE, TRUE, zuser)) - ulog (LOG_FATAL, "Not permitted to send from %s", - zfrom); - strcpy (abtname, "D.0"); - } - else - { - char *zdata; - - zconst = zsysdep_data_file_name (qdestsys, bgrade, - abtname, (char *) NULL, - (char *) NULL); - if (zconst == NULL) - ucabort (); - zdata = xstrdup (zconst); - - ucrecord_file (zdata); - if (! fcopy_file (zfrom, zdata, FALSE, TRUE)) - ucabort (); - xfree ((pointer) zdata); - } - - s.bcmd = 'S'; - s.pseq = NULL; - s.zfrom = zfrom; - s.zto = zdestfile; - s.zuser = zuser; - s.zoptions = absend_options; - s.ztemp = xstrdup (abtname); - s.imode = imode; - s.znotify = znotify; - s.cbytes = -1; - - ucadd_cmd (qdestsys, &s); - } - } - else - { - int clen; - char *zcopy; - struct ssysteminfo *qfromsys; - - /* Add the current directory to the filename if it's not - already there. */ - if (fexpand) - { - zconst = zsysdep_add_cwd (zexclam + 1, FALSE); - if (zconst == NULL) - ucabort (); - zconst = xstrdup (zconst); - } - else - zconst = zexclam + 1; - - /* Read the system information. */ - clen = zexclam - argv[i]; - zcopy = (char *) xmalloc (clen + 1); - strncpy (zcopy, argv[i], clen); - zcopy[clen] = '\0'; - - qfromsys = ((struct ssysteminfo *) - xmalloc (sizeof (struct ssysteminfo))); - if (fread_system_info (zcopy, qfromsys)) - xfree ((pointer) zcopy); - else - { - *qfromsys = sUnknown; - qfromsys->zname = zcopy; - } - - if (! fsysdep_make_spool_dir (qfromsys)) - ucabort (); - - if (flocaldest) - { - char *zto; - - /* Fetch a file from a remote system. If the remote - filespec is wildcarded, we must generate an 'X' - request. We currently check for Unix shell - wildcards. Note that it should do no harm to mistake - a non-wildcard for a wildcard. */ - - if (strchr (zconst, '*') != NULL - || strchr (zconst, '?') != NULL - || strchr (zconst, '[') != NULL) - { - const char *zuse; - - if (qfromsys->zlocalname != NULL) - zuse = qfromsys->zlocalname; - else - zuse = zLocalname; - - s.bcmd = 'X'; - zto = (char *) alloca (strlen (zuse) - + strlen (zdestfile) - + sizeof "!"); - sprintf (zto, "%s!%s", zuse, zdestfile); - zto = xstrdup (zto); - } - else - { - s.bcmd = 'R'; - zto = zdestfile; - } - s.pseq = NULL; - s.zfrom = zconst; - s.zto = zto; - s.zuser = zuser; - s.zoptions = abrec_options; - s.ztemp = ""; - s.imode = 0; - s.znotify = ""; - s.cbytes = -1; - - ucadd_cmd (qfromsys, &s); - } - else - { - /* Move a file from one remote system to another. */ - - s.bcmd = 'X'; - s.pseq = NULL; - s.zfrom = zconst; - s.zto = argv[argc - 1]; - s.zuser = zuser; - s.zoptions = abrec_options; - s.ztemp = ""; - s.imode = 0; - s.znotify = ""; - s.cbytes = -1; - - ucadd_cmd (qfromsys, &s); - } - } - } - - /* See if we got an interrupt, presumably from the user. */ - if (FGOT_SIGNAL ()) - ucabort (); - - /* Now push out the actual commands, making log entries for them. */ - ulog_to_file (TRUE); - ulog_user (zuser); - - ucspool_cmds (bgrade, fjobid); - - ulog_close (); - - if (! fuucico) - fexit = TRUE; - else - { - const char *zsys; - boolean fany; - - zsys = zcone_system (&fany); - if (zsys != NULL) - fexit = fsysdep_run (TRUE, "uucico", "-s", zsys); - else if (fany) - fexit = fsysdep_run (TRUE, "uucico", "-r1", (const char *) NULL); - else - fexit = TRUE; - } - - usysdep_exit (fexit); - - /* Avoid error about not returning. */ - return 0; -} - -static void -ucusage () -{ - fprintf (stderr, - "Taylor UUCP version %s, copyright (C) 1991, 1992 Ian Lance Taylor\n", - abVersion); - fprintf (stderr, - "Usage: uucp [options] file1 [file2 ...] dest\n"); - fprintf (stderr, - " -c: Do not copy local files to spool directory\n"); - fprintf (stderr, - " -C: Copy local files to spool directory (default)\n"); - fprintf (stderr, - " -d: Create necessary directories (default)\n"); - fprintf (stderr, - " -f: Do not create directories (fail if they do not exist)\n"); - fprintf (stderr, - " -g grade: Set job grade (must be alphabetic)\n"); - fprintf (stderr, - " -m: Report status of copy by mail\n"); - fprintf (stderr, - " -n user: Report status of copy by mail to remote user\n"); - fprintf (stderr, - " -r: Do not start uucico daemon\n"); - fprintf (stderr, - " -s file: Report completion status to file\n"); - fprintf (stderr, - " -j: Report job id\n"); - fprintf (stderr, - " -x debug: Set debugging level\n"); -#if HAVE_TAYLOR_CONFIG - fprintf (stderr, - " -I file: Set configuration file to use (default %s%s)\n", - NEWCONFIGLIB, CONFIGFILE); -#endif /* HAVE_TAYLOR_CONFIG */ - exit (EXIT_FAILURE); -} - -/* We keep a list of jobs for each system. */ - -struct sjob -{ - struct sjob *qnext; - const struct ssysteminfo *qsys; - int ccmds; - struct scmd *pascmds; -}; - -static struct sjob *qCjobs; - -static void -ucadd_cmd (qsys, qcmd) - const struct ssysteminfo *qsys; - const struct scmd *qcmd; -{ - struct sjob *qjob; - - for (qjob = qCjobs; qjob != NULL; qjob = qjob->qnext) - if (strcmp (qjob->qsys->zname, qsys->zname) == 0) - break; - - if (qjob == NULL) - { - qjob = (struct sjob *) xmalloc (sizeof (struct sjob)); - qjob->qnext = qCjobs; - qjob->qsys = qsys; - qjob->ccmds = 0; - qjob->pascmds = NULL; - qCjobs = qjob; - } - - qjob->pascmds = ((struct scmd *) - xrealloc ((pointer) qjob->pascmds, - (qjob->ccmds + 1) * sizeof (struct scmd))); - qjob->pascmds[qjob->ccmds] = *qcmd; - ++qjob->ccmds; -} - -static void -ucspool_cmds (bgrade, fjobid) - int bgrade; - boolean fjobid; -{ - struct sjob *qjob; - const char *zjobid; - - for (qjob = qCjobs; qjob != NULL; qjob = qjob->qnext) - { - ulog_system (qjob->qsys->zname); - zjobid = zsysdep_spool_commands (qjob->qsys, bgrade, qjob->ccmds, - qjob->pascmds); - if (zjobid != NULL) - { - int i; - struct scmd *qcmd; - - for (i = 0, qcmd = qjob->pascmds; i < qjob->ccmds; i++, qcmd++) - { - if (qcmd->bcmd == 'S') - ulog (LOG_NORMAL, "Queuing send of %s to %s", - qcmd->zfrom, qcmd->zto); - else if (qcmd->bcmd == 'R') - ulog (LOG_NORMAL, "Queuing request of %s to %s", - qcmd->zfrom, qcmd->zto); - else - ulog (LOG_NORMAL, "Queuing execution (%s to %s)", - qcmd->zfrom, qcmd->zto); - } - - if (fjobid) - printf ("%s\n", zjobid); - } - } -} - -/* Return the system name for which we have created commands, or NULL - if we've created commands for more than one system. Set *pfany to - FALSE if we didn't create work for any system. */ - -static const char * -zcone_system (pfany) - boolean *pfany; -{ - if (qCjobs == NULL) - { - *pfany = FALSE; - return NULL; - } - - *pfany = TRUE; - - if (qCjobs->qnext == NULL) - return qCjobs->qsys->zname; - else - return NULL; -} - -/* Keep track of all files we have created so that we can delete them - if we get a signal. The argument will be on the heap. */ - -static int ccfiles; -static const char **pcaz; - -static void -ucrecord_file (zfile) - const char *zfile; -{ - pcaz = (const char **) xrealloc ((pointer) pcaz, - (ccfiles + 1) * sizeof (const char *)); - pcaz[ccfiles] = zfile; - ++ccfiles; -} - -/* Delete all the files we have recorded and exit. */ - -static void -ucabort () -{ - int i; - - for (i = 0; i < ccfiles; i++) - (void) remove (pcaz[i]); - ulog_close (); - usysdep_exit (FALSE); -} diff --git a/gnu/libexec/uucp/uucp.h b/gnu/libexec/uucp/uucp.h deleted file mode 100644 index 052995591f7..00000000000 --- a/gnu/libexec/uucp/uucp.h +++ /dev/null @@ -1,1208 +0,0 @@ -/* 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 AIRS, P.O. Box 520, Waltham, MA 02254. - - $Id: uucp.h,v 1.2 1993/08/02 17:25:15 mycroft Exp $ -*/ - -/* Get the system configuration parameters. */ - -#include "conf.h" -#include "policy.h" - -/* We always want <stdio.h>. */ - -#include <stdio.h> - -/* We need <signal.h> for sig_atomic_t. */ - -#include <signal.h> - -/* On some systems that won't get us sig_atomic_t. */ - -#if ! HAVE_SIG_ATOMIC_T_IN_SIGNAL_H -#if HAVE_SIG_ATOMIC_T_IN_TYPES_H -#include <sys/types.h> -#else /* ! 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) */ -#endif /* ! HAVE_SIG_ATOMIC_T_IN_TYPES_H */ -#endif /* ! HAVE_SIG_ATOMIC_T_IN_SIGNAL_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) */ - -/* Set up some definitions for both ANSI C and Classic C. - - P() is used for function prototypes (e.g. extern int foo P((int)) ). - pointer is used for a generic pointer (i.e. void *). - constpointer is used for a generic pointer to constant data. - BUCHAR is used 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 */ - -/* 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 int strcmp (), strncmp (); -extern char *strcpy (), *strncpy (), *strchr (), *strrchr (), *strtok (); -extern char *strcat (), *strerror (), *strstr (); -/* These should be size_t, but there's no declaration to conflict with. */ -extern int strlen (), strspn (), strcspn (); -#if ! HAVE_MEMORY_H -extern pointer memcpy (), memmove (), memchr (); -extern int memcmp (); -#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 void free (), exit (), perror (), abort (), qsort (); -extern long atol (), strtol (); -extern int atoi (); -extern char *getenv (); -#endif /* ! HAVE_STDLIB_H */ - -/* Define alloca as suggested by David MacKenzie. AIX requires this - to be the first thing in the file. I really hate system dependent - cruft like this (and this is the only case in which it appears), - but I guess that's the price of using alloca. */ -#define HAVE_ALLOCA 1 -#ifdef __GNUC__ -#ifndef __NeXT__ -#define alloca __builtin_alloca -#endif /* ! defined (__NeXT__) */ -#else /* ! defined(__GNUC__) */ -#ifdef sparc -#include <alloca.h> -#else /* ! defined (sparc) */ -#ifdef _AIX - #pragma alloca -#else /* ! defined (_AIX) */ -/* We may not be using a real alloca. */ -#undef HAVE_ALLOCA -#define HAVE_ALLOCA 0 -#endif /* ! defined (_AIX) */ -#endif /* ! defined (sparc) */ -#endif /* ! defined (__GNUC__) */ - -/* 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 (some versions of SunOS have - <stdlib.h> but left them out). */ -#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 - -/* 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 ffilerewind(e) (fseek (e, (long) 0, SEEK_SET) == 0) -#else -#define ffilerewind(e) (fseek (e, (long) 0, 0) == 0) -#endif -#define ffileclose(e) (fclose (e) == 0) - -extern int fclose (), fseek (); -/* The ferror and feof functions are often macros, so we can't safely - define them. The fread and fwrite functions may return int or may - return size_t, so we can't safely define them. */ - -#else /* ! USE_STDIO */ - -#if HAVE_UNISTD_H -#include <unistd.h> -#endif - -/* It would be nice to provide prototypes for read, write and lseek, but - we can't because they might not return int. */ -extern int close (); - -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 ffilerewind(e) (lseek (e, (long) 0, SEEK_SET) >= 0) -#else -#define ffilerewind(e) (lseek (e, (long) 0, 0) >= 0) -#endif -#define ffileclose(e) (close (e) >= 0) - -extern int read (), write (), close (); -/* The lseek function should return off_t, but we don't want to - include sysdep.h here. */ - -#endif /* ! USE_STDIO */ - -/* Define the time_t type. This still won't help if they don't have - time or ctime. */ - -#if ! HAVE_TIME_T && ! HAVE_SYS_TIME_T -typedef long time_t; -#endif - -/* The types of entries allowed in a command table (struct scmdtab). - If CMDTABTYPE_FN is used, it should be or'ed with the number of - arguments permitted, or 0 if there is no single number. - CMDTABTYPE_PREFIX means that the string in the scmdtab table is a - prefix; any command which matches the prefix should be used to call - a function. The number of arguments should be or'ed in as with - CMDTABTYPE_FN. */ - -#define CMDTABTYPE_BOOLEAN (0x12) -#define CMDTABTYPE_INT (0x22) -#define CMDTABTYPE_LONG (0x32) -#define CMDTABTYPE_STRING (0x40) -#define CMDTABTYPE_FULLSTRING (0x50) -#define CMDTABTYPE_FN (0x60) -#define CMDTABTYPE_PREFIX (0x70) - -#define TTYPE_CMDTABTYPE(i) ((i) & 0x70) -#define CARGS_CMDTABTYPE(i) ((i) & 0x0f) - -/* These flags are or'red together to form an argument to - uprocesscmds. */ -#define CMDFLAG_WARNUNRECOG (0x1) -#define CMDFLAG_CASESIGNIFICANT (0x2) -#define CMDFLAG_BACKSLASH (0x4) - -/* The enumeration returned by functions called by uprocesscmds. */ - -enum tcmdtabret -{ - CMDTABRET_CONTINUE, - CMDTABRET_FREE, - CMDTABRET_EXIT, - CMDTABRET_FREE_AND_EXIT -}; - -/* This structure holds the argument to uprocesscmds. */ - -struct scmdtab -{ - /* Command name. */ - const char *zcmd; - /* Command type (one of CMDTABTYPE_...). */ - int itype; - /* This is the address of the variable if not CMDTABTYPE_FN. */ - pointer pvar; - /* This is used if CMDTABTYPE_FN. */ - enum tcmdtabret (*ptfn) P((int argc, char **argv, pointer par, - const char *zerr)); -}; - -/* This structure holds the information we need for a chat script. */ - -struct schat_info -{ - /* The script itself, if any. */ - char *zchat; - /* The program to run, if any. */ - char *zprogram; - /* The timeout for the chat script. */ - int ctimeout; - /* The list of failure strings. */ - char *zfail; - /* Whether to strip incoming characters to seven bits. */ - boolean fstrip; -}; - -/* This macro is used to initialize the entries of an schat_info - structure to the correct default values. */ - -#define INIT_CHAT(q) \ - ((q)->zchat = NULL, \ - (q)->zprogram = NULL, \ - (q)->ctimeout = 60, \ - (q)->zfail = NULL, \ - (q)->fstrip = TRUE) - -/* This structure holds a set of special commands executed for - particular protocols. */ - -struct sproto_param -{ - /* Protocol. */ - char bproto; - /* Number of entries. */ - int centries; - /* Specific entries. */ - struct sproto_param_entry - { - int cargs; - char **azargs; - } *qentries; -}; - -/* The ssysteminfo structure holds information about a remote system. */ - -struct ssysteminfo -{ - /* System name. */ - const char *zname; - /* List of aliases separated by ' '. */ - char *zalias; - /* Linked list of alternate sets of call information. */ - struct ssysteminfo *qalternate; - /* Name for this alternate (may be NULL). */ - char *zalternate; - /* Legal times to call. A grade, a time string, an optional ';' and - retry time, ' ', repeated. */ - char *ztime; - /* Grade to request of other system and associated time. A grade, a - time string, ' ', repeated. */ - char *zcalltimegrade; - /* Sizes for local requests and calls. A size, ' ', a time string, - ' ', repeated. */ - char *zcall_local_size; - /* Sizes for remote requests and local calls. */ - char *zcall_remote_size; - /* Sizes for local requests when called. */ - char *zcalled_local_size; - /* Sizes for remote requests when called. */ - char *zcalled_remote_size; - /* Baud rate (all right, so it's really bps). */ - long ibaud; - /* High baud rate, if a range is permitted (0 if no range). */ - long ihighbaud; - /* Port name, if qport is not used. */ - char *zport; - /* Specific port information, if zport is not used. */ - struct sport *qport; - /* Phone number. */ - char *zphone; - /* Chat script information. */ - struct schat_info schat; - /* Login name to use when calling the remote system. */ - const char *zcall_login; - /* Password to use when calling the remote system. */ - const char *zcall_password; - /* Login name that must be used by the other system when calling in. */ - const char *zcalled_login; - /* Whether to call back the remote system. */ - boolean fcallback; - /* Whether system uses sequencing. */ - boolean fsequence; - /* List of protocols to use for this system (may be NULL). */ - const char *zprotocols; - /* Number of entries in protocol parameters array. */ - int cproto_params; - /* Protocol parameters array. */ - struct sproto_param *qproto_params; - /* Chat to run when called. */ - struct schat_info scalled_chat; -#if DEBUG > 1 - /* Debugging level to set during a call. */ - int idebug; - /* Maximum remote debugging level. */ - int imax_remote_debug; -#endif - /* Whether the other system may request things when we call them. */ - boolean fcall_request; - /* Whether the other system may request things when they call us. */ - boolean fcalled_request; - /* Whether we may request things when we call. */ - boolean fcall_transfer; - /* Whether we may request things when they call. */ - boolean fcalled_transfer; - /* List of directories that may be sent by local request. */ - const char *zlocal_send; - /* List of directories that may be sent by local request when the - other system placed the call (if NULL, use zlocal_send). This is - actually never used currently. */ - const char *zcalled_local_send; - /* List of directories that may be sent by remote request. */ - const char *zremote_send; - /* List of directories that may be sent by remote request when the - other system placed the call (if NULL, use zremote_send). This - is currently only used by HAVE_BNU_CONFIG. */ - const char *zcalled_remote_send; - /* List of directories that may be received into by local request. */ - const char *zlocal_receive; - /* List of directories that may be received into by local request - when the other system placed the call (if NULL, use - zlocal_receive). This is currently only used under - HAVE_BNU_CONFIG. */ - const char *zcalled_local_receive; - /* List of directories that may be received into by remote request. */ - const char *zremote_receive; - /* List of directories that may be received into by remote request - when the other system placed the call (if NULL, use - zremote_receive). This is currently only used by - HAVE_BNU_CONFIG. */ - const char *zcalled_remote_receive; - /* Path to use for command execution. */ - const char *zpath; - /* List of commands that may be executed. */ - const char *zcmds; - /* Amount of free space to leave. */ - long cfree_space; - /* List of systems that may be forwarded to. */ - const char *zforwardto; - /* The public directory to use for this sytem. */ - const char *zpubdir; - /* The local name to use for this remote system. */ - const char *zlocalname; -}; - -/* The tfailure enumeration holds reasons for failure to be passed to - the pffail function of a protocol. */ - -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 -}; - -/* 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 - isysdep_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, '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 pfreceive protocol function). */ - const char *ztemp; - /* Mode to give newly created file ('S' and pfreceive protocol fn). */ - unsigned int imode; - /* User to notify on remote system (optional; 'S' only). */ - const char *znotify; - /* File size (-1 if not supplied) ('S' and pfreceive protocol fn). */ - long cbytes; -}; - -/* The highest grade. */ -#define BGRADE_HIGH ('0') - -/* The lowest grade. */ -#define BGRADE_LOW ('z') - -/* Whether a character is a legal grade. */ -#define FGRADE_LEGAL(b) (isalnum (BUCHAR (b))) - -#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. */ - -/* Read the configuration file. */ -extern void uread_config P((const char *zname)); - -/* Read information about all systems. */ -extern void uread_all_system_info P((int *pc, struct ssysteminfo **ppas)); - -/* Read information about a specific system. */ -extern boolean fread_system_info P((const char *zsystem, - struct ssysteminfo *qsys)); - -/* Set the default values for an uninitialized system. */ -extern void uset_system_defaults P((struct ssysteminfo *qsys)); - -/* Start getting commands for unknown systems. */ -extern void uiunknown_start P((void)); - -/* Process a command defining unknown systems. */ -extern enum tcmdtabret tiunknown P((int argc, char **argv, - pointer pvar, const char *zerr)); - -/* Finish getting commands for unknown systems. */ -extern void uiunknown_end P((void)); - -/* Set up the sLocalsys structure. */ -extern void uisetup_localsys P((void)); - -/* Open a set of files and pretend that they were all catenated - together. */ -extern struct smulti_file *qmulti_open P((const char *znames)); - -/* Close a set of files opened by qmulti_open. */ -extern boolean fmulti_close P((struct smulti_file *q)); - -/* Process a set of commands. */ -extern void uprocesscmds P((FILE *e, struct smulti_file *qmulti, - const struct scmdtab *qcmds, - const char *zerr, int iflags)); - -/* Process a single command. */ -extern enum tcmdtabret tprocess_one_cmd P((int cargs, char **azargs, - const struct scmdtab *qcmds, - const char *zerr, - int iflags)); - -/* Translate an unknown system name into something acceptable for the - spool directory stuff. */ -extern const char *ztranslate_system P((const char *zsystem)); - -/* Check login name and password. */ -extern boolean fcheck_login P((const char *zuser, const char *zpass)); - -/* 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((int ctimeout, boolean freport)); - -/* See whether a file belongs in the spool directory. */ -extern boolean fspool_file P((const char *zfile)); - -/* Store information about a file being sent. */ -extern boolean fstore_sendfile P((openfile_t e, pointer pseq, - const char *zfrom, const char *zto, - const char *ztosys, const char *zuser, - const char *zmail)); - -/* Finish sending a file. The zwhy and fnever arguments are used - if the file was not received correctly. */ -extern boolean fsent_file P((boolean freceived, long cbytes, - const char *zwhy, boolean fnever)); - -/* Note an error sending a file. The function fsent_file must still - be called after this is called. */ -extern void usendfile_error P((void)); - -/* Store information about a file being received. */ -extern boolean fstore_recfile P((openfile_t e, pointer pseq, - const char *zfrom, const char *zto, - const char *zfromsys, const char *zuser, - unsigned int imode, const char *zmail, - const char *ztemp)); - -/* Finish receiving a file. The zwhy and fnever arguments are used - if the file was not received correctly. */ -extern boolean freceived_file P((boolean fsent, long cbytes, - const char *zwhy, boolean fnever)); - -/* Note an error receiving a file. The function freceived_file must - still be called after this is called. */ -extern void urecfile_error P((void)); - -/* Prepare to receive a file again by discarding the previous - contents. */ -extern boolean frecfile_rewind P((void)); - -/* 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 qsys - argument are passed down to allow ~ expansion. 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 struct ssysteminfo *qsys, - const char *zfile, - const char *zdirs, - boolean fcheck, - boolean freadable, - const char *zuser)); - -/* Get the login name and password to use when calling a system out - of the call out login file. The pzlog and pzpass arguments are set - to point to malloc'ed strings which must be freed after they have - been used. */ -extern boolean fcallout_login P((const struct ssysteminfo *qsys, - char **pzlog, char **pzpass)); - -/* Add a string to the end of another. */ -extern void uadd_string P((char **pz, const char *z, int bsep)); - -/* Process a chat command. These are handled using CMDTABTYPE_PREFIX. - This function switches off on argv[0]. */ -extern enum tcmdtabret tprocess_chat_cmd P((int argc, char **argv, - pointer pvar, - const char *zerr)); - -/* Add a protocol parameter entry. */ -extern enum tcmdtabret tadd_proto_param P((int *pc, - struct sproto_param **pq, - const char *zerr, int cargs, - char **azargs)); - -/* Apply protocol parameters. */ -extern void uapply_proto_params P((int bproto, struct scmdtab *qcmds, - int c, struct sproto_param *pas)); - -/* Parse a command string. */ -extern boolean fparse_cmd P((char *zcmd, struct scmd *qcmd)); - -/* Specify which machines may be accepted for a login name. */ -extern void uadd_validate P((const char *zlogname, int cmachines, - const char **pazmachines)); - -/* Check whether a login name/machine name pair is acceptable. */ -extern boolean fcheck_validate P((const char *zlogname, - const char *zmachine)); - -/* Compare the execution times of two grades. Return < 0 if the first - argument should be executed first, 0 if they are the same, > 0 if - the second argument should be executed first. */ -extern int igradecmp P((int b1, int b2)); - -/* Make a log entry. */ -#if ANSI_C && HAVE_VFPRINTF -extern void ulog P((enum tlog ttype, const char *zfmt, ...)) -#if __GNUC__ > 1 - __attribute__ ((format (printf, 2, 3))) -#endif - ; -#else -extern void ulog (); -#endif - -/* 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((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)); - -/* We have lost the connection; record any in progress file transfers - in the statistics file. */ -extern void ustats_failed P((void)); - -/* 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, - int 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 int 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. If the code is compiled - without debugging this is a dummy function. This returns a value - for iDebug. */ -extern int idebug_parse P((const char *)); - -/* Parse a debugging option in a configuration file. This is used for - the ``debug'' command. */ -extern enum tcmdtabret tidebug_parse P((int argc, char **argv, - pointer pvar, const char *zerr)); - -#else /* DEBUG <= 1 */ - -/* Dummy version of idebug_parse. This makes the option processing - look a little neater. */ - -#define idebug_parse(z) 0 - -#endif /* DEBUG <= 1 */ - -/* Copy one file to another. */ -extern boolean fcopy_file P((const char *zfrom, const char *zto, - boolean fpublic, boolean fmkdirs)); - -/* Read a line from a set of files opened by qmulti_open. The return - value is an malloc'ed buffer. This will return NULL when all the - files have been exhausted. If pffirst is not NULL, it will be set - to TRUE if this is the first line of a file. If pzname is not - NULL, it will be set to the file name from which the line was read. - If fbackslash is TRUE, lines may be continued by using a backslash - as the last character before the newline. */ -extern char *zmulti_gets P((struct smulti_file *q, boolean *pffirst, - const char **pzname, boolean fbackslash)); - -/* Read an arbitrary length string from a file, returning an malloc'ed - buffer. If the fbackslash argument is true, lines may be continued - by using a backslash as the last character before the newline. */ -extern char *zfgets P((FILE *e, boolean fbackslash)); - -/* Copy a string into memory without fail. */ -extern char *xstrdup P((const char *)); - -/* Allocate memory without fail. */ -extern pointer xmalloc P((int)); - -/* Realloc memory without fail. */ -extern pointer xrealloc P((pointer, int)); - -/* Free memory (accepts NULL pointers, which some libraries erroneously - do not). */ -extern void xfree P((pointer)); - -#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 -/* Use macros to access stricmp and strnicmp as strcasecmp and - strncasecmp. */ -#define strcasecmp stricmp -#define strncasecmp strnicmp -#else /* ! HAVE_STRICMP */ -/* Use our own case insensitive string comparisons. */ -extern int strcasecmp P((const char *z1, const char *z2)); -extern int strncasecmp P((const char *z1, const char *z2, int clen)); -#endif /* ! HAVE_STRICMP */ -#endif /* ! HAVE_STRCASECMP */ - -#if ! HAVE_STRERROR -/* Get a string corresponding to an error message. */ -extern char *strerror P((int ierr)); -#endif - -/* Get the appropriate definitions for memcmp, memcpy, memchr and - bzero. Hopefully the declarations of bzero, bcmp and bcopy will - not cause any trouble. */ -#if ! HAVE_MEMCMP -#if HAVE_BCMP -#define memcmp(p1, p2, c) bcmp ((p1), (p2), (c)) -extern int bcmp (); -#else /* ! HAVE_BCMP */ -extern int memcmp P((constpointer p1, constpointer p2, int c)); -#endif /* ! HAVE_BCMP */ -#endif /* ! HAVE_MEMCMP */ - -#if ! HAVE_MEMCPY -#if HAVE_BCOPY -#define memcpy(pto, pfrom, c) bcopy ((pfrom), (pto), (c)) -extern void bcopy (); -#else /* ! HAVE_BCOPY */ -extern pointer memcpy P((pointer pto, constpointer pfrom, int c)); -#endif /* ! HAVE_BCOPY */ -#endif /* ! HAVE_MEMCPY */ - -#if ! HAVE_MEMCHR -extern pointer memchr P((constpointer p, int b, int c)); -#endif - -#if HAVE_BZERO -#ifndef bzero /* bzero is sometimes a macro. */ -extern void bzero (); -#endif -#else /* ! 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 */ - -/* Move a memory block safely. Go through xmemmove to allow for - systems which have the prototype (using size_t, which we don't want - to use since some systems won't have it) but not the function. */ -#if HAVE_MEMMOVE -#define xmemmove memmove -#else /* ! HAVE_MEMMOVE */ -extern pointer xmemmove P((pointer, constpointer, int)); -#endif /* ! HAVE_MEMMOVE */ - -/* 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, - int celes, int cbytes, - int (*pficmp) P((constpointer, constpointer)))); -#endif - -/* Convert a string to lower case. */ -#if ! HAVE_STRLWR -extern char *strlwr P((char *)); -#endif - -/* 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[]; - -/* Version number string. */ -extern char abVersion[]; - -/* Local UUCP name. */ -extern const char *zLocalname; - -/* System information file names. */ -extern char *zSysfile; - -/* Port information file names. */ -extern char *zPortfile; - -/* Dialer information file names. */ -extern char *zDialfile; - -/* Local spool directory. */ -extern const char *zSpooldir; - -/* Public directory. */ -extern const char *zPubdir; - -/* Log file name. */ -extern const char *zLogfile; - -/* Statistics file name. */ -extern const char *zStatfile; - -#if DEBUG > 1 -/* Debugging file name. */ -extern const char *zDebugfile; -#endif - -/* Files containing login names and passwords to use when calling out. */ -extern char *zCallfile; - -/* Files containing login names and passwords to check when somebody - calls in. */ -extern char *zPwdfile; - -/* Files containing dialcodes. */ -extern char *zDialcodefile; - -#if HAVE_V2_CONFIG -/* TRUE if we should read V2 configuration files. */ -extern boolean fV2; - -/* Read the V2 L.sys file. */ -extern void uv2_read_systems P((int *pc, struct ssysteminfo **ppas)); - -#endif /* HAVE_V2_CONFIG */ - -#if HAVE_BNU_CONFIG -/* TRUE if we should read BNU configuration files. */ -extern boolean fBnu; - -/* The names of the BNU system files to read. */ -extern char *zBnu_systems; - -/* The names of the BNU dialers files to read. */ -extern char *zBnu_dialers; - -/* The names of the BNU devices files to read. */ -extern char *zBnu_devices; - -/* Routines to read BNU files. */ -extern void ubnu_read_sysfiles P((void)); -extern void ubnu_read_systems P((int *pc, struct ssysteminfo **ppas)); - -#endif /* HAVE_BNU_CONFIG */ - -/* TRUE if we accept calls from unknown system. */ -extern boolean fUnknown_ok; - -/* The ssysteminfo structure we use for unknown systems. */ -extern struct ssysteminfo sUnknown; - -/* The ssysteminfo structure we use for the local system. */ -extern struct ssysteminfo sLocalsys; - -/* The maximum number of uuxqt processes which may be running at one - time. */ -extern int cMaxuuxqts; - -/* 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). */ -#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]; - -/* 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 fport_open. It may be NULL. */ -extern char *zLdevice; diff --git a/gnu/libexec/uucp/uucp.info b/gnu/libexec/uucp/uucp.info deleted file mode 100644 index 0f23271b8ff..00000000000 --- a/gnu/libexec/uucp/uucp.info +++ /dev/null @@ -1,98 +0,0 @@ -Info file uucp.info, produced by Makeinfo, -*- Text -*- from input -file uucp.texi. - - This file documents Taylor UUCP, version 1.03. - - Copyright (C) 1992 Free Software Foundation, Inc. - - Permission is granted to make and distribute verbatim copies of this -manual provided the copyright notice and this permission notice are -preserved on all copies. - - Permission is granted to copy and distribute modified versions of -this manual under the conditions for verbatim copying, provided also -that the section entitled "Copying" are included exactly as in the -original, and provided that the entire resulting derived work is -distributed under the terms of a permission notice identical to this -one. - - Permission is granted to copy and distribute translations of this -manual into another language, under the above conditions for modified -versions, except that the section entitled "Copying" may be included -in a translation approved by the author instead of in the original -English. - -Indirect: -uucp.info-1: 984 -uucp.info-2: 49152 -uucp.info-3: 98532 -uucp.info-4: 148069 - -Tag Table: -(Indirect) -Node: Top986 -Node: Copying5410 -Node: Introduction7937 -Node: Overall Installation14735 -Node: Configuration15321 -Node: Compilation17211 -Node: Testing22098 -Node: Installation27587 -Node: Usage27959 -Node: TCP29382 -Node: Configuration Files32661 -Node: Configuration File Format34119 -Node: Configuration Examples35799 -Node: config File Examples36462 -Node: Leaf Example40328 -Node: Gateway Example43008 -Node: Time Strings47380 -Node: Chat Scripts49154 -Node: config File57228 -Node: Miscellaneous (config)57841 -Node: Configuration File Names60294 -Node: Log File Names64498 -Node: Debugging Levels65766 -Node: sys File68632 -Node: Defaults and Alternates69512 -Node: Naming the System72606 -Node: Calling Out74334 -Node: When to Call74691 -Node: Placing the Call78279 -Node: Logging In81504 -Node: Accepting a Call84766 -Node: Protocol Selection87579 -Node: File Transfer Control93689 -Node: Miscellaneous (sys)98534 -Node: Default sys File Values102756 -Node: port File103508 -Node: dial File110240 -Node: Security115883 -Node: Protocols121151 -Node: Grades122501 -Node: Lock Files126091 -Node: UUCP Protocol128421 -Node: Initial Handshake129139 -Node: File Requests135702 -Node: S Request136896 -Node: R Request142317 -Node: X Request145480 -Node: H Request147195 -Node: Final Handshake148071 -Node: g Protocol148888 -Node: f Protocol159203 -Node: t Protocol162285 -Node: e Protocol163346 -Node: x Protocol164142 -Node: d Protocol164620 -Node: Capital G Protocol165006 -Node: Documentation References165559 -Node: Hacking166526 -Node: System Dependence166894 -Node: Naming Conventions168827 -Node: Patches170994 -Node: Acknowledgements171490 -Node: Index (concepts)177031 -Node: Index (configuration file)180596 - -End Tag Table diff --git a/gnu/libexec/uucp/uucp.info-1 b/gnu/libexec/uucp/uucp.info-1 deleted file mode 100644 index e8daa0a5879..00000000000 --- a/gnu/libexec/uucp/uucp.info-1 +++ /dev/null @@ -1,1149 +0,0 @@ -Info file uucp.info, produced by Makeinfo, -*- Text -*- from input -file uucp.texi. - - This file documents Taylor UUCP, version 1.03. - - Copyright (C) 1992 Free Software Foundation, Inc. - - Permission is granted to make and distribute verbatim copies of this -manual provided the copyright notice and this permission notice are -preserved on all copies. - - Permission is granted to copy and distribute modified versions of -this manual under the conditions for verbatim copying, provided also -that the section entitled "Copying" are included exactly as in the -original, and provided that the entire resulting derived work is -distributed under the terms of a permission notice identical to this -one. - - Permission is granted to copy and distribute translations of this -manual into another language, under the above conditions for modified -versions, except that the section entitled "Copying" may be included -in a translation approved by the author instead of in the original -English. - - -File: uucp.info, Node: Top, Next: Copying, Prev: (dir), Up: (dir) - -Taylor UUCP 1.03 -**************** - - This is the documentation for the Taylor UUCP package, version 1.03. -The programs were written by Ian Lance Taylor. The author can be -reached at `<ian@airs.com>', or, equivalently, `<uunet!airs!ian>', or -`c/o Infinity Development, P.O. Box 520, Waltham MA, 02254'. - - There is a mailing list for discussion of the package. To join the -list, send a message to `<taylor-uucp-request@gnu.ai.mit.edu>'. Make -sure you include the address you want to receive messages at; do not -rely on the `From:' header. To send a message to the list, send it to -`<taylor-uucp@gnu.ai.mit.edu>'. - -* Menu: - -* Copying:: Taylor UUCP copying conditions -* Introduction:: Introduction to Taylor UUCP -* Overall Installation:: Taylor UUCP installation -* Configuration Files:: Taylor UUCP configuration files -* Protocols:: UUCP protocol internals -* Hacking:: Hacking Taylor UUCP -* Acknowledgements:: Acknowledgements - -* Index (concepts):: Concept index -* Index (configuration file):: Index to new configuration files - - -- The Detailed Node Listing -- - -Taylor UUCP Overall Installation - -* Configuration:: Configuring Taylor UUCP -* Compilation:: Compiling Taylor UUCP -* Testing:: Testing Taylor UUCP -* Installation:: Installing Taylor UUCP -* Usage:: Using Taylor UUCP -* TCP:: TCP together with Taylor UUCP - -Taylor UUCP Configuration Files - -* Configuration File Format:: Configuration file format -* Configuration Examples:: Examples of configuration files -* Time Strings:: How to write time strings -* Chat Scripts:: How to write chat scripts -* config File:: The main configuration file -* sys File:: The system configuration file -* port File:: The port configuration files -* dial File:: The dialer configuration files -* Security:: Security issues - -Examples of Configuration Files - -* config File Examples:: Examples of the main configuration file -* Leaf Example:: Call a single remote site -* Gateway Example:: The gateway for several local systems - -The Main Configuration File - -* Miscellaneous (config):: Miscellaneous config file commands -* Configuration File Names:: Using different configuration files -* Log File Names:: Using different log files -* Debugging Levels:: Debugging levels - -The System Configuration File - -* Defaults and Alternates:: Using defaults and alternates -* Naming the System:: Naming the system -* Calling Out:: Calling out -* Accepting a Call:: Accepting a call -* Protocol Selection:: Protocol selection -* File Transfer Control:: File transfer control -* Miscellaneous (sys):: Miscellaneous sys file commands -* Default sys File Values:: Default values - -Calling Out - -* When to Call:: When to call -* Placing the Call:: Placing the call -* Logging In:: Logging in - -UUCP protocol internals - -* Grades:: UUCP grades -* Lock Files:: UUCP lock file format -* UUCP Protocol:: The common UUCP protocol -* g Protocol:: The UUCP `g' protocol -* f Protocol:: The UUCP `f' protocol -* t Protocol:: The UUCP `t' protocol -* e Protocol:: The UUCP `e' protocol -* x Protocol:: The UUCP `x' protocol -* d Protocol:: The UUCP `d' protocol -* Capital G Protocol:: The UUCP `G' protocol -* Documentation References:: Documentation references - -The Common UUCP Protocol - -* Initial Handshake:: Initial handshake -* File Requests:: File requests -* Final Handshake:: Final handshake - -File Requests - -* S Request:: S request -* R Request:: R request -* X Request:: X request -* H Request:: H request - -Hacking Taylor UUCP - -* System Dependence:: System Dependence -* Naming Conventions:: Naming Conventions -* Patches:: Patches - - -File: uucp.info, Node: Copying, Next: Introduction, Prev: Top, Up: Top - -Taylor UUCP Copying Conditions -****************************** - - This package is covered by the GNU Public License. See the file -`COPYING' for details. If you would like to do something with this -package that you feel is reasonable but you feel is prohibited by the -license, contact me to see if we can work it out. - - Here is some propaganda from the Free Software Foundation. If you -find this stuff offensive or annoying, remember that you probably did -not spend any money to get this code. I did not write this code to -make life easier for developers of UUCP packages, I wrote it to help -end users, and I believe that these are the most appropriate -conditions for distribution. - - All the programs, scripts and documents relating to Taylor UUCP are -"free"; this means that everyone is free to use them and free to -redistribute them on a free basis. The Taylor UUCP-related programs -are not in the public domain; they are copyrighted and there are -restrictions on their distribution, but these restrictions are designed -to permit everything that a good cooperating citizen would want to do. -What is not allowed is to try to prevent others from further sharing -any version of these programs that they might get from you. - - Specifically, we want to make sure that you have the right to give -away copies of the programs that relate to Taylor UUCP, that you -receive source code or else can get it if you want it, that you can -change these programs or use pieces of them in new free programs, and -that you know you can do these things. - - To make sure that everyone has such rights, we have to forbid you to -deprive anyone else of these rights. For example, if you distribute -copies of the Taylor UUCP related programs, you must give the -recipients all the rights that you have. You must make sure that -they, too, receive or can get the source code. And you must tell them -their rights. - - Also, for our own protection, we must make certain that everyone -finds out that there is no warranty for the programs that relate to -Taylor UUCP. If these programs are modified by someone else and -passed on, we want their recipients to know that what they have is not -what we distributed, so that any problems introduced by others will -not reflect on our reputation. - - The precise conditions of the licenses for the programs currently -being distributed that relate to Taylor UUCP are found in the General -Public Licenses that accompany them. - - -File: uucp.info, Node: Introduction, Next: Overall Installation, Prev: Copying, Up: Top - -Introduction to Taylor UUCP -*************************** - - General introductions to UUCP are available, and perhaps one day I -will write one. In the meantime, here is a very brief one that -concentrates on the programs provided by Taylor UUCP. - - Taylor UUCP is a complete UUCP package. It is covered by the GNU -Public License, which means that the source code is always available. -It is composed of several programs, the names of which were -established by earlier UUCP packages. - -`uucp' - The `uucp' program is used to copy file between systems. It is - similar to the standard Unix `cp' program, except that you can - refer to a file on a remote system by using `system!' before the - file name. For example, to copy the file `notes.txt' to the - system `airs', you would say `uucp notes.txt airs!~/notes.txt'. - In this example `~' is used to name the UUCP public directory on - `airs'. - -`uux' - The `uux' program is used to request a program to be executed on a - remote system. This is how mail and news are transferred over - UUCP. As with `uucp', programs and files on remote systems may - be named by using `system!'. For example, to run the `rnews' - program on `airs' passing it standard input, you would say `uux - - airs!rnews'. The `-' means to read standard input and set things - up so that when `rnews' runs on `airs' it will receive the same - standard input. - - Neither `uucp' nor `uux' actually do any work immediately. -Instead, they queue up requests for later processing. They then start -a daemon process which processes the requests and calls up the -appropriate systems. Usually the daemon will also be started -regularly to check if there is any work to be done and to do it. The -advantage of this system is that it all happens automatically. You -don't have to sit around waiting for the files to be transferred. The -disadvantage is that if anything goes wrong it might be a while before -anybody notices. - -`uustat' - The `uustat' program does several things. By default it will - simply list all the jobs you have queued with `uucp' or `uux' - that have not yet been processed. You can use `uustat' to remove - any of your jobs from the queue. You can also it use it to show - the status of the UUCP system in various ways, such as showing the - connection status of all systems your system knows about. - -`uuname' - The `uuname' program by default lists all the remote systems your - system knows about. You can also use it to get the name of your - local system. It is mostly useful for shell scripts. - -`uulog' - The `uulog' program can be used to display entries in the UUCP log - file. It can select the entries for a particular system or a - particular user. You can use it to see what has happened to your - queued jobs in the past. - - These five programs just described, `uucp', `uux', `uustat', -`uuname', and `uulog', are the user programs provided by Taylor UUCP. -The first two add requests to the work queue, the third examines the -work queue, the fourth examines the configuration files, and the last -examines the log files. The real work is actually done by two daemon -processes, which are normally run automatically rather than by a user. - -`uucico' - The `uucico' daemon is the program which actually calls the remote - system and transfers files and requests. `uucico' is normally - started automatically by `uucp' and `uux'. Most systems will - also start it periodically to make sure that all work requests are - handled. `uucico' checks the queue to see what work needs to be - done, and then calls the appropriate systems. If the call fails, - perhaps because the phone line is busy, `uucico' leaves the - requests in the queue and goes on to the next system to call. It - is also possible to force `uucico' to call a remote system even if - there is no work to be done for it, so that it can pick up any - work that may be queued up remotely. - -`uuxqt' - The `uuxqt' daemon processes execution requests made by the `uux' - program on remote systems. It also processes requests made on - the local system which require files from a remote system. It is - normally started by `uucico'. - - Suppose you, on the system `bantam', want to copy a file to the -system `airs'. You would run the `uucp' command locally, with a -command like `uucp notes.txt airs!~/notes.txt'. This would queue up a -request on `bantam' for `airs', and would then start the `uucico' -daemon. `uucico' would see that there was a request for `airs' and -attempt to call it. When the call succeeded, another copy of `uucico' -would be started on `airs'. The two copies of `uucico' would tell -each other what they had to do and transfer the file from `bantam' to -`airs'. When the file transfer was complete the `uucico' on `airs' -would move it into the UUCP public directory. - - UUCP is often used to transfer mail. This is normally done -automatically by mailer programs. When `bantam' has a mail message to -send to `ian' at `airs', it executes `uux - airs!rmail ian' and writes -the mail message to the `uux' process as standard input. The `uux' -program, running on `bantam', will read the standard input and store -it and the `rmail' request on the work queue for `airs'. `uux' will -then start the `uucico' daemon. The `uucico' daemon will call up -`airs', just as in the `uucp' example, and transfer the work request -and the mail message itself. The `uucico' daemon on `airs' will put -the files on a local work queue. When the communication session is -over, the `uucico' daemon on `airs' will start the `uuxqt' daemon. -`uuxqt' will see the request to run, and will run `rmail ian' with the -mail message as standard input. The `rmail' program, which is not -part of the UUCP package, is then responsible for either putting the -message in the right mailbox on `airs' or forwarding the message on to -another system. - - Taylor UUCP comes with two other programs that are useful when -installing and configuring UUCP. - -`uuchk' - The `uuchk' program reads the UUCP configuration files and - displays a rather lengthy description of what it finds. This is - very useful when configuring UUCP to make certain that the UUCP - package will do what you expect it to do. - -`tstuu' - The `tstuu' program is a test harness for the UUCP package, which - will help ensure that it has been configured and compiled - correctly. It does not test everything, however, and it only - runs on Unix systems which support Berkeley style - pseudo-terminals. It can be useful when initially installing - Taylor UUCP. - - -File: uucp.info, Node: Overall Installation, Next: Configuration Files, Prev: Introduction, Up: Top - -Taylor UUCP Overall Installation -******************************** - - These are the installation instructions for the Taylor UUCP package. - -* Menu: - -* Configuration:: Configuring Taylor UUCP -* Compilation:: Compiling Taylor UUCP -* Testing:: Testing Taylor UUCP -* Installation:: Installing Taylor UUCP -* Usage:: Using Taylor UUCP -* TCP:: TCP together with Taylor UUCP - - -File: uucp.info, Node: Configuration, Next: Compilation, Prev: Overall Installation, Up: Overall Installation - -Configuring Taylor UUCP -======================= - - You will have to decide what types of configuration files you want -to use. This package supports a new sort of configuration file; *Note -Configuration files::. It also supports V2 configuration files -(`L.sys', `L-devices', etc.) and BNU configuration files (`Systems', -`Devices', etc.). No documentation is provided for V2 or BNU -configuration files. All types of configuration files can be used at -once, if you are so inclined. Currently using just V2 configuration -files is not really possible, because there is no way to specify a -dialer (there are no built in dialers, and the program does not know -how to read `acucap' or `modemcap'); however, V2 configuration files -can be used with a new style dialer file (*note dial file::.), or with -a BNU `Dialers' file. - - Use of BNU configuration files has two known bugs. A blank line in -the middle of an entry in the `Permissions' file will not be ignored as -it should be. Dialer programs are not recognized directly. If you -must use a dialer program, rather than an entry in `Devices', you must -use the `chat-program' command in a new style dialer file; see *Note -dial file::. You will have to invoke the dialer program via a shell -script, since an exit code of 0 is required to recognize success. - - If you are installing a new system, or you want to use the new form -of configuration files, you must write the configuration files. - - You must also decide what sort of spool directory you want to use. -If you will only be using these programs, I recommend -`SPOOLDIR_TAYLOR'; otherwise select the spool directory corresponding -to your existing UUCP package. The details of the spool directory -choices are described at somewhat tedious length in `sys3.unx'. - - -File: uucp.info, Node: Compilation, Next: Testing, Prev: Configuration, Up: Overall Installation - -Compiling Taylor UUCP -===================== - - 1. Take a look at the top of `Makefile.in' and set the appropriate - values for your system. These control where the program is - installed and which user on the system owns them (normally they - will be owned by a special user `uucp' rather than a real person; - they should probably not be owned by `root'). - - 2. Run the shell script `configure'. This script was generated using - David MacKenzie's `autoconf' program. It takes a while to run. - It will generate a file `conf.h', and copy `Makefile.in' to - `Makefile' with substitions (specifically, it will replace all - words between `@' characters in `Makefile.in'). - - You can pass certain arguments to `configure' in the - environment. Because `configure' will compile and run little - test programs to see what is available on your system, you must - tell it how to run your compiler. It recognizes the following - environment variables: - - `CC' - The C compiler. If this is not set, then if `configure' can - find `gcc' it will use `gcc -O', otherwise it will use `cc'. - - `DEFS' - Flags to pass the C compiler during configuration testing. - If this is not set, `configure' will use the empty string. - - `CFLAGS' - Flags to pass to the C compiler when compiling the actual - code. If this is not set, `configure' will use `-g'. - - `LDFLAGS' - Flags to pass to the C compiler when only linking, not - compiling. If this is not set, `configure' will use the - empty string. - - `LIBS' - Libraries to pass to the C compiler. If this is not set, - `configure' will use the empty string. - - `INSTALL' - The program to run to install UUCP in the binary directory. - If `configure' finds the BSD `install' program, it will set - this to `install -c'; otherwise, it will use `cp'. - - `INSTALLDATA' - The program to run to install UUCP data files, such as the - man pages and the info pages. If `configure' finds the BSD - `install' program, it will set this to `install -c -m 644'; - otherwise, it will use `cp'. - - Suppose you want to set the environment variable `CC' to - `rcc'. If you are using `sh' or `bash', invoke `configure' as - `CC=rcc configure'. If you are using `csh', do `setenv CC rcc; - sh configure'. - - On some systems you will want to use `LIBS=-lmalloc'. On some - you will want `LIBS=-lsocket'. On Xenix derived systems do not - use `LIBS=-lx' because this will bring in the wrong versions of - certain routines; if you want to use `-lx' you must specify - `LIBS=-lc -lx'. - - If `configure' fails for some reason, or if you have a very - wierd system, you may have to configure the package by hand. To - do this, copy the file `conf.h-dist' to `conf.h' and edit it for - your system. Then copy `Makefile.in' to `Makefile', find the - words within `@' characters, and set them correctly for your - system. - - 3. You should verify that `configure' worked correctly by checking - the files `conf.h' and `Makefile'. - - 4. This package uses the `alloca' function. The `configure' script - will try to figure out how to make it work on your system. If - `alloca' cannot be found, a simplistic substitute from `alloca.c' - will be used. If you provide your own `alloca.o' file, it will - be used instead; you might, for example, use the one from the GNU - emacs distribution. If none of this makes any sense to you, - don't worry; everything will probably work fine. - - 5. Edit `policy.h' for your local system. The comments should - explain the various choices. The default values are intended to - be reasonable, so you may not have to make any changes. - - 6. Type `make' to compile everything. You may get warnings about - implicit function declarations; ignore these (if you think they - can be eliminated, and you really know what you are talking - about, you may tell me about them). You may also get warnings - about `getopt.c' (this is from the GNU library and I do not want - to change it) and about a variable not protected from `setjmp' in - `sys2.c' (the data flow ensures that this can never be a - problem). The `tstuu.c' file is not particularly portable; if - you can't figure out how to compile it you can safely ignore it, - as it is only used for testing. If you have any other problems - there is probably a bug in the `configure' script. - - 7. Please report any problems you have. That is the only way they - will get fixed for other people. Supply a patch if you can, or - just ask for help. - - -File: uucp.info, Node: Testing, Next: Installation, Prev: Compilation, Up: Overall Installation - -Testing Taylor UUCP -=================== - - This package is in use at many sites, and has been running at -`airs.com' for several months. However, it will doubtless fail in -some situations. Do not rely on this code until you have proven to -yourself that it will work. - - You can use the `uuchk' program to test your configuration files. -It will read them and print out a verbose description. This is -particularly important if you are using V2 or BNU configuration files, -because there may be bugs in how they are read. This program should -not be made suid, because it will display passwords if it can read -them. - - If your system supports BSD style pseudo-terminals, and you -compiled the code to support the new style of configuration files, you -should be able to use the `tstuu' program to test the `uucico' daemon. - Just type `tstuu' with no arguments while logged in to the compilation -directory (since it runs `./uucp', `./uux' and `./uucico') to run a -lengthy series of tests (it takes over ten minutes on a slow VAX). -You will need a fair amount of space available in `/usr/tmp'. You -will probably want to put it in the background. Do not use `^Z', -because the program traps on `SIGCHLD' and winds up dying. It will -create a directory `/usr/tmp/tstuu' and fill it with configuration -files, and create spool directories `/usr/tmp/tstuu/spool1' and -`/usr/tmp/tstuu/spool2'. - - The program will finish with an execute file `X.SOMETHING' and a -data file `D.SOMETHING' in `/usr/tmp/tstuu/spool1' (or, more likely, -in subdirectories, depending on the choice of `SPOOLDIR' in -`sysdep.h'). The log files `/usr/tmp/tstuu/Log1' and -`/usr/tmp/tstuu/Log2' (or, if you have selected `HAVE_BNU_LOGGING', -`/usr/tmp/tstuu/Log1/uucico/test2' and -`/usr/tmp/tstuu/Log2/uucico/test1') should look fairly normal. You -can test `uuxqt' by typing `./uuxqt -I /usr/tmp/tstuu/Config1'. This -should leave a command file `C.SOMETHING' and a data file -`D.SOMETHING' in `/usr/tmp/tstuu/spool1' or in subdirectories. Again, -there should be no errors in the log file. - - Assuming you compiled the code with debugging enabled, the `-x' -switch can be used to set debugging modes; see the `debug' command for -details (*note Debugging Levels::.). Use `-x all' to turn on all -debugging and generate far more output than you will ever want to see. - The `uucico' daemons will put debugging output in -`/usr/tmp/tstuu/Debug1' and `/usr/tmp/tstuu/Debug2'. At this point -you're pretty much on your own. - - On some systems you can also use `tstuu' to test my `uucico' -against the system `uucico', by using the `-u' switch. For this to -work, change the definitions of `ZUUCICO_CMD' and `UUCICO_EXECL' at -the top of `tstuu.c' to something appropriate for your system. The -definitions in `tstuu.c' are what I used for Ultrix 4.0, in which -`/usr/lib/uucp/uucico' is particularly obstinate about being run as a -child; I was only able to run it by creating a login name with no -password whose shell was `/usr/lib/uucp/uucico'. Calling login in -this way will leave fake entries in `wtmp' and `utmp'; if you compile -`tstout.c' (in the `contrib' directory) as an suid `root' program, -`tstuu' will run it to clear those entries out. On most systems, such -hackery should not be necessary, although on SCO I had to su to `root' -(`uucp' might also have worked) before I could run -`/usr/lib/uucp/uucico'. - - You can test `uucp' and `uux' (give them the `-r' switch to keep -them from starting `uucico') to make sure they create the right sorts -of files. Unfortunately if you don't know what the right sorts of -files are I'm not going to tell you here. - - If `tstuu' passes, or you can't run it for some reason or other, -move on to testing with some other system. Set up the configuration -files (*note Configuration files::.), or use an existing configuration. -Tell `uucico' to dial out to the system by using the `-s' system -switch (e.g. `uucico -s uunet'). The log file should tell you what -happens. - - If you compiled the code with debugging enabled, you can use -debugging mode to get a great deal of information about what sort of -data is flowing back and forth; the various possibilities are -described under the `debug' command (*note Debugging Levels::.). When -initially setting up a connection `-x chat' is probably the most -useful (e.g. `uucico -s uunet -x chat'); you may also want to use `-x -handshake,incoming,outgoing'. You can use `-x' multiple times on one -command line, or you can give it comma separated arguments as in the -last example. Use `-x all' to turn on all possible debugging -information. The debugging information is written to a file, normally -`/usr/spool/uucp/Debug' although the default can be changed in -`policy.h' and the configuration file can override the name with the -`debugfile' command. The debugging file may contain passwords and -some file contents as they are transmitted over the line, so the -debugging file is only readable by the `uucp' user. - - You can use the `-f' switch to force `uucico' to call out even if -the last call failed recently; using `-S' when naming a system has the -same effect. Otherwise the status file (in the `.Status' subdirectory -of the main spool directory, normally `/usr/spool/uucp') will prevent -too many attempts from occurring in rapid succession. - - Again, let me know about any problems you have and how you got -around them. - - -File: uucp.info, Node: Installation, Next: Usage, Prev: Testing, Up: Overall Installation - -Installing Taylor UUCP -====================== - - You can install by suing to `root' and typing `make install'. Or -you can look at what make install does and do it by hand. It tries to -preserve your old programs, if any. You can retrieve them by typing -`make uninstall'. - - -File: uucp.info, Node: Usage, Next: TCP, Prev: Installation, Up: Overall Installation - -Using Taylor UUCP -================= - - This package does not come with any fancy shell scripts or -scheduling programs. Maybe someday. If you have another package, you -may well be able to use the scheduling mechanisms it provides. - - Otherwise, the program can be used by making crontab entries. -Whenever you want to call all systems with outstanding work, use - - uucico -r1 - - Whenever you want to call a specific system `foo', use - - uucico -s foo - - If you want to make sure that a system foo gets retried if the -original call fails, create an empty work file for it. For example, -if using `SPOOLDIR_TAYLOR', - - touch /usr/spool/uucp/foo/C./C.A0000 - - If using `SPOOLDIR_BNU', use - - touch /usr/spool/uucp/foo/C.fooA0000 - - I use the following crontab entries locally: - - 45 * * * * /bin/echo /usr/lib/uucp/uucico -r1 | /bin/su uucpa - 40 4,10,15 * * * touch /usr/spool/uucp/uunet/C./C.A0000 - - Every hour, at 45 minutes past, this will check if there is any -work to be done. Also, at 4:40am, 10:40am and 3:40pm this will create -an empty work file for `uunet', forcing the next check to call `uunet'. - - You will also want to periodically trim the log files, which by -default are `/usr/spool/uucp/Log' and `/usr/spool/uucp/Stats'. The -`savelog' program in the `contrib' directory may be of use. - - -File: uucp.info, Node: TCP, Prev: Usage, Up: Overall Installation - -TCP together with Taylor UUCP -============================= - - If your system has a Berkeley style socket library, you can compile -the code to permit making connections over TCP. Specifying that a -system should be reached via TCP is easy, but nonobvious. - - If you are using the new style configuration files, see *Note -Configuration files::. Basically, you can just add the line `port -type tcp' to the entry in the system configuration file. By default -UUCP will get the port number by looking up `uucp' in `/etc/services'; -if `uucp' is not found, port 540 will be used. You can set the port -number to use with the command `port service XXX', where XXX can be -either a number or a name to look up in `/etc/services'. You can -specify the address of the remote host with `address A.B.C'; if you -don't give an address, the remote system name will be used. You -should give an explicit chat script for the system when you use TCP; -the default chat script begins with a carriage return, which will not -work with some UUCP TCP servers. - - If you are using V2 configuration files, add a line like this to -`L.sys': - - foo Any TCP uucp foo.domain chat-script - - This will make an entry for system foo, to be called at any time, -over TCP, using port number `uucp' (as found in `/etc/services'; this -may be specified as a number), using remote host `foo.domain', with -some chat script. - - If you are using BNU configuration files, add a line like this to -Systems: - - foo Any TCP - foo.domain chat-script - - and a line like this to Devices: - - TCP uucp - - - - You only need one line in Devices regardless of how many systems you -contact over TCP. This will make an entry for system foo, to be called -at any time, over TCP, using port number `uucp' (as found in -`/etc/services'; this may be specified as a number), using remote host -`foo.domain', with some chat script. - - The `uucico' daemon can also be run as a TCP server. This code -mostly works, but it's not perfect. I don't recommend investigating it -unless you are willing to tinker a bit. You will not be able to use -the default port number because `uucico' will not be running as `root' -and will therefore not be able to bind a reserved port. - - Basically, you must define a port, either using the port file -(*note port file::.) if you are using the new configuration method or -with an entry in Devices if you are using BNU; there is no way to -define a port using V2. If you are using BNU the port must be named -`TCP'; a line as shown above will suffice. You can then start -`uucico' as `uucico -p TCP' (after the `-p', name the port; in BNU it -must be `TCP'). This will wait for incoming connections, and fork off -a child for each one. Each connection will be prompted with `login:' -and `Password:'; the results will be checked against the UUCP (not the -system) password file (*note Configuration File Names::.). Of course, -you can get a similar effect by using the BSD `uucpd' program. - - You can also have `inetd' start up `uucico' with the `-l' switch, -which will cause it to prompt with `login:' and `Password:' and check -the results against the UUCP (not the system) password file. This may -be used in place of `uucpd'. - - -File: uucp.info, Node: Configuration Files, Next: Protocols, Prev: Overall Installation, Up: Top - -Taylor UUCP Configuration Files -******************************* - - This chapter describes the configuration files accepted by the -Taylor UUCP package if compiled with `HAVE_TAYLOR_CONFIG' defined in -`conf.h'. - - The configuration files are normally found in the directory -NEWCONFIGDIR, which is defined by the `Makefile' variable -`newconfigdir'; by default NEWCONFIGDIR is `/usr/local/lib/uucp'. -However, the main configuration file, `config', is the only one which -must be in that directory, since it may specify a different location -for any or all of the other files. You may run any of the UUCP -programs with a different main configuration file by using the `-I' -option; this can be useful when testing a new configuration. When you -use the `-I' option the programs will revoke their setuid privileges. - -* Menu: - -* Configuration File Format:: Configuration file format -* Configuration Examples:: Examples of configuration files -* Time Strings:: How to write time strings -* Chat Scripts:: How to write chat scripts -* config File:: The main configuration file -* sys File:: The system configuration file -* port File:: The port configuration files -* dial File:: The dialer configuration files -* Security:: Security issues - - -File: uucp.info, Node: Configuration File Format, Next: Configuration Examples, Prev: Configuration Files, Up: Configuration Files - -Configuration File Format -========================= - - All the configuration files follow a simple line-oriented `KEYWORD -VALUE' format. Empty lines are ignored, as are leading spaces; unlike -BNU, lines with leading spaces are read. The first word on each line -is a keyword. The rest of the line is interpreted according to the -keyword. Most keywords are followed by numbers, boolean values or -simple strings with no embedded spaces. - - The `#' character is used for comments. Everything from a `#' to -the end of the line is ignored unless the `#' is preceded by a `\' -(backslash); if the `#' is preceeded by a `\', the `\' is removed but -the `#' remains in the line. This can be useful for a phone number -containing a `#'. To enter the sequence `\#', you would use `\\#'. - - The backslash character may be used to continue lines. If the last -character in a line is a backslash, the backslash is removed and the -line is continued by the next line. The second line is attached to the -first with no intervening characters; if you want any whitespace -between the end of the first line and the start of the second line, -you must insert it yourself. - - However, the backslash is not a general quoting character. For -example, you cannot use it to get an embedded space in a string -argument. - - Everything after the keyword must be on the same line. A BOOLEAN -may be specified as `y', `Y', `t', or `T' for true and `n', `N', `f', -or `F' for false; any trailing characters are ignored, so `true', -`false', etc., are also acceptable. - - -File: uucp.info, Node: Configuration Examples, Next: Time Strings, Prev: Configuration File Format, Up: Configuration Files - -Examples of Configuration Files -=============================== - - All the configuration commands are explained in the following -sections. However, I'll start by giving a few examples of -configuration files. For a more complete description of any of the -commands used here see the appropriate section of this chapter. - -* Menu: - -* config File Examples:: Examples of the main configuration file -* Leaf Example:: Call a single remote site -* Gateway Example:: The gateway for several local systems - - -File: uucp.info, Node: config File Examples, Next: Leaf Example, Prev: Configuration Examples, Up: Configuration Examples - -config File Examples --------------------- - - To start with, here are some examples of uses of the main -configuration file, `config'. For a complete description of the -commands that are permitted in `config', see *Note config file::. - - In many cases you will not need to create a `config' file at all. -The most common reason to create one is to give your machine a special -UUCP name. Other reasons might be to change the UUCP spool directory -or to permit any remote system to call in. - - If you have an internal network of machines, then it is likely that -the internal name of your UUCP machine is not the name you want to use -when calling other systems. For example, here at `airs.com' our -mail/news gateway machine is named `elmer.airs.com' (it is one of -several machines all named `LOCALNAME.airs.com'). If we did not -provide a `config' file, then our UUCP name would be `elmer'; however, -we actually want it to be `airs'. Therefore, we use the following -line in `config': - - nodename airs - - The UUCP spool directory name is set in `policy.h' when the code is -compiled. You might at some point decide that it is appropriate to -move the spool directory, perhaps to put it on a different disk -partition. You might use the following commands in `config' to change -to directories on the partition `/uucp': - - spool /uucp/spool - pubdir /uucp/uucppublic - logfile /uucp/spool/Log - debugfile /uucp/spool/Debug - - You would then move the contents of the current spool directory to -`/uucp/spool'. If you do this, make sure that no UUCP processes are -running while you change `config' and move the spool directory. - - Suppose you wanted to permit any system to call in to your system -and request files. This is generally known as "anonymous UUCP", since -the systems which call in are effectively anonymous. By default, -unknown systems are not permitted to call in. To permit this you must -use the `unknown' command in `config'. The `unknown' command is -followed by any command that may appear in the system file; for full -details, see *Note sys file::. - - I will show two possible anonymous UUCP configurations. The first -will let any system call in and download files, but will not permit -them to upload files to your system. - - # No files may be transferred to this system - unknown request no - # The public directory is /usr/spool/anonymous - unknown pubdir /usr/spool/anonymous - # Only files in the public directory may be sent (the default anyhow) - unknown remote-send ~ - -Setting the public directory is convenient for the systems which call -in. It permits to request a file by prefixing it with `~/'. For -example, assuming your system is known as `server', then to retrieve -the file `/usr/spool/anonymous/INDEX' a user on a remote site could -just enter `uucp server!~/INDEX ~'; this would transfer `INDEX' from -`server''s public directory to the user's local public directory. -Note that when using `csh' or `bash' the `!' and the second `~' must -be quoted. - - The next example will permit remote systems to upload files to a -special directory `/usr/spool/anonymous/upload'. Permitting a remote -system to upload files permits it to send work requests as well; this -example is careful to prohibit commands from unknown systems. - - # No commands may be executed (the list of permitted commands is empty) - unknown commands - # The public directory is /usr/spool/anonymous - unknown pubdir /usr/spool/anonymous - # Only files in the public directory may be sent; users may not download - # files from the upload directory - unknown remote-send ~ !~/upload - # May only upload files into /usr/spool/anonymous/upload - unknown remote-receive ~/upload - - -File: uucp.info, Node: Leaf Example, Next: Gateway Example, Prev: config File Examples, Up: Configuration Examples - -Leaf Example ------------- - - A relatively common simple case is a "leaf site", a system which -only calls or is called by a single remote site. Here is a typical -`sys' file that might be used in such a case. For full details on -what commands can appear in the `sys' file, see *Note sys file::. - - This is the `sys' file that is used at `airs.com'. We use a single -modem to dial out to `uunet'. This example shows how you can specify -the port and dialer information directly in the `sys' file for simple -cases. It also shows the use of the following: - -`call-login' - Using `call-login' and `call-password' allows the default login - chat script to be used. In this case, the login name is specified - in the call-out login file (*note Configuration File Names::.). - -`call-timegrade' - `uunet' is requested to not send us news during the daytime. - -`chat-fail' - If the modem returns `BUSY' or `NO CARRIER' the call is - immediately aborted. - -`protocol-parameter' - Since `uunet' tends to be slow, the default timeout has been - increased. - - This `sys' file relies on certain defaults. It will allow `uunet' -to queue up `rmail' and `rnews' commands. It will allow users to -request files from `uunet' into the UUCP public directory. It will -also `uunet' to request files from the UUCP public directory; in fact -`uunet' never requests files, but for additional security we could add -the line `request false'. - - # The following information is for uunet - system uunet - - # The login name and password are kept in the callout password file - call-login * - call-password * - - # We can send anything at any time. - time any - - # During the day we only accept grade 'Z' or above; at other times - # (not mentioned here) we accept all grades. uunet queues up news - # at grade 'd', which is lower than 'Z'. - call-timegrade Z Wk0755-2305,Su1655-2305 - - # The phone number. - phone 7389449 - - # uunet tends to be slow, so we increase the timeout - chat-timeout 120 - - # We are using a preconfigured Telebit 2500. - port type modem - port device /dev/ttyd0 - port baud 19200 - port carrier true - port dialer chat "" ATZ\r\d\c OK ATDT\D CONNECT - port dialer chat-fail BUSY - port dialer chat-fail NO\sCARRIER - port dialer complete \d\d+++\d\dATH\r\c - port dialer abort \d\d+++\d\dATH\r\c - - # Increase the timeout and the number of retries. - protocol-parameter g timeout 20 - protocol-parameter g retries 10 - - -File: uucp.info, Node: Gateway Example, Prev: Leaf Example, Up: Configuration Examples - -Gateway Example ---------------- - - Many organizations have several local machines which are connected -by UUCP, and a single machine which connects to the outside world. -This single machine is often referred to as a "gateway" machine. - - For this example I will assume a fairly simple case. It should -still provide a good general example. There are three machines, -`elmer', `comton' and `bugs'. `elmer' is the gateway machine for -which I will show the configuration file. `elmer' calls out to -`uupsi'. As an additional complication, `uupsi' knows `elmer' as -`airs'; this will show how a machine can have one name on an internal -network but a different name to the external world. `elmer' has two -modems. It also has an TCP/IP connection to `uupsi', but since that -is supposed to be reserved for interactive work (it is, perhaps, only -a 9600 baud SLIP line) it will only use it if the modems are not -available. - - A network this small would normally use a single `sys' file. -However, for pedagogical purposes I will show two separate `sys' -files, one for the local systems and one for `uupsi'. This is done -with the `sysfile' command in the `config' file. Here is the `config' -file. - - # This is config - # The local sys file - sysfile /usr/local/lib/uucp/sys.local - # The remote sys file - sysfile /usr/local/lib/uucp/sys.remote - - Using the defaults feature of the `sys' file can greatly simplify -the listing of local systems. Here is `sys.local'. Note that this -assumes that the local systems are trusted; they are permited to -request any world readable file and to write files into any world -writable directory. - - # This is sys.local - # Get the login name and password to use from the call-out file - call-login * - call-password * - - # The systems must use a particular login - called-login Ulocal - - # Permit sending any world readable file - local-send / - remote-send / - - # Permit requesting into any world writable directory - local-receive / - remote-receive / - - # Call at any time - time any - - # Use port1, then port2 - port port1 - - alternate - - port port2 - - # Now define the systems themselves. Because of all the defaults we - # used, there is very little to specify for the systems themselves. - - system comton - phone 5551212 - - system bugs - phone 5552424 - - The `sys.remote' file describes the `uupsi' connection. The -`myname' command is used to change the UUCP name to `airs' when -talking to `uupsi'. - - # This is sys.remote - # Define uupsi - system uupsi - - # The login name and password are in the call-out file - call-login * - call-password * - - # We can call out at any time - time any - - # uupsi uses a special login name - called-login Uuupsi - - # uuspi thinks of us as `airs' - myname airs - - # The phone number - phone 5554848 - - # We use port2 first, then port1, then TCP - - port port2 - - alternate - - port port1 - - alternate - - # We don't bother to make a special entry in the port file for TCP, we - # just describe the entire port right here. We use a special chat - # script over TCP because the usual one confuses some TCP servers. - port type TCP - address uu.psi.com - chat ogin: \L word: \P - - The ports are defined in the file `port' (*note port file::.). For -this example they are both connected to the same type of 2400 baud -Hayes-compatible modem. - - # This is port - - port port1 - type modem - device /dev/ttyd0 - dialer hayes - speed 2400 - - port port2 - type modem - device /dev/ttyd1 - dialer hayes - speed 2400 - - Dialers are described in the `dial' file (*note dial file::.). - - # This is dial - - dialer hayes - - # The chat script used to dial the phone. \D is the phone number. - chat "" ATZ\r\d\c OK ATDT\D CONNECT - - # If we get BUSY or NO CARRIER we abort the dial immediately - chat-fail BUSY - chat-fail NO\sCARRIER - - # When the call is over we make sure we hangup the modem. - complete \d\d+++\d\dATH\r\c - abort \d\d+++\d\dATH\r\c - - -File: uucp.info, Node: Time Strings, Next: Chat Scripts, Prev: Configuration Examples, Up: Configuration Files - -Time Strings -============ - - Several commands use time strings to specify a range of times. This -section describes how to write time strings. - - A time string may be a list of simple time strings separated with a -vertical bar `|' or a command `,'. - - Each simple time string must begin with `Su', `Mo', `Tu', `We', -`Th', `Fr', or `Sa', or `Wk' for any weekday, or `Any' for any day. - - Following the day may be a range of hours separated with a hyphen -using 24 hour time. The range of hours may cross 0; for example -`2300-0700' means any time except 7 AM to 11 PM. If no time is given, -calls may be made at any time on the specified day(s). - - The time string may also consist of the single word `Never', which -does not match any time, or a single word with a name defined in a -previous `timetable' command (*note Miscellaneous (sys)::.). - - Here are a few sample time strings with an explanation of what they -mean. - -`Wk2305-0855,Sa,Su2305-1655' - This means weekdays before 8:55 AM or after 11:05 PM, any time - Saturday, or Sunday before 4:55 PM or after 11:05 PM. These are - approximately the times during which night rates apply to phone - calls in the U.S.A. Note that this time string uses, for - example, `2305' rather than `2300'; this will ensure a cheap rate - phone call even if the computer clock is running up to five - minutes ahead of the real time. - -`Wk0905-2255,Su1705-2255' - This means weekdays from 9:05 AM to 10:55 PM, or Sunday from 5:05 - PM to 10:55 PM. This is approximately the opposite of the - previous example. - -`Any' - Since no time is specified, this means any time on any day. - -
\ No newline at end of file diff --git a/gnu/libexec/uucp/uucp.info-2 b/gnu/libexec/uucp/uucp.info-2 deleted file mode 100644 index ec224c203d3..00000000000 --- a/gnu/libexec/uucp/uucp.info-2 +++ /dev/null @@ -1,1142 +0,0 @@ -Info file uucp.info, produced by Makeinfo, -*- Text -*- from input -file uucp.texi. - - This file documents Taylor UUCP, version 1.03. - - Copyright (C) 1992 Free Software Foundation, Inc. - - Permission is granted to make and distribute verbatim copies of this -manual provided the copyright notice and this permission notice are -preserved on all copies. - - Permission is granted to copy and distribute modified versions of -this manual under the conditions for verbatim copying, provided also -that the section entitled "Copying" are included exactly as in the -original, and provided that the entire resulting derived work is -distributed under the terms of a permission notice identical to this -one. - - Permission is granted to copy and distribute translations of this -manual into another language, under the above conditions for modified -versions, except that the section entitled "Copying" may be included -in a translation approved by the author instead of in the original -English. - - -File: uucp.info, Node: Chat Scripts, Next: config File, Prev: Time Strings, Up: Configuration Files - -Chat Scripts -============ - - Chat scripts are used in several different places, such as dialing -out on modems or logging in to remote systems. Chat scripts are made -up of pairs of strings. The program waits until it sees the first -string, known as the "expect" string, and then sends out the second -string, the "send" string. - - Each chat script is defined using a set of commands. These commands -always end in a string beginning with `chat', but may start with -different strings. For example, in the `sys' file there is one set of -commands beginning with `chat' and another set beginning with -`called-chat'. The prefixes are only used to disambiguate different -types of chat scripts, and this section ignores the prefixes when -describing the commands. - -`chat STRINGS' - Specify a chat script. The arguments to the `chat' command are - pairs of strings separated by whitespace. The first string of - each pair is an expect string, the second is a send string. The - program will wait for the expect string to appear; when it does, - the program will send the send string. If the expect string does - not appear within a certain number of seconds (as set by the - `chat-timeout' command) the chat script fails and, typically, the - call is aborted. If the final expect string is seen (and the - optional final send string has been sent), the chat script is - successful. - - An expect string may contain additional subsend and subexpect - strings, separated by hyphens. If the expect string is not seen, - the subsend string is sent and the chat script continues by - waiting for the subexpect string. This means that a hyphen may - not appear in an expect string; use `\055' instead. - - An expect string may simply be `""', meaning to skip the expect - phase. Otherwise, the following escape characters may appear in - expect strings: - - `\b' - a backspace character - - `\n' - a newline or line feed character - - `\N' - a null character (for BNU compatibility) - - `\r' - a carriage return character - - `\s' - a space character - - `\t' - a tab character - - `\\' - a backslash character - - `\DDD' - character DDD, where DDD are up to three octal digits - - `\xDDD' - character DDD, where DDD are hexadecimal digits. - - As in C, there may be up to three octal digits following a - backslash, but the hexadecimal escape sequence continues as far - as possible. To follow a hexadecimal escape sequence with a hex - digit, interpose a send string of `""'. - - A send string may also simply be `""' to skip the send phase. - Otherwise, all of the escape characters legal for expect strings - may be used, and the following escape characters are also - permitted: - - `EOT' - send an end of transmission character (`^D') - - `BREAK' - send a break character (may not work on all systems) - - `\c' - suppress trailing carriage return at end of send string - - `\d' - delay sending for 1 second - - `\e' - disable echo checking - - `\E' - enable echo checking (wait for echo before continuing) - - `\K' - same as `BREAK' (for BNU compatibility) - - `\p' - pause sending for a fraction of a second - - Some specific types of chat scripts also define additional escape - sequences that may appear in the send string. For example, the - login chat script defines `\L' and `\P' to send the login name and - password, respectively. - - A carriage return will be sent at the end of each send string, - unless the `\c' escape sequence appears in the string. Note that - some UUCP packages use `\b' for break, but here it means - backspace. - - Echo checking means that after writing each character the program - will wait until the character is echoed. Echo checking must be - turned on separately for each send string for which it is - desired; it will be turned on for characters following `\E' and - turned off for characters following `\e'. - -`chat-timeout NUMBER' - The number of seconds to wait for an expect string in the chat - script before timing out and sending the next subsend or failing - the chat script entirely. The default value is 10 for a login - chat or 60 for any other type of chat. - -`chat-fail STRING' - If the STRING is seen at any time during a chat script, the chat - script is aborted. The string may not contain any whitespace - characters; escape sequences must be used for them. Multiple - `chat-fail' commands may appear in a single chat script. The - default is to have none. - - This permits a chat script to be quickly aborted if an error - string is seen. For example, a script used to dial out on a - modem might use the command `chat-fail BUSY' to stop the chat - script immediately if the string `BUSY' was seen. - -`chat-seven-bit BOOLEAN' - If the argument is true, all incoming characters are stripped to - seven bits when being compared to the expect string. Otherwise - all eight bits are used in the comparison. The default is true - because some Unix systems generate parity bits during the login - prompt which must be ignored while running a chat script. This - has no effect on any `chat-program', which must ignore parity by - itself if necessary. - -`chat-program STRINGS' - Specify a program to run before executing the chat script. This - program could run its own version of a chat script, or it could - do whatever it wants. If both `chat-program' and `chat' are - specified, the program is executed first followed by the chat - script. - - The first argument to the `chat-program' command is the program - name to run. The remaining arguments are passed to the program. - The following escape sequences are recognized in the arguments: - - `\Y' - port device name - - `\S' - port speed - - `\\' - backslash - - Some specific uses of `chat-program' define additional escape - sequences. - - Arguments other than escape sequences are passed exactly as they - appear in the configuration file, except that sequences of - whitespace are compressed to a single space character; this - exception may be removed in the future. - - If the `chat-program' command is not used, no program is run. - - On Unix, the standard input and standard output of the program - will be attached to the port in use. Anything the program writes - to standard error will be written to the UUCP log file. No other - file descriptors will be open. If the program does not exit with - a status of 0, it will be assumed to have failed; this means that - the dialing programs used by some versions of BNU may not be used - directly, although of course a shell script could be used as an - interface. - - The program will be run as the `uucp' user, and the environment - will be that of the process that started `uucico', so care must be - taken to maintain security. - - No search path is used to find the program; a full path name must - be given. If the program is an executable shell script, it will - be passed to `/bin/sh' even on systems which are unable to - execute shell scripts. It is also easy to invoke `/bin/sh' - directly. - - Here is a simple example of a chat script that might be used to -reset a Hayes compatible modem. - - chat "" ATZ OK-ATZ-OK - - The first expect string is `""', so it is ignored. The chat script -then sends `ATZ'. If the modem responds with `OK', the chat script -finishes. If 60 seconds (the default timeout) pass before seeing -`OK', the chat script sends another `ATZ'. If it then sees `OK', the -chat script succeeds. Otherwise, the chat script fails. - - For a more complex chat script example, see *Note Logging In::. - - -File: uucp.info, Node: config File, Next: sys File, Prev: Chat Scripts, Up: Configuration Files - -The Main Configuration File -=========================== - - The main configuration file is named `config'. - - Since all the values that may be specified in the main configuration -file also have defaults, there need not be a main configuration file at -all. - -* Menu: - -* Miscellaneous (config):: Miscellaneous config file commands -* Configuration File Names:: Using different configuration files -* Log File Names:: Using different log files -* Debugging Levels:: Debugging levels - - -File: uucp.info, Node: Miscellaneous (config), Next: Configuration File Names, Prev: config File, Up: config File - -Miscellaneous config File Commands ----------------------------------- - -`nodename STRING' -`hostname STRING' -`uuname STRING' - These keywords are equivalent. They specify the UUCP name of the - local host. If there is no configuration file, an appropriate - function will be used to get the host name, if possible. - -`spool STRING' - Specify the spool directory. The default is from `policy.h'. - Command files, work files, temporary files, etc., are stored in - this directory and in subdirectories of it. - -`pubdir STRING' - Specify the public directory. The default is from `policy.h'. On - Unix, when a file is named using a leading `~/', it is taken from - or to the public directory. Each system may use a separate public - directory by using the `pubdir' command in the system - configuration file; see *Note Miscellaneous (sys)::. - -`unknown STRING ...' - The STRING and subsequent arguments are treated as though they - appeared in the system file (*note sys file::.). They are used - to apply to any unknown systems that may call in, probably to set - file transfer permissions and the like. If the `unknown' command - is not used, unknown systems are not permitted to call in. - -`max-uuxqts NUMBER' - Specify the maximum number of `uuxqt' processes which may run at - the same time. Having several `uuxqt' processes running at once - can significantly slow down a system, but since `uuxqt' is - automatically started by `uucico', it can happen quite easily. - The default for `max-uuxqts' is 0, which means that there is no - limit. If BNU configuration files are being read and the code - was compiled without `HAVE_TAYLOR_CONFIG', then if the file - `Maxuuxqts' in the configuration directory contains a readable - number it will be used as the value for `max-uuxqts'. - -`v2-files BOOLEAN' - If the code was compiled to be able to read V2 configuration - files, a false argument to this command will prevent them from - being read. This can be useful while testing. The default is - true. - -`bnu-files BOOLEAN' - If the code was compiled to be able to read BNU configuration - files, a false argument to this command will prevent them from - being read. This can be useful while testing. The default is - true. - - -File: uucp.info, Node: Configuration File Names, Next: Log File Names, Prev: Miscellaneous (config), Up: config File - -Configuration File Names ------------------------- - -`sysfile STRINGS' - Specify the system file(s). The default is the file `sys' in the - directory NEWCONFIGDIR. These files hold information about other - systems with which this system communicates; see *Note sys file::. - Multiple system files may be given on the line, and the `sysfile' - command may be repeated; each system file has its own set of - defaults. - -`portfile STRINGS' - Specify the port file(s). The default is the file `port' in the - directory NEWCONFIGDIR. These files describe ports which are used - to call other systems and accept calls from other systems; see - *Note port file::. No port files need be named at all. Multiple - port files may be given on the line, and the `portfile' command - may be repeated. - -`dialfile STRINGS' - Specify the dial file(s). The default is the file `dial' in the - directory NEWCONFIGDIR. These files describe dialing devices - (modems); *Note dial file::. No dial files need be named at all. - Multiple dial files may be given on the line, and the `dialfile' - command may be repeated. - -`dialcodefile STRINGS' - Specify the dialcode file(s). The default is the file `dialcode' - in the directory NEWCONFIGDIR. These files specify dialcodes that - may be used when sending phone numbers to a modem. This permits - using the same set of phone numbers in different area-codes or - with different phone systems, by using dialcodes to specify the - calling sequence. When a phone number goes through dialcode - translation, the leading alphabetic characters are stripped off. - The dialcode files are read line by line, just like any other - configuration file, and when a line is found whose first word is - the same as the leading characters from the phone number, the - second word on the line (which would normally consist of numbers) - replaces the dialcode in the phone number. No dialcode file need - be used. Multiple dialcode files may be specified on the line, - and the `dialcodefile' command may be repeated; all the dialcode - files will be read in turn until a dialcode is located. - -`callfile STRINGS' - Specify the call out login name and password file(s). The - default is the file `call' in the directory NEWCONFIGDIR. If the - call out login name or password for a system are given as `*' - (*note Logging In::.), these files are read to get the real login - name or password. Each line in the file(s) has three words: the - system name, the login name, and the password. This file is only - used when placing calls to remote systems; the password file - described under `passwdfile' below is used for incoming calls. - The intention of the call out file is to permit the system file - to be publically readable; the call out files must obviously be - kept secure. These files need not be used. Multiple call out - files may be specified on the line, and the `callfile' command - may be repeated; all the files will be read in turn until the - system is found. - -`passwdfile STRINGS' - Specify the password file(s) to use for login names when `uucico' - is doing its own login prompting, which it does when given the - `-e', `-l' or `-w' switch. The default is the file `passwd' in - the directory NEWCONFIGDIR. Each line in the file(s) has two - words: the login name and the password (e.g. `Ufoo foopas'). The - login name is accepted before the system name is known, so these - are independent of which system is calling in; a particular login - may be required for a system by using the `called-login' command - in the system file (*note Accepting a Call::.). These password - files are optional, although one must exist if `uucico' is to - present its own login prompts. Multiple password files may be - specified on the line, and the `passwdfile' command may be - repeated; all the files will be read in turn until the login name - is found. - - -File: uucp.info, Node: Log File Names, Next: Debugging Levels, Prev: Configuration File Names, Up: config File - -Log File Names --------------- - -`logfile STRING' - Name the log file. The default is from `policy.h'. Logging - information is written to this file. If `HAVE_BNU_LOGGING' is - defined in `conf.h', then by default a separate log file is used - for each system. Using this command to name a log file will - cause all the systems to use it. - -`statfile STRING' - Name the statistics file. The default is from `policy.h'. - Statistical information about file transfers is written to this - file. - -`debugfile STRING' - Name the file to which debugging information is written. The - default is from `policy.h'. This command is only effective if - the code has been compiled to include debugging (this is - controlled by the `DEBUG' variable in `policy.h'). After the - first debugging message has been written, messages written to the - log file are also written to the debugging file to make it easier - to keep the order of actions straight. The debugging file is - different from the log file because information such as passwords - can appear in it, so it must be not be publically readable. - - -File: uucp.info, Node: Debugging Levels, Prev: Log File Names, Up: config File - -Debugging Levels ----------------- - -`debug STRING ...' - Set the debugging level. This command is only effective if the - code has been compiled to include debugging. The default is to - have no debugging. The arguments are strings which name the - types of debugging to be turned on. The following types of - debugging are defined: - - `abnormal' - Output debugging messages for abnormal situations, such as - recoverable errors. - - `chat' - Output debugging messages for chat scripts. - - `handshake' - Output debugging messages for the initial handshake. - - `uucp-proto' - Output debugging messages for the UUCP protocol itself. - - `proto' - Output debugging messages for the individual protocols. - - `port' - Output debugging messages for actions on the communication - port. - - `config' - Output debugging messages while reading the configuration - files. - - `spooldir' - Output debugging messages for actions in the spool directory. - - `execute' - Output debugging messages whenever another program is - executed. - - `incoming' - List all incoming data in the debugging file. - - `outgoing' - List all outgoing data in the debugging file. - - `all' - All of the above. - - The debugging level may also be specified as a number. A 1 will - set `chat' debugging, a 2 will set both `chat' and `handshake' - debugging, and so on down the possibilities. Currently an 11 - will turn on all possible debugging, since there are 11 types of - debugging messages listed above; more debugging types may be - added in the future. The `debug' command may be used several - times in the configuration file; every debugging type named will - be turned on. When running any of the programs, the `-x' switch - (actually, for `uulog' it's the `-X' switch) may be used to turn - on debugging. The argument to the `-x' switch is one of the - strings listed above, or a number as described above, or a comma - separated list of strings (e.g. `-x chat,handshake'). The `-x' - switch may also appear several times on the command line, in - which case all named debugging types will be turned on. The `-x' - debugging is in addition to any debugging specified by the - `debug' command; there is no way to cancel debugging information. - The debugging level may also be set specifically for calls to or - from a specific system with the `debug' command in the system - file (*note Miscellaneous (sys)::.). - - The debugging messages are somewhat idiosyncratic; it may be - necessary to refer to the source code for additional information - in some cases. - - -File: uucp.info, Node: sys File, Next: port File, Prev: config File, Up: Configuration Files - -The System Configuration File -============================= - - By default there is a single system configuration, named `sys' in -the directory NEWCONFIGDIR. This may be overridden by the `sysfile' -command in the main configuration file; see *Note Configuration File -Names::. - - These files describe all remote systems known to the UUCP package. - -* Menu: - -* Defaults and Alternates:: Using defaults and alternates -* Naming the System:: Naming the system -* Calling Out:: Calling out -* Accepting a Call:: Accepting a call -* Protocol Selection:: Protocol selection -* File Transfer Control:: File transfer control -* Miscellaneous (sys):: Miscellaneous sys file commands -* Default sys File Values:: Default values - - -File: uucp.info, Node: Defaults and Alternates, Next: Naming the System, Prev: sys File, Up: sys File - -Defaults and Alternates ------------------------ - - The first set of commands in the file, up to the first `system' -command, specify defaults to be used for all systems in that file. -Each system file uses a different set of defaults. - - Subsequently, each set of commands from `system' up to the next -`system' command describe a particular system. Default values may be -overridden for specific systems. - - Each system may then have a series of alternate choices to use when -calling out or calling in. The first set of commands for a particular -system, up to the first `alternate' command, provide the first choice. - Subsequently, each set of commands from `alternate' up to the next -`alternate' command describe an alternate choice for calling out or -calling in. - - When a system is called, the commands before the first `alternate' -are used to select a phone number, port, and so forth; if the call -fails for some reason, the commands between the first `alternate' and -the second are used, and so forth. Well, not quite. Actually, each -succeeding alternate will only be used if it is different in some -relevant way (different phone number, different chat script, etc.). If -you want to force the same alternate to be used again (to retry a phone -call more than once, for example), enter the phone number (or any other -relevant field) again to make it appear different. - - The alternates can also be used to give different permissions to an -incoming call based on the login name. This will only be done if the -first set of commands, before the first `alternate' command, uses the -`called-login' command. The list of alternates will be searched, and -the first alternate with a matching `called-login' command will be -used. If no alternates match, the call will be rejected. - - The `alternate' command may also be used in the file-wide defaults -(the set of commands before the first `system' command). This might -be used to specify a list of ports which are available for all systems -(for an example of this, see *Note Gateway Example::) or to specify -permissions based on the login name used by the remote system when it -calls in. The first alternate for each system will default to the -first alternate for the file-wide defaults (as modified by the -commands used before the first `alternate' command for this system), -the second alternate for each system to the second alternate for the -file-wide defaults (as modified the same way), and so forth. If a -system specifies more alternates than the file-wide defaults, the -trailing ones will default to the last file-wide default alternate. If -a system specifies fewer alternates than the file-wide defaults, the -trailing file-wide default alternates will be used unmodified. The -`default-alternates' command may be used to modify this behaviour. - - This can all get rather confusing, although it's easier to use than -to describe concisely; the `uuchk' program may be used to ensure that -you are getting what you want. - - -File: uucp.info, Node: Naming the System, Next: Calling Out, Prev: Defaults and Alternates, Up: sys File - -Naming the System ------------------ - -`system STRING' - Specify the remote system name. Subsequent commands up to the - next `system' command refer to this system. - -`alternate [STRING]' - Start an alternate set of commands (*note Defaults and - Alternates::.). An optional argument may be used to name the - alternate. This name will be put in the log file if the - alternate is used to call the system. There is no way to name - the first alternate (the commands before the first `alternate' - command). - -`default-alternates BOOLEAN' - If the argument is false, any remaining default alternates (from - the defaults specified at the top of the current system file) - will not be used. The default is true. - -`alias STRING' - Specify an alias for the current system. The alias may be used - by local `uucp' and `uux' commands. The default is to have no - aliases. - -`myname STRING' - Specifies a different system name to use when calling the remote - system. Also, if `called-login' is used and is not `ANY', then, - when a system logs in with that login name, STRING is used as the - system name. Because the local system name must be determined - before the remote system has identified itself, using `myname' and - `called-login' together for any system will set the local name for - that login; this means that each locally used system name must - have a unique login name associated with it. This allows a - system to have different names for an external and an internal - network. The default is to not use a special local name. - - -File: uucp.info, Node: Calling Out, Next: Accepting a Call, Prev: Naming the System, Up: sys File - -Calling Out ------------ - - This section describes commands used when placing a call to another -system. - -* Menu: - -* When to Call:: When to call -* Placing the Call:: Placing the call -* Logging In:: Logging in - - -File: uucp.info, Node: When to Call, Next: Placing the Call, Prev: Calling Out, Up: Calling Out - -When to Call -............ - -`time STRING [NUMBER]' - Specify when the system may be called. The first argument is a - time string; see *Note Time Strings::. The optional second - argument specifies a retry time in minutes. If a call made - during a time that matches the time string fails, no more calls - are permitted until the retry time has passed. By default an - exponentially increasing retry time is used: after each failure - the next retry period is longer. A retry time specified in the - `time' command is always a fixed amount of time. - - The `time' command may appear multiple times in a single - alternate, in which case if any time string matches the system - may be called. The default time string is `Never'. - -`timegrade CHARACTER STRING [NUMBER]' - The CHARACTER specifies a grade. It must be a single letter or - digit. The STRING is a time string (*note Time Strings::.). All - jobs of grade CHARACTER or higher (where `0' > `9' > `A' > `Z' > - `a' > `z') may be run at the specified time. An ordinary `time' - command is equivalent to using `timegrade' with a grade of `z', - permitting all jobs. If there are no jobs of a sufficiently high - grade according to the time string, the system will not be - called. Giving the `-s' switch to `uucico' to force it to call a - system causes it to assume there is a job of grade `0' waiting to - be run. - - The optional third argument specifies a retry time in minutes. - See the `time' command, above, for more details. - - Note that the `timegrade' command serves two purposes: 1) if there - is no job of sufficiently high grade the system will not be - called, and 2) if the system is called anyway (because the `-s' - switch was given to `uucico') only jobs of sufficiently high - grade will be transferred. However, if the other system calls - in, the `timegrade' commands are ignored, and jobs of any grade - may be transferred (but see `call-timegrade' below). Also, the - `timegrade' command will not prevent the other system from - transferring any job it chooses, regardless of who placed the - call. - - The `timegrade' command may appear multiple times without using - `alternate'. If this command does not appear, there are no - restrictions on what grade of work may be done at what time. - -`call-timegrade CHARACTER STRING' - The CHARACTER is a single character `A' to `Z', `a' to `z', or - `0' to `9' and specifies a grade. The STRING is a time string as - described under the `time' command. If a call is placed to the - other system during a time which matches the time string, the - remote system will be requested to only run jobs of grade - CHARACTER or higher. Unfortunately, there is no way to guarantee - that the other system will obey the request (this UUCP package - will, but there are others which will not); moreover job grades - are historically somewhat arbitrary, so specifying a grade will - only be meaningful if the other system cooperates in assigning - grades. This grade restriction only applies when the other - system is called, not when the other system calls in. - - The `call-timegrade' command may appear multiple times without - using `alternate'. If this command does not appear, or if none of - the time strings match, the remote system will be allowed to send - whatever grades of work it chooses. - - -File: uucp.info, Node: Placing the Call, Next: Logging In, Prev: When to Call, Up: Calling Out - -Placing the Call -................ - -`baud NUMBER' -`speed NUMBER' - Specify the speed (the term "baud" is technically incorrect, but - widely understood) at which to call the system. This will try all - available ports with that baud rate until an unlocked port is - found. The ports are defined in the port file. If both `baud' - and `port' commands appear, both are used when selecting a port. - To allow calls at more than one baud rate, the `alternate' command - must be used (*note Defaults and Alternates::.). If this command - does not appear, there is no default; the baud rate may be - specified in the port file, but if it is not then the natural - baud rate of the port will be used (whatever that means on the - system). Specifying an explicit baud rate of 0 will request the - natural baud rate of the port, overriding any default baud rate - from the defaults at the top of the file. - -`port STRING' - Name a particular port or type of port to use when calling the - system. The information for this port is obtained from the port - file. If this command does not appear, there is no default; a - port must somehow be specified in order to call out (it may be - specified implicitly using the `baud' command or explicitly using - the next version of `port'). There may be many ports with the - same name; each will be tried in turn until an unlocked one is - found which matches the desired baud rate. - -`port STRING ...' - If more than one string follows the `port' command, the subsequent - strings are treated as commands that might appear in the port file - (*note port file::.). If a port is named (by using a single - string following `port') these commands are ignored; their - purpose is to permit defining the port completely in the system - file rather than always requiring entries in two different files. - In order to call out, a port must be specified using some - version of the `port' command, or by using the `baud' command to - select ports from the port file. - -`phone STRING' -`address STRING' - Give a phone number to call (when using a modem port) or a remote - host to contact (when using a TCP port). The commands `phone' and - `address' are equivalent, but are intended to be more mnemonic - depending on the type of port in use. - - When used with a modem port, an `=' character in the phone number - means to wait for a secondary dial tone (although only some modems - support this); a `-' character means to pause while dialing for 1 - second (again, only some modems support this). If the system has - more than one phone number, each one must appear in a different - alternate. The `phone' command must appear in order to call out - on a modem; there is no default. - - When used with a TCP port, the string names the host to contact. - It may be a domain name or a numeric Internet address. If no - address is specified, the system name is used. - - When used with a port that neither is a modem nor TCP, this - command is ignored. - - -File: uucp.info, Node: Logging In, Prev: Placing the Call, Up: Calling Out - -Logging In -.......... - -`chat STRINGS' -`chat-timeout NUMBER' -`chat-fail STRING' -`chat-seven-bit BOOLEAN' -`chat-program STRINGS' - These commands describe a chat script to use when logging on to a - remote system. Chat scripts are explained in *Note Chat - Scripts::. - - Two additional escape sequences may be used in send strings. - - `\L' - Send the login name, as set by the `call-login' command. - - `\P' - Send the passowrd, as set by the `call-password' command. - - Three additional escape sequences may be used with the - `chat-program' command. These are `\L' and `\P', which become - the login name and password, respectively, and `\Z', which - becomes the name of the system of being called. - - The default chat script is: - - chat "" \r\c ogin:-BREAK-ogin:-BREAK-ogin: \L word: \P - - This will send a carriage return (the `\c' suppresses the - additional trailing carriage return that would otherwise be sent) - and waits for the string `ogin:' (which would be the last part of - the `login:' prompt supplied by a Unix system). If it doesn't - see `ogin:', it sends a break and waits for `ogin:' again. If it - still doesn't see `ogin:', it sends another break and waits for - `ogin:' again. If it still doesn't see `ogin:', the chat script - aborts and hangs up the phone. If it does see `ogin:' at some - point, it sends the login name (as specified by the `call-login' - command) followed by a carriage return (since all send strings - are followed by a carriage return unless `\c' is used) and waits - for the string `word:' (which would be the last part of the - `Password:' prompt supplied by a Unix system). If it sees - `word:', it sends the password and a carriage return, completing - the chat script. The program will then enter the handshake phase - of the UUCP protocol. - - This chat script will work for most systems, so you will only be - required to use the `call-login' and `call-password' commands. - In fact, in the file-wide defaults you could set defaults of - `call-login *' and `call-password *'; you would then just have to - make an entry for each system in the call-out login file. - - Some systems seem to flush input after the `login:' prompt, so - they may need a version of this chat script with a `\d' before the - `\L'. When using UUCP over TCP, some servers will not be handle - the initial carriage return sent by this chat script; in this - case you may have to specify the simple chat script `ogin: \L - word: \P'. - -`call-login STRING' - Specify the login name to send with `\L' in the chat script. If - the string is `*' (e.g. `call-login *') the login name will be - fetched from the call out login name and password file (*note - Configuration File Names::.). There is no default. - -`call-password STRING' - Specify the password to send with `\P' in the chat script. If the - string is `*' (e.g. `call-password *') the password will be - fetched from the call-out login name and password file (*note - Configuration File Names::.). There is no default. - - -File: uucp.info, Node: Accepting a Call, Next: Protocol Selection, Prev: Calling Out, Up: sys File - -Accepting a Call ----------------- - -`called-login STRINGS' - The first STRING specifies the login name that the system must use - when calling in. If it is `ANY' (e.g. `called-login ANY') any - login name may be used; this is useful to override a file-wide - default and to indicate that future alternates may have different - login names. Case is significant. The default value is `ANY'. - - Different alternates (*note Defaults and Alternates::.) may use - different `called-login' commands, in which case the login name - will be used to select which alternate is in effect; this will - only work if the first alternate (before the first `alternate' - command) uses the `called-login' command. - - Additional strings may be specified after the login name; they - are a list of which systems are permitted to use this login name. - If this feature is used, then normally the login name will only - be given in a single `called-login' command. Only systems which - appear on the list, or which use an explicit `called-login' - command, will be permitted to use that login name. If the same - login name is used more than once with a list of systems, all the - lists are concatenated together. This feature permits you to - restrict a login name to a particular set of systems without - requiring you to use the `called-login' command for every single - system; you can achieve a similar effect by using a different - system file for each permitted login name with an appropriate - `called-login' command in the file-wide defaults. - -`callback BOOLEAN' - If BOOLEAN is true, then when the remote system calls `uucico' - will hang up the connection and prepare to call it back. This is - false by default. - -`called-chat STRINGS' -`called-chat-timeout NUMBER' -`called-chat-fail STRING' -`called-chat-seven-bit BOOLEAN' -`called-chat-program STRINGS' - These commands may be used to define a chat script (*note Chat - Scripts::.) that is run whenever the local system is called by - the system being defined. The chat script defined by the `chat' - command (*note Logging In::.), on the other hand, is used when - the remote system is called. This called chat script might be - used to set special modem parameters that are appropriate to a - particular system. It is run after protocol negotiation is - complete, but before the protocol has been started. See *Note - Logging In:: for additional escape sequence which may be used - besides those defined for all chat scripts. There is no default - called chat script. If the called chat script fails, the - incoming call will be aborted. - - -File: uucp.info, Node: Protocol Selection, Next: File Transfer Control, Prev: Accepting a Call, Up: sys File - -Protocol Selection ------------------- - -`protocol STRING' - Specifies which protocols to use for the other system, and in - which order to use them. This would not normally be used. For - example, `protocol tfg'. - - The default depends on the characteristics of the port and the - dialer, as specified by the `seven-bit' and `reliable' commands. - If neither the port nor the dialer use either of these commands, - the default is to assume an eight-bit reliable connection. The - commands `seven-bit true' or `reliable false' might be used in - either the port or the dialer to change this. Each protocol has - particular requirements that must be met before it will be - considered during negotiation with the remote side. - - The `t' and `e' protocols are intended for use over TCP or some - other communication path with end to end reliability, as they do - no checking of the data at all. They will only be considered on - a TCP port which is both reliable and eight bit. - - The `g' protocol is robust, but requires an eight-bit connection. - - The `f' protocol is intended for use with X.25 connections; it - checksums each file as a whole, so any error causes the entire - file to be retransmitted. It requires a reliable connection, but - only uses seven-bit transmissions. It is a streaming protocol, - so, while it can be used on a serial port, the port must be - completely reliable and flow controlled; many aren't. - - The protocols will be considered in the order shown above. This - means that if neither the `seven-bit' nor the `reliable' command - are used, the `t' protocol will be used over a TCP connection and - the `g' protocol will be used over any other type of connection - (subject, of course, to what is supported by the remote system; - it may be assumed that all systems support the `g' protocol). - - Note that currently specifying both `seven-bit true' and - `reliable false' will not match any protocol. If this occurs - through a combination of port and dialer specifications, you will - have to use the `protocol' command for the system or no protocol - will be selected at all (the only reasonable choice would be - `protocol f'). - - A protocol list may also be specified for a port (*note port - file::.), but if there is a list for the system the list for the - port is ignored. - -`protocol-parameter CHARACTER STRING ...' - CHARACTER is a single character specifying a protocol. The - remaining strings are a command specific to that protocol which - will be executed if that protocol is used. A typical command is - something like `window 7'. The particular commands are protocol - specific. - - The `g' protocol supports the following commands, all of which - take numeric arguments: - - `window' - The window size to request the remote system to use. This - must be between 1 and 7 inclusive. The default is 7. - - `packet-size' - The packet size to request the remote system to use. This - must be a power of 2 between 32 and 4096 inclusive. The - default is 64, which is the only packet size supported by - many older UUCP packages. Some UUCP packages will even dump - core if a larger packet size is requested. - - `startup-retries' - The number of times to retry the initialization sequence. - The default is 8. - - `init-retries' - The number of times to retry one phase of the initialization - sequence (there are three phases). The default is 4. - - `init-timeout' - The timeout in seconds for one phase of the initialization - sequence. The default is 10. - - `retries' - The number of times to retry sending either a data packet or - a request for the next packet. The default is 6. - - `timeout' - The timeout in seconds when waiting for either a data packet - or an acknowledgement. The default is 10. - - `garbage' - The number of unrecognized bytes to permit before dropping - the connection. This must be larger than the packet size. - The default is 10000. - - `errors' - The number of errors (malformed packets, out of order - packets, bad checksums, or packets rejected by the remote - system) to permit before dropping the connection. The - default is 100. - - `remote-window' - If this is between 1 and 7 inclusive, the window size - requested by the remote system is ignored and this is used - instead. This can be useful when dealing with some poor - UUCP packages. The default is 0, which means that the - remote system's request is honored. - - `remote-packet-size' - If this is between 32 and 4096 inclusive the packet size - requested by the remote system is ignored and this is used - instead. There is probably no good reason to use this. The - default is 0, which means that the remote system's request - is honored. - - The `f' protocol is intended for use with error-correcting modems - only; it checksums each file as a whole, so any error causes the - entire file to be retransmitted. It supports the following - commands, both of which take numeric arguments: - - `timeout' - The timeout in seconds before giving up. The default is 120. - - `retries' - How many times to retry sending a file. The default is 2. - - The `t' and `e' protocols are intended for use over TCP or some - other communication path with end to end reliability, as they do - no checking of the data at all. They both support a single - command, which takes a numeric argument: - - `timeout' - The timeout in seconds before giving up. The default is 120. - - The protocol parameters are reset to their default values after - each call. - - -File: uucp.info, Node: File Transfer Control, Next: Miscellaneous (sys), Prev: Protocol Selection, Up: sys File - -File Transfer Control ---------------------- - -`call-request BOOLEAN' - The BOOLEAN is checked when the local system places the call. It - determines whether the remote system may request any file - transfers. The default is yes. - -`called-request BOOLEAN' - The BOOLEAN is checked when the remote system calls in. It - determines whether the remote system may request any file - transfers. The default is yes. - -`request BOOLEAN' - Equivalent to specifying both `call-request BOOLEAN' and - `called-request BOOLEAN'. - -`call-transfer BOOLEAN' - The BOOLEAN is checked when the local system places the call. It - determines whether the local system may do file transfers queued - up for the remote system. The default is yes. - -`called-transfer BOOLEAN' - The BOOLEAN is checked when the remote system calls in. It - determines whether the local system may do file transfers queued - up for the remote system. The default is yes. - -`transfer BOOLEAN' - Equivalent to specifying both `call-transfer BOOLEAN' - `called-transfer BOOLEAN'. - -`call-local-size NUMBER STRING' - The STRING is a time string (*note Time Strings::.). The NUMBER - is the size in bytes of the largest file that should be - transferred at a time matching the time string if the local system - placed the call and the request was made by the local system. - This command may appear multiple times in a single alternate. If - this command does not appear, or if none of the time strings - match, there are no size restrictions. - - With all the size control commands, the size of a file from the - remote system (as opposed to a file from the local system) will - only be checked if the other system is running this package; - other UUCP packages will not understand a maximum size request, - nor will they inform this package of the size of remote files. - -`call-remote-size NUMBER STRING' - Specify the size in bytes of the largest file that should be - transferred at a given time by remote request when the local - system placed the call. This command may appear multiple times - in a single alternate. If this command does not appear, there - are no size restrictions. - -`called-local-size NUMBER STRING' - Specify the size in bytes of the largest file that should be - transferred at a given time by local request when the remote - system placed the call. This command may appear multiple times - in a single alternate. If this command does not appear, there are - no size restrictions. - -`called-remote-size NUMBER STRING' - Specify the size in bytes of the largest file that should be - transferred at a given time by remote request when the remote - system placed the call. This command may appear multiple times - in a single alternate. If this command does not appear, there are - no size restrictions. - -`local-send STRINGS' - Specifies that files in the directories named by the STRINGS may - be sent to the remote system when requested locally (using `uucp' - or `uux'). The directories in the list should be separated by - whitespace. A `~' may be used for the public directory. On a - Unix system, this is typically `/usr/spool/uucppublic'; the public - directory may be set with the `pubdir' command. Here is an - example of `local-send': - - local-send ~ /usr/spool/ftp/pub - - Listing a directory allows all files within the directory and all - subdirectories to be sent. Directories may be excluded by - preceding them with an exclamation point. For example: - - local-send /usr/ftp !/usr/ftp/private ~ - - means that all files in `/usr/ftp' or the public directory may be - sent, except those files in `/usr/ftp/private'. The list of - directories is read from left to right, and the last directory to - apply takes effect; this means that directories should be listed - from top down. The default is the root directory (i.e., any file - at all may be sent by local request). - -`remote-send STRINGS' - Specifies that files in the named directories may be sent to the - remote system when requested by the remote system. The default - is `~'. - -`local-receive STRINGS' - Specifies that files may be received into the named directories - when requested by a local user. The default is `~'. - -`remote-receive STRINGS' - Specifies that files may be received into the named directories - when requested by the remote system. The default is `~'. On - Unix, the remote system may only request that files be received - into directories that are writeable by the world, regardless of - how this is set. - -
\ No newline at end of file diff --git a/gnu/libexec/uucp/uucp.info-3 b/gnu/libexec/uucp/uucp.info-3 deleted file mode 100644 index 618fd745d3c..00000000000 --- a/gnu/libexec/uucp/uucp.info-3 +++ /dev/null @@ -1,1194 +0,0 @@ -Info file uucp.info, produced by Makeinfo, -*- Text -*- from input -file uucp.texi. - - This file documents Taylor UUCP, version 1.03. - - Copyright (C) 1992 Free Software Foundation, Inc. - - Permission is granted to make and distribute verbatim copies of this -manual provided the copyright notice and this permission notice are -preserved on all copies. - - Permission is granted to copy and distribute modified versions of -this manual under the conditions for verbatim copying, provided also -that the section entitled "Copying" are included exactly as in the -original, and provided that the entire resulting derived work is -distributed under the terms of a permission notice identical to this -one. - - Permission is granted to copy and distribute translations of this -manual into another language, under the above conditions for modified -versions, except that the section entitled "Copying" may be included -in a translation approved by the author instead of in the original -English. - - -File: uucp.info, Node: Miscellaneous (sys), Next: Default sys File Values, Prev: File Transfer Control, Up: sys File - -Miscellaneous sys File Commands -------------------------------- - -`sequence BOOLEAN' - If BOOLEAN is true, then conversation sequencing is automatically - used for the remote system, so that if somebody manages to spoof - as the remote system, it will be detected the next time the - remote system actually calls. This is false by default. - -`command-path STRING' - Specifies the path (a list of whitespace separated directories) - to be searched to locate commands to execute. This is only used - for commands requested by `uux', not for chat programs. The - default is from `policy.h'. - -`commands STRINGS' - The list of commands which the remote system is permitted to - execute locally. For example: `commands rnews rmail'. If the - value is `ALL' (case significant), all commands may be executed. - The default is `rnews rmail'. - -`free-space NUMBER' - Specify the minimum amount of file system space (in bytes) to - leave free after receiving a file. If the incoming file will not - fit, it will be rejected. This will only work when talking to - another instance of this package, since older UUCP packages do - not provide the file size of incoming files. There is no - provision for reserving space, so it is still possible for - multiple `uucico' daemons to use up all available file space; a - sufficiently large value for `free-space' will avoid this problem - to some extent. The default is from `policy.h'. Not all systems - may be able to provide the amount of available space. - -`pubdir STRING' - Specifies the public directory that is used when `~' is specifed - in a file transfer or a list of directories. This essentially - overrides the public directory specified in the main - configuration file for this system only. The default is the - public directory specified in the main configuration file (which - defaults to a value from `policy.h'). - -`debug STRING ...' - Set additional debugging for calls to or from the system. This - may be used to debug a connection with a specific system. It is - particularly useful when debugging incoming calls, since - debugging information will be generated whenever the call comes - in. See the `debug' command in the main configuration file - (*note Debugging Levels::.) for more details. The debugging - information specified here is in addition to that specified in - the main configuration file or on the command line. - -`max-remote-debug STRING ...' - When the system calls in, it may request that the debugging level - be set to a certain value. This command may be used to put a - limit on the debugging level which the system may request, to - avoid filling up the disk with debugging information. Only the - debugging types named in the `max-remote-debug' command may be - turned on by the remote system. To prohibit any debugging, use - `max-remote-debug none'. The default is - `abnormal,chat,handshake'; to turn off these default entries, you - must use `max-remote-debug none' followed by other - `max-remote-debug' commands specifying the settings you want. - -`timetable STRING STRING' - This is actually not specific to a system; it can appear anywhere - in the file(s). In a future release this command will probably - be moved to the main configuration file. - - The `timetable' defines a timetable that may be used in - subsequently appearing time strings; *Note Time Strings::. The - first string names the timetable entry; the second is a time - string. - - The following `timetable' commands are predefined. The NonPeak - timetable is included for compatibility. It originally described - the offpeak hours of Tymnet and Telenet, but both have since - changed their schedules. - - timetable Evening Wk1705-0755,Sa,Su - timetable Night Wk2305-0755,Sa,Su2305-1655 - timetable NonPeak Wk1805-0655,Sa,Su - - If this command does not appear, then obviously no additional - timetables will be defined. - - -File: uucp.info, Node: Default sys File Values, Prev: Miscellaneous (sys), Up: sys File - -Default sys File Values ------------------------ - - The following are used as default values for all systems; they can -be considered as appearing before the start of the file. - - timetable Evening Wk1705-0755,Sa,Su - timetable Night Wk2305-0755,Sa,Su2305-1655 - timetable NonPeak Wk1805-0655,Sa,Su - time Never - chat "" \r\c ogin:-BREAK-ogin:-BREAK-ogin: \L word: \P - chat-timeout 10 - callback n - sequence n - request y - transfer y - local-send / - remote-send ~ - local-receive ~ - remove-receive ~ - command-path [ from `policy.h' ] - commands rnews rmail - max-remote-debug abnormal,chat,handshake - - -File: uucp.info, Node: port File, Next: dial File, Prev: sys File, Up: Configuration Files - -The Port Configuration File -=========================== - - The port files may be used to name and describe ports. The first -command in each file must be `port'. All command up to the next -`port' command then describe that port. There are different types of -ports; each type supports its own set of commands. Each command -indicates which types of ports support it. There may be many ports -with the same name; if a system requests a port by name then each port -with that name will be tried until an unlocked one is found. - -`port STRING' - Introduces and names a port. - -`type STRING' - Define the type of port. The default is `modem'. If this command - appears, it must immediately follow the `port' command. The type - defines what commands are subsequently allowed. Currently the - types are: - - `modem' - For a modem hookup. - - `stdin' - For a connection through standard input and standard output, - as when `uucico' is run as a login shell. - - `direct' - For a direct connection to another system. - - `tcp' - For a connection using TCP. - -`protocol STRING' - Specify a list of protocols to use for this port. This is just - like the corresponding command for a system (*note Protocol - Selection::.). A protocol list for a system takes precedence - over a list for a port. - -`protocol-parameter CHARACTER STRINGS [ any type ]' - The same command as the `protocol-parameter' command used for - systems (*note Protocol Selection::.). This one takes precedence. - -`seven-bit BOOLEAN [ any type ]' - This is only used during protocol negotiation; if the argument is - `true', it forces the selection of a protocol which works across a - seven-bit link. It does not prevent eight bit characters from - being transmitted. The default is `false'. - -`reliable BOOLEAN [ any type ]' - This is only used during protocol negotiation; if the argument is - `false', it forces the selection of a protocol which works across - an unreliable communication link. The default is `true'. It - would be more common to specify this for a dialer rather than a - port. - -`device STRING [ modem and direct only ]' - Names the device associated with this port. If the device is not - named, the port name is taken as the device. Device names are - system dependent, but a Unix example would be `/dev/ttyd0'. - -`baud NUMBER [ modem and direct only ]' -`speed NUMBER [modem and direct only ]' - The speed this port runs at. If a system specifies a speed but - no port name, then all ports which match the speed will be tried - in order. If the speed is not specified here and is not - specified by the system, the natural speed of the port will be - used by default. - -`baud-range NUMBER NUMBER [ modem only ]' -`speed-range NUMBER NUMBER [ modem only ]' - Specify a range of speeds this port can run at. The first number - is the minimum speed, the second number is the maximum speed. - These numbers will be used when matching a system which specifies - a desired speed. The simple `speed' (or `baud') command is still - used to determine the speed to run at if the system does not - specify a speed. For example, the command `speed-range 300 - 19200' means that the port will match any system which uses a - speed from 300 to 19200 baud (and will use the speed specified by - the system); this could be combined with `speed 2400', which - means that when this port is used with a system that does not - specify a speed, the port will be used at 2400 baud. - -`carrier BOOLEAN [ modem only ]' - The argument indicates whether the port supports carrier. If it - does not, carrier will never be required on this port, regardless - of what the modem chat script indicates. The default is `true'. - -`dial-device STRING [ modem only ]' - Dialing instructions should be output to the named device, rather - than to the normal port device. The default is to output to the - normal port device. - -`dialer STRING [ modem only ]' - Name a dialer to use. The information is looked up in the dialer - file. There is no default. Some sort of dialer information must - be specified to call out on a modem. - -`dialer STRING ... [ modem only ]' - Execute a dialer command. If a dialer is named (by using the - first form of this command, described just above), these commands - are ignored. They may be used to specify dialer information - directly in simple situations without needing to go to a separate - file. There is no default. Some sort of dialer information must - be specified to call out on a modem. - -`dialer-sequence STRINGS [ modem only ]' - Name a sequence of dialers and tokens (phone numbers) to use. - The first argument names a dialer, and the second argument names - a token. The third argument names another dialer, and so on. If - there are an odd number of arguments, the phone number specified - with a `phone' command in the system file is used as the final - token. The token is what is used for `\D' or `\T' in the dialer - chat script. If the token in this string is `\D', the system - phone number will be used; if it is `\T', the system phone number - will be used after undergoing dialcodes translation. A missing - final token is taken as `\D'. - - This command currently does not work if `dial-device' is - specified; to handle this correctly will require a more - systematic notion of chat scripts. Moreover, only the `complete' - and `abort' chat scripts from the first dialer specified are - used, and only the protocol parameters from the first dialer are - used. - -`lockname STRING [ modem and direct only ]' - Give the name to use when locking this port. On Unix, this is - the name of the file that will be created in the lock directory. - It is used as is, so on Unix it should generally start with - `LCK..'. For example, if a single port were named both - `/dev/ttycu0' and `/dev/tty0' (perhaps with different - characteristics keyed on the minor device number), then the - command `lockname LCK..ttycu0' could be used to force the latter - to use the same lock file name as the former. - -`service STRING [ tcp only ]' - Name the TCP port number to use. This may be a number. If not, - it will be looked up in `/etc/services'. If this is not - specified, the string `uucp' is looked up in `/etc/services'. If - it is not found, port number 540 (the standard UUCP-over-TCP port - number) will be used. - - -File: uucp.info, Node: dial File, Next: Security, Prev: port File, Up: Configuration Files - -The Dialer Configuration File -============================= - - The dialer configuration files define dialers. The first command in -each file must be a `dialer' command, which names the dialer. -Subsequent commands up to the next `dialer' command are associated -with the named dialer. - -`dialer STRING' - Introduces and names a dialer. - -`chat STRINGS' -`chat-timeout NUMBER' -`chat-fail STRING' -`chat-seven-bit BOOLEAN' -`chat-program STRINGS' - Specify a chat script to be used to dial the phone. See *Note - Chat Scripts:: for full details on chat scripts. - - Taylor UUCP will sleep for one second between attempts to dial - out on a modem. If your modem requires a longer wait period, you - must start your chat script with delays (`\d' in a send string). - - The chat script will be read from and sent to the port specified - by the `dial-device' command for the port, if there is one. - - The following escape addition escape sequences may appear in send - strings: - - `\D' - send phone number without dialcode translation - - `\T' - send phone number with dialcode translation - - `\M' - do not require carrier - - `\m' - require carrier (fail if not present) - - See the description of the dialcodes file (*note Configuration - File Names::.) for a description of dialcode translation. If the - port does not support carrier (as set by the `carrier' command in - the port file) `\M' and `\m' are ignored. If both the port and - the dialer support carrier (as set by the `carrier' command in - the port file and the `carrier' command in the dialer file), then - every chat script implicitly begins with `\M' and ends with `\m'. - There is no default chat script for dialers. - - The following additional escape sequences may be used in - `chat-program': - - `\D' - phone number without dialcode translation - - `\T' - phone number with dialcode translation - - If the program changes the port in any way (e.g., sets parity) the - changes will be preserved during protocol negotiation, but once - the protocol is selected it will change the port settings. - -`dialtone STRING' - A string to output when dialing the phone number which causes the - modem to wait for a secondary dial tone. This is used to - translate the `=' character in a phone number. The default is a - comma. - -`pause STRING' - A string to output when dialing the phone number which causes the - modem to wait for 1 second. This is used to translate the `-' - character in a phone number. The default is a comma. - -`carrier BOOLEAN' - If the argument is `true', the dialer supports the modem carrier - signal. After the phone number is dialed, `uucico' will require - that carrier be on. One some systems, it will be able to wait - for it. If the argument is `false', carrier will not be - required. The default is `true'. - -`carrier-wait NUMBER' - If the port is supposed to wait for carrier, this may be used to - indicate how many seconds to wait. The default is 60 seconds. - Only some systems support waiting for carrier. - -`dtr-toggle BOOLEAN BOOLEAN' - If the first argument is `true', then DTR is toggled before using - the modem. This is only supported on some systems and some - ports. The second BOOLEAN need not be present; if it is, and it - is `true', the program will sleep for 1 second after toggling DTR. - The default is not to toggle DTR. - -`complete-chat STRINGS' -`complete-chat-timeout NUMBER' -`complete-chat-fail STRING' -`complete-chat-seven-bit BOOLEAN' -`complete-chat-program STRINGS' - These commands define a chat script (*note Chat Scripts::.) which - is run when a call is finished normally. This allows the modem - to be reset. There is no default. No additional escape - sequences may be used. - -`complete STRING' - This is a simple use of `complete-chat'. It is equivalent to - `complete-chat "" STRING'; this has the effect of sending STRING - to the modem when a call finishes normally. - -`abort-chat STRINGS' -`abort-chat-timeout NUMBER' -`abort-chat-fail STRING' -`abort-chat-seven-bit BOOLEAN' -`abort-chat-program STRINGS' - These commands define a chat script (*note Chat Scripts::.) to be - run when a call is aborted. They may be used to interrupt and - reset the modem. There is no default. No additional escape - sequences may be used. - -`abort STRING' - This is a simple use of `abort-chat'. It is equivalent to - `abort-chat "" STRING'; this has the effect of sending STRING to - the modem when a call is aborted. - -`protocol-parameter CHARACTER STRINGS' - Set protocol parameters, just like the `protocol-parameter' - command in the system configuration file or the port - configuration file; see *Note Protocol Selection::. These - parameters take precedence, then those for the port, then those - for the system. - -`seven-bit BOOLEAN' - This is only used during protocol negotiation; if it is `true', it - forces selection of a protocol which works across a seven-bit - link. It does not prevent eight bit characters from being - transmitted. The default is `false'. It would be more common to - specify this for a port than for a dialer. - -`reliable BOOLEAN' - This is only used during protocol negotiation; if it is `false', - it forces selection of a protocol which works across an unreliable - communication link. The default is `true'. - - -File: uucp.info, Node: Security, Prev: dial File, Up: Configuration Files - -Security -======== - - This discussion of UUCP security applies only to Unix. It is a bit -cursory; suggestions for improvement are solicited. - - UUCP is traditionally not very secure. Taylor UUCP addresses some -security issues, but is still far from being a secure system. - - If security is very important to you, then you should not permit any -external access to your computer, including UUCP. Any opening to the -outside world is a potential security risk. - - By default Taylor UUCP provides few mechanisms to secure local -users of the system from each other. You can allow increased security -by putting the owner of the UUCP programs (normally `uucp') into a -separate group; the use of this is explained in the following -paragraphs, which refer to this separate group as `uucp-group'. - - When the `uucp' program is invoked to copy a file to a remote -system, it will by default copy the file into the UUCP spool directory. -When the `uux' program is used, the `-C' switch must be used to copy -the file into the UUCP spool directory. In any case, once the file -has been copied into the spool directory, other local users will not -be able to access it. In version 1.03 there is a security hole in -that for the file to be copied it must be readable by `uucp'. -Changing the group of the file to `uucp-group' and making it group -readable will permit UUCP to read it without granting access to other -users. - - When a file is requested from a remote system, UUCP will only -permit it to be placed in a directory which is writable by the -requesting user. The directory must also be writable by UUCP. A -local user can create a directory with a group of `uucp-group' and set -the mode to permit group write access. This will allow the file be -requested without permitting it to be viewed by any other user. - - There is no provision for security for `uucp' requests (as opposed -to `uux' requests) made by a user on a remote system. A file sent -over by a remote request may only be placed in a directory which is -world writable, and the file will be world readable and writable. This -will permit any local user to destroy or replace the contents of the -file. A file requested by a remote system must be world readable, and -the directory it is in must be world readable. Any local user will be -able to examine, although not necessarily modify, the file before it is -sent. - - There are some security holes and race conditions that apply to the -above discussion which I will not elaborate on. They are not hidden -from anybody who reads the source code, but they are somewhat technical -and difficult (but scarcely impossible) to exploit. Suffice it to say -that even under the best of conditions UUCP is not completely secure. - - For many sites, security from remote sites is a more important -consideration. Fortunately, Taylor UUCP does provide some support in -this area. - - The greatest security is provided by always dialing out to the other -site. This prevents anybody from pretending to be the other site. Of -course, only one side of the connection can do this. - - If remote dialins must be permitted, then it is best if the dialin -line is used only for UUCP. If this is the case, then you should -create a call-in password file (*note Configuration File Names::.) and -let `uucico' do its own login prompting. For example, to let remote -sites log in on a port named `entry' in the port file (*note port -file::.) you might invoke `uucico -p entry'. This would cause -`uucico' to enter an endless loop of login prompts and daemon -executions. The advantage of this approach is that even if remote -users break into the system by guessing or learning the password, they -will only be able to do whatever `uucico' permits them to do. They -will not be able to start a shell on your system. - - If remote users can dial in and log on to your system, then you -have a security hazard more serious than that posed by UUCP. But -then, you probably knew that already. - - Once your system has connected with the remote UUCP, there is a fair -amount of control you can exercise. You can use the `remote-send' and -`remote-receive' commands to control the directories the remote UUCP -can access. You can use the `request' command to prevent the remote -UUCP from making any requests of your system at all; however, if you -do this it will not even be able to send you mail or news. If you do -permit remote requests, you should be careful to restrict what -commands may be executed at the remote system's request. The default -is `rmail' and `rnews', which will suffice for most systems. - - If different remote systems call in and they must be granted -different privileges (perhaps some systems are within the same -organization and some are not) then the `called-login' command should -be used for each system to require that they different login names. -Otherwise it would be simple for a remote system to use the `myname' -command and pretend to be a different system. The `sequence' command -can be used to detect when one system pretended to be another, but -since the sequence numbers must be reset manually after a failed -handshake this can sometimes be more trouble than it's worth. - - -File: uucp.info, Node: Protocols, Next: Hacking, Prev: Configuration Files, Up: Top - -UUCP protocol internals -*********************** - - This chapter describes how the various UUCP protocols work, and -discusses some other internal UUCP issues. - - This chapter is quite technical. You do not need to understand it, -or even read it, in order to use Taylor UUCP. It is intended for -people who are interested in how UUCP code works. - - Most of the discussion covers the protocols used by all UUCP -packages, not just Taylor UUCP. Any information specific to Taylor -UUCP is indicated as such. There are some pointers to the actual -functions in the Taylor UUCP source code, for those who are extremely -interested in actual UUCP implementation. - -* Menu: - -* Grades:: UUCP grades -* Lock Files:: UUCP lock file format -* UUCP Protocol:: The common UUCP protocol -* g Protocol:: The UUCP `g' protocol -* f Protocol:: The UUCP `f' protocol -* t Protocol:: The UUCP `t' protocol -* e Protocol:: The UUCP `e' protocol -* x Protocol:: The UUCP `x' protocol -* d Protocol:: The UUCP `d' protocol -* Capital G Protocol:: The UUCP `G' protocol -* Documentation References:: Documentation references - - -File: uucp.info, Node: Grades, Next: Lock Files, Prev: Protocols, Up: Protocols - -UUCP Grades -=========== - - Modern UUCP packages support grades for each command. The grades -generally range from `A' (the highest) to `Z' followed by `a' to `z'. -Taylor UUCP also supports `0' to `9' before `A'. Some UUCP packages -may permit any ASCII character as a grade. - - On Unix, these grades are encoded in the name of the command file. -A command file name generally has the form - - C.nnnngssss - -where NNNN is the remote system name for which the command is queued, -G is a single character grade, and SSSS is a four character sequence -number. For example, a command file created for the system `airs' at -grade `Z' might be named - - C.airsZ2551 - - The remote system name will be truncated to seven characters, to -ensure that the command file name will fit in the 14 character file -name limit of the traditional Unix file system. UUCP packages which -have no other means of distinguishing which command files are intended -for which systems thus require all *systems they connect to* to have -names that are unique in the first seven characters. Some UUCP -packages use a variant of this format which truncates the system name -to six characters. BNU uses a different spool directory format, which -allows up to fourteen characters to be used for each system name. The -Taylor UUCP spool directory format is configurable. The new Taylor -spool directory format permits system names to be as long as file -names; the maximum length of a file name depends on the particular -Unix file system being used. - - The sequence number in the command file name may be a decimal -integer, or it may be a hexadecimal integer, or it may contain any -alphanumeric character. Different UUCP packages are different. - - Taylor UUCP creates command files in the function -`zsysdep_spool_commands'. The file name is constructed by the -function `zsfile_name', which knows about all the different types of -spool directories supported by Taylor UUCP. The Taylor UUCP sequence -number can contain any alphanumeric character; the next sequence number -is determined by the function `fscmd_seq'. - - I do not know how command grades are handled in non-Unix UUCP -packages. - - Modern UUCP packages allow you to restrict file transfer by grade -depending on the time of day. Typically this is done with a line in -the `Systems' (or `L.sys') file like this: - - airs Any/Z,Any2305-0855 ... - - This allows only grades `Z' and above to be transferred at any -time. Lower grades may only be transferred at night. I believe that -this grade restriction applies to local commands as well as to remote -commands, but I am not sure. It may only apply if the UUCP package -places the call, not if it is called by the remote system. Taylor UUCP -can use the `timegrade' and `call-timegrade' commands (*note When to -Call::.) to achieve the same effect (and supports the above format -when reading `Systems' or `L.sys'). - - This sort of grade restriction is most useful if you know what -grades are being used at the remote site. The default grades used -depend on the UUCP package. Generally `uucp' and `uux' have different -defaults. A particular grade can be specified with the `-g' option to -`uucp' or `uux'. For example, to request execution of rnews on airs -with grade `d', you might use something like - - uux -gd - airs!rnews <article - - `uunet' queues up mail at grade `Z' and news at grade `d'. The -example above would allow mail to be received at any time, but would -only permit news to be transferred at night. - - -File: uucp.info, Node: Lock Files, Next: UUCP Protocol, Prev: Grades, Up: Protocols - -UUCP Lock File Format -===================== - - This discussion applies only to Unix. I have no idea how UUCP locks -ports on other systems. - - UUCP creates files to lock serial ports and systems. On most (if -not all) systems, these same lock files are also used by cu to -coordinate access to serial ports. On some systems getty also uses -these lock files. - - The lock file normally contains the process ID of the locking -process. This makes it easy to determine whether a lock is still -valid. The algorithm is to create a temporary file and then link it -to the name that must be locked. If the link fails because a file -with that name already exists, the existing file is read to get the -process ID. If the process still exists, the lock attempt fails. -Otherwise the lock file is deleted and the locking algorithm is -retried. - - Older UUCP packages put the lock files in the main UUCP spool -directory, /usr/spool/uucp. BNU UUCP generally puts the lock files in -a directory of their own, usually /usr/spool/locks or /etc/locks. - - The original UUCP lock file format encoded the process ID as a four -byte binary number. The order of the bytes was host-dependent. BNU -UUCP stores the process ID as a ten byte ASCII decimal number, with a -trailing newline. For example, if process 1570 holds a lock file, it -would contain the eleven characters space, space, space, space, space, -space, one, five, seven, zero, newline. Some versions of UUCP add a -second line indicating which program created the lock (uucp, cu, or -getty). I have also seen a third type of UUCP lock file which did not -contain the process ID at all. - - The name of the lock file is generally "LCK.." followed by the base -name of the device. For example, to lock /dev/ttyd0 the file -LCK..ttyd0 would be created. There are various exceptions. On SCO -Unix, the lock file name is always forced to lower case even if the -device name has upper case letters. System V Release 4 UUCP forms the -lock file name using the major and minor device numbers rather than -the device name (this is pretty sensible if you think about it). - - Taylor UUCP can be configured to use various different types of -locking. The actual locking code is in the function `fsdo_lock'. - - -File: uucp.info, Node: UUCP Protocol, Next: g Protocol, Prev: Lock Files, Up: Protocols - -The Common UUCP Protocol -======================== - - The UUCP protocol is a conversation between two UUCP packages. A -UUCP conversation consists of three parts: an initial handshake, a -series of file transfer requests, and a final handshake. - - Before the initial handshake, the caller will usually have logged -in the called machine and somehow started the UUCP package there. On -Unix this is normally done by setting the shell of the login name used -to `uucico'. - -* Menu: - -* Initial Handshake:: Initial handshake -* File Requests:: File requests -* Final Handshake:: Final handshake - - -File: uucp.info, Node: Initial Handshake, Next: File Requests, Prev: UUCP Protocol, Up: UUCP Protocol - -Initial Handshake ------------------ - - All messages in the initial handshake begin with a `^P' (a byte -with the octal value \020) and end with a null byte (\000). - - Taylor UUCP implements the initial handshake for the calling -machine in `fdo_call', and for the called machine in `faccept_call'. - - The initial handshake goes as follows. It is begun by the called -machine. - -called: `\020Shere=HOSTNAME\000' - The HOSTNAME is the UUCP name of the called machine. Older UUCP - packages do not output it, and simply send `\020Shere\000'. - -caller: `\020SHOSTNAME OPTIONS\000' - The HOSTNAME is the UUCP name of the calling machine. The - following OPTIONS may appear (or there may be none): - - `-QSEQ' - Report sequence number for this conversation. The sequence - number is stored at both sites, and incremented after each - call. If there is a sequence number mismatch, something has - gone wrong (somebody may have broken security by pretending - to be one of the machines) and the call is denied. If the - sequence number changes on one of the machines, perhaps - because of an attempted breakin or because a disk backup was - restored, the sequence numbers on the two machines must be - reconciled manually. - - `-xLEVEL' - Requests the called system to set its debugging level to the - specified value. This is not supported by all systems. - Taylor UUCP currently never generates this switch. When it - sees it, it restricts the value according to - `max-remote-debug' (*note Miscellaneous (sys)::.). - - `-pGRADE' - `-vgrade=GRADE' - Requests the called system to only transfer files of the - specified grade or higher. This is not supported by all - systems. Some systems support `-p', some support - `-vgrade='. Taylor UUCP supports both. - - `-R' - Indicates that the calling UUCP understands how to restart - failed file transmissions. Supported only by System V - Release 4 UUCP. - - `-ULIMIT' - Reports the `ulimit' value of the calling UUCP. The limit is - specified as a base 16 number in C notation (e.g., - `-U0x1000000'). This number is the number of 512 byte - blocks in the largest file which the calling UUCP can - create. The called UUCP may not transfer a file larger than - this. Supported by System V Release 4 UUCP. Taylor UUCP - understands this option, but never generates it. - - `-N' - Indicates that the calling UUCP understands the Taylor UUCP - size limiting extensions. Supported only by Taylor UUCP. - -called: `\020ROK\000' - There are actually several possible responses. - - `ROK' - The calling UUCP is acceptable, and the handshake proceeds - to the protocol negotiation. Some options may also appear; - see below. - - `ROKN' - The calling UUCP is acceptable, it specified `-N', and the - called UUCP also understands the Taylor UUCP size limiting - extensions. Supported only by Taylor UUCP. - - `RLCK' - The called UUCP already has a lock for the calling UUCP, - which normally indicates the two machines are already - communicating. - - `RCB' - The called UUCP will call back. This may be used to avoid - impostors. Note that only one machine out of each pair - should call back, or no conversation will ever begin. - - `RBADSEQ' - The call sequence number is wrong (see the `-Q' discussion - above). - - `RLOGIN' - The calling UUCP is using the wrong login name. - - `RYou are unknown to me' - The calling UUCP is not known to the called UUCP, and the - called UUCP does not permit connections from unknown systems. - - If the response is `ROK', the following options are supported by - System V Release 4 UUCP. - - `-R' - The called UUCP knows how to restart failed file - transmissions. - - `-ULIMIT' - Reports the ulimit value of the called UUCP. The limit is - specified as a base 16 number in C notation. This number is - the number of 512 byte blocks in the largest file which the - called UUCP can create. The calling UUCP may not send a - file larger than this. - - `-xLEVEL' - I'm told that this is sometimes sent by SVR4 UUCP, but I'm - not sure exactly what it means. It may request the calling - UUCP to set its debugging level to the specified value. - - If the response is not `ROK' (or `ROKN') both sides hang up the - phone, abandoning the call. - -called: `\020PPROTOCOLS\000' - The `P' is a literal character. Note that the called UUCP outputs - two strings in a row. The PROTOCOLS string is a list of UUCP - protocols supported by the caller. Each UUCP protocol has a - single character name. For example, the called UUCP might send - `\020Pgf\000'. - -caller: `\020UPROTOCOL\000' - The `U' is a literal character. The calling UUCP selects which - PROTOCOL to use out of the protocols offered by the called UUCP. - If there are no mutually supported protocols, the calling UUCP - sends `\020UN\000' and both sides hang up the phone. Otherwise - the calling UUCP sends something like `\020Ug\000'. - - Most UUCP packages will consider each locally supported protocol in -turn and select the first one supported by the called UUCP. With some -versions of BNU UUCP, this can be modified by giving a list of -protocols after the device name in the Devices file or the `Systems' -file. Taylor UUCP provides the `protocol' command which may be used -either for a system (*note Protocol Selection::.) or a port (*note -port file::.). - - After the protocol has been selected and the initial handshake has -been completed, both sides turn on the selected protocol. For some -protocols (notably `g') a further handshake is done at this point. - - Each protocol supports a method for sending a command to the remote -system. This method is used to transmit a series of commands between -the two UUCP packages. At all times, one package is the master and the -other is the slave. Initially, the calling UUCP is the master. - - If a protocol error occurs during the exchange of commands, both -sides move immediately to the final handshake. - - -File: uucp.info, Node: File Requests, Next: Final Handshake, Prev: Initial Handshake, Up: UUCP Protocol - -File Requests -------------- - - The master will send one of four commands: `S', `R', `X' or `H'. - - Any file name referred to below is either an absolute pathname -beginning with `/', a public directory pathname beginning with `~/', a -pathname relative to a user's home directory beginning with `~USER/', -or a spool directory file name. File names in the spool directory are -not pathnames, but instead are converted to pathnames within the spool -directory by UUCP. They always begin with `C.' (for a command file -created by `uucp' or `uux'), `D.' (for a data file created by `uucp', -`uux' or by an execution, or received from another system for an -execution), or `X.' (for an execution file created by `uux' or -received from another system). - - Taylor UUCP chooses which request to send next in the function -`fuucp'. This is also where Taylor UUCP processes incoming commands -from the remote system. - -* Menu: - -* S Request:: S request -* R Request:: R request -* X Request:: X request -* H Request:: H request - - -File: uucp.info, Node: S Request, Next: R Request, Prev: File Requests, Up: File Requests - -S Request -......... - - master: `S FROM TO USER -OPTIONS TEMP MODE NOTIFY SIZE' - - The `S' and the `-' are literal characters. This is a request by -the master to send a file to the slave. Taylor UUCP handles the `S' -request in the function `fsend_file'. - -FROM - The name of the file to send. If the `C' option does not appear - in OPTIONS, the master will actually open and send this file. - Otherwise the file has been copied to the spool directory, where - it is named TEMP. The slave ignores this field unless TO is a - directory, in which case the basename of FROM will be used as the - file name. If FROM is a spool directory filename, it must be a - data file created for or by an execution, and must begin with - `D.'. - -TO - The name to give the file on the slave. If this field names a - directory the file is placed within that directory with the - basename of FROM. A name ending in `/' is taken to be a - directory even if one does not already exist with that name. If - TO begins with `X.', an execution file will be created on the - slave. Otherwise, if TO begins with `D.' it names a data file to - be used by some execution file. Otherwise, TO should not be in - the spool directory. - -USER - The name of the user who requested the transfer. - -OPTIONS - A list of options to control the transfer. The following options - are defined (all options are single characters): - - `C' - The file has been copied to the spool directory (the master - should use TEMP rather than FROM). - - `c' - The file has not been copied to the spool directory (this is - the default). - - `d' - The slave should create directories as necessary (this is - the default). - - `f' - The slave should not create directories if necessary, but - should fail the transfer instead. - - `m' - The master should send mail to USER when the transfer is - complete. - - `n' - The slave should send mail to NOTIFY when the transfer is - complete. - -TEMP - If the `C' option appears in OPTIONS, this names the file to be - sent. Otherwise if FROM is in the spool directory, TEMP is the - same as FROM. Otherwise TEMP is a dummy string, normally `D.0'. - After the transfer has been succesfully completed, the master - will delete the file TEMP. - -MODE - This is an octal number giving the mode of the file on the - master. If the file is not in the spool directory, the slave - will always create it with mode 0666, except that if (MODE & - 0111) is not zero (the file is executable), the slave will create - the file with mode 0777. If the file is in the spool directory, - some UUCP packages will use the algorithm above and some will - always create the file with mode 0600 (Taylor UUCP does the - latter). - -NOTIFY - This field is only used if the `n' option appears in OPTIONS. - Otherwise, it may not appear, or it may be the string `dummy', or - it may simply be a pair of double quotes. If the `n' option is - specified, then when the transfer is successfully completed the - slave will send mail to NOTIFY, which must be a legal mailing - address on the slave. - -SIZE - This field is only present when doing size negotiation, either - with Taylor UUCP or SVR4 UUCP. It is the size of the file in - bytes. SVR4 UUCP sends the size in base 16 as 0x... while Taylor - UUCP sends the size as a decimal integer (a later version of - Taylor UUCP will probably change to the SVR4 behaviour). - - The slave then responds with an S command response. Taylor UUCP -generates these responses in `freceive_file' and `ftransfer_fail'. - -`SY START' - The slave is willing to accept the file, and file transfer - begins. The START field will only be present when using SVR4 - file restart. It specifies the byte offset into the file at - which to start sending. If this is a new file, START will be 0x0. - -`SN2' - The slave denies permission to transfer the file. This can mean - that the destination directory may not be accessed, or that no - requests are permitted. It implies that the file transfer will - never succeed. - -`SN4' - The slave is unable to create the necessary temporary file. This - implies that the file transfer might succeed later. - -`SN6' - This is only used by Taylor UUCP size negotiation. It means that - the slave considers the file too large to transfer at the moment, - but it may be possible to transfer it at some other time. - -`SN7' - This is only used by Taylor UUCP size negotiation. It means that - the slave considers the file too large to ever transfer. - - If the slave responds with `SY', a file transfer begins. When the -file transfer is complete, the slave sends a `C' command response. -Taylor UUCP generates this confirmation in `fprecfile_confirm' and -checks it in `fpsendfile_confirm'. - -`CY' - The file transfer was successful. - -`CN5' - The temporary file could not be moved into the final location. - This implies that the file transfer will never succeed. - - After the `C' command response has been received (in the `SY' case) -or immediately (in an `SN' case) the master will send another command. - - -File: uucp.info, Node: R Request, Next: X Request, Prev: S Request, Up: File Requests - -R Request -......... - - master: `R FROM TO USER -OPTIONS SIZE' - - The `R' and the `-' are literal characters. This is a request by -the master to receive a file from the slave. I do not know how SVR4 -UUCP implements file transfer restart in this case. Taylor UUCP -implements the `R' request in `freceive_file'. - -FROM - This is the name of the file on the slave which the master wishes - to receive. It must not be in the spool directory, and it may - not contain any wildcards. - -TO - This is the name of the file to create on the master. I do not - believe that it can be a directory. It may only be in the spool - directory if this file is being requested to support an execution - either on the master or on some system other than the slave. - -USER - The name of the user who requested the transfer. - -OPTIONS - A list of options to control the transfer. The following options - are defined (all options are single characters): - - `d' - The master should create directories as necessary (this is - the default). - - `f' - The master should not create directories if necessary, but - should fail the transfer instead. - - `m' - The master should send mail to USER when the transfer is - complete. - -SIZE - This only appears if Taylor UUCP size negotiation is being used. - It specifies the largest file which the master is prepared to - accept (when using SVR4 UUCP, this was specified in the `-U' - option during the initial handshake). - - The slave then responds with an `R' command response. Taylor UUCP -generates these responses in `fsend_file' and `ftransfer_fail'. - -`RY MODE' - The slave is willing to send the file, and file transfer begins. - MODE is the octal mode of the file on the slave. The master uses - this to set the mode of the file on the master's system just as - the slave does the MODE argument in the send command (*note S - Request::.). - -`RN2' - The slave is not willing to send the file, either because it is - not permitted or because the file does not exist. This implies - that the file request will never succeed. - -`RN6' - This is only used by Taylor UUCP size negotiation. It means that - the file is too large to send, either because of the size limit - specifies by the master or because the slave considers it too - large. The file transfer might succeed later, or it might not - (this will be cleared up in a later release of Taylor UUCP). - - If the slave responds with `RY', a file transfer begins. When the -file transfer is complete, the master sends a `C' command. The slave -pretty much ignores this, although it may log it. Taylor UUCP sends -this confirmation in `fprecfile_confirm' and checks it in -`fpsendfile_confirm'. - -`CY' - The file transfer was successful. - -`CN5' - The temporary file could not be moved into the final location. - - After the `C' command response has been sent (in the `RY' case) or -immediately (in an `RN' case) the master will send another command. - - -File: uucp.info, Node: X Request, Next: H Request, Prev: R Request, Up: File Requests - -X Request -......... - - master: `X FROM TO USER -OPTIONS' - - The `X' and the `-' are literal characters. This is a request by -the master to, in essence, execute `uucp' on the slave. The slave -should execute `uucp FROM TO'. Taylor UUCP generates the `X' request -in `fxcmd' and handles it in `fdo_xcmd'. - -FROM - This is the name of the file or files on the slave which the - master wishes to transfer. Any wildcards are expanded on the - slave. If the master is requesting that the files be transferred - to itself, the request would normally contain wildcard - characters, since otherwise an `R' command would suffice. The - master can also use this command to request that the slave - transfer files to a third system. - -TO - This is the name of the file or directory to which the files - should be transferred. This will normally use a UUCP name. For - example, if the master wishes to receive the files itself, it - would use `MASTER!PATH'. - -USER - The name of the user who requested the transfer. - -OPTIONS - A list of options to control the transfer. It is not clear - which, if any, options are supported by most UUCP packages. - Taylor UUCP ignores the options field. - - The slave then responds with an X command response. Taylor UUCP -sends this response in either `fxcmd_confirm' or `ftransfer_fail'. - -`XY' - The request was accepted, and the appropriate file transfer - commands have been queued up for later processing. - -`XN' - The request was denied. No particular reason is given. - - In either case, the master will then send another command. - - -File: uucp.info, Node: H Request, Prev: X Request, Up: File Requests - -H Request -......... - - master: `H' - - This is used by the master to hang up the connection. The slave -will respond with an `H' command response. Taylor UUCP processes this -request in `fhangup_request', `fhangup_reply', and `fgetcmd'. - -`HY' - The slave agrees to hang up the connection. In this case the - master sends another `HY' command. In some UUCP packages, - including Taylor UUCP, the slave will then send a third `HY' - command. At this point the protocol is shut down, and the final - handshake is begun. - -`HN' - The slave does not agree to hang up. In this case the master and - the slave exchange roles. The next command will be sent by the - former slave, which is the new master. The roles may be reversed - several times during a single connection. - -
\ No newline at end of file diff --git a/gnu/libexec/uucp/uucp.info-4 b/gnu/libexec/uucp/uucp.info-4 deleted file mode 100644 index 11b5023847c..00000000000 --- a/gnu/libexec/uucp/uucp.info-4 +++ /dev/null @@ -1,946 +0,0 @@ -Info file uucp.info, produced by Makeinfo, -*- Text -*- from input -file uucp.texi. - - This file documents Taylor UUCP, version 1.03. - - Copyright (C) 1992 Free Software Foundation, Inc. - - Permission is granted to make and distribute verbatim copies of this -manual provided the copyright notice and this permission notice are -preserved on all copies. - - Permission is granted to copy and distribute modified versions of -this manual under the conditions for verbatim copying, provided also -that the section entitled "Copying" are included exactly as in the -original, and provided that the entire resulting derived work is -distributed under the terms of a permission notice identical to this -one. - - Permission is granted to copy and distribute translations of this -manual into another language, under the above conditions for modified -versions, except that the section entitled "Copying" may be included -in a translation approved by the author instead of in the original -English. - - -File: uucp.info, Node: Final Handshake, Prev: File Requests, Up: UUCP Protocol - -Final Handshake ---------------- - - After the protocol has been shut down, the final handshake is -performed. This handshake has no real purpose, and some UUCP packages -simply drop the connection rather than do it (in fact, some will drop -the connection immediately after both sides agree to hangup, without -even closing down the protocol). Taylor UUCP always sends the -appropriate final handshake string (in `fdo_call' or `faccept_call') -but ignores the handshake string from the other side unless it is in -`handshake' debugging mode. - -caller: `\020OOOOOO\000' -called: `\020OOOOOOO\000' - That is, the calling UUCP sends six letter O's and the called UUCP -replies with seven letter O's. Some UUCP packages always send six O's. - - -File: uucp.info, Node: g Protocol, Next: f Protocol, Prev: UUCP Protocol, Up: Protocols - -The UUCP `g' Protocol -===================== - - The `g' protocol is a packet based flow controlled error correcting -protocol that requires an eight bit clear connection. It is the -original UUCP protocol, and is supported by all UUCP implementations. -Many implementations of it are only able to support small window and -packet sizes, specifically a window size of 3 and a packet size of 64 -bytes, but the protocol itself can support up to a window size of 7 and -a packet size of 4096 bytes. Complaints about the inefficiency of the -`g' protocol generally refer to specific implementations, rather than -the correctly implemented protocol. - - The `g' protocol was originally designed for general packet drivers, -and thus contains some features that are not used by UUCP, including -an alternate data channel and the ability to renegotiate packet and -window sizes during the communication session. - - The `g' protocol is spoofed by many Telebit modems. When spoofing -is in effect, each Telebit modem uses the `g' protocol to communicate -with the attached computer, but the data between the modems is sent -using a Telebit proprietary error correcting protocol. This allows -for very high throughput over the Telebit connection, which, because -it is half-duplex, would not normally be able to handle the `g' -protocol very well at all. - - This discussion of the `g' protocol explains how it works, but does -not discuss useful error handling techniques. Some discussion of this -can be found in Jamie E. Hanrahan's paper (*note Documentation -references::.). A detailed examination of the source code would also -be profitable. - - The Taylor UUCP code to handle the `g' protocol is in the file -`protg.c'. There are a number of functions; the most important ones -are `fgstart', `fgsend_control', `fgsenddata', and `fgprocess_data'. - - All `g' protocol communication is done with packets. Each packet -begins with a six byte header. Control packets consist only of the -header. Data packets contain additional data. - - The header is as follows: - -`\020' - Every packet begins with a `^P'. - -K (1 <= K <= 9) - The K value is always 9 for a control packet. For a data packet, - the K value indicates how must data follows the six byte header. - The amount of data is 2 ** (K + 4), where ** indicates - exponentiation. Thus a K value of 1 means 32 data bytes and a K - value of 8 means 4096 data bytes. The K value for a data packet - must be between 1 and 8 inclusive. - -checksum low byte -checksum high byte - The checksum value is described below. - -control byte - The control packet indicates the type of packet, and is described - below. - -xor byte - This byte is the xor of K, the checksum low byte, the checksum - high byte and the control byte (i.e. the second, third, fourth - and fifth header bytes). It is used to ensure that the header - data is valid. - - The control byte in the header is composed of three bit fields, -referred to here as TT (two bits), XXX (three bits) and YYY (three -bits). The complete byte is TTXXXYYY, or (TT << 6) + (XXX << 3) + YYY. - - The TT field takes on the following values: - -0 - This is a control packet. In this case the K byte in the header - must be 9. The XXX field indicates the type of control packet; - the types are described below. - -1 - This is an alternate data channel packet. This is not used by - UUCP. - -2 - This is a data packet, and the entire contents of the attached - data field (whose length is given by the K byte in the header) are - valid. The XXX and YYY fields are described below. - -3 - This is a short data packet. Let the length of the data field - (as given by the K byte in the header) be `l'. Let the first - byte in the data field be `b1'. If `b1' is less than 128 (if the - most significant bit of `b1' is 0), then there are `l - b1' valid - bytes of data in the data field, beginning with the second byte. - If `b1 >= 128', let `b2' be the second byte in the data field. - Then there are `l - ((b1 & 0x7f) + (b2 << 7))' valid bytes of data - in the data field, beginning with the third byte. In all cases - `l' bytes of data are sent (and all data bytes participate in the - checksum calculation) but some of the trailing bytes may be - dropped by the receiver. The XXX and YYY fields are described - below. - - In a data packet (short or not) the XXX field gives the sequence -number of the packet. Thus sequence numbers can range from 0 to 7, -inclusive. The YYY field gives the sequence number of the last -correctly received packet. - - Each communication direction uses a window which indicates how many -unacknowledged packets may be transmitted before waiting for an -acknowledgement. The window may range from 1 to 7 packets, and may be -different in each direction. For example, if the window is 3 and the -last packet acknowledged was packet number 6, packet numbers 7, 0 and 1 -may be sent but the sender must wait for an acknowledgement before -sending packet number 2. This acknowledgement could come as the YYY -field of a data packet or as the YYY field of a `RJ' or `RR' control -packet (described below). - - Each packet must be transmitted in order (the sender may not skip -sequence numbers). Each packet must be acknowledged, and each packet -must be acknowledged in order. - - In a control packet, the XXX field takes on the following values: - -1 `CLOSE' - The connection should be closed immediately. This is typically - sent when one side has seen too many errors and wants to give up. - It is also sent when shutting down the protocol. If an - unexpected `CLOSE' packet is received, a `CLOSE' packet should be - sent in reply and the `g' protocol should halt, causing UUCP to - enter the final handshake. - -2 `RJ' or `NAK' - The last packet was not received correctly. The YYY field - contains the sequence number of the last correctly received - packet. - -3 `SRJ' - Selective reject. The YYY field contains the sequence number of a - packet that was not received correctly, and should be - retransmitted. This is not used by UUCP, and most - implementations will not recognize it. Taylor UUCP will - recognize it but not generate it. - -4 `RR' or `ACK' - Packet acknowledgement. The YYY field contains the sequence - number of the last correctly received packet. - -5 `INITC' - Third initialization packet. The YYY field contains the maximum - window size to use. - -6 `INITB' - Second initialization packet. The YYY field contains the packet - size to use. It requests a size of 2 ** (YYY + 5). Note that - this is not the same coding used for the K byte in the packet - header (it is 1 less). Some UUCP implementations can handle any - packet size up to that specified; some can only handled exactly - the size specified. Taylor UUCP will always accept any packet - size. - -7 `INITA' - First initialization packet. The YYY field contains the maximum - window size to use. - - To compute the checksum, call the control byte (the fifth byte in -the header) `c'. - - The checksum of a control packet is simply `0xaaaa - c'. - - The checksum of a data packet is `0xaaaa - (CHECK ^ c)' (`^' -denotes exclusive or, as in C), and `CHECK' is the result of the -following routine run on the contents of the data field (every byte in -the data field participates in the checksum, even for a short data -packet). Below is the routine used by Taylor UUCP; it is a slightly -modified version of a routine which John Gilmore patched from G.L. -Chesson's original paper. The `z' argument points to the data and the -`c' argument indicates how much data there is. - - int - igchecksum (z, c) - register const char *z; - register int c; - { - register unsigned int ichk1, ichk2; - - ichk1 = 0xffff; - ichk2 = 0; - - do - { - register unsigned int b; - - /* Rotate ichk1 left. */ - if ((ichk1 & 0x8000) == 0) - ichk1 <<= 1; - else - { - ichk1 <<= 1; - ++ichk1; - } - - /* Add the next character to ichk1. */ - b = *z++ & 0xff; - ichk1 += b; - - /* Add ichk1 xor the character position in the buffer - counting from the back to ichk2. */ - ichk2 += ichk1 ^ c; - - /* If the character was zero, or adding it to ichk1 - caused an overflow, xor ichk2 to ichk1. */ - if (b == 0 || (ichk1 & 0xffff) < b) - ichk1 ^= ichk2; - } - while (--c > 0); - - return ichk1 & 0xffff; - } - - When the `g' protocol is started, the calling UUCP sends an INITA -control packet with the window size it wishes the called UUCP to use. -The called UUCP responds with an INITA packet with the window size it -wishes the calling UUCP to use. Pairs of INITB and INITC packets are -then similarly exchanged. When these exchanges are completed, the -protocol is considered to have been started. The window size is sent -twice, with both the INITA and the INITC packets. - - When a UUCP package transmits a command, it sends one or more data -packets. All the data packets will normally be complete, although some -UUCP packages may send the last one as a short packet. The command -string is sent with a trailing null byte, to let the receiving package -know when the command is finished. Some UUCP packages require the last -byte of the last packet sent to be null, even if the command ends -earlier in the packet. Some packages may require all the trailing -bytes in the last packet to be null, but I have not confirmed this. - - When a UUCP package sends a file, it will send a sequence of data -packets. The end of the file is signalled by a short data packet -containing zero valid bytes (it will normally be preceeded by a short -data packet containing the last few bytes in the file). - - Note that the sequence numbers cover the entire communication -session, including both command and file data. - - When the protocol is shut down, each UUCP package sends a `CLOSE' -control packet. - - -File: uucp.info, Node: f Protocol, Next: t Protocol, Prev: g Protocol, Up: Protocols - -The UUCP `f' Protocol -===================== - - The `f' protocol is a seven bit protocol which checksums an entire -file at a time. It only uses the characters between \040 and \176 -(ASCII space and `~') inclusive as well as the carriage return -character. It can be very efficient for transferring text only data, -but it is very inefficient at transferring eight bit data (such as -compressed news). It is not flow controlled, and the checksum is -fairly insecure over large files, so using it over a serial connection -requires handshaking (`XON'/`XOFF' can be used) and error correcting -modems. Some people think it should not be used even under those -circumstances. - - I believe the `f' protocol originated in BSD versions of UUCP. It -was originally intended for transmission over X.25 PAD links. - - The Taylor UUCP code for the `f' protocol is in `protf.c'. - - The `f' protocol has no startup or finish protocol. However, both -sides typically sleep for a couple of seconds before starting up, -because they switch the terminal into `XON'/`XOFF' mode and want to -allow the changes to settle before beginning transmission. - - When a UUCP package transmits a command, it simply sends a string -terminated by a carriage return. - - When a UUCP package transmits a file, each byte b of the file is -translated according to the following table: - - 0 <= b <= 037: 0172, b + 0100 (0100 to 0137) - 040 <= b <= 0171: b ( 040 to 0171) - 0172 <= b <= 0177: 0173, b - 0100 ( 072 to 077) - 0200 <= b <= 0237: 0174, b - 0100 (0100 to 0137) - 0240 <= b <= 0371: 0175, b - 0200 ( 040 to 0171) - 0372 <= b <= 0377: 0176, b - 0300 ( 072 to 077) - - That is, a byte between \040 and \171 inclusive is transmitted as -is, and all other bytes are prefixed and modified as shown. - - When all the file data is sent, a seven byte sequence is sent: two -bytes of \176 followed by four ASCII bytes of the checksum as printed -in base 16 followed by a carriage return. For example, if the -checksum was 0x1234, this would be sent: "\176\1761234\r". - - The checksum is initialized to 0xffff. For each byte that is sent -it is modified as follows (where `b' is the byte before it has been -transformed as described above): - - /* Rotate the checksum left. */ - if ((ichk & 0x8000) == 0) - ichk <<= 1; - else - { - ichk <<= 1; - ++ichk; - } - - /* Add the next byte into the checksum. */ - ichk += b; - - When the receiving UUCP sees the checksum, it compares it against -its own calculated checksum and replies with a single character -followed by a carriage return. - -`G' - The file was received correctly. - -`R' - The checksum did not match, and the file should be resent from the - beginning. - -`Q' - The checksum did not match, but too many retries have occurred - and the communication session should be abandoned. - - The sending UUCP checks the returned character and acts accordingly. - - -File: uucp.info, Node: t Protocol, Next: e Protocol, Prev: f Protocol, Up: Protocols - -The UUCP `t' Protocol -===================== - - The `t' protocol is intended for TCP links. It does no error -checking or flow control, and requires an eight bit clear channel. - - I believe the `t' protocol originated in BSD versions of UUCP. - - The Taylor UUCP code for the `t' protocol is in `prott.c'. - - When a UUCP package transmits a command, it first gets the length -of the command string, C. It then sends ((C / 512) + 1) * 512 bytes -(the smallest multiple of 512 which can hold C bytes plus a null byte) -consisting of the command string itself followed by trailing null -bytes. - - When a UUCP package sends a file, it sends it in blocks. Each block -contains at most 1024 bytes of data. Each block consists of four bytes -containing the amount of data in binary (most significant byte first, -the same format as used by the Unix function `htonl') followed by that -amount of data. The end of the file is signalled by a block -containing zero bytes of data. - - -File: uucp.info, Node: e Protocol, Next: x Protocol, Prev: t Protocol, Up: Protocols - -The UUCP `e' Protocol -===================== - - The `e' protocol is similar to the `t' protocol. It does no flow -control or error checking and is intended for use over TCP. - - The `e' protocol originated in versions of BNU UUCP. - - The Taylor UUCP code for the `e' protocol is in `prote.c'. - - When a UUCP package transmits a command, it simply sends the -command as an ASCII string terminated by a null byte. - - When a UUCP package transmits a file, it sends the complete size of -the file as an ASCII decimal number. The ASCII string is padded out -to 20 bytes with null bytes (i.e., if the file is 1000 bytes long, it -sends `1000\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0'). It then sends the -entire file. - - -File: uucp.info, Node: x Protocol, Next: d Protocol, Prev: e Protocol, Up: Protocols - -The UUCP `x' Protocol -===================== - - I believe that the `x' protocol was intended for use over X.25 -virtual circuits. It relies on a write of zero bytes being read as -zero bytes without stopping communication. I have heard that it does -not work correctly. If someone would care to fill this in more, I -would be grateful. Taylor UUCP does not implement the `x' protocol. - - -File: uucp.info, Node: d Protocol, Next: Capital G Protocol, Prev: x Protocol, Up: Protocols - -The UUCP `d' Protocol -===================== - - This is apparently used for DataKit connections, and relies on a -write of zero bytes being read as zero bytes, much as the `x' protocol -does. I don't really know anything else about it. Taylor UUCP does -not implement the `d' protocol. - - -File: uucp.info, Node: Capital G Protocol, Next: Documentation References, Prev: d Protocol, Up: Protocols - -The UUCP `G' Protocol -===================== - - The `G' protocol is apparently simply the `g' protocol, except that -it is known to support all possible window and packet sizes. It was -introduced by SVR4 UUCP; the SVR4 implementation of the `g' protocol -is apparently fixed at a packet size of 64 and a window size of 7. -Taylor UUCP does not recognize the `G' protocol. It does support all -window and packet sizes for the `g' protocol. - - -File: uucp.info, Node: Documentation References, Prev: Capital G Protocol, Up: Protocols - -Documentation References -======================== - - I took a lot of the information from Jamie E. Hanrahan's paper in -the Fall 1990 DECUS Symposium, and from Managing UUCP and Usenet by Tim -O'Reilly and Grace Todino (with contributions by several other people). -The latter includes most of the former, and is published by O'Reilly & -Associates, Inc. - - Some information is originally due to a Usenet article by Chuck -Wegrzyn. The information on the `g' protocol comes partially from a -paper by G.L. Chesson of Bell Laboratories, partially from Jamie E. -Hanrahan's paper, and partially from source code by John Gilmore. The -information on the `f' protocol comes from the source code by Piet -Berteema. The information on the `t' protocol comes from the source -code by Rick Adams. The information on the `e' protocol comes from a -Usenet article by Matthias Urlichs. - - -File: uucp.info, Node: Hacking, Next: Acknowledgements, Prev: Protocols, Up: Top - -Hacking Taylor UUCP -******************* - - This chapter provides the briefest of guides to the Taylor UUCP -source code itself. - -* Menu: - -* System Dependence:: System Dependence -* Naming Conventions:: Naming Conventions -* Patches:: Patches - - -File: uucp.info, Node: System Dependence, Next: Naming Conventions, Prev: Hacking, Up: Hacking - -System Dependence -================= - - The code is carefully segregated into a system independent portion -and a system dependent portion. The system dependent code is in -`sys?.*' and `tcp.c'. Note that `sysh.*' is included as `sysdep.h'. -Currently the only system dependent files are for Unix, and the file -name for all of them ends in `.unx'. Hopefully the code will -eventually be ported to other systems. - - With the right configuration parameters, the system independent code -calls only ANSI C functions. Some of the less common ANSI C functions -are also provided in `util.c'. The replacement function `strtol' in -`util.c' assumes that the characters `A' to `F' and `a' to `f' appear -in strictly sequential order. The function `igradecmp' in `config.c' -assumes that the upper and lower case letters appear in order. Both -assumptions are true for ASCII and EBCDIC, but neither is guaranteed -by ANSI C. The replacement function `memmove' in `util.c' assumes -that two arbitrary pointers may be safely compared. Disregarding -these caveats, I believe that the system independent portion of the -code is strictly conforming. - - That's not too exciting, since all the work is done in the system -dependent code. I think that this code can conform to POSIX 1003.1, -given the right compilation parameters. I'm a bit less certain about -this, though. - - The code is in use on a 16 bit segmented system with no function -prototypes, so I'm certain that all casts to long and pointers are done -when necessary. - - The code uses alloca extensively. It comes with a simple -replacement, in `alloca.c' (otherwise I would lost ANSI C conformance, -after all). Using a real `alloca' function will be considerably more -efficient. It will also cause significant stack usage, which may be a -problem on systems without virtual memory. - - -File: uucp.info, Node: Naming Conventions, Next: Patches, Prev: System Dependence, Up: Hacking - -Naming Conventions -================== - - I use a modified Hungarian naming convention for my variables and -functions. As with all naming conventions, the code is rather opaque -if you are not familiar with it, but becomes clear and easy to use with -time. - - The first character indicates the type of the variable (or function -return value). Sometimes additional characters are used. I use the -following type prefixes: - -`a' - array; the next character is the type of an element - -`b' - byte or character - -`c' - count of something - -`e' - stdio FILE * - -`f' - boolean - -`i' - generic integer - -`l' - double - -`o' - file descriptor (as returned by open, creat, etc.) - -`p' - generic pointer - -`q' - pointer to structure - -`s' - structure - -`u' - void (function return values only) - -`z' - character string - - A generic pointer ('p') is sometimes a `void *', sometimes a -function pointer in which case the prefix is pf, and sometimes a -pointer to another type, in which case the next character is the type -to which it points (pf is overloaded). - - An array of strings (`char *[]') would be named `az' (array of -string). If this array were passed to a function, the function -parameter would be named `paz' (pointer to array of string). - - Note that the variable name prefixes do not necessarily indicate the -type of the variable. For example, a variable prefixed with i may be -int, long or short. Similarly, a variable prefixed with b may be a -char or an int; for example, the return value of getchar would be -caught in an int variable prefixed with b. - - For a non-local variable (extern or file static), the first -character after the type prefix is capitalized. - - Most static variables and functions use another letter after the -type prefix to indicate which module they come from. This is to help -distinguish different names in the debugger. For example, all static -functions in `protg.c', the `g' protocol source code, use a module -prefix of `g'. This isn't too useful, as a number of modules use a -module prefix of `s'. - - -File: uucp.info, Node: Patches, Prev: Naming Conventions, Up: Hacking - -Patches -======= - - I am always grateful for any patches sent in. Much of the -flexibility and portability of the code is due to other people. -Please do not hesitate to send me any changes you have found necessary -or useful. - - I rarely apply the patches directly. Instead I work my way through -them and apply each one separately. This ensures that the naming -remains consistent and that I understand all the code. - - -File: uucp.info, Node: Acknowledgements, Next: Index (concepts), Prev: Hacking, Up: Top - -Acknowledgements -**************** - - This is a list of people who gave help or suggestions while I was -working on the Taylor UUCP project. Appearance on this list does not -constitute endorsement of the program, particularly since some of the -comments were criticisms. I've probably left some people off, and I -apologize for any oversight; it does not mean your contribution was -unappreciated. - - First of all, I would like to thank the people at Infinity -Development Systems (formerly AIRS, which lives on in the domain name, -at least for now) for permitting me to use their computers and `uunet' -access. I would also like to thank Richard Stallman -`<rms@gnu.ai.mit.edu>' for founding the Free Software Foundation and -John Gilmore `<gnu@cygnus.com>' for writing the initial version of -gnuucp which was a direct inspiration for this somewhat larger -project. Chip Salzenberg `<chip@tct.com>' contributed many early -patches. Franc,ois Pinard `<pinard@iro.umontreal.ca>' tirelessly -tested the code and suggested many improvements. He also put together -the initial version of this document. Finally, Verbus M. Counts -`<verbus@westmark.com>' and Centel Federal Systems, Inc. deserve -special thanks, since they actually paid me money to port this code to -System III. - - In alphabetical order: - - "Earle F. Ake - SAIC" `<ake@Dayton.SAIC.COM>' - `mra@searchtech.com' (Michael Almond) - `cambler@zeus.calpoly.edu' (Christopher J. Ambler) - Brian W. Antoine `<briana@tau-ceti.isc-br.com>' - `jantypas@soft21.s21.com' (John Antypas) - `nba@sysware.DK' (Niels Baggesen) - `uunet!hotmomma!sdb' (Scott Ballantyne) - `magus!dolphin!zack' (Zacharias Beckman) - `mike@mbsun.ann-arbor.mi.us' (Mike Bernson) - `bob@usixth.sublink.org' (Roberto Biancardi) - Marc Boucher `<marc@CAM.ORG>' - `dean@coplex.com' (Dean Brooks) - `dave@dlb.com' (Dave Buck) - `gordon@sneaky.lonestar.org' (Gordon Burditt) - `mib@gnu.ai.mit.edu' (Michael I Bushnell) - Brian Campbell `<brianc@quantum.on.ca>' - `verbus@westmark.westmark.com' (Verbus M. Counts) - `cbmvax!snark.thyrsus.com!cowan' (John Cowan) - `denny@dakota.alisa.com' (Bob Denny) - `dje@ersys.edmonton.ab.ca' (Doug Evans) - `fenner@jazz.psu.edu' (Bill Fenner) - "David J. Fiander" `<golem!david@news.lsuc.on.ca>' - Thomas Fischer `<batman@olorin.dark.sub.org>' - `erik@eab.retix.com' (Erik Forsberg) - Lele Gaifax `<piggy@idea.sublink.org>' - `Peter.Galbavy@micromuse.co.uk' - `hunter@phoenix.pub.uu.oz.au' (James Gardiner [hunter]) - Terry Gardner `<cphpcom!tjg01>' - `jimmy@tokyo07.info.com' (Jim Gottlieb) - `ryan@cs.umb.edu' (Daniel R. Guilderson) - `greg@gagme.chi.il.us' (Gregory Gulik) - Michael Haberler `<mah@parrot.prv.univie.ac.at>' - `guy@auspex.auspex.com' (Guy Harris) - Petri Helenius `<pete@fidata.fi>' - Peter Honeyman `<honey@citi.umich.edu>' - `bei@dogface.austin.tx.us' (Bob Izenberg) - `harvee!esj' (Eric S Johansson) - `chris@cj_net.in-berlin.de' (Christof Junge) - `tron@Veritas.COM' (Ronald S. Karr) - `kent@sparky.IMD.Sterling.COM' (Kent Landfield) - `lebaron@inrs-telecom.uquebec.ca' (Gregory LeBaron) - `karl@sugar.NeoSoft.Com' (Karl Lehenbauer) - `libove@libove.det.dec.com' (Jay Vassos-Libove) - `bruce%blilly@Broadcast.Sony.COM' (Bruce Lilly) - Ted Lindgreen `<tlindgreen@encore.nl>' - "Arne Ludwig" `<arne@rrzbu.hanse.de>' - Matthew Lyle `<matt@mips.mitek.com>' - `djm@eng.umd.edu' (David J. MacKenzie) - John R MacMillan `<chance!john@sq.sq.com>' - `mem@mv.MV.COM' (Mark E. Mallett) - `martelli@cadlab.sublink.org' (Alex Martelli) - Yanek Martinson `<yanek@mthvax.cs.miami.edu>' - `les@chinet.chi.il.us' (Leslie Mikesell) - `mmitchel@digi.lonestar.org' (Mitch Mitchell) - `rmohr@infoac.rmi.de' (Rupert Mohr) - `service@infohh.rmi.de' (Dirk Musstopf) - `lyndon@cs.athabascau.ca' (Lyndon Nerenberg) - `nolan@helios.unl.edu' (Michael Nolan) - david nugent `<david@csource.oz.au>' - `abekas!dragoman!mikep@decwrl.dec.com' (Mike Park) - "Mark Pizzolato 415-369-9366" `<mark@infocomm.com>' - `dplatt@ntg.com' (Dave Platt) - `eldorado@tharr.UUCP' (Mark Powell) - `pozar@kumr.lns.com' (Tim Pozar) - `putsch@uicc.com' (Jeff Putsch) - Jarmo Raiha `<jarmo@ksvltd.FI>' - `mcr@Sandelman.OCUnix.On.Ca' (Michael Richardson) - `ross@sun490.fdu.edu' (Jeff Ross) - Aleksey P. Rudnev `<alex@kiae.su>' - `wolfgang@wsrcc.com' (Wolfgang S. Rupprecht) - `tbr@tfic.bc.ca' (Tom Rushworth) - `rsalz@bbn.com' (Rich Salz) - `sojurn!mike@hobbes.cert.sei.cmu.edu' (Mike Sangrey) - `swiers@plains.NoDak.edu' - `s4mjs!mjs@nirvo.nirvonics.com' (M. J. Shannon Jr.) - `peter@ficc.ferranti.com' (Peter da Silva) - `frumious!pat' (Patrick Smith) - `roscom!monty@bu.edu' (Monty Solomon) - `chs@antic.apu.fi' (Hannu Strang) - `ralf@reswi.ruhr.de' (Ralf E. Stranzenbach) - Oleg Tabarovsky `<olg@olghome.pccentre.msk.su>' - John Theus `<john@theus.rain.com>' - `rmtodd@servalan.servalan.com' (Richard Todd) - Len Tower `<tower-prep@ai.mit.edu>' - `mju@mudos.ann-arbor.mi.us' (Marc Unangst) - `jv@mh.nl' (Johan Vromans) - `rna-nl!gerben@relay.nluug.nl' (Drs. Gerben C. Th. Wierda) - `frnkmth!twwells.com!bill' (T. William Wells) - `mauxci!eci386!woods@apple.com' (Greg A. Woods) - `jon@console.ais.org' (Jon Zeeff) - Eric Ziegast `<uunet!ziegast>' - - -File: uucp.info, Node: Index (concepts), Next: Index (configuration file), Prev: Acknowledgements, Up: Top - -Concept Index -************* - -* Menu: - -* /usr/spool/uucp: Miscellaneous (config). -* /usr/spool/uucppublic: Miscellaneous (config). -* UUCP protocol: UUCP Protocol. -* UUCP system name: Miscellaneous (config). -* anonymous UUCP: config File Examples. -* call configuration file: Configuration File Names. -* call in login name: Configuration File Names. -* call in password: Configuration File Names. -* call out file: Configuration File Names. -* call out login name: Configuration File Names. -* call out password: Configuration File Names. -* changing spool directory: config File Examples. -* chat scripts: Chat Scripts. -* config file: config File. -* config file examples: config File Examples. -* configuration file (call): Configuration File Names. -* configuration file (config): config File. -* configuration file (dial): dial File. -* configuration file (dialcode): Configuration File Names. -* configuration file (passwd): Configuration File Names. -* configuration file (port): port File. -* configuration file (sys): sys File. -* debugging file: Log File Names. -* dial file: dial File. -* dialcode configuration file: Configuration File Names. -* dialcode file: Configuration File Names. -* dialer configuration file: dial File. -* e protocol: e Protocol. -* f protocol: f Protocol. -* g protocol: g Protocol. -* gateway: Gateway Example. -* grades: Grades. -* handshake: UUCP Protocol. -* leaf site: Leaf Example. -* lock files: Lock Files. -* log file: Log File Names. -* main configuration file: config File. -* passwd configuration file: Configuration File Names. -* passwd file: Configuration File Names. -* port configuration file: port File. -* port file: port File. -* protocol (UUCP): UUCP Protocol. -* protocol (e): e Protocol. -* protocol (f): f Protocol. -* protocol (g): g Protocol. -* protocol (t): t Protocol. -* public directory: Miscellaneous (config). -* spool directory: Miscellaneous (config). -* spool directory (changing): config File Examples. -* statistics file: Log File Names. -* sys file: sys File. -* sys file example (gateway): Gateway Example. -* sys file example (leaf): Leaf Example. -* system configuration file: sys File. -* system name: Miscellaneous (config). -* t protocol: t Protocol. -* time strings: Time Strings. -* unknown systems: Miscellaneous (config). -* uucppublic: Miscellaneous (config). - - -File: uucp.info, Node: Index (configuration file), Prev: Index (concepts), Up: Top - -Index to New Configuration File -******************************* - -* Menu: - -* abort: dial File. -* abort-chat: dial File. -* abort-chat-fail: dial File. -* abort-chat-program: dial File. -* abort-chat-seven-bit: dial File. -* abort-chat-timeout: dial File. -* address: Placing the Call. -* alias: Naming the System. -* alternate: Naming the System. -* baud in port file: port File. -* baud in sys file: Placing the Call. -* baud-range: port File. -* bnu-files: Miscellaneous (config). -* call-local-size: File Transfer Control. -* call-login: Logging In. -* call-password: Logging In. -* call-remote-size: File Transfer Control. -* call-request: File Transfer Control. -* call-timegrade: When to Call. -* call-transfer: File Transfer Control. -* callback: Accepting a Call. -* called-chat: Accepting a Call. -* called-chat-fail: Accepting a Call. -* called-chat-program: Accepting a Call. -* called-chat-seven-bit: Accepting a Call. -* called-chat-timeout: Accepting a Call. -* called-local-size: File Transfer Control. -* called-login: Accepting a Call. -* called-remote-size: File Transfer Control. -* called-request: File Transfer Control. -* called-transfer: File Transfer Control. -* callfile: Configuration File Names. -* carrier in dial file: dial File. -* carrier in port file: port File. -* carrier-wait: dial File. -* chat: Chat Scripts. -* chat in dial file: dial File. -* chat in sys file: Logging In. -* chat-fail: Chat Scripts. -* chat-fail in dial file: dial File. -* chat-fail in sys file: Logging In. -* chat-program in dial file: dial File. -* chat-program in sys file: Logging In. -* chat-program in sys file: Chat Scripts. -* chat-seven-bit: Chat Scripts. -* chat-seven-bit in dial file: dial File. -* chat-seven-bit in sys file: Logging In. -* chat-timeout: Chat Scripts. -* chat-timeout in dial file: dial File. -* chat-timeout in sys file: Logging In. -* command-path: Miscellaneous (sys). -* commands: Miscellaneous (sys). -* complete: dial File. -* complete-chat: dial File. -* complete-chat-fail: dial File. -* complete-chat-program: dial File. -* complete-chat-seven-bit: dial File. -* complete-chat-timeout: dial File. -* debug in config file: Debugging Levels. -* debug in sys file: Miscellaneous (sys). -* debugfile: Log File Names. -* default-alternates: Naming the System. -* device: port File. -* dial-device: port File. -* dialcodefile: Configuration File Names. -* dialer in dial file: dial File. -* dialer in port file: port File. -* dialer-sequence: port File. -* dialfile: Configuration File Names. -* dialtone: dial File. -* dtr-toggle: dial File. -* free-space: Miscellaneous (sys). -* hostname: Miscellaneous (config). -* local-receive: File Transfer Control. -* local-send: File Transfer Control. -* lockname: port File. -* logfile: Log File Names. -* max-remote-debug: Miscellaneous (sys). -* max-uuxqts: Miscellaneous (config). -* myname: Naming the System. -* nodename: Miscellaneous (config). -* passwdfile: Configuration File Names. -* pause: dial File. -* phone: Placing the Call. -* port in port file: port File. -* port in sys file: Placing the Call. -* portfile: Configuration File Names. -* protocol in port file: port File. -* protocol in sys file: Protocol Selection. -* protocol-parameter in dial file: dial File. -* protocol-parameter in port file: port File. -* protocol-parameter in sys file: Protocol Selection. -* pubdir in config file: Miscellaneous (config). -* pubdir in sys file: Miscellaneous (sys). -* reliable in dial file: dial File. -* reliable in port file: port File. -* remote-receive: File Transfer Control. -* remote-send: File Transfer Control. -* request: File Transfer Control. -* sequence: Miscellaneous (sys). -* service: port File. -* seven-bit in dial file: dial File. -* seven-bit in port file: port File. -* speed in port file: port File. -* speed in sys file: Placing the Call. -* speed-range: port File. -* spool: Miscellaneous (config). -* statfile: Log File Names. -* sysfile: Configuration File Names. -* system: Naming the System. -* time: When to Call. -* timegrade: When to Call. -* timetable: Miscellaneous (sys). -* transfer: File Transfer Control. -* type: port File. -* unknown: Miscellaneous (config). -* uuname: Miscellaneous (config). -* v2-files: Miscellaneous (config). - - diff --git a/gnu/libexec/uucp/uucp.texi b/gnu/libexec/uucp/uucp.texi deleted file mode 100644 index 18155a02de2..00000000000 --- a/gnu/libexec/uucp/uucp.texi +++ /dev/null @@ -1,4495 +0,0 @@ -\input texinfo @c -*-texinfo-*- -@c %**start of header -@setfilename uucp.info -@settitle Taylor UUCP -@setchapternewpage odd -@c %**end of header -@setchapternewpage odd - -@ignore -----------------------------------------------------------------------> -Franc,ois Pinard says: - -Hi, Ian! This is the promised merging of the current documents from -Taylor UUCP 1.01, plus the patches to documentation you sent to me, into -a taylor.texi file. Many things remain to do, among which: - -- merging in the Taylor UUCP program man pages. -- integrating the three documents describing the protocol. -- gleaning miscellaneous information from my archives. -----------------------------------------------------------------------< -@end ignore - -@ifinfo -This file documents Taylor UUCP, version 1.03. - -Copyright @copyright{} 1992 Free Software Foundation, Inc. - -Permission is granted to make and distribute verbatim copies of this -manual provided the copyright notice and this permission notice are -preserved on all copies. - -@ignore -Permission is granted to process this file through TeX and print the -results, provided the printed document carries a copying permission -notice identical to this one except for the removal of this paragraph -(this paragraph not being relevant to the printed manual). - -@end ignore -Permission is granted to copy and distribute modified versions of this -manual under the conditions for verbatim copying, provided also that the -section entitled ``Copying'' are included exactly as in the original, and -provided that the entire resulting derived work is distributed under the -terms of a permission notice identical to this one. - -Permission is granted to copy and distribute translations of this manual -into another language, under the above conditions for modified versions, -except that the section entitled ``Copying'' may be included in a -translation approved by the author instead of in the original English. -@end ifinfo - -@titlepage -@title Taylor UUCP -@subtitle Version 1.03 -@author Ian Lance Taylor @file{<ian@@airs.com>} - -@page -@vskip 0pt plus 1filll -Copyright @copyright{} 1992 Free Software Foundation, Inc. - -Published by Ian Lance Taylor @file{<ian@@airs.com>}. - -Permission is granted to make and distribute verbatim copies of this -manual provided the copyright notice and this permission notice are -preserved on all copies. - -Permission is granted to copy and distribute modified versions of this -manual under the conditions for verbatim copying, provided also that the -section entitled ``Copying'' are included exactly as in the original, and -provided that the entire resulting derived work is distributed under the -terms of a permission notice identical to this one. - -Permission is granted to copy and distribute translations of this manual -into another language, under the above conditions for modified versions, -except that the section entitled ``Copying'' may be included in a -translation approved by the author instead of in the original English. -@end titlepage - -@node Top, Copying, (dir), (dir) -@top Taylor UUCP 1.03 - -This is the documentation for the Taylor UUCP package, version 1.03. -The programs were written by Ian Lance Taylor. The author can be -reached at @file{<ian@@airs.com>}, or, equivalently, -@file{<uunet!airs!ian>}, or @cite{c/o Infinity Development, P.O. Box -520, Waltham MA, 02254}. - -There is a mailing list for discussion of the package. To join the -list, send a message to @file{<taylor-uucp-request@@gnu.ai.mit.edu>}. -Make sure you include the address you want to receive messages at; do -not rely on the @code{From:} header. To send a message to the list, -send it to @file{<taylor-uucp@@gnu.ai.mit.edu>}. - -@menu -* Copying:: Taylor UUCP copying conditions -* Introduction:: Introduction to Taylor UUCP -* Overall Installation:: Taylor UUCP installation -* Configuration Files:: Taylor UUCP configuration files -* Protocols:: UUCP protocol internals -* Hacking:: Hacking Taylor UUCP -* Acknowledgements:: Acknowledgements - -* Index (concepts):: Concept index -* Index (configuration file):: Index to new configuration files - - --- The Detailed Node Listing --- - -Taylor UUCP Overall Installation - -* Configuration:: Configuring Taylor UUCP -* Compilation:: Compiling Taylor UUCP -* Testing:: Testing Taylor UUCP -* Installation:: Installing Taylor UUCP -* Usage:: Using Taylor UUCP -* TCP:: TCP together with Taylor UUCP - -Taylor UUCP Configuration Files - -* Configuration File Format:: Configuration file format -* Configuration Examples:: Examples of configuration files -* Time Strings:: How to write time strings -* Chat Scripts:: How to write chat scripts -* config File:: The main configuration file -* sys File:: The system configuration file -* port File:: The port configuration files -* dial File:: The dialer configuration files -* Security:: Security issues - -Examples of Configuration Files - -* config File Examples:: Examples of the main configuration file -* Leaf Example:: Call a single remote site -* Gateway Example:: The gateway for several local systems - -The Main Configuration File - -* Miscellaneous (config):: Miscellaneous config file commands -* Configuration File Names:: Using different configuration files -* Log File Names:: Using different log files -* Debugging Levels:: Debugging levels - -The System Configuration File - -* Defaults and Alternates:: Using defaults and alternates -* Naming the System:: Naming the system -* Calling Out:: Calling out -* Accepting a Call:: Accepting a call -* Protocol Selection:: Protocol selection -* File Transfer Control:: File transfer control -* Miscellaneous (sys):: Miscellaneous sys file commands -* Default sys File Values:: Default values - -Calling Out - -* When to Call:: When to call -* Placing the Call:: Placing the call -* Logging In:: Logging in - -UUCP protocol internals - -* Grades:: UUCP grades -* Lock Files:: UUCP lock file format -* UUCP Protocol:: The common UUCP protocol -* g Protocol:: The UUCP @samp{g} protocol -* f Protocol:: The UUCP @samp{f} protocol -* t Protocol:: The UUCP @samp{t} protocol -* e Protocol:: The UUCP @samp{e} protocol -* x Protocol:: The UUCP @samp{x} protocol -* d Protocol:: The UUCP @samp{d} protocol -* Capital G Protocol:: The UUCP @samp{G} protocol -* Documentation References:: Documentation references - -The Common UUCP Protocol - -* Initial Handshake:: Initial handshake -* File Requests:: File requests -* Final Handshake:: Final handshake - -File Requests - -* S Request:: S request -* R Request:: R request -* X Request:: X request -* H Request:: H request - -Hacking Taylor UUCP - -* System Dependence:: System Dependence -* Naming Conventions:: Naming Conventions -* Patches:: Patches -@end menu - -@node Copying, Introduction, Top, Top -@unnumbered Taylor UUCP Copying Conditions - -This package is covered by the GNU Public License. See the file -@file{COPYING} for details. If you would like to do something with this -package that you feel is reasonable but you feel is prohibited by the -license, contact me to see if we can work it out. - -Here is some propaganda from the Free Software Foundation. If you find -this stuff offensive or annoying, remember that you probably did not -spend any money to get this code. I did not write this code to make -life easier for developers of UUCP packages, I wrote it to help end -users, and I believe that these are the most appropriate conditions for -distribution. - -All the programs, scripts and documents relating to Taylor UUCP are -@dfn{free}; this means that everyone is free to use them and free to -redistribute them on a free basis. The Taylor UUCP-related programs are -not in the public domain; they are copyrighted and there are -restrictions on their distribution, but these restrictions are designed -to permit everything that a good cooperating citizen would want to do. -What is not allowed is to try to prevent others from further sharing any -version of these programs that they might get from you. - -Specifically, we want to make sure that you have the right to give away -copies of the programs that relate to Taylor UUCP, that you receive -source code or else can get it if you want it, that you can change these -programs or use pieces of them in new free programs, and that you know -you can do these things. - -To make sure that everyone has such rights, we have to forbid you to -deprive anyone else of these rights. For example, if you distribute -copies of the Taylor UUCP related programs, you must give the recipients -all the rights that you have. You must make sure that they, too, -receive or can get the source code. And you must tell them their -rights. - -Also, for our own protection, we must make certain that everyone finds -out that there is no warranty for the programs that relate to Taylor -UUCP. If these programs are modified by someone else and passed on, we -want their recipients to know that what they have is not what we -distributed, so that any problems introduced by others will not reflect -on our reputation. - -The precise conditions of the licenses for the programs currently being -distributed that relate to Taylor UUCP are found in the General Public -Licenses that accompany them. - -@node Introduction, Overall Installation, Copying, Top -@chapter Introduction to Taylor UUCP - -General introductions to UUCP are available, and perhaps one day I will -write one. In the meantime, here is a very brief one that concentrates -on the programs provided by Taylor UUCP. - -Taylor UUCP is a complete UUCP package. It is covered by the GNU Public -License, which means that the source code is always available. It is -composed of several programs, the names of which were established by -earlier UUCP packages. - -@table @code - -@item uucp - -The @code{uucp} program is used to copy file between systems. It is -similar to the standard Unix @code{cp} program, except that you can -refer to a file on a remote system by using @samp{system!} before the -file name. For example, to copy the file @file{notes.txt} to the system -@samp{airs}, you would say @samp{uucp notes.txt airs!~/notes.txt}. In -this example @samp{~} is used to name the UUCP public directory on -@samp{airs}. - -@item uux - -The @code{uux} program is used to request a program to be executed on a -remote system. This is how mail and news are transferred over UUCP. As -with @code{uucp}, programs and files on remote systems may be named by -using @samp{system!}. For example, to run the @code{rnews} program on -@samp{airs} passing it standard input, you would say @samp{uux - -airs!rnews}. The @samp{-} means to read standard input and set things -up so that when @code{rnews} runs on @samp{airs} it will receive the -same standard input. - -@end table - -Neither @code{uucp} nor @code{uux} actually do any work immediately. -Instead, they queue up requests for later processing. They then start a -daemon process which processes the requests and calls up the appropriate -systems. Usually the daemon will also be started regularly to check if -there is any work to be done and to do it. The advantage of this system -is that it all happens automatically. You don't have to sit around -waiting for the files to be transferred. The disadvantage is that if -anything goes wrong it might be a while before anybody notices. - -@table @code - -@item uustat - -The @code{uustat} program does several things. By default it will -simply list all the jobs you have queued with @code{uucp} or @code{uux} -that have not yet been processed. You can use @code{uustat} to remove -any of your jobs from the queue. You can also it use it to show the -status of the UUCP system in various ways, such as showing the -connection status of all systems your system knows about. - -@item uuname - -The @code{uuname} program by default lists all the remote systems your -system knows about. You can also use it to get the name of your local -system. It is mostly useful for shell scripts. - -@item uulog - -The @code{uulog} program can be used to display entries in the UUCP log -file. It can select the entries for a particular system or a particular -user. You can use it to see what has happened to your queued jobs in -the past. - -@end table - -These five programs just described, @code{uucp}, @code{uux}, -@code{uustat}, @code{uuname}, and @code{uulog}, are the user programs -provided by Taylor UUCP. The first two add requests to the work queue, -the third examines the work queue, the fourth examines the configuration -files, and the last examines the log files. The real work is actually -done by two daemon processes, which are normally run automatically -rather than by a user. - -@table @code - -@item uucico - -The @code{uucico} daemon is the program which actually calls the remote -system and transfers files and requests. @code{uucico} is normally -started automatically by @code{uucp} and @code{uux}. Most systems will -also start it periodically to make sure that all work requests are -handled. @code{uucico} checks the queue to see what work needs to be -done, and then calls the appropriate systems. If the call fails, -perhaps because the phone line is busy, @code{uucico} leaves the -requests in the queue and goes on to the next system to call. It is -also possible to force @code{uucico} to call a remote system even if -there is no work to be done for it, so that it can pick up any work that -may be queued up remotely. - -@item uuxqt - -The @code{uuxqt} daemon processes execution requests made by the -@code{uux} program on remote systems. It also processes requests made -on the local system which require files from a remote system. It is -normally started by @code{uucico}. - -@end table - -Suppose you, on the system @samp{bantam}, want to copy a file to the -system @samp{airs}. You would run the @code{uucp} command locally, with -a command like @samp{uucp notes.txt airs!~/notes.txt}. This would queue -up a request on @samp{bantam} for @samp{airs}, and would then start the -@code{uucico} daemon. @code{uucico} would see that there was a request -for @samp{airs} and attempt to call it. When the call succeeded, -another copy of @code{uucico} would be started on @samp{airs}. The two -copies of @code{uucico} would tell each other what they had to do and -transfer the file from @samp{bantam} to @samp{airs}. When the file -transfer was complete the @code{uucico} on @samp{airs} would move it -into the UUCP public directory. - -UUCP is often used to transfer mail. This is normally done -automatically by mailer programs. When @samp{bantam} has a mail message -to send to @samp{ian} at @samp{airs}, it executes @samp{uux - airs!rmail -ian} and writes the mail message to the @code{uux} process as standard -input. The @code{uux} program, running on @samp{bantam}, will read the -standard input and store it and the @code{rmail} request on the work -queue for @code{airs}. @code{uux} will then start the @code{uucico} -daemon. The @code{uucico} daemon will call up @samp{airs}, just as in -the @code{uucp} example, and transfer the work request and the mail -message itself. The @code{uucico} daemon on @samp{airs} will put the -files on a local work queue. When the communication session is over, -the @code{uucico} daemon on @samp{airs} will start the @code{uuxqt} -daemon. @code{uuxqt} will see the request to run, and will run -@samp{rmail ian} with the mail message as standard input. The -@code{rmail} program, which is not part of the UUCP package, is then -responsible for either putting the message in the right mailbox on -@samp{airs} or forwarding the message on to another system. - -Taylor UUCP comes with two other programs that are useful when -installing and configuring UUCP. - -@table @code - -@item uuchk - -The @code{uuchk} program reads the UUCP configuration files and displays -a rather lengthy description of what it finds. This is very useful when -configuring UUCP to make certain that the UUCP package will do what you -expect it to do. - -@item tstuu - -The @code{tstuu} program is a test harness for the UUCP package, which -will help ensure that it has been configured and compiled correctly. It -does not test everything, however, and it only runs on Unix systems -which support Berkeley style pseudo-terminals. It can be useful when -initially installing Taylor UUCP. - -@end table - -@node Overall Installation, Configuration Files, Introduction, Top -@chapter Taylor UUCP Overall Installation - -These are the installation instructions for the Taylor UUCP package. - -@menu -* Configuration:: Configuring Taylor UUCP -* Compilation:: Compiling Taylor UUCP -* Testing:: Testing Taylor UUCP -* Installation:: Installing Taylor UUCP -* Usage:: Using Taylor UUCP -* TCP:: TCP together with Taylor UUCP -@end menu - -@node Configuration, Compilation, Overall Installation, Overall Installation -@section Configuring Taylor UUCP - -You will have to decide what types of configuration files you want to -use. This package supports a new sort of configuration file; -@xref{Configuration files}. It also supports V2 configuration files -(@file{L.sys}, @file{L-devices}, etc.) and BNU configuration files -(@file{Systems}, @file{Devices}, etc.). No documentation is provided -for V2 or BNU configuration files. All types of configuration files can -be used at once, if you are so inclined. Currently using just V2 -configuration files is not really possible, because there is no way to -specify a dialer (there are no built in dialers, and the program does -not know how to read @file{acucap} or @file{modemcap}); however, V2 -configuration files can be used with a new style dialer file -(@pxref{dial file}), or with a BNU @file{Dialers} file. - -Use of BNU configuration files has two known bugs. A blank line in the -middle of an entry in the @file{Permissions} file will not be ignored as -it should be. Dialer programs are not recognized directly. If you must -use a dialer program, rather than an entry in @file{Devices}, you must -use the @code{chat-program} command in a new style dialer file; see -@ref{dial file}. You will have to invoke the dialer program via a shell -script, since an exit code of 0 is required to recognize success. - -If you are installing a new system, or you want to use the new form of -configuration files, you must write the configuration files. - -You must also decide what sort of spool directory you want to use. If -you will only be using these programs, I recommend -@samp{SPOOLDIR_TAYLOR}; otherwise select the spool directory -corresponding to your existing UUCP package. The details of the spool -directory choices are described at somewhat tedious length in -@file{sys3.unx}. - -@node Compilation, Testing, Configuration, Overall Installation -@section Compiling Taylor UUCP - -@enumerate - -@item -Take a look at the top of @file{Makefile.in} and set the appropriate -values for your system. These control where the program is installed -and which user on the system owns them (normally they will be owned by a -special user @code{uucp} rather than a real person; they should probably -not be owned by @code{root}). - -@item -Run the shell script @code{configure}. This script was generated using -David MacKenzie's @code{autoconf} program. It takes a while to run. It -will generate a file @file{conf.h}, and copy @file{Makefile.in} to -@file{Makefile} with substitions (specifically, it will replace all -words between @kbd{@@} characters in @file{Makefile.in}). - -You can pass certain arguments to @code{configure} in the environment. -Because @code{configure} will compile and run little test programs to -see what is available on your system, you must tell it how to run your -compiler. It recognizes the following environment variables: - -@table @samp -@item CC -The C compiler. If this is not set, then if @code{configure} can find -@code{gcc} it will use @samp{gcc -O}, otherwise it will use @samp{cc}. -@item DEFS -Flags to pass the C compiler during configuration testing. If this is -not set, @code{configure} will use the empty string. -@item CFLAGS -Flags to pass to the C compiler when compiling the actual code. If this -is not set, @code{configure} will use @samp{-g}. -@item LDFLAGS -Flags to pass to the C compiler when only linking, not compiling. If -this is not set, @code{configure} will use the empty string. -@item LIBS -Libraries to pass to the C compiler. If this is not set, -@code{configure} will use the empty string. -@item INSTALL -The program to run to install UUCP in the binary directory. If -@code{configure} finds the BSD @code{install} program, it will set this -to @samp{install -c}; otherwise, it will use @samp{cp}. -@item INSTALLDATA -The program to run to install UUCP data files, such as the man pages and -the info pages. If @code{configure} finds the BSD @code{install} -program, it will set this to @samp{install -c -m 644}; otherwise, it -will use @samp{cp}. -@end table - -Suppose you want to set the environment variable @samp{CC} to -@samp{rcc}. If you are using @code{sh} or @code{bash}, invoke -@code{configure} as @samp{CC=rcc configure}. If you are using -@code{csh}, do @samp{setenv CC rcc; sh configure}. - -On some systems you will want to use @samp{LIBS=-lmalloc}. On some you -will want @samp{LIBS=-lsocket}. On Xenix derived systems do not use -@samp{LIBS=-lx} because this will bring in the wrong versions of certain -routines; if you want to use @samp{-lx} you must specify @samp{LIBS=-lc --lx}. - -If @code{configure} fails for some reason, or if you have a very wierd -system, you may have to configure the package by hand. To do this, copy -the file @file{conf.h-dist} to @file{conf.h} and edit it for your -system. Then copy @file{Makefile.in} to @file{Makefile}, find the words -within @kbd{@@} characters, and set them correctly for your system. - -@item -You should verify that @code{configure} worked correctly by checking -the files @file{conf.h} and @file{Makefile}. - -@item -This package uses the @code{alloca} function. The @code{configure} -script will try to figure out how to make it work on your system. If -@code{alloca} cannot be found, a simplistic substitute from -@file{alloca.c} will be used. If you provide your own @file{alloca.o} -file, it will be used instead; you might, for example, use the one from -the GNU emacs distribution. If none of this makes any sense to you, -don't worry; everything will probably work fine. - -@item -Edit @file{policy.h} for your local system. The comments should explain -the various choices. The default values are intended to be reasonable, -so you may not have to make any changes. - -@item -Type @samp{make} to compile everything. You may get warnings about -implicit function declarations; ignore these (if you think they can be -eliminated, and you really know what you are talking about, you may tell -me about them). You may also get warnings about @file{getopt.c} (this -is from the GNU library and I do not want to change it) and about a -variable not protected from @code{setjmp} in @file{sys2.c} (the data -flow ensures that this can never be a problem). The @file{tstuu.c} file -is not particularly portable; if you can't figure out how to compile it -you can safely ignore it, as it is only used for testing. If you have -any other problems there is probably a bug in the @code{configure} -script. - -@item -Please report any problems you have. That is the only way they will get -fixed for other people. Supply a patch if you can, or just ask for -help. - -@end enumerate - -@node Testing, Installation, Compilation, Overall Installation -@section Testing Taylor UUCP - -This package is in use at many sites, and has been running at -@file{airs.com} for several months. However, it will doubtless fail in -some situations. Do not rely on this code until you have proven to -yourself that it will work. - -You can use the @code{uuchk} program to test your configuration files. -It will read them and print out a verbose description. This is -particularly important if you are using V2 or BNU configuration files, -because there may be bugs in how they are read. This program should not -be made suid, because it will display passwords if it can read them. - -If your system supports BSD style pseudo-terminals, and you compiled the -code to support the new style of configuration files, you should be able -to use the @code{tstuu} program to test the @code{uucico} daemon. Just -type @samp{tstuu} with no arguments while logged in to the compilation -directory (since it runs @file{./uucp}, @file{./uux} and -@file{./uucico}) to run a lengthy series of tests (it takes over ten -minutes on a slow VAX). You will need a fair amount of space available -in @file{/usr/tmp}. You will probably want to put it in the background. -Do not use @kbd{^Z}, because the program traps on @code{SIGCHLD} and -winds up dying. It will create a directory @file{/usr/tmp/tstuu} and -fill it with configuration files, and create spool directories -@file{/usr/tmp/tstuu/spool1} and @file{/usr/tmp/tstuu/spool2}. - -The program will finish with an execute file @file{X.@var{something}} -and a data file @file{D.@var{something}} in @file{/usr/tmp/tstuu/spool1} -(or, more likely, in subdirectories, depending on the choice of -@code{SPOOLDIR} in @file{sysdep.h}). The log files -@file{/usr/tmp/tstuu/Log1} and @file{/usr/tmp/tstuu/Log2} (or, if you -have selected @code{HAVE_BNU_LOGGING}, -@file{/usr/tmp/tstuu/Log1/uucico/test2} and -@file{/usr/tmp/tstuu/Log2/uucico/test1}) should look fairly normal. You -can test @code{uuxqt} by typing @samp{./uuxqt -I -/usr/tmp/tstuu/Config1}. This should leave a command file -@file{C.@var{something}} and a data file @file{D.@var{something}} in -@file{/usr/tmp/tstuu/spool1} or in subdirectories. Again, there should -be no errors in the log file. - -Assuming you compiled the code with debugging enabled, the @samp{-x} -switch can be used to set debugging modes; see the @code{debug} command -for details (@pxref{Debugging Levels}). Use @samp{-x all} to turn on -all debugging and generate far more output than you will ever want to -see. The @code{uucico} daemons will put debugging output in -@file{/usr/tmp/tstuu/Debug1} and @file{/usr/tmp/tstuu/Debug2}. At this -point you're pretty much on your own. - -On some systems you can also use @code{tstuu} to test my @code{uucico} -against the system @code{uucico}, by using the @samp{-u} switch. For -this to work, change the definitions of @code{ZUUCICO_CMD} and -@code{UUCICO_EXECL} at the top of @file{tstuu.c} to something -appropriate for your system. The definitions in @file{tstuu.c} are what -I used for Ultrix 4.0, in which @file{/usr/lib/uucp/uucico} is -particularly obstinate about being run as a child; I was only able to -run it by creating a login name with no password whose shell was -@file{/usr/lib/uucp/uucico}. Calling login in this way will leave fake -entries in @file{wtmp} and @file{utmp}; if you compile @file{tstout.c} -(in the @file{contrib} directory) as an suid @code{root} program, -@code{tstuu} will run it to clear those entries out. On most systems, -such hackery should not be necessary, although on SCO I had to su to -@code{root} (@code{uucp} might also have worked) before I could run -@file{/usr/lib/uucp/uucico}. - -You can test @code{uucp} and @code{uux} (give them the @samp{-r} switch -to keep them from starting @code{uucico}) to make sure they create the -right sorts of files. Unfortunately if you don't know what the right -sorts of files are I'm not going to tell you here. - -If @code{tstuu} passes, or you can't run it for some reason or other, -move on to testing with some other system. Set up the configuration -files (@pxref{Configuration files}), or use an existing configuration. -Tell @code{uucico} to dial out to the system by using the @samp{-s} -system switch (e.g. @samp{uucico -s uunet}). The log file should tell -you what happens. - -If you compiled the code with debugging enabled, you can use debugging -mode to get a great deal of information about what sort of data is -flowing back and forth; the various possibilities are described under -the @code{debug} command (@pxref{Debugging Levels}). When initially -setting up a connection @samp{-x chat} is probably the most useful (e.g. -@samp{uucico -s uunet -x chat}); you may also want to use @samp{-x -handshake,incoming,outgoing}. You can use @samp{-x} multiple times on -one command line, or you can give it comma separated arguments as in the -last example. Use @samp{-x all} to turn on all possible debugging -information. The debugging information is written to a file, normally -@file{/usr/spool/uucp/Debug} although the default can be changed in -@file{policy.h} and the configuration file can override the name with -the @code{debugfile} command. The debugging file may contain passwords -and some file contents as they are transmitted over the line, so the -debugging file is only readable by the @code{uucp} user. - -You can use the @samp{-f} switch to force @code{uucico} to call out even -if the last call failed recently; using @samp{-S} when naming a system -has the same effect. Otherwise the status file (in the @file{.Status} -subdirectory of the main spool directory, normally -@file{/usr/spool/uucp}) will prevent too many attempts from occurring in -rapid succession. - -Again, let me know about any problems you have and how you got around -them. - -@node Installation, Usage, Testing, Overall Installation -@section Installing Taylor UUCP - -You can install by suing to @code{root} and typing @samp{make install}. -Or you can look at what make install does and do it by hand. It tries -to preserve your old programs, if any. You can retrieve them by typing -@samp{make uninstall}. - -@node Usage, TCP, Installation, Overall Installation -@section Using Taylor UUCP - -This package does not come with any fancy shell scripts or scheduling -programs. Maybe someday. If you have another package, you may well -be able to use the scheduling mechanisms it provides. - -Otherwise, the program can be used by making crontab entries. -Whenever you want to call all systems with outstanding work, use -@example -uucico -r1 -@end example -Whenever you want to call a specific system @samp{foo}, use -@example -uucico -s foo -@end example -If you want to make sure that a system foo gets retried if the -original call fails, create an empty work file for it. For example, -if using @code{SPOOLDIR_TAYLOR}, -@example -touch /usr/spool/uucp/foo/C./C.A0000 -@end example -If using @code{SPOOLDIR_BNU}, use -@example -touch /usr/spool/uucp/foo/C.fooA0000 -@end example - -I use the following crontab entries locally: - -@example -45 * * * * /bin/echo /usr/lib/uucp/uucico -r1 | /bin/su uucpa -40 4,10,15 * * * touch /usr/spool/uucp/uunet/C./C.A0000 -@end example - -Every hour, at 45 minutes past, this will check if there is any work to -be done. Also, at 4:40am, 10:40am and 3:40pm this will create an empty -work file for @file{uunet}, forcing the next check to call @file{uunet}. - -You will also want to periodically trim the log files, which by default -are @file{/usr/spool/uucp/Log} and @file{/usr/spool/uucp/Stats}. The -@code{savelog} program in the @file{contrib} directory may be of use. - -@node TCP, , Usage, Overall Installation -@section TCP together with Taylor UUCP - -If your system has a Berkeley style socket library, you can compile -the code to permit making connections over TCP. Specifying that a -system should be reached via TCP is easy, but nonobvious. - -If you are using the new style configuration files, see -@ref{Configuration files}. Basically, you can just add the line -@samp{port type tcp} to the entry in the system configuration file. By -default UUCP will get the port number by looking up @samp{uucp} in -@file{/etc/services}; if @samp{uucp} is not found, port 540 will be -used. You can set the port number to use with the command @samp{port -service @var{xxx}}, where @var{xxx} can be either a number or a name to -look up in @file{/etc/services}. You can specify the address of the -remote host with @samp{address @var{a.b.c}}; if you don't give an -address, the remote system name will be used. You should give an -explicit chat script for the system when you use TCP; the default chat -script begins with a carriage return, which will not work with some UUCP -TCP servers. - -If you are using V2 configuration files, add a line like this to -@file{L.sys}: - -@example -foo Any TCP uucp foo.domain chat-script -@end example - -This will make an entry for system foo, to be called at any time, over -TCP, using port number @samp{uucp} (as found in @file{/etc/services}; -this may be specified as a number), using remote host @file{foo.domain}, -with some chat script. - -If you are using BNU configuration files, add a line like this to -Systems: - -@example -foo Any TCP - foo.domain chat-script -@end example - -and a line like this to Devices: - -@example -TCP uucp - - -@end example - -You only need one line in Devices regardless of how many systems you -contact over TCP. This will make an entry for system foo, to be called -at any time, over TCP, using port number @samp{uucp} (as found in -@file{/etc/services}; this may be specified as a number), using remote -host @file{foo.domain}, with some chat script. - -The @code{uucico} daemon can also be run as a TCP server. This code -mostly works, but it's not perfect. I don't recommend investigating it -unless you are willing to tinker a bit. You will not be able to use the -default port number because @code{uucico} will not be running as -@code{root} and will therefore not be able to bind a reserved port. - -Basically, you must define a port, either using the port file -(@pxref{port file}) if you are using the new configuration method or -with an entry in Devices if you are using BNU; there is no way to define -a port using V2. If you are using BNU the port must be named -@samp{TCP}; a line as shown above will suffice. You can then start -@code{uucico} as @samp{uucico -p TCP} (after the @samp{-p}, name the -port; in BNU it must be @samp{TCP}). This will wait for incoming -connections, and fork off a child for each one. Each connection will be -prompted with @samp{login:} and @samp{Password:}; the results will be -checked against the UUCP (not the system) password file -(@pxref{Configuration File Names}). Of course, you can get a similar -effect by using the BSD @code{uucpd} program. - -You can also have @code{inetd} start up @code{uucico} with the @samp{-l} -switch, which will cause it to prompt with @samp{login:} and -@samp{Password:} and check the results against the UUCP (not the system) -password file. This may be used in place of @code{uucpd}. - -@node Configuration Files, Protocols, Overall Installation, Top -@chapter Taylor UUCP Configuration Files - -This chapter describes the configuration files accepted by the Taylor -UUCP package if compiled with @code{HAVE_TAYLOR_CONFIG} defined in -@file{conf.h}. - -The configuration files are normally found in the directory -@var{newconfigdir}, which is defined by the @file{Makefile} variable -@file{newconfigdir}; by default @var{newconfigdir} is -@file{/usr/local/lib/uucp}. However, the main configuration file, -@file{config}, is the only one which must be in that directory, since it -may specify a different location for any or all of the other files. You -may run any of the UUCP programs with a different main configuration -file by using the @samp{-I} option; this can be useful when testing a -new configuration. When you use the @samp{-I} option the programs will -revoke their setuid privileges. - -@menu -* Configuration File Format:: Configuration file format -* Configuration Examples:: Examples of configuration files -* Time Strings:: How to write time strings -* Chat Scripts:: How to write chat scripts -* config File:: The main configuration file -* sys File:: The system configuration file -* port File:: The port configuration files -* dial File:: The dialer configuration files -* Security:: Security issues -@end menu - -@node Configuration File Format, Configuration Examples, Configuration Files, Configuration Files -@section Configuration File Format - -All the configuration files follow a simple line-oriented -@samp{@var{keyword} @var{value}} format. Empty lines are ignored, as -are leading spaces; unlike BNU, lines with leading spaces are read. The -first word on each line is a keyword. The rest of the line is -interpreted according to the keyword. Most keywords are followed by -numbers, boolean values or simple strings with no embedded spaces. - -The @kbd{#} character is used for comments. Everything from a @kbd{#} -to the end of the line is ignored unless the @kbd{#} is preceded by a -@kbd{\} (backslash); if the @kbd{#} is preceeded by a @kbd{\}, the -@kbd{\} is removed but the @kbd{#} remains in the line. This can be -useful for a phone number containing a @kbd{#}. To enter the sequence -@samp{\#}, you would use @samp{\\#}. - -The backslash character may be used to continue lines. If the last -character in a line is a backslash, the backslash is removed and the -line is continued by the next line. The second line is attached to the -first with no intervening characters; if you want any whitespace between -the end of the first line and the start of the second line, you must -insert it yourself. - -However, the backslash is not a general quoting character. For example, -you cannot use it to get an embedded space in a string argument. - -Everything after the keyword must be on the same line. A @var{boolean} -may be specified as @kbd{y}, @kbd{Y}, @kbd{t}, or @kbd{T} for true and -@kbd{n}, @kbd{N}, @kbd{f}, or @kbd{F} for false; any trailing characters -are ignored, so @code{true}, @code{false}, etc., are also acceptable. - -@node Configuration Examples, Time Strings, Configuration File Format, Configuration Files -@section Examples of Configuration Files - -All the configuration commands are explained in the following sections. -However, I'll start by giving a few examples of configuration files. -For a more complete description of any of the commands used here see the -appropriate section of this chapter. - -@menu -* config File Examples:: Examples of the main configuration file -* Leaf Example:: Call a single remote site -* Gateway Example:: The gateway for several local systems -@end menu - -@node config File Examples, Leaf Example, Configuration Examples, Configuration Examples -@subsection config File Examples -@cindex config file examples - -To start with, here are some examples of uses of the main configuration -file, @file{config}. For a complete description of the commands that -are permitted in @file{config}, see @ref{config file}. - -In many cases you will not need to create a @file{config} file at all. -The most common reason to create one is to give your machine a special -UUCP name. Other reasons might be to change the UUCP spool directory or -to permit any remote system to call in. - -If you have an internal network of machines, then it is likely that the -internal name of your UUCP machine is not the name you want to use when -calling other systems. For example, here at @file{airs.com} our -mail/news gateway machine is named @file{elmer.airs.com} (it is one of -several machines all named @file{@var{localname}.airs.com}). If we did -not provide a @file{config} file, then our UUCP name would be -@file{elmer}; however, we actually want it to be @file{airs}. -Therefore, we use the following line in @file{config}: - -@example -nodename airs -@end example - -@cindex changing spool directory -@cindex spool directory (changing) -The UUCP spool directory name is set in @file{policy.h} when the code is -compiled. You might at some point decide that it is appropriate to move -the spool directory, perhaps to put it on a different disk partition. -You might use the following commands in @file{config} to change to -directories on the partition @file{/uucp}: - -@example -spool /uucp/spool -pubdir /uucp/uucppublic -logfile /uucp/spool/Log -debugfile /uucp/spool/Debug -@end example - -You would then move the contents of the current spool directory to -@file{/uucp/spool}. If you do this, make sure that no UUCP processes -are running while you change @file{config} and move the spool directory. - -@cindex anonymous UUCP -Suppose you wanted to permit any system to call in to your system and -request files. This is generally known as @dfn{anonymous UUCP}, since -the systems which call in are effectively anonymous. By default, -unknown systems are not permitted to call in. To permit this you must -use the @code{unknown} command in @file{config}. The @code{unknown} -command is followed by any command that may appear in the system file; -for full details, see @ref{sys file}. - -I will show two possible anonymous UUCP configurations. The first will -let any system call in and download files, but will not permit them to -upload files to your system. - -@example -# No files may be transferred to this system -unknown request no -# The public directory is /usr/spool/anonymous -unknown pubdir /usr/spool/anonymous -# Only files in the public directory may be sent (the default anyhow) -unknown remote-send ~ -@end example - -@noindent -Setting the public directory is convenient for the systems which call -in. It permits to request a file by prefixing it with @file{~/}. For -example, assuming your system is known as @samp{server}, then to -retrieve the file @file{/usr/spool/anonymous/INDEX} a user on a remote -site could just enter @samp{uucp server!~/INDEX ~}; this would transfer -@file{INDEX} from @samp{server}'s public directory to the user's local -public directory. Note that when using @samp{csh} or @samp{bash} the -@kbd{!} and the second @kbd{~} must be quoted. - -The next example will permit remote systems to upload files to a special -directory @file{/usr/spool/anonymous/upload}. Permitting a remote -system to upload files permits it to send work requests as well; this -example is careful to prohibit commands from unknown systems. - -@example -# No commands may be executed (the list of permitted commands is empty) -unknown commands -# The public directory is /usr/spool/anonymous -unknown pubdir /usr/spool/anonymous -# Only files in the public directory may be sent; users may not download -# files from the upload directory -unknown remote-send ~ !~/upload -# May only upload files into /usr/spool/anonymous/upload -unknown remote-receive ~/upload -@end example - -@node Leaf Example, Gateway Example, config File Examples, Configuration Examples -@subsection Leaf Example - -@cindex leaf site -@cindex sys file example (leaf) -A relatively common simple case is a @dfn{leaf site}, a system which -only calls or is called by a single remote site. Here is a typical -@file{sys} file that might be used in such a case. For full details on -what commands can appear in the @file{sys} file, see @ref{sys file}. - -This is the @file{sys} file that is used at @file{airs.com}. We use a -single modem to dial out to @file{uunet}. This example shows how you -can specify the port and dialer information directly in the @file{sys} -file for simple cases. It also shows the use of the following: - -@table @code - -@item call-login -Using @code{call-login} and @code{call-password} allows the default -login chat script to be used. In this case, the login name is specified -in the call-out login file (@pxref{Configuration File Names}). - -@item call-timegrade -@file{uunet} is requested to not send us news during the daytime. - -@item chat-fail -If the modem returns @samp{BUSY} or @samp{NO CARRIER} the call is -immediately aborted. - -@item protocol-parameter -Since @file{uunet} tends to be slow, the default timeout has been -increased. - -@end table - -This @file{sys} file relies on certain defaults. It will allow -@file{uunet} to queue up @samp{rmail} and @samp{rnews} commands. It -will allow users to request files from @file{uunet} into the UUCP public -directory. It will also @file{uunet} to request files from the UUCP -public directory; in fact @file{uunet} never requests files, but for -additional security we could add the line @samp{request false}. - -@example -# The following information is for uunet -system uunet - -# The login name and password are kept in the callout password file -call-login * -call-password * - -# We can send anything at any time. -time any - -# During the day we only accept grade 'Z' or above; at other times -# (not mentioned here) we accept all grades. uunet queues up news -# at grade 'd', which is lower than 'Z'. -call-timegrade Z Wk0755-2305,Su1655-2305 - -# The phone number. -phone 7389449 - -# uunet tends to be slow, so we increase the timeout -chat-timeout 120 - -# We are using a preconfigured Telebit 2500. -port type modem -port device /dev/ttyd0 -port baud 19200 -port carrier true -port dialer chat "" ATZ\r\d\c OK ATDT\D CONNECT -port dialer chat-fail BUSY -port dialer chat-fail NO\sCARRIER -port dialer complete \d\d+++\d\dATH\r\c -port dialer abort \d\d+++\d\dATH\r\c - -# Increase the timeout and the number of retries. -protocol-parameter g timeout 20 -protocol-parameter g retries 10 -@end example - -@node Gateway Example, , Leaf Example, Configuration Examples -@subsection Gateway Example - -@cindex gateway -@cindex sys file example (gateway) -Many organizations have several local machines which are connected by -UUCP, and a single machine which connects to the outside world. This -single machine is often referred to as a @dfn{gateway} machine. - -For this example I will assume a fairly simple case. It should still -provide a good general example. There are three machines, @file{elmer}, -@file{comton} and @file{bugs}. @file{elmer} is the gateway machine for -which I will show the configuration file. @file{elmer} calls out to -@file{uupsi}. As an additional complication, @file{uupsi} knows -@file{elmer} as @file{airs}; this will show how a machine can have one -name on an internal network but a different name to the external world. -@file{elmer} has two modems. It also has an TCP/IP connection to -@file{uupsi}, but since that is supposed to be reserved for interactive -work (it is, perhaps, only a 9600 baud SLIP line) it will only use it if -the modems are not available. - -A network this small would normally use a single @file{sys} file. -However, for pedagogical purposes I will show two separate @file{sys} -files, one for the local systems and one for @file{uupsi}. This is done -with the @code{sysfile} command in the @file{config} file. Here is the -@file{config} file. - -@example -# This is config -# The local sys file -sysfile /usr/local/lib/uucp/sys.local -# The remote sys file -sysfile /usr/local/lib/uucp/sys.remote -@end example - -Using the defaults feature of the @file{sys} file can greatly simplify -the listing of local systems. Here is @file{sys.local}. Note that this -assumes that the local systems are trusted; they are permited to request -any world readable file and to write files into any world writable -directory. - -@example -# This is sys.local -# Get the login name and password to use from the call-out file -call-login * -call-password * - -# The systems must use a particular login -called-login Ulocal - -# Permit sending any world readable file -local-send / -remote-send / - -# Permit requesting into any world writable directory -local-receive / -remote-receive / - -# Call at any time -time any - -# Use port1, then port2 -port port1 - -alternate - -port port2 - -# Now define the systems themselves. Because of all the defaults we -# used, there is very little to specify for the systems themselves. - -system comton -phone 5551212 - -system bugs -phone 5552424 -@end example - -The @file{sys.remote} file describes the @file{uupsi} connection. The -@code{myname} command is used to change the UUCP name to @file{airs} -when talking to @file{uupsi}. - -@example -# This is sys.remote -# Define uupsi -system uupsi - -# The login name and password are in the call-out file -call-login * -call-password * - -# We can call out at any time -time any - -# uupsi uses a special login name -called-login Uuupsi - -# uuspi thinks of us as `airs' -myname airs - -# The phone number -phone 5554848 - -# We use port2 first, then port1, then TCP - -port port2 - -alternate - -port port1 - -alternate - -# We don't bother to make a special entry in the port file for TCP, we -# just describe the entire port right here. We use a special chat -# script over TCP because the usual one confuses some TCP servers. -port type TCP -address uu.psi.com -chat ogin: \L word: \P -@end example - -The ports are defined in the file @file{port} (@pxref{port file}). For -this example they are both connected to the same type of 2400 baud -Hayes-compatible modem. - -@example -# This is port - -port port1 -type modem -device /dev/ttyd0 -dialer hayes -speed 2400 - -port port2 -type modem -device /dev/ttyd1 -dialer hayes -speed 2400 -@end example - -Dialers are described in the @file{dial} file (@pxref{dial file}). - -@example -# This is dial - -dialer hayes - -# The chat script used to dial the phone. \D is the phone number. -chat "" ATZ\r\d\c OK ATDT\D CONNECT - -# If we get BUSY or NO CARRIER we abort the dial immediately -chat-fail BUSY -chat-fail NO\sCARRIER - -# When the call is over we make sure we hangup the modem. -complete \d\d+++\d\dATH\r\c -abort \d\d+++\d\dATH\r\c -@end example - -@node Time Strings, Chat Scripts, Configuration Examples, Configuration Files -@section Time Strings -@cindex time strings - -Several commands use time strings to specify a range of times. This -section describes how to write time strings. - -A time string may be a list of simple time strings separated with a -vertical bar @kbd{|} or a command @kbd{,}. - -Each simple time string must begin with @samp{Su}, @samp{Mo}, @samp{Tu}, -@samp{We}, @samp{Th}, @samp{Fr}, or @samp{Sa}, or @samp{Wk} for any -weekday, or @samp{Any} for any day. - -Following the day may be a range of hours separated with a hyphen using -24 hour time. The range of hours may cross 0; for example -@samp{2300-0700} means any time except 7 AM to 11 PM. If no time is -given, calls may be made at any time on the specified day(s). - -The time string may also consist of the single word @samp{Never}, which -does not match any time, or a single word with a name defined in a -previous @code{timetable} command (@pxref{Miscellaneous (sys)}). - -Here are a few sample time strings with an explanation of what they -mean. - -@table @samp - -@item Wk2305-0855,Sa,Su2305-1655 - -This means weekdays before 8:55 AM or after 11:05 PM, any time Saturday, -or Sunday before 4:55 PM or after 11:05 PM. These are approximately the -times during which night rates apply to phone calls in the U.S.A. Note -that this time string uses, for example, @samp{2305} rather than -@samp{2300}; this will ensure a cheap rate phone call even if the -computer clock is running up to five minutes ahead of the real time. - -@item Wk0905-2255,Su1705-2255 - -This means weekdays from 9:05 AM to 10:55 PM, or Sunday from 5:05 PM to -10:55 PM. This is approximately the opposite of the previous example. - -@item Any - -Since no time is specified, this means any time on any day. - -@end table - -@node Chat Scripts, config File, Time Strings, Configuration Files -@section Chat Scripts -@cindex chat scripts - -Chat scripts are used in several different places, such as dialing out -on modems or logging in to remote systems. Chat scripts are made up of -pairs of strings. The program waits until it sees the first string, -known as the @dfn{expect} string, and then sends out the second string, -the @dfn{send} string. - -Each chat script is defined using a set of commands. These commands -always end in a string beginning with @code{chat}, but may start with -different strings. For example, in the @file{sys} file there is one set -of commands beginning with @code{chat} and another set beginning with -@code{called-chat}. The prefixes are only used to disambiguate -different types of chat scripts, and this section ignores the prefixes -when describing the commands. - -@table @code - -@item chat @var{strings} -@findex chat - -Specify a chat script. The arguments to the @code{chat} command are -pairs of strings separated by whitespace. The first string of each pair -is an expect string, the second is a send string. The program will wait -for the expect string to appear; when it does, the program will send the -send string. If the expect string does not appear within a certain -number of seconds (as set by the @code{chat-timeout} command) the chat -script fails and, typically, the call is aborted. If the final expect -string is seen (and the optional final send string has been sent), the -chat script is successful. - -An expect string may contain additional subsend and subexpect strings, -separated by hyphens. If the expect string is not seen, the subsend -string is sent and the chat script continues by waiting for the -subexpect string. This means that a hyphen may not appear in an expect -string; use @samp{\055} instead. - -An expect string may simply be @samp{""}, meaning to skip the expect -phase. Otherwise, the following escape characters may appear in expect -strings: - -@table @samp -@item \b -a backspace character -@item \n -a newline or line feed character -@item \N -a null character (for BNU compatibility) -@item \r -a carriage return character -@item \s -a space character -@item \t -a tab character -@item \\ -a backslash character -@item \@var{ddd} -character @var{ddd}, where @var{ddd} are up to three octal digits -@item \x@var{ddd} -character @var{ddd}, where @var{ddd} are hexadecimal digits. -@end table - -As in C, there may be up to three octal digits following a backslash, -but the hexadecimal escape sequence continues as far as possible. To -follow a hexadecimal escape sequence with a hex digit, interpose a send -string of @samp{""}. - -A send string may also simply be @samp{""} to skip the send phase. -Otherwise, all of the escape characters legal for expect strings may be -used, and the following escape characters are also permitted: - -@table @samp -@item EOT -send an end of transmission character (@kbd{^D}) -@item BREAK -send a break character (may not work on all systems) -@item \c -suppress trailing carriage return at end of send string -@item \d -delay sending for 1 second -@item \e -disable echo checking -@item \E -enable echo checking (wait for echo before continuing) -@item \K -same as @kbd{BREAK} (for BNU compatibility) -@item \p -pause sending for a fraction of a second -@end table - -Some specific types of chat scripts also define additional escape -sequences that may appear in the send string. For example, the login -chat script defines @samp{\L} and @samp{\P} to send the login name and -password, respectively. - -A carriage return will be sent at the end of each send string, unless -the @kbd{\c} escape sequence appears in the string. Note that some UUCP -packages use @kbd{\b} for break, but here it means backspace. - -Echo checking means that after writing each character the program will -wait until the character is echoed. Echo checking must be turned on -separately for each send string for which it is desired; it will be -turned on for characters following @kbd{\E} and turned off for characters -following @kbd{\e}. - -@item chat-timeout @var{number} -@findex chat-timeout - -The number of seconds to wait for an expect string in the chat script -before timing out and sending the next subsend or failing the chat -script entirely. The default value is 10 for a login chat or 60 for -any other type of chat. - -@item chat-fail @var{string} -@findex chat-fail - -If the @var{string} is seen at any time during a chat script, the chat -script is aborted. The string may not contain any whitespace -characters; escape sequences must be used for them. Multiple -@code{chat-fail} commands may appear in a single chat script. The -default is to have none. - -This permits a chat script to be quickly aborted if an error string is -seen. For example, a script used to dial out on a modem might use the -command @samp{chat-fail BUSY} to stop the chat script immediately if the -string @samp{BUSY} was seen. - -@item chat-seven-bit @var{boolean} -@findex chat-seven-bit - -If the argument is true, all incoming characters are stripped to seven -bits when being compared to the expect string. Otherwise all eight bits -are used in the comparison. The default is true because some Unix -systems generate parity bits during the login prompt which must be -ignored while running a chat script. This has no effect on any -@code{chat-program}, which must ignore parity by itself if necessary. - -@item chat-program @var{strings} -@findex chat-program in sys file - -Specify a program to run before executing the chat script. This program -could run its own version of a chat script, or it could do whatever it -wants. If both @code{chat-program} and @code{chat} are specified, the -program is executed first followed by the chat script. - -The first argument to the @code{chat-program} command is the program -name to run. The remaining arguments are passed to the program. The -following escape sequences are recognized in the arguments: - -@table @kbd -@item \Y -port device name -@item \S -port speed -@item \\ -backslash -@end table - -Some specific uses of @code{chat-program} define additional escape -sequences. - -Arguments other than escape sequences are passed exactly as they appear -in the configuration file, except that sequences of whitespace are -compressed to a single space character; this exception may be removed in -the future. - -If the @code{chat-program} command is not used, no program is run. - -On Unix, the standard input and standard output of the program will be -attached to the port in use. Anything the program writes to standard -error will be written to the UUCP log file. No other file descriptors -will be open. If the program does not exit with a status of 0, it will -be assumed to have failed; this means that the dialing programs used by -some versions of BNU may not be used directly, although of course a -shell script could be used as an interface. - -The program will be run as the @code{uucp} user, and the environment -will be that of the process that started @code{uucico}, so care must be -taken to maintain security. - -No search path is used to find the program; a full path name must be -given. If the program is an executable shell script, it will be passed -to @file{/bin/sh} even on systems which are unable to execute shell -scripts. It is also easy to invoke @file{/bin/sh} directly. - -@end table - -Here is a simple example of a chat script that might be used to reset a -Hayes compatible modem. - -@example -chat "" ATZ OK-ATZ-OK -@end example - -The first expect string is @samp{""}, so it is ignored. The chat script -then sends @samp{ATZ}. If the modem responds with @samp{OK}, the chat -script finishes. If 60 seconds (the default timeout) pass before seeing -@samp{OK}, the chat script sends another @samp{ATZ}. If it then sees -@samp{OK}, the chat script succeeds. Otherwise, the chat script fails. - -For a more complex chat script example, see @ref{Logging In}. - -@node config File, sys File, Chat Scripts, Configuration Files -@section The Main Configuration File -@cindex config file -@cindex main configuration file -@cindex configuration file (config) - -The main configuration file is named @file{config}. - -Since all the values that may be specified in the main configuration -file also have defaults, there need not be a main configuration file at -all. - -@menu -* Miscellaneous (config):: Miscellaneous config file commands -* Configuration File Names:: Using different configuration files -* Log File Names:: Using different log files -* Debugging Levels:: Debugging levels -@end menu - -@node Miscellaneous (config), Configuration File Names, config File, config File -@subsection Miscellaneous config File Commands - -@table @code - -@item nodename @var{string} -@findex nodename -@itemx hostname @var{string} -@findex hostname -@itemx uuname @var{string} -@findex uuname -@cindex UUCP system name -@cindex system name - -These keywords are equivalent. They specify the UUCP name of the -local host. If there is no configuration file, an appropriate -function will be used to get the host name, if possible. - -@item spool @var{string} -@findex spool -@cindex spool directory -@cindex /usr/spool/uucp - -Specify the spool directory. The default is from @file{policy.h}. -Command files, work files, temporary files, etc., are stored in this -directory and in subdirectories of it. - -@item pubdir @var{string} -@findex pubdir in config file -@cindex public directory -@cindex uucppublic -@cindex /usr/spool/uucppublic - -Specify the public directory. The default is from @file{policy.h}. On -Unix, when a file is named using a leading @kbd{~/}, it is taken from or -to the public directory. Each system may use a separate public -directory by using the @code{pubdir} command in the system configuration -file; see @ref{Miscellaneous (sys)}. - -@item unknown @var{string} @dots{} -@findex unknown -@cindex unknown systems - -The @var{string} and subsequent arguments are treated as though they -appeared in the system file (@pxref{sys file}). They are used to apply -to any unknown systems that may call in, probably to set file transfer -permissions and the like. If the @code{unknown} command is not used, -unknown systems are not permitted to call in. - -@item max-uuxqts @var{number} -@findex max-uuxqts - -Specify the maximum number of @code{uuxqt} processes which may run at -the same time. Having several @code{uuxqt} processes running at once -can significantly slow down a system, but since @code{uuxqt} is -automatically started by @code{uucico}, it can happen quite easily. The -default for @code{max-uuxqts} is 0, which means that there is no limit. -If BNU configuration files are being read and the code was compiled -without @code{HAVE_TAYLOR_CONFIG}, then if the file @file{Maxuuxqts} in -the configuration directory contains a readable number it will be used as -the value for @code{max-uuxqts}. - -@item v2-files @var{boolean} -@findex v2-files - -If the code was compiled to be able to read V2 configuration files, a -false argument to this command will prevent them from being read. -This can be useful while testing. The default is true. - -@item bnu-files @var{boolean} -@findex bnu-files - -If the code was compiled to be able to read BNU configuration files, a -false argument to this command will prevent them from being read. -This can be useful while testing. The default is true. - -@end table - -@node Configuration File Names, Log File Names, Miscellaneous (config), config File -@subsection Configuration File Names - -@table @code - -@item sysfile @var{strings} -@findex sysfile - -Specify the system file(s). The default is the file @file{sys} in the -directory @var{newconfigdir}. These files hold information about other -systems with which this system communicates; see @ref{sys file}. -Multiple system files may be given on the line, and the @code{sysfile} -command may be repeated; each system file has its own set of defaults. - -@item portfile @var{strings} -@findex portfile - -Specify the port file(s). The default is the file @file{port} in the -directory @var{newconfigdir}. These files describe ports which are used -to call other systems and accept calls from other systems; see @ref{port -file}. No port files need be named at all. Multiple port files may be -given on the line, and the @code{portfile} command may be repeated. - -@item dialfile @var{strings} -@findex dialfile - -Specify the dial file(s). The default is the file @file{dial} in the -directory @var{newconfigdir}. These files describe dialing devices -(modems); @xref{dial file}. No dial files need be named at all. -Multiple dial files may be given on the line, and the @code{dialfile} -command may be repeated. - -@item dialcodefile @var{strings} -@findex dialcodefile -@cindex configuration file (dialcode) -@cindex dialcode file -@cindex dialcode configuration file - -Specify the dialcode file(s). The default is the file @file{dialcode} -in the directory @var{newconfigdir}. These files specify dialcodes that -may be used when sending phone numbers to a modem. This permits using -the same set of phone numbers in different area-codes or with different -phone systems, by using dialcodes to specify the calling sequence. When -a phone number goes through dialcode translation, the leading alphabetic -characters are stripped off. The dialcode files are read line by line, -just like any other configuration file, and when a line is found whose -first word is the same as the leading characters from the phone number, -the second word on the line (which would normally consist of numbers) -replaces the dialcode in the phone number. No dialcode file need be -used. Multiple dialcode files may be specified on the line, and the -@code{dialcodefile} command may be repeated; all the dialcode files will -be read in turn until a dialcode is located. - -@item callfile @var{strings} -@findex callfile -@cindex call out file -@cindex call configuration file -@cindex call out login name -@cindex call out password -@cindex configuration file (call) - -Specify the call out login name and password file(s). The default is -the file @file{call} in the directory @var{newconfigdir}. If the call -out login name or password for a system are given as @kbd{*} -(@pxref{Logging In}), these files are read to get the real login name or -password. Each line in the file(s) has three words: the system name, -the login name, and the password. This file is only used when placing -calls to remote systems; the password file described under -@code{passwdfile} below is used for incoming calls. The intention of -the call out file is to permit the system file to be publically -readable; the call out files must obviously be kept secure. These files -need not be used. Multiple call out files may be specified on the line, -and the @code{callfile} command may be repeated; all the files will be -read in turn until the system is found. - -@item passwdfile @var{strings} -@findex passwdfile -@cindex passwd file -@cindex passwd configuration file -@cindex configuration file (passwd) -@cindex call in login name -@cindex call in password - -Specify the password file(s) to use for login names when @code{uucico} -is doing its own login prompting, which it does when given the -@samp{-e}, @samp{-l} or @samp{-w} switch. The default is the file -@file{passwd} in the directory @var{newconfigdir}. Each line in the -file(s) has two words: the login name and the password (e.g. @code{Ufoo -foopas}). The login name is accepted before the system name is known, -so these are independent of which system is calling in; a particular -login may be required for a system by using the @code{called-login} -command in the system file (@pxref{Accepting a Call}). These password -files are optional, although one must exist if @code{uucico} is to -present its own login prompts. Multiple password files may be specified -on the line, and the @code{passwdfile} command may be repeated; all the -files will be read in turn until the login name is found. - -@end table - -@node Log File Names, Debugging Levels, Configuration File Names, config File -@subsection Log File Names - -@table @code - -@item logfile @var{string} -@findex logfile -@cindex log file - -Name the log file. The default is from @file{policy.h}. Logging -information is written to this file. If @code{HAVE_BNU_LOGGING} is -defined in @file{conf.h}, then by default a separate log file is used -for each system. Using this command to name a log file will cause all -the systems to use it. - -@item statfile @var{string} -@findex statfile -@cindex statistics file - -Name the statistics file. The default is from @file{policy.h}. -Statistical information about file transfers is written to this file. - -@item debugfile @var{string} -@findex debugfile -@cindex debugging file - -Name the file to which debugging information is written. The default is -from @file{policy.h}. This command is only effective if the code has -been compiled to include debugging (this is controlled by the -@code{DEBUG} variable in @file{policy.h}). After the first debugging -message has been written, messages written to the log file are also -written to the debugging file to make it easier to keep the order of -actions straight. The debugging file is different from the log file -because information such as passwords can appear in it, so it must be -not be publically readable. - -@end table - -@node Debugging Levels, , Log File Names, config File -@subsection Debugging Levels - -@table @code - -@item debug @var{string} @dots{} -@findex debug in config file - -Set the debugging level. This command is only effective if the code has -been compiled to include debugging. The default is to have no -debugging. The arguments are strings which name the types of debugging -to be turned on. The following types of debugging are defined: - -@table @samp -@item abnormal -Output debugging messages for abnormal situations, such as recoverable errors. -@item chat -Output debugging messages for chat scripts. -@item handshake -Output debugging messages for the initial handshake. -@item uucp-proto -Output debugging messages for the UUCP protocol itself. -@item proto -Output debugging messages for the individual protocols. -@item port -Output debugging messages for actions on the communication port. -@item config -Output debugging messages while reading the configuration files. -@item spooldir -Output debugging messages for actions in the spool directory. -@item execute -Output debugging messages whenever another program is executed. -@item incoming -List all incoming data in the debugging file. -@item outgoing -List all outgoing data in the debugging file. -@item all -All of the above. -@end table - -The debugging level may also be specified as a number. A 1 will set -@samp{chat} debugging, a 2 will set both @samp{chat} and -@samp{handshake} debugging, and so on down the possibilities. Currently -an 11 will turn on all possible debugging, since there are 11 types of -debugging messages listed above; more debugging types may be added in -the future. The @code{debug} command may be used several times in the -configuration file; every debugging type named will be turned on. When -running any of the programs, the @samp{-x} switch (actually, for -@code{uulog} it's the @samp{-X} switch) may be used to turn on -debugging. The argument to the @samp{-x} switch is one of the strings -listed above, or a number as described above, or a comma separated list -of strings (e.g. @samp{-x chat,handshake}). The @samp{-x} switch may -also appear several times on the command line, in which case all named -debugging types will be turned on. The @samp{-x} debugging is in -addition to any debugging specified by the @code{debug} command; there -is no way to cancel debugging information. The debugging level may also -be set specifically for calls to or from a specific system with the -@code{debug} command in the system file (@pxref{Miscellaneous (sys)}). - -The debugging messages are somewhat idiosyncratic; it may be necessary -to refer to the source code for additional information in some cases. - -@end table - -@node sys File, port File, config File, Configuration Files -@section The System Configuration File -@cindex sys file -@cindex system configuration file -@cindex configuration file (sys) - -By default there is a single system configuration, named @file{sys} in -the directory @var{newconfigdir}. This may be overridden by the -@code{sysfile} command in the main configuration file; see -@ref{Configuration File Names}. - -These files describe all remote systems known to the UUCP package. - -@menu -* Defaults and Alternates:: Using defaults and alternates -* Naming the System:: Naming the system -* Calling Out:: Calling out -* Accepting a Call:: Accepting a call -* Protocol Selection:: Protocol selection -* File Transfer Control:: File transfer control -* Miscellaneous (sys):: Miscellaneous sys file commands -* Default sys File Values:: Default values -@end menu - -@node Defaults and Alternates, Naming the System, sys File, sys File -@subsection Defaults and Alternates - -The first set of commands in the file, up to the first @code{system} -command, specify defaults to be used for all systems in that file. Each -system file uses a different set of defaults. - -Subsequently, each set of commands from @code{system} up to the next -@code{system} command describe a particular system. Default values may -be overridden for specific systems. - -Each system may then have a series of alternate choices to use when -calling out or calling in. The first set of commands for a particular -system, up to the first @code{alternate} command, provide the first -choice. Subsequently, each set of commands from @code{alternate} up to -the next @code{alternate} command describe an alternate choice for -calling out or calling in. - -When a system is called, the commands before the first @code{alternate} -are used to select a phone number, port, and so forth; if the call fails -for some reason, the commands between the first @code{alternate} and the -second are used, and so forth. Well, not quite. Actually, each -succeeding alternate will only be used if it is different in some -relevant way (different phone number, different chat script, etc.). If -you want to force the same alternate to be used again (to retry a phone -call more than once, for example), enter the phone number (or any other -relevant field) again to make it appear different. - -The alternates can also be used to give different permissions to an -incoming call based on the login name. This will only be done if the -first set of commands, before the first @code{alternate} command, uses -the @code{called-login} command. The list of alternates will be -searched, and the first alternate with a matching @code{called-login} -command will be used. If no alternates match, the call will be -rejected. - -The @code{alternate} command may also be used in the file-wide defaults -(the set of commands before the first @code{system} command). This -might be used to specify a list of ports which are available for all -systems (for an example of this, see @ref{Gateway Example}) or to -specify permissions based on the login name used by the remote system -when it calls in. The first alternate for each system will default to -the first alternate for the file-wide defaults (as modified by the -commands used before the first @code{alternate} command for this -system), the second alternate for each system to the second alternate -for the file-wide defaults (as modified the same way), and so forth. If -a system specifies more alternates than the file-wide defaults, the -trailing ones will default to the last file-wide default alternate. If -a system specifies fewer alternates than the file-wide defaults, the -trailing file-wide default alternates will be used unmodified. The -@code{default-alternates} command may be used to modify this behaviour. - -This can all get rather confusing, although it's easier to use than to -describe concisely; the @code{uuchk} program may be used to ensure that -you are getting what you want. - -@node Naming the System, Calling Out, Defaults and Alternates, sys File -@subsection Naming the System - -@table @code - -@item system @var{string} -@findex system - -Specify the remote system name. Subsequent commands up to the next -@code{system} command refer to this system. - -@item alternate [@var{string}] -@findex alternate - -Start an alternate set of commands (@pxref{Defaults and Alternates}). -An optional argument may be used to name the alternate. This name will -be put in the log file if the alternate is used to call the system. -There is no way to name the first alternate (the commands before the -first @code{alternate} command). - -@item default-alternates @var{boolean} -@findex default-alternates - -If the argument is false, any remaining default alternates (from the -defaults specified at the top of the current system file) will not be -used. The default is true. - -@item alias @var{string} -@findex alias - -Specify an alias for the current system. The alias may be used by local -@code{uucp} and @code{uux} commands. The default is to have no aliases. - -@item myname @var{string} -@findex myname - -Specifies a different system name to use when calling the remote system. -Also, if @code{called-login} is used and is not @samp{ANY}, then, when a -system logs in with that login name, @var{string} is used as the system -name. Because the local system name must be determined before the -remote system has identified itself, using @code{myname} and -@code{called-login} together for any system will set the local name for -that login; this means that each locally used system name must have a -unique login name associated with it. This allows a system to have -different names for an external and an internal network. The default is -to not use a special local name. - -@end table - -@node Calling Out, Accepting a Call, Naming the System, sys File -@subsection Calling Out - -This section describes commands used when placing a call to another -system. - -@menu -* When to Call:: When to call -* Placing the Call:: Placing the call -* Logging In:: Logging in -@end menu - -@node When to Call, Placing the Call, Calling Out, Calling Out -@subsubsection When to Call - -@table @code - -@item time @var{string} [@var{number}] -@findex time - -Specify when the system may be called. The first argument is a time -string; see @ref{Time Strings}. The optional second argument specifies -a retry time in minutes. If a call made during a time that matches the -time string fails, no more calls are permitted until the retry time has -passed. By default an exponentially increasing retry time is used: -after each failure the next retry period is longer. A retry time -specified in the @code{time} command is always a fixed amount of time. - -The @code{time} command may appear multiple times in a single alternate, -in which case if any time string matches the system may be called. The -default time string is @samp{Never}. - -@item timegrade @var{character} @var{string} [@var{number}] -@findex timegrade - -The @var{character} specifies a grade. It must be a single letter or -digit. The @var{string} is a time string (@pxref{Time Strings}). All -jobs of grade @var{character} or higher (where @kbd{0} > @kbd{9} > -@kbd{A} > @kbd{Z} > @kbd{a} > @kbd{z}) may be run at the specified time. -An ordinary @code{time} command is equivalent to using @code{timegrade} -with a grade of @kbd{z}, permitting all jobs. If there are no jobs of a -sufficiently high grade according to the time string, the system will -not be called. Giving the @samp{-s} switch to @code{uucico} to force it -to call a system causes it to assume there is a job of grade @kbd{0} -waiting to be run. - -The optional third argument specifies a retry time in minutes. See the -@code{time} command, above, for more details. - -Note that the @code{timegrade} command serves two purposes: 1) if there -is no job of sufficiently high grade the system will not be called, and -2) if the system is called anyway (because the @samp{-s} switch was -given to @code{uucico}) only jobs of sufficiently high grade will be -transferred. However, if the other system calls in, the -@code{timegrade} commands are ignored, and jobs of any grade may be -transferred (but see @code{call-timegrade} below). Also, the -@code{timegrade} command will not prevent the other system from -transferring any job it chooses, regardless of who placed the call. - -The @code{timegrade} command may appear multiple times without using -@code{alternate}. If this command does not appear, there are no -restrictions on what grade of work may be done at what time. - -@item call-timegrade @var{character} @var{string} -@findex call-timegrade - -The @var{character} is a single character @kbd{A} to @kbd{Z}, @kbd{a} to -@kbd{z}, or @kbd{0} to @kbd{9} and specifies a grade. The @var{string} -is a time string as described under the @code{time} command. If a call -is placed to the other system during a time which matches the time -string, the remote system will be requested to only run jobs of grade -@var{character} or higher. Unfortunately, there is no way to guarantee -that the other system will obey the request (this UUCP package will, but -there are others which will not); moreover job grades are historically -somewhat arbitrary, so specifying a grade will only be meaningful if the -other system cooperates in assigning grades. This grade restriction -only applies when the other system is called, not when the other system -calls in. - -The @code{call-timegrade} command may appear multiple times without -using @code{alternate}. If this command does not appear, or if none of -the time strings match, the remote system will be allowed to send -whatever grades of work it chooses. - -@end table - -@node Placing the Call, Logging In, When to Call, Calling Out -@subsubsection Placing the Call - -@table @code - -@item baud @var{number} -@findex baud in sys file -@itemx speed @var{number} -@findex speed in sys file - -Specify the speed (the term @dfn{baud} is technically incorrect, but -widely understood) at which to call the system. This will try all -available ports with that baud rate until an unlocked port is found. -The ports are defined in the port file. If both @code{baud} and -@code{port} commands appear, both are used when selecting a port. To -allow calls at more than one baud rate, the @code{alternate} command -must be used (@pxref{Defaults and Alternates}). If this command does -not appear, there is no default; the baud rate may be specified in the -port file, but if it is not then the natural baud rate of the port will -be used (whatever that means on the system). Specifying an explicit -baud rate of 0 will request the natural baud rate of the port, -overriding any default baud rate from the defaults at the top of the -file. - -@item port @var{string} -@findex port in sys file - -Name a particular port or type of port to use when calling the system. -The information for this port is obtained from the port file. If this -command does not appear, there is no default; a port must somehow be -specified in order to call out (it may be specified implicitly using the -@code{baud} command or explicitly using the next version of -@code{port}). There may be many ports with the same name; each will be -tried in turn until an unlocked one is found which matches the desired -baud rate. - -@item port @var{string} @dots{} - -If more than one string follows the @code{port} command, the subsequent -strings are treated as commands that might appear in the port file -(@pxref{port file}). If a port is named (by using a single string -following @code{port}) these commands are ignored; their purpose is to -permit defining the port completely in the system file rather than -always requiring entries in two different files. In order to call out, -a port must be specified using some version of the @code{port} command, -or by using the @code{baud} command to select ports from the port file. - -@item phone @var{string} -@findex phone -@itemx address @var{string} -@findex address - -Give a phone number to call (when using a modem port) or a remote host -to contact (when using a TCP port). The commands @code{phone} and -@code{address} are equivalent, but are intended to be more mnemonic -depending on the type of port in use. - -When used with a modem port, an @kbd{=} character in the phone number -means to wait for a secondary dial tone (although only some modems -support this); a @kbd{-} character means to pause while dialing for 1 -second (again, only some modems support this). If the system has more -than one phone number, each one must appear in a different alternate. -The @code{phone} command must appear in order to call out on a modem; -there is no default. - -When used with a TCP port, the string names the host to contact. It may -be a domain name or a numeric Internet address. If no address is -specified, the system name is used. - -When used with a port that neither is a modem nor TCP, this command is -ignored. - -@end table - -@node Logging In, , Placing the Call, Calling Out -@subsubsection Logging In -@table @code - -@item chat @var{strings} -@findex chat in sys file -@item chat-timeout @var{number} -@findex chat-timeout in sys file -@item chat-fail @var{string} -@findex chat-fail in sys file -@item chat-seven-bit @var{boolean} -@findex chat-seven-bit in sys file -@item chat-program @var{strings} -@findex chat-program in sys file - -These commands describe a chat script to use when logging on to a remote -system. Chat scripts are explained in @ref{Chat Scripts}. - -Two additional escape sequences may be used in send strings. - -@table @samp -@item \L -Send the login name, as set by the @code{call-login} command. -@item \P -Send the passowrd, as set by the @code{call-password} command. -@end table - -Three additional escape sequences may be used with the -@code{chat-program} command. These are @samp{\L} and @samp{\P}, which -become the login name and password, respectively, and @samp{\Z}, which -becomes the name of the system of being called. - -The default chat script is: - -@example -chat "" \r\c ogin:-BREAK-ogin:-BREAK-ogin: \L word: \P -@end example - -This will send a carriage return (the @kbd{\c} suppresses the additional -trailing carriage return that would otherwise be sent) and waits for the -string @samp{ogin:} (which would be the last part of the @samp{login:} -prompt supplied by a Unix system). If it doesn't see @samp{ogin:}, it -sends a break and waits for @samp{ogin:} again. If it still doesn't see -@samp{ogin:}, it sends another break and waits for @samp{ogin:} again. -If it still doesn't see @samp{ogin:}, the chat script aborts and hangs -up the phone. If it does see @samp{ogin:} at some point, it sends the -login name (as specified by the @code{call-login} command) followed by a -carriage return (since all send strings are followed by a carriage -return unless @kbd{\c} is used) and waits for the string @samp{word:} -(which would be the last part of the @samp{Password:} prompt supplied by -a Unix system). If it sees @samp{word:}, it sends the password and a -carriage return, completing the chat script. The program will then -enter the handshake phase of the UUCP protocol. - -This chat script will work for most systems, so you will only be -required to use the @code{call-login} and @code{call-password} commands. -In fact, in the file-wide defaults you could set defaults of -@samp{call-login *} and @samp{call-password *}; you would then just have -to make an entry for each system in the call-out login file. - -Some systems seem to flush input after the @samp{login:} prompt, so they -may need a version of this chat script with a @kbd{\d} before the -@kbd{\L}. When using UUCP over TCP, some servers will not be handle the -initial carriage return sent by this chat script; in this case you may -have to specify the simple chat script @samp{ogin: \L word: \P}. - -@item call-login @var{string} -@findex call-login - -Specify the login name to send with @kbd{\L} in the chat script. If the -string is @samp{*} (e.g. @samp{call-login *}) the login name will be -fetched from the call out login name and password file -(@pxref{Configuration File Names}). There is no default. - -@item call-password @var{string} -@findex call-password - -Specify the password to send with @kbd{\P} in the chat script. If the -string is @samp{*} (e.g. @samp{call-password *}) the password will be -fetched from the call-out login name and password file -(@pxref{Configuration File Names}). There is no default. - -@end table - -@node Accepting a Call, Protocol Selection, Calling Out, sys File -@subsection Accepting a Call - -@table @code - -@item called-login @var{strings} -@findex called-login - -The first @var{string} specifies the login name that the system must use -when calling in. If it is @samp{ANY} (e.g. @samp{called-login ANY}) any -login name may be used; this is useful to override a file-wide default -and to indicate that future alternates may have different login names. -Case is significant. The default value is @samp{ANY}. - -Different alternates (@pxref{Defaults and Alternates}) may use different -@code{called-login} commands, in which case the login name will be used -to select which alternate is in effect; this will only work if the first -alternate (before the first @code{alternate} command) uses the -@code{called-login} command. - -Additional strings may be specified after the login name; they are a -list of which systems are permitted to use this login name. If this -feature is used, then normally the login name will only be given in a -single @code{called-login} command. Only systems which appear on the -list, or which use an explicit @code{called-login} command, will be -permitted to use that login name. If the same login name is used more -than once with a list of systems, all the lists are concatenated -together. This feature permits you to restrict a login name to a -particular set of systems without requiring you to use the -@code{called-login} command for every single system; you can achieve a -similar effect by using a different system file for each permitted login -name with an appropriate @code{called-login} command in the file-wide -defaults. - -@item callback @var{boolean} -@findex callback - -If @var{boolean} is true, then when the remote system calls -@code{uucico} will hang up the connection and prepare to call it back. -This is false by default. - -@item called-chat @var{strings} -@findex called-chat -@item called-chat-timeout @var{number} -@findex called-chat-timeout -@item called-chat-fail @var{string} -@findex called-chat-fail -@item called-chat-seven-bit @var{boolean} -@findex called-chat-seven-bit -@item called-chat-program @var{strings} -@findex called-chat-program - -These commands may be used to define a chat script (@pxref{Chat -Scripts}) that is run whenever the local system is called by the system -being defined. The chat script defined by the @code{chat} command -(@pxref{Logging In}), on the other hand, is used when the remote system -is called. This called chat script might be used to set special modem -parameters that are appropriate to a particular system. It is run after -protocol negotiation is complete, but before the protocol has been -started. See @ref{Logging In} for additional escape sequence which may -be used besides those defined for all chat scripts. There is no default -called chat script. If the called chat script fails, the incoming call -will be aborted. - -@end table - -@node Protocol Selection, File Transfer Control, Accepting a Call, sys File -@subsection Protocol Selection - -@table @code - -@item protocol @var{string} -@findex protocol in sys file - -Specifies which protocols to use for the other system, and in which -order to use them. This would not normally be used. For example, -@samp{protocol tfg}. - -The default depends on the characteristics of the port and the dialer, -as specified by the @code{seven-bit} and @code{reliable} commands. If -neither the port nor the dialer use either of these commands, the -default is to assume an eight-bit reliable connection. The commands -@samp{seven-bit true} or @samp{reliable false} might be used in either -the port or the dialer to change this. Each protocol has particular -requirements that must be met before it will be considered during -negotiation with the remote side. - -The @samp{t} and @samp{e} protocols are intended for use over TCP or -some other communication path with end to end reliability, as they do no -checking of the data at all. They will only be considered on a TCP port -which is both reliable and eight bit. - -The @samp{g} protocol is robust, but requires an eight-bit connection. - -The @samp{f} protocol is intended for use with X.25 connections; it -checksums each file as a whole, so any error causes the entire file to -be retransmitted. It requires a reliable connection, but only uses -seven-bit transmissions. It is a streaming protocol, so, while it can -be used on a serial port, the port must be completely reliable and flow -controlled; many aren't. - -The protocols will be considered in the order shown above. This means -that if neither the @code{seven-bit} nor the @code{reliable} command are -used, the @samp{t} protocol will be used over a TCP connection and the -@samp{g} protocol will be used over any other type of connection -(subject, of course, to what is supported by the remote system; it may -be assumed that all systems support the @samp{g} protocol). - -Note that currently specifying both @samp{seven-bit true} and -@samp{reliable false} will not match any protocol. If this occurs -through a combination of port and dialer specifications, you will have -to use the @code{protocol} command for the system or no protocol will be -selected at all (the only reasonable choice would be @samp{protocol f}). - -A protocol list may also be specified for a port (@pxref{port file}), -but if there is a list for the system the list for the port is ignored. - -@item protocol-parameter @var{character} @var{string} @dots{} -@findex protocol-parameter in sys file - -@var{character} is a single character specifying a protocol. The -remaining strings are a command specific to that protocol which will be -executed if that protocol is used. A typical command is something like -@samp{window 7}. The particular commands are protocol specific. - -The @samp{g} protocol supports the following commands, all of which take -numeric arguments: - -@table @code -@item window -The window size to request the remote system to use. This must be -between 1 and 7 inclusive. The default is 7. -@item packet-size -The packet size to request the remote system to use. This must be a -power of 2 between 32 and 4096 inclusive. The default is 64, which is -the only packet size supported by many older UUCP packages. Some UUCP -packages will even dump core if a larger packet size is requested. -@item startup-retries -The number of times to retry the initialization sequence. The default -is 8. -@item init-retries -The number of times to retry one phase of the initialization sequence -(there are three phases). The default is 4. -@item init-timeout -The timeout in seconds for one phase of the initialization sequence. The -default is 10. -@item retries -The number of times to retry sending either a data packet or a request -for the next packet. The default is 6. -@item timeout -The timeout in seconds when waiting for either a data packet or an -acknowledgement. The default is 10. -@item garbage -The number of unrecognized bytes to permit before dropping the -connection. This must be larger than the packet size. The default is -10000. -@item errors -The number of errors (malformed packets, out of order packets, bad -checksums, or packets rejected by the remote system) to permit before -dropping the connection. The default is 100. -@item remote-window -If this is between 1 and 7 inclusive, the window size requested by the -remote system is ignored and this is used instead. This can be useful -when dealing with some poor UUCP packages. The default is 0, which -means that the remote system's request is honored. -@item remote-packet-size -If this is between 32 and 4096 inclusive the packet size requested by -the remote system is ignored and this is used instead. There is -probably no good reason to use this. The default is 0, which means that -the remote system's request is honored. -@end table - -The @samp{f} protocol is intended for use with error-correcting modems -only; it checksums each file as a whole, so any error causes the entire -file to be retransmitted. It supports the following commands, both of -which take numeric arguments: - -@table @code -@item timeout -The timeout in seconds before giving up. The default is 120. -@item retries -How many times to retry sending a file. The default is 2. -@end table - -The @samp{t} and @samp{e} protocols are intended for use over TCP or -some other communication path with end to end reliability, as they do no -checking of the data at all. They both support a single command, which -takes a numeric argument: - -@table @code -@item timeout -The timeout in seconds before giving up. The default is 120. -@end table - -The protocol parameters are reset to their default values after each -call. - -@end table - -@node File Transfer Control, Miscellaneous (sys), Protocol Selection, sys File -@subsection File Transfer Control - -@table @code - -@item call-request @var{boolean} -@findex call-request - -The @var{boolean} is checked when the local system places the call. It -determines whether the remote system may request any file transfers. -The default is yes. - -@item called-request @var{boolean} -@findex called-request - -The @var{boolean} is checked when the remote system calls in. It -determines whether the remote system may request any file transfers. -The default is yes. - -@item request @var{boolean} -@findex request - -Equivalent to specifying both @samp{call-request @var{boolean}} and -@samp{called-request @var{boolean}}. - -@item call-transfer @var{boolean} -@findex call-transfer - -The @var{boolean} is checked when the local system places the call. It -determines whether the local system may do file transfers queued up for -the remote system. The default is yes. - -@item called-transfer @var{boolean} -@findex called-transfer - -The @var{boolean} is checked when the remote system calls in. It -determines whether the local system may do file transfers queued up for -the remote system. The default is yes. - -@item transfer @var{boolean} -@findex transfer - -Equivalent to specifying both @samp{call-transfer @var{boolean}} -@samp{called-transfer @var{boolean}}. - -@item call-local-size @var{number} @var{string} -@findex call-local-size - -The @var{string} is a time string (@pxref{Time Strings}). The -@var{number} is the size in bytes of the largest file that should be -transferred at a time matching the time string if the local system -placed the call and the request was made by the local system. This -command may appear multiple times in a single alternate. If this -command does not appear, or if none of the time strings match, there are -no size restrictions. - -With all the size control commands, the size of a file from the remote -system (as opposed to a file from the local system) will only be checked -if the other system is running this package; other UUCP packages will -not understand a maximum size request, nor will they inform this package -of the size of remote files. - -@item call-remote-size @var{number} @var{string} -@findex call-remote-size - -Specify the size in bytes of the largest file that should be -transferred at a given time by remote request when the local system -placed the call. This command may appear multiple times in a single -alternate. If this command does not appear, there are no size -restrictions. - -@item called-local-size @var{number} @var{string} -@findex called-local-size - -Specify the size in bytes of the largest file that should be transferred -at a given time by local request when the remote system placed the call. -This command may appear multiple times in a single alternate. If this -command does not appear, there are no size restrictions. - -@item called-remote-size @var{number} @var{string} -@findex called-remote-size - -Specify the size in bytes of the largest file that should be transferred -at a given time by remote request when the remote system placed the -call. This command may appear multiple times in a single alternate. If -this command does not appear, there are no size restrictions. - -@item local-send @var{strings} -@findex local-send - -Specifies that files in the directories named by the @var{strings} may -be sent to the remote system when requested locally (using @code{uucp} -or @code{uux}). The directories in the list should be separated by -whitespace. A @kbd{~} may be used for the public directory. On a Unix -system, this is typically @file{/usr/spool/uucppublic}; the public -directory may be set with the @code{pubdir} command. Here is an example -of @code{local-send}: - -@example -local-send ~ /usr/spool/ftp/pub -@end example - -Listing a directory allows all files within the directory and all -subdirectories to be sent. Directories may be excluded by preceding -them with an exclamation point. For example: - -@example -local-send /usr/ftp !/usr/ftp/private ~ -@end example - -@noindent -means that all files in @file{/usr/ftp} or the public directory may be -sent, except those files in @file{/usr/ftp/private}. The list of -directories is read from left to right, and the last directory to apply -takes effect; this means that directories should be listed from top -down. The default is the root directory (i.e., any file at all may be -sent by local request). - -@item remote-send @var{strings} -@findex remote-send - -Specifies that files in the named directories may be sent to the remote -system when requested by the remote system. The default is @kbd{~}. - -@item local-receive @var{strings} -@findex local-receive - -Specifies that files may be received into the named directories when -requested by a local user. The default is @kbd{~}. - -@item remote-receive @var{strings} -@findex remote-receive - -Specifies that files may be received into the named directories when -requested by the remote system. The default is @kbd{~}. On Unix, the -remote system may only request that files be received into directories -that are writeable by the world, regardless of how this is set. - -@end table - -@node Miscellaneous (sys), Default sys File Values, File Transfer Control, sys File -@subsection Miscellaneous sys File Commands - -@table @code - -@item sequence @var{boolean} -@findex sequence - -If @var{boolean} is true, then conversation sequencing is automatically -used for the remote system, so that if somebody manages to spoof as the -remote system, it will be detected the next time the remote system -actually calls. This is false by default. - -@item command-path @var{string} -@findex command-path - -Specifies the path (a list of whitespace separated directories) to be -searched to locate commands to execute. This is only used for commands -requested by @code{uux}, not for chat programs. The default is from -@file{policy.h}. - -@item commands @var{strings} -@findex commands - -The list of commands which the remote system is permitted to execute -locally. For example: @samp{commands rnews rmail}. If the value is -@samp{ALL} (case significant), all commands may be executed. The -default is @samp{rnews rmail}. - -@item free-space @var{number} -@findex free-space - -Specify the minimum amount of file system space (in bytes) to leave free -after receiving a file. If the incoming file will not fit, it will be -rejected. This will only work when talking to another instance of this -package, since older UUCP packages do not provide the file size of -incoming files. There is no provision for reserving space, so it is -still possible for multiple @code{uucico} daemons to use up all -available file space; a sufficiently large value for @code{free-space} -will avoid this problem to some extent. The default is from -@file{policy.h}. Not all systems may be able to provide the amount of -available space. - -@item pubdir @var{string} -@findex pubdir in sys file - -Specifies the public directory that is used when @kbd{~} is specifed in -a file transfer or a list of directories. This essentially overrides -the public directory specified in the main configuration file for this -system only. The default is the public directory specified in the main -configuration file (which defaults to a value from @file{policy.h}). - -@item debug @var{string} @dots{} -@findex debug in sys file - -Set additional debugging for calls to or from the system. This may be -used to debug a connection with a specific system. It is particularly -useful when debugging incoming calls, since debugging information will -be generated whenever the call comes in. See the @code{debug} command -in the main configuration file (@pxref{Debugging Levels}) for more -details. The debugging information specified here is in addition to -that specified in the main configuration file or on the command line. - -@item max-remote-debug @var{string} @dots{} -@findex max-remote-debug - -When the system calls in, it may request that the debugging level be set -to a certain value. This command may be used to put a limit on the -debugging level which the system may request, to avoid filling up the -disk with debugging information. Only the debugging types named in the -@code{max-remote-debug} command may be turned on by the remote system. -To prohibit any debugging, use @samp{max-remote-debug none}. The -default is @samp{abnormal,chat,handshake}; to turn off these default -entries, you must use @samp{max-remote-debug none} followed by other -@code{max-remote-debug} commands specifying the settings you want. - -@item timetable @var{string} @var{string} -@findex timetable - -This is actually not specific to a system; it can appear anywhere in the -file(s). In a future release this command will probably be moved to the -main configuration file. - -The @code{timetable} defines a timetable that may be used in -subsequently appearing time strings; @ref{Time Strings}. The first -string names the timetable entry; the second is a time string. - -The following @code{timetable} commands are predefined. The NonPeak -timetable is included for compatibility. It originally described the -offpeak hours of Tymnet and Telenet, but both have since changed their -schedules. - -@example -timetable Evening Wk1705-0755,Sa,Su -timetable Night Wk2305-0755,Sa,Su2305-1655 -timetable NonPeak Wk1805-0655,Sa,Su -@end example - -If this command does not appear, then obviously no additional timetables -will be defined. - -@end table - -@node Default sys File Values, , Miscellaneous (sys), sys File -@subsection Default sys File Values - -The following are used as default values for all systems; they can be -considered as appearing before the start of the file. - -@example -timetable Evening Wk1705-0755,Sa,Su -timetable Night Wk2305-0755,Sa,Su2305-1655 -timetable NonPeak Wk1805-0655,Sa,Su -time Never -chat "" \r\c ogin:-BREAK-ogin:-BREAK-ogin: \L word: \P -chat-timeout 10 -callback n -sequence n -request y -transfer y -local-send / -remote-send ~ -local-receive ~ -remove-receive ~ -command-path [ from @file{policy.h} ] -commands rnews rmail -max-remote-debug abnormal,chat,handshake -@end example - -@node port File, dial File, sys File, Configuration Files -@section The Port Configuration File -@cindex port file -@cindex port configuration file -@cindex configuration file (port) - -The port files may be used to name and describe ports. The first -command in each file must be @code{port}. All command up to the next -@code{port} command then describe that port. There are different types -of ports; each type supports its own set of commands. Each command -indicates which types of ports support it. There may be many ports with -the same name; if a system requests a port by name then each port with -that name will be tried until an unlocked one is found. - -@table @code - -@item port @var{string} -@findex port in port file - -Introduces and names a port. - -@item type @var{string} -@findex type - -Define the type of port. The default is @samp{modem}. If this command -appears, it must immediately follow the @code{port} command. The type defines -what commands are subsequently allowed. Currently the types are: - -@table @samp -@item modem -For a modem hookup. -@item stdin -For a connection through standard input and standard output, as when -@code{uucico} is run as a login shell. -@item direct -For a direct connection to another system. -@item tcp -For a connection using TCP. -@end table - -@item protocol @var{string} -@findex protocol in port file - -Specify a list of protocols to use for this port. This is just like the -corresponding command for a system (@pxref{Protocol Selection}). A -protocol list for a system takes precedence over a list for a port. - -@item protocol-parameter @var{character} @var{strings} [ any type ] -@findex protocol-parameter in port file - -The same command as the @code{protocol-parameter} command used for -systems (@pxref{Protocol Selection}). This one takes precedence. - -@item seven-bit @var{boolean} [ any type ] -@findex seven-bit in port file - -This is only used during protocol negotiation; if the argument is -@samp{true}, it forces the selection of a protocol which works across a -seven-bit link. It does not prevent eight bit characters from being -transmitted. The default is @samp{false}. - -@item reliable @var{boolean} [ any type ] -@findex reliable in port file - -This is only used during protocol negotiation; if the argument is -@samp{false}, it forces the selection of a protocol which works across -an unreliable communication link. The default is @samp{true}. It would -be more common to specify this for a dialer rather than a port. - -@item device @var{string} [ modem and direct only ] -@findex device - -Names the device associated with this port. If the device is not named, -the port name is taken as the device. Device names are system -dependent, but a Unix example would be @file{/dev/ttyd0}. - -@item baud @var{number} [ modem and direct only ] -@findex baud in port file -@itemx speed @var{number} [modem and direct only ] -@findex speed in port file - -The speed this port runs at. If a system specifies a speed but no port -name, then all ports which match the speed will be tried in order. If -the speed is not specified here and is not specified by the system, the -natural speed of the port will be used by default. - -@item baud-range @var{number} @var{number} [ modem only ] -@findex baud-range -@itemx speed-range @var{number} @var{number} [ modem only ] -@findex speed-range - -Specify a range of speeds this port can run at. The first number is the -minimum speed, the second number is the maximum speed. These numbers -will be used when matching a system which specifies a desired speed. -The simple @code{speed} (or @code{baud}) command is still used to -determine the speed to run at if the system does not specify a speed. -For example, the command @samp{speed-range 300 19200} means that the -port will match any system which uses a speed from 300 to 19200 baud -(and will use the speed specified by the system); this could be combined -with @samp{speed 2400}, which means that when this port is used with a -system that does not specify a speed, the port will be used at 2400 -baud. - -@item carrier @var{boolean} [ modem only ] -@findex carrier in port file - -The argument indicates whether the port supports carrier. If it does -not, carrier will never be required on this port, regardless of what the -modem chat script indicates. The default is @samp{true}. - -@item dial-device @var{string} [ modem only ] -@findex dial-device - -Dialing instructions should be output to the named device, rather than -to the normal port device. The default is to output to the normal port -device. - -@item dialer @var{string} [ modem only ] -@findex dialer in port file - -Name a dialer to use. The information is looked up in the dialer file. -There is no default. Some sort of dialer information must be specified -to call out on a modem. - -@item dialer @var{string} @dots{} [ modem only ] - -Execute a dialer command. If a dialer is named (by using the first form -of this command, described just above), these commands are ignored. -They may be used to specify dialer information directly in simple -situations without needing to go to a separate file. There is no -default. Some sort of dialer information must be specified to call out -on a modem. - -@item dialer-sequence @var{strings} [ modem only ] -@findex dialer-sequence - -Name a sequence of dialers and tokens (phone numbers) to use. The first -argument names a dialer, and the second argument names a token. The -third argument names another dialer, and so on. If there are an odd -number of arguments, the phone number specified with a @code{phone} -command in the system file is used as the final token. The token is -what is used for @kbd{\D} or @kbd{\T} in the dialer chat script. If the -token in this string is @kbd{\D}, the system phone number will be used; -if it is @kbd{\T}, the system phone number will be used after undergoing -dialcodes translation. A missing final token is taken as @kbd{\D}. - -This command currently does not work if @code{dial-device} is specified; -to handle this correctly will require a more systematic notion of chat -scripts. Moreover, only the @code{complete} and @code{abort} chat -scripts from the first dialer specified are used, and only the protocol -parameters from the first dialer are used. - -@item lockname @var{string} [ modem and direct only ] -@findex lockname - -Give the name to use when locking this port. On Unix, this is the name -of the file that will be created in the lock directory. It is used as -is, so on Unix it should generally start with @samp{LCK..}. For -example, if a single port were named both @file{/dev/ttycu0} and -@file{/dev/tty0} (perhaps with different characteristics keyed on the -minor device number), then the command @code{lockname LCK..ttycu0} could -be used to force the latter to use the same lock file name as the -former. - -@item service @var{string} [ tcp only ] -@findex service - -Name the TCP port number to use. This may be a number. If not, it will -be looked up in @file{/etc/services}. If this is not specified, the -string @samp{uucp} is looked up in @file{/etc/services}. If it is not -found, port number 540 (the standard UUCP-over-TCP port number) will be -used. - -@end table - -@node dial File, Security, port File, Configuration Files -@section The Dialer Configuration File -@cindex dial file -@cindex dialer configuration file -@cindex configuration file (dial) - -The dialer configuration files define dialers. The first command in -each file must be a @code{dialer} command, which names the dialer. -Subsequent commands up to the next @code{dialer} command are associated -with the named dialer. - -@table @code - -@item dialer @var{string} -@findex dialer in dial file - -Introduces and names a dialer. - -@item chat @var{strings} -@findex chat in dial file -@item chat-timeout @var{number} -@findex chat-timeout in dial file -@item chat-fail @var{string} -@findex chat-fail in dial file -@item chat-seven-bit @var{boolean} -@findex chat-seven-bit in dial file -@item chat-program @var{strings} -@findex chat-program in dial file - -Specify a chat script to be used to dial the phone. See @ref{Chat -Scripts} for full details on chat scripts. - -Taylor UUCP will sleep for one second between attempts to dial out on a -modem. If your modem requires a longer wait period, you must start your -chat script with delays (@samp{\d} in a send string). - -The chat script will be read from and sent to the port specified by the -@code{dial-device} command for the port, if there is one. - -The following escape addition escape sequences may appear in send -strings: - -@table @kbd -@item \D -send phone number without dialcode translation -@item \T -send phone number with dialcode translation -@item \M -do not require carrier -@item \m -require carrier (fail if not present) -@end table - -See the description of the dialcodes file (@pxref{Configuration File -Names}) for a description of dialcode translation. If the port does not -support carrier (as set by the @code{carrier} command in the port file) -@kbd{\M} and @kbd{\m} are ignored. If both the port and the dialer -support carrier (as set by the @code{carrier} command in the port file -and the @code{carrier} command in the dialer file), then every chat -script implicitly begins with @kbd{\M} and ends with @kbd{\m}. There is -no default chat script for dialers. - -The following additional escape sequences may be used in -@code{chat-program}: - -@table @kbd -@item \D -phone number without dialcode translation -@item \T -phone number with dialcode translation -@end table - -If the program changes the port in any way (e.g., sets parity) the -changes will be preserved during protocol negotiation, but once the -protocol is selected it will change the port settings. - -@item dialtone @var{string} -@findex dialtone - -A string to output when dialing the phone number which causes the modem -to wait for a secondary dial tone. This is used to translate the -@kbd{=} character in a phone number. The default is a comma. - -@item pause @var{string} -@findex pause - -A string to output when dialing the phone number which causes the modem -to wait for 1 second. This is used to translate the @kbd{-} character -in a phone number. The default is a comma. - -@item carrier @var{boolean} -@findex carrier in dial file - -If the argument is @samp{true}, the dialer supports the modem carrier -signal. After the phone number is dialed, @code{uucico} will require -that carrier be on. One some systems, it will be able to wait for it. -If the argument is @samp{false}, carrier will not be required. The -default is @samp{true}. - -@item carrier-wait @var{number} -@findex carrier-wait - -If the port is supposed to wait for carrier, this may be used to -indicate how many seconds to wait. The default is 60 seconds. Only -some systems support waiting for carrier. - -@item dtr-toggle @var{boolean} @var{boolean} -@findex dtr-toggle - -If the first argument is @samp{true}, then DTR is toggled before using -the modem. This is only supported on some systems and some ports. The -second @var{boolean} need not be present; if it is, and it is -@samp{true}, the program will sleep for 1 second after toggling DTR. -The default is not to toggle DTR. - -@item complete-chat @var{strings} -@findex complete-chat -@item complete-chat-timeout @var{number} -@findex complete-chat-timeout -@item complete-chat-fail @var{string} -@findex complete-chat-fail -@item complete-chat-seven-bit @var{boolean} -@findex complete-chat-seven-bit -@item complete-chat-program @var{strings} -@findex complete-chat-program - -These commands define a chat script (@pxref{Chat Scripts}) which is run -when a call is finished normally. This allows the modem to be reset. -There is no default. No additional escape sequences may be used. - -@item complete @var{string} -@findex complete - -This is a simple use of @code{complete-chat}. It is equivalent to -@code{complete-chat "" @var{string}}; this has the effect of sending -@var{string} to the modem when a call finishes normally. - -@item abort-chat @var{strings} -@findex abort-chat -@item abort-chat-timeout @var{number} -@findex abort-chat-timeout -@item abort-chat-fail @var{string} -@findex abort-chat-fail -@item abort-chat-seven-bit @var{boolean} -@findex abort-chat-seven-bit -@item abort-chat-program @var{strings} -@findex abort-chat-program - -These commands define a chat script (@pxref{Chat Scripts}) to be run -when a call is aborted. They may be used to interrupt and reset the -modem. There is no default. No additional escape sequences may be -used. - -@item abort @var{string} -@findex abort - -This is a simple use of @code{abort-chat}. It is equivalent to -@code{abort-chat "" @var{string}}; this has the effect of sending -@var{string} to the modem when a call is aborted. - -@item protocol-parameter @var{character} @var{strings} -@findex protocol-parameter in dial file - -Set protocol parameters, just like the @code{protocol-parameter} command -in the system configuration file or the port configuration file; see -@ref{Protocol Selection}. These parameters take precedence, then those -for the port, then those for the system. - -@item seven-bit @var{boolean} -@findex seven-bit in dial file - -This is only used during protocol negotiation; if it is @samp{true}, it -forces selection of a protocol which works across a seven-bit link. It -does not prevent eight bit characters from being transmitted. The -default is @samp{false}. It would be more common to specify this for a -port than for a dialer. - -@item reliable @var{boolean} -@findex reliable in dial file - -This is only used during protocol negotiation; if it is @samp{false}, it -forces selection of a protocol which works across an unreliable -communication link. The default is @samp{true}. - -@end table - -@node Security, , dial File, Configuration Files -@section Security - -This discussion of UUCP security applies only to Unix. It is a bit -cursory; suggestions for improvement are solicited. - -UUCP is traditionally not very secure. Taylor UUCP addresses some -security issues, but is still far from being a secure system. - -If security is very important to you, then you should not permit any -external access to your computer, including UUCP. Any opening to the -outside world is a potential security risk. - -By default Taylor UUCP provides few mechanisms to secure local users of -the system from each other. You can allow increased security by putting -the owner of the UUCP programs (normally @code{uucp}) into a separate -group; the use of this is explained in the following paragraphs, which -refer to this separate group as @code{uucp-group}. - -When the @code{uucp} program is invoked to copy a file to a remote -system, it will by default copy the file into the UUCP spool directory. -When the @code{uux} program is used, the @samp{-C} switch must be used -to copy the file into the UUCP spool directory. In any case, once the -file has been copied into the spool directory, other local users will -not be able to access it. In version 1.03 there is a security hole in -that for the file to be copied it must be readable by @code{uucp}. -Changing the group of the file to @code{uucp-group} and making it group -readable will permit UUCP to read it without granting access to other -users. - -When a file is requested from a remote system, UUCP will only permit it -to be placed in a directory which is writable by the requesting user. -The directory must also be writable by UUCP. A local user can create a -directory with a group of @code{uucp-group} and set the mode to permit -group write access. This will allow the file be requested without -permitting it to be viewed by any other user. - -There is no provision for security for @code{uucp} requests (as opposed -to @code{uux} requests) made by a user on a remote system. A file sent -over by a remote request may only be placed in a directory which is -world writable, and the file will be world readable and writable. This -will permit any local user to destroy or replace the contents of the -file. A file requested by a remote system must be world readable, and -the directory it is in must be world readable. Any local user will be -able to examine, although not necessarily modify, the file before it is -sent. - -There are some security holes and race conditions that apply to the -above discussion which I will not elaborate on. They are not hidden -from anybody who reads the source code, but they are somewhat technical -and difficult (but scarcely impossible) to exploit. Suffice it to say -that even under the best of conditions UUCP is not completely secure. - -For many sites, security from remote sites is a more important -consideration. Fortunately, Taylor UUCP does provide some support in -this area. - -The greatest security is provided by always dialing out to the other -site. This prevents anybody from pretending to be the other site. Of -course, only one side of the connection can do this. - -If remote dialins must be permitted, then it is best if the dialin line -is used only for UUCP. If this is the case, then you should create a -call-in password file (@pxref{Configuration File Names}) and let -@code{uucico} do its own login prompting. For example, to let remote -sites log in on a port named @samp{entry} in the port file (@pxref{port -file}) you might invoke @samp{uucico -p entry}. This would cause -@code{uucico} to enter an endless loop of login prompts and daemon -executions. The advantage of this approach is that even if remote users -break into the system by guessing or learning the password, they will -only be able to do whatever @code{uucico} permits them to do. They will -not be able to start a shell on your system. - -If remote users can dial in and log on to your system, then you have a -security hazard more serious than that posed by UUCP. But then, you -probably knew that already. - -Once your system has connected with the remote UUCP, there is a fair -amount of control you can exercise. You can use the @code{remote-send} -and @code{remote-receive} commands to control the directories the remote -UUCP can access. You can use the @code{request} command to prevent the -remote UUCP from making any requests of your system at all; however, if -you do this it will not even be able to send you mail or news. If you -do permit remote requests, you should be careful to restrict what -commands may be executed at the remote system's request. The default is -@code{rmail} and @code{rnews}, which will suffice for most systems. - -If different remote systems call in and they must be granted different -privileges (perhaps some systems are within the same organization and -some are not) then the @code{called-login} command should be used for -each system to require that they different login names. Otherwise it -would be simple for a remote system to use the @code{myname} command and -pretend to be a different system. The @code{sequence} command can be -used to detect when one system pretended to be another, but since the -sequence numbers must be reset manually after a failed handshake this -can sometimes be more trouble than it's worth. - -@node Protocols, Hacking, Configuration Files, Top -@chapter UUCP protocol internals - -This chapter describes how the various UUCP protocols work, and -discusses some other internal UUCP issues. - -This chapter is quite technical. You do not need to understand it, or -even read it, in order to use Taylor UUCP. It is intended for people -who are interested in how UUCP code works. - -Most of the discussion covers the protocols used by all UUCP packages, -not just Taylor UUCP. Any information specific to Taylor UUCP is -indicated as such. There are some pointers to the actual functions in -the Taylor UUCP source code, for those who are extremely interested in -actual UUCP implementation. - -@menu -* Grades:: UUCP grades -* Lock Files:: UUCP lock file format -* UUCP Protocol:: The common UUCP protocol -* g Protocol:: The UUCP @samp{g} protocol -* f Protocol:: The UUCP @samp{f} protocol -* t Protocol:: The UUCP @samp{t} protocol -* e Protocol:: The UUCP @samp{e} protocol -* x Protocol:: The UUCP @samp{x} protocol -* d Protocol:: The UUCP @samp{d} protocol -* Capital G Protocol:: The UUCP @samp{G} protocol -* Documentation References:: Documentation references -@end menu - -@node Grades, Lock Files, Protocols, Protocols -@section UUCP Grades -@cindex grades - -Modern UUCP packages support grades for each command. The grades -generally range from @samp{A} (the highest) to @samp{Z} followed by -@samp{a} to @samp{z}. Taylor UUCP also supports @samp{0} to @samp{9} -before @samp{A}. Some UUCP packages may permit any ASCII character as a -grade. - -On Unix, these grades are encoded in the name of the command file. A -command file name generally has the form - -@example -C.nnnngssss -@end example - -@noindent -where @var{nnnn} is the remote system name for which the command is -queued, @var{g} is a single character grade, and @var{ssss} is a four -character sequence number. For example, a command file created for the -system @file{airs} at grade @samp{Z} might be named - -@example -C.airsZ2551 -@end example - -The remote system name will be truncated to seven characters, to ensure -that the command file name will fit in the 14 character file name limit -of the traditional Unix file system. UUCP packages which have no other -means of distinguishing which command files are intended for which -systems thus require all @emph{systems they connect to} to have names -that are unique in the first seven characters. Some UUCP packages use a -variant of this format which truncates the system name to six -characters. BNU uses a different spool directory format, which allows -up to fourteen characters to be used for each system name. The Taylor -UUCP spool directory format is configurable. The new Taylor spool -directory format permits system names to be as long as file names; the -maximum length of a file name depends on the particular Unix file system -being used. - -The sequence number in the command file name may be a decimal integer, -or it may be a hexadecimal integer, or it may contain any alphanumeric -character. Different UUCP packages are different. - -Taylor UUCP creates command files in the function -@code{zsysdep_spool_commands}. The file name is constructed by the -function @code{zsfile_name}, which knows about all the different types -of spool directories supported by Taylor UUCP. The Taylor UUCP sequence -number can contain any alphanumeric character; the next sequence number -is determined by the function @code{fscmd_seq}. - -I do not know how command grades are handled in non-Unix UUCP -packages. - -Modern UUCP packages allow you to restrict file transfer by grade -depending on the time of day. Typically this is done with a line in -the @file{Systems} (or @file{L.sys}) file like this: - -@example -airs Any/Z,Any2305-0855 ... -@end example - -This allows only grades @samp{Z} and above to be transferred at any -time. Lower grades may only be transferred at night. I believe that -this grade restriction applies to local commands as well as to remote -commands, but I am not sure. It may only apply if the UUCP package -places the call, not if it is called by the remote system. Taylor UUCP -can use the @code{timegrade} and @code{call-timegrade} commands -(@pxref{When to Call}) to achieve the same effect (and supports the -above format when reading @file{Systems} or @file{L.sys}). - -This sort of grade restriction is most useful if you know what grades -are being used at the remote site. The default grades used depend on -the UUCP package. Generally @code{uucp} and @code{uux} have different -defaults. A particular grade can be specified with the @samp{-g} option -to @code{uucp} or @code{uux}. For example, to request execution of -rnews on airs with grade @samp{d}, you might use something like - -@example -uux -gd - airs!rnews <article -@end example - -@samp{uunet} queues up mail at grade @samp{Z} and news at grade -@samp{d}. The example above would allow mail to be received at any -time, but would only permit news to be transferred at night. - -@node Lock Files, UUCP Protocol, Grades, Protocols -@section UUCP Lock File Format -@cindex lock files - -This discussion applies only to Unix. I have no idea how UUCP locks -ports on other systems. - -UUCP creates files to lock serial ports and systems. On most (if not -all) systems, these same lock files are also used by cu to coordinate -access to serial ports. On some systems getty also uses these lock -files. - -The lock file normally contains the process ID of the locking process. -This makes it easy to determine whether a lock is still valid. The -algorithm is to create a temporary file and then link it to the name -that must be locked. If the link fails because a file with that name -already exists, the existing file is read to get the process ID. If the -process still exists, the lock attempt fails. Otherwise the lock file -is deleted and the locking algorithm is retried. - -Older UUCP packages put the lock files in the main UUCP spool -directory, /usr/spool/uucp. BNU UUCP generally puts the lock files in -a directory of their own, usually /usr/spool/locks or /etc/locks. - -The original UUCP lock file format encoded the process ID as a four byte -binary number. The order of the bytes was host-dependent. BNU UUCP -stores the process ID as a ten byte ASCII decimal number, with a -trailing newline. For example, if process 1570 holds a lock file, it -would contain the eleven characters space, space, space, space, space, -space, one, five, seven, zero, newline. Some versions of UUCP add a -second line indicating which program created the lock (uucp, cu, or -getty). I have also seen a third type of UUCP lock file which did not -contain the process ID at all. - -The name of the lock file is generally "LCK.." followed by the base name -of the device. For example, to lock /dev/ttyd0 the file LCK..ttyd0 -would be created. There are various exceptions. On SCO Unix, the lock -file name is always forced to lower case even if the device name has -upper case letters. System V Release 4 UUCP forms the lock file name -using the major and minor device numbers rather than the device name -(this is pretty sensible if you think about it). - -Taylor UUCP can be configured to use various different types of locking. -The actual locking code is in the function @code{fsdo_lock}. - -@node UUCP Protocol, g Protocol, Lock Files, Protocols -@section The Common UUCP Protocol -@cindex UUCP protocol -@cindex handshake -@cindex protocol (UUCP) - -The UUCP protocol is a conversation between two UUCP packages. A UUCP -conversation consists of three parts: an initial handshake, a series -of file transfer requests, and a final handshake. - -Before the initial handshake, the caller will usually have logged in the -called machine and somehow started the UUCP package there. On Unix this -is normally done by setting the shell of the login name used to -@file{uucico}. - -@menu -* Initial Handshake:: Initial handshake -* File Requests:: File requests -* Final Handshake:: Final handshake -@end menu - -@node Initial Handshake, File Requests, UUCP Protocol, UUCP Protocol -@subsection Initial Handshake - -All messages in the initial handshake begin with a @samp{^P} (a byte -with the octal value \020) and end with a null byte (\000). - -Taylor UUCP implements the initial handshake for the calling machine in -@code{fdo_call}, and for the called machine in @code{faccept_call}. - -The initial handshake goes as follows. It is begun by the called -machine. - -@table @asis - -@item called: @samp{\020Shere=@var{hostname}\000} -The @var{hostname} is the UUCP name of the called machine. Older UUCP -packages do not output it, and simply send @samp{\020Shere\000}. - -@item caller: @samp{\020S@var{hostname} @var{options}\000} -The @var{hostname} is the UUCP name of the calling machine. The -following @var{options} may appear (or there may be none): - -@table @samp - -@item -Q@var{seq} -Report sequence number for this conversation. The sequence number is -stored at both sites, and incremented after each call. If there is a -sequence number mismatch, something has gone wrong (somebody may have -broken security by pretending to be one of the machines) and the call is -denied. If the sequence number changes on one of the machines, perhaps -because of an attempted breakin or because a disk backup was restored, -the sequence numbers on the two machines must be reconciled manually. - -@item -x@var{level} -Requests the called system to set its debugging level to the specified -value. This is not supported by all systems. Taylor UUCP currently -never generates this switch. When it sees it, it restricts the value -according to @code{max-remote-debug} (@pxref{Miscellaneous (sys)}). - -@item -p@var{grade} -@itemx -vgrade=@var{grade} -Requests the called system to only transfer files of the specified grade -or higher. This is not supported by all systems. Some systems support -@samp{-p}, some support @samp{-vgrade=}. Taylor UUCP supports both. - -@item -R -Indicates that the calling UUCP understands how to restart failed file -transmissions. Supported only by System V Release 4 UUCP. - -@item -U@var{limit} -Reports the @code{ulimit} value of the calling UUCP. The limit is -specified as a base 16 number in C notation (e.g., @samp{-U0x1000000}). -This number is the number of 512 byte blocks in the largest file which -the calling UUCP can create. The called UUCP may not transfer a file -larger than this. Supported by System V Release 4 UUCP. Taylor UUCP -understands this option, but never generates it. - -@item -N -Indicates that the calling UUCP understands the Taylor UUCP size -limiting extensions. Supported only by Taylor UUCP. - -@end table - -@item called: @samp{\020ROK\000} -There are actually several possible responses. - -@table @samp - -@item ROK -The calling UUCP is acceptable, and the handshake proceeds to the -protocol negotiation. Some options may also appear; see below. - -@item ROKN -The calling UUCP is acceptable, it specified @samp{-N}, and the called -UUCP also understands the Taylor UUCP size limiting extensions. -Supported only by Taylor UUCP. - -@item RLCK -The called UUCP already has a lock for the calling UUCP, which normally -indicates the two machines are already communicating. - -@item RCB -The called UUCP will call back. This may be used to avoid impostors. -Note that only one machine out of each pair should call back, or no -conversation will ever begin. - -@item RBADSEQ -The call sequence number is wrong (see the @samp{-Q} discussion above). - -@item RLOGIN -The calling UUCP is using the wrong login name. - -@item RYou are unknown to me -The calling UUCP is not known to the called UUCP, and the called UUCP -does not permit connections from unknown systems. - -@end table - -If the response is @samp{ROK}, the following options are supported by -System V Release 4 UUCP. - -@table @samp - -@item -R -The called UUCP knows how to restart failed file transmissions. - -@item -U@var{limit} -Reports the ulimit value of the called UUCP. The limit is specified as -a base 16 number in C notation. This number is the number of 512 byte -blocks in the largest file which the called UUCP can create. The -calling UUCP may not send a file larger than this. - -@item -x@var{level} -I'm told that this is sometimes sent by SVR4 UUCP, but I'm not sure -exactly what it means. It may request the calling UUCP to set its -debugging level to the specified value. - -@end table - -If the response is not @samp{ROK} (or @samp{ROKN}) both sides hang up -the phone, abandoning the call. - -@item called: @samp{\020P@var{protocols}\000} -The @kbd{P} is a literal character. Note that the called UUCP outputs -two strings in a row. The @var{protocols} string is a list of UUCP -protocols supported by the caller. Each UUCP protocol has a single -character name. For example, the called UUCP might send -@samp{\020Pgf\000}. - -@item caller: @samp{\020U@var{protocol}\000} -The @kbd{U} is a literal character. The calling UUCP selects which -@var{protocol} to use out of the protocols offered by the called UUCP. -If there are no mutually supported protocols, the calling UUCP sends -@samp{\020UN\000} and both sides hang up the phone. Otherwise the -calling UUCP sends something like @samp{\020Ug\000}. - -@end table - -Most UUCP packages will consider each locally supported protocol in turn -and select the first one supported by the called UUCP. With some -versions of BNU UUCP, this can be modified by giving a list of protocols -after the device name in the Devices file or the @file{Systems} file. -Taylor UUCP provides the @code{protocol} command which may be used -either for a system (@pxref{Protocol Selection}) or a port (@pxref{port -file}). - -After the protocol has been selected and the initial handshake has been -completed, both sides turn on the selected protocol. For some protocols -(notably @samp{g}) a further handshake is done at this point. - -Each protocol supports a method for sending a command to the remote -system. This method is used to transmit a series of commands between -the two UUCP packages. At all times, one package is the master and the -other is the slave. Initially, the calling UUCP is the master. - -If a protocol error occurs during the exchange of commands, both sides -move immediately to the final handshake. - -@node File Requests, Final Handshake, Initial Handshake, UUCP Protocol -@subsection File Requests - -The master will send one of four commands: @samp{S}, @samp{R}, @samp{X} -or @samp{H}. - -Any file name referred to below is either an absolute pathname beginning -with @samp{/}, a public directory pathname beginning with @samp{~/}, a -pathname relative to a user's home directory beginning with -@samp{~@var{user}/}, or a spool directory file name. File names in the -spool directory are not pathnames, but instead are converted to -pathnames within the spool directory by UUCP. They always begin with -@samp{C.} (for a command file created by @code{uucp} or @code{uux}), -@samp{D.} (for a data file created by @code{uucp}, @code{uux} or by an -execution, or received from another system for an execution), or -@samp{X.} (for an execution file created by @code{uux} or received from -another system). - -Taylor UUCP chooses which request to send next in the function -@code{fuucp}. This is also where Taylor UUCP processes incoming -commands from the remote system. - -@menu -* S Request:: S request -* R Request:: R request -* X Request:: X request -* H Request:: H request -@end menu - -@node S Request, R Request, File Requests, File Requests -@subsubsection S Request - -master: @samp{S @var{from} @var{to} @var{user} -@var{options} @var{temp} -@var{mode} @var{notify} @var{size}} - -The @samp{S} and the @samp{-} are literal characters. This is a request -by the master to send a file to the slave. Taylor UUCP handles the -@samp{S} request in the function @code{fsend_file}. - -@table @var - -@item from -The name of the file to send. If the @samp{C} option does not appear in -@var{options}, the master will actually open and send this file. -Otherwise the file has been copied to the spool directory, where it is -named @var{temp}. The slave ignores this field unless @var{to} is a -directory, in which case the basename of @var{from} will be used as the -file name. If @var{from} is a spool directory filename, it must be a -data file created for or by an execution, and must begin with @samp{D.}. - -@item to -The name to give the file on the slave. If this field names a directory -the file is placed within that directory with the basename of -@var{from}. A name ending in @samp{/} is taken to be a directory even -if one does not already exist with that name. If @var{to} begins with -@samp{X.}, an execution file will be created on the slave. Otherwise, -if @var{to} begins with @samp{D.} it names a data file to be used by -some execution file. Otherwise, @var{to} should not be in the spool -directory. - -@item user -The name of the user who requested the transfer. - -@item options -A list of options to control the transfer. The following options are -defined (all options are single characters): - -@table @samp - -@item C -The file has been copied to the spool directory (the master should use -@var{temp} rather than @var{from}). - -@item c -The file has not been copied to the spool directory (this is the -default). - -@item d -The slave should create directories as necessary (this is the default). - -@item f -The slave should not create directories if necessary, but should fail -the transfer instead. - -@item m -The master should send mail to @var{user} when the transfer is complete. - -@item n -The slave should send mail to @var{notify} when the transfer is -complete. - -@end table - -@item temp -If the @samp{C} option appears in @var{options}, this names the file to -be sent. Otherwise if @var{from} is in the spool directory, @var{temp} -is the same as @var{from}. Otherwise @var{temp} is a dummy string, -normally @samp{D.0}. After the transfer has been succesfully completed, -the master will delete the file @var{temp}. - -@item mode -This is an octal number giving the mode of the file on the master. If -the file is not in the spool directory, the slave will always create it -with mode 0666, except that if (@var{mode} & 0111) is not zero (the file -is executable), the slave will create the file with mode 0777. If the -file is in the spool directory, some UUCP packages will use the -algorithm above and some will always create the file with mode 0600 -(Taylor UUCP does the latter). - -@item notify -This field is only used if the @samp{n} option appears in @var{options}. -Otherwise, it may not appear, or it may be the string @samp{dummy}, or -it may simply be a pair of double quotes. If the @samp{n} option is -specified, then when the transfer is successfully completed the slave -will send mail to @var{notify}, which must be a legal mailing address on -the slave. - -@item size -This field is only present when doing size negotiation, either with -Taylor UUCP or SVR4 UUCP. It is the size of the file in bytes. SVR4 -UUCP sends the size in base 16 as 0x@dots{} while Taylor UUCP sends the -size as a decimal integer (a later version of Taylor UUCP will probably -change to the SVR4 behaviour). - -@end table - -The slave then responds with an S command response. Taylor UUCP -generates these responses in @code{freceive_file} and -@code{ftransfer_fail}. - -@table @samp - -@item SY @var{start} -The slave is willing to accept the file, and file transfer begins. The -@var{start} field will only be present when using SVR4 file restart. It -specifies the byte offset into the file at which to start sending. If -this is a new file, @var{start} will be 0x0. - -@item SN2 -The slave denies permission to transfer the file. This can mean that -the destination directory may not be accessed, or that no requests are -permitted. It implies that the file transfer will never succeed. - -@item SN4 -The slave is unable to create the necessary temporary file. This -implies that the file transfer might succeed later. - -@item SN6 -This is only used by Taylor UUCP size negotiation. It means that the -slave considers the file too large to transfer at the moment, but it may -be possible to transfer it at some other time. - -@item SN7 -This is only used by Taylor UUCP size negotiation. It means that the -slave considers the file too large to ever transfer. - -@end table - -If the slave responds with @samp{SY}, a file transfer begins. When the -file transfer is complete, the slave sends a @samp{C} command response. -Taylor UUCP generates this confirmation in @code{fprecfile_confirm} and -checks it in @code{fpsendfile_confirm}. - -@table @samp - -@item CY -The file transfer was successful. - -@item CN5 -The temporary file could not be moved into the final location. This -implies that the file transfer will never succeed. - -@end table - -After the @samp{C} command response has been received (in the @samp{SY} -case) or immediately (in an @samp{SN} case) the master will send another -command. - -@node R Request, X Request, S Request, File Requests -@subsubsection R Request - -master: @samp{R @var{from} @var{to} @var{user} -@var{options} -@var{size}} - -The @samp{R} and the @samp{-} are literal characters. This is a request -by the master to receive a file from the slave. I do not know how SVR4 -UUCP implements file transfer restart in this case. Taylor UUCP -implements the @samp{R} request in @code{freceive_file}. - -@table @var - -@item from -This is the name of the file on the slave which the master wishes to -receive. It must not be in the spool directory, and it may not contain -any wildcards. - -@item to -This is the name of the file to create on the master. I do not believe -that it can be a directory. It may only be in the spool directory if -this file is being requested to support an execution either on the -master or on some system other than the slave. - -@item user -The name of the user who requested the transfer. - -@item options -A list of options to control the transfer. The following options are -defined (all options are single characters): - -@table @samp - -@item d -The master should create directories as necessary (this is the default). - -@item f -The master should not create directories if necessary, but should fail -the transfer instead. - -@item m -The master should send mail to @var{user} when the transfer is complete. - -@end table - -@item size -This only appears if Taylor UUCP size negotiation is being used. It -specifies the largest file which the master is prepared to accept (when -using SVR4 UUCP, this was specified in the @samp{-U} option during the -initial handshake). - -@end table - -The slave then responds with an @samp{R} command response. Taylor UUCP -generates these responses in @code{fsend_file} and -@code{ftransfer_fail}. - -@table @samp - -@item RY @var{mode} -The slave is willing to send the file, and file transfer begins. -@var{mode} is the octal mode of the file on the slave. The master uses -this to set the mode of the file on the master's system just as the -slave does the @var{mode} argument in the send command (@pxref{S -Request}). - -@item RN2 -The slave is not willing to send the file, either because it is not -permitted or because the file does not exist. This implies that the -file request will never succeed. - -@item RN6 -This is only used by Taylor UUCP size negotiation. It means that the -file is too large to send, either because of the size limit specifies by -the master or because the slave considers it too large. The file -transfer might succeed later, or it might not (this will be cleared up -in a later release of Taylor UUCP). - -@end table - -If the slave responds with @samp{RY}, a file transfer begins. When the -file transfer is complete, the master sends a @samp{C} command. The -slave pretty much ignores this, although it may log it. Taylor UUCP -sends this confirmation in @code{fprecfile_confirm} and checks it in -@code{fpsendfile_confirm}. - -@table @samp - -@item CY -The file transfer was successful. - -@item CN5 -The temporary file could not be moved into the final -location. - -@end table - -After the @samp{C} command response has been sent (in the @samp{RY} -case) or immediately (in an @samp{RN} case) the master will send another -command. - -@node X Request, H Request, R Request, File Requests -@subsubsection X Request - -master: @samp{X @var{from} @var{to} @var{user} -@var{options}} - -The @samp{X} and the @samp{-} are literal characters. This is a request -by the master to, in essence, execute @code{uucp} on the slave. The -slave should execute @samp{uucp @var{from} @var{to}}. Taylor UUCP -generates the @samp{X} request in @code{fxcmd} and handles it in -@code{fdo_xcmd}. - -@table @var - -@item from -This is the name of the file or files on the slave which the master -wishes to transfer. Any wildcards are expanded on the slave. If the -master is requesting that the files be transferred to itself, the -request would normally contain wildcard characters, since otherwise an -@samp{R} command would suffice. The master can also use this command to -request that the slave transfer files to a third system. - -@item to -This is the name of the file or directory to which the files should be -transferred. This will normally use a UUCP name. For example, if the -master wishes to receive the files itself, it would use -@file{@var{master}!@var{path}}. - -@item user -The name of the user who requested the transfer. - -@item options -A list of options to control the transfer. It is not clear which, if -any, options are supported by most UUCP packages. Taylor UUCP ignores -the options field. - -@end table - -The slave then responds with an X command response. Taylor UUCP sends -this response in either @code{fxcmd_confirm} or @code{ftransfer_fail}. - -@table @samp - -@item XY -The request was accepted, and the appropriate file transfer commands -have been queued up for later processing. - -@item XN -The request was denied. No particular reason is given. - -@end table - -In either case, the master will then send another command. - -@node H Request, , X Request, File Requests -@subsubsection H Request - -master: @samp{H} - -This is used by the master to hang up the connection. The slave will -respond with an @samp{H} command response. Taylor UUCP processes this -request in @code{fhangup_request}, @code{fhangup_reply}, and -@code{fgetcmd}. - -@table @samp - -@item HY -The slave agrees to hang up the connection. In this case the master -sends another @samp{HY} command. In some UUCP packages, including -Taylor UUCP, the slave will then send a third @samp{HY} command. At -this point the protocol is shut down, and the final handshake is begun. - -@item HN -The slave does not agree to hang up. In this case the master and the -slave exchange roles. The next command will be sent by the former -slave, which is the new master. The roles may be reversed several times -during a single connection. - -@end table - -@node Final Handshake, , File Requests, UUCP Protocol -@subsection Final Handshake - -After the protocol has been shut down, the final handshake is -performed. This handshake has no real purpose, and some UUCP packages -simply drop the connection rather than do it (in fact, some will drop -the connection immediately after both sides agree to hangup, without -even closing down the protocol). Taylor UUCP always sends the -appropriate final handshake string (in @code{fdo_call} or -@code{faccept_call}) but ignores the handshake string from the other -side unless it is in @samp{handshake} debugging mode. - -@table @asis - -@item caller: @samp{\020OOOOOO\000} - -@item called: @samp{\020OOOOOOO\000} - -@end table - -That is, the calling UUCP sends six letter O's and the called UUCP -replies with seven letter O's. Some UUCP packages always send six O's. - -@node g Protocol, f Protocol, UUCP Protocol, Protocols -@section The UUCP @samp{g} Protocol -@cindex g protocol -@cindex protocol (g) - -The @samp{g} protocol is a packet based flow controlled error correcting -protocol that requires an eight bit clear connection. It is the -original UUCP protocol, and is supported by all UUCP implementations. -Many implementations of it are only able to support small window and -packet sizes, specifically a window size of 3 and a packet size of 64 -bytes, but the protocol itself can support up to a window size of 7 and -a packet size of 4096 bytes. Complaints about the inefficiency of the -@samp{g} protocol generally refer to specific implementations, rather -than the correctly implemented protocol. - -The @samp{g} protocol was originally designed for general packet drivers, -and thus contains some features that are not used by UUCP, including -an alternate data channel and the ability to renegotiate packet and -window sizes during the communication session. - -The @samp{g} protocol is spoofed by many Telebit modems. When spoofing is -in effect, each Telebit modem uses the @samp{g} protocol to communicate -with the attached computer, but the data between the modems is sent -using a Telebit proprietary error correcting protocol. This allows -for very high throughput over the Telebit connection, which, because -it is half-duplex, would not normally be able to handle the @samp{g} -protocol very well at all. - -This discussion of the @samp{g} protocol explains how it works, but does -not discuss useful error handling techniques. Some discussion of this -can be found in Jamie E. Hanrahan's paper (@pxref{Documentation -references}). A detailed examination of the source code would also be -profitable. - -The Taylor UUCP code to handle the @samp{g} protocol is in the file -@file{protg.c}. There are a number of functions; the most important -ones are @code{fgstart}, @code{fgsend_control}, @code{fgsenddata}, and -@code{fgprocess_data}. - -All @samp{g} protocol communication is done with packets. Each packet -begins with a six byte header. Control packets consist only of the -header. Data packets contain additional data. - -The header is as follows: - -@table @asis - -@item @samp{\020} -Every packet begins with a @samp{^P}. - -@item @var{k} (1 <= @var{k} <= 9) -@ifinfo -The @var{k} value is always 9 for a control packet. For a data packet, -the @var{k} value indicates how must data follows the six byte header. -The amount of data is 2 ** (@var{k} + 4), where ** indicates -exponentiation. Thus a @var{k} value of 1 means 32 data bytes and a -@var{k} value of 8 means 4096 data bytes. The @var{k} value for a data -packet must be between 1 and 8 inclusive. -@end ifinfo -@iftex -The @var{k} value is always 9 for a control packet. For a data packet, -the @var{k} value indicates how must data follows the six byte header. -The amount of data is @math{2^{@var{k} + 4}}. Thus a @var{k} value of 1 -means 32 data bytes and a @var{k} value of 8 means 4096 data bytes. The -@var{k} value for a data packet must be between 1 and 8 inclusive. -@end iftex - -@item checksum low byte -@itemx checksum high byte -The checksum value is described below. - -@item control byte -The control packet indicates the type of packet, and is described below. - -@item xor byte -This byte is the xor of @var{k}, the checksum low byte, the checksum -high byte and the control byte (i.e. the second, third, fourth and fifth -header bytes). It is used to ensure that the header data is valid. - -@end table - -The control byte in the header is composed of three bit fields, referred -to here as @var{tt} (two bits), @var{xxx} (three bits) and @var{yyy} -(three bits). The complete byte is @var{ttxxxyyy}, or (@var{tt} << 6) + -(@var{xxx} << 3) + @var{yyy}. - -The @var{tt} field takes on the following values: - -@table @asis - -@item 0 -This is a control packet. In this case the @var{k} byte in the header -must be 9. The @var{xxx} field indicates the type of control packet; -the types are described below. - -@item 1 -This is an alternate data channel packet. This is not used by UUCP. - -@item 2 -This is a data packet, and the entire contents of the attached data -field (whose length is given by the @var{k} byte in the header) are -valid. The @var{xxx} and @var{yyy} fields are described below. - -@item 3 -This is a short data packet. Let the length of the data field (as given -by the @var{k} byte in the header) be @code{l}. Let the first byte in -the data field be @code{b1}. If @code{b1} is less than 128 (if the most -significant bit of @code{b1} is 0), then there are @code{l - b1} valid -bytes of data in the data field, beginning with the second byte. If -@code{b1 >= 128}, let @code{b2} be the second byte in the data field. -Then there are @code{l - ((b1 & 0x7f) + (b2 << 7))} valid bytes of data -in the data field, beginning with the third byte. In all cases @code{l} -bytes of data are sent (and all data bytes participate in the checksum -calculation) but some of the trailing bytes may be dropped by the -receiver. The @var{xxx} and @var{yyy} fields are described below. - -@end table - -In a data packet (short or not) the @var{xxx} field gives the sequence -number of the packet. Thus sequence numbers can range from 0 to 7, -inclusive. The @var{yyy} field gives the sequence number of the last -correctly received packet. - -Each communication direction uses a window which indicates how many -unacknowledged packets may be transmitted before waiting for an -acknowledgement. The window may range from 1 to 7 packets, and may be -different in each direction. For example, if the window is 3 and the -last packet acknowledged was packet number 6, packet numbers 7, 0 and 1 -may be sent but the sender must wait for an acknowledgement before -sending packet number 2. This acknowledgement could come as the -@var{yyy} field of a data packet or as the @var{yyy} field of a -@code{RJ} or @code{RR} control packet (described below). - -Each packet must be transmitted in order (the sender may not skip -sequence numbers). Each packet must be acknowledged, and each packet -must be acknowledged in order. - -In a control packet, the @var{xxx} field takes on the following values: - -@table @asis - -@item 1 @code{CLOSE} -The connection should be closed immediately. This is typically sent -when one side has seen too many errors and wants to give up. It is also -sent when shutting down the protocol. If an unexpected @code{CLOSE} -packet is received, a @code{CLOSE} packet should be sent in reply and -the @samp{g} protocol should halt, causing UUCP to enter the final -handshake. - -@item 2 @code{RJ} or @code{NAK} -The last packet was not received correctly. The @var{yyy} field -contains the sequence number of the last correctly received packet. - -@item 3 @code{SRJ} -Selective reject. The @var{yyy} field contains the sequence number of a -packet that was not received correctly, and should be retransmitted. -This is not used by UUCP, and most implementations will not recognize -it. Taylor UUCP will recognize it but not generate it. - -@item 4 @code{RR} or @code{ACK} -Packet acknowledgement. The @var{yyy} field contains the sequence -number of the last correctly received packet. - -@item 5 @code{INITC} -Third initialization packet. The @var{yyy} field contains the maximum -window size to use. - -@item 6 @code{INITB} -@ifinfo -Second initialization packet. The @var{yyy} field contains the packet -size to use. It requests a size of 2 ** (@var{yyy} + 5). Note that -this is not the same coding used for the @var{k} byte in the packet -header (it is 1 less). Some UUCP implementations can handle any packet -size up to that specified; some can only handled exactly the size -specified. Taylor UUCP will always accept any packet size. -@end ifinfo -@iftex -Second initialization packet. The @var{yyy} field contains the packet -size to use. It requests a size of @math{2^{@var{yyy}+5}}. Note that -this is not the same coding used for the @var{k} byte in the packet -header (it is 1 less). Some UUCP implementations can handle any packet -size up to that specified; some can only handled exactly the size -specified. Taylor UUCP will always accept any packet size. -@end iftex - -@item 7 @code{INITA} -First initialization packet. The @var{yyy} field contains the maximum -window size to use. - -@end table - -To compute the checksum, call the control byte (the fifth byte in the -header) @code{c}. - -The checksum of a control packet is simply @code{0xaaaa - c}. - -The checksum of a data packet is @code{0xaaaa - (@var{check} ^ c)} -(@code{^} denotes exclusive or, as in C), and @code{@var{check}} is the -result of the following routine run on the contents of the data field -(every byte in the data field participates in the checksum, even for a -short data packet). Below is the routine used by Taylor UUCP; it is a -slightly modified version of a routine which John Gilmore patched from -G.L. Chesson's original paper. The @code{z} argument points to the -data and the @code{c} argument indicates how much data there is. - -@example -int -igchecksum (z, c) - register const char *z; - register int c; -@{ - register unsigned int ichk1, ichk2; - - ichk1 = 0xffff; - ichk2 = 0; - - do - @{ - register unsigned int b; - - /* Rotate ichk1 left. */ - if ((ichk1 & 0x8000) == 0) - ichk1 <<= 1; - else - @{ - ichk1 <<= 1; - ++ichk1; - @} - - /* Add the next character to ichk1. */ - b = *z++ & 0xff; - ichk1 += b; - - /* Add ichk1 xor the character position in the buffer - counting from the back to ichk2. */ - ichk2 += ichk1 ^ c; - - /* If the character was zero, or adding it to ichk1 - caused an overflow, xor ichk2 to ichk1. */ - if (b == 0 || (ichk1 & 0xffff) < b) - ichk1 ^= ichk2; - @} - while (--c > 0); - - return ichk1 & 0xffff; -@} -@end example - -When the @samp{g} protocol is started, the calling UUCP sends an INITA -control packet with the window size it wishes the called UUCP to use. -The called UUCP responds with an INITA packet with the window size it -wishes the calling UUCP to use. Pairs of INITB and INITC packets are -then similarly exchanged. When these exchanges are completed, the -protocol is considered to have been started. The window size is sent -twice, with both the INITA and the INITC packets. - -When a UUCP package transmits a command, it sends one or more data -packets. All the data packets will normally be complete, although some -UUCP packages may send the last one as a short packet. The command -string is sent with a trailing null byte, to let the receiving package -know when the command is finished. Some UUCP packages require the last -byte of the last packet sent to be null, even if the command ends -earlier in the packet. Some packages may require all the trailing bytes -in the last packet to be null, but I have not confirmed this. - -When a UUCP package sends a file, it will send a sequence of data -packets. The end of the file is signalled by a short data packet -containing zero valid bytes (it will normally be preceeded by a short -data packet containing the last few bytes in the file). - -Note that the sequence numbers cover the entire communication session, -including both command and file data. - -When the protocol is shut down, each UUCP package sends a @code{CLOSE} -control packet. - -@node f Protocol, t Protocol, g Protocol, Protocols -@section The UUCP @samp{f} Protocol -@cindex f protocol -@cindex protocol (f) - -The @samp{f} protocol is a seven bit protocol which checksums an entire -file at a time. It only uses the characters between \040 and \176 -(ASCII space and @samp{~}) inclusive as well as the carriage return -character. It can be very efficient for transferring text only data, -but it is very inefficient at transferring eight bit data (such as -compressed news). It is not flow controlled, and the checksum is fairly -insecure over large files, so using it over a serial connection requires -handshaking (@code{XON}/@code{XOFF} can be used) and error correcting -modems. Some people think it should not be used even under those -circumstances. - -I believe the @samp{f} protocol originated in BSD versions of UUCP. It was -originally intended for transmission over X.25 PAD links. - -The Taylor UUCP code for the @samp{f} protocol is in @file{protf.c}. - -The @samp{f} protocol has no startup or finish protocol. However, both -sides typically sleep for a couple of seconds before starting up, -because they switch the terminal into @code{XON}/@code{XOFF} mode and -want to allow the changes to settle before beginning transmission. - -When a UUCP package transmits a command, it simply sends a string -terminated by a carriage return. - -When a UUCP package transmits a file, each byte b of the file is -translated according to the following table: - -@example - 0 <= b <= 037: 0172, b + 0100 (0100 to 0137) - 040 <= b <= 0171: b ( 040 to 0171) - 0172 <= b <= 0177: 0173, b - 0100 ( 072 to 077) - 0200 <= b <= 0237: 0174, b - 0100 (0100 to 0137) - 0240 <= b <= 0371: 0175, b - 0200 ( 040 to 0171) - 0372 <= b <= 0377: 0176, b - 0300 ( 072 to 077) -@end example - -That is, a byte between \040 and \171 inclusive is transmitted as is, -and all other bytes are prefixed and modified as shown. - -When all the file data is sent, a seven byte sequence is sent: two bytes -of \176 followed by four ASCII bytes of the checksum as printed in base -16 followed by a carriage return. For example, if the checksum was -0x1234, this would be sent: "\176\1761234\r". - -The checksum is initialized to 0xffff. For each byte that is sent it is -modified as follows (where @code{b} is the byte before it has been -transformed as described above): - -@example -/* Rotate the checksum left. */ -if ((ichk & 0x8000) == 0) - ichk <<= 1; -else - @{ - ichk <<= 1; - ++ichk; - @} - -/* Add the next byte into the checksum. */ -ichk += b; -@end example - -When the receiving UUCP sees the checksum, it compares it against its -own calculated checksum and replies with a single character followed -by a carriage return. - -@table @samp - -@item G -The file was received correctly. - -@item R -The checksum did not match, and the file should be resent from the -beginning. - -@item Q -The checksum did not match, but too many retries have occurred and the -communication session should be abandoned. - -@end table - -The sending UUCP checks the returned character and acts accordingly. - -@node t Protocol, e Protocol, f Protocol, Protocols -@section The UUCP @samp{t} Protocol -@cindex t protocol -@cindex protocol (t) - -The @samp{t} protocol is intended for TCP links. It does no error -checking or flow control, and requires an eight bit clear channel. - -I believe the @samp{t} protocol originated in BSD versions of UUCP. - -The Taylor UUCP code for the @samp{t} protocol is in @file{prott.c}. - -When a UUCP package transmits a command, it first gets the length of the -command string, @var{c}. It then sends ((@var{c} / 512) + 1) * 512 -bytes (the smallest multiple of 512 which can hold @var{c} bytes plus a -null byte) consisting of the command string itself followed by trailing -null bytes. - -When a UUCP package sends a file, it sends it in blocks. Each block -contains at most 1024 bytes of data. Each block consists of four bytes -containing the amount of data in binary (most significant byte first, -the same format as used by the Unix function @code{htonl}) followed by -that amount of data. The end of the file is signalled by a block -containing zero bytes of data. - -@node e Protocol, x Protocol, t Protocol, Protocols -@section The UUCP @samp{e} Protocol -@cindex e protocol -@cindex protocol (e) - -The @samp{e} protocol is similar to the @samp{t} protocol. It does no -flow control or error checking and is intended for use over TCP. - -The @samp{e} protocol originated in versions of BNU UUCP. - -The Taylor UUCP code for the @samp{e} protocol is in @file{prote.c}. - -When a UUCP package transmits a command, it simply sends the command as -an ASCII string terminated by a null byte. - -When a UUCP package transmits a file, it sends the complete size of the -file as an ASCII decimal number. The ASCII string is padded out to 20 -bytes with null bytes (i.e., if the file is 1000 bytes long, it sends -@samp{1000\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0}). It then sends the entire -file. - -@node x Protocol, d Protocol, e Protocol, Protocols -@section The UUCP @samp{x} Protocol - -I believe that the @samp{x} protocol was intended for use over X.25 -virtual circuits. It relies on a write of zero bytes being read as zero -bytes without stopping communication. I have heard that it does not -work correctly. If someone would care to fill this in more, I would be -grateful. Taylor UUCP does not implement the @samp{x} protocol. - -@node d Protocol, Capital G Protocol, x Protocol, Protocols -@section The UUCP @samp{d} Protocol - -This is apparently used for DataKit connections, and relies on a write -of zero bytes being read as zero bytes, much as the @samp{x} protocol -does. I don't really know anything else about it. Taylor UUCP does not -implement the @samp{d} protocol. - -@node Capital G Protocol, Documentation References, d Protocol, Protocols -@section The UUCP @samp{G} Protocol - -The @samp{G} protocol is apparently simply the @samp{g} protocol, except -that it is known to support all possible window and packet sizes. It -was introduced by SVR4 UUCP; the SVR4 implementation of the @samp{g} -protocol is apparently fixed at a packet size of 64 and a window size of -7. Taylor UUCP does not recognize the @samp{G} protocol. It does -support all window and packet sizes for the @samp{g} protocol. - -@node Documentation References, , Capital G Protocol, Protocols -@section Documentation References - -I took a lot of the information from Jamie E. Hanrahan's paper in the -Fall 1990 DECUS Symposium, and from Managing UUCP and Usenet by Tim -O'Reilly and Grace Todino (with contributions by several other people). -The latter includes most of the former, and is published by O'Reilly & -Associates, Inc. - -Some information is originally due to a Usenet article by Chuck Wegrzyn. -The information on the @samp{g} protocol comes partially from a paper by -G.L. Chesson of Bell Laboratories, partially from Jamie E. Hanrahan's -paper, and partially from source code by John Gilmore. The information -on the @samp{f} protocol comes from the source code by Piet Berteema. -The information on the @samp{t} protocol comes from the source code by -Rick Adams. The information on the @samp{e} protocol comes from a -Usenet article by Matthias Urlichs. - -@node Hacking, Acknowledgements, Protocols, Top -@chapter Hacking Taylor UUCP - -This chapter provides the briefest of guides to the Taylor UUCP source -code itself. - -@menu -* System Dependence:: System Dependence -* Naming Conventions:: Naming Conventions -* Patches:: Patches -@end menu - -@node System Dependence, Naming Conventions, Hacking, Hacking -@section System Dependence - -The code is carefully segregated into a system independent portion and a -system dependent portion. The system dependent code is in @file{sys?.*} -and @file{tcp.c}. Note that @file{sysh.*} is included as -@file{sysdep.h}. Currently the only system dependent files are for -Unix, and the file name for all of them ends in @file{.unx}. Hopefully -the code will eventually be ported to other systems. - -With the right configuration parameters, the system independent code -calls only ANSI C functions. Some of the less common ANSI C functions -are also provided in @file{util.c}. The replacement function -@code{strtol} in @file{util.c} assumes that the characters @kbd{A} to -@kbd{F} and @kbd{a} to @kbd{f} appear in strictly sequential order. The -function @code{igradecmp} in @file{config.c} assumes that the upper and -lower case letters appear in order. Both assumptions are true for ASCII -and EBCDIC, but neither is guaranteed by ANSI C. The replacement -function @code{memmove} in @file{util.c} assumes that two arbitrary -pointers may be safely compared. Disregarding these caveats, I believe -that the system independent portion of the code is strictly conforming. - -That's not too exciting, since all the work is done in the system -dependent code. I think that this code can conform to POSIX 1003.1, -given the right compilation parameters. I'm a bit less certain about -this, though. - -The code is in use on a 16 bit segmented system with no function -prototypes, so I'm certain that all casts to long and pointers are done -when necessary. - -The code uses alloca extensively. It comes with a simple replacement, -in @file{alloca.c} (otherwise I would lost ANSI C conformance, after -all). Using a real @code{alloca} function will be considerably more -efficient. It will also cause significant stack usage, which may be a -problem on systems without virtual memory. - -@node Naming Conventions, Patches, System Dependence, Hacking -@section Naming Conventions - -I use a modified Hungarian naming convention for my variables and -functions. As with all naming conventions, the code is rather opaque if -you are not familiar with it, but becomes clear and easy to use with -time. - -The first character indicates the type of the variable (or function -return value). Sometimes additional characters are used. I use the -following type prefixes: - -@table @samp -@item a -array; the next character is the type of an element -@item b -byte or character -@item c -count of something -@item e -stdio FILE * -@item f -boolean -@item i -generic integer -@item l -double -@item o -file descriptor (as returned by open, creat, etc.) -@item p -generic pointer -@item q -pointer to structure -@item s -structure -@item u -void (function return values only) -@item z -character string -@end table - -A generic pointer ('p') is sometimes a @code{void *}, sometimes a -function pointer in which case the prefix is pf, and sometimes a pointer -to another type, in which case the next character is the type to which -it points (pf is overloaded). - -An array of strings (@code{char *[]}) would be named @code{az} (array of -string). If this array were passed to a function, the function -parameter would be named @code{paz} (pointer to array of string). - -Note that the variable name prefixes do not necessarily indicate the -type of the variable. For example, a variable prefixed with i may be -int, long or short. Similarly, a variable prefixed with b may be a char -or an int; for example, the return value of getchar would be caught in -an int variable prefixed with b. - -For a non-local variable (extern or file static), the first character -after the type prefix is capitalized. - -Most static variables and functions use another letter after the type -prefix to indicate which module they come from. This is to help -distinguish different names in the debugger. For example, all static -functions in @file{protg.c}, the @samp{g} protocol source code, use a -module prefix of @samp{g}. This isn't too useful, as a number of -modules use a module prefix of @samp{s}. - -@node Patches, , Naming Conventions, Hacking -@section Patches - -I am always grateful for any patches sent in. Much of the flexibility -and portability of the code is due to other people. Please do not -hesitate to send me any changes you have found necessary or useful. - -I rarely apply the patches directly. Instead I work my way through them -and apply each one separately. This ensures that the naming remains -consistent and that I understand all the code. - -@node Acknowledgements, Index (concepts), Hacking, Top -@chapter Acknowledgements - -This is a list of people who gave help or suggestions while I was -working on the Taylor UUCP project. Appearance on this list does not -constitute endorsement of the program, particularly since some of the -comments were criticisms. I've probably left some people off, and I -apologize for any oversight; it does not mean your contribution was -unappreciated. - -@ifinfo -First of all, I would like to thank the people at Infinity Development -Systems (formerly AIRS, which lives on in the domain name, at least for -now) for permitting me to use their computers and @file{uunet} access. -I would also like to thank Richard Stallman @file{<rms@@gnu.ai.mit.edu>} -for founding the Free Software Foundation and John Gilmore -@file{<gnu@@cygnus.com>} for writing the initial version of gnuucp which -was a direct inspiration for this somewhat larger project. Chip -Salzenberg @file{<chip@@tct.com>} contributed many early patches. -Franc,ois Pinard @file{<pinard@@iro.umontreal.ca>} tirelessly tested the -code and suggested many improvements. He also put together the initial -version of this document. Finally, Verbus M. Counts -@file{<verbus@@westmark.com>} and Centel Federal Systems, Inc. deserve -special thanks, since they actually paid me money to port this code to -System III. -@end ifinfo -@iftex -First of all, I would like to thank the people at Infinity Development -Systems (formerly AIRS, which lives on in the domain name, at least for -now) for permitting me to use their computers and @file{uunet} access. -I would also like to thank Richard Stallman @file{<rms@@gnu.ai.mit.edu>} -for founding the Free Software Foundation and John Gilmore -@file{<gnu@@cygnus.com>} for writing the initial version of gnuucp which -was a direct inspiration for this somewhat larger project. Chip -Salzenberg @file{<chip@@tct.com>} contributed many early patches. -@tex -Fran\c cois Pinard -@end tex -@file{<pinard@@iro.umontreal.ca>} tirelessly tested -the code and suggested many improvements. He also put together the -initial version of this document. Finally, Verbus M. Counts -@file{<verbus@@westmark.com>} and Centel Federal Systems, Inc. deserve -special thanks, since they actually paid me money to port this code to -System III. -@end iftex - -In alphabetical order: - -@example -"Earle F. Ake - SAIC" @file{<ake@@Dayton.SAIC.COM>} -@file{mra@@searchtech.com} (Michael Almond) -@file{cambler@@zeus.calpoly.edu} (Christopher J. Ambler) -Brian W. Antoine @file{<briana@@tau-ceti.isc-br.com>} -@file{jantypas@@soft21.s21.com} (John Antypas) -@file{nba@@sysware.DK} (Niels Baggesen) -@file{uunet!hotmomma!sdb} (Scott Ballantyne) -@file{magus!dolphin!zack} (Zacharias Beckman) -@file{mike@@mbsun.ann-arbor.mi.us} (Mike Bernson) -@file{bob@@usixth.sublink.org} (Roberto Biancardi) -Marc Boucher @file{<marc@@CAM.ORG>} -@file{dean@@coplex.com} (Dean Brooks) -@file{dave@@dlb.com} (Dave Buck) -@file{gordon@@sneaky.lonestar.org} (Gordon Burditt) -@file{mib@@gnu.ai.mit.edu} (Michael I Bushnell) -Brian Campbell @file{<brianc@@quantum.on.ca>} -@file{verbus@@westmark.westmark.com} (Verbus M. Counts) -@file{cbmvax!snark.thyrsus.com!cowan} (John Cowan) -@file{denny@@dakota.alisa.com} (Bob Denny) -@file{dje@@ersys.edmonton.ab.ca} (Doug Evans) -@file{fenner@@jazz.psu.edu} (Bill Fenner) -"David J. Fiander" @file{<golem!david@@news.lsuc.on.ca>} -Thomas Fischer @file{<batman@@olorin.dark.sub.org>} -@file{erik@@eab.retix.com} (Erik Forsberg) -Lele Gaifax @file{<piggy@@idea.sublink.org>} -@file{Peter.Galbavy@@micromuse.co.uk} -@file{hunter@@phoenix.pub.uu.oz.au} (James Gardiner [hunter]) -Terry Gardner @file{<cphpcom!tjg01>} -@file{jimmy@@tokyo07.info.com} (Jim Gottlieb) -@file{ryan@@cs.umb.edu} (Daniel R. Guilderson) -@file{greg@@gagme.chi.il.us} (Gregory Gulik) -Michael Haberler @file{<mah@@parrot.prv.univie.ac.at>} -@file{guy@@auspex.auspex.com} (Guy Harris) -Petri Helenius @file{<pete@@fidata.fi>} -Peter Honeyman @file{<honey@@citi.umich.edu>} -@file{bei@@dogface.austin.tx.us} (Bob Izenberg) -@file{harvee!esj} (Eric S Johansson) -@file{chris@@cj_net.in-berlin.de} (Christof Junge) -@file{tron@@Veritas.COM} (Ronald S. Karr) -@file{kent@@sparky.IMD.Sterling.COM} (Kent Landfield) -@file{lebaron@@inrs-telecom.uquebec.ca} (Gregory LeBaron) -@file{karl@@sugar.NeoSoft.Com} (Karl Lehenbauer) -@file{libove@@libove.det.dec.com} (Jay Vassos-Libove) -@file{bruce%blilly@@Broadcast.Sony.COM} (Bruce Lilly) -Ted Lindgreen @file{<tlindgreen@@encore.nl>} -"Arne Ludwig" @file{<arne@@rrzbu.hanse.de>} -Matthew Lyle @file{<matt@@mips.mitek.com>} -@file{djm@@eng.umd.edu} (David J. MacKenzie) -John R MacMillan @file{<chance!john@@sq.sq.com>} -@file{mem@@mv.MV.COM} (Mark E. Mallett) -@file{martelli@@cadlab.sublink.org} (Alex Martelli) -Yanek Martinson @file{<yanek@@mthvax.cs.miami.edu>} -@file{les@@chinet.chi.il.us} (Leslie Mikesell) -@file{mmitchel@@digi.lonestar.org} (Mitch Mitchell) -@file{rmohr@@infoac.rmi.de} (Rupert Mohr) -@file{service@@infohh.rmi.de} (Dirk Musstopf) -@file{lyndon@@cs.athabascau.ca} (Lyndon Nerenberg) -@file{nolan@@helios.unl.edu} (Michael Nolan) -david nugent @file{<david@@csource.oz.au>} -@file{abekas!dragoman!mikep@@decwrl.dec.com} (Mike Park) -"Mark Pizzolato 415-369-9366" @file{<mark@@infocomm.com>} -@file{dplatt@@ntg.com} (Dave Platt) -@file{eldorado@@tharr.UUCP} (Mark Powell) -@file{pozar@@kumr.lns.com} (Tim Pozar) -@file{putsch@@uicc.com} (Jeff Putsch) -Jarmo Raiha @file{<jarmo@@ksvltd.FI>} -@file{mcr@@Sandelman.OCUnix.On.Ca} (Michael Richardson) -@file{ross@@sun490.fdu.edu} (Jeff Ross) -Aleksey P. Rudnev @file{<alex@@kiae.su>} -@file{wolfgang@@wsrcc.com} (Wolfgang S. Rupprecht) -@file{tbr@@tfic.bc.ca} (Tom Rushworth) -@file{rsalz@@bbn.com} (Rich Salz) -@file{sojurn!mike@@hobbes.cert.sei.cmu.edu} (Mike Sangrey) -@file{swiers@@plains.NoDak.edu} -@file{s4mjs!mjs@@nirvo.nirvonics.com} (M. J. Shannon Jr.) -@file{peter@@ficc.ferranti.com} (Peter da Silva) -@file{frumious!pat} (Patrick Smith) -@file{roscom!monty@@bu.edu} (Monty Solomon) -@file{chs@@antic.apu.fi} (Hannu Strang) -@file{ralf@@reswi.ruhr.de} (Ralf E. Stranzenbach) -Oleg Tabarovsky @file{<olg@@olghome.pccentre.msk.su>} -John Theus @file{<john@@theus.rain.com>} -@file{rmtodd@@servalan.servalan.com} (Richard Todd) -Len Tower @file{<tower-prep@@ai.mit.edu>} -@file{mju@@mudos.ann-arbor.mi.us} (Marc Unangst) -@file{jv@@mh.nl} (Johan Vromans) -@file{rna-nl!gerben@@relay.nluug.nl} (Drs. Gerben C. Th. Wierda) -@file{frnkmth!twwells.com!bill} (T. William Wells) -@file{mauxci!eci386!woods@@apple.com} (Greg A. Woods) -@file{jon@@console.ais.org} (Jon Zeeff) -Eric Ziegast @file{<uunet!ziegast>} -@end example - -@node Index (concepts), Index (configuration file), Acknowledgements, Top -@unnumbered Concept Index - -@printindex cp - -@node Index (configuration file), , Index (concepts), Top -@unnumbered Index to New Configuration File - -@printindex fn - -@contents -@bye diff --git a/gnu/libexec/uucp/uudir.c b/gnu/libexec/uucp/uudir.c deleted file mode 100644 index b59cfa43c3d..00000000000 --- a/gnu/libexec/uucp/uudir.c +++ /dev/null @@ -1,109 +0,0 @@ -/* uudir.c - Create a directory owned by uucp. This is Unix specific. - - 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 AIRS, P.O. Box 520, Waltham, MA 02254. - - $Log: uudir.c,v $ - Revision 1.1.1.1 1993/03/21 09:45:37 cgd - initial import of 386bsd-0.1 sources - - Revision 1.1 1992/02/09 05:11:42 ian - Initial revision - - */ - -#include "uucp.h" - -#if USE_RCS_ID -char uudir_rcsid[] = "$Id: uudir.c,v 1.1.1.1 1993/03/21 09:45:37 cgd Exp $"; -#endif - -#include <pwd.h> - -#if USE_STDIO && HAVE_UNISTD_H -#include <unistd.h> -#endif - -#include "sysdep.h" - -/* External functions. */ -extern int setuid (); -extern struct passwd *getpwnam (); - -/* This is a simple program which sets its real uid to uucp and then - invokes /bin/mkdir. It is only used if the system does not support - the mkdir system call. It must be installed suid to root. - - This program is needed because the UUCP programs will be run suid - to uucp. On a system without the mkdir system call, /bin/mkdir is - a suid root program. This means that /bin/mkdir always creates - directories using the real uid, rather than the effective uid. - This is wrong, since the UUCP programs always want to create - directories that are owned by uucp. Therefore, this simple suid - root program is used to force /bin/mkdir into making a directory - owned by uucp. - - If we made the program publically executable, this would mean that - anybody could create a directory owned by uucp. This is probably - not a good thing, but since the program must be owned by root we - can't simply make it executable only by uucp. Therefore, the - Makefile hides the program away in /usr/lib/uucp/util, and makes - that directory searchable only by uucp. This should prevent - anybody else from getting to the program. - - This is not a perfect solution, since any suid root program is by - definition a potential security hole. I really can't see any way - to avoid this, though. */ - -int -main (argc, argv) - int argc; - char **argv; -{ - struct passwd *q; - const char *zprog, *zname; - - /* We don't print any error messages, since this program should - never be run directly by a user. */ - - if (argc != 2) - exit (EXIT_FAILURE); - - /* OWNER is passed in from the Makefile. It will normally be - "uucp". */ - q = getpwnam (OWNER); - if (q == NULL) - exit (EXIT_FAILURE); - - if (setuid (q->pw_uid) < 0) - exit (EXIT_FAILURE); - - zprog = MKDIR_PROGRAM; - zname = strrchr (zprog, '/'); - if (zname == NULL) - zname = zprog; - else - ++zname; - - (void) execl (zprog, zname, argv[1], (char *) NULL); - exit (EXIT_FAILURE); -} diff --git a/gnu/libexec/uucp/uulog.c b/gnu/libexec/uucp/uulog.c deleted file mode 100644 index b33b3a5198d..00000000000 --- a/gnu/libexec/uucp/uulog.c +++ /dev/null @@ -1,264 +0,0 @@ -/* uulog.c - Display the UUCP log 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 AIRS, P.O. Box 520, Waltham, MA 02254. - - $Log: uulog.c,v $ - Revision 1.1.1.1 1993/03/21 09:45:37 cgd - initial import of 386bsd-0.1 sources - - Revision 1.4 1992/03/12 19:54:43 ian - Debugging based on types rather than number - - Revision 1.3 1992/02/27 05:40:54 ian - T. William Wells: detach from controlling terminal, handle signals safely - - Revision 1.2 1992/02/23 03:26:51 ian - Overhaul to use automatic configure shell script - - Revision 1.1 1992/02/14 21:22:51 ian - Initial revision - - */ - -#include "uucp.h" - -#if USE_RCS_ID -char uulog_rcsid[] = "$Id: uulog.c,v 1.1.1.1 1993/03/21 09:45:37 cgd Exp $"; -#endif - -#include <errno.h> - -#include "system.h" -#include "sysdep.h" -#include "getopt.h" - -/* This is a pretty bad implementation of uulog, which I don't think - is a very useful program anyhow. It only takes a single -s and/or - -u switch. When using HAVE_BNU_LOGGING it requires a system. It - does not provide -f. */ - -/* The program name. */ -char abProgram[] = "uulog"; - -/* Local functions. */ - -static void ulusage P((void)); - -/* Long getopt options. */ - -static const struct option asLongopts[] = { { NULL, 0, NULL, 0 } }; - -const struct option *_getopt_long_options = asLongopts; - -int -main (argc, argv) - int argc; - char **argv; -{ - int iopt; - /* -s: system name. */ - const char *zsystem = NULL; - /* -u: user name. */ - const char *zuser = NULL; - /* -I: configuration file name. */ - const char *zconfig = NULL; - /* -x: display uuxqt log file. */ - boolean fuuxqt = FALSE; - const char *zfile; - FILE *e; - char *zline; - int csystem = 0; - int cuser = 0; - - while ((iopt = getopt (argc, argv, "I:s:u:xX:")) != EOF) - { - switch (iopt) - { - case 'I': - /* Configuration file name. */ - zconfig = optarg; - break; - - case 's': - /* System name. */ - zsystem = optarg; - break; - - case 'u': - /* User name. */ - zuser = optarg; - break; - - case 'x': - /* Display uuxqt log file. */ - fuuxqt = TRUE; - break; - - case 'X': -#if DEBUG > 1 - /* Set debugging level. */ - iDebug |= idebug_parse (optarg); -#endif - break; - - case 0: - /* Long option found and flag set. */ - break; - - default: - ulusage (); - break; - } - } - - if (optind != argc) - ulusage (); - - uread_config (zconfig); - - usysdep_initialize (FALSE, FALSE); - -#if ! HAVE_BNU_LOGGING - zfile = zLogfile; -#else - { - const char *zprogram; - char *zalc; - - /* We need a system to find a BNU log file. */ - if (zsystem == NULL) - ulusage (); - - if (fuuxqt) - zprogram = "uuxqt"; - else - zprogram = "uucico"; - - zalc = (char *) alloca (strlen (zLogfile) - + strlen (zprogram) - + strlen (zsystem) - + 1); - sprintf (zalc, zLogfile, zprogram, zsystem); - zfile = zalc; - } -#endif - - e = fopen (zfile, "r"); - if (e == NULL) - { - ulog (LOG_ERROR, "fopen (%s): %s", zfile, strerror (errno)); - usysdep_exit (FALSE); - } - - /* Read the log file and output the appropriate lines. */ - - if (zsystem != NULL) - csystem = strlen (zsystem); - - if (zuser != NULL) - cuser = strlen (zuser); - - while ((zline = zfgets (e, FALSE)) != NULL) - { - char *zluser, *zlsys, *znext; - int cluser, clsys; - - /* Skip any leading whitespace (not that there should be any). */ - znext = zline + strspn (zline, " \t"); - -#if ! HAVE_TAYLOR_LOGGING - /* The user name is the first field on the line. */ - zluser = znext; - cluser = strcspn (znext, " \t"); -#endif - - /* Skip the first field. */ - znext += strcspn (znext, " \t"); - znext += strspn (znext, " \t"); - - /* The system is the second field on the line. */ - zlsys = znext; - clsys = strcspn (znext, " \t"); - - /* Skip the second field. */ - znext += clsys; - znext += strspn (znext, " \t"); - -#if HAVE_TAYLOR_LOGGING - /* The user is the third field on the line. */ - zluser = znext; - cluser = strcspn (znext, " \t"); -#endif - - /* See if we should print this line. */ - - if (zsystem != NULL - && (csystem != clsys - || strncmp (zsystem, zlsys, clsys) != 0)) - continue; - - if (zuser != NULL - && (cuser != cluser - || strncmp (zuser, zluser, cluser) != 0)) - continue; - - /* Output the line. */ - - printf ("%s", zline); - } - - ulog_close (); - - usysdep_exit (TRUE); - - /* Avoid errors about not returning a value. */ - return 0; -} - -/* Print a usage message and die. */ - -static void -ulusage () -{ - fprintf (stderr, - "Taylor UUCP version %s, copyright (C) 1991, 1992 Ian Lance Taylor\n", - abVersion); - fprintf (stderr, - "Usage: uulog [-s system] [-u user] [-x] [-I file] [-X debug]\n"); - fprintf (stderr, - " -s: print entries for named system\n"); - fprintf (stderr, - " -u: print entries for name user\n"); -#if HAVE_BNU_LOGGING - fprintf (stderr, - " -x: print uuxqt log rather than uucico log\n"); -#endif - fprintf (stderr, - " -X debug: Set debugging level (0 for none, 9 is max)\n"); -#if HAVE_TAYLOR_CONFIG - fprintf (stderr, - " -I file: Set configuration file to use (default %s%s)\n", - NEWCONFIGLIB, CONFIGFILE); -#endif /* HAVE_TAYLOR_CONFIG */ - exit (EXIT_FAILURE); -} diff --git a/gnu/libexec/uucp/uuname.c b/gnu/libexec/uucp/uuname.c deleted file mode 100644 index dcdfcd0e1bf..00000000000 --- a/gnu/libexec/uucp/uuname.c +++ /dev/null @@ -1,183 +0,0 @@ -/* uuname.c - List the names of known remote UUCP sites. - - 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 AIRS, P.O. Box 520, Waltham, MA 02254. - - $Log: uuname.c,v $ - Revision 1.1.1.1 1993/03/21 09:45:37 cgd - initial import of 386bsd-0.1 sources - - Revision 1.5 1992/03/28 04:42:32 ian - Franc,ois Pinard: output aliases, added -a switch - - Revision 1.4 1992/03/12 19:54:43 ian - Debugging based on types rather than number - - Revision 1.3 1992/02/27 05:40:54 ian - T. William Wells: detach from controlling terminal, handle signals safely - - Revision 1.2 1992/02/23 03:26:51 ian - Overhaul to use automatic configure shell script - - Revision 1.1 1992/02/14 20:25:55 ian - Initial revision - - */ - -#include "uucp.h" - -#if USE_RCS_ID -char uuname_rcsid[] = "$Id: uuname.c,v 1.1.1.1 1993/03/21 09:45:37 cgd Exp $"; -#endif - -#include "system.h" -#include "sysdep.h" -#include "getopt.h" - -/* The program name. */ -char abProgram[] = "uuname"; - -/* Local functions. */ - -static void unusage P((void)); - -/* Long getopt options. */ - -static const struct option asLongopts[] = { { NULL, 0, NULL, 0 } }; - -const struct option *_getopt_long_options = asLongopts; - -int -main (argc, argv) - int argc; - char **argv; -{ - int iopt; - /* -a: don't display aliases. */ - boolean fnoalias = FALSE; - /* -l: if true, output local node name. */ - boolean flocal = FALSE; - /* -I: configuration file name. */ - const char *zconfig = NULL; - - while ((iopt = getopt (argc, argv, "alI:x:")) != EOF) - { - switch (iopt) - { - case 'a': - /* Don't display aliases. */ - fnoalias = TRUE; - break; - - case 'l': - /* Output local node name. */ - flocal = TRUE; - break; - - case 'I': - /* Configuration file name. */ - zconfig = optarg; - break; - - case 'x': -#if DEBUG > 1 - /* Set debugging level. */ - iDebug |= idebug_parse (optarg); -#endif - break; - - case 0: - /* Long option found and flag set. */ - break; - - default: - unusage (); - break; - } - } - - if (optind != argc) - unusage (); - - uread_config (zconfig); - - usysdep_initialize (FALSE, FALSE); - - if (flocal) - printf ("%s\n", zLocalname); - else - { - int c; - struct ssysteminfo *pas; - int i; - - uread_all_system_info (&c, &pas); - - for (i = 0; i < c; i++) - { - printf ("%s\n", pas[i].zname); - - if (! fnoalias && pas[i].zalias != NULL) - { - char *zcopy, *ztok; - - zcopy = (char *) alloca (strlen (pas[i].zalias) + 1); - strcpy (zcopy, pas[i].zalias); - for (ztok = strtok (zcopy, " "); - ztok != NULL; - ztok = strtok ((char *) NULL, " ")) - printf ("%s\n", ztok); - } - } - } - - ulog_close (); - - usysdep_exit (TRUE); - - /* Avoid errors about not returning a value. */ - return 0; -} - -/* Print a usage message and die. */ - -static void -unusage () -{ - fprintf (stderr, - "Taylor UUCP version %s, copyright (C) 1991, 1992 Ian Lance Taylor\n", - abVersion); - fprintf (stderr, - "Usage: uuname [-a] [-l] [-I file] [-x debug]\n"); - fprintf (stderr, - " -a: don't display aliases\n"); - fprintf (stderr, - " -l: print local name\n"); - fprintf (stderr, - " -x debug: Set debugging level (0 for none, 9 is max)\n"); -#if HAVE_TAYLOR_CONFIG - fprintf (stderr, - " -I file: Set configuration file to use (default %s%s)\n", - NEWCONFIGLIB, CONFIGFILE); -#endif /* HAVE_TAYLOR_CONFIG */ - exit (EXIT_FAILURE); -} diff --git a/gnu/libexec/uucp/uustat.1 b/gnu/libexec/uucp/uustat.1 deleted file mode 100644 index 635f86ea320..00000000000 --- a/gnu/libexec/uucp/uustat.1 +++ /dev/null @@ -1,253 +0,0 @@ -''' $Id: uustat.1,v 1.1.1.1 1993/03/21 09:45:37 cgd Exp $ -''' $Log: uustat.1,v $ -''' Revision 1.1.1.1 1993/03/21 09:45:37 cgd -''' initial import of 386bsd-0.1 sources -''' -''' Revision 1.2 1992/04/01 21:13:46 ian -''' Added RCS ID and log strings -''' -''' Revision 1.1 1992/04/01 21:10:46 ian -''' Initial revision -''' -.TH uustat 1 "Taylor UUCP 1.03" -.SH NAME -uustat \- UUCP status inquiry and control -.SH SYNOPSIS -.B uustat \-a -.PP -.B uustat -[ -.B \-s -system ] [ -.B \-u -user ] [ -.B \-o -hours ] [ -.B \-y -hours ] -.PP -.B uustat -[ -.B \-k -jobid ] [ -.B \-r -jobid ] -.PP -.B uustat \-q -.PP -.B uustat \-m -.PP -.B uustat \-p -.SH DESCRIPTION -The -.I uustat -command can display various types of status information about the UUCP -system. It can also be used to cancel or rejuvenate requests made by -.I uucp -(1) or -.I uux -(1). - -By default -.I uustat -displays all jobs queued up for the invoking user, as if given the -.B \-u -option with the appropriate argument. -.SH OPTIONS -The following options may be given to -.I uustat. -.TP 5 -.B \-a -List all queued jobs. -.TP 5 -.B \-s system -List all jobs queued up for the named system. This option may be -specified multiple times, in which case all jobs for all the systems -will be listed. The -.B \-u, -.B \-o, -and -.B \-y -options may be used to restrict which jobs are listed. -.TP 5 -.B \-u user -List all jobs queued up for the named user. This option may be -specified multiple times, in which case all jobs for all the users -will be listed. The -.B \-s, -.B \-o, -and -.B \-y -options may be used to restrict which jobs are listed. -.TP 5 -.B \-o hours -List all queued jobs older than the given number of hours. The -.B \-s, -.B \-u, -and -.B \-y -options may be used to further restrict which jobs are listed. -.TP 5 -.B \-y hours -List all queued jobs younger than the given number of hours. The -.B \-s, -.B \-u, -and -.B \-o -options may be used to further restrict which jobs are listed. -.TP 5 -.B \-k jobid -Kill the named job. The job id is shown by the -.B \-s, -.B \-u, -.B \-o, -or -.B \-y -options, as well as by the -.B \-j -option to -.I uucp -(1) or -.I uux -(1). A job may only be killed by the user who created the job, or by -the UUCP administrator or the superuser. The -.B \-k -option may be used multiple times on the command line to kill several -jobs. -.TP 5 -.B \-r jobid -Rejuvenate the named job. This will mark it as having been invoked at -the current time, affecting the output of the -.B \-o -or -.B \-y -options and preserving it from any automated cleanup daemon. The job -id is shown by the -.B \-s, -.B \-u, -.B \-o, -or -.B \-y -options, as well as by the -.B \-j -option to -.I uucp -(1) or -.I uux -(1). A job may only be rejuvenated by the user who created the job, -or by the UUCP administrator or the superuser. The -.B \-r -option may be used multiple times on the command line to rejuvenate -several jobs. -.TP 5 -.B \-q -Display the status of commands, executions and conversations for all -remote systems for which commands or executions are queued. -.TP 5 -.B \-m -Display the status of conversations for all remote systems. -.TP 5 -.B \-p -Display the status of all processes holding UUCP locks on systems or -ports. -.TP 5 -.B \-x type -Turn on particular debugging types. The following types are -recognized: abnormal, chat, handshake, uucp-proto, proto, port, -config, spooldir, execute, incoming, outgoing. Only abnormal, config, -spooldir and execute are meaningful for -.I uustat. - -Multiple types may be given, separated by commas, and the -.B \-x -option may appear multiple times. A number may also be given, which -will turn on that many types from the foregoing list; for example, -.B \-x 2 -is equivalent to -.B \-x abnormal,chat. -.TP 5 -.B \-I file -Set configuration file to use. This option may not be available, -depending upon how -.I uustat -was compiled. -.SH EXAMPLES -.EX -uustat -a -.EE -Display status of all jobs. A sample output line is as follows: -.EX -bugsA027h bugs ian 1992-04-01 13:50:04 Executing rmail ian@airs.com (sending 1283 bytes) -.EE -The format is -.EX -jobid system user queue-date command (size) -.EE -The jobid may be passed to the -.B \-k -or -.B \-r -options. -The size indicates how much data is to be transferred to the remote -system, and is absent for a file receive request. - -The -.B \-s, -.B \-u, -.B \-o, -and -.B \-y -options also produce output in the above format. - -.EX -uustat -q -.EE -Display status for all systems with queued up commands. A sample -output line is as follows: -.EX -bugs 4C (1 hour) 0X (0 secs) 1992-04-01 14:45:47 Dial failed -.EE -This indicates the system, the number of queued commands, the age of -the oldest queued command, the number of queued local executions, the -age of the oldest queued execution, the date of the last conversation, -and the status of that conversation. - -.EX -uustat -m -.EE -Display conversation status for all remote systems. A sample output -line is as follows: -.EX -bugs 1992-04-01 15:51:30 Conversation complete -.EE -This indicates the system, the date of the last conversation, and the -status of that conversation. If the last conversation failed, -.I uustat -will indicate how many attempts have been made to call the system. If -the retry period is currently preventing calls to that system, -.I uustat -also displays the time when the next call will be permitted. - -.EX -uustat -p -.EE -Display the status of all processes holding UUCP locks. The output -format is system dependent, as -.I uustat -simply invokes -.I ps -(1) on each process holding a lock. -.SH FILES -The file names may be changed at compilation time or by the -configuration file, so these are only approximations. - -.br -/usr/lib/uucp/config - Configuration file. -.br -/usr/spool/uucp - -UUCP spool directory. -.SH SEE ALSO -ps(1), uucp(1), uux(1), uucico(8), uuxqt(8) -.SH AUTHOR -Ian Lance Taylor -(ian@airs.com or uunet!airs!ian) diff --git a/gnu/libexec/uucp/uustat.c b/gnu/libexec/uucp/uustat.c deleted file mode 100644 index c3ba5cc8e08..00000000000 --- a/gnu/libexec/uucp/uustat.c +++ /dev/null @@ -1,1071 +0,0 @@ -/* uustat.c - UUCP status program - - 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 AIRS, P.O. Box 520, Waltham, MA 02254. - - $Log: uustat.c,v $ - Revision 1.1.1.1 1993/03/21 09:45:37 cgd - initial import of 386bsd-0.1 sources - - Revision 1.7 1992/03/28 22:54:45 ian - Allow multiple systems and users or kills and rejuvenates at once - - Revision 1.6 1992/03/12 19:54:43 ian - Debugging based on types rather than number - - Revision 1.5 1992/03/03 21:34:55 ian - Handle local execution files - - Revision 1.4 1992/02/27 05:40:54 ian - T. William Wells: detach from controlling terminal, handle signals safely - - Revision 1.3 1992/02/24 20:36:27 ian - Roberto Biancardi: skip spaces after strtok (NULL, "") - - Revision 1.2 1992/02/23 03:26:51 ian - Overhaul to use automatic configure shell script - - Revision 1.1 1992/02/20 04:18:59 ian - Initial revision - - */ - -#include "uucp.h" - -#if USE_RCS_ID -char uustat_rcsid[] = "$Id: uustat.c,v 1.1.1.1 1993/03/21 09:45:37 cgd Exp $"; -#endif - -#include <errno.h> - -#if HAVE_TIME_H -#include <time.h> -#endif - -#include "system.h" -#include "sysdep.h" -#include "getopt.h" - -/* The uustat program permits various listings and manipulations of - files in the spool directory. This implementation supports the - following switches: - - -a list all jobs - -kjobid kill job with specified ID - -m report status for all remote machines - -ohour report jobs older than specified number of hours - -p do "ps -flp" on all processes holding lock files (Unix specific) - -q list number of jobs for all systems - -rjobid rejuvenate job with specified ID - -ssystem report on all jobs for specified system - -uuser report on all jobs for specified user - -yhour report jobs younger than specified number of hours - -Ifile set configuration file name - -xdebug set debugging level */ - -/* The program name. */ -char abProgram[] = "uustat"; - -/* Local functions. */ - -static void ususage P((void)); -static boolean fsworkfiles P((int csystems, char **pazsystems, - int cusers, char **pazusers, - long iold, long iyoung)); -static boolean fsworkfiles_system P((const struct ssysteminfo *qsys, - int cusers, char **pazusers, - long iold, long iyoung)); -static boolean fsworkfile_show P((const struct ssysteminfo *qsys, - const struct scmd *qcmd, - long itime)); -static void usworkfile_header P((const struct ssysteminfo *qsys, - const struct scmd *qcmd, - const char *zjobid, - long itime, boolean ffirst)); -static boolean fsquery P((void)); -static void usunits_show P((long idiff)); -static boolean fsmachines P((void)); - -/* Long getopt options. */ - -static const struct option asLongopts[] = { { NULL, 0, NULL, 0 } }; - -const struct option *_getopt_long_options = asLongopts; - -int -main (argc, argv) - int argc; - char **argv; -{ - int iopt; - /* -a: list all jobs. */ - boolean fall = FALSE; - /* -k jobid: kill specified job. */ - int ckills = 0; - char **pazkills = NULL; - /* -m: report machine status. */ - boolean fmachine = FALSE; - /* -o hour: report jobs older than given number of hours. */ - int ioldhours = -1; - /* -p: report status of jobs holding lock files. */ - boolean fps = FALSE; - /* -q: list number of jobs for each system. */ - boolean fquery = FALSE; - /* -r jobid: rejuvenate specified job. */ - int crejuvs = 0; - char **pazrejuvs = NULL; - /* -s system: list all jobs for specified system. */ - int csystems = 0; - char **pazsystems = NULL; - /* -u user: list all jobs for specified user. */ - int cusers = 0; - char **pazusers = NULL; - /* -y hour: report jobs younger than given number of hours. */ - int iyounghours = -1; - /* -I file: set configuration file. */ - const char *zconfig = NULL; - int ccmds; - long iold; - long iyoung; - char *azoneuser[1]; - boolean fret; - - while ((iopt = getopt (argc, argv, "aI:k:mo:pqr:s:u:x:y:")) != EOF) - { - switch (iopt) - { - case 'a': - /* List all jobs. */ - fall = TRUE; - break; - - case 'I': - /* Set configuration file name. */ - zconfig = optarg; - break; - - case 'k': - /* Kill specified job. */ - ++ckills; - pazkills = (char **) xrealloc ((pointer) pazkills, - ckills * sizeof (char *)); - pazkills[ckills - 1] = optarg; - break; - - case 'm': - /* Report machine status. */ - fmachine = TRUE; - break; - - case 'o': - /* Report old jobs. */ - ioldhours = atoi (optarg); - break; - - case 'p': - /* Get status of processes holding locks. */ - fps = TRUE; - break; - - case 'q': - /* List number of jobs for each system. */ - fquery = TRUE; - break; - - case 'r': - /* Rejuvenate specified job. */ - ++crejuvs; - pazrejuvs = (char **) xrealloc ((pointer) pazrejuvs, - crejuvs * sizeof (char *)); - pazrejuvs[crejuvs - 1] = optarg; - break; - - case 's': - /* List jobs for specified system. */ - ++csystems; - pazsystems = (char **) xrealloc ((pointer) pazsystems, - csystems * sizeof (char *)); - pazsystems[csystems - 1] = optarg; - break; - - case 'u': - /* List jobs for specified user. */ - ++cusers; - pazusers = (char **) xrealloc ((pointer) pazusers, - cusers * sizeof (char *)); - pazusers[cusers - 1] = optarg; - break; - - case 'x': -#if DEBUG > 1 - /* Set debugging level. */ - iDebug |= idebug_parse (optarg); -#endif - break; - - case 'y': - /* List jobs younger than given number of hours. */ - iyounghours = atoi (optarg); - break; - - case 0: - /* Long option found and flag set. */ - break; - - default: - ususage (); - break; - } - } - - if (optind != argc) - ususage (); - - /* To avoid confusion, most options are only permitted by - themselves. This restriction might be removed later, but it is - imposed by most implementations. We do permit any combination of - -s, -u, -o and -y, and any combination of -k and -r. */ - ccmds = 0; - if (fall) - ++ccmds; - if (ckills > 0 || crejuvs > 0) - ++ccmds; - if (fmachine) - ++ccmds; - if (fps) - ++ccmds; - if (fquery) - ++ccmds; - if (csystems > 0 || cusers > 0 - || ioldhours != -1 || iyounghours != -1) - ++ccmds; - - if (ccmds > 1) - { - fprintf (stderr, "uustat: Too many options\n"); - ususage (); - } - - uread_config (zconfig); - - usysdep_initialize (FALSE, FALSE); - - /* If no commands were specified, we list all commands for the given - user. */ - if (ccmds == 0) - { - cusers = 1; - azoneuser[0] = xstrdup (zsysdep_login_name ()); - pazusers = azoneuser; - } - - if (ioldhours == -1) - iold = (long) -1; - else - { - iold = (isysdep_time ((long *) NULL) - - (long) ioldhours * (long) 60 * (long) 60); - if (iold < 0L) - iold = 0L; - } - if (iyounghours == -1) - iyoung = (long) -1; - else - { - iyoung = (isysdep_time ((long *) NULL) - - (long) iyounghours * (long) 60 * (long) 60); - if (iyoung < 0L) - iyoung = 0L; - } - - if (fall - || ioldhours != -1 - || csystems > 0 - || cusers > 0 - || iyounghours != -1) - fret = fsworkfiles (csystems, pazsystems, cusers, pazusers, iold, - iyoung); - else if (fquery) - fret = fsquery (); - else if (fmachine) - fret = fsmachines (); - else if (ckills > 0 || crejuvs > 0) - { - int i; - - fret = TRUE; - for (i = 0; i < ckills; i++) - if (! fsysdep_kill_job (pazkills[i])) - fret = FALSE; - - for (i = 0; i < crejuvs; i++) - if (! fsysdep_rejuvenate_job (pazrejuvs[i])) - fret = FALSE; - } - else if (fps) - fret = fsysdep_lock_status (); - else - { -#if DEBUG > 0 - ulog (LOG_FATAL, "Can't happen"); -#endif - fret = FALSE; - } - - ulog_close (); - - usysdep_exit (fret); - - /* Avoid errors about not returning a value. */ - return 0; -} - -/* Print a usage message and die. */ - -static void -ususage () -{ - fprintf (stderr, - "Taylor UUCP version %s, copyright (C) 1991, 1992 Ian Lance Taylor\n", - abVersion); - fprintf (stderr, - "Usage: uustat [-ampq] [-kr job] [-oy hours] [-s system] [-u user]\n"); - fprintf (stderr, - " -a: list all UUCP jobs\n"); - fprintf (stderr, - " -k job: kill specified UUCP job\n"); - fprintf (stderr, - " -m: report status for all remote machines\n"); - fprintf (stderr, - " -o hours: list all jobs older than given number of hours\n"); - fprintf (stderr, - " -p: show status of all processes holding UUCP locks\n"); - fprintf (stderr, - " -q: list number of jobs for each system\n"); - fprintf (stderr, - " -r job: rejuvenate specified UUCP job\n"); - fprintf (stderr, - " -s system: list all jobs for specified system\n"); - fprintf (stderr, - " -u user: list all jobs for specified user\n"); - fprintf (stderr, - " -y hours: list all jobs younger than given number of hours\n"); - fprintf (stderr, - " -x debug: Set debugging level (0 for none, 9 is max)\n"); -#if HAVE_TAYLOR_CONFIG - fprintf (stderr, - " -I file: Set configuration file to use (default %s%s)\n", - NEWCONFIGLIB, CONFIGFILE); -#endif /* HAVE_TAYLOR_CONFIG */ - exit (EXIT_FAILURE); -} - -/* Handle various possible requests to look at work files. */ - -static boolean -fsworkfiles (csystems, pazsystems, cusers, pazusers, iold, iyoung) - int csystems; - char **pazsystems; - int cusers; - char **pazusers; - long iold; - long iyoung; -{ - boolean fret; - int i; - - fret = TRUE; - - if (csystems > 0) - { - struct ssysteminfo ssys; - - for (i = 0; i < csystems; i++) - { - if (! fread_system_info (pazsystems[i], &ssys)) - { - ulog (LOG_ERROR, "%s: unknown system", pazsystems[i]); - fret = FALSE; - continue; - } - - if (! fsworkfiles_system (&ssys, cusers, pazusers, iold, iyoung)) - fret = FALSE; - } - } - else - { - int cs; - struct ssysteminfo *pas; - - uread_all_system_info (&cs, &pas); - - for (i = 0; i < cs; i++) - if (! fsworkfiles_system (&pas[i], cusers, pazusers, iold, iyoung)) - fret = FALSE; - } - - return fret; -} - -/* Look at the work files for a particular system. */ - -static boolean -fsworkfiles_system (qsys, cusers, pazusers, iold, iyoung) - const struct ssysteminfo *qsys; - int cusers; - char **pazusers; - long iold; - long iyoung; -{ - boolean fret; - - if (! fsysdep_get_work_init (qsys, BGRADE_LOW)) - return FALSE; - - while (TRUE) - { - struct scmd s; - long itime; - - if (! fsysdep_get_work (qsys, BGRADE_LOW, &s)) - { - usysdep_get_work_free (qsys); - return FALSE; - } - if (s.bcmd == 'H') - break; - - if (cusers > 0) - { - int i; - - for (i = 0; i < cusers; i++) - if (strcmp (pazusers[i], s.zuser) == 0) - break; - if (i >= cusers) - continue; - } - - itime = isysdep_work_time (qsys, s.pseq); - - if (iold != (long) -1 && itime > iold) - continue; - - if (iyoung != (long) -1 && itime < iyoung) - continue; - - if (! fsworkfile_show (qsys, &s, itime)) - { - usysdep_get_work_free (qsys); - return FALSE; - } - } - - fret = fsworkfile_show (qsys, (const struct scmd *) NULL, 0L); - - usysdep_get_work_free (qsys); - - return fret; -} - -/* Show a single workfile. This is actually called once for each line - in the workfile, so we accumulate the lines and show them all at - once. This lets us show an execution in a useful fashion. */ - -struct scmdlist -{ - struct scmdlist *qnext; - struct scmd s; - long itime; -}; - -static boolean -fsworkfile_show (qsys, qcmd, itime) - const struct ssysteminfo *qsys; - const struct scmd *qcmd; - long itime; -{ - static struct scmdlist *qlist; - static const char *zlistid; - const char *zid; - - if (qcmd == NULL) - zid = NULL; - else - { - zid = zsysdep_jobid (qsys, qcmd->pseq); - if (zid == NULL) - return FALSE; - } - - /* If this is the same jobid as the list, put it on the end. */ - - if (qcmd != NULL - && qlist != NULL - && strcmp (zlistid, zid) == 0) - { - struct scmdlist *qnew, **pq; - - qnew = (struct scmdlist *) xmalloc (sizeof (struct scmdlist)); - qnew->qnext = NULL; - qnew->s = *qcmd; - qnew->itime = itime; - for (pq = &qlist; *pq != NULL; pq = &(*pq)->qnext) - ; - *pq = qnew; - return TRUE; - } - - if (qcmd != NULL) - zid = xstrdup (zid); - - /* Here we have found a different job ID, so we print the scmd - structures that we have accumulated. We look for the special - case of an execution (one of the destination files begins with - X.). We could be more clever about other situations as well. */ - - if (qlist != NULL) - { - struct scmdlist *qlook; - - for (qlook = qlist; qlook != NULL; qlook = qlook->qnext) - if (qlook->s.bcmd == 'S' - && qlook->s.zto[0] == 'X' - && qlook->s.zto[1] == '.' - && fspool_file (qlook->s.zfrom)) - break; - - if (qlook == NULL) - { - /* Show all the lines in a regular work file. */ - - for (qlook = qlist; qlook != NULL; qlook = qlook->qnext) - { - const char *zfile; - - usworkfile_header (qsys, &qlook->s, zlistid, qlook->itime, - qlook == qlist); - - switch (qlook->s.bcmd) - { - case 'S': - if (strchr (qlook->s.zoptions, 'C') != NULL - || fspool_file (qlook->s.zfrom)) - zfile = zsysdep_spool_file_name (qsys, qlook->s.ztemp); - else - zfile = zsysdep_real_file_name (qsys, qlook->s.zfrom, - (const char *) NULL); - printf ("Sending %s (%ld bytes) to %s", qlook->s.zfrom, - zfile == NULL ? 0L : csysdep_size (zfile), - qlook->s.zto); - break; - case 'R': - printf ("Requesting %s to %s", qlook->s.zfrom, - qlook->s.zto); - break; - case 'X': - printf ("Requesting %s to %s", qlook->s.zfrom, - qlook->s.zto); - break; -#if DEBUG > 0 - default: - printf ("Bad line %d", qlook->s.bcmd); - break; -#endif - } - - printf ("\n"); - } - } - else - { - const char *zxqt; - FILE *e; - long csize; - struct scmdlist *qsize; - char *zline; - - /* Show the command for an execution file. */ - zxqt = zsysdep_spool_file_name (qsys, qlook->s.zfrom); - if (zxqt == NULL) - return FALSE; - - e = fopen (zxqt, "r"); - if (e == NULL) - { - ulog (LOG_ERROR, "fopen (%s): %s", zxqt, strerror (errno)); - return FALSE; - } - - csize = 0L; - for (qsize = qlist; qsize != NULL; qsize = qsize->qnext) - { - if (qsize->s.bcmd == 'S') - { - const char *zfile; - - if (strchr (qsize->s.zoptions, 'C') != NULL - || fspool_file (qsize->s.zfrom)) - zfile = zsysdep_spool_file_name (qsys, qsize->s.ztemp); - else - zfile = zsysdep_real_file_name (qsys, qsize->s.zfrom, - (const char *) NULL); - if (zfile != NULL) - csize += csysdep_size (zfile); - } - } - - usworkfile_header (qsys, &qlook->s, zlistid, qlook->itime, - TRUE); - - while ((zline = zfgets (e, FALSE)) != NULL) - { - char *ztok; - - ztok = strtok (zline, " \t"); - if (ztok != NULL - && strcmp (ztok, "C") == 0) - { - char *zcmd; - int clen; - - zcmd = strtok ((char *) NULL, ""); - zcmd += strspn (zcmd, " \t"); - clen = strlen (zcmd); - if (zcmd[clen - 1] == '\n') - zcmd[clen - 1] = '\0'; - printf ("Executing %s", zcmd); - xfree ((pointer) zline); - break; - } - xfree ((pointer) zline); - } - - if (zline == NULL) - printf ("Unrecognized execution"); - - printf (" (sending %ld bytes)\n", csize); - - (void) fclose (e); - } - - /* Free up the list of entries. */ - qlook = qlist; - while (qlook != NULL) - { - struct scmdlist *qnext; - - qnext = qlook->qnext; - xfree ((pointer) qlook); - qlook = qnext; - } - - xfree ((pointer) zlistid); - - qlist = NULL; - zlistid = NULL; - } - - /* Start a new list with the entry we just got. */ - - if (qcmd != NULL) - { - qlist = (struct scmdlist *) xmalloc (sizeof (struct scmdlist)); - qlist->qnext = NULL; - qlist->s = *qcmd; - qlist->itime = itime; - zlistid = zid; - } - - return TRUE; -} - -/* Show the header of the line describing a workfile. */ - -static void -usworkfile_header (qsys, qcmd, zjobid, itime, ffirst) - const struct ssysteminfo *qsys; - const struct scmd *qcmd; - const char *zjobid; - long itime; - boolean ffirst; -{ - const char *zshowid; - struct tm stime; - - if (ffirst) - zshowid = zjobid; - else - zshowid = "-"; - - printf ("%.14s %s %s ", zshowid, qsys->zname, qcmd->zuser); - - usysdep_localtime (itime, &stime); - printf ("%04d-%02d-%02d %02d:%02d:%02d ", - stime.tm_year + 1900, stime.tm_mon + 1, - stime.tm_mday, stime.tm_hour, - stime.tm_min, stime.tm_sec); -} - -/* Handle the -q option. For each remote system this lists the number - of jobs queued, the number of executions queued, and the current - call status. We get the executions all at once, because they are - not accessed by system. They could be, but it is possible to have - executions pending for an unknown system, so special handling would - still be required. */ - -struct sxqtlist -{ - struct sxqtlist *qnext; - char *zsystem; - int cxqts; - long ifirst; -}; - -/* These local functions need the definition of sxqtlist for the - prototype. */ - -static boolean fsquery_system P((const struct ssysteminfo *qsys, - struct sxqtlist **pq, - long inow)); -static boolean fsquery_show P((const struct ssysteminfo *qsys, int cwork, - long ifirstwork, - struct sxqtlist *qxqt, - long inow)); - -static boolean -fsquery () -{ - struct sxqtlist *qlist; - const char *zfile; - const char *zsystem; - boolean ferr; - long inow; - int csystems; - struct ssysteminfo *pas; - boolean fret; - int i; - - /* Get a count of all the execution files. */ - - if (! fsysdep_get_xqt_init ()) - return FALSE; - - qlist = NULL; - while ((zfile = zsysdep_get_xqt (&zsystem, &ferr)) != NULL) - { - struct sxqtlist *qlook; - - for (qlook = qlist; qlook != NULL; qlook = qlook->qnext) - if (strcmp (zsystem, qlook->zsystem) == 0) - break; - - if (qlook != NULL) - { - long itime; - - ++qlook->cxqts; - itime = isysdep_file_time (zfile); - if (itime < qlook->ifirst) - qlook->ifirst = itime; - } - else - { - struct sxqtlist *qnew; - - qnew = (struct sxqtlist *) xmalloc (sizeof (struct sxqtlist)); - qnew->qnext = qlist; - qnew->zsystem = xstrdup (zsystem); - qnew->cxqts = 1; - qnew->ifirst = isysdep_file_time (zfile); - qlist = qnew; - } - } - - usysdep_get_xqt_free (); - - if (ferr) - return FALSE; - - inow = isysdep_time ((long *) NULL); - - /* Get a count of all the work files, and print out the system. */ - - uread_all_system_info (&csystems, &pas); - - fret = TRUE; - for (i = 0; i < csystems; i++) - if (! fsquery_system (&pas[i], &qlist, inow)) - fret = FALSE; - - /* Check for the local system in the list of execution files. */ - if (qlist != NULL) - { - struct sxqtlist **pq; - - for (pq = &qlist; *pq != NULL; pq = &(*pq)->qnext) - { - if (strcmp ((*pq)->zsystem, zLocalname) == 0) - { - struct sxqtlist *qfree; - - if (! fsquery_show (&sLocalsys, 0, 0L, *pq, inow)) - fret = FALSE; - qfree = *pq; - *pq = qfree->qnext; - xfree ((pointer) qfree->zsystem); - xfree ((pointer) qfree); - break; - } - } - } - - /* Print out information for any unknown systems for which we have - execution files. */ - - if (qlist != NULL && ! fUnknown_ok) - { - ulog (LOG_ERROR, "Executions queued up for unknown systems"); - return FALSE; - } - - while (qlist != NULL) - { - struct sxqtlist *qnext; - - sUnknown.zname = qlist->zsystem; - if (! fsquery_show (&sUnknown, 0, 0L, qlist, inow)) - fret = FALSE; - qnext = qlist->qnext; - xfree ((pointer) qlist->zsystem); - xfree ((pointer) qlist); - qlist = qnext; - } - - return fret; -} - -/* Query a single known system. */ - -static boolean -fsquery_system (qsys, pq, inow) - const struct ssysteminfo *qsys; - struct sxqtlist **pq; - long inow; -{ - int cwork; - long ifirstwork; - boolean fret; - - if (! fsysdep_get_work_init (qsys, BGRADE_LOW)) - return FALSE; - - cwork = 0; - ifirstwork = 0L; - while (TRUE) - { - struct scmd s; - long itime; - - if (! fsysdep_get_work (qsys, BGRADE_LOW, &s)) - return FALSE; - if (s.bcmd == 'H') - break; - - ++cwork; - - itime = isysdep_work_time (qsys, s.pseq); - if (ifirstwork == 0L || ifirstwork > itime) - ifirstwork = itime; - } - - usysdep_get_work_free (qsys); - - /* Find the execution information, if any. */ - while (*pq != NULL) - { - if (strcmp ((*pq)->zsystem, qsys->zname) == 0) - break; - pq = &(*pq)->qnext; - } - - /* If there are no commands and no executions, don't print any - information for this system. */ - if (cwork == 0 && *pq == NULL) - return TRUE; - - fret = fsquery_show (qsys, cwork, ifirstwork, *pq, inow); - - if (*pq != NULL) - { - struct sxqtlist *qfree; - - qfree = *pq; - *pq = qfree->qnext; - xfree ((pointer) qfree->zsystem); - xfree ((pointer) qfree); - } - - return fret; -} - -/* Print out the query information for a single system. We handle the - local system specially. */ - -static boolean -fsquery_show (qsys, cwork, ifirstwork, qxqt, inow) - const struct ssysteminfo *qsys; - int cwork; - long ifirstwork; - struct sxqtlist *qxqt; - long inow; -{ - boolean flocal; - struct sstatus sstat; - struct tm stime; - - flocal = strcmp (qsys->zname, zLocalname) == 0; - - if (! flocal) - { - if (! fsysdep_get_status (qsys, &sstat)) - return FALSE; - } - - printf ("%s %dC (", qsys->zname, cwork); - - if (cwork == 0) - printf ("0 secs"); - else - usunits_show (inow - ifirstwork); - - printf (") "); - - if (qxqt == NULL) - printf ("0X (0 secs)"); - else - { - printf ("%dX (", qxqt->cxqts); - usunits_show (inow - qxqt->ifirst); - printf (")"); - } - - if (flocal) - { - printf ("\n"); - return TRUE; - } - - usysdep_localtime (sstat.ilast, &stime); - - printf (" %04d-%02d-%02d %02d:%02d:%02d ", - stime.tm_year + 1900, stime.tm_mon + 1, - stime.tm_mday, stime.tm_hour, - stime.tm_min, stime.tm_sec); - - printf ("%s\n", azStatus[(int) sstat.ttype]); - - return TRUE; -} - -/* Print a time difference in the largest applicable units. */ - -static void -usunits_show (idiff) - long idiff; -{ - const char *zunit; - long iunits; - - if (idiff > (long) 24 * (long) 60 * (long) 60) - { - iunits = idiff / ((long) 24 * (long) 60 * (long) 60); - zunit = "day"; - } - else if (idiff > (long) 60 * 60) - { - iunits = idiff / (long) (60 * 60); - zunit = "hour"; - } - else if (idiff > (long) 60) - { - iunits = idiff / (long) 60; - zunit = "min"; - } - else - { - iunits = idiff; - zunit = "sec"; - } - - printf ("%ld %s%s", iunits, zunit, iunits == 1 ? "" : "s"); -} - -/* Give a list of all status entries for all machines that we have - status entries for. We need to get a list of status entries in a - system dependent fashion, since we may have status for unknown - systems. */ - -static boolean -fsmachines () -{ - pointer phold; - const char *zsystem; - boolean ferr; - struct sstatus sstat; - - if (! fsysdep_all_status_init (&phold)) - return FALSE; - - while ((zsystem = zsysdep_all_status (phold, &ferr, &sstat)) != NULL) - { - struct tm stime; - - usysdep_localtime (sstat.ilast, &stime); - printf ("%-14s %04d-%02d-%02d %02d:%02d:%02d %s", zsystem, - stime.tm_year + 1900, stime.tm_mon + 1, - stime.tm_mday, stime.tm_hour, - stime.tm_min, stime.tm_sec, - azStatus[(int) sstat.ttype]); - if (sstat.ttype != STATUS_TALKING - && sstat.cwait > 0) - { - printf (" (%d %s", sstat.cretries, - sstat.cretries == 1 ? "try" : "tries"); - if (sstat.ilast + sstat.cwait > isysdep_time ((long *) NULL)) - { - usysdep_localtime (sstat.ilast + sstat.cwait, &stime); - printf (", next %04d-%02d-%02d %02d:%02d:%02d", - stime.tm_year + 1900, stime.tm_mon + 1, - stime.tm_mday, stime.tm_hour, - stime.tm_min, stime.tm_sec); - } - printf (")"); - } - printf ("\n"); - } - - usysdep_all_status_free (phold); - - return ! ferr; -} diff --git a/gnu/libexec/uucp/uutime.h b/gnu/libexec/uucp/uutime.h deleted file mode 100644 index 7954c3276ee..00000000000 --- a/gnu/libexec/uucp/uutime.h +++ /dev/null @@ -1,137 +0,0 @@ -/* uutime.h - Header file for UUCP time 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 AIRS, P.O. Box 520, Waltham, MA 02254. - - $Id: uutime.h,v 1.2 1993/08/02 17:25:16 mycroft Exp $ -*/ - -#ifndef UUTIME_H - -#define UUTIME_H - -/* Timetables are kept in a array of pairs of strings. */ - -struct stimetable -{ - /* Name of timetable. */ - const char *zname; - /* Time string. */ - const char *ztime; -}; - -extern int cTtable; -extern struct stimetable *pasTtable; - -/* A time string is parsed into a list of the following structures. - Each element of the list represents a span of time. The time - string matches any time that is one of the spans. The time may - only depend on the day of the week, not on the day of the month or - of the year. Also, the time is specified only down to the minute, - not down to the second or below. - - 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 the span. When we add a new time span that overlaps with an - existing one, we use the span with 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. After determining which grade or file size to use, we - eliminate all overlaps. - - Each span also has a retry time associated with it. This permits - different retry times to be used at different times of day. */ - -struct sspan -{ - /* Next time span in this list. */ - struct sspan *qnext; - /* Value for this span (lowest grade or largest file that may be - transferred at this time). */ - long ival; - /* Starting minute. */ - int istart; - /* Ending minute. */ - int iend; - /* Retry time. */ - int cretry; -}; - -/* Time functions. */ - -/* Initialize the array of timetables. */ -extern void uinittimetables P((void)); - -/* Add a new timetable entry. */ -extern void uaddtimetable P((const char *zname, const char *ztime)); - -/* Parse a timegrade string into a time span. A timegrade string is a - sequence of strings separated by a single space. The first - character of each string is a grade. The second character begins a - time string. The time string may end in a semicolon followed by a - retry time. */ -extern struct sspan *qtimegrade_parse P((const char *ztimegrade)); - -/* Parse a timesize string into a time span. A timespan string is a - sequence of pairs of strings, all separated by a single space. The - first string in each pair is a numeric size. The second string is - a time string. */ -extern struct sspan *qtimesize_parse P((const char *ztimesize)); - -/* 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 sspan *, - long *pival, int *pcretry)); - -/* Free a time span returned by either qtparse_timesize or - qtparse_timegrade. */ -extern void utimespan_free P((struct sspan *)); - -/* Determine the grade of work permitted at the current time, given a - timegrade string. This parses the timegrade string, locates the - entry corresponding to the current time, and returns the associated - grade. If no time in the timegrade string matches, this returns - '\0'. */ -extern char btimegrade P((const char *ztimegrade)); - -/* Determine the maximum size that may be transferred at the current - time, given a timesize string. This parses the timesize string, - locates the entry corresponding to the current time, and returns - the associated size. If no time in the timesize string matches, - this returns -1. */ -extern long cmax_size_now P((const char *ztimesize)); - -/* Determine the maximum size that may ever be transferred, given a - timesize string. If there are any time gaps larger than 1 hour not - described by the timesize string, this returns -1. Otherwise it - returns the largest size that may be transferred at some time. */ -extern long cmax_size_ever P((const char *ztimesize)); - -#endif /* ! defined (UUTIME_H) */ diff --git a/gnu/libexec/uucp/uux.1 b/gnu/libexec/uucp/uux.1 deleted file mode 100644 index 3e9056c42ae..00000000000 --- a/gnu/libexec/uucp/uux.1 +++ /dev/null @@ -1,260 +0,0 @@ -''' $Id: uux.1,v 1.1.1.1 1993/03/21 09:45:37 cgd Exp $ -''' $Log: uux.1,v $ -''' Revision 1.1.1.1 1993/03/21 09:45:37 cgd -''' initial import of 386bsd-0.1 sources -''' -''' Revision 1.7 1992/04/01 21:11:19 ian -''' Cleaned up a bit, updated -x switch -''' -''' Revision 1.6 1992/03/28 04:34:11 ian -''' David J. MacKenzie: change .TP5 to .TP 5; also updated to 1.03 -''' -''' Revision 1.5 1992/02/29 04:07:08 ian -''' Added -j option to uucp and uux -''' -''' Revision 1.4 1992/01/20 23:52:23 ian -''' Change to version 1.02 -''' -''' Revision 1.3 1991/12/18 04:37:01 ian -''' Clarified -z switch somewhat -''' -''' Revision 1.2 1991/12/14 19:11:54 ian -''' Added -l option to link files -''' -''' Revision 1.1 1991/12/14 19:05:30 ian -''' Initial revision -''' -''' -.TH uux 1 "Taylor UUCP 1.03" -.SH NAME -uux \- Remote command execution over UUCP -.SH SYNOPSIS -.B uux -[ options ] command -.SH DESCRIPTION -The -.I uux -command is used to execute a command on a remote system, or to execute -a command on the local system using files from remote systems. -The command -is not executed immediately; the request is queued until the -.I uucico -(8) daemon calls the system and executes it. The daemon is -started automatically unless the -.B \-r -switch is given. - -The actual command execution is done by the -.I uuxqt -(8) daemon. - -File arguments can be gathered from remote systems to the execution -system, as can standard input. Standard output may be directed to a -file on a remote system. - -The command name may be preceded by a system name followed by an -exclamation point if it is to be executed on a remote system. An -empty system name is taken as the local system. - -Each argument that contains an exclamation point is treated as naming -a file. The system which the file is on is before the exclamation -point, and the pathname on that system follows it. An empty system -name is taken as the local system; this must be used to transfer a -file to a command being executed on a remote system. If the path is -not absolute, it will be appended to the current working directory on -the local system; the result may not be meaningful on the remote -system. A pathname may begin with ~/, in which case it is relative to -the UUCP public directory (usually /usr/spool/uucppublic) on the -appropriate system. A pathname may begin with ~name/, in which case -it is relative to the home directory of the named user on the -appropriate system. - -Standard input and output may be redirected as usual; the pathnames -used may contain exclamation points to indicate that they are on -remote systems. Note that the redirection characters must be quoted -so that they are passed to -.I uux -rather than interpreted by the shell. Append redirection (>>) does -not work. - -All specified files are gathered together into a single directory -before execution of the command begins. This means that each file -must have a distinct base name. For example, -.EX -uux 'sys1!diff sys2!~user1/foo sys3!~user2/foo >!foo.diff' -.EE -will fail because both files will be copied to sys1 and stored under -the name foo. - -Arguments may be quoted by parentheses to avoid interpretation of -exclamation points. This is useful when executing the -.I uucp -command on a remote system. -.SH OPTIONS -The following options may be given to -.I uux. -.TP 5 -.B \-,\-p -Read standard input and use it as the standard input for the command -to be executed. -.TP 5 -.B \-c -Do not copy local files to the spool directory. This is the default. -If they are -removed before being processed by the -.I uucico -(8) daemon, the copy will fail. The files must be readable by the -.I uucico -(8) daemon, -as well as the by the invoker of -.I uux. -.TP 5 -.B \-C -Copy local files to the spool directory. -.TP 5 -.B \-l -Link local files into the spool directory. If a file can not be -linked because it is on a different device, it will be copied unless -the -.B \-c -option also appears (in other words, use of -.B \-l -switches the default from -.B \-c -to -.B \-C). -If the files are changed before being processed by the -.I uucico -(8) daemon, the changed versions will be used. The files must be -readable by the -.I uucico -(8) daemon, as well as by the invoker of -.I uux. -.TP 5 -.B \-g grade -Set the grade of the file transfer command. Jobs of a higher grade -are executed first. Grades run 0 ... 9 A ... Z a ... z from high to -low. -.TP 5 -.B \-n -Do not send mail about the status of the job, even if it fails. -.TP 5 -.B \-z -Send mail about the status of the job if an error occurs. For many -.I uuxqt -daemons, including the Taylor UUCP -.I uuxqt, -this is the default action; for those, -.B \-z -will have no effect. However, some -.I uuxqt -daemons will send mail if the job succeeds unless the -.B \-z -option is used, and some other -.I uuxqt -daemons will not send mail if the job fails unless the -.B \-z -option is used. -.TP 5 -.B \-r -Do not start the -.I uucico -(8) daemon immediately; merely queue up the execution request for later -processing. -.TP 5 -.B \-j -Print jobids on standard output. A jobid will be generated for each -file copy operation required to perform the operation. These file -copies may be cancelled by -passing the jobid to the -.B \-k -switch of -.I uustat -(1), which will make the execution impossible to complete. -.TP 5 -.B \-a address -Report job status to the specified e-mail address. -.TP 5 -.B \-x type -Turn on particular debugging types. The following types are -recognized: abnormal, chat, handshake, uucp-proto, proto, port, -config, spooldir, execute, incoming, outgoing. Only abnormal, config, -spooldir and execute are meaningful for -.I uux. - -Multiple types may be given, separated by commas, and the -.B \-x -option may appear multiple times. A number may also be given, which -will turn on that many types from the foregoing list; for example, -.B \-x 2 -is equivalent to -.B \-x abnormal,chat. -.TP 5 -.B \-I file -Set configuration file to use. This option may not be available, -depending upon how -.I uux -was compiled. -.SH EXAMPLES -.EX -uux -z - sys1!rmail user1 -.EE -Execute the command ``rmail user1'' on the system sys1, giving it as -standard input whatever is given to -.I uux -as standard input. If a failure occurs, send a message using -.I mail -(1). -.EX -uux 'diff -c sys1!~user1/file1 sys2!~user2/file2 >!file.diff' -.EE -Fetch the two named files from system sys1 and system sys2 and execute -.I diff -putting the result in file.diff in the current directory. The current -directory must be writable by the -.I uuxqt -(8) daemon for this to work. -.EX -uux 'sys1!uucp ~user1/file1 (sys2!~user2/file2)' -.EE -Execute -.I uucp -on the system sys1 copying file1 (on system sys1) to sys2. This -illustrates the use of parentheses for quoting. -.SH RESTRICTIONS -The remote system may not permit you to execute certain commands. -Many remote systems only permit the execution of -.I rmail -and -.I rnews. - -Some of the options are dependent on the capabilities of the -.I uuxqt -(8) daemon on the remote system. -.SH FILES -The file names may be changed at compilation time or by the -configuration file, so these are only approximations. - -.br -/usr/lib/uucp/config - Configuration file. -.br -/usr/spool/uucp - -UUCP spool directory. -.br -/usr/spool/uucp/Log - -UUCP log file. -.br -/usr/spool/uucppublic - -Default UUCP public directory. -.SH SEE ALSO -mail(1), uustat(1), uucp(1), uucico(8), uuxqt(8) -.SH BUGS -Files can not be referenced across multiple systems. - -Too many jobids are output by -.B \-j, -and there is no good way to cancel a local execution requiring remote -files. -.SH AUTHOR -Ian Lance Taylor -(ian@airs.com or uunet!airs!ian) diff --git a/gnu/libexec/uucp/uux.c b/gnu/libexec/uucp/uux.c deleted file mode 100644 index 132ad69e6c8..00000000000 --- a/gnu/libexec/uucp/uux.c +++ /dev/null @@ -1,1280 +0,0 @@ -/* uux.c - Prepare to execute a command on a remote system. - - 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 AIRS, P.O. Box 520, Waltham, MA 02254. - - $Log: uux.c,v $ - Revision 1.1.1.1 1993/03/21 09:45:37 cgd - initial import of 386bsd-0.1 sources - - Revision 1.32 1992/03/15 04:51:17 ian - Keep an array of signals we've received rather than a single variable - - Revision 1.31 1992/03/12 19:54:43 ian - Debugging based on types rather than number - - Revision 1.30 1992/03/02 15:20:43 ian - Check iSignal before entering fread - - Revision 1.29 1992/02/29 04:07:08 ian - Added -j option to uucp and uux - - Revision 1.28 1992/02/29 01:06:59 ian - Chip Salzenberg: recheck file permissions before sending - - Revision 1.27 1992/02/28 05:06:15 ian - T. William Wells: fsysdep_catch must be a macro - - Revision 1.26 1992/02/27 05:40:54 ian - T. William Wells: detach from controlling terminal, handle signals safely - - Revision 1.25 1992/02/23 03:26:51 ian - Overhaul to use automatic configure shell script - - Revision 1.24 1992/02/08 22:33:32 ian - Only get the current working directory if it's going to be needed - - Revision 1.23 1992/02/08 20:33:57 ian - Handle all possible signals raised by abort - - Revision 1.22 1992/02/08 03:54:18 ian - Include <string.h> only in <uucp.h>, added 1992 copyright - - Revision 1.21 1992/02/02 20:34:36 ian - Niels Baggesen: must check user permissions on access to local files - - Revision 1.20 1992/01/21 19:39:12 ian - Chip Salzenberg: uucp and uux start uucico for right system, not any - - Revision 1.19 1992/01/15 07:06:29 ian - Set configuration directory in Makefile rather than sysdep.h - - Revision 1.18 1992/01/05 03:09:17 ian - Changed abProgram and abVersion to non const to avoid compiler bug - - Revision 1.17 1992/01/05 02:51:38 ian - Allocate enough space for log message - - Revision 1.16 1991/12/29 04:04:18 ian - Added a bunch of extern definitions - - Revision 1.15 1991/12/21 21:16:05 ian - Franc,ois Pinard: remove parentheses from ZSHELLSEPS - - Revision 1.14 1991/12/20 03:07:54 ian - Added space and tab to ZSHELLSEPS to stop command at whitespace - - Revision 1.13 1991/12/18 03:54:14 ian - Made error messages to terminal appear more normal - - Revision 1.12 1991/12/14 16:09:07 ian - Added -l option to uux to link files into the spool directory - - Revision 1.11 1991/12/11 03:59:19 ian - Create directories when necessary; don't just assume they exist - - Revision 1.10 1991/12/07 03:03:12 ian - Split arguments like sh; request sh execution if any metachars appear - - Revision 1.9 1991/11/21 22:17:06 ian - Add version string, print version when printing usage - - Revision 1.8 1991/11/15 19:17:32 ian - Hannu Strang: copy stdin using fread/fwrite, not fgets/fputs - - Revision 1.7 1991/11/13 23:08:40 ian - Expand remote pathnames in uucp and uux; fix up uux special cases - - Revision 1.6 1991/11/08 21:53:17 ian - Brian Campbell: fix argument handling when looking for '-' - - Revision 1.5 1991/11/07 22:52:49 ian - Chip Salzenberg: avoid recursive strtok, handle redirection better - - Revision 1.4 1991/09/19 03:23:34 ian - Chip Salzenberg: append to private debugging file, don't overwrite it - - Revision 1.3 1991/09/19 02:30:37 ian - From Chip Salzenberg: check whether signal is ignored differently - - Revision 1.2 1991/09/11 02:33:14 ian - Added ffork argument to fsysdep_run - - Revision 1.1 1991/09/10 19:40:31 ian - Initial revision - - */ - -#include "uucp.h" - -#if USE_RCS_ID -char uux_rcsid[] = "$Id: uux.c,v 1.1.1.1 1993/03/21 09:45:37 cgd Exp $"; -#endif - -#include <ctype.h> -#include <errno.h> - -#include "getopt.h" - -#include "system.h" -#include "sysdep.h" - -/* External functions. */ -extern int fclose (); - -/* These character lists should, perhaps, be in sysdep.h. */ - -/* This is the list of shell metacharacters that we check for. If one - of these is present, we request uuxqt to execute the command with - /bin/sh. Otherwise we let it execute using execve. */ - -#define ZSHELLCHARS "\"'`*?[;&()|<>\\$" - -/* This is the list of word separators. We break filename arguments - at these characters. */ -#define ZSHELLSEPS ";&*|<> \t" - -/* This is the list of word separators without the redirection - operators. */ -#define ZSHELLNONREDIRSEPS ";&*| \t" - -/* The program name. */ -char abProgram[] = "uux"; - -/* Long getopt options. */ - -static const struct option asXlongopts[] = { { NULL, 0, NULL, 0 } }; - -const struct option *_getopt_long_options = asXlongopts; - -/* The execute file we are creating. */ - -static FILE *eXxqt_file; - -/* A list of commands to be spooled. */ - -static struct scmd *pasXcmds; -static int cXcmds; - -/* A file to close if we're forced to exit. */ - -static FILE *eXclose; - -/* Local functions. */ - -static void uxusage P((void)); -static void uxadd_xqt_line P((int bchar, const char *z1, const char *z2)); -static void uxadd_send_file P((const char *zfrom, const char *zto, - const char *zoptions, const char *ztemp)); -static void uxcopy_stdin P((FILE *e)); -static void uxrecord_file P((const char *zfile)); -static void uxabort P((void)); - -int -main (argc, argv) - int argc; - char **argv; -{ - int iopt; - /* -a: requestor address for status reports. */ - const char *zrequestor = NULL; - /* -b: if true, return standard input on error. */ - boolean fretstdin = FALSE; - /* -c,-C: if true, copy to spool directory. */ - boolean fcopy = FALSE; - /* -c: set if -c appears explicitly; if it and -l appear, then if the - link fails we don't copy the file. */ - boolean fdontcopy = FALSE; - /* -I: configuration file name. */ - const char *zconfig = NULL; - /* -j: output job id. */ - boolean fjobid = FALSE; - /* -g: job grade. */ - char bgrade = BDEFAULT_UUX_GRADE; - /* -l: link file to spool directory. */ - boolean flink = FALSE; - /* -n: do not notify upon command completion. */ - boolean fno_ack = FALSE; - /* -p: read standard input for command standard input. */ - boolean fread_stdin = FALSE; - /* -r: do not start uucico when finished. */ - boolean fuucico = TRUE; - /* -s: report status to named file. */ - const char *zstatus_file = NULL; - /* -W: only expand local file names. */ - boolean fexpand = TRUE; - /* -z: report status only on error. */ - boolean ferror_ack = FALSE; - int i; - int clen; - char *zargs; - char *zarg; - char *zcmd; - char *zexclam; - boolean fgetcwd; - const char *zuser; - struct ssysteminfo sxqtsys; - const struct ssysteminfo *qxqtsys; - boolean fxqtlocal; - char **pzargs; - int calloc_args; - int cargs; - const char *zxqtname; - char abxqt_tname[CFILE_NAME_LEN]; - char abxqt_xname[CFILE_NAME_LEN]; - boolean fneedshell; - char *zprint; - const char *zcall_system; - boolean fcall_any; - boolean fexit; - - /* We need to be able to read a single - as an option, which getopt - won't do. So that we can still use getopt, we run through the - options looking for an option "-"; if we find one we change it to - "-p", which is an equivalent option. */ - - for (i = 1; i < argc; i++) - { - if (argv[i][0] != '-') - break; - if (argv[i][1] == '\0') - argv[i] = xstrdup ("-p"); - else - { - const char *z; - - for (z = argv[i] + 1; *z != '\0'; z++) - { - /* If the option takes an argument, and the argument is - not appended, then skip the next argument. */ - if (*z == 'a' || *z == 'g' || *z == 'I' - || *z == 's' || *z == 'x') - { - if (z[1] == '\0') - i++; - break; - } - } - } - } - - /* The leading + in the getopt string means to stop processing - options as soon as a non-option argument is seen. */ - - while ((iopt = getopt (argc, argv, "+a:bcCg:I:jlnprs:Wx:z")) != EOF) - { - switch (iopt) - { - case 'a': - /* Set requestor name: mail address to which status reports - should be sent. */ - zrequestor = optarg; - break; - - case 'b': - /* Return standard input on error. */ - fretstdin = TRUE; - break; - - case 'c': - /* Do not copy local files to spool directory. */ - fcopy = FALSE; - fdontcopy = TRUE; - break; - - case 'C': - /* Copy local files to spool directory. */ - fcopy = TRUE; - break; - - case 'I': - /* Configuration file name. */ - zconfig = optarg; - break; - - case 'j': - /* Output jobid. */ - fjobid = TRUE; - break; - - case 'g': - /* Set job grade. */ - bgrade = optarg[0]; - break; - - case 'l': - /* Link file to spool directory. */ - flink = TRUE; - break; - - case 'n': - /* Do not notify upon command completion. */ - fno_ack = TRUE; - break; - - case 'p': - /* Read standard input for command standard input. */ - fread_stdin = TRUE; - break; - - case 'r': - /* Do not start uucico when finished. */ - fuucico = FALSE; - break; - - case 's': - /* Report status to named file. */ - zstatus_file = optarg; - break; - - case 'W': - /* Only expand local file names. */ - fexpand = FALSE; - break; - - case 'x': -#if DEBUG > 1 - /* Set debugging level. */ - iDebug |= idebug_parse (optarg); -#endif - break; - - case 'z': - /* Report status only on error. */ - ferror_ack = TRUE; - break; - - case 0: - /* Long option found and flag set. */ - break; - - default: - uxusage (); - break; - } - } - - if (! FGRADE_LEGAL (bgrade)) - { - ulog (LOG_ERROR, "Ignoring illegal grade"); - bgrade = BDEFAULT_UUX_GRADE; - } - - if (optind == argc) - uxusage (); - - uread_config (zconfig); - - /* The command and files arguments could be quoted in any number of - ways, so we split them apart ourselves. We do this before - calling usysdep_initialize because we want to set fgetcwd - correctly. */ - clen = 1; - for (i = optind; i < argc; i++) - clen += strlen (argv[i]) + 1; - - zargs = (char *) alloca (clen); - *zargs = '\0'; - for (i = optind; i < argc; i++) - { - strcat (zargs, argv[i]); - strcat (zargs, " "); - } - - /* The first argument is the command to execute. */ - clen = strcspn (zargs, ZSHELLSEPS); - zcmd = (char *) alloca (clen + 1); - strncpy (zcmd, zargs, clen); - zcmd[clen] = '\0'; - zargs += clen; - - /* Split the arguments out into an array. We break the arguments - into alternating sequences of characters not in ZSHELLSEPS - and characters in ZSHELLSEPS. We remove whitespace. We - separate the redirection characters '>' and '<' into their - own arguments to make them easier to process below. */ - - calloc_args = 10; - pzargs = (char **) xmalloc (calloc_args * sizeof (char *)); - cargs = 0; - - for (zarg = strtok (zargs, " \t"); - zarg != NULL; - zarg = strtok ((char *) NULL, " \t")) - { - while (*zarg != '\0') - { - if (cargs >= calloc_args + 1) - { - calloc_args += 10; - pzargs = (char **) xrealloc ((pointer) pzargs, - calloc_args * sizeof (char *)); - } - - clen = strcspn (zarg, ZSHELLSEPS); - if (clen > 0) - { - pzargs[cargs] = (char *) xmalloc (clen + 1); - strncpy (pzargs[cargs], zarg, clen); - pzargs[cargs][clen] = '\0'; - ++cargs; - zarg += clen; - } - - /* We deliberately separate '>' and '<' out. */ - if (*zarg != '\0') - { - clen = strspn (zarg, ZSHELLNONREDIRSEPS); - if (clen == 0) - clen = 1; - pzargs[cargs] = (char *) xmalloc (clen + 1); - strncpy (pzargs[cargs], zarg, clen); - pzargs[cargs][clen] = '\0'; - ++cargs; - zarg += clen; - } - } - } - - /* Now look through the arguments to see if we are going to need the - current working directory. We don't try to make a precise - determination, just a conservative one. The basic idea is that - we don't want to get the cwd for 'rmail - foo!user' (note that we - don't examine the command itself). */ - fgetcwd = FALSE; - for (i = 0; i < cargs; i++) - { - zexclam = strrchr (pzargs[i], '!'); - if (zexclam != NULL && fsysdep_needs_cwd (zexclam + 1)) - { - fgetcwd = TRUE; - break; - } - if ((pzargs[i][0] == '<' || pzargs[i][0] == '>') - && i + 1 < cargs - && strchr (pzargs[i + 1], '!') == NULL - && fsysdep_needs_cwd (pzargs[i + 1])) - { - fgetcwd = TRUE; - break; - } - } - -#ifdef SIGINT - usysdep_signal (SIGINT); -#endif -#ifdef SIGHUP - usysdep_signal (SIGHUP); -#endif -#ifdef SIGQUIT - usysdep_signal (SIGQUIT); -#endif -#ifdef SIGTERM - usysdep_signal (SIGTERM); -#endif -#ifdef SIGPIPE - usysdep_signal (SIGPIPE); -#endif - - usysdep_initialize (FALSE, fgetcwd); - - ulog_fatal_fn (uxabort); - - zuser = zsysdep_login_name (); - - /* Figure out which system the command is to be executed on. */ - zexclam = strchr (zcmd, '!'); - if (zexclam == NULL) - { - qxqtsys = &sLocalsys; - fxqtlocal = TRUE; - } - else - { - *zexclam = '\0'; - - if (*zcmd == '\0' || strcmp (zcmd, zLocalname) == 0) - { - qxqtsys = &sLocalsys; - fxqtlocal = TRUE; - } - else - { - if (fread_system_info (zcmd, &sxqtsys)) - qxqtsys = &sxqtsys; - else - { - if (! fUnknown_ok) - ulog (LOG_FATAL, "System %s unknown", zcmd); - qxqtsys = &sUnknown; - sUnknown.zname = zcmd; - } - - fxqtlocal = FALSE; - } - - zcmd = zexclam + 1; - } - - /* Make sure we have a spool directory. */ - - if (! fsysdep_make_spool_dir (qxqtsys)) - uxabort (); - - /* Name and open the execute file. If the execution is to occur on - a remote system, we must create a data file and copy it over. */ - if (fxqtlocal) - zxqtname = zsysdep_xqt_file_name (); - else - zxqtname = zsysdep_data_file_name (qxqtsys, 'X', abxqt_tname, - (char *) NULL, abxqt_xname); - if (zxqtname == NULL) - uxabort (); - - eXxqt_file = esysdep_fopen (zxqtname, FALSE, FALSE, TRUE); - if (eXxqt_file == NULL) - uxabort (); - - uxrecord_file (xstrdup (zxqtname)); - - /* Specify the user. */ - uxadd_xqt_line ('U', zuser, zLocalname); - - /* Look through the arguments. Any argument containing an - exclamation point character is interpreted as a file name, and is - sent to the appropriate system. */ - - zcall_system = NULL; - fcall_any = FALSE; - - for (i = 0; i < cargs; i++) - { - const char *zsystem, *zconst; - char *zfile; - boolean finput, foutput; - boolean flocal; - - /* Check for a parenthesized argument; remove the parentheses - and otherwise ignore it (this is how an exclamation point is - quoted). */ - - if (pzargs[i][0] == '(') - { - clen = strlen (pzargs[i]); - if (pzargs[i][clen - 1] != ')') - ulog (LOG_ERROR, "Mismatched parentheses"); - else - pzargs[i][clen - 1] = '\0'; - ++pzargs[i]; - continue; - } - - /* Check whether we are doing a redirection. */ - - finput = FALSE; - foutput = FALSE; - if (i + 1 < cargs) - { - if (pzargs[i][0] == '<') - finput = TRUE; - else if (pzargs[i][0] == '>') - foutput = TRUE; - if (finput || foutput) - { - pzargs[i] = NULL; - i++; - } - } - - zexclam = strchr (pzargs[i], '!'); - - /* If there is no exclamation point and no redirection, this - argument is left untouched. */ - - if (zexclam == NULL && ! finput && ! foutput) - continue; - - /* Get the system name and file name for this file. */ - - if (zexclam == NULL) - { - zsystem = zLocalname; - zfile = pzargs[i]; - flocal = TRUE; - } - else - { - *zexclam = '\0'; - zsystem = pzargs[i]; - if (zsystem[0] != '\0') - flocal = strcmp (zsystem, zLocalname) == 0; - else - { - zsystem = zLocalname; - flocal = TRUE; - } - zfile = zexclam + 1; - } - - /* Add the current working directory to the file name if it's - not an absolute path. */ - if (fexpand || flocal) - { - zconst = zsysdep_add_cwd (zfile, flocal); - if (zconst == NULL) - uxabort (); - zfile = xstrdup (zconst); - } - - /* Check for output redirection. We strip this argument out, - and create an O command which tells uuxqt where to send the - output. */ - - if (foutput) - { - if (flocal) - { - if (! fin_directory_list (qxqtsys, zfile, - qxqtsys->zremote_receive, TRUE, - FALSE, (const char *) NULL)) - ulog (LOG_FATAL, "Not permitted to create %s", zfile); - } - - if (strcmp (zsystem, qxqtsys->zname) == 0) - uxadd_xqt_line ('O', zfile, (const char *) NULL); - else - uxadd_xqt_line ('O', zfile, zsystem); - pzargs[i] = NULL; - continue; - } - - if (finput) - { - if (fread_stdin) - ulog (LOG_FATAL, "Standard input specified twice"); - pzargs[i] = NULL; - } - - if (flocal) - { - char *zuse; - const char *zdata; - char abtname[CFILE_NAME_LEN]; - char abdname[CFILE_NAME_LEN]; - - /* It's a local file. If requested by -C, copy the file to - the spool directory. If requested by -l, link the file - to the spool directory; if the link fails, we copy the - file, unless -c was explictly used. If the execution is - occurring on the local system, we force the copy as well, - because otherwise we would have to have some way to tell - uuxqt not to move the file. If the file is being shipped - to another system, we must set up a transfer request. - First make sure the user has legitimate access, since we - are running setuid. */ - - if (! fsysdep_access (zfile)) - uxabort (); - - if (fcopy || flink || fxqtlocal) - { - char *zdup; - boolean fdid; - - zdata = zsysdep_data_file_name (qxqtsys, bgrade, abtname, - abdname, (char *) NULL); - if (zdata == NULL) - uxabort (); - - zdup = xstrdup (zdata); - uxrecord_file (zdup); - - fdid = FALSE; - if (flink) - { - boolean fworked; - - if (! fsysdep_link (zfile, zdup, &fworked)) - uxabort (); - - if (fworked) - fdid = TRUE; - else if (fdontcopy) - ulog (LOG_FATAL, "%s: Can't link to spool directory", - zfile); - } - - if (! fdid) - { - if (! fcopy_file (zfile, zdup, FALSE, TRUE)) - uxabort (); - } - - xfree ((pointer) zdup); - - zuse = abtname; - } - else - { - /* Make sure the daemon can access the file. */ - if (! fsysdep_daemon_access (zfile)) - uxabort (); - if (! fin_directory_list (&sLocalsys, zfile, - sLocalsys.zlocal_send, - TRUE, TRUE, zuser)) - ulog (LOG_FATAL, "Not permitted to send from %s", - zfile); - - zuse = zfile; - - zdata = zsysdep_data_file_name (qxqtsys, bgrade, - (char *) NULL, abdname, - (char *) NULL); - if (zdata == NULL) - uxabort (); - strcpy (abtname, "D.0"); - } - - if (fxqtlocal) - { - if (finput) - uxadd_xqt_line ('I', zuse, (char *) NULL); - else - pzargs[i] = zuse; - } - else - { - uxadd_send_file (zuse, abdname, - fcopy || flink || fxqtlocal ? "C" : "c", - abtname); - - if (finput) - { - uxadd_xqt_line ('F', abdname, (char *) NULL); - uxadd_xqt_line ('I', abdname, (char *) NULL); - } - else - { - const char *zbase; - - zbase = zsysdep_base_name (zfile); - if (zbase == NULL) - uxabort (); - uxadd_xqt_line ('F', abdname, zbase); - pzargs[i] = xstrdup (zbase); - } - } - } - else if (strcmp (qxqtsys->zname, zsystem) == 0) - { - /* The file is already on the system where the command is to - be executed. */ - if (finput) - uxadd_xqt_line ('I', zfile, (const char *) NULL); - else - pzargs[i] = zfile; - } - else - { - struct ssysteminfo sfromsys; - const struct ssysteminfo *qfromsys; - char abtname[CFILE_NAME_LEN]; - char abdname[CFILE_NAME_LEN]; - char *ztemp; - struct scmd s; - const char *zjobid; - - /* We need to request a remote file. Make sure we have a - spool directory for the remote system. */ - - if (! fread_system_info (zsystem, &sfromsys)) - { - if (! fUnknown_ok) - ulog (LOG_FATAL, "System %s unknown", zsystem); - sfromsys = sUnknown; - sfromsys.zname = zsystem; - } - qfromsys = &sfromsys; - - if (! fsysdep_make_spool_dir (qfromsys)) - uxabort (); - - /* We want the file to wind up in the spool directory of the - local system (whether the execution is occurring - locally or not); we have to use an absolute file name - here, because otherwise the file would wind up in the - spool directory of the system it is coming from. */ - - if (! fxqtlocal) - { - if (! fsysdep_make_spool_dir (&sLocalsys)) - uxabort (); - } - - zconst = zsysdep_data_file_name (&sLocalsys, bgrade, - abtname, (char *) NULL, - (char *) NULL); - if (zconst == NULL) - uxabort (); - - /* Request the file. The special option '9' is a signal to - uucico that it's OK to receive a file into the spool - directory; normally such requests are rejected. */ - - s.bcmd = 'R'; - s.pseq = NULL; - s.zfrom = zfile; - s.zto = abtname; - s.zuser = zuser; - s.zoptions = "9"; - s.ztemp = ""; - s.imode = 0600; - s.znotify = ""; - s.cbytes = -1; - - zjobid = zsysdep_spool_commands (qfromsys, bgrade, 1, &s); - if (zjobid == NULL) - uxabort (); - - if (fjobid) - printf ("%s\n", zjobid); - - if (fcall_any) - zcall_system = NULL; - else - { - fcall_any = TRUE; - zcall_system = xstrdup (qfromsys->zname); - } - - /* Now if the execution is to occur on another system, we - must create an execute file to send the file there. The - name of the file on the execution system is put into - abdname. */ - - if (fxqtlocal) - ztemp = abtname; - else - { - const char *zxqt_file; - FILE *e; - - /* Get a file name to use on the execution system. */ - - if (zsysdep_data_file_name (qxqtsys, bgrade, - (char *) NULL, abdname, - (char *) NULL) == NULL) - uxabort (); - ztemp = abdname; - - /* The local spool directory was created above, if it - didn't already exist. */ - - zxqt_file = zsysdep_xqt_file_name (); - if (zxqt_file == NULL) - uxabort (); - - /* Queue up a uucp command to be executed locally once - the file arrives. We take advantage of the file - renaming and moving that uuxqt does to remove the - file and avoid the hassles of adding the current - directory. The -W switch to uucp prevents from - adding the current directory to the remote file. */ - - e = esysdep_fopen (zxqt_file, FALSE, FALSE, TRUE); - if (e == NULL) - uxabort (); - - eXclose = e; - uxrecord_file (xstrdup (zxqt_file)); - - fprintf (e, "U %s %s\n", zuser, zLocalname); - fprintf (e, "F %s foo\n", abtname); - fprintf (e, "C uucp -CW foo %s!%s\n", qxqtsys->zname, - abdname); - - eXclose = NULL; - if (fclose (e) != 0) - ulog (LOG_FATAL, "fclose: %s", strerror (errno)); - } - - /* Tell the command execution to wait until the file has - been received, and tell it the real file name to use. */ - - if (finput) - { - uxadd_xqt_line ('F', ztemp, (char *) NULL); - uxadd_xqt_line ('I', ztemp, (char *) NULL); - } - else - { - const char *zbase; - - zbase = zsysdep_base_name (zfile); - if (zbase == NULL) - uxabort (); - uxadd_xqt_line ('F', ztemp, zbase); - pzargs[i] = xstrdup (zbase); - } - } - } - - /* If standard input is to be read from the stdin of uux, we read it - here into a temporary file and send it to the execute system. */ - - if (fread_stdin) - { - const char *zdata; - char abtname[CFILE_NAME_LEN]; - char abdname[CFILE_NAME_LEN]; - FILE *e; - - zdata = zsysdep_data_file_name (qxqtsys, bgrade, abtname, abdname, - (char *) NULL); - if (zdata == NULL) - uxabort (); - - e = esysdep_fopen (zdata, FALSE, FALSE, TRUE); - if (e == NULL) - uxabort (); - - eXclose = e; - uxrecord_file (xstrdup (zdata)); - - uxcopy_stdin (e); - - eXclose = NULL; - if (fclose (e) != 0) - ulog (LOG_FATAL, "fclose: %s", strerror (errno)); - - if (fxqtlocal) - uxadd_xqt_line ('I', abtname, (const char *) NULL); - else - { - uxadd_xqt_line ('F', abdname, (const char *) NULL); - uxadd_xqt_line ('I', abdname, (const char *) NULL); - uxadd_send_file (abtname, abdname, "C", abtname); - } - } - - /* Here all the arguments have been determined, so the command can - be written out. If any of the arguments contain shell - metacharacters, we request remote execution with /bin/sh (this is - the 'e' command in the execute file). The default is assumed to - be remote execution with execve. */ - - fprintf (eXxqt_file, "C %s", zcmd); - - fneedshell = FALSE; - - if (zcmd[strcspn (zcmd, ZSHELLCHARS)] != '\0') - fneedshell = TRUE; - - for (i = 0; i < cargs; i++) - { - if (pzargs[i] != NULL) - { - fprintf (eXxqt_file, " %s", pzargs[i]); - if (pzargs[i][strcspn (pzargs[i], ZSHELLCHARS)] != '\0') - fneedshell = TRUE; - } - } - - fprintf (eXxqt_file, "\n"); - - /* Write out all the other miscellaneous junk. */ - - if (fno_ack) - uxadd_xqt_line ('N', (const char *) NULL, (const char *) NULL); - - if (ferror_ack) - uxadd_xqt_line ('Z', (const char *) NULL, (const char *) NULL); - - if (zrequestor != NULL) - uxadd_xqt_line ('R', zrequestor, (const char *) NULL); - - if (fretstdin) - uxadd_xqt_line ('B', (const char *) NULL, (const char *) NULL); - - if (zstatus_file != NULL) - uxadd_xqt_line ('M', zstatus_file, (const char *) NULL); - - if (fneedshell) - uxadd_xqt_line ('e', (const char *) NULL, (const char *) NULL); - - if (fclose (eXxqt_file) != 0) - ulog (LOG_FATAL, "fclose: %s", strerror (errno)); - eXxqt_file = NULL; - - /* If the execution is to occur on another system, we must now - arrange to copy the execute file to this system. */ - - if (! fxqtlocal) - uxadd_send_file (abxqt_tname, abxqt_xname, "C", abxqt_tname); - - /* If we got a signal, get out before spooling anything. */ - - if (FGOT_SIGNAL ()) - uxabort (); - - /* From here on in, it's too late. We don't call uxabort. */ - - if (cXcmds > 0) - { - const char *zjobid; - - zjobid = zsysdep_spool_commands (qxqtsys, bgrade, cXcmds, pasXcmds); - if (zjobid == NULL) - { - ulog_close (); - usysdep_exit (FALSE); - } - - if (fjobid) - printf ("%s\n", zjobid); - - if (fcall_any) - zcall_system = NULL; - else - { - fcall_any = TRUE; - zcall_system = qxqtsys->zname; - } - } - - /* If all that worked, make a log file entry. All log file reports - up to this point went to stderr. */ - - ulog_to_file (TRUE); - ulog_system (qxqtsys->zname); - ulog_user (zuser); - - clen = strlen (zcmd) + 2; - for (i = 0; i < cargs; i++) - if (pzargs[i] != NULL) - clen += strlen (pzargs[i]) + 1; - - zprint = (char *) alloca (clen); - strcpy (zprint, zcmd); - strcat (zprint, " "); - for (i = 0; i < cargs; i++) - { - if (pzargs[i] != NULL) - { - strcat (zprint, pzargs[i]); - strcat (zprint, " "); - } - } - zprint[strlen (zprint) - 1] = '\0'; - - ulog (LOG_NORMAL, "Queuing %s", zprint); - - ulog_close (); - - if (! fuucico) - fexit = TRUE; - else - { - if (zcall_system != NULL) - fexit = fsysdep_run (TRUE, "uucico", "-s", zcall_system); - else if (fcall_any) - fexit = fsysdep_run (TRUE, "uucico", "-r1", (const char *) NULL); - else - fexit = TRUE; - } - - usysdep_exit (fexit); - - /* Avoid error about not returning a value. */ - return 0; -} - -/* Report command usage. */ - -static void -uxusage () -{ - fprintf (stderr, - "Taylor UUCP version %s, copyright (C) 1991, 1992 Ian Lance Taylor\n", - abVersion); - fprintf (stderr, - "Usage: uux [options] [-] command\n"); - fprintf (stderr, - " -,-p: Read standard input for standard input of command\n"); - fprintf (stderr, - " -c: Do not copy local files to spool directory (default)\n"); - fprintf (stderr, - " -C: Copy local files to spool directory\n"); - fprintf (stderr, - " -l: link local files to spool directory\n"); - fprintf (stderr, - " -g grade: Set job grade (must be alphabetic)\n"); - fprintf (stderr, - " -n: Do not report completion status\n"); - fprintf (stderr, - " -z: Report completion status only on error\n"); - fprintf (stderr, - " -r: Do not start uucico daemon\n"); - fprintf (stderr, - " -a address: Address to mail status report to\n"); - fprintf (stderr, - " -b: Return standard input with status report\n"); - fprintf (stderr, - " -s file: Report completion status to file\n"); - fprintf (stderr, - " -j: Report job id\n"); - fprintf (stderr, - " -x debug: Set debugging level\n"); -#if HAVE_TAYLOR_CONFIG - fprintf (stderr, - " -I file: Set configuration file to use (default %s%s)\n", - NEWCONFIGLIB, CONFIGFILE); -#endif /* HAVE_TAYLOR_CONFIG */ - exit (EXIT_FAILURE); -} - -/* Add a line to the execute file. */ - -static void -uxadd_xqt_line (bchar, z1, z2) - int bchar; - const char *z1; - const char *z2; -{ - if (z1 == NULL) - fprintf (eXxqt_file, "%c\n", bchar); - else if (z2 == NULL) - fprintf (eXxqt_file, "%c %s\n", bchar, z1); - else - fprintf (eXxqt_file, "%c %s %s\n", bchar, z1, z2); -} - -/* Add a file to be sent to the execute system. */ - -static void -uxadd_send_file (zfrom, zto, zoptions, ztemp) - const char *zfrom; - const char *zto; - const char *zoptions; - const char *ztemp; -{ - struct scmd s; - - s.bcmd = 'S'; - s.pseq = NULL; - s.zfrom = xstrdup (zfrom); - s.zto = xstrdup (zto); - s.zuser = zsysdep_login_name (); - s.zoptions = xstrdup (zoptions); - s.ztemp = xstrdup (ztemp); - s.imode = 0666; - s.znotify = ""; - s.cbytes = -1; - - ++cXcmds; - pasXcmds = (struct scmd *) xrealloc ((pointer) pasXcmds, - cXcmds * sizeof (struct scmd)); - pasXcmds[cXcmds - 1] = s; -} - -/* Copy stdin to a file. This is a separate function because it may - call setjump. */ - -static void -uxcopy_stdin (e) - FILE *e; -{ - CATCH_PROTECT int cread; - char ab[1024]; - - do - { - int cwrite; - - if (fsysdep_catch ()) - { - usysdep_start_catch (); - if (FGOT_SIGNAL ()) - uxabort (); - - /* There's an unimportant race here. If the user hits ^C - between the FGOT_SIGNAL we just did and the time we enter - fread, we won't know about the signal (unless we're doing - a longjmp, but we normally aren't). It's not a big - problem, because the user can just hit ^C again. */ - - cread = fread (ab, sizeof (char), sizeof ab, stdin); - } - - usysdep_end_catch (); - - if (FGOT_SIGNAL ()) - uxabort (); - - if (cread > 0) - { - cwrite = fwrite (ab, sizeof (char), cread, e); - if (cwrite != cread) - { - if (cwrite == EOF) - ulog (LOG_FATAL, "fwrite: %s", strerror (errno)); - else - ulog (LOG_FATAL, "fwrite: Wrote %d when attempted %d", - cwrite, cread); - } - } - } - while (cread == sizeof ab); -} - -/* Keep track of all files we have created so that we can delete them - if we get a signal. The argument will be on the heap. */ - -static int cxfiles; -static const char **pxaz; - -static void -uxrecord_file (zfile) - const char *zfile; -{ - pxaz = (const char **) xrealloc ((pointer) pxaz, - (cxfiles + 1) * sizeof (const char *)); - pxaz[cxfiles] = zfile; - ++cxfiles; -} - -/* Delete all the files we have recorded and exit. */ - -static void -uxabort () -{ - int i; - - if (eXxqt_file != NULL) - (void) fclose (eXxqt_file); - if (eXclose != NULL) - (void) fclose (eXclose); - for (i = 0; i < cxfiles; i++) - (void) remove (pxaz[i]); - ulog_close (); - usysdep_exit (FALSE); -} diff --git a/gnu/libexec/uucp/uuxqt.8 b/gnu/libexec/uucp/uuxqt.8 deleted file mode 100644 index 30f007f065b..00000000000 --- a/gnu/libexec/uucp/uuxqt.8 +++ /dev/null @@ -1,109 +0,0 @@ -''' $Id: uuxqt.8,v 1.1.1.1 1993/03/21 09:45:37 cgd Exp $ -''' $Log: uuxqt.8,v $ -''' Revision 1.1.1.1 1993/03/21 09:45:37 cgd -''' initial import of 386bsd-0.1 sources -''' -''' Revision 1.4 1992/04/01 21:11:19 ian -''' Cleaned up a bit, updated -x switch -''' -''' Revision 1.3 1992/03/28 04:34:11 ian -''' David J. MacKenzie: change .TP5 to .TP 5; also updated to 1.03 -''' -''' Revision 1.2 1992/01/20 23:52:23 ian -''' Change to version 1.02 -''' -''' Revision 1.1 1991/12/14 19:05:30 ian -''' Initial revision -''' -''' -.TH uuxqt 8 "Taylor UUCP 1.03" -.SH NAME -uuxqt \- UUCP execution daemon -.SH SYNOPSIS -.B uuxqt -[ options ] -.SH DESCRIPTION -The -.I uuxqt -daemon executes commands requested by -.I uux -(1) from either the local system or from remote systems. -It is started automatically by the -.I uucico -(8) daemon (unless -.I uucico -(8) is given the -.B \-q -option). - -There is normally no need to run this command, since it will be -invoked by -.I uucico -(8). However, it can be used to provide greater control over the -processing of the work queue. - -Multiple invocations of -.I uuxqt -may be run at once, as controlled by the -.I max-uuxqts -configuration command. -.SH OPTIONS -The following options may be given to -.I uuxqt. -.TP 5 -.B \-c command -Only execute requests for the specified command. For example: -.EX -uuxqt -c rmail -.EE -.TP 5 -.B \-s system -Only execute requests originating from the specified system. -.TP 5 -.B \-x type -Turn on particular debugging types. The following types are -recognized: abnormal, chat, handshake, uucp-proto, proto, port, -config, spooldir, execute, incoming, outgoing. Only abnormal, config, -spooldir and execute are meaningful for -.I uuxqt. - -Multiple types may be given, separated by commas, and the -.B \-x -option may appear multiple times. A number may also be given, which -will turn on that many types from the foregoing list; for example, -.B \-x 2 -is equivalent to -.B \-x abnormal,chat. - -The debugging output is sent to the debugging file, usually one of -/usr/spool/uucp/Debug, /usr/spool/uucp/DEBUG, or -/usr/spool/uucp/.Admin/audit.local. -.TP 5 -.B \-I file -Set configuration file to use. This option may not be available, -depending upon how -.I uuxqt -was compiled. -.SH FILES -The file names may be changed at compilation time or by the -configuration file, so these are only approximations. - -.br -/usr/lib/uucp/config - Configuration file. -.br -/usr/spool/uucp - -UUCP spool directory. -.br -/usr/spool/uucp/Log - -UUCP log file. -.br -/usr/spool/uucppublic - -Default UUCP public directory. -.br -/usr/spool/uucp/Debug - -Debugging file. -.SH SEE ALSO -uucp(1), uux(1), uucico(8) -.SH AUTHOR -Ian Lance Taylor -(ian@airs.com or uunet!airs!ian) diff --git a/gnu/libexec/uucp/uuxqt.c b/gnu/libexec/uucp/uuxqt.c deleted file mode 100644 index c1d9f990fda..00000000000 --- a/gnu/libexec/uucp/uuxqt.c +++ /dev/null @@ -1,1370 +0,0 @@ -/* uuxqt.c - Run uux commands. - - 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 AIRS, P.O. Box 520, Waltham, MA 02254. - - $Log: uuxqt.c,v $ - Revision 1.1.1.1 1993/03/21 09:45:37 cgd - initial import of 386bsd-0.1 sources - - Revision 1.43 1992/03/17 04:42:41 ian - Correct bug in previous patch - - Revision 1.42 1992/03/17 03:15:40 ian - Pass command to fsysdep_execute as first element of argument array - - Revision 1.41 1992/03/17 01:07:15 ian - Miscellaneous cleanup - - Revision 1.40 1992/03/16 19:44:45 ian - Cast result of alloca - - Revision 1.39 1992/03/15 04:51:17 ian - Keep an array of signals we've received rather than a single variable - - Revision 1.38 1992/03/15 01:54:46 ian - All execs are now done in isspawn, all waits are done in iswait - - Revision 1.37 1992/03/12 19:54:43 ian - Debugging based on types rather than number - - Revision 1.36 1992/03/11 22:34:25 ian - Chip Salzenberg: support Internet mail addresses in uuxqt replies - - Revision 1.35 1992/03/11 22:06:37 ian - Marty Shannon: added max-uuxqts command - - Revision 1.34 1992/03/11 17:04:53 ian - Jon Zeeff: retry execution later if temporary failure - - Revision 1.33 1992/03/11 02:09:19 ian - Correct bug in previous change - - Revision 1.32 1992/03/04 02:32:26 ian - Handle executions on local system - - Revision 1.31 1992/02/29 04:07:08 ian - Added -j option to uucp and uux - - Revision 1.30 1992/02/29 01:06:59 ian - Chip Salzenberg: recheck file permissions before sending - - Revision 1.29 1992/02/27 05:40:54 ian - T. William Wells: detach from controlling terminal, handle signals safely - - Revision 1.28 1992/02/24 04:58:47 ian - Only permit files to be received into directories that are world-writeable - - Revision 1.27 1992/02/23 19:50:50 ian - Handle READ and WRITE in Permissions correctly - - Revision 1.26 1992/02/23 03:26:51 ian - Overhaul to use automatic configure shell script - - Revision 1.25 1992/02/18 19:03:02 ian - Pass fdaemon argument correctly to usysdep_initialize - - Revision 1.24 1992/02/18 04:53:26 ian - T. William Wells: make sure sh execution uses absolute path - - Revision 1.23 1992/02/14 21:32:50 ian - Niels Baggesen: under HAVE_BNU_LOGGING, don't lost system name when dieing - - Revision 1.22 1992/02/08 22:33:32 ian - Only get the current working directory if it's going to be needed - - Revision 1.21 1992/02/08 20:33:57 ian - Handle all possible signals raised by abort - - Revision 1.20 1992/02/08 03:54:18 ian - Include <string.h> only in <uucp.h>, added 1992 copyright - - Revision 1.19 1992/01/16 17:48:41 ian - Niels Baggesen: was checking strcmp return incorrectly - - Revision 1.18 1992/01/15 07:06:29 ian - Set configuration directory in Makefile rather than sysdep.h - - Revision 1.17 1992/01/05 03:09:17 ian - Changed abProgram and abVersion to non const to avoid compiler bug - - Revision 1.16 1992/01/04 21:43:24 ian - Chip Salzenberg: added ALLOW_FILENAME_ARGUMENTS to permit them - - Revision 1.15 1992/01/04 04:12:54 ian - David J. Fiander: make sure execution arguments are not bad file names - - Revision 1.14 1991/12/29 04:22:41 ian - The mailing address was not getting initialized - - Revision 1.13 1991/12/29 04:04:18 ian - Added a bunch of extern definitions - - Revision 1.12 1991/12/20 00:17:38 ian - Don't process execute files for unknown systems - - Revision 1.11 1991/12/19 03:52:07 ian - David Nugent: rescan the list of execute files until nothing can be done - - Revision 1.10 1991/12/18 03:54:14 ian - Made error messages to terminal appear more normal - - Revision 1.9 1991/12/17 04:55:01 ian - David Nugent: ignore SIGHUP in uucico and uuxqt - - Revision 1.8 1991/12/09 18:49:06 ian - Richard Todd: the requestor address is relative to the requesting system - - Revision 1.7 1991/12/06 23:42:18 ian - Don't acknowledge success by default - - Revision 1.6 1991/12/01 01:28:44 ian - Mitch Mitchell: fixed comment listing supported commands - - Revision 1.5 1991/11/21 22:17:06 ian - Add version string, print version when printing usage - - Revision 1.4 1991/11/07 20:52:33 ian - Chip Salzenberg: pass command as single argument to /bin/sh - - Revision 1.3 1991/09/19 16:15:58 ian - Chip Salzenberg: configuration option for permitting execution via sh - - Revision 1.2 1991/09/19 02:30:37 ian - From Chip Salzenberg: check whether signal is ignored differently - - Revision 1.1 1991/09/10 19:40:31 ian - Initial revision - - */ - -#include "uucp.h" - -#if USE_RCS_ID -char uuxqt_rcsid[] = "$Id: uuxqt.c,v 1.1.1.1 1993/03/21 09:45:37 cgd Exp $"; -#endif - -#include <errno.h> -#include <ctype.h> - -#include "getopt.h" - -#include "system.h" -#include "sysdep.h" - -/* External functions. */ -extern int fclose (); - -/* The program name. */ -char abProgram[] = "uuxqt"; - -/* Static variables used to unlock things if we get a fatal error. */ - -static int iQunlock_seq = -1; -static const char *zQunlock_cmd; -static const char *zQunlock_file; -static boolean fQunlock_directory; - -/* Local functions. */ - -static void uqusage P((void)); -static void uqabort P((void)); -static void uqdo_xqt_file P((const char *zfile, - const struct ssysteminfo *qsys, - const char *zcmd, boolean *pfprocessed)); -static void uqcleanup P((const char *zfile, int iflags)); - -/* Long getopt options. */ - -static const struct option asQlongopts[] = { { NULL, 0, NULL, 0 } }; - -const struct option *_getopt_long_options = asQlongopts; - -int -main (argc, argv) - int argc; - char **argv; -{ - int iopt; - /* The type of command to execute (NULL for any type). */ - const char *zcmd = NULL; - /* The configuration file name. */ - const char *zconfig = NULL; - /* The system to execute commands for. */ - const char *zdosys = NULL; - boolean fany; - const char *z; - const char *zgetsys; - boolean ferr; - struct ssysteminfo sreadsys; - const struct ssysteminfo *qreadsys; - - while ((iopt = getopt (argc, argv, "c:I:s:x:")) != EOF) - { - switch (iopt) - { - case 'c': - /* Set the type of command to execute. */ - zcmd = optarg; - break; - - case 'I': - /* Set the configuration file name. */ - zconfig = optarg; - break; - - case 's': - zdosys = optarg; - break; - - case 'x': -#if DEBUG > 1 - /* Set the debugging level. */ - iDebug |= idebug_parse (optarg); -#endif - break; - - case 0: - /* Long option found and flag set. */ - break; - - default: - uqusage (); - break; - } - } - - if (optind != argc) - uqusage (); - - uread_config (zconfig); - -#ifdef SIGINT - usysdep_signal (SIGINT); -#endif -#ifdef SIGHUP - usysdep_signal (SIGHUP); -#endif -#ifdef SIGQUIT - usysdep_signal (SIGQUIT); -#endif -#ifdef SIGTERM - usysdep_signal (SIGTERM); -#endif -#ifdef SIGPIPE - usysdep_signal (SIGPIPE); -#endif - - usysdep_initialize (TRUE, FALSE); - - ulog_to_file (TRUE); - ulog_fatal_fn (uqabort); - - /* Limit the number of uuxqt processes, and make sure we're the only - uuxqt daemon running for this command. */ - iQunlock_seq = isysdep_lock_uuxqt (zcmd); - if (iQunlock_seq < 0) - { - ulog_close (); - usysdep_exit (TRUE); - } - zQunlock_cmd = zcmd; - - /* Keep scanning the execute files until we don't process any of - them. */ - - do - { - fany = FALSE; - - /* Look for each execute file, and run it. */ - - if (! fsysdep_get_xqt_init ()) - { - ulog_close (); - usysdep_exit (FALSE); - } - - qreadsys = NULL; - - while ((z = zsysdep_get_xqt (&zgetsys, &ferr)) != NULL) - { - char *zcopy; - boolean fprocessed; - const struct ssysteminfo *qusesys; - -#if ! HAVE_ALLOCA - /* Clear out any accumulated alloca buffers. */ - (void) alloca (0); -#endif - - /* It would be more efficient to pass zdosys down to the - routines which retrieve execute files. */ - if (zdosys != NULL && strcmp (zdosys, zgetsys) != 0) - continue; - - if (strcmp (zgetsys, zLocalname) == 0) - qusesys = &sLocalsys; - else - { - if (qreadsys == NULL - || strcmp (qreadsys->zname, zgetsys) != 0) - { - if (fread_system_info (zgetsys, &sreadsys)) - qreadsys = &sreadsys; - else - { - if (! fUnknown_ok) - { - ulog (LOG_ERROR, - "%s: Execute file for unknown system %s", - z, zgetsys); - (void) remove (z); - continue; - } - qreadsys = &sUnknown; - sUnknown.zname = xstrdup (zgetsys); - } - - if (! fsysdep_make_spool_dir (qreadsys)) - continue; - } - - qusesys = qreadsys; - } - - /* If we've received a signal, get out of the loop. */ - if (FGOT_SIGNAL ()) - break; - - zcopy = xstrdup (z); - - ulog_system (qusesys->zname); - uqdo_xqt_file (zcopy, qusesys, zcmd, &fprocessed); - ulog_system ((const char *) NULL); - ulog_user ((const char *) NULL); - - if (fprocessed) - fany = TRUE; - xfree ((pointer) zcopy); - } - - usysdep_get_xqt_free (); - } - while (fany && ! FGOT_SIGNAL ()); - - (void) fsysdep_unlock_uuxqt (iQunlock_seq, zcmd); - iQunlock_seq = -1; - - ulog_close (); - - if (FGOT_SIGNAL ()) - ferr = TRUE; - - usysdep_exit (! ferr); - - /* Avoid errors about not returning a value. */ - return 0; -} - -static void -uqusage () -{ - fprintf (stderr, - "Taylor UUCP version %s, copyright (C) 1991, 1992 Ian Lance Taylor\n", - abVersion); - fprintf (stderr, - "Usage: uuxqt [-c cmd] [-I file] [-s system] [-x debug]\n"); - fprintf (stderr, - " -c cmd: Set type of command to execute\n"); - fprintf (stderr, - " -s system: Execute commands only for named system\n"); - fprintf (stderr, - " -x debug: Set debugging level (0 for none, 9 is max)\n"); -#if HAVE_TAYLOR_CONFIG - fprintf (stderr, - " -I file: Set configuration file to use (default %s%s)\n", - NEWCONFIGLIB, CONFIGFILE); -#endif /* HAVE_TAYLOR_CONFIG */ - exit (EXIT_FAILURE); -} - -/* This is the abort function called when we get a fatal error. */ - -static void -uqabort () -{ -#if ! HAVE_BNU_LOGGING - /* When using BNU logging, it's a pain to have no system name. */ - ulog_system ((const char *) NULL); -#endif - - ulog_user ((const char *) NULL); - - if (fQunlock_directory) - (void) fsysdep_unlock_uuxqt_dir (); - - if (zQunlock_file != NULL) - (void) fsysdep_unlock_uuxqt_file (zQunlock_file); - - if (iQunlock_seq >= 0) - (void) fsysdep_unlock_uuxqt (iQunlock_seq, zQunlock_cmd); - - ulog_close (); - - usysdep_exit (FALSE); -} - -/* An execute file is a series of lines. The first character of each - line is a command. The following commands are defined: - - C command-line - I standard-input - O standard-output [ system ] - F required-file filename-to-use - R requestor-address - U user system - Z (acknowledge if command failed; default) - N (no acknowledgement on failure) - n (acknowledge if command succeeded) - B (return command input on error) - e (process with sh) - E (process with exec) - M status-file - # comment - - Unrecognized commands are ignored. We actually do not recognize - the Z command, since it requests default behaviour. We always send - mail on failure, unless the N command appears. We never send mail - on success, unless the n command appears. - - This code does not currently support the B or M commands. */ - -/* Command arguments. */ -static const char **azQargs; -/* Command as a complete string. */ -static char *zQcmd; -/* Standard input file name. */ -static const char *zQinput; -/* Standard output file name. */ -static const char *zQoutfile; -/* Standard output system. */ -static const char *zQoutsys; -/* Number of required files. */ -static int cQfiles; -/* Names of required files. */ -static char **azQfiles; -/* Names required files should be renamed to (NULL if original is OK). */ -static char **azQfiles_to; -/* Requestor address (this is where mail should be sent). */ -static const char *zQrequestor; -/* User name. */ -static const char *zQuser; -/* System name. */ -static const char *zQsystem; -/* This is set by the N flag, meaning that no acknowledgement should - be mailed on failure. */ -static boolean fQno_ack; -/* This is set by the n flag, meaning that acknowledgement should be - mailed if the command succeeded. */ -static boolean fQsuccess_ack; -/* This is set by the B flag, meaning that command input should be - mailed to the requestor if an error occurred. */ -static boolean fQsend_input; -/* This is set by the E flag, meaning that exec should be used to - execute the command. */ -static boolean fQuse_exec; -/* The status should be copied to this file on the requesting host. */ -static const char *zQstatus_file; -#if ALLOW_SH_EXECUTION -/* This is set by the e flag, meaning that sh should be used to - execute the command. */ -static boolean fQuse_sh; -#endif /* ALLOW_SH_EXECUTION */ - -static enum tcmdtabret tqcmd P((int argc, char **argv, pointer pvar, - const char *zerr)); -static enum tcmdtabret tqout P((int argc, char **argv, pointer pvar, - const char *zerr)); -static enum tcmdtabret tqfile P((int argc, char **argv, pointer pvar, - const char *zerr)); -static enum tcmdtabret tquser P((int argc, char **argv, pointer pvar, - const char *zerr)); -static enum tcmdtabret tqset P((int argc, char **argv, pointer pvar, - const char *zerr)); - -static struct scmdtab asQcmds[] = -{ - { "C", CMDTABTYPE_FN | 0, NULL, tqcmd }, - { "I", CMDTABTYPE_STRING, (pointer) &zQinput, NULL }, - { "O", CMDTABTYPE_FN | 0, NULL, tqout }, - { "F", CMDTABTYPE_FN | 0, NULL, tqfile }, - { "R", CMDTABTYPE_STRING, (pointer) &zQrequestor, NULL }, - { "U", CMDTABTYPE_FN | 3, NULL, tquser }, - { "N", CMDTABTYPE_FN | 1, (pointer) &fQno_ack, tqset }, - { "n", CMDTABTYPE_FN | 1, (pointer) &fQsuccess_ack, tqset }, - { "B", CMDTABTYPE_FN | 1, (pointer) &fQsend_input, tqset }, -#if ALLOW_SH_EXECUTION - { "e", CMDTABTYPE_FN | 1, (pointer) &fQuse_sh, tqset }, -#endif - { "E", CMDTABTYPE_FN | 1, (pointer) &fQuse_exec, tqset }, - { "M", CMDTABTYPE_STRING, (pointer) &zQstatus_file, NULL }, - { NULL, 0, NULL, NULL } -}; - -/* Handle the C command: store off the arguments. */ - -/*ARGSUSED*/ -static enum tcmdtabret -tqcmd (argc, argv, pvar, zerr) - int argc; - char **argv; - pointer pvar; - const char *zerr; -{ - int i; - int clen; - - if (argc <= 1) - return CMDTABRET_FREE; - - azQargs = (const char **) xmalloc (argc * sizeof (char *)); - clen = 0; - for (i = 1; i < argc; i++) - { - azQargs[i - 1] = argv[i]; - clen += strlen (argv[i]) + 1; - } - azQargs[i - 1] = NULL; - - zQcmd = (char *) xmalloc (clen); - zQcmd[0] = '\0'; - for (i = 1; i < argc - 1; i++) - { - strcat (zQcmd, argv[i]); - strcat (zQcmd, " "); - } - strcat (zQcmd, argv[i]); - - return CMDTABRET_CONTINUE; -} - -/* Handle the O command, which may have one or two arguments. */ - -/*ARGSUSED*/ -static enum tcmdtabret -tqout (argc, argv, pvar, zerr) - int argc; - char **argv; - pointer pvar; - const char *zerr; -{ - if (argc != 2 && argc != 3) - { - ulog (LOG_ERROR, "%s: %s: Wrong number of arguments", - zerr, argv[0]); - return CMDTABRET_FREE; - } - - zQoutfile = argv[1]; - if (argc == 3) - zQoutsys = argv[2]; - - return CMDTABRET_CONTINUE; -} - -/* Handle the F command, which may have one or two arguments. */ - -/*ARGSUSED*/ -static enum tcmdtabret -tqfile (argc, argv, pvar, zerr) - int argc; - char **argv; - pointer pvar; - const char *zerr; -{ - if (argc != 2 && argc != 3) - { - ulog (LOG_ERROR, "%s: %s: Wrong number of arguments", - zerr, argv[0]); - return CMDTABRET_FREE; - } - - /* If this file is not in the spool directory, just ignore it. */ - if (! fspool_file (argv[1])) - return CMDTABRET_FREE; - - ++cQfiles; - azQfiles = (char **) xrealloc ((pointer) azQfiles, - cQfiles * sizeof (char *)); - azQfiles_to = (char **) xrealloc ((pointer) azQfiles_to, - cQfiles * sizeof (char *)); - - azQfiles[cQfiles - 1] = xstrdup (argv[1]); - if (argc == 3) - azQfiles_to[cQfiles - 1] = xstrdup (argv[2]); - else - azQfiles_to[cQfiles - 1] = NULL; - - return CMDTABRET_FREE; -} - -/* Handle the U command, which takes two arguments. */ - -/*ARGSUSED*/ -static enum tcmdtabret -tquser (argc, argv, pvar, zerr) - int argc; - char **argv; - pointer pvar; - const char *zerr; -{ - zQuser = argv[1]; - zQsystem = argv[2]; - return CMDTABRET_CONTINUE; -} - -/* Handle various commands which just set boolean variables. */ - -/*ARGSUSED*/ -static enum tcmdtabret -tqset (argc, argv, pvar, zerr) - int argc; - char **argv; - pointer pvar; - const char *zerr; -{ - boolean *pf = (boolean *) pvar; - - *pf = TRUE; - return CMDTABRET_FREE; -} - -/* The execution processing does a lot of things that have to be - cleaned up. Rather than try to add the appropriate statements - to each return point, we keep a set of flags indicating what - has to be cleaned up. The actual clean up is done by the - function uqcleanup. */ - -#define REMOVE_FILE (01) -#define REMOVE_NEEDED (02) -#define FREE_QINPUT (04) - -/* Process an execute file. The zfile argument is the name of the - execute file. The qsys argument describes the system it came from. - The zcmd argument is the name of the command we are executing (from - the -c option) or NULL if any command is OK. This sets - *pfprocessed to TRUE if the file is ready to be executed. */ - -static void -uqdo_xqt_file (zfile, qsys, zcmd, pfprocessed) - const char *zfile; - const struct ssysteminfo *qsys; - const char *zcmd; - boolean *pfprocessed; -{ - const char *zcmds; - const char *zabsolute; - boolean ferr; - FILE *e; - int i; - int iclean; - const char *zmail; - const char *zoutput; - char abtemp[CFILE_NAME_LEN]; - char abdata[CFILE_NAME_LEN]; - const char *zerror; - struct ssysteminfo soutsys; - const struct ssysteminfo *qoutsys; - boolean fshell; - char *zfullcmd; - boolean ftemp; - - *pfprocessed = FALSE; - - /* If we're not permitted to execute anything for this system, - we can just clobber the file without even looking at it. */ - zcmds = qsys->zcmds; - - if (*zcmds == '\0') - { - ulog (LOG_ERROR, "%s: No commands permitted for system %s", - zfile, qsys->zname); - (void) remove (zfile); - return; - } - - /* If we are only willing to execute a particular command, and it - is not one of those accepted by this system, quit now. */ - if (zcmd != NULL - && strcmp (zcmds, "ALL") != 0 - && strstr (zcmds, zcmd) == NULL) - return; - - e = fopen (zfile, "r"); - if (e == NULL) - return; - - azQargs = NULL; - zQcmd = NULL; - zQinput = NULL; - zQoutfile = NULL; - zQoutsys = NULL; - cQfiles = 0; - azQfiles = NULL; - azQfiles_to = NULL; - zQrequestor = NULL; - zQuser = NULL; - zQsystem = NULL; - fQno_ack = FALSE; - fQsuccess_ack = FALSE; - fQsend_input = FALSE; - fQuse_exec = FALSE; - zQstatus_file = NULL; -#if ALLOW_SH_EXECUTION - fQuse_sh = FALSE; -#endif - - uprocesscmds (e, (struct smulti_file *) NULL, asQcmds, zfile, 0); - - (void) fclose (e); - - iclean = 0; - - if (azQargs == NULL) - { - ulog (LOG_ERROR, "%s: No command given", zfile); - uqcleanup (zfile, iclean | REMOVE_FILE); - return; - } - - if (zcmd != NULL) - { - if (strcmp (zcmd, azQargs[0]) != 0) - { - uqcleanup (zfile, iclean); - return; - } - } - else - { - /* If there is a lock file for this particular command already, - it means that some other uuxqt is supposed to handle it. */ - if (fsysdep_uuxqt_locked (azQargs[0])) - { - uqcleanup (zfile, iclean); - return; - } - } - - /* Lock this particular file. */ - - if (! fsysdep_lock_uuxqt_file (zfile)) - { - uqcleanup (zfile, iclean); - return; - } - - zQunlock_file = zfile; - - if (zQuser != NULL) - ulog_user (zQuser); - else if (zQrequestor != NULL) - ulog_user (zQrequestor); - else - ulog_user ("unknown"); - - /* Make sure that all the required files exist, and get their - full names in the spool directory. */ - - for (i = 0; i < cQfiles; i++) - { - const char *zreal; - - zreal = zsysdep_spool_file_name (qsys, azQfiles[i]); - if (zreal == NULL) - { - uqcleanup (zfile, iclean); - return; - } - if (! fsysdep_file_exists (zreal)) - { - uqcleanup (zfile, iclean); - return; - } - xfree ((pointer) azQfiles[i]); - azQfiles[i] = xstrdup (zreal); - } - - /* See if we need the execute directory, and lock it if we do. */ - - for (i = 0; i < cQfiles; i++) - { - int itries; - - if (azQfiles_to[i] == NULL) - continue; - - for (itries = 0; itries < 5; itries++) - { - if (fsysdep_lock_uuxqt_dir ()) - break; - usysdep_sleep (30); - } - if (itries >= 5) - { - ulog (LOG_ERROR, "Could not lock execute directory"); - uqcleanup (zfile, iclean); - return; - } - - fQunlock_directory = TRUE; - break; - } - - iclean |= REMOVE_FILE | REMOVE_NEEDED; - *pfprocessed = TRUE; - - /* Get the address to mail results to. Prepend the system from - which the execute file originated, since mail addresses are - relative to it. */ - - zmail = NULL; - if (zQrequestor != NULL) - zmail = zQrequestor; - else if (zQuser != NULL) - zmail = zQuser; - if (zmail != NULL - && zQsystem != NULL -#if HAVE_INTERNET_MAIL - && strchr (zmail, '@') == NULL -#endif - && strcmp (zQsystem, zLocalname) != 0) - { - char *zset; - - zset = (char *) alloca (strlen (zQsystem) + strlen (zmail) + 2); - - sprintf (zset, "%s!%s", zQsystem, zmail); - zmail = zset; - } - - /* Get the pathname to execute. */ - - zabsolute = zsysdep_find_command (azQargs[0], zcmds, qsys->zpath, - &ferr); - if (zabsolute == NULL) - { - if (ferr) - { - /* If we get an error, try again later. */ - uqcleanup (zfile, iclean &~ (REMOVE_FILE | REMOVE_NEEDED)); - *pfprocessed = FALSE; - return; - } - - /* Not permitted. Send mail to requestor. */ - - ulog (LOG_ERROR, "Not permitted to execute %s", - azQargs[0]); - - if (zmail != NULL && ! fQno_ack) - { - const char *az[20]; - - i = 0; - az[i++] = "Your execution request failed because you are not"; - az[i++] = " permitted to execute\n\t"; - az[i++] = azQargs[0]; - az[i++] = "\non this system.\n"; - az[i++] = "Execution requested was:\n\t"; - az[i++] = zQcmd; - az[i++] = "\n"; - - (void) fsysdep_mail (zmail, "Execution failed", i, az); - } - - uqcleanup (zfile, iclean); - return; - } - - { - char *zcopy; - - zcopy = (char *) alloca (strlen (zabsolute) + 1); - strcpy (zcopy, zabsolute); - zabsolute = zcopy; - } - - azQargs[0] = zabsolute; - -#if ! ALLOW_FILENAME_ARGUMENTS - - /* Check all the arguments to make sure they don't try to specify - files they are not permitted to access. */ - - for (i = 1; azQargs[i] != NULL; i++) - { - if (! fsysdep_xqt_check_file (qsys, azQargs[i])) - { - if (zmail != NULL && ! fQno_ack) - { - const char *az[20]; - const char *zfailed; - - zfailed = azQargs[i]; - i = 0; - az[i++] = "Your execution request failed because you are not"; - az[i++] = " permitted to refer to file\n\t"; - az[i++] = zfailed; - az[i++] = "\non this system.\n"; - az[i++] = "Execution requested was:\n\t"; - az[i++] = zQcmd; - az[i++] = "\n"; - - (void) fsysdep_mail (zmail, "Execution failed", i, az); - } - - uqcleanup (zfile, iclean); - return; - } - } - -#endif /* ! ALLOW_FILENAME_ARGUMENTS */ - - ulog (LOG_NORMAL, "Executing %s (%s)", zfile, zQcmd); - - if (zQinput != NULL) - { - boolean fspool; - - fspool = fspool_file (zQinput); - if (fspool) - zQinput = zsysdep_spool_file_name (qsys, zQinput); - else - zQinput = zsysdep_real_file_name (qsys, zQinput, - (const char *) NULL); - if (zQinput == NULL) - { - /* If we get an error, try again later. */ - uqcleanup (zfile, iclean &~ (REMOVE_FILE | REMOVE_NEEDED)); - *pfprocessed = FALSE; - return; - } - - zQinput = xstrdup (zQinput); - iclean |= FREE_QINPUT; - - if (! fspool - && ! fin_directory_list (qsys, zQinput, - qsys->zremote_send, TRUE, TRUE, - (const char *) NULL)) - { - ulog (LOG_ERROR, "Not permitted to read %s", zQinput); - - if (zmail != NULL && ! fQno_ack) - { - const char *az[20]; - - i = 0; - az[i++] = "Your execution request failed because you are"; - az[i++] = " not permitted to read\n\t"; - az[i++] = zQinput; - az[i++] = "\non this system.\n"; - az[i++] = "Execution requested was:\n\t"; - az[i++] = zQcmd; - az[i++] = "\n"; - - (void) fsysdep_mail (zmail, "Execution failed", i, az); - } - - uqcleanup (zfile, iclean); - return; - } - } - - if (zQoutfile == NULL) - { - zoutput = NULL; - qoutsys = NULL; - } - else if (zQoutsys != NULL - && strcmp (zQoutsys, zLocalname) != 0) - { - const char *zdata; - char *zcopy; - - /* The output file is destined for some other system, so we must - use a temporary file to catch standard output. */ - - if (strcmp (zQoutsys, qsys->zname) == 0) - qoutsys = qsys; - else - { - if (! fread_system_info (zQoutsys, &soutsys)) - { - if (! fUnknown_ok) - { - ulog (LOG_ERROR, - "Can't send standard output to unknown system %s", - zQoutsys); - /* We don't send mail to unknown systems, either. - Maybe we should. */ - uqcleanup (zfile, iclean); - return; - } - soutsys = sUnknown; - soutsys.zname = zQoutsys; - } - - qoutsys = &soutsys; - - if (! fsysdep_make_spool_dir (qoutsys)) - { - /* If we get an error, try again later. */ - uqcleanup (zfile, iclean &~ (REMOVE_FILE | REMOVE_NEEDED)); - *pfprocessed = FALSE; - return; - } - } - - zdata = zsysdep_data_file_name (qoutsys, BDEFAULT_UUX_GRADE, abtemp, - abdata, (char *) NULL); - if (zdata == NULL) - { - /* If we get an error, try again later. */ - uqcleanup (zfile, iclean &~ (REMOVE_FILE | REMOVE_NEEDED)); - *pfprocessed = FALSE; - return; - } - - zcopy = (char *) alloca (strlen (zdata) + 1); - strcpy (zcopy, zdata); - zoutput = zcopy; - } - else - { - boolean fok; - char *zcopy; - - qoutsys = NULL; - - /* If we permitted the standard output to be redirected into - the spool directory, people could set up phony commands. */ - - if (fspool_file (zQoutfile)) - fok = FALSE; - else - { - zQoutfile = zsysdep_real_file_name (&sLocalsys, zQoutfile, - (const char *) NULL); - if (zQoutfile == NULL) - { - /* If we get an error, try again later. */ - uqcleanup (zfile, iclean &~ (REMOVE_FILE | REMOVE_NEEDED)); - *pfprocessed = FALSE; - return; - } - - /* Make sure it's OK to receive this file. Note that this - means that a locally executed uux (which presumably - requires remote files) will only be able to create files - in standard directories. If we don't it this way, users - could clobber files which uucp has access to; still, it - would be nice to allow them to direct the output to their - home directory. */ - - fok = fin_directory_list (qsys, zQoutfile, qsys->zremote_receive, - TRUE, FALSE, (const char *) NULL); - } - - if (! fok) - { - ulog (LOG_ERROR, "Not permitted to write to %s", zQoutfile); - - if (zmail != NULL && ! fQno_ack) - { - const char *az[20]; - - i = 0; - az[i++] = "Your execution request failed because you are"; - az[i++] = " not permitted to write to\n\t"; - az[i++] = zQoutfile; - az[i++] = "\non this system.\n"; - az[i++] = "Execution requested was:\n\t"; - az[i++] = zQcmd; - az[i++] = "\n"; - - (void) fsysdep_mail (zmail, "Execution failed", i, az); - } - - uqcleanup (zfile, iclean); - return; - } - - zcopy = (char *) alloca (strlen (zQoutfile) + 1); - strcpy (zcopy, zQoutfile); - zQoutfile = zcopy; - zoutput = zcopy; - } - - /* Move the required files to the execution directory if necessary. */ - - for (i = 0; i < cQfiles; i++) - { - if (azQfiles_to[i] != NULL) - { - const char *zname; - - /* Move the file to the execute directory. */ - - zname = zsysdep_in_dir (XQTDIR, azQfiles_to[i]); - if (zname == NULL) - { - /* If we get an error, try again later. */ - uqcleanup (zfile, iclean &~ (REMOVE_FILE | REMOVE_NEEDED)); - *pfprocessed = FALSE; - return; - } - if (! fsysdep_move_file (azQfiles[i], zname, 0, FALSE, - (const char *) NULL)) - { - /* If we get an error, try again later. This may not be - correct, depending on what kind of error we get. */ - uqcleanup (zfile, iclean &~ (REMOVE_FILE | REMOVE_NEEDED)); - *pfprocessed = FALSE; - return; - } - - /* If we just moved the standard input file, adjust the - file name. */ - if (zQinput != NULL && strcmp (azQfiles[i], zQinput) == 0) - { - xfree ((pointer) zQinput); - zQinput = xstrdup (zname); - } - } - } - -#if ALLOW_SH_EXECUTION - fshell = fQuse_sh; -#else - fshell = FALSE; -#endif - - /* Get a shell command which uses the full path of the command to - execute. */ - zfullcmd = (char *) alloca (strlen (zQcmd) + strlen (azQargs[0]) + 2); - *zfullcmd = '\0'; - for (i = 0; azQargs[i] != NULL; i++) - { - strcat (zfullcmd, azQargs[i]); - strcat (zfullcmd, " "); - } - zfullcmd[strlen (zfullcmd) - 1] = '\0'; - - if (! fsysdep_execute (qsys, - zQuser == NULL ? (const char *) "uucp" : zQuser, - azQargs, zfullcmd, zQinput, zoutput, fshell, - &zerror, &ftemp)) - { - if (ftemp) - { - ulog (LOG_NORMAL, "Will retry later (%s)", zfile); - if (zoutput != NULL) - (void) remove (zoutput); - if (zerror != NULL) - (void) remove (zerror); - uqcleanup (zfile, iclean &~ (REMOVE_FILE | REMOVE_NEEDED)); - *pfprocessed = FALSE; - return; - } - - ulog (LOG_NORMAL, "Execution failed (%s)", zfile); - - if (zmail != NULL && ! fQno_ack) - { - const char **pz; - int cgot; - FILE *eerr; - int istart; - - cgot = 20; - pz = (const char **) xmalloc (cgot * sizeof (const char *)); - i = 0; - pz[i++] = "Execution request failed:\n\t"; - pz[i++] = zQcmd; - pz[i++] = "\n"; - - if (zerror == NULL) - eerr = NULL; - else - eerr = fopen (zerror, "r"); - if (eerr == NULL) - { - pz[i++] = "There was no output on standard error\n"; - istart = i; - } - else - { - char *zline; - - pz[i++] = "Standard error output was:\n"; - istart = i; - - while ((zline = zfgets (eerr, FALSE)) != NULL) - { - if (i >= cgot) - { - cgot += 20; - pz = ((const char **) - xrealloc ((pointer) pz, - cgot * sizeof (const char *))); - } - pz[i++] = zline; - } - - (void) fclose (eerr); - } - - (void) fsysdep_mail (zmail, "Execution failed", i, pz); - - for (; istart < i; istart++) - xfree ((pointer) pz[istart]); - xfree ((pointer) pz); - } - - if (qoutsys != NULL) - (void) remove (zoutput); - } - else - { - if (zmail != NULL && fQsuccess_ack) - { - const char *az[20]; - - i = 0; - az[i++] = "\nExecution request succeeded:\n\t"; - az[i++] = zQcmd; - az[i++] = "\n"; - - (void) fsysdep_mail (zmail, "Execution succeded", i, az); - } - - /* Now we may have to uucp the output to some other machine. */ - - if (qoutsys != NULL) - { - struct scmd s; - - /* Fill in the command structure. */ - - s.bcmd = 'S'; - s.pseq = NULL; - s.zfrom = abtemp; - s.zto = zQoutfile; - if (zQuser != NULL) - s.zuser = zQuser; - else - s.zuser = "uucp"; - if (zmail != NULL && fQsuccess_ack) - s.zoptions = "Cn"; - else - s.zoptions = "C"; - s.ztemp = abtemp; - s.imode = 0666; - if (zmail != NULL && fQsuccess_ack) - s.znotify = zmail; - else - s.znotify = ""; - /* The number of bytes will be filled in when the file is - actually sent. */ - s.cbytes = -1; - - (void) zsysdep_spool_commands (qoutsys, BDEFAULT_UUX_GRADE, - 1, &s); - } - } - - if (zerror != NULL) - (void) remove (zerror); - - uqcleanup (zfile, iclean); -} - -/* Clean up the results of uqdo_xqt_file. */ - -static void -uqcleanup (zfile, iflags) - const char *zfile; - int iflags; -{ - int i; - - DEBUG_MESSAGE2 (DEBUG_SPOOLDIR, - "uqcleanup: %s, %d", zfile, iflags); - - if (zQunlock_file != NULL) - { - (void) fsysdep_unlock_uuxqt_file (zQunlock_file); - zQunlock_file = NULL; - } - - if ((iflags & REMOVE_FILE) != 0) - (void) remove (zfile); - - if ((iflags & REMOVE_NEEDED) != 0) - { - for (i = 0; i < cQfiles; i++) - { - if (azQfiles[i] != NULL) - (void) remove (azQfiles[i]); - } - } - - if ((iflags & FREE_QINPUT) != 0) - xfree ((pointer) zQinput); - - if (fQunlock_directory) - { - (void) fsysdep_unlock_uuxqt_dir (); - fQunlock_directory = FALSE; - } - - for (i = 0; i < cQfiles; i++) - { - xfree ((pointer) azQfiles[i]); - xfree ((pointer) azQfiles_to[i]); - } - - xfree ((pointer) azQargs); - azQargs = NULL; - - xfree ((pointer) zQcmd); - zQcmd = NULL; - - xfree ((pointer) azQfiles); - azQfiles = NULL; - - xfree ((pointer) azQfiles_to); - azQfiles_to = NULL; -} diff --git a/gnu/libexec/uucp/v2.c b/gnu/libexec/uucp/v2.c deleted file mode 100644 index e514688889c..00000000000 --- a/gnu/libexec/uucp/v2.c +++ /dev/null @@ -1,652 +0,0 @@ -/* v2.c - Read V2 configuration files. Much of this file is identical to bnu.c, - and they really should be partially merged. - - 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 AIRS, P.O. Box 520, Waltham, MA 02254. - - $Log: v2.c,v $ - Revision 1.1.1.1 1993/03/21 09:45:37 cgd - initial import of 386bsd-0.1 sources - - Revision 1.15 1992/03/12 19:54:43 ian - Debugging based on types rather than number - - Revision 1.14 1992/03/10 21:47:39 ian - Added protocol command for ports - - Revision 1.13 1992/03/04 02:09:36 ian - Jeff Putsch: infinite loop when parsing time string - - Revision 1.12 1992/02/24 20:36:27 ian - Roberto Biancardi: skip spaces after strtok (NULL, "") - - Revision 1.11 1992/02/08 03:54:18 ian - Include <string.h> only in <uucp.h>, added 1992 copyright - - Revision 1.10 1992/01/15 07:06:29 ian - Set configuration directory in Makefile rather than sysdep.h - - Revision 1.9 1992/01/05 04:30:45 ian - Set chat script correctly - - Revision 1.8 1991/12/28 03:49:23 ian - Added HAVE_MEMFNS and HAVE_BFNS; changed uses of memset to bzero - - Revision 1.7 1991/12/01 19:35:38 ian - David Nugent: read V2 and BNU files by default even with TAYLOR_CONFIG - - Revision 1.6 1991/11/26 01:04:04 ian - Marty Shannon: initialize ireliable for BNU and V2 configuration files - - Revision 1.5 1991/11/14 03:20:13 ian - Added seven-bit and reliable commands to help when selecting protocols - - Revision 1.4 1991/11/13 20:38:00 ian - Added TCP port type for connections over TCP - - Revision 1.3 1991/11/11 16:59:05 ian - Eliminate fread_port_info, allow NULL pflock arg to ffind_port - - Revision 1.2 1991/09/19 02:22:44 ian - Chip Salzenberg's patch to allow ";retrytime" at the end of a time string - - Revision 1.1 1991/09/10 19:40:31 ian - Initial revision - - */ - -#include "uucp.h" - -#if HAVE_V2_CONFIG - -#if USE_RCS_ID -char v2_rcsid[] = "$Id: v2.c,v 1.1.1.1 1993/03/21 09:45:37 cgd Exp $"; -#endif - -#include <errno.h> - -#include "port.h" -#include "sysdep.h" - -/* Whether to use V2 configuration files. */ -boolean fV2 = TRUE; - -/* A little routine to add a grade and a time string to a system. */ - -static void uvadd_time P((struct ssysteminfo *q, int bgrade, - const char *ztime, int cretry)); - -static void -uvadd_time (q, bgrade, ztime, cretry) - struct ssysteminfo *q; - int bgrade; - const char *ztime; - int cretry; -{ - char *zset; - - zset = (char *) alloca (strlen (ztime) + 20); - if (cretry == 0) - sprintf (zset, "%c%s", bgrade, ztime); - else - sprintf (zset, "%c%s;%d", bgrade, ztime, cretry); - uadd_string (&q->ztime, zset, ' '); -} - -/* Read V2 system information. This means reading the L.sys file and - the USERFILE file. */ - -void -uv2_read_systems (pc, ppas) - int *pc; - struct ssysteminfo **ppas; -{ - int calc; - char ab[sizeof OLDCONFIGLIB + sizeof V2_SYSTEMS - 1]; - FILE *e; - char *zline; - - *pc = 0; - *ppas = NULL; - calc = 0; - - /* Read the L.sys file first. */ - - sprintf (ab, "%s%s", OLDCONFIGLIB, V2_SYSTEMS); - e = fopen (ab, "r"); - if (e == NULL) - { - ulog (LOG_ERROR, "fopen (%s): %s", ab, strerror (errno)); - return; - } - - while ((zline = zfgets (e, FALSE)) != NULL) - { - char *ztok; - int i, cretry; - struct ssysteminfo *qset; - char *zsemi, *zslash; - - zline[strcspn (zline, "#\n")] = '\0'; - ztok = strtok (zline, " \t"); - if (ztok == NULL) - { - xfree ((pointer) zline); - continue; - } - - DEBUG_MESSAGE1 (DEBUG_CONFIG, - "uv2_read_systems: Reading system %s", ztok); - - /* See if we already have information for this system. */ - for (i = 0; i < *pc; i++) - if (strcmp ((*ppas)[i].zname, ztok) == 0) - break; - if (i >= *pc) - { - if (*pc >= calc) - { - calc += 10; - *ppas = ((struct ssysteminfo *) - xrealloc ((pointer) *ppas, - calc * sizeof (struct ssysteminfo))); - } - qset = &(*ppas)[*pc]; - (*pc)++; - } - else - { - struct ssysteminfo **pq; - - for (pq = &(*ppas)[i].qalternate; - *pq != NULL; - pq = &(*pq)->qalternate) - ; - *pq = (struct ssysteminfo *) xmalloc (sizeof (struct ssysteminfo)); - qset = *pq; - } - - uset_system_defaults (qset); - qset->zname = ztok; - - /* Get the time string. */ - ztok = strtok ((char *) NULL, " \t"); - if (ztok == NULL) - continue; - - /* The format of the time string appears to be time/grade, - time/grade;retry. A missing grade is taken as 'z'. */ - - cretry = 0; - zsemi = strchr (ztok, ';'); - if (zsemi != NULL) - { - *zsemi = '\0'; - cretry = atoi (zsemi + 1); - } - - qset->ztime = NULL; - while (TRUE) - { - char *zcomma; - - zcomma = strchr (ztok, ','); - if (zcomma != NULL) - *zcomma = '\0'; - - zslash = strchr (ztok, '/'); - if (zslash == NULL || zslash[1] == '\0') - uvadd_time (qset, BGRADE_LOW, ztok, cretry); - else - { - *zslash = '\0'; - uvadd_time (qset, zslash[1], ztok, cretry); - } - - if (zcomma == NULL) - break; - - ztok = zcomma + 1; - } - - /* Get the devices entry. */ - qset->zport = strtok ((char *) NULL, " \t"); - - if (qset->zport != NULL) - { - /* Get the speed entry. This is the baud rate to use. */ - ztok = strtok ((char *) NULL, " \t"); - -#if HAVE_TCP - /* If the port is "TCP", we set up a system specific port. - The baud rate becomes the service number and the phone - number becomes the address (which is still stored in - qsys->zphone). */ - if (strcmp (qset->zport, "TCP") == 0) - { - qset->zport = NULL; - qset->qport = ((struct sport *) - xmalloc (sizeof (struct sport))); - qset->qport->zname = "TCP"; - qset->qport->ttype = PORTTYPE_TCP; - qset->qport->zprotocols = NULL; - qset->qport->cproto_params = 0; - qset->qport->qproto_params = NULL; - qset->qport->ireliable = (RELIABLE_ENDTOEND - | RELIABLE_RELIABLE - | RELIABLE_EIGHT - | RELIABLE_SPECIFIED); - qset->qport->zlockname = NULL; - qset->qport->u.stcp.o = -1; - if (ztok == NULL) - qset->qport->u.stcp.zport = "uucp"; - else - qset->qport->u.stcp.zport = ztok; - } -#endif /* HAVE_TCP */ - - if (ztok != NULL) - { - qset->ibaud = atol (ztok); - - /* Get the phone number. */ - qset->zphone = strtok ((char *) NULL, " \t"); - - /* The rest of the line is the login script. */ - if (qset->zphone != NULL) - { - qset->schat.zchat = strtok ((char *) NULL, ""); - qset->schat.zchat += strspn (qset->schat.zchat, " \t"); - } - } - } - } - - (void) fclose (e); - - /* Now read USERFILE and L.cmds to get permissions. We can't fully - handle USERFILE since that specifies permissions based on local - users which we do not support. */ - - { - char abuserfile[sizeof OLDCONFIGLIB + sizeof V2_USERFILE - 1]; - - sprintf (abuserfile, "%s%s", OLDCONFIGLIB, V2_USERFILE); - e = fopen (abuserfile, "r"); - if (e == NULL) - ulog (LOG_ERROR, "fopen (%s): %s", abuserfile, strerror (errno)); - else - { - boolean *affound; - boolean fothercallback; - char *zother; - - affound = (boolean *) alloca (*pc * sizeof (boolean)); - bzero (affound, *pc * sizeof (boolean)); - - fothercallback = FALSE; - zother = NULL; - - while ((zline = zfgets (e, FALSE)) != NULL) - { - char *ztok, *zcomma, *zfiles, *zset; - boolean fcallback; - - zline[strcspn (zline, "#\n")] = '\0'; - - /* The first field is username,machinename */ - - ztok = strtok (zline, " \t"); - if (ztok == NULL) - { - xfree ((pointer) zline); - continue; - } - - zcomma = strchr (ztok, ','); - if (zcomma == NULL) - { - xfree ((pointer) zline); - continue; - } - - *zcomma++ = '\0'; - - /* The rest of the line is the list of directories, expect - that if the first directory is "c" we must call the - system back. */ - zfiles = strtok ((char *) NULL, ""); - zfiles += strspn (zfiles, " \t"); - fcallback = FALSE; - if (*zfiles == 'c' - && (zfiles[1] == '\0' - || zfiles[1] == ' ' - || zfiles[1] == '\t')) - { - fcallback = TRUE; - ++zfiles; - } - - zset = NULL; - for (zfiles = strtok (zfiles, " \t"); - zfiles != NULL; - zfiles = strtok ((char *) NULL, " \t")) - uadd_string (&zset, zfiles, ' '); - - if (*ztok == '\0') - { - /* There is no user name. If this is the first entry - with no user name, then this line specifies the - directories which may be sent by local request - for login names which are not listed otherwise. */ - if (zother == NULL) - { - zother = zset; - fothercallback = fcallback; - } - } - else if (*zcomma == '\0') - { - int i; - - /* There is no system name. This entry specifies - permissions based on the login name. We must add - an alternate to each system specifying what to do - when this login name is used. */ - for (i = 0; i < *pc; i++) - { - struct ssysteminfo *q; - - if ((*ppas)[i].zcalled_login != NULL - && strcmp ((*ppas)[i].zcalled_login, "ANY") != 0) - continue; - - (*ppas)[i].zcalled_login = "ANY"; - - q = ((struct ssysteminfo *) - xmalloc (sizeof (struct ssysteminfo))); - *q = (*ppas)[i]; - q->qalternate = (*ppas)[i].qalternate; - (*ppas)[i].qalternate = q; - - q->zcalled_login = xstrdup (ztok); - q->fcallback = fcallback; - q->zremote_send = q->zremote_receive = zset; - } - } - else - { - int i; - struct ssysteminfo *q; - - /* Both the login name and the machine name were - listed; require the machine to be logged in under - this name. This is not fully backward compatible, - and perhaps should be changed. On the other hand, - it is more useful. */ - - for (i = 0; i < *pc; i++) - if (strcmp ((*ppas)->zname, zcomma) == 0) - break; - if (i >= *pc) - { - /* We don't warn about systems which don't already - exist, since they may appear in sample - USERFILES. */ - xfree ((pointer) zline); - continue; - } - - affound[i] = TRUE; - - for (q = &(*ppas)[i]; q != NULL; q = q->qalternate) - { - q->zcalled_login = xstrdup (ztok); - q->zlocal_send = q->zlocal_receive = zset; - q->zremote_send = q->zremote_receive = zset; - q->fcallback = fcallback; - } - } - - xfree ((pointer) zline); - } - - (void) fclose (e); - - if (zother != NULL) - { - int i; - - for (i = 0; i < *pc; i++) - { - struct ssysteminfo *q; - - if (affound[i]) - continue; - q = &(*ppas)[i]; - if (q->zcalled_login != NULL - && strcmp (q->zcalled_login, "ANY") != 0) - continue; - q->zlocal_send = q->zlocal_receive = zother; - q->fcallback = fothercallback; - } - } - } - } - - /* Now we must read L.cmds to determine which commands may be - executed. */ - - { - char abcmds[sizeof OLDCONFIGLIB + sizeof V2_CMDS - 1]; - - sprintf (abcmds, "%s%s", OLDCONFIGLIB, V2_CMDS); - e = fopen (abcmds, "r"); - if (e == NULL) - ulog (LOG_ERROR, "fopen (%s): %s", abcmds, strerror (errno)); - else - { - char *zcmds; - int i; - struct ssysteminfo *q; - - zline = zfgets (e, FALSE); - zline[strcspn (zline, "#\n")] = '\0'; - if (strncmp (zline, "PATH=", sizeof "PATH=" - 1) == 0) - { - char *z; - - zline += sizeof "PATH=" - 1; - while ((z = strchr (zline, ':')) != NULL) - *z = ' '; - for (i = 0; i < *pc; i++) - for (q = &(*ppas)[i]; q != NULL; q = q->qalternate) - q->zpath = zline; - - zline = zfgets (e, FALSE); - } - - zcmds = NULL; - while (zline != NULL) - { - zline[strcspn (zline, "#\n")] = '\0'; - uadd_string (&zcmds, zline, ' '); - xfree ((pointer) zline); - zline = zfgets (e, FALSE); - } - - (void) fclose (e); - - for (i = 0; i < *pc; i++) - for (q = &(*ppas)[i]; q != NULL; q = q->qalternate) - q->zcmds = zcmds; - } - } -} - -/* Find a port with a given name and speed in the file L-devices and - lock it. If found and locked, fill in the structure pointed at by - qport. Set *pffound to TRUE if a port was found but could not be - locked. */ - -boolean -fv2_find_port (zname, ibaud, ihighbaud, qport, pflock, pffound) - const char *zname; - long ibaud; - long ihighbaud; - struct sport *qport; - boolean (*pflock) P((struct sport *, boolean fin)); - boolean *pffound; -{ - char ab[sizeof OLDCONFIGLIB + sizeof V2_DEVICES - 1]; - FILE *e; - char *zline; - - sprintf (ab, "%s%s", OLDCONFIGLIB, V2_DEVICES); - e = fopen (ab, "r"); - if (e == NULL) - { - ulog (LOG_ERROR, "fopen (%s): %s", ab, strerror (errno)); - return FALSE; - } - - while ((zline = zfgets (e, FALSE)) != NULL) - { - char *ztok, *zdevice, *zdial_device; - long ilow, ihigh; - - zline[strcspn (zline, "#\n")] = '\0'; - - /* An entry in L-devices is type device dial-device baud. */ - ztok = strtok (zline, " \t"); - if (ztok == NULL) - { - xfree ((pointer) zline); - continue; - } - - if (zname != NULL - && strcmp (zname, ztok) != 0) - { - xfree ((pointer) zline); - continue; - } - qport->zname = ztok; - - zdevice = strtok ((char *) NULL, " \t"); - if (zdevice == NULL) - { - xfree ((pointer) zline); - continue; - } - - zdial_device = strtok ((char *) NULL, " \t"); - if (zdial_device == NULL) - { - xfree ((pointer) zline); - continue; - } - if (strcmp (zdial_device, "-") == 0) - zdial_device = NULL; - - ztok = strtok ((char *) NULL, " \t"); - if (ztok == NULL) - { - xfree ((pointer) zline); - continue; - } - ilow = strtol (ztok, &ztok, 10); - if (ilow == 0) - ihigh = 38400L; - else - { - if (*ztok == '-') - ihigh = atol (ztok + 1); - else - ihigh = ilow; - } - - if (ibaud != 0 - && (ihighbaud < ilow || ibaud > ihigh)) - { - xfree ((pointer) zline); - continue; - } - - /* We have found a matching port. We now fill in the sport - structure so that we can try to lock it. */ - qport->zprotocols = NULL; - qport->cproto_params = 0; - qport->qproto_params = NULL; - qport->ireliable = 0; - qport->zlockname = NULL; - if (strcmp (qport->zname, "DIR") == 0) - { - qport->ttype = PORTTYPE_DIRECT; - qport->u.sdirect.zdevice = zdevice; - qport->u.sdirect.ibaud = ilow; -#ifdef SYSDEP_DIRECT_INIT - SYSDEP_DIRECT_INIT (&qport->u.sdirect.s); -#endif - } - else - { - qport->ttype = PORTTYPE_MODEM; - qport->u.smodem.zdevice = zdevice; - qport->u.smodem.zdial_device = zdial_device; - if (ilow != ihigh) - qport->u.smodem.ibaud = 0; - else - qport->u.smodem.ibaud = ilow; - qport->u.smodem.ilowbaud = ilow; - qport->u.smodem.ihighbaud = ihigh; - qport->u.smodem.fcarrier = TRUE; - qport->u.smodem.zdialer = strtok ((char *) NULL, ""); - qport->u.smodem.zdialer += strspn (qport->u.smodem.zdialer, - " \t"); - qport->u.smodem.qdialer = NULL; -#ifdef SYSDEP_MODEM_INIT - SYSDEP_MODEM_INIT (&qport->u.smodem.s); -#endif - } - - if (pffound != NULL) - *pffound = TRUE; - - if (pflock != NULL - && ! (*pflock) (qport, FALSE)) - { - xfree ((pointer) zline); - continue; - } - - (void) fclose (e); - - return TRUE; - } - - (void) fclose (e); - - return FALSE; -} - -#endif /* HAVE_V2_CONFIG */ diff --git a/gnu/libexec/uucp/version.c b/gnu/libexec/uucp/version.c deleted file mode 100644 index a907891c62f..00000000000 --- a/gnu/libexec/uucp/version.c +++ /dev/null @@ -1,55 +0,0 @@ -/* version.c - The version number string. - - 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 AIRS, P.O. Box 520, Waltham, MA 02254. - - $Log: version.c,v $ - Revision 1.1.1.1 1993/03/21 09:45:37 cgd - initial import of 386bsd-0.1 sources - - Revision 1.6 1992/04/07 05:30:43 ian - Changed version to 1.03 - - Revision 1.5 1992/03/16 19:10:33 ian - Changed version to beta 1.03 - - Revision 1.4 1992/02/08 03:54:18 ian - Include <string.h> only in <uucp.h>, added 1992 copyright - - Revision 1.3 1992/01/20 23:53:25 ian - Changed version to 1.02 - - Revision 1.2 1992/01/05 03:09:44 ian - Changed abVersion to non const; changed version to beta 1.02 - - Revision 1.1 1991/11/21 22:17:06 ian - Initial revision - - */ - -#include "uucp.h" - -#if USE_RCS_ID -char version_rcsid[] = "$Id: version.c,v 1.1.1.1 1993/03/21 09:45:37 cgd Exp $"; -#endif - -char abVersion[] = "1.03"; |
