*** ../1.7/elvprsv.c	Fri May 14 11:39:34 1993
--- elvprsv.c	Fri May 21 10:22:54 1993
***************
*** 84,89 ****
--- 84,93 ----
  # include "wildcard.c"
  #endif
  
+ #if VMS
+ char *ownername(file) char *file; { return "user"; }
+ void mail(user, file, when) {};
+ #endif
  
  BLK	buf;
  BLK	hdr;
***************
*** 281,287 ****
  	argv = wildexpand(&argc, argv);
  #endif
  
! 	/* do we have a "-c", "-R", or "-when elvis died" argument? */
  	i = 1;
  	if (argc >= i + 1 && !strcmp(argv[i], "-R"))
  	{
--- 285,291 ----
  	argv = wildexpand(&argc, argv);
  #endif
  
! 	/* do we have a "-R", or "-when elvis died" argument? */
  	i = 1;
  	if (argc >= i + 1 && !strcmp(argv[i], "-R"))
  	{
***************
*** 303,308 ****
--- 307,321 ----
  		when = argv[i] + 1;
  		i++;
  	}
+ 
+ #if VMS
+ 	/* VMS doesn't have `elvrec', so `elvprsv' should always use `-R' */
+ 	if (!rewrite_now)
+ 	{
+ 		fprintf(stderr, "VMS doesn't have `elvrec', so `elvprsv' should always use `-R'\n");
+ 		exit(0);
+ 	}
+ #endif
  
  	/* preserve everything we're supposed to */
  	while (i < argc)
*** ../1.7/prsvunix.c	Fri May 14 11:39:56 1993
--- prsvunix.c	Fri May 21 10:46:45 1993
***************
*** 14,19 ****
--- 14,135 ----
  extern struct passwd *getpwuid();
  #endif
  
+ #if ANY_UNIX /* { */
+ /* Since elvprsv runs as SUID-root, we need a *secure* version of popen() */
+ #define popen safe_popen
+ #define pclose safe_pclose
+ 
+ /* This function is similar to the standard popen() function, except for...
+  *	1) It doesn't use the shell, for security reasons.
+  *	2) Shell services are not supported, including quoting.
+  *	3) The mode can only be "w".  "r" is not supported.
+  *	4) No more than 9 arguments can be given, including the command.
+  */
+ /*ARGSUSED*/
+ static FILE *safe_popen(cmd, mode)
+ 	char	*cmd;	/* the filename of the program to be run */
+ 	char	*mode;	/* "w", ignored */
+ {
+ 	char	path[100];/* full pathname of argv[0] */
+ 	char	*argv[10];/* the arguments */
+ 	int	r0w1[2];/* the pipe fd's */
+ 	int	i;
+ 	FILE	*fp;
+ 
+ 	/* parse the arguments */
+ 	for (i = 0; i < 9 && *cmd; i++)
+ 	{
+ 		/* remember where this arg starts */
+ 		argv[i] = cmd;
+ 
+ 		/* move to the end of the argument */
+ 		do
+ 		{
+ 			cmd++;
+ 		} while (*cmd && *cmd != ' ');
+ 
+ 		/* then mark end of arg & skip to next */
+ 		while (*cmd && *cmd == ' ')
+ 		{
+ 			*cmd++ = '\0';
+ 		}
+ printf("argv[%d]=\"%s\"\n", i, argv[i]);
+ 	}
+ 	argv[i] = (char *)0;
+ 
+ 	/* make the pipe */
+ 	if (pipe(r0w1) < 0)
+ 	{
+ perror("pipe()");
+ 		return (FILE *)0;	/* pipe failed */
+ 	}
+ 
+ 	switch (fork())
+ 	{
+ 	  case -1:						/* error */
+ perror("fork()");
+ 		return (FILE *)0;
+ 
+ 	  case 0:						/* child */
+ 		/* close the "write" end of the pipe */
+ 		close(r0w1[1]);
+ 
+ 		/* redirect stdin to come from the "read" end of the pipe */
+ 		close(0);
+ 		dup(r0w1[0]);
+ 		close(r0w1[0]);
+ 
+ 		/* exec the shell to run the command */
+ 		if (*argv[0] != '/')
+ 		{
+ 			/* no path, try "/bin/argv[0]" */
+ 			strcpy(path, "/bin/");
+ 			strcat(path, argv[0]);
+ 			execv(path, argv);
+ perror(path);
+ 
+ 			/* if that failed, then try "/usr/bin/argv[0]" */
+ 			strcpy(path, "/usr/bin/");
+ 			strcat(path, argv[0]);
+ 			execv(path, argv);
+ perror(path);
+ 		}
+ 		else
+ 		{
+ 			/* full pathname given, so use it */
+ 			execv(argv[0], argv);
+ perror(argv[0]);
+ 		}
+ 
+ 		/* if we get here, exec failed */
+ 		exit(1);
+ 
+ 	  default:						/* parent */
+ 		/* close the "read" end of the pipe */	
+ 		close(r0w1[0]);
+ 
+ 		/* convert the "write" fd into a (FILE *) */
+ 		fp = fdopen(r0w1[1], "w");
+ 		return fp;
+ 	}
+ 	/*NOTREACHED*/
+ }
+ 
+ 
+ /* This function closes the pipe opened by popen(), and returns 0 for success */
+ static int safe_pclose(fp)
+ 	FILE	*fp;	/* value returned by popen() */
+ {
+ 	int	status;
+ 
+ 	/* close the file, and return the defunct child's exit status */
+ 	fclose(fp);
+ 	wait(&status);
+ 	return status;
+ }
+ #endif /* } ANY UNIX */
+ 
+ 
  /* This variable is used to add extra error messages for mail sent to root */
  char *ps;
  
***************
*** 53,59 ****
  	char	*when;	/* description of why the file was preserved */
  {
  	char	cmd[80];/* buffer used for constructing a "mail" command */
! 	FILE	*m, *popen();	/* stream used for giving text to the "mail" program */
  	char	*base;	/* basename of the file */
  
  	/* separate the directory name from the basename. */
--- 169,175 ----
  	char	*when;	/* description of why the file was preserved */
  {
  	char	cmd[80];/* buffer used for constructing a "mail" command */
! 	FILE	*m;	/* stream used for giving text to the "mail" program */
  	char	*base;	/* basename of the file */
  
  	/* separate the directory name from the basename. */
***************
*** 75,85 ****
  #if OSK
  	sprintf(cmd, "mail \"-s=%s preserved!\" %s", base, user);
  #else /* ANY_UNIX */
! 	sprintf(cmd, "mail %s >/dev/null 2>/dev/null", user);
  #endif
  	m = popen(cmd, "w");
  	if (!m)
  	{
  		/* Can't send mail!  Hope the user figures it out. */
  		return;
  	}
--- 191,202 ----
  #if OSK
  	sprintf(cmd, "mail \"-s=%s preserved!\" %s", base, user);
  #else /* ANY_UNIX */
! 	sprintf(cmd, "mail -s Graceland %s", user);
  #endif
  	m = popen(cmd, "w");
  	if (!m)
  	{
+ 		perror(cmd);
  		/* Can't send mail!  Hope the user figures it out. */
  		return;
  	}
*** ../1.7/config.h	Fri May 14 11:39:14 1993
--- config.h	Fri May 21 10:59:47 1993
***************
*** 476,481 ****
--- 476,487 ----
  # ifndef TMPDIR
  #  define TMPDIR        "sys$scratch:"  /* directory where temp files live */
  # endif
+ # ifndef PRSVDIR
+ #  define PRSVDIR	"sys$scratch:"	/* directory where preserved file live */
+ # endif
+ # ifndef PRSVINDEX
+ #  define PRSVINDEX	"sys$scratch:index;1" /* index of files in PRSVDIR */
+ # endif
  # define TMPNAME        "%selv_%x.%x;1" /* temp file */
  # define SCRATCHIN      "%ssiXXXXXX"    /* DOS ONLY - output of filter program */
  # define SCRATCHOUT     "%ssoXXXXXX"    /* temp file used as input to filter */
