static char rcsid[] = "@(#)$Id: can_open.c,v 1.13 2006/04/09 07:37:05 hurtta Exp $";
/******************************************************************************
* The Elm (ME+) Mail System - $Revision: 1.13 $ $State: Exp $
*
* Modified by: Kari Hurtta <hurtta+elm@poasti.FMI.FI>
* (was hurtta+elm@ozone.FMI.FI)
******************************************************************************
* The Elm Mail System
*
* Copyright (c) 1988-1992 USENET Community Trust
* Copyright (c) 1986,1987 Dave Taylor
*****************************************************************************/
/** can_open - can this user open this file using their normal uid/gid
**/
#include "headers.h"
#include <errno.h>
#ifndef ANSI_C
extern int errno; /* system error number */
#endif
DEBUG_VAR(Debug,__FILE__,"file");
#ifndef I_UNISTD
void _exit();
#endif
int can_open(file, mode)
CONST char *file, *mode;
{
/** Returns 0 iff user can open the file. This is not
the same as can_access - it's used for when the file might
not exist... **/
FILE *fd;
int the_stat = 0, pid, w, sig;
VOLATILE int preexisted = 0;
S__ status;
#ifdef VFORK
if ((pid = vfork()) == 0) {
#else
if ((pid = fork()) == 0) {
#endif
if (-1 == setgid(groupid)) {
int err = errno;
fprintf(stderr,"can_open: setgid(%d) FAILED: %s\n",
groupid,error_description(err));
fflush(stderr);
_exit(err != 0? err : 1); /* never return zero! */
}
if (-1 == setuid(userid)) { /** back to normal userid **/
int err = errno;
fprintf(stderr,"can_open: setuid(%d) FAILED: %s\n",
userid,error_description(err));
fflush(stderr);
_exit(err != 0? err : 1); /* never return zero! */
}
errno = 0;
if (mode[0] == 's' && mode[1] == 'w' && ! mode[2]) {
int filedes = open(file, O_WRONLY | O_CREAT | O_EXCL, 0600);
if (filedes < 0 &&
(unlink(file) ||
(filedes = open(file, O_WRONLY|O_CREAT|O_EXCL, 0600)) < 0))
_exit(errno);
else {
close(filedes);
_exit(0);
}
}
if (access(file, ACCESS_EXISTS) == 0)
preexisted = 1;
if ((fd = fopen(file, mode)) == NULL)
_exit(errno != 0 ? errno : 1);
else {
fclose(fd); /* don't just leave it open! */
if(!preexisted) /* don't leave it if this test created it! */
unlink(file);
_exit(0);
}
_exit(127);
}
errno = 0;
while ((w = my_wait(pid,&status)) != pid &&
(w != -1 || EINTR == errno))
;
sig = convert_status(status,&the_stat);
if (sig)
the_stat = 1;
DPRINT(Debug,1,(&Debug,
"can_open(%s,%s) = %d\n",file,mode,the_stat));
return(the_stat);
}
/*
* Local Variables:
* mode:c
* c-basic-offset:4
* buffer-file-coding-system: iso-8859-1
* End:
*/
syntax highlighted by Code2HTML, v. 0.9.1