1 /* 2 * prof-int.h 3 */ 4 5 #include "k5-platform.h" 6 #include "k5-thread.h" 7 #include "k5-plugin.h" 8 9 #include <time.h> 10 11 #if defined(__MACH__) && defined(__APPLE__) 12 #include <TargetConditionals.h> 13 #define PROFILE_SUPPORTS_FOREIGN_NEWLINES 14 #endif 15 16 #include "com_err.h" 17 #include "profile.h" 18 19 typedef long prf_magic_t; 20 21 /* 22 * This is the structure which stores the profile information for a 23 * particular configuration file. 24 * 25 * Locking strategy: 26 * - filespec, fslen are fixed after creation 27 * - refcount and next should only be tweaked with the global lock held 28 * - other fields can be tweaked after grabbing the in-struct lock 29 */ 30 struct _prf_data_t { 31 prf_magic_t magic; 32 k5_mutex_t lock; 33 struct profile_node *root; 34 time_t last_stat; 35 time_t timestamp; /* time tree was last updated from file */ 36 unsigned long frac_ts; /* fractional part of timestamp, if any */ 37 int flags; /* r/w, dirty */ 38 int upd_serial; /* incremented when data changes */ 39 40 size_t fslen; 41 42 /* Some separation between fields controlled by different 43 mutexes. Theoretically, both could be accessed at the same 44 time from different threads on different CPUs with separate 45 caches. Don't let the threads clobber each other's 46 changes. One mutex controlling the whole thing would be 47 better, but sufficient separation might suffice. 48 49 This is icky. I just hope it's adequate. 50 51 For next major release, fix this. */ 52 union { double d; void *p; uint64_t ll; k5_mutex_t m; } pad; 53 54 int refcount; /* prf_file_t references */ 55 struct _prf_data_t *next; 56 /* Was: "profile_filespec_t filespec". Now: flexible char 57 array ... except, we need to work in C89, so an array 58 length must be specified. */ 59 const char filespec[sizeof("/etc/krb5.conf")]; 60 }; 61 62 typedef struct _prf_data_t *prf_data_t; 63 prf_data_t profile_make_prf_data(const char *); 64 65 struct _prf_file_t { 66 prf_magic_t magic; 67 struct _prf_data_t *data; 68 struct _prf_file_t *next; 69 }; 70 71 typedef struct _prf_file_t *prf_file_t; 72 73 /* 74 * The profile flags 75 */ 76 #define PROFILE_FILE_NO_RELOAD 0x0001 77 #define PROFILE_FILE_DIRTY 0x0002 78 #define PROFILE_FILE_SHARED 0x0004 79 80 struct _prf_lib_handle_t { 81 k5_mutex_t lock; 82 int refcount; 83 struct plugin_file_handle *plugin_handle; 84 }; 85 86 typedef struct _prf_lib_handle_t *prf_lib_handle_t; 87 88 /* 89 * This structure defines the high-level, user visible profile_t 90 * object, which is used as a handle by users who need to query some 91 * configuration file(s) 92 */ 93 struct _profile_t { 94 prf_magic_t magic; 95 prf_file_t first_file; 96 97 /* If non-null, use vtable operations instead of native ones. */ 98 struct profile_vtable *vt; 99 void *cbdata; 100 prf_lib_handle_t lib_handle; 101 }; 102 103 /* 104 * Used by the profile iterator in prof_get.c 105 */ 106 #define PROFILE_ITER_LIST_SECTION 0x0001 107 #define PROFILE_ITER_SECTIONS_ONLY 0x0002 108 #define PROFILE_ITER_RELATIONS_ONLY 0x0004 109 110 #define PROFILE_ITER_FINAL_SEEN 0x0100 111 112 /* 113 * Check if a filespec is last in a list (NULL on UNIX, invalid FSSpec on MacOS 114 */ 115 116 #define PROFILE_LAST_FILESPEC(x) (((x) == NULL) || ((x)[0] == '\0')) 117 118 /* profile_parse.c */ 119 120 errcode_t profile_parse_file 121 (FILE *f, struct profile_node **root, char **ret_modspec); 122 123 errcode_t profile_process_directory 124 (const char *dirname, struct profile_node **root); 125 126 errcode_t profile_write_tree_file 127 (struct profile_node *root, FILE *dstfile); 128 129 errcode_t profile_write_tree_to_buffer 130 (struct profile_node *root, char **buf); 131 132 133 /* prof_tree.c */ 134 135 void profile_free_node 136 (struct profile_node *relation); 137 138 errcode_t profile_create_node 139 (const char *name, const char *value, 140 struct profile_node **ret_node); 141 142 struct profile_node *profile_copy_node 143 (struct profile_node *oldnode); 144 145 errcode_t profile_verify_node 146 (struct profile_node *node); 147 148 errcode_t profile_add_node 149 (struct profile_node *section, 150 const char *name, const char *value, int check_final, 151 struct profile_node **ret_node); 152 153 errcode_t profile_make_node_final 154 (struct profile_node *node); 155 156 int profile_is_node_final 157 (struct profile_node *node); 158 159 const char *profile_get_node_name 160 (struct profile_node *node); 161 162 const char *profile_get_node_value 163 (struct profile_node *node); 164 165 errcode_t profile_find_node 166 (struct profile_node *section, 167 const char *name, const char *value, 168 int section_flag, void **state, 169 struct profile_node **node); 170 171 errcode_t profile_find_node_relation 172 (struct profile_node *section, 173 const char *name, void **state, 174 char **ret_name, char **value, int *ret_final); 175 176 errcode_t profile_find_node_subsection 177 (struct profile_node *section, 178 const char *name, void **state, 179 char **ret_name, struct profile_node **subsection); 180 181 errcode_t profile_get_node_parent 182 (struct profile_node *section, 183 struct profile_node **parent); 184 185 errcode_t profile_delete_node_relation 186 (struct profile_node *section, const char *name); 187 188 errcode_t profile_find_node_name 189 (struct profile_node *section, void **state, 190 char **ret_name); 191 192 errcode_t profile_node_iterator_create 193 (profile_t profile, const char *const *names, 194 int flags, void **ret_iter); 195 196 void profile_node_iterator_free 197 (void **iter_p); 198 199 errcode_t profile_node_iterator 200 (void **iter_p, struct profile_node **ret_node, 201 char **ret_name, char **ret_value); 202 203 errcode_t profile_remove_node 204 (struct profile_node *node); 205 206 errcode_t profile_set_relation_value 207 (struct profile_node *node, const char *new_value); 208 209 errcode_t profile_rename_node 210 (struct profile_node *node, const char *new_name); 211 212 /* prof_file.c */ 213 214 errcode_t profile_open_file 215 (const_profile_filespec_t file, prf_file_t *ret_prof, 216 char **ret_modspec); 217 218 prf_file_t profile_open_memory(void); 219 220 #define profile_update_file(P, M) profile_update_file_data((P)->data, M) 221 errcode_t profile_update_file_data 222 (prf_data_t profile, char **ret_modspec); 223 #define profile_update_file_locked(P, M) profile_update_file_data_locked((P)->data, M) 224 errcode_t profile_update_file_data_locked 225 (prf_data_t data, char **ret_modspec); 226 227 #define profile_flush_file(P) (((P) && (P)->magic == PROF_MAGIC_FILE) ? profile_flush_file_data((P)->data) : PROF_MAGIC_FILE) 228 errcode_t profile_flush_file_data 229 (prf_data_t data); 230 231 #define profile_flush_file_to_file(P,F) (((P) && (P)->magic == PROF_MAGIC_FILE) ? profile_flush_file_data_to_file((P)->data, (F)) : PROF_MAGIC_FILE) 232 errcode_t profile_flush_file_data_to_file 233 (prf_data_t data, const char *outfile); 234 235 errcode_t profile_flush_file_data_to_buffer 236 (prf_data_t data, char **bufp); 237 238 prf_file_t profile_copy_file 239 (prf_file_t oldfile); 240 241 void profile_free_file 242 (prf_file_t profile); 243 244 errcode_t profile_close_file 245 (prf_file_t profile); 246 247 int profile_file_is_writable 248 (prf_file_t profile); 249 250 void profile_dereference_data (prf_data_t); 251 void profile_dereference_data_locked (prf_data_t); 252 253 void profile_lock_global (void); 254 void profile_unlock_global (void); 255 256 /* prof_init.c -- included from profile.h */ 257 errcode_t profile_ser_size 258 (profile_t, size_t *); 259 260 errcode_t profile_ser_externalize 261 (profile_t, unsigned char **, size_t *); 262 263 errcode_t profile_ser_internalize 264 (profile_t *, unsigned char **, size_t *); 265 266 /* prof_get.c */ 267 268 errcode_t profile_get_value 269 (profile_t profile, const char **names, char **ret_value); 270 /* Others included from profile.h */ 271 272 /* prof_set.c -- included from profile.h */ 273