home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
rtsi.com
/
2014.01.www.rtsi.com.tar
/
www.rtsi.com
/
OS9
/
OSK
/
TELECOM
/
xyz.lzh
/
main.c
< prev
next >
Wrap
C/C++ Source or Header
|
1995-08-18
|
10KB
|
308 lines
/*
`main' function for XY, Z, and K programs.
This file shamelessly uses ANSI token-pasting and other
hairy constructs in order to provide a single main file
for three different programs. GCC 1.42 has no problems
with this, and Ultra-C should work. The older Microware
C compiler will almost certainly not work.
*/
#include <stdio.h>
#include <time.h>
#include <ctype.h>
#include "ftserial.h"
#include "ftdisk.h"
#include "ftdebug.h"
#include "ftprog.h"
#ifdef XYMAIN
#include "ftxy.h"
#define PROG "XY"
#define PROTOCOL_FCN(func) XYModem ## func
#endif
#ifdef ZMAIN
#include "ftz.h"
#define PROG "Z"
#define PROTOCOL_FCN(func) ZModem ## func
#endif
#ifdef KMAIN
#include "ftk.h"
#define PROG "K"
#define PROTOCOL_FCN(func) Kermit ## func
#endif
#define DEBUG_FILE (0x80000000U)
#include <stddef.h>
const char *getenv(const char *);
void exit(int);
void *malloc(size_t);
int strlen(const char *);
char *strcpy(char *,const char *);
char *strcat(char *,const char *);
#define FALSE (0)
#define TRUE (1)
/****************************************************************************/
static void Banner(void)
{
const char *banner[] = {
PROG " version 1.1 (" __DATE__ ")",
"Copyright (C) 1995 Tim Kientzle. All Rights Reserved.",
NULL
};
const char **p = banner;
while (*p) fprintf(stderr, "%s\n",*p++);
}
/****************************************************************************/
static void Usage(void)
{
const char *help[] = {
"General Usage:",
" To send files: " PROG " <file1> <file2> <etc.>",
" To receive files: " PROG,
"",
"By default, " PROG " will automatically guess the type of each file.",
" To treat all files as a certain type:",
" -A All files are ASCII -B All files are Binary",
#ifdef XYMAIN
"By default, XY attempts to use the YModem protocol.",
" To influence xy's protocol determination:",
" -X XModem -K XModem-K -G YModem-G",
" -C XModem-CRC -Y YModem",
#endif
#ifdef ZMAIN
" To send a command via ZModem: -c \"command\"",
#endif
#ifdef KMAIN
#endif
" To get debugging information: -d, -dd, etc.",
"",
PROG " uses the MODEM environment variable to determine the port",
"to use. If none is available, stdio paths will be used.",
"The -p<port> option overrides the MODEM environment variable.",
"Host mode: -h forces " PROG " to use stdio paths and suppresses all",
"progress and debug messages. Equivalent to `unsetenv MODEM'.",
"",
"Based on \"The Working Programmer's Guide to Serial Protocols\"",
"Copyright (C) 1995 Tim Kientzle and The Coriolis Group, Inc.",
NULL
};
const char **p = help;
while (*p) fprintf(stderr, "%s\n",*p++);
exit(0);
}
/****************************************************************************/
int main(int argc, char **argv)
{
SERIAL_PORT serialPort;
const char *portName = getenv("MODEM");
DEBUG debug = NULL;
long debugFilter = 0;
PROGRESS progress = NULL;
const char **fileList;
int fileListLength = 0;
int hostMode = 0;
int fileType = diskFileUnknown;
int returnVal = 1;
#ifdef XYMAIN
XYMODEM ftHandle;
int protocol = YMODEM; /* Default protocol */
#endif
#ifdef ZMAIN
ZMODEM ftHandle;
int commandMode = FALSE;
#endif
#ifdef KMAIN
KERMIT ftHandle;
int speed = 0;
#endif
/* Allocate buffer for list of files to send */
fileList = (const char **)malloc(argc * sizeof(char *));
/* Process options */
while( --argc > 0 ) {
char *p=*++argv;
if (*p == '-') { /* Process option */
while (*++p) { /* Loop through all the letters */
switch(*p) { /* Process each letter */
/* Generic options */
case '?': Usage(); break;
case 'p':
case 'P':
p++;
if (*p == '=') p++;
if ( (*p == 0) && (--argc > 0) )
p = *++argv;
if (*p) {
portName = p;
p = p + strlen(p) - 1;
}
break;
case 'h': case 'H': hostMode++; break;
case 'D': debugFilter |= DEBUG_FILE;
case 'd':
{
char *q = p+1;
int d = 0;
while (isdigit(*q)) {
d = d*10 + *q++ - '0';
}
debugFilter |= d;
p = q-1;
}
break;
case 'a': case 'A': fileType = diskFileAscii; break;
case 'b': case 'B': fileType = diskFileBinary; break;
default: fprintf(stderr,"I don't understand option `-%c'.\n",*p);
Usage(); break;
#ifdef XYMAIN
/* XYModem-specific options */
case 'g': case 'G': protocol = YMODEMG; break;
case 'y': case 'Y': protocol = YMODEM; break;
case 'k': case 'K': protocol = XMODEMK; break;
case 'c': case 'C': protocol = XMODEMCRC; break;
case 'x': case 'X': protocol = XMODEM; break;
#endif
#ifdef ZMAIN
/* ZModem-specific options */
case 'c': case 'C': commandMode = TRUE; break;
#endif
#ifdef KMAIN
/* Kermit-specific options */
case 'f': case 'F': speed++; break;
#endif
}
}
} else {
fileList[fileListLength++] = p;
}
}
fileList[fileListLength] = NULL;
/* If no port name, suppress progress */
if ((portName != NULL) && (portName[0] == 0)) portName = NULL;
if (portName == NULL) hostMode++;
/* Print banner */
if (!hostMode) Banner();
#ifdef ZMAIN
/* ZModem-specific: If command mode, build command string */
if (commandMode) {
char *command;
unsigned length = 0;
int i;
for (i=0; i<fileListLength; i++) length += strlen(fileList[i])+1;
command = malloc(length);
strcpy(command,fileList[0]);
for (i=1; i<fileListLength; i++) {
strcat(command," ");
strcat(command,fileList[i]);
}
if (strlen(command) == 0) {
fprintf(stderr,"Z: Empty command not allowed!\n");
exit(1);
}
fileList[0] = command;
}
#endif
/* Print `Sending' or `Receiving' message */
if (fileListLength > 0) { /* Do send */
int i;
fprintf(stderr,"Sending: %s",fileList[0]);
for(i=1;i<fileListLength;i++)
fprintf(stderr,", %s",fileList[i]);
fprintf(stderr,"\n");
} else
fprintf(stderr,"Receiving...\n");
/* Initialize debug handle */
if (debugFilter & ~DEBUG_FILE) /* Leave NULL if no debugging requested */
DebugInit(&debug);
if ( (debugFilter & DEBUG_FILE) || (hostMode) ) {
DebugFile(debug,PROG ".log");
debugFilter &= ~DEBUG_FILE;
}
DebugSetFilter(debug, debugFilter);
/* if (!hostMode) diskDebug = debugFilter;*/
/* Initialize progress handle */
if (!hostMode) { /* No progress display in host mode */
ProgressInit(&progress);
ProgressSetDebug(progress, debug);
}
/* Open and setup serial port */
if (hostMode) portName = NULL;
if (SerialOpen(&serialPort,portName)) {
if (portName)
fprintf(stderr,PROG ": Couldn't open serial port ``%s.''\n",
portName);
else
fprintf(stderr,PROG ": Can't access stdio??\n");
exit(1);
};
SerialSaveState(serialPort);
#ifdef XYMAIN /* XYModem requires 8 bits, no parity, and no Xon/Xoff */
SerialSetWord(serialPort,8);
SerialSetParity(serialPort,parityNone);
SerialMakeTransparent(serialPort); /* XYModem-specific */
#endif
#ifdef ZMAIN /* ZModem requires 8 bits, no parity */
SerialSetWord(serialPort,8);
SerialSetParity(serialPort,parityNone);
#endif
if (PROTOCOL_FCN(Init)( &ftHandle, serialPort))
fprintf(stderr,"Error initializing file transfer handle\n");
else if (PROTOCOL_FCN(SetDebug)(ftHandle,debug))
fprintf(stderr,"Error setting debug handle\n");
else if (PROTOCOL_FCN(SetProgress)(ftHandle,progress))
fprintf(stderr,"Error setting progress handle\n");
else if (PROTOCOL_FCN(SetFileType)(ftHandle,fileType))
fprintf(stderr,"Error setting file type\n");
#ifdef XYMAIN
else if (PROTOCOL_FCN(SetProtocol)(ftHandle, protocol)) /* XYModem-specific */
fprintf(stderr,"Error setting protocol dialect\n");
#endif
#ifdef KMAIN
else if ((speed > 0) && PROTOCOL_FCN(SetFast)(ftHandle,speed))
fprintf(stderr,"Error setting speed\n");
#endif
#ifdef ZMAIN
else if (commandMode) { /* ZModem-specific: Send Command */
if ((returnVal = PROTOCOL_FCN(SendCommand)(ftHandle,fileList[0])))
fprintf(stderr,"\nError sending command!!\n");
}
#endif
else if (fileListLength > 0) { /* Send Files */
if ((returnVal = PROTOCOL_FCN(Send)(ftHandle,fileList,fileListLength)))
fprintf(stderr,"\nError sending!!\n");
} else { /* Receive Files */
if ((returnVal = PROTOCOL_FCN(Receive)(ftHandle)))
fprintf(stderr,"\nError receiving!!\n");
}
/* Destroy the handles and close the port */
PROTOCOL_FCN(Destroy)(ftHandle);
ProgressDestroy(progress);
DebugDestroy(debug);
SerialRestoreState(serialPort);
SerialClose(serialPort);
return returnVal;
}