1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4
5 /* this example does not work for WIN32 */
6
7 #ifndef WIN32
8 #include <dlfcn.h> /* for dlopen(), dlerror(), dlclose() */
9 #include <unistd.h>
10 #endif
11
12 #include <dotconf.h>
13
14 /* define our callbacks; */
15 /* for definition of DOTCONF_CB see dotconf.h */
16
17 static DOTCONF_CB(cb_example);
18 static DOTCONF_CB(cb_moreargs);
19 static DOTCONF_CB(cb_addmodule);
20 static DOTCONF_CB(cb_multiline); /* here document test */
21 static DOTCONF_CB(cb_unknown); /* fallback for unknwon options */
22
23 /* define the Option ExampleOption that expects a string
24 * and tell the parser to call the function cb_example
25 */
26 static const configoption_t options[] = {
27 {"ExampleOption", ARG_STR, cb_example, 0, 0},
28 {"MoreArgs", ARG_LIST, cb_moreargs, 0, 0},
29 {"AddModule", ARG_STR, cb_addmodule, 0, 0},
30 {"MultiLineRaw", ARG_STR, cb_multiline, 0, 0},
31 {"", ARG_NAME, cb_unknown, 0, 0},
32 LAST_OPTION
33 };
34
35 #define NUM_MODULES 10
36 static void *handles[NUM_MODULES]; /* handles of dynamically loaded modules */
37
main(int argc,char ** argv)38 int main(int argc, char **argv)
39 {
40 int i;
41 configfile_t *configfile;
42
43 memset(handles, 0, sizeof(handles));
44 putenv("TESTUSER=lukas");
45
46 /*
47 * start reading config, CASE_INSENSITIVE (specify NONE or 0 for the
48 * the default behaviour which matches case sensitive
49 */
50 configfile = dotconf_create(argv[1] ? argv[1] : "sample.conf",
51 options, 0, CASE_INSENSITIVE);
52 if (!configfile) {
53 fprintf(stderr, "Error opening config file\n");
54 return 1;
55 }
56
57 if (dotconf_command_loop(configfile) == 0)
58 fprintf(stderr, "Error reading config file\n");
59
60 dotconf_cleanup(configfile);
61
62 for (i = 0; i < NUM_MODULES && handles[i]; i++)
63 dlclose(handles[i]);
64
65 return 0;
66 }
67
68 /* the error-handler; a new feature of v0.7.0 to filter out messages
69 issued using config_warning
70 FUNC_ERRORHANDLER(my_errorhandler)
71 {
72 printf("ERROR [type=%d][%d] %s\n", type, dc_errno, msg);
73 }
74 */
75
76 /* declare our callback function */
DOTCONF_CB(cb_example)77 DOTCONF_CB(cb_example)
78 {
79 printf("%s:%ld: ExampleOption: [arg=%s]\n", cmd->configfile->filename,
80 cmd->configfile->line, cmd->data.str);
81 return NULL;
82 }
83
84 /*
85 * we dont need the userdata, so dont mention it
86 * otherwise we should've appended it as argument 3
87 */
DOTCONF_CB(cb_moreargs)88 DOTCONF_CB(cb_moreargs)
89 {
90 int i;
91 for (i = 0; i < cmd->arg_count; i++)
92 printf("%s:%ld: [MoreArgs] Arg #%d '%s'\n",
93 cmd->configfile->filename, cmd->configfile->line, i + 1,
94 cmd->data.list[i]);
95 return 0;
96 }
97
DOTCONF_CB(cb_addmodule)98 DOTCONF_CB(cb_addmodule)
99 {
100 int i;
101 char filename[128]; /* filename of modules */
102
103 for (i = 0; (i < NUM_MODULES) && (handles[i] != 0); i++) ;
104
105 snprintf(filename, 128, "./%s.so", cmd->data.str);
106
107 if (!access(filename, R_OK)) { /* if file access is permitted */
108 /* load library */
109 handles[i] = dlopen(filename, RTLD_LAZY);
110 if (!handles[i])
111 printf("Error opening library: %s\n", dlerror());
112 dotconf_register_options(cmd->configfile,
113 dlsym(handles[i], "new_options"));
114 }
115 printf("Module %s successfully loaded\n", cmd->data.str);
116 return NULL;
117 }
118
DOTCONF_CB(cb_multiline)119 DOTCONF_CB(cb_multiline)
120 {
121 printf("%s:%ld: [MultiLine - START] -%s- [MultiLine - END]\n",
122 cmd->configfile->filename, cmd->configfile->line, cmd->data.str);
123 return NULL;
124 }
125
DOTCONF_CB(cb_unknown)126 DOTCONF_CB(cb_unknown)
127 {
128 int i = 0;
129
130 printf("%s:%ld: UNKNOWN [%s]",
131 cmd->configfile->filename, cmd->configfile->line, cmd->name);
132
133 for (i = 0; cmd->data.list[i]; i++)
134 printf(", %s", cmd->data.list[i]);
135 printf("\n");
136 return NULL;
137 }
138