[mod.sources] 4.2BSD XMODEM programs

sources-request@panda.UUCP (05/13/86)

Mod.sources:  Volume 4, Issue 118
Submitted by: seismo!uwvax!nicmad!brown (Mr. Video)

#! /bin/sh
# This is a shell archive, meaning:
# 1. Remove everything above the #! /bin/sh line.
# 2. Save the resulting text in a file.
# 3. Execute the file with /bin/sh (not csh) to create the files:
#	README
#	xmodrec.1
#	xmodtran.1
#	Makefile
#	add.c
#	addcr.c
#	addlf.c
#	copy.c
#	cr.c
#	cr2lf.c
#	del.c
#	delcr.c
#	lf.c
#	lf2cr.c
#	receive.c
#	to_pc.c
#	to_vax.c
#	transmit.c
# This archive created: Mon May 12 23:22:53 1986
export PATH; PATH=/bin:$PATH
echo shar: extracting "'README'" '(684 characters)'
if test -f 'README'
then
	echo shar: will not over-write existing file "'README'"
else
cat << \SHAR_EOF > 'README'
To create the two xmodem programs, run:
	make all

To (compile and) install run:
	make install

There are two manual files: xmodtran.1 and xmodrec.1

The two compiled programs, xmodrec and xmodtran, will be moved to the
/usr/local directory.  If this is not where you want them, change the
Makefile $PATH variable to what you want for your system.

The programs are being used on a VAX 750 with BSD 4.2.  They are used
to transfer data between PCs and the VAX.

If you have any questions or comments, send UUCP mail to:

              ihnp4------\
            harvard-\     \
               seismo!uwvax!nicmad!brown
              topaz-/     /
             decvax------/

Mike Brown
SHAR_EOF
if test 684 -ne "`wc -c < 'README'`"
then
	echo shar: error transmitting "'README'" '(should have been 684 characters)'
fi
fi
echo shar: extracting "'xmodrec.1'" '(579 characters)'
if test -f 'xmodrec.1'
then
	echo shar: will not over-write existing file "'xmodrec.1'"
else
cat << \SHAR_EOF > 'xmodrec.1'
.TH XMODREC 1
.SH NAME
xmodrec \- receive file using XMODEM protocol
.SH SYNOPSIS
.B xmodrec
[
.B \-t
] filename
.SH DESCRIPTION
.I Xmodrec
is used to receive a file from another computer, ie, IBM PC or look-alike.
The computer from which the file is to be received must also have the
XMODEM protocol.
.PP
This version of XMODEM uses the checksum method of error detection.
.PP
Options:
.TP 6
.B  \-t
Remove the carriage returns from the incoming data.  Also removes the ^Z
end-of-file marker and any data after it.
.SH AUTHOR
Jim Hein {ihnp4,seismo}!uwvax!astroatc!nicmad!jhein
SHAR_EOF
if test 579 -ne "`wc -c < 'xmodrec.1'`"
then
	echo shar: error transmitting "'xmodrec.1'" '(should have been 579 characters)'
fi
fi
echo shar: extracting "'xmodtran.1'" '(614 characters)'
if test -f 'xmodtran.1'
then
	echo shar: will not over-write existing file "'xmodtran.1'"
else
cat << \SHAR_EOF > 'xmodtran.1'
.TH XMODTRAN 1
.SH NAME
xmodtran \- transmit a file using XMODEM protocol
.SH SYNOPSIS
.B xmodtran
[
.B \-t
] filename
.SH DESCRIPTION
.I Xmodtran
is used to transmit a file to another computer, ie, IBM PC or look-alike.
The computer to which the file is to be transmitted must also have the
XMODEM protocol.
.PP
This version of XMODEM uses the checksum method of error detection.
.PP
Options:
.TP 6
.B  \-t
Adds carriage returns to each line of data being transmitted.  Some computers
require that the text file have a CR/LF at the end of each line.
.SH AUTHOR
Jim Hein {ihnp4,seismo}!uwvax!astroatc!nicmad!jhein
SHAR_EOF
if test 614 -ne "`wc -c < 'xmodtran.1'`"
then
	echo shar: error transmitting "'xmodtran.1'" '(should have been 614 characters)'
fi
fi
echo shar: extracting "'Makefile'" '(1340 characters)'
if test -f 'Makefile'
then
	echo shar: will not over-write existing file "'Makefile'"
else
cat << \SHAR_EOF > 'Makefile'
FILES	= receive.c transmit.c addcr.c delcr.c add.c del.c\
          lf2cr.c cr.c lf.c cr2lf.c
OBJS	= receive.o transmit.o addcr.o delcr.o add.o del.o\
          lf2cr.o cr.o lf.o cr2lf.o
LIBS 	= -lcurses -ltermlib
FLAGS	= -O -c -I/sys/h
PATH	= /usr/local
all:		receive transmit
clean:
		rm -f $(OBJS) receive transmit
pr:
		lpr -Plp $(FILES)
install:	receive transmit
		strip receive
		cp receive $(PATH)/xmodrec
		strip transmit
		cp transmit $(PATH)/xmodtran
receive.o:	receive.c
		cc $(FLAGS) receive.c
receive:	receive.o del.o lf.o
		cc -O -o receive del.o lf.o receive.o $(LIBS)
transmit.o:	transmit.c
		cc $(FLAGS) transmit.c
transmit:	transmit.o add.o cr.o
		cc -O -o transmit add.o cr.o transmit.o $(LIBS)
addcr.o:	addcr.c
		cc $(FLAGS) addcr.c
addcr:		addcr.o add.o
		cc -O -o addcr add.o addcr.o
		strip addcr
		cp addcr $(PATH)
delcr.o:	delcr.c
		cc $(FLAGS) delcr.c
delcr:		delcr.o del.o
		cc -O -o delcr del.o delcr.o
		strip delcr
		cp delcr $(PATH)
add.o:		add.c
		cc $(FLAGS) add.c
del.o:		del.c
		cc $(FLAGS) del.c
cr.o:		cr.c
		cc $(FLAGS) cr.c
lf2cr.o:	lf2cr.c
		cc $(FLAGS) lf2cr.c
lf2cr:		lf2cr.o cr.o
		cc -O -o lf2cr lf2cr.o cr.o
		strip lf2cr
		cp lf2cr $(PATH)
lf.o:		lf.c
		cc $(FLAGS) lf.c
cr2lf.o:	cr2lf.c
		cc $(FLAGS) cr2lf.c
cr2lf:		cr2lf.o lf.o
		cc -O -o cr2lf cr2lf.o lf.o
		strip cr2lf
		cp cr2lf $(PATH)
SHAR_EOF
if test 1340 -ne "`wc -c < 'Makefile'`"
then
	echo shar: error transmitting "'Makefile'" '(should have been 1340 characters)'
fi
fi
echo shar: extracting "'add.c'" '(881 characters)'
if test -f 'add.c'
then
	echo shar: will not over-write existing file "'add.c'"
else
cat << \SHAR_EOF > 'add.c'
#
# include <file.h>

# define CR	13
# define NL	10
# define CTRL_Z 26

char *
ADDCR(file)
char *file; {
	int id, oid;
	char buf[512], *index();
	static char temp[11];
	char *end = "\r\n";
	int ln, cnt;
	register char *ptr = buf, *od;
	register i, count;

	strcpy(temp,"tempXXXXXX");
	mktemp(temp);
	if ((oid = open(temp,O_CREAT | O_WRONLY,0644)) < 0) {
		perror(temp);
		unlink(temp);
		exit(-1);
	}
	if ((id = open(file,O_RDONLY,0644)) < 0) {
		perror(file);
		unlink(temp);
		exit(-1);
	}
			
	while (ln = read(id,ptr,512)) {
		count = 0;
		while ( od = index(ptr,NL) ) {
			if (od > &buf[ln]) break;
			*od = '\0';
			cnt = strlen(ptr);
			count += cnt;
			write(oid, ptr, cnt);
			write(oid, end, 2);
			ptr = ++od;
			count++;
		}
		if (count = ln - count)
			write(oid,ptr,count);
		ptr = buf;
	}
	*ptr = CTRL_Z;
	write(oid,ptr,1);

	close(oid); close(id);
	return(temp);
}
SHAR_EOF
if test 881 -ne "`wc -c < 'add.c'`"
then
	echo shar: error transmitting "'add.c'" '(should have been 881 characters)'
fi
fi
echo shar: extracting "'addcr.c'" '(219 characters)'
if test -f 'addcr.c'
then
	echo shar: will not over-write existing file "'addcr.c'"
else
cat << \SHAR_EOF > 'addcr.c'
main(argc,argv)
int argc;
char *argv[]; {
	char buf[512];
	register int i;

	for (i = 1; i < argc; i++) {
		strcpy(buf,"mv ");
		strcat(buf,ADDCR(argv[i]));
		strcat(buf," ");
		strcat(buf,argv[i]);
		system(buf);
	}
}
SHAR_EOF
if test 219 -ne "`wc -c < 'addcr.c'`"
then
	echo shar: error transmitting "'addcr.c'" '(should have been 219 characters)'
fi
fi
echo shar: extracting "'addlf.c'" '(935 characters)'
if test -f 'addlf.c'
then
	echo shar: will not over-write existing file "'addlf.c'"
else
cat << \SHAR_EOF > 'addlf.c'
#
# define CR	13
# define NL	10

main(argc,argv)
int argc;
char *argv[]; {
	int id, oid;
	char buf[512];
	char *temp, *index();
	char *end = "\r\n";
	int ln, cnt;
	register char *ptr, *od;
	register i, count;

	for (i = 1; i < argc; i++) {
		if ((id = open(argv[i],0)) < 0) {
			printf("CAN NOT OPEN FILE `%s'. . . . .\n",argv[i]);
			break;
		} else {
			temp = "tempXXXXXX";
			mktemp(temp);
			oid = creat(temp,0644);
			
			ptr = buf;
			while (ln = read(id,ptr,512)) {
				count = 0;
				while ( od = index(ptr,CR) ) {
					if (od > &buf[ln]) break;
					*od = '\0';
					cnt = strlen(ptr);
					count += cnt;
					write(oid, ptr, cnt);
					write(oid, end, 2);
					ptr = ++od;
					count++;
				}
				if (count = ln - count)
					write(oid,ptr,count);
				ptr = buf;
			}

			close(oid); close(id);
			strcpy(buf,"mv ");
			strcat(buf,temp);
			strcat(buf," ");
			strcat(buf,argv[i]);
			system(buf);
			unlink(temp);
		}
	}
}
SHAR_EOF
if test 935 -ne "`wc -c < 'addlf.c'`"
then
	echo shar: error transmitting "'addlf.c'" '(should have been 935 characters)'
fi
fi
echo shar: extracting "'copy.c'" '(6082 characters)'
if test -f 'copy.c'
then
	echo shar: will not over-write existing file "'copy.c'"
else
cat << \SHAR_EOF > 'copy.c'
#
#include <stdio.h>
#include <sys/types.h>
#include <sys/dir.h>
#include <sys/stat.h>
#include <signal.h>
#include <pwd.h>
#include <grp.h>


/*
**	copy - copy a  subtree to a new directory
**	preserving ownership and dates (access and modification only)
**
**	Keith Thompson	- Feb 7, 1981
**	revised		- May 1, 1981	(added options)
**
**	Options:	(can only be used by superuser)
**
**		-o login_name	make all files owned by 'login_name'
**		-u login_name	make all user ownership 'login_name'
**		-g group_name	make all group ownership 'group_name'
*/

#define BSIZE 4096

#define DEST (argc-1)
#define SRC  (argc-2)

#define EXISTS 0
#define READABLE 4
#define WRITEABLE 2
#define EXECUTABLE 1

#define MODE 0666
#define READ 0

#define strncat strcatn
extern char *strcat();
extern char *strcpy();

int superuser;
int user;
int group;

main(argc,argv)
int argc;
char **argv;
{
	register i,j,badarg;
	register struct passwd *pw;
	extern struct passwd *getpwnam();

	signal(SIGINT,SIG_IGN);
	signal(SIGHUP,SIG_IGN);
	signal(SIGQUIT,SIG_IGN);
	signal(SIGTERM,SIG_IGN);
	signal(SIGPIPE,SIG_IGN);

	user = getuid();
	superuser = user == 0;
	group = superuser ? 0 : getgid();

	badarg = 0;

	if(argc < 3) {
		fprintf(stderr,"usage: %s [ options ] src_dir dst_dir\n",
				argv[0]);
		exit(2);
	}

	if(superuser) for(i=1 ; i<SRC; i = j) {
		register char *ptr;

		ptr = argv[i];
		j = i+1;
		if(j >= SRC) {
			fprintf(stderr,"Invalid argument: %s\n",argv[i]);
			badarg++;
			break;
		}

		if(*ptr++ != '-') {
			fprintf(stderr,"Invalid argument: %s\n",argv[i]);
			badarg++;
			continue;
		}

		pw = getpwnam(argv[j]);
		j++;

		switch(*ptr) {

		case 'o':
			user = pw->pw_uid;
			group = pw->pw_gid;
			break;

		case 'u':
			user = pw->pw_uid;
			break;

		case 'g':
			group = pw->pw_gid;
			break;

		default:
			fprintf(stderr,"Bad option: %c\n",*(ptr-1));
			badarg++;
		}
	}

	if(badarg) exit(4);


	if(!access(argv[DEST],EXISTS)) {
		fprintf(stderr,"%s already exists\n",argv[DEST]);
		exit(2);
	}

	if(access(argv[SRC],READABLE)) {
		fprintf(stderr,"%s not readable\n",argv[SRC]);
		exit(2);
	}


	copy(argv[SRC],argv[DEST]);
}

copy(src,dst)
char *src,*dst;
{
	struct direct dirbuf;
	union {
		char *c;
		struct direct *d;
	} u_dir;
	struct stat statbuf;
	struct stat srcstat;
	char src_file[256],dst_file[256];
	int src_fd;

	u_dir.d = &dirbuf;

	if(stat(src,&srcstat)) {
		perror(src);
		exit(4);
	}

	if((srcstat.st_mode&S_IFMT) != S_IFDIR) {
		fprintf(stderr,"copy: %s is not a directory\n",src);
		exit(4);
	}

	/*
	**	src exists and is readable
	**	now make the target directory
	*/

	if(mkdir(dst)) {
		exit(4);
	}

	change(dst, &srcstat);

	if((src_fd = open(src,0)) < 0) {
		perror(src);
		exit(4);
	}

	while(read(src_fd,u_dir.c,sizeof(dirbuf)) == sizeof(dirbuf)) {

		/*
		**	test to see if the directory slot is in use
		*/

		if(!dirbuf.d_ino)  {
			continue;
		}

		/*
		**	skip "." & "..", mkdir takes care of them
		*/

		if(!strcmp(".",dirbuf.d_name)
		|| !strcmp("..",dirbuf.d_name)) {
			continue;
		}

		/*
		**	we have a file or directory to copy now
		*/

		mkname(src_file,src,dirbuf.d_name);
		mkname(dst_file,dst,dirbuf.d_name);

		if(stat(src_file,&statbuf)) {
			perror(src_file);
			exit(4);
		}

		if(!superuser && access(src_file,READABLE)) {
			fprintf(stdout,"copy: no access %s\n",src_file);
			continue;
		}

		/*
		**	do the copy depending on the file type
		**
		**	directory:	recursively copy the subtree
		**	regular:	copy the file
		**	special:	make a new node (super user only)
		*/

		switch((statbuf.st_mode)&S_IFMT) {

		case S_IFDIR:
			copy(src_file,dst_file);
			break;

		case S_IFCHR:
		case S_IFBLK:
			if(!superuser) break;

			fprintf(stdout,"making special file %s\n",dst_file);

			if(mknod(dst_file,(int) statbuf.st_mode,
				statbuf.st_rdev)) {
			}
			change(dst_file, &statbuf);
			utime(dst_file,&(statbuf.st_atime));
			if(chmod(dst_file,(int) statbuf.st_mode)) {
				perror(dst_file);
				exit(4);
			}
			break;

		case S_IFREG:
			filecopy(src_file,dst_file);
			change(dst_file, &statbuf);
			utime(dst_file,&(statbuf.st_atime));
			if(chmod(dst_file,(int) statbuf.st_mode)) {
				perror(dst_file);
				exit(4);
			}
			break;

		default:
			fprintf(stderr,"bad file type: %s\n",src_file);
		}

	}
	utime(dst,&(srcstat.st_atime));
	if(chmod(dst,(int) srcstat.st_mode)) {
		perror(dst_file);
		exit(4);
	}

	close(src_fd);
}


mkname(dst,str1,str2)
char *dst,*str1,*str2;
{
	dst[0] = '\0';
	strcat(dst,str1);
	strcat(dst,"/");
	strncat(dst,str2,14);

}

filecopy(src,dst)
char *src,*dst;
{
	register int src_fd,dst_fd;
	char block[BSIZE];
	register int size;

	if((src_fd = open(src,READ)) < 0) {
		perror(src);
		exit(4);
	}

	if((dst_fd = creat(dst,MODE)) < 0) {
		perror(dst);
		exit(4);
	}

	while((size = read(src_fd,block,BSIZE)) > 0) {
		if(write(dst_fd,block,size) != size) {
			perror(dst);
			exit(4);
		}
	}

	if(size < 0) {
		perror(src);
		exit(4);
	}

	if(close(src_fd)) {
		perror(src);
		exit(4);
	}
	if(close(dst_fd)) {
		perror(src);
		exit(4);
	}

}

change(file,status)
char *file;
struct stat *status;
{
	int u,g;

	u = user;
	g = group;

	if(superuser) {
		if(!user) {
			u = status->st_uid;
		}
		if(!group) {
			g = status->st_gid;
		}
	}
	if(chown(file, u, g)) {
		perror(file);
		exit(4);
	}
}


mkdir(d)
register char *d;
{
	char pname[128], dname[128];
	register i, slash = 0;

	pname[0] = '\0';
	for(i = 0; d[i]; ++i)
		if(d[i] == '/')
			slash = i + 1;
	if(slash)
		strncpy(pname, d, slash);
	strcpy(pname+slash, ".");
	if (access(pname, WRITEABLE)) {
		fprintf(stderr,"mkdir: cannot access %s\n", pname);
		return(-1);
	}

	if ((mknod(d, 040777, 0)) < 0) {
		fprintf(stderr,"mkdir: cannot make directory %s\n", d);
		return(-1);
	}
	strcpy(dname, d);
	strcat(dname, "/.");

	if((link(d, dname)) < 0) {
		fprintf(stderr, "mkdir: cannot link %s\n", dname);
		unlink(d);
		return(-1);
	}
	strcat(dname, ".");
	if((link(pname, dname)) < 0) {
		fprintf(stderr, "mkdir: cannot link %s\n",dname);
		dname[strlen(dname)] = '\0';
		unlink(dname);
		unlink(d);
		return(-1);
	}

	return(0);
}
SHAR_EOF
if test 6082 -ne "`wc -c < 'copy.c'`"
then
	echo shar: error transmitting "'copy.c'" '(should have been 6082 characters)'
fi
fi
echo shar: extracting "'cr.c'" '(778 characters)'
if test -f 'cr.c'
then
	echo shar: will not over-write existing file "'cr.c'"
else
cat << \SHAR_EOF > 'cr.c'
#
#include <file.h>

#define CR	13
#define NL	10

char *
LF2CR(file)
char *file; {
	int id, oid;
	char buf[512], *index();
	static char temp[11];
	register char *ptr = buf;
	register ln, count;

	strcpy(temp,"tempXXXXXX");
	mktemp(temp);
	if ((oid = open(temp,O_CREAT | O_WRONLY,0644)) < 0) {
		perror(temp);
		unlink(temp);
		exit(-1);
	}
	if ((id = open(file,O_RDONLY,0644)) < 0) {
		perror(file);
		unlink(temp);
		exit(-1);
	}
			
	count = 0;
	while (ln = read(id,ptr,512)) {
		while ( ptr = index(ptr,NL) ) {
			if (ptr > &buf[ln]) break;
			*ptr = CR;
		}
		write(oid,ptr = buf,ln);
		count += ln;
	}
	if (ln = count % 128) {
		count = 128 - ln;
		for (ln = 0, ptr = buf; ln < count ; ln++, *ptr++ = ' ');
		write(oid,buf,ln);
	}

	close(oid); close(id);
	return(temp);
}
SHAR_EOF
if test 778 -ne "`wc -c < 'cr.c'`"
then
	echo shar: error transmitting "'cr.c'" '(should have been 778 characters)'
fi
fi
echo shar: extracting "'cr2lf.c'" '(129 characters)'
if test -f 'cr2lf.c'
then
	echo shar: will not over-write existing file "'cr2lf.c'"
else
cat << \SHAR_EOF > 'cr2lf.c'
main(argc,argv)
int argc;
char *argv[]; {
	char buf[512];
	register int i;

	for (i = 1; i < argc; i++) {
		CR2LF(argv[i]);
	}
}
SHAR_EOF
if test 129 -ne "`wc -c < 'cr2lf.c'`"
then
	echo shar: error transmitting "'cr2lf.c'" '(should have been 129 characters)'
fi
fi
echo shar: extracting "'del.c'" '(1030 characters)'
if test -f 'del.c'
then
	echo shar: will not over-write existing file "'del.c'"
else
cat << \SHAR_EOF > 'del.c'
#
# include <file.h>

# define CR	13
# define NL	10
# define CTRL_Z	26
# define BLOCK	512

DELCR(file)
char *file; {
	int id, oid;
	char buf[BLOCK+10], *index();
	static char temp[11];
	register char *ptr = buf, *od, *cz;
	register int len;

	strcpy(temp,"tempXXXXXX");
	mktemp(temp);
	if ((oid = open(temp,O_CREAT | O_WRONLY,0644)) < 0) {
		perror(temp);
		unlink(temp);
		exit(-1);
	}

	if ((id = open(file,O_RDONLY,0644)) < 0) {
		perror(file);
		unlink(temp);
		exit(-1);
	}

	while ((len = read(id,ptr,BLOCK)) > 0) {
		*(ptr + len) = 0;
		while ( od = index(ptr,CR) ) {
			*od = '\0';
			if (cz = index(ptr,CTRL_Z)) {
				*cz = '\0';
				write(oid, ptr, strlen(ptr));
			 	goto OUT;
			}
			write(oid, ptr, strlen(ptr));
			ptr = ++od;
		}
		if (cz = index(ptr,CTRL_Z)) {
			*cz = '\0';
			write(oid, ptr, strlen(ptr));
		 	goto OUT;
		}
		if (len = strlen(ptr))
		write(oid, ptr, len);
		ptr = buf;
	}

OUT:
	close(oid); close(id);
	strcpy(buf,"mv ");
	strcat(buf,temp);
	strcat(buf," ");
	strcat(buf,file);
	system(buf);
}
SHAR_EOF
if test 1030 -ne "`wc -c < 'del.c'`"
then
	echo shar: error transmitting "'del.c'" '(should have been 1030 characters)'
fi
fi
echo shar: extracting "'delcr.c'" '(129 characters)'
if test -f 'delcr.c'
then
	echo shar: will not over-write existing file "'delcr.c'"
else
cat << \SHAR_EOF > 'delcr.c'
main(argc,argv)
int argc;
char *argv[]; {
	char buf[512];
	register int i;

	for (i = 1; i < argc; i++) {
		DELCR(argv[i]);
	}
}
SHAR_EOF
if test 129 -ne "`wc -c < 'delcr.c'`"
then
	echo shar: error transmitting "'delcr.c'" '(should have been 129 characters)'
fi
fi
echo shar: extracting "'lf.c'" '(1252 characters)'
if test -f 'lf.c'
then
	echo shar: will not over-write existing file "'lf.c'"
else
cat << \SHAR_EOF > 'lf.c'
#
#include <file.h>

#define CR	13
#define NL	10
#define BLOCK	512
#define STOP	0xff

CR2LF(file)
char *file; {
	int id, oid;
	char buf[BLOCK+1], *index();
	char temp[11], temp1[11];
	register char *ptr = buf;
	register int len;

	strcpy(temp,"tempXXXXXX");
	mktemp(temp);
	if ((oid = open(temp,O_CREAT | O_RDWR,0644)) < 0) {
		perror(temp);
		unlink(temp);
		exit(-1);
	}

	if ((id = open(file,O_RDONLY,0644)) < 0) {
		perror(file);
		unlink(temp);
		exit(-1);
	}

	buf[BLOCK] = 0;
	while ((len = read(id,ptr,BLOCK)) > 0) {
		while ( ptr = index(ptr,CR) ) {
			*ptr = NL;
		}
		write(oid, ptr = buf, len);
	}
	
	close(id);
	lseek(oid,1,L_XTND);
	do {
		lseek(oid,-2,L_INCR);
		read(oid,ptr,1);
	} while ( *ptr != NL );
	*ptr = STOP;
	write(oid,ptr,1);
	lseek(oid,0,L_SET);

	strcpy(temp1,"tempXXXXXX");
	mktemp(temp1);
	if ((id = open(temp1,O_CREAT | O_WRONLY,0644)) < 0) {
		perror(temp1);
		unlink(temp1);
		unlink(temp);
		exit(-1);
	}

	ptr = buf;
	while ((len = read(oid,ptr,BLOCK)) > 0) {
		if (ptr = index(ptr,STOP))  {
			*ptr = 0;
			write(id, buf, strlen(buf));
			break;
		}
		write(id, ptr = buf, len);
	}

	close(oid); close(id);
	strcpy(buf,"mv ");
	strcat(buf,temp1);
	strcat(buf," ");
	strcat(buf,file);
	system(buf);
	unlink(temp);
}
SHAR_EOF
if test 1252 -ne "`wc -c < 'lf.c'`"
then
	echo shar: error transmitting "'lf.c'" '(should have been 1252 characters)'
fi
fi
echo shar: extracting "'lf2cr.c'" '(219 characters)'
if test -f 'lf2cr.c'
then
	echo shar: will not over-write existing file "'lf2cr.c'"
else
cat << \SHAR_EOF > 'lf2cr.c'
main(argc,argv)
int argc;
char *argv[]; {
	char buf[512];
	register int i;

	for (i = 1; i < argc; i++) {
		strcpy(buf,"mv ");
		strcat(buf,LF2CR(argv[i]));
		strcat(buf," ");
		strcat(buf,argv[i]);
		system(buf);
	}
}
SHAR_EOF
if test 219 -ne "`wc -c < 'lf2cr.c'`"
then
	echo shar: error transmitting "'lf2cr.c'" '(should have been 219 characters)'
fi
fi
echo shar: extracting "'receive.c'" '(4527 characters)'
if test -f 'receive.c'
then
	echo shar: will not over-write existing file "'receive.c'"
else
cat << \SHAR_EOF > 'receive.c'
/*
**	receive filename
*/
#
# include <file.h>
# include <curses.h>
# include <signal.h>
# include <time.h>
# include <setjmp.h>

# define	SOH	0x1
# define	NAK	0x15
# define	ACK	0x6
# define	EOT	0x4
# define	CANCEL	0x18

char filename[64];
int retries;		/* retries counter */
int seq_num;		/* sequence number */
int caught();		/* interrupt routine, called if haven't received a
			   block in 1 second */
struct sigvec vec;
jmp_buf env;

main(argc,argv)
int argc;
char *argv[]; {

	int fd;
	char c;
	register int i;

	if (!((argc == 2) || (argc == 3))) {
		printf("ILLEGAL NUMBER OF ARGUMENTS.\n");
		printf("SYNOPSIS: to_vax_x [-t] [-m] filename\n");
		exit(-1);
	}

	if (argc == 3) {
		if (strcmp(argv[1],"-t") && strcmp(argv[1],"-m")) {
			printf("bad argument `%s'\n",argv[1]);
			printf("SYNOPSIS: to_vax_x [-t] [-m] filename\n");
			exit(-1);
		}
	}

	strcpy(filename,argv[argc-1]);
	if ((fd = open(filename,O_WRONLY|O_CREAT|O_TRUNC,0644)) < 0) {
		perror(filename);
		exit(-1);
	}

	initscr();
	raw();			/* set terminal to 8-bit I/O */
	noecho();

/*
**	Ignore interrupts from the user.
**	If the user could delete this program the terminal
**	would be left in a undiserable state of mind.
*/

	vec.sv_handler = caught;
	vec.sv_mask = vec.sv_onstack = 0;
	sigvec(SIGALRM,&vec,(struct sigvec *)0);

	sigsetmask(-1 ^ (1 << (SIGALRM-1)));	/* enable alarm signal */

	c = NAK;
	retries = 0;
	if (setjmp(env)) {
	    write(1,&c,1);
	    if (retries++ > 10) {
		reset(1); 	     /* restore terminal to normal state */
		printf("Can not get reply from transmitter\n");
		exit(0); 
	    }
	}
	
	SET_TIMER(10);
	read(0,&c,1);
	DISABLE_TIMER();

	seq_num = 1; retries = 0;
	for(;;) {

		if (retries == 10) {
			c = CANCEL;
			write(1,&c,1);
			reset(1);
			printf("Terminated after 10 retries\r\n");
			exit(-1);
		}

		switch( c & 0x7f ) {
			case SOH:
				BLOCK(fd);
				break;
			case CANCEL:
				printf("Received CANCEL signal\r\n");
				reset(1);
				exit(-1);
			case EOT:
				c = ACK;
				write(1,&c,1);
				reset(0);
				goto END;
			default:
				sleep(2);	/* wait for a bit */
				noraw();	/* flush input buffer */
				raw();
				c = NAK;
				write(1,&c,1);
				retries++;
				break;
		}
		c = NAK;
		if (setjmp(env)) {
		    write(1,&c,1);
		    if (retries++ > 10) {
			reset(1); 	     /* restore terminal to normal state */
			printf("Can not get reply from transmitter\n");
			exit(0); 
		    }
		}
	
		SET_TIMER(10);
		read(0,&c,1);
	        DISABLE_TIMER();
		
	}
END:

	close(fd);
	if (argc == 3) {
		switch( argv[1][1] ) {
			case 't':
				printf("Deleting carriage returns\n");
				DELCR(filename);
				break;
			case 'm':
				printf("Changing cr's to lf's\n");
				CR2LF(filename);
		}
	}
}

BLOCK(fd) 
int fd; {
	
	register i;
	register char *p;
	char block[131];
	char c;
	int xsum;

	retries = 0;		/* start fresh */

	/* used to be 1 */
	SET_TIMER(10);
	if (setjmp(env)) {
	    noraw();
	    raw();
	    c = NAK;
	    write(1,&c,1);
	    retries++;
	    return;
	} else {
	    i = read(0,block,131);
	    while( i < 131 ) {
	    	i += read(0,&block[i],131-i);	/* data block */
	    }
	    DISABLE_TIMER();
	}
	
	if ( (block[0] & 0xff) != seq_num ) {
		i = (seq_num ? seq_num - 1 : 255);
		if ((block[0] & 0xff) != i ) {
			if ( (block[1] & 0xff) != (255 - seq_num) ) {
				i = 255 - i;
				if ((block[1] & 0xff) == i ) {
					c = NAK;
					write(1,&c,1);
					retries++;
					return;
				}
				c = CANCEL; 	/* loss of synchronization */
				write(1,&c,1);
				reset(1);
				exit(-1);
			}
		}
		retries++;
		goto leave;
	}

	if ( (block[1] & 0xff) != (255 - seq_num) ) {
		c = NAK;
		write(1,&c,1);
		retries++;
		return;
	}
	
	xsum = 0;
	for (i = 0, p = &block[2]; i < 128; i++) xsum += (*p++ & 0xff);
	xsum &= 0xff;
	if ( (block[130] & 0xff) != xsum ) {
		c = NAK;
		write(1,&c,1);
		retries++;
		return;
	}

	write(fd,&block[2],128);
	retries = 0;
	seq_num = ++seq_num % 256;
leave:
	c = ACK;
	write(1,&c,1);
}

reset(remove) 
int remove; {
	
	DISABLE_TIMER();
	sigsetmask(0);
	vec.sv_handler = SIG_DFL;
	vec.sv_mask = vec.sv_onstack = 0;
	sigvec(SIGALRM,&vec,(struct sigvec *)0);
	noraw(); echo();
	endwin();
	if (remove) unlink(filename);
}
	

caught() {
	longjmp(env,1);
}

SET_TIMER(secs) 
int secs; {
	struct itimerval val;

	val.it_value.tv_sec = secs;
	val.it_value.tv_usec = secs * 1000;
	timerclear(&val.it_interval);
	setitimer(ITIMER_REAL,&val,(struct itimerval *)0);
}

DISABLE_TIMER() {
	struct itimerval val;

	timerclear(&val.it_value);
	setitimer(ITIMER_REAL,&val,(struct itimerval *)0);
}
SHAR_EOF
if test 4527 -ne "`wc -c < 'receive.c'`"
then
	echo shar: error transmitting "'receive.c'" '(should have been 4527 characters)'
fi
fi
echo shar: extracting "'to_pc.c'" '(5027 characters)'
if test -f 'to_pc.c'
then
	echo shar: will not over-write existing file "'to_pc.c'"
else
cat << \SHAR_EOF > 'to_pc.c'
#
# include <curses.h>
# include <signal.h>
# include <file.h>

# define	ST_BLK	33		/* ! */
# define	READY	34		/* " */
# define	OKAY	35		/* # */
# define	NOT_OK	36		/* $ */
# define	CANCEL	37		/* % */
# define	CR	13		/* \r */
# define	pad "    "

int seq_num, old, flags;
char buf[95], seq[4], filename[64];

main(argc,argv)
int argc;
char *argv[]; {

	int fd;
	register i;
	register char *ptr;
	char *ADDCR();
	char c, chunck[45];
	char *MK_SEQ(), *MK_START(), *itos();
	int lim, pid;
	int first = 1;

	flags = argc;
	if (!((argc == 2) || (argc == 3))) {
		printf("ILLEGAL NUMBER OF ARGUMENTS.\n");
		printf("SYNOPSIS: to_pc [-t] filename\n");
		exit(-1);
	}

	if (argc == 2) strcpy(filename,argv[1]);  /* don't put in CR's */
	else { 
		if (strcmp(argv[1],"-t")) {
			printf("bad argument `%s'\n",argv[1]);
			printf("SYNOPSIS: to_pc [-t] filename\n");
			exit(-1);
		}
		printf("Adding carriage returns, wait .......\n");
		strcpy(filename,ADDCR(argv[2]));
	}

	if ((fd = open(filename,O_RDONLY,0644)) < 0) {
		perror(filename);
		exit(-1);
	}

	printf("\nPress Alt-F6 to transmit file to PC.\n");

	initscr();
	crmode();	/* set terminal to unbuffered I/O */

/*
**	Ignore interrupts from the user.
**	If the user could delete this program the terminal
**	would be left in a undiserable state of mind.
*/
	sigsetmask( -1 );    /* ignore all signals */

	if ((pid = fork()) == 0) {   /* child sends ready prompt */
		sleep(8); i = 0;
		strcpy(buf,"\"\r");
		while (1) {
			write(1, buf, 2);
			sleep(2);
			if ( i++ == 30 ) break;  /* not receiving ready character */
		}
		RESET(); 	    /* restore terminal to normal state */
		kill(0,SIGKILL);    /* kill all processes */
	}

	for(;;) {  		/* wait for ready character */
		READ(buf);	/* if not received in 68 sec's, program terminates */
		if (buf[0] == OKAY) break;
	}

	kill(pid,SIGKILL);  /* received ok response, so kill child */
	wait(0);

	seq_num = 0; strcpy(chunck,argv[argc-1]); lim = strlen(chunck);
	do {			 /* make 90 character block */

		ptr = MK_START();			/* make start of block */
		if (first) {			/* header record */
			strcpy(ptr,"HH");
			strcat(ptr,chunck);
			ptr = lim + &buf[6];
			first = 0;
		} else {
			if (lim < 5) strcat(ptr,"0");
			strcat(ptr,itos( 2 * lim ));
			ptr = &buf[6];
			for (i = 0; i < lim; i++) {
				c = (chunck[i] & 0xf0) / 16 + '0';
				*ptr++ = c > '9' ? c + 7 : c;
				c = (chunck[i] & 0xf) + '0';
				*ptr++ = c > '9' ? c + 7 : c;
			}
		}

		strcat(ptr,MK_SEQ(MK_XSUM(ptr)));

		WRITE();
		WAIT(chunck);
		ERR_CHECK(chunck);

	} while ( (lim = read(fd,chunck,40)) > 0 );

	ptr = MK_START();
	strcat(ptr,"EE");
	ptr = &buf[6];
	strcat(ptr,MK_SEQ(MK_XSUM(ptr)));
	WRITE();
	READ(chunck);
	ERR_CHECK(chunck);

	RESET();

	close(fd);
}

WAIT(s)
char *s; {
	int pid;
	register i;

	if ((pid = fork()) == 0) {
		i = 1;
		while (i++ < 10) {
			WRITE();
		}
		sleep(10);
		LEAVE();
		kill(0,SIGKILL);    /* kill all processes */
	}

	READ(s);
	kill(pid,SIGKILL);          /* received response, kill child */
	wait(0);
}


MK_XSUM(s) 
char *s; {
	register xsum;
	register char *ptr;

	ptr = s;
	while ( ptr < &buf[86] ) *ptr++ = ' ';   /* pad buffer with blanks */
	xsum = 0; *ptr = '\0'; ptr = buf;
	while ( *ptr )  			 /* compute check sum */
		xsum = (xsum ^ *ptr++) & 0177;
	return(xsum);
}

char *MK_START() {
	register char *ptr;

	ptr = buf;
	*ptr = ST_BLK; *(ptr + 1) = '\0';
	seq_num = ++seq_num % 1000;
	strcpy(seq,MK_SEQ(seq_num));
	strcat(ptr,seq);
	return( &buf[4] );       /* return address to record type */
}

ERR_CHECK(resp)
char *resp; {
	char ok[6];
	int count = 1;

	while (*resp == NOT_OK) {
		if (count++ > 10) {     /* tried 10 times so exit */
			LEAVE(); exit(0);
		}
		WRITE();
		WAIT(resp);
	}

	strcpy(ok,"#"); strcat(ok,seq); strcat(ok,"#");
	count = 1;
	while (strncmp(ok,resp,5)) {
		/* used to be a literal control X */
		if (*resp == '\030') { /* user terminated transfer Alt-F6 */
			RESET(); exit(0);
		}
		if (*resp == CANCEL) { /* programs not in synch */
			RESET(); exit(0);
		}  
		if (count++ > 10) {    /* gave up, tried ten times */
			LEAVE(); exit(0);
		}
		WRITE();
		WAIT(resp);
	}
}


LEAVE() {
	register char *ptr;

	ptr = MK_START();
	strcat(ptr,"XX");
	ptr = &buf[6];
	strcat(ptr,MK_SEQ(MK_XSUM(ptr)));
	WRITE();
	RESET();
}


char *MK_SEQ(i)
int i; {
	char *itos();
	static char s[3];

	if ( i < 100 ) strcpy(s,"0");
	else s[0] = '\0';
	if ( i < 10 ) strcat(s,"0");
	strcat(s,itos(i));
	return( s );
}

READ(s)
register char *s; {
	
	char c;
	while (read( 0, s++, 1) > 0) {      /* read characters until a CR is read */
		c = *(s-1);
		if ((c == '\n') || (c == CR)) break;
	}
	*s = '\0';
}

WRITE() {

	buf[89] = CR; buf[90] = '\0';
	write( 1, buf, 90);
}

RESET() {

	if (flags == 3) unlink(filename);
	endwin();
}

char *itos(i1)
int	i1;
{
	register char	*a;
	register int	i;
	static char	buf[10];

	i = i1;
	if (i < 0)
		i = -i;

	a = &buf[sizeof buf - 1];
	*a-- = '\0';
	do
	{
		*a-- = i % 10 + '0';
		i /= 10;
	} while (i);
	if (i1 < 0)
		*a-- = '-';

	a++;
	return (a);
}
SHAR_EOF
if test 5027 -ne "`wc -c < 'to_pc.c'`"
then
	echo shar: error transmitting "'to_pc.c'" '(should have been 5027 characters)'
fi
fi
echo shar: extracting "'to_vax.c'" '(3655 characters)'
if test -f 'to_vax.c'
then
	echo shar: will not over-write existing file "'to_vax.c'"
else
cat << \SHAR_EOF > 'to_vax.c'
#
# include <file.h>
# include <curses.h>
# include <signal.h>

# define	ST_BLK	33
# define	READY	34
# define	OKAY	35
# define	NOT_OK	36
# define	CANCEL	37
# define	CR	13
# define	ctoi(c)	(c - '0' > 9 ? c - '0' - 7 : c - '0')

char filename[64];
int old;
main(argc,argv)
int argc;
char *argv[]; {

	int fd;
	register i;
	register char *ptr, *op;
	char buf[512], seq[4];
	char *index();
	int xsum, lim, old_seq, pid;

	if (!((argc == 2) || (argc == 3))) {
		printf("ILLEGAL NUMBER OF ARGUMENTS.\n");
		printf("SYNOPSIS: to_vax [-t] filename\n");
		exit(-1);
	}

	if (argc == 3) {
		if (strcmp(argv[1],"-t")) {
			printf("bad argument `%s'\n",argv[1]);
			printf("SYNOPSIS: to_vax [-t] filename\n");
			exit(-1);
		}
	}

	strcpy(filename,argv[argc-1]);
	if ((fd = open(filename,O_WRONLY|O_CREAT|O_TRUNC,0644)) < 0) {
		perror(filename);
		exit(-1);
	}

	initscr();
	crmode();		/* set terminal to unbuffered I/O */

	printf("\nPress Alt-F7 to transmit file to VAX.\n");


/*
**	Ignore interrupts from the user.
**	If the user could delete this program the terminal
**	would be left in a undiserable state of mind.
*/
	sigsetmask( -1 );    /* ignore all signals */

	if ((pid = fork()) == 0) {
		sleep(100);
		RESET(fd);
		kill(0, SIGKILL); 	/* Can't wait forever for a READY reply */
	}

	ptr = buf;
	while (1) {  			/* wait for ready character */
		read(0,ptr,1);
		if (*ptr == READY) break;
	}
	kill(pid, SIGKILL);
	wait(0);
	read(0,ptr,1);			/* get the CR from the READY */
	WCHAR(OKAY); WCHAR(CR);

	for(;;) {
input:
		if ((pid = fork()) == 0) {
			i = 0;
			while ( i++ < 10 ) {
				sleep(10);
				WCHAR(NOT_OK); WCHAR(CR);
			}
			sleep(10);
			RESET(fd);
			kill(0, SIGKILL);  	/* kill all processes */
		}
		READ(buf);			/* read data block */
		kill( pid, SIGKILL );  		/* kill child */
		wait(0);

		/* check for 90 character block */
		ptr = index(buf,ST_BLK);
		if (strlen(ptr) != 90) {
			WCHAR(NOT_OK); WCHAR(CR);
			goto input;
		}

		xsum = 0;
		while ( ptr < &buf[86] )  /* compute check sum */
			xsum = (xsum ^ *ptr++) & 0177;
		if ( xsum != atoi(ptr) ) { 	/* check sum not ok */
			WCHAR(NOT_OK); WCHAR(CR);
			goto input;
		}

		ptr = index(buf,ST_BLK) + 1;
		strncpy(seq,ptr,3);
		switch( (lim = atoi(seq)) - old_seq ) {
			case 0:			/* reply garbled, resend reply */
				WCHAR(OKAY); WSTR(seq); WCHAR(OKAY); WCHAR(CR);
				goto input;
			case 1: case -999:      /* sequence number ok */
				old_seq = lim;
				break;
			default:             /* fatal loss of synchronization */
				WCHAR(CANCEL); WCHAR(CANCEL); WCHAR(CANCEL); WCHAR(CR);
				RESET(fd);
				exit(-1);
		}
		
		ptr += 3;
		if (!(strncmp(ptr,"XX",2) && strncmp(ptr,"EE",2))) break;

		if (strncmp(ptr,"HH",2)) {  	/* decode data block */
			lim = ctoi(*ptr) * 10 + ctoi(*(ptr+1));
			op = buf;
			for ( i = 2; i < lim + 2; i += 2 )
				*op++ = ctoi( *(ptr+i) ) * 16 + ctoi( *(ptr+i+1) );
			write(fd, buf, lim/2); 	/* write data block to file */
		}

		WCHAR(OKAY); WSTR(seq); WCHAR(OKAY); WCHAR(CR);
	} /* end while */

	WCHAR(OKAY); WSTR(seq); WCHAR(OKAY); WCHAR(CR);
	nocrmode();
	endwin();
	close(fd);
	if (argc == 3) {
		printf("Deleting carriage returns\n");
		DELCR(filename);
	}
} /* end main */

WCHAR(c)
char c; {   /* write a character to standard output */

	write(1, &c, 1);
}

WSTR(s)
char *s; {   /* write a string to standard output */
	
	write(1, s, strlen(s));
}

READ(s) 
char *s; {
	register char *ptr;

	ptr = s;
	while ( read(0, ptr, 1) > 0 ) {   	/* read characters until CR */
		if (*ptr++ == CR) break;
	}
	*ptr = '\0';
}

RESET(fd) 
int fd; {			/* put terminal back into start up state */

	nocrmode();
	endwin();
	close(fd);
	unlink(filename);
}
SHAR_EOF
if test 3655 -ne "`wc -c < 'to_vax.c'`"
then
	echo shar: error transmitting "'to_vax.c'" '(should have been 3655 characters)'
fi
fi
echo shar: extracting "'transmit.c'" '(2908 characters)'
if test -f 'transmit.c'
then
	echo shar: will not over-write existing file "'transmit.c'"
else
cat << \SHAR_EOF > 'transmit.c'
/*
**	transmit filename
*/
# include <curses.h>
# include <file.h>
# include <signal.h>
# include <time.h>

# define	SOH	0x1
# define	NAK	0x15
# define	ACK	0x6
# define	EOT	0x4
# define	CANCEL	0x18

int flags;
char filename[64];

main(argc,argv)
int argc;
char *argv[]; {

	int fd;
	register i;
	register char *p;
	char block[132];
	char c;
	int length, pid;
	int seq_num, xsum;
	int retries;
	struct sigvec vec;
	int caught();

	flags = argc;
	if (!((argc == 2) || (argc == 3))) {
		printf("ILLEGAL NUMBER OF ARGUMENTS.\n");
		printf("SYNOPSIS: to_pc_x [-t] [-m] filename\n");
		exit(-1);
	}

	if (argc == 2) strcpy(filename,argv[1]);  /* don't put in CR's */
	else { 
		switch (argv[1][1]) {
			case 't':
				printf("Adding carriage returns, wait .......\n");
				strcpy(filename,ADDCR(argv[2]));
				printf("DONE\n");
				break;
			case 'm':
				printf("Changing lf's to cr's, wait .......\n");
				strcpy(filename,LF2CR(argv[2]));
				printf("DONE\n");
				break;
			default:
				printf("bad argument `%s'\n",argv[1]);
				printf("SYNOPSIS: to_pc_x [-t] [-m] filename\n");
				exit(-1);
		}
	}

	if ((fd = open(filename,O_RDONLY,0644)) < 0) {
		perror(filename);
		exit(-1);
	}

	initscr();
	raw();			/* set terminal to 8-bit I/O */
	noecho();

/*
**	Ignore interrupts from the user.
**	If the user could delete this program the terminal
**	would be left in a undiserable state of mind.
*/
	vec.sv_handler = caught;
	vec.sv_mask = vec.sv_onstack = 0;
	sigvec(SIGALRM,&vec,(struct sigvec *)0);

	sigsetmask(-1 ^ (1 << (SIGALRM-1)));

	SET_TIMER();

	for(;;) {  		/* wait for NAK */
		read(0,&c,1);	/* if not received in 60 sec's, program terminates */
		if ((c&0x7f) == NAK) break;
	}

	DISABLE_TIMER();

	seq_num = 1;
	p = &block[3];
	while ( (length = read(fd,p,128)) > 0 ) {

		p = block;
		*p++ = SOH;
		*p++ = seq_num;
		*p++ = 255 - seq_num;

		p += length;
		for( i = length; i < 128; i++) *p++ = 0;
		xsum = 0;
		for (i = 3; i < 131; i++) xsum += block[i];
		*p = xsum & 0xff;

		retries = 0;
		do {
			if (retries) sleep(10);

			write(1,block,132);
			SET_TIMER();
			read(0,&c,1);
			DISABLE_TIMER();

			if ( (c&0x7f) == CANCEL ) {RESET(); exit(-1);}
			if (retries++ > 10 ) {
				c = CANCEL;
				write(1,&c,1);
				RESET(); exit(-1);
			}
		} while ( (c&0x7f) != ACK );

		seq_num = ++seq_num % 256;
		p = &block[3];
			
	}

	SET_TIMER();
	do {
		c = EOT;
		write(1,&c,1);
		read(0,&c,1);
	} while ( (c&0x7f) != ACK );
	DISABLE_TIMER();

	RESET();
}

RESET() {

	noraw();
	echo();
	endwin();
	if (flags == 3) unlink(filename);
} /* END */

caught() {
	RESET();
	kill(0,SIGKILL);
}

SET_TIMER() {
	struct itimerval val;

	val.it_value.tv_sec = 60;
	val.it_value.tv_usec = 60 * 1000;
	timerclear(&val.it_interval);
	setitimer(ITIMER_REAL,&val,(struct itimerval *)0);
}

DISABLE_TIMER() {
	struct itimerval val;

	timerclear(&val.it_value);
	setitimer(ITIMER_REAL,&val,(struct itimerval *)0);
}
SHAR_EOF
if test 2908 -ne "`wc -c < 'transmit.c'`"
then
	echo shar: error transmitting "'transmit.c'" '(should have been 2908 characters)'
fi
fi
exit 0
#	End of shell archive