/* This file contains the UNIX-specific parts of the "elvprsv" program. */
/* some older systems don't declare this in pwd.h, I guess. */
extern struct passwd
*getpwuid();
/* Since elvprsv runs as SUID-root, we need a *secure* version of 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.
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 */
/* parse the arguments */
for (i
= 0; i
< 9 && *cmd
; i
++)
/* remember where this arg starts */
/* move to the end of the argument */
} while (*cmd
&& *cmd
!= ' ');
/* then mark end of arg & skip to next */
while (*cmd
&& *cmd
== ' ')
printf("argv[%d]=\"%s\"\n", i
, argv
[i
]);
return (FILE *)0; /* pipe failed */
/* close the "write" end of the pipe */
/* redirect stdin to come from the "read" end of the pipe */
/* exec the shell to run the command */
/* no path, try "/bin/argv[0]" */
/* if that failed, then try "/usr/bin/argv[0]" */
strcpy(path
, "/usr/bin/");
/* full pathname given, so use it */
/* if we get here, exec failed */
/* close the "read" end of the pipe */
/* convert the "write" fd into a (FILE *) */
fp
= fdopen(r0w1
[1], "w");
/* This function closes the pipe opened by popen(), and returns 0 for success */
static int safe_pclose(fp
)
FILE *fp
; /* value returned by popen() */
/* close the file, and return the defunct child's exit status */
/* This variable is used to add extra error messages for mail sent to root */
/* This function returns the login name of the owner of a file */
char *ownername(filename
)
char *filename
; /* name of a file */
/* stat the file, to get its uid */
if (stat(filename
, &st
) < 0)
/* get the /etc/passwd entry for that user */
pw
= getpwuid(st
.st_uid
);
ps
= "uid not found in password file";
/* return the user's name */
/* This function sends a mail message to a given user, saying that a file
void mail(user
, file
, when
)
char *user
; /* name of user who should receive the mail */
char *file
; /* name of original text file that was preserved */
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. */
for (base
= file
+ strlen(file
); --base
> file
&& *base
!= SLASH
; )
/* for anonymous buffers, pretend the name was "foo" */
/* open a pipe to the "mail" program */
sprintf(cmd
, "mail \"-s=%s preserved!\" %s", base
, user
);
sprintf(cmd
, "mail -s Graceland %s", user
);
/* Can't send mail! Hope the user figures it out. */
/* Tell the user that the file was preserved */
fprintf(m
, "A version of your file \"%s%c%s\"\n", file
, SLASH
, base
);
fprintf(m
, "was preserved when %s.\n", when
);
fprintf(m
, "To recover this file, do the following:\n");
fprintf(m
, " chd %s\n", file
);
fprintf(m
, " cd %s\n", file
);
fprintf(m
, " elvisrecover %s\n", base
);
fprintf(m
, "With fond wishes for a speedy recovery,\n");
fprintf(m
, "\nP.S. %s\n", ps
);