This is the mail archive of the libc-hacker@sources.redhat.com mailing list for the glibc project.
Note that libc-hacker is a closed list. You may look at the archives of this list, but subscription and posting are not open.
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |
Other format: | [Raw text] |
Hi! Only lightly tested so far. It is not neccessary to download, allocate and copy whole services map and then search through it. Instead, we can search already in the foreach callback and if we find something tell the caller we don't need further input. BTW: __xdr_ypresp_all uses the foreach callback return value as 0 -> need further data, != 0 break the loop. But saveit callbacks I see return 0 when further data should be examined and YP_FALSE (== 0) on error (e.g. memory failures). This certainly doesn't sound right. 2004-03-30 Jakub Jelinek <jakub@redhat.com> * nis/nss_nis/nis-service.c (struct search_t): New type. (dosearch): New function. (_nss_nis_getservbyname_r): Use it. Call yp_get_default_domain unconditionally. (_nss_nis_getservbyport_r): Likewise. --- libc/nis/nss_nis/nis-service.c.jj 2003-01-18 11:18:41.000000000 +0100 +++ libc/nis/nss_nis/nis-service.c 2004-03-30 00:49:23.341175888 +0200 @@ -51,6 +51,18 @@ typedef struct intern_t intern_t; static intern_t intern = { NULL, NULL }; +struct search_t +{ + const char *name; + const char *proto; + int port; + enum nss_status status; + struct servent *serv; + char *buffer; + size_t buflen; + int *errnop; +}; + static int saveit (int instatus, char *inkey, int inkeylen, char *inval, int invallen, char *indata) @@ -87,6 +99,68 @@ saveit (int instatus, char *inkey, int i return 0; } +static int +dosearch (int instatus, char *inkey, int inkeylen, char *inval, + int invallen, char *indata) +{ + struct search_t *req = (struct search_t *) indata; + + if (instatus != YP_TRUE) + return 1; + + if (inkey && inkeylen > 0 && inval && invallen > 0) + { + struct parser_data *pdata = (void *) req->buffer; + int parse_res; + char *p; + + if ((size_t) (invallen + 1) > req->buflen) + { + *req->errnop = ERANGE; + req->status = NSS_STATUS_TRYAGAIN; + return 1; + } + + p = strncpy (req->buffer, inval, invallen); + req->buffer[invallen] = '\0'; + while (isspace (*p)) + ++p; + + parse_res = _nss_files_parse_servent (p, req->serv, pdata, req->buflen, + req->errnop); + if (parse_res == -1) + { + req->status = NSS_STATUS_TRYAGAIN; + return 1; + } + + if (!parse_res) + return 0; + + if (req->proto != NULL && strcmp (req->serv->s_proto, req->proto) != 0) + return 0; + + if (req->port != -1 && req->serv->s_port != req->port) + return 0; + + if (req->name != NULL && strcmp (req->serv->s_name, req->name) != 0) + { + char **cp; + for (cp = req->serv->s_aliases; *cp; cp++) + if (strcmp (req->name, *cp) == 0) + break; + + if (*cp == NULL) + return 0; + } + + req->status = NSS_STATUS_SUCCESS; + return 1; + } + + return 0; +} + static enum nss_status internal_nis_endservent (intern_t * intern) { @@ -136,6 +210,7 @@ internal_nis_setservent (intern_t *inter return status; } + enum nss_status _nss_nis_setservent (int stayopen) { @@ -201,9 +276,8 @@ _nss_nis_getservbyname_r (const char *na struct servent *serv, char *buffer, size_t buflen, int *errnop) { - intern_t data = { NULL, NULL }; enum nss_status status; - int found; + char *domain; if (name == NULL) { @@ -211,19 +285,18 @@ _nss_nis_getservbyname_r (const char *na return NSS_STATUS_UNAVAIL; } + if (yp_get_default_domain (&domain)) + return NSS_STATUS_UNAVAIL; + /* If the protocol is given, we could try if our NIS server knows about services.byservicename map. If yes, we only need one query */ if (protocol != NULL) { char key[strlen (name) + strlen (protocol) + 2]; - char *cp, *domain, *result; + char *cp, *result; size_t keylen, len; int int_len; - /* If this fails, the other solution will also fail. */ - if (yp_get_default_domain (&domain)) - return NSS_STATUS_UNAVAIL; - /* key is: "name/protocol" */ cp = stpcpy (key, name); *cp++ = '/'; @@ -267,34 +340,25 @@ _nss_nis_getservbyname_r (const char *na } } - status = internal_nis_setservent (&data); - if (status != NSS_STATUS_SUCCESS) - return status; - - found = 0; - while (!found && - ((status = internal_nis_getservent_r (serv, buffer, buflen, errnop, - &data)) == NSS_STATUS_SUCCESS)) - { - if (protocol == NULL || strcmp (serv->s_proto, protocol) == 0) - { - char **cp; - - if (strcmp (serv->s_name, name) == 0) - found = 1; - else - for (cp = serv->s_aliases; *cp; cp++) - if (strcmp (name, *cp) == 0) - found = 1; - } - } + struct ypall_callback ypcb; + struct search_t req; - internal_nis_endservent (&data); + ypcb.foreach = dosearch; + ypcb.data = (char *) &req; + req.name = name; + req.proto = protocol; + req.port = -1; + req.serv = serv; + req.buffer = buffer; + req.buflen = buflen; + req.errnop = errnop; + req.status = NSS_STATUS_NOTFOUND; + status = yperr2nss (yp_all (domain, "services.byservicename", &ypcb)); - if (!found && status == NSS_STATUS_SUCCESS) - return NSS_STATUS_NOTFOUND; - else + if (status != NSS_STATUS_SUCCESS) return status; + + return req.status; } enum nss_status @@ -302,22 +366,20 @@ _nss_nis_getservbyport_r (int port, cons struct servent *serv, char *buffer, size_t buflen, int *errnop) { - intern_t data = { NULL, NULL }; enum nss_status status; - int found; + char *domain; + + if (yp_get_default_domain (&domain)) + return NSS_STATUS_UNAVAIL; /* If the protocol is given, we only need one query */ if (protocol != NULL) { char key[100 + strlen (protocol) + 2]; - char *domain, *result; + char *result; size_t keylen, len; int int_len; - /* If this fails, the other solution will also fail. */ - if (yp_get_default_domain (&domain)) - return NSS_STATUS_UNAVAIL; - /* key is: "port/protocol" */ keylen = snprintf (key, sizeof (key), "%d/%s", port, protocol); status = yperr2nss (yp_match (domain, "services.byname", key, @@ -358,22 +420,26 @@ _nss_nis_getservbyport_r (int port, cons } } - status = internal_nis_setservent (&data); - if (status != NSS_STATUS_SUCCESS) - return status; + if (port == -1) + return NSS_STATUS_NOTFOUND; - found = 0; - while (!found && - ((status = internal_nis_getservent_r (serv, buffer, buflen, errnop, - &data)) == NSS_STATUS_SUCCESS)) - if (serv->s_port == port && - (protocol == NULL || strcmp (serv->s_proto, protocol) == 0)) - found = 1; + struct ypall_callback ypcb; + struct search_t req; - internal_nis_endservent (&data); + ypcb.foreach = dosearch; + ypcb.data = (char *) &req; + req.name = NULL; + req.proto = protocol; + req.port = port; + req.serv = serv; + req.buffer = buffer; + req.buflen = buflen; + req.errnop = errnop; + req.status = NSS_STATUS_NOTFOUND; + status = yperr2nss (yp_all (domain, "services.byname", &ypcb)); - if (!found && status == NSS_STATUS_SUCCESS) - return NSS_STATUS_NOTFOUND; - else + if (status != NSS_STATUS_SUCCESS) return status; + + return req.status; } Jakub
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |