/*      UNIX support routines for file transfer

	Support routines for microcomputer file transfer between
	UNIX and UCSD (TTY program )

	Ann Macintosh   August 1980           */

#include <stdio.h>
#include <sgtty.h>
#include <signal.h>

#define END '?'
#define DLE 16
#define XON 17

#define GTTY TIOCGETA
#define STTY TIOCSETA

#define MAXNAME 40
#define TRUE 1
#define FALSE 0
#define ULINE '_'
#define GT '>'
#define QUOTE '\''
#define SLASH '/'

FILE *tf;
char ch, file[MAXNAME];
struct sgttyb oldmodes, newmodes;
int TERMS;

int terms_reset();

main()
{
int i, chcount;
int finish=FALSE;

	TERMS = FALSE;
#ifdef DEBUG
	testroutine(0);
#endif
	signal(SIGINT, terms_reset);
	i=0;
	printf("Take file(small files only):");
	getchar();
	while(( ch = getchar()) != QUOTE ) {
		if ( ch == GT) ch = ULINE; /* greater thans are translated to underlines */
#ifdef DEBUG
		testroutine(4);
#endif
		file[i] = ch;
		if (i == MAXNAME) error(1);
		i++;
	}

	file[i] = NULL;

	while (getchar() != '\n');

#ifdef DEBUG
	testroutine(1);
#endif
	terms_set();

	openfile();
#ifdef DEBUG
	testroutine(5);
#endif

	putchar(XON);
	fflush(stdout);
#ifdef DEBUG
	testroutine(10);
#endif

	chcount = 0;
	while( ! finish) {
		if((ch=getchar() ) == DLE) {
			ch=getchar();
			putc(ch, tf);
#ifdef DEBUG
			testroutine(6);
#endif
			chcount++;
		}
		else if (ch == END) finish = TRUE;
		else {
			putc(ch, tf);
			chcount++;
#ifdef DEBUG
			testroutine(6);
#endif
		}
	}
#ifdef DEBUG
	testroutine(7);
#endif

	fclose(tf);
#ifdef DEBUG
	testroutine(8);
#endif
	getchar();
#ifdef DEBUG
	testroutine(9);
#endif
	terms_reset();
	printf("** Host:  %d characters transferred \n",chcount);
}

openfile()
{
int length, i;
int sbuf[60];

#ifdef DEBUG
	testroutine(2);
#endif

	i=0; length = 0;
	while(file[i] != NULL)
	{
		if (file[i] != SLASH)
		{
			length++;
			if (length > 14) error(2);
		}
		else length = 0;
		i++;
	}

	if ( stat(file,sbuf) > -1) error(3);
	if (( tf = fopen(file, "w")) == NULL) error(4);
}

error(flg)
int flg;
{
#ifdef DEBUG
	testroutine(3);
#endif
	switch (flg) {
		case 1:
		printf("** Host: pathname greater than %d chars\r\n", MAXNAME);
		break;
		case 2:
		printf("** Host: filename greater than 14 characters\r\n");
		break;
		case 3:
		printf("** Host: filename already exists\r\n");
		break;
		case 4:
		printf("** Host: unable to open output file\r\n");
		break;
		}
	terms_reset();
	exit();
}


terms_set()
{
	ioctl(0,GTTY,&oldmodes);
	ioctl(0,GTTY,&newmodes);
	newmodes.sg_flags = (CBREAK|ODDP|EVENP|TANDEM);
	newmodes.sg_width  = newmodes.sg_length = 0;
	TERMS = TRUE;
	ioctl(0,STTY,&newmodes);
}

terms_reset()
{
     if ( TERMS )
     {
	TERMS = FALSE;
	ioctl(0,STTY,&oldmodes);
     }
}

testroutine(flag)
int flag;
{
static FILE *er;

	switch(flag) {
		case 0:
		er = fopen("/tmp/take.er", "w");
		break;
		case 1:
		fprintf(er, "filename receieved\n");
		break;
		case 2:
		fprintf(er, "start of openfile\n");
		break;
		case 3:
		fprintf(er, "start of error routine\n");
		break;
		case 4:
		putc(ch ,er);
		break;
		case 5:
		fprintf(er ,"end of openfile\n");
		break;
		case 6:
		putc(ch, er);
		break;
		case 7:
		fprintf(er, "end of collecting data\n");
		break;
		case 8:
		fprintf(er, "before getchar\n");
		break;
		case 9:
		fprintf(er, "after getchar\n");
		break;
		case 10:
		fprintf(er, "after fflush of XON\n");
		break;
		}
		fflush(er);
}