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 >
Wrap
Text File
|
1995-06-30
|
12KB
|
330 lines
#ifndef lint
static char *RCSid = "$Id:$";
#endif
/*
* The Regina Rexx Interpreter
* Copyright (C) 1992-1994 Anders Christensen <anders@pvv.unit.no>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the Free
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/*
This code modified for Win32 port by Ataman Software, Inc. June 29, 1995.
*/
#if defined(DOS) || defined(WIN32)
#include "rexx.h"
#include <stdio.h>
#include <string.h>
#include <errno.h>
#ifdef WIN32
# define MAXPATHLEN (8192)
# include <io.h>
#else
# include <sys/param.h>
#endif
#define BUF_SIZE 512
#define RC_OUT_OF_MEMORY (-1)
#define RC_EOF (-2)
static char *temp_buf;
/***********************************************************************/
static char *get_a_line(FILE *fp,char *string,int *length,int *rcode)
/***********************************************************************/
{
int ch;
int bufs = 1;
register int i=0;
/*---------------------------------------------------------------------*/
/* Allocate the first block of memory. */
/*---------------------------------------------------------------------*/
if ((string = (char *)malloc(BUF_SIZE+1)) == NULL)
{
*rcode = RC_OUT_OF_MEMORY;
return(NULL);
}
while(1)
{
/*---------------------------------------------------------------------*/
/* Read a character form the stream... */
/*---------------------------------------------------------------------*/
if ((ch = fgetc(fp)) == EOF)
{
/*---------------------------------------------------------------------*/
/* If EOF is reached, check that it really is end of file. */
/*---------------------------------------------------------------------*/
if (feof(fp))
{
*length = i;
*rcode = RC_EOF;
return(string);
}
}
/*---------------------------------------------------------------------*/
/* If end of line is reached, nul terminate string and return. */
/*---------------------------------------------------------------------*/
if ((char)ch == '\n')
{
*(string+i) = '\0';
break;
}
/*---------------------------------------------------------------------*/
/* All other characters, copy to string. */
/*---------------------------------------------------------------------*/
*(string+i++) = (char)ch;
/*---------------------------------------------------------------------*/
/* If we have got to the end of the allocated memory, realloc some more*/
/*---------------------------------------------------------------------*/
if (i == BUF_SIZE*bufs)
{
if ((string = (char *)realloc(string,(BUF_SIZE*(++bufs))+1)) == NULL)
{
*rcode = RC_OUT_OF_MEMORY;
return(NULL);
}
}
}
/*---------------------------------------------------------------------*/
/* Return a line read form the temporary file. */
/*---------------------------------------------------------------------*/
*length = i;
*rcode = 0;
return(string);
}
/***********************************************************************/
static char *strtrans(char *str,char oldch,char newch)
/***********************************************************************/
/* Function : Translate all occurrences of oldch to newch in str */
/* Parameters: *str - string to be amendedd */
/* oldch - character to be replaced */
/* newch - character to replace oldch */
/* Return : same string but with characters translated */
/***********************************************************************/
{
register size_t len;
register size_t i;
len = strlen(str);
for (i=0;i<strlen(str); i++)
{
if (*(str+i) == oldch)
*(str+i) = newch;
}
return(str);
}
/***********************************************************************/
static char *make_temp_file(char *str)
/***********************************************************************/
/* Function : Make a temporary file name in directory pointed to by */
/* TMPDIR or TEMP or TMP or if none defined /tmp. */
/* Parameters: *str - buffer in which to store filename */
/* Return : pointer to filename including directory. */
/***********************************************************************/
{
char *dir;
char endchar;
if (!str)
{
if ((temp_buf = (char *)malloc(MAXPATHLEN)) == NULL)
return(NULL);
str = temp_buf;
}
if ((dir = (char *)getenv("TMPDIR")) == NULL)
{
if ((dir = (char *)getenv("TEMP")) == NULL)
{
if ((dir = (char *)getenv("TMP")) == NULL)
dir = P_tmpdir;
}
}
strcpy(str,dir);
endchar = *(str+strlen(str)-1);
if (endchar == '/' || endchar == '\\')
*(str+strlen(str)-1) = '\0';
strcat(str,"/XXXXXX");
return(mktemp(strtrans(str,'\\','/')));
}
/***********************************************************************/
int dos_do_command( streng *command, int io_flags, int envir )
/***********************************************************************/
{
int rc;
streng *cmd ;
int in, out, fout ;
streng *inredir=NULL,*outredir=NULL ;
int length, rcode, flush ;
streng *result ;
char *string=NULL;
FILE *infp,*outfp;
char *infile="",*outfile="";
in = io_flags & REDIR_INPUT ;
out = io_flags & REDIR_OUTLIFO ;
fout = io_flags & REDIR_OUTFIFO ;
command = Str_ify( command ) ;
flush = (out!=0) + ((fout!=0)*2) ;
if ((!in)&&(!out)&&(!fout))
{
; /* maybe this should not be allowed. ... */
}
cmd = NULL ;
/*---------------------------------------------------------------------*/
/* If redirecting stdin, create a temporary file and write the contents*/
/* of the stack to the file. */
/*---------------------------------------------------------------------*/
if (in)
{
if ((infile = make_temp_file(NULL)) == NULL)
{
perror("While getting temporary in-file name") ;
return (-1);
}
if ((infp = fopen(infile,"w")) == NULL)
{
perror("While opening input file") ;
return (-1);
}
while(!stack_empty())
{
result = Str_ify(popline()) ;
fputs(result->value,infp);
fputs("\n",infp);
}
if (fclose(infp))
{
perror("While closing input file") ;
return (-1);
}
inredir = Str_make(strlen(infile)+4);
sprintf(inredir->value,"< %s ",strtrans(infile,'/','\\'));
inredir->len = strlen(inredir->value);
}
/*---------------------------------------------------------------------*/
/* If redirecting stdout, create the name of a temporary file for the */
/* output. */
/*---------------------------------------------------------------------*/
if ((out)||(fout))
{
if ((outfile = make_temp_file(NULL)) == NULL)
{
perror("While getting temporary out-file name") ;
return (-1);
}
outredir = Str_make(strlen(outfile)+3);
sprintf(outredir->value,"> %s",strtrans(outfile,'/','\\'));
outredir->len = strlen(outredir->value);
}
/*---------------------------------------------------------------------*/
/* Build up the command to be passed to the system() command. The */
/* command will contain the command to be executed, any arguments and */
/* the redirection commands and file names. */
/*---------------------------------------------------------------------*/
length = command->len + ((in) ? inredir->len : 0) + (((out)||(fout)) ? outredir->len : 0) + 2;
cmd = Str_make(length);
cmd = Str_cat(cmd,command);
if (in)
{
cmd = Str_cat(cmd,inredir);
Free(inredir);
}
if (out||fout)
{
cmd = Str_cat(cmd,outredir);
Free(outredir);
}
/*---------------------------------------------------------------------*/
/* Execute the command. */
/*---------------------------------------------------------------------*/
cmd = Str_ify(cmd);
rc = system(cmd->value);
Free(cmd);
/*---------------------------------------------------------------------*/
/* If redirecting stdout, we now have to read the file and push each */
/* line onto the stack. */
/*---------------------------------------------------------------------*/
if ((out)||(fout))
{
strtrans(outfile,'\\','/');
if ((outfp = fopen(outfile,"r")) == NULL)
{
perror("While opening output file") ;
return(-1);
}
/*---------------------------------------------------------------------*/
/* If redirecting stdin, create a temporary file and write the contents*/
/* of the stack to the file. */
/*---------------------------------------------------------------------*/
result->len = 0;
while(1)
{
string = get_a_line(outfp,string,&length,&rcode);
if (rcode == RC_OUT_OF_MEMORY)
{
perror("While reading output file");
return (-1);
}
if (rcode == RC_EOF && length == 0)
{
free(string);
break;
}
result = Str_ncre(string,length);
tmp_stack(result,flush==2);
free(string);
if (rcode == RC_EOF)
break;
}
if (flush)
flush_stack(flush==2);
if (fclose(outfp))
{
perror("While closing output file") ;
return(-1);
}
}
/*---------------------------------------------------------------------*/
/* Delete the temporary file(s) and free up any memory. */
/*---------------------------------------------------------------------*/
if (in)
{
unlink(strtrans(infile,'\\','/'));
free(infile);
}
if ((out)||(fout))
{
unlink(strtrans(outfile,'\\','/'));
free(outfile);
}
/*---------------------------------------------------------------------*/
/* Return with, hopefully, return code from system() command. */
/*---------------------------------------------------------------------*/
return rc ;
}
#endif