param: correctly use param_table.c as a regular C file
[mat/samba.git] / source3 / param / loadparm.c
index fdc4d52eeb4db40da2bc13d3a0eb2478911936b1..100ef8d2e94cb4753efc24e6226666ed5de0779a 100644 (file)
@@ -256,29 +256,15 @@ static int iServiceIndex = 0;
 static struct db_context *ServiceHash;
 static bool bInGlobalSection = true;
 static bool bGlobalOnly = false;
+static struct file_lists *file_lists = NULL;
 
-#define NUMPARAMETERS (sizeof(parm_table) / sizeof(struct parm_struct))
-
-/* prototypes for the special type handlers */
-static bool handle_include(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr);
-static bool handle_copy(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr);
-static bool handle_idmap_backend(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr);
-static bool handle_idmap_uid(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr);
-static bool handle_idmap_gid(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr);
-static bool handle_netbios_aliases(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr );
-static bool handle_charset(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr );
-static bool handle_dos_charset(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr );
-static bool handle_printing(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr);
-static bool handle_ldap_debug_level(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr);
+#define NUMPARAMETERS (num_parameters())
 
 static void set_allowed_client_auth(void);
 
-static void add_to_file_list(const char *fname, const char *subfname);
 static bool lp_set_cmdline_helper(const char *pszParmName, const char *pszParmValue, bool store_values);
 static void free_param_opts(struct parmlist_entry **popts);
 
-#include "lib/param/param_table.c"
-
 /* this is used to prevent lots of mallocs of size 1 */
 static const char null_string[] = "";
 
@@ -325,7 +311,7 @@ bool lp_string_set(char **dest, const char *src) {
  Initialise the sDefault parameter structure for the printer values.
 ***************************************************************************/
 
-static void init_printer_values(TALLOC_CTX *ctx, struct loadparm_service *pService)
+void init_printer_values(TALLOC_CTX *ctx, struct loadparm_service *pService)
 {
        /* choose defaults depending on the type of printing */
        switch (pService->printing) {
@@ -333,52 +319,52 @@ static void init_printer_values(TALLOC_CTX *ctx, struct loadparm_service *pServi
                case PRINT_AIX:
                case PRINT_LPRNT:
                case PRINT_LPROS2:
-                       string_set(ctx, &pService->lpq_command, "lpq -P'%p'");
-                       string_set(ctx, &pService->lprm_command, "lprm -P'%p' %j");
-                       string_set(ctx, &pService->print_command, "lpr -r -P'%p' %s");
+                       lpcfg_string_set(ctx, &pService->lpq_command, "lpq -P'%p'");
+                       lpcfg_string_set(ctx, &pService->lprm_command, "lprm -P'%p' %j");
+                       lpcfg_string_set(ctx, &pService->print_command, "lpr -r -P'%p' %s");
                        break;
 
                case PRINT_LPRNG:
                case PRINT_PLP:
-                       string_set(ctx, &pService->lpq_command, "lpq -P'%p'");
-                       string_set(ctx, &pService->lprm_command, "lprm -P'%p' %j");
-                       string_set(ctx, &pService->print_command, "lpr -r -P'%p' %s");
-                       string_set(ctx, &pService->queuepause_command, "lpc stop '%p'");
-                       string_set(ctx, &pService->queueresume_command, "lpc start '%p'");
-                       string_set(ctx, &pService->lppause_command, "lpc hold '%p' %j");
-                       string_set(ctx, &pService->lpresume_command, "lpc release '%p' %j");
+                       lpcfg_string_set(ctx, &pService->lpq_command, "lpq -P'%p'");
+                       lpcfg_string_set(ctx, &pService->lprm_command, "lprm -P'%p' %j");
+                       lpcfg_string_set(ctx, &pService->print_command, "lpr -r -P'%p' %s");
+                       lpcfg_string_set(ctx, &pService->queuepause_command, "lpc stop '%p'");
+                       lpcfg_string_set(ctx, &pService->queueresume_command, "lpc start '%p'");
+                       lpcfg_string_set(ctx, &pService->lppause_command, "lpc hold '%p' %j");
+                       lpcfg_string_set(ctx, &pService->lpresume_command, "lpc release '%p' %j");
                        break;
 
                case PRINT_CUPS:
                case PRINT_IPRINT:
                        /* set the lpq command to contain the destination printer
                           name only.  This is used by cups_queue_get() */
-                       string_set(ctx, &pService->lpq_command, "%p");
-                       string_set(ctx, &pService->lprm_command, "");
-                       string_set(ctx, &pService->print_command, "");
-                       string_set(ctx, &pService->lppause_command, "");
-                       string_set(ctx, &pService->lpresume_command, "");
-                       string_set(ctx, &pService->queuepause_command, "");
-                       string_set(ctx, &pService->queueresume_command, "");
+                       lpcfg_string_set(ctx, &pService->lpq_command, "%p");
+                       lpcfg_string_set(ctx, &pService->lprm_command, "");
+                       lpcfg_string_set(ctx, &pService->print_command, "");
+                       lpcfg_string_set(ctx, &pService->lppause_command, "");
+                       lpcfg_string_set(ctx, &pService->lpresume_command, "");
+                       lpcfg_string_set(ctx, &pService->queuepause_command, "");
+                       lpcfg_string_set(ctx, &pService->queueresume_command, "");
                        break;
 
                case PRINT_SYSV:
                case PRINT_HPUX:
-                       string_set(ctx, &pService->lpq_command, "lpstat -o%p");
-                       string_set(ctx, &pService->lprm_command, "cancel %p-%j");
-                       string_set(ctx, &pService->print_command, "lp -c -d%p %s; rm %s");
-                       string_set(ctx, &pService->queuepause_command, "disable %p");
-                       string_set(ctx, &pService->queueresume_command, "enable %p");
+                       lpcfg_string_set(ctx, &pService->lpq_command, "lpstat -o%p");
+                       lpcfg_string_set(ctx, &pService->lprm_command, "cancel %p-%j");
+                       lpcfg_string_set(ctx, &pService->print_command, "lp -c -d%p %s; rm %s");
+                       lpcfg_string_set(ctx, &pService->queuepause_command, "disable %p");
+                       lpcfg_string_set(ctx, &pService->queueresume_command, "enable %p");
 #ifndef HPUX
-                       string_set(ctx, &pService->lppause_command, "lp -i %p-%j -H hold");
-                       string_set(ctx, &pService->lpresume_command, "lp -i %p-%j -H resume");
+                       lpcfg_string_set(ctx, &pService->lppause_command, "lp -i %p-%j -H hold");
+                       lpcfg_string_set(ctx, &pService->lpresume_command, "lp -i %p-%j -H resume");
 #endif /* HPUX */
                        break;
 
                case PRINT_QNX:
-                       string_set(ctx, &pService->lpq_command, "lpq -P%p");
-                       string_set(ctx, &pService->lprm_command, "lprm -P%p %j");
-                       string_set(ctx, &pService->print_command, "lp -r -P%p %s");
+                       lpcfg_string_set(ctx, &pService->lpq_command, "lpq -P%p");
+                       lpcfg_string_set(ctx, &pService->lprm_command, "lprm -P%p %j");
+                       lpcfg_string_set(ctx, &pService->print_command, "lp -r -P%p %s");
                        break;
 
 #if defined(DEVELOPER) || defined(ENABLE_SELFTEST)
@@ -386,7 +372,7 @@ static void init_printer_values(TALLOC_CTX *ctx, struct loadparm_service *pServi
        case PRINT_TEST:
        case PRINT_VLP: {
                const char *tdbfile;
-               TALLOC_CTX *tmp_ctx = talloc_stackframe();
+               TALLOC_CTX *tmp_ctx = talloc_new(ctx);
                char *tmp;
 
                tdbfile = talloc_asprintf(
@@ -399,37 +385,37 @@ static void init_printer_values(TALLOC_CTX *ctx, struct loadparm_service *pServi
 
                tmp = talloc_asprintf(tmp_ctx, "vlp %s print %%p %%s",
                                      tdbfile);
-               string_set(ctx, &pService->print_command,
+               lpcfg_string_set(ctx, &pService->print_command,
                           tmp ? tmp : "vlp print %p %s");
 
                tmp = talloc_asprintf(tmp_ctx, "vlp %s lpq %%p",
                                      tdbfile);
-               string_set(ctx, &pService->lpq_command,
+               lpcfg_string_set(ctx, &pService->lpq_command,
                           tmp ? tmp : "vlp lpq %p");
 
                tmp = talloc_asprintf(tmp_ctx, "vlp %s lprm %%p %%j",
                                      tdbfile);
-               string_set(ctx, &pService->lprm_command,
+               lpcfg_string_set(ctx, &pService->lprm_command,
                           tmp ? tmp : "vlp lprm %p %j");
 
                tmp = talloc_asprintf(tmp_ctx, "vlp %s lppause %%p %%j",
                                      tdbfile);
-               string_set(ctx, &pService->lppause_command,
+               lpcfg_string_set(ctx, &pService->lppause_command,
                           tmp ? tmp : "vlp lppause %p %j");
 
                tmp = talloc_asprintf(tmp_ctx, "vlp %s lpresume %%p %%j",
                                      tdbfile);
-               string_set(ctx, &pService->lpresume_command,
+               lpcfg_string_set(ctx, &pService->lpresume_command,
                           tmp ? tmp : "vlp lpresume %p %j");
 
                tmp = talloc_asprintf(tmp_ctx, "vlp %s queuepause %%p",
                                      tdbfile);
-               string_set(ctx, &pService->queuepause_command,
+               lpcfg_string_set(ctx, &pService->queuepause_command,
                           tmp ? tmp : "vlp queuepause %p");
 
                tmp = talloc_asprintf(tmp_ctx, "vlp %s queueresume %%p",
                                      tdbfile);
-               string_set(ctx, &pService->queueresume_command,
+               lpcfg_string_set(ctx, &pService->queueresume_command,
                           tmp ? tmp : "vlp queueresume %p");
                TALLOC_FREE(tmp_ctx);
 
@@ -1174,15 +1160,9 @@ FN_LOCAL_BOOL(autoloaded, autoloaded)
 
 static int map_parameter_canonical(const char *pszParmName, bool *inverse);
 static const char *get_boolean(bool bool_value);
-static int getservicebyname(const char *pszServiceName,
-                           struct loadparm_service *pserviceDest);
-static void copy_service(struct loadparm_service *pserviceDest,
-                        struct loadparm_service *pserviceSource,
-                        struct bitmap *pcopymapDest);
 static bool do_parameter(const char *pszParmName, const char *pszParmValue,
                         void *userdata);
 static bool do_section(const char *pszSectionName, void *userdata);
-static void init_copymap(struct loadparm_service *pservice);
 static bool hash_a_service(const char *name, int number);
 static void free_service_byindex(int iService);
 static void show_parameter(int parmIndex);
@@ -1262,54 +1242,6 @@ static struct parmlist_entry *get_parametrics(int snum, const char *type,
 #define MISSING_PARAMETER(name) \
     DEBUG(0, ("%s(): value is NULL or empty!\n", #name))
 
-/*******************************************************************
-convenience routine to return int parameters.
-********************************************************************/
-static int lp_int(const char *s)
-{
-
-       if (!s || !*s) {
-               MISSING_PARAMETER(lp_int);
-               return (-1);
-       }
-
-       return (int)strtol(s, NULL, 0);
-}
-
-/*******************************************************************
-convenience routine to return unsigned long parameters.
-********************************************************************/
-static unsigned long lp_ulong(const char *s)
-{
-
-       if (!s || !*s) {
-               MISSING_PARAMETER(lp_ulong);
-               return (0);
-       }
-
-       return strtoul(s, NULL, 0);
-}
-
-/*******************************************************************
-convenience routine to return boolean parameters.
-********************************************************************/
-static bool lp_bool(const char *s)
-{
-       bool ret = false;
-
-       if (!s || !*s) {
-               MISSING_PARAMETER(lp_bool);
-               return false;
-       }
-
-       if (!set_boolean(s, &ret)) {
-               DEBUG(0,("lp_bool(%s): value is not boolean!\n",s));
-               return false;
-       }
-
-       return ret;
-}
-
 /*******************************************************************
 convenience routine to return enum parameters.
 ********************************************************************/
@@ -1362,12 +1294,14 @@ const char *lp_parm_const_string(int snum, const char *type, const char *option,
        return data->value;
 }
 
-const char *lp_parm_const_string_service(struct loadparm_service *service, const char *type, const char *option)
+const char *lp_parm_const_string_service(struct loadparm_service *service,
+                                        const char *type, const char *option,
+                                        const char *def)
 {
        struct parmlist_entry *data = get_parametrics_by_service(service, type, option);
 
        if (data == NULL||data->value==NULL)
-               return NULL;
+               return def;
 
        return data->value;
 }
@@ -1443,18 +1377,6 @@ int lp_parm_enum(int snum, const char *type, const char *option,
        return def;
 }
 
-
-/***************************************************************************
- Initialise a service to the defaults.
-***************************************************************************/
-
-static void init_service(struct loadparm_service *pservice)
-{
-       memset((char *)pservice, '\0', sizeof(struct loadparm_service));
-       copy_service(pservice, &sDefault, NULL);
-}
-
-
 /**
  * free a param_opts structure.
  * param_opts handling should be moved to talloc;
@@ -1539,12 +1461,9 @@ static void free_service_byindex(int idx)
 static int add_a_service(const struct loadparm_service *pservice, const char *name)
 {
        int i;
-       struct loadparm_service tservice;
        int num_to_alloc = iNumServices + 1;
        struct loadparm_service **tsp = NULL;
 
-       tservice = *pservice;
-
        /* it might already exist */
        if (name) {
                i = getservicebyname(name, NULL);
@@ -1561,7 +1480,7 @@ static int add_a_service(const struct loadparm_service *pservice, const char *na
                return (-1);
        }
        ServicePtrs = tsp;
-       ServicePtrs[iNumServices] = talloc(NULL, struct loadparm_service);
+       ServicePtrs[iNumServices] = talloc_zero(NULL, struct loadparm_service);
        if (!ServicePtrs[iNumServices]) {
                DEBUG(0,("add_a_service: out of memory!\n"));
                return (-1);
@@ -1570,8 +1489,7 @@ static int add_a_service(const struct loadparm_service *pservice, const char *na
 
        ServicePtrs[i]->valid = true;
 
-       init_service(ServicePtrs[i]);
-       copy_service(ServicePtrs[i], &tservice, NULL);
+       copy_service(ServicePtrs[i], pservice, NULL);
        if (name)
                string_set(ServicePtrs[i], &ServicePtrs[i]->szService, name);
 
@@ -2092,7 +2010,7 @@ bool lp_canonicalize_boolean(const char *str, const char**canon_str)
 Find a service by name. Otherwise works like get_service.
 ***************************************************************************/
 
-static int getservicebyname(const char *pszServiceName, struct loadparm_service *pserviceDest)
+int getservicebyname(const char *pszServiceName, struct loadparm_service *pserviceDest)
 {
        int iService = -1;
        char *canon_name;
@@ -2148,141 +2066,6 @@ struct loadparm_service *lp_default_loadparm_service()
        return &sDefault;
 }
 
-
-/***************************************************************************
- Copy a service structure to another.
- If pcopymapDest is NULL then copy all fields
-***************************************************************************/
-
-/**
- * Add a parametric option to a parmlist_entry,
- * replacing old value, if already present.
- */
-static void set_param_opt(struct parmlist_entry **opt_list,
-                         const char *opt_name,
-                         const char *opt_value,
-                         unsigned priority)
-{
-       struct parmlist_entry *new_opt, *opt;
-       bool not_added;
-
-       opt = *opt_list;
-       not_added = true;
-
-       /* Traverse destination */
-       while (opt) {
-               /* If we already have same option, override it */
-               if (strwicmp(opt->key, opt_name) == 0) {
-                       if ((opt->priority & FLAG_CMDLINE) &&
-                           !(priority & FLAG_CMDLINE)) {
-                               /* it's been marked as not to be
-                                  overridden */
-                               return;
-                       }
-                       string_free(&opt->value);
-                       TALLOC_FREE(opt->list);
-
-                       opt->value = talloc_strdup(NULL, opt_value);
-                       if (opt->value == NULL) {
-                               smb_panic("talloc_strdup failed");
-                       }
-
-                       opt->priority = priority;
-                       not_added = false;
-                       break;
-               }
-               opt = opt->next;
-       }
-       if (not_added) {
-               new_opt = talloc(NULL, struct parmlist_entry);
-               if (new_opt == NULL) {
-                       smb_panic("OOM");
-               }
-
-               new_opt->key = talloc_strdup(NULL, opt_name);
-               if (new_opt->key == NULL) {
-                       smb_panic("talloc_strdup failed");
-               }
-
-               new_opt->value = talloc_strdup(NULL, opt_value);
-               if (new_opt->value == NULL) {
-                       smb_panic("talloc_strdup failed");
-               }
-
-               new_opt->list = NULL;
-               new_opt->priority = priority;
-               DLIST_ADD(*opt_list, new_opt);
-       }
-}
-
-static void copy_service(struct loadparm_service *pserviceDest, struct loadparm_service *pserviceSource,
-                        struct bitmap *pcopymapDest)
-{
-       int i;
-       bool bcopyall = (pcopymapDest == NULL);
-       struct parmlist_entry *data;
-
-       for (i = 0; parm_table[i].label; i++)
-               if (parm_table[i].p_class == P_LOCAL &&
-                   (bcopyall || bitmap_query(pcopymapDest,i))) {
-                       void *src_ptr = lp_parm_ptr(pserviceSource, &parm_table[i]);
-                       void *dest_ptr = lp_parm_ptr(pserviceDest, &parm_table[i]);
-
-                       switch (parm_table[i].type) {
-                               case P_BOOL:
-                               case P_BOOLREV:
-                                       *(bool *)dest_ptr = *(bool *)src_ptr;
-                                       break;
-
-                               case P_INTEGER:
-                               case P_ENUM:
-                               case P_OCTAL:
-                               case P_BYTES:
-                                       *(int *)dest_ptr = *(int *)src_ptr;
-                                       break;
-
-                               case P_CHAR:
-                                       *(char *)dest_ptr = *(char *)src_ptr;
-                                       break;
-
-                               case P_STRING:
-                                       string_set(pserviceDest, (char **)dest_ptr,
-                                                  *(char **)src_ptr);
-                                       break;
-
-                               case P_USTRING:
-                               {
-                                       char *upper_string = strupper_talloc(talloc_tos(), 
-                                                                            *(char **)src_ptr);
-                                       string_set(pserviceDest, (char **)dest_ptr,
-                                                  upper_string);
-                                       TALLOC_FREE(upper_string);
-                                       break;
-                               }
-                               case P_LIST:
-                                       TALLOC_FREE(*((char ***)dest_ptr));
-                                       *((char ***)dest_ptr) = str_list_copy(NULL, 
-                                                     *(const char ***)src_ptr);
-                                       break;
-                               default:
-                                       break;
-                       }
-               }
-
-       if (bcopyall) {
-               init_copymap(pserviceDest);
-               if (pserviceSource->copymap)
-                       bitmap_copy(pserviceDest->copymap,
-                                   pserviceSource->copymap);
-       }
-
-       data = pserviceSource->param_opt;
-       while (data) {
-               set_param_opt(&pserviceDest->param_opt, data->key, data->value, data->priority);
-               data = data->next;
-       }
-}
-
 /***************************************************************************
 Check a service for consistency. Return false if the service is in any way
 incomplete or faulty, else true.
@@ -2424,7 +2207,7 @@ static bool process_registry_globals(void)
 {
        bool ret;
 
-       add_to_file_list(INCLUDE_REGISTRY_NAME, INCLUDE_REGISTRY_NAME);
+       add_to_file_list(NULL, &file_lists, INCLUDE_REGISTRY_NAME, INCLUDE_REGISTRY_NAME);
 
        ret = do_parameter("registry shares", "yes", NULL);
        if (!ret) {
@@ -2506,58 +2289,6 @@ done:
 
 static uint8_t include_depth;
 
-static struct file_lists {
-       struct file_lists *next;
-       char *name;
-       char *subfname;
-       time_t modtime;
-} *file_lists = NULL;
-
-/*******************************************************************
- Keep a linked list of all config files so we know when one has changed 
- it's date and needs to be reloaded.
-********************************************************************/
-
-static void add_to_file_list(const char *fname, const char *subfname)
-{
-       struct file_lists *f = file_lists;
-
-       while (f) {
-               if (f->name && !strcmp(f->name, fname))
-                       break;
-               f = f->next;
-       }
-
-       if (!f) {
-               f = talloc(NULL, struct file_lists);
-               if (!f) {
-                       goto fail;
-               }
-               f->next = file_lists;
-               f->name = talloc_strdup(f, fname);
-               if (!f->name) {
-                       TALLOC_FREE(f);
-                       goto fail;
-               }
-               f->subfname = talloc_strdup(f, subfname);
-               if (!f->subfname) {
-                       TALLOC_FREE(f);
-                       goto fail;
-               }
-               file_lists = f;
-               f->modtime = file_modtime(subfname);
-       } else {
-               time_t t = file_modtime(subfname);
-               if (t)
-                       f->modtime = t;
-       }
-       return;
-
-fail:
-       DEBUG(0, ("Unable to add file to file list: %s\n", fname));
-
-}
-
 /**
  * Free the file lists
  */
@@ -2670,65 +2401,12 @@ static void init_iconv(void)
                                                      true, global_iconv_handle);
 }
 
-static bool handle_charset(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr)
-{
-       if (strcmp(*ptr, pszParmValue) != 0) {
-               string_set(Globals.ctx, ptr, pszParmValue);
-               init_iconv();
-       }
-       return true;
-}
-
-static bool handle_dos_charset(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr)
-{
-       bool is_utf8 = false;
-       size_t len = strlen(pszParmValue);
-
-       if (len == 4 || len == 5) {
-               /* Don't use StrCaseCmp here as we don't want to
-                  initialize iconv. */
-               if ((toupper_m(pszParmValue[0]) == 'U') &&
-                   (toupper_m(pszParmValue[1]) == 'T') &&
-                   (toupper_m(pszParmValue[2]) == 'F')) {
-                       if (len == 4) {
-                               if (pszParmValue[3] == '8') {
-                                       is_utf8 = true;
-                               }
-                       } else {
-                               if (pszParmValue[3] == '-' &&
-                                   pszParmValue[4] == '8') {
-                                       is_utf8 = true;
-                               }
-                       }
-               }
-       }
-
-       if (strcmp(*ptr, pszParmValue) != 0) {
-               if (is_utf8) {
-                       DEBUG(0,("ERROR: invalid DOS charset: 'dos charset' must not "
-                               "be UTF8, using (default value) %s instead.\n",
-                               DEFAULT_DOS_CHARSET));
-                       pszParmValue = DEFAULT_DOS_CHARSET;
-               }
-               string_set(Globals.ctx, ptr, pszParmValue);
-               init_iconv();
-       }
-       return true;
-}
-
-static bool handle_netbios_aliases(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr)
-{
-       TALLOC_FREE(Globals.netbios_aliases);
-       Globals.netbios_aliases = (const char **)str_list_make_v3(NULL, pszParmValue, NULL);
-       return set_netbios_aliases(Globals.netbios_aliases);
-}
-
 /***************************************************************************
  Handle the include operation.
 ***************************************************************************/
 static bool bAllowIncludeRegistry = true;
 
-static bool handle_include(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr)
+bool lp_include(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr)
 {
        char *fname;
 
@@ -2759,7 +2437,7 @@ static bool handle_include(struct loadparm_context *unused, int snum, const char
                                 current_user_info.domain,
                                 pszParmValue);
 
-       add_to_file_list(pszParmValue, fname);
+       add_to_file_list(NULL, &file_lists, pszParmValue, fname);
 
        if (snum < 0) {
                string_set(Globals.ctx, ptr, fname);
@@ -2781,69 +2459,6 @@ static bool handle_include(struct loadparm_context *unused, int snum, const char
        return true;
 }
 
-/***************************************************************************
- Handle the interpretation of the copy parameter.
-***************************************************************************/
-
-static bool handle_copy(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr)
-{
-       bool bRetval;
-       int iTemp;
-
-       bRetval = false;
-
-       DEBUG(3, ("Copying service from service %s\n", pszParmValue));
-
-       if ((iTemp = getservicebyname(pszParmValue, NULL)) >= 0) {
-               if (iTemp == iServiceIndex) {
-                       DEBUG(0, ("Can't copy service %s - unable to copy self!\n", pszParmValue));
-               } else {
-                       copy_service(ServicePtrs[iServiceIndex],
-                                    ServicePtrs[iTemp],
-                                    ServicePtrs[iServiceIndex]->copymap);
-                       string_set(ServicePtrs[iServiceIndex], ptr, pszParmValue);
-                       bRetval = true;
-               }
-       } else {
-               DEBUG(0, ("Unable to copy service - source not found: %s\n", pszParmValue));
-               bRetval = false;
-       }
-
-       return (bRetval);
-}
-
-static bool handle_ldap_debug_level(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr)
-{
-       Globals.ldap_debug_level = lp_int(pszParmValue);
-       init_ldap_debugging();
-       return true;
-}
-
-/*
- * idmap related parameters
- */
-
-static bool handle_idmap_backend(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr)
-{
-       lp_do_parameter(snum, "idmap config * : backend", pszParmValue);
-
-       return true;
-}
-
-static bool handle_idmap_uid(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr)
-{
-       lp_do_parameter(snum, "idmap config * : range", pszParmValue);
-
-       return true;
-}
-
-static bool handle_idmap_gid(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr)
-{
-       lp_do_parameter(snum, "idmap config * : range", pszParmValue);
-
-       return true;
-}
-
 bool lp_idmap_range(const char *domain_name, uint32_t *low, uint32_t *high)
 {
        char *config_option = NULL;
@@ -2971,70 +2586,6 @@ const char *lp_ldap_idmap_suffix(TALLOC_CTX *ctx)
        return lp_string(ctx, Globals.ldap_suffix);
 }
 
-/****************************************************************************
- set the value for a P_ENUM
- ***************************************************************************/
-
-static void lp_set_enum_parm( struct parm_struct *parm, const char *pszParmValue,
-                              int *ptr )
-{
-       int i;
-
-       for (i = 0; parm->enum_list[i].name; i++) {
-               if ( strequal(pszParmValue, parm->enum_list[i].name)) {
-                       *ptr = parm->enum_list[i].value;
-                       return;
-               }
-       }
-       DEBUG(0, ("WARNING: Ignoring invalid value '%s' for parameter '%s'\n",
-                 pszParmValue, parm->label));
-}
-
-/***************************************************************************
-***************************************************************************/
-
-static bool handle_printing(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr)
-{
-       static int parm_num = -1;
-       struct loadparm_service *s;
-
-       if ( parm_num == -1 )
-               parm_num = lpcfg_map_parameter( "printing" );
-
-       lp_set_enum_parm( &parm_table[parm_num], pszParmValue, (int*)ptr );
-
-       if ( snum < 0 ) {
-               s = &sDefault;
-               init_printer_values(Globals.ctx, s);
-       } else {
-               s = ServicePtrs[snum];
-               init_printer_values(s, s);
-       }
-
-       return true;
-}
-
-
-/***************************************************************************
- Initialise a copymap.
-***************************************************************************/
-
-static void init_copymap(struct loadparm_service *pservice)
-{
-       int i;
-
-       TALLOC_FREE(pservice->copymap);
-
-       pservice->copymap = bitmap_talloc(NULL, NUMPARAMETERS);
-       if (!pservice->copymap)
-               DEBUG(0,
-                     ("Couldn't allocate copymap!! (size %d)\n",
-                      (int)NUMPARAMETERS));
-       else
-               for (i = 0; i < NUMPARAMETERS; i++)
-                       bitmap_set(pservice->copymap, i);
-}
-
 /**
   return the parameter pointer for a parameter
 */
@@ -3085,9 +2636,13 @@ bool lp_do_parameter(int snum, const char *pszParmName, const char *pszParmValue
                 * We've got a parametric option
                 */
 
-               opt_list = (snum < 0)
-                       ? &Globals.param_opt : &ServicePtrs[snum]->param_opt;
-               set_param_opt(opt_list, pszParmName, pszParmValue, 0);
+               if (snum < 0) {
+                       opt_list = &Globals.param_opt;
+                       set_param_opt(NULL, opt_list, pszParmName, pszParmValue, 0);
+               } else {
+                       opt_list = &ServicePtrs[snum]->param_opt;
+                       set_param_opt(ServicePtrs[snum], opt_list, pszParmName, pszParmValue, 0);
+               }
 
                return true;
        }
@@ -3138,6 +2693,8 @@ bool lp_do_parameter(int snum, const char *pszParmName, const char *pszParmValue
                bool ok;
                struct loadparm_context *lp_ctx = loadparm_init_s3(talloc_tos(),
                                                                   loadparm_s3_helpers());
+               lp_ctx->sDefault = &sDefault;
+               lp_ctx->services = ServicePtrs;
                ok = parm_table[parmnum].special(lp_ctx, snum, pszParmValue,
                                                  (char **)parm_ptr);
                TALLOC_FREE(lp_ctx);
@@ -3206,7 +2763,9 @@ bool lp_do_parameter(int snum, const char *pszParmName, const char *pszParmValue
                        break;
                }
                case P_ENUM:
-                       lp_set_enum_parm( &parm_table[parmnum], pszParmValue, (int*)parm_ptr );
+                       if (!lp_set_enum_parm(&parm_table[parmnum], pszParmValue, (int*)parm_ptr)) {
+                               return false;
+                       }
                        break;
                case P_SEP:
                        break;
@@ -3253,7 +2812,7 @@ static bool lp_set_cmdline_helper(const char *pszParmName, const char *pszParmVa
 
        /* it might be parametric */
        if (strchr(pszParmName, ':') != NULL) {
-               set_param_opt(&Globals.param_opt, pszParmName, pszParmValue, FLAG_CMDLINE);
+               set_param_opt(NULL, &Globals.param_opt, pszParmName, pszParmValue, FLAG_CMDLINE);
                if (store_values) {
                        store_lp_set_cmdline(pszParmName, pszParmValue);
                }
@@ -3285,37 +2844,6 @@ static bool do_parameter(const char *pszParmName, const char *pszParmValue,
                                pszParmName, pszParmValue));
 }
 
-/*
-  set a option from the commandline in 'a=b' format. Use to support --option
-*/
-bool lp_set_option(const char *option)
-{
-       char *p, *s;
-       bool ret;
-
-       s = talloc_strdup(NULL, option);
-       if (!s) {
-               return false;
-       }
-
-       p = strchr(s, '=');
-       if (!p) {
-               talloc_free(s);
-               return false;
-       }
-
-       *p = 0;
-
-       /* skip white spaces after the = sign */
-       do {
-               p++;
-       } while (*p == ' ');
-
-       ret = lp_set_cmdline(s, p);
-       talloc_free(s);
-       return ret;
-}
-
 /***************************************************************************
  Initialize any local variables in the sDefault table, after parsing a
  [globals] section.
@@ -3417,7 +2945,7 @@ static bool is_default(int i)
        switch (parm_table[i].type) {
                case P_LIST:
                case P_CMDLIST:
-                       return str_list_equal((const char **)parm_table[i].def.lvalue, 
+                       return str_list_equal((const char * const *)parm_table[i].def.lvalue,
                                              *(const char ***)lp_parm_ptr(NULL, 
                                                                           &parm_table[i]));
                case P_STRING:
@@ -4595,7 +4123,7 @@ static bool lp_load_ex(const char *pszFname,
                        smb_panic("lp_load_ex: out of memory");
                }
 
-               add_to_file_list(pszFname, n2);
+               add_to_file_list(NULL, &file_lists, pszFname, n2);
 
                bRetval = pm_process(n2, do_section, do_parameter, NULL);
                TALLOC_FREE(n2);
@@ -5006,22 +4534,6 @@ void lp_remove_service(int snum)
        ServicePtrs[snum]->valid = false;
 }
 
-/*******************************************************************
- Copy a service.
-********************************************************************/
-
-void lp_copy_service(int snum, const char *new_name)
-{
-       do_section(new_name, NULL);
-       if (snum >= 0) {
-               snum = lp_servicenumber(new_name);
-               if (snum >= 0) {
-                       char *name = lp_servicename(talloc_tos(), snum);
-                       lp_do_parameter(snum, "copy", name);
-               }
-       }
-}
-
 const char *lp_printername(TALLOC_CTX *ctx, int snum)
 {
        const char *ret = lp__printername(ctx, snum);