[comp.sys.ibm.pc] uuslave.c

simpsong@ncoast.UUCP (01/17/87)

*** Line-eater foo-d. ***

Greetings Fellow Neter's... There was a lot of talk about
UUCP for MS-DOS a week or two ago, and one thing that was
mentioned was a program called uuslave.c from a BBS in NJ.
Well, even though I am in Cleveland, I went ahead and registered
just so I could get this program...

Unfortunately, it contains very few comments, and appears to
be originally targeted for CPM, as well as having lots of stuff
hard-wired into the code...

I really don't know if it will be of any use, but it may be a 
building block from which the readers of net-land can produce
a usable uucp for msdos. (Does Minix have uucp?)

There was absolutely no documentation, and after looking at it
briefly, I really don't know where to start...

So, I ask... can anyone out there make heads or tails of this?
I will be trying to, but it really isn't my cup of tea. If anyone
can make this work, please repost your enhanced version with some
documentation.

Thanks, and Enjoy.


      Gregory R. Simpson       

UUCP: {ihnp4, seismo, decwrl, philabs, ucbvax}!decvax!cwruecmp!ncoast!simpsong
CSNET: ncoast!simpsong@case.CSNET     
ARPA:  ncoast!simpsong%case.CSNET@Csnet-Relay.ARPA

------- This is NOT a shar, or an arc, or anything... just straight code ----


/* @[$]uuslave.c	1.7 08/12/85 14:04:20 */

#include <stdio.h>
#include <fcntl.h>
#ifndef CPM
#include <termio.h>
#include <signal.h>
#endif

#define	MAGIC	0125252
#define	EOT	4

#define	CTRL	0
#define	ALTCHN	1
#define	LNGDAT	2
#define	SHTDAT	3

#define	CLOSE	1
#define	RJ	2
#define	SRJ	3
#define	RR	4
#define	INITC	5
#define	INITB	6
#define	INITA	7

extern errno;
char msgi[256],msgo[256],ttynam[32],cmnd[8],srcnam[32],dstnam[32],dskbuf[256],msgbld[256];
int fdtty,fddsk,tt,xxx,yyy,rseq,wseq;
#ifndef CPM
struct termio atermio,btermio;
#endif
#ifdef ERRLOG
FILE *file;
#endif

int wndsiz = 1;
int segsiz = 1;

char msgo0[] = "9800rcs login: ";
char msgo1[] = "Password:";
char msgo2[] = "\20Shere\0";
char msgo3[] = "\20ROK\0\20Pg\0";
char msgo4[] = "\20OOOOOO\0";
char msgo5[] = "...abort...";

char msgi0[] = "uucp\n";
char msgi1[] = "s8000\n";
char msgi2[] = "\20S*\0";
char msgi3[] = "\20Ug\0";

#ifdef CPM
extern xgetc(),xwrite();
#else
sigint()
{
	ioctl(fdtty,TCSETA,&atermio);
	close(fdtty);
	exit(0);
}

sigalrm()
{
}

xgetc()
{
	char data;

	signal(SIGALRM,sigalrm);
	alarm(10);
	if (read(fdtty,&data,1) > 0)
	{
		alarm(0);
		return(data & 0xFF);
	}
	return(EOF);
}

xwrite(fd,buf,ctr)
int fd;
char *buf;
int ctr;
{
	write(fd,buf,ctr);
}
#endif

zero(p,c)
char *p;
int c;
{
	while (c--)
		*p++ = 0;
}

ackmsg()
{
	int cksm,index;

	msgo[0] = 020;
	msgo[1] = 9;
	msgo[4] = (CTRL << 6) | (RR << 3) | rseq;
	cksm = MAGIC - msgo[4];
	msgo[2] = cksm;
	msgo[3] = cksm >> 8;
	msgo[5] = msgo[1] ^ msgo[2] ^ msgo[3] ^ msgo[4];
#ifdef DEBUG
	
	printf("T ");
	for (index = 0; index < 6; index++)
		printf("%03o ",msgo[index] & 0xFF);
	putchar('\n');
#endif
	xwrite(fdtty,msgo,6);
	rseq = (rseq + 1) & 7;
}

ctlmsg(byte)
char byte;
{
	int cksm,index;

	msgo[0] = 020;
	msgo[1] = 9;
	msgo[4] = (CTRL << 6) | byte;
	cksm = MAGIC - msgo[4];
	msgo[2] = cksm;
	msgo[3] = cksm >> 8;
	msgo[5] = msgo[1] ^ msgo[2] ^ msgo[3] ^ msgo[4];
#ifdef DEBUG
	printf("T ");
	for (index = 0; index < 6; index++)
		printf("%03o ",msgo[index] & 0xFF);
	putchar('\n');
#endif
	xwrite(fdtty,msgo,6);
}

lngput(s,n)
char *s;
int n;
{
	int cksm,index;

	zero(msgo,256);
	msgo[0] = 020;
	msgo[1] = segsiz + 1;
	msgo[4] = (LNGDAT << 6) + (wseq << 3) + rseq;
	for (index = 0; index < (segsiz + 1) * 32; index++)
		msgo[6+index] = 0;
	for (index = 0; index < n; index++)
		msgo[6+index] = *(s+index);
	cksm = MAGIC - (chksum(&msgo[6],(segsiz + 1) * 32) ^ (0377 & msgo[4]));
	msgo[2] = cksm;
	msgo[3] = cksm >> 8;
	msgo[5] = msgo[1] ^ msgo[2] ^ msgo[3] ^ msgo[4];
#ifdef DEBUG
	printf("T ");
	for (index = 0; index < (segsiz + 1) * 32 + 6; index++)
		printf("%03o ",msgo[index] & 0xFF);
	putchar('\n');
#endif
	do
	{
		xwrite(fdtty,msgo,(segsiz + 1) * 32 + 6);
		if (inpkt())
			return(1);
	}
	while (tt != CTRL || xxx != RR || yyy != wseq);
	wseq = (wseq + 1) & 7;
	return(0);
}

shtput(s,n)
char *s;
int n;
{
	int cksm,index;

	zero(msgo,256);
	msgo[0] = 020;
	msgo[1] = segsiz + 1;
	msgo[4] = (SHTDAT << 6) + (wseq << 3) + rseq;
	for (index = 0; index < (segsiz + 1) * 32; index++)
		msgo[6+index] = 0;
	msgo[6] = (segsiz + 1) * 32 - n;
	for (index = 0; index < n; index++)
		msgo[7+index] = *(s+index);
	cksm = MAGIC - (chksum(&msgo[6],(segsiz + 1) * 32) ^ (0377 & msgo[4]));
	msgo[2] = cksm;
	msgo[3] = cksm >> 8;
	msgo[5] = msgo[1] ^ msgo[2] ^ msgo[3] ^ msgo[4];
#ifdef DEBUG
	printf("T ");
	for (index = 0; index < (segsiz + 1) * 32 + 6; index++)
		printf("%03o ",msgo[index] & 0xFF);
	putchar('\n');
#endif
	do
	{
		xwrite(fdtty,msgo,(segsiz + 1) * 32 + 6);
		if (inpkt())
			return(1);
	}
	while (tt != CTRL || xxx != RR || yyy != wseq);
	wseq = (wseq + 1) & 7;
	return(0);
}

instr(s,n)
char *s;
int n;
{
	int data,count,i,j;

	count = 0;
#ifdef DEBUG
	printf("Expecting ");
	for (i = 0; i < n; i++)
		printf("%03o ",*(s+i));
	printf("\nR ");
#endif
	while ((data = xgetc()) != EOF)
	{
		msgi[count++] = data & 0x7F;
#ifdef DEBUG
		printf("%03o ",msgi[count-1]);
#endif
		if (count >= n)
		{
			for (i = n - 1, j = count - 1; i >= 0; i--, j--)
				if (*(s+i) == '*' || *(s+i) != msgi[j])
					break;
			if (i < 0 || *(s+i) == '*')
			{
#ifdef DEBUG
				putchar('\n');
#endif
				return(0);
			}
		}
	}
#ifdef DEBUG
	putchar('\n');
#endif
	msgi[count] = 0;
	return(1);
}

inpkt()
{
	int data,count,need;

	count = 0;
#ifdef DEBUG
	printf("R ");
#endif
	while ((data = xgetc()) != EOF)
	{
#ifdef DEBUG
		printf("%03o ",data & 0xFF);
#endif
		switch (count)
		{
		case 0 :
			if (data == 020)
				msgi[count++] = 020;
			break;
		case 1 :
			msgi[count++] = data;
			if (data == 9)
				need = 4;
			else
				need = 32 * data + 4;
			break;
		case 4 :
			tt = (data >> 6) & 3;
			xxx = (data >> 3) & 7;
			yyy = data & 7;
		default :
			msgi[count++] = data;
			if (!--need)
			{
#ifdef DEBUG
				putchar('\n');
#endif
				return(0);
			}
			break;
		}
	}
#ifdef DEBUG
	putchar('\n');
#endif
	return(1);
}

chksum(s,n)
register char *s;
register n;
{
	register short sum;
	register unsigned short t;
	register short x;

	sum = -1;
	x = 0;
	do
	{
		if (sum < 0)
		{
			sum <<= 1;
			sum++;
		}
		else
			sum <<= 1;
		t = sum;
		sum += *s++ & 0377;
		x += sum ^ n;
		if ((unsigned) sum <= t)
			sum ^= x;
	}
	while (--n > 0);
	return(sum);
}

main(argc,argv)
int argc;
char *argv[];
{
	char *p;
	int data,count;

#ifdef CPM
	sioinit();
#else
	if (argc > 1)
		strcpy(ttynam,argv[1]);
	else
		strcpy(ttynam,"/dev/tty12");
	if ((fdtty = open(ttynam,O_RDWR)) < 0)
	{
		printf("Cannot open %s for read/write %d\n",ttynam,errno);
		exit(1);
	}
	ioctl(fdtty,TCGETA,&atermio);
	btermio = atermio;
	btermio.c_iflag = btermio.c_oflag = btermio.c_lflag = 0;
	btermio.c_cc[VMIN] = 1;
	btermio.c_cc[VTIME] = 0;
	btermio.c_cflag = (btermio.c_cflag & ~CBAUD) | B1200;
	ioctl(fdtty,TCSETA,&btermio);
	signal(SIGINT,sigint);
#endif
	while (1)
	{
#ifdef DEBUG
		puts("restarting");
#endif
		rseq = 0;
		wseq = 1;

/* wait for EOT */

		while ((data = xgetc()) == EOF || (data &= 0x7F) != EOT);

/* output login request, verify uucp */

		xwrite(fdtty,msgo0,sizeof(msgo0)-1);
		if (instr(msgi0,sizeof(msgi0)-1))
			goto abort;

/* output password request, verify s8000 */

		xwrite(fdtty,msgo1,sizeof(msgo1)-1);
		if (instr(msgi1,sizeof(msgi1)-1))
			goto abort;

/* output here message, wait for response */

		xwrite(fdtty,msgo2,sizeof(msgo2)-1);
		if (instr(msgi2,sizeof(msgi2)-1))
			goto abort;

/* output ok message, output protocol request, wait for response */

		xwrite(fdtty,msgo3,sizeof(msgo3)-1);
		if (instr(msgi3,sizeof(msgi3)-1))
			goto abort;

/* output inita message, wait for response */

		ctlmsg((INITA << 3) | wndsiz);
		if (inpkt() || tt != CTRL || xxx != INITA)
			goto abort;

/* output initb message, wait for response */

		ctlmsg((INITB << 3) | segsiz);
		if (inpkt() || tt != CTRL || xxx != INITB)
			goto abort;

/* output initc message, wait for response */

		ctlmsg((INITC << 3) | wndsiz);
		if (inpkt() || tt != CTRL || xxx != INITC)
			goto abort;

/* output initial acknowledge, wait for command */

		ackmsg();
		while (1)
		{
			if (inpkt() || tt != LNGDAT)
			{
				intf("OVER EIGHT");
				goto abort;
			}
			strcpy(msgbld,&msgi[6]);
			while (strlen(&msgi[6]) == (segsiz + 1) * 32)
			{
				ackmsg();
				if (inpkt() || tt != LNGDAT)
				{
					intf("OVER ABORT SEVEN");
					goto abort;
				}
				strcat(msgbld,&msgi[6]);
			}
			switch (msgbld[0])
			{
			case 'S' :
				sscanf(msgbld,"%s %s %s",cmnd,srcnam,dstnam);
#ifdef CPM
				for (p = dstnam + strlen(dstnam); p != dstnam && *(p-1) != '/'; p--);
#else
				p = dstnam;
#endif
				if ((fddsk = creat(p,0644)) >= 0)
				{
					ackmsg();
					if (lngput("SY",2))
					{
						intf("OVER NINE");
						goto abort;
					}
					do
						if (inpkt())
						{
							intf("OVER TEN");	
							goto abort;
						}	
						else
							switch (tt)
							{
							case LNGDAT :
								write(fddsk,&msgi[6],(segsiz + 1) * 32);
								ackmsg();
								break;
							case SHTDAT :
								if (msgi[6] & 0x80)
								{
									intf("OVER ELEVEN");
#ifdef DEBUG
									puts("short packet error");
#endif
									goto abort;
								}
								else
								{
									if (msgi[6] != (segsiz + 1) * 32)
										write(fddsk,&msgi[7],(segsiz + 1) * 32 - msgi[6]);
									ackmsg();
								}
								break;
							default :
								intf("OVER TWELVE");
								goto abort;
							}
					while (tt != SHTDAT || msgi[6] != (segsiz + 1) * 32);
					close(fddsk);
					if (lngput("CY",2))
						goto abort;
				}
				else
				{
					ackmsg();
#ifdef ERRLOG
					if (file = fopen("uuslave.log","a+"))
					{
						fprintf(file,"Cannot open file=%s for writing errno=%d\n",p,errno);
						fclose(file);
					}
#endif
					sprintf(dskbuf,"SN%d",errno);
					if (lngput(dskbuf,strlen(dskbuf)))
						goto abort;
				}
				break;
			case 'R' :
				sscanf(msgbld,"%s %s %s",cmnd,srcnam,dstnam);
#ifdef CPM
				for (p = srcnam + strlen(srcnam); p != srcnam && *(p-1) != '/'; p--);
#else
				p = srcnam;
#endif
				if ((fddsk = open(p,O_RDONLY)) >= 0)
				{
					ackmsg();
					if (lngput("RY",2))
						goto abort;
					do
						if ((count = read(fddsk,dskbuf,(segsiz + 1) * 32)) == (segsiz + 1) * 32)
							if (lngput(dskbuf,(segsiz + 1) * 32))
								goto abort;
							else;
						else
							if (shtput(dskbuf,count))
								goto abort;
					while (count);
					close(fddsk);
					do
						if (inpkt())
							goto abort;
					while (tt != LNGDAT);
					ackmsg();
				}
				else
				{
					ackmsg();
#ifdef ERRLOG
					if (file = fopen("uuslave.log","a+"))
					{
						fprintf(file,"Cannot open file=%s for reading errno=%d\n",p,errno);
						fclose(file);
					}
#endif
					sprintf(dskbuf,"RN%d",errno);
					if (lngput(dskbuf,strlen(dskbuf)))
						goto abort;
				}
				break;
			case 'H' :
				intf("IN H CASE");
				if (lngput("HY",2))
				{
					intf("OVER ABORT ONE");	
					goto abort;
				}
				if (inpkt() || tt != LNGDAT)
				{
					intf("OVER ABORT TWO");		
					goto abort;
				}
				if (!strcmp(&msgi[6],"HY"))
				{
					ctlmsg(CLOSE << 3);
					do
						if (inpkt())
						{
							intf("OVER ABORT THREE");
							goto abort;
						}
					while (tt != CTRL && xxx != CLOSE);
					xwrite(fdtty,msgo4,sizeof(msgo4)-1);
					instr(msgo4,sizeof(msgo4)-1);
				}
				intf("OVER ABORT FIVE");
				break;
				/*goto abort;*/
			}
		}
abort:;
		xwrite(fdtty,msgo5,sizeof(msgo5)-1);
	}
}
intf(buffer)
register char *buffer;
{
	int fd;
	fd = open("UUCP.DAT",O_RDWR + O_CREAT);
	lseek(fd,0L,2);
	write(fd,buffer,strlen(buffer));
	close(fd);
}
-- 
      Gregory R. Simpson       

UUCP: {ihnp4, seismo, decwrl, philabs, ucbvax}!decvax!cwruecmp!ncoast!simpsong
CSNET: ncoast!simpsong@case.CSNET     
ARPA:  ncoast!simpsong%case.CSNET@Csnet-Relay.ARPA

pozar@hoptoad.UUCP (01/24/87)

    Sorry to post this, my mailer upchucked on ncoast.UUCP.

    I picked off the uuslave code.  Could you point me the direction of where
you got it from?   There seems to be some header files that I'm unfamiler
with and weren't included with the code.  Mucho functions I don't fully
know what they need, etc...
       Thanks

-- 
        Tim Pozar
UUCP    pozar@hoptoad.UUCP
Fido    125/406
USNail  KLOK-FM
	77 Maiden Lane
	San Francisco CA 94108
terrorist cryptography DES drugs cipher secret decode NSA CIA NRO IRS
coke crack pot LSD russian missile atom nuclear assassinate libyan RSA
(Thanks to Robert Bickford for the suggestion for the NSA line eater)

allbery@ncoast.UUCP (01/26/87)

As quoted from <1683@hoptoad.uucp> by pozar@hoptoad.uucp (Tim Pozar):
+---------------
|     Sorry to post this, my mailer upchucked on ncoast.UUCP.
| 
|     I picked off the uuslave code.  Could you point me the direction of where
| you got it from?   There seems to be some header files that I'm unfamiler
| with and weren't included with the code.  Mucho functions I don't fully
| know what they need, etc...
+---------------

I can't tell you what BBS it came from, but I'm pretty sure it's legit; I
was given a copy somewhat earlier on another machine (tdi2.uucp).

The posting mentioned the fact that we're all pretty well stumped by it.  (I
don't have a C compiler, so I can't translate it to C on my PC; and while I
could conceivably translate to Turbo Pascal (I have done so in the past with
C programs), pointer problems usually result and reasonable COMn: I/O seems
to choke at anything over 1200 baud (and is somewhat flaky at 1200).)

It *does* seem to be written for CP/M, as opposed to MS-DOS.  This might mean
Aztec or BDS C, the two most common for CP/M.

++Brandon
-- 
 ____   ______________
/    \ / __   __   __ \   Brandon S. Allbery	    <backbone>!ncoast!allbery
 ___  | /__> /  \ /  \    aXcess Co., Consulting    ncoast!allbery@Case.CSNET
/   \ | |    `--, `--,    6615 Center St. #A1-105 	   (...@relay.CS.NET)
|     | \__/ \__/ \__/    Mentor, OH 44060-4101     
\____/ \______________/   +1 216 781 6201

shapiro@oucs.UUCP (01/28/87)

What is uuslave.c? What is it supposed to do?
 
Thanks.
 
Brian Shapiro
Ohio University Computing and Learning Services
Athens Ohio  45710
 
UUCP:    !inhp4!cbatt!oucs!shapiro
Fido:    126/110
BITNET:  SHAPIROB@OUACCVMA

mjranum@osiris.UUCP (01/30/87)

In article <1943@ncoast.UUCP>, allbery@ncoast.UUCP (Brandon Allbery) writes:
> As quoted from <1683@hoptoad.uucp> by pozar@hoptoad.uucp (Tim Pozar):
> | 
> |    I picked off the uuslave code.  Could you point me the direction of where
> | you got it from?   There seems to be some header files that I'm unfamiler
> | with and weren't included with the code.  Mucho functions I don't fully
> | know what they need, etc...

	I took a bang at it and found that it makes a variety of system
calls that my Lattice C compiler doesn't support. On the other hand, if
anyone is interested in a totally kluged version, I have hacked, ifdef'ed,
and frobbed the darn thing so I think it will compile with Lattice or
Microsoft C. I could either send uuencoded executables, with no guarantee
of functionality, source, or both. Rather that post to the whole net,
just email to me if you're interested.

	Changes I had to make: no ioctl() or stat(). I commented out the
ioctl() and made a stat() look-alike. (uuslave uses stat largely to see
if things are there, rather than caring about modes, etc.)  I suppose there
*might* be a chance it would work if you used the DOS 'mode' command to
set baud rates first, *then* started uuslave. Other problem: I'm too 
busy to sort it out and figure what it does. I have added some comments,
but other than that it's still a totally undocumented gadget...

++mjr;
-- 
{decuac}!gouldsd!mjranum || {decuac}!osiris!mjranum

"It is better to shred the bugger than to bugger the shredder."
					-ancient doltic proverb.

mikes@sir-alan.UUCP (03/09/87)

If anyone knows how to invoke uuslave.exe so that it uses COM1: at 1200 or 9600
baud, please e-mail me the information.  I have the sources and a compiled
version, but do not understand Lattice C conventions.  Using 
"mode com1:12,n,8,1" and "uuslave -lcom1 {plus other options}" causes uuslave to
execute but there is no indication that the PC port is active.

Michael L. Squires                       Office: 814-724-3360
Department of Political Science          Home: 814-337-5528
Allegheny College
Meadville, PA 16335
 
uucp:  ..!decvax!cwruecmp!ncoast!{mikes,peng!sir-alan!mikes}
       ..!pitt!sir-alan!mikes

BITNET: mikes%sir-alan@pitt.UUCP