2 * prof_set.c --- routines that expose the public interfaces for
3 * inserting, updating and deleting items from the profile.
5 * WARNING: These routines only look at the first file opened in the
6 * profile. It's not clear how to handle multiple files, actually.
7 * In the future it may be necessary to modify this public interface,
8 * or possibly add higher level functions to support this correctly.
10 * WARNING: We're not yet doing locking yet, either.
23 static errcode_t rw_setup(profile_t profile)
29 return PROF_NO_PROFILE;
31 if (profile->magic != PROF_MAGIC_PROFILE)
32 return PROF_MAGIC_PROFILE;
34 file = profile->first_file;
36 if (!(file->data->flags & PROFILE_FILE_RW))
37 return PROF_READ_ONLY;
39 retval = profile_lock_global();
43 /* Don't update the file if we've already made modifications */
44 if (file->data->flags & PROFILE_FILE_DIRTY) {
45 profile_unlock_global();
49 #ifdef SHARE_TREE_DATA
50 if ((file->data->flags & PROFILE_FILE_SHARED) != 0) {
52 new_data = malloc(sizeof(struct _prf_data_t));
53 if (new_data == NULL) {
56 *new_data = *file->data;
57 /* We can blow away the information because update
58 will be called further down */
59 new_data->comment = NULL;
60 new_data->root = NULL;
61 new_data->flags &= ~PROFILE_FILE_SHARED;
62 new_data->timestamp = 0;
63 /* copy the file spec */
64 new_data->filespec = malloc(strlen(file->data->filespec) + 1);
65 if (new_data->filespec == NULL) {
68 strcpy (new_data->filespec, file->data->filespec);
73 profile_unlock_global();
77 profile_dereference_data(file->data);
78 file->data = new_data;
80 #endif /* SHARE_TREE_DATA */
82 profile_unlock_global();
83 retval = profile_update_file(file);
90 * Delete or update a particular child node
92 * ADL - 2/23/99, rewritten TYT 2/25/99
94 errcode_t KRB5_CALLCONV
95 profile_update_relation(profile_t profile, const char **names,
96 const char *old_value, const char *new_value)
99 struct profile_node *section, *node;
103 retval = rw_setup(profile);
107 if (names == 0 || names[0] == 0 || names[1] == 0)
108 return PROF_BAD_NAMESET;
110 if (!old_value || !*old_value)
113 retval = k5_mutex_lock(&profile->first_file->data->lock);
116 section = profile->first_file->data->root;
117 for (cpp = names; cpp[1]; cpp++) {
119 retval = profile_find_node(section, *cpp, 0, 1,
122 k5_mutex_unlock(&profile->first_file->data->lock);
128 retval = profile_find_node(section, *cpp, old_value, 0, &state, &node);
131 retval = profile_set_relation_value(node, new_value);
133 retval = profile_remove_node(node);
136 profile->first_file->data->flags |= PROFILE_FILE_DIRTY;
137 k5_mutex_unlock(&profile->first_file->data->lock);
143 * Clear a particular all of the relations with a specific name.
147 errcode_t KRB5_CALLCONV
148 profile_clear_relation(profile_t profile, const char **names)
151 struct profile_node *section, *node;
155 retval = rw_setup(profile);
159 if (names == 0 || names[0] == 0 || names[1] == 0)
160 return PROF_BAD_NAMESET;
162 section = profile->first_file->data->root;
163 for (cpp = names; cpp[1]; cpp++) {
165 retval = profile_find_node(section, *cpp, 0, 1,
173 retval = profile_find_node(section, *cpp, 0, 0, &state, &node);
176 retval = profile_remove_node(node);
181 profile->first_file->data->flags |= PROFILE_FILE_DIRTY;
187 * Rename a particular section; if the new_section name is NULL,
190 * ADL - 2/23/99, rewritten TYT 2/25/99
192 errcode_t KRB5_CALLCONV
193 profile_rename_section(profile_t profile, const char **names,
194 const char *new_name)
197 struct profile_node *section, *node;
201 retval = rw_setup(profile);
205 if (names == 0 || names[0] == 0 || names[1] == 0)
206 return PROF_BAD_NAMESET;
208 retval = k5_mutex_lock(&profile->first_file->data->lock);
211 section = profile->first_file->data->root;
212 for (cpp = names; cpp[1]; cpp++) {
214 retval = profile_find_node(section, *cpp, 0, 1,
217 k5_mutex_unlock(&profile->first_file->data->lock);
223 retval = profile_find_node(section, *cpp, 0, 1, &state, &node);
226 retval = profile_rename_node(node, new_name);
228 retval = profile_remove_node(node);
231 profile->first_file->data->flags |= PROFILE_FILE_DIRTY;
232 k5_mutex_unlock(&profile->first_file->data->lock);
237 * Insert a new relation. If the new_value argument is NULL, then
238 * create a new section instead.
240 * Note: if the intermediate sections do not exist, this function will
241 * automatically create them.
243 * ADL - 2/23/99, rewritten TYT 2/25/99
245 errcode_t KRB5_CALLCONV
246 profile_add_relation(profile_t profile, const char **names,
247 const char *new_value)
250 struct profile_node *section;
254 retval = rw_setup(profile);
258 if (names == 0 || names[0] == 0 || names[1] == 0)
259 return PROF_BAD_NAMESET;
261 retval = k5_mutex_lock(&profile->first_file->data->lock);
264 section = profile->first_file->data->root;
265 for (cpp = names; cpp[1]; cpp++) {
267 retval = profile_find_node(section, *cpp, 0, 1,
269 if (retval == PROF_NO_SECTION)
270 retval = profile_add_node(section, *cpp, 0, §ion);
272 k5_mutex_unlock(&profile->first_file->data->lock);
277 if (new_value == 0) {
278 retval = profile_find_node(section, *cpp, 0, 1, &state, 0);
280 k5_mutex_unlock(&profile->first_file->data->lock);
282 } else if (retval != PROF_NO_SECTION) {
283 k5_mutex_unlock(&profile->first_file->data->lock);
288 retval = profile_add_node(section, *cpp, new_value, 0);
290 k5_mutex_unlock(&profile->first_file->data->lock);
294 profile->first_file->data->flags |= PROFILE_FILE_DIRTY;
295 k5_mutex_unlock(&profile->first_file->data->lock);