1 /*
2 * vars.c: All the dealing of the irc variables are handled here.
3 *
4 * Written By Michael Sandrof
5 *
6 * Copyright (c) 1990 Michael Sandrof.
7 * Copyright (c) 1991, 1992 Troy Rollo.
8 * Copyright (c) 1992-2017 Matthew R. Green.
9 * All rights reserved.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
19 * 3. The name of the author may not be used to endorse or promote products
20 * derived from this software without specific prior written permission.
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
23 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
24 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
25 * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
27 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
29 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
30 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 * SUCH DAMAGE.
33 */
34
35 #include "irc.h"
36 IRCII_RCSID("@(#)$eterna: vars.c,v 1.108 2019/01/16 06:27:37 mrg Exp $");
37
38 #include "status.h"
39 #include "window.h"
40 #include "lastlog.h"
41 #include "log.h"
42 #include "irccrypt.h"
43 #include "history.h"
44 #include "notify.h"
45 #include "vars.h"
46 #include "input.h"
47 #include "ircaux.h"
48 #include "whois.h"
49 #include "ircterm.h"
50 #include "translat.h"
51 #include "output.h"
52 #include "server.h"
53 #include "dcc.h"
54 #include "ssl.h"
55
56 #define VF_NODAEMON 0x0001
57 #define VF_EXPAND_PATH 0x0002
58
59 #define VIF_CHANGED 0x01
60 #define VIF_GLOBAL 0x02
61
62 /* the types of IrcVariables */
63 #define BOOL_TYPE_VAR 0
64 #define CHAR_TYPE_VAR 1
65 #define INT_TYPE_VAR 2
66 #define STR_TYPE_VAR 3
67
68 static void check_variable_order(void);
69 static int find_variable(u_char *, int *);
70 static void exec_warning(int);
71 static void input_warning(int);
72 static void eight_bit_characters(int);
73 static void v_update_all_status(int);
74
75 /* IrcVariable: structure for each variable in the variable table */
76 typedef struct
77 {
78 char *name; /* what the user types */
79 int type; /* variable types, see below */
80 int integer; /* int value of variable */
81 u_char *string; /* string value of variable */
82 /* function to call every time variable is set */
83 void (*ifunc)(int);
84 void (*sfunc)(u_char *);
85 unsigned short int_flags; /* internal flags to the variable */
86 unsigned short flags; /* flags for this variable */
87 } IrcVariable;
88
89 /*
90 * irc_variable: all the irc variables used. Note that the integer and
91 * boolean defaults are set here, which the string default value are set in
92 * the init_variables() procedure.
93 *
94 * this structure needs to be in alphabetical order, and the
95 * check_variable_order() procedure will assert that it is from
96 * init_variables()
97 */
98 static IrcVariable irc_variable[] =
99 {
100 { "ALWAYS_SPLIT_BIGGEST", BOOL_TYPE_VAR, DEFAULT_ALWAYS_SPLIT_BIGGEST, NULL, 0, NULL, 0, 0 },
101 { "AUTO_UNMARK_AWAY", BOOL_TYPE_VAR, DEFAULT_AUTO_UNMARK_AWAY, NULL, 0, NULL, 0, 0 },
102 { "AUTO_WHOWAS", BOOL_TYPE_VAR, DEFAULT_AUTO_WHOWAS, NULL, 0, NULL, 0, 0 },
103 { "BACKGROUND_COLOUR", INT_TYPE_VAR, DEFAULT_BACKGROUND_COLOUR, NULL, 0, NULL, 0, 0 },
104 { "BEEP", BOOL_TYPE_VAR, DEFAULT_BEEP, NULL, 0, NULL, 0, 0 },
105 { "BEEP_MAX", INT_TYPE_VAR, DEFAULT_BEEP_MAX, NULL, 0, NULL, 0, 0 },
106 { "BEEP_ON_MSG", STR_TYPE_VAR, 0, NULL, 0, set_beep_on_msg, 0, 0 },
107 { "BEEP_WHEN_AWAY", INT_TYPE_VAR, DEFAULT_BEEP_WHEN_AWAY, NULL, 0, NULL, 0, 0 },
108 { "BIND_LOCAL_DCCHOST", BOOL_TYPE_VAR, DEFAULT_BIND_LOCAL_DCCHOST, NULL, 0, NULL, 0, 0 },
109 { "BOLD_VIDEO", BOOL_TYPE_VAR, DEFAULT_BOLD_VIDEO, NULL, 0, NULL, 0, 0 },
110 { "CHANNEL_NAME_WIDTH", INT_TYPE_VAR, DEFAULT_CHANNEL_NAME_WIDTH, NULL, v_update_all_status, 0, 0, 0 },
111 { "CLIENT_INFORMATION", STR_TYPE_VAR, 0, NULL, 0, NULL, 0, 0 },
112 { "CLOCK", BOOL_TYPE_VAR, DEFAULT_CLOCK, NULL, v_update_all_status, 0, 0, 0 },
113 { "CLOCK_24HOUR", BOOL_TYPE_VAR, DEFAULT_CLOCK_24HOUR, NULL, reset_clock, 0, 0, 0 },
114 { "CLOCK_ALARM", STR_TYPE_VAR, 0, NULL, 0, set_alarm, 0, 0 },
115 { "CMDCHARS", STR_TYPE_VAR, 0, NULL, 0, NULL, 0, 0 },
116 { "COLOUR", BOOL_TYPE_VAR, DEFAULT_COLOUR, NULL, 0, NULL, 0, 0 },
117 { "COMMAND_MODE", BOOL_TYPE_VAR, DEFAULT_COMMAND_MODE, NULL, 0, NULL, 0, 0 },
118 { "CONTINUED_LINE", STR_TYPE_VAR, 0, NULL, 0, set_continued_line, 0, 0 },
119 { "CTCP_REPLY_BACKLOG_SECONDS", INT_TYPE_VAR, DEFAULT_CTCP_REPLY_BACKLOG_SECONDS, NULL, ctcp_reply_backlog_change, 0, 0, 0 },
120 { "CTCP_REPLY_FLOOD_SIZE", INT_TYPE_VAR, DEFAULT_CTCP_REPLY_FLOOD_SIZE_VAR, NULL, 0, NULL, 0, 0 },
121 { "CTCP_REPLY_IGNORE_SECONDS", INT_TYPE_VAR, DEFAULT_CTCP_REPLY_IGNORE_SECONDS, NULL, 0, NULL, 0, 0 },
122 { "DCCHOST", STR_TYPE_VAR, 0, NULL, 0, set_dcchost, 0, 0 },
123 { "DCCPORT", INT_TYPE_VAR, DEFAULT_DCCPORT, NULL, 0, NULL, 0, 0 },
124 { "DCC_BLOCK_SIZE", INT_TYPE_VAR, DEFAULT_DCC_BLOCK_SIZE, NULL, 0, NULL, 0, 0 },
125 { "DEBUG", INT_TYPE_VAR, 0, NULL, 0, NULL, 0, 0 },
126 { "DECRYPT_PROGRAM", STR_TYPE_VAR, 0, NULL, 0, NULL, 0, VF_NODAEMON },
127 { "DISPLAY", BOOL_TYPE_VAR, DEFAULT_DISPLAY, NULL, 0, NULL, 0, 0 },
128 { "DISPLAY_ENCODING", STR_TYPE_VAR, 0, NULL, 0, set_display_encoding, 0, 0 },
129 { "EIGHT_BIT_CHARACTERS", BOOL_TYPE_VAR, DEFAULT_EIGHT_BIT_CHARACTERS, NULL, eight_bit_characters, 0, 0, 0 },
130 { "ENCRYPT_PROGRAM", STR_TYPE_VAR, 0, NULL, 0, NULL, 0, VF_NODAEMON },
131 { "EXEC_PROTECTION", BOOL_TYPE_VAR, DEFAULT_EXEC_PROTECTION, NULL, exec_warning, 0, 0, VF_NODAEMON },
132 { "FLOOD_AFTER", INT_TYPE_VAR, DEFAULT_FLOOD_AFTER, NULL, 0, NULL, 0, 0 },
133 { "FLOOD_RATE", INT_TYPE_VAR, DEFAULT_FLOOD_RATE, NULL, 0, NULL, 0, 0 },
134 { "FLOOD_USERS", INT_TYPE_VAR, DEFAULT_FLOOD_USERS, NULL, 0, NULL, 0, 0 },
135 { "FLOOD_WARNING", BOOL_TYPE_VAR, DEFAULT_FLOOD_WARNING, NULL, 0, NULL, 0, 0 },
136 { "FOREGROUND_COLOUR", INT_TYPE_VAR, DEFAULT_FOREGROUND_COLOUR, NULL, 0, NULL, 0, 0 },
137 { "FULL_STATUS_LINE", BOOL_TYPE_VAR, DEFAULT_FULL_STATUS_LINE, NULL, v_update_all_status, 0, 0, 0 },
138 { "HELP_PAGER", BOOL_TYPE_VAR, DEFAULT_HELP_PAGER, NULL, 0, NULL, 0, 0 },
139 { "HELP_PATH", STR_TYPE_VAR, 0, NULL, 0, NULL, 0, VF_EXPAND_PATH|VF_NODAEMON },
140 { "HELP_PROMPT", BOOL_TYPE_VAR, DEFAULT_HELP_PROMPT, NULL, 0, NULL, 0, 0 },
141 { "HELP_WINDOW", BOOL_TYPE_VAR, DEFAULT_HELP_WINDOW, NULL, 0, NULL, 0, 0 },
142 { "HIDE_CHANNEL_KEYS", BOOL_TYPE_VAR, DEFAULT_HIDE_CHANNEL_KEYS, NULL, v_update_all_status, 0, 0, 0 },
143 { "HIDE_PRIVATE_CHANNELS", BOOL_TYPE_VAR, DEFAULT_HIDE_PRIVATE_CHANNELS, NULL, v_update_all_status, 0, 0, 0 },
144 { "HIGHLIGHT_CHAR", STR_TYPE_VAR, 0, NULL, 0, set_highlight_char, 0, 0 },
145 { "HISTORY", INT_TYPE_VAR, DEFAULT_HISTORY, NULL, set_history_size, 0, 0, VF_NODAEMON },
146 { "HISTORY_FILE", STR_TYPE_VAR, 0, NULL, 0, set_history_file, 0, 0 },
147 { "HOLD_MODE", BOOL_TYPE_VAR, DEFAULT_HOLD_MODE, NULL, reset_line_cnt, 0, 0, 0 },
148 { "HOLD_MODE_MAX", INT_TYPE_VAR, DEFAULT_HOLD_MODE_MAX, NULL, 0, NULL, 0, 0 },
149 { "INDENT", BOOL_TYPE_VAR, DEFAULT_INDENT, NULL, 0, NULL, 0, 0 },
150 { "INPUT_ALIASES", BOOL_TYPE_VAR, DEFAULT_INPUT_ALIASES, NULL, 0, NULL, 0, 0 },
151 { "INPUT_ENCODING", STR_TYPE_VAR, 0, NULL, 0, set_input_encoding, 0, 0 },
152 { "INPUT_PROMPT", STR_TYPE_VAR, 0, NULL, 0, set_input_prompt, 0, 0 },
153 { "INPUT_PROTECTION", BOOL_TYPE_VAR, DEFAULT_INPUT_PROTECTION, NULL, input_warning, 0, 0, 0 },
154 { "INSERT_MODE", BOOL_TYPE_VAR, DEFAULT_INSERT_MODE, NULL, v_update_all_status, 0, 0, 0 },
155 { "INVERSE_VIDEO", BOOL_TYPE_VAR, DEFAULT_INVERSE_VIDEO, NULL, 0, NULL, 0, 0 },
156 { "IRCHOST", STR_TYPE_VAR, 0, NULL, 0, set_irchost, 0, 0 },
157 { "IRC_ENCODING", STR_TYPE_VAR, 0, NULL, 0, set_irc_encoding, 0, 0 },
158 { "LASTLOG", INT_TYPE_VAR, DEFAULT_LASTLOG, NULL, set_lastlog_size, 0, 0, 0 },
159 { "LASTLOG_LEVEL", STR_TYPE_VAR, 0, NULL, 0, set_lastlog_level, 0, 0 },
160 { "LOAD_PATH", STR_TYPE_VAR, 0, NULL, 0, NULL, 0, VF_NODAEMON },
161 { "LOG", BOOL_TYPE_VAR, DEFAULT_LOG, NULL, logger, 0, 0, 0 },
162 { "LOGFILE", STR_TYPE_VAR, 0, NULL, 0, set_log_file, 0, VF_NODAEMON },
163 { "MAIL", INT_TYPE_VAR, DEFAULT_MAIL, NULL, v_update_all_status, 0, 0, VF_NODAEMON },
164 { "MAKE_NOTICE_MSG", BOOL_TYPE_VAR, DEFAULT_MAKE_NOTICE_MSG, NULL, 0, NULL, 0, 0},
165 { "MAX_RECURSIONS", INT_TYPE_VAR, DEFAULT_MAX_RECURSIONS, NULL, 0, NULL, 0, 0 },
166 { "MENU", STR_TYPE_VAR, 0, NULL, 0, set_menu, 0, 0 },
167 { "MINIMUM_SERVERS", INT_TYPE_VAR, DEFAULT_MINIMUM_SERVERS, NULL, 0, NULL, 0, VF_NODAEMON },
168 { "MINIMUM_USERS", INT_TYPE_VAR, DEFAULT_MINIMUM_USERS, NULL, 0, NULL, 0, VF_NODAEMON },
169 { "NOTIFY_HANDLER", STR_TYPE_VAR, 0, NULL, 0, set_notify_handler, 0, 0 },
170 { "NOTIFY_LEVEL", STR_TYPE_VAR, 0, NULL, 0, set_notify_level, 0, 0 },
171 { "NOTIFY_ON_TERMINATION", BOOL_TYPE_VAR, DEFAULT_NOTIFY_ON_TERMINATION, NULL, 0, NULL, 0, VF_NODAEMON },
172 { "NOVICE", BOOL_TYPE_VAR, DEFAULT_NOVICE, NULL, 0, NULL, 0, 0 },
173 { "NO_ASK_NICKNAME", BOOL_TYPE_VAR, DEFAULT_NO_ASK_NICKNAME, NULL, 0, NULL, 0, 0 },
174 { "NO_CTCP_FLOOD", BOOL_TYPE_VAR, DEFAULT_NO_CTCP_FLOOD, NULL, 0, NULL, 0, 0 },
175 { "OLD_ENCRYPT_PROGRAM", BOOL_TYPE_VAR, 0, NULL, 0, NULL, 0, VF_NODAEMON },
176 { "REALNAME", STR_TYPE_VAR, 0, NULL, 0, set_realname, 0, VF_NODAEMON },
177 { "SAME_WINDOW_ONLY", BOOL_TYPE_VAR, DEFAULT_SAME_WINDOW_ONLY, NULL, 0, NULL, 0, 0 },
178 { "SCREEN_OPTIONS", STR_TYPE_VAR, 0, NULL, 0, NULL, 0, VF_NODAEMON },
179 { "SCROLL", BOOL_TYPE_VAR, DEFAULT_SCROLL, NULL, set_scroll, 0, 0, 0 },
180 { "SCROLL_LINES", INT_TYPE_VAR, DEFAULT_SCROLL_LINES, NULL, set_scroll_lines, 0, 0, 0 },
181 { "SEND_IGNORE_MSG", BOOL_TYPE_VAR, DEFAULT_SEND_IGNORE_MSG, NULL, 0, NULL, 0, 0 },
182 { "SHELL", STR_TYPE_VAR, 0, NULL, 0, NULL, 0, VF_NODAEMON },
183 { "SHELL_FLAGS", STR_TYPE_VAR, 0, NULL, 0, NULL, 0, VF_NODAEMON },
184 { "SHELL_LIMIT", INT_TYPE_VAR, DEFAULT_SHELL_LIMIT, NULL, 0, NULL, 0, VF_NODAEMON },
185 { "SHOW_AWAY_ONCE", BOOL_TYPE_VAR, DEFAULT_SHOW_AWAY_ONCE, NULL, 0, NULL, 0, 0 },
186 { "SHOW_CHANNEL_NAMES", BOOL_TYPE_VAR, DEFAULT_SHOW_CHANNEL_NAMES, NULL, 0, NULL, 0, 0 },
187 { "SHOW_END_OF_MSGS", BOOL_TYPE_VAR, DEFAULT_SHOW_END_OF_MSGS, NULL, 0, NULL, 0, 0 },
188 { "SHOW_NUMERICS", BOOL_TYPE_VAR, DEFAULT_SHOW_NUMERICS, NULL, 0, NULL, 0, 0 },
189 { "SHOW_STARS", BOOL_TYPE_VAR, 1, NULL, 0, NULL, 0, 0 },
190 { "SHOW_STATUS_ALL", BOOL_TYPE_VAR, DEFAULT_SHOW_STATUS_ALL, NULL, v_update_all_status, 0, 0, 0 },
191 { "SHOW_WHO_HOPCOUNT", BOOL_TYPE_VAR, DEFAULT_SHOW_WHO_HOPCOUNT, NULL, 0, NULL, 0, 0 },
192 { "SSL_CA_CHAIN_FILE", STR_TYPE_VAR, 0, NULL, 0, ssl_setup_certs, 0, VF_NODAEMON },
193 { "SSL_CA_FILE", STR_TYPE_VAR, 0, NULL, 0, ssl_setup_certs, 0, VF_NODAEMON },
194 { "SSL_CA_PATH", STR_TYPE_VAR, 0, NULL, 0, ssl_setup_certs, 0, VF_NODAEMON },
195 { "SSL_CA_PRIVATE_KEY_FILE", STR_TYPE_VAR, 0, NULL, 0, ssl_setup_certs, 0, VF_NODAEMON },
196 { "STAR_PREFIX", STR_TYPE_VAR, 0, NULL, 0, NULL, 0, 0 },
197 { "STATUS_AWAY", STR_TYPE_VAR, 0, NULL, 0, build_status, 0, 0 },
198 { "STATUS_CHANNEL", STR_TYPE_VAR, 0, NULL, 0, build_status, 0, 0 },
199 { "STATUS_CHANOP", STR_TYPE_VAR, 0, NULL, 0, build_status, 0, 0 },
200 { "STATUS_CLOCK", STR_TYPE_VAR, 0, NULL, 0, build_status, 0, 0 },
201 { "STATUS_FORMAT", STR_TYPE_VAR, 0, NULL, 0, build_status, 0, 0 },
202 { "STATUS_FORMAT1", STR_TYPE_VAR, 0, NULL, 0, build_status, 0, 0 },
203 { "STATUS_FORMAT2", STR_TYPE_VAR, 0, NULL, 0, build_status, 0, 0 },
204 { "STATUS_GROUP", STR_TYPE_VAR, 0, NULL, 0, build_status, 0, 0 },
205 { "STATUS_HOLD", STR_TYPE_VAR, 0, NULL, 0, build_status, 0, 0 },
206 { "STATUS_HOLD_LINES", STR_TYPE_VAR, 0, NULL, 0, build_status, 0, 0 },
207 { "STATUS_INSERT", STR_TYPE_VAR, 0, NULL, 0, build_status, 0, 0 },
208 { "STATUS_MAIL", STR_TYPE_VAR, 0, NULL, 0, build_status, 0, VF_NODAEMON },
209 { "STATUS_MODE", STR_TYPE_VAR, 0, NULL, 0, build_status, 0, 0 },
210 { "STATUS_NOTIFY", STR_TYPE_VAR, 0, NULL, 0, build_status, 0, 0 },
211 { "STATUS_OPER", STR_TYPE_VAR, 0, NULL, 0, build_status, 0, 0 },
212 { "STATUS_OVERWRITE", STR_TYPE_VAR, 0, NULL, 0, build_status, 0, 0 },
213 { "STATUS_QUERY", STR_TYPE_VAR, 0, NULL, 0, build_status, 0, 0 },
214 { "STATUS_SCROLLED", STR_TYPE_VAR, 0, NULL, 0, build_status, 0, 0 },
215 { "STATUS_SCROLLED_LINES", STR_TYPE_VAR, 0, NULL, 0, build_status, 0, 0 },
216 { "STATUS_SERVER", STR_TYPE_VAR, 0, NULL, 0, build_status, 0, 0 },
217 { "STATUS_UMODE", STR_TYPE_VAR, 0, NULL, 0, build_status, 0, 0 },
218 { "STATUS_USER", STR_TYPE_VAR, 0, NULL, 0, build_status, 0, 0 },
219 { "STATUS_USER1", STR_TYPE_VAR, 0, NULL, 0, build_status, 0, 0 },
220 { "STATUS_USER2", STR_TYPE_VAR, 0, NULL, 0, build_status, 0, 0 },
221 { "STATUS_USER3", STR_TYPE_VAR, 0, NULL, 0, build_status, 0, 0 },
222 { "STATUS_VOICE", STR_TYPE_VAR, 0, NULL, 0, build_status, 0, 0 },
223 { "STATUS_WINDOW", STR_TYPE_VAR, 0, NULL, 0, build_status, 0, 0 },
224 { "SUPPRESS_SERVER_MOTD", BOOL_TYPE_VAR, DEFAULT_SUPPRESS_SERVER_MOTD, NULL, 0, NULL, 0, VF_NODAEMON },
225 { "SWITCH_TO_QUIET_CHANNELS", BOOL_TYPE_VAR, DEFAULT_SWITCH_TO_QUIET_CHANNELS, NULL, 0, NULL, 0, VF_NODAEMON },
226 { "TAB", BOOL_TYPE_VAR, DEFAULT_TAB, NULL, 0, NULL, 0, 0 },
227 { "TAB_MAX", INT_TYPE_VAR, DEFAULT_TAB_MAX, NULL, 0, NULL, 0, 0 },
228 { "UNDERLINE_VIDEO", BOOL_TYPE_VAR, DEFAULT_UNDERLINE_VIDEO, NULL, 0, NULL, 0, 0 },
229 { "USER_INFORMATION", STR_TYPE_VAR, 0, NULL, 0, NULL, 0, 0 },
230 { "USER_WALLOPS", BOOL_TYPE_VAR, DEFAULT_USER_WALLOPS, NULL, 0, NULL, 0, 0 },
231 { "VERBOSE_CTCP", BOOL_TYPE_VAR, DEFAULT_VERBOSE_CTCP, NULL, 0, NULL, 0, 0 },
232 { "WARN_OF_IGNORES", BOOL_TYPE_VAR, DEFAULT_WARN_OF_IGNORES, NULL, 0, NULL, 0, 0 },
233 { "WSERV_PATH", STR_TYPE_VAR, 0, NULL, 0, NULL, 0, 0 },
234 { "XTERM_GEOMOPTSTR", STR_TYPE_VAR, 0, NULL, 0, NULL, 0, VF_NODAEMON },
235 { "XTERM_OPTIONS", STR_TYPE_VAR, 0, NULL, 0, NULL, 0, VF_NODAEMON },
236 { "XTERM_PATH", STR_TYPE_VAR, 0, NULL, 0, NULL, 0, VF_NODAEMON },
237 { NULL, 0, 0, NULL, 0, NULL, 0, 0 }
238 };
239
240 /*
241 * init_variables: initializes the string variables that can't really be
242 * initialized properly above
243 */
244 void
init_variables(void)245 init_variables(void)
246 {
247 check_variable_order();
248
249 set_string_var(CMDCHARS_VAR, UP(DEFAULT_CMDCHARS));
250 set_string_var(LOGFILE_VAR, UP(DEFAULT_LOGFILE));
251 set_string_var(SHELL_VAR, UP(DEFAULT_SHELL));
252 set_string_var(SHELL_FLAGS_VAR, UP(DEFAULT_SHELL_FLAGS));
253 set_string_var(DECRYPT_PROGRAM_VAR, UP(DEFAULT_DECRYPT_PROGRAM));
254 set_string_var(DISPLAY_ENCODING_VAR, UP(DEFAULT_DISPLAY_ENCODING));
255 set_string_var(ENCRYPT_PROGRAM_VAR, UP(DEFAULT_ENCRYPT_PROGRAM));
256 set_string_var(CONTINUED_LINE_VAR, UP(DEFAULT_CONTINUED_LINE));
257 set_string_var(INPUT_ENCODING_VAR, UP(DEFAULT_INPUT_ENCODING));
258 set_string_var(INPUT_PROMPT_VAR, UP(DEFAULT_INPUT_PROMPT));
259 set_string_var(IRC_ENCODING_VAR, UP(DEFAULT_IRC_ENCODING));
260 set_string_var(HIGHLIGHT_CHAR_VAR, UP(DEFAULT_HIGHLIGHT_CHAR));
261 set_string_var(HISTORY_FILE_VAR, UP(DEFAULT_HISTORY_FILE));
262 set_string_var(LASTLOG_LEVEL_VAR, UP(DEFAULT_LASTLOG_LEVEL));
263 set_string_var(NOTIFY_HANDLER_VAR, UP(DEFAULT_NOTIFY_HANDLER));
264 set_string_var(NOTIFY_LEVEL_VAR, UP(DEFAULT_NOTIFY_LEVEL));
265 set_string_var(REALNAME_VAR, my_realname());
266 set_string_var(SSL_CA_CHAIN_FILE_VAR, UP(DEFAULT_SSL_CA_CHAIN_FILE));
267 set_string_var(SSL_CA_FILE_VAR, UP(DEFAULT_SSL_CA_FILE));
268 set_string_var(SSL_CA_PATH_VAR, UP(DEFAULT_SSL_CA_PATH));
269 set_string_var(SSL_CA_PRIVATE_KEY_FILE_VAR, UP(DEFAULT_SSL_CA_PRIVATE_KEY_FILE));
270 set_string_var(STAR_PREFIX_VAR, UP(DEFAULT_STAR_PREFIX));
271 set_string_var(STATUS_FORMAT_VAR, UP(DEFAULT_STATUS_FORMAT));
272 set_string_var(STATUS_FORMAT1_VAR, UP(DEFAULT_STATUS_FORMAT1));
273 set_string_var(STATUS_FORMAT2_VAR, UP(DEFAULT_STATUS_FORMAT2));
274 set_string_var(STATUS_AWAY_VAR, UP(DEFAULT_STATUS_AWAY));
275 set_string_var(STATUS_CHANNEL_VAR, UP(DEFAULT_STATUS_CHANNEL));
276 set_string_var(STATUS_CHANOP_VAR, UP(DEFAULT_STATUS_CHANOP));
277 set_string_var(STATUS_CLOCK_VAR, UP(DEFAULT_STATUS_CLOCK));
278 set_string_var(STATUS_GROUP_VAR, UP(DEFAULT_STATUS_GROUP));
279 set_string_var(STATUS_HOLD_VAR, UP(DEFAULT_STATUS_HOLD));
280 set_string_var(STATUS_HOLD_LINES_VAR, UP(DEFAULT_STATUS_HOLD_LINES));
281 set_string_var(STATUS_INSERT_VAR, UP(DEFAULT_STATUS_INSERT));
282 set_string_var(STATUS_MAIL_VAR, UP(DEFAULT_STATUS_MAIL));
283 set_string_var(STATUS_MODE_VAR, UP(DEFAULT_STATUS_MODE));
284 set_string_var(STATUS_OPER_VAR, UP(DEFAULT_STATUS_OPER));
285 set_string_var(STATUS_OVERWRITE_VAR, UP(DEFAULT_STATUS_OVERWRITE));
286 set_string_var(STATUS_QUERY_VAR, UP(DEFAULT_STATUS_QUERY));
287 set_string_var(STATUS_SCROLLED_VAR, UP(DEFAULT_STATUS_SCROLLED));
288 set_string_var(STATUS_SCROLLED_LINES_VAR, UP(DEFAULT_STATUS_SCROLLED_LINES));
289 set_string_var(STATUS_SERVER_VAR, UP(DEFAULT_STATUS_SERVER));
290 set_string_var(STATUS_UMODE_VAR, UP(DEFAULT_STATUS_UMODE));
291 set_string_var(STATUS_USER_VAR, UP(DEFAULT_STATUS_USER));
292 set_string_var(STATUS_USER1_VAR, UP(DEFAULT_STATUS_USER1));
293 set_string_var(STATUS_USER2_VAR, UP(DEFAULT_STATUS_USER2));
294 set_string_var(STATUS_USER3_VAR, UP(DEFAULT_STATUS_USER3));
295 set_string_var(STATUS_WINDOW_VAR, UP(DEFAULT_STATUS_WINDOW));
296 set_string_var(USER_INFO_VAR, UP(DEFAULT_USERINFO));
297 #ifdef WSERV_PATH
298 set_string_var(WSERV_PATH_VAR, UP(WSERV_PATH));
299 #else
300 set_string_var(WSERV_PATH_VAR, UP(DEFAULT_WSERV_PATH));
301 #endif
302 set_string_var(XTERM_GEOMOPTSTR_VAR, UP(DEFAULT_XTERM_GEOMOPTSTR));
303 set_string_var(XTERM_OPTIONS_VAR, UP(DEFAULT_XTERM_OPTIONS));
304 set_string_var(XTERM_PATH_VAR, UP(DEFAULT_XTERM_PATH));
305 set_alarm(DEFAULT_CLOCK_ALARM);
306 set_beep_on_msg(UP(DEFAULT_BEEP_ON_MSG));
307 set_string_var(STATUS_NOTIFY_VAR, UP(DEFAULT_STATUS_NOTIFY));
308 set_string_var(CLIENTINFO_VAR, UP(IRCII_COMMENT));
309 set_string_var(IRCHOST_VAR, get_irchost());
310 set_string_var(DCCHOST_VAR, get_dcchost());
311 #ifdef HAVE_ICONV_OPEN
312 set_irc_encoding(UP(irc_variable[IRC_ENCODING_VAR].string));
313 set_input_encoding(UP(irc_variable[INPUT_ENCODING_VAR].string));
314 set_display_encoding(UP(irc_variable[DISPLAY_ENCODING_VAR].string));
315 #endif /* HAVE_ICONV_OPEN */
316 set_string_var(HELP_PATH_VAR, UP(DEFAULT_HELP_PATH));
317 set_lastlog_size(irc_variable[LASTLOG_VAR].integer);
318 set_history_size(irc_variable[HISTORY_VAR].integer);
319 set_history_file(UP(irc_variable[HISTORY_FILE_VAR].string));
320 set_highlight_char(UP(irc_variable[HIGHLIGHT_CHAR_VAR].string));
321 set_lastlog_level(UP(irc_variable[LASTLOG_LEVEL_VAR].string));
322 set_notify_level(UP(irc_variable[NOTIFY_LEVEL_VAR].string));
323 if (get_int_var(LOG_VAR))
324 set_int_var(LOG_VAR, 1);
325 }
326
327 /*
328 * check_variable_order: make sure irc_variable[] is properly ordered.
329 */
330 static void
check_variable_order(void)331 check_variable_order(void)
332 {
333 IrcVariable *curr, *prev = NULL;
334 size_t len;
335
336 for (curr = irc_variable; curr->name; prev = curr++)
337 if (prev && (len = my_strlen(prev->name)) && my_strncmp(prev->name, curr->name, len) > 0)
338 {
339 yell("irc_variables[] order is wrong at elements \"%s\" and \"%s\"!", prev->name, curr->name);
340 abort();
341 }
342
343 }
344
345 /*
346 * find_variable: looks up variable name in the variable table and returns
347 * the index into the variable array of the match. If there is no match, cnt
348 * is set to 0 and -1 is returned. If more than one match the string, cnt is
349 * set to that number, and it returns the first match. Index will contain
350 * the index into the array of the first found entry
351 */
352 static int
find_variable(u_char * org_name,int * cnt)353 find_variable(u_char *org_name, int *cnt)
354 {
355 IrcVariable *v,
356 *first;
357 size_t len;
358 int var_index;
359 u_char *name = NULL;
360
361 malloc_strcpy(&name, org_name);
362 upper(name);
363 len = my_strlen(name);
364 var_index = 0;
365 for (first = irc_variable; first->name; first++, var_index++)
366
367 {
368 if (my_strncmp(name, first->name, len) == 0)
369 {
370 *cnt = 1;
371 break;
372 }
373 }
374 if (first->name)
375
376 {
377 if (my_strlen(first->name) != len)
378 {
379 v = first;
380 for (v++; v->name; v++, (*cnt)++)
381
382 {
383 if (my_strncmp(name, v->name, len) != 0)
384 break;
385 }
386 }
387 new_free(&name);
388 return (var_index);
389 }
390 else
391 {
392 *cnt = 0;
393 new_free(&name);
394 return (-1);
395 }
396 }
397
398 /*
399 * do_boolean: just a handy thing. Returns 1 if the str is not ON, OFF, or
400 * TOGGLE
401 */
402 int
do_boolean(u_char * str,int * value)403 do_boolean(u_char *str, int *value)
404 {
405 upper(str);
406 if (my_strcmp(str, var_settings(ON)) == 0)
407 *value = 1;
408 else if (my_strcmp(str, var_settings(OFF)) == 0)
409 *value = 0;
410 else if (my_strcmp(str, var_settings(TOGGLE)) == 0)
411 {
412 if (*value)
413 *value = 0;
414 else
415 *value = 1;
416 }
417 else
418 return (1);
419 return (0);
420 }
421
422 /*
423 * set_var_value: Given the variable structure and the string representation
424 * of the value, this sets the value in the most verbose and error checking
425 * of manors. It displays the results of the set and executes the function
426 * defined in the var structure
427 */
428 void
set_var_value(int var_index,u_char * value)429 set_var_value(int var_index, u_char *value)
430 {
431 u_char *rest;
432 IrcVariable *var;
433 int old;
434
435
436 var = &(irc_variable[var_index]);
437 #ifdef DAEMON_UID
438 if (getuid() == DAEMON_UID && var->flags&VF_NODAEMON && value && *value)
439 {
440 say("You are not permitted to set that variable");
441 return;
442 }
443 #endif /* DAEMON_UID */
444 switch (var->type)
445 {
446 case BOOL_TYPE_VAR:
447 if (value && *value && (value = next_arg(value, &rest)))
448 {
449 old = var->integer;
450 if (do_boolean(value, &(var->integer)))
451
452 {
453 say("Value must be either ON, OFF, or TOGGLE");
454 break;
455 }
456 if (!(var->int_flags & VIF_CHANGED))
457 {
458 if (old != var->integer)
459 var->int_flags |= VIF_CHANGED;
460 }
461 if (loading_global())
462 var->int_flags |= VIF_GLOBAL;
463 if (var->ifunc)
464 (*var->ifunc)(var->integer);
465 say("Value of %s set to %s", var->name,
466 var->integer ? var_settings(ON)
467 : var_settings(OFF));
468 }
469 else
470 say("Current value of %s is %s", var->name,
471 (var->integer) ?
472 var_settings(ON) : var_settings(OFF));
473 break;
474 case CHAR_TYPE_VAR:
475 if (value && *value && (value = next_arg(value, &rest)))
476 {
477 if ((int) my_strlen(value) > 1)
478 say("Value of %s must be a single character",
479 var->name);
480 else
481 {
482 if (!(var->int_flags & VIF_CHANGED))
483 {
484 if (var->integer != *value)
485 var->int_flags |= VIF_CHANGED;
486 }
487 if (loading_global())
488 var->int_flags |= VIF_GLOBAL;
489 var->integer = *value;
490 if (var->ifunc)
491 (*var->ifunc)(var->integer);
492 say("Value of %s set to '%c'", var->name,
493 var->integer);
494 }
495 }
496 else
497 say("Current value of %s is '%c'", var->name,
498 var->integer);
499 break;
500 case INT_TYPE_VAR:
501 if (value && *value && (value = next_arg(value, &rest)))
502 {
503 int val;
504
505 if (!is_number(value))
506 {
507 say("Value of %s must be numeric!", var->name);
508 break;
509 }
510 if ((val = my_atoi(value)) < 0)
511 {
512 say("Value of %s must be greater than 0",
513 var->name);
514 break;
515 }
516 if (!(var->int_flags & VIF_CHANGED))
517 {
518 if (var->integer != val)
519 var->int_flags |= VIF_CHANGED;
520 }
521 if (loading_global())
522 var->int_flags |= VIF_GLOBAL;
523 var->integer = val;
524 if (var->ifunc)
525 (*var->ifunc)(var->integer);
526 say("Value of %s set to %d", var->name, var->integer);
527 }
528 else
529 say("Current value of %s is %d", var->name,
530 var->integer);
531 break;
532 case STR_TYPE_VAR:
533 if (value)
534 {
535 if (*value)
536 {
537 u_char *temp = NULL;
538
539 if (var->flags & VF_EXPAND_PATH)
540 {
541 temp = expand_twiddle(value);
542 value = temp;
543 }
544 if (!(var->int_flags & VIF_CHANGED))
545 {
546 if ((var->string && ! value) ||
547 (! var->string && value) ||
548 my_stricmp(var->string, value))
549 var->int_flags |= VIF_CHANGED;
550 }
551 if (loading_global())
552 var->int_flags |= VIF_GLOBAL;
553 malloc_strcpy(&var->string, value);
554 if (temp)
555 new_free(&temp);
556 }
557 else
558 {
559 if (var->string)
560 say("Current value of %s is %s",
561 var->name, var->string);
562 else
563 say("No value for %s has been set",
564 var->name);
565 return;
566 }
567 }
568 else
569 new_free(&var->string);
570 if (var->sfunc)
571 (*var->sfunc)(var->string);
572 say("Value of %s set to %s", var->name, var->string ?
573 var->string : UP("<EMPTY>"));
574 break;
575 }
576 }
577
578 /*
579 * set_variable: The SET command sets one of the irc variables. The args
580 * should consist of "variable-name setting", where variable name can be
581 * partial, but non-ambbiguous, and setting depends on the variable being set
582 */
583 void
set_variable(u_char * command,u_char * args,u_char * subargs)584 set_variable(u_char *command, u_char *args, u_char *subargs)
585 {
586 u_char *var;
587 int cnt,
588 var_index,
589 lastlog_level;
590
591 if ((var = next_arg(args, &args)) != NULL)
592 {
593 if (*var == '-')
594 {
595 var++;
596 args = NULL;
597 }
598 var_index = find_variable(var, &cnt);
599 switch (cnt)
600 {
601 case 0:
602 say("No such variable \"%s\"", var);
603 return;
604 case 1:
605 set_var_value(var_index, args);
606 return;
607 default:
608 say("%s is ambiguous", var);
609 for (cnt += var_index; var_index < cnt; var_index++)
610 set_var_value(var_index, empty_string());
611 return;
612 }
613 }
614 lastlog_level = message_from_level(LOG_CRAP);
615 for (var_index = 0; var_index < NUMBER_OF_VARIABLES; var_index++)
616 set_var_value(var_index, empty_string());
617 (void) message_from_level(lastlog_level);
618 }
619
620 /*
621 * get_string_var: returns the value of the string variable given as an index
622 * into the variable table. Does no checking of variable types, etc
623 */
624 u_char *
get_string_var(int var)625 get_string_var(int var)
626 {
627 return irc_variable[var].string;
628 }
629
630 /*
631 * get_int_var: returns the value of the integer string given as an index
632 * into the variable table. Does no checking of variable types, etc
633 */
634 int
get_int_var(int var)635 get_int_var(int var)
636 {
637 return (irc_variable[var].integer);
638 }
639
640 /*
641 * set_string_var: sets the string variable given as an index into the
642 * variable table to the given string. If string is null, the current value
643 * of the string variable is freed and set to null
644 */
645 void
set_string_var(int var,u_char * string)646 set_string_var(int var, u_char *string)
647 {
648 if (string)
649 malloc_strcpy(&irc_variable[var].string, string);
650 else
651 new_free(&irc_variable[var].string);
652 }
653
654 /*
655 * set_int_var: sets the integer value of the variable given as an index into
656 * the variable table to the given value
657 */
658 void
set_int_var(int var,unsigned value)659 set_int_var(int var, unsigned value)
660 {
661 if (var == NOVICE_VAR && !get_load_depth() && !value)
662 {
663 say("WARNING: Setting NOVICE to OFF enables commands in your client which");
664 say(" could be used by others on IRC to control your IRC session");
665 say(" or compromise security on your machine. If somebody has");
666 say(" asked you to do this, and you do not know EXACTLY why, or if");
667 say(" you are not ABSOLUTELY sure what you are doing, you should");
668 say(" immediately /SET NOVICE ON and find out more information.");
669 }
670 irc_variable[var].integer = value;
671 }
672
673 /*
674 * save_variables: this writes all of the IRCII variables to the given FILE
675 * pointer in such a way that they can be loaded in using LOAD or the -l switch
676 */
677 void
save_variables(FILE * fp,int do_all)678 save_variables(FILE *fp, int do_all)
679 {
680 IrcVariable *var;
681
682 for (var = irc_variable; var->name; var++)
683 {
684 if (!(var->int_flags & VIF_CHANGED))
685 continue;
686 if (do_all || !(var->int_flags & VIF_GLOBAL))
687 {
688 if (my_strcmp(var->name, "DISPLAY") == 0 || my_strcmp(var->name, "CLIENT_INFORMATION") == 0)
689 continue;
690 fprintf(fp, "SET ");
691 switch (var->type)
692 {
693 case BOOL_TYPE_VAR:
694 fprintf(fp, "%s %s\n", var->name, var->integer ?
695 var_settings(ON) : var_settings(OFF));
696 break;
697 case CHAR_TYPE_VAR:
698 fprintf(fp, "%s %c\n", var->name, var->integer);
699 break;
700 case INT_TYPE_VAR:
701 fprintf(fp, "%s %u\n", var->name, var->integer);
702 break;
703 case STR_TYPE_VAR:
704 if (var->string)
705 fprintf(fp, "%s %s\n", var->name,
706 var->string);
707 else
708 fprintf(fp, "-%s\n", var->name);
709 break;
710 }
711 }
712 }
713 }
714
715 u_char *
make_string_var(u_char * var_name)716 make_string_var(u_char *var_name)
717 {
718 int cnt,
719 var_index;
720 u_char *ret = NULL,
721 *cmd = NULL;
722
723 malloc_strcpy(&cmd, var_name);
724 upper(cmd);
725 if (((var_index = find_variable(cmd, &cnt)) == -1) ||
726 (cnt > 1) ||
727 my_strcmp(cmd, irc_variable[var_index].name))
728 goto out;
729 switch (irc_variable[var_index].type)
730 {
731 case STR_TYPE_VAR:
732 malloc_strcpy(&ret, irc_variable[var_index].string);
733 break;
734 case INT_TYPE_VAR:
735 malloc_snprintf(&ret, "%u", irc_variable[var_index].integer);
736 break;
737 case BOOL_TYPE_VAR:
738 malloc_strcpy(&ret, UP(var_settings(irc_variable[var_index].integer)));
739 break;
740 case CHAR_TYPE_VAR:
741 malloc_snprintf(&ret, "%c", irc_variable[var_index].integer);
742 break;
743 }
744 out:
745 new_free(&cmd);
746 return (ret);
747
748 }
749
750 /* exec_warning: a warning message displayed whenever EXEC_PROTECTION is turned off. */
751 static void
exec_warning(int value)752 exec_warning(int value)
753 {
754 if (value == OFF)
755 {
756 say("Warning! You have turned EXEC_PROTECTION off");
757 say("Please read the /HELP SET EXEC_PROTECTION documentation");
758 }
759 }
760
761 static void
input_warning(int value)762 input_warning(int value)
763 {
764 if (value == OFF)
765 {
766 say("Warning! You have turned INPUT_PROTECTION off");
767 say("Please read the /HELP ON INPUT, and /HELP SET INPUT_PROTECTION documentation");
768 }
769 }
770
771 /* returns the size of the character set */
772 int
charset_size(void)773 charset_size(void)
774 {
775 return get_int_var(EIGHT_BIT_CHARACTERS_VAR) ? 256 : 128;
776 }
777
778 static void
eight_bit_characters(int value)779 eight_bit_characters(int value)
780 {
781 if (value == ON && !term_eight_bit())
782 say("Warning! Your terminal says it does not support eight bit characters");
783 set_term_eight_bit(value);
784 }
785
786 static void
v_update_all_status(int dummy)787 v_update_all_status(int dummy)
788 {
789 update_all_status();
790 }
791
792 char *
var_settings(int idx)793 var_settings(int idx)
794 {
795 if (idx == OFF)
796 return "OFF";
797 else if (idx == ON)
798 return "ON";
799 else if (idx == TOGGLE)
800 return "TOGGLE";
801 return "<internal error>";
802 };
803