static char rcsid[] = "@(#)$Id: can_open.c,v 1.3 1999/03/24 14:03:51 wfp5p Exp $"; /******************************************************************************* * The Elm Mail System - $Revision: 1.3 $ $State: Exp $ * * Copyright (c) 1988-1995 USENET Community Trust * Copyright (c) 1986,1987 Dave Taylor ******************************************************************************* * Bug reports, patches, comments, suggestions should be sent to: * * Bill Pemberton, Elm Coordinator * flash@virginia.edu * ******************************************************************************* * $Log: can_open.c,v $ * Revision 1.3 1999/03/24 14:03:51 wfp5p * elm 2.5PL0 * * Revision 1.2 1995/09/29 17:41:06 wfp5p * Alpha 8 (Chip's big changes) * * Revision 1.1.1.1 1995/04/19 20:38:31 wfp5p * Initial import of elm 2.4 PL0 as base for elm 2.5. * ******************************************************************************/ /** can_open - can this user open this file using their normal uid/gid **/ #include "elm_defs.h" #include #include "port_stat.h" #include "port_wait.h" #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 pid, err, w, preexisted; waitstatus_t status; register SIGHAND_TYPE (*istat)(), (*qstat)(); #ifdef VFORK if ((pid = vfork()) == 0) #else if ((pid = fork()) == 0) #endif { SETGID(getgid()); setuid(getuid()); /** back to normal userid **/ preexisted = (access(file, ACCESS_EXISTS) == 0); if ((fd = fopen(file, mode)) == NULL) _exit(errno); fclose(fd); /* don't just leave it open! */ if(!preexisted) /* don't leave it if this test created it! */ unlink(file); _exit(0); } if (pid < 0) return EAGAIN; istat = signal(SIGINT, SIG_IGN); qstat = signal(SIGQUIT, SIG_IGN); while ((w = wait(&status)) != pid) { if (w < 0 && errno != EINTR) break; } err = errno; signal(SIGINT, istat); signal(SIGQUIT, qstat); if (w < 0) return err; if (!WIFEXITED(status)) return EINTR; /* ehhh...pick one...shouldn't really happen */ return WEXITSTATUS(status); }