xref: /386bsd/usr/src/libexec/uucp/uucp.h (revision a2142627)
1 /* uucp.h
2    Header file for the UUCP package.
3 
4    Copyright (C) 1991, 1992 Ian Lance Taylor
5 
6    This file is part of the Taylor UUCP package.
7 
8    This program is free software; you can redistribute it and/or
9    modify it under the terms of the GNU General Public License as
10    published by the Free Software Foundation; either version 2 of the
11    License, or (at your option) any later version.
12 
13    This program is distributed in the hope that it will be useful, but
14    WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16    General Public License for more details.
17 
18    You should have received a copy of the GNU General Public License
19    along with this program; if not, write to the Free Software
20    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 
22    The author of the program may be contacted at ian@airs.com or
23    c/o AIRS, P.O. Box 520, Waltham, MA 02254.
24 
25    $Log: uucp.h,v $
26    Revision 1.67  1992/04/02  22:51:09  ian
27    Add gcc 2.0 format checking to ulog, and fixed discovered problems
28 
29    Revision 1.66  1992/03/30  04:49:10  ian
30    Niels Baggesen: added debugging types abnormal and uucp-proto
31 
32    Revision 1.65  1992/03/28  22:06:38  ian
33    Michael I Bushnell: renamed enum tstatus to avoid header file conflict
34 
35    Revision 1.64  1992/03/28  20:31:55  ian
36    Franc,ois Pinard: allow a name to be given to an alternate
37 
38    Revision 1.63  1992/03/28  04:23:46  ian
39    Gerben Wierda: don't always declare bzero
40 
41    Revision 1.62  1992/03/28  04:04:55  ian
42    Niels Baggesen: simplified debugging message macros
43 
44    Revision 1.61  1992/03/17  01:33:47  ian
45    Move definition of const before use for non ANSI C
46 
47    Revision 1.60  1992/03/17  01:28:18  ian
48    Undefine remove in uucp.h if ! HAVE_REMOVE
49 
50    Revision 1.59  1992/03/17  00:06:56  ian
51    Changed HAVE_SIG_ATOMIC_T_IN_SYS_TYPES_H to HAVE_SIG_ATOMIC_T_IN_TYPES_H
52 
53    Revision 1.58  1992/03/16  23:44:56  ian
54    Sometimes sig_atomic_t is in <sys/types.h> but not <signal.h>
55 
56    Revision 1.57  1992/03/15  04:51:17  ian
57    Keep an array of signals we've received rather than a single variable
58 
59    Revision 1.56  1992/03/12  21:58:32  ian
60    Added padding byte to scmd
61 
62    Revision 1.55  1992/03/12  19:54:43  ian
63    Debugging based on types rather than number
64 
65    Revision 1.54  1992/03/11  22:06:37  ian
66    Marty Shannon: added max-uuxqts command
67 
68    Revision 1.53  1992/03/11  01:18:15  ian
69    Niels Baggesen: drop the connection on a write failure
70 
71    Revision 1.52  1992/03/11  00:18:50  ian
72    Save temporary file if file send fails
73 
74    Revision 1.51  1992/03/09  20:14:37  ian
75    Ted Lindgreen: added max-remote-debug command
76 
77    Revision 1.50  1992/03/09  05:08:16  ian
78    Added status for wrong time to call, not used if system can't be called
79 
80    Revision 1.49  1992/03/08  16:42:41  ian
81    Ted Lindgreen: report port and login name in log file
82 
83    Revision 1.48  1992/03/07  04:58:09  ian
84    Eric Ziegast: some systems don't define EXIT_SUCCESS or FAILURE
85 
86    Revision 1.47  1992/03/07  02:56:30  ian
87    Rewrote time routines
88 
89    Revision 1.46  1992/03/04  01:40:51  ian
90    Thomas Fischer: tweaked a bit for the NeXT
91 
92    Revision 1.45  1992/03/04  00:36:44  ian
93    Michael Richardson: better chat script debugging
94 
95    Revision 1.44  1992/03/02  04:53:07  ian
96    Marc Unangst: added HAVE_SCO_LOCKFILES configuration parameter
97 
98    Revision 1.43  1992/02/29  01:06:59  ian
99    Chip Salzenberg: recheck file permissions before sending
100 
101    Revision 1.42  1992/02/27  05:40:54  ian
102    T. William Wells: detach from controlling terminal, handle signals safely
103 
104    Revision 1.41  1992/02/24  18:38:42  ian
105    John Theus: don't declare ulog with ellipsis if we don't have vprintf
106 
107    Revision 1.40  1992/02/24  04:58:47  ian
108    Only permit files to be received into directories that are world-writeable
109 
110    Revision 1.39  1992/02/23  19:50:50  ian
111    Handle READ and WRITE in Permissions correctly
112 
113    Revision 1.38  1992/02/23  03:26:51  ian
114    Overhaul to use automatic configure shell script
115 
116    Revision 1.37  1992/02/08  03:54:18  ian
117    Include <string.h> only in <uucp.h>, added 1992 copyright
118 
119    Revision 1.36  1992/01/19  21:30:21  ian
120    Matthew Lyle: some systems don't declare errno in <errno.h>
121 
122    Revision 1.35  1992/01/19  18:29:05  ian
123    Added HAVE_BSEARCH configuration parameter
124 
125    Revision 1.34  1992/01/18  22:48:53  ian
126    Reworked sending of mail and general handling of failed transfers
127 
128    Revision 1.33  1992/01/15  19:53:27  ian
129    Mike Park: If HAVE_ALLOCA is 0 when using gcc, don't define alloca
130 
131    Revision 1.32  1992/01/15  07:06:29  ian
132    Set configuration directory in Makefile rather than sysdep.h
133 
134    Revision 1.31  1992/01/14  03:46:55  ian
135    Chip Salzenberg: handle invalid status values in status files
136 
137    Revision 1.30  1992/01/05  03:18:54  ian
138    Avoid redefining SEEK_SET
139 
140    Revision 1.29  1992/01/05  03:09:17  ian
141    Changed abProgram and abVersion to non const to avoid compiler bug
142 
143    Revision 1.28  1991/12/30  04:28:30  ian
144    John Theus: check for EOF to work around bug in fread
145 
146    Revision 1.27  1991/12/29  04:04:18  ian
147    Added a bunch of extern definitions
148 
149    Revision 1.26  1991/12/28  06:10:50  ian
150    Added HAVE_STRCHR and HAVE_INDEX to conf.h
151 
152    Revision 1.25  1991/12/28  03:49:23  ian
153    Added HAVE_MEMFNS and HAVE_BFNS; changed uses of memset to bzero
154 
155    Revision 1.24  1991/12/23  05:15:54  ian
156    David Nugent: set debugging level for a specific system
157 
158    Revision 1.23  1991/12/22  22:14:19  ian
159    Monty Solomon: added HAVE_UNISTD_H configuration parameter
160 
161    Revision 1.22  1991/12/22  20:38:50  ian
162    Monty Solomon: don't define strcasecmp and strncasecmp
163 
164    Revision 1.21  1991/12/21  23:10:43  ian
165    Terry Gardner: record failed file transfers in statistics file
166 
167    Revision 1.20  1991/12/18  03:54:14  ian
168    Made error messages to terminal appear more normal
169 
170    Revision 1.19  1991/12/17  07:09:58  ian
171    Record statistics in fractions of a second
172 
173    Revision 1.18  1991/12/15  04:17:11  ian
174    Added chat-seven-bit command to control parity bit stripping
175 
176    Revision 1.17  1991/12/15  03:42:33  ian
177    Added tprocess_chat_cmd for all chat commands, and added CMDTABTYPE_PREFIX
178 
179    Revision 1.16  1991/12/11  19:35:48  ian
180    Mark Powell: put in my own version of strtol
181 
182    Revision 1.15  1991/12/11  03:59:19  ian
183    Create directories when necessary; don't just assume they exist
184 
185    Revision 1.14  1991/12/10  19:45:05  ian
186    Added ulog_device to record device name for log file
187 
188    Revision 1.13  1991/12/10  19:29:02  ian
189    Move statistics file stuff from file.c to log.c
190 
191    Revision 1.12  1991/11/21  22:17:06  ian
192    Add version string, print version when printing usage
193 
194    Revision 1.11  1991/11/21  21:20:41  ian
195    Brian Campbell: offer str{n}icmp as an alternative to str{n}casecmp
196 
197    Revision 1.10  1991/11/12  19:47:04  ian
198    Add called-chat set of commands to run a chat script on an incoming call
199 
200    Revision 1.9  1991/11/11  23:47:24  ian
201    Added chat-program to run a program to do a chat script
202 
203    Revision 1.8  1991/11/11  19:32:03  ian
204    Added breceive_char to read characters through protocol buffering
205 
206    Revision 1.7  1991/11/10  20:05:44  ian
207    Changed ffilerewind to use fseek rather than rewind
208 
209    Revision 1.6  1991/11/10  19:24:22  ian
210    Added pffile protocol entry point for file level control
211 
212    Revision 1.5  1991/11/07  20:32:04  ian
213    Chip Salzenberg: allow ANSI_C to be defined in conf.h
214 
215    Revision 1.4  1991/11/07  18:21:47  ian
216    Chip Salzenberg: move CMAXRETRIES to conf.h for easy configuration
217 
218    Revision 1.3  1991/09/19  17:43:48  ian
219    Chip Salzenberg: undef TRUE and FALSE in case system defines them
220 
221    Revision 1.2  1991/09/19  02:22:44  ian
222    Chip Salzenberg's patch to allow ";retrytime" at the end of a time string
223 
224    Revision 1.1  1991/09/10  19:47:55  ian
225    Initial revision
226 
227    */
228 
229 /* Get the system configuration parameters.  */
230 
231 #include "conf.h"
232 #include "policy.h"
233 
234 /* We always want <stdio.h>.  */
235 
236 #include <stdio.h>
237 
238 /* We need <signal.h> for sig_atomic_t.  */
239 
240 #include <signal.h>
241 
242 /* On some systems that won't get us sig_atomic_t.  */
243 
244 #if ! HAVE_SIG_ATOMIC_T_IN_SIGNAL_H
245 #if HAVE_SIG_ATOMIC_T_IN_TYPES_H
246 #include <sys/types.h>
247 #else /* ! HAVE_SIG_ATOMIC_T_IN_TYPES_H */
248 #ifndef sig_atomic_t
249 /* There is no portable definition for sig_atomic_t.  */
250 #define sig_atomic_t char
251 #endif /* ! defined (sig_atomic_t) */
252 #endif /* ! HAVE_SIG_ATOMIC_T_IN_TYPES_H */
253 #endif /* ! HAVE_SIG_ATOMIC_T_IN_SIGNAL_H */
254 
255 /* Get a definition for ANSI_C if we weren't given one.  */
256 
257 #ifndef ANSI_C
258 #ifdef __STDC__
259 #define ANSI_C 1
260 #else /* ! defined (__STDC__) */
261 #define ANSI_C 0
262 #endif /* ! defined (__STDC__) */
263 #endif /* ! defined (ANSI_C) */
264 
265 /* Set up some definitions for both ANSI C and Classic C.
266 
267    P() is used for function prototypes (e.g. extern int foo P((int)) ).
268    pointer is used for a generic pointer (i.e. void *).
269    constpointer is used for a generic pointer to constant data.
270    BUCHAR is used to convert a character to unsigned.  */
271 
272 #if ANSI_C
273 #if ! HAVE_VOID || ! HAVE_UNSIGNED_CHAR
274  #error ANSI C compiler without void or unsigned char
275 #endif
276 #define P(x) x
277 typedef void *pointer;
278 typedef const void *constpointer;
279 #define BUCHAR(b) ((unsigned char) (b))
280 #else /* ! ANSI_C */
281 /* Handle uses of const, volatile and void in Classic C.  */
282 #define const
283 #define volatile
284 #if ! HAVE_VOID
285 #define void int
286 #endif
287 #define P(x) ()
288 typedef char *pointer;
289 typedef const char *constpointer;
290 #if HAVE_UNSIGNED_CHAR
291 #define BUCHAR(b) ((unsigned char) (b))
292 #else /* ! HAVE_UNSIGNED_CHAR */
293 /* This should work on most systems, but not necessarily all.  */
294 #define BUCHAR(b) ((b) & 0xff)
295 #endif /* ! HAVE_UNSIGNED_CHAR */
296 #endif /* ! ANSI_C */
297 
298 /* Only use inline with gcc.  */
299 
300 #ifndef __GNUC__
301 #define __inline__
302 #endif
303 
304 /* Get the string functions, which are used throughout the code.  */
305 
306 #if HAVE_MEMORY_H
307 #include <memory.h>
308 #else
309 /* We really need a definition for memchr, and this should not
310    conflict with anything in <string.h>.  I hope.  */
311 extern pointer memchr ();
312 #endif
313 
314 #if HAVE_STRING_H
315 #include <string.h>
316 #else /* ! HAVE_STRING_H */
317 #if HAVE_STRINGS_H
318 #include <strings.h>
319 #else /* ! HAVE_STRINGS_H */
320 extern int strcmp (), strncmp ();
321 extern char *strcpy (), *strncpy (), *strchr (), *strrchr (), *strtok ();
322 extern char *strcat (), *strerror (), *strstr ();
323 /* These should be size_t, but there's no declaration to conflict with.  */
324 extern int strlen (), strspn (), strcspn ();
325 #if ! HAVE_MEMORY_H
326 extern pointer memcpy (), memmove (), memchr ();
327 extern int memcmp ();
328 #endif /* ! HAVE_MEMORY_H */
329 #endif /* ! HAVE_STRINGS_H */
330 #endif /* ! HAVE_STRING_H */
331 
332 /* Get what we need from <stdlib.h>.  */
333 
334 #if HAVE_STDLIB_H
335 #include <stdlib.h>
336 #else /* ! HAVE_STDLIB_H */
337 extern pointer malloc (), realloc (), bsearch ();
338 extern void free (), exit (), perror (), abort (), qsort ();
339 extern long atol (), strtol ();
340 extern int atoi ();
341 extern char *getenv ();
342 #endif /* ! HAVE_STDLIB_H */
343 
344 /* Define alloca as suggested by David MacKenzie.  AIX requires this
345    to be the first thing in the file.  I really hate system dependent
346    cruft like this (and this is the only case in which it appears),
347    but I guess that's the price of using alloca.  */
348 #define HAVE_ALLOCA 1
349 #ifdef __GNUC__
350 #ifndef __NeXT__
351 #define alloca __builtin_alloca
352 #endif /* ! defined (__NeXT__) */
353 #else /* ! defined(__GNUC__) */
354 #ifdef sparc
355 #include <alloca.h>
356 #else /* ! defined (sparc) */
357 #ifdef _AIX
358  #pragma alloca
359 #else /* ! defined (_AIX) */
360 /* We may not be using a real alloca.  */
361 #undef HAVE_ALLOCA
362 #define HAVE_ALLOCA 0
363 #endif /* ! defined (_AIX) */
364 #endif /* ! defined (sparc) */
365 #endif /* ! defined (__GNUC__) */
366 
367 /* NeXT uses <libc.h> to declare a bunch of functions.  */
368 #if HAVE_LIBC_H
369 #include <libc.h>
370 #endif
371 
372 /* Make sure we have the EXIT_ macros (some versions of SunOS have
373    <stdlib.h> but left them out).  */
374 #ifndef EXIT_SUCCESS
375 #define EXIT_SUCCESS (0)
376 #endif
377 #ifndef EXIT_FAILURE
378 #define EXIT_FAILURE (1)
379 #endif
380 
381 /* If we need to declare errno, do so.  I don't want to always do
382    this, because some system might theoretically have a different
383    declaration for errno.  On a POSIX system this is sure to work.  */
384 #if ! HAVE_ERRNO_DECLARATION
385 extern int errno;
386 #endif
387 
388 /* If the system has the socket call, guess that we can compile the
389    TCP code.  */
390 #define HAVE_TCP HAVE_SOCKET
391 
392 /* The boolean type holds boolean values.  */
393 
394 typedef int boolean;
395 
396 #undef TRUE
397 #undef FALSE
398 #define TRUE (1)
399 #define FALSE (0)
400 
401 /* The openfile_t type holds an open file.  This depends on whether we
402    are using stdio or not.  */
403 
404 #if USE_STDIO
405 
406 typedef FILE *openfile_t;
407 #define EFILECLOSED ((FILE *) NULL)
408 #define ffileisopen(e) ((e) != NULL)
409 #define ffileeof(e) feof (e)
410 #define cfileread(e, z, c) fread ((z), 1, (c), (e))
411 #define ffilereaderror(e, c) ferror (e)
412 #define cfilewrite(e, z, c) fwrite ((z), 1, (c), (e))
413 #ifdef SEEK_SET
414 #define ffilerewind(e) (fseek (e, (long) 0, SEEK_SET) == 0)
415 #else
416 #define ffilerewind(e) (fseek (e, (long) 0, 0) == 0)
417 #endif
418 #define ffileclose(e) (fclose (e) == 0)
419 
420 extern int fclose (), fseek ();
421 /* The ferror and feof functions are often macros, so we can't safely
422    define them.  The fread and fwrite functions may return int or may
423    return size_t, so we can't safely define them.  */
424 
425 #else /* ! USE_STDIO */
426 
427 #if HAVE_UNISTD_H
428 #include <unistd.h>
429 #endif
430 
431 /* It would be nice to provide prototypes for read, write and lseek, but
432    we can't because they might not return int.  */
433 extern int close ();
434 
435 typedef int openfile_t;
436 #define EFILECLOSED (-1)
437 #define ffileisopen(e) ((e) >= 0)
438 #define ffileeof(e) (FALSE)
439 #define cfileread(e, z, c) read ((e), (z), (c))
440 #define ffilereaderror(e, c) ((c) < 0)
441 #define cfilewrite(e, z, c) write ((e), (z), (c))
442 #ifdef SEEK_SET
443 #define ffilerewind(e) (lseek (e, (long) 0, SEEK_SET) >= 0)
444 #else
445 #define ffilerewind(e) (lseek (e, (long) 0, 0) >= 0)
446 #endif
447 #define ffileclose(e) (close (e) >= 0)
448 
449 extern int read (), write (), close ();
450 /* The lseek function should return off_t, but we don't want to
451    include sysdep.h here.  */
452 
453 #endif /* ! USE_STDIO */
454 
455 /* Define the time_t type.  This still won't help if they don't have
456    time or ctime.  */
457 
458 #if ! HAVE_TIME_T && ! HAVE_SYS_TIME_T
459 typedef long time_t;
460 #endif
461 
462 /* The types of entries allowed in a command table (struct scmdtab).
463    If CMDTABTYPE_FN is used, it should be or'ed with the number of
464    arguments permitted, or 0 if there is no single number.
465    CMDTABTYPE_PREFIX means that the string in the scmdtab table is a
466    prefix; any command which matches the prefix should be used to call
467    a function.  The number of arguments should be or'ed in as with
468    CMDTABTYPE_FN.  */
469 
470 #define CMDTABTYPE_BOOLEAN (0x12)
471 #define CMDTABTYPE_INT (0x22)
472 #define CMDTABTYPE_LONG (0x32)
473 #define CMDTABTYPE_STRING (0x40)
474 #define CMDTABTYPE_FULLSTRING (0x50)
475 #define CMDTABTYPE_FN (0x60)
476 #define CMDTABTYPE_PREFIX (0x70)
477 
478 #define TTYPE_CMDTABTYPE(i) ((i) & 0x70)
479 #define CARGS_CMDTABTYPE(i) ((i) & 0x0f)
480 
481 /* These flags are or'red together to form an argument to
482    uprocesscmds.  */
483 #define CMDFLAG_WARNUNRECOG (0x1)
484 #define CMDFLAG_CASESIGNIFICANT (0x2)
485 #define CMDFLAG_BACKSLASH (0x4)
486 
487 /* The enumeration returned by functions called by uprocesscmds.  */
488 
489 enum tcmdtabret
490 {
491   CMDTABRET_CONTINUE,
492   CMDTABRET_FREE,
493   CMDTABRET_EXIT,
494   CMDTABRET_FREE_AND_EXIT
495 };
496 
497 /* This structure holds the argument to uprocesscmds.  */
498 
499 struct scmdtab
500 {
501   /* Command name.  */
502   const char *zcmd;
503   /* Command type (one of CMDTABTYPE_...).  */
504   int itype;
505   /* This is the address of the variable if not CMDTABTYPE_FN.  */
506   pointer pvar;
507   /* This is used if CMDTABTYPE_FN.  */
508   enum tcmdtabret (*ptfn) P((int argc, char **argv, pointer par,
509 			     const char *zerr));
510 };
511 
512 /* This structure holds the information we need for a chat script.  */
513 
514 struct schat_info
515 {
516   /* The script itself, if any.  */
517   char *zchat;
518   /* The program to run, if any.  */
519   char *zprogram;
520   /* The timeout for the chat script.  */
521   int ctimeout;
522   /* The list of failure strings.  */
523   char *zfail;
524   /* Whether to strip incoming characters to seven bits.  */
525   boolean fstrip;
526 };
527 
528 /* This macro is used to initialize the entries of an schat_info
529    structure to the correct default values.  */
530 
531 #define INIT_CHAT(q) \
532   ((q)->zchat = NULL, \
533    (q)->zprogram = NULL, \
534    (q)->ctimeout = 60, \
535    (q)->zfail = NULL, \
536    (q)->fstrip = TRUE)
537 
538 /* This structure holds a set of special commands executed for
539    particular protocols.  */
540 
541 struct sproto_param
542 {
543   /* Protocol.  */
544   char bproto;
545   /* Number of entries.  */
546   int centries;
547   /* Specific entries.  */
548   struct sproto_param_entry
549     {
550       int cargs;
551       char **azargs;
552     } *qentries;
553 };
554 
555 /* The ssysteminfo structure holds information about a remote system.  */
556 
557 struct ssysteminfo
558 {
559   /* System name.  */
560   const char *zname;
561   /* List of aliases separated by ' '.  */
562   char *zalias;
563   /* Linked list of alternate sets of call information.  */
564   struct ssysteminfo *qalternate;
565   /* Name for this alternate (may be NULL).  */
566   char *zalternate;
567   /* Legal times to call.  A grade, a time string, an optional ';' and
568      retry time, ' ', repeated.  */
569   char *ztime;
570   /* Grade to request of other system and associated time.  A grade, a
571      time string, ' ', repeated.  */
572   char *zcalltimegrade;
573   /* Sizes for local requests and calls.  A size, ' ', a time string,
574      ' ', repeated.  */
575   char *zcall_local_size;
576   /* Sizes for remote requests and local calls.  */
577   char *zcall_remote_size;
578   /* Sizes for local requests when called.  */
579   char *zcalled_local_size;
580   /* Sizes for remote requests when called.  */
581   char *zcalled_remote_size;
582   /* Baud rate (all right, so it's really bps).  */
583   long ibaud;
584   /* High baud rate, if a range is permitted (0 if no range).  */
585   long ihighbaud;
586   /* Port name, if qport is not used.  */
587   char *zport;
588   /* Specific port information, if zport is not used.  */
589   struct sport *qport;
590   /* Phone number.  */
591   char *zphone;
592   /* Chat script information.  */
593   struct schat_info schat;
594   /* Login name to use when calling the remote system.  */
595   const char *zcall_login;
596   /* Password to use when calling the remote system.  */
597   const char *zcall_password;
598   /* Login name that must be used by the other system when calling in.  */
599   const char *zcalled_login;
600   /* Whether to call back the remote system.  */
601   boolean fcallback;
602   /* Whether system uses sequencing.  */
603   boolean fsequence;
604   /* List of protocols to use for this system (may be NULL).  */
605   const char *zprotocols;
606   /* Number of entries in protocol parameters array.  */
607   int cproto_params;
608   /* Protocol parameters array.  */
609   struct sproto_param *qproto_params;
610   /* Chat to run when called.  */
611   struct schat_info scalled_chat;
612 #if DEBUG > 1
613   /* Debugging level to set during a call.  */
614   int idebug;
615   /* Maximum remote debugging level.  */
616   int imax_remote_debug;
617 #endif
618   /* Whether the other system may request things when we call them.  */
619   boolean fcall_request;
620   /* Whether the other system may request things when they call us.  */
621   boolean fcalled_request;
622   /* Whether we may request things when we call.  */
623   boolean fcall_transfer;
624   /* Whether we may request things when they call.  */
625   boolean fcalled_transfer;
626   /* List of directories that may be sent by local request.  */
627   const char *zlocal_send;
628   /* List of directories that may be sent by local request when the
629      other system placed the call (if NULL, use zlocal_send).  This is
630      actually never used currently.  */
631   const char *zcalled_local_send;
632   /* List of directories that may be sent by remote request.  */
633   const char *zremote_send;
634   /* List of directories that may be sent by remote request when the
635      other system placed the call (if NULL, use zremote_send).  This
636      is currently only used by HAVE_BNU_CONFIG.  */
637   const char *zcalled_remote_send;
638   /* List of directories that may be received into by local request.  */
639   const char *zlocal_receive;
640   /* List of directories that may be received into by local request
641      when the other system placed the call (if NULL, use
642      zlocal_receive).  This is currently only used under
643      HAVE_BNU_CONFIG.  */
644   const char *zcalled_local_receive;
645   /* List of directories that may be received into by remote request.  */
646   const char *zremote_receive;
647   /* List of directories that may be received into by remote request
648      when the other system placed the call (if NULL, use
649      zremote_receive).  This is currently only used by
650      HAVE_BNU_CONFIG.  */
651   const char *zcalled_remote_receive;
652   /* Path to use for command execution.  */
653   const char *zpath;
654   /* List of commands that may be executed.  */
655   const char *zcmds;
656   /* Amount of free space to leave.  */
657   long cfree_space;
658   /* List of systems that may be forwarded to.  */
659   const char *zforwardto;
660   /* The public directory to use for this sytem.  */
661   const char *zpubdir;
662   /* The local name to use for this remote system.  */
663   const char *zlocalname;
664 };
665 
666 /* The tfailure enumeration holds reasons for failure to be passed to
667    the pffail function of a protocol.  */
668 
669 enum tfailure
670 {
671   /* No failure.  */
672   FAILURE_NONE,
673   /* No permission for operation.  */
674   FAILURE_PERM,
675   /* Can't open necessary file.  */
676   FAILURE_OPEN,
677   /* Not enough space to receive file.  */
678   FAILURE_SIZE
679 };
680 
681 /* The tlog enumeration holds the different types of logging.  */
682 
683 enum tlog
684 {
685   /* Normal log entry.  */
686   LOG_NORMAL,
687   /* Error log entry.  */
688   LOG_ERROR,
689   /* Fatal log entry.  */
690   LOG_FATAL
691 #if DEBUG > 1
692     ,
693   /* Debugging log entry.  */
694   LOG_DEBUG,
695   /* Start debugging log entry.  */
696   LOG_DEBUG_START,
697   /* Continue debugging log entry.  */
698   LOG_DEBUG_CONTINUE,
699   /* End debugging log entry.  */
700   LOG_DEBUG_END
701 #endif
702 };
703 
704 /* The tstatus_type enumeration holds the kinds of status information
705    we put in the status file.  The order of entries here corresponds
706    to the order of entries in the azStatus array.  */
707 
708 enum tstatus_type
709 {
710   /* Conversation complete.  */
711   STATUS_COMPLETE,
712   /* Port unavailable.  */
713   STATUS_PORT_FAILED,
714   /* Dial failed.  */
715   STATUS_DIAL_FAILED,
716   /* Login failed.  */
717   STATUS_LOGIN_FAILED,
718   /* Handshake failed.  */
719   STATUS_HANDSHAKE_FAILED,
720   /* Failed after logging in.  */
721   STATUS_FAILED,
722   /* Talking to remote system.  */
723   STATUS_TALKING,
724   /* Wrong time to call.  */
725   STATUS_WRONG_TIME,
726   /* Number of status values.  */
727   STATUS_VALUES
728 };
729 
730 /* An array to convert status entries to strings.  If more status entries
731    are added, this array must be extended.  */
732 extern const char *azStatus[];
733 
734 /* The sstatus structure holds the contents of a system status file.  */
735 
736 struct sstatus
737 {
738   /* Current status of conversation.  */
739   enum tstatus_type ttype;
740   /* Number of failed retries.  */
741   int cretries;
742   /* Time of last call in seconds since epoch (determined by
743      isysdep_time).  */
744   long ilast;
745   /* Number of seconds until a retry is permitted.  */
746   int cwait;
747 };
748 
749 /* How long we have to wait for the next call, given the number of retries
750    we have already made.  This should probably be configurable.  */
751 #define CRETRY_WAIT(c) ((c) * 10 * 60)
752 
753 /* The scmd structure holds a complete UUCP command.  */
754 
755 struct scmd
756 {
757   /* Command ('S' for send, 'R' for receive, 'X' for execute, 'H' for
758      hangup, 'Y' for hangup confirm, 'N' for hangup deny).  */
759   char bcmd;
760   /* At least one compiler needs an explicit padding byte here.  */
761   char bdummy;
762   /* Sequence handle for fsysdep_did_work.  */
763   pointer pseq;
764   /* File name to transfer from.  */
765   const char *zfrom;
766   /* File name to transfer to.  */
767   const char *zto;
768   /* User who requested transfer.  */
769   const char *zuser;
770   /* Options.  */
771   const char *zoptions;
772   /* Temporary file name ('S' and pfreceive protocol function).  */
773   const char *ztemp;
774   /* Mode to give newly created file ('S' and pfreceive protocol fn).  */
775   unsigned int imode;
776   /* User to notify on remote system (optional; 'S' only).  */
777   const char *znotify;
778   /* File size (-1 if not supplied) ('S' and pfreceive protocol fn).  */
779   long cbytes;
780 };
781 
782 /* The highest grade.  */
783 #define BGRADE_HIGH ('0')
784 
785 /* The lowest grade.  */
786 #define BGRADE_LOW ('z')
787 
788 /* Whether a character is a legal grade.  */
789 #define FGRADE_LEGAL(b) (isalnum (BUCHAR (b)))
790 
791 #if DEBUG > 1
792 
793 /* We allow independent control over several different types of
794    debugging output, using a bit string with individual bits dedicated
795    to particular debugging types.  */
796 
797 /* The bit string is stored in iDebug.  */
798 extern int iDebug;
799 
800 /* Debug abnormal events.  */
801 #define DEBUG_ABNORMAL (01)
802 /* Debug chat scripts.  */
803 #define DEBUG_CHAT (02)
804 /* Debug initial handshake.  */
805 #define DEBUG_HANDSHAKE (04)
806 /* Debug UUCP protocol.  */
807 #define DEBUG_UUCP_PROTO (010)
808 /* Debug protocols.  */
809 #define DEBUG_PROTO (020)
810 /* Debug port actions.  */
811 #define DEBUG_PORT (040)
812 /* Debug configuration files.  */
813 #define DEBUG_CONFIG (0100)
814 /* Debug spool directory actions.  */
815 #define DEBUG_SPOOLDIR (0200)
816 /* Debug executions.  */
817 #define DEBUG_EXECUTE (0400)
818 /* Debug incoming data.  */
819 #define DEBUG_INCOMING (01000)
820 /* Debug outgoing data.  */
821 #define DEBUG_OUTGOING (02000)
822 
823 /* Maximum possible value for iDebug.  */
824 #define DEBUG_MAX (03777)
825 
826 /* Intializer for array of debug names.  The index of the name in the
827    array is the corresponding bit position in iDebug.  We only check
828    for prefixes, so these names only need to be long enough to
829    distinguish each name from every other.  The last entry must be
830    NULL.  The string "all" is also recognized to turn on all
831    debugging.  */
832 #define DEBUG_NAMES \
833   { "a", "ch", "h", "u", "pr", "po", "co", "s", "e", "i", "o", NULL }
834 
835 /* The prefix to use to turn off all debugging.  */
836 #define DEBUG_NONE "n"
837 
838 /* Check whether a particular type of debugging is being done.  */
839 #define FDEBUGGING(i) ((iDebug & (i)) != 0)
840 
841 /* These macros are used to output debugging information.  I use
842    several different macros depending on the number of arguments
843    because no macro can take a variable number of arguments and I
844    don't want to use double parentheses.  */
845 #define DEBUG_MESSAGE0(i, z) \
846   do { if (FDEBUGGING (i)) ulog (LOG_DEBUG, (z)); } while (0)
847 #define DEBUG_MESSAGE1(i, z, a1) \
848   do { if (FDEBUGGING (i)) ulog (LOG_DEBUG, (z), (a1)); } while (0)
849 #define DEBUG_MESSAGE2(i, z, a1, a2) \
850   do { if (FDEBUGGING (i)) ulog (LOG_DEBUG, (z), (a1), (a2)); } while (0)
851 #define DEBUG_MESSAGE3(i, z, a1, a2, a3) \
852   do \
853     { \
854       if (FDEBUGGING (i)) \
855 	ulog (LOG_DEBUG, (z), (a1), (a2), (a3)); \
856     } \
857   while (0)
858 #define DEBUG_MESSAGE4(i, z, a1, a2, a3, a4) \
859   do \
860     { \
861       if (FDEBUGGING (i)) \
862 	ulog (LOG_DEBUG, (z), (a1), (a2), (a3), (a4)); \
863     } \
864   while (0)
865 
866 #else /* DEBUG <= 1 */
867 
868 /* If debugging information is not being compiled, provide versions of
869    the debugging macros which just disappear.  */
870 #define DEBUG_MESSAGE0(i, z)
871 #define DEBUG_MESSAGE1(i, z, a1)
872 #define DEBUG_MESSAGE2(i, z, a1, a2)
873 #define DEBUG_MESSAGE3(i, z, a1, a2, a3)
874 #define DEBUG_MESSAGE4(i, z, a1, a2, a3, a4)
875 
876 #endif /* DEBUG <= 1 */
877 
878 /* Functions.  */
879 
880 /* Read the configuration file.  */
881 extern void uread_config P((const char *zname));
882 
883 /* Read information about all systems.  */
884 extern void uread_all_system_info P((int *pc, struct ssysteminfo **ppas));
885 
886 /* Read information about a specific system.  */
887 extern boolean fread_system_info P((const char *zsystem,
888 				    struct ssysteminfo *qsys));
889 
890 /* Set the default values for an uninitialized system.  */
891 extern void uset_system_defaults P((struct ssysteminfo *qsys));
892 
893 /* Start getting commands for unknown systems.  */
894 extern void uiunknown_start P((void));
895 
896 /* Process a command defining unknown systems.  */
897 extern enum tcmdtabret tiunknown P((int argc, char **argv,
898 				    pointer pvar, const char *zerr));
899 
900 /* Finish getting commands for unknown systems.  */
901 extern void uiunknown_end P((void));
902 
903 /* Set up the sLocalsys structure.  */
904 extern void uisetup_localsys P((void));
905 
906 /* Open a set of files and pretend that they were all catenated
907    together.  */
908 extern struct smulti_file *qmulti_open P((const char *znames));
909 
910 /* Close a set of files opened by qmulti_open.  */
911 extern boolean fmulti_close P((struct smulti_file *q));
912 
913 /* Process a set of commands.  */
914 extern void uprocesscmds P((FILE *e, struct smulti_file *qmulti,
915 			    const struct scmdtab *qcmds,
916 			    const char *zerr, int iflags));
917 
918 /* Process a single command.  */
919 extern enum tcmdtabret tprocess_one_cmd P((int cargs, char **azargs,
920 					   const struct scmdtab *qcmds,
921 					   const char *zerr,
922 					   int iflags));
923 
924 /* Translate an unknown system name into something acceptable for the
925    spool directory stuff.  */
926 extern const char *ztranslate_system P((const char *zsystem));
927 
928 /* Check login name and password.  */
929 extern boolean fcheck_login P((const char *zuser, const char *zpass));
930 
931 /* Get one character from the remote system, going through the
932    procotol buffering.  The ctimeout argument is the timeout in
933    seconds, and the freport argument is TRUE if errors should be
934    reported (when closing a connection it is pointless to report
935    errors).  This returns a character or -1 on a timeout or -2 on an
936    error.  */
937 extern int breceive_char P((int ctimeout, boolean freport));
938 
939 /* See whether a file belongs in the spool directory.  */
940 extern boolean fspool_file P((const char *zfile));
941 
942 /* Store information about a file being sent.  */
943 extern boolean fstore_sendfile P((openfile_t e, pointer pseq,
944 				  const char *zfrom, const char *zto,
945 				  const char *ztosys, const char *zuser,
946 				  const char *zmail));
947 
948 /* Finish sending a file.  The zwhy and fnever arguments are used
949    if the file was not received correctly.  */
950 extern boolean fsent_file P((boolean freceived, long cbytes,
951 			     const char *zwhy, boolean fnever));
952 
953 /* Note an error sending a file.  The function fsent_file must still
954    be called after this is called.  */
955 extern void usendfile_error P((void));
956 
957 /* Store information about a file being received.  */
958 extern boolean fstore_recfile P((openfile_t e, pointer pseq,
959 				 const char *zfrom, const char *zto,
960 				 const char *zfromsys, const char *zuser,
961 				 unsigned int imode, const char *zmail,
962 				 const char *ztemp));
963 
964 /* Finish receiving a file.  The zwhy and fnever arguments are used
965    if the file was not received correctly.  */
966 extern boolean freceived_file P((boolean fsent, long cbytes,
967 				 const char *zwhy, boolean fnever));
968 
969 /* Note an error receiving a file.  The function freceived_file must
970    still be called after this is called.  */
971 extern void urecfile_error P((void));
972 
973 /* Prepare to receive a file again by discarding the previous
974    contents.  */
975 extern boolean frecfile_rewind P((void));
976 
977 /* Send mail about a file transfer.  */
978 extern boolean fmail_transfer P((boolean fok, const char *zuser,
979 				 const char *zmail, const char *zwhy,
980 				 const char *zfrom, const char *zfromsys,
981 				 const char *zto, const char *ztosys,
982 				 const char *zsaved));
983 
984 /* See whether a file is in one of a list of directories.  The qsys
985    argument are passed down to allow ~ expansion.  If fcheck is FALSE,
986    this does not check accessibility.  Otherwise, if freadable is
987    TRUE, the user zuser must have read access to the file and all
988    appropriate directories; if freadable is FALSE zuser must have
989    write access to the appropriate directories.  The zuser argument
990    may be NULL, in which case all users must have the appropriate
991    access (this is used for a remote request).  */
992 extern boolean fin_directory_list P((const struct ssysteminfo *qsys,
993 				     const char *zfile,
994 				     const char *zdirs,
995 				     boolean fcheck,
996 				     boolean freadable,
997 				     const char *zuser));
998 
999 /* Get the login name and password to use when calling a system out
1000    of the call out login file.  The pzlog and pzpass arguments are set
1001    to point to malloc'ed strings which must be freed after they have
1002    been used.  */
1003 extern boolean fcallout_login P((const struct ssysteminfo *qsys,
1004 				 char **pzlog, char **pzpass));
1005 
1006 /* Add a string to the end of another.  */
1007 extern void uadd_string P((char **pz, const char *z, int bsep));
1008 
1009 /* Process a chat command.  These are handled using CMDTABTYPE_PREFIX.
1010    This function switches off on argv[0].  */
1011 extern enum tcmdtabret tprocess_chat_cmd P((int argc, char **argv,
1012 					    pointer pvar,
1013 					    const char *zerr));
1014 
1015 /* Add a protocol parameter entry.  */
1016 extern enum tcmdtabret tadd_proto_param P((int *pc,
1017 					   struct sproto_param **pq,
1018 					   const char *zerr, int cargs,
1019 					   char **azargs));
1020 
1021 /* Apply protocol parameters.  */
1022 extern void uapply_proto_params P((int bproto, struct scmdtab *qcmds,
1023 				   int c, struct sproto_param *pas));
1024 
1025 /* Parse a command string.  */
1026 extern boolean fparse_cmd P((char *zcmd, struct scmd *qcmd));
1027 
1028 /* Specify which machines may be accepted for a login name.  */
1029 extern void uadd_validate P((const char *zlogname, int cmachines,
1030 			     const char **pazmachines));
1031 
1032 /* Check whether a login name/machine name pair is acceptable.  */
1033 extern boolean fcheck_validate P((const char *zlogname,
1034 				  const char *zmachine));
1035 
1036 /* Compare the execution times of two grades.  Return < 0 if the first
1037    argument should be executed first, 0 if they are the same, > 0 if
1038    the second argument should be executed first.  */
1039 extern int igradecmp P((int b1, int b2));
1040 
1041 /* Make a log entry.  */
1042 #if ANSI_C && HAVE_VFPRINTF
1043 extern void ulog P((enum tlog ttype, const char *zfmt, ...))
1044 #if __GNUC__ > 1
1045      __attribute__ ((format (printf, 2, 3)))
1046 #endif
1047      ;
1048 #else
1049 extern void ulog ();
1050 #endif
1051 
1052 /* Set the function to call if a fatal error occurs.  */
1053 extern void ulog_fatal_fn P((void (*pfn) P((void))));
1054 
1055 /* If ffile is TRUE, send log entries to the log file rather than to
1056    stderr.  */
1057 extern void ulog_to_file P((boolean ffile));
1058 
1059 /* Set the ID number used by the logging functions.  */
1060 extern void ulog_id P((int iid));
1061 
1062 /* Set the system name used by the logging functions.  */
1063 extern void ulog_system P((const char *zsystem));
1064 
1065 /* Set the system and user name used by the logging functions.  */
1066 extern void ulog_user P((const char *zuser));
1067 
1068 /* Set the device name used by the logging functions.  */
1069 extern void ulog_device P((const char *zdevice));
1070 
1071 /* Close the log file.  */
1072 extern void ulog_close P((void));
1073 
1074 /* Make an entry in the statistics file.  */
1075 extern void ustats P((boolean fsucceeded, const char *zuser,
1076 		      const char *zsystem, boolean fsent,
1077 		      long cbytes, long csecs, long cmicros));
1078 
1079 /* We have lost the connection; record any in progress file transfers
1080    in the statistics file.  */
1081 extern void ustats_failed P((void));
1082 
1083 /* Close the statistics file.  */
1084 extern void ustats_close P((void));
1085 
1086 #if DEBUG > 1
1087 /* A debugging routine to output a buffer.  This outputs zhdr, the
1088    buffer length clen, and the contents of the buffer in quotation
1089    marks.  */
1090 extern void udebug_buffer P((const char *zhdr, const char *zbuf,
1091 			     int clen));
1092 
1093 /* A debugging routine to make a readable version of a character.
1094    This takes a buffer at least 5 bytes long, and returns the length
1095    of the string it put into it (not counting the null byte).  */
1096 extern int cdebug_char P((char *z, int ichar));
1097 
1098 /* Parse a debugging option string.  This can either be a number or a
1099    comma separated list of debugging names.  If the code is compiled
1100    without debugging this is a dummy function.  This returns a value
1101    for iDebug.  */
1102 extern int idebug_parse P((const char *));
1103 
1104 /* Parse a debugging option in a configuration file.  This is used for
1105    the ``debug'' command.  */
1106 extern enum tcmdtabret tidebug_parse P((int argc, char **argv,
1107 					pointer pvar, const char *zerr));
1108 
1109 #else /* DEBUG <= 1 */
1110 
1111 /* Dummy version of idebug_parse.  This makes the option processing
1112    look a little neater.  */
1113 
1114 #define idebug_parse(z) 0
1115 
1116 #endif /* DEBUG <= 1 */
1117 
1118 /* Copy one file to another.  */
1119 extern boolean fcopy_file P((const char *zfrom, const char *zto,
1120 			     boolean fpublic, boolean fmkdirs));
1121 
1122 /* Read a line from a set of files opened by qmulti_open.  The return
1123    value is an malloc'ed buffer.  This will return NULL when all the
1124    files have been exhausted.  If pffirst is not NULL, it will be set
1125    to TRUE if this is the first line of a file.  If pzname is not
1126    NULL, it will be set to the file name from which the line was read.
1127    If fbackslash is TRUE, lines may be continued by using a backslash
1128    as the last character before the newline.  */
1129 extern char *zmulti_gets P((struct smulti_file *q, boolean *pffirst,
1130 			    const char **pzname, boolean fbackslash));
1131 
1132 /* Read an arbitrary length string from a file, returning an malloc'ed
1133    buffer.  If the fbackslash argument is true, lines may be continued
1134    by using a backslash as the last character before the newline.  */
1135 extern char *zfgets P((FILE *e, boolean fbackslash));
1136 
1137 /* Copy a string into memory without fail.  */
1138 extern char *xstrdup P((const char *));
1139 
1140 /* Allocate memory without fail.  */
1141 extern pointer xmalloc P((int));
1142 
1143 /* Realloc memory without fail.  */
1144 extern pointer xrealloc P((pointer, int));
1145 
1146 /* Free memory (accepts NULL pointers, which some libraries erroneously
1147    do not).  */
1148 extern void xfree P((pointer));
1149 
1150 #if ! HAVE_REMOVE
1151 /* Erase a file.  */
1152 #undef remove
1153 extern int remove P((const char *zfile));
1154 #endif
1155 
1156 #if ! HAVE_STRDUP
1157 /* Copy a string into memory.  */
1158 extern char *strdup P((const char *z));
1159 #endif
1160 
1161 #if ! HAVE_STRSTR
1162 /* Look for one string within another.  */
1163 extern char *strstr P((const char *zouter, const char *zinner));
1164 #endif
1165 
1166 #if ! HAVE_STRCASECMP
1167 #if HAVE_STRICMP
1168 /* Use macros to access stricmp and strnicmp as strcasecmp and
1169    strncasecmp.  */
1170 #define strcasecmp stricmp
1171 #define strncasecmp strnicmp
1172 #else /* ! HAVE_STRICMP */
1173 /* Use our own case insensitive string comparisons.  */
1174 extern int strcasecmp P((const char *z1, const char *z2));
1175 extern int strncasecmp P((const char *z1, const char *z2, int clen));
1176 #endif /* ! HAVE_STRICMP */
1177 #endif /* ! HAVE_STRCASECMP */
1178 
1179 #if ! HAVE_STRERROR
1180 /* Get a string corresponding to an error message.  */
1181 extern char *strerror P((int ierr));
1182 #endif
1183 
1184 /* Get the appropriate definitions for memcmp, memcpy, memchr and
1185    bzero.  Hopefully the declarations of bzero, bcmp and bcopy will
1186    not cause any trouble.  */
1187 #if ! HAVE_MEMCMP
1188 #if HAVE_BCMP
1189 #define memcmp(p1, p2, c) bcmp ((p1), (p2), (c))
1190 extern int bcmp ();
1191 #else /* ! HAVE_BCMP */
1192 extern int memcmp P((constpointer p1, constpointer p2, int c));
1193 #endif /* ! HAVE_BCMP */
1194 #endif /* ! HAVE_MEMCMP */
1195 
1196 #if ! HAVE_MEMCPY
1197 #if HAVE_BCOPY
1198 #define memcpy(pto, pfrom, c) bcopy ((pfrom), (pto), (c))
1199 extern void bcopy ();
1200 #else /* ! HAVE_BCOPY */
1201 extern pointer memcpy P((pointer pto, constpointer pfrom, int c));
1202 #endif /* ! HAVE_BCOPY */
1203 #endif /* ! HAVE_MEMCPY */
1204 
1205 #if ! HAVE_MEMCHR
1206 extern pointer memchr P((constpointer p, int b, int c));
1207 #endif
1208 
1209 #if HAVE_BZERO
1210 #ifndef bzero  /* bzero is sometimes a macro.  */
1211 extern void bzero ();
1212 #endif
1213 #else /* ! HAVE_BZERO */
1214 #if HAVE_MEMSET
1215 #define bzero(p, c) memset ((p), 0, (c))
1216 #else /* ! HAVE_MEMSET */
1217 extern void bzero P((pointer p, int c));
1218 #endif /* ! HAVE_MEMSET */
1219 #endif /* ! HAVE_BZERO */
1220 
1221 /* Move a memory block safely.  Go through xmemmove to allow for
1222    systems which have the prototype (using size_t, which we don't want
1223    to use since some systems won't have it) but not the function.  */
1224 #if HAVE_MEMMOVE
1225 #define xmemmove memmove
1226 #else /* ! HAVE_MEMMOVE */
1227 extern pointer xmemmove P((pointer, constpointer, int));
1228 #endif /* ! HAVE_MEMMOVE */
1229 
1230 /* Look up a character in a string.  */
1231 #if ! HAVE_STRCHR
1232 #if HAVE_INDEX
1233 #define strchr index
1234 extern char *index ();
1235 #else /* ! HAVE_INDEX */
1236 extern char *strchr P((const char *z, int b));
1237 #endif /* ! HAVE_INDEX */
1238 #endif /* ! HAVE_STRCHR */
1239 
1240 #if ! HAVE_STRRCHR
1241 #if HAVE_RINDEX
1242 #define strrchr rindex
1243 extern char *rindex ();
1244 #else /* ! HAVE_RINDEX */
1245 extern char *strrchr P((const char *z, int b));
1246 #endif /* ! HAVE_RINDEX */
1247 #endif /* ! HAVE_STRRCHR */
1248 
1249 /* Turn a string into a long integer.  */
1250 #if ! HAVE_STRTOL
1251 extern long strtol P((const char *, char **, int));
1252 #endif
1253 
1254 /* Lookup a key in a sorted array.  */
1255 #if ! HAVE_BSEARCH
1256 extern pointer bsearch P((constpointer pkey, constpointer parray,
1257 			  int celes, int cbytes,
1258 			  int (*pficmp) P((constpointer, constpointer))));
1259 #endif
1260 
1261 /* Convert a string to lower case.  */
1262 #if ! HAVE_STRLWR
1263 extern char *strlwr P((char *));
1264 #endif
1265 
1266 /* Global variables.  */
1267 
1268 /* The name of the program being run.  This is statically initialized,
1269    although it should perhaps be set from argv[0].  */
1270 extern char abProgram[];
1271 
1272 /* Version number string.  */
1273 extern char abVersion[];
1274 
1275 /* Local UUCP name.  */
1276 extern const char *zLocalname;
1277 
1278 /* System information file names.  */
1279 extern char *zSysfile;
1280 
1281 /* Port information file names.  */
1282 extern char *zPortfile;
1283 
1284 /* Dialer information file names.  */
1285 extern char *zDialfile;
1286 
1287 /* Local spool directory.  */
1288 extern const char *zSpooldir;
1289 
1290 /* Public directory.  */
1291 extern const char *zPubdir;
1292 
1293 /* Log file name.  */
1294 extern const char *zLogfile;
1295 
1296 /* Statistics file name.  */
1297 extern const char *zStatfile;
1298 
1299 #if DEBUG > 1
1300 /* Debugging file name.  */
1301 extern const char *zDebugfile;
1302 #endif
1303 
1304 /* Files containing login names and passwords to use when calling out.  */
1305 extern char *zCallfile;
1306 
1307 /* Files containing login names and passwords to check when somebody
1308    calls in.  */
1309 extern char *zPwdfile;
1310 
1311 /* Files containing dialcodes.  */
1312 extern char *zDialcodefile;
1313 
1314 #if HAVE_V2_CONFIG
1315 /* TRUE if we should read V2 configuration files.  */
1316 extern boolean fV2;
1317 
1318 /* Read the V2 L.sys file.  */
1319 extern void uv2_read_systems P((int *pc, struct ssysteminfo **ppas));
1320 
1321 #endif /* HAVE_V2_CONFIG */
1322 
1323 #if HAVE_BNU_CONFIG
1324 /* TRUE if we should read BNU configuration files.  */
1325 extern boolean fBnu;
1326 
1327 /* The names of the BNU system files to read.  */
1328 extern char *zBnu_systems;
1329 
1330 /* The names of the BNU dialers files to read.  */
1331 extern char *zBnu_dialers;
1332 
1333 /* The names of the BNU devices files to read.  */
1334 extern char *zBnu_devices;
1335 
1336 /* Routines to read BNU files.  */
1337 extern void ubnu_read_sysfiles P((void));
1338 extern void ubnu_read_systems P((int *pc, struct ssysteminfo **ppas));
1339 
1340 #endif /* HAVE_BNU_CONFIG */
1341 
1342 /* TRUE if we accept calls from unknown system.  */
1343 extern boolean fUnknown_ok;
1344 
1345 /* The ssysteminfo structure we use for unknown systems.  */
1346 extern struct ssysteminfo sUnknown;
1347 
1348 /* The ssysteminfo structure we use for the local system.  */
1349 extern struct ssysteminfo sLocalsys;
1350 
1351 /* The maximum number of uuxqt processes which may be running at one
1352    time.  */
1353 extern int cMaxuuxqts;
1354 
1355 /* When a signal occurs, the signal handlers sets the appropriate
1356    element of the arrays afSignal and afLog_signal to TRUE.  The
1357    afSignal array is used to check whether a signal occurred.  The
1358    afLog_signal array tells ulog to log the signal; ulog will clear
1359    the element after logging it, which means that if a signal comes in
1360    at just the right moment it will not be logged.  It will always be
1361    recorded in afSignal, though.  At the moment we handle 5 signals:
1362    SIGHUP, SIGINT, SIGQUIT, SIGTERM and SIGPIPE (the Unix code also
1363    handles SIGALRM).  If we want to handle more, the afSignal array
1364    must be extended; I see little point to handling any of the other
1365    ANSI C or POSIX signals, as they are either unlikely to occur
1366    (SIGABRT, SIGUSR1) or nearly impossible to handle cleanly (SIGILL,
1367    SIGSEGV).  */
1368 #define INDEXSIG_SIGHUP (0)
1369 #define INDEXSIG_SIGINT (1)
1370 #define INDEXSIG_SIGQUIT (2)
1371 #define INDEXSIG_SIGTERM (3)
1372 #define INDEXSIG_SIGPIPE (4)
1373 #define INDEXSIG_COUNT (5)
1374 
1375 extern volatile sig_atomic_t afSignal[INDEXSIG_COUNT];
1376 extern volatile sig_atomic_t afLog_signal[INDEXSIG_COUNT];
1377 
1378 /* The names of the signals to use in error messages, as an
1379    initializer for an array.  */
1380 #define INDEXSIG_NAMES \
1381   { "hangup", "interrupt", "quit", "termination", "SIGPIPE" }
1382 
1383 /* Check to see whether we've received a signal.  It would be nice if
1384    we could use a single variable for this, but we sometimes want to
1385    clear our knowledge of a signal and that would cause race
1386    conditions (clearing a single element of the array is not a race
1387    assuming that we don't care about a particular signal, even if it
1388    occurs after we've examined the array).  */
1389 #define FGOT_SIGNAL() \
1390   (afSignal[INDEXSIG_SIGHUP] || afSignal[INDEXSIG_SIGINT] \
1391    || afSignal[INDEXSIG_SIGQUIT] || afSignal[INDEXSIG_SIGTERM] \
1392    || afSignal[INDEXSIG_SIGPIPE])
1393 
1394 /* If we get a SIGINT in uucico, we continue the current communication
1395    session but don't start any new ones.  This macros checks for any
1396    signal other than SIGINT, which means we should get out
1397    immediately.  */
1398 #define FGOT_QUIT_SIGNAL() \
1399   (afSignal[INDEXSIG_SIGHUP] || afSignal[INDEXSIG_SIGQUIT] \
1400    || afSignal[INDEXSIG_SIGTERM] || afSignal[INDEXSIG_SIGPIPE])
1401 
1402 /* File being sent.  */
1403 extern openfile_t eSendfile;
1404 
1405 /* File being received.  */
1406 extern openfile_t eRecfile;
1407 
1408 /* Device name to log.  This is set by fport_open.  It may be NULL.  */
1409 extern char *zLdevice;
1410