1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19: #include <errno.h>
20: #include <netdb.h>
21: #include "nsswitch.h"
22:
23:
24:
25:
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:
38: return 1;
39: else
40: {
41: if (all || !*nip)
42:
43: *nip = *startp;
44:
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:
70:
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:
113: no_more = setup (func_name, lookup_fct, &fct.ptr, nip, startp, 1);
114: while (! no_more)
115: {
116:
117: DL_CALL_FCT (fct.f, ());
118:
119: if (*nip == *last_nip)
120:
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:
154: status = NSS_STATUS_NOTFOUND;
155:
156:
157:
158:
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:
169:
170:
171:
172:
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:
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:
216: : (h_errnop == NULL || *h_errnop == NETDB_INTERNAL) ? errno
217: : EAGAIN);
218: }