home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
back2roots/padua
/
padua.7z
/
padua
/
ftp.vapor.com
/
microdot-1
/
md1_src_02.lzx
/
zm_utils.c
< prev
next >
Wrap
C/C++ Source or Header
|
2014-05-19
|
16KB
|
534 lines
/**********************************************************************
* Utils.c: Miscellaneous support routines for xprzmodem.library;
* Version 2.10, 12 February 1991, by Rick Huebner.
* Released to the Public Domain; do as you like with this code.
*
* Version 2.50, 15 November 1991, by William M. Perkins. Added code
* to update_rate() function in utils.c to avoid the Guru # 80000005
* you would have gotten if you had decided to adjust the system clock
* back during an upload or download.
*
* Mysprintf() function to replace sprintf() and proto code to use
* libinit.o and linent.o library code was supplied by Jim Cooper of SAS.
*
**********************************************************************/
/*#include <proto/all.h>
#include <exec/types.h>
#include <exec/memory.h>
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <dos.h>*/
#include "microdot.h"
#include "xproto.h"
#include "zmodem.h"
#include "xprzmodem.h"
#include "asyncio.h"
/* Transfer options to use if XProtocolSetup not called */
struct SetupVars Default_Config =
{
NULL, NULL, 0,
{ "N" }, { "R" }, { "16" }, { "0" }, { "20" },
{ "N" }, { "N" }, { "Y" }, { "N" }, { "Y" }, { "" }
};
#ifdef DEBUGLOG
UBYTE DebugName[] = "T:XDebug.Log";
void *DebugLog = NULL;
#endif
/**********************************************************
* long XProtocolCleanup(struct XPR_IO *xio)
*
* Called by comm program to give us a chance to clean
* up before program ends
**********************************************************/
long XProtocolCleanup(struct XPR_IO *xio)
{
/* Release option memory, if any */
if (xio->xpr_data)
{
FreeMem(xio->xpr_data, (long) sizeof(struct SetupVars));
xio->xpr_data = NULL;
}
return XPRS_SUCCESS;
} /* End of long XProtocolCleanup() */
/**********************************************************
* struct Vars *setup(struct XPR_IO *io)
*
* Perform setup and initializations common to both Send
* and Receive routines
**********************************************************/
struct Vars *setup(struct XPR_IO *io)
{
/* static long bauds[] = { 110, 300, 1200, 2400, 4800, 9600, 19200, 31250,
38400, 57600, 76800, 115200 };*/
struct SetupVars *sv;
struct Vars *v;
#ifdef DEBUGLOG
long i, *lng;
#endif
/* Hook in default transfer options if XProtocolSetup wasn't called */
if (! (sv = (void *) io->xpr_data))
{
io->xpr_data = AllocMem((long) sizeof(struct SetupVars), MEMF_CLEAR);
if (! (sv = (void *) io->xpr_data))
{
ioerr(io, "Kein Speicher!");
return NULL;
}
*sv = Default_Config;
}
/* Allocate memory for our unshared variables, to provide reentrancy */
if (! (v = AllocMem((long) sizeof(struct Vars), MEMF_CLEAR)))
{
nomem:
ioerr(io, "Kein Speicher!");
return NULL;
}
v->Modemchar = v->Modembuf;
/* If framelength was intended to match buffer size, stay in sync */
/* v->Tframlen = atol(sv->option_f);
if (v->Tframlen && v->Tframlen == origbuf)
v->Tframlen = v->Filebufmax;*/
v->ErrorLimit = atol(sv->option_e);
/* Copy caller's io struct into our Vars for easier passing */
v->io = *io;
#ifdef DEBUGLOG
if (! DebugLog)
DebugLog = (*v->io.xpr_fopen)(DebugName, "w");
dlog(v, "XPR_IO struct:\n");
for (i = 0, lng = (long *) io; i < sizeof(struct XPR_IO) / 4; ++i)
{
mysprintf(v->Msgbuf, " %08lx\n", *lng++);
dlog(v, v->Msgbuf);
}
#endif
/* Get baud rate; set serial port mode if necessary (and possible) */
v->Baud = 38400;
return v;
} /* End of struct Vars *setup() */
/**********************************************************
* void set_textmode(struct Vars *v)
*
* Set text/binary mode flags in accordance with T option
* setting
**********************************************************/
void set_textmode(struct Vars *v)
{
v->Rxascii = FALSE;
v->Rxbinary = TRUE;
v->Lzconv = ZCBIN;
} /* End of void set_textmode() */
/**********************************************************
* UBYTE *find_option(UBYTE *buf, UBYTE option)
*
* Search for specified option setting in string
**********************************************************/
UBYTE *find_option(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;
} /* End of UBYTE *find_option() */
/**********************************************************
* void canit(struct Vars *v)
*
* send cancel string to get the other end to shut up
**********************************************************/
void canit(struct Vars *v)
{
static char canistr[] = { 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 0 };
zmputs(v, canistr);
} /* End of void canit() */
/**********************************************************
* void zmputs(struct Vars *v, UBYTE *s)
*
* Send a string to the modem, with processing for \336 (sleep 1 sec)
* and \335 (break signal, ignored since XPR spec doesn't support it)
**********************************************************/
void zmputs(struct Vars *v, UBYTE *s)
{
UBYTE c;
while (*s)
{
switch (c = *s++)
{
case '\336':
Delay(50L);
case '\335':
break;
default:
sendline(v,c);
}
}
sendbuf(v);
} /* End of void zmputs() */
/**********************************************************
* void xsendline(struct Vars *v, UBYTE c)
*
* Write one character to the modem
**********************************************************/
void xsendline(struct Vars *v, UBYTE c)
{
v->Outbuf[v->Outbuflen++] = c;
if (v->Outbuflen >= sizeof(v->Outbuf))
sendbuf(v);
} /* End of void xsendline() */
/**********************************************************
* void sendbuf(struct Vars *v)
*
* Send any data waiting in modem output buffer
**********************************************************/
void sendbuf(struct Vars *v)
{
if (v->Outbuflen)
{
xpr_swrite(v->Outbuf, (long) v->Outbuflen);
v->Outbuflen = 0;
}
} /* End of void sendbuf() */
/**********************************************************
* short readock(struct Vars *v, short tenths)
*
* Get a byte from the modem;
* return TIMEOUT if no read within timeout tenths of a
* second, return RCDO if carrier lost or other fatal error
* (sread returns -1). Added in some buffering so we
* wouldn't hammer the system with single-byte serial port
* reads. Also, the buffering makes char_avail() a lot
* easier to implement.
**********************************************************/
short readock(struct Vars *v, short tenths)
{
long t;
/* If there's data waiting in our buffer, return next byte */
if (v->Modemcount)
{
gotdata:
--v->Modemcount;
return (short) (*v->Modemchar++);
}
/*
* Our buffer is empty; see if there's anything waiting in system buffer.
* If the caller is in a hurry, don't wait around, but if it can spare
* a half second, wait a bit and build up some input so we don't do as
* many sread() calls.
*/
t = (tenths < 5) ? 0 : 500000;
#ifdef DEBUGLOG
mysprintf(v->Msgbuf,
"Input buffer empty; calling sread for %ld bytes, %ld usec\n",
(long) sizeof(v->Modembuf), t);
dlog(v, v->Msgbuf);
#endif
v->Modemcount = xpr_sread(v->Modembuf, (long) sizeof(v->Modembuf),
t);
#ifdef DEBUGLOG
mysprintf(v->Msgbuf, " sread returned %ld\n", v->Modemcount);
dlog(v, v->Msgbuf);
#endif
if (v->Modemcount < 0) /* Carrier dropped or other fatal error; abort */
{
v->Modemcount = 0;
return RCDO;
}
else if (! v->Modemcount) /* Nothing in system buffer; try waiting */
{
t = tenths * 100000L - t;
#ifdef DEBUGLOG
mysprintf(v->Msgbuf, " calling sread for 1 byte, %ld usec\n", t);
dlog(v, v->Msgbuf);
#endif
v->Modemcount = xpr_sread(v->Modembuf, 1L, t);
#ifdef DEBUGLOG
mysprintf(v->Msgbuf, " sread returned %ld\n", v->Modemcount);
dlog(v, v->Msgbuf);
#endif
if (v->Modemcount < 0)
{
v->Modemcount = 0;
return RCDO;
}
else if (! v->Modemcount) /* Nothing received in time */
return TIMEOUT;
}
v->Modemchar = v->Modembuf; /* Reset buffer pointer to start of data */
goto gotdata;
} /* End of short readock() */
/**********************************************************
* char char_avail(struct Vars *v)
*
* Check if there's anything available to read from the
* modem
**********************************************************/
char char_avail(struct Vars *v)
{
if (v->Modemcount)
return TRUE;
/* No data in our buffer; check system's input buffer */
v->Modemcount = xpr_sread(v->Modembuf, (long) sizeof(v->Modembuf), 0L);
if (v->Modemcount < 1) /* Nothing in system buffer either */
{
v->Modemcount = 0;
return FALSE;
}
else /* System buffer had something waiting for us */
{
v->Modemchar = v->Modembuf;
return TRUE;
}
} /* End of char char_avail() */
/**********************************************************
* void update_rate(struct Vars *v)
*
* Update the elapsed time, expected total time, and
* effective data transfer rate values for status display
**********************************************************/
void update_rate(struct Vars *v)
{
ULONG sent, elapsed, expect;
short hr, min;
struct timeval tv;
/* Compute effective data rate so far in characters per second */
sent = v->xpru.xpru_bytes - v->Strtpos;
getsystime(&tv);
elapsed = (tv.tv_secs & 0x7FFFFF) * 128 + tv.tv_micro / 8192;
elapsed -= (v->Starttime.tv_secs & 0x7FFFFF) * 128
+ v->Starttime.tv_micro / 8192;
if (elapsed < 128 || elapsed > 0x7FFFFF)
/* ^^^^^^^^^^^^^^^^^^ Kludge for the GURU! -WMP- */
elapsed = 128;
/*
* If we haven't transferred anything yet (just starting), make reasonable
* guess (95% throughput); otherwise, compute actual effective transfer
* rate
*/
v->xpru.xpru_datarate = (sent) ? (sent * 128 / elapsed)
: (v->Baud * 95 / 1000);
if(v->xpru.xpru_datarate<1) v->xpru.xpru_datarate=1;
/* Compute expected total transfer time based on data rate so far */
if (v->xpru.xpru_filesize < 0)
expect = 0; /* Don't know filesize; display time=0 */
else
expect = (v->xpru.xpru_filesize - v->Strtpos) / v->xpru.xpru_datarate;
hr = expect / 3600; /* How many whole hours */
expect -= hr * 3600; /* Remainder not counting hours */
min = expect / 60; /* How many whole minutes */
expect -= min * 60; /* Remaining seconds */
mysprintf(v->Msgbuf, "%02ld:%02ld:%02ld", (long) hr, (long) min, expect);
v->xpru.xpru_expecttime = (char *) v->Msgbuf;
/* Compute elapsed time for this transfer so far */
elapsed /= 128;
hr = elapsed / 3600;
elapsed -= hr * 3600;
min = elapsed / 60;
elapsed -= min * 60;
mysprintf(v->Msgbuf + 20, "%02ld:%02ld:%02ld", (long) hr, (long) min,
elapsed);
v->xpru.xpru_elapsedtime = (char *) v->Msgbuf + 20;
} /* End of void update_rate() */
/**********************************************************
* long bfopen(struct Vars *v, UBYTE *mode)
*
* Buffered file I/O fopen() interface routine
**********************************************************/
extern BOOL nowdoicons;
long bfopen(struct Vars *v, UBYTE *mode)
{
int om;
switch(*mode) {
case 'A':
case 'a': om=MODE_APPEND; break;
case 'w':
case 'W': om=MODE_WRITE; break;
default: om=MODE_READ; break;
}
if( nowdoicons && ( om == MODE_WRITE || om == MODE_APPEND ) )
createdataicon( v->Filename, prefs.dl_defaulttool );
return( ( long )OpenAsync( v->Filename,om, max( 32, prefs.zmodembuffer ) * 1024 ) );
} /* End of long bfopen() */
/**********************************************************
* void bfclose(struct Vars *v)
*
* Buffered file I/O fclose() interface routine
**********************************************************/
void bfclose(struct Vars *v)
{
if (v->File) {
CloseAsync((struct AsyncFile*)v->File);
v->File=NULL;
}
} /* End of void bfclose() */
/**********************************************************
* void bfseek(struct Vars *v, long pos)
*
* Buffered file I/O fseek() interface routine
**********************************************************/
void bfseek(struct Vars *v, long pos)
{
SeekAsync((struct AsyncFile*)v->File,pos,MODE_START);
} /* End of void bfseek() */
/**********************************************************
* long bfread(struct Vars *v, UBYTE *buf, long length)
*
* Buffered file I/O fread() interface routine
**********************************************************/
long bfread(struct Vars *v, UBYTE *buf, long length)
{
return(ReadAsync((struct AsyncFile*)v->File,buf,length));
} /* End of long bfread() */
/**********************************************************
* long bfwrite(struct Vars *v, UBYTE *buf, long length)
*
* Buffered file I/O fwrite() interface routine
**********************************************************/
long bfwrite(struct Vars *v, UBYTE *buf, long length)
{
return(WriteAsync((struct AsyncFile*)v->File,buf,length));
} /* End of long bfwrite() */
/**********************************************************
* void ioerr(struct XPR_IO *io, char *msg)
*
* Have the comm program display an error message for us,
* using a temporary XPR_UPDATE structure; used to display
* errors before Vars gets allocated
**********************************************************/
void ioerr(struct XPR_IO *io, char *msg)
{
struct XPR_UPDATE xpru;
xpru.xpru_updatemask = XPRU_ERRORMSG;
xpru.xpru_errormsg = msg;
xpr_update(&xpru);
} /* End of void ioerr() */
/**********************************************************
* void upderr(struct Vars *v, char *msg)
*
* Have the comm program display an error message for us, using the
* normal XPR_IO structure allocated in Vars
**********************************************************/
void upderr(struct Vars *v, char *msg)
{
v->xpru.xpru_updatemask = XPRU_ERRORMSG;
v->xpru.xpru_errormsg = msg;
if (msg == v->Msgbuf) /* Ensure message length < 50 */
msg[48] = '\0';
xpr_update(&v->xpru);
#ifdef DEBUGLOG
dlog(v, msg);
dlog(v, "\n");
#endif
} /* End of void upderr() */
/**********************************************************
* void updmsg(struct Vars *v,char *msg)
*
* Have the comm program display a normal message for us
**********************************************************/
void updmsg(struct Vars *v,char *msg)
{
v->xpru.xpru_updatemask = XPRU_MSG;
v->xpru.xpru_msg = msg;
if (msg == v->Msgbuf) /* Ensure message length < 50 */
msg[48] = '\0';
xpr_update(&v->xpru);
#ifdef DEBUGLOG
dlog(v, msg);
dlog(v, "\n");
#endif
} /* End of void updmsg() */
/**********************************************************
* char exist(struct Vars *v)
*
* Check whether file already exists; used to detect
* potential overwrites
**********************************************************/
char exist(struct Vars *v)
{
BPTR f;
f=Lock(v->Filename,SHARED_LOCK);
if(f) { UnLock(f); return(TRUE); }
else return(FALSE);
} /* End of char exist() */
ULONG UnixTimeOffset = 252482400;
/**********************************************************
* 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-
**********************************************************/
ULONG getsystime(struct timeval *tv)
{
struct DateStamp ds;
ULONG secs;
DateStamp(&ds);
secs = (ds.ds_Days * 86400) + (ds.ds_Minute * 60)
+ (ds.ds_Tick / TICKS_PER_SECOND);
if (tv)
{
tv->tv_secs = secs;
tv->tv_micro = 0; /* Not Used. */
}
return secs;
} /* End of ULONG getsystime() */