uuslave.c (Straight from the BBS in NJ)

simpsong at ncoast.UUCP simpsong at ncoast.UUCP
Sun Jan 18 02:16:37 AEST 1987


*** 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 at case.CSNET     
ARPA:  ncoast!simpsong%case.CSNET at 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 at case.CSNET     
ARPA:  ncoast!simpsong%case.CSNET at Csnet-Relay.ARPA



More information about the Comp.sources.unix mailing list