source: branches/fc20-dev/server/common/oursrc/nss_nonlocal/walk_nss.h @ 2523

Last change on this file since 2523 was 2434, checked in by achernya, 11 years ago
Merge r2402-r2433 from trunk to branches/fc19-dev
File size: 2.3 KB
Line 
1/*
2 * walk_nss.h
3 * NSS walking template for nss_nonlocal proxy
4 *
5 * Copyright © 2011 Anders Kaseorg <andersk@mit.edu> and Tim Abbott
6 * <tabbott@mit.edu>
7 *
8 * This file is part of nss_nonlocal.
9 *
10 * nss_nonlocal is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU Lesser General Public License
12 * as published by the Free Software Foundation; either version 2.1 of
13 * the License, or (at your option) any later version.
14 *
15 * nss_nonlocal is distributed in the hope that it will be useful, but
16 * WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18 * Lesser General Public License for more details.
19 *
20 * You should have received a copy of the GNU Lesser General Public
21 * License along with nss_nonlocal; if not, write to the Free Software
22 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
23 * 02110-1301  USA
24 */
25
26{
27    static bool initialized = false;
28    static service_user *startp;
29    static void *fct_start;
30
31    service_user *nip;
32    union {
33        __typeof__(self) l;
34        void *ptr;
35    } fct;
36    int old_errno = errno;
37
38    if (!initialized) {
39        if (w.lookup(&startp, w.fct_name, &fct_start) != 0) {
40            *w.status = NSS_STATUS_UNAVAIL;
41            goto walk_nss_out;
42        }
43        __sync_synchronize();
44        initialized = true;
45    }
46
47    nip = startp;
48    fct.ptr = fct_start;
49
50    if (w.buf != NULL) {
51        *w.buf = malloc(*w.buflen);
52        errno = old_errno;
53        if (*w.buf == NULL) {
54            *w.status = NSS_STATUS_TRYAGAIN;
55            *w.errnop = ENOMEM;
56            goto walk_nss_out;
57        }
58    }
59
60    do {
61    walk_nss_morebuf:
62        if (fct.ptr == NULL)
63            *w.status = NSS_STATUS_UNAVAIL;
64        else if (self != NULL && fct.l == self)
65            *w.status = NSS_STATUS_NOTFOUND;
66        else
67            *w.status = DL_CALL_FCT(fct.l, args);
68        if (*w.status == NSS_STATUS_TRYAGAIN &&
69            w.errnop != NULL && *w.errnop == ERANGE) {
70            if (w.buf == NULL)
71                break;
72            free(*w.buf);
73            *w.buflen *= 2;
74            *w.buf = malloc(*w.buflen);
75            errno = old_errno;
76            if (*w.buf == NULL) {
77                *w.errnop = ENOMEM;
78                goto walk_nss_out;
79            }
80            goto walk_nss_morebuf;
81        }
82    } while (__nss_next(&nip, w.fct_name, &fct.ptr, *w.status, w.all_values) ==
83             0);
84
85    if (w.buf != NULL && *w.status != NSS_STATUS_SUCCESS) {
86        free(*w.buf);
87        *w.buf = NULL;
88    }
89
90 walk_nss_out:
91    ;
92}
Note: See TracBrowser for help on using the repository browser.