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

glibc/2.7/nss/getnssent_r.c

    1: /* Copyright (C) 2000, 2002, 2004 Free Software Foundation, Inc.
    2:    This file is part of the GNU C Library.
    3: 
    4:    The GNU C Library is free software; you can redistribute it and/or
    5:    modify it under the terms of the GNU Lesser General Public
    6:    License as published by the Free Software Foundation; either
    7:    version 2.1 of the License, or (at your option) any later version.
    8: 
    9:    The GNU C Library 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 GNU
   12:    Lesser General Public License for more details.
   13: 
   14:    You should have received a copy of the GNU Lesser General Public
   15:    License along with the GNU C Library; if not, write to the Free
   16:    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
   17:    02111-1307 USA.  */
   18: 
   19: #include <errno.h>
   20: #include <netdb.h>
   21: #include "nsswitch.h"
   22: 
   23: /* Set up NIP to run through the services.  If ALL is zero, use NIP's
   24:    current location if it's not nil.  Return nonzero if there are no
   25:    services (left).  */
   26: static int
   27: setup (const char *func_name, db_lookup_function lookup_fct,
   28:        void **fctp, service_user **nip, service_user **startp, int all)
   29: {
   30:   int no_more;
   31:   if (*startp == NULL)
   32:     {
   33:       no_more = lookup_fct (nip, func_name, fctp);
   34:       *startp = no_more ? (service_user *) -1l : *nip;
   35:     }
   36:   else if (*startp == (service_user *) -1l)
   37:     /* No services at all.  */
   38:     return 1;
   39:   else
   40:     {
   41:       if (all || !*nip)
   42:         /* Reset to the beginning of the service list.  */
   43:         *nip = *startp;
   44:       /* Look up the first function.  */
   45:       no_more = __nss_lookup (nip, func_name, fctp);
   46:     }
   47:   return no_more;
   48: }
   49: ^L
   50: void
   51: __nss_setent (const char *func_name, db_lookup_function lookup_fct,
   52:               service_user **nip, service_user **startp,
   53:               service_user **last_nip, int stayopen, int *stayopen_tmp,
   54:               int res)
   55: {
   56:   union
   57:   {
   58:     setent_function f;
   59:     void *ptr;
   60:   } fct;
   61:   int no_more;
   62: 
   63:   if (res && __res_maybe_init (&_res, 0) == -1)
   64:     {
   65:       __set_h_errno (NETDB_INTERNAL);
   66:       return;
   67:     }
   68: 
   69:   /* Cycle through the services and run their `setXXent' functions until
   70:      we find an available service.  */
   71:   no_more = setup (func_name, lookup_fct, &fct.ptr, nip,
   72:                    startp, 1);
   73:   while (! no_more)
   74:     {
   75:       int is_last_nip = *nip == *last_nip;
   76:       enum nss_status status;
   77: 
   78:       if (stayopen_tmp)
   79:         status = DL_CALL_FCT (fct.f, (*stayopen_tmp));
   80:       else
   81:         status = DL_CALL_FCT (fct.f, (0));
   82: 
   83:       no_more = __nss_next (nip, func_name, &fct.ptr,
   84:                             status, 0);
   85:       if (is_last_nip)
   86:         *last_nip = *nip;
   87:     }
   88: 
   89:   if (stayopen_tmp)
   90:     *stayopen_tmp = stayopen;
   91: }
   92: 
   93: 
   94: void
   95: __nss_endent (const char *func_name, db_lookup_function lookup_fct,
   96:               service_user **nip, service_user **startp,
   97:               service_user **last_nip, int res)
   98: {
   99:   union
  100:   {
  101:     endent_function f;
  102:     void *ptr;
  103:   } fct;
  104:   int no_more;
  105: 
  106:   if (res && __res_maybe_init (&_res, 0) == -1)
  107:     {
  108:       __set_h_errno (NETDB_INTERNAL);
  109:       return;
  110:     }
  111: 
  112:   /* Cycle through all the services and run their endXXent functions.  */
  113:   no_more = setup (func_name, lookup_fct, &fct.ptr, nip, startp, 1);
  114:   while (! no_more)
  115:     {
  116:       /* Ignore status, we force check in __NSS_NEXT.  */
  117:       DL_CALL_FCT (fct.f, ());
  118: 
  119:       if (*nip == *last_nip)
  120:         /* We have processed all services which were used.  */
  121:         break;
  122: 
  123:       no_more = __nss_next (nip, func_name, &fct.ptr, 0, 1);
  124:     }
  125:   *last_nip = *nip = NULL;
  126: }
  127: 
  128: 
  129: int
  130: __nss_getent_r (const char *getent_func_name,
  131:                 const char *setent_func_name,
  132:                 db_lookup_function lookup_fct,
  133:                 service_user **nip, service_user **startp,
  134:                 service_user **last_nip, int *stayopen_tmp, int res,
  135:                 void *resbuf, char *buffer, size_t buflen,
  136:                 void **result, int *h_errnop)
  137: {
  138:   union
  139:   {
  140:     getent_function f;
  141:     void *ptr;
  142:   } fct;
  143:   int no_more;
  144:   enum nss_status status;
  145: 
  146:   if (res && __res_maybe_init (&_res, 0) == -1)
  147:     {
  148:       *h_errnop = NETDB_INTERNAL;
  149:       *result = NULL;
  150:       return errno;
  151:     }
  152: 
  153:   /* Initialize status to return if no more functions are found.  */
  154:   status = NSS_STATUS_NOTFOUND;
  155: 
  156:   /* Run through available functions, starting with the same function last
  157:      run.  We will repeat each function as long as it succeeds, and then go
  158:      on to the next service action.  */
  159:   no_more = setup (getent_func_name, lookup_fct, &fct.ptr, nip,
  160:                    startp, 0);
  161:   while (! no_more)
  162:     {
  163:       int is_last_nip = *nip == *last_nip;
  164: 
  165:       status = DL_CALL_FCT (fct.f,
  166:                             (resbuf, buffer, buflen, &errno, &h_errno));
  167: 
  168:       /* The the status is NSS_STATUS_TRYAGAIN and errno is ERANGE the
  169:          provided buffer is too small.  In this case we should give
  170:          the user the possibility to enlarge the buffer and we should
  171:          not simply go on with the next service (even if the TRYAGAIN
  172:          action tells us so).  */
  173:       if (status == NSS_STATUS_TRYAGAIN
  174:           && (h_errnop == NULL || *h_errnop == NETDB_INTERNAL)
  175:           && errno == ERANGE)
  176:         break;
  177: 
  178:       do
  179:         {
  180:           no_more = __nss_next (nip, getent_func_name, &fct.ptr,
  181:                                 status, 0);
  182: 
  183:           if (is_last_nip)
  184:             *last_nip = *nip;
  185: 
  186:           if (! no_more)
  187:             {
  188:               /* Call the `setXXent' function.  This wasn't done before.  */
  189:               union
  190:               {
  191:                 setent_function f;
  192:                 void *ptr;
  193:               } sfct;
  194: 
  195:               no_more = __nss_lookup (nip, setent_func_name,
  196:                                       &sfct.ptr);
  197: 
  198:               if (! no_more)
  199:                 {
  200:                   if (stayopen_tmp)
  201:                     status = DL_CALL_FCT (sfct.f, (*stayopen_tmp));
  202:                   else
  203:                     status = DL_CALL_FCT (sfct.f, (0));
  204:                 }
  205:               else
  206:                 status = NSS_STATUS_NOTFOUND;
  207:             }
  208:         }
  209:       while (! no_more && status != NSS_STATUS_SUCCESS);
  210:     }
  211: 
  212:   *result = status == NSS_STATUS_SUCCESS ? resbuf : NULL;
  213:   return (status == NSS_STATUS_SUCCESS ? 0
  214:           : status != NSS_STATUS_TRYAGAIN ? ENOENT
  215:           /* h_errno functions only set errno if h_errno is NETDB_INTERNAL.  */
  216:           : (h_errnop == NULL || *h_errnop == NETDB_INTERNAL) ? errno
  217:           : EAGAIN);
  218: }
Syntax (Markdown)