📄 loadparm.c
字号:
string_set(pserviceDest, (char **)dest_ptr, *(char **)src_ptr); strupper(*(char **)dest_ptr); break; case P_LIST: *(const char ***)dest_ptr = str_list_copy(pserviceDest, *(const char ***)src_ptr); break; default: break; } } if (bcopyall) { init_copymap(pserviceDest); if (pserviceSource->copymap) memcpy((void *)pserviceDest->copymap, (void *)pserviceSource->copymap, sizeof(int) * NUMPARAMETERS); } data = pserviceSource->param_opt; while (data) { not_added = true; pdata = pserviceDest->param_opt; /* Traverse destination */ while (pdata) { /* If we already have same option, override it */ if (strcmp(pdata->key, data->key) == 0) { talloc_free(pdata->value); pdata->value = talloc_reference(pdata, data->value); not_added = false; break; } pdata = pdata->next; } if (not_added) { paramo = talloc(pserviceDest, struct param_opt); if (paramo == NULL) smb_panic("OOM"); paramo->key = talloc_reference(paramo, data->key); paramo->value = talloc_reference(paramo, data->value); DLIST_ADD(pserviceDest->param_opt, paramo); } data = data->next; }}/** * Check a service for consistency. Return False if the service is in any way * incomplete or faulty, else True. */static bool service_ok(struct loadparm_service *service){ bool bRetval; bRetval = true; if (service->szService[0] == '\0') { DEBUG(0, ("The following message indicates an internal error:\n")); DEBUG(0, ("No service name in service entry.\n")); bRetval = false; } /* The [printers] entry MUST be printable. I'm all for flexibility, but */ /* I can't see why you'd want a non-printable printer service... */ if (strwicmp(service->szService, PRINTERS_NAME) == 0) { if (!service->bPrint_ok) { DEBUG(0, ("WARNING: [%s] service MUST be printable!\n", service->szService)); service->bPrint_ok = true; } /* [printers] service must also be non-browsable. */ if (service->bBrowseable) service->bBrowseable = false; } /* If a service is flagged unavailable, log the fact at level 0. */ if (!service->bAvailable) DEBUG(1, ("NOTE: Service %s is flagged unavailable.\n", service->szService)); return bRetval;}/******************************************************************* 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(struct loadparm_context *lp_ctx, const char *fname, const char *subfname){ struct file_lists *f = lp_ctx->file_lists; while (f) { if (f->name && !strcmp(f->name, fname)) break; f = f->next; } if (!f) { f = talloc(lp_ctx, struct file_lists); if (!f) return; f->next = lp_ctx->file_lists; f->name = talloc_strdup(f, fname); if (!f->name) { talloc_free(f); return; } f->subfname = talloc_strdup(f, subfname); if (!f->subfname) { talloc_free(f); return; } lp_ctx->file_lists = f; f->modtime = file_modtime(subfname); } else { time_t t = file_modtime(subfname); if (t) f->modtime = t; }}/******************************************************************* Check if a config file has changed date.********************************************************************/bool lp_file_list_changed(struct loadparm_context *lp_ctx){ struct file_lists *f; DEBUG(6, ("lp_file_list_changed()\n")); for (f = lp_ctx->file_lists; f != NULL; f = f->next) { char *n2; time_t mod_time; n2 = standard_sub_basic(lp_ctx, f->name); DEBUGADD(6, ("file %s -> %s last mod_time: %s\n", f->name, n2, ctime(&f->modtime))); mod_time = file_modtime(n2); if (mod_time && ((f->modtime != mod_time) || (f->subfname == NULL) || (strcmp(n2, f->subfname) != 0))) { DEBUGADD(6, ("file %s modified: %s\n", n2, ctime(&mod_time))); f->modtime = mod_time; talloc_free(f->subfname); f->subfname = talloc_strdup(f, n2); return true; } } return false;}/*************************************************************************** Handle the include operation.***************************************************************************/static bool handle_include(struct loadparm_context *lp_ctx, const char *pszParmValue, char **ptr){ char *fname = standard_sub_basic(lp_ctx, pszParmValue); add_to_file_list(lp_ctx, pszParmValue, fname); string_set(lp_ctx, ptr, fname); if (file_exist(fname)) return pm_process(fname, do_section, do_parameter, lp_ctx); DEBUG(2, ("Can't find include file %s\n", fname)); return false;}/*************************************************************************** Handle the interpretation of the copy parameter.***************************************************************************/static bool handle_copy(struct loadparm_context *lp_ctx, const char *pszParmValue, char **ptr){ bool bRetval; struct loadparm_service *serviceTemp; string_set(lp_ctx, ptr, pszParmValue); bRetval = false; DEBUG(3, ("Copying service from service %s\n", pszParmValue)); if ((serviceTemp = getservicebyname(lp_ctx, pszParmValue)) != NULL) { if (serviceTemp == lp_ctx->currentService) { DEBUG(0, ("Can't copy service %s - unable to copy self!\n", pszParmValue)); } else { copy_service(lp_ctx->currentService, serviceTemp, lp_ctx->currentService->copymap); bRetval = true; } } else { DEBUG(0, ("Unable to copy service - source not found: %s\n", pszParmValue)); bRetval = false; } return bRetval;}static bool handle_debuglevel(struct loadparm_context *lp_ctx, const char *pszParmValue, char **ptr){ DEBUGLEVEL = atoi(pszParmValue); return true;}static bool handle_logfile(struct loadparm_context *lp_ctx, const char *pszParmValue, char **ptr){ logfile = pszParmValue; return true;}/*************************************************************************** Initialise a copymap.***************************************************************************/static void init_copymap(struct loadparm_service *pservice){ int i; talloc_free(pservice->copymap); pservice->copymap = talloc_array(pservice, int, NUMPARAMETERS); if (pservice->copymap == NULL) { DEBUG(0, ("Couldn't allocate copymap!! (size %d)\n", (int)NUMPARAMETERS)); return; } for (i = 0; i < NUMPARAMETERS; i++) pservice->copymap[i] = true;}/** * Process a parametric option */static bool lp_do_parameter_parametric(struct loadparm_context *lp_ctx, struct loadparm_service *service, const char *pszParmName, const char *pszParmValue, int flags){ struct param_opt *paramo, *data; char *name; TALLOC_CTX *mem_ctx; while (isspace((unsigned char)*pszParmName)) { pszParmName++; } name = strdup(pszParmName); if (!name) return false; strlower(name); if (service == NULL) { data = lp_ctx->globals->param_opt; mem_ctx = lp_ctx->globals; } else { data = service->param_opt; mem_ctx = service; } /* Traverse destination */ for (paramo=data; paramo; paramo=paramo->next) { /* If we already have the option set, override it unless it was a command line option and the new one isn't */ if (strcmp(paramo->key, name) == 0) { if ((paramo->flags & FLAG_CMDLINE) && !(flags & FLAG_CMDLINE)) { return true; } talloc_free(paramo->value); paramo->value = talloc_strdup(paramo, pszParmValue); paramo->flags = flags; free(name); return true; } } paramo = talloc(mem_ctx, struct param_opt); if (!paramo) smb_panic("OOM"); paramo->key = talloc_strdup(paramo, name); paramo->value = talloc_strdup(paramo, pszParmValue); paramo->flags = flags; if (service == NULL) { DLIST_ADD(lp_ctx->globals->param_opt, paramo); } else { DLIST_ADD(service->param_opt, paramo); } free(name); return true;}static bool set_variable(TALLOC_CTX *mem_ctx, int parmnum, void *parm_ptr, const char *pszParmName, const char *pszParmValue, struct loadparm_context *lp_ctx){ int i; /* if it is a special case then go ahead */ if (parm_table[parmnum].special) { parm_table[parmnum].special(lp_ctx, pszParmValue, (char **)parm_ptr); return true; } /* now switch on the type of variable it is */ switch (parm_table[parmnum].type) { case P_BOOL: { bool b; if (!set_boolean(pszParmValue, &b)) { DEBUG(0,("lp_do_parameter(%s): value is not boolean!\n", pszParmValue)); return false; } *(int *)parm_ptr = b; } break; case P_INTEGER: *(int *)parm_ptr = atoi(pszParmValue); break; case P_OCTAL: *(int *)parm_ptr = strtol(pszParmValue, NULL, 8); break; case P_BYTES: { uint64_t val; if (conv_str_size(pszParmValue, &val)) { if (val <= INT_MAX) { *(int *)parm_ptr = (int)val; break; } } DEBUG(0,("lp_do_parameter(%s): value is not " "a valid size specifier!\n", pszParmValue)); return false; } case P_LIST: *(const char ***)parm_ptr = str_list_make(mem_ctx, pszParmValue, NULL); break; case P_STRING: string_set(mem_ctx, (char **)parm_ptr, pszParmValue); break; case P_USTRING: string_set(mem_ctx, (char **)parm_ptr, pszParmValue); strupper(*(char **)parm_ptr); break; case P_ENUM: for (i = 0; parm_table[parmnum].enum_list[i].name; i++) { if (strequal (pszParmValue, parm_table[parmnum].enum_list[i].name)) { *(int *)parm_ptr = parm_table[parmnum]. enum_list[i].value; break; } } if (!parm_table[parmnum].enum_list[i].name) { DEBUG(0,("Unknown enumerated value '%s' for '%s'\n", pszParmValue, pszParmName)); return false; } break; } if (lp_ctx->flags[parmnum] & FLAG_DEFAULT) { lp_ctx->flags[parmnum] &= ~FLAG_DEFAULT; /* we have to also unset FLAG_DEFAULT on aliases */ for (i=parmnum-1;i>=0 && parm_table[i].offset == parm_table[parmnum].offset;i--) { lp_ctx->flags[i] &= ~FLAG_DEFAULT; } for (i=parmnum+1;i<NUMPARAMETERS && parm_table[i].offset == parm_table[parmnum].offset;i++) { lp_ctx->flags[i] &= ~FLAG_DEFAULT; } } return true;}bool lp_do_global_parameter(struct loadparm_context *lp_ctx, const char *pszParmName, const char *pszParmValue){ int parmnum = map_parameter(pszParmName); void *parm_ptr; if (parmnum < 0) { if (strchr(pszParmName, ':')) { return lp_do_parameter_parametric(lp_ctx, NULL, pszParmName, pszParmValue, 0); } DEBUG(0, ("Ignoring unknown parameter \"%s\"\n", pszParmName)); return true; } /* if the flag has been set on the command line, then don't allow override, but don't report an error */ if (lp_ctx->flags[parmnum] & FLAG_CMDLINE) { return true; } parm_ptr = lp_parm_ptr(lp_ctx, NULL, &parm_table[parmnum]); return set_variable(lp_ctx, parmnum, parm_ptr, pszParmName, pszParmValue, lp_ctx);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -