]> granicus.if.org Git - sudo/commitdiff
Move list manipulation macros to list.h and create C versions of
authorTodd C. Miller <Todd.Miller@courtesan.com>
Fri, 31 Aug 2007 23:13:26 +0000 (23:13 +0000)
committerTodd C. Miller <Todd.Miller@courtesan.com>
Fri, 31 Aug 2007 23:13:26 +0000 (23:13 +0000)
the more complex ones in list.c.  The names have been down-cased
so they appear more like normal functions.

Makefile.in
alias.c
defaults.c
gram.y
list.c [new file with mode: 0644]
list.h [new file with mode: 0644]
match.c
parse.c
parse.h
testsudoers.c
visudo.c

index 760e0fba59834f5caf86a4975fc144d304c2364c..f651fd0ac91ff15d4e0cd106b46ce7c635d36ce7 100644 (file)
@@ -113,15 +113,15 @@ AUTH_SRCS = auth/afs.c auth/aix_auth.c auth/bsdauth.c auth/dce.c auth/fwtk.c \
            auth/sudo_auth.c
 
 HDRS = compat.h def_data.h defaults.h error.h ins_2001.h ins_classic.h \
-       ins_csops.h ins_goons.h insults.h interfaces.h lbuf.h logging.h parse.h \
-       sudo.h gram.h version.h auth/sudo_auth.h emul/fnmatch.h emul/utime.h \
-       redblack.h
+       ins_csops.h ins_goons.h insults.h interfaces.h lbuf.h list.h \
+       logging.h parse.h sudo.h gram.h version.h auth/sudo_auth.h \
+       emul/fnmatch.h emul/utime.h redblack.h
 
 AUTH_OBJS = sudo_auth.o @AUTH_OBJS@
 
 # Note: gram.o must come first here
-COMMON_OBJS = gram.o alias.o alloc.o defaults.o error.o match.o toke.o \
-             redblack.o zero_bytes.o
+COMMON_OBJS = gram.o alias.o alloc.o defaults.o error.o list.o match.o \
+             toke.o redblack.o zero_bytes.o
 
 SUDO_OBJS = $(COMMON_OBJS) $(AUTH_OBJS) @SUDO_OBJS@ check.o env.o \
            getspwuid.o gettime.o goodpath.o fileops.o find_path.o \
@@ -214,7 +214,7 @@ $(devdir)/toke.c: $(srcdir)/toke.l
 @DEV@  perl $(srcdir)/mkdefaults -o def_data $(srcdir)/def_data.in
 
 # Dependencies (not counting auth functions)
-alias.o: $(srcdir)/alias.c $(SUDODEP) $(srcdir)/parse.h $(srcdir)/redblack.h
+alias.o: $(srcdir)/alias.c $(SUDODEP) $(srcdir)/parse.h $(srcdir)/list.h $(srcdir)/redblack.h
        $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(OPTIONS) $(srcdir)/alias.c
 alloc.o: $(srcdir)/alloc.c $(SUDODEP)
        $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(OPTIONS) $(srcdir)/alloc.c
@@ -248,17 +248,19 @@ glob.o: $(srcdir)/glob.c $(srcdir)/emul/glob.h $(srcdir)/compat.h config.h
        $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(OPTIONS) $(srcdir)/glob.c
 goodpath.o: $(srcdir)/goodpath.c $(SUDODEP)
        $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(OPTIONS) $(srcdir)/goodpath.c
-gram.o: $(devdir)/gram.c $(SUDODEP) $(srcdir)/parse.h $(devdir)/gram.h
+gram.o: $(devdir)/gram.c $(SUDODEP) $(srcdir)/parse.h $(srcdir)/list.h $(devdir)/gram.h
        $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(OPTIONS) $(devdir)/gram.c
 interfaces.o: $(srcdir)/interfaces.c $(SUDODEP) $(srcdir)/interfaces.h
        $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(OPTIONS) $(srcdir)/interfaces.c
-ldap.o: $(srcdir)/ldap.c $(SUDODEP) $(srcdir)/parse.h
-       $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(OPTIONS) $(srcdir)/ldap.c
 lbuf.o: $(srcdir)/lbuf.c $(SUDODEP)
        $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(OPTIONS) $(srcdir)/lbuf.c
+ldap.o: $(srcdir)/ldap.c $(SUDODEP) $(srcdir)/parse.h $(srcdir)/list.h
+       $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(OPTIONS) $(srcdir)/ldap.c
+list.o: $(srcdir)/list.c $(SUDODEP)
+       $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(OPTIONS) $(srcdir)/list.c
 logging.o: $(srcdir)/logging.c $(SUDODEP)
        $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(OPTIONS) $(srcdir)/logging.c
-match.o: $(srcdir)/match.c $(SUDODEP) $(srcdir)/parse.h $(srcdir)/interfaces.h $(devdir)/gram.h
+match.o: $(srcdir)/match.c $(SUDODEP) $(srcdir)/parse.h $(srcdir)/list.h $(srcdir)/interfaces.h $(devdir)/gram.h
        $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(OPTIONS) $(srcdir)/match.c
 memrchr.o: $(srcdir)/memrchr.c $(SUDODEP)
        $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(OPTIONS) $(srcdir)/memrchr.c
@@ -266,7 +268,7 @@ mkstemp.o: $(srcdir)/mkstemp.c $(SUDODEP)
        $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(OPTIONS) $(srcdir)/mkstemp.c
 mon_solaris.o: $(srcdir)/mon_solaris.c $(SUDODEP) $(srcdir)/mon_solaris.h
        $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(OPTIONS) $(srcdir)/mon_solaris.c
-parse.o: $(srcdir)/parse.c $(SUDODEP) $(srcdir)/parse.h $(devdir)/gram.h
+parse.o: $(srcdir)/parse.c $(SUDODEP) $(srcdir)/parse.h $(srcdir)/list.h $(devdir)/gram.h
        $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(OPTIONS) $(srcdir)/parse.c
 pwutil.o: $(srcdir)/pwutil.c $(SUDODEP)
        $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(OPTIONS) $(srcdir)/pwutil.c
@@ -292,11 +294,11 @@ sudo_edit.o: $(srcdir)/sudo_edit.c $(SUDODEP)
        $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(OPTIONS) $(srcdir)/sudo_edit.c
 sudo_noexec.o: $(srcdir)/sudo_noexec.c $(srcdir)/compat.h config.h
        $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(OPTIONS) $(srcdir)/sudo_noexec.c
-testsudoers.o: $(srcdir)/testsudoers.c $(SUDODEP) $(srcdir)/parse.h $(srcdir)/interfaces.h $(devdir)/gram.h
+testsudoers.o: $(srcdir)/testsudoers.c $(SUDODEP) $(srcdir)/parse.h $(srcdir)/list.h $(srcdir)/interfaces.h $(devdir)/gram.h
        $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(OPTIONS) $(srcdir)/testsudoers.c
 tgetpass.o: $(srcdir)/tgetpass.c $(SUDODEP)
        $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(OPTIONS) $(srcdir)/tgetpass.c
-toke.o: $(devdir)/toke.c $(SUDODEP) $(srcdir)/parse.h $(devdir)/gram.h
+toke.o: $(devdir)/toke.c $(SUDODEP) $(srcdir)/parse.h $(srcdir)/list.h $(devdir)/gram.h
        $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(OPTIONS) $(devdir)/toke.c
 tsgetgrpw.o: $(srcdir)/tsgetgrpw.c $(SUDODEP)
        $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(OPTIONS) $(srcdir)/tsgetgrpw.c
diff --git a/alias.c b/alias.c
index 847131a54b8d1f67be592f041e539a02498facbd..067cbd5347eb0081083a77a51c459bbe221939e5 100644 (file)
--- a/alias.c
+++ b/alias.c
@@ -114,7 +114,7 @@ alias_add(name, type, members)
     a = emalloc(sizeof(*a));
     a->name = name;
     a->type = type;
-    LIST2HEAD(a->members, members);
+    list2head(&a->members, members);
     if (rbinsert(aliases, a)) {
        efree(a);
        snprintf(errbuf, sizeof(errbuf), "Alias `%s' already defined", name);
index 27d17340cfba7ac43030236d84b92b676061fa9b..d55a512724b6d0bdf74b67c4b3ace76ae7c7834e 100644 (file)
@@ -501,7 +501,7 @@ update_defaults(skip_cmnd)
 {
     struct defaults *def;
 
-    LH_FOREACH_FWD(&defaults, def) {
+    lh_foreach_fwd(&defaults, def) {
        if (skip_cmnd == (def->type == DEFAULTS_CMND))
            continue;
        switch (def->type) {
diff --git a/gram.y b/gram.y
index 5d1cad807ea6c81ee12ded6738d8763e38cece64..5699303fbcd850783f87c1d36c1cb0a3a5dfeab2 100644 (file)
--- a/gram.y
+++ b/gram.y
@@ -211,7 +211,7 @@ entry               :       COMMENT {
 
 defaults_list  :       defaults_entry
                |       defaults_list ',' defaults_entry {
-                           LIST_APPEND($1, $3);
+                           list_append($1, $3);
                            $$ = $1;
                        }
                ;
@@ -235,7 +235,7 @@ defaults_entry      :       DEFVAR {
 
 privileges     :       privilege
                |       privileges ':' privilege {
-                           LIST_APPEND($1, $3);
+                           list_append($1, $3);
                            $$ = $1;
                        }
                ;
@@ -248,8 +248,8 @@ privilege   :       hostlist '=' cmndspeclist {
                            /* propagate tags and runas lists */
                            tags.nopasswd = tags.noexec = tags.setenv = UNSPEC;
                            for (cs = $3; cs != NULL; cs = cs->next) {
-                               if (LH_EMPTY(&cs->runaslist) &&
-                                   !LH_EMPTY(&cs->prev->runaslist)) {
+                               if (lh_empty(&cs->runaslist) &&
+                                   !lh_empty(&cs->prev->runaslist)) {
                                    memcpy(&cs->runaslist, &cs->prev->runaslist,
                                        sizeof(cs->runaslist));
                                }
@@ -261,8 +261,8 @@ privilege   :       hostlist '=' cmndspeclist {
                                    cs->tags.setenv = tags.setenv;
                                memcpy(&tags, &cs->tags, sizeof(tags));
                            }
-                           LIST2HEAD(p->hostlist, $1);
-                           LIST2HEAD(p->cmndlist, $3);
+                           list2head(&p->hostlist, $1);
+                           list2head(&p->cmndlist, $3);
                            p->prev = p;
                            p->next = NULL;
                            $$ = p;
@@ -298,14 +298,14 @@ host              :       ALIAS {
 
 cmndspeclist   :       cmndspec
                |       cmndspeclist ',' cmndspec {
-                           LIST_APPEND($1, $3);
+                           list_append($1, $3);
                            $$ = $1;
                        }
                ;
 
 cmndspec       :       runasspec cmndtag opcmnd {
                            struct cmndspec *cs = emalloc(sizeof(*cs));
-                           LIST2HEAD(cs->runaslist, $1);
+                           list2head(&cs->runaslist, $1);
                            cs->tags = $2;
                            cs->cmnd = $3;
                            cs->prev = cs;
@@ -334,7 +334,7 @@ runasspec   :       /* empty */ {
 
 runaslist      :       oprunasuser
                |       runaslist ',' oprunasuser {
-                           LIST_APPEND($1, $3);
+                           list_append($1, $3);
                            $$ = $1;
                        }
                ;
@@ -418,7 +418,7 @@ hostalias   :       ALIAS '=' hostlist {
 
 hostlist       :       ophost
                |       hostlist ',' ophost {
-                           LIST_APPEND($1, $3);
+                           list_append($1, $3);
                            $$ = $1;
                        }
                ;
@@ -438,7 +438,7 @@ cmndalias   :       ALIAS '=' cmndlist {
 
 cmndlist       :       opcmnd
                |       cmndlist ',' opcmnd {
-                           LIST_APPEND($1, $3);
+                           list_append($1, $3);
                            $$ = $1;
                        }
                ;
@@ -471,7 +471,7 @@ useralias   :       ALIAS '=' userlist {
 
 userlist       :       opuser
                |       userlist ',' opuser {
-                           LIST_APPEND($1, $3);
+                           list_append($1, $3);
                            $$ = $1;
                        }
                ;
@@ -515,7 +515,7 @@ new_default(var, val, op)
     d = emalloc(sizeof(struct defaults));
     d->var = var;
     d->val = val;
-    LH_INIT(&d->binding);
+    lh_init(&d->binding);
     d->type = 0;
     d->op = op;
     d->prev = d;
@@ -558,9 +558,9 @@ add_defaults(type, binding, defs)
      */
     for (d = defs; d != NULL; d = d->next) {
        d->type = type;
-       LIST2HEAD(d->binding, binding);
+       list2head(&d->binding, binding);
     }
-    HEAD_APPEND(defaults, defs);
+    lh_append(&defaults, defs);
 }
 
 /*
@@ -575,11 +575,11 @@ add_userspec(members, privs)
     struct userspec *u;
 
     u = emalloc(sizeof(*u));
-    LIST2HEAD(u->users, members);
-    LIST2HEAD(u->privileges, privs);
+    list2head(&u->users, members);
+    list2head(&u->privileges, privs);
     u->prev = u;
     u->next = NULL;
-    HEAD_APPEND(userspecs, u);
+    lh_append(&userspecs, u);
 }
 
 /*
@@ -597,24 +597,18 @@ init_parser(path, quiet)
     struct privilege *priv;
     struct cmndspec *cs;
 
-    while ((us = LH_LAST(&userspecs)) != NULL) {
-       LH_POP(&userspecs);
-       while ((m = LH_LAST(&us->users)) != NULL) {
-           LH_POP(&us->users);
+    while ((us = lh_pop(&userspecs)) != NULL) {
+       while ((m = lh_pop(&us->users)) != NULL) {
            efree(m->name);
            efree(m);
        }
-       while ((priv = LH_LAST(&us->privileges)) != NULL) {
-           LH_POP(&us->privileges);
-           while ((m = LH_LAST(&priv->hostlist)) != NULL) {
-               LH_POP(&priv->hostlist);
+       while ((priv = lh_pop(&us->privileges)) != NULL) {
+           while ((m = lh_pop(&priv->hostlist)) != NULL) {
                efree(m->name);
                efree(m);
            }
-           while ((cs = LH_LAST(&priv->cmndlist)) != NULL) {
-               LH_POP(&priv->cmndlist);
-               while ((m = LH_LAST(&cs->runaslist)) != NULL) {
-                   LH_POP(&cs->runaslist);
+           while ((cs = lh_pop(&priv->cmndlist)) != NULL) {
+               while ((m = lh_pop(&cs->runaslist)) != NULL) {
                    efree(m->name);
                    efree(m);
                }
@@ -625,15 +619,12 @@ init_parser(path, quiet)
            efree(priv);
        }
     }
-    LH_INIT(&userspecs);
+    lh_init(&userspecs);
 
     lastbinding = NULL;
-    while ((d = LH_LAST(&defaults)) != NULL) {
-       LH_POP(&defaults);
-       if (LH_FIRST(&d->binding) != lastbinding) {
-           lastbinding = LH_FIRST(&d->binding);
-           while ((m = LH_LAST(&d->binding)) != NULL) {
-               LH_POP(&d->binding);
+    while ((d = lh_pop(&defaults)) != NULL) {
+       if (lh_pop(&d->binding) != lastbinding) {
+           while ((m = lh_pop(&d->binding)) != NULL) {
                efree(m->name);
                efree(m);
            }
@@ -642,7 +633,7 @@ init_parser(path, quiet)
        efree(d->val);
        efree(d);
     }
-    LH_INIT(&defaults);
+    lh_init(&defaults);
 
     init_aliases();
 
diff --git a/list.c b/list.c
new file mode 100644 (file)
index 0000000..cba973e
--- /dev/null
+++ b/list.c
@@ -0,0 +1,132 @@
+/*
+ * Copyright (c) 2007 Todd C. Miller <Todd.Miller@courtesan.com>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <config.h>
+
+#include <sys/types.h>
+#include <stdio.h>
+#ifdef STDC_HEADERS
+# include <stdlib.h>
+# include <stddef.h>
+#else
+# ifdef HAVE_STDLIB_H
+#  include <stdlib.h>
+# endif
+#endif /* STDC_HEADERS */
+
+#include "sudo.h"
+#include "list.h"
+
+#ifndef lint
+__unused static const char rcsid[] = "$Sudo$";
+#endif /* lint */
+
+struct list_proto {
+    struct list_proto *prev;
+    struct list_proto *next;
+};
+
+struct list_head_proto {
+    struct list_proto *first;
+    struct list_proto *last;
+};
+
+/*
+ * Pop the last element off the end of vh.
+ * Returns the popped element.
+ */
+VOID *
+lh_pop(vh)
+    VOID *vh;
+{
+    struct list_head_proto *h = (struct list_head_proto *)vh;
+    VOID *last = NULL;
+
+    if (!lh_empty(h)) {
+       last = (VOID *)h->last;
+       if (h->first == h->last) {
+           h->first = NULL;
+           h->last = NULL;
+       } else {
+           h->last = h->last->prev;
+           h->last->next = NULL;
+       }
+    }
+    return (last);
+}
+
+/*
+ * Convert from a semi-circle queue to normal doubly-linked list
+ * with a head node.
+ */
+void
+list2head(vh, vl)
+    VOID *vh;
+    VOID *vl;
+{
+    struct list_head_proto *h = (struct list_head_proto *)vh;
+    struct list_proto *l = (struct list_proto *)vl;
+
+    if (l != NULL) {
+       h->first = l;
+       h->last = l->prev;      /* l->prev points to the last member of l */
+       l->prev = NULL;         /* zero last ptr now that we have a head */
+    } else {
+       h->first = NULL;
+       h->last = NULL;
+    }
+}
+
+/*
+ * Append one queue (or single entry) to another using the
+ * circular properties of the prev pointer to simplify the logic.
+ */
+void
+list_append(vl1, vl2)
+    VOID *vl1;
+    VOID *vl2;
+{
+    struct list_proto *l1 = (struct list_proto *)vl1;
+    struct list_proto *l2 = (struct list_proto *)vl2;
+    VOID *tail = l2->prev;
+
+    l1->prev->next = l2;
+    l2->prev = l1->prev;
+    l1->prev = tail;
+}
+
+/*
+ * Append the list of entries to the head node and convert 
+ * e from a semi-circle queue to normal doubly-linked list. 
+ */
+void
+lh_append(vh, vl)
+    VOID *vh;
+    VOID *vl;
+{
+    struct list_head_proto *h = (struct list_head_proto *)vh;
+    struct list_proto *l = (struct list_proto *)vl;
+    VOID *tail = l->prev;
+
+    if (h->first == NULL)
+       h->first = l;
+    else
+       h->last->next = l;
+    l->prev = h->last;
+    h->last = tail;
+}
diff --git a/list.h b/list.h
new file mode 100644 (file)
index 0000000..a852971
--- /dev/null
+++ b/list.h
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2007 Todd C. Miller <Todd.Miller@courtesan.com>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * $Sudo$
+ */
+
+#ifndef _SUDO_LIST_H
+#define _SUDO_LIST_H
+
+/*
+ * Convenience macro for declaring a list head.
+ */
+#ifdef __STDC__
+#define LH_DECLARE(n)                                  \
+struct n##_list {                                      \
+    struct n *first;                                   \
+    struct n *last;                                    \
+};
+#else
+#define LH_DECLARE(n)                                  \
+struct n/**/_list {                                    \
+    struct n *first;                                   \
+    struct n *last;                                    \
+};
+#endif
+
+/*
+ * Foreach loops: forward and reverse
+ */
+#undef lh_foreach_fwd
+#define lh_foreach_fwd(h, v)                           \
+    for ((v) = (h)->first; (v) != NULL; (v) = (v)->next)
+
+#undef lh_foreach_rev
+#define lh_foreach_rev(h, v)                           \
+    for ((v) = (h)->last; (v) != NULL; (v) = (v)->prev)
+
+/*
+ * Init a list head.
+ */
+#undef lh_init
+#define lh_init(h) do {                                        \
+    (h)->first = NULL;                                 \
+    (h)->last = NULL;                                  \
+} while (0)
+
+/*
+ * Simple macros to avoid exposing first/last and prev/next.
+ */
+#undef lh_empty
+#define lh_empty(h)    ((h)->first == NULL)
+
+#undef lh_first
+#define lh_first(h)    ((h)->first)
+
+#undef lh_last
+#define lh_last(h)     ((h)->last)
+
+#undef list_next
+#define list_next(e)   ((e)->next)
+
+#undef list_prev
+#define list_prev(e)   ((e)->prev)
+
+/*
+ * Prototypes for list.c
+ */
+VOID *lh_pop           __P((VOID *));
+void lh_append         __P((VOID *, VOID *));
+void list_append       __P((VOID *, VOID *));
+void list2head         __P((VOID *, VOID *));
+
+#endif /* _SUDO_LIST_H */
diff --git a/match.c b/match.c
index 324e527eaf2db67d53e8a144e5a5fa14dd771ffe..3b84e8472907f0259a4ff52f07fb4a28bab1edfc 100644 (file)
--- a/match.c
+++ b/match.c
@@ -111,7 +111,7 @@ userlist_matches(pw, list)
     struct alias *a;
     int rval, matched = UNSPEC;
 
-    LH_FOREACH_REV(list, m) {
+    lh_foreach_rev(list, m) {
        switch (m->type) {
            case ALL:
                matched = !m->negated;
@@ -159,7 +159,7 @@ runaslist_matches(list)
     if (list == NULL)
        return(userpw_matches(def_runas_default, runas_pw->pw_name, runas_pw));
 
-    LH_FOREACH_REV(list, m) {
+    lh_foreach_rev(list, m) {
        switch (m->type) {
            case ALL:
                matched = !m->negated;
@@ -203,7 +203,7 @@ hostlist_matches(list)
     struct alias *a;
     int rval, matched = UNSPEC;
 
-    LH_FOREACH_REV(list, m) {
+    lh_foreach_rev(list, m) {
        switch (m->type) {
            case ALL:
                matched = !m->negated;
@@ -278,7 +278,7 @@ cmndlist_matches(list)
     struct member *m;
     int rval, matched = UNSPEC;
 
-    LH_FOREACH_REV(list, m) {
+    lh_foreach_rev(list, m) {
        rval = cmnd_matches(m);
        if (rval != UNSPEC) {
            matched = m->negated ? !rval : rval;
diff --git a/parse.c b/parse.c
index 36c14a696078f7c7f8d9ba56a23ad6648aed0d95..cd0f0a1ca218e3e600c0362f62135db1dbf45d41 100644 (file)
--- a/parse.c
+++ b/parse.c
@@ -110,13 +110,13 @@ sudoers_lookup(pwflag)
        CLR(validated, FLAG_NO_USER);
        CLR(validated, FLAG_NO_HOST);
        match = DENY;
-       LH_FOREACH_REV(&userspecs, us) {
+       lh_foreach_rev(&userspecs, us) {
            if (userlist_matches(sudo_user.pw, &us->users) != ALLOW)
                continue;
-           LH_FOREACH_REV(&us->privileges, priv) {
+           lh_foreach_rev(&us->privileges, priv) {
                if (hostlist_matches(&priv->hostlist) != ALLOW)
                    continue;
-               LH_FOREACH_REV(&priv->cmndlist, cs) {
+               lh_foreach_rev(&priv->cmndlist, cs) {
                    /* Only check the command when listing another user. */
                    if (user_uid == 0 || list_pw == NULL ||
                        user_uid == list_pw->pw_uid ||
@@ -147,19 +147,19 @@ sudoers_lookup(pwflag)
     set_perms(PERM_RUNAS);
 
     match = UNSPEC;
-    LH_FOREACH_REV(&userspecs, us) {
+    lh_foreach_rev(&userspecs, us) {
        if (userlist_matches(sudo_user.pw, &us->users) != ALLOW)
            continue;
        CLR(validated, FLAG_NO_USER);
-       LH_FOREACH_REV(&us->privileges, priv) {
+       lh_foreach_rev(&us->privileges, priv) {
            host_match = hostlist_matches(&priv->hostlist);
            if (host_match == ALLOW)
                CLR(validated, FLAG_NO_HOST);
            else
                continue;
            runas = NULL;
-           LH_FOREACH_REV(&priv->cmndlist, cs) {
-               if (!LH_EMPTY(&cs->runaslist))
+           lh_foreach_rev(&priv->cmndlist, cs) {
+               if (!lh_empty(&cs->runaslist))
                    runas = &cs->runaslist;
                runas_match = runaslist_matches(runas);
                if (runas_match == ALLOW) {
@@ -228,24 +228,24 @@ display_privs(v, pw)
        printf("User %s may run the following commands on this host:\n",
            pw->pw_name);
 
-       LH_FOREACH_FWD(&userspecs, us) {
+       lh_foreach_fwd(&userspecs, us) {
            /* XXX - why only check the first privilege here? */
            if (userlist_matches(pw, &us->users) != ALLOW ||
                hostlist_matches(&us->privileges.first->hostlist) != ALLOW)
                continue;
 
-           LH_FOREACH_FWD(&us->privileges, priv) {
+           lh_foreach_fwd(&us->privileges, priv) {
                tags.noexec = def_noexec;
                tags.setenv = def_setenv;
                tags.nopasswd = !def_authenticate;
                lbuf_append(&lbuf, "    ", NULL);
-               LH_FOREACH_FWD(&priv->cmndlist, cs) {
-                   if (cs != LH_FIRST(&priv->cmndlist))
+               lh_foreach_fwd(&priv->cmndlist, cs) {
+                   if (cs != lh_first(&priv->cmndlist))
                        lbuf_append(&lbuf, ", ", NULL);
                    lbuf_append(&lbuf, "(", NULL);
-                   if (!LH_EMPTY(&cs->runaslist)) {
-                       LH_FOREACH_FWD(&cs->runaslist, m) {
-                           if (m != LH_FIRST(&cs->runaslist))
+                   if (!lh_empty(&cs->runaslist)) {
+                       lh_foreach_fwd(&cs->runaslist, m) {
+                           if (m != lh_first(&cs->runaslist))
                                lbuf_append(&lbuf, ", ", NULL);
                            print_member(&lbuf, m->name, m->type, m->negated,
                                RUNASALIAS);
@@ -298,7 +298,7 @@ display_defaults(pw)
 
     lbuf_init(&lbuf, NULL, 4, 0);
 
-    LH_FOREACH_FWD(&defaults, d) {
+    lh_foreach_fwd(&defaults, d) {
        switch (d->type) {
            case DEFAULTS_HOST:
                if (hostlist_matches(&d->binding) != ALLOW)
@@ -385,12 +385,12 @@ display_bound_defaults(dtype)
     }
     lbuf_init(&lbuf, NULL, 4, 0);
     printf("Per-%s Defaults entries:\n", dname);
-    LH_FOREACH_FWD(&defaults, d) {
+    lh_foreach_fwd(&defaults, d) {
        if (d->type != dtype)
            continue;
 
-       if (binding != LH_FIRST(&d->binding)) {
-           binding = LH_FIRST(&d->binding);
+       if (binding != lh_first(&d->binding)) {
+           binding = lh_first(&d->binding);
            lbuf_append(&lbuf, "    Defaults", dsep, NULL);
            for (m = binding; m != NULL; m = m->next) {
                if (m != binding)
@@ -434,17 +434,17 @@ display_cmnd(v, pw)
 #endif
     if (rval != 0 && !def_ignore_local_sudoers) {
        match = NULL;
-       LH_FOREACH_REV(&userspecs, us) {
+       lh_foreach_rev(&userspecs, us) {
            if (userlist_matches(pw, &us->users) != ALLOW)
                continue;
 
-           LH_FOREACH_REV(&us->privileges, priv) {
+           lh_foreach_rev(&us->privileges, priv) {
                host_match = hostlist_matches(&priv->hostlist);
                if (host_match != ALLOW)
                    continue;
                runas = NULL;
-               LH_FOREACH_REV(&priv->cmndlist, cs) {
-                   if (!LH_EMPTY(&cs->runaslist) != NULL)
+               lh_foreach_rev(&priv->cmndlist, cs) {
+                   if (!lh_empty(&cs->runaslist) != NULL)
                        runas = &cs->runaslist;
                    runas_match = runaslist_matches(runas);
                    if (runas_match == ALLOW) {
@@ -497,8 +497,8 @@ print_member(lbuf, name, type, negated, alias_type)
            break;
        case ALIAS:
            if ((a = find_alias(name, alias_type)) != NULL) {
-               LH_FOREACH_FWD(&a->members, m) {
-                   if (m != LH_FIRST(&a->members))
+               lh_foreach_fwd(&a->members, m) {
+                   if (m != lh_first(&a->members))
                        lbuf_append(lbuf, ", ", NULL);
                    print_member(lbuf, m->name, m->type,
                        negated ? !m->negated : m->negated, alias_type);
diff --git a/parse.h b/parse.h
index a6e6b464f9cccfff9ee92b8860f78ec26b26a9d0..2d614dd814ed00b4acd9b33a3471b435ad2493c1 100644 (file)
--- a/parse.h
+++ b/parse.h
@@ -20,6 +20,8 @@
 #ifndef _SUDO_PARSE_H
 #define _SUDO_PARSE_H
 
+#include "list.h"
+
 #undef ALLOW
 #define ALLOW  1
 #undef DENY
@@ -58,72 +60,56 @@ struct cmndtag {
  * to trivally append sub-lists.  In addition, the prev pointer is always
  * valid (even if it points to itself).  Unlike a circle queue, the next
  * pointer of the last entry is NULL and does not point back to the head.
+ *
+ * Note that each list struct must contain a "prev" and "next" pointer as
+ * the first two members of the struct (in that order).
  */
 
 /*
  * Tail queue list head structure.
  */
-struct defaults_list {
-    struct defaults *first;
-    struct defaults *last;
-};
-
-struct userspec_list {
-    struct userspec *first;
-    struct userspec *last;
-};
-
-struct member_list {
-    struct member *first;
-    struct member *last;
-};
-
-struct privilege_list {
-    struct privilege *first;
-    struct privilege *last;
-};
-
-struct cmndspec_list {
-    struct cmndspec *first;
-    struct cmndspec *last;
-};
+LH_DECLARE(defaults)
+LH_DECLARE(userspec)
+LH_DECLARE(member)
+LH_DECLARE(privilege)
+LH_DECLARE(cmndspec)
 
 /*
  * Structure describing a user specification and list thereof.
  */
 struct userspec {
+    struct userspec *prev, *next;
     struct member_list users;          /* list of users */
     struct privilege_list privileges;  /* list of privileges */
-    struct userspec *prev, *next;
 };
 
 /*
  * Structure describing a privilege specification.
  */
 struct privilege {
+    struct privilege *prev, *next;
     struct member_list hostlist;       /* list of hosts */
     struct cmndspec_list cmndlist;     /* list of Cmnd_Specs */
-    struct privilege *prev, *next;
 };
 
 /*
  * Structure describing a linked list of Cmnd_Specs.
  */
 struct cmndspec {
+    struct cmndspec *prev, *next;
     struct member_list runaslist;      /* list of runas users */
     struct member *cmnd;               /* command to allow/deny */
     struct cmndtag tags;               /* tag specificaion */
-    struct cmndspec *prev, *next;
 };
 
 /*
  * Generic structure to hold users, hosts, commands.
  */
 struct member {
+    struct member *prev, *next;
     char *name;                                /* member name */
     short type;                                /* type (see gram.h) */
     short negated;                     /* negated via '!'? */
-    struct member *prev, *next;
 };
 
 /*
@@ -140,102 +126,14 @@ struct alias {
  * Structure describing a Defaults entry and a list thereof.
  */
 struct defaults {
+    struct defaults *prev, *next;
     char *var;                         /* variable name */
     char *val;                         /* variable value */
     struct member_list binding;                /* user/host/runas binding */
     int type;                          /* DEFAULTS{,_USER,_RUNAS,_HOST} */
     int op;                            /* TRUE, FALSE, '+', '-' */
-    struct defaults *prev, *next;
 };
 
-/*
- * Append one queue (or single entry) to another using the
- * circular properties of the prev pointer to simplify the logic.
- */
-#undef LIST_APPEND
-#define LIST_APPEND(h, e) do {                         \
-    void *_tail = (e)->prev;                           \
-    (h)->prev->next = (e);                             \
-    (e)->prev = (h)->prev;                             \
-    (h)->prev = _tail;                                 \
-} while (0)
-
-/*
- * Append the list of entries to the head node and convert
- * e from a semi-circle queue to normal doubly-linked list.
- */
-#undef HEAD_APPEND
-#define HEAD_APPEND(h, e) do {                         \
-    void *_tail = (e)->prev;                           \
-    if ((h).first == NULL)                             \
-       (h).first = (e);                                \
-    else                                               \
-       (h).last->next = (e);                           \
-    (e)->prev = (h).last;                              \
-    (h).last = _tail;                                  \
-} while (0)
-
-/*
- * Convert from a semi-circle queue to normal doubly-linked list
- * with a head node.
- */
-#undef LIST2HEAD
-#define LIST2HEAD(h, e) do {                           \
-    if ((e) != NULL) {                                 \
-       (h).first = (e);                                \
-       (h).last = (e)->prev;                           \
-       (e)->prev = NULL;                               \
-    } else {                                           \
-       (h).first = NULL;                               \
-       (h).last = NULL;                                \
-    }                                                  \
-} while (0)
-
-#undef LH_FOREACH_FWD
-#define LH_FOREACH_FWD(h, v)                           \
-    for ((v) = (h)->first; (v) != NULL; (v) = (v)->next)
-
-#undef LH_FOREACH_REV
-#define LH_FOREACH_REV(h, v)                           \
-    for ((v) = (h)->last; (v) != NULL; (v) = (v)->prev)
-
-/*
- * Pop the last element off the end of h.
- * XXX - really should return the popped element.
- */
-#undef LH_POP
-#define LH_POP(h) do {                                 \
-    if (!LH_EMPTY(h)) {                                        \
-       if ((h)->first == (h)->last)                    \
-           (h)->first = (h)->last = NULL;              \
-       else {                                          \
-           (h)->last = (h)->last->prev;                \
-           (h)->last->next = NULL;                     \
-       }                                               \
-    }                                                  \
-} while (0)
-
-#undef LH_INIT
-#define LH_INIT(h) do {                                        \
-    (h)->first = NULL;                                 \
-    (h)->last = NULL;                                  \
-} while (0)
-
-#undef LH_EMPTY
-#define LH_EMPTY(h)    ((h)->first == NULL)
-
-#undef LH_FIRST
-#define LH_FIRST(h)    ((h)->first)
-
-#undef LH_LAST
-#define LH_LAST(h)     ((h)->last)
-
-#undef LIST_NEXT
-#define LIST_NEXT(e)   ((e)->next)
-
-#undef LIST_PREV
-#define LIST_PREV(e)   ((e)->prev)
-
 /*
  * Parsed sudoers info.
  */
index 9cb5b63e4a8bfe5c540d014b1a2e65036671b9aa..e34da20bcb98ab5037120ee542cfe14295276f1f 100644 (file)
@@ -269,18 +269,18 @@ main(argc, argv)
     /* This loop must match the one in sudoers_lookup() */
     printf("\nEntries for user %s:\n", user_name);
     matched = UNSPEC;
-    LH_FOREACH_REV(&userspecs, us) {
+    lh_foreach_rev(&userspecs, us) {
        if (userlist_matches(sudo_user.pw, &us->users) != ALLOW)
            continue;
-       LH_FOREACH_REV(&us->privileges, priv) {
+       lh_foreach_rev(&us->privileges, priv) {
            putchar('\n');
            print_privilege(priv); /* XXX */
            putchar('\n');
            if (hostlist_matches(&priv->hostlist) == ALLOW) {
                puts("\thost  matched");
                runas = NULL;
-               LH_FOREACH_REV(&priv->cmndlist, cs) {
-                   if (!LH_EMPTY(&cs->runaslist))
+               lh_foreach_rev(&priv->cmndlist, cs) {
+                   if (!lh_empty(&cs->runaslist))
                        runas = &cs->runaslist;
                    if (runaslist_matches(runas) == ALLOW) {
                        puts("\trunas matched");
@@ -389,7 +389,7 @@ print_defaults()
     struct defaults *d;
     struct member *m;
 
-    LH_FOREACH_FWD(&defaults, d) {
+    lh_foreach_fwd(&defaults, d) {
        (void) fputs("Defaults", stdout);
        switch (d->type) {
            case DEFAULTS_HOST:
@@ -405,8 +405,8 @@ print_defaults()
                putchar('!');
                break;
        }
-       LH_FOREACH_FWD(&d->binding, m) {
-           if (m != LH_FIRST(&d->binding))
+       lh_foreach_fwd(&d->binding, m) {
+           if (m != lh_first(&d->binding))
                putchar(',');
            print_member(m);
        }
@@ -440,8 +440,8 @@ print_alias(v1, v2)
            (void) printf("Runas_Alias\t%s = ", a->name);
            break;
     }
-    LH_FOREACH_FWD(&a->members, m) {
-       if (m != LH_FIRST(&a->members))
+    lh_foreach_fwd(&a->members, m) {
+       if (m != lh_first(&a->members))
            fputs(", ", stdout);
        if (m->type == COMMAND) {
            c = (struct sudo_command *) m->name;
@@ -466,20 +466,20 @@ print_privilege(priv)
     for (p = priv; p != NULL; p = p->next) {
        if (p != priv)
            fputs(" : ", stdout);
-       LH_FOREACH_FWD(&p->hostlist, m) {
-           if (m != LH_FIRST(&p->hostlist))
+       lh_foreach_fwd(&p->hostlist, m) {
+           if (m != lh_first(&p->hostlist))
                fputs(", ", stdout);
            print_member(m);
        }
        fputs(" = ", stdout);
        tags.nopasswd = tags.noexec = UNSPEC;
-       LH_FOREACH_FWD(&p->cmndlist, cs) {
-           if (cs != LH_FIRST(&p->cmndlist))
+       lh_foreach_fwd(&p->cmndlist, cs) {
+           if (cs != lh_first(&p->cmndlist))
                fputs(", ", stdout);
-           if (!LH_EMPTY(&cs->runaslist)) {
+           if (!lh_empty(&cs->runaslist)) {
                fputs("(", stdout);
-               LH_FOREACH_FWD(&cs->runaslist, m) {
-                   if (m != LH_FIRST(&cs->runaslist))
+               lh_foreach_fwd(&cs->runaslist, m) {
+                   if (m != lh_first(&cs->runaslist))
                        fputs(", ", stdout);
                    print_member(m);
                }
@@ -501,9 +501,9 @@ print_userspecs()
     struct member *m;
     struct userspec *us;
 
-    LH_FOREACH_FWD(&userspecs, us) {
-       LH_FOREACH_FWD(&us->users, m) {
-           if (m != LH_FIRST(&us->users))
+    lh_foreach_fwd(&userspecs, us) {
+       lh_foreach_fwd(&us->users, m) {
+           if (m != lh_first(&us->users))
                fputs(", ", stdout);
            print_member(m);
        }
index 3e2bb4f7513249b0a5bb1d943b35f96f62049545..81e1f5f12120588bf594988f8b53fafdf074ec26 100644 (file)
--- a/visudo.c
+++ b/visudo.c
@@ -212,8 +212,8 @@ main(argc, argv)
     setup_signals();
 
     /* Edit the sudoers file(s) */
-    LH_FOREACH_FWD(&sudoerslist, sp) {
-       if (sp != LH_FIRST(&sudoerslist)) {
+    lh_foreach_fwd(&sudoerslist, sp) {
+       if (sp != lh_first(&sudoerslist)) {
            printf("press return to edit %s: ", sp->path);
            while ((ch = getchar()) != EOF && ch != '\n')
                    continue;
@@ -225,7 +225,7 @@ main(argc, argv)
     reparse_sudoers(editor, args, strict, quiet);
 
     /* Install the sudoers temp files. */
-    LH_FOREACH_FWD(&sudoerslist, sp) {
+    lh_foreach_fwd(&sudoerslist, sp) {
        if (!sp->modified)
            (void) unlink(sp->tpath);
        else
@@ -400,8 +400,8 @@ reparse_sudoers(editor, args, strict, quiet)
      * Parse the edited sudoers files and do sanity checking
      */
     do {
-       sp = LH_FIRST(&sudoerslist);
-       last = LH_LAST(&sudoerslist);
+       sp = lh_first(&sudoerslist);
+       last = lh_last(&sudoerslist);
        fp = fopen(sp->tpath, "r+");
        if (fp == NULL)
            errorx(1, "can't re-open temporary file (%s), %s unchanged.",
@@ -437,7 +437,7 @@ reparse_sudoers(editor, args, strict, quiet)
        }
        if (parse_error) {
            /* Edit file with the parse error */
-           LH_FOREACH_FWD(&sudoerslist, sp) {
+           lh_foreach_fwd(&sudoerslist, sp) {
                if (errorfile == NULL || strcmp(sp->path, errorfile) == 0) {
                    edit_sudoers(sp, editor, args, errorlineno);
                    break;
@@ -708,7 +708,7 @@ open_sudoers(path, keepopen)
     FILE *fp;
 
     /* Check for existing entry */
-    LH_FOREACH_FWD(&sudoerslist, entry) {
+    lh_foreach_fwd(&sudoerslist, entry) {
        if (strcmp(path, entry->path) == 0)
            break;
     }
@@ -886,8 +886,8 @@ check_aliases(strict)
     int error = 0;
 
     /* Forward check. */
-    LH_FOREACH_FWD(&userspecs, us) {
-       LH_FOREACH_FWD(&us->users, m) {
+    lh_foreach_fwd(&userspecs, us) {
+       lh_foreach_fwd(&us->users, m) {
            if (m->type == USERALIAS) {
                if (find_alias(m->name, m->type) == NULL) {
                    fprintf(stderr,
@@ -897,8 +897,8 @@ check_aliases(strict)
                }
            }
        }
-       LH_FOREACH_FWD(&us->privileges, priv) {
-           LH_FOREACH_FWD(&priv->hostlist, m) {
+       lh_foreach_fwd(&us->privileges, priv) {
+           lh_foreach_fwd(&priv->hostlist, m) {
                if (m->type == HOSTALIAS) {
                    if (find_alias(m->name, m->type) == NULL) {
                        fprintf(stderr,
@@ -908,8 +908,8 @@ check_aliases(strict)
                    }
                }
            }
-           LH_FOREACH_FWD(&priv->cmndlist, cs) {
-               LH_FOREACH_FWD(&cs->runaslist, m) {
+           lh_foreach_fwd(&priv->cmndlist, cs) {
+               lh_foreach_fwd(&cs->runaslist, m) {
                    if (m->type == RUNASALIAS) {
                        if (find_alias(m->name, m->type) == NULL) {
                            fprintf(stderr,
@@ -932,18 +932,18 @@ check_aliases(strict)
     }
 
     /* Reverse check (destructive) */
-    LH_FOREACH_FWD(&userspecs, us) {
-       LH_FOREACH_FWD(&us->users, m) {
+    lh_foreach_fwd(&userspecs, us) {
+       lh_foreach_fwd(&us->users, m) {
            if (m->type == USERALIAS)
                (void) alias_remove(m->name, m->type);
        }
-       LH_FOREACH_FWD(&us->privileges, priv) {
-           LH_FOREACH_FWD(&priv->hostlist, m) {
+       lh_foreach_fwd(&us->privileges, priv) {
+           lh_foreach_fwd(&priv->hostlist, m) {
                if (m->type == HOSTALIAS)
                    (void) alias_remove(m->name, m->type);
            }
-           LH_FOREACH_FWD(&priv->cmndlist, cs) {
-               LH_FOREACH_FWD(&cs->runaslist, m) {
+           lh_foreach_fwd(&priv->cmndlist, cs) {
+               lh_foreach_fwd(&cs->runaslist, m) {
                    if (m->type == RUNASALIAS)
                        (void) alias_remove(m->name, m->type);
                }
@@ -983,7 +983,7 @@ cleanup(gotsignal)
 {
     struct sudoersfile *sp;
 
-    LH_FOREACH_FWD(&sudoerslist, sp) {
+    lh_foreach_fwd(&sudoerslist, sp) {
        if (sp->tpath != NULL)
            (void) unlink(sp->tpath);
     }