home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / gnu / uucp-1.04 / unix / opensr.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-02-13  |  5.7 KB  |  245 lines

  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 ian@airs.com 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. }
  245.