/* * parse_config_line -- (internal) parse single config line. Store possible * errors in errno. */ static void parse_config_line(char *line, struct rpmemd_special_chars_pos *pos, struct rpmemd_config *config, uint64_t disabled) { if (pos->comment_char < pos->equal_char) pos->equal_char = INVALID_CHAR_POS; uint64_t end_of_content = pos->comment_char != INVALID_CHAR_POS ? pos->comment_char : pos->EOL_char; if (pos->equal_char == INVALID_CHAR_POS) { char *leftover = trim_line_element(line, 0, end_of_content); if (leftover != NULL) errno = EINVAL; return; } char *key_name = trim_line_element(line, 0, pos->equal_char); char *value = trim_line_element(line, pos->equal_char + 1, end_of_content); if (key_name == NULL || value == NULL) { errno = EINVAL; return; } enum rpmemd_option key = parse_config_key(key_name); if (key != RPD_OPT_INVALID) { if ((disabled & (uint64_t)(1 << key)) == 0) set_option((uint32_t)key, value, config); } else errno = EINVAL; }
int userdiff_config(const char *k, const char *v) { struct userdiff_driver *drv; const char *name, *type; int namelen; if (parse_config_key(k, "diff", &name, &namelen, &type) || !name) return 0; drv = userdiff_find_by_namelen(name, namelen); if (!drv) { ALLOC_GROW(drivers, ndrivers+1, drivers_alloc); drv = &drivers[ndrivers++]; memset(drv, 0, sizeof(*drv)); drv->name = xmemdupz(name, namelen); drv->binary = -1; } if (!strcmp(type, "funcname")) return parse_funcname(&drv->funcname, k, v, 0); if (!strcmp(type, "xfuncname")) return parse_funcname(&drv->funcname, k, v, REG_EXTENDED); if (!strcmp(type, "binary")) return parse_tristate(&drv->binary, k, v); if (!strcmp(type, "command")) return git_config_string(&drv->external, k, v); if (!strcmp(type, "textconv")) return git_config_string(&drv->textconv, k, v); if (!strcmp(type, "cachetextconv")) return parse_bool(&drv->textconv_want_cache, k, v); if (!strcmp(type, "wordregex")) return git_config_string(&drv->word_regex, k, v); return 0; }
int parse_submodule_config_option(const char *var, const char *value) { struct string_list_item *config; const char *name, *key; int namelen; if (parse_config_key(var, "submodule", &name, &namelen, &key) < 0 || !name) return 0; if (!strcmp(key, "path")) { if (!value) return config_error_nonbool(var); config = unsorted_string_list_lookup(&config_name_for_path, value); if (config) free(config->util); else config = string_list_append(&config_name_for_path, xstrdup(value)); config->util = xmemdupz(name, namelen); } else if (!strcmp(key, "fetchrecursesubmodules")) { char *name_cstr = xmemdupz(name, namelen); config = unsorted_string_list_lookup(&config_fetch_recurse_submodules_for_name, name_cstr); if (!config) config = string_list_append(&config_fetch_recurse_submodules_for_name, name_cstr); else free(name_cstr); config->util = (void *)(intptr_t)parse_fetch_recurse_submodules_arg(var, value); } else if (!strcmp(key, "ignore")) { char *name_cstr; if (!value) return config_error_nonbool(var); if (strcmp(value, "untracked") && strcmp(value, "dirty") && strcmp(value, "all") && strcmp(value, "none")) { warning("Invalid parameter \"%s\" for config option \"submodule.%s.ignore\"", value, var); return 0; } name_cstr = xmemdupz(name, namelen); config = unsorted_string_list_lookup(&config_ignore_for_name, name_cstr); if (config) { free(config->util); free(name_cstr); } else config = string_list_append(&config_ignore_for_name, name_cstr); config->util = xstrdup(value); return 0; } return 0; }
static int name_and_item_from_var(const char *var, struct strbuf *name, struct strbuf *item) { const char *subsection, *key; int subsection_len, parse; parse = parse_config_key(var, "submodule", &subsection, &subsection_len, &key); if (parse < 0 || !subsection) return 0; strbuf_add(name, subsection, subsection_len); strbuf_addstr(item, key); return 1; }
static int reflog_expire_config(const char *var, const char *value, void *cb) { const char *pattern, *key; int pattern_len; timestamp_t expire; int slot; struct reflog_expire_cfg *ent; if (parse_config_key(var, "gc", &pattern, &pattern_len, &key) < 0) return git_default_config(var, value, cb); if (!strcmp(key, "reflogexpire")) { slot = EXPIRE_TOTAL; if (git_config_expiry_date(&expire, var, value)) return -1; } else if (!strcmp(key, "reflogexpireunreachable")) { slot = EXPIRE_UNREACH; if (git_config_expiry_date(&expire, var, value)) return -1; } else return git_default_config(var, value, cb); if (!pattern) { switch (slot) { case EXPIRE_TOTAL: default_reflog_expire = expire; break; case EXPIRE_UNREACH: default_reflog_expire_unreachable = expire; break; } return 0; } ent = find_cfg_ent(pattern, pattern_len); if (!ent) return -1; switch (slot) { case EXPIRE_TOTAL: ent->expire_total = expire; break; case EXPIRE_UNREACH: ent->expire_unreachable = expire; break; } return 0; }
static int fsck_gitmodules_fn(const char *var, const char *value, void *vdata) { struct fsck_gitmodules_data *data = vdata; const char *subsection, *key; int subsection_len; char *name; if (parse_config_key(var, "submodule", &subsection, &subsection_len, &key) < 0 || !subsection) return 0; name = xmemdupz(subsection, subsection_len); if (check_submodule_name(name) < 0) data->ret |= report(data->options, data->obj, FSCK_MSG_GITMODULES_NAME, "disallowed submodule name: %s", name); free(name); return 0; }
static int name_and_item_from_var(const char *var, struct strbuf *name, struct strbuf *item) { const char *subsection, *key; int subsection_len, parse; parse = parse_config_key(var, "submodule", &subsection, &subsection_len, &key); if (parse < 0 || !subsection) return 0; strbuf_add(name, subsection, subsection_len); if (check_submodule_name(name->buf) < 0) { warning(_("ignoring suspicious submodule name: %s"), name->buf); strbuf_release(name); return 0; } strbuf_addstr(item, key); return 1; }
int parse_hide_refs_config(const char *var, const char *value, const char *section) { const char *key; if (!strcmp("transfer.hiderefs", var) || (!parse_config_key(var, section, NULL, NULL, &key) && !strcmp(key, "hiderefs"))) { char *ref; int len; if (!value) return config_error_nonbool(var); ref = xstrdup(value); len = strlen(ref); while (len && ref[len - 1] == '/') ref[--len] = '\0'; if (!hide_refs) { hide_refs = xcalloc(1, sizeof(*hide_refs)); hide_refs->strdup_strings = 1; } string_list_append(hide_refs, ref); } return 0; }
static int tar_filter_config(const char *var, const char *value, void *data) { struct archiver *ar; const char *name; const char *type; int namelen; if (parse_config_key(var, "tar", &name, &namelen, &type) < 0 || !name) return 0; ar = find_tar_filter(name, namelen); if (!ar) { ar = xcalloc(1, sizeof(*ar)); ar->name = xmemdupz(name, namelen); ar->write_archive = write_tar_filter_archive; ar->flags = ARCHIVER_WANT_COMPRESSION_LEVELS; ALLOC_GROW(tar_filters, nr_tar_filters + 1, alloc_tar_filters); tar_filters[nr_tar_filters++] = ar; } if (!strcmp(type, "command")) { if (!value) return config_error_nonbool(var); free(ar->data); ar->data = xstrdup(value); return 0; } if (!strcmp(type, "remote")) { if (git_config_bool(var, value)) ar->flags |= ARCHIVER_REMOTE; else ar->flags &= ~ARCHIVER_REMOTE; return 0; } return 0; }
static int read_merge_config(const char *var, const char *value, void *cb) { struct ll_merge_driver *fn; const char *key, *name; int namelen; if (!strcmp(var, "merge.default")) return git_config_string(&default_ll_merge, var, value); /* * We are not interested in anything but "merge.<name>.variable"; * especially, we do not want to look at variables such as * "merge.summary", "merge.tool", and "merge.verbosity". */ if (parse_config_key(var, "merge", &name, &namelen, &key) < 0 || !name) return 0; /* * Find existing one as we might be processing merge.<name>.var2 * after seeing merge.<name>.var1. */ for (fn = ll_user_merge; fn; fn = fn->next) if (!strncmp(fn->name, name, namelen) && !fn->name[namelen]) break; if (!fn) { fn = xcalloc(1, sizeof(struct ll_merge_driver)); fn->name = xmemdupz(name, namelen); fn->fn = ll_ext_merge; *ll_user_merge_tail = fn; ll_user_merge_tail = &(fn->next); } if (!strcmp("name", key)) return git_config_string(&fn->description, var, value); if (!strcmp("driver", key)) { if (!value) return error("%s: lacks value", var); /* * merge.<name>.driver specifies the command line: * * command-line * * The command-line will be interpolated with the following * tokens and is given to the shell: * * %O - temporary file name for the merge base. * %A - temporary file name for our version. * %B - temporary file name for the other branches' version. * %L - conflict marker length * %P - the original path (safely quoted for the shell) * * The external merge driver should write the results in the * file named by %A, and signal that it has done with zero exit * status. */ fn->cmdline = xstrdup(value); return 0; } if (!strcmp("recursive", key)) return git_config_string(&fn->recursive, var, value); return 0; }