📄 loadparm.c
字号:
bool lp_do_service_parameter(struct loadparm_context *lp_ctx, struct loadparm_service *service, const char *pszParmName, const char *pszParmValue){ void *parm_ptr; int i; int parmnum = map_parameter(pszParmName); if (parmnum < 0) { if (strchr(pszParmName, ':')) { return lp_do_parameter_parametric(lp_ctx, service, 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; } if (parm_table[parmnum].class == P_GLOBAL) { DEBUG(0, ("Global parameter %s found in service section!\n", pszParmName)); return true; } parm_ptr = ((char *)service) + parm_table[parmnum].offset; if (!service->copymap) init_copymap(service); /* this handles the aliases - set the copymap for other * entries with the same data pointer */ for (i = 0; parm_table[i].label; i++) if (parm_table[i].offset == parm_table[parmnum].offset && parm_table[i].class == parm_table[parmnum].class) service->copymap[i] = false; return set_variable(service, parmnum, parm_ptr, pszParmName, pszParmValue, lp_ctx);}/** * Process a parameter. */static bool do_parameter(const char *pszParmName, const char *pszParmValue, void *userdata){ struct loadparm_context *lp_ctx = (struct loadparm_context *)userdata; if (lp_ctx->bInGlobalSection) return lp_do_global_parameter(lp_ctx, pszParmName, pszParmValue); else return lp_do_service_parameter(lp_ctx, lp_ctx->currentService, pszParmName, pszParmValue);}/* variable argument do parameter*/bool lp_do_global_parameter_var(struct loadparm_context *lp_ctx, const char *pszParmName, const char *fmt, ...) PRINTF_ATTRIBUTE(3, 4);bool lp_do_global_parameter_var(struct loadparm_context *lp_ctx, const char *pszParmName, const char *fmt, ...){ char *s; bool ret; va_list ap; va_start(ap, fmt); s = talloc_vasprintf(NULL, fmt, ap); va_end(ap); ret = lp_do_global_parameter(lp_ctx, pszParmName, s); talloc_free(s); return ret;}/* set a parameter from the commandline - this is called from command line parameter parsing code. It sets the parameter then marks the parameter as unable to be modified by smb.conf processing*/bool lp_set_cmdline(struct loadparm_context *lp_ctx, const char *pszParmName, const char *pszParmValue){ int parmnum = map_parameter(pszParmName); int i; while (isspace((unsigned char)*pszParmValue)) pszParmValue++; if (parmnum < 0 && strchr(pszParmName, ':')) { /* set a parametric option */ return lp_do_parameter_parametric(lp_ctx, NULL, pszParmName, pszParmValue, FLAG_CMDLINE); } if (parmnum < 0) { DEBUG(0,("Unknown option '%s'\n", pszParmName)); return false; } /* reset the CMDLINE flag in case this has been called before */ lp_ctx->flags[parmnum] &= ~FLAG_CMDLINE; if (!lp_do_global_parameter(lp_ctx, pszParmName, pszParmValue)) { return false; } lp_ctx->flags[parmnum] |= FLAG_CMDLINE; /* we have to also set FLAG_CMDLINE on aliases */ for (i=parmnum-1;i>=0 && parm_table[i].offset == parm_table[parmnum].offset;i--) { lp_ctx->flags[i] |= FLAG_CMDLINE; } for (i=parmnum+1;i<NUMPARAMETERS && parm_table[i].offset == parm_table[parmnum].offset;i++) { lp_ctx->flags[i] |= FLAG_CMDLINE; } return true;}/* set a option from the commandline in 'a=b' format. Use to support --option*/bool lp_set_option(struct loadparm_context *lp_ctx, const char *option){ char *p, *s; bool ret; s = strdup(option); if (!s) { return false; } p = strchr(s, '='); if (!p) { free(s); return false; } *p = 0; ret = lp_set_cmdline(lp_ctx, s, p+1); free(s); return ret;}#define BOOLSTR(b) ((b) ? "Yes" : "No")/** * Print a parameter of the specified type. */static void print_parameter(struct parm_struct *p, void *ptr, FILE * f){ int i; switch (p->type) { case P_ENUM: for (i = 0; p->enum_list[i].name; i++) { if (*(int *)ptr == p->enum_list[i].value) { fprintf(f, "%s", p->enum_list[i].name); break; } } break; case P_BOOL: fprintf(f, "%s", BOOLSTR((bool)*(int *)ptr)); break; case P_INTEGER: case P_BYTES: fprintf(f, "%d", *(int *)ptr); break; case P_OCTAL: fprintf(f, "0%o", *(int *)ptr); break; case P_LIST: if ((char ***)ptr && *(char ***)ptr) { char **list = *(char ***)ptr; for (; *list; list++) fprintf(f, "%s%s", *list, ((*(list+1))?", ":"")); } break; case P_STRING: case P_USTRING: if (*(char **)ptr) { fprintf(f, "%s", *(char **)ptr); } break; }}/** * Check if two parameters are equal. */static bool equal_parameter(parm_type type, void *ptr1, void *ptr2){ switch (type) { case P_BOOL: return (*((int *)ptr1) == *((int *)ptr2)); case P_INTEGER: case P_OCTAL: case P_BYTES: case P_ENUM: return (*((int *)ptr1) == *((int *)ptr2)); case P_LIST: return str_list_equal((const char **)(*(char ***)ptr1), (const char **)(*(char ***)ptr2)); case P_STRING: case P_USTRING: { char *p1 = *(char **)ptr1, *p2 = *(char **)ptr2; if (p1 && !*p1) p1 = NULL; if (p2 && !*p2) p2 = NULL; return (p1 == p2 || strequal(p1, p2)); } } return false;}/** * Process a new section (service). * * At this stage all sections are services. * Later we'll have special sections that permit server parameters to be set. * Returns True on success, False on failure. */static bool do_section(const char *pszSectionName, void *userdata){ struct loadparm_context *lp_ctx = (struct loadparm_context *)userdata; bool bRetval; bool isglobal = ((strwicmp(pszSectionName, GLOBAL_NAME) == 0) || (strwicmp(pszSectionName, GLOBAL_NAME2) == 0)); bRetval = false; /* if we've just struck a global section, note the fact. */ lp_ctx->bInGlobalSection = isglobal; /* check for multiple global sections */ if (lp_ctx->bInGlobalSection) { DEBUG(3, ("Processing section \"[%s]\"\n", pszSectionName)); return true; } /* if we have a current service, tidy it up before moving on */ bRetval = true; if (lp_ctx->currentService != NULL) bRetval = service_ok(lp_ctx->currentService); /* if all is still well, move to the next record in the services array */ if (bRetval) { /* We put this here to avoid an odd message order if messages are */ /* issued by the post-processing of a previous section. */ DEBUG(2, ("Processing section \"[%s]\"\n", pszSectionName)); if ((lp_ctx->currentService = lp_add_service(lp_ctx, lp_ctx->sDefault, pszSectionName)) == NULL) { DEBUG(0, ("Failed to add a new service\n")); return false; } } return bRetval;}/** * Determine if a particular base parameter is currently set to the default value. */static bool is_default(struct loadparm_service *sDefault, int i){ void *def_ptr = ((char *)sDefault) + parm_table[i].offset; if (!defaults_saved) return false; switch (parm_table[i].type) { case P_LIST: return str_list_equal((const char **)parm_table[i].def.lvalue, (const char **)def_ptr); case P_STRING: case P_USTRING: return strequal(parm_table[i].def.svalue, *(char **)def_ptr); case P_BOOL: return parm_table[i].def.bvalue == *(int *)def_ptr; case P_INTEGER: case P_OCTAL: case P_BYTES: case P_ENUM: return parm_table[i].def.ivalue == *(int *)def_ptr; } return false;}/** *Display the contents of the global structure. */static void dump_globals(struct loadparm_context *lp_ctx, FILE *f, bool show_defaults){ int i; struct param_opt *data; fprintf(f, "# Global parameters\n[global]\n"); for (i = 0; parm_table[i].label; i++) if (parm_table[i].class == P_GLOBAL && parm_table[i].offset != -1 && (i == 0 || (parm_table[i].offset != parm_table[i - 1].offset))) { if (!show_defaults && (lp_ctx->flags[i] & FLAG_DEFAULT)) continue; fprintf(f, "\t%s = ", parm_table[i].label); print_parameter(&parm_table[i], lp_parm_ptr(lp_ctx, NULL, &parm_table[i]), f); fprintf(f, "\n"); } if (lp_ctx->globals->param_opt != NULL) { for (data = lp_ctx->globals->param_opt; data; data = data->next) { fprintf(f, "\t%s = %s\n", data->key, data->value); } }}/** * Display the contents of a single services record. */static void dump_a_service(struct loadparm_service * pService, struct loadparm_service *sDefault, FILE * f){ int i; struct param_opt *data; if (pService != sDefault) fprintf(f, "\n[%s]\n", pService->szService); for (i = 0; parm_table[i].label; i++) if (parm_table[i].class == P_LOCAL && parm_table[i].offset != -1 && (*parm_table[i].label != '-') && (i == 0 || (parm_table[i].offset != parm_table[i - 1].offset))) { if (pService == sDefault) { if (defaults_saved && is_default(sDefault, i)) continue; } else { if (equal_parameter(parm_table[i].type, ((char *)pService) + parm_table[i].offset, ((char *)sDefault) + parm_table[i].offset)) continue; } fprintf(f, "\t%s = ", parm_table[i].label); print_parameter(&parm_table[i], ((char *)pService) + parm_table[i].offset, f); fprintf(f, "\n"); } if (pService->param_opt != NULL) { for (data = pService->param_opt; data; data = data->next) { fprintf(f, "\t%s = %s\n", data->key, data->value); } }}bool lp_dump_a_parameter(struct loadparm_context *lp_ctx, struct loadparm_service *service, const char *parm_name, FILE * f){ struct parm_struct *parm; void *ptr; parm = lp_parm_struct(parm_name); if (!parm) { return false; } ptr = lp_parm_ptr(lp_ctx, service,parm); print_parameter(parm, ptr, f); fprintf(f, "\n"); return true;}/** * Return info about the next service in a service. snum==-1 gives the globals. * Return NULL when out of parameters. */struct parm_struct *lp_next_parameter(struct loadparm_context *lp_ctx, int snum, int *i, int allparameters){ if (snum == -1) { /* do the globals */ for (; parm_table[*i].label; (*i)++) { if (parm_table[*i].offset == -1 || (*parm_table[*i].label == '-')) continue; if ((*i) > 0 && (parm_table[*i].offset == parm_table[(*i) - 1].offset)) continue; return &parm_table[(*i)++];
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -