/* * Insert a new relation. If the new_value argument is NULL, then * create a new section instead. * * Note: if the intermediate sections do not exist, this function will * automatically create them. * * ADL - 2/23/99, rewritten TYT 2/25/99 */ errcode_t KRB5_CALLCONV profile_add_relation(profile_t profile, const char **names, const char *new_value) { errcode_t retval; struct profile_node *section; const char **cpp; void *state; if (profile->vt) { if (!profile->vt->add_relation) return PROF_UNSUPPORTED; return profile->vt->add_relation(profile->cbdata, names, new_value); } retval = rw_setup(profile); if (retval) return retval; if (names == 0 || names[0] == 0 || names[1] == 0) return PROF_BAD_NAMESET; k5_mutex_lock(&profile->first_file->data->lock); section = profile->first_file->data->root; for (cpp = names; cpp[1]; cpp++) { state = 0; retval = profile_find_node(section, *cpp, 0, 1, &state, §ion); if (retval == PROF_NO_SECTION) retval = profile_add_node(section, *cpp, 0, §ion); if (retval) { k5_mutex_unlock(&profile->first_file->data->lock); return retval; } } if (new_value == 0) { retval = profile_find_node(section, *cpp, 0, 1, &state, 0); if (retval == 0) { k5_mutex_unlock(&profile->first_file->data->lock); return PROF_EXISTS; } else if (retval != PROF_NO_SECTION) { k5_mutex_unlock(&profile->first_file->data->lock); return retval; } } retval = profile_add_node(section, *cpp, new_value, 0); if (retval) { k5_mutex_unlock(&profile->first_file->data->lock); return retval; } profile->first_file->data->flags |= PROFILE_FILE_DIRTY; k5_mutex_unlock(&profile->first_file->data->lock); return 0; }
/* * Delete or update a particular child node * * ADL - 2/23/99, rewritten TYT 2/25/99 */ errcode_t KRB5_CALLCONV profile_update_relation(profile_t profile, const char **names, const char *old_value, const char *new_value) { errcode_t retval; struct profile_node *section, *node; void *state; const char **cpp; if (profile->vt) { if (!profile->vt->update_relation) return PROF_UNSUPPORTED; return profile->vt->update_relation(profile->cbdata, names, old_value, new_value); } retval = rw_setup(profile); if (retval) return retval; if (names == 0 || names[0] == 0 || names[1] == 0) return PROF_BAD_NAMESET; if (!old_value || !*old_value) return PROF_EINVAL; k5_mutex_lock(&profile->first_file->data->lock); section = profile->first_file->data->root; for (cpp = names; cpp[1]; cpp++) { state = 0; retval = profile_find_node(section, *cpp, 0, 1, &state, §ion); if (retval) { k5_mutex_unlock(&profile->first_file->data->lock); return retval; } } state = 0; retval = profile_find_node(section, *cpp, old_value, 0, &state, &node); if (retval == 0) { if (new_value) retval = profile_set_relation_value(node, new_value); else retval = profile_remove_node(node); } if (retval == 0) profile->first_file->data->flags |= PROFILE_FILE_DIRTY; k5_mutex_unlock(&profile->first_file->data->lock); return retval; }
/* * Clear a particular all of the relations with a specific name. * * TYT - 2/25/99 */ errcode_t KRB5_CALLCONV profile_clear_relation(profile_t profile, const char **names) { errcode_t retval; struct profile_node *section, *node; void *state; const char **cpp; if (profile->vt) { if (!profile->vt->update_relation) return PROF_UNSUPPORTED; return profile->vt->update_relation(profile->cbdata, names, NULL, NULL); } retval = rw_setup(profile); if (retval) return retval; if (names == 0 || names[0] == 0 || names[1] == 0) return PROF_BAD_NAMESET; section = profile->first_file->data->root; for (cpp = names; cpp[1]; cpp++) { state = 0; retval = profile_find_node(section, *cpp, 0, 1, &state, §ion); if (retval) return retval; } state = 0; do { retval = profile_find_node(section, *cpp, 0, 0, &state, &node); if (retval) return retval; retval = profile_remove_node(node); if (retval) return retval; } while (state); profile->first_file->data->flags |= PROFILE_FILE_DIRTY; return 0; }
/* * Rename a particular section; if the new_section name is NULL, * delete it. * * ADL - 2/23/99, rewritten TYT 2/25/99 */ errcode_t KRB5_CALLCONV profile_rename_section(profile_t profile, const char **names, const char *new_name) { errcode_t retval; struct profile_node *section, *node; void *state; const char **cpp; retval = rw_setup(profile); if (retval) return retval; if (names == 0 || names[0] == 0 || names[1] == 0) return PROF_BAD_NAMESET; retval = k5_mutex_lock(&profile->first_file->data->lock); if (retval) return retval; section = profile->first_file->data->root; for (cpp = names; cpp[1]; cpp++) { state = 0; retval = profile_find_node(section, *cpp, 0, 1, &state, §ion); if (retval) { k5_mutex_unlock(&profile->first_file->data->lock); return retval; } } state = 0; retval = profile_find_node(section, *cpp, 0, 1, &state, &node); if (retval == 0) { if (new_name) retval = profile_rename_node(node, new_name); else retval = profile_remove_node(node); } if (retval == 0) profile->first_file->data->flags |= PROFILE_FILE_DIRTY; k5_mutex_unlock(&profile->first_file->data->lock); return retval; }
static long parse_line(char *line, struct parse_state *state) { char *cp, ch, *tag, *value; char *p; long retval; struct profile_node *node; int do_subsection = 0; void *iter = 0; state->line_num++; if (state->state == STATE_GET_OBRACE) { cp = skip_over_blanks(line); if (*cp != '{') return PROF_MISSING_OBRACE; state->state = STATE_STD_LINE; return 0; } if (state->state == STATE_INIT_COMMENT) { if (line[0] != '[') return 0; state->state = STATE_STD_LINE; } if (*line == 0) return 0; strip_line(line); cp = skip_over_blanks(line); ch = *cp; if (end_or_comment(ch)) return 0; if (ch == '[') { if (state->group_level > 0) return PROF_SECTION_NOTOP; cp++; cp = skip_over_blanks(cp); p = strchr(cp, ']'); if (p == NULL) return PROF_SECTION_SYNTAX; if (*cp == '"') { cp++; parse_quoted_string(cp); } else { *p-- = '\0'; while (isspace(*p) && (p > cp)) *p-- = '\0'; if (*cp == 0) return PROF_SECTION_SYNTAX; } retval = profile_find_node(state->root_section, cp, 0, 1, &iter, &state->current_section); if (retval == PROF_NO_SECTION) { retval = profile_add_node(state->root_section, cp, 0, &state->current_section); if (retval) return retval; } else if (retval) return retval; /* * Finish off the rest of the line. */ cp = p+1; if (*cp == '*') { state->current_section->final = 1; cp++; } /* * Spaces or comments after ']' should not be fatal */ cp = skip_over_blanks(cp); if (!end_or_comment(*cp)) return PROF_SECTION_SYNTAX; return 0; }