|
|
1.1 ! root 1: /* opensr.c ! 2: Open files for sending and receiving. ! 3: ! 4: Copyright (C) 1991, 1992 Ian Lance Taylor ! 5: ! 6: This file is part of the Taylor UUCP package. ! 7: ! 8: This program is free software; you can redistribute it and/or ! 9: modify it under the terms of the GNU General Public License as ! 10: published by the Free Software Foundation; either version 2 of the ! 11: License, or (at your option) any later version. ! 12: ! 13: This program is distributed in the hope that it will be useful, but ! 14: WITHOUT ANY WARRANTY; without even the implied warranty of ! 15: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ! 16: General Public License for more details. ! 17: ! 18: You should have received a copy of the GNU General Public License ! 19: along with this program; if not, write to the Free Software ! 20: Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ! 21: ! 22: The author of the program may be contacted at [email protected] or ! 23: c/o Infinity Development Systems, P.O. Box 520, Waltham, MA 02254. ! 24: */ ! 25: ! 26: #include "uucp.h" ! 27: ! 28: #include "uudefs.h" ! 29: #include "uuconf.h" ! 30: #include "system.h" ! 31: #include "sysdep.h" ! 32: ! 33: #include <errno.h> ! 34: ! 35: #if HAVE_TIME_H ! 36: #include <time.h> ! 37: #endif ! 38: ! 39: #if HAVE_FCNTL_H ! 40: #include <fcntl.h> ! 41: #else ! 42: #if HAVE_SYS_FILE_H ! 43: #include <sys/file.h> ! 44: #endif ! 45: #endif ! 46: ! 47: #ifndef O_RDONLY ! 48: #define O_RDONLY 0 ! 49: #define O_WRONLY 1 ! 50: #define O_RDWR 2 ! 51: #endif ! 52: ! 53: #ifndef O_NOCTTY ! 54: #define O_NOCTTY 0 ! 55: #endif ! 56: ! 57: #ifndef FD_CLOEXEC ! 58: #define FD_CLOEXEC 1 ! 59: #endif ! 60: ! 61: #ifndef time ! 62: extern time_t time (); ! 63: #endif ! 64: ! 65: /* Open a file to send to another system, and return the mode and ! 66: the size. */ ! 67: ! 68: openfile_t ! 69: esysdep_open_send (qsys, zfile, fcheck, zuser) ! 70: const struct uuconf_system *qsys; ! 71: const char *zfile; ! 72: boolean fcheck; ! 73: const char *zuser; ! 74: { ! 75: struct stat s; ! 76: openfile_t e; ! 77: int o; ! 78: ! 79: if (fsysdep_directory (zfile)) ! 80: { ! 81: ulog (LOG_ERROR, "%s: is a directory", zfile); ! 82: return EFILECLOSED; ! 83: } ! 84: ! 85: #if USE_STDIO ! 86: e = fopen (zfile, BINREAD); ! 87: if (e == NULL) ! 88: { ! 89: ulog (LOG_ERROR, "fopen (%s): %s", zfile, strerror (errno)); ! 90: return NULL; ! 91: } ! 92: o = fileno (e); ! 93: #else ! 94: e = open ((char *) zfile, O_RDONLY | O_NOCTTY, 0); ! 95: if (e == -1) ! 96: { ! 97: ulog (LOG_ERROR, "open (%s): %s", zfile, strerror (errno)); ! 98: return -1; ! 99: } ! 100: o = e; ! 101: #endif ! 102: ! 103: if (fcntl (o, F_SETFD, fcntl (o, F_GETFD, 0) | FD_CLOEXEC) < 0) ! 104: { ! 105: ulog (LOG_ERROR, "fcntl (FD_CLOEXEC): %s", strerror (errno)); ! 106: (void) ffileclose (e); ! 107: return EFILECLOSED; ! 108: } ! 109: ! 110: if (fstat (o, &s) == -1) ! 111: { ! 112: ulog (LOG_ERROR, "fstat: %s", strerror (errno)); ! 113: s.st_mode = 0666; ! 114: } ! 115: ! 116: /* We have to recheck the file permission, although we probably ! 117: checked it already, because otherwise there would be a window in ! 118: which somebody could change the contents of a symbolic link to ! 119: point to some file which was only readable by uucp. */ ! 120: if (fcheck) ! 121: { ! 122: if (! fsuser_access (&s, R_OK, zuser)) ! 123: { ! 124: ulog (LOG_ERROR, "%s: %s", zfile, strerror (EACCES)); ! 125: (void) ffileclose (e); ! 126: return EFILECLOSED; ! 127: } ! 128: } ! 129: ! 130: return e; ! 131: } ! 132: ! 133: /* Get a temporary file name to receive into. We use the ztemp ! 134: argument to pick the file name, so that we relocate the file if the ! 135: transmission is aborted. */ ! 136: ! 137: char * ! 138: zsysdep_receive_temp (qsys, zto, ztemp) ! 139: const struct uuconf_system *qsys; ! 140: const char *zto; ! 141: const char *ztemp; ! 142: { ! 143: if (ztemp != NULL ! 144: && *ztemp == 'D' ! 145: && strcmp (ztemp, "D.0") != 0) ! 146: return zsappend3 (".Temp", qsys->uuconf_zname, ztemp); ! 147: else ! 148: return zstemp_file (qsys); ! 149: } ! 150: ! 151: /* Open a temporary file to receive into. This should, perhaps, check ! 152: that we have write permission on the receiving directory, but it ! 153: doesn't. */ ! 154: ! 155: openfile_t ! 156: esysdep_open_receive (qsys, zto, ztemp, zreceive, pcrestart) ! 157: const struct uuconf_system *qsys; ! 158: const char *zto; ! 159: const char *ztemp; ! 160: const char *zreceive; ! 161: long *pcrestart; ! 162: { ! 163: int o; ! 164: openfile_t e; ! 165: ! 166: /* If we used the ztemp argument in zsysdep_receive_temp, above, ! 167: then we will have a name consistent across conversations. In ! 168: that case, we may have already received some portion of this ! 169: file. */ ! 170: o = -1; ! 171: *pcrestart = -1; ! 172: if (ztemp != NULL ! 173: && *ztemp == 'D' ! 174: && strcmp (ztemp, "D.0") != 0) ! 175: { ! 176: o = open ((char *) zreceive, O_WRONLY); ! 177: if (o >= 0) ! 178: { ! 179: struct stat s; ! 180: ! 181: /* For safety, we insist on the file being less than 1 week ! 182: old. This can still catch people, unfortunately. I ! 183: don't know of any good solution to the problem of old ! 184: files hanging around. If anybody has a file they want ! 185: restarted, and they know about this issue, they can touch ! 186: it to bring it up to date. */ ! 187: if (fstat (o, &s) < 0 ! 188: || s.st_mtime + 7 * 24 * 60 * 60 < time ((time_t *) NULL)) ! 189: { ! 190: (void) close (o); ! 191: o = -1; ! 192: } ! 193: else ! 194: { ! 195: DEBUG_MESSAGE1 (DEBUG_SPOOLDIR, ! 196: "esysdep_open_receive: Reusing %s", ! 197: zreceive); ! 198: *pcrestart = (long) s.st_size; ! 199: } ! 200: } ! 201: } ! 202: ! 203: if (o < 0) ! 204: o = creat ((char *) zreceive, IPRIVATE_FILE_MODE); ! 205: ! 206: if (o < 0) ! 207: { ! 208: if (errno == ENOENT) ! 209: { ! 210: if (! fsysdep_make_dirs (zreceive, FALSE)) ! 211: return EFILECLOSED; ! 212: o = creat ((char *) zreceive, IPRIVATE_FILE_MODE); ! 213: } ! 214: if (o < 0) ! 215: { ! 216: ulog (LOG_ERROR, "creat (%s): %s", zreceive, strerror (errno)); ! 217: return EFILECLOSED; ! 218: } ! 219: } ! 220: ! 221: if (fcntl (o, F_SETFD, fcntl (o, F_GETFD, 0) | FD_CLOEXEC) < 0) ! 222: { ! 223: ulog (LOG_ERROR, "fcntl (FD_CLOEXEC): %s", strerror (errno)); ! 224: (void) close (o); ! 225: (void) remove (zreceive); ! 226: return EFILECLOSED; ! 227: } ! 228: ! 229: #if USE_STDIO ! 230: e = fdopen (o, (char *) BINWRITE); ! 231: ! 232: if (e == NULL) ! 233: { ! 234: ulog (LOG_ERROR, "fdopen (%s): %s", zreceive, strerror (errno)); ! 235: (void) close (o); ! 236: (void) remove (zreceive); ! 237: return EFILECLOSED; ! 238: } ! 239: #else ! 240: e = o; ! 241: #endif ! 242: ! 243: return e; ! 244: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.