Convert comsat to mu_cli
Showing
4 changed files
with
341 additions
and
88 deletions
... | @@ -31,7 +31,7 @@ biff.rc.h: $(top_srcdir)/comsat/biff.rc | ... | @@ -31,7 +31,7 @@ biff.rc.h: $(top_srcdir)/comsat/biff.rc |
31 | $(top_srcdir)/comsat/biff.rc > biff.rc.h | 31 | $(top_srcdir)/comsat/biff.rc > biff.rc.h |
32 | 32 | ||
33 | comsatd_LDADD = \ | 33 | comsatd_LDADD = \ |
34 | ${MU_APP_LIBRARIES}\ | 34 | ${MU_APP_NEW_LIBRARIES}\ |
35 | ${MU_LIB_MBOX}\ | 35 | ${MU_LIB_MBOX}\ |
36 | ${MU_LIB_IMAP}\ | 36 | ${MU_LIB_IMAP}\ |
37 | ${MU_LIB_POP}\ | 37 | ${MU_LIB_POP}\ | ... | ... |
... | @@ -18,7 +18,7 @@ | ... | @@ -18,7 +18,7 @@ |
18 | #include "comsat.h" | 18 | #include "comsat.h" |
19 | #define MU_CFG_COMPATIBILITY /* This source uses deprecated cfg interfaces */ | 19 | #define MU_CFG_COMPATIBILITY /* This source uses deprecated cfg interfaces */ |
20 | #include "mailutils/libcfg.h" | 20 | #include "mailutils/libcfg.h" |
21 | #include "mailutils/libargp.h" | 21 | #include "mailutils/cli.h" |
22 | 22 | ||
23 | #ifndef PATH_DEV | 23 | #ifndef PATH_DEV |
24 | # define PATH_DEV "/dev" | 24 | # define PATH_DEV "/dev" |
... | @@ -59,44 +59,62 @@ typedef struct utmp UTMP; | ... | @@ -59,44 +59,62 @@ typedef struct utmp UTMP; |
59 | #define MAX_TTY_SIZE (sizeof (PATH_TTY_PFX) + sizeof (((UTMP*)0)->ut_line)) | 59 | #define MAX_TTY_SIZE (sizeof (PATH_TTY_PFX) + sizeof (((UTMP*)0)->ut_line)) |
60 | 60 | ||
61 | const char *program_version = "comsatd (" PACKAGE_STRING ")"; | 61 | const char *program_version = "comsatd (" PACKAGE_STRING ")"; |
62 | static char doc[] = N_("GNU comsatd -- notify users about incoming mail"); | ||
63 | static char args_doc[] = N_("\n--test MBOX-URL MSG-QID"); | ||
64 | 62 | ||
65 | #define OPT_FOREGROUND 256 | 63 | int test_mode; |
64 | char *biffrc = BIFF_RC; | ||
65 | mu_m_server_t server; | ||
66 | 66 | ||
67 | static struct argp_option options[] = | 67 | static void |
68 | set_inetd_mode (struct mu_parseopt *po, struct mu_option *opt, | ||
69 | char const *arg) | ||
68 | { | 70 | { |
69 | { "test", 't', NULL, 0, N_("run in test mode"), 0 }, | 71 | mu_m_server_set_mode (server, MODE_INTERACTIVE); |
70 | { "foreground", OPT_FOREGROUND, 0, 0, N_("remain in foreground"), 0}, | 72 | } |
71 | { "inetd", 'i', 0, 0, N_("run in inetd mode"), 0 }, | ||
72 | { "daemon", 'd', N_("NUMBER"), OPTION_ARG_OPTIONAL, | ||
73 | N_("runs in daemon mode with a maximum of NUMBER children"), 0 }, | ||
74 | { "file", 'f', N_("FILE"), 0, | ||
75 | N_("read FILE instead of .biffrc"), 0 }, | ||
76 | { NULL, 0, NULL, 0, NULL, 0 } | ||
77 | }; | ||
78 | 73 | ||
79 | static error_t comsatd_parse_opt (int key, char *arg, | 74 | static void |
80 | struct argp_state *state); | 75 | set_daemon_mode (struct mu_parseopt *po, struct mu_option *opt, |
76 | char const *arg) | ||
77 | { | ||
78 | mu_m_server_set_mode (server, MODE_DAEMON); | ||
79 | if (arg) | ||
80 | { | ||
81 | size_t max_children; | ||
82 | char *errmsg; | ||
83 | int rc = mu_str_to_c (arg, mu_c_size, &max_children, &errmsg); | ||
84 | if (rc) | ||
85 | { | ||
86 | mu_parseopt_error (po, _("%s: bad argument"), arg); | ||
87 | exit (po->po_exit_error); | ||
88 | } | ||
89 | mu_m_server_set_max_children (server, max_children); | ||
90 | } | ||
91 | } | ||
81 | 92 | ||
82 | static struct argp argp = { | 93 | static void |
83 | options, | 94 | set_foreground (struct mu_parseopt *po, struct mu_option *opt, |
84 | comsatd_parse_opt, | 95 | char const *arg) |
85 | args_doc, | 96 | { |
86 | doc, | 97 | mu_m_server_set_foreground (server, 1); |
87 | NULL, | 98 | } |
88 | NULL, NULL | ||
89 | }; | ||
90 | 99 | ||
91 | static const char *comsat_argp_capa[] = { | 100 | static struct mu_option comsat_options[] = { |
92 | "mailutils", | 101 | { "test", 't', NULL, MU_OPTION_DEFAULT, |
93 | "common", | 102 | N_("run in test mode"), |
94 | "debug", | 103 | mu_c_bool, &test_mode }, |
95 | "logging", | 104 | { "foreground", 0, NULL, MU_OPTION_DEFAULT, |
96 | "mailbox", | 105 | N_("remain in foreground"), |
97 | "locking", | 106 | mu_c_bool, NULL, set_foreground }, |
98 | NULL | 107 | { "inetd", 'i', NULL, MU_OPTION_DEFAULT, |
99 | }; | 108 | N_("run in inetd mode"), |
109 | mu_c_bool, NULL, set_inetd_mode }, | ||
110 | { "daemon", 'd', N_("NUMBER"), MU_OPTION_ARG_OPTIONAL, | ||
111 | N_("runs in daemon mode with a maximum of NUMBER children"), | ||
112 | mu_c_string, NULL, set_daemon_mode }, | ||
113 | { "file", 'f', N_("FILE"), MU_OPTION_DEFAULT, | ||
114 | N_("read FILE instead of .biffrc"), | ||
115 | mu_c_string, &biffrc }, | ||
116 | MU_OPTION_END | ||
117 | }, *options[] = { comsat_options, NULL }; | ||
100 | 118 | ||
101 | #define SUCCESS 0 | 119 | #define SUCCESS 0 |
102 | #define NOT_HERE 1 | 120 | #define NOT_HERE 1 |
... | @@ -107,7 +125,6 @@ char *hostname; | ... | @@ -107,7 +125,6 @@ char *hostname; |
107 | const char *username; | 125 | const char *username; |
108 | int require_tty; | 126 | int require_tty; |
109 | int biffrc_errors = BIFFRC_ERRORS_TO_TTY | BIFFRC_ERRORS_TO_ERR; | 127 | int biffrc_errors = BIFFRC_ERRORS_TO_TTY | BIFFRC_ERRORS_TO_ERR; |
110 | mu_m_server_t server; | ||
111 | 128 | ||
112 | static void comsat_init (void); | 129 | static void comsat_init (void); |
113 | static int comsat_main (int fd); | 130 | static int comsat_main (int fd); |
... | @@ -118,9 +135,6 @@ static char *mailbox_path (const char *user); | ... | @@ -118,9 +135,6 @@ static char *mailbox_path (const char *user); |
118 | static int change_user (const char *user); | 135 | static int change_user (const char *user); |
119 | 136 | ||
120 | static int reload = 0; | 137 | static int reload = 0; |
121 | int test_mode; | ||
122 | char *biffrc = BIFF_RC; | ||
123 | |||
124 | static int | 138 | static int |
125 | biffrc_error_ctl (mu_config_value_t *val, int flag) | 139 | biffrc_error_ctl (mu_config_value_t *val, int flag) |
126 | { | 140 | { |
... | @@ -178,48 +192,23 @@ struct mu_cfg_param comsat_cfg_param[] = { | ... | @@ -178,48 +192,23 @@ struct mu_cfg_param comsat_cfg_param[] = { |
178 | { NULL } | 192 | { NULL } |
179 | }; | 193 | }; |
180 | 194 | ||
181 | static error_t | 195 | static char const *alt_args[] = { N_("--test MBOX-URL MSG-QID"), NULL }; |
182 | comsatd_parse_opt (int key, char *arg, struct argp_state *state) | ||
183 | { | ||
184 | static mu_list_t lst; | ||
185 | |||
186 | switch (key) | ||
187 | { | ||
188 | case 'd': | ||
189 | mu_argp_node_list_new (lst, "mode", "daemon"); | ||
190 | if (arg) | ||
191 | mu_argp_node_list_new (lst, "max-children", arg); | ||
192 | break; | ||
193 | |||
194 | case 'f': | ||
195 | biffrc = arg; | ||
196 | break; | ||
197 | |||
198 | case 'i': | ||
199 | mu_argp_node_list_new (lst, "mode", "inetd"); | ||
200 | break; | ||
201 | |||
202 | case OPT_FOREGROUND: | ||
203 | mu_argp_node_list_new (lst, "foreground", "yes"); | ||
204 | break; | ||
205 | 196 | ||
206 | case 't': | 197 | static struct mu_cli_setup cli = { |
207 | test_mode = 1; | 198 | options, |
208 | break; | 199 | comsat_cfg_param, |
209 | 200 | N_("GNU comsatd -- notify users about incoming mail"), | |
210 | case ARGP_KEY_INIT: | 201 | "", |
211 | mu_argp_node_list_init (&lst); | 202 | alt_args, |
212 | break; | 203 | }; |
213 | |||
214 | case ARGP_KEY_FINI: | ||
215 | mu_argp_node_list_finish (lst, NULL, NULL); | ||
216 | break; | ||
217 | 204 | ||
218 | default: | 205 | static char *capa[] = { |
219 | return ARGP_ERR_UNKNOWN; | 206 | "debug", |
220 | } | 207 | "logging", |
221 | return 0; | 208 | "mailbox", |
222 | } | 209 | "locking", |
210 | NULL | ||
211 | }; | ||
223 | 212 | ||
224 | static RETSIGTYPE | 213 | static RETSIGTYPE |
225 | sig_hup (int sig) | 214 | sig_hup (int sig) |
... | @@ -558,12 +547,11 @@ int | ... | @@ -558,12 +547,11 @@ int |
558 | main (int argc, char **argv) | 547 | main (int argc, char **argv) |
559 | { | 548 | { |
560 | int c; | 549 | int c; |
561 | int ind; | 550 | char **save_argv; |
562 | 551 | ||
563 | /* Native Language Support */ | 552 | /* Native Language Support */ |
564 | MU_APP_INIT_NLS (); | 553 | MU_APP_INIT_NLS (); |
565 | 554 | ||
566 | mu_argp_init (NULL, NULL); | ||
567 | comsat_init (); | 555 | comsat_init (); |
568 | mu_acl_cfg_init (); | 556 | mu_acl_cfg_init (); |
569 | mu_m_server_create (&server, program_version); | 557 | mu_m_server_create (&server, program_version); |
... | @@ -579,18 +567,15 @@ main (int argc, char **argv) | ... | @@ -579,18 +567,15 @@ main (int argc, char **argv) |
579 | /* FIXME: timeout is not needed. How to disable it? */ | 567 | /* FIXME: timeout is not needed. How to disable it? */ |
580 | mu_log_syslog = 1; | 568 | mu_log_syslog = 1; |
581 | 569 | ||
582 | if (mu_app_init (&argp, comsat_argp_capa, comsat_cfg_param, argc, argv, 0, | 570 | save_argv = argv; |
583 | &ind, server)) | 571 | |
584 | exit (EXIT_FAILURE); | 572 | mu_cli (argc, argv, &cli, capa, NULL, &argc, &argv); |
585 | 573 | ||
586 | if (test_mode) | 574 | if (test_mode) |
587 | { | 575 | { |
588 | struct passwd *pw; | 576 | struct passwd *pw; |
589 | char *user; | 577 | char *user; |
590 | 578 | ||
591 | argc -= ind; | ||
592 | argv += ind; | ||
593 | |||
594 | mu_stdstream_strerr_setup (MU_STRERR_STDERR); | 579 | mu_stdstream_strerr_setup (MU_STRERR_STDERR); |
595 | biffrc_errors = BIFFRC_ERRORS_TO_ERR; | 580 | biffrc_errors = BIFFRC_ERRORS_TO_ERR; |
596 | if (argc < 2 || argc > 2) | 581 | if (argc < 2 || argc > 2) |
... | @@ -630,7 +615,7 @@ main (int argc, char **argv) | ... | @@ -630,7 +615,7 @@ main (int argc, char **argv) |
630 | 615 | ||
631 | if (mu_m_server_mode (server) == MODE_DAEMON) | 616 | if (mu_m_server_mode (server) == MODE_DAEMON) |
632 | { | 617 | { |
633 | if (argv[0][0] != '/') | 618 | if (save_argv[0][0] != '/') |
634 | mu_diag_output (MU_DIAG_NOTICE, | 619 | mu_diag_output (MU_DIAG_NOTICE, |
635 | _("program name is not absolute; reloading will not " | 620 | _("program name is not absolute; reloading will not " |
636 | "be possible")); | 621 | "be possible")); |
... | @@ -651,7 +636,7 @@ main (int argc, char **argv) | ... | @@ -651,7 +636,7 @@ main (int argc, char **argv) |
651 | if (reload) | 636 | if (reload) |
652 | { | 637 | { |
653 | mu_diag_output (MU_DIAG_NOTICE, _("restarting")); | 638 | mu_diag_output (MU_DIAG_NOTICE, _("restarting")); |
654 | execvp (argv[0], argv); | 639 | execvp (save_argv[0], save_argv); |
655 | } | 640 | } |
656 | } | 641 | } |
657 | else | 642 | else | ... | ... |
libmailutils/cli/acl.c
0 → 100644
1 | /* This file is part of GNU Mailutils | ||
2 | Copyright (C) 2007-2012, 2014-2016 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 | GNU Mailutils 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 GNU Mailutils. If not, see <http://www.gnu.org/licenses/>. | ||
16 | */ | ||
17 | |||
18 | #ifdef HAVE_CONFIG_H | ||
19 | # include <config.h> | ||
20 | #endif | ||
21 | #include "mailutils/acl.h" | ||
22 | #include "mailutils/argcv.h" | ||
23 | #include "mailutils/cidr.h" | ||
24 | #include "mailutils/cfg.h" | ||
25 | #include "mailutils/errno.h" | ||
26 | #include "mailutils/nls.h" | ||
27 | #include <stdlib.h> | ||
28 | #include <stdio.h> | ||
29 | #include <string.h> | ||
30 | #include <unistd.h> | ||
31 | #include <sys/time.h> | ||
32 | #include <sys/types.h> | ||
33 | #include <sys/socket.h> | ||
34 | #include <netinet/in.h> | ||
35 | #include <arpa/inet.h> | ||
36 | |||
37 | #define ISSPACE(c) ((c)==' '||(c)=='\t') | ||
38 | |||
39 | #define SKIPWS(p) while (*(p) && ISSPACE (*(p))) (p)++; | ||
40 | |||
41 | static const char * | ||
42 | getword (mu_config_value_t *val, int *pn) | ||
43 | { | ||
44 | int n = (*pn)++; | ||
45 | mu_config_value_t *v; | ||
46 | |||
47 | if (n >= val->v.arg.c) | ||
48 | { | ||
49 | mu_error (_("not enough arguments")); | ||
50 | return NULL; | ||
51 | } | ||
52 | v = &val->v.arg.v[n]; | ||
53 | if (mu_cfg_assert_value_type (v, MU_CFG_STRING)) | ||
54 | return NULL; | ||
55 | return v->v.string; | ||
56 | } | ||
57 | |||
58 | static int | ||
59 | parsearg (mu_config_value_t *val, struct mu_cidr *cidr, char **prest) | ||
60 | { | ||
61 | const char *w; | ||
62 | int n = 0; | ||
63 | int rc; | ||
64 | |||
65 | if (mu_cfg_assert_value_type (val, MU_CFG_ARRAY)) | ||
66 | return 1; | ||
67 | |||
68 | w = getword (val, &n); | ||
69 | if (!w) | ||
70 | return 1; | ||
71 | if (strcmp (w, "from") == 0) { | ||
72 | w = getword (val, &n); | ||
73 | if (!w) | ||
74 | return 1; | ||
75 | } | ||
76 | |||
77 | if (strcmp (w, "any") == 0) | ||
78 | cidr->len = 0; | ||
79 | else | ||
80 | { | ||
81 | rc = mu_cidr_from_string (cidr, w); | ||
82 | if (rc) | ||
83 | { | ||
84 | mu_error (_("invalid source CIDR: %s"), mu_strerror (rc)); | ||
85 | return 1; | ||
86 | } | ||
87 | } | ||
88 | |||
89 | if (prest) | ||
90 | { | ||
91 | if (n == val->v.arg.c) | ||
92 | *prest = NULL; | ||
93 | else | ||
94 | { | ||
95 | size_t size = 0; | ||
96 | int i; | ||
97 | char *buf; | ||
98 | |||
99 | for (i = n; i < val->v.arg.c; i++) | ||
100 | { | ||
101 | if (mu_cfg_assert_value_type (&val->v.arg.v[i], MU_CFG_STRING)) | ||
102 | return 1; | ||
103 | size += strlen (val->v.arg.v[i].v.string) + 1; | ||
104 | } | ||
105 | |||
106 | buf = malloc (size); | ||
107 | if (!buf) | ||
108 | { | ||
109 | mu_error ("%s", mu_strerror (errno)); | ||
110 | return 1; | ||
111 | } | ||
112 | |||
113 | *prest = buf; | ||
114 | for (i = n; i < val->v.arg.c; i++) | ||
115 | { | ||
116 | if (i > n) | ||
117 | *buf++ = ' '; | ||
118 | strcpy (buf, val->v.arg.v[i].v.string); | ||
119 | buf += strlen (buf); | ||
120 | } | ||
121 | *buf = 0; | ||
122 | } | ||
123 | } | ||
124 | else if (n != val->v.arg.c) | ||
125 | { | ||
126 | mu_error (_("junk after IP address")); | ||
127 | return 1; | ||
128 | } | ||
129 | return 0; | ||
130 | } | ||
131 | |||
132 | static int | ||
133 | cb_allow (void *data, mu_config_value_t *val) | ||
134 | { | ||
135 | int rc; | ||
136 | mu_acl_t acl = *(mu_acl_t*)data; | ||
137 | struct mu_cidr cidr; | ||
138 | |||
139 | if (parsearg (val, &cidr, NULL)) | ||
140 | return 1; | ||
141 | rc = mu_acl_append (acl, mu_acl_accept, NULL, &cidr); | ||
142 | if (rc) | ||
143 | mu_error (_("cannot append acl entry: %s"), mu_strerror (rc)); | ||
144 | return rc; | ||
145 | } | ||
146 | |||
147 | static int | ||
148 | cb_deny (void *data, mu_config_value_t *val) | ||
149 | { | ||
150 | int rc; | ||
151 | mu_acl_t acl = *(mu_acl_t*)data; | ||
152 | struct mu_cidr cidr; | ||
153 | |||
154 | if (parsearg (val, &cidr, NULL)) | ||
155 | return 1; | ||
156 | rc = mu_acl_append (acl, mu_acl_deny, NULL, &cidr); | ||
157 | if (rc) | ||
158 | mu_error (_("cannot append acl entry: %s"), mu_strerror (rc)); | ||
159 | return rc; | ||
160 | } | ||
161 | |||
162 | static int | ||
163 | cb_log (void *data, mu_config_value_t *val) | ||
164 | { | ||
165 | int rc; | ||
166 | mu_acl_t acl = *(mu_acl_t*)data; | ||
167 | struct mu_cidr cidr; | ||
168 | char *rest; | ||
169 | |||
170 | if (parsearg (val, &cidr, &rest)) | ||
171 | return 1; | ||
172 | rc = mu_acl_append (acl, mu_acl_log, rest, &cidr); | ||
173 | if (rc) | ||
174 | mu_error (_("cannot append acl entry: %s"), mu_strerror (rc)); | ||
175 | return rc; | ||
176 | } | ||
177 | |||
178 | static int | ||
179 | cb_exec (void *data, mu_config_value_t *val) | ||
180 | { | ||
181 | int rc; | ||
182 | mu_acl_t acl = *(mu_acl_t*)data; | ||
183 | struct mu_cidr cidr; | ||
184 | char *rest; | ||
185 | |||
186 | if (parsearg (val, &cidr, &rest)) | ||
187 | return 1; | ||
188 | rc = mu_acl_append (acl, mu_acl_exec, rest, &cidr); | ||
189 | if (rc) | ||
190 | mu_error (_("cannot append acl entry: %s"), mu_strerror (rc)); | ||
191 | return rc; | ||
192 | } | ||
193 | |||
194 | static int | ||
195 | cb_ifexec (void *data, mu_config_value_t *val) | ||
196 | { | ||
197 | int rc; | ||
198 | mu_acl_t acl = *(mu_acl_t*)data; | ||
199 | struct mu_cidr cidr; | ||
200 | char *rest; | ||
201 | |||
202 | if (parsearg (val, &cidr, &rest)) | ||
203 | return 1; | ||
204 | rc = mu_acl_append (acl, mu_acl_ifexec, rest, &cidr); | ||
205 | if (rc) | ||
206 | mu_error (_("cannot append acl entry: %s"), mu_strerror (rc)); | ||
207 | return rc; | ||
208 | } | ||
209 | |||
210 | static struct mu_cfg_param acl_param[] = { | ||
211 | { "allow", mu_cfg_callback, NULL, 0, cb_allow, | ||
212 | N_("Allow connections from this IP address. Optional word `from' is " | ||
213 | "allowed between it and its argument. The same holds true for other " | ||
214 | "actions below."), | ||
215 | N_("addr: IP") }, | ||
216 | { "deny", mu_cfg_callback, NULL, 0, cb_deny, | ||
217 | N_("Deny connections from this IP address."), | ||
218 | N_("addr: IP") }, | ||
219 | { "log", mu_cfg_callback, NULL, 0, cb_log, | ||
220 | N_("Log connections from this IP address."), | ||
221 | N_("addr: IP") }, | ||
222 | { "exec", mu_cfg_callback, NULL, 0, cb_exec, | ||
223 | N_("Execute supplied program if a connection from this IP address is " | ||
224 | "requested. Arguments are:\n" | ||
225 | " <addr: IP> <program: string>\n" | ||
226 | "Following macros are expanded in <program> before executing:\n" | ||
227 | " address - Source IP address\n" | ||
228 | " port - Source port number\n") }, | ||
229 | { "ifexec", mu_cfg_callback, NULL, 0, cb_ifexec, | ||
230 | N_("If a connection from this IP address is requested, execute supplied " | ||
231 | "program and allow or deny the connection depending on its exit code. " | ||
232 | "See `exec' for a description of its arguments.") }, | ||
233 | { NULL } | ||
234 | }; | ||
235 | |||
236 | static int | ||
237 | acl_section_parser (enum mu_cfg_section_stage stage, | ||
238 | const mu_cfg_node_t *node, | ||
239 | const char *section_label, void **section_data, | ||
240 | void *call_data, | ||
241 | mu_cfg_tree_t *tree) | ||
242 | { | ||
243 | switch (stage) | ||
244 | { | ||
245 | case mu_cfg_section_start: | ||
246 | { | ||
247 | void *data = *section_data; | ||
248 | mu_acl_create ((mu_acl_t*)data); | ||
249 | } | ||
250 | break; | ||
251 | |||
252 | case mu_cfg_section_end: | ||
253 | break; | ||
254 | } | ||
255 | return 0; | ||
256 | } | ||
257 | |||
258 | void | ||
259 | mu_acl_cfg_init (void) | ||
260 | { | ||
261 | struct mu_cfg_section *section; | ||
262 | if (mu_create_canned_section ("acl", §ion) == 0) | ||
263 | { | ||
264 | section->parser = acl_section_parser; | ||
265 | mu_cfg_section_add_params (section, acl_param); | ||
266 | } | ||
267 | } |
-
Please register or sign in to post a comment