]> granicus.if.org Git - sudo/commitdiff
o Add a new LIST type and functions to manipulate it.
authorTodd C. Miller <Todd.Miller@courtesan.com>
Tue, 11 Dec 2001 23:00:34 +0000 (23:00 +0000)
committerTodd C. Miller <Todd.Miller@courtesan.com>
Tue, 11 Dec 2001 23:00:34 +0000 (23:00 +0000)
 o This is for use with environment handling variables.
 o Call new init_envtables() routine inside init_defaults() to
   initialize the environment lists.

defaults.c
defaults.h

index 7d2f6cace62875506e0153daa88b4624e7b6d26f..cd51028104dfc8e87f167078091a4ae2a233f90c 100644 (file)
@@ -34,6 +34,7 @@
 
 #include "config.h"
 
+#include <ctype.h>
 #include <stdio.h>
 #ifdef STDC_HEADERS
 #include <stdlib.h>
@@ -108,11 +109,13 @@ static int store_syslogfac __P((char *, struct sudo_defs_types *, int));
 static int store_syslogpri __P((char *, struct sudo_defs_types *, int));
 static int store_mode __P((char *, struct sudo_defs_types *, int));
 static int store_pwflag __P((char *, struct sudo_defs_types *, int));
+static int store_list __P((char *, struct sudo_defs_types *, int));
+static void list_op __P((char *, size_t, struct sudo_defs_types *, enum list_ops));
 
 /*
  * Table describing compile-time and run-time options.
  */
-#include "def_data.c"
+#include <def_data.c>
 
 /*
  * Print version and configure info.
@@ -121,6 +124,7 @@ void
 dump_defaults()
 {
     struct sudo_defs_types *cur;
+    struct list_member *item;
 
     for (cur = sudo_defs_table; cur->name; cur++) {
        if (cur->desc) {
@@ -147,6 +151,13 @@ dump_defaults()
                    (void) printf(cur->desc, cur->sd_un.mode);
                    putchar('\n');
                    break;
+               case T_LIST:
+                   if (cur->sd_un.list) {
+                       puts(cur->desc);
+                       for (item = cur->sd_un.list; item; item = item->next)
+                           printf("\t%s\n", item->value);
+                   }
+                   break;
            }
        }
     }
@@ -335,6 +346,22 @@ set_default(var, val, op)
            if (num == I_FQDN && op)
                set_fqdn();
            break;
+       case T_LIST:
+           if (!val) {
+               /* Check for bogus boolean usage or lack of a value. */
+               if (!(cur->type & T_BOOL) || op != FALSE) {
+                   (void) fprintf(stderr,
+                       "%s: no value specified for `%s' on line %d\n", Argv[0],
+                       var, sudolineno);
+                   return(FALSE);
+               }
+           }
+           if (!store_list(val, cur, op)) {
+               (void) fprintf(stderr,
+                   "%s: value '%s' is invalid for option '%s'\n", Argv[0],
+                   val, var);
+               return(FALSE);
+           }
     }
 
     return(TRUE);
@@ -363,6 +390,9 @@ init_defaults()
                        def->sd_un.str = NULL;
                    }
                    break;
+               case T_LIST:
+                   list_op(NULL, 0, def, freeall);
+                   break;
            }
     }
 
@@ -444,7 +474,7 @@ init_defaults()
     def_ival(I_PASSWD_TIMEOUT) = PASSWORD_TIMEOUT;
     def_ival(I_PASSWD_TRIES) = TRIES_FOR_PASSWORD;
 
-    /* Finally do the strings */
+    /* Now do the strings */
     def_str(I_MAILTO) = estrdup(MAILTO);
     def_str(I_MAILSUB) = estrdup(MAILSUBJECT);
     def_str(I_BADPASS_MESSAGE) = estrdup(INCORRECT_PASSWORD);
@@ -466,6 +496,9 @@ init_defaults()
 #endif
     def_str(I_EDITOR) = estrdup(EDITOR);
 
+    /* Finally do the lists (currently just environment tables). */
+    init_envtables();
+
     /*
      * The following depend on the above values.
      * We use a pointer to the string so that if its
@@ -535,6 +568,34 @@ store_str(val, def, op)
     return(TRUE);
 }
 
+static int
+store_list(str, def, op)
+    char *str;
+    struct sudo_defs_types *def;
+    int op;
+{
+    char *start, *end;
+
+    /* Remove all old members. */
+    if (op == FALSE || op == TRUE)
+       list_op(NULL, 0, def, freeall);
+
+    /* Split str into multiple space-separated words and act on each one. */
+    if (op != FALSE) {
+       for (start = str; isblank(*start); start++)
+           ;
+       while ((end = strpbrk(start, " \t"))) {
+           list_op(start, end - start, def, op == '-' ? delete : add);
+           start = end;
+           for (; isblank(*start); start++)
+               ;
+       }
+       if (*start)
+           list_op(start, strlen(start), def, op == '-' ? delete : add);
+    }
+    return(TRUE);
+}
+
 static int
 store_syslogfac(val, def, op)
     char *val;
@@ -668,3 +729,49 @@ store_pwflag(val, def, op)
 
     return(TRUE);
 }
+
+static void
+list_op(val, len, def, op)
+    char *val;
+    size_t len;
+    struct sudo_defs_types *def;
+    enum list_ops op;
+{
+    struct list_member *cur, *prev, *tmp;
+
+    if (op == freeall) {
+       for (cur = def->sd_un.list; cur; ) {
+           tmp = cur;
+           cur = tmp->next;
+           free(tmp->value);
+           free(tmp);
+       }
+       def->sd_un.list = NULL;
+       return;
+    }
+
+    for (cur = def->sd_un.list, prev = NULL; cur; prev = cur, cur = cur->next) {
+       if ((strncmp(cur->value, val, len) == 0 && cur->value[len] == '\0')) {
+
+           if (op == add)
+               return;                 /* already exists */
+
+           /* Delete node */
+           if (prev != NULL)
+               prev->next = cur->next;
+           else
+               def->sd_un.list = cur->next;
+           free(cur->value);
+           free(cur);
+           break;
+       }
+    }
+
+    /* Add new node to the head of the list. */
+    if (op == add) {
+       cur = emalloc(sizeof(struct list_member));
+       cur->value = estrdup(val);
+       cur->next = def->sd_un.list;
+       def->sd_un.list = cur;
+    }
+}
index dbbe89a93b976375b9cc682b809ed2738813d1bc..fd3e44b3a473644d02f67c6de6241a0e63fd3af0 100644 (file)
 #ifndef _SUDO_DEFAULTS_H
 #define _SUDO_DEFAULTS_H
 
+struct list_member {
+    char *value;
+    struct list_member *next;
+};
+
+enum list_ops {
+    add,
+    delete,
+    freeall
+};
+
 /*
  * Structure describing compile-time and run-time options.
  */
@@ -49,6 +60,7 @@ struct sudo_defs_types {
        int ival;
        char *str;
        mode_t mode;
+       struct list_member *list;
     } sd_un;
 };
 
@@ -67,12 +79,14 @@ struct sudo_defs_types {
 #define T_FLAG         0x004
 #undef T_MODE
 #define T_MODE         0x005
+#undef T_LIST
+#define T_LIST         0x006
 #undef T_LOGFAC
-#define T_LOGFAC       0x006
+#define T_LOGFAC       0x007
 #undef T_LOGPRI
-#define T_LOGPRI       0x007
+#define T_LOGPRI       0x008
 #undef T_PWFLAG
-#define T_PWFLAG       0x008
+#define T_PWFLAG       0x009
 #undef T_MASK
 #define T_MASK         0x0FF
 #undef T_BOOL
@@ -83,7 +97,7 @@ struct sudo_defs_types {
 /*
  * Indexes into sudo_defs_table
  */
-#include "def_data.h"
+#include <def_data.h>
 #define I_LOGFAC       I_SYSLOG_IFAC
 #define I_GOODPRI      I_SYSLOG_IGOODPRI
 #define I_BADPRI       I_SYSLOG_IBADPRI 
@@ -94,6 +108,7 @@ struct sudo_defs_types {
 #define def_flag(_i)   (sudo_defs_table[(_i)].sd_un.flag)
 #define def_ival(_i)   (sudo_defs_table[(_i)].sd_un.ival)
 #define def_str(_i)    (sudo_defs_table[(_i)].sd_un.str)
+#define def_list(_i)   (sudo_defs_table[(_i)].sd_un.list)
 #define def_mode(_i)   (sudo_defs_table[(_i)].sd_un.mode)
 
 /*