Mercurial > dovecot > core-2.2
annotate src/config/config-connection.c @ 9793:d7ccdbb58a03 HEAD
config: If master module requests configuration, reread it before replying.
If new configuration is invalid, send an ERROR reply back.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Fri, 14 Aug 2009 18:13:35 -0400 |
parents | 04cade277134 |
children | e95135898a3c |
rev | line source |
---|---|
9013
8b616cc6d848
Added dovecof --exec and made deliver use it instead of forking.
Timo Sirainen <tss@iki.fi>
parents:
9002
diff
changeset
|
1 /* Copyright (C) 2005-2009 Dovecot authors, see the included COPYING file */ |
9002 | 2 |
9179
f8460b27db00
doveconf: With -p only protocol-specific settings are returned. -n and -a return human-readable output.
Timo Sirainen <tss@iki.fi>
parents:
9159
diff
changeset
|
3 #include "lib.h" |
9159
6324a79d3ee1
Initial commit for v2.0 master rewrite. Several features are still missing.
Timo Sirainen <tss@iki.fi>
parents:
9087
diff
changeset
|
4 #include "llist.h" |
9002 | 5 #include "istream.h" |
6 #include "ostream.h" | |
9274
39c2db5f1fcc
config: If value contains <file, the setting value is read from the given file.
Timo Sirainen <tss@iki.fi>
parents:
9263
diff
changeset
|
7 #include "settings-parser.h" |
9349
04cade277134
Added missing master_service_client_connection_destroyed() calls.
Timo Sirainen <tss@iki.fi>
parents:
9274
diff
changeset
|
8 #include "master-service.h" |
9179
f8460b27db00
doveconf: With -p only protocol-specific settings are returned. -n and -a return human-readable output.
Timo Sirainen <tss@iki.fi>
parents:
9159
diff
changeset
|
9 #include "config-request.h" |
9793
d7ccdbb58a03
config: If master module requests configuration, reread it before replying.
Timo Sirainen <tss@iki.fi>
parents:
9349
diff
changeset
|
10 #include "config-parser.h" |
9002 | 11 #include "config-connection.h" |
12 | |
13 #include <stdlib.h> | |
14 #include <unistd.h> | |
15 | |
16 #define MAX_INBUF_SIZE 1024 | |
17 | |
18 #define CONFIG_CLIENT_PROTOCOL_MAJOR_VERSION 1 | |
19 #define CONFIG_CLIENT_PROTOCOL_MINOR_VERSION 0 | |
20 | |
21 struct config_connection { | |
9159
6324a79d3ee1
Initial commit for v2.0 master rewrite. Several features are still missing.
Timo Sirainen <tss@iki.fi>
parents:
9087
diff
changeset
|
22 struct config_connection *prev, *next; |
6324a79d3ee1
Initial commit for v2.0 master rewrite. Several features are still missing.
Timo Sirainen <tss@iki.fi>
parents:
9087
diff
changeset
|
23 |
9002 | 24 int fd; |
25 struct istream *input; | |
26 struct ostream *output; | |
27 struct io *io; | |
28 | |
29 unsigned int version_received:1; | |
30 unsigned int handshaked:1; | |
31 }; | |
32 | |
9159
6324a79d3ee1
Initial commit for v2.0 master rewrite. Several features are still missing.
Timo Sirainen <tss@iki.fi>
parents:
9087
diff
changeset
|
33 struct config_connection *config_connections = NULL; |
6324a79d3ee1
Initial commit for v2.0 master rewrite. Several features are still missing.
Timo Sirainen <tss@iki.fi>
parents:
9087
diff
changeset
|
34 |
9002 | 35 static const char *const * |
36 config_connection_next_line(struct config_connection *conn) | |
37 { | |
38 const char *line; | |
39 | |
40 line = i_stream_next_line(conn->input); | |
41 if (line == NULL) | |
42 return NULL; | |
43 | |
44 return t_strsplit(line, "\t"); | |
45 } | |
46 | |
9179
f8460b27db00
doveconf: With -p only protocol-specific settings are returned. -n and -a return human-readable output.
Timo Sirainen <tss@iki.fi>
parents:
9159
diff
changeset
|
47 static void |
f8460b27db00
doveconf: With -p only protocol-specific settings are returned. -n and -a return human-readable output.
Timo Sirainen <tss@iki.fi>
parents:
9159
diff
changeset
|
48 config_request_output(const char *key, const char *value, |
f8460b27db00
doveconf: With -p only protocol-specific settings are returned. -n and -a return human-readable output.
Timo Sirainen <tss@iki.fi>
parents:
9159
diff
changeset
|
49 bool list ATTR_UNUSED, void *context) |
f8460b27db00
doveconf: With -p only protocol-specific settings are returned. -n and -a return human-readable output.
Timo Sirainen <tss@iki.fi>
parents:
9159
diff
changeset
|
50 { |
f8460b27db00
doveconf: With -p only protocol-specific settings are returned. -n and -a return human-readable output.
Timo Sirainen <tss@iki.fi>
parents:
9159
diff
changeset
|
51 struct ostream *output = context; |
9274
39c2db5f1fcc
config: If value contains <file, the setting value is read from the given file.
Timo Sirainen <tss@iki.fi>
parents:
9263
diff
changeset
|
52 const char *p; |
9179
f8460b27db00
doveconf: With -p only protocol-specific settings are returned. -n and -a return human-readable output.
Timo Sirainen <tss@iki.fi>
parents:
9159
diff
changeset
|
53 |
f8460b27db00
doveconf: With -p only protocol-specific settings are returned. -n and -a return human-readable output.
Timo Sirainen <tss@iki.fi>
parents:
9159
diff
changeset
|
54 o_stream_send_str(output, key); |
f8460b27db00
doveconf: With -p only protocol-specific settings are returned. -n and -a return human-readable output.
Timo Sirainen <tss@iki.fi>
parents:
9159
diff
changeset
|
55 o_stream_send_str(output, "="); |
9274
39c2db5f1fcc
config: If value contains <file, the setting value is read from the given file.
Timo Sirainen <tss@iki.fi>
parents:
9263
diff
changeset
|
56 while ((p = strchr(value, '\n')) != NULL) { |
39c2db5f1fcc
config: If value contains <file, the setting value is read from the given file.
Timo Sirainen <tss@iki.fi>
parents:
9263
diff
changeset
|
57 o_stream_send(output, value, p-value); |
39c2db5f1fcc
config: If value contains <file, the setting value is read from the given file.
Timo Sirainen <tss@iki.fi>
parents:
9263
diff
changeset
|
58 o_stream_send(output, SETTING_STREAM_LF_CHAR, 1); |
39c2db5f1fcc
config: If value contains <file, the setting value is read from the given file.
Timo Sirainen <tss@iki.fi>
parents:
9263
diff
changeset
|
59 value = p+1; |
39c2db5f1fcc
config: If value contains <file, the setting value is read from the given file.
Timo Sirainen <tss@iki.fi>
parents:
9263
diff
changeset
|
60 } |
9179
f8460b27db00
doveconf: With -p only protocol-specific settings are returned. -n and -a return human-readable output.
Timo Sirainen <tss@iki.fi>
parents:
9159
diff
changeset
|
61 o_stream_send_str(output, value); |
f8460b27db00
doveconf: With -p only protocol-specific settings are returned. -n and -a return human-readable output.
Timo Sirainen <tss@iki.fi>
parents:
9159
diff
changeset
|
62 o_stream_send_str(output, "\n"); |
f8460b27db00
doveconf: With -p only protocol-specific settings are returned. -n and -a return human-readable output.
Timo Sirainen <tss@iki.fi>
parents:
9159
diff
changeset
|
63 } |
f8460b27db00
doveconf: With -p only protocol-specific settings are returned. -n and -a return human-readable output.
Timo Sirainen <tss@iki.fi>
parents:
9159
diff
changeset
|
64 |
9793
d7ccdbb58a03
config: If master module requests configuration, reread it before replying.
Timo Sirainen <tss@iki.fi>
parents:
9349
diff
changeset
|
65 static int config_connection_request(struct config_connection *conn, |
d7ccdbb58a03
config: If master module requests configuration, reread it before replying.
Timo Sirainen <tss@iki.fi>
parents:
9349
diff
changeset
|
66 const char *const *args) |
9002 | 67 { |
9263
5d0a69504867
config handling fixes and improvements. Separated module/service lookups. Added support for per-lip/rip settings.
Timo Sirainen <tss@iki.fi>
parents:
9233
diff
changeset
|
68 struct config_filter filter; |
9793
d7ccdbb58a03
config: If master module requests configuration, reread it before replying.
Timo Sirainen <tss@iki.fi>
parents:
9349
diff
changeset
|
69 const char *path, *error, *module = ""; |
9179
f8460b27db00
doveconf: With -p only protocol-specific settings are returned. -n and -a return human-readable output.
Timo Sirainen <tss@iki.fi>
parents:
9159
diff
changeset
|
70 |
9181
150a98d2407c
config: service names had an extra "service=".
Timo Sirainen <tss@iki.fi>
parents:
9179
diff
changeset
|
71 /* [<args>] */ |
9263
5d0a69504867
config handling fixes and improvements. Separated module/service lookups. Added support for per-lip/rip settings.
Timo Sirainen <tss@iki.fi>
parents:
9233
diff
changeset
|
72 memset(&filter, 0, sizeof(filter)); |
9181
150a98d2407c
config: service names had an extra "service=".
Timo Sirainen <tss@iki.fi>
parents:
9179
diff
changeset
|
73 for (; *args != NULL; args++) { |
150a98d2407c
config: service names had an extra "service=".
Timo Sirainen <tss@iki.fi>
parents:
9179
diff
changeset
|
74 if (strncmp(*args, "service=", 8) == 0) |
9263
5d0a69504867
config handling fixes and improvements. Separated module/service lookups. Added support for per-lip/rip settings.
Timo Sirainen <tss@iki.fi>
parents:
9233
diff
changeset
|
75 filter.service = *args + 8; |
5d0a69504867
config handling fixes and improvements. Separated module/service lookups. Added support for per-lip/rip settings.
Timo Sirainen <tss@iki.fi>
parents:
9233
diff
changeset
|
76 else if (strncmp(*args, "module=", 7) == 0) |
5d0a69504867
config handling fixes and improvements. Separated module/service lookups. Added support for per-lip/rip settings.
Timo Sirainen <tss@iki.fi>
parents:
9233
diff
changeset
|
77 module = *args + 7; |
5d0a69504867
config handling fixes and improvements. Separated module/service lookups. Added support for per-lip/rip settings.
Timo Sirainen <tss@iki.fi>
parents:
9233
diff
changeset
|
78 else if (strncmp(*args, "lip=", 4) == 0) { |
5d0a69504867
config handling fixes and improvements. Separated module/service lookups. Added support for per-lip/rip settings.
Timo Sirainen <tss@iki.fi>
parents:
9233
diff
changeset
|
79 if (net_addr2ip(*args + 4, &filter.local_net) == 0) { |
5d0a69504867
config handling fixes and improvements. Separated module/service lookups. Added support for per-lip/rip settings.
Timo Sirainen <tss@iki.fi>
parents:
9233
diff
changeset
|
80 filter.local_bits = |
5d0a69504867
config handling fixes and improvements. Separated module/service lookups. Added support for per-lip/rip settings.
Timo Sirainen <tss@iki.fi>
parents:
9233
diff
changeset
|
81 IPADDR_IS_V4(&filter.local_net) ? |
5d0a69504867
config handling fixes and improvements. Separated module/service lookups. Added support for per-lip/rip settings.
Timo Sirainen <tss@iki.fi>
parents:
9233
diff
changeset
|
82 32 : 128; |
5d0a69504867
config handling fixes and improvements. Separated module/service lookups. Added support for per-lip/rip settings.
Timo Sirainen <tss@iki.fi>
parents:
9233
diff
changeset
|
83 } |
5d0a69504867
config handling fixes and improvements. Separated module/service lookups. Added support for per-lip/rip settings.
Timo Sirainen <tss@iki.fi>
parents:
9233
diff
changeset
|
84 } else if (strncmp(*args, "rip=", 4) == 0) { |
5d0a69504867
config handling fixes and improvements. Separated module/service lookups. Added support for per-lip/rip settings.
Timo Sirainen <tss@iki.fi>
parents:
9233
diff
changeset
|
85 if (net_addr2ip(*args + 4, &filter.remote_net) == 0) { |
5d0a69504867
config handling fixes and improvements. Separated module/service lookups. Added support for per-lip/rip settings.
Timo Sirainen <tss@iki.fi>
parents:
9233
diff
changeset
|
86 filter.remote_bits = |
5d0a69504867
config handling fixes and improvements. Separated module/service lookups. Added support for per-lip/rip settings.
Timo Sirainen <tss@iki.fi>
parents:
9233
diff
changeset
|
87 IPADDR_IS_V4(&filter.remote_net) ? |
5d0a69504867
config handling fixes and improvements. Separated module/service lookups. Added support for per-lip/rip settings.
Timo Sirainen <tss@iki.fi>
parents:
9233
diff
changeset
|
88 32 : 128; |
5d0a69504867
config handling fixes and improvements. Separated module/service lookups. Added support for per-lip/rip settings.
Timo Sirainen <tss@iki.fi>
parents:
9233
diff
changeset
|
89 } |
5d0a69504867
config handling fixes and improvements. Separated module/service lookups. Added support for per-lip/rip settings.
Timo Sirainen <tss@iki.fi>
parents:
9233
diff
changeset
|
90 } |
9181
150a98d2407c
config: service names had an extra "service=".
Timo Sirainen <tss@iki.fi>
parents:
9179
diff
changeset
|
91 } |
9087
81ff88345441
Some cleanups to the config parsing code.
Timo Sirainen <tss@iki.fi>
parents:
9013
diff
changeset
|
92 |
9793
d7ccdbb58a03
config: If master module requests configuration, reread it before replying.
Timo Sirainen <tss@iki.fi>
parents:
9349
diff
changeset
|
93 if (strcmp(module, "master") == 0) { |
d7ccdbb58a03
config: If master module requests configuration, reread it before replying.
Timo Sirainen <tss@iki.fi>
parents:
9349
diff
changeset
|
94 /* master reads configuration only when reloading settings */ |
d7ccdbb58a03
config: If master module requests configuration, reread it before replying.
Timo Sirainen <tss@iki.fi>
parents:
9349
diff
changeset
|
95 path = master_service_get_config_path(master_service); |
d7ccdbb58a03
config: If master module requests configuration, reread it before replying.
Timo Sirainen <tss@iki.fi>
parents:
9349
diff
changeset
|
96 if (config_parse_file(path, TRUE, &error) < 0) { |
d7ccdbb58a03
config: If master module requests configuration, reread it before replying.
Timo Sirainen <tss@iki.fi>
parents:
9349
diff
changeset
|
97 o_stream_send_str(conn->output, |
d7ccdbb58a03
config: If master module requests configuration, reread it before replying.
Timo Sirainen <tss@iki.fi>
parents:
9349
diff
changeset
|
98 t_strconcat("ERROR ", error, "\n", NULL)); |
d7ccdbb58a03
config: If master module requests configuration, reread it before replying.
Timo Sirainen <tss@iki.fi>
parents:
9349
diff
changeset
|
99 config_connection_destroy(conn); |
d7ccdbb58a03
config: If master module requests configuration, reread it before replying.
Timo Sirainen <tss@iki.fi>
parents:
9349
diff
changeset
|
100 return -1; |
d7ccdbb58a03
config: If master module requests configuration, reread it before replying.
Timo Sirainen <tss@iki.fi>
parents:
9349
diff
changeset
|
101 } |
d7ccdbb58a03
config: If master module requests configuration, reread it before replying.
Timo Sirainen <tss@iki.fi>
parents:
9349
diff
changeset
|
102 } |
d7ccdbb58a03
config: If master module requests configuration, reread it before replying.
Timo Sirainen <tss@iki.fi>
parents:
9349
diff
changeset
|
103 |
9087
81ff88345441
Some cleanups to the config parsing code.
Timo Sirainen <tss@iki.fi>
parents:
9013
diff
changeset
|
104 o_stream_cork(conn->output); |
9263
5d0a69504867
config handling fixes and improvements. Separated module/service lookups. Added support for per-lip/rip settings.
Timo Sirainen <tss@iki.fi>
parents:
9233
diff
changeset
|
105 config_request_handle(&filter, module, 0, config_request_output, |
5d0a69504867
config handling fixes and improvements. Separated module/service lookups. Added support for per-lip/rip settings.
Timo Sirainen <tss@iki.fi>
parents:
9233
diff
changeset
|
106 conn->output); |
9227
f155917f1615
Split doveconf and libexec/dovecot/config binaries.
Timo Sirainen <tss@iki.fi>
parents:
9181
diff
changeset
|
107 o_stream_send_str(conn->output, "\n"); |
9087
81ff88345441
Some cleanups to the config parsing code.
Timo Sirainen <tss@iki.fi>
parents:
9013
diff
changeset
|
108 o_stream_uncork(conn->output); |
9793
d7ccdbb58a03
config: If master module requests configuration, reread it before replying.
Timo Sirainen <tss@iki.fi>
parents:
9349
diff
changeset
|
109 return 0; |
9002 | 110 } |
111 | |
112 static void config_connection_input(void *context) | |
113 { | |
114 struct config_connection *conn = context; | |
115 const char *const *args, *line; | |
116 | |
117 switch (i_stream_read(conn->input)) { | |
118 case -2: | |
119 i_error("BUG: Config client connection sent too much data"); | |
120 config_connection_destroy(conn); | |
121 return; | |
122 case -1: | |
123 config_connection_destroy(conn); | |
124 return; | |
125 } | |
126 | |
127 if (!conn->version_received) { | |
128 line = i_stream_next_line(conn->input); | |
129 if (line == NULL) | |
130 return; | |
131 | |
132 if (strncmp(line, "VERSION\t", 8) != 0 || | |
133 atoi(t_strcut(line + 8, '\t')) != | |
134 CONFIG_CLIENT_PROTOCOL_MAJOR_VERSION) { | |
135 i_error("Config client not compatible with this server " | |
136 "(mixed old and new binaries?)"); | |
137 config_connection_destroy(conn); | |
138 return; | |
139 } | |
140 conn->version_received = TRUE; | |
141 } | |
142 | |
143 while ((args = config_connection_next_line(conn)) != NULL) { | |
144 if (args[0] == NULL) | |
145 continue; | |
9793
d7ccdbb58a03
config: If master module requests configuration, reread it before replying.
Timo Sirainen <tss@iki.fi>
parents:
9349
diff
changeset
|
146 if (strcmp(args[0], "REQ") == 0) { |
d7ccdbb58a03
config: If master module requests configuration, reread it before replying.
Timo Sirainen <tss@iki.fi>
parents:
9349
diff
changeset
|
147 if (config_connection_request(conn, args + 1) < 0) |
d7ccdbb58a03
config: If master module requests configuration, reread it before replying.
Timo Sirainen <tss@iki.fi>
parents:
9349
diff
changeset
|
148 break; |
d7ccdbb58a03
config: If master module requests configuration, reread it before replying.
Timo Sirainen <tss@iki.fi>
parents:
9349
diff
changeset
|
149 } |
9002 | 150 } |
151 } | |
152 | |
153 struct config_connection *config_connection_create(int fd) | |
154 { | |
155 struct config_connection *conn; | |
156 | |
157 conn = i_new(struct config_connection, 1); | |
158 conn->fd = fd; | |
159 conn->input = i_stream_create_fd(fd, MAX_INBUF_SIZE, FALSE); | |
160 conn->output = o_stream_create_fd(fd, (size_t)-1, FALSE); | |
161 conn->io = io_add(fd, IO_READ, config_connection_input, conn); | |
9159
6324a79d3ee1
Initial commit for v2.0 master rewrite. Several features are still missing.
Timo Sirainen <tss@iki.fi>
parents:
9087
diff
changeset
|
162 DLLIST_PREPEND(&config_connections, conn); |
9002 | 163 return conn; |
164 } | |
165 | |
166 void config_connection_destroy(struct config_connection *conn) | |
167 { | |
9159
6324a79d3ee1
Initial commit for v2.0 master rewrite. Several features are still missing.
Timo Sirainen <tss@iki.fi>
parents:
9087
diff
changeset
|
168 DLLIST_REMOVE(&config_connections, conn); |
6324a79d3ee1
Initial commit for v2.0 master rewrite. Several features are still missing.
Timo Sirainen <tss@iki.fi>
parents:
9087
diff
changeset
|
169 |
9002 | 170 io_remove(&conn->io); |
171 i_stream_destroy(&conn->input); | |
172 o_stream_destroy(&conn->output); | |
173 if (close(conn->fd) < 0) | |
174 i_error("close(config conn) failed: %m"); | |
175 i_free(conn); | |
9349
04cade277134
Added missing master_service_client_connection_destroyed() calls.
Timo Sirainen <tss@iki.fi>
parents:
9274
diff
changeset
|
176 |
04cade277134
Added missing master_service_client_connection_destroyed() calls.
Timo Sirainen <tss@iki.fi>
parents:
9274
diff
changeset
|
177 master_service_client_connection_destroyed(master_service); |
9002 | 178 } |
179 | |
9159
6324a79d3ee1
Initial commit for v2.0 master rewrite. Several features are still missing.
Timo Sirainen <tss@iki.fi>
parents:
9087
diff
changeset
|
180 void config_connections_destroy_all(void) |
6324a79d3ee1
Initial commit for v2.0 master rewrite. Several features are still missing.
Timo Sirainen <tss@iki.fi>
parents:
9087
diff
changeset
|
181 { |
6324a79d3ee1
Initial commit for v2.0 master rewrite. Several features are still missing.
Timo Sirainen <tss@iki.fi>
parents:
9087
diff
changeset
|
182 while (config_connections != NULL) |
6324a79d3ee1
Initial commit for v2.0 master rewrite. Several features are still missing.
Timo Sirainen <tss@iki.fi>
parents:
9087
diff
changeset
|
183 config_connection_destroy(config_connections); |
6324a79d3ee1
Initial commit for v2.0 master rewrite. Several features are still missing.
Timo Sirainen <tss@iki.fi>
parents:
9087
diff
changeset
|
184 } |