home *** CD-ROM | disk | FTP | other *** search
/ Chip 1998 March / CHIPCD_3_98.iso / software / share / sharmies / unixdos / data.z / diff4a.txt < prev    next >
Text File  |  1997-11-18  |  24KB  |  683 lines

  1. /*****************************************************************************/
  2. /* (C) Copyright, B. EICHBGERGER, All rights reserved.                       */
  3. /*                                                                           */
  4. /* This program remains the exclusive property of B. EICHBERGER              */
  5. /* may not be sold, used, copied, displayed or modified without the written  */
  6. /* consent of Burkhard Eichberger, P.O.Box 4767, Boulder, Colorado 80306     */
  7. /*****************************************************************************/
  8. #include <stdio.h>
  9. #include <sys\types.h>
  10. #include <sys\stat.h>
  11. #include "def.h"
  12. #define EXPARG_M
  13. #include "exparg.h"
  14. #include "def_s.h"
  15. #include "dir.h"
  16.  
  17. VAR_EXT;
  18.  
  19. int system(const char *);
  20.  
  21. #define MAXBUF 100
  22. #define MAXLEAD 20
  23.  
  24. #define FN_WRK    "~"
  25. #define FN_CFG    "dx.cfg"
  26. #define CHR_SYS   '`'
  27. #define CHR_QUOTE '"'
  28. #define CHR_INV   '!'
  29. #define CHR_SEP   ';'
  30. #define CHR_PIPE  '#'
  31. #define CHR_IN    '{'
  32. #define CHR_OUT   '}'
  33. #define CHR_ENV1  '%'
  34. #define CHR_ENV2  '$'
  35. #define CHR_LST   '@'
  36.  
  37. int  do_arg_xinv = OFF;
  38. char do_arg_sep  = CHR_SEP;
  39. char do_arg_pipe = CHR_PIPE;
  40. char do_arg_in   = CHR_IN;
  41. char do_arg_out  = CHR_OUT;
  42. char do_arg_dir[MAXFILNAM+1];   /* last directory */
  43. char do_arg_fnwrk[MAXFILNAM+1]; /* work filename */
  44. char do_arg_lead[MAXLEAD+1];    /* leadin command */
  45.  
  46. int do_arg_ins(char *szNew);
  47. int do_fillst(char *szArg);
  48. int do_getenv(char *szArg,char *szOut);
  49. int do_arg_bld(char *szArg);
  50. int do_arg_sys(char *szCmd,char *szTail);
  51.  
  52. /****** PROCESS ARGUMENT EXPANSION ******************************************/
  53. /* Input:                                                                   */
  54. /* ac        = Number of arguments on command line                          */
  55. /* av        = Argument Vector                                              */
  56. /*                                                                          */
  57. /* Output:                                                                  */
  58. /* 0          = OK                                                          */
  59. /* -1         = Cannot open database                                        */
  60. /* -2         = Cannot open window environment                              */
  61. /* -3         = Cannot open getinp environment                              */
  62. /* -4         = Cannot get sellst RAM                                       */
  63. /* -5         = Not enough RAM                                              */
  64. /* -6         = Missing string flex file                                    */
  65. /* -7         = Escape at initial screen                                    */
  66. /****************************************************************************/
  67. int do_arg  (int ac,char *av[])
  68. {
  69. FILE *fcfg;
  70. register int i, i0, i1;
  71. char buf1[100+1];
  72. char bufcmd[128+1];
  73. char fncfg[MAXFILNAM+1];
  74. char c, c1, c2, cout;
  75. char *arg, *p, *p0, *pout;
  76. char *ptail;
  77. int xend;
  78. int xsys;
  79.  
  80.     /****** INIT ************************************************************/
  81.     argc = 0;
  82.     MEMZAP0(do_arg_dir,sizeof(do_arg_dir));
  83.     
  84.     /****** PROCESS PROGRAM NAME ********************************************/
  85.     do_arg_ins(av[0]);
  86.  
  87.     /****** PROCESS ARGUMENTS ***********************************************/
  88.     for (i=1; i < ac; i++)
  89.         {
  90.         /****** GET ARGUMENT ************************************************/
  91.         arg = av[i];
  92.  
  93.         /****** PROCESS FILE LIST *******************************************/
  94.         if (do_fillst(arg) == 0)
  95.              {
  96.              continue;
  97.              }
  98.  
  99.         /****** PROCESS ENVIRONMENT *****************************************/
  100.         if (do_getenv(arg,buf1) == 0)
  101.              {
  102.              do_arg_bld(buf1);
  103.              continue;
  104.              }
  105.  
  106.         /****** CHECK FOR BACK QUOTE SYSTEM CALLS `cmd` *********************/
  107.         xsys = OFF;
  108.         p = arg;
  109.         pout = do_arg_lead;
  110.         while ((c = *p++) != '\0')
  111.             {
  112.             if (c == CHR_SYS) { xsys = ON; break; }
  113.             *pout++ = c;
  114.             }
  115.         *pout = '\0';
  116.  
  117.         /****** REGULAR PLAIN ARGUMENT **************************************/
  118.         if (xsys == OFF)
  119.             {
  120.             do_arg_bld(arg);
  121.             continue;
  122.             }
  123.         p0 = p;
  124.  
  125.         /****** PROCESS THE CONFIG FILE *************************************/
  126.         strncpy(do_arg_fnwrk,FN_WRK,sizeof(do_arg_fnwrk));
  127.         strncpy(fncfg,av[0],sizeof(fncfg));
  128.         p = fncfg + strlen(fncfg) - 1;
  129.         while (*p != '\\') *p-- = '\0';
  130.         p++;
  131.         strcat(p,FN_CFG);
  132.         if ((fcfg = fopen(fncfg,"rb")) != NULL)
  133.             {
  134.             while (fgetl(bufcmd,sizeof(bufcmd)-1,fcfg) != EOF)
  135.                 {
  136.                 p = bufcmd;
  137.                 cout = '\0';
  138.                 while ((c = *p++) != '\0')
  139.                     {
  140.                     if (c != '=')  continue;
  141.                     if (*p != '\\') { cout = *p; break; }
  142.                     c1 = shtoi(p[1]);
  143.                     c2 = shtoi(p[2]);
  144.                     if ((c1 < 0) || (c2 < 0)) 
  145.                         {
  146.                         FERR"exp: Invalid hex number in '%s': %s\n",
  147.                             fncfg,bufcmd);
  148.                         break;
  149.                         }
  150.                     cout = (c1<<4) + c2;
  151.                     break;
  152.                     }
  153.                 if (cout == '\0') continue;
  154. if (memcmp(bufcmd,"PIPE="  ,5) == 0) { do_arg_pipe = cout; continue; }
  155. if (memcmp(bufcmd,"CMDSEP=",7) == 0) { do_arg_sep  = cout; continue; }
  156. if (memcmp(bufcmd,"IN="    ,3) == 0) { do_arg_in   = cout; continue; }
  157. if (memcmp(bufcmd,"OUT="   ,4) == 0) { do_arg_out  = cout; continue; }
  158. if (memcmp(bufcmd,"WRK="   ,4) == 0)
  159.     {
  160.     strncpy(do_arg_fnwrk,p,sizeof(do_arg_fnwrk));
  161.     continue;
  162.     }
  163.                 FERR"exp: Incorrect command in '%s': %s\n",fncfg,bufcmd);
  164.                 }
  165.             fclose(fcfg);
  166.             }
  167.  
  168.         /****** JOIN COMMANDS UNTIL CLOSING BACK QUOTE **********************/
  169. if (xdebug > 0) FERR"do_arg: pipe=%c, sep=%c, in=%c, out=%c, wrk=%s\n",
  170. do_arg_pipe,
  171. do_arg_sep,
  172. do_arg_in,
  173. do_arg_out,
  174. do_arg_fnwrk);
  175.         xend = OFF;
  176.         pout = bufcmd;
  177.         i0 = i;
  178.         do  {
  179.             if (i == i0) p = p0;    /* start after leadin */
  180.             else         p = av[i]; /* regular argument */
  181.             if (*p == CHR_SYS) p++; /* skip leading backquote ` */
  182.             if (do_getenv(p,buf1) == 0) p = buf1;
  183.             i1 = strlen(p) - 1;
  184.             ptail = p;
  185.             while (*ptail != '\0')
  186.                 {
  187.                 if (*ptail != CHR_SYS) { ptail++; continue; }
  188.                 *ptail++ = '\0'; /* cut ` out */
  189.                 xend = ON;
  190.                 break;
  191.                 }
  192.             while ((c = *p++) != '\0')
  193.                 {
  194.                 if (c == do_arg_pipe) c = '|';
  195.                 if (c == do_arg_in  ) c = '<';
  196.                 if (c == do_arg_out ) c = '>';
  197.                 *pout++ = c;
  198.                 }
  199.             if (xend == ON) break;
  200.             *pout++ = ' ';
  201.             i++;
  202.             } while (i < ac);
  203.         *pout = '\0';
  204.         do_arg_sys(bufcmd,ptail);
  205.         }
  206.  
  207.     /****** CLEANUP *********************************************************/
  208.     unlink(EXP_FN_LST);
  209.     for (i=0; i < MAXDIRLEV; i++) dir_close();
  210.     return(argc);
  211. }
  212.  
  213. /****** BUILD NEW ARGUMENT INTO TABLE ***************************************/
  214. /* Input:                                                                   */
  215. /* argtxt    = Text of new argument                                         */
  216. /*                                                                          */
  217. /* Output:                                                                  */
  218. /* 0          = Inserted                                                    */
  219. /* -1         = Directory contains meta char                                */
  220. /* -2         = Cannot change to new directory                              */
  221. /****************************************************************************/
  222. do_arg_bld(argtxt)
  223. char *argtxt;
  224. {
  225. register char c, *p, *p0, *pin, *pout;
  226. char *pexp;
  227. char *pexpinv;
  228. char bufdir[MAXFILNAM+1];
  229. char bufarg[MAXFILNAM+1];
  230. char bufin[MAXFILNAM+1];
  231. char fn[MAXFILNAM+1];
  232. char rdbu[MAXFILNAM+1];
  233. char bufexp[100];
  234. char bufexp_[100];
  235. char bufexpinv[100];
  236. char bufexpinv_[100];
  237. int nlen;
  238. int ncolon;
  239. int col;
  240. int xexp;
  241. int xfile;
  242. int xdir;
  243. int xdrv;
  244. int xcopy;
  245. int xsamedir;                 /* same directory as last argument one */
  246. int xroot;                    /* ON: root directory exception */
  247. int nhit;
  248. int ret_, ret;
  249. int i, i1, i2;
  250.  
  251.     /****** CHECK IF ARGUMENT CONTAINS EXPRESSION(S) ************************/
  252.     pin = p0 = argtxt;
  253.     xexp = OFF;
  254.     xfile = ON;
  255.     xcopy = OFF;
  256.     pexpinv = NULL;
  257.     c = *pin;
  258.     if (c == '\'') { xcopy = ON; p0++; }
  259.     pin = p0 + strlen(p0) - 1;
  260.     if ((*pin == '\'') || (*pin == '`')) *pin = '\0'; /* strip trailing '` */
  261.     if (access(argtxt,ACC_RD) == 0) xcopy = ON;
  262.  
  263.     /****** CHECK IF TEXT CONTAINS NO META CHARACTER ************************/
  264.     if (xcopy == ON)
  265.         {
  266. NOEXP:
  267.         /****** INSERT ROOT DIR & CONVERT DOUBLE \\ TO \ ********************/
  268.         p = p0;
  269.         pout = bufarg;
  270.         i = 0;
  271.         ncolon = 0;
  272.         while ((c = *p++) != '\0')
  273.             {
  274.             *pout++ = c;
  275.             if (c == ':') ncolon++;
  276.             if ((i++ == 1) && (c == ':') && ((*p != '/') && (*p != '\\')))
  277.                 *pout++ = '/';
  278.             }
  279.         *pout = '\0';
  280.         if (ncolon > 1) strncpy(bufarg,p0,sizeof(bufarg));
  281.         return(do_arg_ins(bufarg));
  282.         }
  283.  
  284.     /****** INIT ************************************************************/
  285.     MEMZAP0(bufdir,sizeof(bufdir));
  286.     MEMZAP0(bufexp,sizeof(bufexp));
  287.  
  288.     /****** SKIP LEADING BLANKS *********************************************/
  289.     if (*p0 == CHR_INV)
  290.         {
  291.         do_arg_xinv = ON;
  292.         p0++;
  293.         strfld(p0,CHR_INV,1,1,bufin,sizeof(bufin)); /* get invert expr */
  294.         if (strfld(p0,CHR_INV,2,2,bufexpinv,sizeof(bufexpinv)) > 0)
  295.             {
  296.             /****** TRANSLATE THE SHELL EXPRESSION TO REGULAR EXPRESSION ****/
  297.             pin = bufexpinv;
  298.             pout = bufexpinv_;
  299.             *pout++ = '^';
  300.             while ((c = *pin++) != '\0')
  301.                 {
  302.                 /****** ESCAPE **********************************************/
  303.                 if (c == '\\') { *pout++ = *pin++; continue; }
  304.         
  305.                 /****** STAR TO: ANY CHAR REPEATED ANY AMOUNT ***************/
  306.                 if (c == '*') { *pout++ = '.';  *pout++ = '*'; continue; }
  307.         
  308.                 /****** QUESTION MARK TO: SINGLE CHARACTER ******************/
  309.                 if (c == '?') { *pout++ = '.';                 continue; }
  310.         
  311.                 /****** DOT TO: ACTUAL CHARACTER DOT ************************/
  312.                 if (c == '.') { *pout++ = '\\'; *pout++ = c;   continue; }
  313.                 *pout++ = c;
  314.                 }
  315.             *pout++ = '$';
  316.             *pout = '\0';
  317.         
  318.             /****** COMPILER REGULAR EXPRESSION *****************************/
  319. if (getenv("REDEBUG") != NULL) FERR"INV: in: %s out: %s\n",bufexpinv,bufexpinv_);
  320.             pexpinv = regcmp(bufexpinv_,NULL);
  321.             }
  322.         }
  323.     else{
  324.         do_arg_xinv = OFF;
  325.         strncpy(bufin,p0,sizeof(bufin));
  326.         }
  327.     pin = bufin;
  328.     pout = bufdir;
  329.     while (*pin == ' ') pin++;  /* skip leading blanks */
  330.  
  331.     /****** TRANSLATE \ TO / AND INSERT ROOT / AFTER D: *********************/
  332.     p = pin;
  333.     pout = bufarg;
  334.     i = 0;
  335.     ncolon = 0;
  336.     while ((c = *p++) != '\0')
  337.         {
  338.         /****** CHECK FOR RE ESCAPE *****************************************/
  339.         if ((c == '/') && (*p == '\\'))
  340.             {
  341.             *pout++ = '\\';
  342.             *pout++ = *++p;
  343.             p++;
  344.             continue;
  345.             }
  346.  
  347.         /****** CHECK FOR DIRECTORY SEPARATOR *******************************/
  348.         if (*p == '\\') *p = '/';
  349.  
  350.         /****** COPY ********************************************************/
  351.         *pout++ = c;
  352.  
  353.         /****** CHECK FOR DRIVE : *******************************************/
  354.         if (c == ':') ncolon++;
  355.  
  356.         /****** INSERT ROOT DIRECTORY IF DRIVE ******************************/
  357.         if ((i++ == 1) && (c == ':') && ((*p != '/') && (*p != '\\')))
  358.             *pout++ = '/';
  359.         }
  360.     *pout = '\0';
  361.     if (ncolon > 1) strncpy(bufarg,pin,sizeof(bufarg));
  362.  
  363.     /****** SEPARATE DIRECTORY FROM FILE/EXPRESSION *************************/
  364.     p0 = bufarg;
  365.     nlen = strlen(p0);
  366.     pin = p0 + nlen - 1;
  367.     xdir = xdrv = OFF;
  368.     col = nlen;
  369.     while (pin >= p0)
  370.         {
  371.         c = *pin--;
  372.         col--;
  373.         if (c == '/') { xdir = ON; break; }
  374.         }
  375.  
  376.     /****** CHECK IF DIRECTORY FOUND ****************************************/
  377.     if (xdir == ON)
  378.         {
  379.         MEMCPY(bufdir,p0,col);
  380.         MEMCPY(bufexp,p0+col+1,nlen-col);
  381.         }
  382.     else{
  383.         sprintf(bufdir,".");
  384.         MEMCPY(bufexp,p0,nlen);
  385.         }
  386.  
  387.     /****** CHECK IF META CHARACTER ON DIRECTORY ****************************/
  388.     pin = bufdir;
  389.     xexp = OFF;
  390.     while ((c = *pin++) != '\0')
  391.         {
  392.         switch (c)
  393.         {
  394.         case '*':
  395.         case '?':
  396.         case '[':
  397.         case ']':
  398.         case '^':
  399.         case '$':
  400.             xexp = ON;
  401.             break;
  402.         }
  403.         if (xexp == ON) { p0 = argtxt; goto NOEXP; }
  404.         }
  405.  
  406.     /****** GET ALL FILES ***************************************************/
  407.     xsamedir = xroot = OFF;
  408.     if (bufdir[0] == '\0') /* straight root exception */
  409.         {
  410.         xroot = ON;
  411.         bufdir[0] = '/'; bufdir[1] = '\0';
  412.         }
  413.     if ((bufdir[1] == ':') && (bufdir[2] == '\0')) /* drive root exception */
  414.         {
  415.         xroot = ON;
  416.         bufdir[2] = '/'; bufdir[3] = '\0';
  417.         }
  418.     if ((i1 = strlen(bufdir)) == (i2 = strlen(do_arg_dir)))
  419.         {
  420.         if (memcmp(bufdir,do_arg_dir,i1) == 0) xsamedir = ON;
  421.         }
  422.     if (xsamedir == OFF)
  423.         {
  424.         MEMCPY(do_arg_dir,bufdir,sizeof(do_arg_dir));
  425.         dir_close();
  426.         if (dir_open(bufdir) < 1) { p0 = argtxt; goto NOEXP; }
  427.         }
  428.     else{
  429.         dir_rewind();
  430.         }
  431.  
  432.     /****** TRANSLATE THE SHELL EXPRESSION TO REGULAR EXPRESSION ************/
  433.     pin = bufexp;
  434.     pout = bufexp_;
  435.     *pout++ = '^';
  436.     while ((c = *pin++) != '\0')
  437.         {
  438.         /****** ESCAPE ******************************************************/
  439.         if (c == '\\') { *pout++ = *pin++; continue; }
  440.  
  441.         /****** STAR TO: ANY CHAR REPEATED ANY AMOUNT ***********************/
  442.         if (c == '*') { *pout++ = '.';  *pout++ = '*'; continue; }
  443.  
  444.         /****** QUESTION MARK TO: SINGLE CHARACTER **************************/
  445.         if (c == '?') { *pout++ = '.';                 continue; }
  446.  
  447.         /****** DOT TO: ACTUAL CHARACTER DOT ********************************/
  448.         if (c == '.') { *pout++ = '\\'; *pout++ = c;   continue; }
  449.         *pout++ = c;
  450.         }
  451.     *pout++ = '$';
  452.     *pout = '\0';
  453.  
  454.  
  455.     /****** COMPILER REGULAR EXPRESSION *************************************/
  456. if (getenv("REDEBUG") != NULL) FERR"in: %s out: %s\n",bufexp,bufexp_);
  457.     if ((pexp = regcmp(bufexp_,NULL)) == NULL) { p0 = argtxt; goto NOEXP; }
  458.  
  459.     /****** SCAN FILENAMES **************************************************/
  460.     nhit = 0;
  461.     while (dir_read(fn) == 0)
  462.         {
  463.         if ((fn[0] == '.') && (fn[1] == '\0')) continue;
  464.         if ((fn[0] == '.') && (fn[1] == '.')) continue;
  465.         if (pexpinv == NULL)
  466.             {
  467.             ret_ = regchk(fn,pexp);
  468.             if (do_arg_xinv == OFF)
  469.                 {
  470.                 if (ret_ != 0) continue;
  471.                 }
  472.             else{
  473.                 if (ret_ == 0) continue;
  474.                 }
  475.             }
  476.         else{
  477.             /****** FIRST CHECK IF HIT ***************************************/
  478.             ret_ = regchk(fn,pexpinv);
  479.             if (ret_ != 0) continue;
  480.  
  481.             /****** THEN CHECK IF NOT INVERSE EXPR ***************************/
  482.             ret_ = regchk(fn,pexp);
  483.             if (ret_ == 0) continue;
  484.             }
  485.         nhit++;
  486.         if ((bufdir[0] == '\0') || (memcmp(bufdir,".",2) == 0))
  487.             {
  488.             do_arg_ins(fn);
  489.             continue;
  490.             }
  491.         if (xroot == OFF) sprintf(rdbu,"%s/%s",bufdir,fn);
  492.         else              sprintf(rdbu,"%s%s",bufdir,fn);
  493.         do_arg_ins(rdbu);
  494.         }
  495.     free_(pexp);
  496.     if (nhit == 0) { p0 = argtxt; goto NOEXP; }
  497.     ret = 0;
  498.  
  499.     return(ret);
  500. }
  501.  
  502. /****** INSERT NEW ARGUMENT INTO TABLE **************************************/
  503. /* Input:                                                                   */
  504. /* argtxt    = Text of new argument                                         */
  505. /*                                                                          */
  506. /* Output:                                                                  */
  507. /* 0          = Inserted                                                    */
  508. /* -1         = Out of memory                                               */
  509. /****************************************************************************/
  510. do_arg_ins(argtxt)
  511. char *argtxt;
  512. {
  513. register char c, *pin;
  514. int xfile;
  515. int nlen;
  516.         
  517.     /****** CHECK IF FIRST TIME ******************************************/
  518.     if (argc == 0)
  519.         {
  520.         MEMZAP0(argv,sizeof(argv));
  521.         if ((argv_p = malloc_(MAXARGVLEN,"argv")) == NULL) return(-1);
  522.         argv_nwr = 0;
  523.         }
  524.  
  525.     /****** CHECK IF FILE ************************************************/
  526.     if (access(argtxt,ACC_RD) == 0) xfile = ON;
  527.     else                            xfile = OFF;
  528.  
  529.     /****** CHECK MEMORY *************************************************/
  530.     nlen = strlen(argtxt) + 1;
  531.     if ((argv_nwr+nlen) > MAXARGVLEN)
  532.         {
  533.         if ((argv_p = malloc_(MAXARGVLEN,"argv")) == NULL) return(-1);
  534.         argv_nwr = 0;
  535.         }
  536.  
  537.     /****** INSERT NEW ARGUMENT ******************************************/
  538.     pin = argtxt;
  539.     if (argc >= MAXARGV)
  540.         {
  541.         if (argc == MAXARGV) { FERR"More than %d arguments\n",MAXARGV); argc++;}
  542.         return(-3);
  543.         }
  544.     argv[argc++] = argv_p;
  545.     while ((c = *pin++) != '\0')
  546.         {
  547.         /****** TRANSLATE CHARACTER TO UNIX STYLE IF FILE/DIRECTORY ******/
  548.         if (xfile == ON)
  549.            {
  550.            if (c == '\\') c = '/';
  551.            else           c = tolower(c);
  552.            }
  553.         *argv_p++ = c;
  554.         }
  555.     *argv_p++ = '\0';
  556.     argv_nwr += nlen;
  557.     return(0);
  558. }
  559. /****** PROCESS SYSTEM CALL *************************************************/
  560. /* Input:                                                                   */
  561. /* argtxt    = Text of new argument                                         */
  562. /* tail      = tail text (if any)                                           */
  563. /*                                                                          */
  564. /* Output:                                                                  */
  565. /* 0          = Inserted                                                    */
  566. /* -1         = Out of memory                                               */
  567. /****************************************************************************/
  568. do_arg_sys(argtxt,tail)
  569. char *argtxt, *tail;
  570. {
  571. FILE *fin;
  572. register char c;
  573. char bufcmd[128+1];
  574. char rdbu[MAXBUF+1];
  575. char *p;
  576. int xredirect;
  577. int nmax, i;
  578.  
  579.     /****** INIT ************************************************************/
  580.     unlink(do_arg_fnwrk);
  581.  
  582.     /****** RUN COMMANDS ****************************************************/
  583.     i = 1;
  584.     while (strfld(argtxt,do_arg_sep,i,i,bufcmd,sizeof(bufcmd)) > 0)
  585.         {
  586.         i++;
  587.         xredirect = OFF;
  588.         p = bufcmd;
  589.         while ((c = *p++) != '\0')
  590.             {
  591.             if (c != '>') continue;
  592.             xredirect = ON;
  593.             break;
  594.             }
  595.         if (xredirect == OFF)
  596.             {
  597.             strcat(bufcmd,">>");
  598.             strcat(bufcmd,do_arg_fnwrk);
  599.             }
  600. if (xdebug > 0) FERR"do_arg_sys: %s\n",bufcmd);
  601.         system(bufcmd);
  602.         }
  603.  
  604.     /****** GET RESULT ******************************************************/
  605.     if ((fin = fopen(do_arg_fnwrk,"rb")) == NULL) return(-1);
  606.     nmax = 0;
  607.     while (fgetl(rdbu,MAXBUF,fin) != EOF) nmax++;
  608.     rewind(fin);
  609.     i = 0;
  610.     while (fgetl(rdbu,MAXBUF,fin) != EOF)
  611.         {
  612.         if (i++ == 0) sprintf(p = bufcmd,"%s%s",do_arg_lead,rdbu);
  613.         else          p = rdbu;
  614.         if (i == nmax) strcat(p,tail);
  615.         do_arg_bld(p);
  616.         }
  617.     fclose(fin);
  618.     unlink(do_arg_fnwrk);
  619.     return(0);
  620. }
  621.  
  622. /****** RETRIEVE ENVIRONMENT ************************************************/
  623. /* Input:                                                                   */
  624. /* arg       = argument                                                     */
  625. /* out       = text output                                                  */
  626. /*                                                                          */
  627. /* Output:                                                                  */
  628. /* 0          = out filled with environment                                 */
  629. /* 1          = no environment variable given                               */
  630. /* -1         = environment not found                                       */
  631. /****************************************************************************/
  632. do_getenv(arg,out)
  633. char *arg, *out;
  634. {
  635. char buf1[100];
  636. char *p;
  637. char *penv;
  638.  
  639.     if ((arg[0] != CHR_ENV1) && (arg[0] != CHR_ENV2)) return(1);
  640.     strncpy(buf1,arg,sizeof(buf1));
  641.     p = buf1 + strlen(buf1) - 1;
  642.     if (*p == CHR_ENV1) *p = '\0'; /* cancel trailing % */
  643.     if (*p == CHR_SYS ) *p = '\0'; /* cancel trailing ` */
  644.     strupp(buf1);
  645.     *out = '\0';
  646.     if ((penv = getenv(buf1+1)) == NULL) return(0);
  647.     strcpy(out,penv);
  648.     return(0);
  649. }
  650.  
  651. /****** PROCESS FILE LIST ***************************************************/
  652. /* Input:                                                                   */
  653. /* arg       = argument                                                     */
  654. /* out       = text output                                                  */
  655. /*                                                                          */
  656. /* Output:                                                                  */
  657. /* 0          = out filled with environment                                 */
  658. /* 1          = no environment variable given                               */
  659. /* -1         = environment not found                                       */
  660. /****************************************************************************/
  661. do_fillst(char *arg)
  662. {
  663. FILE *fin;
  664. char rdbu[MAXBUF+1];
  665.  
  666.     fin = NULL;
  667.     if (arg[0] != CHR_LST) return(1);
  668.  
  669.     if ((fin = fopen(arg+1,"rb")) == NULL)
  670.         {
  671.         FERR"ARG: Cannot open file '%s' (%s)\n",arg+1,SYSERR);
  672.         return(0); /* so that it is not passed on */
  673.         }
  674.     while (fgetl(rdbu,MAXBUF,fin) != EOF)
  675.         {
  676.         do_arg_bld(rdbu);
  677.         }
  678.     
  679.     if (fin != NULL)
  680.         fclose(fin);
  681.     return(0);
  682. }
  683.