1 #pragma ident "%Z%%M% %I% %E% SMI" 2 /* 3 * prof_set.c --- routines that expose the public interfaces for 4 * inserting, updating and deleting items from the profile. 5 * 6 * WARNING: These routines only look at the first file opened in the 7 * profile. It's not clear how to handle multiple files, actually. 8 * In the future it may be necessary to modify this public interface, 9 * or possibly add higher level functions to support this correctly. 10 * 11 * WARNING: We're not yet doing locking yet, either. 12 * 13 */ 14 15 #include <stdio.h> 16 #include <string.h> 17 #ifdef HAVE_STDLIB_H 18 #include <stdlib.h> 19 #endif 20 #include <errno.h> 21 22 #include "prof_int.h" 23 24 static errcode_t rw_setup(profile) 25 profile_t profile; 26 { 27 prf_file_t file; 28 errcode_t retval; 29 30 if (!profile) 31 return PROF_NO_PROFILE; 32 33 if (profile->magic != PROF_MAGIC_PROFILE) 34 return PROF_MAGIC_PROFILE; 35 36 file = profile->first_file; 37 if (!(file->flags & PROFILE_FILE_RW)) 38 return PROF_READ_ONLY; 39 40 /* Don't update the file if we've already made modifications */ 41 if (file->flags & PROFILE_FILE_DIRTY) 42 return 0; 43 44 retval = profile_update_file(file); 45 46 return retval; 47 } 48 49 50 /* 51 * Delete or update a particular child node 52 * 53 * ADL - 2/23/99, rewritten TYT 2/25/99 54 */ 55 KRB5_DLLIMP errcode_t KRB5_CALLCONV 56 profile_update_relation(profile, names, old_value, new_value) 57 profile_t profile; 58 const char **names; 59 const char *old_value; 60 const char *new_value; 61 { 62 errcode_t retval; 63 struct profile_node *section, *node; 64 void *state; 65 const char **cpp; 66 67 retval = rw_setup(profile); 68 if (retval) 69 return retval; 70 71 if (names == 0 || names[0] == 0 || names[1] == 0) 72 return PROF_BAD_NAMESET; 73 74 if (!old_value || !*old_value) 75 return PROF_EINVAL; 76 77 section = profile->first_file->root; 78 for (cpp = names; cpp[1]; cpp++) { 79 state = 0; 80 retval = profile_find_node(section, *cpp, 0, 1, 81 &state, §ion); 82 if (retval) 83 return retval; 84 } 85 86 state = 0; 87 retval = profile_find_node(section, *cpp, old_value, 0, &state, &node); 88 if (retval) 89 return retval; 90 91 if (new_value) 92 retval = profile_set_relation_value(node, new_value); 93 else 94 retval = profile_remove_node(node); 95 if (retval) 96 return retval; 97 98 profile->first_file->flags |= PROFILE_FILE_DIRTY; 99 100 return 0; 101 } 102 103 /* 104 * Clear a particular all of the relations with a specific name. 105 * 106 * TYT - 2/25/99 107 */ 108 KRB5_DLLIMP errcode_t KRB5_CALLCONV 109 profile_clear_relation(profile, names) 110 profile_t profile; 111 const char **names; 112 { 113 errcode_t retval; 114 struct profile_node *section, *node; 115 void *state; 116 const char **cpp; 117 118 retval = rw_setup(profile); 119 if (retval) 120 return retval; 121 122 if (names == 0 || names[0] == 0 || names[1] == 0) 123 return PROF_BAD_NAMESET; 124 125 section = profile->first_file->root; 126 for (cpp = names; cpp[1]; cpp++) { 127 state = 0; 128 retval = profile_find_node(section, *cpp, 0, 1, 129 &state, §ion); 130 if (retval) 131 return retval; 132 } 133 134 state = 0; 135 do { 136 retval = profile_find_node(section, *cpp, 0, 0, &state, &node); 137 if (retval) 138 return retval; 139 retval = profile_remove_node(node); 140 if (retval) 141 return retval; 142 } while (state); 143 144 profile->first_file->flags |= PROFILE_FILE_DIRTY; 145 146 return 0; 147 } 148 149 /* 150 * Rename a particular section; if the new_section name is NULL, 151 * delete it. 152 * 153 * ADL - 2/23/99, rewritten TYT 2/25/99 154 */ 155 KRB5_DLLIMP errcode_t KRB5_CALLCONV 156 profile_rename_section(profile, names, new_name) 157 profile_t profile; 158 const char **names; 159 const char *new_name; 160 { 161 errcode_t retval; 162 struct profile_node *section, *node; 163 void *state; 164 const char **cpp; 165 166 retval = rw_setup(profile); 167 if (retval) 168 return retval; 169 170 if (names == 0 || names[0] == 0 || names[1] == 0) 171 return PROF_BAD_NAMESET; 172 173 section = profile->first_file->root; 174 for (cpp = names; cpp[1]; cpp++) { 175 state = 0; 176 retval = profile_find_node(section, *cpp, 0, 1, 177 &state, §ion); 178 if (retval) 179 return retval; 180 } 181 182 state = 0; 183 retval = profile_find_node(section, *cpp, 0, 1, &state, &node); 184 if (retval) 185 return retval; 186 187 if (new_name) 188 retval = profile_rename_node(node, new_name); 189 else 190 retval = profile_remove_node(node); 191 if (retval) 192 return retval; 193 194 profile->first_file->flags |= PROFILE_FILE_DIRTY; 195 196 return 0; 197 } 198 199 /* 200 * Insert a new relation. If the new_value argument is NULL, then 201 * create a new section instead. 202 * 203 * Note: if the intermediate sections do not exist, this function will 204 * automatically create them. 205 * 206 * ADL - 2/23/99, rewritten TYT 2/25/99 207 */ 208 KRB5_DLLIMP errcode_t KRB5_CALLCONV 209 profile_add_relation(profile, names, new_value) 210 profile_t profile; 211 const char **names; 212 const char *new_value; 213 { 214 errcode_t retval; 215 struct profile_node *section; 216 const char **cpp; 217 void *state; 218 219 retval = rw_setup(profile); 220 if (retval) 221 return retval; 222 223 if (names == 0 || names[0] == 0 || names[1] == 0) 224 return PROF_BAD_NAMESET; 225 226 section = profile->first_file->root; 227 for (cpp = names; cpp[1]; cpp++) { 228 state = 0; 229 retval = profile_find_node(section, *cpp, 0, 1, 230 &state, §ion); 231 if (retval == PROF_NO_SECTION) 232 retval = profile_add_node(section, *cpp, 0, §ion); 233 if (retval) 234 return retval; 235 } 236 237 if (new_value == 0) { 238 retval = profile_find_node(section, *cpp, 0, 1, &state, 0); 239 if (retval == 0) 240 return PROF_EXISTS; 241 else if (retval != PROF_NO_SECTION) 242 return retval; 243 } 244 245 retval = profile_add_node(section, *cpp, new_value, 0); 246 if (retval) 247 return retval; 248 249 profile->first_file->flags |= PROFILE_FILE_DIRTY; 250 251 return 0; 252 } 253 254