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