summaryrefslogtreecommitdiffabout
path: root/include/sitecing/configuration.h
blob: 330a5a613f061233f7fe2fbba2c06302f05e7437 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
#ifndef __SITECING_CONFIGURATION_H
#define __SITECING_CONFIGURATION_H

#include <sys/types.h>
#include <sys/stat.h>
#include <string>
#include <list>
#include <map>
#include <pcre++.h>

/**
 * @file
 * @brief Classes related to configuration.
 */

namespace sitecing {
    using namespace std;

    class configuration;

    /**
     * The config options container class.
     */
    class config_options {
	public:
	    /**
	     * The flags enumeration.
	     */
	    enum _flags {
		/**
		 * Skeleton has been specified in the context.
		 * @see skeleton
		 */
		flag_skeleton             = 0x0001,
		/**
		 * CPPFLAGS have been specified in the context
		 * @see cpp_flags
		 */
		flag_cpp_flags            = 0x0002,
		/**
		 * LDFLAGS have been specified in the context.
		 * @see ld_flags
		 */
		flag_ld_flags             = 0x0004,
		/**
		 * Enforced intermediate dependencies have been specified in the
		 * context.
		 * @see internediate_deps
		 */
		flag_intermediate_deps    = 0x0008,
		/**
		 * Enforced .so dependencies have been specified in the context.
		 * @see so_deps
		 */
		flag_so_deps              = 0x0010,
		/**
		 * Whether components should be built specified in the context.
		 * @see build
		 */
		flag_build                = 0x0020,
		/**
		 * Whether to track down cpp dependencies has been specified in
		 * the context.
		 * @see cpp_deps
		 */
		flag_cpp_deps             = 0x0040,
		/**
		 * The exception handler has been specified in the context.
		 * @see exception_handler
		 */
		flag_exception_handler    = 0x0080,
		/**
		 * Action handlers have been specified in the context.
		 * @see action_handlers
		 */
		flag_action_handlers      = 0x0100,
		/**
		 * HTTP status handerls have been specified in the context.
		 * @see http_status_handlers
		 */
		flag_http_status_handlers = 0x0200,
		/**
		 * The files to be built are specified in the context.
		 * @see auto_build_files
		 */
		flag_auto_build_files     = 0x0400
	    };
	    /**
	     * The flags specifying what parts of configuration have been
	     * specified for the context.
	     */
	    int flags;

	    /**
	     * The skeleton for building components.
	     */
	    string skeleton;
	    /**
	     * The flags to pass to compiler.
	     */
	    list<string> cpp_flags;
	    /**
	     * The flags to pass to linker.
	     */
	    list<string> ld_flags;
	    /**
	     * Whether to build inexstent and outdated components.
	     */
	    bool build;
	    /**
	     * Whether to track cpp dependencies.
	     */
	    bool cpp_deps;
	    /**
	     * The component handling caught exceptions.
	     */
	    string exception_handler;
	    /**
	     * Enforced intermediate dependencies.
	     */
	    list<string> intermediate_deps;
	    /**
	     * Enforced depencies for .so objects.
	     */
	    list<string> so_deps;
	    /**
	     * The action handler type.
	     */
	    struct action_handler_t {
		/**
		 * The regexp to check request against.
		 */
		string s_regex;
		/**
		 * Precompiled regex.
		 */
		pcrepp::Pcre regex;
		/**
		 * The action handler component.
		 */
		string action;
		/**
		 * Arguments for the action hander coponent.
		 */
		list<string> args;

		action_handler_t(const string& s,const string& a)
		    : s_regex(s), regex(s), action(a) { }
		action_handler_t(const action_handler_t& s)
		    : s_regex(s.s_regex), regex(s.regex), action (s.action), args(s.args) { }
	    };
	    /**
	     * Type for the list of action handlers.
	     */
	    typedef list<action_handler_t> action_handlers_t;
	    /**
	     * The list of action handlers.
	     */
	    action_handlers_t action_handlers;
	    /**
	     * Type for the map of HTTP status handler components.
	     */
	    typedef map<string,string> http_status_handlers_t;
	    /**
	     * The map of HTTP status handler components.
	     */
	    http_status_handlers_t http_status_handlers;
	    /**
	     * Files to be built automatically.
	     */
	    list<string> auto_build_files;

	    config_options()
		: flags(0) { }

	    /**
	     * Look up if there is an action handler for the target defined.
	     * @param target the target component.
	     * @return the pointer to handler or zero.
	     */
	    action_handler_t *lookup_action_handler(const string& target);
	    /**
	     * Look up if there is a handler defined for the HTTP status.
	     * @param status HTTP status
	     * @return the handler component.
	     */
	    string lookup_http_status_handler(const string& status);
	    /**
	     * Check whether the file should be build automatically.
	     * @param fn file name.
	     * @param rv reference to the boolean where the answer should go.
	     * @return true if we know the answer.
	     */
	    bool match_autobuild_files(const char *fn,bool &rv);
    };

    /**
     * Configuration data container for the configuration loaded from disk file.
     */
    class loaded_options : public config_options {
	public:
	    /**
	     * The file where configuration originates from.
	     */
	    string source_file;
	    /**
	     * The stat structure for the source file as it was when we have
	     * loaded it.
	     */
	    struct stat st;

	    /**
	     * See if the data is still valid.
	     * @return true if yes.
	     */
	    bool is_valid();

	    /**
	     * Load the configuration file.
	     * @param config the main configuration container.
	     * @param the configuration file.
	     */
	    void parse(configuration *config,const string& cfile);
    };

    /**
     * The main configuration container.
     */
    class configuration {
	public:
	    /**
	     * @todo TODO:: document me.
	     */
	    bool autobuild;
	    /**
	     * The flags enumeration.
	     */
	    enum _flags {
		/**
		 * Was the source root specified?
		 * @see root_source
		 */
		flag_root_source        = 0x00000001,
		/**
		 * Was the root for intermediate files specified?
		 * @see root_intermediate
		 */
		flag_root_intermediate  = 0x00000002,
		/**
		 * Was the root for the resulting .so files specified?
		 * @see root_so
		 */
		flag_root_so            = 0x00000004,
		/**
		 * Was the socket to listen to specified?
		 * @see listen_socket
		 */
		flag_listen_socket      = 0x00000008,
		/**
		 * Was the per-dir config file name specified.
		 * @see rc_file_name
		 */
		flag_rc_file_name       = 0x00000010,
		/**
		 * Was the minimum number of child processes specified?
		 * @see min_children
		 */
		flag_min_children       = 0x00000020,
		/**
		 * Was the maximum number of child processes specified?
		 * @see max_children
		 */
		flag_max_children       = 0x00000040,
		/**
		 * Was the minimum number of spare child processes specified?
		 * @see min_spare_children
		 */
		flag_min_spare_children = 0x00000080,
		/**
		 * Was he maximum number of spare child processes specified?
		 * @see max_spare_children
		 */
		flag_max_spare_children = 0x00000100,
		/**
		 * Was the number of requests to handle per child process
		 * specified?
		 * @see requests_per_child
		 */
		flag_requests_per_child = 0x00000200,
		/**
		 * Was the multiprocess node (or it's absences) specified?
		 * @see multi_process
		 */
		flag_multi_process      = 0x00000400,
		/**
		 * Was the user specified?
		 * @see user
		 */
		flag_user               = 0x00000800,
		/**
		 * @Was the group specified?
		 * @see group
		 */
		flag_group              = 0x00001000,
		/**
		 * Was the root to change to specified?
		 * @see chroot
		 */
		flag_chroot             = 0x00002000,
		/**
		 * Was the file for storing PID specified?
		 * @see pidfile
		 */
		flag_pid_file           = 0x00004000,
		/**
		 * Was it specified wether we should daemonize the process?
		 * @see daemonize
		 */
		flag_daemonize          = 0x00008000
	    };
	    /**
	     * The flags specifying what parts of the configuration has been
	     * loaded into the object.
	     */
	    long flags;

	    /**
	     * The root for the components source code.
	     */
	    string root_source;
	    /**
	     * The root for intermediate files.
	     */
	    string root_intermediate;
	    /**
	     * The root for .so files.
	     */
	    string root_so;
	    /**
	     * Socket to bind to
	     */
	    string listen_socket;
	    /**
	     * per-dir config file name.
	     */
	    string rc_file_name;
	    /**
	     * The minimum number of child processes in multiprocess mode.
	     */
	    int min_children;
	    /**
	     * The maxium number of child processes in multiprocess mode.
	     */
	    int max_children;
	    /**
	     * The minimum number of spare chidren in multiprocess mode.
	     */
	    int min_spare_children;
	    /**
	     * The maximum number of spare children in multiprocess mode.
	     */
	    int max_spare_children;
	    /**
	     * The number of requests the child process should handle before
	     * exiting.
	     */
	    int requests_per_child;
	    /**
	     * Whether we should run in multiprocess mode or not.
	     */
	    bool multi_process;
	    /**
	     * User to change to.
	     */
	    string user;
	    /**
	     * Group to set to.
	     */
	    string group;
	    /**
	     * Directory to change root to.
	     */
	    string chroot;
	    /**
	     * The file to store PID into.
	     */
	    string pid_file;
	    /**
	     * Whether we should fork into background.
	     */
	    bool daemonize;

	    typedef map<string,config_options> specs_t;
	    /**
	     * The local config options map.
	     */
	    specs_t specs;
	    typedef map<string,loaded_options> loaded_specs_t;
	    /**
	     * The local config options as specified in per-dir config files
	     * map.
	     */
	    loaded_specs_t loaded_specs;

	    configuration();
	    /**
	     * @param cfile the configuration file.
	     * @param ab @todo TODO:: document me
	     */
	    configuration(const string& cfile,bool ab=false);

	    /**
	     * Parse the configuration file.
	     * @param cfile the configuration file.
	     */
	    void parse(const string& cfile);

	    /**
	     * Fetch the reference to options for the very root.
	     */
	    config_options& root_options() { return specs[""]; }
	    /**
	     * Lookup where the certain config option for the target lies in.
	     * @param target the target component.
	     * @param flag the flag specifying the option we're looking for.
	     * @return the destination options continer or zero.
	     */
	    config_options* lookup_config(const string& target,int flag);
	    /**
	     * Lookup the action handler for the target.
	     * @param target the target request.
	     * @return the action handler or zero.
	     */
	    config_options::action_handler_t *lookup_action_handler(const string& target);
	    /**
	     * Lookup the HTPP status handler for the target.
	     * @param target the target.
	     * @param status the HTTP status.
	     * @return the handler component.
	     */
	    string lookup_http_status_handler(const string& target,const string& status);
	    /**
	     * Lookup the options loaded from per-dir config for the target
	     * @param target the target.
	     * @return options container or zero.
	     */
	    loaded_options* lookup_loaded_options(const string& target);
	    /**
	     * Check whether the components for the target should be prebuilt.
	     * @param target the target.
	     * @param fn file name.
	     * @return true if yes.
	     */
	    bool match_autobuild_files(const string& target,const char *fn);
    };

}

#endif /* __SITECING_CONFIGURATION_H */