

#include "csource/xprascii.h"


STATIC BOOL test(struct XPR_IO *io);
STATIC BOOL setup(struct XPR_IO *io);
STATIC VOID ParseConfigString(struct XPR_IO *io, char *buf);
STATIC UBYTE *FindOption(UBYTE *buf, UBYTE option);
STATIC LONG AtoL(UBYTE *);
VOID myGetSysTime(ULONG *);
VOID myGetDate(BPTR);


LONG __saveds __asm XProtocolCleanup(register __a0 struct XPR_IO *io)
{
	struct XProtocolData *xdata = (struct XProtocolData *)io->xpr_data;

	if(xdata)
	{
		FreeMem(xdata, sizeof(struct XProtocolData));
		io->xpr_data = NULL;
	}

	return(XPRS_SUCCESS);
}


LONG __saveds __asm XProtocolSetup(register __a0 struct XPR_IO *io)
{
	struct XProtocolData *xdata;

	if(test(io) == FALSE)
		return(XPRS_FAILURE);

	if(io->xpr_data == NULL)
	{
		if(setup(io) == FALSE)
			return(XPRS_FAILURE);
	}

	xdata = (struct XProtocolData *)io->xpr_data;


	/* If setup string isn't handed to us, ask questions */

	if(io->xpr_filename == NULL)
	{
		if(io->xpr_options != NULL)
		{
			enum { OPT_HEADER=0, OPT_CHARDELAY, OPT_LINEDELAY, OPT_LF_CONVERT,
					 OPT_CR_CONVERT, OPT_PROMPTCHAR, OPT_EXPANDBLANKS,
					 /* OPT_UU_MODE,*/ OPT_STRIPHIBIT };
			ULONG numopts;

		struct xpr_option {
		   char *xpro_description;      /* description of the option                  */
		   long  xpro_type;             /* type of option                             */
		   char *xpro_value;            /* pointer to a buffer with the current value */
		   long  xpro_length;           /* buffer size                                */
		};
			struct xpr_option *opti[10];
			UBYTE charbuf[LONGLEN], linebuf[LONGLEN], lfbuf[CHARLEN],
					crbuf[CHARLEN], stripbuf[STRINGLEN], uubuf[STRINGLEN],
					expandbuf[STRINGLEN];

			struct xpr_option opt0;
			struct xpr_option opt1;
			struct xpr_option opt2;
			struct xpr_option opt3;
			struct xpr_option opt4;
			struct xpr_option opt5;
			struct xpr_option opt6;
			struct xpr_option opt7;
			struct xpr_option opt8;
			struct xpr_option opt9;

			opti[0] = &opt0;
			opti[1] = &opt1;
			opti[2] = &opt2;
			opti[3] = &opt3;
			opti[4] = &opt4;
			opti[5] = &opt5;
			opti[6] = &opt6;
			opti[7] = &opt7;
			opti[8] = &opt8;
			opti[9] = &opt9;


			numopts = 0;

			opti[OPT_HEADER]->xpro_description	= "ASCII Options:";
			opti[OPT_HEADER]->xpro_type	= XPRO_HEADER;
			opti[OPT_HEADER]->xpro_value	= NULL;
			opti[OPT_HEADER]->xpro_length	= NULL;

/* */

			numopts++;
			opti[OPT_CHARDELAY]->xpro_description	= "Char Delay (ticks):";
			opti[OPT_CHARDELAY]->xpro_type			= XPRO_LONG;
			sprintf(charbuf, "%ld", xdata->CharDelay);
			opti[OPT_CHARDELAY]->xpro_value			= charbuf;
			opti[OPT_CHARDELAY]->xpro_length			= LONGLEN;

/* */

			numopts++;
			opti[OPT_LINEDELAY]->xpro_description	= "Line Delay (ticks):";
			opti[OPT_LINEDELAY]->xpro_type			= XPRO_LONG;
			sprintf(linebuf, "%ld", xdata->LineDelay);
			opti[OPT_LINEDELAY]->xpro_value			= linebuf;
			opti[OPT_LINEDELAY]->xpro_length			= LONGLEN;

/* */

			numopts++;
			switch(xdata->LF_Mode)
			{
				case STRIP_MODE:
					lfbuf[0] = 'S';
				break;

				case ADD_MODE:
					lfbuf[0] = 'A';
				break;

				case EXCHANGE_MODE:
					lfbuf[0] = 'X';
				break;

				default:
					lfbuf[0] = 'N';
				break;

			}
			lfbuf[1] = '\0';

			opti[OPT_LF_CONVERT]->xpro_description	= "Convert `LF' (N,S,A,X)";
			opti[OPT_LF_CONVERT]->xpro_type			= XPRO_STRING;
			opti[OPT_LF_CONVERT]->xpro_value			= lfbuf;
			opti[OPT_LF_CONVERT]->xpro_length		= CHARLEN;

/* */

			numopts++;
			switch(xdata->CR_Mode)
			{
				case STRIP_MODE:
					crbuf[0] = 'S';
				break;

				case ADD_MODE:
					crbuf[0] = 'A';
				break;

				case EXCHANGE_MODE:
					crbuf[0] = 'X';
				break;

				default:
					crbuf[0] = 'N';
				break;

			}
			crbuf[1] = '\0';

			opti[OPT_CR_CONVERT]->xpro_description	= "Convert `CR' (N,S,A,X)";
			opti[OPT_CR_CONVERT]->xpro_type			= XPRO_STRING;
			opti[OPT_CR_CONVERT]->xpro_value			= crbuf;
			opti[OPT_CR_CONVERT]->xpro_length		= CHARLEN;

/* */

			numopts++;
			opti[OPT_PROMPTCHAR]->xpro_description	= "Prompt Char:";
			opti[OPT_PROMPTCHAR]->xpro_type			= XPRO_STRING;
			opti[OPT_PROMPTCHAR]->xpro_value			= &xdata->PromptChar;
			opti[OPT_PROMPTCHAR]->xpro_length		= CHARLEN;

/* */
/*
**			numopts++;
**			if(xdata->UU_Mode)
**				strcpy(uubuf, "on");
**			else
**				strcpy(uubuf, "off");
**			opti[OPT_UU_MODE]->xpro_description	= "Use uuencode & decode:";
**			opti[OPT_UU_MODE]->xpro_type			= XPRO_BOOLEAN;
**			opti[OPT_UU_MODE]->xpro_value			= uubuf;
**			opti[OPT_UU_MODE]->xpro_length		= STRINGLEN;
*/
/* */

			numopts++;
			if(xdata->ExpandBlanks)
				strcpy(expandbuf, "on");
			else
				strcpy(expandbuf, "off");
			opti[OPT_EXPANDBLANKS]->xpro_description	= "Expand Blank Lines:";
			opti[OPT_EXPANDBLANKS]->xpro_type			= XPRO_BOOLEAN;
			opti[OPT_EXPANDBLANKS]->xpro_value			= expandbuf;
			opti[OPT_EXPANDBLANKS]->xpro_length			= STRINGLEN;

/* */

			numopts++;
			if(xdata->StripHiBit)
				strcpy(stripbuf, "on");
			else
				strcpy(stripbuf, "off");
			opti[OPT_STRIPHIBIT]->xpro_description	= "Strip High Bit:";
			opti[OPT_STRIPHIBIT]->xpro_type			= XPRO_BOOLEAN;
			opti[OPT_STRIPHIBIT]->xpro_value			= stripbuf;
			opti[OPT_STRIPHIBIT]->xpro_length		= STRINGLEN;


			io->xpr_options(++numopts, opti); 


			xdata->CharDelay = AtoL(charbuf);
			if(xdata->CharDelay > 500)
				xdata->CharDelay = 500;


			xdata->LineDelay = AtoL(linebuf);
			if(xdata->LineDelay > 500)
				xdata->LineDelay = 500;

			switch(*lfbuf)
			{
				case 's':
				case 'S':	/* Strip LF */
					xdata->LF_Mode = STRIP_MODE;
				break;

				case 'a':
				case 'A':	/* Add CR */
					xdata->LF_Mode = ADD_MODE;
				break;

				case 'x':
				case 'X':	/* LF -> CR */
					xdata->LF_Mode = EXCHANGE_MODE;
				break;

				default:		/* None */
					xdata->LF_Mode = NONE_MODE;
				break;

			}

			switch(*crbuf)
			{
				case 's':
				case 'S':	/* Strip CR */
					xdata->CR_Mode = STRIP_MODE;
				break;

				case 'a':
				case 'A':	/* Add LF */
					xdata->CR_Mode = ADD_MODE;
				break;

				case 'x':
				case 'X':	/* CR -> LF */
					xdata->CR_Mode = EXCHANGE_MODE;
				break;

				default:		/* None */
					xdata->CR_Mode = NONE_MODE;
				break;

			}

			xdata->ExpandBlanks	= (!stricmp(expandbuf, "yes") ||
											!stricmp(expandbuf, "on"));

/*
**			xdata->UU_Mode			= (!stricmp(uubuf, "yes") ||
**											!stricmp(uubuf, "on"));
*/
			xdata->StripHiBit		= (!stricmp(stripbuf, "yes") ||
											!stricmp(stripbuf, "on"));

/*			xdata->PromptChar updated sich selbst */
		}
		else
		{
			if(io->xpr_gets != NULL)
			{
				UWORD expand, strip;
				UBYTE lf, cr, buffy[128];

				expand = (xdata->ExpandBlanks)	? 1 : 0;
				strip	 = (xdata->StripHiBit)		? 1 : 0;

				switch(xdata->LF_Mode)
				{
					case STRIP_MODE:
						lf = 'S';
					break;

					case ADD_MODE:
						lf = 'A';
					break;

					case EXCHANGE_MODE:
						lf = 'X';
					break;

					default:
						lf = 'N';
					break;

				}

				switch(xdata->CR_Mode)
				{
					case STRIP_MODE:
						cr = 'S';
					break;

					case ADD_MODE:
						cr = 'A';
					break;

					case EXCHANGE_MODE:
						cr = 'X';
					break;

					default:
						cr = 'N';
					break;

				}

				sprintf(buffy, "C%ld,L%ld,F%lc,R%lc,E%ld,S%ld,P%lc", xdata->CharDelay, xdata->LineDelay, lf, cr, expand, strip, xdata->PromptChar);

				if(io->xpr_gets("ASCII Options", buffy))
					ParseConfigString(io, buffy);
			}
		}
	}
	else
		ParseConfigString(io, io->xpr_filename);

	return(XPRS_SUCCESS);
}


STATIC VOID WaitForPrompt(struct XPR_IO *io)
{
	struct XProtocolData *xdata = (struct XProtocolData *)io->xpr_data;
	UWORD data;

	if(data = io->xpr_sread(xdata->SerBuf, 1, 0) > 0)
	{
		UWORD i;

		for(i=0; i<data; i++)
		{
			if(xdata->SerBuf[i] == xdata->PromptChar)
				return;
		}
	}

	for(;;)
	{
		if(io->xpr_sread(xdata->SerBuf, 1, 10000000) > 0)
		{
			if(xdata->SerBuf[0] == xdata->PromptChar)
				break;
		}
		else
			break;
	}
}


STATIC BOOL SendAsciiPacket(struct XPR_IO *io, UBYTE *filebuf, ULONG datalen)
{
	struct XProtocolData *xdata = (struct XProtocolData *)io->xpr_data;
	UWORD i, out;
	UBYTE *ptr;

	ptr = filebuf;

	for(i=0, out=0; i<datalen; i++, ptr++)
	{
		if(*ptr == '\n')
		{
			switch(xdata->LF_Mode)
			{
				case STRIP_MODE:
					;
				continue;

				case ADD_MODE:
					xdata->SerBuf[out++] = '\r';
				break;

				case EXCHANGE_MODE:
					*ptr = '\r';
				break;

			}
		}

		if(*ptr == '\r')
		{
			switch(xdata->CR_Mode)
			{
				case STRIP_MODE:
					;
				continue;

				case ADD_MODE:
					xdata->SerBuf[out++] = '\n';
					xdata->SerBuf[out++] = '\r';
				continue;

				case EXCHANGE_MODE:
					*ptr = '\n';
				break;

			}
		}

		xdata->SerBuf[out++] = *ptr;
	}


	if(xdata->ExpandBlanks  &&  (xdata->SerBuf[0] == '\n'  ||  xdata->SerBuf[0] == '\r'))
		io->xpr_swrite(" ", 1);


	if(xdata->CharDelay)	/* writin' in slo'-motion..(-: */
	{
		ptr = xdata->SerBuf;
		for(i=0; i<out; i++, ptr++)
		{
			io->xpr_swrite(ptr, 1);
   		Delay(xdata->CharDelay);
		}
	}
	else
		io->xpr_swrite(xdata->SerBuf, out);	/* BLAST IT..!! */


	if(xdata->LineDelay)
  		Delay(xdata->LineDelay);

	if(xdata->PromptChar  &&  xdata->PromptChar	!= ' ')
		WaitForPrompt(io);

	io->xpr_sflush();

	return(io->xpr_chkabort());
}


/*
**STATIC BOOL uudecode(struct XPR_IO *io)
**{
**	struct XProtocolData *xdata = (struct XProtocolData *)io->xpr_data;
**	BPTR fh;
**	ULONG systemtags[] = { SYS_Output, 0, TAG_DONE };
**	BOOL success;
**
**	if((fh = Open("T:uudecode.log", MODE_OLDFILE)) == NULL)
**		 fh = Open("T:uudecode.log", MODE_NEWFILE);
**	else
**		Seek(fh, 0, OFFSET_END);
**
**	sprintf(&xdata->FileBuf[511], "uudecode %s", xdata->FileBuf);
**	if(fh)
**	{
**		fprintf(fh, "-------------------------------\n");
**		myGetDate(fh);
**		fprintf(fh, "System(\"%s\")\n", &xdata->FileBuf[511]);
**	}
**
**	systemtags[1] = fh;
**	success = (System(&xdata->FileBuf[511], (APTR)&systemtags[0]) != -1);
**
**	if(fh)
**		Close(fh);
**
**	return(success);
**}
**
**
**STATIC VOID *uuencode(struct XPR_IO *io, VOID *fp)
**{
**	struct XProtocolData *xdata = (struct XProtocolData *)io->xpr_data;
**	VOID *tmp_fp=NULL;
**	BPTR fh;
**	ULONG sys_time;
**	ULONG systemtags[] = { SYS_Output, 0, TAG_DONE };
**	UBYTE tmp_file[24];
**
**	if((fh = Open("T:uuencode.log", MODE_OLDFILE)) == NULL)
**		 fh = Open("T:uuencode.log", MODE_NEWFILE);
**	else
**		Seek(fh, 0, OFFSET_END);
**
**	myGetSysTime(&sys_time);
**	sprintf(tmp_file, "T:%ld.uue", sys_time);
**	sprintf(xdata->FileBuf, "uuencode %s %s", io->xpr_filename, tmp_file);
**	if(fh)
**	{
**		fprintf(fh, "-------------------------------\n");
**		myGetDate(fh);
**		fprintf(fh, "System(\"%s\")\n", xdata->FileBuf);
**	}
**
**	systemtags[1] = fh;
**	if(System(xdata->FileBuf, (APTR)&systemtags[0]) != -1)
**		tmp_fp = io->xpr_fopen(tmp_file, "r");
**
**	if(fh)
**		Close(fh);
**
**	return(tmp_fp);
**}
*/

LONG __saveds __asm XProtocolSend(register __a0 struct XPR_IO *io)
{
	struct XPR_UPDATE xpru;
	struct XProtocolData *xdata;
	VOID *fp;
	LONG read;
	BOOL brkflag;

	if(test(io) == FALSE)
		return(XPRS_FAILURE);

	if(io->xpr_data == NULL)
	{
		if(setup(io) == FALSE)
		{
      	xpru.xpru_updatemask = XPRU_ERRORMSG;
      	xpru.xpru_errormsg   = "Ran out of memory!";
			io->xpr_update(&xpru);
			return(XPRS_FAILURE);
		}
	}
	xdata = (struct XProtocolData *)io->xpr_data;


	xpru.xpru_updatemask	= XPRU_FILENAME;
	xpru.xpru_filename	= io->xpr_filename;
	io->xpr_update(&xpru);

	fp = io->xpr_fopen(io->xpr_filename, "r");
   if(fp == NULL)
	{
		xpru.xpru_updatemask	= XPRU_ERRORMSG;
		xpru.xpru_errormsg	= "Failed to open input file";
		io->xpr_update(&xpru);
		return(XPRS_FAILURE);
	}

/*
**	if(xdata->UU_Mode)
**	{
**		VOID *tmp_fp;
**
**		if(tmp_fp = uuencode(io, fp))
**		{
**			io->xpr_fclose(fp);
**			fp = tmp_fp;
**		}
**		else
**		{
**			io->xpr_fclose(fp);
**			xpru.xpru_updatemask	= XPRU_ERRORMSG;
**			xpru.xpru_errormsg	= "Failed to create uuencoded file";
**			io->xpr_update(&xpru);
**			return(XPRS_FAILURE);
**		}
**	}
*/
	xpru.xpru_updatemask	= XPRU_PACKETDELAY | XPRU_CHARDELAY | XPRU_MSG;

	xpru.xpru_packetdelay= xdata->LineDelay * 20;  /* msec! */
	xpru.xpru_chardelay	= xdata->CharDelay * 20;  /* msec! */
/*
**	xpru.xpru_msg			= (xdata->UU_Mode) ? "Sending uuencoded File" :
**															"Starting ASCII Send";
*/
	xpru.xpru_msg			= "Starting ASCII Send";
	io->xpr_update(&xpru);


	xpru.xpru_bytes		= 0;
	xpru.xpru_blocks		= 0;
	xpru.xpru_blocksize	= 0;

	while(read = io->xpr_fread(xdata->FileBuf, 1, FILEBUF, fp))
	{
		WORD send, sent;
		UBYTE *buf;

		for(send=read, buf=xdata->FileBuf; send>0; buf+=sent, send-=sent)
		{
			sent  = strcspn(buf, "\r\n");
			sent++;

			xpru.xpru_updatemask = XPRU_BYTES | XPRU_BLOCKS | XPRU_BLOCKSIZE;
			xpru.xpru_blocks++;
			xpru.xpru_bytes     += sent;
			xpru.xpru_blocksize  = sent;
			io->xpr_update(&xpru);

			if(brkflag = SendAsciiPacket(io, buf, sent))
				goto bibi;
		}
	}

bibi:
	io->xpr_fclose(fp);

	xpru.xpru_updatemask = XPRU_MSG;
	xpru.xpru_msg = (brkflag) ? "Aborted" : "Done";
	io->xpr_update(&xpru);

	return((brkflag) ? XPRS_SUCCESS : XPRS_FAILURE);
}


LONG __saveds __asm XProtocolReceive(register __a0 struct XPR_IO *io)
{
	struct XPR_UPDATE xpru;
	struct XProtocolData *xdata;
	VOID *fp;
	LONG read;
	BOOL brkflag=FALSE;

	if(test(io) == FALSE)
		return(XPRS_FAILURE);

	if(io->xpr_data == NULL)
	{
		if(setup(io) == FALSE)
		{
      	xpru.xpru_updatemask = XPRU_ERRORMSG;
      	xpru.xpru_errormsg   = "Ran out of memory!";
			io->xpr_update(&xpru);
			return(XPRS_FAILURE);
		}
	}
	xdata = (struct XProtocolData *)io->xpr_data;

	fp = io->xpr_fopen(io->xpr_filename, "w");
   if(fp == NULL)
	{
		xpru.xpru_updatemask = XPRU_ERRORMSG | XPRU_FILENAME;
		xpru.xpru_errormsg   = "Failed to open output file";
		xpru.xpru_filename   = xdata->FileBuf;
		io->xpr_update(&xpru);
		return(XPRS_FAILURE);
   }

	xpru.xpru_updatemask = XPRU_MSG | XPRU_FILENAME;
	xpru.xpru_msg        = "Starting ASCII Receive";
	xpru.xpru_filename   = xdata->FileBuf;
	io->xpr_update(&xpru);


	xpru.xpru_bytes		= 0;
	xpru.xpru_blocks		= 0;
	xpru.xpru_blocksize	= 0;
	while((read = io->xpr_sread(xdata->SerBuf, 80, 5000000)) > 0)
	{
		if(xdata->StripHiBit)
		{
			UWORD i;

			for(i=0; i<read; i++)
				xdata->SerBuf[i] &= 0x7f;
		}

      xpru.xpru_updatemask	= XPRU_BYTES | XPRU_BLOCKS | XPRU_BLOCKSIZE;
      xpru.xpru_bytes	  += read;
      xpru.xpru_blocks++;
      xpru.xpru_blocksize  = read;
      io->xpr_update(&xpru);

      io->xpr_fwrite(xdata->SerBuf, 1, read, fp);

		if(brkflag = io->xpr_chkabort())
			break;
   }

	io->xpr_fclose(fp);
	fp = NULL;

/*
**	if(xdata->UU_Mode)
**	{
**		uudecode(io);
**	}
*/

	xpru.xpru_updatemask = XPRU_MSG;
	xpru.xpru_msg = (brkflag) ? "Aborted" : "Done";
	io->xpr_update(&xpru);

	return((brkflag) ? XPRS_SUCCESS : XPRS_FAILURE);
}


LONG __saveds __asm XProtocolHostMon(register __a0 struct XPR_IO *io, register __a1 UBYTE *serbuff, register __d0 LONG actual, register __d1 LONG maxsize)
{
  return(actual);
}


LONG __saveds __asm XProtocolUserMon(register __a0 struct XPR_IO *io, register __a1 UBYTE *serbuff, register __d0 LONG actual, register __d1 LONG maxsize)
{
  return(actual);
}


STATIC BOOL test(struct XPR_IO *io)
{
	/* all we need..(-: */

	if(io->xpr_swrite == NULL)
		return(FALSE);

	if(io->xpr_sread == NULL)
		return(FALSE);

	if(io->xpr_sflush == NULL)
		return(FALSE);

	if(io->xpr_fopen == NULL)
		return(FALSE);

	if(io->xpr_fwrite == NULL)
		return(FALSE);

	if(io->xpr_fread == NULL)
		return(FALSE);

	if(io->xpr_fclose == NULL)
		return(FALSE);

	if(io->xpr_update == NULL)
		return(FALSE);

	if(io->xpr_chkabort == NULL)
		return(FALSE);

	return(TRUE);
}


STATIC BOOL setup(struct XPR_IO *io)
{
	struct XProtocolData *xdata = (struct XProtocolData *)io->xpr_data;

	xdata = io->xpr_data = AllocMem(sizeof(struct XProtocolData), MEMF_PUBLIC | MEMF_CLEAR);

	if(io->xpr_data == NULL)
		return(FALSE);

/* some good settings.. */
	xdata->CharDelay	= 0;
	xdata->LineDelay	= 0;
	xdata->PromptChar	= ' ';

	xdata->ExpandBlanks	= TRUE;
	xdata->StripHiBit		= FALSE;
/*	xdata->UU_Mode			= FALSE;*/

	xdata->LF_Mode = NONE_MODE;
	xdata->CR_Mode = NONE_MODE;

	return(TRUE);
}

/* Search for specified option setting in string */
STATIC UBYTE *FindOption(UBYTE *buf, UBYTE option)
{
	while(*buf)
	{
		buf += strspn(buf," ,\t\r\n");
		if(*buf == option)
			return(++buf);
		buf += strcspn(buf," ,\t\r\n");
  }

  return(NULL);
}


STATIC VOID ParseConfigString(struct XPR_IO *io, char *buf)
{
	struct XProtocolData *xdata = (struct XProtocolData *)io->xpr_data;
	UBYTE *p;

	if(p = FindOption(buf, 'P'))
		xdata->PromptChar = *p;
	else
	{
		if(p = FindOption(buf, 'p'))
			xdata->PromptChar = *p;
	}

	strupr(buf);

	if(p = FindOption(buf, 'C'))
	{
		xdata->CharDelay = AtoL(p);
		if(xdata->CharDelay > 500)
			xdata->CharDelay = 500;
	}


	if(p = FindOption(buf, 'L'))
	{
		xdata->LineDelay = AtoL(p);
		if(xdata->LineDelay > 500)
			xdata->LineDelay = 500;
	}


	if(p = FindOption(buf, 'F'))
	{
		switch(*p)
		{
			case 'A':
				xdata->LF_Mode = ADD_MODE;
			break;

			case 'S':
				xdata->LF_Mode = STRIP_MODE;
			break;

			case 'X':
				xdata->LF_Mode = EXCHANGE_MODE;
			break;

			default:
				xdata->LF_Mode = NONE_MODE;
			break;

		}
	}


	if(p = FindOption(buf, 'R'))
	{
		switch(*p)
		{
			case 'A':
				xdata->CR_Mode = ADD_MODE;
			break;

			case 'S':
				xdata->CR_Mode = STRIP_MODE;
			break;

			case 'X':	/* LF -> CR */
				xdata->CR_Mode = EXCHANGE_MODE;
			break;

			default:
				xdata->CR_Mode = NONE_MODE;
			break;

		}
	}


	if(p = FindOption(buf, 'E'))
		xdata->ExpandBlanks = (*p == '1');

/*
**	if(p = FindOption(buf, 'U'))
**		xdata->UU_Mode = (*p == '1');
*/

	if(p = FindOption(buf, 'S'))
		xdata->StripHiBit = (*p == '1');
}


STATIC LONG AtoL(UBYTE *str)
{
	LONG cnt=0, help;

	while(*str <= ' ')		/* skip white spaces.. */
	{
		if(*str == '\0')
			return(0);
		str++;
	}

	if(*str == '-')
	{
		help = -1;
		str++;
	}
	else
	{
		if(*str == '+')
			str++;
		help = 1;
	}
	
	for(;;)
	{
		if(*str >= '0' && *str <= '9')
		{
			cnt *= 10;
			cnt += *str - '0';
		}
		else
			break;

		if(!(*str))
			break;

		str++;
	}

	return(cnt * help);
}


/**********************************************************
 *	ULONG getsystime(struct timeval *tv)
 *
 *      This function was rewritten using DateStamp() to
 * eliminate the opening and closing of the timer.device
 * that was occurring everytime this function was called.
 * An attempt to save some processing time.   -WMP-
 **********************************************************/
VOID myGetSysTime(ULONG *secs)
{
	struct DateStamp ds;

	DateStamp(&ds);
	*secs = (ds.ds_Days * 86400) + (ds.ds_Minute * 60 + (ds.ds_Tick / TICKS_PER_SECOND));
}


VOID myGetDate(BPTR fh)
{
	struct DateTime dt;
	UBYTE time[12];
	UBYTE date[12];
	UBYTE day[12];

	DateStamp(&dt.dat_Stamp);

	dt.dat_Format	= FORMAT_DOS;
	dt.dat_Flags	= 0;
	dt.dat_StrDay	= day;
	dt.dat_StrDate	= date;
	dt.dat_StrTime	= time;

	DateToStr(&dt);

	fprintf(fh, "%s %s %s\n", day, date, time);
}


/* end of source-code */
