home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Columbia Kermit
/
kermit.zip
/
archives
/
uniflex.tar.gz
/
uniflex.tar
/
ufkerm.uue
/
ufkerm.arc
/
UFUTIL.C
< prev
Wrap
C/C++ Source or Header
|
1989-01-09
|
17KB
|
622 lines
#include "ufk.h"
#include <pwd.h>
#include <sgtty.h>
#include <signal.h>
#include <setjmp.h>
#include <stat.h>
/*
* split command line into seperate strings
*/
split(cmd_str, cmds)
char *cmd_str[],
*cmds[];
{
char *malloc();
char *p,
*q,
result[128];
numprm = 0; /* no parameters yet */
p = &cmd_str[0]; /* setup pointer to input string */
while (*p && (*p != COMMENT)) /* do till end of string */
{
if (numprm == MAXPRM) /* no more space */
{
prterr(ER_TOOMPRM);
return(FALSE);
}
while (isspace(*p)) /* strip leading white space */
p++;
sscanf(p, "%s", result); /* get part of input string */
if ((q = malloc(strlen(result) + 1)) == NULL) /* allocate string space */
{
prterr(ER_NOMEM);
kerm_exit();
}
strcpy(q, result); /* copy part to allocated memory */
cmds[numprm++] = q; /* save pointer to string */
while ((!isspace(*p)) && *p) /* skip to end of this string */
p++;
}
return (TRUE);
}
/*
* parse command components
*/
parse(command_string, table)
char *command_string;
TABLE table[];
{
char i = 0,
j;
int mstat,
cmd_num = 0,
tv = 0,
unique = FALSE;
make_lower(command_string); /* convert to lower case */
while (*table[i].string) /* do until end of command table */
{
mstat = match(table[i].string, command_string); /* do compare */
if (mstat == -1)
return (table[i].funcadr); /* exact match found */
if (mstat != 0) /* some characters did match */
{
if (mstat > tv) /* longer than so far ? */
{
tv = mstat; /* save longest length */
cmd_num = i; /* remember which command */
unique = TRUE; /* it's unique so far */
}
j = i;
while (*table[++j].string) /* start new search from next entry */
{
mstat = match(table[j].string, command_string); /* other match ? */
if (mstat == -1)
return (table[j].funcadr); /* exact match */
if (mstat != 0) /* some characters did match */
{
if (mstat > tv) /* longer than so far ? */
{
tv = mstat; /* save greatest length */
cmd_num = i; /* remember which command */
unique = TRUE; /* it's unique so far */
}
if (mstat == tv) /* another one of the same length ? */
unique = FALSE; /* yes, it's not unique anymore */
}
}
if (!unique) /* if it was'nt unique it's ambiguous */
return (NULL);
else
return (table[cmd_num].funcadr); /* else it's a valid command */
}
i++; /* try next entry */
}
if (cmd_num == 0)
return (ERROR); /* no such command */
else return (table[cmd_num].funcadr); /* return command number */
}
match(s, t)
char *s, *t;
{
int len = 0,
inputlen;
inputlen = strlen(t); /* length of input command */
while (*s) /* do until end of string */
{
if (*s++ != *t++) /* if no match */
{
if (inputlen == 0) /* total command checked */
return (len); /* return matched length */
else
return (0); /* no match for this command */
}
len++; /* one more character done */
--inputlen; /* count down input string length */
}
return (-1); /* full match found */
}
/*
* m a k e _ u p p e r
*
* Convert string to upper case
*/
make_upper(p)
char *p;
{
while (*p)
{
if (islower(*p))
*p = toupper(*p);
p++;
}
}
/*
* m a k e _ l o w e r
*
* Convert string to lower case
*/
make_lower(p)
char *p;
{
while (*p)
{
if (isupper(*p))
*p = tolower(*p);
p++;
}
}
/*
* p r e r r p k t
*
* Print contents of error packet received from remote host.
*/
prerrpkt(msg)
char *msg;
{
if (!nooutput)
{
disp(0,19,"Kermit aborting with following error from remote host:");
foreground();
disp(0,20,msg);
background();
beep();
}
}
/*
* send ASCII file to remote without protocol.
* handshake is used.
*/
jmp_buf trn_env;
trnsmit()
{
FILE *xmitfp;
char c1;
int c, trnsm_int();
struct sgttyb mode;
if (numprm <= 1) /* check for parameters */
prterr(ER_FSPCREQ);
else
{
if ((xmitfp = fopen(params[1], "r")) == NULL)
prterr(ER_OPENERR);
else
{
if (!open_port(FALSE,FALSE))
prterr(ER_POPNERR);
else
{
signal(SIGINT,trnsm_int);
if (!setjmp(trn_env))
while ((c = getc(xmitfp)) != EOF) /* get character from file */
{
if (debug)
putc(c, stdout); /* send to console as well */
gtty(ttyfd,&mode);
if (mode.sg_speed & INCHR)
{
read(ttyfd,&c1,1); /* Check received character */
if ((c1 & 0177) == dstop && dstop != 0)/* Stop chr ? */
do /* Yes */
read(ttyfd,&c1,1); /* Wait for next character */
while ((c1 & 0177) != dstart);/* Wait for start chr */
}
c1 = c; /* Only high byte of int would be send (=0) */
write(ttyfd,&c1,1); /* Send to output port */
}
else
if (debug)
fputs("\n",stdout);
fclose(xmitfp);
kdelay(1); /* Give the port time to finish */
close_port(FALSE,FALSE);
}
}
}
}
trnsm_int()
{
longjmp(trn_env,TRUE); /* Transmit interrupted... */
}
/*
* Read KERMIT commands from file
*/
take(startup,echo)
char startup, echo;
{
FILE *tfp;
char data[133], /* Command input */
fname[132];
if (startup)
strcpy(fname, INITFILE); /* Use default name at startup */
else
{
if (numprm <= 1) /* Filename must be given */
{
prterr(ER_FSPCREQ);
return;
}
else
strcpy(fname, params[1]);
}
if ((tfp = fopen(fname,"r")) != NULL) /* Look for command file */
{ /* Found file, read commands */
while (fgets(data,132,tfp))
{
if (echo)
{
fputs(prompt,stdout); /* Echo prompt */
fputs(data,stdout); /* Echo command */
}
data[strlen(data) - 1] = '\0'; /* Zap newline */
if (data[0] && data[0] != COMMENT) /* Not a blank line */
kerm_command(data); /* Do command */
}
fclose(tfp);
}
else
if (!startup)
prterr(ER_OPENERR);
}
/*
* call UniFLEX to perform external command
*/
do_uniflex()
{
static char *shell = { "/bin/shell" };
static char *opt = { "+xc" };
char *prm[4],
*p,
cmdline[256];
int i,
kerm_exit();
prm[0] = &shell[5]; /* setup program name */
prm[1] = prm[3] = 0; /* end of parameters pointer */
if (numprm > 1)
{
prm[1] = opt; /* one shot option */
prm[2] = p = cmdline; /* pointers to start of commandline */
for (i = 1; i < numprm; i++)
{
strcpy(p,params[i]); /* copy params into one line */
p += strlen(p); /* point after command */
*p++ = ' '; /* separator */
}
*p = '\0'; /* end of string */
}
if (!fork()) /* duplicate myself */
{
execvp(shell,prm); /* execute command in child */
prterr(ER_SPAWN); /* should not come here */
}
else
{
signal(SIGTERM,SIG_IGN); /* Ignore this signals */
signal(SIGHUP,SIG_IGN);
signal(SIGQUIT,SIG_IGN);
signal(SIGINT,SIG_IGN);
wait(0); /* wait for child to die */
signal(SIGTERM,kerm_exit); /* Set signals again */
signal(SIGHUP,kerm_exit);
signal(SIGQUIT,SIG_DFL); /* Make these default */
signal(SIGINT,SIG_DFL);
}
}
disk_free()
{
char dev[30];
long size;
if (numprm <= 1)
strcpy(dev,"."); /* use current place if not specified */
else
strcpy(dev,params[1]); /* use specified place */
if ((size = get_free(dev)) != -1l)/* if no error... */
printf("Number of free blocks: %ld (%ld bytes)\n",size, size * 512);
}
chd()
{
struct passwd *p;
if (numprm <= 1)
{
if ((p = getpwuid(getuid())) == NULL)
prterr(ER_GETPWDID);
chdir(p->pw_dir);
set_dir(p->pw_dir);
}
else
{
if (chdir(params[1]) == ERROR)
prterr(ER_INVDIR);
else
set_dir(params[1]);
}
}
/*
* show statistics about connection
*/
statistics()
{
static char s1[] = "Characters sent:\t\t%ld\n";
static char s2[] = "Data characters sent:\t\t%ld\n";
static char s3[] = "NAK's sent:\t\t\t%d\n";
static char s4[] = "Packets sent:\t\t\t%d\n";
static char s5[] = "Characters received:\t\t%ld\n";
static char s6[] = "Data characters received:\t%ld\n";
static char s7[] = "NAK's received:\t\t\t%d\n";
static char s8[] = "Packets received:\t\t%d\n";
printf("Totals for the last transfer:\n\n");
printf(s1, chr_sent);
printf(s2, dchr_sent);
printf(s3, nak_sent);
printf(s4, pack_sent);
printf(s5, chr_rec);
printf(s6, dchr_rec);
printf(s7, nak_rec);
printf(s8, pack_rec);
printf("Effective data rate:\t\t%d baud\n", data_rate);
printf("\nTotals since KERMIT was started:\n\n");
printf(s1, t_chr_sent);
printf(s2, t_dchr_sent);
printf(s3, t_nak_sent);
printf(s4, t_pack_sent);
printf(s5, t_chr_rec);
printf(s6, t_dchr_rec);
printf(s7, t_nak_rec);
printf(s8, t_pack_rec);
printf("Mean effective data rate:\t%d baud\n", t_data_rate);
}
#define POLYIT 0x8408 /* Polynomial for CRC-CCITT */
#define POLY16 0xa001 /* Polynomial for CRC-16 (not used here) */
unsigned int crc_value, crc[256]; /* Global accessible variables */
init_crc_table()
{
int count, nr;
unsigned int accum, crcch;
for (count = 0; count < 256; count++) /* Build CRC lookup table */
{
accum = 0;
crcch = count;
for (nr = 0; nr < 8; nr++)
{
if (((accum & 0xff) ^ crcch) & 1)
accum = (accum / 2) ^ POLYIT;
else
accum = (accum / 2);
crcch = (crcch / 2);
}
crc[count] = accum; /* Save calculated value in table */
}
}
zero_crc()
{
crc_value = 0; /* Initial value is zero */
}
unsigned int calc_crc(value)
unsigned char value;
{
crc_value = crc[value ^ (crc_value & 0xff)] ^ ((crc_value >> 8) & 0xff);
return crc_value; /* Return accumulated value so far */
}
beep()
{
if (!remote && !nooutput)
putc(BELL,stdout);
}
disp(x,y,string)
int x,y;
char *string;
{
if (!remote)
{
posit(x,y);
fputs(string,stdout);
if (!screen && !nooutput)
fputs("\n",stdout);
}
}
set_frame()
{
if (screen && !remote && !nooutput)
{
clear_screen();
posit(28,0);
foreground();
fprintf(stdout," KERMIT version %s ",VERSION);
background();
if (sflg || rflg)
{
disp(0,4,"Transferred:");
disp(27,4,"Percentage:");
}
disp(0,6,"Packet received:");
disp(0,7,"Packet transmitted:");
if (debug >= 1)
{
disp(0,9,"Data received:");
disp(0,11,"Data transmitted:");
disp(0,13,"Receive state:");
disp(36,13,"Send state:");
disp(27,6,"Type:");
disp(27,7,"Type:");
disp(37,6,"Length:");
disp(37,7,"Length:");
disp(50,6,"Checksum:");
disp(50,7,"Checksum:");
}
curs_off(); /* Turn off cursor */
}
}
disp_state(x,y,state)
int x,y;
char state;
{
static char sa[] = "Attribute ";
static char sb[] = "Break ";
static char sc[] = "Complete ";
static char sd[] = "Data ";
static char sf[] = "Filename ";
static char sq[] = "Abort ";
static char sr[] = "Receive init";
static char ss[] = "Send init ";
static char st[] = "Timeout ";
static char sz[] = "End of file ";
static char un[] = "Unknown ";
char dsc[5];
if (debug == 2)
strcpy(dsc,"%s\r");
else
strcpy(dsc,"%s\r\l");
posit(x,y);
switch(state)
{
case 'A':
prtdbg(dsc,sa);
break;
case 'B':
prtdbg(dsc,sb);
break;
case 'C':
prtdbg(dsc,sc);
break;
case 'D':
prtdbg(dsc,sd);
break;
case 'F':
prtdbg(dsc,sf);
break;
case 'Q':
prtdbg(dsc,sq);
break;
case 'R':
prtdbg(dsc,sr);
break;
case 'S':
prtdbg(dsc,ss);
break;
case 'T':
prtdbg(dsc,st);
break;
case 'Z':
prtdbg(dsc,sz);
break;
default:
prtdbg(dsc,un);
}
}
prtdbg(fmt, a1, a2, a3, a4, a5, a6)
char *fmt;
{
if ((debug >= 1) && !remote)
fprintf(stdout,fmt,a1,a2,a3,a4,a5,a6);
if (debug == 2)
fprintf(dbgfil,fmt,a1,a2,a3,a4,a5,a6);
}
prtdbgf(fmt, a1, a2, a3, a4, a5, a6)
char *fmt;
{
if (debug == 2)
fprintf(dbgfil,fmt,a1,a2,a3,a4,a5,a6);
}
map_case(name,mode)
char *name;
int mode;
{
if (mapping)
{
if (mode == IN)
make_lower(name);
else if (mode == OUT)
make_upper(name);
}
}
new_name(s)
char *s;
{
struct stat buf;
int num;
char new_str[15],
num_str[5];
num = 0;
do /* Construct new filename */
{ /* until new name not found */
if (num++ > 4095) /* Bump counter */
{
error(PER_CREATE,"%s",new_str);/* FATAL error */
kerm_exit(); /* More than 4096 files ??? */
}
strncpy(new_str,s,10); /* Copy 10 characters at most */
new_str[10] = '\0'; /* Truncate at position 10 */
sprintf(num_str,".%03x",num); /* Format new filename */
strcat(new_str,num_str);
}
while (!stat(new_str,&buf)); /* If it exists, try again */
strcpy(s,new_str); /* Save new filename */
}
synerr(threshold)
int threshold;
{
if ((threshold != 0) && (numprm >= threshold))
return FALSE;
prterr(ER_SYNERR);
return TRUE;
}
check_bg()
{
int oldsig;
oldsig = signal(SIGINT,SIG_IGN); /* Get old KBD signal */
signal(SIGINT,oldsig); /* Restore */
bg = oldsig; /* TRUE if we're in the background */
}