home *** CD-ROM | disk | FTP | other *** search
- /*****************************************************************************/
- /* (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);
- }
-