home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Club Amiga de Montreal - CAM
/
CAM_CD_1.iso
/
files
/
550b.lha
/
Term_v1.8a
/
Libs.LZH
/
Libs
/
XprXModem
/
xprxmodem.c
< prev
next >
Wrap
C/C++ Source or Header
|
1991-07-26
|
11KB
|
529 lines
/*
* This XPR is based on bmodem - the BIX modem program
*
* by David Betz, BYTE Magazine/BIX
*
* bmodem consists of three files: bmodem.c, dlink.c, mdio.c. bmodem.c and
* mdio.c were substantially modified and merged into this file, xprxmodem.c
*
* dlink.c was ANSIsized and made re-entrant for xprlib by m. boucher.
*
* Modified substantially by W.G.J. Langeveld for use in VLT.
*
* Transformed into XPR by Marc Boucher
* (BIX: mboucher Internet: marc@CAM.ORG)
*
*/
static char _StAmP[] = "Copyright ©1990 Marc Boucher, All Rights Reserved -- Compiled: " __DATE__ " " __TIME__;
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
#include "xprxmodem.h"
#include "proto-callback.h"
#include "proto-dlink.h"
long XProtocolCleanup(struct XPR_IO * IO)
{
if (IO->xpr_data) {
FreeMem(IO->xpr_data, sizeof(struct XProtocolData));
IO->xpr_data = NULL;
}
return (1);
}
static char *MYstrtok(char *cmd, char *toks, char **ptr)
{
char *pa;
if (!cmd) {
cmd = *ptr;
if (!cmd)
return (NULL);
}
while (*cmd && strchr(toks, (int) *cmd))
++cmd;
if (!*cmd)
return (NULL);
if (pa = strpbrk(cmd, toks))
*pa++ = 0;
*ptr = pa;
return (cmd);
}
static void ParseConfigString(struct XPR_IO * IO, char *str)
{
char *delim = ",";
char *tokptr;
char *dupstr, *zz;
dupstr = AllocMem(strlen(str) + 1, MEMF_PUBLIC);
if (!dupstr)
return;
strcpy(dupstr, str);
zz = MYstrtok(dupstr, delim, &tokptr);
if (zz)
do {
switch (toupper((int) *zz)) {
case 'T':
switch (toupper((int) *(zz + 1))) {
case '0':
IO->xpr_data->ascii = 0;
break;
case '1':
IO->xpr_data->ascii = 1;
break;
default:
DisplayBeep(NULL);
break;
}
break;
case 'C':
switch (*(zz + 1)) {
case '0':
IO->xpr_data->crc_conf = 0;
break;
case '1':
IO->xpr_data->crc_conf = 1;
break;
default:
DisplayBeep(NULL);
break;
}
break;
case 'K':
switch (*(zz + 1)) {
case '0':
IO->xpr_data->big = 0;
break;
case '1':
IO->xpr_data->big = 1;
break;
default:
DisplayBeep(NULL);
break;
}
break;
default:
DisplayBeep(NULL);
break;
}
zz = MYstrtok(0, delim, &tokptr);
} while (zz);
FreeMem(dupstr, strlen(str) + 1);
}
long XProtocolSetup(struct XPR_IO * IO)
{
long (*xupdate) (), (*xgets) (), (*xoptions) () = NULL;
struct XPR_UPDATE xpru;
char buffy[128];
if ((xupdate = IO->xpr_update) == NULL)
return (0);
if ((xgets = IO->xpr_gets) == NULL)
return (0);
if (IO->xpr_extension >= 1)
xoptions = IO->xpr_options;
/*
* Allocate a bit of memory for a data buffer
*/
if (IO->xpr_data == NULL) {
IO->xpr_data = AllocMem(sizeof(struct XProtocolData), MEMF_PUBLIC | MEMF_CLEAR);
if (!IO->xpr_data) {
xpru.xpru_updatemask = XPRU_ERRORMSG;
xpru.xpru_errormsg = "XModem - Out of memory!";
calla(xupdate, &xpru);
return (0L);
}
IO->xpr_data->buffer = &IO->xpr_data->packet[3];
}
/* If setup string isn't handed to us, ask questions */
if (IO->xpr_filename == NULL) {
if (xoptions) {
struct xpr_option *opti[4];
struct xpr_option opti3 =
{"Text Mode", XPRO_BOOLEAN, NULL, 4};
struct xpr_option opti2 =
{"1K Blocks", XPRO_BOOLEAN, NULL, 4};
struct xpr_option opti1 =
{"CRC", XPRO_BOOLEAN, NULL, 4};
struct xpr_option opti0 =
{"XModem options:", XPRO_HEADER, NULL, 0};
/* kludge because of manx aztec 5.0b stupid bug */
opti[0] = &opti0;
opti[1] = &opti1;
opti[2] = &opti2;
opti[3] = &opti3;
opti1.xpro_value = AllocMem(4, MEMF_PUBLIC);
if (opti1.xpro_value) {
if (IO->xpr_data->crc_conf)
strcpy(opti1.xpro_value, "on");
else
strcpy(opti1.xpro_value, "off");
}
opti2.xpro_value = AllocMem(4, MEMF_PUBLIC);
if (opti2.xpro_value) {
if (IO->xpr_data->big)
strcpy(opti2.xpro_value, "on");
else
strcpy(opti2.xpro_value, "off");
}
opti3.xpro_value = AllocMem(4, MEMF_PUBLIC);
if (opti3.xpro_value) {
if (IO->xpr_data->ascii)
strcpy(opti3.xpro_value, "on");
else
strcpy(opti3.xpro_value, "off");
}
callad(xoptions, &opti, IO->xpr_finfo?3:4);
if (
(!strcmp(opti1.xpro_value, "yes")) ||
(!strcmp(opti1.xpro_value, "on"))
)
IO->xpr_data->crc_conf = 1;
else
IO->xpr_data->crc_conf = 0;
if (
(!strcmp(opti2.xpro_value, "yes")) ||
(!strcmp(opti2.xpro_value, "on"))
)
IO->xpr_data->big = 1;
else
IO->xpr_data->big = 0;
if (
(!strcmp(opti3.xpro_value, "yes")) ||
(!strcmp(opti3.xpro_value, "on"))
)
IO->xpr_data->ascii = 1;
else
IO->xpr_data->ascii = 0;
if (opti3.xpro_value)
FreeMem(opti3.xpro_value, 4);
if (opti2.xpro_value)
FreeMem(opti2.xpro_value, 4);
if (opti1.xpro_value)
FreeMem(opti1.xpro_value, 4);
} else {
sprintf(buffy, "T%d,C%d,K%d", IO->xpr_data->ascii, IO->xpr_data->crc_conf, IO->xpr_data->big);
callaa(xgets, "Enter XModem config string (A<0|1>,C<0|1>,K<0|1>)", buffy);
ParseConfigString(IO, buffy);
}
} else
ParseConfigString(IO, IO->xpr_filename);
return (1);
}
void PutCH(struct XPR_IO * IO, int ch)
{
long (*xfwrite) ();
if ((xfwrite = IO->xpr_fwrite) == NULL)
return;
if (IO->xpr_data->savech == '\032')
return;
if (IO->xpr_data->savech == '\r') {
if (ch != '\n') {
unsigned char blou = IO->xpr_data->savech;
calladda(xfwrite, &blou, 1, 1, (void *) IO->xpr_data->fp);
}
IO->xpr_data->savech = 0;
}
if (IO->xpr_data->ascii) {
if (ch == '\r' || ch == '\032')
IO->xpr_data->savech = ch;
else {
unsigned char blou = ch;
calladda(xfwrite, &blou, 1, 1, (void *) IO->xpr_data->fp);
}
} else {
unsigned char blou = ch;
calladda(xfwrite, &blou, 1, 1, (void *) IO->xpr_data->fp);
}
}
int GetCH(struct XPR_IO * IO)
{
unsigned char chc;
int ch;
long (*xfread) ();
if ((xfread = IO->xpr_fread) == NULL)
return (0L);
if (IO->xpr_data->savech) {
ch = IO->xpr_data->savech;
IO->xpr_data->savech = 0;
} else {
if (!calladda(xfread, &chc, 1, 1, (void *) IO->xpr_data->fp))
ch = EOF;
else
ch = (int) chc;
if (IO->xpr_data->ascii) {
if (ch == '\n') {
IO->xpr_data->savech = ch;
ch = '\r';
} else if (ch == EOF) {
IO->xpr_data->savech = EOF;
ch = '\032';
}
}
}
return (ch);
}
void SerialTransparent(struct XPR_IO * IO)
{
if (IO->xpr_setserial) {
IO->xpr_data->serialbits = calld(IO->xpr_setserial, -1);
calld(IO->xpr_setserial, ((IO->xpr_data->serialbits) & ~(1 + 2 + 4 + 64 + 256 + 1024 + 2048 + 4096)) | 128);
}
}
void SerialRestore(struct XPR_IO * IO)
{
if (IO->xpr_setserial)
calld(IO->xpr_setserial, IO->xpr_data->serialbits);
}
long XProtocolSend(struct XPR_IO * IO)
{
long brkflag = 0, size=0, oldascii;
long (*xupdate) (), (*xswrite) (), (*xfopen) (), (*xfclose) (),
(*xfread) (), (*xsread) (), (*xfinfo) (), (*xchkabort) (void);
struct XPR_UPDATE xpru;
if ((xupdate = IO->xpr_update) == NULL)
return (0L);
if ((xswrite = IO->xpr_swrite) == NULL)
return (0L);
if ((xfopen = IO->xpr_fopen) == NULL)
return (0L);
if ((xfclose = IO->xpr_fclose) == NULL)
return (0L);
if ((xfread = IO->xpr_fread) == NULL)
return (0L);
if ((xsread = IO->xpr_sread) == NULL)
return (0L);
if ((xchkabort = IO->xpr_chkabort) == NULL)
return (0L);
oldascii=IO->xpr_data->ascii;
if(xfinfo = IO->xpr_finfo) {
size = callad(xfinfo, IO->xpr_filename, 1); /* get file size */
switch(callad(xfinfo, IO->xpr_filename, 2)) { /* get file type */
case 1: IO->xpr_data->ascii=0; break; /* Binary */
case 2: IO->xpr_data->ascii=1; break; /* Text */
default: break; /* uh? */
}
}
IO->xpr_data->fp = callaa(xfopen, IO->xpr_filename, "r");
if (!IO->xpr_data->fp) {
xpru.xpru_updatemask = XPRU_ERRORMSG | XPRU_FILENAME;
xpru.xpru_errormsg = "Failed to open input file";
xpru.xpru_filename = IO->xpr_filename;
calla(xupdate, &xpru);
IO->xpr_data->ascii=oldascii;
return (0L);
}
/* Initialize display */
bm_infoinit(IO, 1, size);
SerialTransparent(IO);
if (!dl_snd(IO, GetCH))
brkflag = 2;
SerialRestore(IO);
if (IO->xpr_data->abort == 1)
brkflag = 1;
calla(xfclose, (void *) IO->xpr_data->fp);
xpru.xpru_updatemask = XPRU_MSG;
switch (brkflag) {
case 0:
xpru.xpru_msg = "Done";
break;
case 1:
xpru.xpru_msg = "Aborted";
break;
case 2:
xpru.xpru_msg = "Failed";
break;
}
calla(xupdate, &xpru);
IO->xpr_data->ascii=oldascii;
if (brkflag)
return (0);
else
return (1);
}
long XProtocolReceive(struct XPR_IO * IO)
{
long brkflag = 0, oldascii;
long (*xupdate) (), (*xswrite) (), (*xfopen) (), (*xfclose) (),
(*xfwrite) (), (*xsread) (), (*xfinfo) ();
struct XPR_UPDATE xpru;
if ((xupdate = IO->xpr_update) == NULL)
return (0L);
if ((xswrite = IO->xpr_swrite) == NULL)
return (0L);
if ((xfopen = IO->xpr_fopen) == NULL)
return (0L);
if ((xfclose = IO->xpr_fclose) == NULL)
return (0L);
if ((xfwrite = IO->xpr_fwrite) == NULL)
return (0L);
if ((xsread = IO->xpr_sread) == NULL)
return (0L);
oldascii=IO->xpr_data->ascii;
if(xfinfo = IO->xpr_finfo) switch(callad(xfinfo, IO->xpr_filename, 2)) { /* get file type */
case 1: IO->xpr_data->ascii=0; break; /* Binary */
case 2: IO->xpr_data->ascii=1; break; /* Text */
default: break; /* uh? */
}
IO->xpr_data->fp = callaa(xfopen, IO->xpr_filename, "w");
if (IO->xpr_data->fp == NULL) {
xpru.xpru_updatemask = XPRU_ERRORMSG | XPRU_FILENAME;
xpru.xpru_errormsg = "Failed to open output file";
xpru.xpru_filename = IO->xpr_filename;
calla(xupdate, &xpru);
IO->xpr_data->ascii=oldascii;
return (0L);
}
IO->xpr_data->savech = 0;
/* Initialize display */
bm_infoinit(IO, 0, 0);
SerialTransparent(IO);
if (!dl_rcv(IO, PutCH))
brkflag = 2;
SerialRestore(IO);
if (IO->xpr_data->abort == 1)
brkflag = 1;
/*
* Close the file
*/
calla(xfclose, (void *) IO->xpr_data->fp);
xpru.xpru_updatemask = XPRU_MSG;
switch (brkflag) {
case 0:
xpru.xpru_msg = "Done";
break;
case 1:
xpru.xpru_msg = "Aborted";
break;
case 2:
xpru.xpru_msg = "Failed";
break;
}
calla(xupdate, &xpru);
IO->xpr_data->ascii=oldascii;
if (brkflag) {
long (*xsflush)(void);
if (xsflush = IO->xpr_sflush) xsflush();
return (0);
} else return (1);
}
/**
*
* The following is stuff replacing mdio.c
*
**/
/*
* md_get - get a character from the modem with timeout
*/
int md_get(struct XPR_IO * IO, int tmo)
{
int ch;
unsigned char chc;
long howmany;
long (*xchkabort) (void);
xchkabort = IO->xpr_chkabort;
if (xchkabort())
if (!IO->xpr_data->abort)
IO->xpr_data->abort = 1;
if (IO->xpr_data->abort) {
calladd(IO->xpr_sread, &chc, 1, 1);
return (DT_ERR);
}
howmany = calladd(IO->xpr_sread, &chc, 1, tmo * 1000000L);
ch = chc;
if (!howmany)
return (DT_TIME);
return (ch);
}
/*
* md_put - output a character to the modem
*/
void md_put(struct XPR_IO * IO, int ch)
{
unsigned char chc = ch;
callad(IO->xpr_swrite, &chc, 1);
}
/*
* md_write - write a packet to the modem
*/
void md_write(struct XPR_IO * IO, char *buf, int len)
{
callad(IO->xpr_swrite, buf, len);
}