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