53941caea0912c8cb7efba3246765b510251d232
[apps/livebox/data-provider-master.git] / src / conf.c
1 /*
2  * Copyright 2013  Samsung Electronics Co., Ltd
3  *
4  * Licensed under the Flora License, Version 1.1 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://floralicense.org/license/
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #include <stdio.h>
18 #include <ctype.h>
19 #include <errno.h>
20 #include <string.h>
21 #include <stdlib.h>
22
23 #include <dlog.h>
24 #if defined(HAVE_LIVEBOX)
25 #include <livebox-errno.h>
26 #else
27 #include "lite-errno.h"
28 #endif
29 #include <Eina.h>
30
31 #include "conf.h"
32 #include "util.h"
33 #include "debug.h"
34
35 static const char *CONF_DEFAULT_SERVICES = "[livebox],[shortcut],[notification],[badge],[utility],[file]";
36 static const char *CONF_DEFAULT_EMERGENCY_DISK = "source=tmpfs;type=tmpfs;option=size=6M";
37 static const char *CONF_DEFAULT_PATH_CONF = "/opt/usr/live/%s/etc/%s.conf";
38 static const char *CONF_DEFAULT_PATH_IMAGE = "/opt/usr/share/live_magazine/";
39 static const char *CONF_DEFAULT_PATH_LOG = "/opt/usr/share/live_magazine/log";
40 static const char *CONF_DEFAULT_PATH_READER = "/opt/usr/share/live_magazine/reader";
41 static const char *CONF_DEFAULT_PATH_ALWAYS = "/opt/usr/share/live_magazine/always";
42 static const char *CONF_DEFAULT_PATH_SCRIPT = "/opt/usr/live/%s/res/script/%s.edj";
43 static const char *CONF_DEFAULT_PATH_ROOT = "/opt/usr/live/";
44 static const char *CONF_DEFAULT_PATH_SCRIPT_PORT = "/usr/share/data-provider-master/plugin-script/";
45 static const char *CONF_DEFAULT_PATH_DB = "/opt/dbspace/.livebox.db";
46 static const char *CONF_DEFAULT_PATH_INPUT = "/dev/input/event2";
47 static const char *CONF_DEFAULT_SCRIPT_TYPE = "edje";
48 static const char *CONF_DEFAULT_ABI = "c";
49 static const char *CONF_DEFAULT_PD_GROUP = "disclosure";
50 static const char *CONF_DEFAULT_LAUNCH_BUNDLE_NAME = "name";
51 static const char *CONF_DEFAULT_LAUNCH_BUNDLE_SECURED = "secured";
52 static const char *CONF_DEFAULT_LAUNCH_BUNDLE_ABI = "abi";
53 static const char *CONF_DEFAULT_CONTENT = "default";
54 static const char *CONF_DEFAULT_TITLE = "";
55 static const char *CONF_DEFAULT_EMPTY_CONTENT = "";
56 static const char *CONF_DEFAULT_EMPTY_TITLE = "";
57 static const char *CONF_DEFAULT_REPLACE_TAG = "/APPID/";
58 static const char *CONF_DEFAULT_PROVIDER_METHOD = "pixmap";
59 static const int CONF_DEFAULT_WIDTH = 0;
60 static const int CONF_DEFAULT_HEIGHT = 0;
61 static const int CONF_DEFAULT_BASE_WIDTH = 720;
62 static const int CONF_DEFAULT_BASE_HEIGHT = 1280;
63 static const double CONF_DEFAULT_MINIMUM_PERIOD = 1.0f;
64 static const double CONF_DEFAULT_PERIOD = -1.0f;
65 static const double CONF_DEFAULT_PACKET_TIME = 0.0001f;
66 static const unsigned long CONF_DEFAULT_MINIMUM_SPACE = 5242880;
67 static const double CONF_DEFAULT_SLAVE_TTL = 30.0f;
68 static const double CONF_DEFAULT_SLAVE_ACTIVATE_TIME = 30.0f;
69 static const double CONF_DEFAULT_SLAVE_RELAUNCH_TIME = 3.0f;
70 static const int CONF_DEFAULT_SLAVE_RELAUNCH_COUNT = 3;
71 static const int CONF_DEFAULT_MAX_LOG_LINE = 1000;
72 static const int CONF_DEFAULT_MAX_LOG_FILE = 3;
73 static const int CONF_DEFAULT_SQLITE_FLUSH_MAX = 1048576;
74 static const double CONF_DEFAULT_PING_TIME = 240.0f;
75 static const int CONF_DEFAULT_SLAVE_MAX_LOAD = 30;
76 static const int CONF_DEFAULT_USE_SW_BACKEND = 0;
77 static const int CONF_DEFAULT_DEBUG_MODE = 0;
78 static const int CONF_DEFAULT_OVERWRITE_CONTENT = 0;
79 static const int CONF_DEFAULT_COM_CORE_THREAD = 1;
80 static const int CONF_DEFAULT_USE_XMONITOR = 0;
81 static const int CONF_DEFAULT_PREMULTIPLIED = 1;
82 static const double CONF_DEFAULT_SCALE_WIDTH_FACTOR = 1.0f;
83 static const double CONF_DEFAULT_SCALE_HEIGHT_FACTOR = 1.0f;
84 static const double CONF_DEFAULT_PD_REQUEST_TIMEOUT = 5.0f;
85 static const int CONF_DEFAULT_PIXELS = sizeof(int);
86
87 int errno;
88
89 HAPI struct conf g_conf;
90
91 HAPI void conf_update_size(void)
92 {
93         util_screen_size_get(&g_conf.width, &g_conf.height);
94
95         g_conf.scale_width_factor = (double)g_conf.width / (double)BASE_W;
96         g_conf.scale_height_factor = (double)g_conf.height / (double)BASE_H;
97 }
98
99 static void use_xmonitor(char *buffer)
100 {
101         g_conf.use_xmonitor = !strcasecmp(buffer, "true");
102 }
103
104 static void emergency_disk_handler(char *buffer)
105 {
106         g_conf.emergency_disk = strdup(buffer);
107         if (!g_conf.emergency_disk) {
108                 ErrPrint("Heap: %s\n", strerror(errno));
109         }
110 }
111
112 static void services_handler(char *buffer)
113 {
114         g_conf.services = strdup(buffer);
115         if (!g_conf.services) {
116                 ErrPrint("Heap: %s\n", strerror(errno));
117         }
118 }
119
120 static void use_sw_backend_handler(char *buffer)
121 {
122         g_conf.use_sw_backend = !strcasecmp(buffer, "true");
123 }
124
125 static void provider_method_handler(char *buffer)
126 {
127         g_conf.provider_method = strdup(buffer);
128         if (!g_conf.provider_method) {
129                 ErrPrint("Heap: %s\n", strerror(errno));
130         }
131 }
132
133 static void debug_mode_handler(char *buffer)
134 {
135         g_conf.debug_mode = !strcasecmp(buffer, "true");
136 }
137
138 static void overwrite_content_handler(char *buffer)
139 {
140         g_conf.overwrite_content = !strcasecmp(buffer, "true");
141 }
142
143 static void com_core_thread_handler(char *buffer)
144 {
145         g_conf.com_core_thread = !strcasecmp(buffer, "true");
146 }
147
148 static void base_width_handler(char *buffer)
149 {
150         if (sscanf(buffer, "%d", &g_conf.base_width) != 1) {
151                 ErrPrint("Failed to parse the base_width\n");
152         }
153 }
154
155 static void base_height_handler(char *buffer)
156 {
157         if (sscanf(buffer, "%d", &g_conf.base_height) != 1) {
158                 ErrPrint("Failed to parse the base_height\n");
159         }
160 }
161
162 static void minimum_period_handler(char *buffer)
163 {
164         if (sscanf(buffer, "%lf", &g_conf.minimum_period) != 1) {
165                 ErrPrint("Failed to parse the minimum_period\n");
166         }
167         DbgPrint("Minimum period: %lf\n", g_conf.minimum_period);
168 }
169
170 static void pixels_handler(char *buffer)
171 {
172         if (sscanf(buffer, "%d", &g_conf.default_conf.pixels) != 1) {
173                 ErrPrint("Failed to parse the minimum_period\n");
174         }
175         DbgPrint("Default pixels: %lf\n", g_conf.default_conf.pixels);
176 }
177
178 static void script_handler(char *buffer)
179 {
180         g_conf.default_conf.script = strdup(buffer);
181         if (!g_conf.default_conf.script) {
182                 ErrPrint("Heap: %s\n", strerror(errno));
183         }
184 }
185
186 static void default_abi_handler(char *buffer)
187 {
188         g_conf.default_conf.abi = strdup(buffer);
189         if (!g_conf.default_conf.abi) {
190                 ErrPrint("Heap: %s\n", strerror(errno));
191         }
192 }
193
194 static void default_group_handler(char *buffer)
195 {
196         g_conf.default_conf.pd_group = strdup(buffer);
197         if (!g_conf.default_conf.pd_group) {
198                 ErrPrint("Heap: %s\n", strerror(errno));
199         }
200 }
201
202 static void default_period_handler(char *buffer)
203 {
204         if (sscanf(buffer, "%lf", &g_conf.default_conf.period) != 1) {
205                 ErrPrint("Failed to parse the default_period\n");
206         }
207         DbgPrint("Default Period: %lf\n", g_conf.default_conf.period);
208 }
209
210 static void default_packet_time_handler(char *buffer)
211 {
212         if (sscanf(buffer, "%lf", &g_conf.default_packet_time) != 1) {
213                 ErrPrint("Failed to parse the default_packet_time\n");
214         }
215         DbgPrint("Default packet time: %lf\n", g_conf.default_packet_time);
216 }
217
218 static void default_content_handler(char *buffer)
219 {
220         g_conf.default_content = strdup(buffer);
221         if (!g_conf.default_content) {
222                 ErrPrint("Heap: %s\n", strerror(errno));
223         }
224 }
225
226 static void default_title_handler(char *buffer)
227 {
228         g_conf.default_title = strdup(buffer);
229         if (!g_conf.default_title) {
230                 ErrPrint("Heap: %s\n", strerror(errno));
231         }
232 }
233
234 static void minimum_space_handler(char *buffer)
235 {
236         if (sscanf(buffer, "%lu", &g_conf.minimum_space) != 1) {
237                 ErrPrint("Failed to parse the minimum_space\n");
238         }
239 }
240
241 static void replace_tag_handler(char *buffer)
242 {
243         g_conf.replace_tag = strdup(buffer);
244         if (!g_conf.replace_tag) {
245                 ErrPrint("Heap: %s\n", strerror(errno));
246         }
247 }
248
249 static void slave_ttl_handler(char *buffer)
250 {
251         if (sscanf(buffer, "%lf", &g_conf.slave_ttl) != 1) {
252                 ErrPrint("Failed to parse the slave_ttl\n");
253         }
254         DbgPrint("Slave TTL: %lf\n", g_conf.slave_ttl);
255 }
256
257 static void slave_activate_time_handler(char *buffer)
258 {
259         if (sscanf(buffer, "%lf", &g_conf.slave_activate_time) != 1) {
260                 ErrPrint("Failed to parse the slave_activate_time\n");
261         }
262         DbgPrint("Slave activate time: %lf\n", g_conf.slave_activate_time);
263 }
264
265 static void slave_relaunch_time_handler(char *buffer)
266 {
267         if (sscanf(buffer, "%lf", &g_conf.slave_relaunch_time) != 1) {
268                 ErrPrint("Failed to parse the slave_activate_time\n");
269         }
270         DbgPrint("Slave relaunch time: %lf\n", g_conf.slave_relaunch_time);
271 }
272
273 static void slave_relaunch_count_handler(char *buffer)
274 {
275         if (sscanf(buffer, "%d", &g_conf.slave_relaunch_count) != 1) {
276                 ErrPrint("Failed to parse the max_log_line\n");
277         }
278 }
279
280 static void max_log_line_handler(char *buffer)
281 {
282         if (sscanf(buffer, "%d", &g_conf.max_log_line) != 1) {
283                 ErrPrint("Failed to parse the max_log_line\n");
284         }
285 }
286
287 static void max_log_file_handler(char *buffer)
288 {
289         if (sscanf(buffer, "%d", &g_conf.max_log_file) != 1) {
290                 ErrPrint("Failed to parse the max_log_file\n");
291         }
292 }
293
294 static void sqlite_flush_max_handler(char *buffer)
295 {
296         if (sscanf(buffer, "%lu", &g_conf.sqlite_flush_max) != 1) {
297                 ErrPrint("Failed to parse the sqlite_flush_max\n");
298         }
299 }
300
301 static void db_path_handler(char *buffer)
302 {
303         g_conf.path.db = strdup(buffer);
304         if (!g_conf.path.db) {
305                 ErrPrint("Heap: %s\n", strerror(errno));
306         }
307 }
308
309 static void reader_path_handler(char *buffer)
310 {
311         g_conf.path.reader = strdup(buffer);
312         if (!g_conf.path.reader) {
313                 ErrPrint("Heap: %s\n", strerror(errno));
314         }
315 }
316
317 static void always_path_handler(char *buffer)
318 {
319         g_conf.path.always = strdup(buffer);
320         if (!g_conf.path.always) {
321                 ErrPrint("Heap: %s\n", strerror(errno));
322         }
323 }
324
325 static void log_path_handler(char *buffer)
326 {
327         g_conf.path.slave_log = strdup(buffer);
328         if (!g_conf.path.slave_log) {
329                 ErrPrint("Heap: %s\n", strerror(errno));
330         }
331 }
332
333 static void script_port_path_handler(char *buffer)
334 {
335         g_conf.path.script_port = strdup(buffer);
336         if (!g_conf.path.script_port) {
337                 ErrPrint("Heap: %s\n", strerror(errno));
338         }
339 }
340
341 static void share_path_handler(char *buffer)
342 {
343         g_conf.path.image = strdup(buffer);
344         if (!g_conf.path.image) {
345                 ErrPrint("Heap: %s\n", strerror(errno));
346         }
347 }
348
349 static void input_path_handler(char *buffer)
350 {
351         g_conf.path.input = strdup(buffer);
352         if (!g_conf.path.input) {
353                 ErrPrint("Heap: %s\n", strerror(errno));
354         }
355 }
356
357 static void ping_time_handler(char *buffer)
358 {
359         if (sscanf(buffer, "%lf", &g_conf.ping_time) != 1) {
360                 ErrPrint("Failed to parse the ping_time\n");
361         }
362         DbgPrint("Default ping time: %lf\n", g_conf.ping_time);
363 }
364
365 static void slave_max_loader(char *buffer)
366 {
367         if (sscanf(buffer, "%d", &g_conf.slave_max_load) != 1) {
368                 ErrPrint("Failed to parse the slave_max_load\n");
369         }
370 }
371
372 static void premultiplied_handler(char *buffer)
373 {
374         if (sscanf(buffer, "%d", &g_conf.premultiplied) != 1) {
375                 ErrPrint("Failed to parse the premultiplied color\n");
376         }
377
378         DbgPrint("Premultiplied: %d\n", g_conf.premultiplied);
379 }
380
381 static void pd_request_timeout_handler(char *buffer)
382 {
383         if (sscanf(buffer, "%lf", &g_conf.pd_request_timeout) != 1) {
384                 ErrPrint("Failed to parse the request_timeout\n");
385         }
386         DbgPrint("Default PD request timeout: %lf\n", g_conf.pd_request_timeout);
387 }
388
389 HAPI void conf_init(void)
390 {
391         g_conf.width = CONF_DEFAULT_WIDTH;
392         g_conf.height = CONF_DEFAULT_HEIGHT;
393         g_conf.base_width = CONF_DEFAULT_BASE_WIDTH;
394         g_conf.base_height = CONF_DEFAULT_BASE_HEIGHT;
395         g_conf.minimum_period = CONF_DEFAULT_MINIMUM_PERIOD;
396         g_conf.default_conf.period = CONF_DEFAULT_PERIOD;
397         g_conf.default_conf.pixels = CONF_DEFAULT_PIXELS;
398         g_conf.minimum_space = CONF_DEFAULT_MINIMUM_SPACE;
399         g_conf.default_packet_time = CONF_DEFAULT_PACKET_TIME;
400         g_conf.slave_ttl = CONF_DEFAULT_SLAVE_TTL;
401         g_conf.slave_activate_time = CONF_DEFAULT_SLAVE_ACTIVATE_TIME;
402         g_conf.slave_relaunch_time = CONF_DEFAULT_SLAVE_RELAUNCH_TIME;
403         g_conf.slave_relaunch_count = CONF_DEFAULT_SLAVE_RELAUNCH_COUNT;
404         g_conf.max_log_line = CONF_DEFAULT_MAX_LOG_LINE;
405         g_conf.max_log_file = CONF_DEFAULT_MAX_LOG_FILE;
406         g_conf.sqlite_flush_max = CONF_DEFAULT_SQLITE_FLUSH_MAX;
407         g_conf.ping_time = CONF_DEFAULT_PING_TIME;
408         g_conf.slave_max_load = CONF_DEFAULT_SLAVE_MAX_LOAD;
409         g_conf.use_sw_backend = CONF_DEFAULT_USE_SW_BACKEND;
410         g_conf.debug_mode = CONF_DEFAULT_DEBUG_MODE;
411         g_conf.overwrite_content = CONF_DEFAULT_OVERWRITE_CONTENT;
412         g_conf.com_core_thread = CONF_DEFAULT_COM_CORE_THREAD;
413         g_conf.use_xmonitor = CONF_DEFAULT_USE_XMONITOR;
414         g_conf.scale_width_factor = CONF_DEFAULT_SCALE_WIDTH_FACTOR;
415         g_conf.scale_height_factor = CONF_DEFAULT_SCALE_HEIGHT_FACTOR;
416         g_conf.pd_request_timeout = CONF_DEFAULT_PD_REQUEST_TIMEOUT;
417         g_conf.premultiplied = CONF_DEFAULT_PREMULTIPLIED;
418         g_conf.default_conf.script = (char *)CONF_DEFAULT_SCRIPT_TYPE;
419         g_conf.default_conf.abi = (char *)CONF_DEFAULT_ABI;
420         g_conf.default_conf.pd_group = (char *)CONF_DEFAULT_PD_GROUP;
421         g_conf.launch_key.name = (char *)CONF_DEFAULT_LAUNCH_BUNDLE_NAME;
422         g_conf.launch_key.secured = (char *)CONF_DEFAULT_LAUNCH_BUNDLE_SECURED;
423         g_conf.launch_key.abi = (char *)CONF_DEFAULT_LAUNCH_BUNDLE_ABI;
424         g_conf.empty_content = (char *)CONF_DEFAULT_EMPTY_CONTENT;
425         g_conf.empty_title = (char *)CONF_DEFAULT_EMPTY_TITLE;
426         g_conf.default_content = (char *)CONF_DEFAULT_CONTENT;
427         g_conf.default_title = (char *)CONF_DEFAULT_TITLE;
428         g_conf.replace_tag = (char *)CONF_DEFAULT_REPLACE_TAG;
429         g_conf.path.conf = (char *)CONF_DEFAULT_PATH_CONF;
430         g_conf.path.image = (char *)CONF_DEFAULT_PATH_IMAGE;
431         g_conf.path.slave_log = (char *)CONF_DEFAULT_PATH_LOG;
432         g_conf.path.reader = (char *)CONF_DEFAULT_PATH_READER;
433         g_conf.path.always = (char *)CONF_DEFAULT_PATH_ALWAYS;
434         g_conf.path.script = (char *)CONF_DEFAULT_PATH_SCRIPT;
435         g_conf.path.root = (char *)CONF_DEFAULT_PATH_ROOT;
436         g_conf.path.script_port = (char *)CONF_DEFAULT_PATH_SCRIPT_PORT;
437         g_conf.path.db = (char *)CONF_DEFAULT_PATH_DB;
438         g_conf.path.input = (char *)CONF_DEFAULT_PATH_INPUT;
439         g_conf.provider_method = (char *)CONF_DEFAULT_PROVIDER_METHOD;
440         g_conf.emergency_disk = (char *)CONF_DEFAULT_EMERGENCY_DISK;
441         g_conf.services = (char *)CONF_DEFAULT_SERVICES;
442 }
443
444 HAPI int conf_loader(void)
445 {
446         FILE *fp;
447         int c;
448         enum state {
449                 START,
450                 SPACE,
451                 TOKEN,
452                 VALUE,
453                 ERROR,
454                 COMMENT,
455                 END
456         } state;
457         int ch_idx;
458         int token_idx;
459         int buffer_idx;
460         int quote;
461         int linelen;
462         char buffer[256];
463         static const struct token_parser {
464                 const char *name;
465                 void (*handler)(char *buffer);
466         } token_handler[] = {
467                 {
468                         .name = "base_width",
469                         .handler = base_width_handler,
470                 },
471                 {
472                         .name = "base_height",
473                         .handler = base_height_handler,
474                 },
475                 {
476                         .name = "minimum_period",
477                         .handler = minimum_period_handler,
478                 },
479                 {
480                         .name = "script",
481                         .handler = script_handler,
482                 },
483                 {
484                         .name = "pixels",
485                         .handler = pixels_handler,
486                 },
487                 {
488                         .name = "default_abi",
489                         .handler = default_abi_handler,
490                 },
491                 {
492                         .name = "default_group",
493                         .handler = default_group_handler,
494                 },
495                 {
496                         .name = "default_period",
497                         .handler = default_period_handler,
498                 },
499                 {
500                         .name = "default_packet_time",
501                         .handler = default_packet_time_handler,
502                 },
503                 {
504                         .name = "default_content",
505                         .handler = default_content_handler,
506                 },
507                 {
508                         .name = "default_title",
509                         .handler = default_title_handler,
510                 },
511                 {
512                         .name = "minimum_space",
513                         .handler = minimum_space_handler,
514                 },
515                 {
516                         .name = "replace_tag",
517                         .handler = replace_tag_handler,
518                 },
519                 {
520                         .name = "slave_ttl",
521                         .handler = slave_ttl_handler,
522                 },
523                 {
524                         .name = "slave_activate_time",
525                         .handler = slave_activate_time_handler,
526                 },
527                 {
528                         .name = "slave_relaunch_time",
529                         .handler = slave_relaunch_time_handler,
530                 },
531                 {
532                         .name = "slave_relaunch_count",
533                         .handler = slave_relaunch_count_handler,
534                 },
535                 {
536                         .name = "max_log_line",
537                         .handler = max_log_line_handler,
538                 },
539                 {
540                         .name = "max_log_file",
541                         .handler = max_log_file_handler,
542                 },
543                 {
544                         .name = "sqilte_flush_max",
545                         .handler = sqlite_flush_max_handler,
546                 },
547                 {
548                         .name = "db_path",
549                         .handler = db_path_handler,
550                 },
551                 {
552                         .name = "log_path",
553                         .handler = log_path_handler,
554                 },
555                 {
556                         .name = "reader_path",
557                         .handler = reader_path_handler,
558                 },
559                 {
560                         .name = "always_path",
561                         .handler = always_path_handler,
562                 },
563                 {
564                         .name = "share_path",
565                         .handler = share_path_handler,
566                 },
567                 {
568                         .name = "script_port_path",
569                         .handler = script_port_path_handler,
570                 },
571                 {
572                         .name = "ping_interval",
573                         .handler = ping_time_handler,
574                 },
575                 {
576                         .name = "slave_max_load",
577                         .handler = slave_max_loader,
578                 },
579                 {
580                         .name = "use_sw_backend",
581                         .handler = use_sw_backend_handler,
582                 },
583                 {
584                         .name = "emergency_disk",
585                         .handler = emergency_disk_handler,
586                 },
587                 {
588                         .name = "services",
589                         .handler = services_handler,
590                 },
591                 {
592                         .name = "use_xmonitor",
593                         .handler = use_xmonitor,
594                 },
595                 {
596                         .name = "provider_method",
597                         .handler = provider_method_handler,
598                 },
599                 {
600                         .name = "debug_mode",
601                         .handler = debug_mode_handler,
602                 },
603                 {
604                         .name = "overwrite_content",
605                         .handler = overwrite_content_handler,
606                 },
607                 {
608                         .name = "com_core_thread",
609                         .handler = com_core_thread_handler,
610                 },
611                 {
612                         .name = "input",
613                         .handler = input_path_handler,
614                 },
615                 {
616                         .name = "pd_request_timeout",
617                         .handler = pd_request_timeout_handler,
618                 },
619                 {
620                         .name = "premultiplied",
621                         .handler = premultiplied_handler,
622                 },
623                 {
624                         .name = NULL,
625                         .handler = NULL,
626                 },
627         };
628
629         fp = fopen(DEFAULT_MASTER_CONF, "rt");
630         if (!fp) {
631                 ErrPrint("Error: %s\n", strerror(errno));
632                 return LB_STATUS_ERROR_IO;
633         }
634
635         state = START;
636         ch_idx = 0;
637         token_idx = -1;
638         buffer_idx = 0;
639         quote = 0;
640         linelen = 0;
641         do {
642                 c = getc(fp);
643                 if ((c == EOF) && (state == VALUE)) {
644                         DbgPrint("[%s:%d] VALUE state EOF\n", __func__, __LINE__);
645                         state = END;
646                 }
647
648                 switch (state) {
649                 case COMMENT:
650                         if (c == CR || c == LF || c == EOF) {
651                                 buffer[buffer_idx] = '\0';
652
653                                 state = START;
654                                 token_idx = -1;
655                                 ch_idx = 0;
656                                 buffer_idx = 0;
657                                 linelen = -1; /* Will be ZERO by follwing increment code */
658                                 quote = 0;
659                         } else {
660                                 buffer[buffer_idx++] = c;
661                                 if (buffer_idx == (sizeof(buffer) - 1)) {
662                                         buffer[buffer_idx] = '\0';
663                                         buffer_idx = 0;
664                                 }
665                         }
666                         break;
667                 case START:
668                         if (linelen == 0 && c == '#') {
669                                 state = COMMENT;
670                         } else if (isspace(c)) {
671                                 /* Ignore empty space */
672                         } else {
673                                 state = TOKEN;
674                                 ungetc(c, fp);
675                         }
676                         break;
677                 case SPACE:
678                         if (c == '=') {
679                                 state = VALUE;
680                         } else if (!isspace(c)) {
681                                 state = ERROR;
682                         }
683                         break;
684                 case VALUE:
685                         if (c == '"') {
686                                 if (quote == 1) {
687                                         buffer[buffer_idx] = '\0';
688                                         state = END;
689                                 } else if (buffer_idx != 0) {
690                                         buffer[buffer_idx++] = c;
691                                         if (buffer_idx >= sizeof(buffer)) {
692                                                 state = ERROR;
693                                         }
694                                 } else {
695                                         quote = 1;
696                                 }
697                         } else if (isspace(c)) {
698                                 if (buffer_idx == 0) {
699                                         /* Ignore */
700                                 } else if (quote == 1) {
701                                         buffer[buffer_idx++] = c;
702                                         if (buffer_idx >= sizeof(buffer)) {
703                                                 state = ERROR;
704                                         }
705                                 } else {
706                                         buffer[buffer_idx] = '\0';
707                                         ungetc(c, fp);
708                                         state = END;
709                                 }
710                         } else {
711                                 buffer[buffer_idx++] = c;
712                                 if (buffer_idx >= sizeof(buffer)) {
713                                         state = ERROR;
714                                 }
715                         }
716                         break;
717                 case TOKEN:
718                         if (c == '=') {
719                                 if (token_idx < 0) {
720                                         state = ERROR;
721                                 } else {
722                                         state = VALUE;
723                                 }
724                         } else if (isspace(c)) {
725                                 if (token_idx < 0) {
726                                         break;
727                                 }
728
729                                 if (token_handler[token_idx].name[ch_idx] != '\0') {
730                                         state = ERROR;
731                                 } else {
732                                         state = SPACE;
733                                 }
734                         } else  {
735                                 if (token_idx < 0) {
736                                         /* Now start to find a token! */
737                                         token_idx = 0;
738                                 }
739
740                                 if (token_handler[token_idx].name[ch_idx] == c) {
741                                         ch_idx++;
742                                 } else {
743                                         ungetc(c, fp);
744                                         while (ch_idx-- > 0)
745                                                 ungetc(token_handler[token_idx].name[ch_idx], fp);
746
747                                         token_idx++;
748
749                                         if (token_handler[token_idx].name == NULL) {
750                                                 state = ERROR;
751                                         } else {
752                                                 ch_idx = 0;
753                                         }
754                                 }
755                         }
756                         break;
757                 case ERROR:
758                         if (c == CR || c == LF || c == EOF) {
759                                 state = START;
760                                 token_idx = -1;
761                                 buffer_idx = 0;
762                                 ch_idx = 0;
763                                 linelen = -1;
764                                 quote = 0;
765                         }
766                         break;
767                 case END:
768                         if (c == LF || c == CR || c == EOF) {
769                                 state = START;
770
771                                 if (token_idx >= 0 && token_handler[token_idx].handler) {
772                                         buffer[buffer_idx] = '\0';
773                                         token_handler[token_idx].handler(buffer);
774                                 }
775
776                                 token_idx = -1;
777                                 ch_idx = 0;
778                                 buffer_idx = 0;
779                                 linelen = -1;
780                                 quote = 0;
781                                 /* Finish */
782                         } else if (isspace(c)) {
783                                 /* ignore */
784                         } else {
785                                 state = ERROR;
786                         }
787                         break;
788                 default:
789                         /* ?? */
790                         break;
791                 }
792
793                 linelen++;
794          } while (c != EOF);
795
796         if (fclose(fp) != 0) {
797                 ErrPrint("fclose: %s\n", strerror(errno));
798         }
799         return LB_STATUS_SUCCESS;
800 }
801
802 HAPI void conf_reset(void)
803 {
804         g_conf.width = CONF_DEFAULT_WIDTH;
805         g_conf.height = CONF_DEFAULT_HEIGHT;
806         g_conf.base_width = CONF_DEFAULT_BASE_WIDTH;
807         g_conf.base_height = CONF_DEFAULT_BASE_HEIGHT;
808         g_conf.minimum_period = CONF_DEFAULT_MINIMUM_PERIOD;
809         g_conf.default_conf.period = CONF_DEFAULT_PERIOD;
810         g_conf.minimum_space = CONF_DEFAULT_MINIMUM_SPACE;
811         g_conf.default_packet_time = CONF_DEFAULT_PACKET_TIME;
812         g_conf.slave_ttl = CONF_DEFAULT_SLAVE_TTL;
813         g_conf.slave_activate_time = CONF_DEFAULT_SLAVE_ACTIVATE_TIME;
814         g_conf.slave_relaunch_time = CONF_DEFAULT_SLAVE_RELAUNCH_TIME;
815         g_conf.slave_relaunch_count = CONF_DEFAULT_SLAVE_RELAUNCH_COUNT;
816         g_conf.max_log_line = CONF_DEFAULT_MAX_LOG_LINE;
817         g_conf.max_log_file = CONF_DEFAULT_MAX_LOG_FILE;
818         g_conf.sqlite_flush_max = CONF_DEFAULT_SQLITE_FLUSH_MAX;
819         g_conf.ping_time = CONF_DEFAULT_PING_TIME;
820         g_conf.slave_max_load = CONF_DEFAULT_SLAVE_MAX_LOAD;
821         g_conf.use_sw_backend = CONF_DEFAULT_USE_SW_BACKEND;
822         g_conf.debug_mode = CONF_DEFAULT_DEBUG_MODE;
823         g_conf.overwrite_content = CONF_DEFAULT_OVERWRITE_CONTENT;
824         g_conf.com_core_thread = CONF_DEFAULT_COM_CORE_THREAD;
825         g_conf.use_xmonitor = CONF_DEFAULT_USE_XMONITOR;
826         g_conf.scale_width_factor = CONF_DEFAULT_SCALE_WIDTH_FACTOR;
827         g_conf.scale_height_factor = CONF_DEFAULT_SCALE_HEIGHT_FACTOR;
828         g_conf.pd_request_timeout = CONF_DEFAULT_PD_REQUEST_TIMEOUT;
829         g_conf.premultiplied = CONF_DEFAULT_PREMULTIPLIED;
830         g_conf.default_conf.pixels = CONF_DEFAULT_PIXELS;
831
832         if (g_conf.default_conf.script != CONF_DEFAULT_SCRIPT_TYPE) {
833                 DbgFree(g_conf.default_conf.script);
834                 g_conf.default_conf.script = (char *)CONF_DEFAULT_SCRIPT_TYPE;
835         }
836
837         if (g_conf.default_conf.abi != CONF_DEFAULT_ABI) {
838                 DbgFree(g_conf.default_conf.abi);
839                 g_conf.default_conf.abi = (char *)CONF_DEFAULT_ABI;
840         }
841
842         if (g_conf.default_conf.pd_group != CONF_DEFAULT_PD_GROUP) {
843                 DbgFree(g_conf.default_conf.pd_group);
844                 g_conf.default_conf.pd_group = (char *)CONF_DEFAULT_PD_GROUP;
845         }
846
847         if (g_conf.launch_key.name != CONF_DEFAULT_LAUNCH_BUNDLE_NAME) {
848                 DbgFree(g_conf.launch_key.name);
849                 g_conf.launch_key.name = (char *)CONF_DEFAULT_LAUNCH_BUNDLE_NAME;
850         }
851
852         if (g_conf.launch_key.secured != CONF_DEFAULT_LAUNCH_BUNDLE_SECURED) {
853                 DbgFree(g_conf.launch_key.secured);
854                 g_conf.launch_key.secured = (char *)CONF_DEFAULT_LAUNCH_BUNDLE_SECURED;
855         }
856
857         if (g_conf.launch_key.abi != CONF_DEFAULT_LAUNCH_BUNDLE_ABI) {
858                 DbgFree(g_conf.launch_key.abi);
859                 g_conf.launch_key.abi = (char *)CONF_DEFAULT_LAUNCH_BUNDLE_ABI;
860         }
861
862         if (g_conf.empty_content != CONF_DEFAULT_EMPTY_CONTENT) {
863                 DbgFree(g_conf.empty_content);
864                 g_conf.empty_content = (char *)CONF_DEFAULT_EMPTY_CONTENT;
865         }
866
867         if (g_conf.empty_title != CONF_DEFAULT_EMPTY_TITLE) {
868                 DbgFree(g_conf.empty_title);
869                 g_conf.empty_title = (char *)CONF_DEFAULT_EMPTY_TITLE;
870         }
871
872         if (g_conf.default_content != CONF_DEFAULT_CONTENT) {
873                 DbgFree(g_conf.default_content);
874                 g_conf.default_content = (char *)CONF_DEFAULT_CONTENT;
875         }
876
877         if (g_conf.default_title != CONF_DEFAULT_TITLE) {
878                 DbgFree(g_conf.default_title);
879                 g_conf.default_title = (char *)CONF_DEFAULT_TITLE;
880         }
881
882         if (g_conf.replace_tag != CONF_DEFAULT_REPLACE_TAG) {
883                 DbgFree(g_conf.replace_tag);
884                 g_conf.replace_tag = (char *)CONF_DEFAULT_REPLACE_TAG;
885         }
886
887         if (g_conf.path.conf != CONF_DEFAULT_PATH_CONF) {
888                 DbgFree(g_conf.path.conf);
889                 g_conf.path.conf = (char *)CONF_DEFAULT_PATH_CONF;
890         }
891
892         if (g_conf.path.image != CONF_DEFAULT_PATH_IMAGE) {
893                 DbgFree(g_conf.path.image);
894                 g_conf.path.image = (char *)CONF_DEFAULT_PATH_IMAGE;
895         }
896
897         if (g_conf.path.slave_log != CONF_DEFAULT_PATH_LOG) {
898                 DbgFree(g_conf.path.slave_log);
899                 g_conf.path.slave_log = (char *)CONF_DEFAULT_PATH_LOG;
900         }
901
902         if (g_conf.path.reader != CONF_DEFAULT_PATH_READER) {
903                 DbgFree(g_conf.path.reader);
904                 g_conf.path.reader = (char *)CONF_DEFAULT_PATH_READER;
905         }
906
907         if (g_conf.path.always != CONF_DEFAULT_PATH_ALWAYS) {
908                 DbgFree(g_conf.path.always);
909                 g_conf.path.always = (char *)CONF_DEFAULT_PATH_ALWAYS;
910         }
911
912         if (g_conf.path.script != CONF_DEFAULT_PATH_SCRIPT) {
913                 DbgFree(g_conf.path.script);
914                 g_conf.path.script = (char *)CONF_DEFAULT_PATH_SCRIPT;
915         }
916
917         if (g_conf.path.root != CONF_DEFAULT_PATH_ROOT) {
918                 DbgFree(g_conf.path.root);
919                 g_conf.path.root = (char *)CONF_DEFAULT_PATH_ROOT;
920         }
921
922         if (g_conf.path.script_port != CONF_DEFAULT_PATH_SCRIPT_PORT) {
923                 DbgFree(g_conf.path.script_port);
924                 g_conf.path.script_port = (char *)CONF_DEFAULT_PATH_SCRIPT_PORT;
925         }
926
927         if (g_conf.path.db != CONF_DEFAULT_PATH_DB) {
928                 DbgFree(g_conf.path.db);
929                 g_conf.path.db = (char *)CONF_DEFAULT_PATH_DB;
930         }
931
932         if (g_conf.path.input != CONF_DEFAULT_PATH_INPUT) {
933                 DbgFree(g_conf.path.input);
934                 g_conf.path.input = (char *)CONF_DEFAULT_PATH_INPUT;
935         }
936
937         if (g_conf.provider_method != CONF_DEFAULT_PROVIDER_METHOD) {
938                 DbgFree(g_conf.provider_method);
939                 g_conf.provider_method = (char *)CONF_DEFAULT_PROVIDER_METHOD;
940         }
941
942         if (g_conf.emergency_disk != CONF_DEFAULT_EMERGENCY_DISK) {
943                 DbgFree(g_conf.emergency_disk);
944                 g_conf.emergency_disk = (char *)CONF_DEFAULT_EMERGENCY_DISK;
945         }
946
947         if (g_conf.services != CONF_DEFAULT_SERVICES) {
948                 DbgFree(g_conf.services);
949                 g_conf.services = (char *)CONF_DEFAULT_SERVICES;
950         }
951 }
952
953 /* End of a file */