home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Boot Disc 8
/
boot-disc-1997-04.iso
/
PDA_Soft
/
Psion
/
comms
/
p3nfs
/
nfsc
/
xymodem.c
< prev
Wrap
C/C++ Source or Header
|
1996-05-26
|
7KB
|
314 lines
/*
* In this file lines end with CR/LF, as our psion C-compiler lives in the
* DOS-WORLD
* Copyright GNU Public License
*/
#include <plib.h>
#include <p_xmodem.h>
#include <p_serial.h>
#include <hwif.h>
#include "nfsc.h"
#ifdef HAVE_XYMODEM
TEXT *XYEnv="NFSC_XY";
static void
xy_configure(void)
{
UWORD xymodem = set.xymodem;
if ( uOpenDialog ("Choose the protocol")
|| uAddChoiceList ("Protocol: ", &xymodem,
"Xmodem, 1 Byte Checksum",
"Xmodem, 2 Byte CRC",
"Xmodem, 2 Byte CRC (1K)",
"Ymodem, 2 Byte CRC",
"Ymodem, 2 Byte CRC (1K)",
"Ymodem-G, 2 Byte CRC",
"Ymodem-G, 2 Byte CRC (1K)", NULL)
|| uRunDialog() <= 0)
return;
set.xymodem = xymodem;
return;
}
static UWORD
setmode(void)
{
UWORD ret = 0;
switch(set.xymodem)
{
case XY_XMODEM:
ret = P_XMDM_CHECKSUMMODE;
break;
case XY_XMODEMCRC:
ret = P_XMDM_CRCMODE;
break;
case XY_XMODEMCRC1K:
ret = P_XMDM_CRCMODE | P_XMDM_ONE_K;
break;
case XY_YMODEM:
ret = P_YMODEM_MODE;
break;
case XY_YMODEM1K:
ret = P_YMODEM_MODE | P_XMDM_ONE_K;
break;
case XY_YMODEMG:
ret = P_YMODEM_G_MODE;
break;
case XY_YMODEMG1K:
ret = P_YMODEM_G_MODE | P_XMDM_ONE_K;
break;
}
return ret;
}
static void *fp;
static char *buf;
static char fname[129]; /* Damn OPL string semantic */
static void
errmsg(char *txt)
{
wInfoMsgCorner(txt, W_CORNER_BOTTOM_RIGHT);
if(buf) p_free(buf);
if(fp) p_close(fp);
p_close(serial);
Sw_Serial(ON);
}
static char c_cancel[] = "Cancel";
static char c_cantopen[] = "Can't open XMD:";
static char c_filename[] = "Filename: ";
static char c_aborting[] = "XYmodem: Aborting";
static char c_done[] = "XYmodem: Done";
static char c_timedout[] = "Connection timed out";
char c_nomem[] = "Not enough memory";
static void
xy_sendfile(void)
{
H_DI_FSEL line1 = {fname, 0};
WORD len, l, ret;
UWORD type, mode;
P_INFO p_info;
char *s;
if((len = p_getenviron (XYEnv, p_slen(XYEnv), fname+1)) > 0)
*fname = len;
if ( uOpenDialog ("Select file to send")
|| uAddDialogItem (H_DIALOG_FSEL, c_filename, &line1)
|| (uAddButtonList (c_cancel,W_KEY_ESCAPE,"Send file",W_KEY_RETURN,NULL))
|| uRunDialog() <= 0)
return;
p_setenviron(XYEnv, p_slen(XYEnv), fname+1, p_slen(fname+1)+1);
/* ---------------------------------------- Let's open the XYmodem device */
Sw_Serial(OFF); /* Cancel outstanding events */
if(p_open(&serial, "XMD:",-1))
{
wInfoMsgCorner(c_cantopen, W_CORNER_BOTTOM_RIGHT);
Sw_Serial(ON); /* Re-enable input */
return;
}
type = P_XMDM_ACCP;
mode = setmode();
len = (mode & P_XMDM_ONE_K) ? 1024 : 128;
buf = 0;
fp = 0;
if(p_open(&fp, fname+1, P_FOPEN|P_FSTREAM|P_FSHARE))
{
errmsg("Can't read the file");
return;
}
if(!(buf = p_alloc(len)))
{
errmsg(c_nomem);
return;
}
AddToHistory('>');
if(p_iow(serial, P_FCONNECT, &type, &mode))
{
errmsg(c_timedout);
return;
}
AddToHistory('s');
/* ---------------------------------------------- Transmit the whole file */
ret = 0;
if(set.xymodem >= XY_YMODEM) /* Ymode protocol must send the filename */
{
/* Transmit only the filename, not the whole path */
if((l = p_slocr(fname+1, '\\')) >= 0 ||
(l = p_slocr(fname+1, ':' )) >= 0)
l++;
else
l = 0;
/* Filename + length(decimal) + date(octal) */
p_bfil(buf, 128, 0);
p_finfo(fname+1, &p_info);
s = p_scpy(buf, fname+1+l) + 1;
s += p_gltob(s, p_info.size, 10);
*s++ = ' ';
s += p_gltob(s, p_info.modst, 8);
l = 128;
ret = p_iow(serial, P_FWRITE, buf, &l);
AddToHistory(ret ? 'F' : 'f');
}
l = 0;
while(ret == 0 && (l = p_read(fp, buf, len)) > 0)
{
ret = p_iow(serial, P_FWRITE, buf, &l);
AddToHistory(ret ? 'S' : 's');
}
if(!ret && (!l || l == E_FILE_EOF)) /* Send EOT */
{
l = 0;
ret = p_iow(serial, P_FWRITE, buf, &l);
if(set.xymodem >= XY_YMODEM)
p_iow(serial, P_FCONNECT, &type, &mode);
}
if(l)
AddToHistory(l < 0 ? 'L' : 'l');
else
AddToHistory(ret ? 'C' : 'c');
/* --------------------------------------------- Close the XYmodem device */
p_iow(serial, P_FDISCONNECT);
errmsg((ret || l) ? c_aborting : c_done);
}
static void
xy_receivefile(void)
{
H_DI_FSEL line1 = {fname, 0};
WORD len, l, ret;
UWORD type, mode;
char xname[128];
mode = setmode();
len = (mode & P_XMDM_ONE_K) ? 1024 : 128;
/*
p_bfil(fname, sizeof(fname), 0);
*/
if(mode >= XY_YMODEM)
line1.flags = H_FILE_JUST_DIRS;
if ( uOpenDialog ("XYmodem receive")
|| uAddDialogItem (H_DIALOG_FSEL,
mode >= XY_YMODEM? "Directory: ":c_filename, &line1)
|| (uAddButtonList (c_cancel,W_KEY_ESCAPE,"Receive",W_KEY_RETURN,NULL))
|| uRunDialog() <= 0)
return;
/* ---------------------------------------- Let's open the XYmodem device */
Sw_Serial(OFF); /* Cancel outstanding events */
if(p_open(&serial, "XMD:",-1))
{
wInfoMsgCorner(c_cantopen, W_CORNER_BOTTOM_RIGHT);
Sw_Serial(ON); /* Re-enable input */
return;
}
type = P_XMDM_INIT;
buf = 0;
fp = 0;
if(!(buf = p_alloc(len)))
{
errmsg(c_nomem);
return;
}
for(;;)
{
AddToHistory('>');
if(p_iow(serial, P_FCONNECT, &type, &mode))
{
errmsg(c_timedout);
return;
}
if(set.xymodem >= XY_YMODEM) /* Ymodem: the first frame is filename */
{
l = len;
if((ret = p_iow(serial, P_FREAD, buf, &l)) != 0)
{
errmsg(c_timedout);
return;
}
if(p_slen(buf) == 0)
{
p_iow(serial, P_FDISCONNECT);
errmsg(c_done);
return;
}
if((l = p_slocr(buf, '\\')) >= 0 || (l = p_slocr(buf, '/')) >= 0)
l++;
else
l = 0;
p_scpy(xname, fname+1);
p_scat(xname, buf+l);
}
else
p_scpy(xname, fname+1);
if(p_open(&fp, xname, P_FUPDATE|P_FSTREAM|P_FREPLACE))
{
p_iow(serial, P_FDISCONNECT);
/*
errmsg("Can't write the file");
*/
errmsg(xname);
return;
}
AddToHistory('f');
/* ------------------------------------------ Transmit the whole file */
ret = 0;
while(ret == 0)
{
l = len;
if((ret = p_iow(serial, P_FREAD, buf, &l)) != 0)
break;
ret = p_write(fp, buf, l);
AddToHistory(ret ? 'R' : 'r');
}
p_close(fp); fp = 0;
if(set.xymodem < XY_YMODEM)
break;
if(ret != E_FILE_EOF)
break;
}
AddToHistory(ret == E_FILE_EOF ? 'c' : 'C');
/* --------------------------------------------- Close the XYmodem device */
p_iow(serial, P_FDISCONNECT);
errmsg((ret || l) ? c_aborting : c_done);
}
void
DoXYmodem(char key)
{
if(key == 'C')
xy_configure();
if(key == 'S')
xy_sendfile();
if(key == 'R')
xy_receivefile();
}
#endif /* HAVE_XYMODEM */