PageRenderTime 40ms CodeModel.GetById 11ms RepoModel.GetById 0ms app.codeStats 0ms

/src/plugins/relay/relay-config.c

#
C | 512 lines | 367 code | 72 blank | 73 comment | 36 complexity | f50952c0c23503b942c76d795f5da731 MD5 | raw file
Possible License(s): GPL-3.0
  1. /*
  2. * Copyright (C) 2003-2012 Sebastien Helleu <flashcode@flashtux.org>
  3. *
  4. * This file is part of WeeChat, the extensible chat client.
  5. *
  6. * WeeChat is free software; you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation; either version 3 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * WeeChat is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with WeeChat. If not, see <http://www.gnu.org/licenses/>.
  18. */
  19. /*
  20. * relay-config.c: relay configuration options (file relay.conf)
  21. */
  22. #include <stdlib.h>
  23. #include <limits.h>
  24. #include <regex.h>
  25. #include "../weechat-plugin.h"
  26. #include "relay.h"
  27. #include "relay-config.h"
  28. #include "relay-client.h"
  29. #include "relay-buffer.h"
  30. #include "relay-server.h"
  31. struct t_config_file *relay_config_file = NULL;
  32. struct t_config_section *relay_config_section_port = NULL;
  33. /* relay config, look section */
  34. struct t_config_option *relay_config_look_auto_open_buffer;
  35. struct t_config_option *relay_config_look_raw_messages;
  36. /* relay config, color section */
  37. struct t_config_option *relay_config_color_text;
  38. struct t_config_option *relay_config_color_text_bg;
  39. struct t_config_option *relay_config_color_text_selected;
  40. struct t_config_option *relay_config_color_status[RELAY_NUM_STATUS];
  41. /* relay config, network section */
  42. struct t_config_option *relay_config_network_allowed_ips;
  43. struct t_config_option *relay_config_network_bind_address;
  44. struct t_config_option *relay_config_network_compression_level;
  45. struct t_config_option *relay_config_network_max_clients;
  46. struct t_config_option *relay_config_network_password;
  47. /* other */
  48. regex_t *relay_config_regex_allowed_ips = NULL;
  49. /*
  50. * relay_config_refresh_cb: callback called when user changes relay option that
  51. * needs a refresh of relay list
  52. */
  53. void
  54. relay_config_refresh_cb (void *data, struct t_config_option *option)
  55. {
  56. /* make C compiler happy */
  57. (void) data;
  58. (void) option;
  59. if (relay_buffer)
  60. relay_buffer_refresh (NULL);
  61. }
  62. /*
  63. * relay_config_change_network_allowed_ips: called when allowed ips changes
  64. */
  65. void
  66. relay_config_change_network_allowed_ips (void *data,
  67. struct t_config_option *option)
  68. {
  69. const char *allowed_ips;
  70. /* make C compiler happy */
  71. (void) data;
  72. (void) option;
  73. if (relay_config_regex_allowed_ips)
  74. {
  75. regfree (relay_config_regex_allowed_ips);
  76. free (relay_config_regex_allowed_ips);
  77. relay_config_regex_allowed_ips = NULL;
  78. }
  79. allowed_ips = weechat_config_string (relay_config_network_allowed_ips);
  80. if (allowed_ips && allowed_ips[0])
  81. {
  82. relay_config_regex_allowed_ips = malloc (sizeof (*relay_config_regex_allowed_ips));
  83. if (relay_config_regex_allowed_ips)
  84. {
  85. if (weechat_string_regcomp (relay_config_regex_allowed_ips,
  86. allowed_ips,
  87. REG_EXTENDED | REG_ICASE) != 0)
  88. {
  89. free (relay_config_regex_allowed_ips);
  90. relay_config_regex_allowed_ips = NULL;
  91. }
  92. }
  93. }
  94. }
  95. /*
  96. * relay_config_change_network_bind_address_cb: callback called when user changes
  97. * network bind address option
  98. */
  99. void
  100. relay_config_change_network_bind_address_cb (void *data,
  101. struct t_config_option *option)
  102. {
  103. struct t_relay_server *ptr_server;
  104. /* make C compiler happy */
  105. (void) data;
  106. (void) option;
  107. for (ptr_server = relay_servers; ptr_server;
  108. ptr_server = ptr_server->next_server)
  109. {
  110. relay_server_close_socket (ptr_server);
  111. relay_server_create_socket (ptr_server);
  112. }
  113. }
  114. /*
  115. * relay_config_change_port_cb: callback called when relay port option is
  116. * modified
  117. */
  118. int
  119. relay_config_check_port_cb (void *data, struct t_config_option *option,
  120. const char *value)
  121. {
  122. char *error;
  123. long port;
  124. struct t_relay_server *ptr_server;
  125. /* make C compiler happy */
  126. (void) data;
  127. (void) option;
  128. error = NULL;
  129. port = strtol (value, &error, 10);
  130. ptr_server = relay_server_search_port ((int)port);
  131. if (ptr_server)
  132. {
  133. weechat_printf (NULL, _("%s%s: error: port \"%d\" is already used"),
  134. weechat_prefix ("error"),
  135. RELAY_PLUGIN_NAME, (int)port);
  136. return 0;
  137. }
  138. return 1;
  139. }
  140. /*
  141. * relay_config_change_port_cb: callback called when relay port option is
  142. * modified
  143. */
  144. void
  145. relay_config_change_port_cb (void *data, struct t_config_option *option)
  146. {
  147. struct t_relay_server *ptr_server;
  148. /* make C compiler happy */
  149. (void) data;
  150. ptr_server = relay_server_search (weechat_config_option_get_pointer (option, "name"));
  151. if (ptr_server)
  152. {
  153. relay_server_update_port (ptr_server,
  154. *((int *)weechat_config_option_get_pointer (option, "value")));
  155. }
  156. }
  157. /*
  158. * relay_config_delete_port_cb: callback called when relay port option is
  159. * deleted
  160. */
  161. void
  162. relay_config_delete_port_cb (void *data, struct t_config_option *option)
  163. {
  164. struct t_relay_server *ptr_server;
  165. /* make C compiler happy */
  166. (void) data;
  167. ptr_server = relay_server_search (weechat_config_option_get_pointer (option, "name"));
  168. if (ptr_server)
  169. relay_server_free (ptr_server);
  170. }
  171. /*
  172. * relay_config_create_option_port: create a relay for a port
  173. */
  174. int
  175. relay_config_create_option_port (void *data,
  176. struct t_config_file *config_file,
  177. struct t_config_section *section,
  178. const char *option_name,
  179. const char *value)
  180. {
  181. int rc, protocol_number;
  182. char *error, *protocol, *protocol_args;
  183. long port;
  184. struct t_relay_server *ptr_server;
  185. /* make C compiler happy */
  186. (void) data;
  187. rc = WEECHAT_CONFIG_OPTION_SET_OK_SAME_VALUE;
  188. relay_server_get_protocol_args (option_name,
  189. &protocol, &protocol_args);
  190. protocol_number = -1;
  191. port = -1;
  192. if (protocol)
  193. protocol_number = relay_protocol_search (protocol);
  194. if (protocol_number < 0)
  195. {
  196. weechat_printf (NULL, _("%s%s: error: unknown protocol \"%s\""),
  197. weechat_prefix ("error"),
  198. RELAY_PLUGIN_NAME, protocol);
  199. rc = WEECHAT_CONFIG_OPTION_SET_ERROR;
  200. }
  201. if ((protocol_number == RELAY_PROTOCOL_WEECHAT) && protocol_args)
  202. {
  203. weechat_printf (NULL, _("%s%s: error: name is not allowed for protocol "
  204. "\"%s\""),
  205. weechat_prefix ("error"),
  206. RELAY_PLUGIN_NAME, protocol);
  207. rc = WEECHAT_CONFIG_OPTION_SET_ERROR;
  208. }
  209. else if ((protocol_number == RELAY_PROTOCOL_IRC) && !protocol_args)
  210. {
  211. weechat_printf (NULL, _("%s%s: error: name is not required for protocol "
  212. "\"%s\""),
  213. weechat_prefix ("error"),
  214. RELAY_PLUGIN_NAME, protocol);
  215. rc = WEECHAT_CONFIG_OPTION_SET_ERROR;
  216. }
  217. if (rc != WEECHAT_CONFIG_OPTION_SET_ERROR)
  218. {
  219. if (weechat_config_search_option (config_file, section, option_name))
  220. {
  221. weechat_printf (NULL, _("%s%s: error: relay for \"%s\" already exists"),
  222. weechat_prefix ("error"),
  223. RELAY_PLUGIN_NAME, option_name);
  224. rc = WEECHAT_CONFIG_OPTION_SET_ERROR;
  225. }
  226. }
  227. if (rc != WEECHAT_CONFIG_OPTION_SET_ERROR)
  228. {
  229. error = NULL;
  230. port = strtol (value, &error, 10);
  231. ptr_server = relay_server_search_port ((int)port);
  232. if (ptr_server)
  233. {
  234. weechat_printf (NULL, _("%s%s: error: port \"%d\" is already used"),
  235. weechat_prefix ("error"),
  236. RELAY_PLUGIN_NAME, (int)port);
  237. rc = WEECHAT_CONFIG_OPTION_SET_ERROR;
  238. }
  239. }
  240. if (rc != WEECHAT_CONFIG_OPTION_SET_ERROR)
  241. {
  242. if (relay_server_new (protocol_number, protocol_args, port))
  243. {
  244. /* create config option */
  245. weechat_config_new_option (
  246. config_file, section,
  247. option_name, "integer", NULL,
  248. NULL, 0, 65535, "", value, 0,
  249. &relay_config_check_port_cb, NULL,
  250. &relay_config_change_port_cb, NULL,
  251. &relay_config_delete_port_cb, NULL);
  252. rc = WEECHAT_CONFIG_OPTION_SET_OK_SAME_VALUE;
  253. }
  254. else
  255. rc = WEECHAT_CONFIG_OPTION_SET_ERROR;
  256. }
  257. if (protocol)
  258. free (protocol);
  259. if (protocol_args)
  260. free (protocol_args);
  261. return rc;
  262. }
  263. /*
  264. * relay_config_reload: reload relay configuration file
  265. */
  266. int
  267. relay_config_reload (void *data, struct t_config_file *config_file)
  268. {
  269. /* make C compiler happy */
  270. (void) data;
  271. return weechat_config_reload (config_file);
  272. }
  273. /*
  274. * relay_config_init: init relay configuration file
  275. * return: 1 if ok, 0 if error
  276. */
  277. int
  278. relay_config_init ()
  279. {
  280. struct t_config_section *ptr_section;
  281. relay_config_file = weechat_config_new (RELAY_CONFIG_NAME,
  282. &relay_config_reload, NULL);
  283. if (!relay_config_file)
  284. return 0;
  285. ptr_section = weechat_config_new_section (relay_config_file, "look",
  286. 0, 0,
  287. NULL, NULL, NULL, NULL,
  288. NULL, NULL, NULL, NULL,
  289. NULL, NULL);
  290. if (!ptr_section)
  291. {
  292. weechat_config_free (relay_config_file);
  293. return 0;
  294. }
  295. relay_config_look_auto_open_buffer = weechat_config_new_option (
  296. relay_config_file, ptr_section,
  297. "auto_open_buffer", "boolean",
  298. N_("auto open relay buffer when a new client is connecting"),
  299. NULL, 0, 0, "on", NULL, 0, NULL, NULL, NULL, NULL, NULL, NULL);
  300. relay_config_look_raw_messages = weechat_config_new_option (
  301. relay_config_file, ptr_section,
  302. "raw_messages", "integer",
  303. N_("number of raw messages to save in memory when raw data buffer is "
  304. "closed (messages will be displayed when opening raw data buffer)"),
  305. NULL, 0, 65535, "256", NULL, 0, NULL, NULL, NULL, NULL, NULL, NULL);
  306. ptr_section = weechat_config_new_section (relay_config_file, "color",
  307. 0, 0,
  308. NULL, NULL, NULL, NULL,
  309. NULL, NULL, NULL, NULL,
  310. NULL, NULL);
  311. if (!ptr_section)
  312. {
  313. weechat_config_free (relay_config_file);
  314. return 0;
  315. }
  316. relay_config_color_text = weechat_config_new_option (
  317. relay_config_file, ptr_section,
  318. "text", "color",
  319. N_("text color"),
  320. NULL, 0, 0, "default", NULL, 0,
  321. NULL, NULL, &relay_config_refresh_cb, NULL, NULL, NULL);
  322. relay_config_color_text_bg = weechat_config_new_option (
  323. relay_config_file, ptr_section,
  324. "text_bg", "color",
  325. N_("background color"),
  326. NULL, 0, 0, "default", NULL, 0,
  327. NULL, NULL, &relay_config_refresh_cb, NULL, NULL, NULL);
  328. relay_config_color_text_selected = weechat_config_new_option (
  329. relay_config_file, ptr_section,
  330. "text_selected", "color",
  331. N_("text color of selected client line"),
  332. NULL, 0, 0, "white", NULL, 0,
  333. NULL, NULL, &relay_config_refresh_cb, NULL, NULL, NULL);
  334. relay_config_color_status[RELAY_STATUS_CONNECTING] = weechat_config_new_option (
  335. relay_config_file, ptr_section,
  336. "status_connecting", "color",
  337. N_("text color for \"connecting\" status"),
  338. NULL, 0, 0, "yellow", NULL, 0,
  339. NULL, NULL, &relay_config_refresh_cb, NULL, NULL, NULL);
  340. relay_config_color_status[RELAY_STATUS_WAITING_AUTH] = weechat_config_new_option (
  341. relay_config_file, ptr_section,
  342. "status_waiting_auth", "color",
  343. N_("text color for \"waiting authentication\" status"),
  344. NULL, 0, 0, "brown", NULL, 0,
  345. NULL, NULL, &relay_config_refresh_cb, NULL, NULL, NULL);
  346. relay_config_color_status[RELAY_STATUS_CONNECTED] = weechat_config_new_option (
  347. relay_config_file, ptr_section,
  348. "status_active", "color",
  349. N_("text color for \"connected\" status"),
  350. NULL, 0, 0, "lightblue", NULL, 0,
  351. NULL, NULL, &relay_config_refresh_cb, NULL, NULL, NULL);
  352. relay_config_color_status[RELAY_STATUS_AUTH_FAILED] = weechat_config_new_option (
  353. relay_config_file, ptr_section,
  354. "status_auth_failed", "color",
  355. N_("text color for \"authentication failed\" status"),
  356. NULL, 0, 0, "lightred", NULL, 0,
  357. NULL, NULL, &relay_config_refresh_cb, NULL, NULL, NULL);
  358. relay_config_color_status[RELAY_STATUS_DISCONNECTED] = weechat_config_new_option (
  359. relay_config_file, ptr_section,
  360. "status_disconnected", "color",
  361. N_("text color for \"disconnected\" status"),
  362. NULL, 0, 0, "lightred", NULL, 0,
  363. NULL, NULL, &relay_config_refresh_cb, NULL, NULL, NULL);
  364. ptr_section = weechat_config_new_section (relay_config_file, "network",
  365. 0, 0,
  366. NULL, NULL, NULL, NULL,
  367. NULL, NULL, NULL, NULL,
  368. NULL, NULL);
  369. if (!ptr_section)
  370. {
  371. weechat_config_free (relay_config_file);
  372. return 0;
  373. }
  374. relay_config_network_allowed_ips = weechat_config_new_option (
  375. relay_config_file, ptr_section,
  376. "allowed_ips", "string",
  377. N_("regular expression with IPs allowed to use relay (case insensitive, "
  378. "use \"(?-i)\" at beginning to make it case sensitive), example: "
  379. "\"^(123.45.67.89|192.160.*)$\""),
  380. NULL, 0, 0, "", NULL, 0, NULL, NULL,
  381. &relay_config_change_network_allowed_ips, NULL, NULL, NULL);
  382. relay_config_network_bind_address = weechat_config_new_option (
  383. relay_config_file, ptr_section,
  384. "bind_address", "string",
  385. N_("address for bind (if empty, connection is possible on all "
  386. "interfaces, use \"127.0.0.1\" to allow connections from "
  387. "local machine only)"),
  388. NULL, 0, 0, "", NULL, 0, NULL, NULL,
  389. &relay_config_change_network_bind_address_cb, NULL, NULL, NULL);
  390. relay_config_network_compression_level = weechat_config_new_option (
  391. relay_config_file, ptr_section,
  392. "compression_level", "integer",
  393. N_("compression level for packets sent to client with WeeChat protocol "
  394. "(0 = disable compression, 1 = low compression ... 9 = best "
  395. "compression)"),
  396. NULL, 0, 9, "6", NULL, 0,
  397. NULL, NULL, NULL, NULL, NULL, NULL);
  398. relay_config_network_max_clients = weechat_config_new_option (
  399. relay_config_file, ptr_section,
  400. "max_clients", "integer",
  401. N_("maximum number of clients connecting to a port"),
  402. NULL, 1, 1024, "5", NULL, 0,
  403. NULL, NULL, NULL, NULL, NULL, NULL);
  404. relay_config_network_password = weechat_config_new_option (
  405. relay_config_file, ptr_section,
  406. "password", "string",
  407. N_("password required by clients to access this relay (empty value "
  408. "means no password required)"),
  409. NULL, 0, 0, "", NULL, 0, NULL, NULL, NULL, NULL, NULL, NULL);
  410. ptr_section = weechat_config_new_section (relay_config_file, "port",
  411. 1, 1,
  412. NULL, NULL,
  413. NULL, NULL,
  414. NULL, NULL,
  415. &relay_config_create_option_port, NULL,
  416. NULL, NULL);
  417. if (!ptr_section)
  418. {
  419. weechat_config_free (relay_config_file);
  420. return 0;
  421. }
  422. relay_config_section_port = ptr_section;
  423. return 1;
  424. }
  425. /*
  426. * relay_config_read: read relay configuration file
  427. */
  428. int
  429. relay_config_read ()
  430. {
  431. return weechat_config_read (relay_config_file);
  432. }
  433. /*
  434. * relay_config_write: write relay configuration file
  435. */
  436. int
  437. relay_config_write ()
  438. {
  439. return weechat_config_write (relay_config_file);
  440. }