home *** CD-ROM | disk | FTP | other *** search
/ OpenStep 4.2J (Developer) / os42jdev.iso / NextDeveloper / Source / GNU / uucp / Uucp.framework / unix.subproj / indir.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-10-09  |  3.4 KB  |  134 lines

  1. /* indir.c
  2.    See if a file is in a directory.
  3.  
  4.    Copyright (C) 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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  21.  
  22.    The author of the program may be contacted at ian@airs.com or
  23.    c/o Cygnus Support, 48 Grove Street, Somerville, MA 02144.
  24.    */
  25.  
  26. #include "uucp.h"
  27.  
  28. #include "uudefs.h"
  29. #include "sysdep.h"
  30. #include "system.h"
  31.  
  32. #include <errno.h>
  33.  
  34. /* See whether a file is in a directory, and optionally check access.  */
  35.  
  36. boolean
  37. fsysdep_in_directory (zfile, zdir, fcheck, freadable, zuser)
  38.      const char *zfile;
  39.      const char *zdir;
  40.      boolean fcheck;
  41.      boolean freadable;
  42.      const char *zuser;
  43. {
  44.   size_t c;
  45.   char *zcopy, *zslash;
  46.   struct stat s;
  47.  
  48.   if (*zfile != '/')
  49.     return FALSE;
  50.   c = strlen (zdir);
  51.   if (c > 0 && zdir[c - 1] == '/')
  52.     c--;
  53.   if (strncmp (zfile, zdir, c) != 0
  54.       || (zfile[c] != '/' && zfile[c] != '\0'))
  55.     return FALSE;
  56.   if (strstr (zfile + c, "/../") != NULL)
  57.     return FALSE;
  58.  
  59.   /* If we're not checking access, get out now.  */
  60.   if (! fcheck)
  61.     return TRUE;
  62.  
  63.   zcopy = zbufcpy (zfile);
  64.  
  65.   /* Start checking directories after zdir.  Otherwise, we would
  66.      require that all directories down to /usr/spool/uucppublic be
  67.      publically searchable; they probably are but it should not be a
  68.      requirement.  */
  69.   zslash = zcopy + c;
  70.   do
  71.     {
  72.       char b;
  73.       struct stat shold;
  74.  
  75.       b = *zslash;
  76.       *zslash = '\0';
  77.  
  78.       shold = s;
  79.       if (stat (zcopy, &s) != 0)
  80.     {
  81.       if (errno != ENOENT)
  82.         {
  83.           ulog (LOG_ERROR, "stat (%s): %s", zcopy, strerror (errno));
  84.           ubuffree (zcopy);
  85.           return FALSE;
  86.         }
  87.  
  88.       /* If this is the top directory, any problems will be caught
  89.          later when we try to open it.  */
  90.       if (zslash == zcopy + c)
  91.         {
  92.           ubuffree (zcopy);
  93.           return TRUE;
  94.         }
  95.  
  96.       /* Go back and check the last directory for read or write
  97.          access.  */
  98.       s = shold;
  99.       break;
  100.     }
  101.  
  102.       /* If this is not a directory, get out of the loop.  */
  103.       if (! S_ISDIR (s.st_mode))
  104.     break;
  105.  
  106.       /* Make sure the directory is searchable.  */
  107.       if (! fsuser_access (&s, X_OK, zuser))
  108.     {
  109.       ulog (LOG_ERROR, "%s: %s", zcopy, strerror (EACCES));
  110.       ubuffree (zcopy);
  111.       return FALSE;
  112.     }
  113.  
  114.       /* If we've reached the end of the string, get out.  */
  115.       if (b == '\0')
  116.     break;
  117.  
  118.       *zslash = b;
  119.     }
  120.   while ((zslash = strchr (zslash + 1, '/')) != NULL);
  121.  
  122.   /* At this point s holds a stat on the last component of the path.
  123.      We must check it for readability or writeability.  */
  124.   if (! fsuser_access (&s, freadable ? R_OK : W_OK, zuser))
  125.     {
  126.       ulog (LOG_ERROR, "%s: %s", zcopy, strerror (EACCES));
  127.       ubuffree (zcopy);
  128.       return FALSE;
  129.     }
  130.  
  131.   ubuffree (zcopy);
  132.   return TRUE;
  133. }
  134.