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 / idcache.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-10-12  |  5.4 KB  |  218 lines

  1. /* idcache.c -- map user and group IDs, cached for speed
  2.    Copyright (C) 1985, 1988, 1989, 1990 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. #ifdef HAVE_CONFIG_H
  19. #if defined (CONFIG_BROKETS)
  20. /* We use <config.h> instead of "config.h" so that a compilation
  21.    using -I. -I$srcdir will use ./config.h rather than $srcdir/config.h
  22.    (which it would do because it found this file in $srcdir).  */
  23. #include <config.h>
  24. #else
  25. #include "config.h"
  26. #endif
  27. #endif
  28.  
  29. #include <stdio.h>
  30. #include <sys/types.h>
  31. #include <pwd.h>
  32. #include <grp.h>
  33.  
  34. #if defined(STDC_HEADERS) || defined(HAVE_STRING_H)
  35. #include <string.h>
  36. #else
  37. #include <strings.h>
  38. #endif
  39.  
  40. #ifdef HAVE_UNISTD_H
  41. #include <unistd.h>
  42. #endif
  43. #ifndef _POSIX_VERSION
  44. struct passwd *getpwuid ();
  45. struct passwd *getpwnam ();
  46. struct group *getgrgid ();
  47. struct group *getgrnam ();
  48. #endif
  49.  
  50. char *xmalloc ();
  51. char *xstrdup ();
  52.  
  53. struct userid
  54. {
  55.   union
  56.     {
  57.       uid_t u;
  58.       gid_t g;
  59.     } id;
  60.   char *name;
  61.   struct userid *next;
  62. };
  63.  
  64. static struct userid *user_alist;
  65.  
  66. /* The members of this list have names not in the local passwd file.  */
  67. static struct userid *nouser_alist;
  68.  
  69. /* Translate UID to a login name or a stringified number,
  70.    with cache.  */
  71.  
  72. char *
  73. getuser (uid)
  74.      uid_t uid;
  75. {
  76.   register struct userid *tail;
  77.   struct passwd *pwent;
  78.   char usernum_string[20];
  79.  
  80.   for (tail = user_alist; tail; tail = tail->next)
  81.     if (tail->id.u == uid)
  82.       return tail->name;
  83.  
  84.   pwent = getpwuid (uid);
  85.   tail = (struct userid *) xmalloc (sizeof (struct userid));
  86.   tail->id.u = uid;
  87.   if (pwent == 0)
  88.     {
  89.       sprintf (usernum_string, "%u", (unsigned) uid);
  90.       tail->name = xstrdup (usernum_string);
  91.     }
  92.   else
  93.     tail->name = xstrdup (pwent->pw_name);
  94.  
  95.   /* Add to the head of the list, so most recently used is first.  */
  96.   tail->next = user_alist;
  97.   user_alist = tail;
  98.   return tail->name;
  99. }
  100.  
  101. /* Translate USER to a UID, with cache.
  102.    Return NULL if there is no such user.
  103.    (We also cache which user names have no passwd entry,
  104.    so we don't keep looking them up.)  */
  105.  
  106. uid_t *
  107. getuidbyname (user)
  108.      char *user;
  109. {
  110.   register struct userid *tail;
  111.   struct passwd *pwent;
  112.  
  113.   for (tail = user_alist; tail; tail = tail->next)
  114.     /* Avoid a function call for the most common case.  */
  115.     if (*tail->name == *user && !strcmp (tail->name, user))
  116.       return &tail->id.u;
  117.  
  118.   for (tail = nouser_alist; tail; tail = tail->next)
  119.     /* Avoid a function call for the most common case.  */
  120.     if (*tail->name == *user && !strcmp (tail->name, user))
  121.       return 0;
  122.  
  123.   pwent = getpwnam (user);
  124.  
  125.   tail = (struct userid *) xmalloc (sizeof (struct userid));
  126.   tail->name = xstrdup (user);
  127.  
  128.   /* Add to the head of the list, so most recently used is first.  */
  129.   if (pwent)
  130.     {
  131.       tail->id.u = pwent->pw_uid;
  132.       tail->next = user_alist;
  133.       user_alist = tail;
  134.       return &tail->id.u;
  135.     }
  136.  
  137.   tail->next = nouser_alist;
  138.   nouser_alist = tail;
  139.   return 0;
  140. }
  141.  
  142. /* Use the same struct as for userids.  */
  143. static struct userid *group_alist;
  144. static struct userid *nogroup_alist;
  145.  
  146. /* Translate GID to a group name or a stringified number,
  147.    with cache.  */
  148.  
  149. char *
  150. getgroup (gid)
  151.      gid_t gid;
  152. {
  153.   register struct userid *tail;
  154.   struct group *grent;
  155.   char groupnum_string[20];
  156.  
  157.   for (tail = group_alist; tail; tail = tail->next)
  158.     if (tail->id.g == gid)
  159.       return tail->name;
  160.  
  161.   grent = getgrgid (gid);
  162.   tail = (struct userid *) xmalloc (sizeof (struct userid));
  163.   tail->id.g = gid;
  164.   if (grent == 0)
  165.     {
  166.       sprintf (groupnum_string, "%u", (unsigned int) gid);
  167.       tail->name = xstrdup (groupnum_string);
  168.     }
  169.   else
  170.     tail->name = xstrdup (grent->gr_name);
  171.  
  172.   /* Add to the head of the list, so most recently used is first.  */
  173.   tail->next = group_alist;
  174.   group_alist = tail;
  175.   return tail->name;
  176. }
  177.  
  178. /* Translate GROUP to a UID, with cache.
  179.    Return NULL if there is no such group.
  180.    (We also cache which group names have no group entry,
  181.    so we don't keep looking them up.)  */
  182.  
  183. gid_t *
  184. getgidbyname (group)
  185.      char *group;
  186. {
  187.   register struct userid *tail;
  188.   struct group *grent;
  189.  
  190.   for (tail = group_alist; tail; tail = tail->next)
  191.     /* Avoid a function call for the most common case.  */
  192.     if (*tail->name == *group && !strcmp (tail->name, group))
  193.       return &tail->id.g;
  194.  
  195.   for (tail = nogroup_alist; tail; tail = tail->next)
  196.     /* Avoid a function call for the most common case.  */
  197.     if (*tail->name == *group && !strcmp (tail->name, group))
  198.       return 0;
  199.  
  200.   grent = getgrnam (group);
  201.  
  202.   tail = (struct userid *) xmalloc (sizeof (struct userid));
  203.   tail->name = xstrdup (group);
  204.  
  205.   /* Add to the head of the list, so most recently used is first.  */
  206.   if (grent)
  207.     {
  208.       tail->id.g = grent->gr_gid;
  209.       tail->next = group_alist;
  210.       group_alist = tail;
  211.       return &tail->id.g;
  212.     }
  213.  
  214.   tail->next = nogroup_alist;
  215.   nogroup_alist = tail;
  216.   return 0;
  217. }
  218.