getXXent_r.c 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211
  1. /* Copyright (C) 1996-2019 Free Software Foundation, Inc.
  2. This file is part of the GNU C Library.
  3. Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
  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. The GNU C Library is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  11. Lesser General Public License for more details.
  12. You should have received a copy of the GNU Lesser General Public
  13. License along with the GNU C Library; if not, see
  14. <http://www.gnu.org/licenses/>. */
  15. #include <errno.h>
  16. #include <libc-lock.h>
  17. #include "nsswitch.h"
  18. /*******************************************************************\
  19. |* Here we assume several symbols to be defined: *|
  20. |* *|
  21. |* LOOKUP_TYPE - the return type of the function *|
  22. |* *|
  23. |* SETFUNC_NAME - name of the non-reentrant setXXXent function *|
  24. |* *|
  25. |* GETFUNC_NAME - name of the non-reentrant getXXXent function *|
  26. |* *|
  27. |* ENDFUNC_NAME - name of the non-reentrant endXXXent function *|
  28. |* *|
  29. |* DATABASE_NAME - name of the database the function accesses *|
  30. |* (e.g., host, services, ...) *|
  31. |* *|
  32. |* Optionally the following vars can be defined: *|
  33. |* *|
  34. |* STAYOPEN - variable declaration for setXXXent function *|
  35. |* *|
  36. |* STAYOPEN_VAR - variable name for setXXXent function *|
  37. |* *|
  38. |* NEED_H_ERRNO - an extra parameter will be passed to point to *|
  39. |* the global `h_errno' variable. *|
  40. |* *|
  41. \*******************************************************************/
  42. /* To make the real sources a bit prettier. */
  43. #define REENTRANT_GETNAME APPEND_R (GETFUNC_NAME)
  44. #define APPEND_R(Name) CONCAT2_2 (Name, _r)
  45. #define INTERNAL(Name) CONCAT2_2 (__, Name)
  46. #define CONCAT2_1(Pre, Post) CONCAT2_2 (Pre, Post)
  47. #define CONCAT2_2(Pre, Post) Pre##Post
  48. #define NEW(name) NEW1 (name)
  49. #define NEW1(name) __new_##name
  50. #define SETFUNC_NAME_STRING STRINGIZE (SETFUNC_NAME)
  51. #define GETFUNC_NAME_STRING STRINGIZE (REENTRANT_GETNAME)
  52. #define ENDFUNC_NAME_STRING STRINGIZE (ENDFUNC_NAME)
  53. #define DATABASE_NAME_STRING STRINGIZE (DATABASE_NAME)
  54. #define STRINGIZE(Name) STRINGIZE1 (Name)
  55. #define STRINGIZE1(Name) #Name
  56. #ifndef DB_LOOKUP_FCT
  57. # define DB_LOOKUP_FCT CONCAT3_1 (__nss_, DATABASE_NAME, _lookup2)
  58. # define CONCAT3_1(Pre, Name, Post) CONCAT3_2 (Pre, Name, Post)
  59. # define CONCAT3_2(Pre, Name, Post) Pre##Name##Post
  60. #endif
  61. /* Sometimes we need to store error codes in the `h_errno' variable. */
  62. #ifdef NEED_H_ERRNO
  63. # define H_ERRNO_PARM , int *h_errnop
  64. # define H_ERRNO_VAR , &h_errno
  65. # define H_ERRNO_VAR_P &h_errno
  66. #else
  67. # define H_ERRNO_PARM
  68. # define H_ERRNO_VAR
  69. # define H_ERRNO_VAR_P NULL
  70. #endif
  71. /* Some databases take the `stayopen' flag. */
  72. #ifdef STAYOPEN
  73. # define STAYOPEN_TMP CONCAT2_1 (STAYOPEN, _tmp)
  74. # define STAYOPEN_TMPVAR &CONCAT2_1 (STAYOPEN_VAR, _tmp)
  75. #else
  76. # define STAYOPEN void
  77. # define STAYOPEN_VAR 0
  78. # define STAYOPEN_TMPVAR NULL
  79. #endif
  80. #ifndef NEED__RES
  81. # define NEED__RES 0
  82. #endif
  83. /* This handle for the NSS data base is shared between all
  84. set/get/endXXXent functions. */
  85. static service_user *nip;
  86. /* Remember the last service used since the last call to `endXXent'. */
  87. static service_user *last_nip;
  88. /* Remember the first service_entry, it's always the same. */
  89. static service_user *startp;
  90. #ifdef STAYOPEN_TMP
  91. /* We need to remember the last `stayopen' flag given by the user
  92. since the `setent' function is only called for the first available
  93. service. */
  94. static STAYOPEN_TMP;
  95. #endif
  96. /* Protect above variable against multiple uses at the same time. */
  97. __libc_lock_define_initialized (static, lock)
  98. /* The lookup function for the first entry of this service. */
  99. extern int DB_LOOKUP_FCT (service_user **nip, const char *name,
  100. const char *name2, void **fctp);
  101. libc_hidden_proto (DB_LOOKUP_FCT)
  102. void
  103. SETFUNC_NAME (STAYOPEN)
  104. {
  105. int save;
  106. __libc_lock_lock (lock);
  107. __nss_setent (SETFUNC_NAME_STRING, DB_LOOKUP_FCT, &nip, &startp,
  108. &last_nip, STAYOPEN_VAR, STAYOPEN_TMPVAR, NEED__RES);
  109. save = errno;
  110. __libc_lock_unlock (lock);
  111. __set_errno (save);
  112. }
  113. void
  114. ENDFUNC_NAME (void)
  115. {
  116. int save;
  117. /* If the service has not been used before do not do anything. */
  118. if (startp != NULL)
  119. {
  120. __libc_lock_lock (lock);
  121. __nss_endent (ENDFUNC_NAME_STRING, DB_LOOKUP_FCT, &nip, &startp,
  122. &last_nip, NEED__RES);
  123. save = errno;
  124. __libc_lock_unlock (lock);
  125. __set_errno (save);
  126. }
  127. }
  128. int
  129. INTERNAL (REENTRANT_GETNAME) (LOOKUP_TYPE *resbuf, char *buffer, size_t buflen,
  130. LOOKUP_TYPE **result H_ERRNO_PARM)
  131. {
  132. int status;
  133. int save;
  134. __libc_lock_lock (lock);
  135. status = __nss_getent_r (GETFUNC_NAME_STRING, SETFUNC_NAME_STRING,
  136. DB_LOOKUP_FCT, &nip, &startp, &last_nip,
  137. STAYOPEN_TMPVAR, NEED__RES, resbuf, buffer,
  138. buflen, (void **) result, H_ERRNO_VAR_P);
  139. save = errno;
  140. __libc_lock_unlock (lock);
  141. __set_errno (save);
  142. return status;
  143. }
  144. #ifdef NO_COMPAT_NEEDED
  145. strong_alias (INTERNAL (REENTRANT_GETNAME), REENTRANT_GETNAME);
  146. #else
  147. # include <shlib-compat.h>
  148. # if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_1_2)
  149. # define OLD(name) OLD1 (name)
  150. # define OLD1(name) __old_##name
  151. int
  152. attribute_compat_text_section
  153. OLD (REENTRANT_GETNAME) (LOOKUP_TYPE *resbuf, char *buffer, size_t buflen,
  154. LOOKUP_TYPE **result H_ERRNO_PARM)
  155. {
  156. int ret = INTERNAL (REENTRANT_GETNAME) (resbuf, buffer, buflen,
  157. result H_ERRNO_VAR);
  158. if (ret != 0)
  159. ret = -1;
  160. return ret;
  161. }
  162. # define do_symbol_version(real, name, version) \
  163. compat_symbol (libc, real, name, version)
  164. do_symbol_version (OLD (REENTRANT_GETNAME), REENTRANT_GETNAME, GLIBC_2_0);
  165. # endif
  166. /* As INTERNAL (REENTRANT_GETNAME) may be hidden, we need an alias
  167. in between so that the REENTRANT_GETNAME@@GLIBC_2.1.2 is not
  168. hidden too. */
  169. strong_alias (INTERNAL (REENTRANT_GETNAME), NEW (REENTRANT_GETNAME));
  170. # define do_default_symbol_version(real, name, version) \
  171. versioned_symbol (libc, real, name, version)
  172. do_default_symbol_version (NEW (REENTRANT_GETNAME),
  173. REENTRANT_GETNAME, GLIBC_2_1_2);
  174. #endif
  175. nss_interface_function (SETFUNC_NAME)
  176. nss_interface_function (ENDFUNC_NAME)
  177. nss_interface_function (REENTRANT_GETNAME)