home *** CD-ROM | disk | FTP | other *** search
/ Fresh Fish 4 / FreshFish_May-June1994.bin / bbs / gnu / fileutils-3.9-src.lha / src / amiga / fileutils-3.9 / lib / eaccess.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-10-12  |  4.2 KB  |  179 lines

  1. /* eaccess -- check if effective user id can access file
  2.    Copyright (C) 1990, 1991 Free Software Foundation, Inc.
  3.  
  4.    This program is free software; you can redistribute it and/or modify
  5.    it under the terms of the GNU General Public License as published by
  6.    the Free Software Foundation; either version 2, or (at your option)
  7.    any later version.
  8.  
  9.    This program is distributed in the hope that it will be useful,
  10.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  11.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12.    GNU General Public License for more details.
  13.  
  14.    You should have received a copy of the GNU General Public License
  15.    along with this program; if not, write to the Free Software
  16.    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
  17.  
  18. /* Written by David MacKenzie and Torbjorn Granlund. */
  19.  
  20. #ifdef HAVE_CONFIG_H
  21. #if defined (CONFIG_BROKETS)
  22. /* We use <config.h> instead of "config.h" so that a compilation
  23.    using -I. -I$srcdir will use ./config.h rather than $srcdir/config.h
  24.    (which it would do because it found this file in $srcdir).  */
  25. #include <config.h>
  26. #else
  27. #include "config.h"
  28. #endif
  29. #endif
  30.  
  31. #include <sys/types.h>
  32. #include <sys/stat.h>
  33.  
  34. #ifdef HAVE_UNISTD_H
  35. #include <unistd.h>
  36. #endif
  37.  
  38. #ifdef _POSIX_VERSION
  39. #include <limits.h>
  40. #if !defined(NGROUPS_MAX) || NGROUPS_MAX < 1
  41. #undef NGROUPS_MAX
  42. #define NGROUPS_MAX sysconf (_SC_NGROUPS_MAX)
  43. #endif /* NGROUPS_MAX */
  44.  
  45. #else /* not _POSIX_VERSION */
  46. uid_t geteuid ();
  47. gid_t getegid ();
  48. #include <sys/param.h>
  49. #if !defined(NGROUPS_MAX) && defined(NGROUPS)
  50. #define NGROUPS_MAX NGROUPS
  51. #endif /* not NGROUPS_MAX and NGROUPS */
  52. #endif /* not POSIX_VERSION */
  53.  
  54. #include <errno.h>
  55. #ifndef STDC_HEADERS
  56. extern int errno;
  57. #endif
  58.  
  59. #if defined(EACCES) && !defined(EACCESS)
  60. #define EACCESS EACCES
  61. #endif
  62.  
  63. #ifndef F_OK
  64. #define F_OK 0
  65. #define X_OK 1
  66. #define W_OK 2
  67. #define R_OK 4
  68. #endif
  69.  
  70. int eaccess_stat ();
  71.  
  72. /* The user's effective user id. */
  73. static uid_t euid;
  74.  
  75. /* The user's effective group id. */
  76. static gid_t egid;
  77.  
  78. #ifdef NGROUPS_MAX
  79. char *xmalloc ();
  80. static int in_group ();
  81.  
  82. /* Array of group id's that the user is in. */
  83. static GETGROUPS_T *groups = 0;
  84.  
  85. /* The number of valid elements in `groups'. */
  86. static int ngroups;
  87. #endif
  88.  
  89. /* Nonzero if the other static variables have valid values. */
  90. static int initialized = 0;
  91.  
  92. /* Return 0 if the user has permission of type MODE on file PATH;
  93.    otherwise, return -1 and set `errno' to EACCESS.
  94.    Like access, except that it uses the effective user and group
  95.    id's instead of the real ones, and it does not check for read-only
  96.    filesystem, text busy, etc. */
  97.  
  98. int
  99. eaccess (path, mode)
  100.      char *path;
  101.      int mode;
  102. {
  103.   struct stat stats;
  104.  
  105.   if (stat (path, &stats))
  106.     return -1;
  107.  
  108.   return eaccess_stat (&stats, mode);
  109. }
  110.  
  111. /* Like eaccess, except that a pointer to a filled-in stat structure
  112.    describing the file is provided instead of a filename. */
  113.  
  114. int
  115. eaccess_stat (statp, mode)
  116.      struct stat *statp;
  117.      int mode;
  118. {
  119.   int granted;
  120.  
  121.   mode &= (X_OK | W_OK | R_OK);    /* Clear any bogus bits. */
  122.  
  123.   if (mode == F_OK)
  124.     return 0;            /* The file exists. */
  125.  
  126.   if (initialized == 0)
  127.     {
  128.       initialized = 1;
  129.       euid = geteuid ();
  130.       egid = getegid ();
  131. #ifdef NGROUPS_MAX
  132.       groups = (GETGROUPS_T *)
  133.         xmalloc ((unsigned) NGROUPS_MAX * sizeof (GETGROUPS_T));
  134.       ngroups = getgroups ((int) NGROUPS_MAX, groups);
  135. #endif
  136.     }
  137.  
  138.   /* The super-user can read and write any file, and execute any file
  139.      that anyone can execute. */
  140.   if (euid == 0 && ((mode & X_OK) == 0 || (statp->st_mode & 0111)))
  141.     return 0;
  142.   if (euid == statp->st_uid)
  143.     granted = (unsigned) (statp->st_mode & (mode << 6)) >> 6;
  144.   else if (egid == statp->st_gid
  145. #ifdef NGROUPS_MAX
  146.        || in_group (statp->st_gid)
  147. #endif
  148.        )
  149.     granted = (unsigned) (statp->st_mode & (mode << 3)) >> 3;
  150.   else
  151.     granted = (statp->st_mode & mode);
  152.   if (granted == mode)
  153.     return 0;
  154.   errno = EACCESS;
  155.   return -1;
  156. }
  157.  
  158. #ifdef NGROUPS_MAX
  159. static int
  160. in_group (gid)
  161.      GETGROUPS_T gid;
  162. {
  163.   int i;
  164.  
  165.   for (i = 0; i < ngroups; i++)
  166.     if (gid == groups[i])
  167.       return 1;
  168.   return 0;
  169. }
  170. #endif
  171.  
  172. #ifdef TEST
  173. main (argc, argv)
  174.      char **argv;
  175. {
  176.   printf ("%d\n", eaccess (argv[1], atoi (argv[2])));
  177. }
  178. #endif
  179.