
GNUUCP                                                          12-NOV-1988 14:08:27    VAX C      V2.3-024                 Page 1
V1.0                                                            13-OCT-1988 21:04:50    [VMSNET.DEVEL.GNUUCP.SRC]GNUUCP.C;27 (1)



    1        	/*
    2        	 * @(#)gnuucp.c 1.29 87/09/29	Copyright 1987 Free Software Foundation, Inc.
    3        	 *
    4        	 * Copying and use of this program are controlled by the terms of the
    5        	 * GNU Emacs General Public License.
    6        	 *
    7        	 * Derived from:
    8        	 * i[$]uuslave.c	1.7 08/12/85 14:04:20
    9        	 * which came from the ACGNJ BBS system at +1 201 753 9758.  Original
   10        	 * author unknown.  Many people, too numerous to list here, have contributed
   11        	 * changes and ports to this program.
   12        	 */
   13        	
   14        	char version[] = "Version hoptoad-1.29";
   15        	
   16        	/*
   17        	

GNUUCP                                                          12-NOV-1988 14:08:27    VAX C      V2.3-024                 Page 2
V1.0                                                            13-OCT-1988 21:04:50    [VMSNET.DEVEL.GNUUCP.SRC]GNUUCP.C;27 (2)

             	
   18        	This program implements the uucp (Unix-to-Unix CoPy) protocol, used to
   19        	transfer mail, files, and Usenet news among Unix machines.  UUCP comes
   20        	free with Unix (unless you get a sleazeoid version like Xenix, where
   21        	they charge you extra for it), but you don't get sources.  You can buy
   22        	a commercial program for MSDOS, called UULINK, which also implements
   23        	this protocol.  UULINK costs $300 and you still don't get sources.
   24        	This program not only runs on Unix and MSDOS, but on many other
   25        	machines, and comes with the Free Software Foundation copyright, which
   26        	guarantees you access to sources.
   27        	
   28        	The protocol requires a full 8-bit data path with no characters inserted
   29        	or deleted (e.g. ^S and ^Q are used as DATA characters).  Simple serial
   30        	ports and modems do this; most complicated networks do not, at least without
   31        	setting up odd modes and such.  Telenet's PC Pursuit works fine though.
   32        	
   33        	The basic flow of the protocol is that the calling machine will send down
   34        	a line of text saying what it wants to do (send a file, receive a file,
   35        	or hang up).  (The lines of text are encapsulated into packets; see below.)
   36        	The called machine responds with a "yes" or "no" answer, and if the answer
   37        	was yes, it sends or receives the file.  Files are terminated with a
   38        	packet containing 0 bytes of data.  Then the system that received the file
   39        	sends a "copy succeeded" or "copy failed" line to the other end, and 
   40        	they go back to "what do we do now".  A request to hang up should be
   41        	answered "no" if the called machine has some mail or files it wants to
   42        	send to the calling machine; the two machines reverse roles and the calling
   43        	machine goes into "what do we do now".  If a hangup request is answered "yes",
   44        	the call is terminated.
   45        	
   46        	The data flow described above is actually sent by a lower level "protocol
   47        	module".  The default "g" protocol module sends the data in packets containing
   48        	checksums and acknowledgements.  Each packet can either hold a short
   49        	control message, e.g. an ack, or a data block.  The data blocks are
   50        	numbered with a 3-bit counter, and sent with a checksum.  If the sender
   51        	has not received an acknowledgement for a data block within a certain
   52        	time, it retransmits the block.  The size of a data block is negotiated
   53        	at the start of a call.  To send a block with fewer bytes, a "short
   54        	data" block is sent, which is just as big as a "long data" block, but
   55        	contains a 1- or 2-byte count of "how many bytes in this block are just
   56        	padding".  This is a cute trick since it always works (e.g. if you want
   57        	to send 1023 out of 1024 bytes, you only need one byte for the count;
   58        	while if you want to send 1 byte out of 1024 then you have enough space
   59        	for the count to be 2 bytes).
   60        	
   61        	The short control messages are used to start the call and negotiate the
   62        	packet size and the "window size", to acknowledge or reject packets,
   63        	and to terminate the packet protocol at the end of a call.  The window
   64        	size is how many packets one side can send before it will stop and wait
   65        	for an acknowledgement from the other side.  A window size of 1 makes
   66        	for a half-duplex protocol (which is what gnuucp currently
   67        	implements), but also makes it easy to implement on micros that don't
   68        	handle serial lines with interrupts.  In window 1, you just keep
   69        	sending the same packet until the other side acknowledges it.  Unix
   70        	always uses a window size of 3, which is the max that can be dealt with
   71        	given the 3-bit packet numbers (for reasons that would take more space
   72        	than I want to spend here).  This gives much better throughput, but
   73        	requires full duplex serial port handling and more complicated

GNUUCP                                                          12-NOV-1988 14:08:27    VAX C      V2.3-024                 Page 3
V1.0                                                            13-OCT-1988 21:04:50    [VMSNET.DEVEL.GNUUCP.SRC]GNUUCP.C;27 (2)

   74        	acknowledgement strategies.
   75        	
   76        	In receiving data, the "g" protocol scans for a DLE (hex 10) which
   77        	indicates the start of a packet, and the next 5 bytes are read and
   78        	checked.  If they pass, this is a good packet and it is acted upon.
   79        	(If it's a data packet, we have to read in and check the data part
   80        	too.)  If the checks fail, all the bytes read so far should be rescanned
   81        	for another DLE, since it's possible that some characters were dropped
   82        	and the first DLE we saw was actually part of a data packet.
   83        	
   84        	Other protocol modules have been implemented; e.g. the "f" protocol which
   85        	eliminates the packets and acknowledgements, for reduced overhead when
   86        	running over an error-free, flow controlled connection on an X.25 network.
   87        	There has been talk of a "z" protocol which implements ZMODEM.  So far,
   88        	none of these modules are supplied with gnuucp, though "f" is public domain
   89        	and "z" is intended to be, because they are not ported and tested yet.
   90        	
   91        	At the start of a call, the caller sends the list of protocols it supports,
   92        	and the callee picks the best one it knows and says "use this one please".
   93        	
   94        	At the low level, full 8-bit bytes are sent out and received on an async
   95        	serial port.
   96        	*/
   97        	

GNUUCP                                                          12-NOV-1988 14:08:27    VAX C      V2.3-024                 Page 4
V1.0                                                            13-OCT-1988 21:04:50    [VMSNET.DEVEL.GNUUCP.SRC]GNUUCP.C;27 (3)

             	
   98        	#include "includes.h"		/* System include files, system dependent */
 3027        	#include "uucp.h"		/* Uucp definitions and parameters */
 3113        	#include "sysdep.h"		/* System dependent parts of gnuucp */
 3217        	
 3218        	#define	MAX_FLAGS	40
 3219        	
 3220        	extern int errno;
 3221        	
 3222        	char	ttynam[NAMESIZE],		/* Name of tty we use as serial port */
 3223        		srcnam[NAMESIZE],		/* Source file name */
 3224        		dstnam[NAMESIZE],		/* Dest file name */
 3225        		flags[MAX_FLAGS],		/* Flags from file xfer cmd */
 3226        		temp[NAMESIZE];			/* Temp file name */
 3227        	
 3228        	int	fdtty,				/* Opaque handle to pass to protocol */
 3229        		ignore_time_restrictions = 0,	/* Call out even if L.sys sez no */
 3230        		mode;				/* File mode from file xfer cmd */
 3231        	
 3232        	int   f_wait    = 0;	/* FIXME, unreferenced now */
 3233        	int   loop    = 1;	/* Loop accepting logins if tty name specified */
 3234        	int   curtemp = 0;
 3235        	
 3236        	#define	MAX_STRING	200	/* Max length string to send/expect */
 3237        	
 3238        	/* Strings sent by the slave side to the master */
 3239        	char msgo0[] = "login: ";
 3240        	char msgo1[] = "Password:";
 3241        	char msgo2[] = "\20Shere\0";
 3242        	char msgo3[] = "\20ROK\0";
 3243        	char msgo3a[]= "\20Pg\0";
 3244        	char msgo4[] = "\20OOOOOOO\0";
 3245        	
 3246        	/* Strings sent by the master to the slave */
 3247        	char msgi0[] = "uucp\n";
 3248        	char msgi1[] = "s8000\n";
 3249        	/* char msgi2[] = "\20S*\0"; We now scan it specially FIXME */
 3250        	char msgi3[] = "\20Ug\0";
 3251        	char msgi4[] = "OOOOOO";
 3252        	

GNUUCP                                                          12-NOV-1988 14:08:27    VAX C      V2.3-024                 Page 5
V1.0                                                            13-OCT-1988 21:04:50    [VMSNET.DEVEL.GNUUCP.SRC]GNUUCP.C;27 (4)

             	
 3253        	/*
 3254        	 * Protocol switch data structure
 3255        	 */
 3256        	struct proto {
 3257        		char	p_id;
 3258        		int	(*p_turnon)();
 3259        		int	(*p_rdmsg)();
 3260        		int	(*p_wrmsg)();
 3261        		int	(*p_rddata)();
 3262        		int	(*p_wrdata)();
 3263        		int	(*p_turnoff)();
 3264        	};
 3265        	
 3266        	extern int gturnon(), grdmsg(), gwrmsg(), grddata(), gwrdata(), gturnoff();
 3267        	/*
 3268        	 * This is how the "f" protocol would be declared:
 3269        	 * extern int fturnon(), frdmsg(), fwrmsg(), frddata(), fwrdata(), fturnoff();
 3270        	 */
 3271        	
 3272        	struct proto ptbl[] = {
 3273        		/* "f" protocol to run on X.25 PADs */
 3274        	  /*	{'f', fturnon, frdmsg, fwrmsg, frddata, fwrdata, fturnoff}, */
 3275        		/* Original "g" protocol for dialup async modem lines */
 3276        		{'g', gturnon, grdmsg, gwrmsg, grddata, gwrdata, gturnoff},
 3277        	};
 3278        	
 3279        	struct proto *curproto = &ptbl[0];
 3280        	
 3281        	#define	turnon	(*curproto->p_turnon)
 3282        	#define	rdmsg	(*curproto->p_rdmsg)
 3283        	#define	wrmsg	(*curproto->p_wrmsg)
 3284        	#define	rddata	(*curproto->p_rddata)
 3285        	#define	wrdata	(*curproto->p_wrdata)
 3286        	#define	turnoff	(*curproto->p_turnoff)
 3287        	

GNUUCP                                                          12-NOV-1988 14:08:27    VAX C      V2.3-024                 Page 6
V1.0                                                            13-OCT-1988 21:04:50    [VMSNET.DEVEL.GNUUCP.SRC]GNUUCP.C;27 (5)

             	
 3288        	/*
 3289        	 * Read from the serial port a null-terminated string.
 3290        	 * The string FIXME should not overrun MAX_STRING.
 3291        	 * String starts with first printing character.
 3292        	 */
 3293        	int
 3294        	getstring(where)
 3295        		register char *where;
 3296        	{
 3297    1   		register int data, count = 0;
 3298    1   	
 3299    1   		DEBUG(8, "Getstring:  ", 0);
 3300    1   		/* Read data until null character */
 3301    1   		while ( ((data = xgetc()) != EOF)) {
 3302    2   			data &= 0x7F;
 3303    2   			if (DEBUG_LEVEL(9)) {
 3304    3   				printf("%02x%c ", data, isprint(data)? data: ' ');
 3305    3   			}
 3306    2   	
 3307    2   			where[count++] = data;
 3308    2   			if (data == 0x00) {
 3309    3   				if (DEBUG_LEVEL(9)) putchar('\n');
 3310    3   				return SUCCESS;
 3311    3   			}
 3312    2   			if (count == 1 && !isprint(where[0]))
 3313    2   				count = 0;
 3314    2   		}
 3315    1   		if (DEBUG_LEVEL(9)) putchar('\n');
 3316    1   		return FAIL;
 3317    1   	}
 3318        	
 3319        	
 3320        	/*
 3321        	 * Medium level input routine.
 3322        	 *
 3323        	 * Look for an input string for the send-expect sequence.
 3324        	 * Return 0 for matching string, 1 for timeout before we found it.
 3325        	 * FIXME:  we only time out if the other end stops sending.  If it
 3326        	 *	   keeps sending, we keep listening forever.
 3327        	 * (But we need to be able to read a LOT of characters, 'cause some systems
 3328        	 * may send us system announcement messages, etc., when we dial in.  Suggest 
 3329        	 * counting the characters read and giving up when we've seen 4000 (about two 
 3330        	 * screens' worth) or so.  
 3331        	 * On the other hand, once the protocol gets going this shouldn't happen,
 3332        	 * so maybe the babble limit should be dynamic, large when we're
 3333        	 * initializing the protocol and small later on.  On the third hand 
 3334        	 * 4000 characters is less than 20 seconds at 2400 bps, so a static value
 3335        	 * isn't all that bad.  --- JEH)
 3336        	 */
 3337        	instr(s,n)
 3338        	register char *s;
 3339        	register int n;
 3340        	{
 3341    1   		register int data;
 3342    1   		register char	*pattern;
 3343    1   		register int i;

GNUUCP                                                          12-NOV-1988 14:08:27    VAX C      V2.3-024                 Page 7
V1.0                                                            13-OCT-1988 21:04:50    [VMSNET.DEVEL.GNUUCP.SRC]GNUUCP.C;27 (5)

 3344    1   	
 3345    1   		if (DEBUG_LEVEL(2)) {
 3346    2   			printf("Expecting ");
 3347    2   			for (i = 0; i < n; i++)
 3348    2   				printf("%02x%c ",s[i] & 0xFF, isprint(s[i])? s[i]: ' ');
 3349    2   			printf("\nR ");
 3350    2   		}
 3351    1   	
 3352    1   		pattern = s;
 3353    1   	
 3354    1   		while ((data = xgetc()) != EOF) {
 3355    2   			data &= 0x7F;			/* Ignore parity */
 3356    2   	
 3357    2   			if (DEBUG_LEVEL(2)) {
 3358    3   				printf("%02x%c ", data, isprint(data)? data: ' ');
 3359    3   			}
 3360    2   	
 3361    2   		tryfirst:
 3362    2   	
 3363    2   			if (data == *pattern) {
 3364    3   				/* Input matches next byte of pattern */
 3365    3   				pattern++;
 3366    3   				if (pattern >= &s[n]) {
 3367    4   					if (DEBUG_LEVEL(2)) putchar('\n');
 3368    4   					return 0;		/* Done */
 3369    4   				}
 3370    3   			} else {
 3371    3   				/* Input doesn't match pattern */
 3372    3   				if (pattern == s) continue;	/* First char */
 3373    3   				/* FIXME!  This doesn't work if pattern can match
 3374    3   				 * in more than one way initially, e.g.:
 3375    3   				 * "NECT" works when "CONNECT" is output, but
 3376    3   				 * "NNECT" fails when "CONNNECT" is output... */
 3377    3   				pattern = s;	/* Does cur char match first? */
 3378    3   				goto tryfirst;	/* FIXME */
 3379    3   			}
 3380    2   		}
 3381    1   	
 3382    1   		if (DEBUG_LEVEL(2))	putchar('\n');
 3383    1   		DEBUG(1, "Didn't see expected string '%s'\n", s);
 3384    1   		return 1;
 3385    1   	}
 3386        	
 3387        	/*
 3388        	 * Debugging hack for stuff written to the modem.
 3389        	 */
 3390        	int
 3391        	twrite(s, n)
 3392        		char *s;
 3393        		int	n;
 3394        	{
 3395    1   		register int i;
 3396    1   	
 3397    1   		if (DEBUG_LEVEL(9)) {
 3398    2   			printf("Wrote:  ");
 3399    2   			for (i = 0; i < n; i++)
 3400    2   				printf("%02x%c ",s[i] & 0xFF, isprint(s[i])? s[i]: ' ');

GNUUCP                                                          12-NOV-1988 14:08:27    VAX C      V2.3-024                 Page 8
V1.0                                                            13-OCT-1988 21:04:50    [VMSNET.DEVEL.GNUUCP.SRC]GNUUCP.C;27 (5)

 3401    2   			printf("\n");
 3402    2   		}
 3403    1   	
 3404    1   		return xwrite(s, n);
 3405    1   	}
 3406        	

GNUUCP                                                          12-NOV-1988 14:08:27    VAX C      V2.3-024                 Page 9
V1.0                                                            13-OCT-1988 21:04:50    [VMSNET.DEVEL.GNUUCP.SRC]GNUUCP.C;27 (6)

             	
 3407        	/*
 3408        	 * MAIN ROUTINE.
 3409        	 *
 3410        	 * This is called at program startup.  It parses the arguments to the
 3411        	 * program (if any) and sets up to receive a call on the modem.
 3412        	 *
 3413        	 * If there are no arguments, we assume the caller is already on standard
 3414        	 * input, waiting to do uucp protocols (past the login prompt), and we
 3415        	 * just handle one caller.
 3416        	 *
 3417        	 * If there is an argument, it is the name of the tty device where we
 3418        	 * should listen for multiple callers and handle login and password.
 3419        	 */
 3420        	main(argc,argv)
 3421        	int argc;
 3422        	char *argv[];
 3423        	{
 3424    1   		int	ontheline = 1;
 3425    1   		int	i;
 3426    1   		int	dbglog = 0;
 3427    1   		char	*poll_sys = (char *)NULL;  /* System name to poll, or none */
 3428    1   	
 3429    1   	#ifdef MSDOS
 3430   X    		fprintf(stderr, "\n\n");
 3431   X    		fprintf(stderr, "UUCICO  : for MS-DOS             Ver 0787-2.05a\n");
 3432   X    		fprintf(stderr, "Base code from gnuucp - hoptoad version 1.27\n");
 3433   X    		fprintf(stderr, "Copyright 1987 Free Software Foundation, Inc.  Copying by GNU rules only,\n");
 3434   X    		fprintf(stderr, "e.g. copies must include source code as well as binaries!\n");
 3435   X    		fprintf(stderr, "Modified by Garry M. Paxinos\n");
 3436   X    		fprintf(stderr, "FidoNet : 135/6   the 'Eye of Osiris'   SEAdog/OPUS/Dutchie/uuslave\n");
 3437   X    		fprintf(stderr, "        : 135/17  Megasystems Online    OPUS/Dutchie\n");
 3438   X    		fprintf(stderr, "UUCP    : ...!{allegra|codas|ucf-cs}!novavax!ankh!pax\n");
 3439   X    		fprintf(stderr, "USNail  : % Megasystems Inc. 1075 Broken Sound Pkwy NW, Boca Raton FL 33431\n\n");
 3440   X    	
 3441   X    		if (signal(SIGINT,handler) == (int(*)())-1) {
 3442   X    			fprintf(stderr,"Couldn't set SIGINT\n");
 3443   X    			abort();
 3444   X    		}
 3445    1   	#endif
 3446    1   	
 3447    1   		debug = -1;		/* Let read_params set it if -x doesn't */
 3448    1   		ttynam[0] = '\0';
 3449    1   		/* FIXME, use getopt */
 3450    1   		/* scan command line arguments, kinda kludgy but it works */
 3451    1   		for (i = 1; i < argc; i++) {
 3452    2   			if (argv[i][0] != '-')
 3453    2   				break;
 3454    2   			switch (argv[i][1]) {
 3455    3   	
 3456    3   			case 'l':
 3457    3   				dbglog++;
 3458    3   				break;
 3459    3   	
 3460    3   			case 'w':
 3461    3   				f_wait++;
 3462    3   				printf("uucico: will wait for call after outbound\n");

GNUUCP                                                          12-NOV-1988 14:08:27    VAX C      V2.3-024                 Page 10
V1.0                                                            13-OCT-1988 21:04:50    [VMSNET.DEVEL.GNUUCP.SRC]GNUUCP.C;27 (6)

 3463    3   				break;
 3464    3   	
 3465    3   			case 'x':
 3466    3   				debug = atoi(&argv[i][2]);
 3467    3   				break;
 3468    3   	
 3469    3   			case 'S':
 3470    3   				ignore_time_restrictions++;
 3471    3   			case 's':
 3472    3   				poll_sys = &argv[i][2];
 3473    3   				ontheline = 0;
 3474    3   				break;
 3475    3   	
 3476    3   			case 'e':
 3477    3   				loop++;
 3478    3   				printf("uucico: endless loop mode\n");
 3479    3   				break;
 3480    3   	
 3481    3   			case 'C':
 3482    3   				Control = &argv[i][2];
 3483    3   				break;
 3484    3   	
 3485    3   			/* Is -t needed for MSDOS?  Why?  -- hoptoad!gnu */
 3486    3   			case 't':
 3487    3   				curtemp++;
 3488    3   				printf("uucico: using ~uutemp.$$$ for temp file\n");
 3489    3   				break;
 3490    3   			}
 3491    2   		}
 3492    1   	
 3493    1   		/* If argument provided, use it as name of comm port */
 3494    1   		if (i < argc) {
 3495    2   			ontheline = 0;
 3496    2   			strcpy(ttynam, argv[i]);
 3497    2   		}
 3498    1   	
 3499    1   		read_params(Control);		/* Read control file */
 3500    1   	
 3501    1   		if (chdir(Spool)) {
 3502    2   			perror("Can't chdir to Spool directory");
 3503    2   			exit(EXIT_ERR);
 3504    2   		}
 3505    1   	
 3506    1   		/*
 3507    1   		 * If running via getty/login, our debug stdout had better
 3508    1   		 * go to a file, not to the usual stdout!
 3509    1   		 */
 3510    1   		if ((DEBUG_LEVEL(0) && ontheline) || dbglog) {
 3511    2   			freopen(DEBUG_LOG_FILE, "a", stdout);
 3512    2   		}
 3513    1   	
 3514    1   		setbuf(stdout, (char *)NULL);	/* Unbuffered debug output */
 3515    1   	
 3516    1   		/* Timestamp the long debug log */
 3517    1   		if (DEBUG_LEVEL(0)) {
 3518    2   			printf("\n\n\n\ngnuucp log on tty '%s' starting %s\n",
 3519    2   				ttynam, time_and_pid());

GNUUCP                                                          12-NOV-1988 14:08:27    VAX C      V2.3-024                 Page 11
V1.0                                                            13-OCT-1988 21:04:50    [VMSNET.DEVEL.GNUUCP.SRC]GNUUCP.C;27 (6)

 3520    2   		}
 3521    1   	
 3522    1   		/* Log our presence so we humans reading the logs can find the
 3523    1   		   entries created by gnuucp. */
 3524    1   		logit("GNUUCP", version);
 3525    1   	
 3526    1   		if (poll_sys) {
 3527    2   			if (*poll_sys == '\0') poll_sys = (char *)NULL;
 3528    2   			call_system(poll_sys);
 3529    2   			if (!f_wait) goto end;
 3530    2   		}
 3531    1   	
 3532    1   		do {
 3533    2   			/*
 3534    2   			 *  Set up serial channel, wait for incoming call. 
 3535    2   			 */
 3536    2   	
 3537    2   			DEBUG(0, "\nRestarting\n", 0);
 3538    2   			openline(ttynam, 0);	/* FIXME, let user specify baudrate */
 3539    2   	
 3540    2   			do_session(ontheline);
 3541    2   	
 3542    2   			hangup();
 3543    2   			DEBUG(0, "\nEnd of call\n", 0);
 3544    2   	
 3545    2   		} while (loop && !ontheline);
 3546    1   	
 3547    1   	end:
 3548    1   	#ifndef VMS
 3549   X    	
 3550   X    		if (DEBUG_LEVEL(0))
 3551   X    			execlp("forktest", "testing file descriptors", 0);
 3552   X    		else
 3553   X    			execlp("/usr/lib/uucp/uuxqt", "-uuxqt", 0);
 3554    1   	#endif
 3555    1   		exit(EXIT_OK);
 3556    1   	}
 3557        	
 3558        	debuggit()
 3559        	{
 3560    1   	#ifndef VMS
 3561   X    		if (fork() == 0)
 3562   X    			execlp("forktest", "testing file descriptors", 0);
 3563    1   	#endif
 3564    1   	}
 3565        	

GNUUCP                                                          12-NOV-1988 14:08:27    VAX C      V2.3-024                 Page 12
V1.0                                                            13-OCT-1988 21:04:50    [VMSNET.DEVEL.GNUUCP.SRC]GNUUCP.C;27 (7)

             	
 3566        	/*
 3567        	 * Handle a single set of uucp expect/send strings.
 3568        	 *
 3569        	 * Return SUCCESS if the expect string is found, or FAIL if not.
 3570        	 */
 3571        	sendexpect(expect, send)
 3572        		register char *expect;
 3573        		char *send;
 3574        	{
 3575    1   		char *dasher, *dancer;
 3576    1   	
 3577    1   		while ((dasher = strchr(expect, '-'))
 3578    1   		    && (dancer = strchr(dasher+1, '-'))) {
 3579    2   			/* Two dashes found -- we have an expect-send-expect string */
 3580    2   			*dasher = '\0'; *dancer = '\0';
 3581    2   			/* FIXME, instr returns 1 for "not matched" (which is handled
 3582    2   			 * properly here) and for timeout or hangup (which isn't).--JEH */
 3583    2   			if (instr(expect, dasher-expect) == 0)
 3584    2   				goto sendit;
 3585    2   			xlat_str(dasher+1);		/* Send the alternative */
 3586    2   			expect = dancer + 1;		/* Try next pair, if any */
 3587    2   		}
 3588    1   			
 3589    1   		if (expect[0] != '"' || expect[1] != '"' || expect[2] != '\0')
 3590    1   			if (instr(expect, strlen(expect)))
 3591    1   				return FAIL;
 3592    1   	
 3593    1   	sendit:
 3594    1   		if (send) {
 3595    2   			xlat_str(send);
 3596    2   		}
 3597    1   		return SUCCESS;
 3598    1   	}
 3599        	
 3600        	/*
 3601        	 * translate embedded escape characters in a "send" string, and send 'em.
 3602        	 */
 3603        	xlat_str(msg)
 3604        		register char	*msg;
 3605        	{
 3606    1   		register int	i  = 0,
 3607    1   			j  = 0;
 3608    1   		int	cr = 1;
 3609    1   		char	out[MAX_STRING+SLOP];
 3610    1   	
 3611    1   		sleep(1);		/* Old uucp did this, guess we'd better */
 3612    1   		while (msg[i]) {
 3613    2   			if (msg[i] == '\\') {
 3614    3   				switch (msg[++i]) {
 3615    4   				case 'r':            /* carriage return */
 3616    4   					out[j++] = 0x0d;
 3617    4   					break;
 3618    4   				case 'n':            /* line feed */
 3619    4   					out[j++] = 0x0a;
 3620    4   					break;
 3621    4   				case '\\':           /* back slash */

GNUUCP                                                          12-NOV-1988 14:08:27    VAX C      V2.3-024                 Page 13
V1.0                                                            13-OCT-1988 21:04:50    [VMSNET.DEVEL.GNUUCP.SRC]GNUUCP.C;27 (7)

 3622    4   					out[j++] = '\\';
 3623    4   					break;
 3624    4   				case 't':            /* tab */
 3625    4   					out[j++] = '\t';
 3626    4   					break;
 3627    4   				case 'd':            /* delay */
 3628    4   					/* Print output, delay, resume */
 3629    4   					twrite(out, j);
 3630    4   					j = 0;
 3631    4   					if (DEBUG_LEVEL(2)) printf("(SLEEP)  ");
 3632    4   					sleep(1);
 3633    4   					break;
 3634    4   				case 's':            /* space */
 3635    4   					out[j++] = ' ';
 3636    4   					break;
 3637    4   				case 'c':            /* no CR at end */
 3638    4   					cr = 0;
 3639    4   					break;
 3640    4   				default:            /* don't know so skip it */
 3641    4   					break;
 3642    4   				}
 3643    3   				i++;
 3644    3   			} else {
 3645    3   				out[j++] = msg[i++];
 3646    3   			}
 3647    2   		}
 3648    1   	
 3649    1   		if (cr)
 3650    1   			out[j++] = 0x0d;
 3651    1   	
 3652    1   		if (j) twrite(out, j);
 3653    1   	}
 3654        	

GNUUCP                                                          12-NOV-1988 14:08:27    VAX C      V2.3-024                 Page 14
V1.0                                                            13-OCT-1988 21:04:50    [VMSNET.DEVEL.GNUUCP.SRC]GNUUCP.C;27 (8)

             	
 3655        	/*
 3656        	 * Line finder.  Given an "ACU" specifier from the L.sys file,
 3657        	 * and a baud rate, determine a file name that we should try to lock
 3658        	 * and open.
 3659        	 *
 3660        	 * On initial call, pass in (struct port *)0 as the port argument.
 3661        	 * On subsequent calls, we skip past that port, which is presumed to
 3662        	 * have been tried and failed.
 3663        	 *
 3664        	 * If we find a matching entry in the config file ports database,
 3665        	 * return it; else return a dummy entry that might let the user get
 3666        	 * by with specifying just the device name for hardwired lines.
 3667        	 */
 3668        	#ifdef FIXME
 3669   X    	static struct port dummyport = {
 3670   X    		"",				/* Name -- filled in later */
 3671   X    		"none",				/* Modem type */
 3672   X    		"",				/* Dev name -- filled in later */
 3673   X    		0,				/* Baud rate -- filled in later */
 3674   X    		(struct port *)0};		/* Chain */
 3675        	#endif FIXME
 3676        		
 3677        	struct port *
 3678        	pickport(acu, baud, p)
 3679        		char	*acu;
 3680        		long	baud;
 3681        		register struct port *p;
 3682        	{
 3683    1   	
 3684    1   		if (p == 0)
 3685    1   			p = ports;
 3686    1   		else
 3687    1   			p = p->chain;
 3688    1   	
 3689    1   		for ( ; p; p = p->chain) {
 3690    2   			if (baud == p->baud &&
 3691    2   			    strcmp(acu, p->portname) == 0)
 3692    2   				return p;
 3693    2   		}
 3694    1   	
 3695    1   		return p;			/* Didn't find it -- return null ptr */
 3696    1   	
 3697    1   	#ifdef FIXME
 3698   X    		strcpy(dummyport.portname, acu);	/* Fill in acu name */
 3699   X    		strcpy(dummyport.devname,  acu);	/* Fill in acu name */
 3700   X    		dummyport.baud = baud;
 3701   X    		return &dummyport;
 3702    1   	#endif FIXME
 3703    1   	}
 3704        	
 3705        	
 3706        	#ifdef VMS
 3707        	/*
 3708        	 * Simple dialer routine.  Uses dial(), borrowed (with heavy mods)
 3709        	 * from C-Kermmit. Still not great.  -- JEH
 3710        	 */

GNUUCP                                                          12-NOV-1988 14:08:27    VAX C      V2.3-024                 Page 15
V1.0                                                            13-OCT-1988 21:04:50    [VMSNET.DEVEL.GNUUCP.SRC]GNUUCP.C;27 (8)

 3711        	
 3712        	dial_nbr(port, nbr)
 3713        		struct port *port;
 3714        		char  *nbr;
 3715        	{
 3716    1   		char  dial[30];
 3717    1   		char  conn[30];
 3718    1   		int   i;
 3719    1   	
 3720    1   		/* Hardwired lines do no dialing. */
 3721    1   		if (strcmp("none", port->modemname) == 0)
 3722    1   			return SUCCESS;
 3723    1   	
 3724    1   		if (DEBUG_LEVEL(2))
 3725    1   			printf("dialing %s at %d baud: %s\n",
 3726    1   				port->devname, port->baud, dial);
 3727    1   	
 3728    1   		i = tdial(nbr, port->modemname);
 3729    1   	
 3730    1   		if (!i) sleep(2);	/* Let the line settle. */
 3731    1   	
 3732    1   		return (i);
 3733    1   	}
 3734        	
 3735        	#else
 3736   X    	
 3737   X    	/*
 3738   X    	 * Simple dialer routine.  Needs replacement with a full blown
 3739   X    	 * script driven dialer.  Next week maybe :-).  FIXME.
 3740   X    	 */
 3741   X    	dial_nbr(port, nbr)
 3742   X    		struct port *port;
 3743   X    		char  *nbr;
 3744   X    	{
 3745   X    		char  dial[30];
 3746   X    		char  conn[30];
 3747   X    		int   i;
 3748   X    	
 3749   X    		/* Hardwired lines do no dialing. */
 3750   X    		if (strcmp("none", port->modemname) == 0)
 3751   X    			return SUCCESS;
 3752   X    	
 3753   X    		/* If it doesn't say hayes, we can't dial it. */
 3754   X    		if (strcmp("hayes", port->modemname) != 0)
 3755   X    			return FAIL;
 3756   X    	
 3757   X    		sprintf(dial, "ATV1DT %s\r", nbr);
 3758   X    	
 3759   X    		if (DEBUG_LEVEL(2))
 3760   X    			printf("dialing %s at %d baud: %s\n",
 3761   X    				port->devname, port->baud, dial);
 3762   X    	
 3763   X    		twrite(dial, strlen(dial));
 3764   X    	
 3765   X    		/* FIXME, we've got to be more flexible here... */
 3766   X    	/* sprintf(conn, "CONNECT %s\r", baud);*/
 3767   X    		sprintf(conn, "CONNECT");

GNUUCP                                                          12-NOV-1988 14:08:27    VAX C      V2.3-024                 Page 16
V1.0                                                            13-OCT-1988 21:04:50    [VMSNET.DEVEL.GNUUCP.SRC]GNUUCP.C;27 (8)

 3768   X    	
 3769   X    		i = instr(conn, strlen(conn));
 3770   X    	
 3771   X    		/* FIXME, scan out the baud rate, or whatever's before the CR, here.
 3772   X    		 */
 3773   X    	
 3774   X    		if (!i) sleep(2);	/* Let the line settle. */
 3775   X    	
 3776   X    		return (i);
 3777   X    	}
 3778        	#endif
 3779        	
 3780        	

GNUUCP                                                          12-NOV-1988 14:08:27    VAX C      V2.3-024                 Page 17
V1.0                                                            13-OCT-1988 21:04:50    [VMSNET.DEVEL.GNUUCP.SRC]GNUUCP.C;27 (9)

             	
 3781        	/*
 3782        	 * Call a specific system, or all systems that have work pending.
 3783        	 */
 3784        	call_system(sys)
 3785        		char	*sys;
 3786        	{
 3787    1   		FILE	*lsys;
 3788    1   		char	buf[MAX_LSYS];
 3789    1   		char	sysnam[MAX_HOST];
 3790    1   		char	prev_name[MAX_HOST];
 3791    1   		int	called = FAIL;
 3792    1   	
 3793    1   		/*
 3794    1   		 * Unix uucico just reads the directory, and calls the systems
 3795    1   		 * in the order of the files in the directory.  We want more
 3796    1   		 * control than that, though I'm not sure that L.sys order is
 3797    1   		 * best either.  For example, in the first call after 11PM,
 3798    1   		 * I'd like to call the sites that haven't been callable before
 3799    1   		 * 11PM first, and finish up with the ones I've been able to call
 3800    1   		 * all day.  FIXME.
 3801    1   		 */
 3802    1   	
 3803    1   		if (! (lsys = fopen(Sysfile, "r"))) {
 3804    2   			DEBUG(0, "uucico: can't open L.sys, errno %d\n", errno);
 3805    2   			return 0;
 3806    2   		}
 3807    1   		sysnam[0] = '\0';		/* Initially, no previous sys */
 3808    1   	
 3809    1   		/* Once per system in L.sys... */
 3810    1   		/* FIXME, handle continuation lines (trailing "\") */
 3811    1   		while (fgets(buf, sizeof buf, lsys)) {
 3812    2   	
 3813    2   			if (buf[0] == '#')
 3814    2   				continue;
 3815    2   			
 3816    2   			/*
 3817    2   			 * Grab the system name.  If same as previous, and
 3818    2   			 * the previous call worked, skip it.
 3819    2   			 */
 3820    2   			strcpy(prev_name, sysnam);
 3821    2   			(void) sscanf(buf, "%s", sysnam);
 3822    2   			if (!strcmp(sysnam, prev_name)) {
 3823    3   				if (called == SUCCESS) continue;
 3824    3   			}
 3825    2   	
 3826    2   			/*
 3827    2   			 * If a system name was specified, skip til we find it.
 3828    2   			 * If none was specified, only call if there is work.
 3829    2   	    		 * (Need to add provision for polling other systems --
 3830    2   	    		 * maybe they have work for us, and they can't dial out!
 3831    2   	    		 *   -- JEH)
 3832    2   			 */
 3833    2   			if (sys) {
 3834    3   				if (0 != strcmp(sys, sysnam))
 3835    3   					continue;
 3836    3   			} else {

GNUUCP                                                          12-NOV-1988 14:08:27    VAX C      V2.3-024                 Page 18
V1.0                                                            13-OCT-1988 21:04:50    [VMSNET.DEVEL.GNUUCP.SRC]GNUUCP.C;27 (9)

 3837    3   				DEBUG(4,"searching for outbound to %s\n", sysnam);
 3838    3   	
 3839    3   				if (!work_scan(sysnam, "C")) {
 3840    4   					DEBUG(3,"no work for %s\n", sysnam);
 3841    4   					called = SUCCESS;	/* Don't try further */
 3842    4   					continue;
 3843    4   				}
 3844    3   	
 3845    3   				DEBUG(3, "found work for %s\n", sysnam);
 3846    3   			}
 3847    2   	
 3848    2   			called = call_sysline(buf);
 3849    2   	
 3850    2   			if (called == SUCCESS && sys) break;
 3851    2   		}
 3852    1   	
 3853    1   		fclose(lsys);
 3854    1   		if (called == FAIL && sys)
 3855    1   			DEBUG(0, "Could not call system %s\n", sys);
 3856    1   		return 0;
 3857    1   	}
 3858        	

GNUUCP                                                          12-NOV-1988 14:08:27    VAX C      V2.3-024                 Page 19
V1.0                                                            13-OCT-1988 21:04:50    [VMSNET.DEVEL.GNUUCP.SRC]GNUUCP.C;27 (10)

             	
 3859        	/*
 3860        	 * Call out to a system, given its L.sys line.
 3861        	 */
 3862        	int
 3863        	call_sysline(lsysline)
 3864        		char	*lsysline;
 3865        	{
 3866    1   		char	tempname[MAX_HOST + 30 + SLOP],
 3867    1   			*sysnam,
 3868    1   			*times,
 3869    1   			*acu,
 3870    1   			*sbaud,
 3871    1   			*telno,
 3872    1   			*send,
 3873    1   			*expect;
 3874    1   		struct port *port;
 3875    1   		char	logbuf[MAX_HOST+30+SLOP];
 3876    1   		char	msgbuf[MAX_STRING+SLOP];
 3877    1   		int	baud;
 3878    1   	
 3879    1   		who[0] = '-'; who[1] = '\0';	/* No user now (for logit) */
 3880    1   	
 3881    1   		/* FIXME, use the values it is ignoring here */
 3882    1   		sysnam = strtok(lsysline, " ");
 3883    1   		times = strtok((char *)NULL, " ");	/* Time */
 3884    1   		acu = strtok((char *)NULL, " ");	/* ACU */
 3885    1   		sbaud = strtok((char *)NULL, " ");	/* Baud */
 3886    1   		telno = strtok((char *)NULL," ");	/* phone */
 3887    1   	
 3888    1   		strcpy(host_name, sysnam);
 3889    1   	
 3890    1   		if (!ignore_time_restrictions) {
 3891    2   			/* FIXME, check the time parameter and return FAIL if
 3892    2   			 * it does not allow calls now.  Meanwhile, bounce
 3893    2   			 * all calls unless -S is specified. */
 3894    2   			logit("WRONG TIME TO CALL", sysnam);
 3895    2   			return FAIL;
 3896    2   		}
 3897    1   	
 3898    1   		baud = atoi(sbaud);
 3899    1   	
 3900    1   		port = (struct port *)0;
 3901    1   		for (;;) {
 3902    2   			port = pickport(acu, baud, port);
 3903    2   			if (!port)
 3904    2   				return FAIL;		/* Tried them all */
 3905    2   			DEBUG(2, "Opening outgoing line %s\n", port->devname);
 3906    2   			if (openout(port->devname, baud) != SUCCESS) {
 3907    3   				logit("CAN'T USE", port->devname);
 3908    3   			} else {
 3909    3   				break;
 3910    3   			}
 3911    2   		}
 3912    1   		logit("USING", port->devname);
 3913    1   	
 3914    1   	#ifdef VMS

GNUUCP                                                          12-NOV-1988 14:08:27    VAX C      V2.3-024                 Page 20
V1.0                                                            13-OCT-1988 21:04:50    [VMSNET.DEVEL.GNUUCP.SRC]GNUUCP.C;27 (10)

 3915    1   		if(!get_lock_nowait()) {
 3916    2   			logit("CAN'T ACQUIRE LOCK FOR SYSTEM", sysnam);
 3917    2   			return FAIL;
 3918    2   		}
 3919    1   	
 3920    1   		/* 
 3921    1   		from here on, any abort paths must remember to release the lock.
 3922    1   		(But no big deal if they don't, since the program will exit
 3923    1   		eventually... 
 3924    1   		*/
 3925    1   	
 3926    1   	#endif 
 3927    1   		sprintf(logbuf, "%s %s %d", host_name, port->devname, port->baud);
 3928    1   		DEBUG(1, "Trying %s\n", logbuf);
 3929    1   	
 3930    1   		if (dial_nbr(port, telno)) {
 3931    2   	#ifndef VMS
 3932   X    			ttyunlock();
 3933    2   	#endif
 3934    2   			logit("FAILED", logbuf);
 3935    2   	#ifdef VMS
 3936    2   			release_lock();
 3937    2   	#endif 
 3938    2   			return FAIL;
 3939    2   		}
 3940    1   	
 3941    1   		logit("DIALED", logbuf);
 3942    1   	
 3943    1   		/*
 3944    1   		 * Process send-expect strings.
 3945    1   		 */
 3946    1   		while (expect = strtok((char *)NULL, " ")) {
 3947    2   			send = strtok((char *)NULL, " ");
 3948    2   			if (sendexpect(expect, send) != SUCCESS)
 3949    2   				goto bort1;
 3950    2   		}
 3951    1   	
 3952    1   		/*
 3953    1   		 * FIXME, there should be a way to detect login/passwd
 3954    1   		 * failure here and keep doing the script rather than
 3955    1   		 * continuing to expect Shere at another login: prompt.
 3956    1   		 */
 3957    1   		sprintf(logbuf, "call to %s", host_name);
 3958    1   		logit("SUCCEEDED", logbuf);
 3959    1   	
 3960    1   		/* wait for Shere message, grab whatever is sent, send response */
 3961    1   		sprintf(tempname, "\20Shere");
 3962    1   		if (instr(tempname, strlen(tempname)))
 3963    1   			goto bort1;
 3964    1   		if (getstring(msgbuf) != SUCCESS)
 3965    1   			goto bort1;
 3966    1   		if (msgbuf[0] == '=') {
 3967    2   			if (!!strcmp(host_name, msgbuf+1)) {
 3968    3   				logit("WRONG HOST", msgbuf);
 3969    3   				goto bort1;
 3970    3   			}
 3971    2   		} else if (msgbuf[0] != '\0') {

GNUUCP                                                          12-NOV-1988 14:08:27    VAX C      V2.3-024                 Page 21
V1.0                                                            13-OCT-1988 21:04:50    [VMSNET.DEVEL.GNUUCP.SRC]GNUUCP.C;27 (10)

 3972    2   			DEBUG(0, "strange Shere%s\n", msgbuf);
 3973    2   		}
 3974    1   	
 3975    1   		sprintf(tempname, "\20S%s\0", Myname);
 3976    1   		twrite(tempname, strlen(tempname)+1); /* Including null */
 3977    1   	
 3978    1   		/* wait for ok message */
 3979    1   		if (getstring(msgbuf) != SUCCESS)
 3980    1   			goto bort1;
 3981    1   		if (msgbuf[0] != 'R')
 3982    1   			goto bort1;
 3983    1   		if (strcmp("OK", msgbuf+1)) {
 3984    2   			logit("HANDSHAKE FAILED", msgbuf+1);
 3985    2   			goto bort1;
 3986    2   		}
 3987    1   	
 3988    1   		/*
 3989    1   		 * Get Protocol string, make sure it supports our protocol.
 3990    1   		 * FIXME, should scan our table versus theirs.
 3991    1   		 */
 3992    1   		if (getstring(msgbuf) != SUCCESS)
 3993    1   			goto bort1;
 3994    1   		if (msgbuf[0] != 'P')
 3995    1   			goto bort1;
 3996    1   		if (!strchr(msgbuf+1, curproto->p_id)) {
 3997    2   			logit("PROTOCOL UNSUPPORTED", msgbuf);
 3998    2   			goto bort1;
 3999    2   		}
 4000    1   		twrite(msgi3, sizeof(msgi3)-1);	/* FIXME, build real reply */
 4001    1   	
 4002    1   		if (turnon(1))
 4003    1   			goto bort1;
 4004    1   	
 4005    1   		logit("OK", "startup");
 4006    1   	
 4007    1   	#ifdef VMS
 4008    1   		arm_uuxqt();		/* queue the uuxqt batch job */
 4009    1   	#endif
 4010    1   		top_level(1);		/* Returns SUCCESS or FAIL, we dont care */
 4011    1   	#ifdef VMS
 4012    1   	    	release_lock();		/* release the lock, so batch job to run */
 4013    1   	#endif
 4014    1   		hangup();
 4015    1   		return SUCCESS;
 4016    1   	
 4017    1   	bort1:
 4018    1   	#ifdef VMS
 4019    1   		release_lock();
 4020    1   	#endif
 4021    1   		hangup();
 4022    1   		return FAIL;
 4023    1   	}
 4024        	

GNUUCP                                                          12-NOV-1988 14:08:27    VAX C      V2.3-024                 Page 22
V1.0                                                            13-OCT-1988 21:04:50    [VMSNET.DEVEL.GNUUCP.SRC]GNUUCP.C;27 (11)

             	
 4025        	/* Handle a single uucp [slave] login session */
 4026        	do_session(ontheline)
 4027        		int ontheline;
 4028        	{
 4029    1   		char	trash[MAX_STRING+SLOP];	/* Incoming trash buffer */
 4030    1   	
 4031    1   		if (!ontheline) {
 4032    2   			/* output login request, verify uucp */
 4033    2   			twrite(msgo0,sizeof(msgo0)-1);
 4034    2   			if (instr(msgi0,sizeof(msgi0)-1)) {
 4035    3   				printf("uucico: invalid login name\n");
 4036    3   				goto bort;
 4037    3   			}
 4038    2   	
 4039    2   			/* output password request, verify s8000 */
 4040    2   			twrite(msgo1,sizeof(msgo1)-1);
 4041    2   			if (instr(msgi1,sizeof(msgi1)-1)) {
 4042    3   				printf("uucico: invalid password\n");
 4043    3   				goto bort;
 4044    3   			}
 4045    2   	
 4046    2   			printf("uucico: correct login\n");
 4047    2   		}
 4048    1   	
 4049    1   		/* output here message, wait for response */
 4050    1   		twrite(msgo2,sizeof(msgo2)-1);
 4051    1   	/* FIXME, handle this kludge */
 4052    1   	/*	if (instr(msgi2,sizeof(msgi2)-1)) */
 4053    1   		if (getstring(trash) != SUCCESS || trash[0] != 'S')
 4054    1   			goto bort;
 4055    1   	
 4056    1   		strcpy (host_name, strtok(trash, "\20S "));
 4057    1   		logit("INCOMING CALL FROM (Shere exchanged with) ", host_name);
 4058    1   	
 4059    1   	#ifdef VMS
 4060    1   		if (!get_lock_nowait()) {
 4061    2   			logit("COULDN'T ACQUIRE LOCK FOR ", host_name);
 4062    2   			goto bort;
 4063    2   		}
 4064    1   	#endif
 4065    1   			
 4066    1   		/* output ROK message, output protocol request, wait for response */
 4067    1   		twrite(msgo3,sizeof(msgo3)-1);
 4068    1   	
 4069    1   		/* FIXME, make the protocol list here, and use it */
 4070    1   		twrite(msgo3a,sizeof(msgo3a)-1);
 4071    1   		if (instr(msgi3,sizeof(msgi3)-1))
 4072    1   			goto bort;
 4073    1   	
 4074    1   		if (turnon(0)) goto bort;
 4075    1   		logit("OK", "startup");
 4076    1   	#ifdef VMS
 4077    1   	    	arm_uuxqt();		/* grab the lock and queue the batch job */
 4078    1   	#endif
 4079    1   		top_level(0);		/* Returns SUCCESS or FAIL, we dont care */
 4080    1   	

GNUUCP                                                          12-NOV-1988 14:08:27    VAX C      V2.3-024                 Page 23
V1.0                                                            13-OCT-1988 21:04:50    [VMSNET.DEVEL.GNUUCP.SRC]GNUUCP.C;27 (11)

 4081    1   	bort:
 4082    1   	#ifdef VMS
 4083    1   	    	release_lock();		/* release the lock */
 4084    1   	#endif
 4085    1   		printf("uucico: call complete\n");
 4086    1   	}
 4087        	

GNUUCP                                                          12-NOV-1988 14:08:27    VAX C      V2.3-024                 Page 24
V1.0                                                            13-OCT-1988 21:04:50    [VMSNET.DEVEL.GNUUCP.SRC]GNUUCP.C;27 (12)

             	
 4088        	/*
 4089        	 * Handle transactions "at top level", as Unix uucp's debug log says.
 4090        	 *
 4091        	 * As master, we scan our queues for work and send requests to the
 4092        	 * other side.  When done, we send a hangup request and switch to slave mode.
 4093        	 *
 4094        	 * As slave, we accept requests from the other side; when it is done,
 4095        	 * it sends a hangup request, and we switch to master mode, if we have
 4096        	 * any work queued up for that system.
 4097        	 *
 4098        	 * This repeats as long as either side has work to do.  When all the
 4099        	 * queued work is done, we agree to hang up, terminate the packet protocol,
 4100        	 * and return to the caller.  (We still haven't hung up the phone line yet.)
 4101        	 *
 4102        	 * A curious feature of the hangup protocol is that it is not a simple
 4103        	 * question-answer.  The master says "H", asking about hangup.  The
 4104        	 * slave responds "HY" saying OK.  The master then says "HY" also,
 4105        	 * then both of them hang up.  Maybe this is to make sure the first HY
 4106        	 * got ack'ed?  Anyway, an "H" is reported as HANGUP and an "HY" as
 4107        	 * HANGNOW.  After we send an HY, we go back to listening for commands;
 4108        	 * if the master sends something other than HY, we'll do it.
 4109        	 */
 4110        	#define	HANGUP	2		/* Signal to switch master/slave roles */
 4111        	#define	HANGNOW	3		/* Signal to hang up now */
 4112        	#define	COPYFAIL	4	/* File copy failed */
 4113        	
 4114        	int
 4115        	top_level(master_mode)
 4116        		int master_mode;
 4117        	{
 4118    1   		char	buf[MAXMSGLEN];		/* For hangup responses */
 4119    1   	
 4120    1   		if (master_mode) {
 4121    2   			(void) work_scan(host_name, "C"); /* Kick off queue scan */
 4122    2   			goto master;
 4123    2   		}
 4124    1   	
 4125    1   		for (;;) {
 4126    2   			/* Slave side */
 4127    2   		slave:
 4128    2   			for (;;) {
 4129    3   				DEBUG(4, "*** TOP *** - slave\n", 0);
 4130    3   				switch (do_one_slave()) {
 4131    4   				case SUCCESS:
 4132    4   					break;
 4133    4   				case FAIL:
 4134    4   					return FAIL;
 4135    4   				case HANGUP:
 4136    4   					if (work_scan(host_name, "C")) {
 4137    5   						if (wrmsg('H', "N", fdtty))
 4138    5   							return FAIL;
 4139    5   						goto master;
 4140    5   					} else {
 4141    5   						if (wrmsg('H', "Y", fdtty))
 4142    5   							return FAIL;
 4143    5   						break;

GNUUCP                                                          12-NOV-1988 14:08:27    VAX C      V2.3-024                 Page 25
V1.0                                                            13-OCT-1988 21:04:50    [VMSNET.DEVEL.GNUUCP.SRC]GNUUCP.C;27 (12)

 4144    5   					}
 4145    4   				case HANGNOW:
 4146    4   					goto quit;
 4147    4   				}
 4148    3   			}
 4149    2   		
 4150    2   			/* Master side */
 4151    2   		master:
 4152    2   			for (;;) {
 4153    3   				DEBUG(4, "*** TOP *** - master\n", 0);
 4154    3   				switch (do_one_master()) {
 4155    4   				case SUCCESS:
 4156    4   					break;
 4157    4   				case FAIL:
 4158    4   					return FAIL;
 4159    4   				case HANGUP:
 4160    4   					/* We wrote an H command, what's the resp? */
 4161    4   					if (rdmsg(buf, fdtty) != SUCCESS)
 4162    4   						return FAIL;
 4163    4   					if (buf[0] != 'H')
 4164    4   						return FAIL;
 4165    4   					if (buf[1] == 'N')
 4166    4   						goto slave;
 4167    4   					else {
 4168    5   						/* Write the final HY */
 4169    5   						if (wrmsg('H', "Y", fdtty))
 4170    5   							return FAIL;
 4171    5   						goto quit;
 4172    5   					}
 4173    4   				}
 4174    3   			}
 4175    2   		}
 4176    1   	
 4177    1   	quit:
 4178    1   		/* Shut down the packet protocol */
 4179    1   		turnoff();
 4180    1   	
 4181    1   		/* Write the closing sequence */
 4182    1   		twrite(msgo4, sizeof(msgo4)-1);
 4183    1   		(void) instr(msgi4, sizeof(msgi4)-1);
 4184    1   	
 4185    1   		twrite(msgo4, sizeof(msgo4)-1);
 4186    1   	
 4187    1   		logit("OK", "conversation complete");
 4188    1   	
 4189    1   		return SUCCESS;   /* Go byebye */
 4190    1   	}
 4191        	

GNUUCP                                                          12-NOV-1988 14:08:27    VAX C      V2.3-024                 Page 26
V1.0                                                            13-OCT-1988 21:04:50    [VMSNET.DEVEL.GNUUCP.SRC]GNUUCP.C;27 (13)

             	
 4192        	/*
 4193        	 * We are slave; get a command from the other side and execute it.
 4194        	 *
 4195        	 * Result is SUCCESS, FAIL, HANGUP, or HANGNOW.
 4196        	 */
 4197        	int
 4198        	do_one_slave()
 4199        	{
 4200    1   		char msg[MAXMSGLEN];		/* Master's message to us */
 4201    1   	
 4202    1   		/* Get master's command */
 4203    1   		if (rdmsg(msg, fdtty) != SUCCESS)
 4204    1   			return FAIL;
 4205    1   	
 4206    1   		/* Print it for easy debugging */
 4207    1   		DEBUG(4,"Command: %s\n\n", msg);
 4208    1   	
 4209    1   		switch (msg[0]) {
 4210    2   	
 4211    2   		case 'S':
 4212    2   			if (msg[1] != ' ') break;
 4213    2   			return host_send_file(msg);
 4214    2   	
 4215    2   		case 'R':
 4216    2   			if (msg[1] != ' ') break;
 4217    2   			return host_receive_file(msg);
 4218    2   	
 4219    2   		case 'X':
 4220    2   			/* Cause uuxqt to run (on certain files?)
 4221    2   			 * See Protocol.doc for sketchy details.
 4222    2   			 */
 4223    2   			break;
 4224    2   	
 4225    2   		case 'H':
 4226    2   			if (msg[1] == '\0') return HANGUP;
 4227    2   			if (msg[1] == 'Y')  return HANGNOW;
 4228    2   			if (msg[1] == 'N')  return SUCCESS;	/* Ignore HN to slave */
 4229    2   			break;
 4230    2   	
 4231    2   		}
 4232    1   	
 4233    1   		/* Unrecognized packet from the other end */
 4234    1   		DEBUG(0, "Bad control packet refused: %s\n", msg);
 4235    1   		if (yesno(msg[0], 0, 0))	/* FIXME: return error code */
 4236    1   			return FAIL;
 4237    1   		return SUCCESS;
 4238    1   	}
 4239        	

GNUUCP                                                          12-NOV-1988 14:08:27    VAX C      V2.3-024                 Page 27
V1.0                                                            13-OCT-1988 21:04:50    [VMSNET.DEVEL.GNUUCP.SRC]GNUUCP.C;27 (14)

             	
 4240        	/*
 4241        	 * Do one piece of work as master.
 4242        	 *
 4243        	 * FIXME:  we don't handle the flags, e.g. -c, properly!
 4244        	 */
 4245        	int
 4246        	do_one_master()
 4247        	{
 4248    1   		FILE	*fd;
 4249    1   		char	*sname;
 4250    1   		char	cmnd[1];		/* Command character */
 4251    1   		char 	buf[100];
 4252    1   		int	fail;
 4253    1   		int	num;
 4254    1   		char	notify[NAMESIZE];	/* A bit large...FIXME */
 4255    1   				/* FIXME: do the notify stuff */
 4256    1   	
 4257    1   		sname = work_next();
 4258    1   		if (!sname) {
 4259    2   			/* No more work, time to hang up. */
 4260    2   			if (wrmsg('H', "", fdtty))
 4261    2   				return FAIL;
 4262    2   			return HANGUP;
 4263    2   		}
 4264    1   	
 4265    1   		DEBUG(4, "Request file %s\n", sname);
 4266    1   	
 4267    1   		fd = fopen(munge_filename(sname), "r");
 4268    1   		if (fd == NULL) {
 4269    2   			DEBUG(0, "uucico: couldn't open %s\n", sname);
 4270    2   			return SUCCESS;
 4271    2   		}
 4272    1   	
 4273    1   		while (fgets(buf, sizeof buf, fd)) {
 4274    2   			DEBUG(4, "Queued request: %s", buf);
 4275    2   			if (buf[1] != ' ') goto badnum;
 4276    2   			num = sscanf(buf, "%s %s %s %s %s %s %o\n",
 4277    2   				cmnd, srcnam, dstnam, who, flags, temp, &mode, notify);
 4278    2   	
 4279    2   			switch (cmnd[0]) {
 4280    3   			case 'S':
 4281    3   				if (num < 7 || num > 8) goto badnum;
 4282    3   				fail = local_send_file(buf);
 4283    3   				break;
 4284    3   	
 4285    3   			case 'R':
 4286    3   				if (num != 5) goto badnum;
 4287    3   				fail = local_receive_file(buf);
 4288    3   				break;
 4289    3   	
 4290    3   			default: badnum:
 4291    3   				DEBUG(0, "Unknown/invalid queued request: %s\n",
 4292    3   					 buf);
 4293    3   				goto badline;
 4294    3   			}
 4295    2   	

GNUUCP                                                          12-NOV-1988 14:08:27    VAX C      V2.3-024                 Page 28
V1.0                                                            13-OCT-1988 21:04:50    [VMSNET.DEVEL.GNUUCP.SRC]GNUUCP.C;27 (14)

 4296    2   			/* FIXME, what does uucp do if one of N xfers fails? */
 4297    2   			if (fail == FAIL) {
 4298    3   				/* protocol over the wire is failing */
 4299    3   				fclose(fd);
 4300    3   				return FAIL;
 4301    3   			}
 4302    2   			if (fail) {
 4303    3   		badline:
 4304    3   				logit("ERROR IN WORK FILE", sname);
 4305    3   				logit("BAD LINE IS", buf);
 4306    3   			}
 4307    2   		}
 4308    1   		fclose(fd);
 4309    1   	
 4310    1   		/* Zap the queue file */
 4311    1   		fail = remove(munge_filename(sname));
 4312    1   		if (fail != 0) {
 4313    2   			logit("CAN'T REMOVE WORK FILE", sname);
 4314    2   			DEBUG(0, "Can't remove, errno %d\n", errno);
 4315    2   		} else {
 4316    2   			DEBUG(4, "Removed work file %s\n", sname);
 4317    2   		}
 4318    1   		return SUCCESS;
 4319    1   	}
 4320        	

GNUUCP                                                          12-NOV-1988 14:08:27    VAX C      V2.3-024                 Page 29
V1.0                                                            13-OCT-1988 21:04:50    [VMSNET.DEVEL.GNUUCP.SRC]GNUUCP.C;27 (15)

             	
 4321        	/* Send a "yes or no" packet with character 'c'. */
 4322        	int
 4323        	yesno(c, true, err)
 4324        		char c;
 4325        		int true;
 4326        		int err;
 4327        	{
 4328    1   		char buf[20];
 4329    1   	
 4330    1   		buf[0] = true? 'Y': 'N';
 4331    1   		buf[1] = 0;
 4332    1   		if (err && !true) 
 4333    1   			sprintf(buf+1,"%d", err);
 4334    1   	
 4335    1   		return wrmsg(c, buf, fdtty);
 4336    1   	}
 4337        	

GNUUCP                                                          12-NOV-1988 14:08:27    VAX C      V2.3-024                 Page 30
V1.0                                                            13-OCT-1988 21:04:50    [VMSNET.DEVEL.GNUUCP.SRC]GNUUCP.C;27 (16)

             	
 4338        	/*
 4339        	 * Master wishes to send a file to us -- we receive it.
 4340        	 * Return 1 to abort the call, 0 to continue.
 4341        	 */
 4342        	int
 4343        	host_send_file(msg)
 4344        	char  *msg;
 4345        	{
 4346    1   		FILE *fddsk;			/* Disk file pointer */
 4347    1   		char	cmnd[1];		/* Command character */
 4348    1   	
 4349    1   		sscanf(msg,"%s %s %s %s %s %s %o",
 4350    1   			cmnd, srcnam, dstnam, who, flags, temp, &mode);
 4351    1   		logit("REQUESTED", msg);
 4352    1   		strcpy (dstnam, munge_filename(dstnam));  /* Translate to local name */
 4353    1   		strcpy (temp, temp_filename(dstnam));     /* Create a handy temp file */
 4354    1   	
 4355    1   		/* FIXME: deal with file modes now that we fopen. */
 4356    1   		fddsk = fopen(temp, FOPEN_W_MODE /*, mode|0600 */);
 4357    1   		if (fddsk == NULL) {
 4358    2   			/* Can't open file -- send error response */
 4359    2   			if (DEBUG_LEVEL(0)) {
 4360    3   			    printf(
 4361    3   				"Cannot open temp file %s (%s) for writing, errno=%d\n",
 4362    3   					temp, dstnam, errno);
 4363    3   			}
 4364    2   			logit("REQUEST", "FAILED -- TEMP FILE");
 4365    2   			if (yesno('S', 0, 4))
 4366    2   				return FAIL;
 4367    2   			return SUCCESS;
 4368    2   		}
 4369    1   	
 4370    1   		/* FIXME: Are the above permissions right?? */
 4371    1   		/* FIXME: Should we create directories for the file? */
 4372    1   		if (yesno('S',1, 0))    /* Say yes */
 4373    1   			return 1;
 4374    1   	
 4375    1   		return receive_file(fddsk, temp, dstnam, srcnam);
 4376    1   	}
 4377        	

GNUUCP                                                          12-NOV-1988 14:08:27    VAX C      V2.3-024                 Page 31
V1.0                                                            13-OCT-1988 21:04:50    [VMSNET.DEVEL.GNUUCP.SRC]GNUUCP.C;27 (17)

             	
 4378        	/*
 4379        	 * Master wants to Recieve a file from us -- we send it.
 4380        	 * Return 1 to abort the call, 0 to continue.
 4381        	 */
 4382        	host_receive_file(msg)
 4383        	char  *msg;
 4384        	{
 4385    1   		FILE *fddsk;     /* Disk file descriptor */
 4386    1   		int x;
 4387    1   		char	cmnd[1];		/* Command character */
 4388    1   	
 4389    1   		logit("REQUESTED", msg);
 4390    1   	
 4391    1   		sscanf(msg,"%s %s %s",cmnd,srcnam,dstnam);
 4392    1   		strcpy (temp, munge_filename(srcnam));
 4393    1   	
 4394    1   		fddsk = fopen(temp, FOPEN_R_MODE);	/* Try to open the file */
 4395    1   		if (fddsk == NULL) {
 4396    2   			/* File didn't open, sigh. */
 4397    2   			if (DEBUG_LEVEL(0)) {
 4398    3   			    printf("Cannot open file %s (%s) for reading, errno=%d\n",
 4399    3   					temp, srcnam, errno);
 4400    3   			}
 4401    2   			logit("DENIED", "CAN'T OPEN");
 4402    2   			if (yesno('R', 0, 2))
 4403    2   				return 1;
 4404    2   			return 0;
 4405    2   		}
 4406    1   	
 4407    1   	
 4408    1   		if (yesno('R',1, 0))    /* Say yes */
 4409    1   			return 1;
 4410    1   	
 4411    1   		x = send_file(fddsk);
 4412    1   		switch (x) {
 4413    2   		default:
 4414    2   			return x;
 4415    2   	
 4416    2   		case COPYFAIL:
 4417    2   			/* We don't care if the copy failed, since the master
 4418    2   			   asked for the file and knows the result. */
 4419    2   			return SUCCESS;
 4420    2   		}
 4421    1   	}
 4422        	

GNUUCP                                                          12-NOV-1988 14:08:27    VAX C      V2.3-024                 Page 32
V1.0                                                            13-OCT-1988 21:04:50    [VMSNET.DEVEL.GNUUCP.SRC]GNUUCP.C;27 (18)

             	
 4423        	/*
 4424        	 * We, as master, want to Send a file.
 4425        	 *
 4426        	 * Return FAIL, SUCCESS, or COPYFAIL.
 4427        	 * SUCCESS is returned either if the file was not found locally (local
 4428        	 * error, and the queued transfer should be flushed) or if it was moved
 4429        	 * successfully.  COPYFAIL indicates that the queued transfer should be
 4430        	 * left queued, and later retried.  FIXME, there are several failure points
 4431        	 * in the transaction (see Protocol.doc) and we need finer control here.
 4432        	 */
 4433        	int
 4434        	local_send_file(workstr)
 4435        		char *workstr;
 4436        	{
 4437    1   		char buf[MAXMSGLEN];	/* Used for both xmit and receive */
 4438    1   		FILE *fddsk;     /* Disk file descriptor */
 4439    1   		int res, status;	/* Result and file removal status */
 4440    1   	
 4441    1   		/* WHY are temp and srcnam switched?  FIXME!  And no notify? */
 4442    1   		sprintf(buf,"S %s %s %s %s %s 0%o %s",
 4443    1   			temp, dstnam, who, flags, srcnam, mode, who);
 4444    1   	
 4445    1   		logit("REQUEST", buf);
 4446    1   	
 4447    1   		if (strchr(flags, 'c')) {
 4448    2   			strcpy(temp, munge_filename(srcnam));
 4449    2   		} else {
 4450    2   			strcpy(temp, munge_filename(temp));
 4451    2   		}
 4452    1   		fddsk = fopen(temp, FOPEN_R_MODE);
 4453    1   		if (fddsk == NULL) {
 4454    2   			/* FIXME -- handle queued request for nonexistent file */
 4455    2   			if (DEBUG_LEVEL(0))
 4456    2   				printf("Can't open file %s (%s), errno=%d\n",
 4457    2   					temp, srcnam, errno);
 4458    2   			logit("NOT FOUND", temp);
 4459    2   			return COPYFAIL;	/* FIXME caller won't deal with this */
 4460    2   		}
 4461    1   	
 4462    1   		/* Tell the other side we want to send this file */
 4463    1   		if (wrmsg('S', buf+1, fdtty) != SUCCESS) {
 4464    2   			DEBUG(0, "problem sending request\n", 0);
 4465    2   			return FAIL;
 4466    2   		}
 4467    1   	
 4468    1   		/* See what they have to say about it */
 4469    1   		if (rdmsg(buf, fdtty) != SUCCESS)	
 4470    1   			return FAIL;
 4471    1   		if ((buf[0] != 'S') || (buf[1] != 'Y')) {
 4472    2   			logit("REQUEST DENIED", buf);
 4473    2   			return COPYFAIL;
 4474    2   		}
 4475    1   		res = send_file(fddsk);	/* FAIL, SUCCESS, or COPYFAIL */
 4476    1   	
 4477    1   		/* Delete the source file if it was just a copy */
 4478    1   		if (res != SUCCESS)

GNUUCP                                                          12-NOV-1988 14:08:27    VAX C      V2.3-024                 Page 33
V1.0                                                            13-OCT-1988 21:04:50    [VMSNET.DEVEL.GNUUCP.SRC]GNUUCP.C;27 (18)

 4479    1   			return res;
 4480    1   		if (strchr(flags, 'c'))		/* If copied direct from source */
 4481    1   			return res;		/* ...just return. */
 4482    1   		status = remove(temp);		/* Delete uucp's copy of the file */
 4483    1   		if (status != 0) {
 4484    2   			logit("CAN'T REMOVE SENT FILE", temp);
 4485    2   			DEBUG(0, "Can't remove, errno %d\n", errno);
 4486    2   		} else {
 4487    2   			DEBUG(4, "Removed sent file %s\n", temp);
 4488    2   		}
 4489    1   		return res;
 4490    1   	}
 4491        	

GNUUCP                                                          12-NOV-1988 14:08:27    VAX C      V2.3-024                 Page 34
V1.0                                                            13-OCT-1988 21:04:50    [VMSNET.DEVEL.GNUUCP.SRC]GNUUCP.C;27 (19)

             	
 4492        	/*
 4493        	 * We want to Receive a file -- so we ask for it.
 4494        	 * Return 1 to abort the call, 0 to continue.
 4495        	 */
 4496        	int
 4497        	local_receive_file()
 4498        	{
 4499    1   		char buf[MAXMSGLEN];
 4500    1   		FILE *fddsk;			/* Disk file pointer */
 4501    1   	
 4502    1   		/* FIXME, test dest file access before we ask for it. */
 4503    1   	
 4504    1   		sprintf(buf,"R %s %s %s %s %s 0%o %s",
 4505    1   			srcnam, dstnam, who, flags, temp, mode, who);
 4506    1   	
 4507    1   		strcpy (dstnam, munge_filename(dstnam));  /* Translate to local name */
 4508    1   		strcpy (temp, temp_filename(dstnam));     /* Create a handy temp file */
 4509    1   	
 4510    1   		/* FIXME: deal with file modes now that we fopen. */
 4511    1   		/* FIXME: Are the above permissions right?? */
 4512    1   		/* FIXME: Should we create directories for the file? */
 4513    1   		fddsk = fopen(temp, FOPEN_W_MODE /*, mode|060 */);
 4514    1   	
 4515    1   		if (fddsk == NULL) {
 4516    2   			/* Can't open temp file -- send error response */
 4517    2   			if (DEBUG_LEVEL(0)) {
 4518    3   			    printf(
 4519    3   				"Cannot open temp file %s (%s) for writing, errno=%d\n",
 4520    3   					temp, dstnam, errno);
 4521    3   			}
 4522    2   			logit("REQUEST", "FAILED -- TEMPFILE");
 4523    2   			return FAIL;
 4524    2   		}
 4525    1   	
 4526    1   		logit("REQUEST", buf);
 4527    1   		if (wrmsg('R', buf+1, fdtty) != SUCCESS) {
 4528    2   			printf("uucico: problem sending request\n");
 4529    2   			return FAIL;
 4530    2   		}
 4531    1   	
 4532    1   		/* See what the other side has to say about it */
 4533    1   		if (rdmsg(buf, fdtty) != SUCCESS)
 4534    1   			return FAIL;
 4535    1   		if ((buf[0] != 'R') || (buf[1] != 'Y')) {
 4536    2   			logit("REQUEST DENIED", buf);
 4537    2   			return SUCCESS;	/* FIXME, should do something more here */
 4538    2   		}
 4539    1   	
 4540    1   		return receive_file(fddsk, temp, dstnam, srcnam);
 4541    1   		/* FIXME - We should deal with files that didn't get there */
 4542    1   	}
 4543        	

GNUUCP                                                          12-NOV-1988 14:08:27    VAX C      V2.3-024                 Page 35
V1.0                                                            13-OCT-1988 21:04:50    [VMSNET.DEVEL.GNUUCP.SRC]GNUUCP.C;27 (20)

             	
 4544        	/* general file receive routine */
 4545        	int
 4546        	receive_file(fddsk, temp, dstnam, srcnam)
 4547        		FILE *fddsk;			/* Disk file pointer */
 4548        		char	*temp, *dstnam, *srcnam;
 4549        	{
 4550    1   		int status;
 4551    1   		int error = 0;			/* No errors so far */
 4552    1   	
 4553    1   		if (rddata(fdtty, fddsk) != SUCCESS) error++;
 4554    1   		status = fclose(fddsk);		/* Make sure the data got here */
 4555    1   		if (status != 0) {
 4556    2   			error++;
 4557    2   			DEBUG(0, "fclose errno=%d\n", errno);
 4558    2   		}
 4559    1   	
 4560    1   		/* Move the file from its temp location to its real loc */
 4561    1   		/* FIXME:  This needs to be able to copy the file, if 
 4562    1   		   a simple rename does not suffice. */
 4563    1   		/* FIXME:  should create directories if necessary, e.g. D.
 4564    1   		   or subdirs of /usr/spool/uucppublic. */
 4565    1   		/* FIXME:  should use source name if target is a directory e.g. ~/ */
 4566    1   	#ifdef VMS
 4567    1   		fix_x_filename(dstnam);
 4568    1   	#endif
 4569    1   		status = rename(temp, dstnam);
 4570    1   		if (status != 0) {
 4571    2   			error++;
 4572    2   			if (DEBUG_LEVEL(0)) {
 4573    3   				printf("Cannot rename file %s to %s, errno=%d\n",
 4574    3   					temp, dstnam, errno);
 4575    3   			}
 4576    2   		}
 4577    1   	
 4578    1   		logit("COPY", error? "FAILED": "SUCCEEDED");
 4579    1   		if (yesno('C', error == 0, 5))	/* Send yes or no */
 4580    1   			return FAIL;
 4581    1   		return SUCCESS;
 4582    1   	}
 4583        	

GNUUCP                                                          12-NOV-1988 14:08:27    VAX C      V2.3-024                 Page 36
V1.0                                                            13-OCT-1988 21:04:50    [VMSNET.DEVEL.GNUUCP.SRC]GNUUCP.C;27 (21)

             	
 4584        	/*
 4585        	 * general file send routine
 4586        	 * Return SUCCESS, FAIL, or COPYFAIL.
 4587        	 */
 4588        	int
 4589        	send_file(fddsk)
 4590        		FILE *fddsk;     /* Disk file pointer */
 4591        	{
 4592    1   		char ansbuf[MAXMSGLEN];
 4593    1   	
 4594    1   		if (wrdata(fddsk, fdtty) != SUCCESS)
 4595    1   			return FAIL;
 4596    1   		(void) fclose(fddsk);
 4597    1   		/* Await the "CY" or "CNddd" packet, and toss it. */
 4598    1   		while (1) {
 4599    2   			if (rdmsg(ansbuf, fdtty) != SUCCESS)	
 4600    2   				return FAIL;
 4601    2   			if (ansbuf[0] != 'C') {
 4602    3   				DEBUG(0,"\nDidn't get 'CY' or 'CN', got %s\n",
 4603    3   					ansbuf);
 4604    3   				/* and loop looking for C message */
 4605    3   			} else if (ansbuf[1] == 'Y') {
 4606    3   				logit("REQUESTED", ansbuf);
 4607    3   				return SUCCESS;
 4608    3   			} else {
 4609    3   				logit("COPY FAILED", ansbuf);
 4610    3   				return COPYFAIL;
 4611    3   			}
 4612    2   		}
 4613    1   	}
 4614        	
 4615        	

GNUUCP                                                          12-NOV-1988 14:08:27    VAX C      V2.3-024                 Page 37
V1.0                                                            13-OCT-1988 21:04:50    [VMSNET.DEVEL.GNUUCP.SRC]GNUUCP.C;27 (22)

             	
 4616        	
 4617        	char *dialv = "Dial Command, V2.0(009) 14 Sep 87";
 4618        	
 4619        	/*  C K U D I A  --  Dialing program for connection to remote system */
 4620        	
 4621        	/*
 4622        	 Author: Herm Fischer (HFISCHER@USC-ECLB)
 4623        	 Contributed to Columbia University for inclusion in C-Kermit.
 4624        	 Copyright (C) 1985, Herman Fischer, 16400 Ventura Blvd, Encino CA 91436
 4625        	 Permission is granted to any individual or institution to use, copy, or
 4626        	 redistribute this software so long as it is not sold for profit, provided this
 4627        	 copyright notice is retained. 
 4628        	
 4629        	 ------
 4630        	
 4631        	 This module should work under all versions of Unix.  It calls externally
 4632        	 defined system-depended functions for i/o, but depends upon the existence
 4633        	 of various modem control functions.
 4634        	
 4635        	 This module, and the supporting routines in the ckutio.c module, assume
 4636        	 that the computer and modem properly utilize the following data communi-
 4637        	 cations signals (that means one should prepare the modem to use, not
 4638        	 circumvent, these signals):
 4639        	
 4640        	     Data Terminal Ready:  This signal is asserted by the computer
 4641        	     when Kermit is about to ask the modem to dial a call, and is
 4642        	     removed when Kermit wishes to have the modem hang up a call.
 4643        	     The signal is asserted both while Kermit is asking the modem
 4644        	     to dial a specific number, and after connection, while Kermit
 4645        	     is in a data exchange mode.  
 4646        	
 4647        	     Carrier detect:  This signal must be asserted by the modem when
 4648        	     a carrier is detected from a remote modem on a communications
 4649        	     circuit.  It must be removed by the modem when the circuit
 4650        	     disconnects or is hung up.  (Carrier detect is ignored while
 4651        	     Kermit is asking the modem to dial the call, because there is
 4652        	     no consistant usage of this signal during the dialing phase
 4653        	     among different modem manufacturers.)
 4654        	
 4655        	*/
 4656        	
 4657        	/*
 4658        	 * Modifications:
 4659        	 *
 4660        	 *	01-Oct-88	Heavily modified for use under GNUUCP/VMS.  
 4661        	 *			We now look for CD rather than a text response from
 4662        	 *			the modem, since on many VAX terminal muxes we can't
 4663        	 *			get text from the modem until it gives us CD.  
 4664        	 *			Because of this, we can't use wake_prompt or
 4665        	 *			dmode_prompt, but must rely on simple delays. -- JEH
 4666        	 *
 4667        	 *	21-Jul-85	Fixed failure returns hanging on no carrier signal
 4668        	 *			Requires tthang change too (ckutio.c revision)
 4669        	 *							-- Herm Fischer
 4670        	 *
 4671        	 *	28-Jun-85	Fixed bug with defaulting the modem-failure message

GNUUCP                                                          12-NOV-1988 14:08:27    VAX C      V2.3-024                 Page 38
V1.0                                                            13-OCT-1988 21:04:50    [VMSNET.DEVEL.GNUUCP.SRC]GNUUCP.C;27 (22)

 4672        	 *			in lbuf.
 4673        	 *							-- Dan Schullman
 4674        	 *
 4675        	 *	27-Jun-85	Merged in code from Joe Orost at Berkeley for
 4676        	 *			supporting the US Robotics modem, which included
 4677        	 *			changing the single characters in MDMINF into
 4678        	 *			multi-character strings and modifying waitFor.
 4679        	 *							-- Dan Schullman
 4680        	 *
 4681        	 *	26-Jun-85	Allow interrupts to be used to abort dialing,
 4682        	 *			and ring the bell when a connection is made.
 4683        	 *			Reorganized some of the failure paths to use the
 4684        	 *			same code, and now close the line on failures.
 4685        	 *			Allow use of stored numbers with the DF100 and
 4686        	 *			DF200 modems.  Handlers now declared after the
 4687        	 *			call to setjmp.
 4688        	 *							-- Dan Schullman
 4689        	 *
 4690        	 *	24-May-85	DF03, DF100-series, DF200-series, and "unknown" modem
 4691        	 *			support added.  Also restructured the various data
 4692        	 *			tables, fixed some bugs related to missing data and
 4693        	 *			missing case labels, and modified the failure message
 4694        	 *			to display the "reason" given by the modem.
 4695        	 *							-- Dan Schullman
 4696        	 */
 4697        	
 4698        	/*
 4699        	 * To add support for another modem, do the following:
 4700        	 *
 4701        	 *	Define a modem number symbol (n_XXX) for it, keeping the list
 4702        	 *	in alphabetical and numerical order, and renumbering the values
 4703        	 *	as necessary.
 4704        	 *
 4705        	 *	Create a MDMINF structure for it, again keeping the list alphabetical
 4706        	 *	for sanity's sake.
 4707        	 *
 4708        	 *	Add the address of the MDMINF structure to the ptrtab array, again
 4709        	 *	in alphabetical and numerical order.
 4710        	 *
 4711        	 *	Add the "user visible" modem name and corresponding modem number to
 4712        	 *	the mdmtab array, again in alphabetical order.
 4713        	 *
 4714        	 *	Read through the code and add modem-specific sections as necessary.
 4715        	 */
 4716        	
 4717        	/*
 4718        	 * The intent of the "unknown" modem is hopefully to allow KERMIT to support
 4719        	 * unknown modems by having the user type the entire autodial sequence
 4720        	 * (possibly including control characters, etc.) as the "phone number".
 4721        	 * The only reason that the CONNECT command cannot be used to do this is
 4722        	 * that a remote line cannot normally be opened unless carrier is present.
 4723        	 *
 4724        	 * The protocol and other characteristics of this modem are unknown, with
 4725        	 * some "reasonable" values being chosen for some of them.  The only way to
 4726        	 * detect if a connection is made is to look for carrier present.
 4727        	 *
 4728        	 * SUPPORT IS CURRENTLY ONLY PARTIALLY SKETCHED OUT FOR THIS.  ALSO, IT

GNUUCP                                                          12-NOV-1988 14:08:27    VAX C      V2.3-024                 Page 39
V1.0                                                            13-OCT-1988 21:04:50    [VMSNET.DEVEL.GNUUCP.SRC]GNUUCP.C;27 (22)

 4729        	 * SHOULD PERHAPS BE HANDLED MUCH EARLIER, SIMPLY READING USER INPUT AND
 4730        	 * SENDING IT TO THE MODEM AND ECHOING MODEM RESPONSES BACK TO THE USER,
 4731        	 * ALL THE TIME LOOKING FOR CARRIER.  OF COURSE, THE PROBLEM THEN BECOMES
 4732        	 * ONE OF ALLOWING THE USER TO ABORT THE DIALING.  WE COULD CHOOSE SOME
 4733        	 * PHRASE THAT WOULD PRESUMABLY NEVER BE A PART OF A VALID AUTODIAL SEQUENCE
 4734        	 * (E.G., "QUIT" and "quit"). -- DS
 4735        	 */
 4736        	
 4737        	

GNUUCP                                                          12-NOV-1988 14:08:27    VAX C      V2.3-024                 Page 40
V1.0                                                            13-OCT-1988 21:04:50    [VMSNET.DEVEL.GNUUCP.SRC]GNUUCP.C;27 (23)

             	
 4738        	
 4739        	#define	MDMINF	struct mdminf
 4740        	
 4741        	MDMINF		/* structure for modem-specific information */
 4742        	    {
 4743        	    int		dial_time;	/* time modem allows for dialing (secs) */
 4744        	    char	*pause_chars;	/* character(s) to tell modem to pause */
 4745        	    int		pause_time;	/* time associated with pause chars (secs) */
 4746        	    char	*wake_str;	/* string to wakeup modem & put in cmd mode */
 4747        	    int		wake_rate;	/* delay between wake_str characters (msecs) */
 4748        	    char	*wake_prompt;	/* string prompt after wake_str */
 4749        	    char	*dmode_str;	/* string to put modem in dialing mode */
 4750        	    char	*dmode_prompt;	/* string prompt for dialing mode */
 4751        	    char	*dial_str;	/* dialing string, with "%s" for number */
 4752        	    int		dial_rate;	/* delay between dialing characters (msecs) */
 4753        	    };
 4754        	
 4755        	/* Keyword Table Template */
 4756        	 
 4757        	struct keytab {				/* Keyword table */
 4758        	    char *kwd;				/* Pointer to keyword string */
 4759        	    int val;				/* Associated value */
 4760        	    int flgs;				/* Flags (as defined above) */
 4761        	};
 4762        	
 4763        	/*
 4764        	 * Define symbolic modem numbers.
 4765        	 *
 4766        	 * The numbers MUST correspond to the ordering of entries
 4767        	 * within the ptrtab array, and start at one (1).
 4768        	 *
 4769        	 * It is assumed that there are relatively few of these
 4770        	 * values, and that the high(er) bytes of the value may
 4771        	 * be used for modem-specific mode information.
 4772        	 *
 4773        	 * REMEMBER that only the first eight characters of these
 4774        	 * names are guaranteed to be unique.
 4775        	 */
 4776        	
 4777        	#define		n_CERMETEK	 1
 4778        	#define		n_DF03		 2
 4779        	#define		n_DF100		 3
 4780        	#define		n_DF200		 4
 4781        	#define		n_GDC		 5
 4782        	#define		n_HAYES		 6
 4783        	#define		n_PENRIL	 7
 4784        	#define		n_RACAL		 8
 4785        	#define		n_UNKNOWN	 9
 4786        	#define		n_USROBOT	10
 4787        	#define		n_VENTEL	11
 4788        	#define         n_CONCORD       12
 4789        	
 4790        	/*
 4791        	 * Declare modem "variant" numbers for any of the above for which it is
 4792        	 * necessary to note various operational modes, using the second byte
 4793        	 * of a modem number.

GNUUCP                                                          12-NOV-1988 14:08:27    VAX C      V2.3-024                 Page 41
V1.0                                                            13-OCT-1988 21:04:50    [VMSNET.DEVEL.GNUUCP.SRC]GNUUCP.C;27 (23)

 4794        	 *
 4795        	 * It is assumed that such modem modes share the same modem-specific
 4796        	 * information (see MDMINF structure) but may differ in some of the actions
 4797        	 * that are performed.
 4798        	 */
 4799        	#define		n_HAYESNV	( n_HAYES + ( 1<<8 ) )
 4800        	

GNUUCP                                                          12-NOV-1988 14:08:27    VAX C      V2.3-024                 Page 42
V1.0                                                            13-OCT-1988 21:04:50    [VMSNET.DEVEL.GNUUCP.SRC]GNUUCP.C;27 (24)

             	
 4801        	/*
 4802        	 * Declare structures containing modem-specific information.
 4803        	 *
 4804        	 * REMEMBER that only the first SEVEN characters of these
 4805        	 * names are guaranteed to be unique.
 4806        	 */
 4807        	
 4808        	static
 4809        	MDMINF CERMETEK =	/* information for "Cermetek Info-Mate 212 A" modem */
 4810        	    {
 4811        	    20,			/* dial_time */
 4812        	    "BbPpTt",		/* pause_chars */
 4813        	    0,			/* pause_time */	/** unknown -- DS **/
 4814        	    "  XY\016R\r",	/* wake_str */
 4815        	    200,		/* wake_rate */
 4816        	    "",			/* wake_prompt */
 4817        	    "",			/* dmode_str */
 4818        	    "",			/* dmode_prompt */
 4819        	    "\016D '%s'\r",	/* dial_str */
 4820        	    200			/* dial_rate */
 4821        	    };
 4822        	
 4823        	static
 4824        	MDMINF DF03 =		/* information for "DEC DF03-AC" modem */
 4825        	    {
 4826        	    27,			/* dial_time */
 4827        	    "=",		/* pause_chars */	/* wait for second dial tone */
 4828        	    15,			/* pause_time */
 4829        	    "\001\002",		/* wake_str */
 4830        	    0,			/* wake_rate */
 4831        	    "",			/* wake_prompt */
 4832        	    "",			/* dmode_str */
 4833        	    "",			/* dmode_prompt */
 4834        	    "%s",		/* dial_str */
 4835        	    0			/* dial_rate */
 4836        	    };
 4837        	
 4838        	static
 4839        	MDMINF DF100 =		/* information for "DEC DF100-series" modem */
 4840        				/*
 4841        				 * The telephone "number" can include "P"s and/or "T"s
 4842        				 * within it to indicate that subsequent digits are
 4843        				 * to be dialed using pulse or tone dialing.  The
 4844        				 * modem defaults to pulse dialing.  You may modify
 4845        				 * the dial string below to explicitly default all
 4846        				 * dialing to pulse or tone, but doing so prevents
 4847        				 * the use of phone numbers that you may have stored
 4848        				 * in the modem's memory.
 4849        				 */
 4850        	    {
 4851        	    30,			/* dial_time */
 4852        	    "=",		/* pause_chars */	/* wait for second dial tone */
 4853        	    15,			/* pause_time */
 4854        	    "\001",		/* wake_str */
 4855        	    0,			/* wake_rate */
 4856        	    "",			/* wake_prompt */

GNUUCP                                                          12-NOV-1988 14:08:27    VAX C      V2.3-024                 Page 43
V1.0                                                            13-OCT-1988 21:04:50    [VMSNET.DEVEL.GNUUCP.SRC]GNUUCP.C;27 (24)

 4857        	    "",			/* dmode_str */
 4858        	    "",			/* dmode_prompt */
 4859        	    "%s#",		/* dial_str */
 4860        	    0			/* dial_rate */
 4861        	    };
 4862        	
 4863        	static
 4864        	MDMINF DF200 =		/* information for "DEC DF200-series" modem */
 4865        				/*
 4866        				 * The telephone "number" can include "P"s and/or "T"s
 4867        				 * within it to indicate that subsequent digits are
 4868        				 * to be dialed using pulse or tone dialing.  The
 4869        				 * modem defaults to pulse dialing.  You may modify
 4870        				 * the dial string below to explicitly default all
 4871        				 * dialing to pulse or tone, but doing so prevents
 4872        				 * the use of phone numbers that you may have stored
 4873        				 * in the modem's memory.
 4874        				 */
 4875        	    {
 4876        	    30,			/* dial_time */
 4877        	    "=W",		/* pause_chars */	/* =: second tone; W: 5 secs */
 4878        	    15,			/* pause_time */	/* worst case */
 4879        	    "\002",		/* wake_str */		/* allow stored number usage */
 4880        	    0,			/* wake_rate */
 4881        	    "",			/* wake_prompt */
 4882        	    "",			/* dmode_str */
 4883        	    "",			/* dmode_prompt */
 4884        	    "%s!",		/* dial_str */
 4885        	    0			/* dial_rate */
 4886        	    };
 4887        	
 4888        	static
 4889        	MDMINF GDC =		/* information for "GeneralDataComm 212A/ED" modem */
 4890        	    {
 4891        	    32,			/* dial_time */
 4892        	    "%",		/* pause_chars */
 4893        	    3,			/* pause_time */
 4894        	    "\r\r",		/* wake_str */
 4895        	    500,		/* wake_rate */
 4896        	    "$",		/* wake_prompt */
 4897        	    "D\r",		/* dmode_str */
 4898        	    ":",		/* dmode_prompt */
 4899        	    "T%s\r",		/* dial_str */
 4900        	    0			/* dial_rate */
 4901        	    };
 4902        	
 4903        	static
 4904        	MDMINF HAYES =		/* information for "Hayes" modem */
 4905        	    {
 4906        	    35,			/* dial_time */
 4907        	    ",",		/* pause_chars */
 4908        	    2,			/* pause_time */
 4909        	    "AT\r",		/* wake_str */
 4910        	    0,			/* wake_rate */
 4911        	    "",			/* wake_prompt */
 4912        	    "",			/* dmode_str */
 4913        	    "",			/* dmode_prompt */

GNUUCP                                                          12-NOV-1988 14:08:27    VAX C      V2.3-024                 Page 44
V1.0                                                            13-OCT-1988 21:04:50    [VMSNET.DEVEL.GNUUCP.SRC]GNUUCP.C;27 (24)

 4914        	    "ATDT%s\r",		/* dial_str */
 4915        	    0			/* dial_rate */
 4916        	    };
 4917        	
 4918        	static
 4919        	MDMINF PENRIL =		/* information for "Penril" modem */
 4920        	    {
 4921        	    50,			/* dial_time */
 4922        	    "",			/* pause_chars */	/** unknown -- HF **/
 4923        	    0,			/* pause_time */
 4924        	    "\r\r",		/* wake_str */
 4925        	    300,		/* wake_rate */
 4926        	    ">",		/* wake_prompt */
 4927        	    "k\r",		/* dmode_str */
 4928        	    ":",		/* dmode_prompt */
 4929        	    "%s\r",		/* dial_str */
 4930        	    0			/* dial_rate */
 4931        	    };
 4932        	
 4933        	static
 4934        	MDMINF RACAL =		/* information for "Racal Vadic" modem */
 4935        	    {
 4936        	    35,			/* dial_time */
 4937        	    "Kk",		/* pause_chars */
 4938        	    5,			/* pause_time */
 4939        	    "\005\r",		/* wake_str */
 4940        	    50,			/* wake_rate */
 4941        	    "*",		/* wake_prompt */
 4942        	    "D\r",		/* dmode_str */
 4943        	    "?",		/* dmode_prompt */
 4944        	    "%s\r",		/* dial_str */
 4945        	    0			/* dial_rate */
 4946        	    };
 4947        	
 4948        	static
 4949        	MDMINF UNKNOWN =	/* information for "Unknown" modem */
 4950        	    {
 4951        	    30,			/* dial_time */
 4952        	    "",			/* pause_chars */
 4953        	    0,			/* pause_time */
 4954        	    "",			/* wake_str */
 4955        	    0,			/* wake_rate */
 4956        	    "",			/* wake_prompt */
 4957        	    "",			/* dmode_str */
 4958        	    "",			/* dmode_prompt */
 4959        	    "%s\r",		/* dial_str */
 4960        	    0			/* dial_rate */
 4961        	    };
 4962        	
 4963        	static
 4964        	MDMINF USROBOT =	/* information for "US Robotics 212A" modem */
 4965        	    {
 4966        	    30,			/* dial_time */
 4967        	    ",",		/* pause_chars */
 4968        	    2,			/* pause_time */
 4969        	    "ATS2=01\r",	/* wake_str */
 4970        	    0,			/* wake_rate */

GNUUCP                                                          12-NOV-1988 14:08:27    VAX C      V2.3-024                 Page 45
V1.0                                                            13-OCT-1988 21:04:50    [VMSNET.DEVEL.GNUUCP.SRC]GNUUCP.C;27 (24)

 4971        	    "OK\r",		/* wake_prompt */
 4972        	    "",			/* dmode_str */
 4973        	    "",			/* dmode_prompt */
 4974        	    "ATTD%s\r",		/* dial_str */
 4975        	    0			/* dial_rate */
 4976        	    };
 4977        	
 4978        	static
 4979        	MDMINF VENTEL =		/* information for "Ventel" modem */
 4980        	    {
 4981        	    20,			/* dial_time */
 4982        	    "%",		/* pause_chars */
 4983        	    5,			/* pause_time */
 4984        	    "\r\r\r",		/* wake_str */
 4985        	    300,		/* wake_rate */
 4986        	    "$",		/* wake_prompt */
 4987        	    "",			/* dmode_str */
 4988        	    "",			/* dmode_prompt */
 4989        	    "<K%s\r>",		/* dial_str */
 4990        	    0			/* dial_rate */
 4991        	    };
 4992        	
 4993        	static
 4994        	MDMINF CONCORD =	/* Info for Condor CDS 220 2400b modem */
 4995        	    {
 4996        	    35,			/* dial_time */
 4997        	    ",",		/* pause_chars */
 4998        	    2,			/* pause_time */
 4999        	    "\r\r",		/* wake_str */
 5000        	    20,			/* wake_rate */
 5001        	    "CDS >",		/* wake_prompt */
 5002        	    "",			/* dmode_str */
 5003        	    "",			/* dmode_prompt */
 5004        	    "<D M%s\r>",	/* dial_str */
 5005        	    0			/* dial_rate */
 5006        	    };
 5007        	

GNUUCP                                                          12-NOV-1988 14:08:27    VAX C      V2.3-024                 Page 46
V1.0                                                            13-OCT-1988 21:04:50    [VMSNET.DEVEL.GNUUCP.SRC]GNUUCP.C;27 (25)

             	
 5008        	/*
 5009        	 * Declare table for converting modem numbers to information pointers.
 5010        	 *
 5011        	 * The entries MUST be in ascending order by modem number, without any
 5012        	 * "gaps" in the numbers, and starting from one (1).
 5013        	 *
 5014        	 * This table should NOT include entries for the "variant" modem numbers,
 5015        	 * since it is assumed that they share the same information as the normal
 5016        	 * value.
 5017        	 */
 5018        	static
 5019        	MDMINF *ptrtab[] =
 5020        	    {
 5021        	    &CERMETEK,
 5022        	    &DF03,
 5023        	    &DF100,
 5024        	    &DF200,
 5025        	    &GDC,
 5026        	    &HAYES,
 5027        	    &PENRIL,
 5028        	    &RACAL,
 5029        	    &UNKNOWN,
 5030        	    &USROBOT,
 5031        	    &VENTEL,
 5032        	    &CONCORD
 5033        	    };
 5034        	
 5035        	/*
 5036        	 * Declare modem names and associated numbers for command parsing,
 5037        	 * and also for doing number-to-name translation.
 5038        	 *
 5039        	 * The entries MUST be in alphabetical order by modem name.
 5040        	 */
 5041        	struct keytab mdmtab[] =
 5042        	    {
 5043        	    "cermetek",		n_CERMETEK,	0,
 5044        	    "concord",          n_CONCORD,      0,
 5045        	    "df03-ac",		n_DF03,		0,
 5046        	    "df100-series",	n_DF100,	0,
 5047        	    "df200-series",	n_DF200,	0,
 5048        	    "direct",		0,		0,
 5049        	    "gendatacomm",	n_GDC,		0,
 5050        	    "hayes",		n_HAYES,	0,
 5051        	    "penril",		n_PENRIL,	0,
 5052        	    "racalvadic",	n_RACAL,	0,
 5053        	    "unknown",		n_UNKNOWN,	0,
 5054        	    "usrobotics-212a",	n_USROBOT,	0,
 5055        	    "ventel",		n_VENTEL,	0
 5056        	    };
 5057        	
 5058        	int nmdm = (sizeof(mdmtab) / sizeof(struct keytab));	/* number of modems */
 5059        	

GNUUCP                                                          12-NOV-1988 14:08:27    VAX C      V2.3-024                 Page 47
V1.0                                                            13-OCT-1988 21:04:50    [VMSNET.DEVEL.GNUUCP.SRC]GNUUCP.C;27 (26)

             	
 5060        	
 5061        	#define LBUFL 100
 5062        	static char lbuf[LBUFL];
 5063        	
 5064        	/*  T D I A L  --  Dial up the remote system */
 5065        	
 5066        	int
 5067        	tdial(telnbr, modemname) 
 5068        	char *telnbr, *modemname;
 5069        	
 5070        	{
 5071    1   	    int mdmtyp;
 5072    1   	    int junk;
 5073    1   	    int tries;
 5074    1   	    char c;
 5075    1   	    char *i, *j;
 5076    1   	    int waitct, status;
 5077    1   	    char errmsg[50], *erp;
 5078    1   	    MDMINF *pmdminf;	/* pointer to modem-specific info */
 5079    1   	    int mdmEcho = 0;	/* assume modem does not echo */
 5080    1   	    int n, n1;
 5081    1   	    char *pc;		/* pointer to a character */
 5082    1   	
 5083    1   		if ((mdmtyp=lookup(mdmtab, modemname, nmdm, &junk)) < 0) {
 5084    2   			if (DEBUG_LEVEL(1))
 5085    2   				printf("bad modem type <%s>\n", modemname);
 5086    2   			return FAIL;
 5087    2   		}
 5088    1   	
 5089    1   		pmdminf = ptrtab[mdmtyp-1];	/* set pointer to modem info */ 
 5090    1   	
 5091    1   		waitct = 1*strlen(telnbr) ;	/* compute time to dial worst case */
 5092    1   		waitct += pmdminf->dial_time;	/* dialtone + completion wait times */
 5093    1   		for (i=telnbr; *i; i++) 	/* add in pause characters time */
 5094    1   		    for (j=pmdminf->pause_chars; *j; j++)
 5095    1   			if (*i == *j) {
 5096    2   			    waitct += pmdminf->pause_time; 
 5097    2   			    break;
 5098    2   			    }
 5099    1   	
 5100    1   		if (DEBUG_LEVEL(2))
 5101    1   			printf("Dialing number %s.\n",telnbr);
 5102    1   		if (DEBUG_LEVEL(2))
 5103    1   			printf("The timeout for completing the call is %d seconds.\n",waitct);
 5104    1   	
 5105    1   	/* Hang up the modem (in case it wasn't "on hook") */
 5106    1   	
 5107    1   		tthang();
 5108    1   		ttflui();			/* flush input buffer if any */
 5109    1   	
 5110    1   	

GNUUCP                                                          12-NOV-1988 14:08:27    VAX C      V2.3-024                 Page 48
V1.0                                                            13-OCT-1988 21:04:50    [VMSNET.DEVEL.GNUUCP.SRC]GNUUCP.C;27 (27)

             	
 5111    1   	/*
 5112    1   	 * Put modem in command mode.
 5113    1   	 */
 5114    1   	
 5115    1   		switch (mdmtyp) {
 5116    2   	    		case n_HAYES:
 5117    2   			case n_HAYESNV:
 5118    2   				tries = 0;
 5119    2   				while(tries++ < 4) {
 5120    3   				    twrite( HAYES.wake_str, strlen(HAYES.wake_str) );	/* wakeup */
 5121    3   				    ttflui();
 5122    3   				    sleep(1);		/* wait before retrying */
 5123    3   				    }
 5124    2   				break;
 5125    2   	
 5126    2   			default:			/* place modem into command mode */
 5127    2   				ttolSlow(pmdminf->wake_str, pmdminf->wake_rate);
 5128    2   				ttflui();
 5129    2   				sleep(1);		/* wait before proceeding */
 5130    2   				break;
 5131    2   			}
 5132    1   			
 5133    1   	

GNUUCP                                                          12-NOV-1988 14:08:27    VAX C      V2.3-024                 Page 49
V1.0                                                            13-OCT-1988 21:04:50    [VMSNET.DEVEL.GNUUCP.SRC]GNUUCP.C;27 (28)

             	
 5134    1   	/* Dial the number */
 5135    1   	
 5136    1   					/* put modem into dialing mode */
 5137    1   		ttolSlow(pmdminf->dmode_str, pmdminf->dial_rate);	
 5138    1   	
 5139    1   		sprintf(lbuf, pmdminf->dial_str, telnbr); /* form dialing string */
 5140    1   		ttolSlow(lbuf,pmdminf->dial_rate);	/* send dialing string */
 5141    1   	
 5142    1   		if (mdmtyp == n_RACAL) {	/* acknowledge printout of dialing string */
 5143    2   			sleep(3);
 5144    2   			ttflui();
 5145    2   			twrite("\r", 1);
 5146    2   			}
 5147    1   	
 5148    1   	/* Check for connection */
 5149    1   	
 5150    1   		tries = 0;
 5151    1   		while(tries++ < waitct) {
 5152    2   			sleep(1);
 5153    2   			if (DEBUG_LEVEL(2))
 5154    2   				printf("Checking for carrier\n");
 5155    2   			if (ttcd()) {
 5156    3   				if (DEBUG_LEVEL(2))
 5157    3   					printf("Carrier received!\n");
 5158    3   				return(SUCCESS);
 5159    3   			}
 5160    2   		}
 5161    1   		ttflui();
 5162    1   		if (DEBUG_LEVEL(1))
 5163    1   			printf("Waited long enough, aborting call\n");
 5164    1   		return(FAIL);
 5165    1   	}
 5166        	
 5167        	

GNUUCP                                                          12-NOV-1988 14:08:27    VAX C      V2.3-024                 Page 50
V1.0                                                            13-OCT-1988 21:04:50    [VMSNET.DEVEL.GNUUCP.SRC]GNUUCP.C;27 (29)

             	
 5168        	/*	The following routines are borrowed from C-Kermit to support 
 5169        		tdial().  There are some others in sysdep.c .  These are here
 5170        		rather than in sysdep so that other main progs that use sysdep
 5171        		won't be told that twrite is undefined.  --- JEH
 5172        	*/
 5173        	
 5174        	void
 5175        	ttolSlow(s,millisec) char *s; int millisec; {  /* output s-l-o-w-l-y */
 5176    1   	    for (; *s; s++) {
 5177    2   		twrite(s,1);
 5178    2   		msleep(millisec);
 5179    2   		}
 5180    1   	    }
 5181        	
 5182        	/*  M S L E E P  --  Millisecond version of sleep().  */
 5183        	
 5184        	/*
 5185        	 Handles intervals up to about 7 minutes (2**32 / 10**7 seconds)
 5186        	*/
 5187        	
 5188        	void
 5189        	msleep(m) int m; {
 5190    1   	
 5191    1   	    struct time_struct {
 5192    1   		long int hi, lo;
 5193    1   		} t;
 5194    1   	    if (m <= 0) return;
 5195    1   	    t.hi = -10000 * m;  /*  Time in 100-nanosecond units  */
 5196    1   	    t.lo = -1;
 5197    1   	    SYS$SCHDWK(0, 0, &t, 0);
 5198    1   	    SYS$HIBER();
 5199    1   	    return;
 5200    1   	}
 5201        	

GNUUCP                                                          12-NOV-1988 14:08:27    VAX C      V2.3-024                 Page 51
V1.0                                                            13-OCT-1988 21:04:50    [VMSNET.DEVEL.GNUUCP.SRC]GNUUCP.C;27 (30)

             	
 5202        	 
 5203        	/*  L O O K U P  --  Lookup the string in the given array of strings  */
 5204        	
 5205        	/*	Borrowed from C-Kermit to look up the modem type in the modem 
 5206        	 	table.  At present called only from gnuucp(), and only for dialer
 5207        		support, so it's here in the sysdep source file.  Might be useful
 5208        		elsewhere someday, in which case it should be moved.  --- JEH
 5209        	*/
 5210        	 
 5211        	/*
 5212        	 Call this way:  v = lookup(table,word,n,&x);
 5213        	 
 5214        	   table - a 'struct keytab' table.
 5215        	   word  - the target string to look up in the table.
 5216        	   n     - the number of elements in the table.
 5217        	   x     - address of an integer for returning the table array index.
 5218        	 
 5219        	 The keyword table must be arranged in ascending alphabetical order, and
 5220        	 all letters must be lowercase.
 5221        	 
 5222        	 Returns the keyword's associated value ( zero or greater ) if found,
 5223        	 with the variable x set to the array index, or:
 5224        	 
 5225        	  -3 if nothing to look up (target was null),
 5226        	  -2 if ambiguous,
 5227        	  -1 if not found.
 5228        	 
 5229        	 A match is successful if the target matches a keyword exactly, or if
 5230        	 the target is a prefix of exactly one keyword.  It is ambiguous if the
 5231        	 target matches two or more keywords from the table.
 5232        	*/
 5233        	 
 5234        	lookup(table,cmd,n,x) char *cmd; struct keytab table[]; int n, *x; {
 5235    1   	 
 5236    1   	    int i, v, cmdlen;
 5237    1   	 
 5238    1   	/* Lowercase & get length of target, if it's null return code -3. */
 5239    1   	 
 5240    1   	    if ((((cmdlen = tolower(cmd))) == 0) || (n < 1)) return(-3);
 5241    1   	 
 5242    1   	/* Not null, look it up */
 5243    1   	 
 5244    1   	    for (i = 0; i < n-1; i++) {
 5245    2   	        if (!strcmp(table[i].kwd,cmd) ||
 5246    2   	           ((v = !strncmp(table[i].kwd,cmd,cmdlen)) &&
 5247    2   	             strncmp(table[i+1].kwd,cmd,cmdlen))) {
 5248    3   	                *x = i;
 5249    3   	                return(table[i].val);
 5250    3   	             }
 5251    2   	        if (v) return(-2);
 5252    2   	    }   
 5253    1   	 
 5254    1   	/* Last (or only) element */
 5255    1   	 
 5256    1   	    if (!strncmp(table[n-1].kwd,cmd,cmdlen)) {
 5257    2   	        *x = n-1;

GNUUCP                                                          12-NOV-1988 14:08:27    VAX C      V2.3-024                 Page 52
V1.0                                                            13-OCT-1988 21:04:50    [VMSNET.DEVEL.GNUUCP.SRC]GNUUCP.C;27 (30)

 5258    2   	        return(table[n-1].val);
 5259    2   	    } else return(-1);
 5260    1   	}
 5261        	


GNUUCP                                                          12-NOV-1988 14:08:27    VAX C      V2.3-024                 Page 53
V1.0                                                            13-OCT-1988 21:04:50    [VMSNET.DEVEL.GNUUCP.SRC]GNUUCP.C;27 (30)

                                       +-------------+
                                       | Storage Map |
                                       +-------------+
 
 

External Declarations
---------------------

 Identifier Name                 Line    Size            Class        Type
 ---------------                 ----    ----            -----        ----

atoi                             2413                    Extern       Function returning long int
CABS_T                           1576    16 bytes                     Structure tag
 x                               1576    1 quadword                    Member (offset = 0), double
 y                               1576    1 quadword                    Member (offset = 8 bytes), double
CERMETEK                         4809    40 bytes        Static       Initialized struct mdminf
clock_t                          2608    1 longword                   Typedef:  long int
CONCORD                          4994    40 bytes        Static       Initialized struct mdminf
Control                          3103    1 longword      Extern       Pointer to char
curproto                         3279    1 longword      Extern def.  Initialized pointer to struct proto
curtemp                          3234    1 longword      Extern def.  Initialized long int
debug                            3068    1 longword      Extern       Long int
dev_t                            2348    1 longword                   Typedef:  pointer to char
DF03                             4824    40 bytes        Static       Initialized struct mdminf
DF100                            4839    40 bytes        Static       Initialized struct mdminf
DF200                            4864    40 bytes        Static       Initialized struct mdminf
dial_nbr                         3712                    Extern def.  Function returning long int
dstnam                           3224    255 bytes       Extern def.  Array [255] of char
errno                            3220    1 longword      Extern       Long int
exit                             2439                    Extern       Void function
fclose                           2552                    Extern       Function returning long int
fdtty                            3228    1 longword      Extern def.  Long int
fgets                            2557                    Extern       Function returning pointer to char
FILE                             2505    1 longword                   Typedef:  pointer to struct _iobuf
fix_x_filename                   3198                    Extern       Void function
flags                            3225    40 bytes        Extern def.  Array [40] of char
fopen                            2546                    Extern       Function returning pointer to pointer to struct _iobuf
fputc                            2579                    Extern       Function returning long int
freopen                          2550                    Extern       Function returning pointer to pointer to struct _iobuf
f_wait                           3232    1 longword      Extern def.  Initialized long int
GDC                              4889    40 bytes        Static       Initialized struct mdminf
getstring                        3294                    Extern def.  Function returning long int
grddata                          3266                    Extern       Function returning long int
grdmsg                           3266                    Extern       Function returning long int
gturnoff                         3266                    Extern       Function returning long int
gturnon                          3266                    Extern       Function returning long int
gwrdata                          3266                    Extern       Function returning long int
gwrmsg                           3266                    Extern       Function returning long int
HAYES                            4904    40 bytes        Static       Initialized struct mdminf
host_name                        3105    20 bytes        Extern       Array [20] of char
ignore_time_restrictions         3229    1 longword      Extern def.  Initialized long int
ino_t                            2347    1 word                       Typedef:  unsigned short int
instr                            3337                    Extern def.  Function returning long int
jmp_buf                          1826    15 longwords                 Typedef:  array [15] of long int
keytab                           4757    12 bytes                     Structure tag
 kwd                             4758    1 longword                    Member (offset = 0), pointer to char

GNUUCP                                                          12-NOV-1988 14:08:27    VAX C      V2.3-024                 Page 54
V1.0                                                            13-OCT-1988 21:04:50    [VMSNET.DEVEL.GNUUCP.SRC]GNUUCP.C;27 (30)

 Identifier Name                 Line    Size            Class        Type
 ---------------                 ----    ----            -----        ----

 val                             4759    1 longword                    Member (offset = 4 bytes), long int
 flgs                            4760    1 longword                    Member (offset = 8 bytes), long int
lbuf                             5062    100 bytes       Static       Array [100] of char
lookup                           3205                    Extern       Function returning long int
loop                             3233    1 longword      Extern def.  Initialized long int
mdminf                           4741    40 bytes                     Structure tag
 dial_time                       4743    1 longword                    Member (offset = 0), long int
 pause_chars                     4744    1 longword                    Member (offset = 4 bytes), pointer to char
 pause_time                      4745    1 longword                    Member (offset = 8 bytes), long int
 wake_str                        4746    1 longword                    Member (offset = 12 bytes), pointer to char
 wake_rate                       4747    1 longword                    Member (offset = 16 bytes), long int
 wake_prompt                     4748    1 longword                    Member (offset = 20 bytes), pointer to char
 dmode_str                       4749    1 longword                    Member (offset = 24 bytes), pointer to char
 dmode_prompt                    4750    1 longword                    Member (offset = 28 bytes), pointer to char
 dial_str                        4751    1 longword                    Member (offset = 32 bytes), pointer to char
 dial_rate                       4752    1 longword                    Member (offset = 36 bytes), long int
mdmtab                           5041    156 bytes       Extern def.  Initialized array [13] of struct keytab
mode                             3230    1 longword      Extern def.  Long int
msgi0                            3247    6 bytes         Extern def.  Initialized array [6] of char
msgi1                            3248    7 bytes         Extern def.  Initialized array [7] of char
msgi3                            3250    5 bytes         Extern def.  Initialized array [5] of char
msgi4                            3251    7 bytes         Extern def.  Initialized array [7] of char
msgo0                            3239    8 bytes         Extern def.  Initialized array [8] of char
msgo1                            3240    10 bytes        Extern def.  Initialized array [10] of char
msgo2                            3241    8 bytes         Extern def.  Initialized array [8] of char
msgo3                            3242    6 bytes         Extern def.  Initialized array [6] of char
msgo3a                           3243    5 bytes         Extern def.  Initialized array [5] of char
msgo4                            3244    10 bytes        Extern def.  Initialized array [10] of char
msleep                           3207                    Extern       Void function
munge_filename                   3137                    Extern       Function returning pointer to char
Myname                           3104    20 bytes        Extern       Array [20] of char
nmdm                             5058    1 longword      Extern def.  Initialized long int
off_t                            2346    1 longword                   Typedef:  unsigned long int
openline                         3151                    Extern       Function returning long int
openout                          3152                    Extern       Function returning long int
PENRIL                           4919    40 bytes        Static       Initialized struct mdminf
pickport                         3678                    Extern def.  Function returning pointer to struct port
port                             3092    68 bytes                     Structure tag
 portname                        3093    20 bytes                      Member (offset = 0), array [20] of char
 modemname                       3094    20 bytes                      Member (offset = 20 bytes), array [20] of char
 devname                         3095    20 bytes                      Member (offset = 40 bytes), array [20] of char
 baud                            3096    1 longword                    Member (offset = 60 bytes), long int
 chain                           3097    1 longword                    Member (offset = 64 bytes), pointer to struct port
ports                            3110    1 longword      Extern       Pointer to struct port
printf                           2576                    Extern       Function returning long int
proto                            3256    25 bytes                     Structure tag
 p_id                            3257    1 byte                        Member (offset = 0), char
 p_turnon                        3258    1 longword                    Member (offset = 1 byte), pointer to function returning 
                                                                         long int
 p_rdmsg                         3259    1 longword                    Member (offset = 5 bytes), pointer to function returning 
                                                                         long int
 p_wrmsg                         3260    1 longword                    Member (offset = 9 bytes), pointer to function returning 
                                                                         long int
 p_rddata                        3261    1 longword                    Member (offset = 13 bytes), pointer to function returning 

GNUUCP                                                          12-NOV-1988 14:08:27    VAX C      V2.3-024                 Page 55
V1.0                                                            13-OCT-1988 21:04:50    [VMSNET.DEVEL.GNUUCP.SRC]GNUUCP.C;27 (30)

 Identifier Name                 Line    Size            Class        Type
 ---------------                 ----    ----            -----        ----

                                                                         long int
 p_wrdata                        3262    1 longword                    Member (offset = 17 bytes), pointer to function returning 
                                                                         long int
 p_turnoff                       3263    1 longword                    Member (offset = 21 bytes), pointer to function returning 
                                                                         long int
ptbl                             3272    25 bytes        Extern def.  Initialized array [1] of struct proto
ptrtab                           5019    12 longwords    Static       Initialized array [12] of pointer to struct mdminf
RACAL                            4934    40 bytes        Static       Initialized struct mdminf
sendexpect                       3571                    Extern def.  Function returning long int
setbuf                           2594                    Extern       Void function
sigstack                         1892    8 bytes                      Structure tag
 ss_sp                           1894    1 longword                    Member (offset = 0), pointer to char
 ss_onstack                      1895    1 longword                    Member (offset = 4 bytes), long int
sigvec                           1876    12 bytes                     Structure tag
 sv_handler                      1878    1 longword                    Member (offset = 0), pointer to function returning long int
 sv_mask                         1879    1 longword                    Member (offset = 4 bytes), long int
 sv_onstack                      1880    1 longword                    Member (offset = 8 bytes), long int
sleep                            1919                    Extern       Function returning long int
Spool                            3102    1 longword      Extern       Pointer to char
sprintf                          2577                    Extern       Function returning long int
srcnam                           3223    255 bytes       Extern def.  Array [255] of char
sscanf                           2571                    Extern       Function returning long int
stdout                           2506    1 longword      Extern       Noshare pointer to pointer to struct _iobuf
strchr                           2916                    Extern       Function returning pointer to char
strcmp                           2912                    Extern       Function returning long int
strcpy                           2904                    Extern       Function returning pointer to char
strlen                           2932                    Extern       Function returning long int
strncmp                          2914                    Extern       Function returning long int
strtok                           2928                    Extern       Function returning pointer to char
Sysfile                          3107    1 longword      Extern       Pointer to char
tbuffer                          2619    16 bytes                     Structure tag
 proc_user_time                  2621    1 longword                    Member (offset = 0), long int
 proc_system_time                2621    1 longword                    Member (offset = 4 bytes), long int
 child_user_time                 2622    1 longword                    Member (offset = 8 bytes), long int
 child_system_time               2622    1 longword                    Member (offset = 12 bytes), long int
tbuffer_t                        2625    16 bytes                     Typedef:  struct tbuffer
tdial                            3204                    Extern       Function returning long int
temp                             3226    255 bytes       Extern def.  Array [255] of char
temp_filename                    3129                    Extern       Function returning pointer to char
timeb                            2641    10 bytes                     Structure tag
 time                            2643    1 longword                    Member (offset = 0), long int
 millitm                         2644    1 word                        Member (offset = 4 bytes), unsigned short int
 timezone                        2645    1 word                        Member (offset = 6 bytes), short int
 dstflag                         2646    1 word                        Member (offset = 8 bytes), short int
timeb_t                          2649    10 bytes                     Typedef:  struct timeb
time_and_pid                     3216                    Extern       Function returning pointer to char
time_t                           2614    1 longword                   Typedef:  long int
tm                               2653    36 bytes                     Structure tag
 tm_sec                          2655    1 longword                    Member (offset = 0), long int
 tm_min                          2655    1 longword                    Member (offset = 4 bytes), long int
 tm_hour                         2655    1 longword                    Member (offset = 8 bytes), long int
 tm_mday                         2656    1 longword                    Member (offset = 12 bytes), long int
 tm_mon                          2656    1 longword                    Member (offset = 16 bytes), long int
 tm_year                         2656    1 longword                    Member (offset = 20 bytes), long int

GNUUCP                                                          12-NOV-1988 14:08:27    VAX C      V2.3-024                 Page 56
V1.0                                                            13-OCT-1988 21:04:50    [VMSNET.DEVEL.GNUUCP.SRC]GNUUCP.C;27 (30)

 Identifier Name                 Line    Size            Class        Type
 ---------------                 ----    ----            -----        ----

 tm_wday                         2657    1 longword                    Member (offset = 24 bytes), long int
 tm_yday                         2657    1 longword                    Member (offset = 28 bytes), long int
 tm_isdst                        2657    1 longword                    Member (offset = 32 bytes), long int
tm_t                             2660    36 bytes                     Typedef:  struct tm
ttcd                             3206                    Extern       Function returning long int
ttflui                           3209                    Extern       Void function
tthang                           3210                    Extern       Void function
ttolSlow                         3208                    Extern       Void function
ttynam                           3222    255 bytes       Extern def.  Array [255] of char
twrite                           3391                    Extern def.  Function returning long int
UNKNOWN                          4949    40 bytes        Static       Initialized struct mdminf
USROBOT                          4964    40 bytes        Static       Initialized struct mdminf
VENTEL                           4979    40 bytes        Static       Initialized struct mdminf
version                          14      21 bytes        Extern def.  Initialized array [21] of char
who                              3111    255 bytes       Extern       Array [255] of char
work_next                        3182                    Extern       Function returning pointer to char
work_scan                        3181                    Extern       Function returning long int
xgetc                            3149                    Extern       Function returning long int
xwrite                           3148                    Extern       Function returning long int
yesno                            4323                    Extern def.  Function returning long int
_ctype_                          239     byte            Extern       Const array of char
_iobuf                           2485    14 bytes                     Structure tag
 _cnt                            2487    1 longword                    Member (offset = 0), long int
 _ptr                            2488    1 longword                    Member (offset = 4 bytes), pointer to char
 _base                           2489    1 longword                    Member (offset = 8 bytes), pointer to char
 _flag                           2490    1 byte                        Member (offset = 12 bytes), char
 _file                           2501    1 byte                        Member (offset = 13 bytes), char
 
 

Function "getstring" defined at line 3294
-----------------------------------------

 Identifier Name                 Line    Size            Class        Type
 ---------------                 ----    ----            -----        ----

count                            3297    1 longword      Register     Initialized long int
data                             3297    1 longword      Register     Long int
where                            3295    1 longword      Register     Parameter # 1, pointer to char
 
 

Function "instr" defined at line 3337
-------------------------------------

 Identifier Name                 Line    Size            Class        Type
 ---------------                 ----    ----            -----        ----

data                             3341    1 longword      Register     Long int
i                                3343    1 longword      Register     Long int
n                                3339    1 longword      Register     Parameter # 2, long int
pattern                          3342    1 longword      Register     Pointer to char
s                                3338    1 longword      Register     Parameter # 1, pointer to char
tryfirst                         3361                                 Label

GNUUCP                                                          12-NOV-1988 14:08:27    VAX C      V2.3-024                 Page 57
V1.0                                                            13-OCT-1988 21:04:50    [VMSNET.DEVEL.GNUUCP.SRC]GNUUCP.C;27 (30)

 Identifier Name                 Line    Size            Class        Type
 ---------------                 ----    ----            -----        ----

 
 

Function "twrite" defined at line 3391
--------------------------------------

 Identifier Name                 Line    Size            Class        Type
 ---------------                 ----    ----            -----        ----

i                                3395    1 longword      Register     Long int
n                                3393    1 longword                   Parameter # 2, long int
s                                3392    1 longword                   Parameter # 1, pointer to char
 
 

Function "main" defined at line 3420
------------------------------------

 Identifier Name                 Line    Size            Class        Type
 ---------------                 ----    ----            -----        ----

argc                             3421    1 longword                   Parameter # 1, long int
argv                             3422    1 longword                   Parameter # 2, pointer to pointer to char
call_system                      3528                    Extern       Function returning long int
chdir                            3501                    Extern       Function returning long int
dbglog                           3426    1 longword      Auto         Initialized long int
do_session                       3540                    Extern       Function returning long int
end                              3547                                 Label
hangup                           3542                    Extern       Function returning long int
i                                3425    1 longword      Register     Long int
logit                            3524                    Extern       Function returning long int
ontheline                        3424    1 longword      Register     Initialized long int
perror                           3502                    Extern       Function returning long int
poll_sys                         3427    1 longword      Auto         Initialized pointer to char
read_params                      3499                    Extern       Function returning long int
 
 

Function "debuggit" defined at line 3558
----------------------------------------

 Identifier Name                 Line    Size            Class        Type
 ---------------                 ----    ----            -----        ----

No names declared
 
 

GNUUCP                                                          12-NOV-1988 14:08:27    VAX C      V2.3-024                 Page 58
V1.0                                                            13-OCT-1988 21:04:50    [VMSNET.DEVEL.GNUUCP.SRC]GNUUCP.C;27 (30)


Function "sendexpect" defined at line 3571
------------------------------------------

 Identifier Name                 Line    Size            Class        Type
 ---------------                 ----    ----            -----        ----

dancer                           3575    1 longword      Register     Pointer to char
dasher                           3575    1 longword      Register     Pointer to char
expect                           3572    1 longword      Register     Parameter # 1, pointer to char
send                             3573    1 longword                   Parameter # 2, pointer to char
sendit                           3593                                 Label
xlat_str                         3585                    Extern       Function returning long int
 
 

Function "xlat_str" defined at line 3603
----------------------------------------

 Identifier Name                 Line    Size            Class        Type
 ---------------                 ----    ----            -----        ----

cr                               3608    1 longword      Register     Initialized long int
i                                3606    1 longword      Register     Initialized long int
j                                3607    1 longword      Register     Initialized long int
msg                              3604    1 longword      Register     Parameter # 1, pointer to char
out                              3609    210 bytes       Auto         Array [210] of char
 
 

Function "pickport" defined at line 3678
----------------------------------------

 Identifier Name                 Line    Size            Class        Type
 ---------------                 ----    ----            -----        ----

acu                              3679    1 longword                   Parameter # 1, pointer to char
baud                             3680    1 longword                   Parameter # 2, long int
p                                3681    1 longword      Register     Parameter # 3, pointer to struct port
 
 

Function "dial_nbr" defined at line 3712
----------------------------------------

 Identifier Name                 Line    Size            Class        Type
 ---------------                 ----    ----            -----        ----

dial                             3716    30 bytes        Auto         Array [30] of char
i                                3718    1 longword      Register     Long int
nbr                              3714    1 longword                   Parameter # 2, pointer to char
port                             3713    1 longword                   Parameter # 1, pointer to struct port
 
 

GNUUCP                                                          12-NOV-1988 14:08:27    VAX C      V2.3-024                 Page 59
V1.0                                                            13-OCT-1988 21:04:50    [VMSNET.DEVEL.GNUUCP.SRC]GNUUCP.C;27 (30)


Function "call_system" defined at line 3784
-------------------------------------------

 Identifier Name                 Line    Size            Class        Type
 ---------------                 ----    ----            -----        ----

buf                              3788    500 bytes       Auto         Array [500] of char
called                           3791    1 longword      Register     Initialized long int
call_sysline                     3848                    Extern       Function returning long int
lsys                             3787    1 longword      Register     Pointer to pointer to struct _iobuf
prev_name                        3790    20 bytes        Auto         Array [20] of char
sys                              3785    1 longword                   Parameter # 1, pointer to char
sysnam                           3789    20 bytes        Auto         Array [20] of char
 
 

Function "call_sysline" defined at line 3863
--------------------------------------------

 Identifier Name                 Line    Size            Class        Type
 ---------------                 ----    ----            -----        ----

acu                              3869    1 longword      Register     Pointer to char
arm_uuxqt                        4008                    Extern       Function returning long int
baud                             3877    1 longword      Register     Long int
bort1                            4017                                 Label
expect                           3873    1 longword      Register     Pointer to char
get_lock_nowait                  3915                    Extern       Function returning long int
hangup                           4014                    Extern       Function returning long int
logbuf                           3875    60 bytes        Auto         Array [60] of char
logit                            3894                    Extern       Function returning long int
lsysline                         3864    1 longword                   Parameter # 1, pointer to char
msgbuf                           3876    210 bytes       Auto         Array [210] of char
port                             3874    1 longword      Register     Pointer to struct port
release_lock                     3936                    Extern       Function returning long int
sbaud                            3870    1 longword      Not Alloc.   Pointer to char
send                             3872    1 longword      Not Alloc.   Pointer to char
sysnam                           3867    1 longword      Register     Pointer to char
telno                            3871    1 longword      Register     Pointer to char
tempname                         3866    60 bytes        Auto         Array [60] of char
times                            3868    1 longword      Not Alloc.   Pointer to char
top_level                        4010                    Extern       Function returning long int
 
 

Function "do_session" defined at line 4026
------------------------------------------

 Identifier Name                 Line    Size            Class        Type
 ---------------                 ----    ----            -----        ----

arm_uuxqt                        4077                    Extern       Function returning long int
bort                             4081                                 Label
get_lock_nowait                  4060                    Extern       Function returning long int
logit                            4057                    Extern       Function returning long int
ontheline                        4027    1 longword                   Parameter # 1, long int

GNUUCP                                                          12-NOV-1988 14:08:27    VAX C      V2.3-024                 Page 60
V1.0                                                            13-OCT-1988 21:04:50    [VMSNET.DEVEL.GNUUCP.SRC]GNUUCP.C;27 (30)

 Identifier Name                 Line    Size            Class        Type
 ---------------                 ----    ----            -----        ----

release_lock                     4083                    Extern       Function returning long int
top_level                        4079                    Extern       Function returning long int
trash                            4029    210 bytes       Auto         Array [210] of char
 
 

Function "top_level" defined at line 4115
-----------------------------------------

 Identifier Name                 Line    Size            Class        Type
 ---------------                 ----    ----            -----        ----

buf                              4118    1030 bytes      Auto         Array [1030] of char
do_one_master                    4154                    Extern       Function returning long int
do_one_slave                     4130                    Extern       Function returning long int
logit                            4187                    Extern       Function returning long int
master                           4151                                 Label
master_mode                      4116    1 longword                   Parameter # 1, long int
quit                             4177                                 Label
slave                            4127                                 Label
 
 

Function "do_one_slave" defined at line 4198
--------------------------------------------

 Identifier Name                 Line    Size            Class        Type
 ---------------                 ----    ----            -----        ----

host_receive_file                4217                    Extern       Function returning long int
host_send_file                   4213                    Extern       Function returning long int
msg                              4200    1030 bytes      Auto         Array [1030] of char
yesno                            4235                    Extern       Function returning long int
 
 

Function "do_one_master" defined at line 4246
---------------------------------------------

 Identifier Name                 Line    Size            Class        Type
 ---------------                 ----    ----            -----        ----

badline                          4303                                 Label
badnum                           4290                                 Label
buf                              4251    100 bytes       Auto         Array [100] of char
cmnd                             4250    1 byte          Auto         Array [1] of char
delete                           4311                    Extern       Function returning long int
fail                             4252    1 longword      Register     Long int
fd                               4248    1 longword      Register     Pointer to pointer to struct _iobuf
local_receive_file               4287                    Extern       Function returning long int
local_send_file                  4282                    Extern       Function returning long int
logit                            4304                    Extern       Function returning long int
notify                           4254    255 bytes       Auto         Array [255] of char
num                              4253    1 longword      Not Alloc.   Long int

GNUUCP                                                          12-NOV-1988 14:08:27    VAX C      V2.3-024                 Page 61
V1.0                                                            13-OCT-1988 21:04:50    [VMSNET.DEVEL.GNUUCP.SRC]GNUUCP.C;27 (30)

 Identifier Name                 Line    Size            Class        Type
 ---------------                 ----    ----            -----        ----

sname                            4249    1 longword      Register     Pointer to char
 
 

Function "yesno" defined at line 4323
-------------------------------------

 Identifier Name                 Line    Size            Class        Type
 ---------------                 ----    ----            -----        ----

buf                              4328    20 bytes        Auto         Array [20] of char
c                                4324    1 byte                       Parameter # 1, char
err                              4326    1 longword                   Parameter # 3, long int
true                             4325    1 longword                   Parameter # 2, long int
 
 

Function "host_send_file" defined at line 4343
----------------------------------------------

 Identifier Name                 Line    Size            Class        Type
 ---------------                 ----    ----            -----        ----

cmnd                             4347    1 byte          Auto         Array [1] of char
fddsk                            4346    1 longword      Not Alloc.   Pointer to pointer to struct _iobuf
logit                            4351                    Extern       Function returning long int
msg                              4344    1 longword                   Parameter # 1, pointer to char
receive_file                     4375                    Extern       Function returning long int
 
 

Function "host_receive_file" defined at line 4382
-------------------------------------------------

 Identifier Name                 Line    Size            Class        Type
 ---------------                 ----    ----            -----        ----

cmnd                             4387    1 byte          Auto         Array [1] of char
fddsk                            4385    1 longword      Not Alloc.   Pointer to pointer to struct _iobuf
logit                            4389                    Extern       Function returning long int
msg                              4383    1 longword                   Parameter # 1, pointer to char
send_file                        4411                    Extern       Function returning long int
x                                4386    1 longword      Not Alloc.   Long int
 
 

GNUUCP                                                          12-NOV-1988 14:08:27    VAX C      V2.3-024                 Page 62
V1.0                                                            13-OCT-1988 21:04:50    [VMSNET.DEVEL.GNUUCP.SRC]GNUUCP.C;27 (30)


Function "local_send_file" defined at line 4434
-----------------------------------------------

 Identifier Name                 Line    Size            Class        Type
 ---------------                 ----    ----            -----        ----

buf                              4437    1030 bytes      Auto         Array [1030] of char
delete                           4482                    Extern       Function returning long int
fddsk                            4438    1 longword      Not Alloc.   Pointer to pointer to struct _iobuf
logit                            4445                    Extern       Function returning long int
res                              4439    1 longword      Not Alloc.   Long int
send_file                        4475                    Extern       Function returning long int
status                           4439    1 longword      Not Alloc.   Long int
 
 

Function "local_receive_file" defined at line 4497
--------------------------------------------------

 Identifier Name                 Line    Size            Class        Type
 ---------------                 ----    ----            -----        ----

buf                              4499    1030 bytes      Auto         Array [1030] of char
fddsk                            4500    1 longword      Not Alloc.   Pointer to pointer to struct _iobuf
logit                            4522                    Extern       Function returning long int
receive_file                     4540                    Extern       Function returning long int
 
 

Function "receive_file" defined at line 4546
--------------------------------------------

 Identifier Name                 Line    Size            Class        Type
 ---------------                 ----    ----            -----        ----

dstnam                           4548    1 longword                   Parameter # 3, pointer to char
error                            4551    1 longword      Register     Initialized long int
fddsk                            4547    1 longword                   Parameter # 1, pointer to pointer to struct _iobuf
logit                            4578                    Extern       Function returning long int
rename                           4569                    Extern       Function returning long int
status                           4550    1 longword      Not Alloc.   Long int
temp                             4548    1 longword                   Parameter # 2, pointer to char
 
 

Function "send_file" defined at line 4589
-----------------------------------------

 Identifier Name                 Line    Size            Class        Type
 ---------------                 ----    ----            -----        ----

ansbuf                           4592    1030 bytes      Auto         Array [1030] of char
fddsk                            4590    1 longword                   Parameter # 1, pointer to pointer to struct _iobuf
logit                            4606                    Extern       Function returning long int
 
 

GNUUCP                                                          12-NOV-1988 14:08:27    VAX C      V2.3-024                 Page 63
V1.0                                                            13-OCT-1988 21:04:50    [VMSNET.DEVEL.GNUUCP.SRC]GNUUCP.C;27 (30)


Function "tdial" defined at line 5067
-------------------------------------

 Identifier Name                 Line    Size            Class        Type
 ---------------                 ----    ----            -----        ----

i                                5075    1 longword      Register     Pointer to char
j                                5075    1 longword      Register     Pointer to char
junk                             5072    1 longword      Auto         Long int
mdmEcho                          5079    1 longword      Not Alloc.   Initialized long int
mdmtyp                           5071    1 longword      Register     Long int
modemname                        5068    1 longword                   Parameter # 2, pointer to char
pmdminf                          5078    1 longword      Register     Pointer to struct mdminf
telnbr                           5068    1 longword                   Parameter # 1, pointer to char
tries                            5073    1 longword      Register     Long int
waitct                           5076    1 longword      Register     Long int
 
 

Function "ttolSlow" defined at line 5175
----------------------------------------

 Identifier Name                 Line    Size            Class        Type
 ---------------                 ----    ----            -----        ----

millisec                         5175    1 longword                   Parameter # 2, long int
s                                5175    1 longword                   Parameter # 1, pointer to char
 
 

Function "msleep" defined at line 5189
--------------------------------------

 Identifier Name                 Line    Size            Class        Type
 ---------------                 ----    ----            -----        ----

m                                5189    1 longword                   Parameter # 1, long int
SYS$HIBER                        5198                    Extern       Function returning long int
SYS$SCHDWK                       5197                    Extern       Function returning long int
t                                5193    8 bytes         Auto         Struct time_struct
time_struct                      5191    8 bytes                      Structure tag
 hi                              5192    1 longword                    Member (offset = 0), long int
 lo                              5192    1 longword                    Member (offset = 4 bytes), long int
 
 

Function "lookup" defined at line 5234
--------------------------------------

 Identifier Name                 Line    Size            Class        Type
 ---------------                 ----    ----            -----        ----

cmd                              5234    1 longword                   Parameter # 2, pointer to char
cmdlen                           5236    1 longword      Register     Long int
i                                5236    1 longword      Register     Long int
n                                5234    1 longword                   Parameter # 3, long int

GNUUCP                                                          12-NOV-1988 14:08:27    VAX C      V2.3-024                 Page 64
V1.0                                                            13-OCT-1988 21:04:50    [VMSNET.DEVEL.GNUUCP.SRC]GNUUCP.C;27 (30)

 Identifier Name                 Line    Size            Class        Type
 ---------------                 ----    ----            -----        ----

table                            5234    1 longword                   Parameter # 1, pointer to struct keytab
tolower                          5240                    Extern       Function returning long int
v                                5236    1 longword      Not Alloc.   Long int
x                                5234    1 longword                   Parameter # 4, pointer to long int
 
 

Psect Synopsis
--------------

 Psect Name                     Allocation  Attributes
 ----------                     ----------  ----------

$CODE                           7272 bytes  Position-independent, relocatable, shareable, executable, readable
$DATA                           628 bytes   Position-independent, relocatable, readable, writeable
VERSION                         21 bytes    Position-independent, overlay, relocatable, global, shareable, readable, writeable
_CTYPE_                         0           Position-independent, overlay, relocatable, global, shareable, readable
ERRNO                           4 bytes     Position-independent, overlay, relocatable, global, readable, writeable
VAXC$ERRNO                      4 bytes     Position-independent, overlay, relocatable, global, readable, writeable
STDIN                           4 bytes     Position-independent, overlay, relocatable, global, readable, writeable
STDOUT                          4 bytes     Position-independent, overlay, relocatable, global, readable, writeable
STDERR                          4 bytes     Position-independent, overlay, relocatable, global, readable, writeable
DEBUG                           4 bytes     Position-independent, overlay, relocatable, global, shareable, readable, writeable
PROGNAME                        20 bytes    Position-independent, overlay, relocatable, global, shareable, readable, writeable
SPOOL                           4 bytes     Position-independent, overlay, relocatable, global, shareable, readable, writeable
CONTROL                         4 bytes     Position-independent, overlay, relocatable, global, shareable, readable, writeable
MYNAME                          20 bytes    Position-independent, overlay, relocatable, global, shareable, readable, writeable
HOST_NAME                       20 bytes    Position-independent, overlay, relocatable, global, shareable, readable, writeable
OURPID                          4 bytes     Position-independent, overlay, relocatable, global, shareable, readable, writeable
SYSFILE                         4 bytes     Position-independent, overlay, relocatable, global, shareable, readable, writeable
USERFILE                        4 bytes     Position-independent, overlay, relocatable, global, shareable, readable, writeable
PUBDIR                          4 bytes     Position-independent, overlay, relocatable, global, shareable, readable, writeable
PORTS                           4 bytes     Position-independent, overlay, relocatable, global, shareable, readable, writeable
WHO                             255 bytes   Position-independent, overlay, relocatable, global, shareable, readable, writeable
LOGFD                           4 bytes     Position-independent, overlay, relocatable, global, shareable, readable, writeable
SYSDEP_CONTROL                  0           Position-independent, overlay, relocatable, global, shareable, readable, writeable
TTYNAM                          255 bytes   Position-independent, overlay, relocatable, global, shareable, readable, writeable
SRCNAM                          255 bytes   Position-independent, overlay, relocatable, global, shareable, readable, writeable
DSTNAM                          255 bytes   Position-independent, overlay, relocatable, global, shareable, readable, writeable
FLAGS                           40 bytes    Position-independent, overlay, relocatable, global, shareable, readable, writeable
TEMP                            255 bytes   Position-independent, overlay, relocatable, global, shareable, readable, writeable
FDTTY                           4 bytes     Position-independent, overlay, relocatable, global, shareable, readable, writeable
IGNORE_TIME_RESTRICTIONS        4 bytes     Position-independent, overlay, relocatable, global, shareable, readable, writeable
MODE                            4 bytes     Position-independent, overlay, relocatable, global, shareable, readable, writeable
F_WAIT                          4 bytes     Position-independent, overlay, relocatable, global, shareable, readable, writeable
LOOP                            4 bytes     Position-independent, overlay, relocatable, global, shareable, readable, writeable
CURTEMP                         4 bytes     Position-independent, overlay, relocatable, global, shareable, readable, writeable
MSGO0                           8 bytes     Position-independent, overlay, relocatable, global, shareable, readable, writeable
MSGO1                           10 bytes    Position-independent, overlay, relocatable, global, shareable, readable, writeable
MSGO2                           8 bytes     Position-independent, overlay, relocatable, global, shareable, readable, writeable
MSGO3                           6 bytes     Position-independent, overlay, relocatable, global, shareable, readable, writeable
MSGO3A                          5 bytes     Position-independent, overlay, relocatable, global, shareable, readable, writeable
MSGO4                           10 bytes    Position-independent, overlay, relocatable, global, shareable, readable, writeable
MSGI0                           6 bytes     Position-independent, overlay, relocatable, global, shareable, readable, writeable

GNUUCP                                                          12-NOV-1988 14:08:27    VAX C      V2.3-024                 Page 65
V1.0                                                            13-OCT-1988 21:04:50    [VMSNET.DEVEL.GNUUCP.SRC]GNUUCP.C;27 (30)

 Psect Name                     Allocation  Attributes
 ----------                     ----------  ----------

MSGI1                           7 bytes     Position-independent, overlay, relocatable, global, shareable, readable, writeable
MSGI3                           5 bytes     Position-independent, overlay, relocatable, global, shareable, readable, writeable
MSGI4                           7 bytes     Position-independent, overlay, relocatable, global, shareable, readable, writeable
PTBL                            25 bytes    Position-independent, overlay, relocatable, global, shareable, readable, writeable
CURPROTO                        4 bytes     Position-independent, overlay, relocatable, global, shareable, readable, writeable
$CHAR_STRING_CONSTANTS          2529 bytes  Position-independent, relocatable, readable, writeable
DIALV                           4 bytes     Position-independent, overlay, relocatable, global, shareable, readable, writeable
MDMTAB                          156 bytes   Position-independent, overlay, relocatable, global, shareable, readable, writeable
NMDM                            4 bytes     Position-independent, overlay, relocatable, global, shareable, readable, writeable
 
 

Function Definition Map
-----------------------

 Line   Name
 ----   ----

3294    getstring
3337    instr
3391    twrite
3420    main
3558    debuggit
3571    sendexpect
3603    xlat_str
3678    pickport
3712    dial_nbr
3784    call_system
3863    call_sysline
4026    do_session
4115    top_level
4198    do_one_slave
4246    do_one_master
4323    yesno
4343    host_send_file
4382    host_receive_file
4434    local_send_file
4497    local_receive_file
4546    receive_file
4589    send_file
5067    tdial
5175    ttolSlow
5189    msleep
5234    lookup
 
 
Command Line
------------
 
CC/LIST=[-.BLD]/OBJE=[-.BLD]/SHOW=(BRIEF,SOURCE,SYMBOLS)/DEFINE=LOG GNUUCP

