aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog4
-rw-r--r--nis/nss_compat/compat-initgroups.c146
2 files changed, 83 insertions, 67 deletions
diff --git a/ChangeLog b/ChangeLog
index 53b4b44067..8908dbb6f4 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+1998-08-21 Thorsten Kukuk <kukuk@vt.uni-paderborn.de>
+
+ * nis/nss_compat/compat-initgroups.c: Optimize NIS query.
+
1998-08-21 17:21 Ulrich Drepper <drepper@cygnus.com>
* sysdeps/unix/sysv/linux/glob64.c: Define __stat using __xstat64.
diff --git a/nis/nss_compat/compat-initgroups.c b/nis/nss_compat/compat-initgroups.c
index 97ddaeebab..a0c3455eb6 100644
--- a/nis/nss_compat/compat-initgroups.c
+++ b/nis/nss_compat/compat-initgroups.c
@@ -29,6 +29,7 @@
#include <rpcsvc/nis.h>
#include <nsswitch.h>
+#include "nss-nis.h"
#include "nss-nisplus.h"
#include "nisplus-parser.h"
@@ -53,6 +54,12 @@ struct blacklist_t
int size;
};
+struct response_t
+{
+ char *val;
+ struct response_t *next;
+};
+
struct ent_t
{
bool_t nis;
@@ -62,6 +69,8 @@ struct ent_t
nis_result *result;
FILE *stream;
struct blacklist_t blacklist;
+ struct response_t *start;
+ struct response_t *next;
};
typedef struct ent_t ent_t;
@@ -70,6 +79,36 @@ typedef struct ent_t ent_t;
static void blacklist_store_name (const char *, ent_t *);
static int in_blacklist (const char *, int, ent_t *);
+static int
+saveit (int instatus, char *inkey, int inkeylen, char *inval,
+ int invallen, char *indata)
+{
+ ent_t *intern = (ent_t *) indata;
+
+ if (instatus != YP_TRUE)
+ return instatus;
+
+ if (inkey && inkeylen > 0 && inval && invallen > 0)
+ {
+ if (intern->start == NULL)
+ {
+ intern->start = malloc (sizeof (struct response_t));
+ intern->next = intern->start;
+ }
+ else
+ {
+ intern->next->next = malloc (sizeof (struct response_t));
+ intern->next = intern->next->next;
+ }
+ intern->next->next = NULL;
+ intern->next->val = malloc (invallen + 1);
+ strncpy (intern->next->val, inval, invallen);
+ intern->next->val[invallen] = '\0';
+ }
+
+ return 0;
+}
+
static enum nss_status
_nss_first_init (void)
{
@@ -105,6 +144,9 @@ internal_setgrent (ent_t *ent)
ent->nis = ent->nis_first = 0;
+ ent->start = NULL;
+ ent->next = NULL;
+
if (_nss_first_init () != NSS_STATUS_SUCCESS)
return NSS_STATUS_UNAVAIL;
@@ -197,6 +239,16 @@ internal_endgrent (ent_t *ent)
else
ent->blacklist.current = 0;
+ while (ent->start != NULL)
+ {
+ if (ent->start->val != NULL)
+ free (ent->start->val);
+ ent->next = ent->start;
+ ent->start = ent->start->next;
+ free (ent->next);
+ }
+
+
return NSS_STATUS_SUCCESS;
}
@@ -205,10 +257,8 @@ getgrent_next_nis (struct group *result, ent_t *ent, char *buffer,
size_t buflen, int *errnop)
{
struct parser_data *data = (void *) buffer;
- char *domain;
- char *outkey, *outval;
- int outkeylen, outvallen, parse_res;
- char *p;
+ char *domain, *p;
+ int parse_res;
if (yp_get_default_domain (&domain) != YPERR_SUCCESS)
{
@@ -216,85 +266,47 @@ getgrent_next_nis (struct group *result, ent_t *ent, char *buffer,
return NSS_STATUS_NOTFOUND;
}
- do
+ if (ent->start == NULL)
{
- char *save_oldkey;
- int save_oldlen;
- bool_t save_nis_first;
+ struct ypall_callback ypcb;
+ enum nss_status status;
- if (ent->nis_first)
- {
- if (yp_first (domain, "group.byname", &outkey, &outkeylen,
- &outval, &outvallen) != YPERR_SUCCESS)
- {
- ent->nis = 0;
- *errnop = ENOENT;
- return NSS_STATUS_UNAVAIL;
- }
+ ypcb.foreach = saveit;
+ ypcb.data = (char *) ent;
+ status = yperr2nss (yp_all (domain, "group.byname", &ypcb));
+ ent->next = ent->start;
- if ( buflen < ((size_t) outvallen + 1))
- {
- free (outval);
- *errnop = ERANGE;
- return NSS_STATUS_TRYAGAIN;
- }
-
- save_oldkey = ent->oldkey;
- save_oldlen = ent->oldkeylen;
- save_nis_first = TRUE;
- ent->oldkey = outkey;
- ent->oldkeylen = outkeylen;
- ent->nis_first = FALSE;
- }
- else
+ if (ent->start == NULL || status != NSS_STATUS_SUCCESS)
{
- if (yp_next (domain, "group.byname", ent->oldkey, ent->oldkeylen,
- &outkey, &outkeylen, &outval, &outvallen)
- != YPERR_SUCCESS)
- {
- ent->nis = 0;
- *errnop = ENOENT;
- return NSS_STATUS_NOTFOUND;
- }
-
- if ( buflen < ((size_t) outvallen + 1))
- {
- free (outval);
- *errnop = ERANGE;
- return NSS_STATUS_TRYAGAIN;
- }
-
- save_oldkey = ent->oldkey;
- save_oldlen = ent->oldkeylen;
- save_nis_first = FALSE;
- ent->oldkey = outkey;
- ent->oldkeylen = outkeylen;
+ ent->nis = 0;
+ *errnop = ENOENT;
+ return NSS_STATUS_UNAVAIL;
}
+ }
- /* Copy the found data to our buffer... */
- p = strncpy (buffer, outval, buflen);
- /* ...and free the data. */
- free (outval);
+ do
+ {
+ if (ent->next == NULL)
+ {
+ *errnop = ENOENT;
+ ent->nis = 0;
+ return NSS_STATUS_NOTFOUND;
+ }
+ /* Copy the found data to our buffer... */
+ p = strncpy (buffer, ent->next->val, buflen);
while (isspace (*p))
- ++p;
+ ++p;
parse_res = _nss_files_parse_grent (p, result, data, buflen, errnop);
if (parse_res == -1)
{
- free (ent->oldkey);
- ent->oldkey = save_oldkey;
- ent->oldkeylen = save_oldlen;
- ent->nis_first = save_nis_first;
*errnop = ERANGE;
return NSS_STATUS_TRYAGAIN;
}
- else
- {
- if (!save_nis_first)
- free (save_oldkey);
- }
+
+ ent->next = ent->next->next;
if (parse_res &&
in_blacklist (result->gr_name, strlen (result->gr_name), ent))