home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Chip 1998 March
/
CHIPCD_3_98.iso
/
software
/
share
/
sharmies
/
unixdos
/
data.z
/
diff4a.txt
< prev
next >
Wrap
Text File
|
1997-11-18
|
24KB
|
683 lines
/*****************************************************************************/
/* (C) Copyright, B. EICHBGERGER, All rights reserved. */
/* */
/* This program remains the exclusive property of B. EICHBERGER */
/* may not be sold, used, copied, displayed or modified without the written */
/* consent of Burkhard Eichberger, P.O.Box 4767, Boulder, Colorado 80306 */
/*****************************************************************************/
#include <stdio.h>
#include <sys\types.h>
#include <sys\stat.h>
#include "def.h"
#define EXPARG_M
#include "exparg.h"
#include "def_s.h"
#include "dir.h"
VAR_EXT;
int system(const char *);
#define MAXBUF 100
#define MAXLEAD 20
#define FN_WRK "~"
#define FN_CFG "dx.cfg"
#define CHR_SYS '`'
#define CHR_QUOTE '"'
#define CHR_INV '!'
#define CHR_SEP ';'
#define CHR_PIPE '#'
#define CHR_IN '{'
#define CHR_OUT '}'
#define CHR_ENV1 '%'
#define CHR_ENV2 '$'
#define CHR_LST '@'
int do_arg_xinv = OFF;
char do_arg_sep = CHR_SEP;
char do_arg_pipe = CHR_PIPE;
char do_arg_in = CHR_IN;
char do_arg_out = CHR_OUT;
char do_arg_dir[MAXFILNAM+1]; /* last directory */
char do_arg_fnwrk[MAXFILNAM+1]; /* work filename */
char do_arg_lead[MAXLEAD+1]; /* leadin command */
int do_arg_ins(char *szNew);
int do_fillst(char *szArg);
int do_getenv(char *szArg,char *szOut);
int do_arg_bld(char *szArg);
int do_arg_sys(char *szCmd,char *szTail);
/****** PROCESS ARGUMENT EXPANSION ******************************************/
/* Input: */
/* ac = Number of arguments on command line */
/* av = Argument Vector */
/* */
/* Output: */
/* 0 = OK */
/* -1 = Cannot open database */
/* -2 = Cannot open window environment */
/* -3 = Cannot open getinp environment */
/* -4 = Cannot get sellst RAM */
/* -5 = Not enough RAM */
/* -6 = Missing string flex file */
/* -7 = Escape at initial screen */
/****************************************************************************/
int do_arg (int ac,char *av[])
{
FILE *fcfg;
register int i, i0, i1;
char buf1[100+1];
char bufcmd[128+1];
char fncfg[MAXFILNAM+1];
char c, c1, c2, cout;
char *arg, *p, *p0, *pout;
char *ptail;
int xend;
int xsys;
/****** INIT ************************************************************/
argc = 0;
MEMZAP0(do_arg_dir,sizeof(do_arg_dir));
/****** PROCESS PROGRAM NAME ********************************************/
do_arg_ins(av[0]);
/****** PROCESS ARGUMENTS ***********************************************/
for (i=1; i < ac; i++)
{
/****** GET ARGUMENT ************************************************/
arg = av[i];
/****** PROCESS FILE LIST *******************************************/
if (do_fillst(arg) == 0)
{
continue;
}
/****** PROCESS ENVIRONMENT *****************************************/
if (do_getenv(arg,buf1) == 0)
{
do_arg_bld(buf1);
continue;
}
/****** CHECK FOR BACK QUOTE SYSTEM CALLS `cmd` *********************/
xsys = OFF;
p = arg;
pout = do_arg_lead;
while ((c = *p++) != '\0')
{
if (c == CHR_SYS) { xsys = ON; break; }
*pout++ = c;
}
*pout = '\0';
/****** REGULAR PLAIN ARGUMENT **************************************/
if (xsys == OFF)
{
do_arg_bld(arg);
continue;
}
p0 = p;
/****** PROCESS THE CONFIG FILE *************************************/
strncpy(do_arg_fnwrk,FN_WRK,sizeof(do_arg_fnwrk));
strncpy(fncfg,av[0],sizeof(fncfg));
p = fncfg + strlen(fncfg) - 1;
while (*p != '\\') *p-- = '\0';
p++;
strcat(p,FN_CFG);
if ((fcfg = fopen(fncfg,"rb")) != NULL)
{
while (fgetl(bufcmd,sizeof(bufcmd)-1,fcfg) != EOF)
{
p = bufcmd;
cout = '\0';
while ((c = *p++) != '\0')
{
if (c != '=') continue;
if (*p != '\\') { cout = *p; break; }
c1 = shtoi(p[1]);
c2 = shtoi(p[2]);
if ((c1 < 0) || (c2 < 0))
{
FERR"exp: Invalid hex number in '%s': %s\n",
fncfg,bufcmd);
break;
}
cout = (c1<<4) + c2;
break;
}
if (cout == '\0') continue;
if (memcmp(bufcmd,"PIPE=" ,5) == 0) { do_arg_pipe = cout; continue; }
if (memcmp(bufcmd,"CMDSEP=",7) == 0) { do_arg_sep = cout; continue; }
if (memcmp(bufcmd,"IN=" ,3) == 0) { do_arg_in = cout; continue; }
if (memcmp(bufcmd,"OUT=" ,4) == 0) { do_arg_out = cout; continue; }
if (memcmp(bufcmd,"WRK=" ,4) == 0)
{
strncpy(do_arg_fnwrk,p,sizeof(do_arg_fnwrk));
continue;
}
FERR"exp: Incorrect command in '%s': %s\n",fncfg,bufcmd);
}
fclose(fcfg);
}
/****** JOIN COMMANDS UNTIL CLOSING BACK QUOTE **********************/
if (xdebug > 0) FERR"do_arg: pipe=%c, sep=%c, in=%c, out=%c, wrk=%s\n",
do_arg_pipe,
do_arg_sep,
do_arg_in,
do_arg_out,
do_arg_fnwrk);
xend = OFF;
pout = bufcmd;
i0 = i;
do {
if (i == i0) p = p0; /* start after leadin */
else p = av[i]; /* regular argument */
if (*p == CHR_SYS) p++; /* skip leading backquote ` */
if (do_getenv(p,buf1) == 0) p = buf1;
i1 = strlen(p) - 1;
ptail = p;
while (*ptail != '\0')
{
if (*ptail != CHR_SYS) { ptail++; continue; }
*ptail++ = '\0'; /* cut ` out */
xend = ON;
break;
}
while ((c = *p++) != '\0')
{
if (c == do_arg_pipe) c = '|';
if (c == do_arg_in ) c = '<';
if (c == do_arg_out ) c = '>';
*pout++ = c;
}
if (xend == ON) break;
*pout++ = ' ';
i++;
} while (i < ac);
*pout = '\0';
do_arg_sys(bufcmd,ptail);
}
/****** CLEANUP *********************************************************/
unlink(EXP_FN_LST);
for (i=0; i < MAXDIRLEV; i++) dir_close();
return(argc);
}
/****** BUILD NEW ARGUMENT INTO TABLE ***************************************/
/* Input: */
/* argtxt = Text of new argument */
/* */
/* Output: */
/* 0 = Inserted */
/* -1 = Directory contains meta char */
/* -2 = Cannot change to new directory */
/****************************************************************************/
do_arg_bld(argtxt)
char *argtxt;
{
register char c, *p, *p0, *pin, *pout;
char *pexp;
char *pexpinv;
char bufdir[MAXFILNAM+1];
char bufarg[MAXFILNAM+1];
char bufin[MAXFILNAM+1];
char fn[MAXFILNAM+1];
char rdbu[MAXFILNAM+1];
char bufexp[100];
char bufexp_[100];
char bufexpinv[100];
char bufexpinv_[100];
int nlen;
int ncolon;
int col;
int xexp;
int xfile;
int xdir;
int xdrv;
int xcopy;
int xsamedir; /* same directory as last argument one */
int xroot; /* ON: root directory exception */
int nhit;
int ret_, ret;
int i, i1, i2;
/****** CHECK IF ARGUMENT CONTAINS EXPRESSION(S) ************************/
pin = p0 = argtxt;
xexp = OFF;
xfile = ON;
xcopy = OFF;
pexpinv = NULL;
c = *pin;
if (c == '\'') { xcopy = ON; p0++; }
pin = p0 + strlen(p0) - 1;
if ((*pin == '\'') || (*pin == '`')) *pin = '\0'; /* strip trailing '` */
if (access(argtxt,ACC_RD) == 0) xcopy = ON;
/****** CHECK IF TEXT CONTAINS NO META CHARACTER ************************/
if (xcopy == ON)
{
NOEXP:
/****** INSERT ROOT DIR & CONVERT DOUBLE \\ TO \ ********************/
p = p0;
pout = bufarg;
i = 0;
ncolon = 0;
while ((c = *p++) != '\0')
{
*pout++ = c;
if (c == ':') ncolon++;
if ((i++ == 1) && (c == ':') && ((*p != '/') && (*p != '\\')))
*pout++ = '/';
}
*pout = '\0';
if (ncolon > 1) strncpy(bufarg,p0,sizeof(bufarg));
return(do_arg_ins(bufarg));
}
/****** INIT ************************************************************/
MEMZAP0(bufdir,sizeof(bufdir));
MEMZAP0(bufexp,sizeof(bufexp));
/****** SKIP LEADING BLANKS *********************************************/
if (*p0 == CHR_INV)
{
do_arg_xinv = ON;
p0++;
strfld(p0,CHR_INV,1,1,bufin,sizeof(bufin)); /* get invert expr */
if (strfld(p0,CHR_INV,2,2,bufexpinv,sizeof(bufexpinv)) > 0)
{
/****** TRANSLATE THE SHELL EXPRESSION TO REGULAR EXPRESSION ****/
pin = bufexpinv;
pout = bufexpinv_;
*pout++ = '^';
while ((c = *pin++) != '\0')
{
/****** ESCAPE **********************************************/
if (c == '\\') { *pout++ = *pin++; continue; }
/****** STAR TO: ANY CHAR REPEATED ANY AMOUNT ***************/
if (c == '*') { *pout++ = '.'; *pout++ = '*'; continue; }
/****** QUESTION MARK TO: SINGLE CHARACTER ******************/
if (c == '?') { *pout++ = '.'; continue; }
/****** DOT TO: ACTUAL CHARACTER DOT ************************/
if (c == '.') { *pout++ = '\\'; *pout++ = c; continue; }
*pout++ = c;
}
*pout++ = '$';
*pout = '\0';
/****** COMPILER REGULAR EXPRESSION *****************************/
if (getenv("REDEBUG") != NULL) FERR"INV: in: %s out: %s\n",bufexpinv,bufexpinv_);
pexpinv = regcmp(bufexpinv_,NULL);
}
}
else{
do_arg_xinv = OFF;
strncpy(bufin,p0,sizeof(bufin));
}
pin = bufin;
pout = bufdir;
while (*pin == ' ') pin++; /* skip leading blanks */
/****** TRANSLATE \ TO / AND INSERT ROOT / AFTER D: *********************/
p = pin;
pout = bufarg;
i = 0;
ncolon = 0;
while ((c = *p++) != '\0')
{
/****** CHECK FOR RE ESCAPE *****************************************/
if ((c == '/') && (*p == '\\'))
{
*pout++ = '\\';
*pout++ = *++p;
p++;
continue;
}
/****** CHECK FOR DIRECTORY SEPARATOR *******************************/
if (*p == '\\') *p = '/';
/****** COPY ********************************************************/
*pout++ = c;
/****** CHECK FOR DRIVE : *******************************************/
if (c == ':') ncolon++;
/****** INSERT ROOT DIRECTORY IF DRIVE ******************************/
if ((i++ == 1) && (c == ':') && ((*p != '/') && (*p != '\\')))
*pout++ = '/';
}
*pout = '\0';
if (ncolon > 1) strncpy(bufarg,pin,sizeof(bufarg));
/****** SEPARATE DIRECTORY FROM FILE/EXPRESSION *************************/
p0 = bufarg;
nlen = strlen(p0);
pin = p0 + nlen - 1;
xdir = xdrv = OFF;
col = nlen;
while (pin >= p0)
{
c = *pin--;
col--;
if (c == '/') { xdir = ON; break; }
}
/****** CHECK IF DIRECTORY FOUND ****************************************/
if (xdir == ON)
{
MEMCPY(bufdir,p0,col);
MEMCPY(bufexp,p0+col+1,nlen-col);
}
else{
sprintf(bufdir,".");
MEMCPY(bufexp,p0,nlen);
}
/****** CHECK IF META CHARACTER ON DIRECTORY ****************************/
pin = bufdir;
xexp = OFF;
while ((c = *pin++) != '\0')
{
switch (c)
{
case '*':
case '?':
case '[':
case ']':
case '^':
case '$':
xexp = ON;
break;
}
if (xexp == ON) { p0 = argtxt; goto NOEXP; }
}
/****** GET ALL FILES ***************************************************/
xsamedir = xroot = OFF;
if (bufdir[0] == '\0') /* straight root exception */
{
xroot = ON;
bufdir[0] = '/'; bufdir[1] = '\0';
}
if ((bufdir[1] == ':') && (bufdir[2] == '\0')) /* drive root exception */
{
xroot = ON;
bufdir[2] = '/'; bufdir[3] = '\0';
}
if ((i1 = strlen(bufdir)) == (i2 = strlen(do_arg_dir)))
{
if (memcmp(bufdir,do_arg_dir,i1) == 0) xsamedir = ON;
}
if (xsamedir == OFF)
{
MEMCPY(do_arg_dir,bufdir,sizeof(do_arg_dir));
dir_close();
if (dir_open(bufdir) < 1) { p0 = argtxt; goto NOEXP; }
}
else{
dir_rewind();
}
/****** TRANSLATE THE SHELL EXPRESSION TO REGULAR EXPRESSION ************/
pin = bufexp;
pout = bufexp_;
*pout++ = '^';
while ((c = *pin++) != '\0')
{
/****** ESCAPE ******************************************************/
if (c == '\\') { *pout++ = *pin++; continue; }
/****** STAR TO: ANY CHAR REPEATED ANY AMOUNT ***********************/
if (c == '*') { *pout++ = '.'; *pout++ = '*'; continue; }
/****** QUESTION MARK TO: SINGLE CHARACTER **************************/
if (c == '?') { *pout++ = '.'; continue; }
/****** DOT TO: ACTUAL CHARACTER DOT ********************************/
if (c == '.') { *pout++ = '\\'; *pout++ = c; continue; }
*pout++ = c;
}
*pout++ = '$';
*pout = '\0';
/****** COMPILER REGULAR EXPRESSION *************************************/
if (getenv("REDEBUG") != NULL) FERR"in: %s out: %s\n",bufexp,bufexp_);
if ((pexp = regcmp(bufexp_,NULL)) == NULL) { p0 = argtxt; goto NOEXP; }
/****** SCAN FILENAMES **************************************************/
nhit = 0;
while (dir_read(fn) == 0)
{
if ((fn[0] == '.') && (fn[1] == '\0')) continue;
if ((fn[0] == '.') && (fn[1] == '.')) continue;
if (pexpinv == NULL)
{
ret_ = regchk(fn,pexp);
if (do_arg_xinv == OFF)
{
if (ret_ != 0) continue;
}
else{
if (ret_ == 0) continue;
}
}
else{
/****** FIRST CHECK IF HIT ***************************************/
ret_ = regchk(fn,pexpinv);
if (ret_ != 0) continue;
/****** THEN CHECK IF NOT INVERSE EXPR ***************************/
ret_ = regchk(fn,pexp);
if (ret_ == 0) continue;
}
nhit++;
if ((bufdir[0] == '\0') || (memcmp(bufdir,".",2) == 0))
{
do_arg_ins(fn);
continue;
}
if (xroot == OFF) sprintf(rdbu,"%s/%s",bufdir,fn);
else sprintf(rdbu,"%s%s",bufdir,fn);
do_arg_ins(rdbu);
}
free_(pexp);
if (nhit == 0) { p0 = argtxt; goto NOEXP; }
ret = 0;
return(ret);
}
/****** INSERT NEW ARGUMENT INTO TABLE **************************************/
/* Input: */
/* argtxt = Text of new argument */
/* */
/* Output: */
/* 0 = Inserted */
/* -1 = Out of memory */
/****************************************************************************/
do_arg_ins(argtxt)
char *argtxt;
{
register char c, *pin;
int xfile;
int nlen;
/****** CHECK IF FIRST TIME ******************************************/
if (argc == 0)
{
MEMZAP0(argv,sizeof(argv));
if ((argv_p = malloc_(MAXARGVLEN,"argv")) == NULL) return(-1);
argv_nwr = 0;
}
/****** CHECK IF FILE ************************************************/
if (access(argtxt,ACC_RD) == 0) xfile = ON;
else xfile = OFF;
/****** CHECK MEMORY *************************************************/
nlen = strlen(argtxt) + 1;
if ((argv_nwr+nlen) > MAXARGVLEN)
{
if ((argv_p = malloc_(MAXARGVLEN,"argv")) == NULL) return(-1);
argv_nwr = 0;
}
/****** INSERT NEW ARGUMENT ******************************************/
pin = argtxt;
if (argc >= MAXARGV)
{
if (argc == MAXARGV) { FERR"More than %d arguments\n",MAXARGV); argc++;}
return(-3);
}
argv[argc++] = argv_p;
while ((c = *pin++) != '\0')
{
/****** TRANSLATE CHARACTER TO UNIX STYLE IF FILE/DIRECTORY ******/
if (xfile == ON)
{
if (c == '\\') c = '/';
else c = tolower(c);
}
*argv_p++ = c;
}
*argv_p++ = '\0';
argv_nwr += nlen;
return(0);
}
/****** PROCESS SYSTEM CALL *************************************************/
/* Input: */
/* argtxt = Text of new argument */
/* tail = tail text (if any) */
/* */
/* Output: */
/* 0 = Inserted */
/* -1 = Out of memory */
/****************************************************************************/
do_arg_sys(argtxt,tail)
char *argtxt, *tail;
{
FILE *fin;
register char c;
char bufcmd[128+1];
char rdbu[MAXBUF+1];
char *p;
int xredirect;
int nmax, i;
/****** INIT ************************************************************/
unlink(do_arg_fnwrk);
/****** RUN COMMANDS ****************************************************/
i = 1;
while (strfld(argtxt,do_arg_sep,i,i,bufcmd,sizeof(bufcmd)) > 0)
{
i++;
xredirect = OFF;
p = bufcmd;
while ((c = *p++) != '\0')
{
if (c != '>') continue;
xredirect = ON;
break;
}
if (xredirect == OFF)
{
strcat(bufcmd,">>");
strcat(bufcmd,do_arg_fnwrk);
}
if (xdebug > 0) FERR"do_arg_sys: %s\n",bufcmd);
system(bufcmd);
}
/****** GET RESULT ******************************************************/
if ((fin = fopen(do_arg_fnwrk,"rb")) == NULL) return(-1);
nmax = 0;
while (fgetl(rdbu,MAXBUF,fin) != EOF) nmax++;
rewind(fin);
i = 0;
while (fgetl(rdbu,MAXBUF,fin) != EOF)
{
if (i++ == 0) sprintf(p = bufcmd,"%s%s",do_arg_lead,rdbu);
else p = rdbu;
if (i == nmax) strcat(p,tail);
do_arg_bld(p);
}
fclose(fin);
unlink(do_arg_fnwrk);
return(0);
}
/****** RETRIEVE ENVIRONMENT ************************************************/
/* Input: */
/* arg = argument */
/* out = text output */
/* */
/* Output: */
/* 0 = out filled with environment */
/* 1 = no environment variable given */
/* -1 = environment not found */
/****************************************************************************/
do_getenv(arg,out)
char *arg, *out;
{
char buf1[100];
char *p;
char *penv;
if ((arg[0] != CHR_ENV1) && (arg[0] != CHR_ENV2)) return(1);
strncpy(buf1,arg,sizeof(buf1));
p = buf1 + strlen(buf1) - 1;
if (*p == CHR_ENV1) *p = '\0'; /* cancel trailing % */
if (*p == CHR_SYS ) *p = '\0'; /* cancel trailing ` */
strupp(buf1);
*out = '\0';
if ((penv = getenv(buf1+1)) == NULL) return(0);
strcpy(out,penv);
return(0);
}
/****** PROCESS FILE LIST ***************************************************/
/* Input: */
/* arg = argument */
/* out = text output */
/* */
/* Output: */
/* 0 = out filled with environment */
/* 1 = no environment variable given */
/* -1 = environment not found */
/****************************************************************************/
do_fillst(char *arg)
{
FILE *fin;
char rdbu[MAXBUF+1];
fin = NULL;
if (arg[0] != CHR_LST) return(1);
if ((fin = fopen(arg+1,"rb")) == NULL)
{
FERR"ARG: Cannot open file '%s' (%s)\n",arg+1,SYSERR);
return(0); /* so that it is not passed on */
}
while (fgetl(rdbu,MAXBUF,fin) != EOF)
{
do_arg_bld(rdbu);
}
if (fin != NULL)
fclose(fin);
return(0);
}