Implement normal UNIX-style configuration files:
* mailbox/cfg_lexer.c: New file. * mailbox/cfg_parser.c: New file. * mailbox/cfg_parser.h: New file. * mailbox/Makefile.am: Add cfg_ sources and socket_stream.c. * include/mailutils/cfg.h: New file. * include/mailutils/Makefile.am (pkginclude_HEADERS): Add cfg.h. * include/mailutils/argp.h: Include cfg.h. (mu_create_argcv): Remove prototype. * include/mailutils/mu_auth.h (struct mu_auth_module): New member `cfg'. (MU_AUTH_REGISTER_ALL_MODULES): Call mu_auth_init first. * mailbox/mu_argp.c: Rewrite. Implement normal configuration (resource) file support. Overloaded command line options begin to phase out. * mailbox/mu_auth.c, auth/gsasl.c, auth/pam.c, auth/radius.c, auth/sql.c, auth/tls.c, auth/virtual.c, libsieve/argp.c, mailbox/system.c: Implement configuration statements. * imap4d/imap4d.c: Begin switching to the new configuration scheme.
Showing
18 changed files
with
842 additions
and
60 deletions
... | @@ -41,8 +41,7 @@ char *mu_gsasl_cram_md5_pwd = SITE_CRAM_MD5_PWD; | ... | @@ -41,8 +41,7 @@ char *mu_gsasl_cram_md5_pwd = SITE_CRAM_MD5_PWD; |
41 | #define ARG_CRAM_PASSWD 1 | 41 | #define ARG_CRAM_PASSWD 1 |
42 | 42 | ||
43 | static struct argp_option _gsasl_argp_options[] = { | 43 | static struct argp_option _gsasl_argp_options[] = { |
44 | {NULL, 0, NULL, 0, N_("GSASL options"), 0}, | 44 | {"cram-passwd", ARG_CRAM_PASSWD, N_("FILE"), OPTION_HIDDEN, |
45 | {"cram-passwd", ARG_CRAM_PASSWD, N_("FILE"), 0, | ||
46 | N_("Specify password file for CRAM-MD5 authentication"), 0}, | 45 | N_("Specify password file for CRAM-MD5 authentication"), 0}, |
47 | { NULL, 0, NULL, 0, NULL, 0 } | 46 | { NULL, 0, NULL, 0, NULL, 0 } |
48 | }; | 47 | }; |
... | @@ -77,7 +76,7 @@ static struct argp_child _gsasl_argp_child = { | ... | @@ -77,7 +76,7 @@ static struct argp_child _gsasl_argp_child = { |
77 | void | 76 | void |
78 | mu_gsasl_init_argp () | 77 | mu_gsasl_init_argp () |
79 | { | 78 | { |
80 | if (mu_register_capa ("gsasl", &_gsasl_argp_child)) | 79 | if (mu_register_capa ("gsasl", &_gsasl_argp_child, NULL)) |
81 | { | 80 | { |
82 | mu_error (_("INTERNAL ERROR: cannot register argp capability gsasl")); | 81 | mu_error (_("INTERNAL ERROR: cannot register argp capability gsasl")); |
83 | abort (); | 82 | abort (); | ... | ... |
... | @@ -150,7 +150,7 @@ mu_pam_argp_parser (int key, char *arg, struct argp_state *state) | ... | @@ -150,7 +150,7 @@ mu_pam_argp_parser (int key, char *arg, struct argp_state *state) |
150 | } | 150 | } |
151 | 151 | ||
152 | static struct argp_option mu_pam_argp_option[] = { | 152 | static struct argp_option mu_pam_argp_option[] = { |
153 | { "pam-service", ARG_PAM_SERVICE, N_("STRING"), 0, | 153 | { "pam-service", ARG_PAM_SERVICE, N_("STRING"), OPTION_HIDDEN, |
154 | N_("Use STRING as PAM service name"), 0}, | 154 | N_("Use STRING as PAM service name"), 0}, |
155 | { NULL, 0, NULL, 0, NULL, 0 } | 155 | { NULL, 0, NULL, 0, NULL, 0 } |
156 | }; | 156 | }; |
... | @@ -179,8 +179,10 @@ struct mu_auth_module mu_auth_pam_module = { | ... | @@ -179,8 +179,10 @@ struct mu_auth_module mu_auth_pam_module = { |
179 | "pam", | 179 | "pam", |
180 | #ifdef USE_LIBPAM | 180 | #ifdef USE_LIBPAM |
181 | &mu_pam_argp, | 181 | &mu_pam_argp, |
182 | NULL, | ||
182 | #else | 183 | #else |
183 | NULL, | 184 | NULL, |
185 | NULL, | ||
184 | #endif | 186 | #endif |
185 | mu_authenticate_pam, | 187 | mu_authenticate_pam, |
186 | NULL, | 188 | NULL, | ... | ... |
... | @@ -51,13 +51,13 @@ | ... | @@ -51,13 +51,13 @@ |
51 | #define ARG_RADIUS_DIR 259 | 51 | #define ARG_RADIUS_DIR 259 |
52 | 52 | ||
53 | static struct argp_option mu_radius_argp_option[] = { | 53 | static struct argp_option mu_radius_argp_option[] = { |
54 | { "radius-auth-request", ARG_AUTH_REQUEST, N_("REQUEST"), 0, | 54 | { "radius-auth-request", ARG_AUTH_REQUEST, N_("REQUEST"), OPTION_HIDDEN, |
55 | N_("Radius request to authenitcate the user"), 0 }, | 55 | N_("Radius request to authenitcate the user"), 0 }, |
56 | { "radius-getpwnam-request", ARG_GETPWNAM_REQUEST, N_("REQUEST"), 0, | 56 | { "radius-getpwnam-request", ARG_GETPWNAM_REQUEST, N_("REQUEST"), OPTION_HIDDEN, |
57 | N_("Radius request to retrieve a passwd entry based on username"), 0 }, | 57 | N_("Radius request to retrieve a passwd entry based on username"), 0 }, |
58 | { "radius-getpwuid-request", ARG_GETPWUID_REQUEST, N_("REQUEST"), 0, | 58 | { "radius-getpwuid-request", ARG_GETPWUID_REQUEST, N_("REQUEST"), OPTION_HIDDEN, |
59 | N_("Radius request to retrieve a passwd entry based on UID"), 0 }, | 59 | N_("Radius request to retrieve a passwd entry based on UID"), 0 }, |
60 | { "radius-directory", ARG_RADIUS_DIR, N_("DIR"), 0, | 60 | { "radius-directory", ARG_RADIUS_DIR, N_("DIR"), OPTION_HIDDEN, |
61 | N_("Set path to the radius configuration directory"), 0 }, | 61 | N_("Set path to the radius configuration directory"), 0 }, |
62 | { NULL } | 62 | { NULL } |
63 | }; | 63 | }; |
... | @@ -598,8 +598,10 @@ struct mu_auth_module mu_auth_radius_module = { | ... | @@ -598,8 +598,10 @@ struct mu_auth_module mu_auth_radius_module = { |
598 | "radius", | 598 | "radius", |
599 | #ifdef ENABLE_RADIUS | 599 | #ifdef ENABLE_RADIUS |
600 | &mu_radius_argp, | 600 | &mu_radius_argp, |
601 | NULL, | ||
601 | #else | 602 | #else |
602 | NULL, | 603 | NULL, |
604 | NULL, | ||
603 | #endif | 605 | #endif |
604 | mu_radius_authenticate, | 606 | mu_radius_authenticate, |
605 | NULL, | 607 | NULL, | ... | ... |
... | @@ -175,6 +175,22 @@ mu_sql_expand_query (const char *query, const char *ustr) | ... | @@ -175,6 +175,22 @@ mu_sql_expand_query (const char *query, const char *ustr) |
175 | return res; | 175 | return res; |
176 | } | 176 | } |
177 | 177 | ||
178 | static int | ||
179 | set_sql_password_type (const char *arg) | ||
180 | { | ||
181 | if (strcmp (arg, "plain") == 0) | ||
182 | mu_sql_password_type = password_plaintext; | ||
183 | else if (strcmp (arg, "hash") == 0) | ||
184 | mu_sql_password_type = password_hash; | ||
185 | else if (strcmp (arg, "scrambled") == 0) | ||
186 | mu_sql_password_type = password_scrambled; | ||
187 | else | ||
188 | return 1; | ||
189 | return 0; | ||
190 | } | ||
191 | |||
192 | |||
193 | /* Command-line configuration */ | ||
178 | # define ARG_SQL_INTERFACE 256 | 194 | # define ARG_SQL_INTERFACE 256 |
179 | # define ARG_SQL_GETPWNAM 257 | 195 | # define ARG_SQL_GETPWNAM 257 |
180 | # define ARG_SQL_GETPWUID 258 | 196 | # define ARG_SQL_GETPWUID 258 |
... | @@ -188,27 +204,27 @@ mu_sql_expand_query (const char *query, const char *ustr) | ... | @@ -188,27 +204,27 @@ mu_sql_expand_query (const char *query, const char *ustr) |
188 | # define ARG_SQL_FIELD_MAP 266 | 204 | # define ARG_SQL_FIELD_MAP 266 |
189 | 205 | ||
190 | static struct argp_option mu_sql_argp_option[] = { | 206 | static struct argp_option mu_sql_argp_option[] = { |
191 | {"sql-interface", ARG_SQL_INTERFACE, N_("NAME"), 0, | 207 | {"sql-interface", ARG_SQL_INTERFACE, N_("NAME"), OPTION_HIDDEN, |
192 | N_("Type of SQL interface to use"), 0}, | 208 | N_("Type of SQL interface to use"), }, |
193 | {"sql-getpwnam", ARG_SQL_GETPWNAM, N_("QUERY"), 0, | 209 | {"sql-getpwnam", ARG_SQL_GETPWNAM, N_("QUERY"), OPTION_HIDDEN, |
194 | N_("SQL query to retrieve a passwd entry based on username"), 0}, | 210 | N_("SQL query to retrieve a passwd entry based on username"), 0}, |
195 | {"sql-getpwuid", ARG_SQL_GETPWUID, N_("QUERY"), 0, | 211 | {"sql-getpwuid", ARG_SQL_GETPWUID, N_("QUERY"), OPTION_HIDDEN, |
196 | N_("SQL query to retrieve a passwd entry based on UID"), 0}, | 212 | N_("SQL query to retrieve a passwd entry based on UID"), 0}, |
197 | {"sql-getpass", ARG_SQL_GETPASS, N_("QUERY"), 0, | 213 | {"sql-getpass", ARG_SQL_GETPASS, N_("QUERY"), OPTION_HIDDEN, |
198 | N_("SQL query to retrieve a password from the database"), 0}, | 214 | N_("SQL query to retrieve a password from the database"), 0}, |
199 | {"sql-host", ARG_SQL_HOST, N_("HOSTNAME"), 0, | 215 | {"sql-host", ARG_SQL_HOST, N_("HOSTNAME"), OPTION_HIDDEN, |
200 | N_("Name or IP of MySQL server to connect to"), 0}, | 216 | N_("Name or IP of MySQL server to connect to"), 0}, |
201 | {"sql-user", ARG_SQL_USER, N_("NAME"), 0, | 217 | {"sql-user", ARG_SQL_USER, N_("NAME"), OPTION_HIDDEN, |
202 | N_("SQL user name"), 0}, | 218 | N_("SQL user name"), 0}, |
203 | {"sql-passwd", ARG_SQL_PASSWD, N_("STRING"), 0, | 219 | {"sql-passwd", ARG_SQL_PASSWD, N_("STRING"), OPTION_HIDDEN, |
204 | N_("SQL connection password"), 0}, | 220 | N_("SQL connection password"), 0}, |
205 | {"sql-db", ARG_SQL_DB, N_("STRING"), 0, | 221 | {"sql-db", ARG_SQL_DB, N_("STRING"), OPTION_HIDDEN, |
206 | N_("Name of the database to connect to"), 0}, | 222 | N_("Name of the database to connect to"), 0}, |
207 | {"sql-port", ARG_SQL_PORT, N_("NUMBER"), 0, | 223 | {"sql-port", ARG_SQL_PORT, N_("NUMBER"), OPTION_HIDDEN, |
208 | N_("Port to use"), 0}, | 224 | N_("Port to use"), 0}, |
209 | {"sql-password-type", ARG_SQL_MU_PASSWORD_TYPE, N_("STRING"), 0, | 225 | {"sql-password-type", ARG_SQL_MU_PASSWORD_TYPE, N_("STRING"), OPTION_HIDDEN, |
210 | N_("Type of password returned by --sql-getpass query. STRING is one of: plain, hash, scrambled"), 0}, | 226 | N_("Type of password returned by --sql-getpass query. STRING is one of: plain, hash, scrambled"), 0}, |
211 | {"sql-field-map", ARG_SQL_FIELD_MAP, N_("MAP"), 0, | 227 | {"sql-field-map", ARG_SQL_FIELD_MAP, N_("MAP"), OPTION_HIDDEN, |
212 | N_("Declare a name translation map for SQL fields in results of sql-getpwnam and " | 228 | N_("Declare a name translation map for SQL fields in results of sql-getpwnam and " |
213 | "sql-getpwuid queries"), 0}, | 229 | "sql-getpwuid queries"), 0}, |
214 | { NULL, 0, NULL, 0, NULL, 0 } | 230 | { NULL, 0, NULL, 0, NULL, 0 } |
... | @@ -260,13 +276,7 @@ mu_sql_argp_parser (int key, char *arg, struct argp_state *state) | ... | @@ -260,13 +276,7 @@ mu_sql_argp_parser (int key, char *arg, struct argp_state *state) |
260 | break; | 276 | break; |
261 | 277 | ||
262 | case ARG_SQL_MU_PASSWORD_TYPE: | 278 | case ARG_SQL_MU_PASSWORD_TYPE: |
263 | if (strcmp (arg, "plain") == 0) | 279 | if (set_sql_password_type (arg)) |
264 | mu_sql_password_type = password_plaintext; | ||
265 | else if (strcmp (arg, "hash") == 0) | ||
266 | mu_sql_password_type = password_hash; | ||
267 | else if (strcmp (arg, "scrambled") == 0) | ||
268 | mu_sql_password_type = password_scrambled; | ||
269 | else | ||
270 | argp_error (state, _("Unknown password type `%s'"), arg); | 280 | argp_error (state, _("Unknown password type `%s'"), arg); |
271 | break; | 281 | break; |
272 | 282 | ||
... | @@ -283,11 +293,59 @@ mu_sql_argp_parser (int key, char *arg, struct argp_state *state) | ... | @@ -283,11 +293,59 @@ mu_sql_argp_parser (int key, char *arg, struct argp_state *state) |
283 | return 0; | 293 | return 0; |
284 | } | 294 | } |
285 | 295 | ||
286 | struct argp mu_sql_argp = { | 296 | static struct argp mu_sql_argp = { |
287 | mu_sql_argp_option, | 297 | mu_sql_argp_option, |
288 | mu_sql_argp_parser, | 298 | mu_sql_argp_parser, |
289 | }; | 299 | }; |
290 | 300 | ||
301 | |||
302 | /* Resource file configuration */ | ||
303 | static int | ||
304 | cb_iface (mu_cfg_locus_t *locus, void *data, char *arg) | ||
305 | { | ||
306 | sql_interface = mu_sql_interface_index (arg); | ||
307 | if (sql_interface == 0) | ||
308 | mu_error (_("%s:%d: Unknown SQL interface `%s'"), | ||
309 | locus->file, locus->line, arg); | ||
310 | return 0; | ||
311 | } | ||
312 | |||
313 | static int | ||
314 | cb_password_type (mu_cfg_locus_t *locus, void *data, char *arg) | ||
315 | { | ||
316 | if (set_sql_password_type (arg)) | ||
317 | mu_error (_("%s:%d: Unknown password type `%s'"), | ||
318 | locus->file, locus->line, arg); | ||
319 | return 0; | ||
320 | } | ||
321 | |||
322 | static int | ||
323 | cb_field_map (mu_cfg_locus_t *locus, void *data, char *arg) | ||
324 | { | ||
325 | int err; | ||
326 | int rc = mutil_parse_field_map (arg, &sql_field_map, &err); | ||
327 | if (rc) | ||
328 | mu_error (_("%s:%d: Error near element %d: %s"), | ||
329 | locus->file, locus->line, err, mu_strerror (rc)); | ||
330 | return 0; | ||
331 | } | ||
332 | |||
333 | static struct mu_cfg_param mu_sql_param[] = { | ||
334 | { "interface", mu_cfg_callback, NULL, cb_iface }, | ||
335 | { "getwpnam", mu_cfg_string, &mu_sql_getpwnam_query }, | ||
336 | { "getpwuid", mu_cfg_string, &mu_sql_getpwuid_query }, | ||
337 | { "getpass", mu_cfg_string, &mu_sql_getpass_query }, | ||
338 | { "host", mu_cfg_string, &mu_sql_host }, | ||
339 | { "user", mu_cfg_string, &mu_sql_user }, | ||
340 | { "passwd", mu_cfg_string, &mu_sql_passwd }, | ||
341 | { "db", mu_cfg_string, &mu_sql_db }, | ||
342 | { "port", mu_cfg_int, &mu_sql_port }, | ||
343 | { "password-type", mu_cfg_callback, NULL, cb_password_type }, | ||
344 | { "field-map", mu_cfg_callback, NULL, cb_field_map }, | ||
345 | { NULL } | ||
346 | }; | ||
347 | |||
348 | |||
291 | static int | 349 | static int |
292 | decode_tuple_v1_0 (mu_sql_connection_t conn, int n, | 350 | decode_tuple_v1_0 (mu_sql_connection_t conn, int n, |
293 | struct mu_auth_data **return_data) | 351 | struct mu_auth_data **return_data) |
... | @@ -787,8 +845,10 @@ struct mu_auth_module mu_auth_sql_module = { | ... | @@ -787,8 +845,10 @@ struct mu_auth_module mu_auth_sql_module = { |
787 | "sql", | 845 | "sql", |
788 | #ifdef USE_SQL | 846 | #ifdef USE_SQL |
789 | &mu_sql_argp, | 847 | &mu_sql_argp, |
848 | mu_sql_param, | ||
790 | #else | 849 | #else |
791 | NULL, | 850 | NULL, |
851 | NULL, | ||
792 | #endif | 852 | #endif |
793 | mu_sql_authenticate, | 853 | mu_sql_authenticate, |
794 | NULL, | 854 | NULL, | ... | ... |
... | @@ -55,12 +55,11 @@ static char *ssl_cafile = NULL; | ... | @@ -55,12 +55,11 @@ static char *ssl_cafile = NULL; |
55 | #define ARG_SSL_CAFILE 4 | 55 | #define ARG_SSL_CAFILE 4 |
56 | 56 | ||
57 | static struct argp_option _tls_argp_options[] = { | 57 | static struct argp_option _tls_argp_options[] = { |
58 | {NULL, 0, NULL, 0, N_("Encryption options"), 0}, | 58 | {"ssl-cert", ARG_SSL_CERT, N_("FILE"), OPTION_HIDDEN, |
59 | {"ssl-cert", ARG_SSL_CERT, N_("FILE"), 0, | ||
60 | N_("Specify SSL certificate file"), 0}, | 59 | N_("Specify SSL certificate file"), 0}, |
61 | {"ssl-key", ARG_SSL_KEY, N_("FILE"), 0, | 60 | {"ssl-key", ARG_SSL_KEY, N_("FILE"), OPTION_HIDDEN, |
62 | N_("Specify SSL certificate key"), 0}, | 61 | N_("Specify SSL certificate key"), }, |
63 | {"ssl-cafile", ARG_SSL_CAFILE, N_("FILE"), 0, | 62 | {"ssl-cafile", ARG_SSL_CAFILE, N_("FILE"), OPTION_HIDDEN, |
64 | N_("Specify trusted CAs file"), 0}, | 63 | N_("Specify trusted CAs file"), 0}, |
65 | {NULL, 0, NULL, 0, NULL, 0} | 64 | {NULL, 0, NULL, 0, NULL, 0} |
66 | }; | 65 | }; |
... | @@ -117,7 +116,7 @@ static struct argp_child _tls_argp_child = { | ... | @@ -117,7 +116,7 @@ static struct argp_child _tls_argp_child = { |
117 | void | 116 | void |
118 | mu_tls_init_argp () | 117 | mu_tls_init_argp () |
119 | { | 118 | { |
120 | if (mu_register_capa ("tls", &_tls_argp_child)) | 119 | if (mu_register_capa ("tls", &_tls_argp_child, NULL)) |
121 | { | 120 | { |
122 | mu_error (_("INTERNAL ERROR: cannot register argp capability tls")); | 121 | mu_error (_("INTERNAL ERROR: cannot register argp capability tls")); |
123 | abort (); | 122 | abort (); |
... | @@ -145,7 +144,7 @@ static struct argp_child _tls_argp_client_child = { | ... | @@ -145,7 +144,7 @@ static struct argp_child _tls_argp_client_child = { |
145 | void | 144 | void |
146 | mu_tls_init_client_argp () | 145 | mu_tls_init_client_argp () |
147 | { | 146 | { |
148 | if (mu_register_capa ("tls", &_tls_argp_client_child)) | 147 | if (mu_register_capa ("tls", &_tls_argp_client_child, NULL)) |
149 | { | 148 | { |
150 | mu_error (_("INTERNAL ERROR: cannot register argp capability tls")); | 149 | mu_error (_("INTERNAL ERROR: cannot register argp capability tls")); |
151 | abort (); | 150 | abort (); | ... | ... |
... | @@ -191,7 +191,7 @@ mu_virt_argp_parser (int key, char *arg, struct argp_state *state) | ... | @@ -191,7 +191,7 @@ mu_virt_argp_parser (int key, char *arg, struct argp_state *state) |
191 | } | 191 | } |
192 | 192 | ||
193 | static struct argp_option mu_virt_argp_option[] = { | 193 | static struct argp_option mu_virt_argp_option[] = { |
194 | { "virtual-passwd-dir", ARG_PWDDIR, N_("DIR"), 0, | 194 | { "virtual-passwd-dir", ARG_PWDDIR, N_("DIR"), OPTION_HIDDEN, |
195 | N_("Search for virtual passwd file in DIR"), 0}, | 195 | N_("Search for virtual passwd file in DIR"), 0}, |
196 | { NULL, 0, NULL, 0, NULL, 0 } | 196 | { NULL, 0, NULL, 0, NULL, 0 } |
197 | }; | 197 | }; |
... | @@ -216,8 +216,10 @@ struct mu_auth_module mu_auth_virtual_module = { | ... | @@ -216,8 +216,10 @@ struct mu_auth_module mu_auth_virtual_module = { |
216 | "virtdomain", | 216 | "virtdomain", |
217 | #ifdef ENABLE_VIRTUAL_DOMAINS | 217 | #ifdef ENABLE_VIRTUAL_DOMAINS |
218 | &mu_virt_argp, | 218 | &mu_virt_argp, |
219 | NULL, | ||
219 | #else | 220 | #else |
220 | NULL, | 221 | NULL, |
222 | NULL, | ||
221 | #endif | 223 | #endif |
222 | mu_auth_nosupport, | 224 | mu_auth_nosupport, |
223 | NULL, | 225 | NULL, | ... | ... |
... | @@ -41,7 +41,8 @@ int login_disabled; /* Disable LOGIN command */ | ... | @@ -41,7 +41,8 @@ int login_disabled; /* Disable LOGIN command */ |
41 | int tls_required; /* Require STARTTLS */ | 41 | int tls_required; /* Require STARTTLS */ |
42 | int create_home_dir; /* Create home directory if it does not | 42 | int create_home_dir; /* Create home directory if it does not |
43 | exist */ | 43 | exist */ |
44 | int home_dir_mode; | 44 | int home_dir_mode = S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH; |
45 | |||
45 | 46 | ||
46 | /* Number of child processes. */ | 47 | /* Number of child processes. */ |
47 | size_t children; | 48 | size_t children; |
... | @@ -54,21 +55,23 @@ static char doc[] = N_("GNU imap4d -- the IMAP4D daemon"); | ... | @@ -54,21 +55,23 @@ static char doc[] = N_("GNU imap4d -- the IMAP4D daemon"); |
54 | #define ARG_CREATE_HOME_DIR 3 | 55 | #define ARG_CREATE_HOME_DIR 3 |
55 | 56 | ||
56 | static struct argp_option options[] = { | 57 | static struct argp_option options[] = { |
57 | {"other-namespace", 'O', N_("PATHLIST"), 0, | 58 | {"other-namespace", 'O', N_("PATHLIST"), OPTION_HIDDEN, |
58 | N_("Set the `other' namespace"), 0}, | 59 | N_("Set the `other' namespace"), 0}, |
59 | {"shared-namespace", 'S', N_("PATHLIST"), 0, | 60 | {"shared-namespace", 'S', N_("PATHLIST"), OPTION_HIDDEN, |
60 | N_("Set the `shared' namespace"), 0}, | 61 | N_("Set the `shared' namespace"), 0}, |
61 | {"login-disabled", ARG_LOGIN_DISABLED, NULL, 0, | 62 | {"login-disabled", ARG_LOGIN_DISABLED, NULL, OPTION_HIDDEN, |
62 | N_("Disable LOGIN command")}, | 63 | N_("Disable LOGIN command")}, |
63 | {"create-home-dir", ARG_CREATE_HOME_DIR, N_("MODE"), OPTION_ARG_OPTIONAL, | 64 | {"create-home-dir", ARG_CREATE_HOME_DIR, N_("MODE"), |
65 | OPTION_ARG_OPTIONAL|OPTION_HIDDEN, | ||
64 | N_("Create home directory, if it does not exist")}, | 66 | N_("Create home directory, if it does not exist")}, |
65 | #ifdef WITH_TLS | 67 | #ifdef WITH_TLS |
66 | {"tls-required", ARG_TLS_REQUIRED, NULL, 0, | 68 | {"tls-required", ARG_TLS_REQUIRED, NULL, OPTION_HIDDEN, |
67 | N_("Always require STARTTLS before entering authentication phase")}, | 69 | N_("Always require STARTTLS before entering authentication phase")}, |
68 | #endif | 70 | #endif |
69 | {NULL, 0, NULL, 0, NULL, 0} | 71 | {NULL, 0, NULL, 0, NULL, 0} |
70 | }; | 72 | }; |
71 | 73 | ||
74 | |||
72 | static error_t imap4d_parse_opt (int key, char *arg, | 75 | static error_t imap4d_parse_opt (int key, char *arg, |
73 | struct argp_state *state); | 76 | struct argp_state *state); |
74 | 77 | ||
... | @@ -120,7 +123,6 @@ imap4d_parse_opt (int key, char *arg, struct argp_state *state) | ... | @@ -120,7 +123,6 @@ imap4d_parse_opt (int key, char *arg, struct argp_state *state) |
120 | 123 | ||
121 | case ARG_LOGIN_DISABLED: | 124 | case ARG_LOGIN_DISABLED: |
122 | login_disabled = 1; | 125 | login_disabled = 1; |
123 | imap4d_capability_add (IMAP_CAPA_LOGINDISABLED); | ||
124 | break; | 126 | break; |
125 | 127 | ||
126 | case ARG_CREATE_HOME_DIR: | 128 | case ARG_CREATE_HOME_DIR: |
... | @@ -132,14 +134,11 @@ imap4d_parse_opt (int key, char *arg, struct argp_state *state) | ... | @@ -132,14 +134,11 @@ imap4d_parse_opt (int key, char *arg, struct argp_state *state) |
132 | if (p || (home_dir_mode & 0777)) | 134 | if (p || (home_dir_mode & 0777)) |
133 | argp_error (state, _("Invalid mode specification: %s"), arg); | 135 | argp_error (state, _("Invalid mode specification: %s"), arg); |
134 | } | 136 | } |
135 | else | ||
136 | home_dir_mode = S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH; | ||
137 | break; | 137 | break; |
138 | 138 | ||
139 | #ifdef WITH_TLS | 139 | #ifdef WITH_TLS |
140 | case ARG_TLS_REQUIRED: | 140 | case ARG_TLS_REQUIRED: |
141 | tls_required = 1; | 141 | tls_required = 1; |
142 | imap4d_capability_add (IMAP_CAPA_XTLSREQUIRED); | ||
143 | break; | 142 | break; |
144 | #endif | 143 | #endif |
145 | 144 | ||
... | @@ -149,6 +148,41 @@ imap4d_parse_opt (int key, char *arg, struct argp_state *state) | ... | @@ -149,6 +148,41 @@ imap4d_parse_opt (int key, char *arg, struct argp_state *state) |
149 | return 0; | 148 | return 0; |
150 | } | 149 | } |
151 | 150 | ||
151 | static int | ||
152 | cb_other (mu_cfg_locus_t *locus, void *data, char *arg) | ||
153 | { | ||
154 | set_namespace (NS_OTHER, arg); | ||
155 | return 0; | ||
156 | } | ||
157 | |||
158 | static int | ||
159 | cb_shared (mu_cfg_locus_t *locus, void *data, char *arg) | ||
160 | { | ||
161 | set_namespace (NS_SHARED, arg); | ||
162 | return 0; | ||
163 | } | ||
164 | |||
165 | static int | ||
166 | cb_mode (mu_cfg_locus_t *locus, void *data, char *arg) | ||
167 | { | ||
168 | char *p; | ||
169 | home_dir_mode = strtoul (arg, &p, 8); | ||
170 | if (p || (home_dir_mode & 0777)) | ||
171 | mu_error (_("%s:%d: Invalid mode specification: %s"), | ||
172 | locus->file, locus->line, arg); | ||
173 | return 0; | ||
174 | } | ||
175 | |||
176 | static struct mu_cfg_param imap4d_cfg_param[] = { | ||
177 | { "other-namespace", mu_cfg_callback, NULL, cb_other }, | ||
178 | { "shared-namespace", mu_cfg_callback, NULL, cb_shared }, | ||
179 | { "login-disabled", mu_cfg_int, &login_disabled }, | ||
180 | { "create-home-dir", mu_cfg_bool, &create_home_dir }, | ||
181 | { "home-dir-mode", mu_cfg_callback, NULL, cb_mode }, | ||
182 | { "tls-required", mu_cfg_int, &tls_required }, | ||
183 | { NULL } | ||
184 | }; | ||
185 | |||
152 | int | 186 | int |
153 | main (int argc, char **argv) | 187 | main (int argc, char **argv) |
154 | { | 188 | { |
... | @@ -170,8 +204,16 @@ main (int argc, char **argv) | ... | @@ -170,8 +204,16 @@ main (int argc, char **argv) |
170 | #ifdef WITH_GSASL | 204 | #ifdef WITH_GSASL |
171 | mu_gsasl_init_argp (); | 205 | mu_gsasl_init_argp (); |
172 | #endif | 206 | #endif |
207 | mu_config_register_plain_section (NULL, NULL, imap4d_cfg_param); | ||
173 | mu_argp_parse (&argp, &argc, &argv, 0, imap4d_capa, NULL, &daemon_param); | 208 | mu_argp_parse (&argp, &argc, &argv, 0, imap4d_capa, NULL, &daemon_param); |
174 | 209 | ||
210 | if (login_disabled) | ||
211 | imap4d_capability_add (IMAP_CAPA_LOGINDISABLED); | ||
212 | #ifdef WITH_TLS | ||
213 | if (tls_required) | ||
214 | imap4d_capability_add (IMAP_CAPA_XTLSREQUIRED); | ||
215 | #endif | ||
216 | |||
175 | auth_gssapi_init (); | 217 | auth_gssapi_init (); |
176 | auth_gsasl_init (); | 218 | auth_gsasl_init (); |
177 | 219 | ... | ... |
... | @@ -21,6 +21,7 @@ | ... | @@ -21,6 +21,7 @@ |
21 | #define _MAILUTILS_ARGP_H | 21 | #define _MAILUTILS_ARGP_H |
22 | 22 | ||
23 | #include <mailutils/types.h> | 23 | #include <mailutils/types.h> |
24 | #include <mailutils/cfg.h> | ||
24 | #include <argp.h> | 25 | #include <argp.h> |
25 | #include <errno.h> /* May declare program_invocation_name */ | 26 | #include <errno.h> /* May declare program_invocation_name */ |
26 | 27 | ||
... | @@ -49,15 +50,13 @@ extern "C" { | ... | @@ -49,15 +50,13 @@ extern "C" { |
49 | 50 | ||
50 | extern void mu_argp_init (const char *vers, const char *bugaddr); | 51 | extern void mu_argp_init (const char *vers, const char *bugaddr); |
51 | 52 | ||
52 | extern void mu_create_argcv (const char *capa[], | ||
53 | int argc, char **argv, | ||
54 | int *p_argc, char ***p_argv); | ||
55 | extern error_t mu_argp_parse (const struct argp * argp, | 53 | extern error_t mu_argp_parse (const struct argp * argp, |
56 | int *p_argc, char ***p_argv, | 54 | int *p_argc, char ***p_argv, |
57 | unsigned flags, | 55 | unsigned flags, |
58 | const char *capa[], | 56 | const char *capa[], |
59 | int *arg_index, void *input); | 57 | int *arg_index, void *input); |
60 | extern int mu_register_capa (const char *name, struct argp_child *child); | 58 | extern int mu_register_capa (const char *name, struct argp_child *child, |
59 | struct mu_cfg_param *param); | ||
61 | 60 | ||
62 | extern void mu_print_options (void); | 61 | extern void mu_print_options (void); |
63 | extern const char *mu_check_option (char *name); | 62 | extern const char *mu_check_option (char *name); | ... | ... |
include/mailutils/cfg.h
0 → 100644
1 | /* cfg.h -- general-purpose configuration file parser | ||
2 | Copyright (C) 2007 Free Software Foundation, Inc. | ||
3 | |||
4 | GNU Mailutils is free software; you can redistribute it and/or | ||
5 | modify it under the terms of the GNU General Public License as | ||
6 | published by the Free Software Foundation; either version 3, or (at | ||
7 | your option) any later version. | ||
8 | |||
9 | This program is distributed in the hope that it will be useful, but | ||
10 | WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
12 | General Public License for more details. | ||
13 | |||
14 | You should have received a copy of the GNU General Public License | ||
15 | along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
16 | */ | ||
17 | |||
18 | #ifndef _MAILUTILS_CFG_H | ||
19 | #define _MAILUTILS_CFG_H | ||
20 | |||
21 | #include <sys/socket.h> | ||
22 | #include <netinet/in.h> | ||
23 | #include <arpa/inet.h> | ||
24 | |||
25 | typedef enum mu_cfg_node_type mu_cfg_node_type_t; | ||
26 | typedef struct mu_cfg_node mu_cfg_node_t; | ||
27 | typedef struct mu_cfg_locus mu_cfg_locus_t; | ||
28 | |||
29 | typedef int (*mu_cfg_lexer_t) (void *ptr); | ||
30 | typedef void (*mu_cfg_perror_t) (void *ptr, const mu_cfg_locus_t *loc, | ||
31 | const char *fmt, ...); | ||
32 | typedef void *(*mu_cfg_alloc_t) (size_t size); | ||
33 | typedef void (*mu_cfg_free_t) (void *ptr); | ||
34 | |||
35 | enum mu_cfg_node_type | ||
36 | { | ||
37 | mu_cfg_node_undefined, | ||
38 | mu_cfg_node_tag, | ||
39 | mu_cfg_node_param | ||
40 | }; | ||
41 | |||
42 | struct mu_cfg_locus | ||
43 | { | ||
44 | char *file; | ||
45 | size_t line; | ||
46 | }; | ||
47 | |||
48 | struct mu_cfg_node | ||
49 | { | ||
50 | mu_cfg_node_t *next; | ||
51 | mu_cfg_locus_t locus; | ||
52 | enum mu_cfg_node_type type; | ||
53 | char *tag_name; | ||
54 | char *tag_label; | ||
55 | mu_cfg_node_t *node; | ||
56 | }; | ||
57 | |||
58 | int mu_cfg_parse (mu_cfg_node_t **ptree, | ||
59 | void *data, | ||
60 | mu_cfg_lexer_t lexer, | ||
61 | mu_cfg_perror_t perror, | ||
62 | mu_cfg_alloc_t alloc, | ||
63 | mu_cfg_free_t free); | ||
64 | |||
65 | extern mu_cfg_locus_t mu_cfg_locus; | ||
66 | extern int mu_cfg_tie_in; | ||
67 | extern mu_cfg_perror_t mu_cfg_perror; | ||
68 | |||
69 | #define MU_CFG_ITER_OK 0 | ||
70 | #define MU_CFG_ITER_SKIP 1 | ||
71 | #define MU_CFG_ITER_STOP 2 | ||
72 | |||
73 | typedef int (*mu_cfg_iter_func_t) (const mu_cfg_node_t *node, void *data); | ||
74 | |||
75 | void mu_cfg_destroy_tree (mu_cfg_node_t **tree); | ||
76 | |||
77 | int mu_cfg_preorder (mu_cfg_node_t *node, | ||
78 | mu_cfg_iter_func_t fun, mu_cfg_iter_func_t endfun, | ||
79 | void *data); | ||
80 | int mu_cfg_postorder (mu_cfg_node_t *node, | ||
81 | mu_cfg_iter_func_t fun, mu_cfg_iter_func_t endfun, | ||
82 | void *data); | ||
83 | |||
84 | int mu_cfg_find_node (mu_cfg_node_t *tree, const char *path, | ||
85 | mu_cfg_node_t **pval); | ||
86 | int mu_cfg_find_node_label (mu_cfg_node_t *tree, const char *path, | ||
87 | const char **pval); | ||
88 | |||
89 | /* Table-driven parsing */ | ||
90 | enum mu_cfg_param_data_type | ||
91 | { | ||
92 | mu_cfg_string, | ||
93 | mu_cfg_short, | ||
94 | mu_cfg_ushort, | ||
95 | mu_cfg_int, | ||
96 | mu_cfg_uint, | ||
97 | mu_cfg_long, | ||
98 | mu_cfg_ulong, | ||
99 | mu_cfg_size, | ||
100 | mu_cfg_off, | ||
101 | mu_cfg_bool, | ||
102 | mu_cfg_ipv4, | ||
103 | mu_cfg_cidr, | ||
104 | mu_cfg_host, | ||
105 | mu_cfg_callback | ||
106 | }; | ||
107 | |||
108 | typedef int (*mu_cfg_callback_t) (mu_cfg_locus_t *, void *, char *); | ||
109 | |||
110 | struct mu_cfg_param | ||
111 | { | ||
112 | const char *ident; | ||
113 | enum mu_cfg_param_data_type type; | ||
114 | void *data; | ||
115 | mu_cfg_callback_t callback; | ||
116 | }; | ||
117 | |||
118 | enum mu_cfg_section_stage | ||
119 | { | ||
120 | mu_cfg_section_start, | ||
121 | mu_cfg_section_end | ||
122 | }; | ||
123 | |||
124 | typedef int (*mu_cfg_section_fp) (enum mu_cfg_section_stage stage, | ||
125 | const mu_cfg_node_t *node, | ||
126 | void *section_data, void *call_data); | ||
127 | |||
128 | struct mu_cfg_section | ||
129 | { | ||
130 | const char *ident; | ||
131 | mu_cfg_section_fp parser; | ||
132 | void *data; | ||
133 | struct mu_cfg_section *subsec; | ||
134 | struct mu_cfg_param *param; | ||
135 | }; | ||
136 | |||
137 | typedef struct mu_cfg_cidr mu_cfg_cidr_t; | ||
138 | |||
139 | struct mu_cfg_cidr | ||
140 | { | ||
141 | struct in_addr addr; | ||
142 | unsigned long mask; | ||
143 | }; | ||
144 | |||
145 | int mu_cfg_scan_tree (mu_cfg_node_t *node, | ||
146 | struct mu_cfg_section *sections, | ||
147 | void *data, mu_cfg_perror_t perror, | ||
148 | mu_cfg_alloc_t palloc, mu_cfg_free_t pfree); | ||
149 | |||
150 | int mu_cfg_find_section (struct mu_cfg_section *root_sec, | ||
151 | const char *path, struct mu_cfg_section **retval); | ||
152 | |||
153 | int mu_config_register_section (const char *parent_path, | ||
154 | const char *ident, | ||
155 | mu_cfg_section_fp parser, | ||
156 | void *data, | ||
157 | struct mu_cfg_param *param); | ||
158 | int mu_config_register_plain_section (const char *parent_path, | ||
159 | const char *ident, | ||
160 | struct mu_cfg_param *params); | ||
161 | |||
162 | #endif |
... | @@ -116,7 +116,7 @@ sieve_argp_parser (int key, char *arg, struct argp_state *state) | ... | @@ -116,7 +116,7 @@ sieve_argp_parser (int key, char *arg, struct argp_state *state) |
116 | void | 116 | void |
117 | mu_sieve_argp_init () | 117 | mu_sieve_argp_init () |
118 | { | 118 | { |
119 | if (mu_register_capa ("sieve", &sieve_argp_child)) | 119 | if (mu_register_capa ("sieve", &sieve_argp_child, NULL)) |
120 | { | 120 | { |
121 | mu_error ("INTERNAL ERROR: cannot register argp capability sieve"); | 121 | mu_error ("INTERNAL ERROR: cannot register argp capability sieve"); |
122 | abort (); | 122 | abort (); | ... | ... |
... | @@ -32,7 +32,7 @@ AM_CPPFLAGS = \ | ... | @@ -32,7 +32,7 @@ AM_CPPFLAGS = \ |
32 | -DSITE_VIRTUAL_PWDDIR=\"@SITE_VIRTUAL_PWDDIR@\"\ | 32 | -DSITE_VIRTUAL_PWDDIR=\"@SITE_VIRTUAL_PWDDIR@\"\ |
33 | -DLOCALEDIR=\"$(localedir)\" | 33 | -DLOCALEDIR=\"$(localedir)\" |
34 | 34 | ||
35 | EXTRA_DIST = @MU_EXTRA_DIST@ errors muerrno.cin parsedate.y fgetpwent.c | 35 | EXTRA_DIST = @MU_EXTRA_DIST@ errors muerrno.cin parsedate.y fgetpwent.c cfg_parser.y cfg_parser.h |
36 | 36 | ||
37 | libmailutils_la_SOURCES = \ | 37 | libmailutils_la_SOURCES = \ |
38 | address.c \ | 38 | address.c \ |
... | @@ -46,6 +46,8 @@ body.c \ | ... | @@ -46,6 +46,8 @@ body.c \ |
46 | daemon.c \ | 46 | daemon.c \ |
47 | date.c \ | 47 | date.c \ |
48 | debug.c \ | 48 | debug.c \ |
49 | cfg_lexer.c \ | ||
50 | cfg_parser.c \ | ||
49 | envelope.c \ | 51 | envelope.c \ |
50 | file_stream.c \ | 52 | file_stream.c \ |
51 | filter.c \ | 53 | filter.c \ |
... | @@ -83,6 +85,7 @@ parsedate.c \ | ... | @@ -83,6 +85,7 @@ parsedate.c \ |
83 | property.c \ | 85 | property.c \ |
84 | registrar.c \ | 86 | registrar.c \ |
85 | rfc2047.c \ | 87 | rfc2047.c \ |
88 | socket_stream.c \ | ||
86 | stream.c \ | 89 | stream.c \ |
87 | system.c \ | 90 | system.c \ |
88 | tcp.c \ | 91 | tcp.c \ |
... | @@ -98,6 +101,12 @@ parsedate.c: $(srcdir)/parsedate.y | ... | @@ -98,6 +101,12 @@ parsedate.c: $(srcdir)/parsedate.y |
98 | y.tab.c parsedate.c y.output parsedate.y.output \ | 101 | y.tab.c parsedate.c y.output parsedate.y.output \ |
99 | -- -yy pd_yy | 102 | -- -yy pd_yy |
100 | 103 | ||
104 | cfg_parser.c: $(srcdir)/cfg_parser.y | ||
105 | $(YLWRAP) "$(YACC) $(AM_YFLAGS) -d" $< \ | ||
106 | y.tab.c cfg_parser.c y.tab.h cfg_parser.h \ | ||
107 | y.output cfg_parser.y.output \ | ||
108 | -- -yy mu_cfg_yy | ||
109 | |||
101 | muerrno.c: errors muerrno.cin | 110 | muerrno.c: errors muerrno.cin |
102 | $(AWK) -f $(top_srcdir)/scripts/generr.awk $^ > $@ | 111 | $(AWK) -f $(top_srcdir)/scripts/generr.awk $^ > $@ |
103 | 112 | ... | ... |
mailbox/cfg_lexer.c
0 → 100644
1 | /* cfg_lexer.c -- default lexer for Mailutils configuration files | ||
2 | Copyright (C) 2007 Free Software Foundation, Inc. | ||
3 | |||
4 | GNU Mailutils is free software; you can redistribute it and/or | ||
5 | modify it under the terms of the GNU General Public License as | ||
6 | published by the Free Software Foundation; either version 3, or (at | ||
7 | your option) any later version. | ||
8 | |||
9 | This program is distributed in the hope that it will be useful, but | ||
10 | WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
12 | General Public License for more details. | ||
13 | |||
14 | You should have received a copy of the GNU General Public License | ||
15 | along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
16 | */ | ||
17 | |||
18 | #include <stdio.h> | ||
19 | #include <stdlib.h> | ||
20 | #include <sys/types.h> | ||
21 | #include <sys/stat.h> | ||
22 | #include <fcntl.h> | ||
23 | #include <errno.h> | ||
24 | #include <unistd.h> | ||
25 | #include <ctype.h> | ||
26 | #include <mailutils/argcv.h> | ||
27 | #include <mailutils/nls.h> | ||
28 | #include <mailutils/cfg.h> | ||
29 | #include <mailutils/errno.h> | ||
30 | #include <mailutils/error.h> | ||
31 | #include <mailutils/mutil.h> | ||
32 | |||
33 | #define obstack_chunk_alloc malloc | ||
34 | #define obstack_chunk_free free | ||
35 | #include "obstack.h" | ||
36 | #include "cfg_parser.h" | ||
37 | |||
38 | struct lexer_data | ||
39 | { | ||
40 | char *buffer; | ||
41 | char *curp; | ||
42 | struct obstack stk; | ||
43 | }; | ||
44 | |||
45 | static void | ||
46 | skipws (struct lexer_data *p) | ||
47 | { | ||
48 | while (*p->curp && isspace (*p->curp)) | ||
49 | { | ||
50 | if (*p->curp == '\n') | ||
51 | mu_cfg_locus.line++; | ||
52 | p->curp++; | ||
53 | } | ||
54 | } | ||
55 | |||
56 | static void | ||
57 | skipline (struct lexer_data *p) | ||
58 | { | ||
59 | while (*p->curp && *p->curp != '\n') | ||
60 | p->curp++; | ||
61 | } | ||
62 | |||
63 | static int | ||
64 | isword (int c) | ||
65 | { | ||
66 | if (mu_cfg_tie_in) | ||
67 | return c && c != ';'; | ||
68 | |||
69 | return isalnum (c) || c == '_' || c == '-'; | ||
70 | } | ||
71 | |||
72 | static char * | ||
73 | copy_alpha (struct lexer_data *p) | ||
74 | { | ||
75 | do | ||
76 | { | ||
77 | if (*p->curp == '\n') | ||
78 | mu_cfg_locus.line++; | ||
79 | obstack_1grow (&p->stk, *p->curp); | ||
80 | p->curp++; | ||
81 | } while (*p->curp && isword(*p->curp)); | ||
82 | obstack_1grow (&p->stk, 0); | ||
83 | return obstack_finish (&p->stk); | ||
84 | } | ||
85 | |||
86 | static char * | ||
87 | copy_string(struct lexer_data *p) | ||
88 | { | ||
89 | int quote = *p->curp++; | ||
90 | |||
91 | while (*p->curp) | ||
92 | { | ||
93 | if (*p->curp == '\\') | ||
94 | { | ||
95 | char c; | ||
96 | if (*++p->curp == 0) | ||
97 | { | ||
98 | obstack_1grow (&p->stk, '\\'); | ||
99 | break; | ||
100 | } | ||
101 | c = mu_argcv_unquote_char (*p->curp); | ||
102 | if (c == *p->curp) | ||
103 | { | ||
104 | obstack_1grow (&p->stk, '\\'); | ||
105 | obstack_1grow (&p->stk, *p->curp); | ||
106 | } | ||
107 | else | ||
108 | obstack_1grow (&p->stk, c); | ||
109 | p->curp++; | ||
110 | } | ||
111 | else if (*p->curp == quote) | ||
112 | { | ||
113 | p->curp++; | ||
114 | break; | ||
115 | } | ||
116 | else | ||
117 | { | ||
118 | obstack_1grow (&p->stk, *p->curp); | ||
119 | p->curp++; | ||
120 | } | ||
121 | } | ||
122 | obstack_1grow (&p->stk, 0); | ||
123 | return obstack_finish (&p->stk); | ||
124 | } | ||
125 | |||
126 | int | ||
127 | default_lexer (void *dp) | ||
128 | { | ||
129 | struct lexer_data *p = dp; | ||
130 | char *save_start; | ||
131 | char *tag, *label; | ||
132 | |||
133 | again: | ||
134 | skipws (p); | ||
135 | |||
136 | if (*p->curp == '#') | ||
137 | { | ||
138 | skipline (p); | ||
139 | goto again; | ||
140 | } | ||
141 | |||
142 | if (*p->curp == '/' && p->curp[1] == '*') | ||
143 | { | ||
144 | int keep_line = mu_cfg_locus.line; | ||
145 | |||
146 | p->curp += 2; | ||
147 | do | ||
148 | { | ||
149 | while (*p->curp != '*') | ||
150 | { | ||
151 | if (*p->curp == 0) | ||
152 | { | ||
153 | mu_cfg_perror (p, | ||
154 | &mu_cfg_locus, | ||
155 | _("unexpected EOF in comment started at line %d"), | ||
156 | keep_line); | ||
157 | return 0; | ||
158 | } | ||
159 | else if (*p->curp == '\n') | ||
160 | mu_cfg_locus.line++; | ||
161 | ++p->curp; | ||
162 | } | ||
163 | } while (*++p->curp != '/'); | ||
164 | ++p->curp; | ||
165 | goto again; | ||
166 | } | ||
167 | |||
168 | if (*p->curp == 0) | ||
169 | return 0; | ||
170 | |||
171 | if (*p->curp == '\"') | ||
172 | { | ||
173 | mu_cfg_yylval.string = copy_string (p); | ||
174 | return MU_CFG_STRING_TOKEN; | ||
175 | } | ||
176 | |||
177 | if (mu_cfg_tie_in) | ||
178 | { | ||
179 | mu_cfg_yylval.string = copy_alpha (p); | ||
180 | return MU_CFG_STRING_TOKEN; | ||
181 | } | ||
182 | |||
183 | if (*p->curp == '}') | ||
184 | { | ||
185 | p->curp++; | ||
186 | memset (&mu_cfg_yylval.node, 0, sizeof mu_cfg_yylval.node); | ||
187 | mu_cfg_yylval.node.locus = mu_cfg_locus; | ||
188 | return MU_CFG_END_TOKEN; | ||
189 | } | ||
190 | |||
191 | if (*p->curp == ';') | ||
192 | { | ||
193 | p->curp++; | ||
194 | return MU_CFG_EOL_TOKEN; | ||
195 | } | ||
196 | |||
197 | tag = copy_alpha (p); | ||
198 | skipws (p); | ||
199 | if (*p->curp == '"') | ||
200 | { | ||
201 | mu_cfg_yylval.string = tag; | ||
202 | return MU_CFG_STRING_TOKEN; | ||
203 | } | ||
204 | |||
205 | save_start = p->curp; | ||
206 | if (*p->curp != '{') | ||
207 | { | ||
208 | label = copy_alpha(p); | ||
209 | skipws(p); | ||
210 | } | ||
211 | else | ||
212 | label = NULL; | ||
213 | if (*p->curp == '{') | ||
214 | { | ||
215 | p->curp++; | ||
216 | mu_cfg_yylval.node.tag_name = tag; | ||
217 | mu_cfg_yylval.node.locus = mu_cfg_locus; | ||
218 | mu_cfg_yylval.node.tag_label = label; | ||
219 | return MU_CFG_START_TOKEN; | ||
220 | } | ||
221 | else | ||
222 | { | ||
223 | p->curp = save_start; | ||
224 | mu_cfg_yylval.string = tag; | ||
225 | } | ||
226 | return MU_CFG_STRING_TOKEN; | ||
227 | } | ||
228 | |||
229 | static struct mu_cfg_section *root_section; | ||
230 | |||
231 | int | ||
232 | mu_config_register_section (const char *parent_path, | ||
233 | const char *ident, | ||
234 | mu_cfg_section_fp parser, | ||
235 | void *data, | ||
236 | struct mu_cfg_param *param) | ||
237 | { | ||
238 | struct mu_cfg_section *parent; | ||
239 | size_t size = 0; | ||
240 | |||
241 | if (!root_section) | ||
242 | { | ||
243 | root_section = calloc (1, sizeof (root_section[0])); | ||
244 | if (!root_section) | ||
245 | return MU_ERR_NOENT; | ||
246 | } | ||
247 | |||
248 | if (parent_path) | ||
249 | { | ||
250 | if (mu_cfg_find_section (root_section, parent_path, &parent)) | ||
251 | return MU_ERR_NOENT; | ||
252 | } | ||
253 | else | ||
254 | parent = root_section; | ||
255 | |||
256 | if (ident) | ||
257 | { | ||
258 | struct mu_cfg_section *s; | ||
259 | |||
260 | if (parent->subsec) | ||
261 | for (s = parent->subsec; s->ident; s++) | ||
262 | size++; | ||
263 | |||
264 | s = realloc (parent->subsec, (size + 2) * sizeof parent->subsec[0]); | ||
265 | if (!s) | ||
266 | return ENOMEM; | ||
267 | parent->subsec = s; | ||
268 | s = parent->subsec + size; | ||
269 | s[1].ident = NULL; | ||
270 | |||
271 | s->ident = strdup (ident); | ||
272 | s->parser = parser; | ||
273 | s->data = data; | ||
274 | s->subsec = NULL; | ||
275 | s->param = param; | ||
276 | } | ||
277 | else | ||
278 | { | ||
279 | size_t orig_size = 0; | ||
280 | struct mu_cfg_param *p; | ||
281 | if (parent->param) | ||
282 | for (p = parent->param; p->ident; p++) | ||
283 | orig_size++; | ||
284 | size = 0; | ||
285 | for (p = param; p->ident; p++) | ||
286 | size++; | ||
287 | parent->param = realloc (parent->param, | ||
288 | (size + orig_size + 1) | ||
289 | * sizeof (parent->param[0])); | ||
290 | memcpy (parent->param + orig_size, param, | ||
291 | size * sizeof (parent->param[0])); | ||
292 | if (!parent->parser) | ||
293 | parent->parser = parser; | ||
294 | if (!parent->data) | ||
295 | parent->data = data; | ||
296 | } | ||
297 | return 0; | ||
298 | } | ||
299 | |||
300 | int | ||
301 | mu_config_register_plain_section (const char *parent_path, const char *ident, | ||
302 | struct mu_cfg_param *params) | ||
303 | { | ||
304 | return mu_config_register_section (parent_path, ident, NULL, NULL, params); | ||
305 | } | ||
306 | |||
307 | static int | ||
308 | _mu_parse_config (char *file, char *progname) | ||
309 | { | ||
310 | struct lexer_data data; | ||
311 | struct stat st; | ||
312 | int fd; | ||
313 | extern int mu_cfg_yydebug; | ||
314 | int rc; | ||
315 | mu_cfg_node_t *parse_tree; | ||
316 | |||
317 | mu_cfg_locus.file = file; | ||
318 | mu_cfg_locus.line = 1; | ||
319 | |||
320 | if (stat (mu_cfg_locus.file, &st)) | ||
321 | { | ||
322 | mu_error (_("can't stat `%s'"), mu_cfg_locus.file); | ||
323 | return -1; | ||
324 | } | ||
325 | fd = open (mu_cfg_locus.file, O_RDONLY); | ||
326 | if (fd == -1) | ||
327 | { | ||
328 | if (errno != ENOENT) | ||
329 | mu_error (_("can't open config file `%s'"), | ||
330 | mu_cfg_locus.file); | ||
331 | return -1; | ||
332 | } | ||
333 | data.buffer = malloc (st.st_size+1); | ||
334 | |||
335 | read (fd, data.buffer, st.st_size); | ||
336 | data.buffer[st.st_size] = 0; | ||
337 | close (fd); | ||
338 | data.curp = data.buffer; | ||
339 | |||
340 | mu_cfg_yydebug = strncmp (data.curp, "#debug", 6) == 0; | ||
341 | |||
342 | obstack_init (&data.stk); | ||
343 | |||
344 | /* Parse configuration */ | ||
345 | rc = mu_cfg_parse (&parse_tree, | ||
346 | &data, | ||
347 | default_lexer, | ||
348 | NULL, | ||
349 | NULL, | ||
350 | NULL); | ||
351 | |||
352 | if (rc == 0) | ||
353 | { | ||
354 | rc = mu_cfg_scan_tree (parse_tree, root_section, | ||
355 | progname, NULL, NULL, NULL); | ||
356 | } | ||
357 | |||
358 | mu_cfg_destroy_tree (&parse_tree); | ||
359 | obstack_free (&data.stk, NULL); | ||
360 | free (data.buffer); | ||
361 | |||
362 | return rc; | ||
363 | } | ||
364 | |||
365 | int | ||
366 | mu_parse_config (char *file, char *progname) | ||
367 | { | ||
368 | int rc; | ||
369 | char *full_name = mu_tilde_expansion (file, "/", NULL); | ||
370 | if (full_name) | ||
371 | { | ||
372 | if (access (full_name, R_OK) == 0) | ||
373 | { | ||
374 | rc = _mu_parse_config (full_name, progname); | ||
375 | free (full_name); | ||
376 | } | ||
377 | else | ||
378 | rc = ENOENT; | ||
379 | } | ||
380 | else | ||
381 | rc = ENOMEM; | ||
382 | return rc; | ||
383 | } |
mailbox/cfg_parser.c
0 → 100644
This diff is collapsed.
Click to expand it.
mailbox/cfg_parser.h
0 → 100644
1 | /* A Bison parser, made by GNU Bison 2.3. */ | ||
2 | |||
3 | /* Skeleton interface for Bison's Yacc-like parsers in C | ||
4 | |||
5 | Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006 | ||
6 | Free Software Foundation, Inc. | ||
7 | |||
8 | This program is free software; you can redistribute it and/or modify | ||
9 | it under the terms of the GNU General Public License as published by | ||
10 | the Free Software Foundation; either version 2, or (at your option) | ||
11 | any later version. | ||
12 | |||
13 | This program is distributed in the hope that it will be useful, | ||
14 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
16 | GNU General Public License for more details. | ||
17 | |||
18 | You should have received a copy of the GNU General Public License | ||
19 | along with this program; if not, write to the Free Software | ||
20 | Foundation, Inc., 51 Franklin Street, Fifth Floor, | ||
21 | Boston, MA 02110-1301, USA. */ | ||
22 | |||
23 | /* As a special exception, you may create a larger work that contains | ||
24 | part or all of the Bison parser skeleton and distribute that work | ||
25 | under terms of your choice, so long as that work isn't itself a | ||
26 | parser generator using the skeleton or a modified version thereof | ||
27 | as a parser skeleton. Alternatively, if you modify or redistribute | ||
28 | the parser skeleton itself, you may (at your option) remove this | ||
29 | special exception, which will cause the skeleton and the resulting | ||
30 | Bison output files to be licensed under the GNU General Public | ||
31 | License without this special exception. | ||
32 | |||
33 | This special exception was added by the Free Software Foundation in | ||
34 | version 2.2 of Bison. */ | ||
35 | |||
36 | /* Tokens. */ | ||
37 | #ifndef YYTOKENTYPE | ||
38 | # define YYTOKENTYPE | ||
39 | /* Put the tokens into the symbol table, so that GDB and other debuggers | ||
40 | know about them. */ | ||
41 | enum mu_cfg_yytokentype { | ||
42 | MU_CFG_EOL_TOKEN = 258, | ||
43 | MU_CFG_START_TOKEN = 259, | ||
44 | MU_CFG_END_TOKEN = 260, | ||
45 | MU_CFG_STRING_TOKEN = 261 | ||
46 | }; | ||
47 | #endif | ||
48 | /* Tokens. */ | ||
49 | #define MU_CFG_EOL_TOKEN 258 | ||
50 | #define MU_CFG_START_TOKEN 259 | ||
51 | #define MU_CFG_END_TOKEN 260 | ||
52 | #define MU_CFG_STRING_TOKEN 261 | ||
53 | |||
54 | |||
55 | |||
56 | |||
57 | #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED | ||
58 | typedef union YYSTYPE | ||
59 | #line 115 "cfg_parser.y" | ||
60 | { | ||
61 | mu_cfg_node_t node; | ||
62 | mu_cfg_node_t *pnode; | ||
63 | struct | ||
64 | { | ||
65 | mu_cfg_node_t *head, *tail; | ||
66 | } nodelist; | ||
67 | char *string; | ||
68 | } | ||
69 | /* Line 1489 of yacc.c. */ | ||
70 | #line 71 "cfg_parser.h" | ||
71 | YYSTYPE; | ||
72 | # define mu_cfg_yystype YYSTYPE /* obsolescent; will be withdrawn */ | ||
73 | # define YYSTYPE_IS_DECLARED 1 | ||
74 | # define YYSTYPE_IS_TRIVIAL 1 | ||
75 | #endif | ||
76 | |||
77 | extern YYSTYPE mu_cfg_yylval; | ||
78 |
This diff is collapsed.
Click to expand it.
... | @@ -241,8 +241,10 @@ mu_authenticate (struct mu_auth_data *auth_data, char *pass) | ... | @@ -241,8 +241,10 @@ mu_authenticate (struct mu_auth_data *auth_data, char *pass) |
241 | return mu_auth_runlist (mu_authenticate_list, NULL, auth_data, pass); | 241 | return mu_auth_runlist (mu_authenticate_list, NULL, auth_data, pass); |
242 | } | 242 | } |
243 | 243 | ||
244 | /* Modules & configuration */ | 244 | |
245 | 245 | /* ************************************************************************* */ | |
246 | /* Traditional configuration */ | ||
247 | /* ************************************************************************* */ | ||
246 | 248 | ||
247 | #define ARG_AUTHORIZATION 1 | 249 | #define ARG_AUTHORIZATION 1 |
248 | #define ARG_AUTHENTICATION 2 | 250 | #define ARG_AUTHENTICATION 2 |
... | @@ -252,22 +254,22 @@ static error_t mu_auth_argp_parser (int key, char *arg, | ... | @@ -252,22 +254,22 @@ static error_t mu_auth_argp_parser (int key, char *arg, |
252 | 254 | ||
253 | /* Options used by programs that use extended authentication mechanisms. */ | 255 | /* Options used by programs that use extended authentication mechanisms. */ |
254 | static struct argp_option mu_auth_argp_option[] = { | 256 | static struct argp_option mu_auth_argp_option[] = { |
255 | { "authentication", ARG_AUTHENTICATION, N_("MODLIST"), 0, | 257 | { "authentication", ARG_AUTHENTICATION, N_("MODLIST"), OPTION_HIDDEN, |
256 | N_("Set the list of modules to be used for authentication"), 0 }, | 258 | N_("Set the list of modules to be used for authentication"), 0 }, |
257 | { "authorization", ARG_AUTHORIZATION, N_("MODLIST"), 0, | 259 | { "authorization", ARG_AUTHORIZATION, N_("MODLIST"), OPTION_HIDDEN, |
258 | N_("Set list of modules to be used for authorization"), 0 }, | 260 | N_("Set list of modules to be used for authorization"), 0 }, |
259 | { NULL, 0, NULL, 0, NULL, 0 } | 261 | { NULL, 0, NULL, 0, NULL, 0 } |
260 | }; | 262 | }; |
261 | 263 | ||
262 | struct argp mu_auth_argp = { | 264 | static struct argp mu_auth_argp = { |
263 | mu_auth_argp_option, | 265 | mu_auth_argp_option, |
264 | mu_auth_argp_parser, | 266 | mu_auth_argp_parser, |
265 | }; | 267 | }; |
266 | 268 | ||
267 | struct argp_child mu_auth_argp_child = { | 269 | static struct argp_child mu_auth_argp_child = { |
268 | &mu_auth_argp, | 270 | &mu_auth_argp, |
269 | 0, | 271 | 0, |
270 | "Authentication options", | 272 | NULL, |
271 | 0 | 273 | 0 |
272 | }; | 274 | }; |
273 | 275 | ||
... | @@ -295,6 +297,43 @@ mu_auth_argp_parser (int key, char *arg, struct argp_state *state) | ... | @@ -295,6 +297,43 @@ mu_auth_argp_parser (int key, char *arg, struct argp_state *state) |
295 | return 0; | 297 | return 0; |
296 | } | 298 | } |
297 | 299 | ||
300 | |||
301 | /* ************************************************************************* */ | ||
302 | /* Resource-style configuration */ | ||
303 | /* ************************************************************************* */ | ||
304 | static int | ||
305 | cb_authentication (mu_cfg_locus_t *locus, void *data, char *arg) | ||
306 | { | ||
307 | mu_authentication_add_module_list (arg);/*FIXME: error reporting*/ | ||
308 | return 0; | ||
309 | } | ||
310 | |||
311 | static int | ||
312 | cb_authorization (mu_cfg_locus_t *locus, void *data, char *arg) | ||
313 | { | ||
314 | mu_authorization_add_module_list (arg); | ||
315 | return 0; | ||
316 | } | ||
317 | |||
318 | static struct mu_cfg_param mu_auth_param[] = { | ||
319 | { "authentication", mu_cfg_callback, NULL, cb_authentication }, | ||
320 | { "authorization", mu_cfg_callback, NULL, cb_authorization }, | ||
321 | { NULL } | ||
322 | }; | ||
323 | |||
324 | |||
325 | void | ||
326 | mu_auth_init () | ||
327 | { | ||
328 | if (mu_register_capa ("auth", &mu_auth_argp_child, mu_auth_param)) | ||
329 | { | ||
330 | mu_error (_("INTERNAL ERROR: cannot register argp capability auth (please report)")); | ||
331 | abort (); | ||
332 | } | ||
333 | } | ||
334 | |||
335 | |||
336 | /* ************************************************************************* */ | ||
298 | 337 | ||
299 | struct _module_handler { | 338 | struct _module_handler { |
300 | struct auth_stack_entry authenticate; | 339 | struct auth_stack_entry authenticate; |
... | @@ -342,7 +381,10 @@ mu_auth_register_module (struct mu_auth_module *mod) | ... | @@ -342,7 +381,10 @@ mu_auth_register_module (struct mu_auth_module *mod) |
342 | cp++; | 381 | cp++; |
343 | cp->argp = NULL; | 382 | cp->argp = NULL; |
344 | } | 383 | } |
345 | 384 | ||
385 | if (mod->cfg) | ||
386 | mu_config_register_plain_section (NULL, mod->name, mod->cfg); | ||
387 | |||
346 | if (!module_handler_list && mu_list_create (&module_handler_list)) | 388 | if (!module_handler_list && mu_list_create (&module_handler_list)) |
347 | abort (); | 389 | abort (); |
348 | 390 | ... | ... |
... | @@ -138,6 +138,7 @@ mu_authenticate_system (struct mu_auth_data **return_data MU_ARG_UNUSED, | ... | @@ -138,6 +138,7 @@ mu_authenticate_system (struct mu_auth_data **return_data MU_ARG_UNUSED, |
138 | struct mu_auth_module mu_auth_system_module = { | 138 | struct mu_auth_module mu_auth_system_module = { |
139 | "system", | 139 | "system", |
140 | NULL, | 140 | NULL, |
141 | NULL, | ||
141 | mu_authenticate_system, | 142 | mu_authenticate_system, |
142 | NULL, | 143 | NULL, |
143 | mu_auth_system_by_name, | 144 | mu_auth_system_by_name, |
... | @@ -150,6 +151,7 @@ struct mu_auth_module mu_auth_system_module = { | ... | @@ -150,6 +151,7 @@ struct mu_auth_module mu_auth_system_module = { |
150 | struct mu_auth_module mu_auth_generic_module = { | 151 | struct mu_auth_module mu_auth_generic_module = { |
151 | "generic", | 152 | "generic", |
152 | NULL, | 153 | NULL, |
154 | NULL, | ||
153 | mu_authenticate_generic, | 155 | mu_authenticate_generic, |
154 | NULL, | 156 | NULL, |
155 | mu_auth_nosupport, | 157 | mu_auth_nosupport, | ... | ... |
-
Please register or sign in to post a comment