1/* efopen.c 2 Open a stdio file with appropriate permissions. */ 3 4#include "uucp.h" 5 6#include "uudefs.h" 7#include "sysdep.h" 8#include "system.h" 9 10#include <errno.h> 11 12#if HAVE_FCNTL_H 13#include <fcntl.h> 14#else 15#if HAVE_SYS_FILE_H 16#include <sys/file.h> 17#endif 18#endif 19 20#include <sys/types.h> 21#include <sys/stat.h> 22 23#ifndef O_RDONLY 24#define O_RDONLY 0 25#define O_WRONLY 1 26#define O_RDWR 2 27#endif 28 29#ifndef O_APPEND 30#ifdef FAPPEND 31#define O_APPEND FAPPEND 32#endif 33#endif 34 35#ifndef O_NOCTTY 36#define O_NOCTTY 0 37#endif 38 39#ifndef FD_CLOEXEC 40#define FD_CLOEXEC 1 41#endif 42 43FILE * 44esysdep_fopen (zfile, fpublic, fappend, fmkdirs) 45 const char *zfile; 46 boolean fpublic; 47 boolean fappend; 48 boolean fmkdirs; 49{ 50 int imode; 51 int o; 52 FILE *e; 53 int force_chmod = 0; 54 char rfile[PATH_MAX]; 55 56 if (fpublic) 57 imode = IPUBLIC_FILE_MODE; 58 else 59 imode = IPRIVATE_FILE_MODE; 60 61#ifdef WORLD_WRITABLE_FILE_IN 62 realpath(zfile, rfile); 63 if (rfile == strstr(rfile, WORLD_WRITABLE_FILE_IN)) { 64 imode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH; 65 force_chmod = 1; 66 } 67#endif 68 69 if (! fappend) 70 o = creat ((char *) zfile, imode); 71 else 72 { 73#ifdef O_CREAT 74 o = open ((char *) zfile, 75 O_WRONLY | O_APPEND | O_CREAT | O_NOCTTY, 76 imode); 77#else 78 o = open ((char *) zfile, O_WRONLY | O_NOCTTY); 79 if (o < 0 && errno == ENOENT) 80 o = creat ((char *) zfile, imode); 81#endif /* ! defined (O_CREAT) */ 82 } 83 84 if (o < 0) 85 { 86 if (errno == ENOENT && fmkdirs) 87 { 88 if (! fsysdep_make_dirs (zfile, fpublic)) 89 return NULL; 90 if (! fappend) 91 o = creat ((char *) zfile, imode); 92 else 93 { 94#ifdef O_CREAT 95 o = open ((char *) zfile, 96 O_WRONLY | O_APPEND | O_CREAT | O_NOCTTY, 97 imode); 98#else 99 o = creat ((char *) zfile, imode); 100#endif 101 } 102 } 103 if (o < 0) 104 { 105 ulog (LOG_ERROR, "open (%s): %s", zfile, strerror (errno)); 106 if (errno == EPERM) { 107 struct stat sb; 108 o = stat(zfile, &sb); 109 if (o == 0) { 110 ulog(LOG_ERROR, "my uid %d; file uid %d, mode %o", 111 getuid(), sb.st_uid, sb.st_mode); 112 } else { 113 ulog(LOG_ERROR, "can't stat %s", zfile); 114 } 115 } 116 return NULL; 117 } 118 } 119 120#ifndef O_CREAT 121#ifdef O_APPEND 122 if (fappend) 123 { 124 if (fcntl (o, F_SETFL, O_APPEND) < 0) 125 { 126 ulog (LOG_ERROR, "fcntl (%s, O_APPEND): %s", zfile, 127 strerror (errno)); 128 (void) close (o); 129 return NULL; 130 } 131 } 132#endif /* defined (O_APPEND) */ 133#endif /* ! defined (O_CREAT) */ 134 135 if (fcntl (o, F_SETFD, fcntl (o, F_GETFD, 0) | FD_CLOEXEC) < 0) 136 { 137 ulog (LOG_ERROR, "fcntl (%s, FD_CLOEXEC): %s", zfile, 138 strerror (errno)); 139 (void) close (o); 140 return NULL; 141 } 142 143 if (imode == IPUBLIC_FILE_MODE || force_chmod) { 144 e = fchmod(o, imode); 145 if (e) { 146 ulog(LOG_ERROR, "fchmod %s %o %s", zfile, imode, strerror(errno)); 147 } 148 } 149 150 if (fappend) 151 e = fdopen (o, (char *) "a"); 152 else 153 e = fdopen (o, (char *) "w"); 154 155 if (e == NULL) 156 { 157 ulog (LOG_ERROR, "fdopen: %s", strerror (errno)); 158 (void) close (o); 159 } 160 161 return e; 162} 163