[comp.sys.amiga] csh207 mods and a system

ricks@iscuva.ISCS.COM (Rick Schaeffer) (08/21/88)

Here is a shar file containing my path mods to CSH as well as a unix-like
system() function for Manx C.  I'm not sure if my .signature file will
be appended, so be sure to check for it before unsharing.  I hope I don't
get flamed for posting this here rather than in comp.sources.amiga!  It's
pretty small.
     Rick Schaeffer

#	This is a shell archive.
#	Remove everything above and including the cut line.
#	Then run the rest of the file through sh.
#----cut here-----cut here-----cut here-----cut here----#
#!/bin/sh
# shar:    Shell Archiver
#	Run the following text with /bin/sh to create:
#	README
#	pathdiffs
#	getpath.c
#	system.c
# This archive created: Sat Aug 20 12:31:34 1988
cat << \SHAR_EOF > README
This posting includes patches to csh version 2.07m and a new module
(getpath.c) for inclusion in the link of csh.  These changes cause
csh to default to AmigaDos's PATH for it's internal "_path" variable.
A new internal command, "path" has also been added which, after
setting AmigaDos's path, changes the "_path" variable to agree.  I
didn't change the version number of csh although I perhaps should have.

Also included is a module, "system.c", for inclusion in other programs
or perhaps the Manx library.  It implements a unix-like "system()" 
function which, combined with the above changes to csh, supports
redirection and returns the correct exit status.

    Rick Schaeffer
    E. 13611 26th Ave.
    Spokane, Wa.  99216
    Usenet address: uunet!iscuva!ricks (ricks@iscuva.ISCS.COM)
SHAR_EOF
cat << \SHAR_EOF > pathdiffs
*** df2:csh207/Makefile	Mon Oct 12 21:17:32 1987
--- Makefile	Sat Aug 13 16:03:42 1988
***************
*** 6,12 ****
  ######################################################################
   
  OBJS	= run.o main.o comm1.o comm2.o execom.o set.o sub.o \
! 		globals.o rawconsole.o sort.o
   
  INCL	= shell.h
   
--- 6,12 ----
  ######################################################################
   
  OBJS	= run.o main.o comm1.o comm2.o execom.o set.o sub.o \
! 		globals.o rawconsole.o sort.o getpath.o
   
  INCL	= shell.h
   
***************
*** 39,41 ****
--- 39,44 ----
   
  execom.o : execom.c $(INCL)
  	cc    +IShell.syms execom.c
+ 
+ getpath.o : getpath.c
+ 	cc    getpath.c
*** df2:csh207/main.c	Mon Oct 12 21:17:31 1987
--- main.c	Sat Aug 13 16:06:15 1988
***************
*** 78,83 ****
--- 78,85 ----
   
  init_vars()
  {
+    char *getPath();
+ 
     if (IsInteractive(Input()))
        set_var (LEVEL_SET, V_PROMPT, "$ ");
     else
***************
*** 84,90 ****
        set_var (LEVEL_SET, V_PROMPT, "");
     set_var (LEVEL_SET, V_HIST,	 "20");
     set_var (LEVEL_SET, V_LASTERR, "0");
!    set_var (LEVEL_SET, V_PATH, "ram:,ram:c/,c:,df1:c/,df0:c/");
     set_var (LEVEL_SET, "_insert", "1");
  }
   
--- 86,93 ----
        set_var (LEVEL_SET, V_PROMPT, "");
     set_var (LEVEL_SET, V_HIST,	 "20");
     set_var (LEVEL_SET, V_LASTERR, "0");
! /* set_var (LEVEL_SET, V_PATH, "ram:,ram:c/,c:,df1:c/,df0:c/"); */
!    set_var (LEVEL_SET, V_PATH, getPath());
     set_var (LEVEL_SET, "_insert", "1");
  }
   
*** df2:csh207/execom.c	Mon Oct 12 21:17:23 1987
--- execom.c	Sat Aug 13 16:39:37 1988
***************
*** 42,48 ****
  extern int do_input(), do_ver(), do_sleep(), do_help();
  extern int do_strhead(), do_strtail();
  extern int do_copy(), date(),  do_ps();
! extern int do_forever(), do_abortline();
  char *push_cpy();
   
  static struct COMMAND Command[] = {
--- 42,48 ----
  extern int do_input(), do_ver(), do_sleep(), do_help();
  extern int do_strhead(), do_strtail();
  extern int do_copy(), date(),  do_ps();
! extern int do_forever(), do_abortline(), do_path();
  char *push_cpy();
   
  static struct COMMAND Command[] = {
***************
*** 72,77 ****
--- 72,78 ----
     do_mem      , 0,  0,		 0 ,   "mem",
     do_mkdir    , 0,  0,		 0 ,   "mkdir",
     do_mv       , 2,  0,		 0 ,   "mv",
+    do_path     , 0,  0,          0 ,   "path",
     do_ps       , 0,  0,		 0,    "ps",
     do_pwd      , 0,  0,		 0 ,   "pwd",
     do_quit     , 0,  ST_NORED,	 0 ,   "quit",
*** df2:csh207/set.c	Mon Oct 12 21:17:40 1987
--- set.c	Sat Aug 13 16:45:36 1988
***************
*** 171,173 ****
--- 171,184 ----
        if (S_histlen < 2)   S_histlen = 2;
     }
  }
+ 
+ do_path(command)
+ char	*command;
+ {
+ 	char *getPath();
+ 
+ 	command[0] = 'P';
+ 	exec_command(command);
+ 	set_var (LEVEL_SET, V_PATH, getPath());
+ 	return(0);
+ }
SHAR_EOF
cat << \SHAR_EOF > getpath.c
/* GETPATH.C
** Get amigados's path for use in CSH.
**
** Rick Schaeffer
** uunet!iscuva!ricks (ricks@iscuva.ISCS.COM)
*/
#include <stdio.h>
#include <libraries/dosextens.h>
#include <exec/memory.h>

extern struct Process *FindTask();
extern struct FileLock *ParentDir();
extern char *AllocMem();

struct Path {
	BPTR  path_Next;
	LONG  path_Lock;
	};

/*
** This function returns a string containing AmigaDos's path.  Each
** element of the path is separated by a comma (,) from it's neighbor.
** Since "C:" is assumed to be the end of the path, it is appended
** to the string returned.
*/
char *getPath()
{
	static char pathstr[258],*newpath;
	char *followpath();
	struct Process *proc;
	struct CommandLineInterface *cli;
	struct Path *path;

	proc = (struct Process *)FindTask(NULL);
	cli = (struct CommandLineInterface *)(proc->pr_CLI << 2);
	if (!cli) {
		printf("getPath: Not a cli process\n");
		exit(1);
		}
	pathstr[0] = 0;
	for(path = (struct Path *) BADDR(cli->cli_CommandDir);
		(path); path = (struct Path *) BADDR(path->path_Next)) {
		newpath = followpath(path->path_Lock,0);
		if ((strlen(newpath) + strlen(pathstr) + 2) > 256)
			break;	/* Not enough room for another path var */
		strcat(pathstr,newpath);
		strcat(pathstr,",");
		}
	strcat(pathstr,"C:");
	return(pathstr);
}

static char *followpath(lock,level)
struct FileLock *lock;
int		level;
{
	struct FileInfoBlock *fib;
	struct FileLock *newlock;
	static char pathbuf[256];

	if (! lock)
		return(pathbuf);
	if (level == 0)
		pathbuf[0] = 0;
	fib = (struct FileInfoBlock *) AllocMem((long)sizeof(struct FileInfoBlock),MEMF_CLEAR);
	if (fib == NULL) {
		printf("followpath: Out of Memory\n");
		return(pathbuf);
		}
	newlock = ParentDir(lock);
	followpath(newlock,1); /* recurse till we hit the root directory */
	if (Examine(lock,fib)) {
		if (fib->fib_FileName[0] > ' ')
			strcat(pathbuf,fib->fib_FileName);
		else
			strcat(pathbuf,"RAM");
		if (newlock == NULL)
			strcat(pathbuf,":");
		else
			strcat(pathbuf,"/");
		}
	if (level)
		UnLock(lock);
	if (fib)
		FreeMem(fib,(long) sizeof(struct FileInfoBlock));
	return(pathbuf);
}
SHAR_EOF
cat << \SHAR_EOF > system.c
/*
** SYSTEM.C
** This module implements a unix-like "system()" function for Manx C.
** It does so by utilizing the Dillon/Drew shell program (usually
** called "csh") in order to support i/o redirection and piping in the
** program being called.  For this function to work, you MUST have
** the Shell somewhere in your path and it MUST be named "csh".  You
** should also have a version of the shell which inherits the AmigaDos
** path since the current version of csh (2.07M) uses a default path
** which may be unsuitable.  
**
** Given the above caveats, you invoke this function like this:
**   exitval = system("command parm1 parm2 >outfile");
** "command" will be executed by prepending "csh -c" to it.  exitval
** will be the exit status of "command".  "outfile" will contain the
** stdout output of "command".
**
** Rick Schaeffer
** uunet!iscuva!ricks (ricks@iscuva.ISCS.COM)
*/

#include <stdio.h>
#include <ctype.h>
#include <errno.h>

extern int errno;
extern char *malloc();

int system(cmd)
char *cmd;
{
    char **xrgs,*myrealloc(),*optr;
    register char *ptr;
    register int i,j;
    
   	optr = ptr = malloc(strlen(cmd) + 1);
   	if (ptr == NULL) {
   		errno = ENOMEM;
   		return(-1);
   		}
   	strcpy(ptr,cmd); /* make a copy of cmd so we don't mung it in parsing */

/* The next 4 non-comment lines can be replaced by:
**   xrgs = (char **) malloc(sizeof(xrgs));
** if you don't have/want to use CSH.  The function will work but
** you won't be able to do i/o redirection in the command being executed.
*/
   	xrgs = (char **) malloc(sizeof(xrgs) * 3);
   	xrgs[0] = "csh";
   	xrgs[1] = "-c";
   	xrgs[2] = NULL;

   	i = 2;
   	while (*ptr) {
   		while (isspace(*ptr)) {
   			if (*ptr == 0)
   				break;
   			ptr++;
   			}
		if (*ptr) {
			xrgs = (char **) myrealloc(xrgs,sizeof(xrgs) * (i+2));
			if (xrgs == NULL) {
				errno = ENOMEM;
				return(-1);
				}
			xrgs[i++] = ptr;
			}
		while (*ptr)
			if (! isspace(*ptr))
				ptr++;
			else
				break;
		if (*ptr)
			*ptr++ = 0;
		}
	xrgs[i] = NULL;
	if ((fexecv(xrgs[0],xrgs)) != 0) {
		free(xrgs);
		free(optr);
		return(-1);
		}
	else {
		free(xrgs);
		free(optr);
		return(wait());
		}
}

static char *myrealloc(ptr,nb)
char		*ptr;
unsigned	nb;
{
	char	*tptr,*malloc();

	tptr = malloc(nb);
	if (tptr != NULL) {
		movmem(ptr,tptr,nb);
		free(ptr);
		}
	return(tptr);
}
SHAR_EOF
#	End of shell archive
exit 0
-- 
Rick Schaeffer          UUCP:  uunet!iscuva!ricks
ISC Systems Corp.              ricks@iscuva.ISCS.COM
Box TAF-C8              Phone: (509)927-5114
Spokane, WA  99220