328 lines
5.3 KiB
C
328 lines
5.3 KiB
C
|
#ifndef lint
|
||
|
static const char rcsid[] = "$Id: send.c,v 1.2 2001/10/25 23:56:29 efalk Exp $" ;
|
||
|
#endif
|
||
|
|
||
|
|
||
|
#define TEST /* standalone test */
|
||
|
|
||
|
#include <unistd.h>
|
||
|
#include <string.h>
|
||
|
#include "zmodem.h"
|
||
|
#include <sys/stat.h>
|
||
|
|
||
|
#include <fcntl.h>
|
||
|
#include <errno.h>
|
||
|
#include <sys/time.h>
|
||
|
#include <sys/termios.h>
|
||
|
#include <sys/termio.h> /* define TCSBRK */
|
||
|
#include <sys/param.h>
|
||
|
|
||
|
extern int errno ;
|
||
|
|
||
|
static u_char zeros[4] = {0,0,0,0} ;
|
||
|
|
||
|
main(argc,argv)
|
||
|
int argc ;
|
||
|
char **argv ;
|
||
|
{
|
||
|
struct termios old_settings, new_settings ;
|
||
|
fd_set readfds ;
|
||
|
struct timeval timeout ;
|
||
|
int i ;
|
||
|
int len ;
|
||
|
char buffer[1024] ;
|
||
|
int done = 0 ;
|
||
|
int filecount = 0 ;
|
||
|
ZModem info ;
|
||
|
|
||
|
#ifdef TEST
|
||
|
|
||
|
static u_char Amsg0[] = {
|
||
|
0x43,
|
||
|
} ;
|
||
|
static u_char Amsg1[] = {
|
||
|
0x06, 0x43,
|
||
|
} ;
|
||
|
static u_char Amsg2[] = {
|
||
|
0x06,
|
||
|
} ;
|
||
|
static u_char Amsg3[] = {
|
||
|
0x06,
|
||
|
} ;
|
||
|
static u_char Amsg4[] = {
|
||
|
0x06, 0x43,
|
||
|
} ;
|
||
|
static u_char Amsg5[] = {
|
||
|
0x06, 0x43,
|
||
|
} ;
|
||
|
static u_char Amsg6[] = {
|
||
|
0x06,
|
||
|
} ;
|
||
|
static u_char Amsg7[] = {
|
||
|
0x06,
|
||
|
} ;
|
||
|
static u_char Amsg8[] = {
|
||
|
0x06,
|
||
|
} ;
|
||
|
static u_char Amsg9[] = {
|
||
|
0x06, 0x43,
|
||
|
} ;
|
||
|
|
||
|
|
||
|
#define E(b) {b, sizeof(b)}
|
||
|
static struct {u_char *bm; int len} Bmsgs[] = {
|
||
|
E(Amsg0),
|
||
|
E(Amsg1),
|
||
|
E(Amsg2),
|
||
|
E(Amsg3),
|
||
|
E(Amsg4),
|
||
|
E(Amsg5),
|
||
|
E(Amsg6),
|
||
|
E(Amsg7),
|
||
|
E(Amsg8),
|
||
|
E(Amsg9),} ;
|
||
|
|
||
|
|
||
|
#endif /* TEST */
|
||
|
|
||
|
/* try to trap uninit. variables */
|
||
|
memset(&info,0xa5,sizeof(info)) ;
|
||
|
|
||
|
info.zsinitflags = 0 ;
|
||
|
info.attn = "\17\336" ;
|
||
|
info.packetsize = 1024 ;
|
||
|
info.windowsize = 4096 ;
|
||
|
|
||
|
#ifdef TEST
|
||
|
done = YmodemTInit(&info) ;
|
||
|
for(i=0; !done; ++i )
|
||
|
done = ZmodemRcv(Bmsgs[i].bm, Bmsgs[i].len, &info) ;
|
||
|
|
||
|
done = ZmodemTFile("utils.c","utils.c", 0,0,0,0, 1,0, &info) ;
|
||
|
for(; !done; ++i )
|
||
|
done = ZmodemRcv(Bmsgs[i].bm, Bmsgs[i].len, &info) ;
|
||
|
|
||
|
done = ZmodemTFile("foo.c","foo.c", 0,0,0,0, 1,0, &info) ;
|
||
|
for(; !done; ++i )
|
||
|
done = ZmodemRcv(Bmsgs[i].bm, Bmsgs[i].len, &info) ;
|
||
|
|
||
|
done = ZmodemTFinish(info) ;
|
||
|
|
||
|
#else
|
||
|
if( argc < 2 )
|
||
|
exit(2) ;
|
||
|
|
||
|
info.ifd = open(argv[1], O_RDWR) ;
|
||
|
|
||
|
if( info.ifd == -1 )
|
||
|
exit(1) ;
|
||
|
|
||
|
tcgetattr(info.ifd,&old_settings) ;
|
||
|
new_settings = old_settings ;
|
||
|
|
||
|
new_settings.c_iflag &=
|
||
|
~(ISTRIP|INLCR|IGNCR|ICRNL|IUCLC|IXON|IXOFF|IMAXBEL) ;
|
||
|
new_settings.c_oflag = 0 ;
|
||
|
new_settings.c_cflag = B300|CS8|CREAD|CLOCAL ;
|
||
|
new_settings.c_lflag = 0 ;
|
||
|
new_settings.c_cc[VMIN] = 32 ;
|
||
|
new_settings.c_cc[VTIME] = 1 ;
|
||
|
tcsetattr(info.ifd,TCSADRAIN, &new_settings) ;
|
||
|
|
||
|
InitXmit(&info) ;
|
||
|
XmitFile("utils.c",1,0,&info) ;
|
||
|
#ifdef COMMENT
|
||
|
XmitFile("foo",1,0,&info) ;
|
||
|
XmitFile("foo.c",1,0,&info) ;
|
||
|
XmitFile("raw",1,0,&info) ;
|
||
|
#endif /* COMMENT */
|
||
|
FinishXmit(&info) ;
|
||
|
|
||
|
tcsetattr(info.ifd,TCSADRAIN, &old_settings) ;
|
||
|
#endif /* TEST */
|
||
|
exit(0) ;
|
||
|
}
|
||
|
|
||
|
|
||
|
static int
|
||
|
doIO(info)
|
||
|
ZModem *info ;
|
||
|
{
|
||
|
fd_set readfds ;
|
||
|
struct timeval timeout ;
|
||
|
int i ;
|
||
|
int len ;
|
||
|
char buffer[1024] ;
|
||
|
int done = 0 ;
|
||
|
|
||
|
while(!done)
|
||
|
{
|
||
|
FD_ZERO(&readfds) ;
|
||
|
FD_SET(info->ifd, &readfds) ;
|
||
|
timeout.tv_sec = info->timeout ;
|
||
|
timeout.tv_usec = 0 ;
|
||
|
i = select(info->ifd+1, &readfds,NULL,NULL, &timeout) ;
|
||
|
if( i<0 )
|
||
|
perror("select") ;
|
||
|
else if( i==0 )
|
||
|
done = ZmodemTimeout(info) ;
|
||
|
else {
|
||
|
len = read(info->ifd, buffer, sizeof(buffer)) ;
|
||
|
done = ZmodemRcv(buffer, len, info) ;
|
||
|
}
|
||
|
}
|
||
|
return done ;
|
||
|
}
|
||
|
|
||
|
|
||
|
int
|
||
|
InitXmit(info)
|
||
|
ZModem *info ;
|
||
|
{
|
||
|
int done ;
|
||
|
|
||
|
done = ZmodemTInit(info) ;
|
||
|
if( !done )
|
||
|
done = doIO(info) ;
|
||
|
|
||
|
return done != ZmDone ;
|
||
|
}
|
||
|
|
||
|
|
||
|
XmitFile(filename,nfiles,nbytes,info)
|
||
|
char *filename ;
|
||
|
int nfiles, nbytes ;
|
||
|
ZModem *info ;
|
||
|
{
|
||
|
int done ;
|
||
|
|
||
|
done = ZmodemTFile(filename,filename, 0,ZMCLOB,0,0,
|
||
|
nfiles,nbytes, info) ;
|
||
|
if( done == ZmErrCantOpen || done == ZmFileTooLong )
|
||
|
return 0 ;
|
||
|
|
||
|
if( !done )
|
||
|
done = doIO(info) ;
|
||
|
|
||
|
return done != ZmDone ;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
FinishXmit(info)
|
||
|
ZModem *info ;
|
||
|
{
|
||
|
int done ;
|
||
|
|
||
|
done = ZmodemTFinish(info) ;
|
||
|
if( !done )
|
||
|
done = doIO(info) ;
|
||
|
|
||
|
return done != ZmDone ;
|
||
|
}
|
||
|
|
||
|
|
||
|
int
|
||
|
ZXmitStr(buffer, len, info)
|
||
|
u_char *buffer ;
|
||
|
int len ;
|
||
|
ZModem *info ;
|
||
|
{
|
||
|
int i,j ;
|
||
|
u_char c ;
|
||
|
extern double drand48() ;
|
||
|
|
||
|
#ifdef TEST
|
||
|
for(i=0; i<len; i += 16)
|
||
|
{
|
||
|
printf(" ") ;
|
||
|
for(j=0; j<16 && i+j<len; ++j)
|
||
|
printf("%2.2x ", buffer[i+j]) ;
|
||
|
for(; j<16; ++j)
|
||
|
printf(" ") ;
|
||
|
printf(" |") ;
|
||
|
for(j=0; j<16 && i+j<len; ++j)
|
||
|
putchar(((c=buffer[i+j]) < 040 || c >= 0177) ? '.' : c ) ;
|
||
|
printf("|\n") ;
|
||
|
}
|
||
|
#else
|
||
|
|
||
|
#ifdef COMMENT
|
||
|
/* TEST: randomly corrupt one out of every 300 bytes */
|
||
|
for(i=0; i<len; ++i)
|
||
|
if( drand48() < 1./300. ) {
|
||
|
fprintf(stderr, "byte %d was %2.2x, is", i, buffer[i]) ;
|
||
|
buffer[i] ^= 1<<(lrand48()&7) ;
|
||
|
fprintf(stderr, " %2.2x\n", buffer[i]) ;
|
||
|
}
|
||
|
#endif /* COMMENT */
|
||
|
|
||
|
if( write(info->ifd, buffer, len) != len )
|
||
|
return ZmErrSys ;
|
||
|
#endif /* TEST */
|
||
|
|
||
|
return 0 ;
|
||
|
}
|
||
|
|
||
|
|
||
|
void
|
||
|
ZIFlush(info)
|
||
|
ZModem *info ;
|
||
|
{
|
||
|
}
|
||
|
|
||
|
void
|
||
|
ZOFlush(info)
|
||
|
ZModem *info ;
|
||
|
{
|
||
|
}
|
||
|
|
||
|
void
|
||
|
ZStatus(i,j,str)
|
||
|
{
|
||
|
fprintf(stderr,"status %d=%d\n",i,j) ;
|
||
|
}
|
||
|
|
||
|
|
||
|
int
|
||
|
ZAttn(info)
|
||
|
ZModem *info ;
|
||
|
{
|
||
|
char *ptr ;
|
||
|
int i = 0 ;
|
||
|
|
||
|
for(ptr = info->attn; *ptr != '\0'; ++ptr) {
|
||
|
if( *ptr == ATTNBRK )
|
||
|
ioctl(info->ifd, TCSBRK, 0) ;
|
||
|
else if( *ptr == ATTNPSE )
|
||
|
sleep(1) ;
|
||
|
else
|
||
|
write(info->ifd, ptr, 1) ;
|
||
|
}
|
||
|
return 0 ;
|
||
|
}
|
||
|
|
||
|
|
||
|
FILE *
|
||
|
ZOpenFile(name, f0,f1,f2,f3, len, date, mode, filesRem, bytesRem, crc)
|
||
|
char *name ;
|
||
|
int f0,f1,f2,f3, len, mode, filesRem, bytesRem ;
|
||
|
long date ;
|
||
|
u_long crc ;
|
||
|
{
|
||
|
}
|
||
|
|
||
|
|
||
|
int
|
||
|
ZWriteFile()
|
||
|
{}
|
||
|
|
||
|
|
||
|
ZCloseFile(info)
|
||
|
ZModem *info ;
|
||
|
{}
|
||
|
|
||
|
ZFlowControl(info)
|
||
|
ZModem *info ;
|
||
|
{}
|