(linenum→info "unix/slp.c:2238")

glibc/2.7/grp/compat-initgroups.c

    1: /* Prototype for the setgrent functions we use here.  */
    2: typedef enum nss_status (*set_function) (void);
    3: 
    4: /* Prototype for the endgrent functions we use here.  */
    5: typedef enum nss_status (*end_function) (void);
    6: 
    7: /* Prototype for the setgrent functions we use here.  */
    8: typedef enum nss_status (*get_function) (struct group *, char *,
    9:                                          size_t, int *);
   10: 
   11: static enum nss_status
   12: compat_call (service_user *nip, const char *user, gid_t group, long int *start,
   13:              long int *size, gid_t **groupsp, long int limit, int *errnop)
   14: {
   15:   struct group grpbuf;
   16:   size_t buflen = __sysconf (_SC_GETGR_R_SIZE_MAX);
   17:   char *tmpbuf;
   18:   enum nss_status status;
   19:   set_function setgrent_fct;
   20:   get_function getgrent_fct;
   21:   end_function endgrent_fct;
   22:   gid_t *groups = *groupsp;
   23: 
   24:   getgrent_fct = __nss_lookup_function (nip, "getgrent_r");
   25:   if (getgrent_fct == NULL)
   26:     return NSS_STATUS_UNAVAIL;
   27: 
   28:   setgrent_fct = __nss_lookup_function (nip, "setgrent");
   29:   if (setgrent_fct)
   30:     {
   31:       status = DL_CALL_FCT (setgrent_fct, ());
   32:       if (status != NSS_STATUS_SUCCESS)
   33:         return status;
   34:     }
   35: 
   36:   endgrent_fct = __nss_lookup_function (nip, "endgrent");
   37: 
   38:   tmpbuf = __alloca (buflen);
   39: 
   40:   do
   41:     {
   42:       while ((status = DL_CALL_FCT (getgrent_fct,
   43:                                      (&grpbuf, tmpbuf, buflen, errnop)),
   44:               status == NSS_STATUS_TRYAGAIN)
   45:              && *errnop == ERANGE)
   46:         {
   47:           buflen *= 2;
   48:           tmpbuf = __alloca (buflen);
   49:         }
   50: 
   51:       if (status != NSS_STATUS_SUCCESS)
   52:         goto done;
   53: 
   54:       if (grpbuf.gr_gid != group)
   55:         {
   56:           char **m;
   57: 
   58:           for (m = grpbuf.gr_mem; *m != NULL; ++m)
   59:             if (strcmp (*m, user) == 0)
   60:               {
   61:                 /* Check whether the group is already on the list.  */
   62:                 long int cnt;
   63:                 for (cnt = 0; cnt < *start; ++cnt)
   64:                   if (groups[cnt] == grpbuf.gr_gid)
   65:                     break;
   66: 
   67:                 if (cnt == *start)
   68:                   {
   69:                     /* Matches user and not yet on the list.  Insert
   70:                        this group.  */
   71:                     if (__builtin_expect (*start == *size, 0))
   72:                       {
   73:                         /* Need a bigger buffer.  */
   74:                         gid_t *newgroups;
   75:                         long int newsize;
   76: 
   77:                         if (limit > 0 && *size == limit)
   78:                           /* We reached the maximum.  */
   79:                           goto done;
   80: 
   81:                         if (limit <= 0)
   82:                           newsize = 2 * *size;
   83:                         else
   84:                           newsize = MIN (limit, 2 * *size);
   85: 
   86:                         newgroups = realloc (groups,
   87:                                              newsize * sizeof (*groups));
   88:                         if (newgroups == NULL)
   89:                           goto done;
   90:                         *groupsp = groups = newgroups;
   91:                         *size = newsize;
   92:                       }
   93: 
   94:                     groups[*start] = grpbuf.gr_gid;
   95:                     *start += 1;
   96:                   }
   97: 
   98:                 break;
   99:               }
  100:         }
  101:     }
  102:   while (status == NSS_STATUS_SUCCESS);
  103: 
  104:  done:
  105:   if (endgrent_fct)
  106:     DL_CALL_FCT (endgrent_fct, ());
  107: 
  108:   return NSS_STATUS_SUCCESS;
  109: }
Syntax (Markdown)