Back to index

glibc  2.9
getXXent_r.c
Go to the documentation of this file.
00001 /* Copyright (C) 1996-2000,2002,2004,2007 Free Software Foundation, Inc.
00002    This file is part of the GNU C Library.
00003    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
00004 
00005    The GNU C Library is free software; you can redistribute it and/or
00006    modify it under the terms of the GNU Lesser General Public
00007    License as published by the Free Software Foundation; either
00008    version 2.1 of the License, or (at your option) any later version.
00009 
00010    The GNU C Library is distributed in the hope that it will be useful,
00011    but WITHOUT ANY WARRANTY; without even the implied warranty of
00012    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013    Lesser General Public License for more details.
00014 
00015    You should have received a copy of the GNU Lesser General Public
00016    License along with the GNU C Library; if not, write to the Free
00017    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
00018    02111-1307 USA.  */
00019 
00020 #include <errno.h>
00021 #include <bits/libc-lock.h>
00022 
00023 #include "nsswitch.h"
00024 
00025 /*******************************************************************\
00026 |* Here we assume several symbols to be defined:           *|
00027 |*                                                         *|
00028 |* LOOKUP_TYPE   - the return type of the function                *|
00029 |*                                                         *|
00030 |* SETFUNC_NAME  - name of the non-reentrant setXXXent function          *|
00031 |*                                                         *|
00032 |* GETFUNC_NAME  - name of the non-reentrant getXXXent function          *|
00033 |*                                                         *|
00034 |* ENDFUNC_NAME  - name of the non-reentrant endXXXent function          *|
00035 |*                                                         *|
00036 |* DATABASE_NAME - name of the database the function accesses     *|
00037 |*               (e.g., host, services, ...)                      *|
00038 |*                                                         *|
00039 |* Optionally the following vars can be defined:           *|
00040 |*                                                         *|
00041 |* STAYOPEN      - variable declaration for setXXXent function    *|
00042 |*                                                         *|
00043 |* STAYOPEN_VAR  - variable name for setXXXent function           *|
00044 |*                                                         *|
00045 |* NEED_H_ERRNO  - an extra parameter will be passed to point to   *|
00046 |*               the global `h_errno' variable.            *|
00047 |*                                                         *|
00048 \*******************************************************************/
00049 
00050 /* To make the real sources a bit prettier.  */
00051 #define REENTRANT_GETNAME APPEND_R (GETFUNC_NAME)
00052 #define APPEND_R(Name) CONCAT2_2 (Name, _r)
00053 #define INTERNAL(Name) CONCAT2_2 (__, Name)
00054 #define CONCAT2_1(Pre, Post) CONCAT2_2 (Pre, Post)
00055 #define CONCAT2_2(Pre, Post) Pre##Post
00056 #define NEW(name) NEW1 (name)
00057 #define NEW1(name) __new_##name
00058 
00059 #define SETFUNC_NAME_STRING STRINGIZE (SETFUNC_NAME)
00060 #define GETFUNC_NAME_STRING STRINGIZE (REENTRANT_GETNAME)
00061 #define ENDFUNC_NAME_STRING STRINGIZE (ENDFUNC_NAME)
00062 #define DATABASE_NAME_STRING STRINGIZE (DATABASE_NAME)
00063 #define STRINGIZE(Name) STRINGIZE1 (Name)
00064 #define STRINGIZE1(Name) #Name
00065 
00066 #ifndef DB_LOOKUP_FCT
00067 # define DB_LOOKUP_FCT CONCAT3_1 (__nss_, DATABASE_NAME, _lookup2)
00068 # define CONCAT3_1(Pre, Name, Post) CONCAT3_2 (Pre, Name, Post)
00069 # define CONCAT3_2(Pre, Name, Post) Pre##Name##Post
00070 #endif
00071 
00072 /* Sometimes we need to store error codes in the `h_errno' variable.  */
00073 #ifdef NEED_H_ERRNO
00074 # define H_ERRNO_PARM , int *h_errnop
00075 # define H_ERRNO_VAR , &h_errno
00076 # define H_ERRNO_VAR_P &h_errno
00077 #else
00078 # define H_ERRNO_PARM
00079 # define H_ERRNO_VAR
00080 # define H_ERRNO_VAR_P NULL
00081 #endif
00082 
00083 /* Some databases take the `stayopen' flag.  */
00084 #ifdef STAYOPEN
00085 # define STAYOPEN_TMP CONCAT2_1 (STAYOPEN, _tmp)
00086 # define STAYOPEN_TMPVAR &CONCAT2_1 (STAYOPEN_VAR, _tmp)
00087 #else
00088 # define STAYOPEN void
00089 # define STAYOPEN_VAR 0
00090 # define STAYOPEN_TMPVAR NULL
00091 #endif
00092 
00093 #ifndef NEED__RES
00094 # define NEED__RES 0
00095 #endif
00096 
00097 /* This handle for the NSS data base is shared between all
00098    set/get/endXXXent functions.  */
00099 static service_user *nip;
00100 /* Remember the last service used since the last call to  `endXXent'.  */
00101 static service_user *last_nip;
00102 /* Remember the first service_entry, it's always the same.  */
00103 static service_user *startp;
00104 
00105 #ifdef STAYOPEN_TMP
00106 /* We need to remember the last `stayopen' flag given by the user
00107    since the `setent' function is only called for the first available
00108    service.  */
00109 static STAYOPEN_TMP;
00110 #endif
00111 
00112 /* Protect above variable against multiple uses at the same time.  */
00113 __libc_lock_define_initialized (static, lock)
00114 
00115 /* The lookup function for the first entry of this service.  */
00116 extern int DB_LOOKUP_FCT (service_user **nip, const char *name,
00117                        const char *name2, void **fctp)
00118      internal_function;
00119 libc_hidden_proto (DB_LOOKUP_FCT)
00120 
00121 void
00122 SETFUNC_NAME (STAYOPEN)
00123 {
00124   int save;
00125 
00126   __libc_lock_lock (lock);
00127   __nss_setent (SETFUNC_NAME_STRING, DB_LOOKUP_FCT, &nip, &startp,
00128               &last_nip, STAYOPEN_VAR, STAYOPEN_TMPVAR, NEED__RES);
00129 
00130   save = errno;
00131   __libc_lock_unlock (lock);
00132   __set_errno (save);
00133 }
00134 
00135 
00136 void
00137 ENDFUNC_NAME (void)
00138 {
00139   int save;
00140 
00141   /* If the service has not been used before do not do anything.  */
00142   if (startp != NULL)
00143     {
00144       __libc_lock_lock (lock);
00145       __nss_endent (ENDFUNC_NAME_STRING, DB_LOOKUP_FCT, &nip, &startp,
00146                   &last_nip, NEED__RES);
00147       save = errno;
00148       __libc_lock_unlock (lock);
00149       __set_errno (save);
00150     }
00151 }
00152 
00153 
00154 int
00155 INTERNAL (REENTRANT_GETNAME) (LOOKUP_TYPE *resbuf, char *buffer, size_t buflen,
00156                            LOOKUP_TYPE **result H_ERRNO_PARM)
00157 {
00158   int status;
00159   int save;
00160 
00161   __libc_lock_lock (lock);
00162   status = __nss_getent_r (GETFUNC_NAME_STRING, SETFUNC_NAME_STRING,
00163                         DB_LOOKUP_FCT, &nip, &startp, &last_nip,
00164                         STAYOPEN_TMPVAR, NEED__RES, resbuf, buffer,
00165                         buflen, (void **) result, H_ERRNO_VAR_P);
00166   save = errno;
00167   __libc_lock_unlock (lock);
00168   __set_errno (save);
00169   return status;
00170 }
00171 
00172 
00173 #include <shlib-compat.h>
00174 #if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_1_2)
00175 #define OLD(name) OLD1 (name)
00176 #define OLD1(name) __old_##name
00177 
00178 int
00179 attribute_compat_text_section
00180 OLD (REENTRANT_GETNAME) (LOOKUP_TYPE *resbuf, char *buffer, size_t buflen,
00181                       LOOKUP_TYPE **result H_ERRNO_PARM)
00182 {
00183   int ret = INTERNAL (REENTRANT_GETNAME) (resbuf, buffer, buflen,
00184                                      result H_ERRNO_VAR);
00185 
00186   if (ret != 0)
00187     ret = -1;
00188 
00189   return ret;
00190 }
00191 
00192 #define do_symbol_version(real, name, version) \
00193   compat_symbol (libc, real, name, version)
00194 do_symbol_version (OLD (REENTRANT_GETNAME), REENTRANT_GETNAME, GLIBC_2_0);
00195 #endif
00196 
00197 /* As INTERNAL (REENTRANT_GETNAME) may be hidden, we need an alias
00198    in between so that the REENTRANT_GETNAME@@GLIBC_2.1.2 is not
00199    hidden too.  */
00200 strong_alias (INTERNAL (REENTRANT_GETNAME), NEW (REENTRANT_GETNAME));
00201 
00202 #define do_default_symbol_version(real, name, version) \
00203   versioned_symbol (libc, real, name, version)
00204 do_default_symbol_version (NEW (REENTRANT_GETNAME),
00205                         REENTRANT_GETNAME, GLIBC_2_1_2);
00206 
00207 static_link_warning (SETFUNC_NAME)
00208 static_link_warning (ENDFUNC_NAME)
00209 static_link_warning (REENTRANT_GETNAME)