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