summaryrefslogtreecommitdiff
path: root/revnetgroup/getnetgrent.c
diff options
context:
space:
mode:
Diffstat (limited to 'revnetgroup/getnetgrent.c')
-rw-r--r--revnetgroup/getnetgrent.c272
1 files changed, 272 insertions, 0 deletions
diff --git a/revnetgroup/getnetgrent.c b/revnetgroup/getnetgrent.c
new file mode 100644
index 0000000..ab717e1
--- /dev/null
+++ b/revnetgroup/getnetgrent.c
@@ -0,0 +1,272 @@
+/* Copyright (C) 1995 Free Software Foundation, Inc.
+ * This file is part of the GNU C Library.
+ *
+ * The GNU C Library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * The GNU C Library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with the GNU C Library; see the file COPYING.LIB. If
+ * not, write to the Free Software Foundation, Inc., 51 Franklin Street,
+ * Suite 500, Boston, MA 02110-1335, USA.
+ *
+ * Author: Swen Thuemmler <swen@uni-paderborn.de>
+ *
+ * Changes for the use with revnetgroup:
+ * Thorsten Kukuk <kukuk@suse.de>
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stddef.h>
+#include <ctype.h>
+#include <string.h>
+#include <assert.h>
+
+#include "hash.h"
+
+extern hash_t *input;
+
+void rev_setnetgrent (const char *);
+void rev_endnetgrent (void);
+int rev_getnetgrent (char **, char **, char **);
+
+struct netgrentry
+ {
+ char *host;
+ char *user;
+ char *domain;
+ };
+
+
+struct netgrlist
+ {
+ int maxmembers;
+ int members;
+ struct netgrentry *list;
+ };
+
+
+static void rev_expand_netgroupentry (const char *, struct netgrlist *);
+static void rev_parse_entry (char *, char *, struct netgrlist *);
+static void rev_netgr_free (struct netgrlist *);
+static struct netgrlist list = {0, 0, NULL};
+static int first = 1;
+static char *netgroup = NULL;
+
+static char *
+search_netgroup (hash_t ** liste, const char *key)
+{
+ hash_t *work;
+
+ work = *liste;
+
+ while ((work != NULL) && (0 != strcmp (work->key, key)))
+ work = work->next;
+
+ if (work != NULL)
+ return work->val;
+ else
+ return NULL;
+}
+
+void
+rev_setnetgrent (const char *netgr)
+{
+ if (NULL == netgroup || 0 != strcmp (netgroup, netgr))
+ {
+ rev_endnetgrent ();
+ netgroup = strdup (netgr);
+ rev_expand_netgroupentry (netgr, &list);
+ }
+ first = 1;
+}
+
+void
+rev_endnetgrent (void)
+{
+ if (NULL != netgroup)
+ {
+ free (netgroup);
+ netgroup = NULL;
+ }
+
+ if (NULL != list.list)
+ rev_netgr_free (&list);
+ first = 1;
+}
+
+int
+rev_getnetgrent (char **machinep, char **userp, char **domainp)
+{
+ static int current = 0;
+ struct netgrentry *entry;
+
+ if (1 == first)
+ current = first = 0;
+ else
+ current++;
+
+ if (current < list.members)
+ {
+ entry = &list.list[current];
+ *machinep = entry->host;
+ *userp = entry->user;
+ *domainp = entry->domain;
+ return 1;
+ }
+ return 0;
+}
+
+static void
+rev_netgr_free (struct netgrlist *list)
+{
+ int i;
+ for (i = 0; i < list->members; i++)
+ {
+ free (list->list[i].host);
+ free (list->list[i].user);
+ free (list->list[i].domain);
+ }
+ free (list->list);
+ list->maxmembers = 0;
+ list->members = 0;
+ list->list = NULL;
+}
+
+static void
+rev_expand_netgroupentry (const char *netgr, struct netgrlist *list)
+{
+ char *outval = NULL;
+ char *outptr = NULL;
+ char *start = NULL;
+ char *end = NULL;
+ char *realend = NULL;
+
+ if (*netgr == '\0')
+ return;
+
+ outptr = search_netgroup (&input, netgr);
+ if (outptr == NULL)
+ return;
+
+ /* make a copy to work with */
+ outval = strdup (outptr);
+ if (outval == NULL)
+ {
+ fprintf (stderr, "ERROR: could not allocate enough memory! [%s|%d]\n",
+ __FILE__, __LINE__);
+ exit (1);
+ }
+
+ /* outval enthaelt den Eintrag. Zuerst Leerzeichen ueberlesen */
+ start = outval;
+ realend = start + strlen (outval);
+ while (isspace (*start) && start < realend)
+ start++;
+
+ while (start < realend)
+ {
+ if ('(' == *start) /* Eintrag gefunden */
+ {
+ /* this a tuple... */
+ end = strchr (start, ')');
+ if (NULL == end)
+ {
+ free (outval);
+ return;
+ }
+
+ /* add the entry to the list? */
+ rev_parse_entry (start + 1, end, list);
+ }
+ else
+ {
+ /* okay, this should be a group (ie. not
+ a tuple... */
+ end = start + 1;
+
+ while ((*end != '\0') && (!isspace (*end)))
+ end++;
+
+ *end = '\0';
+
+ /* recursion */
+ rev_expand_netgroupentry (start, list);
+ }
+
+ /* skip to the next entry */
+ start = end + 1;
+
+ if (end == realend)
+ break;
+
+ assert (start <= realend);
+
+ while ((start < realend) && (isspace (*start)))
+ start++;
+ }
+
+ /* free the copy */
+ free (outval);
+}
+
+static void
+rev_parse_entry (char *start, char *end, struct netgrlist *list)
+{
+ char *host, *user, *domain;
+ struct netgrentry *entry;
+ /* First split entry into fields. Return, when finding malformed entry */
+ host = start;
+ start = strchr (host, ',');
+ if (NULL == start || start >= end)
+ return;
+ *start = '\0';
+ user = start + 1;
+ start = strchr (user, ',');
+ if (NULL == start || start >= end)
+ return;
+ *start = '\0';
+ domain = start + 1;
+ if (start > end)
+ return;
+ *end = '\0';
+ /* Entry is correctly formed, put it into the list */
+ if (0 == list->maxmembers)
+ {
+ list->list = malloc (10 * sizeof (struct netgrentry));
+ if (NULL != list->list)
+ list->maxmembers = 10;
+ else
+ return;
+ }
+
+ if (list->members == list->maxmembers)
+ {
+ list->list = realloc (list->list,
+ (list->maxmembers + 10) * sizeof (struct netgrentry));
+ if (NULL == list->list)
+ {
+ list->maxmembers = 0;
+ list->members = 0;
+ return;
+ }
+ list->maxmembers += 10;
+ }
+ /*
+ * FIXME: this will not handle entries of the form ( asdf, sdfa , asdf )
+ * (note the spaces). This should be handled better!
+ */
+ entry = &list->list[list->members];
+ entry->user = ('\0' == *user) ? NULL : strdup (user);
+ entry->host = ('\0' == *host) ? NULL : strdup (host);
+ entry->domain = ('\0' == *domain) ? NULL : strdup (domain);
+ list->members++;
+ return;
+}