[comp.os.minix] UUPC for Minix, part 2/5

housel@en.ecn.purdue.edu (Peter S. Housel) (07/03/89)

echo 'x - Makefile'
sed 's/^X//' <<'**-Makefile-EOF-**' >Makefile
X#
X# makefile for dcp
X#
X
XCFLAGS=
XSRCS=	dcp.c dcpsys.c dcpxfer.c dcpunix.c dcputil.c newgpkt.c uux.c
XOBJS=	dcp.s dcpsys.s dcpxfer.s dcpunix.s dcputil.s newgpkt.s
X
Xdcp:	$(OBJS)
X	cc -o dcp $(OBJS) modemcap/libmodemcap.a
X
Xuux:	uux.s
X	cc -o uux uux.s
X	chmem =10240 uux
X
Xclean:
X	rm -f uux dcp $(OBJS) core a.out
X
Xdepend:
X	mkdep $(CFLAGS) $(SRCS)
X
X# DO NOT DELETE THIS LINE -- mkdep uses it.
X# DO NOT PUT ANYTHING AFTER THIS LINE, IT WILL GO AWAY.
X
Xdcp.s: /usr/include/stdio.h
Xdcp.s: /usr/include/sys/types.h
Xdcp.s: /usr/include/time.h
Xdcp.s: dcp.c
Xdcp.s: dcp.h
Xdcpsys.s: /usr/include/dirent.h
Xdcpsys.s: /usr/include/stdio.h
Xdcpsys.s: /usr/include/sys/dirent.h
Xdcpsys.s: /usr/include/sys/types.h
Xdcpsys.s: dcp.h
Xdcpsys.s: dcpsys.c
Xdcpxfer.s: /usr/include/ctype.h
Xdcpxfer.s: /usr/include/stdio.h
Xdcpxfer.s: dcp.h
Xdcpxfer.s: dcpxfer.c
Xdcpunix.s: /usr/include/ctype.h
Xdcpunix.s: /usr/include/dial.h
Xdcpunix.s: /usr/include/sgtty.h
Xdcpunix.s: /usr/include/signal.h
Xdcpunix.s: /usr/include/stdio.h
Xdcpunix.s: dcp.h
Xdcpunix.s: dcpunix.c
Xdcputil.s: /usr/include/ctype.h
Xdcputil.s: /usr/include/pwd.h
Xdcputil.s: /usr/include/stdio.h
Xdcputil.s: dcp.h
Xdcputil.s: dcputil.c
Xnewgpkt.s: /usr/include/stdio.h
Xnewgpkt.s: dcp.h
Xnewgpkt.s: newgpkt.c
Xuux.s: /usr/include/ctype.h
Xuux.s: /usr/include/pwd.h
Xuux.s: /usr/include/stdio.h
Xuux.s: uux.c
X
X# IF YOU PUT ANYTHING HERE IT WILL GO AWAY
**-Makefile-EOF-**
echo 'x - README'
sed 's/^X//' <<'**-README-EOF-**' >README
XMINIX installation instructions.
XVery brief - dare I even say vauge. I assume that the reader is, or
Xpotentially is, a highly motivated UUCP guru.
X
X1) Creat the file "/etc/uucpname".  It should be one line, containing
Xyour uucpname.  Also, create an account "uucp".  The password
Xline should be something like:
X
Xuucp:*:40:40:Unix-Unix Copy:/usr/spool/uucp:/usr/lib/uucp/uucico
X
XCreate a group named uucp (gid 40) if you like. It's not important.
XSave your ramdisk.
X
X2) Create the directory "/usr/lib/uucp". Copy the contents of the
X"lib.uucp" directory to it. Change the ownership of the directory and all
Xof the files to be uucp. It should look something like this
X(note the permissions).
X	total 6
X	-rw-r--r--  1   uucp      88 Jul 29 00:33 L-devices
X	-rw-------  1   uucp     125 Dec 20 11:46 L.sys
X	-rw-rw-rw-  1   uucp    1609 Jan 11 03:23 LOGFILE
X	-rw-------  1   uucp       3 Jan  3 17:42 SPOOLSEQ
X
X3) Create the directory "/usr/spool/uucp". It should be mode 755 and owned
Xby "uucp". Maybe 777, I'm not sure.
X
X4) Install "dial.h" from the "uucp/modemcap" directory in /usr/include.
XCreate the directory "/usr/etc" if you haven't already got one, and install
Xthe "modemcap" file from the same directory in /usr/etc/modemcap. Do a make.
X
X5) For this you need Doug Gwyn's POSIX directory routines, as posted in Dec.
Xby Terrence Holm. In the "uucp" directory, do a "make". You should end up
Xwith a file "dcp". Change it to be owned by uucp, and mode 4755.
XDo a "make uux". Copy uux to /usr/bin, change owner to uucp, and mode to 4755.
X
X6) Edit the file "/usr/lib/uucp/L-devices".  Change any of the fields
Xthat need changing for your dialout line.  The "brand" field will
Xprobably be "hayes".
X
X7) Arrange a UUCP connection with the other end. Set up the
X/usr/lib/uucp/L.sys file appropriately.
X
X8) Do "./dcp -s<remote-sys> -x20".  You should get lots of exciting
Xdetails about how dcp is dialing the phone, logging into the remote
Xsystem, setting up the UUCP protocol, transferring packets, deciding to
Xhang up, hanging up, etc.
**-README-EOF-**
echo 'x - cleanlog'
sed 's/^X//' <<'**-cleanlog-EOF-**' >cleanlog
X#!/bin/sh
X>/usr/lib/uucp/LOGFILE
**-cleanlog-EOF-**
echo 'x - dcp.c'
sed 's/^X//' <<'**-dcp.c-EOF-**' >dcp.c
X/*
X * dcp.c 
X *
X * revised edition of dcp 
X *
X * stuart lynne may/87 
X *
X * copyright (c) richard h. lamb 1985, 1986, 1987 changes copyright (c) stuart
X * lynne 1987 
X *
X * "dcp" a uucp clone. copyright richard h. lamb 1985,1986,1987
X *
X * this program implements a uucico type file transfer and remote execution
X * type protocol. 
X */
X
X#include <time.h>
X#include "dcp.h"
X
Xint pktsize;			/* packet size for pro */
XFILE *logfile;			/* system log file */
XFILE *fw;			/* cfile pointer */
Xchar state;			/* system state */
Xchar cfile[80];			/* work file pointer */
Xint remote;			/* -1 means we're remote ..7 */
Xint msgtime;			/* timout setting */
Xchar fromfile[132];		/* source of copy */
Xchar tofile[132];		/* destination of copy */
XFILE *fp;			/* current disk file ptr */
Xint size;			/* nbytes in buff */
Xtime_t now;			/* current time */
XFILE *fsys;			/* L.sys file pointer */
Xchar Rmtname[20];
Xchar rmtname[20];
Xchar *cctime;			/* legal call times */
Xchar proto[5];			/* list of protocols */
Xchar *nodename;			/* UUCP node name */
X
Xchar sysline[BUFSIZ];
Xchar *flds[60];
Xint kflds;
Xint debuglevel;			/* debugging flag */
X
Xunsigned int checksum();
X
X/*
X * usage:
X *
X *	dcp	[-xn]			slave mode
X *	dcp	[-xn] -r1 -shost 	call host
X *	dcp	[-xn] -r1 -sall		call all hosts
X *	dcp	[-xn] -r1		call any hosts as required by C. files 
X */
X
Xstatic void cant(file)
Xchar *file;
X{
X   fprintf(stderr, "Can't open: \"%s\"\n", file);
X   exit(NULL);
X}
X
Xmain(argc, argv)
Xint argc;
Xchar *argv[];
X{
X FILE *ftmp;
X char line[132];
X
X if((logfile = fopen(LOGFILE, "a")) == NULL)
X    cant(LOGFILE);
X
X debuglevel = 0;
X fp = NULL;
X fw = NULL;
X nodename = uucpname();
X
X remote = SLAVE;
X strcpy(Rmtname, "any");
X 
X while(--argc)
X      {
X       if(**++argv == '-')
X	 {
X	  switch(argv[0][1])
X	        {
X		 case 'x':
X		 	debuglevel = atoi(&argv[0][2]);
X			break;
X		 case 's':
X			remote = MASTER;
X			sprintf(Rmtname, "%.7s", &argv[0][2]);
X			break;
X		 case 'r':
X			remote = atoi(&argv[0][2]);
X			break;
X
X		 default:
X			break;
X		}
X	 }
X      }
X
X printmsg(M_INFO, "nodename = %s", nodename);
X
X if(remote == MASTER)
X   {
X    time(&now);
X    printmsg(M_CALL, "Calling %s, debuglevel=%d (%.19s)", Rmtname, debuglevel,
X		ctime(&now));
X
X    if((fsys = fopen(LSYS, "r")) == NULL)
X      exit(FAILED);
X    state = 'I';
X
X    while(TRUE)
X         {
X	  printmsg(M_CALL, "Mstate = %c", state);
X	  switch(state)
X	        {
X		 case 'I':	/* no system, get one */
X		 	state = getsystem();
X			break;
X		 case 'S':	/* got system, call it */
X			state = callup();
X			break;
X		 case 'P':	/* called, negotiate protocol */
X			state = startup();
X			break;
X		 case 'D':	/* got protocol, start running */
X			state = master();
X			break;
X		 case 'Y':	/* abort */
X			state = sysend();
X			break;
X		 case 'G':
X			state = 'I';
X			break;
X#ifdef NOTDEF
X			if(strcmp(Rmtname, "any") != SAME)
X			  state = 'Y';
X			else
X			  state = 'I';
X			break;
X#endif
X		}
X	  if(state == 'A')
X	    break;
X	 }
X    fclose(fsys);
X   }
X else	/* slave */
X   {
X    state = '0';
X    while(TRUE)
X         {
X	  printmsg(M_CALL, "Sstate = %c", state);
X	  switch(state)
X	        {
X		 case '0':
X			  if(initline() < 0)
X			     state = 'Y';
X			  else
X			     state = 'I';
X			  break;
X		 case 'I':
X			  state = startup();
X			  break;
X		 case 'R':
X			  state = slave();
X			  break;
X		 case 'Y':
X			  state = sysend();
X			  break;
X		}
X	  if(state == 'A')
X	    break;
X	 }
X    dcpundial();
X   }
X
X /* fprintf( stderr, "calling dcxqt\n" ); */
X if (dcxqt())
X   printmsg(M_ERROR, "ERROR in DCXQT");
X
X fclose(logfile);
X return 0;
X}
X
X
X/*
X * master
X */
Xmaster()
X{
X state = 'I';
X while(TRUE)
X      {
X       printmsg(M_CONVERSE, "Top level state (master mode) %c", state);
X       switch(state)
X	     {
X	      case 'I':
X	      		state = sinit();
X			break;
X	      case 'B':
X			state = scandir();
X			break;
X	      case 'S':
X			state = sendf();
X			break;
X	      case 'Q':
X			state = sbreak();
X			break;
X	      case 'G':
X			state = recvf();
X			break;
X	      case 'C':
X			state = 'Y';
X			break;
X	      case 'Y':
X			state = endp();
X			break;
X	      case 'P':
X			return ('Y');
X	      case 'A':
X			return ('A');
X	      default:
X			return ('A');
X	     }
X      }
X}
X
X
X/*
X * slave
X */
Xslave()
X{
X state = 'I';
X while(TRUE)
X      {
X       printmsg(M_CONVERSE, "Top level state (slave mode) %c", state);
X       switch(state)
X	     {
X	      case 'I':
X	      		state = rinit();
X			break;
X	      case 'F':
X			state = recvf();
X			break;
X	      case 'C':
X			state = schkdir();
X			break;
X	      case 'T':
X			state = 'B';
X			break;
X	      case 'B':
X			state = scandir();
X			break;
X	      case 'S':
X			state = sendf();
X			break;
X	      case 'Q':
X			state = sbreak();
X			break;
X	      case 'G':
X			return ('Y');
X	      case 'Y':
X			state = endp();
X			break;
X	      case 'P':
X			return ('Y');
X	      case 'A':
X			return ('A');
X	      default:
X			return ('A');
X	     }
X      }
X}
X
X/*
X * r e c v f
X *
X * This is the state table switcher for receiving files. 
X */
X
Xrecvf()
X{
X state = 'F';			/* Receive-Init is the start state */
X
X while(TRUE)
X      {
X       printmsg(M_TRANSFER, " receive state: %c", state);
X       switch(state)
X	     {				/* Do until done */
X	      case 'F':
X	      		state = rfile();
X			break;			/* Receive-File */
X	      case 'D':
X			state = rdata();
X			break;			/* Receive-Data */
X	      case 'C':
X			return ('C');		/* Complete state */
X	      case 'A':
X			return ('Y');		/* "Abort" state */
X	      default:
X			return ('Y');
X	     }
X      }
X}
X
X
X/*
X * s e n d f
X *
X * Sendsw is the state table switcher for sending files. It loops until either
X * it finishes, or an error is encountered.  The routines called by sendsw
X * are responsible for changing the state. 
X *
X */
Xsendf()
X{
X fp = NULL;			/* reset file getter/opener */
X state = 'F';			/* Send initiate is the start state */
X while(TRUE)
X      {				/* Do this as long as necessary */
X       printmsg(M_TRANSFER, "send state: %c", state);
X       switch(state)
X	     {
X	      case 'F':
X	      		state = sfile();
X			break;			/* Send-File */
X	      case 'D':
X			state = sdata();
X			break;			/* Send-Data */
X	      case 'Z':
X			state = seof();
X			break;			/* Send-End-of-File */
X	      case 'B':
X			return ('B');		/* Complete */
X	      case 'A':
X			return ('Y');		/* "Abort" */
X	      default:
X			return ('Y');		/* Unknown, fail */
X	     }
X      }
X}
X
X/*
X * A command formatter for DCP. RH Lamb.
X * sets up stdin and stdout on various machines
X * There is NO command checking so watch what you send and who you
X * let accsess your machine. "C rm /usr/*.*" could be executed.
X */
Xdcxqt()
X{
X int i;
X char command[60], input[60], output[60], line[BUFSIZ];
X char *cp;
X 
X while(dscandir())
X   {
X    strcpy(line, cfile);
X    fw = fopen(line, "r");	/* imported X file */
X    strcpy(cfile, line);
X    printmsg(M_INFO, "dcxqt:%s", cfile);
X    input[0] = '\0';
X    output[0] = '\0';
X    command[0] = '\0';
X    while(fgets(line, BUFSIZ, fw) != (char *) NULL)
X         {
X	  cp = index(line, '\n');
X	  if(cp != (char *) NULL)
X	    *cp = '\0';
X
X	  printmsg(M_INFO, "dcxqt: %s", line);
X	  switch(line[0])
X	        {
X		 case 'U':
X		 	break;
X		 case 'I':
X			sprintf(input, "%s/%s", SPOOLDIR, &line[2]);
X			break;
X		 case 'O':
X			sprintf(output, "%s/%s", SPOOLDIR, &line[2]);
X			break;
X		 case 'C':
X			strcpy(command, &line[2]);
X			break;
X		 case 'R':
X			break;
X		 default:
X			break;
X		}
X	 }
X    fclose(fw);
X    
X    printmsg(M_CALL, "xqt: %s", command);
X
X    shell(command, input, output, (char *) NULL);
X
X    unlink(cfile);
X    unlink(input);
X    unlink(output);
X   }
X return (0);
X}
**-dcp.c-EOF-**
echo 'x - dcp.h'
sed 's/^X//' <<'**-dcp.h-EOF-**' >dcp.h
X/* DCP a uucp clone. Copyright Richard H. Lamb 1985,1986,1987 */
X#include <stdio.h>		/* Standard UNIX  definitions */
X
X#define LSYS		"/usr/lib/uucp/L.sys"
X#define NODENAME	"/etc/uucpname"
X#define LOGFILE		"/usr/lib/uucp/LOGFILE"
X#define PUBDIR		"/usr/spool/uucppublic"
X#define SPOOLDIR	"/usr/spool/uucp"
X#define CALLFILE	"C.%s"
X#define XQTFILE		"X.%s"
X
X#define SITENAMELEN	32
X#define PATHLEN		256
X
X#define MSGTIME         20
X#define MAXPACK         256
X
X#define DLE		'\020'	/* ASCII 'DLE' character */
X
X#define	SLAVE	0
X#define	MASTER	1
X
X#ifndef TRUE
X#define TRUE   (-1)
X#define FALSE   0
X#endif
X
X#define SAME	0
X#define FAILED	-1
X#define OK		0
X
X/* log messages */
X#define M_ERROR		0	/* log regardless of debuglevel */
X#define M_CALL		1	/* the call and pre-protocol negotiation */
X#define M_CONVERSE	2	/* conversation level */
X#define M_TRANSFER	3	/* file transfer */
X#define M_SPOOL		4	/* spool files */
X#define M_CALLMSG	5	/* messages sent out during call/pre-proto */
X#define M_HIGHPROTO	6	/* high-level protocol */
X#define M_MEDPROTO	7	/* med-level protocol */
X#define M_LOWPROTO	8	/* low-level protocol (framing and such) */
X#define M_DATA		9	/* actual packet data */
X#define M_INFO		10	/* reading config files */
X
X/* L.sys field defines */
X
X#define	FLD_REMOTE	0	/* remote system name */
X#define	FLD_CCTIME	1	/* legal call times */
X#define	FLD_DEVICE	2	/* device, or ACU for modem */
X#define	FLD_SPEED	3	/* bit rate */
X#define FLD_PHONE	4	/* phone number */
X#define	FLD_EXPECT	5	/* first login "expect" field */
X#define FLD_SEND	6	/* first login "send" field */
X
Xtypedef int (*procref) ();
X
Xtypedef struct
X{
X   char type;
X   procref a;
X   procref b;
X   procref c;
X   procref d;
X} Proto;
X
X/* the various protocols available. Add here for others */
Xextern procref getpkt, sendpkt, openpk, closepk;
X
Xextern int ggetpkt(), gsendpkt(), gopenpk(), gclosepk();
X
X/* [ I don't have these... ]
X * extern int	kgetpkt(), ksendpkt(), kopenpk(), kclosepk();
X * extern int	rgetpkt(), rsendpkt(), ropenpk(), rclosepk();
X * extern int	tgetpkt(), tsendpkt(), topenpk(), tclosepk(); 
X */
X
Xextern int pktsize;		/* packet size for this protocol */
Xextern FILE *logfile;		/* system log file */
Xextern FILE *fw;		/* cfile pointer */
Xextern char cfile[80];		/* work file name */
Xextern int remote;		/* -1 means we're remote */
Xextern int findwork;
Xextern int msgtime;		/* timeout setting */
Xextern char fromfile[132];	/* source of copy */
Xextern char tofile[132];	/* destiation of copy */
Xextern char state;		/* present state */
Xextern FILE *fp;		/* current disk file ptr */
Xextern int size;		/* nbytes in buff */
Xextern FILE *fsys;
Xextern char Rmtname[20];
Xextern char rmtname[20];
Xextern char *cctime;
X	
Xextern int swritefd;		/* serial write file descriptor */
Xextern int sreadfd;		/* serial read file descriptor */
Xextern int timedout;
X
Xextern char sysline[BUFSIZ];
Xextern char s_systems[64];
Xextern char s_logfile[64];
Xextern char s_syslog[64];
Xextern char *flds[60];
Xextern int kflds;
X
Xextern int debuglevel;		/* debugging flag */
Xextern unsigned int checksum();
Xextern char *index();
Xextern char *rindex();
X
Xextern char *uucpname();
Xextern char *visib();
X
Xextern char speed[];
Xextern char device[];
Xextern char *nodename;
**-dcp.h-EOF-**
echo 'x - dcpsys.c'
sed 's/^X//' <<'**-dcpsys.c-EOF-**' >dcpsys.c
X/*
X * dcpsys.c Revised edition of dcp Stuart Lynne May/87 Copyright (c) Richard
X * H. Lamb 1985, 1986, 1987 Changes Copyright (c) Stuart Lynne 1987 
X *
X * "DCP" a uucp clone. Copyright Richard H. Lamb 1985,1986,1987
X */
X
X/* Get the next system, and other support routines  */
X
X#include <sys/types.h>
X#ifdef BSD
X#include <sys/dir.h>
X#else
X#include <dirent.h>
X#define direct dirent
X#endif
X
X#include "dcp.h"
X#define PROTOS  "g"
X#define MAXLOGTRY       3
X
XProto Protolst[] =
X{
X   'g', ggetpkt, gsendpkt, gopenpk, gclosepk,
X/*
X * 'k', kgetpkt, ksendpkt, kopenpk, kclosepk,
X * 'r', rgetpkt, rsendpkt, ropenpk, rclosepk,
X * 't', tgetpkt, tsendpkt, topenpk, tclosepk, 
X */
X   '0',
X};
X
X#define EOTMSG "\004\r\004\r"
X
Xprocref getpkt, sendpkt, openpk, closepk;
X
Xchar device[32];
Xchar speed[10];
X
X/*
X *            Sub Systems
X *
X * getsystem
X * Process an "L.sys" file entry
X */
Xgetsystem()
X{
X int i;
X
X if(fgets(sysline, BUFSIZ, fsys) == (char *) NULL)
X   return ('A');
X printmsg(M_INFO, "%s", sysline);
X
X kflds = getargs(sysline, flds);
X strcpy(rmtname, flds[FLD_REMOTE]);
X cctime = flds[FLD_CCTIME];
X strcpy(device, flds[FLD_DEVICE]);
X strcpy(speed, flds[FLD_SPEED]);
X 
X if(debuglevel >= M_INFO)
X   for(i = FLD_EXPECT; i < kflds; i += 2)
X     fprintf(stderr, "expect[%02d]:\t%s\nsend  [%02d]:\t%s\n",
X	             i, flds[i], i + 1, flds[i + 1]);
X
X printmsg(M_INFO, "rmt=%s ctm=%s", rmtname, flds[FLD_CCTIME]);
X printmsg(M_INFO, "dev=%s spd=%s tel=%s ", device, speed, flds[FLD_PHONE]);
X
X fw = (FILE *) NULL;
X if(/* (checktime( cctime )) || */
X    (strcmp(Rmtname, "all") == SAME) ||
X    (strcmp(Rmtname, rmtname) == SAME) ||
X    ((strcmp(Rmtname, "any") == SAME) && scandir() == 'S'))
X   {
X    if (fw != (FILE *) NULL)
X      fclose(fw);		/* in case we matched with scandir */
X    return ('S');		/* startup this system */
X   }
X else
X   return ('G');
X}
X
X
X/*
X *
X * checkname
X * Do we know the guy ? 
X */
Xcheckname(name)
Xchar name[];
X{
X FILE *ff;
X char line[BUFSIZ], tmp[20];	/* can change to 8 if %8s works */
X 
X if ((ff = fopen(LSYS, "r")) == NULL)
X   return (FAILED);
X 
X while (fgets(line, BUFSIZ, ff) != (char *) NULL)
X   {
X    sscanf(line, "%8s ", tmp);
X    printmsg(M_INFO, "rmt= '%s' sys= '%s'", name, tmp);
X    if(strncmp(tmp, name, 7) == 0)
X      {
X       fclose(ff);
X       return (OK);		/* OK I like you */
X      }
X   }
X fclose(ff);
X return (FAILED);		/* Who are you ? */
X}
X
X/*
X *
X * checktime
X * check if we may make a call at this time
X */
Xchecktime(xtime)
Xchar xtime[];
X{
X return (0);			/* OK go to it */
X}
X
X/*
X * sysend
X * end UUCP session negotiation 
X */
Xsysend()
X{
X char msg[80];
X
X msg[1] = '\0';
X msgtime = 2 * MSGTIME;
X /* while (msg[1] != 'O') { */
X wmsg("OOOOOO", 2);
X if(rmsg(msg, 2) == -1)
X   goto hang;
X /* } */
Xhang:
X wmsg("OOOOOO", 2);
X dcpundial();
X if(remote == MASTER)
X   return ('I');
X return ('A');
X}
X
X/*
X *
X * wmsg
X * write a ^P type msg to the remote uucp 
X */
Xwmsg(msg, syn)
Xint syn;
Xchar msg[];
X{
X int len;
X
X printmsg(M_CALL, "wmsg %s", msg);
X
X len = strlen(msg);
X if(syn == 2)
X   swrite("\0\020", 2);
X swrite(msg, len);
X if(syn == 2)
X   swrite("\0", 1);
X}
X
X/*
X * rmsg
X * read a ^P msg from UUCP 
X */
Xrmsg(msg, syn)
Xint syn;
Xchar msg[];
X{
X int ii;
X char c, cc[5];
X
X c = 'a';
X if(syn == 2)
X   {
X    while( c != 0x10 )
X         {
X	  if(sread(cc, 1, msgtime) < 1)
X	    return (-1);
X	  c = cc[0] & 0x7f;	/* Dont ask. MSC needs more than a byte to
X				 * breathe */
X	 }
X   }
X
X for (ii = 0; ii < 132 && c; ii++)
X   {
X    if (sread(cc, 1, msgtime) < 1)
X      return (-1);
X    c = cc[0] & 0x7f;
X    if(c == '\r' || c == '\n')
X      c = '\0';
X    msg[ii] = c;
X   }
X return (strlen(msg));
X}
X
X/*
X *
X * startup
X */
Xstartup()
X{
X char msg[80], tmp1[20], tmp2[20];
X int i;
X char pro;
X
X if(remote == MASTER)
X   {
X    msgtime = 2 * MSGTIME;
X    if (rmsg(msg, 2) == -1)
X      return ('Y');
X    printmsg(M_CALL, "1st msg = %s", msg);
X    if(msg[5] == '=' && strncmp(&msg[6], rmtname, 7))
X      return ('Y');
X
X    sprintf(msg, "S%.7s -Q0 -x%d", nodename, debuglevel);
X    /* -Q0 -x16 remote debuglevel set */
X    /* sprintf(msg, "S%.7s", nodename); */
X    printmsg(M_CALL, "Reply to 1st msg = %s", msg);
X    wmsg(msg, 2);
X
X    if(rmsg(msg, 2) == -1)
X      return ('Y');
X    printmsg(M_CALL, "2nd msg = %s", msg);
X    if(strncmp(&msg[1], "OK", 2))
X      return ('Y');
X
X    if (rmsg(msg, 2) == -1)
X      return ('Y');
X    printmsg(M_CALL, "3rd msg = %s", msg);
X
X    for(i = 0; (pro = PROTOS[i]), pro; ++i)
X        if(msg[0] == 'P' && index(&msg[1], pro) != NULL)
X	  {
X	   sprintf(msg, "U%c", pro);
X	   printmsg(M_CALL, "Reply to 3rd msg = %s", msg);
X	   wmsg(msg, 2);
X	   setproto(pro);
X	   return ('D');
X	  }
X    printmsg(M_ERROR, "Replying 'UN' - no common protocol");
X    wmsg("UN", 2);
X    return ('Y');
X   }
X else	/* slave */
X   {
X    msgtime = 2 * MSGTIME;
X    sprintf(msg, "Shere=%s", nodename);
X    wmsg(msg, 2);
X    if (rmsg(msg, 2) == -1)
X      return ('Y');
X    sscanf(&msg[1], "%s %s %s", rmtname, tmp1, tmp2);
X    sscanf(tmp2, "-x%d", &debuglevel);
X    printmsg(M_CALL, "debuglevel level = %d", debuglevel);
X    printmsg(M_CALL, "1st msg from remote = %s", msg);
X    if(checkname(rmtname))
X      return ('Y');
X    wmsg("ROK", 2);
X    sprintf(msg, "P%s", PROTOS);
X    wmsg(msg, 2);
X    if (rmsg(msg, 2) == -1)
X      return ('Y');
X    if (msg[0] != 'U' || index(PROTOS, msg[1]) == (char *) NULL)
X      return ('Y');
X    setproto(msg[1]);
X    return ('R');
X   }
X}
X
X/*
X * set the protocol
X */
Xsetproto(pr)
Xchar pr;
X{
X int i;
X Proto *tproto;
X
X for(tproto = Protolst; tproto->type != '\0' && pr != tproto->type; tproto++)
X    {
X     printmsg(M_CALL, "setproto: %c %c", pr, tproto->type);
X    }
X if(tproto->type == '\0')
X   {
X    printmsg(M_ERROR, "setproto:You said I had it but I cant find it");
X    exit(1);
X   }
X getpkt = tproto->a;
X sendpkt = tproto->b;
X openpk = tproto->c;
X closepk = tproto->d;
X}
X
X
Xint prefix(sh, lg)
Xchar *sh, *lg;
X{
X return (strncmp(sh, lg, strlen(sh)) == SAME);
X}
X
Xint notin(sh, lg)
Xchar *sh, *lg;
X{
X while(*lg)
X      {
X       if(prefix(sh, lg++))
X	  return (FALSE);
X      }
X return (TRUE);
X}
X
X#define MAXR 300
Xint expectstr(str, timeout)
Xchar *str;
X{
X static char rdvec[MAXR];
X char *rp = rdvec;
X int kr;
X char nextch;
X 
X printmsg(M_CALL, "wanted %s", str);
X
X if(strcmp(str, "\"\"") == SAME)
X   {
X    return (TRUE);
X   }	
X *rp = 0;
X while(notin(str, rdvec))
X      {
X       /* fprintf(stderr, "---------->%s<------\n", rdvec);/* */
X       kr = sread(&nextch, 1, timeout /* 40 */ );
X       /*
X	* nextch &= 0177; fprintf(stderr, "kr - %2d '%c'\n", kr, nextch); 
X	*/
X       if(kr <= 0)
X	 {
X	  return (FALSE);
X	 }
X       if ((*rp = nextch & 0177) != '\0')
X	 {
X	  rp++;
X	 }
X       *rp = '\0';
X       if (rp >= rdvec + MAXR)
X	 {
X	  return (FALSE);
X	 }
X      }
X return (TRUE);
X}
X
Xint writestr(s)
Xregister char *s;
X{
X register char last;
X register char *m;
X int nocr;
X 
X last = '\0';
X nocr = FALSE;
X while(*s)
X      {
X       if(last == '\\')
X	 {
X	  switch(*s)
X	        {
X		 case 'd':
X		 case 'D':		/* delay */
X		 		sleep(2);
X				break;
X		 case 'c':
X		 case 'C':		/* end string don't output CR */
X				nocr = TRUE;
X				break;
X		 case 'r':
X		 case 'R':		/* carriage return */
X		 case 'm':
X		 case 'M':
X				swrite("\r", 1);
X				break;
X		 case 'n':
X		 case 'N':
X				swrite("\n", 1);
X				break;
X		 case 'b':
X		 case 'B':
X				swrite("\b", 1);
X				break;
X		 case 't':
X		 case 'T':
X				swrite("\t", 1);
X				break;
X		 case 's':
X		 case 'S':
X				swrite(" ", 1);
X				break;
X#ifdef ZSPEED
X		 case 'z':
X		 case 'Z':
X				SIOSpeed(++s);
X				while(*s != '\0' && *s != '\\')
X				  s++;
X				if(*s == '\\')
X				  s++;
X				break;
X#endif ZSPEED
X		 default:
X				swrite(s, 1);
X		}
X	  last = '\0';
X	 }
X       else if (*s != '\\')
X	 {
X	  swrite(s, 1);
X	  /* fputc(*s,stderr); */
X	 }
X       else
X	 {
X	  last = *s;
X	 }
X       s++;
X      }
X return (nocr);
X}
X
X/*
X *   void sendthem(str)   send line of login sequence
X *         char *str;
X *
X *   return codes:  none
X */
X
Xvoid sendstr(str)
Xchar *str;
X{
X   int nw, ns;
X   int nulls;
X
X   printmsg(M_CALL, "sending %s", str);
X
X#ifdef BREAK
X   if(prefix("BREAK", str))
X     {
X      sscanf(&str[5], "%1d", &nulls);
X      if (nulls <= 0 || nulls > 10)
X	nulls = 3;
X      /* send break */
X      ssendbrk(nulls);
X      return;
X     }
X#endif
X   
X   if(strcmp(str, "EOT") == SAME)
X     {
X      swrite(EOTMSG, strlen(EOTMSG));
X      return;
X     }
X   if(strcmp(str, "\"\"") == SAME)
X      *str = '\0';
X   /* fprintf(stderr,"'%s'\n",str); */
X
X   if(strcmp(str, "") != SAME)
X     {
X      if(!writestr(str))
X	{
X	 swrite("\r", 1);
X	}
X     }
X   else
X     {
X      swrite("\r", 1);
X     }
X   return;
X}
X
Xint sendexpect(s, e, timeout)
Xchar *s;
Xchar *e;
X{
X sendstr(s);
X return (expectstr(e, timeout));
X}
X
X#ifdef SLDIAL
Xdial()
X{
X int flg, kk, jj, ll, firstflg;
X char buf[4], *prsend;
X 
X char *exp;
X char *alternate;
X int ok;
X int i;
X 
X if(strcmp(flds[FLD_TYPE], "HAYES") != SAME)
X   {
X    printmsg(0, "dial: unsupported dialer %s", flds[FLD_TYPE]);
X    return (FALSE);
X   }
X printmsg(3, "calling host %s", rmtname);
X if (openline(device, "2400"))
X   return (FALSE);
X 
X printmsg(0, "hayes: trying 2400");
X if(sendexpect("ATZ", "OK", 2) != TRUE)
X   {
X    sendexpect("\\d+++\\d", "OK", 2);
X    if(sendexpect("ATZ", "OK", 2) != TRUE)
X      {
X       printmsg(0, "hayes: trying 1200");
X       SIOSpeed("1200");
X       if(sendexpect("ATZ", "OK", 2) != TRUE)
X	 {
X	  sendexpect("\\d+++\\d", "OK", 2);
X	  if (sendexpect("ATZ", "OK", 2) != TRUE)
X	    return (FALSE);
X	 }
X      }
X   }
X printmsg(0, "hayes: got modem response");
X
X /*
X  * (sendstr( "\\d\\dATS7=30" ); expectstr( "OK", 40 ); 
X  */
X
X sendstr("\\d\\dATX4\\c");
X
X if (sendexpect(speed, "CONNECT ", 40) == TRUE)
X   {
X    printmsg(3, "hayes: got CONNECT");
X
X    if(sread(buf, 4, 4) == 4)
X      {
X       printmsg(3, "hayes: speed select %s", buf);
X       /* set speed appropriately */
X       SIOSpeed(buf);
X      }
X    return (TRUE);
X   }
X else
X   return (FALSE);
X
X#endif SLDIAL
X
X/*
X *
X * callup
X * script processor - nothing fancy! 
X */
Xcallup()
X{
X int flg, kk, jj, ll, firstflg;
X char *prsend;
X 
X char *exp;
X char *alternate;
X int ok;
X int i;
X 
X printmsg(M_CALL, "calling host %s", rmtname);
X 
X if (strcmp(device, "ACU") == SAME)
X   {
X    if (dcpdial((char *) NULL, speed, flds[FLD_PHONE]) == FALSE)
X      return ('G');
X   }
X else if (dcpdial(device, speed, (char *) NULL) == FALSE)
X   return ('G');
X 
X for (i = FLD_EXPECT; i < kflds; i += 2)
X   {
X    exp = flds[i];
X    printmsg(M_CALL, "callup: expect %d of %d  \"%s\"", i, kflds, exp);
X    
X    ok = FALSE;
X    while(ok != TRUE)
X         {
X	  alternate = index(exp, '-');
X	  if (alternate != (char *) NULL)
X	    *alternate++ = '\0';
X	  
X	  ok = expectstr(exp, 45);
X	  
X	  printmsg(M_CALL, "got %s", ok != TRUE ? "?" : "that");
X	  
X	  if (ok == TRUE)
X	     break;
X
X	  if (alternate == (char *) NULL)
X	    {
X	     printmsg(0, "LOGIN FAILED");
X	     return ('Y');
X	    }
X	  exp = index(alternate, '-');
X	  if (exp != (char *) NULL)
X	    *exp++ = '\0';
X	  
X	  printmsg(M_CALL, "send alternate");
X	  
X	  sendstr(alternate);
X	 }
X    
X    printmsg(M_CALL, "callup: send %d of %d \"%s\"", i+1, kflds, flds[i + 1]);
X    sleep(1);			/* (1) */
X    sendstr(flds[i + 1]);
X   }
X return ('P');
X}
X
X/*
X *
X * slowrite
X * comunication slow write. needed for auto-baud modems 
X */
X/*
X * slowrite(st)
X * register char *st;
X * {
X *  int	len, j;
X *  char c;
X *  len = strlen(st);
X *  printmsg( 2, "sent %s", st );
X *  for(j = 0; j < len; j++) {
X *      swrite(&st[j], 1);
X *	ddelay(80000);
X *  }
X * } 
X */
X
X/*
X *
X * scandir
X *
X * scan work dir for "C." files matching current remote host (rmtname)
X * return: A	- abort
X *	   Y	- can't open file
X *	   S	- ok
X *	   Q	- no files 
X */
Xscandir()
X{
X int fn, len, i;
X char cname[40], tmp[132];
X 
X DIR *dirp;
X struct direct *dp;
X 
X if ((dirp = opendir(SPOOLDIR)) == NULL)
X   {
X    printmsg(M_ERROR, "couldn't open dir %s", SPOOLDIR);
X    return ('A');
X   }
X sprintf(cname, CALLFILE, rmtname);
X len = strlen(cname);
X while((dp = readdir(dirp)) != NULL)
X   {
X    printmsg(M_INFO, "scandir: %s", dp->d_name);
X    if (strncmp(cname, dp->d_name, len) == SAME)
X      {
X       printmsg(M_INFO, "scandir: match!!");
X       sprintf(cfile, "%s/%s", SPOOLDIR, dp->d_name);
X       closedir(dirp);
X       if ((fw = fopen(cfile, "r")) == NULL)
X	 return ('Y');
X       return ('S');
X      }
X   }
X closedir(dirp);
X return ('Q');
X}
X
X
X/*
X * dscandir
X * scan the directory for xqt files
X */
Xdscandir()
X{
X int fn, len, i;
X char tmp[132];
X 
X DIR *dirp;
X struct direct *dp;
X 
X if((dirp = opendir(SPOOLDIR)) == NULL)
X   {
X    fprintf(stderr, "couldn't open dir %s\n", SPOOLDIR);
X    return (0);
X   }
X while((dp = readdir(dirp)) != (struct direct *) NULL)
X      {
X       printmsg(M_INFO, "dscandir: file = %s", dp->d_name);
X       if(strncmp(dp->d_name, "X.", 2) == SAME)
X	 {
X	  printmsg(M_INFO, "dscandir: match!!");
X	  sprintf(cfile, "%s/%s", SPOOLDIR, dp->d_name);
X	  closedir(dirp);
X	  return (-1);
X	 }
X      }
X closedir(dirp);
X return (0);
X}
X
X
**-dcpsys.c-EOF-**

hjg@amms4.UUCP (Harry Gross) (07/08/89)

In article <13076@ea.ecn.purdue.edu> housel@en.ecn.purdue.edu (Peter S. Housel) writes:
>XMINIX installation instructions.
	[stuff deleted]
>X5) For this you need Doug Gwyn's POSIX directory routines, as posted in Dec.
>Xby Terrence Holm.

Ok, I need them - from where can I get them?  Also, when I ran make on what I
_did_ have, I got three undefined externals (_getopt and 2 _optsomethings).
Will these go away with the inclusion of the POSIX routines? or do I need
something else as well (like the AT&T getopt routine maybe?).

-- 
		Harry Gross				 |  reserved for
							 |  something really
Internet: hjg@amms4.UUCP   (we're working on registering)|  clever - any
UUCP: {jyacc, qtny, rna, bklyncis}!amms4!hjg		 |  suggestions?