home *** CD-ROM | disk | FTP | other *** search
/ The Best of Select: Windows 95 Special 1 / WINDOWS95_1.ISO / utils / w32-rex / regina / srccode / src / doscmd.c < prev    next >
Text File  |  1995-06-30  |  12KB  |  330 lines

  1. #ifndef lint
  2. static char *RCSid = "$Id:$";
  3. #endif
  4.  
  5. /*
  6.  *  The Regina Rexx Interpreter
  7.  *  Copyright (C) 1992-1994  Anders Christensen <anders@pvv.unit.no>
  8.  *
  9.  *  This library is free software; you can redistribute it and/or
  10.  *  modify it under the terms of the GNU Library General Public
  11.  *  License as published by the Free Software Foundation; either
  12.  *  version 2 of the License, or (at your option) any later version.
  13.  *
  14.  *  This library is distributed in the hope that it will be useful,
  15.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  16.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  17.  *  Library General Public License for more details.
  18.  *
  19.  *  You should have received a copy of the GNU Library General Public
  20.  *  License along with this library; if not, write to the Free
  21.  *  Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  22.  */
  23.  
  24. /*
  25.     This code modified for Win32 port by Ataman Software, Inc. June 29, 1995.
  26. */
  27.  
  28. #if defined(DOS) || defined(WIN32)
  29.  
  30. #include "rexx.h"
  31. #include <stdio.h>
  32. #include <string.h>
  33. #include <errno.h>
  34. #ifdef WIN32
  35. # define MAXPATHLEN (8192)
  36. # include <io.h>
  37. #else
  38. # include <sys/param.h>
  39. #endif
  40.  
  41. #define BUF_SIZE 512
  42.  
  43. #define RC_OUT_OF_MEMORY (-1)
  44. #define RC_EOF           (-2)
  45.  
  46. static char *temp_buf;
  47.  
  48. /***********************************************************************/
  49. static char *get_a_line(FILE *fp,char *string,int *length,int *rcode)
  50. /***********************************************************************/
  51. {
  52.  int ch;
  53.  int bufs = 1;
  54.  register int i=0;
  55.  
  56. /*---------------------------------------------------------------------*/
  57. /* Allocate the first block of memory.                                 */
  58. /*---------------------------------------------------------------------*/
  59.  if ((string = (char *)malloc(BUF_SIZE+1)) == NULL)
  60.    {
  61.     *rcode = RC_OUT_OF_MEMORY;
  62.     return(NULL);
  63.    }
  64.  
  65.  while(1)
  66.    {
  67. /*---------------------------------------------------------------------*/
  68. /* Read a character form the stream...                                 */
  69. /*---------------------------------------------------------------------*/
  70.     if ((ch = fgetc(fp)) == EOF)
  71.       {
  72. /*---------------------------------------------------------------------*/
  73. /* If EOF is reached, check that it really is end of file.             */
  74. /*---------------------------------------------------------------------*/
  75.        if (feof(fp))
  76.          {
  77.           *length = i;
  78.           *rcode = RC_EOF;
  79.           return(string);
  80.          }
  81.       }
  82. /*---------------------------------------------------------------------*/
  83. /* If end of line is reached, nul terminate string and return.         */
  84. /*---------------------------------------------------------------------*/
  85.     if ((char)ch == '\n')
  86.       {
  87.        *(string+i) = '\0';
  88.        break;
  89.       }
  90. /*---------------------------------------------------------------------*/
  91. /* All other characters, copy to string.                               */
  92. /*---------------------------------------------------------------------*/
  93.     *(string+i++) = (char)ch;
  94. /*---------------------------------------------------------------------*/
  95. /* If we have got to the end of the allocated memory, realloc some more*/
  96. /*---------------------------------------------------------------------*/
  97.     if (i == BUF_SIZE*bufs)
  98.       {
  99.        if ((string = (char *)realloc(string,(BUF_SIZE*(++bufs))+1)) == NULL)
  100.          {
  101.           *rcode = RC_OUT_OF_MEMORY;
  102.           return(NULL);
  103.          }
  104.       }
  105.    }
  106. /*---------------------------------------------------------------------*/
  107. /* Return a line read form the temporary file.                         */
  108. /*---------------------------------------------------------------------*/
  109.  *length = i;
  110.  *rcode = 0;
  111.  return(string);
  112. }
  113. /***********************************************************************/
  114. static char *strtrans(char *str,char oldch,char newch)
  115. /***********************************************************************/
  116. /* Function  : Translate all occurrences of oldch to newch in str      */
  117. /* Parameters: *str     - string to be amendedd                        */
  118. /*             oldch    - character to be replaced                     */
  119. /*             newch    - character to replace oldch                   */
  120. /* Return    : same string but with characters translated              */
  121. /***********************************************************************/
  122. {
  123.  register size_t len;
  124.  register size_t i;
  125.  
  126.  len = strlen(str);
  127.  for (i=0;i<strlen(str); i++)
  128.    {
  129.     if (*(str+i) == oldch)
  130.        *(str+i) = newch;
  131.    }
  132.  return(str);
  133. }
  134. /***********************************************************************/
  135. static char *make_temp_file(char *str)
  136. /***********************************************************************/
  137. /* Function  : Make a temporary file name in directory pointed to by   */
  138. /*             TMPDIR or TEMP or TMP or if none defined /tmp.          */
  139. /* Parameters: *str     - buffer in which to store filename            */
  140. /* Return    : pointer to filename including directory.                */
  141. /***********************************************************************/
  142. {
  143.  char *dir;
  144.  char endchar;
  145.  
  146.  if (!str)
  147.    {
  148.     if ((temp_buf = (char *)malloc(MAXPATHLEN)) == NULL)
  149.        return(NULL);
  150.     str = temp_buf;
  151.    }
  152.  if ((dir = (char *)getenv("TMPDIR")) == NULL)
  153.    {
  154.     if ((dir = (char *)getenv("TEMP")) == NULL)
  155.       {
  156.        if ((dir = (char *)getenv("TMP")) == NULL)
  157.           dir = P_tmpdir;
  158.       }
  159.    }
  160.  strcpy(str,dir);
  161.  endchar = *(str+strlen(str)-1);
  162.  if (endchar == '/' || endchar == '\\')
  163.     *(str+strlen(str)-1) = '\0';
  164.  strcat(str,"/XXXXXX");
  165.  return(mktemp(strtrans(str,'\\','/')));
  166. }
  167.  
  168. /***********************************************************************/
  169. int dos_do_command( streng *command, int io_flags, int envir )
  170. /***********************************************************************/
  171. {
  172.    int rc;
  173.    streng *cmd ;
  174.    int in, out, fout ;
  175.    streng *inredir=NULL,*outredir=NULL ;
  176.    int length, rcode, flush ;
  177.    streng *result ;
  178.    char *string=NULL;
  179.  
  180.    FILE *infp,*outfp;
  181.    char *infile="",*outfile="";
  182.  
  183.    in = io_flags & REDIR_INPUT ;
  184.    out = io_flags & REDIR_OUTLIFO ;
  185.    fout = io_flags & REDIR_OUTFIFO ;
  186.  
  187.    command = Str_ify( command ) ;
  188.    flush = (out!=0) + ((fout!=0)*2) ;
  189.  
  190.    if ((!in)&&(!out)&&(!fout))
  191.    {
  192.       ;       /* maybe this should not be allowed. ... */
  193.    }
  194.    cmd = NULL ;
  195. /*---------------------------------------------------------------------*/
  196. /* If redirecting stdin, create a temporary file and write the contents*/
  197. /* of the stack to the file.                                           */
  198. /*---------------------------------------------------------------------*/
  199.    if (in)
  200.      {
  201.       if ((infile = make_temp_file(NULL)) == NULL)
  202.         {
  203.          perror("While getting temporary in-file name") ;
  204.          return (-1);
  205.         }
  206.       if ((infp = fopen(infile,"w")) == NULL)
  207.         {
  208.          perror("While opening input file") ;
  209.          return (-1);
  210.         }
  211.       while(!stack_empty())
  212.         {
  213.          result = Str_ify(popline()) ;
  214.          fputs(result->value,infp);
  215.          fputs("\n",infp);
  216.         }
  217.       if (fclose(infp))
  218.         {
  219.          perror("While closing input file") ;
  220.          return (-1);
  221.         }
  222.       inredir = Str_make(strlen(infile)+4);
  223.       sprintf(inredir->value,"< %s ",strtrans(infile,'/','\\'));
  224.       inredir->len = strlen(inredir->value);
  225.      }
  226. /*---------------------------------------------------------------------*/
  227. /* If redirecting stdout, create the name of a temporary file for the  */
  228. /* output.                                                             */
  229. /*---------------------------------------------------------------------*/
  230.    if ((out)||(fout))
  231.      {
  232.       if ((outfile = make_temp_file(NULL)) == NULL)
  233.         {
  234.          perror("While getting temporary out-file name") ;
  235.          return (-1);
  236.         }
  237.       outredir = Str_make(strlen(outfile)+3);
  238.       sprintf(outredir->value,"> %s",strtrans(outfile,'/','\\'));
  239.       outredir->len = strlen(outredir->value);
  240.      }
  241. /*---------------------------------------------------------------------*/
  242. /* Build up the command to be passed to the system() command. The      */
  243. /* command will contain the command to be executed, any arguments and  */
  244. /* the redirection commands and file names.                            */
  245. /*---------------------------------------------------------------------*/
  246.    length = command->len + ((in) ? inredir->len : 0) + (((out)||(fout)) ? outredir->len : 0) + 2;
  247.    cmd = Str_make(length);
  248.    cmd = Str_cat(cmd,command);
  249.    if (in)
  250.      {
  251.       cmd = Str_cat(cmd,inredir);
  252.       Free(inredir);
  253.      }
  254.    if (out||fout)
  255.      {
  256.       cmd = Str_cat(cmd,outredir);
  257.       Free(outredir);
  258.      }
  259. /*---------------------------------------------------------------------*/
  260. /* Execute the command.                                                */
  261. /*---------------------------------------------------------------------*/
  262.    cmd = Str_ify(cmd);
  263.    rc = system(cmd->value);
  264.    Free(cmd);
  265. /*---------------------------------------------------------------------*/
  266. /* If redirecting stdout, we now have to read the file and push each   */
  267. /* line onto the stack.                                                */
  268. /*---------------------------------------------------------------------*/
  269.    if ((out)||(fout))
  270.      {
  271.       strtrans(outfile,'\\','/');
  272.       if ((outfp = fopen(outfile,"r")) == NULL)
  273.         {
  274.          perror("While opening output file") ;
  275.          return(-1);
  276.         }
  277.  
  278. /*---------------------------------------------------------------------*/
  279. /* If redirecting stdin, create a temporary file and write the contents*/
  280. /* of the stack to the file.                                           */
  281. /*---------------------------------------------------------------------*/
  282.       result->len = 0;
  283.       while(1)
  284.         {
  285.          string = get_a_line(outfp,string,&length,&rcode);
  286.          if (rcode == RC_OUT_OF_MEMORY)
  287.            {
  288.             perror("While reading output file");
  289.             return (-1);
  290.            }
  291.          if (rcode == RC_EOF && length == 0)
  292.            {
  293.             free(string);
  294.             break;
  295.            }
  296.          result = Str_ncre(string,length);
  297.          tmp_stack(result,flush==2);
  298.          free(string);
  299.          if (rcode == RC_EOF)
  300.             break;
  301.         }
  302.       if (flush)
  303.          flush_stack(flush==2);
  304.  
  305.       if (fclose(outfp))
  306.         {
  307.          perror("While closing output file") ;
  308.          return(-1);
  309.         }
  310.      }
  311. /*---------------------------------------------------------------------*/
  312. /* Delete the temporary file(s) and free up any memory.                */
  313. /*---------------------------------------------------------------------*/
  314.   if (in)
  315.     {
  316.      unlink(strtrans(infile,'\\','/'));
  317.      free(infile);
  318.     }
  319.   if ((out)||(fout))
  320.     {
  321.      unlink(strtrans(outfile,'\\','/'));
  322.      free(outfile);
  323.     }
  324. /*---------------------------------------------------------------------*/
  325. /* Return with, hopefully, return code from system() command.          */
  326. /*---------------------------------------------------------------------*/
  327.   return rc ;
  328. }
  329. #endif
  330.