NetBSD/gnu/libexec/uucp/uucp.h

1209 lines
37 KiB
C
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/* 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;