getXXent_r.c 6.4 KB

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