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