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