1 /* $EPIC: vars.c,v 1.51 2014/03/31 13:57:22 jnelson Exp $ */
2 /*
3 * vars.c: All the dealing of the irc variables are handled here.
4 *
5 * Copyright (c) 1990 Michael Sandroff.
6 * Copyright (c) 1991, 1992 Troy Rollo.
7 * Copyright (c) 1992-1996 Matthew Green.
8 * Copyright � 1993, 2003 EPIC Software Labs.
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 * notices, the above paragraph (the one permitting redistribution),
18 * this list of conditions and the following disclaimer in the
19 * documentation and/or other materials provided with the distribution.
20 * 3. The names of the author(s) may not be used to endorse or promote
21 * products derived from this software without specific prior written
22 * permission.
23 *
24 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
25 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
26 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
27 * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
28 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
29 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
30 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
31 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
32 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 * SUCH DAMAGE.
35 */
36
37 #include "irc.h"
38 #include "alist.h"
39 #include "status.h"
40 #include "window.h"
41 #include "lastlog.h"
42 #include "log.h"
43 #include "hook.h"
44 #include "sedcrypt.h"
45 #include "history.h"
46 #include "notify.h"
47 #include "vars.h"
48 #include "input.h"
49 #include "ircaux.h"
50 #include "termx.h"
51 #include "output.h"
52 #include "stack.h"
53 #include "dcc.h"
54 #include "keys.h"
55 #include "translat.h"
56 #include "timer.h"
57 #include "clock.h"
58 #include "mail.h"
59
60 /* IrcVariable: structure for each variable in the variable table */
61 typedef struct
62 {
63 const char * name; /* what the user types */
64 int type; /* variable types, see below */
65 int integer; /* int value of variable */
66 double number; /* decimal value of variable */
67 char * string; /* string value of variable */
68 void (*func) (const void *); /* func called when var is set */
69 char int_flags; /* internal flags to the variable */
70 unsigned short flags; /* flags for this variable */
71 } IrcVariable;
72
73 /*
74 * The VIF_* macros stand for "(V)ariable.(i)nt_(f)lags", and have been
75 * used for the various possible values of the int_flags data member.
76 * The first two are, the third one is not. The third one is used in
77 * the 'flags' data member, but its based on the same idea.
78 */
79 #define VIF_CHANGED 0x01 /* /set has been changed by user */
80 #define VIF_GLOBAL 0x02 /* /set was changed only by global */
81 #define VIF_PENDING 0x04 /* A /set is pending for this variable */
82
83 /* the types of IrcVariables */
84 #define BOOL_TYPE_VAR 0
85 #define CHAR_TYPE_VAR 1
86 #define INT_TYPE_VAR 2
87 #define STR_TYPE_VAR 3
88 #define FLOAT_TYPE_VAR 4
89
90 const char *var_settings[] =
91 {
92 "OFF", "ON", "TOGGLE"
93 };
94
95 static void eight_bit_characters (const void *);
96 static void set_realname (const void *);
97 static void set_display_pc_characters (const void *);
98 static void set_dcc_timeout (const void *);
99 static void set_mangle_inbound (const void *);
100 static void set_mangle_outbound (const void *);
101 static void set_mangle_logfiles (const void *);
102 static void set_scroll (const void *);
103 static void update_all_status_wrapper (const void *);
104 static void set_highlight_char (const void *);
105 static void set_wserv_type (const void *);
106
107 /*
108 * irc_variable: all the irc variables used. Note that the integer and
109 * boolean defaults are set here, which the string default value are set in
110 * the init_variables() procedure
111 */
112 static IrcVariable irc_variable[] =
113 {
114 { "ALLOW_C1_CHARS", BOOL_TYPE_VAR, DEFAULT_ALLOW_C1_CHARS, 0, NULL, NULL, 0, 0 },
115 { "ALT_CHARSET", BOOL_TYPE_VAR, DEFAULT_ALT_CHARSET, 0, NULL, NULL, 0, 0 },
116 { "ALWAYS_SPLIT_BIGGEST", BOOL_TYPE_VAR, DEFAULT_ALWAYS_SPLIT_BIGGEST, 0, NULL, NULL, 0, 0 },
117 { "AUTO_NEW_NICK", BOOL_TYPE_VAR, DEFAULT_AUTO_NEW_NICK, 0, NULL, NULL, 0, 0 },
118 { "AUTO_RECONNECT", BOOL_TYPE_VAR, DEFAULT_AUTO_RECONNECT, 0, NULL, NULL, 0, 0 },
119 { "AUTO_RECONNECT_DELAY", INT_TYPE_VAR, DEFAULT_AUTO_RECONNECT_DELAY, 0, NULL, NULL, 0, 0 },
120 { "AUTO_REJOIN", BOOL_TYPE_VAR, DEFAULT_AUTO_REJOIN, 0, NULL, NULL, 0, 0 },
121 { "AUTO_REJOIN_CONNECT", BOOL_TYPE_VAR, DEFAULT_AUTO_REJOIN_CONNECT, 0, NULL, NULL, 0, 0 },
122 { "AUTO_REJOIN_DELAY", INT_TYPE_VAR, DEFAULT_AUTO_REJOIN_DELAY, 0, NULL, NULL, 0, 0 },
123 { "AUTO_UNMARK_AWAY", BOOL_TYPE_VAR, DEFAULT_AUTO_UNMARK_AWAY, 0, NULL, NULL, 0, 0 },
124 { "AUTO_WHOWAS", BOOL_TYPE_VAR, DEFAULT_AUTO_WHOWAS, 0, NULL, NULL, 0, 0 },
125 { "BAD_STYLE", BOOL_TYPE_VAR, DEFAULT_BAD_STYLE, 0, NULL, NULL, 0, 0 },
126 { "BANNER", STR_TYPE_VAR, 0, 0, NULL, NULL, 0, 0 },
127 { "BANNER_EXPAND", BOOL_TYPE_VAR, 0, 0, NULL, NULL, 0, 0 },
128 { "BEEP", BOOL_TYPE_VAR, DEFAULT_BEEP, 0, NULL, NULL, 0, 0 },
129 { "BEEP_MAX", INT_TYPE_VAR, DEFAULT_BEEP_MAX, 0, NULL, NULL, 0, 0 },
130 { "BEEP_ON_MSG", STR_TYPE_VAR, 0, 0, NULL, set_beep_on_msg, 0, 0 },
131 { "BEEP_WHEN_AWAY", INT_TYPE_VAR, DEFAULT_BEEP_WHEN_AWAY, 0, NULL, NULL, 0, 0 },
132 { "BLINK_VIDEO", BOOL_TYPE_VAR, DEFAULT_BLINK_VIDEO, 0, NULL, NULL, 0, 0 },
133 { "BOLD_VIDEO", BOOL_TYPE_VAR, DEFAULT_BOLD_VIDEO, 0, NULL, NULL, 0, 0 },
134 { "CHANNEL_NAME_WIDTH", INT_TYPE_VAR, DEFAULT_CHANNEL_NAME_WIDTH, 0, NULL, update_all_status_wrapper, 0, 0 },
135 { "CLIENT_INFORMATION", STR_TYPE_VAR, 0, 0, NULL, NULL, 0, 0 },
136 { "CLOCK", BOOL_TYPE_VAR, DEFAULT_CLOCK, 0, NULL, set_clock, 0, 0 },
137 { "CLOCK_24HOUR", BOOL_TYPE_VAR, DEFAULT_CLOCK_24HOUR, 0, NULL, reset_clock, 0, 0 },
138 { "CLOCK_FORMAT", STR_TYPE_VAR, 0, 0, NULL, set_clock_format, 0, 0 },
139 { "CLOCK_INTERVAL", INT_TYPE_VAR, DEFAULT_CLOCK_INTERVAL, 0, NULL, set_clock_interval, 0, 0 },
140 { "CMDCHARS", STR_TYPE_VAR, 0, 0, NULL, NULL, 0, 0 },
141 { "COLOR", BOOL_TYPE_VAR, DEFAULT_COLOR, 0, NULL, NULL, 0, 0 },
142 { "COMMAND_MODE", BOOL_TYPE_VAR, DEFAULT_COMMAND_MODE, 0, NULL, NULL, 0, 0 },
143 { "COMMENT_HACK", BOOL_TYPE_VAR, DEFAULT_COMMENT_HACK, 0, NULL, NULL, 0, 0 },
144 { "CONNECT_TIMEOUT", INT_TYPE_VAR, DEFAULT_CONNECT_TIMEOUT, 0, NULL, NULL, 0, 0 },
145 { "CONTINUED_LINE", STR_TYPE_VAR, 0, 0, NULL, set_continued_line, 0, 0 },
146 { "CPU_SAVER_AFTER", INT_TYPE_VAR, DEFAULT_CPU_SAVER_AFTER, 0, NULL, set_cpu_saver_after, 0, 0 },
147 { "CPU_SAVER_EVERY", INT_TYPE_VAR, DEFAULT_CPU_SAVER_EVERY, 0, NULL, set_cpu_saver_every, 0, 0 },
148 { "CURRENT_WINDOW_LEVEL", STR_TYPE_VAR, 0, 0, NULL, set_current_window_level, 0, 0 },
149 { "DCC_AUTO_SEND_REJECTS", BOOL_TYPE_VAR, DEFAULT_DCC_AUTO_SEND_REJECTS, 0, NULL, NULL, 0, 0 },
150 { "DCC_DEQUOTE_FILENAMES", BOOL_TYPE_VAR, DEFAULT_DCC_DEQUOTE_FILENAMES, 0, NULL, NULL, 0, 0 },
151 { "DCC_LONG_PATHNAMES", BOOL_TYPE_VAR, DEFAULT_DCC_LONG_PATHNAMES, 0, NULL, NULL, 0, 0 },
152 { "DCC_SLIDING_WINDOW", INT_TYPE_VAR, DEFAULT_DCC_SLIDING_WINDOW, 0, NULL, NULL, 0, 0 },
153 { "DCC_STORE_PATH", STR_TYPE_VAR, 0, 0, NULL, NULL, 0, 0 },
154 { "DCC_TIMEOUT", INT_TYPE_VAR, DEFAULT_DCC_TIMEOUT, 0, NULL, set_dcc_timeout, 0, 0 },
155 { "DCC_USE_GATEWAY_ADDR", BOOL_TYPE_VAR, 0, 0, NULL, NULL, 0, 0 },
156 { "DEBUG", INT_TYPE_VAR, 0, 0, NULL, NULL, 0, 0 },
157 { "DISPATCH_UNKNOWN_COMMANDS", BOOL_TYPE_VAR, DEFAULT_DISPATCH_UNKNOWN_COMMANDS, 0, NULL, NULL, 0, 0 },
158 { "DISPLAY", BOOL_TYPE_VAR, DEFAULT_DISPLAY, 0, NULL, NULL, 0, 0 },
159 { "DISPLAY_ANSI", BOOL_TYPE_VAR, DEFAULT_DISPLAY_ANSI, 0, NULL, NULL, 0, 0 },
160 { "DISPLAY_PC_CHARACTERS", INT_TYPE_VAR, DEFAULT_DISPLAY_PC_CHARACTERS, 0, NULL, set_display_pc_characters, 0, 0 },
161 { "DO_NOTIFY_IMMEDIATELY", BOOL_TYPE_VAR, DEFAULT_DO_NOTIFY_IMMEDIATELY, 0, NULL, NULL, 0, 0 },
162 { "EIGHT_BIT_CHARACTERS", BOOL_TYPE_VAR, DEFAULT_EIGHT_BIT_CHARACTERS, 0, NULL, eight_bit_characters, 0, 0 },
163 { "FLOATING_POINT_MATH", BOOL_TYPE_VAR, DEFAULT_FLOATING_POINT_MATH, 0, NULL, NULL, 0, 0 },
164 { "FLOATING_POINT_PRECISION", INT_TYPE_VAR, DEFAULT_FLOATING_POINT_PRECISION, 0, NULL, NULL, 0, 0 },
165 { "FLOOD_AFTER", INT_TYPE_VAR, DEFAULT_FLOOD_AFTER, 0, NULL, NULL, 0, 0 },
166 { "FLOOD_IGNORE", BOOL_TYPE_VAR, DEFAULT_FLOOD_IGNORE, 0, NULL, NULL, 0, 0 },
167 { "FLOOD_MASKUSER", INT_TYPE_VAR, DEFAULT_FLOOD_MASKUSER, 0, NULL, NULL, 0, 0 },
168 { "FLOOD_RATE", INT_TYPE_VAR, DEFAULT_FLOOD_RATE, 0, NULL, NULL, 0, 0 },
169 { "FLOOD_RATE_PER", INT_TYPE_VAR, DEFAULT_FLOOD_RATE_PER, 0, NULL, NULL, 0, 0 },
170 { "FLOOD_USERS", INT_TYPE_VAR, DEFAULT_FLOOD_USERS, 0, NULL, NULL, 0, 0 },
171 { "FLOOD_WARNING", BOOL_TYPE_VAR, DEFAULT_FLOOD_WARNING, 0, NULL, NULL, 0, 0 },
172 { "FULL_STATUS_LINE", BOOL_TYPE_VAR, DEFAULT_FULL_STATUS_LINE, 0, NULL, update_all_status_wrapper, 0, 0 },
173 { "HELP_PAGER", BOOL_TYPE_VAR, DEFAULT_HELP_PAGER, 0, NULL, NULL, 0, 0 },
174 { "HELP_PATH", STR_TYPE_VAR, 0, 0, NULL, NULL, 0, 0 },
175 { "HELP_PROMPT", BOOL_TYPE_VAR, DEFAULT_HELP_PROMPT, 0, NULL, NULL, 0, 0 },
176 { "HELP_WINDOW", BOOL_TYPE_VAR, DEFAULT_HELP_WINDOW, 0, NULL, NULL, 0, 0 },
177 { "HIDE_PRIVATE_CHANNELS", BOOL_TYPE_VAR, DEFAULT_HIDE_PRIVATE_CHANNELS, 0, NULL, update_all_status_wrapper, 0, 0 },
178 { "HIGHLIGHT_CHAR", STR_TYPE_VAR, 0, 0, NULL, set_highlight_char, 0, 0 },
179 { "HIGH_BIT_ESCAPE", INT_TYPE_VAR, DEFAULT_HIGH_BIT_ESCAPE, 0, NULL, set_meta_8bit, 0, 0 },
180 { "HISTORY", INT_TYPE_VAR, DEFAULT_HISTORY, 0, NULL, set_history_size, 0, 0 },
181 { "HISTORY_CIRCLEQ", BOOL_TYPE_VAR, DEFAULT_HISTORY_CIRCLEQ, 0, NULL, NULL, 0, 0 },
182 { "HOLD_SLIDER", INT_TYPE_VAR, DEFAULT_HOLD_SLIDER, 0, NULL, NULL, 0, 0 },
183 { "INDENT", BOOL_TYPE_VAR, DEFAULT_INDENT, 0, NULL, NULL, 0, 0 },
184 { "INPUT_ALIASES", BOOL_TYPE_VAR, DEFAULT_INPUT_ALIASES, 0, NULL, NULL, 0, 0 },
185 { "INPUT_PROMPT", STR_TYPE_VAR, 0, 0, NULL, set_input_prompt, 0, 0 },
186 { "INSERT_MODE", BOOL_TYPE_VAR, DEFAULT_INSERT_MODE, 0, NULL, update_all_status_wrapper, 0, 0 },
187 { "INVERSE_VIDEO", BOOL_TYPE_VAR, DEFAULT_INVERSE_VIDEO, 0, NULL, NULL, 0, 0 },
188 { "KEY_INTERVAL", INT_TYPE_VAR, DEFAULT_KEY_INTERVAL, 0, NULL, set_key_interval, 0, 0 },
189 { "LASTLOG", INT_TYPE_VAR, DEFAULT_LASTLOG, 0, NULL, set_lastlog_size, 0, 0 },
190 { "LASTLOG_LEVEL", STR_TYPE_VAR, 0, 0, NULL, set_lastlog_level, 0, 0 },
191 { "LOAD_PATH", STR_TYPE_VAR, 0, 0, NULL, NULL, 0, 0 },
192 { "LOG", BOOL_TYPE_VAR, DEFAULT_LOG, 0, NULL, logger, 0, 0 },
193 { "LOGFILE", STR_TYPE_VAR, 0, 0, NULL, NULL, 0, 0 },
194 { "LOG_REWRITE", STR_TYPE_VAR, 0, 0, NULL, NULL, 0, 0 },
195 { "MAIL", INT_TYPE_VAR, DEFAULT_MAIL, 0, NULL, set_mail, 0, 0 },
196 { "MAIL_INTERVAL", INT_TYPE_VAR, DEFAULT_MAIL_INTERVAL, 0, NULL, set_mail_interval, 0, 0 },
197 { "MAIL_TYPE", STR_TYPE_VAR, 0, 0, NULL, set_mail_type, 0, 0 },
198 { "MANGLE_INBOUND", STR_TYPE_VAR, 0, 0, NULL, set_mangle_inbound, 0, 0 },
199 { "MANGLE_LOGFILES", STR_TYPE_VAR, 0, 0, NULL, set_mangle_logfiles, 0, 0 },
200 { "MANGLE_OUTBOUND", STR_TYPE_VAR, 0, 0, NULL, set_mangle_outbound, 0, 0 },
201 { "MAX_RECONNECTS", INT_TYPE_VAR, DEFAULT_MAX_RECONNECTS, 0, NULL, NULL, 0, 0 },
202 { "METRIC_TIME", BOOL_TYPE_VAR, DEFAULT_METRIC_TIME, 0, NULL, reset_clock, 0, 0 },
203 { "MIRC_BROKEN_DCC_RESUME", BOOL_TYPE_VAR, 0, 0, NULL, NULL, 0, 0 },
204 { "MODE_STRIPPER", BOOL_TYPE_VAR, DEFAULT_MODE_STRIPPER, 0, NULL, NULL, 0, 0 },
205 { "ND_SPACE_MAX", INT_TYPE_VAR, DEFAULT_ND_SPACE_MAX, 0, NULL, NULL, 0, 0 },
206 { "NEW_SERVER_LASTLOG_LEVEL", STR_TYPE_VAR, 0, 0, NULL, set_new_server_lastlog_level, 0, 0 },
207 { "NOTIFY", BOOL_TYPE_VAR, DEFAULT_NOTIFY, 0, NULL, set_notify, 0, 0 },
208 { "NOTIFY_INTERVAL", INT_TYPE_VAR, DEFAULT_NOTIFY_INTERVAL, 0, NULL, set_notify_interval, 0, 0 },
209 { "NOTIFY_LEVEL", STR_TYPE_VAR, 0, 0, NULL, set_notify_level, 0, 0 },
210 { "NOTIFY_ON_TERMINATION", BOOL_TYPE_VAR, DEFAULT_NOTIFY_ON_TERMINATION, 0, NULL, NULL, 0, 0 },
211 { "NOTIFY_USERHOST_AUTOMATIC", BOOL_TYPE_VAR, DEFAULT_NOTIFY_USERHOST_AUTOMATIC, 0, NULL, NULL, 0, 0 },
212 { "NO_CONTROL_LOG", BOOL_TYPE_VAR, DEFAULT_NO_CONTROL_LOG, 0, NULL, NULL, 0, 0 },
213 { "NO_CTCP_FLOOD", BOOL_TYPE_VAR, DEFAULT_NO_CTCP_FLOOD, 0, NULL, NULL, 0, 0 },
214 { "NO_FAIL_DISCONNECT", BOOL_TYPE_VAR, DEFAULT_NO_FAIL_DISCONNECT, 0, NULL, NULL, 0, 0 },
215 { "NUM_OF_WHOWAS", INT_TYPE_VAR, DEFAULT_NUM_OF_WHOWAS, 0, NULL, NULL, 0, 0 },
216 { "OUTPUT_REWRITE", STR_TYPE_VAR, 0, 0, NULL, NULL, 0, 0 },
217 { "PAD_CHAR", CHAR_TYPE_VAR, DEFAULT_PAD_CHAR, 0, NULL, NULL, 0, 0 },
218 { "QUIT_MESSAGE", STR_TYPE_VAR, 0, 0, NULL, NULL, 0, 0 },
219 { "RANDOM_SOURCE", INT_TYPE_VAR, DEFAULT_RANDOM_SOURCE, 0, NULL, NULL, 0, 0 },
220 { "REALNAME", STR_TYPE_VAR, 0, 0, NULL, set_realname, 0, 0 },
221 { "REVERSE_STATUS_LINE", BOOL_TYPE_VAR, DEFAULT_REVERSE_STATUS_LINE, 0, NULL, update_all_status_wrapper, 0, 0 },
222 { "SCREEN_OPTIONS", STR_TYPE_VAR, 0, 0, NULL, NULL, 0, 0 },
223 { "SCROLL", BOOL_TYPE_VAR, 1, 0, NULL, set_scroll, 0, 0 },
224 { "SCROLLBACK", INT_TYPE_VAR, DEFAULT_SCROLLBACK, 0, NULL, set_scrollback_size, 0, 0 },
225 { "SCROLLBACK_RATIO", INT_TYPE_VAR, DEFAULT_SCROLLBACK_RATIO, 0, NULL, NULL, 0, 0 },
226 { "SCROLL_LINES", INT_TYPE_VAR, DEFAULT_SCROLL_LINES, 0, NULL, set_scroll_lines, 0, 0 },
227 { "SECURITY", INT_TYPE_VAR, DEFAULT_SECURITY, 0, NULL, NULL, 0, 0 },
228 { "SHELL", STR_TYPE_VAR, 0, 0, NULL, NULL, 0, 0 },
229 { "SHELL_FLAGS", STR_TYPE_VAR, 0, 0, NULL, NULL, 0, 0 },
230 { "SHELL_LIMIT", INT_TYPE_VAR, DEFAULT_SHELL_LIMIT, 0, NULL, NULL, 0, 0 },
231 { "SHOW_CHANNEL_NAMES", BOOL_TYPE_VAR, DEFAULT_SHOW_CHANNEL_NAMES, 0, NULL, NULL, 0, 0 },
232 { "SHOW_END_OF_MSGS", BOOL_TYPE_VAR, DEFAULT_SHOW_END_OF_MSGS, 0, NULL, NULL, 0, 0 },
233 { "SHOW_NUMERICS", BOOL_TYPE_VAR, DEFAULT_SHOW_NUMERICS, 0, NULL, NULL, 0, 0 },
234 { "SHOW_STATUS_ALL", BOOL_TYPE_VAR, DEFAULT_SHOW_STATUS_ALL, 0, NULL, update_all_status_wrapper, 0, 0 },
235 { "SHOW_WHO_HOPCOUNT", BOOL_TYPE_VAR, DEFAULT_SHOW_WHO_HOPCOUNT, 0, NULL, NULL, 0, 0 },
236 { "SSL_CERTFILE", STR_TYPE_VAR, 0, 0, NULL, NULL, 0, 0 },
237 { "SSL_KEYFILE", STR_TYPE_VAR, 0, 0, NULL, NULL, 0, 0 },
238 { "SSL_PATH", STR_TYPE_VAR, 0, 0, NULL, NULL, 0, 0 },
239 { "STATUS_AWAY", STR_TYPE_VAR, 0, 0, NULL, build_status, 0, 0 },
240 { "STATUS_CHANNEL", STR_TYPE_VAR, 0, 0, NULL, build_status, 0, 0 },
241 { "STATUS_CHANOP", STR_TYPE_VAR, 0, 0, NULL, build_status, 0, 0 },
242 { "STATUS_CLOCK", STR_TYPE_VAR, 0, 0, NULL, build_status, 0, 0 },
243 { "STATUS_CPU_SAVER", STR_TYPE_VAR, 0, 0, NULL, build_status, 0, 0 },
244 { "STATUS_DOES_EXPANDOS", BOOL_TYPE_VAR, 0, 0, NULL, NULL, 0, 0 },
245 { "STATUS_FORMAT", STR_TYPE_VAR, 0, 0, NULL, build_status, 0, 0 },
246 { "STATUS_FORMAT1", STR_TYPE_VAR, 0, 0, NULL, build_status, 0, 0 },
247 { "STATUS_FORMAT2", STR_TYPE_VAR, 0, 0, NULL, build_status, 0, 0 },
248 { "STATUS_HALFOP", STR_TYPE_VAR, 0, 0, NULL, build_status, 0, 0 },
249 { "STATUS_HOLD", STR_TYPE_VAR, 0, 0, NULL, build_status, 0, 0 },
250 { "STATUS_HOLD_LINES", STR_TYPE_VAR, 0, 0, NULL, build_status, 0, 0 },
251 { "STATUS_INSERT", STR_TYPE_VAR, 0, 0, NULL, build_status, 0, 0 },
252 { "STATUS_MAIL", STR_TYPE_VAR, 0, 0, NULL, build_status, 0, 0 },
253 { "STATUS_MODE", STR_TYPE_VAR, 0, 0, NULL, build_status, 0, 0 },
254 { "STATUS_NICKNAME", STR_TYPE_VAR, 0, 0, NULL, build_status, 0, 0 },
255 { "STATUS_NOSWAP", STR_TYPE_VAR, 0, 0, NULL, build_status, 0, 0 },
256 { "STATUS_NOTIFY", STR_TYPE_VAR, 0, 0, NULL, build_status, 0, 0 },
257 { "STATUS_NO_REPEAT", BOOL_TYPE_VAR, DEFAULT_STATUS_NO_REPEAT, 0, NULL, build_status, 0, 0 },
258 { "STATUS_OPER", STR_TYPE_VAR, 0, 0, NULL, build_status, 0, 0 },
259 { "STATUS_OVERWRITE", STR_TYPE_VAR, 0, 0, NULL, build_status, 0, 0 },
260 { "STATUS_QUERY", STR_TYPE_VAR, 0, 0, NULL, build_status, 0, 0 },
261 { "STATUS_SCROLLBACK", STR_TYPE_VAR, 0, 0, NULL, build_status, 0, 0 },
262 { "STATUS_SERVER", STR_TYPE_VAR, 0, 0, NULL, build_status, 0, 0 },
263 { "STATUS_SSL_OFF", STR_TYPE_VAR, 0, 0, NULL, build_status, 0, 0 },
264 { "STATUS_SSL_ON", STR_TYPE_VAR, 0, 0, NULL, build_status, 0, 0 },
265 { "STATUS_TRUNCATE_RHS", BOOL_TYPE_VAR, DEFAULT_STATUS_TRUNCATE_RHS, 0, NULL, build_status, 0, 0 },
266 { "STATUS_UMODE", STR_TYPE_VAR, 0, 0, NULL, build_status, 0, 0 },
267 { "STATUS_USER", STR_TYPE_VAR, 0, 0, NULL, build_status, 0, 0 },
268 { "STATUS_USER1", STR_TYPE_VAR, 0, 0, NULL, build_status, 0, 0 },
269 { "STATUS_USER10", STR_TYPE_VAR, 0, 0, NULL, build_status, 0, 0 },
270 { "STATUS_USER11", STR_TYPE_VAR, 0, 0, NULL, build_status, 0, 0 },
271 { "STATUS_USER12", STR_TYPE_VAR, 0, 0, NULL, build_status, 0, 0 },
272 { "STATUS_USER13", STR_TYPE_VAR, 0, 0, NULL, build_status, 0, 0 },
273 { "STATUS_USER14", STR_TYPE_VAR, 0, 0, NULL, build_status, 0, 0 },
274 { "STATUS_USER15", STR_TYPE_VAR, 0, 0, NULL, build_status, 0, 0 },
275 { "STATUS_USER16", STR_TYPE_VAR, 0, 0, NULL, build_status, 0, 0 },
276 { "STATUS_USER17", STR_TYPE_VAR, 0, 0, NULL, build_status, 0, 0 },
277 { "STATUS_USER18", STR_TYPE_VAR, 0, 0, NULL, build_status, 0, 0 },
278 { "STATUS_USER19", STR_TYPE_VAR, 0, 0, NULL, build_status, 0, 0 },
279 { "STATUS_USER2", STR_TYPE_VAR, 0, 0, NULL, build_status, 0, 0 },
280 { "STATUS_USER20", STR_TYPE_VAR, 0, 0, NULL, build_status, 0, 0 },
281 { "STATUS_USER21", STR_TYPE_VAR, 0, 0, NULL, build_status, 0, 0 },
282 { "STATUS_USER22", STR_TYPE_VAR, 0, 0, NULL, build_status, 0, 0 },
283 { "STATUS_USER23", STR_TYPE_VAR, 0, 0, NULL, build_status, 0, 0 },
284 { "STATUS_USER24", STR_TYPE_VAR, 0, 0, NULL, build_status, 0, 0 },
285 { "STATUS_USER25", STR_TYPE_VAR, 0, 0, NULL, build_status, 0, 0 },
286 { "STATUS_USER26", STR_TYPE_VAR, 0, 0, NULL, build_status, 0, 0 },
287 { "STATUS_USER27", STR_TYPE_VAR, 0, 0, NULL, build_status, 0, 0 },
288 { "STATUS_USER28", STR_TYPE_VAR, 0, 0, NULL, build_status, 0, 0 },
289 { "STATUS_USER29", STR_TYPE_VAR, 0, 0, NULL, build_status, 0, 0 },
290 { "STATUS_USER3", STR_TYPE_VAR, 0, 0, NULL, build_status, 0, 0 },
291 { "STATUS_USER30", STR_TYPE_VAR, 0, 0, NULL, build_status, 0, 0 },
292 { "STATUS_USER31", STR_TYPE_VAR, 0, 0, NULL, build_status, 0, 0 },
293 { "STATUS_USER32", STR_TYPE_VAR, 0, 0, NULL, build_status, 0, 0 },
294 { "STATUS_USER33", STR_TYPE_VAR, 0, 0, NULL, build_status, 0, 0 },
295 { "STATUS_USER34", STR_TYPE_VAR, 0, 0, NULL, build_status, 0, 0 },
296 { "STATUS_USER35", STR_TYPE_VAR, 0, 0, NULL, build_status, 0, 0 },
297 { "STATUS_USER36", STR_TYPE_VAR, 0, 0, NULL, build_status, 0, 0 },
298 { "STATUS_USER37", STR_TYPE_VAR, 0, 0, NULL, build_status, 0, 0 },
299 { "STATUS_USER38", STR_TYPE_VAR, 0, 0, NULL, build_status, 0, 0 },
300 { "STATUS_USER39", STR_TYPE_VAR, 0, 0, NULL, build_status, 0, 0 },
301 { "STATUS_USER4", STR_TYPE_VAR, 0, 0, NULL, build_status, 0, 0 },
302 { "STATUS_USER5", STR_TYPE_VAR, 0, 0, NULL, build_status, 0, 0 },
303 { "STATUS_USER6", STR_TYPE_VAR, 0, 0, NULL, build_status, 0, 0 },
304 { "STATUS_USER7", STR_TYPE_VAR, 0, 0, NULL, build_status, 0, 0 },
305 { "STATUS_USER8", STR_TYPE_VAR, 0, 0, NULL, build_status, 0, 0 },
306 { "STATUS_USER9", STR_TYPE_VAR, 0, 0, NULL, build_status, 0, 0 },
307 { "STATUS_VOICE", STR_TYPE_VAR, 0, 0, NULL, build_status, 0, 0 },
308 { "STATUS_WINDOW", STR_TYPE_VAR, 0, 0, NULL, build_status, 0, 0 },
309 { "SUPPRESS_FROM_REMOTE_SERVER",BOOL_TYPE_VAR, DEFAULT_SUPPRESS_FROM_REMOTE_SERVER, 0, NULL, NULL, 0, 0},
310 { "SWITCH_CHANNELS_BETWEEN_WINDOWS", BOOL_TYPE_VAR, DEFAULT_SWITCH_CHANNELS_BETWEEN_WINDOWS, 0, NULL, NULL, 0, 0 },
311 { "SWITCH_CHANNEL_ON_PART", BOOL_TYPE_VAR, DEFAULT_SWITCH_CHANNEL_ON_PART, 0, NULL, NULL, 0, 0 },
312 { "TAB", BOOL_TYPE_VAR, DEFAULT_TAB, 0, NULL, NULL, 0, 0 },
313 { "TAB_MAX", INT_TYPE_VAR, DEFAULT_TAB_MAX, 0, NULL, NULL, 0, 0 },
314 { "TERM_DOES_BRIGHT_BLINK", BOOL_TYPE_VAR, DEFAULT_TERM_DOES_BRIGHT_BLINK, 0, NULL, NULL, 0, 0 },
315 { "TRANSLATION", STR_TYPE_VAR, 0, 0, NULL, set_translation, 0, 0 },
316 { "TRANSLATION_PATH", STR_TYPE_VAR, 0, 0, NULL, NULL, 0, 0 },
317 { "UNDERLINE_VIDEO", BOOL_TYPE_VAR, DEFAULT_UNDERLINE_VIDEO, 0, NULL, NULL, 0, 0 },
318 { "USER_INFORMATION", STR_TYPE_VAR, 0, 0, NULL, NULL, 0, 0 },
319 { "VERBOSE_CTCP", BOOL_TYPE_VAR, DEFAULT_VERBOSE_CTCP, 0, NULL, NULL, 0, 0 },
320 { "WORD_BREAK", STR_TYPE_VAR, 0, 0, NULL, NULL, 0, 0 },
321 { "WSERV_PATH", STR_TYPE_VAR, 0, 0, NULL, NULL, 0, 0 },
322 { "WSERV_TYPE", STR_TYPE_VAR, 0, 0, NULL, set_wserv_type, 0, 0 },
323 { "XTERM", STR_TYPE_VAR, 0, 0, NULL, NULL, 0, 0 },
324 { "XTERM_OPTIONS", STR_TYPE_VAR, 0, 0, NULL, NULL, 0, 0 },
325 { (char *) 0, 0, 0, 0, 0, 0, 0, 0 }
326 };
327
328 /*
329 * init_variables: initializes the string variables that can't really be
330 * initialized properly above
331 */
init_variables(void)332 void init_variables (void)
333 {
334 char *s;
335 int i;
336
337 for (i = 1; i < NUMBER_OF_VARIABLES - 1; i++)
338 if (strcmp(irc_variable[i-1].name, irc_variable[i].name) >= 0)
339 panic("Variable [%d] (%s) is out of order.", i, irc_variable[i].name);
340
341 set_string_var(BANNER_VAR, DEFAULT_BANNER);
342 set_string_var(BEEP_ON_MSG_VAR, DEFAULT_BEEP_ON_MSG);
343 set_string_var(CMDCHARS_VAR, DEFAULT_CMDCHARS);
344 set_string_var(CURRENT_WINDOW_LEVEL_VAR, DEFAULT_CURRENT_WINDOW_LEVEL);
345 set_string_var(LOGFILE_VAR, DEFAULT_LOGFILE);
346 set_string_var(SHELL_VAR, DEFAULT_SHELL);
347 set_string_var(SHELL_FLAGS_VAR, DEFAULT_SHELL_FLAGS);
348 set_string_var(CONTINUED_LINE_VAR, DEFAULT_CONTINUED_LINE);
349 set_string_var(INPUT_PROMPT_VAR, DEFAULT_INPUT_PROMPT);
350 set_string_var(HIGHLIGHT_CHAR_VAR, DEFAULT_HIGHLIGHT_CHAR);
351 set_string_var(LASTLOG_LEVEL_VAR, DEFAULT_LASTLOG_LEVEL);
352 set_string_var(LOG_REWRITE_VAR, NULL);
353 set_string_var(MAIL_TYPE_VAR, DEFAULT_MAIL_TYPE);
354 set_string_var(MANGLE_INBOUND_VAR, NULL);
355 set_string_var(MANGLE_LOGFILES_VAR, NULL);
356 set_string_var(MANGLE_OUTBOUND_VAR, NULL);
357 set_string_var(NEW_SERVER_LASTLOG_LEVEL_VAR,
358 DEFAULT_NEW_SERVER_LASTLOG_LEVEL);
359 set_string_var(NOTIFY_LEVEL_VAR, DEFAULT_NOTIFY_LEVEL);
360 set_string_var(OUTPUT_REWRITE_VAR, NULL);
361 set_string_var(QUIT_MESSAGE_VAR, DEFAULT_QUIT_MESSAGE);
362 set_string_var(REALNAME_VAR, realname);
363 set_string_var(SSL_CERTFILE_VAR, NULL);
364 set_string_var(SSL_KEYFILE_VAR, NULL);
365 set_string_var(SSL_PATH_VAR, NULL);
366 set_string_var(STATUS_FORMAT_VAR, DEFAULT_STATUS_FORMAT);
367 set_string_var(STATUS_FORMAT1_VAR, DEFAULT_STATUS_FORMAT1);
368 set_string_var(STATUS_FORMAT2_VAR, DEFAULT_STATUS_FORMAT2);
369 set_string_var(STATUS_AWAY_VAR, DEFAULT_STATUS_AWAY);
370 set_string_var(STATUS_CHANNEL_VAR, DEFAULT_STATUS_CHANNEL);
371 set_string_var(STATUS_CHANOP_VAR, DEFAULT_STATUS_CHANOP);
372 set_string_var(STATUS_HALFOP_VAR, DEFAULT_STATUS_HALFOP);
373 set_string_var(STATUS_SSL_ON_VAR, DEFAULT_STATUS_SSL_ON);
374 set_string_var(STATUS_SSL_OFF_VAR, DEFAULT_STATUS_SSL_OFF);
375 set_string_var(STATUS_CLOCK_VAR, DEFAULT_STATUS_CLOCK);
376 set_string_var(STATUS_CPU_SAVER_VAR, DEFAULT_STATUS_CPU_SAVER);
377 set_string_var(STATUS_HOLD_VAR, DEFAULT_STATUS_HOLD);
378 set_string_var(STATUS_HOLD_LINES_VAR, DEFAULT_STATUS_HOLD_LINES);
379 set_string_var(STATUS_INSERT_VAR, DEFAULT_STATUS_INSERT);
380 set_string_var(STATUS_MAIL_VAR, DEFAULT_STATUS_MAIL);
381 set_string_var(STATUS_MODE_VAR, DEFAULT_STATUS_MODE);
382 set_string_var(STATUS_NICK_VAR, DEFAULT_STATUS_NICK);
383 set_string_var(STATUS_NOSWAP_VAR, DEFAULT_STATUS_NOSWAP);
384 set_string_var(STATUS_OPER_VAR, DEFAULT_STATUS_OPER);
385 set_string_var(STATUS_OVERWRITE_VAR, DEFAULT_STATUS_OVERWRITE);
386 set_string_var(STATUS_QUERY_VAR, DEFAULT_STATUS_QUERY);
387 set_string_var(STATUS_SCROLLBACK_VAR, DEFAULT_STATUS_SCROLLBACK);
388 set_string_var(STATUS_SERVER_VAR, DEFAULT_STATUS_SERVER);
389 set_string_var(STATUS_UMODE_VAR, DEFAULT_STATUS_UMODE);
390 set_string_var(STATUS_USER0_VAR, DEFAULT_STATUS_USER);
391 set_string_var(STATUS_USER1_VAR, DEFAULT_STATUS_USER1);
392 set_string_var(STATUS_USER2_VAR, DEFAULT_STATUS_USER2);
393 set_string_var(STATUS_USER3_VAR, DEFAULT_STATUS_USER3);
394 set_string_var(STATUS_USER4_VAR, DEFAULT_STATUS_USER4);
395 set_string_var(STATUS_USER5_VAR, DEFAULT_STATUS_USER5);
396 set_string_var(STATUS_USER6_VAR, DEFAULT_STATUS_USER6);
397 set_string_var(STATUS_USER7_VAR, DEFAULT_STATUS_USER7);
398 set_string_var(STATUS_USER8_VAR, DEFAULT_STATUS_USER8);
399 set_string_var(STATUS_USER9_VAR, DEFAULT_STATUS_USER9);
400 set_string_var(STATUS_USER10_VAR, DEFAULT_STATUS_USER10);
401 set_string_var(STATUS_USER11_VAR, DEFAULT_STATUS_USER11);
402 set_string_var(STATUS_USER12_VAR, DEFAULT_STATUS_USER12);
403 set_string_var(STATUS_USER13_VAR, DEFAULT_STATUS_USER13);
404 set_string_var(STATUS_USER14_VAR, DEFAULT_STATUS_USER14);
405 set_string_var(STATUS_USER15_VAR, DEFAULT_STATUS_USER15);
406 set_string_var(STATUS_USER16_VAR, DEFAULT_STATUS_USER16);
407 set_string_var(STATUS_USER17_VAR, DEFAULT_STATUS_USER17);
408 set_string_var(STATUS_USER18_VAR, DEFAULT_STATUS_USER18);
409 set_string_var(STATUS_USER19_VAR, DEFAULT_STATUS_USER19);
410 set_string_var(STATUS_USER20_VAR, DEFAULT_STATUS_USER20);
411 set_string_var(STATUS_USER21_VAR, DEFAULT_STATUS_USER21);
412 set_string_var(STATUS_USER22_VAR, DEFAULT_STATUS_USER22);
413 set_string_var(STATUS_USER23_VAR, DEFAULT_STATUS_USER23);
414 set_string_var(STATUS_USER24_VAR, DEFAULT_STATUS_USER24);
415 set_string_var(STATUS_USER25_VAR, DEFAULT_STATUS_USER25);
416 set_string_var(STATUS_USER26_VAR, DEFAULT_STATUS_USER26);
417 set_string_var(STATUS_USER27_VAR, DEFAULT_STATUS_USER27);
418 set_string_var(STATUS_USER28_VAR, DEFAULT_STATUS_USER28);
419 set_string_var(STATUS_USER29_VAR, DEFAULT_STATUS_USER29);
420 set_string_var(STATUS_USER30_VAR, DEFAULT_STATUS_USER30);
421 set_string_var(STATUS_USER31_VAR, DEFAULT_STATUS_USER31);
422 set_string_var(STATUS_USER32_VAR, DEFAULT_STATUS_USER32);
423 set_string_var(STATUS_USER33_VAR, DEFAULT_STATUS_USER33);
424 set_string_var(STATUS_USER34_VAR, DEFAULT_STATUS_USER34);
425 set_string_var(STATUS_USER35_VAR, DEFAULT_STATUS_USER35);
426 set_string_var(STATUS_USER36_VAR, DEFAULT_STATUS_USER36);
427 set_string_var(STATUS_USER37_VAR, DEFAULT_STATUS_USER37);
428 set_string_var(STATUS_USER38_VAR, DEFAULT_STATUS_USER38);
429 set_string_var(STATUS_USER39_VAR, DEFAULT_STATUS_USER39);
430 set_string_var(STATUS_VOICE_VAR, DEFAULT_STATUS_VOICE);
431 set_string_var(STATUS_WINDOW_VAR, DEFAULT_STATUS_WINDOW);
432 set_string_var(TRANSLATION_VAR, NULL);
433 set_string_var(USERINFO_VAR, DEFAULT_USERINFO);
434 set_string_var(XTERM_VAR, DEFAULT_XTERM);
435 set_string_var(XTERM_OPTIONS_VAR, DEFAULT_XTERM_OPTIONS);
436 set_string_var(STATUS_NOTIFY_VAR, DEFAULT_STATUS_NOTIFY);
437 set_string_var(CLIENTINFO_VAR, IRCII_COMMENT);
438 set_string_var(WORD_BREAK_VAR, DEFAULT_WORD_BREAK);
439 set_string_var(WSERV_PATH_VAR, WSERV_PATH);
440 set_string_var(WSERV_TYPE_VAR, DEFAULT_WSERV_TYPE);
441
442 /*
443 * Construct the default help path
444 */
445 s = malloc_strdup(irc_lib);
446 malloc_strcat(&s, "/help");
447 set_string_var(HELP_PATH_VAR, s);
448 new_free(&s);
449
450 /*
451 * Forcibly init all the variables
452 */
453 for (i = 0; i < NUMBER_OF_VARIABLES; i++)
454 {
455 IrcVariable *var = &irc_variable[i];
456
457 if (var->func)
458 {
459 if (var->func == build_status)
460 continue;
461 if (var->func == update_all_status_wrapper)
462 continue;
463
464 var->flags |= VIF_PENDING;
465 switch (var->type)
466 {
467 case (BOOL_TYPE_VAR):
468 case (INT_TYPE_VAR):
469 case (CHAR_TYPE_VAR):
470 var->func(&var->integer);
471 break;
472 case (FLOAT_TYPE_VAR):
473 var->func(&var->number);
474 break;
475 case (STR_TYPE_VAR):
476 var->func(var->string);
477 break;
478 }
479 var->flags &= ~VIF_PENDING;
480 }
481 }
482 }
483
484 /*
485 * do_boolean: just a handy thing. Returns 1 if the str is not ON, OFF, or
486 * TOGGLE
487 */
do_boolean(char * str,int * value)488 int do_boolean (char *str, int *value)
489 {
490 upper(str);
491 if (strcmp(str, var_settings[ON]) == 0)
492 *value = 1;
493 else if (strcmp(str, var_settings[OFF]) == 0)
494 *value = 0;
495 else if (strcmp(str, "TOGGLE") == 0)
496 {
497 if (*value)
498 *value = 0;
499 else
500 *value = 1;
501 }
502 else
503 return (1);
504 return (0);
505 }
506
507 /*
508 * get_variable_index: converts a string into an offset into the set table.
509 * Returns NUMBER_OF_VARIABLES if varname doesn't exist.
510 */
get_variable_index(const char * varname)511 static enum VAR_TYPES get_variable_index (const char *varname)
512 {
513 enum VAR_TYPES retval;
514 int cnt;
515
516 find_fixed_array_item(irc_variable, sizeof(IrcVariable),
517 NUMBER_OF_VARIABLES, varname, &cnt,
518 (int *)&retval);
519
520 if (cnt < 0)
521 return retval;
522
523 return NUMBER_OF_VARIABLES;
524 }
525
526 /*
527 * set_var_value: Given the variable structure and the string representation
528 * of the value, this sets the value in the most verbose and error checking
529 * of manors. It displays the results of the set and executes the function
530 * defined in the var structure
531 */
set_var_value(int svv_index,char * value)532 void set_var_value (int svv_index, char *value)
533 {
534 char *rest;
535 IrcVariable *var;
536 int old;
537
538 var = &(irc_variable[svv_index]);
539 switch (var->type)
540 {
541 case BOOL_TYPE_VAR:
542 {
543 if (value && *value && (value = next_arg(value, &rest)))
544 {
545 old = var->integer;
546 if (do_boolean(value, &(var->integer)))
547 {
548 say("Value must be either ON, OFF, or TOGGLE");
549 break;
550 }
551 if (!(var->int_flags & VIF_CHANGED))
552 {
553 if (old != var->integer)
554 var->int_flags |= VIF_CHANGED;
555 }
556 if (loading_global)
557 var->int_flags |= VIF_GLOBAL;
558 if (var->func)
559 (var->func) (&var->integer);
560 say("Value of %s set to %s", var->name,
561 var->integer ? var_settings[ON]
562 : var_settings[OFF]);
563 }
564 else
565 say("Current value of %s is %s", var->name,
566 (var->integer) ?
567 var_settings[ON] : var_settings[OFF]);
568 break;
569 }
570 case CHAR_TYPE_VAR:
571 {
572 if (!value)
573 {
574 if (!(var->int_flags & VIF_CHANGED))
575 {
576 if (var->integer)
577 var->int_flags |= VIF_CHANGED;
578 }
579 if (loading_global)
580 var->int_flags |= VIF_GLOBAL;
581 var->integer = ' ';
582 if (var->func)
583 (var->func) (&var->integer);
584 say("Value of %s set to '%c'", var->name, var->integer);
585 }
586
587
588 else if (value && *value && (value = next_arg(value, &rest)))
589 {
590 if (strlen(value) > 1)
591 say("Value of %s must be a single character",
592 var->name);
593 else
594 {
595 if (!(var->int_flags & VIF_CHANGED))
596 {
597 if (var->integer != *value)
598 var->int_flags |= VIF_CHANGED;
599 }
600 if (loading_global)
601 var->int_flags |= VIF_GLOBAL;
602 var->integer = *value;
603 if (var->func)
604 (var->func) (&var->integer);
605 say("Value of %s set to '%c'", var->name,
606 var->integer);
607 }
608 }
609 else
610 say("Current value of %s is '%c'", var->name,
611 var->integer);
612 break;
613 }
614 case INT_TYPE_VAR:
615 {
616 if (value && *value && (value = next_arg(value, &rest)))
617 {
618 int val;
619
620 if (!is_number(value))
621 {
622 say("Value of %s must be numeric!", var->name);
623 break;
624 }
625 if ((val = my_atol(value)) < 0)
626 {
627 say("Value of %s must be a non-negative number", var->name);
628 break;
629 }
630 if (!(var->int_flags & VIF_CHANGED))
631 {
632 if (var->integer != val)
633 var->int_flags |= VIF_CHANGED;
634 }
635 if (loading_global)
636 var->int_flags |= VIF_GLOBAL;
637 var->integer = val;
638 if (var->func)
639 (var->func) (&var->integer);
640 say("Value of %s set to %d", var->name, var->integer);
641 }
642 else
643 say("Current value of %s is %d", var->name, var->integer);
644 break;
645 }
646 case FLOAT_TYPE_VAR:
647 {
648 if (value && *value && (value = next_arg(value, &rest)))
649 {
650 int val;
651
652 if (!is_real_number(value))
653 {
654 say("Value of %s must be numeric!", var->name);
655 break;
656 }
657 val = atof(value);
658 if (!(var->int_flags & VIF_CHANGED))
659 {
660 if (var->number != val)
661 var->int_flags |= VIF_CHANGED;
662 }
663 if (loading_global)
664 var->int_flags |= VIF_GLOBAL;
665 var->number = val;
666 if (var->func)
667 (var->func) (&var->number);
668 say("Value of %s set to %f", var->name, var->number);
669 }
670 else
671 say("Current value of %s is %f", var->name, var->number);
672 break;
673 }
674 case STR_TYPE_VAR:
675 {
676 if (value)
677 {
678 if (*value)
679 {
680 if ((!var->int_flags & VIF_CHANGED))
681 {
682 if ((var->string && !value) ||
683 (!var->string && value) ||
684 my_stricmp(var->string, value))
685 var->int_flags |= VIF_CHANGED;
686 }
687 if (loading_global)
688 var->int_flags |= VIF_GLOBAL;
689 malloc_strcpy(&(var->string), value);
690 }
691 else
692 {
693 if (var->string)
694 say("Current value of %s is %s",
695 var->name, var->string);
696 else
697 say("No value for %s has been set",
698 var->name);
699 return;
700 }
701 }
702 else
703 new_free(&(var->string));
704
705 if (var->func && !(var->int_flags & VIF_PENDING))
706 {
707 var->int_flags |= VIF_PENDING;
708 (var->func) (var->string);
709 var->int_flags &= ~VIF_PENDING;
710 }
711
712 say("Value of %s set to %s", var->name, var->string ?
713 var->string : "<EMPTY>");
714 break;
715 }
716 }
717 }
718
719 /*
720 * set_variable: The SET command sets one of the irc variables. The args
721 * should consist of "variable-name setting", where variable name can be
722 * partial, but non-ambbiguous, and setting depends on the variable being set
723 */
BUILT_IN_COMMAND(setcmd)724 BUILT_IN_COMMAND(setcmd)
725 {
726 char *var = NULL;
727 int cnt;
728 enum VAR_TYPES sv_index;
729 int hook = 0;
730
731 /*
732 * XXX Ugh. This is a hideous offense of good taste which is
733 * necessary to support set's abominable syntax, particularly
734 * acute with /set continued_line<space><space>
735 */
736 while (args && *args && isspace(*args))
737 args++;
738 var = args;
739 while (args && *args && !isspace(*args))
740 args++;
741 if (args && *args)
742 *args++ = 0;
743
744 if (var && *var)
745 {
746 if (*var == '-')
747 {
748 var++;
749 args = (char *) 0;
750 }
751
752 /* Exact match? */
753 upper(var);
754 find_fixed_array_item (irc_variable, sizeof(IrcVariable), NUMBER_OF_VARIABLES, var, &cnt, (int *)&sv_index);
755
756 if (cnt == 1)
757 cnt = -1;
758
759 if ((cnt >= 0) || !(irc_variable[sv_index].int_flags & VIF_PENDING))
760 hook = 1;
761
762 if (cnt < 0)
763 irc_variable[sv_index].int_flags |= VIF_PENDING;
764
765 if (hook)
766 {
767 hook = do_hook(SET_LIST, "%s %s",
768 var, args ? args : "<unset>");
769
770 if (hook && (cnt < 0))
771 {
772 hook = do_hook(SET_LIST, "%s %s",
773 irc_variable[sv_index].name,
774 args ? args : "<unset>");
775 }
776 }
777
778 if (cnt < 0)
779 irc_variable[sv_index].int_flags &= ~VIF_PENDING;
780
781 if (hook)
782 {
783 if (cnt < 0)
784 set_var_value(sv_index, args);
785 else if (cnt == 0)
786 {
787 if (do_hook(SET_LIST, "set-error No such variable \"%s\"", var))
788 say("No such variable \"%s\"", var);
789 }
790 else
791 {
792 if (do_hook(SET_LIST, "set-error %s is ambiguous", var))
793 {
794 say("%s is ambiguous", var);
795 for (cnt += sv_index; (int)sv_index < cnt; sv_index = (enum VAR_TYPES)(sv_index + 1))
796 set_var_value(sv_index, empty_string);
797 }
798 }
799 }
800 }
801 else
802 {
803 int var_index;
804 for (var_index = 0; var_index < NUMBER_OF_VARIABLES; var_index++)
805 set_var_value(var_index, empty_string);
806 }
807 }
808
809 /*
810 * get_string_var: returns the value of the string variable given as an index
811 * into the variable table. Does no checking of variable types, etc
812 */
get_string_var(enum VAR_TYPES var)813 char * get_string_var (enum VAR_TYPES var)
814 {
815 return (irc_variable[var].string);
816 }
817
818 /*
819 * get_int_var: returns the value of the integer string given as an index
820 * into the variable table. Does no checking of variable types, etc
821 */
get_int_var(enum VAR_TYPES var)822 int get_int_var (enum VAR_TYPES var)
823 {
824 return (irc_variable[var].integer);
825 }
826
827 /*
828 * get_int_var: returns the value of the integer string given as an index
829 * into the variable table. Does no checking of variable types, etc
830 */
get_float_var(enum VAR_TYPES var)831 double get_float_var (enum VAR_TYPES var)
832 {
833 return (irc_variable[var].number);
834 }
835
836 /*
837 * set_string_var: sets the string variable given as an index into the
838 * variable table to the given string. If string is null, the current value
839 * of the string variable is freed and set to null
840 */
set_string_var(enum VAR_TYPES var,const char * string)841 void set_string_var (enum VAR_TYPES var, const char *string)
842 {
843 if (string)
844 malloc_strcpy(&(irc_variable[var].string), string);
845 else
846 new_free(&(irc_variable[var].string));
847 }
848
849 /* Same story, second verse. */
set_int_var(enum VAR_TYPES var,int value)850 void set_int_var (enum VAR_TYPES var, int value)
851 {
852 irc_variable[var].integer = value;
853 }
854
855 /* Same story, second verse. */
set_float_var(enum VAR_TYPES var,double value)856 void set_float_var (enum VAR_TYPES var, double value)
857 {
858 irc_variable[var].number = value;
859 }
860
861 /*
862 * save_variables: this writes all of the IRCII variables to the given FILE
863 * pointer in such a way that they can be loaded in using LOAD or the -l switch
864 */
save_variables(FILE * fp,int do_all)865 void save_variables (FILE *fp, int do_all)
866 {
867 IrcVariable *var;
868
869 for (var = irc_variable; var->name; var++)
870 {
871 if (!(var->int_flags & VIF_CHANGED))
872 continue;
873 if (do_all || !(var->int_flags & VIF_GLOBAL))
874 {
875 if (strcmp(var->name, "DISPLAY") == 0 || strcmp(var->name, "CLIENT_INFORMATION") == 0)
876 continue;
877 fprintf(fp, "SET ");
878 switch (var->type)
879 {
880 case BOOL_TYPE_VAR:
881 fprintf(fp, "%s %s\n", var->name, var->integer ?
882 var_settings[ON] : var_settings[OFF]);
883 break;
884 case CHAR_TYPE_VAR:
885 fprintf(fp, "%s %c\n", var->name, var->integer);
886 break;
887 case INT_TYPE_VAR:
888 fprintf(fp, "%s %u\n", var->name, var->integer);
889 break;
890 case FLOAT_TYPE_VAR:
891 fprintf(fp, "%s %f\n", var->name, var->number);
892 break;
893 case STR_TYPE_VAR:
894 if (var->string)
895 fprintf(fp, "%s %s\n", var->name,
896 var->string);
897 else
898 fprintf(fp, "-%s\n", var->name);
899 break;
900 }
901 }
902 }
903 }
904
make_string_var(const char * var_name)905 char *make_string_var (const char *var_name)
906 {
907 enum VAR_TYPES msv_index;
908 char *ret = (char *) 0;
909 char *copy;
910
911 copy = LOCAL_COPY(var_name);
912 upper(copy);
913
914 msv_index = get_variable_index(copy);
915 if (msv_index == NUMBER_OF_VARIABLES)
916 return NULL;
917
918 switch (irc_variable[msv_index].type)
919 {
920 case STR_TYPE_VAR:
921 if (irc_variable[msv_index].string)
922 ret = malloc_strdup(irc_variable[msv_index].string);
923 break;
924 case INT_TYPE_VAR:
925 ret = malloc_strdup(ltoa(irc_variable[msv_index].integer));
926 break;
927 case FLOAT_TYPE_VAR:
928 ret = malloc_strdup(ftoa(irc_variable[msv_index].number));
929 break;
930 case BOOL_TYPE_VAR:
931 ret = malloc_strdup(var_settings[irc_variable[msv_index].integer]);
932 break;
933 case CHAR_TYPE_VAR:
934 ret = malloc_dupchar(irc_variable[msv_index].integer);
935 break;
936 }
937 return (ret);
938
939 }
940
GET_FIXED_ARRAY_NAMES_FUNCTION(get_set,irc_variable)941 GET_FIXED_ARRAY_NAMES_FUNCTION(get_set, irc_variable)
942
943 /* returns the size of the character set */
944 int charset_size (void)
945 {
946 return get_int_var(EIGHT_BIT_CHARACTERS_VAR) ? 256 : 128;
947 }
948
eight_bit_characters(const void * stuff)949 static void eight_bit_characters (const void *stuff)
950 {
951 int value = *(const int *)stuff;
952
953 if (value == ON && !term_eight_bit())
954 say("Warning! Your terminal says it does not support eight bit characters");
955 set_term_eight_bit(value);
956 }
957
set_realname(const void * stuff)958 static void set_realname (const void *stuff)
959 {
960 const char *value = (const char *)stuff;
961
962 if (!value)
963 {
964 say("Unsetting your realname will do you no good. So there.");
965 value = empty_string;
966 }
967 strlcpy(realname, value, sizeof realname);
968 }
969
set_display_pc_characters(const void * stuff)970 static void set_display_pc_characters (const void *stuff)
971 {
972 int value = *(const int *)stuff;
973
974 if (value < 0 || value > 5)
975 {
976 say("The value of DISPLAY_PC_CHARACTERS must be between 0 and 5 inclusive");
977 set_int_var(DISPLAY_PC_CHARACTERS_VAR, 0);
978 }
979 }
980
set_dcc_timeout(const void * stuff)981 static void set_dcc_timeout (const void *stuff)
982 {
983 int value = *(const int *)stuff;
984
985 if (value == 0)
986 dcc_timeout = (time_t) -1;
987 else
988 dcc_timeout = value;
989 }
990
parse_mangle(const char * value,int nvalue,char ** rv)991 int parse_mangle (const char *value, int nvalue, char **rv)
992 {
993 char *str1, *str2;
994 char *copy;
995 char *nv = NULL;
996
997 if (rv)
998 *rv = NULL;
999
1000 if (!value)
1001 return 0;
1002
1003 copy = LOCAL_COPY(value);
1004
1005 while ((str1 = new_next_arg(copy, ©)))
1006 {
1007 while (*str1 && (str2 = next_in_comma_list(str1, &str1)))
1008 {
1009 if (!my_strnicmp(str2, "ALL_OFF", 4))
1010 nvalue |= STRIP_ALL_OFF;
1011 else if (!my_strnicmp(str2, "-ALL_OFF", 5))
1012 nvalue &= ~(STRIP_ALL_OFF);
1013 else if (!my_strnicmp(str2, "ALL", 3))
1014 nvalue = (0x7FFFFFFF ^ (MANGLE_ESCAPES) ^ (STRIP_OTHER));
1015 else if (!my_strnicmp(str2, "-ALL", 4))
1016 nvalue = 0;
1017 else if (!my_strnicmp(str2, "ALT_CHAR", 3))
1018 nvalue |= STRIP_ALT_CHAR;
1019 else if (!my_strnicmp(str2, "-ALT_CHAR", 4))
1020 nvalue &= ~(STRIP_ALT_CHAR);
1021 else if (!my_strnicmp(str2, "ANSI", 2))
1022 nvalue |= MANGLE_ANSI_CODES;
1023 else if (!my_strnicmp(str2, "-ANSI", 3))
1024 nvalue &= ~(MANGLE_ANSI_CODES);
1025 else if (!my_strnicmp(str2, "BLINK", 2))
1026 nvalue |= STRIP_BLINK;
1027 else if (!my_strnicmp(str2, "-BLINK", 3))
1028 nvalue &= ~(STRIP_BLINK);
1029 else if (!my_strnicmp(str2, "BOLD", 2))
1030 nvalue |= STRIP_BOLD;
1031 else if (!my_strnicmp(str2, "-BOLD", 3))
1032 nvalue &= ~(STRIP_BOLD);
1033 else if (!my_strnicmp(str2, "COLOR", 1))
1034 nvalue |= STRIP_COLOR;
1035 else if (!my_strnicmp(str2, "-COLOR", 2))
1036 nvalue &= ~(STRIP_COLOR);
1037 else if (!my_strnicmp(str2, "ESCAPE", 1))
1038 nvalue |= MANGLE_ESCAPES;
1039 else if (!my_strnicmp(str2, "-ESCAPE", 2))
1040 nvalue &= ~(MANGLE_ESCAPES);
1041 else if (!my_strnicmp(str2, "ND_SPACE", 2))
1042 nvalue |= STRIP_ND_SPACE;
1043 else if (!my_strnicmp(str2, "-ND_SPACE", 3))
1044 nvalue &= ~(STRIP_ND_SPACE);
1045 else if (!my_strnicmp(str2, "NONE", 2))
1046 nvalue = 0;
1047 else if (!my_strnicmp(str2, "OTHER", 2))
1048 nvalue |= STRIP_OTHER;
1049 else if (!my_strnicmp(str2, "-OTHER", 3))
1050 nvalue &= ~(STRIP_OTHER);
1051 else if (!my_strnicmp(str2, "REVERSE", 2))
1052 nvalue |= STRIP_REVERSE;
1053 else if (!my_strnicmp(str2, "-REVERSE", 3))
1054 nvalue &= ~(STRIP_REVERSE);
1055 else if (!my_strnicmp(str2, "ROM_CHAR", 2))
1056 nvalue |= STRIP_ROM_CHAR;
1057 else if (!my_strnicmp(str2, "-ROM_CHAR", 3))
1058 nvalue &= ~(STRIP_ROM_CHAR);
1059 else if (!my_strnicmp(str2, "UNDERLINE", 1))
1060 nvalue |= STRIP_UNDERLINE;
1061 else if (!my_strnicmp(str2, "-UNDERLINE", 2))
1062 nvalue &= ~(STRIP_UNDERLINE);
1063 }
1064 }
1065
1066 if (rv)
1067 {
1068 if (nvalue & MANGLE_ESCAPES)
1069 malloc_strcat_wordlist(&nv, comma, "ESCAPE");
1070 if (nvalue & MANGLE_ANSI_CODES)
1071 malloc_strcat_wordlist(&nv, comma, "ANSI");
1072 if (nvalue & STRIP_COLOR)
1073 malloc_strcat_wordlist(&nv, comma, "COLOR");
1074 if (nvalue & STRIP_REVERSE)
1075 malloc_strcat_wordlist(&nv, comma, "REVERSE");
1076 if (nvalue & STRIP_UNDERLINE)
1077 malloc_strcat_wordlist(&nv, comma, "UNDERLINE");
1078 if (nvalue & STRIP_BOLD)
1079 malloc_strcat_wordlist(&nv, comma, "BOLD");
1080 if (nvalue & STRIP_BLINK)
1081 malloc_strcat_wordlist(&nv, comma, "BLINK");
1082 if (nvalue & STRIP_ALT_CHAR)
1083 malloc_strcat_wordlist(&nv, comma, "ALT_CHAR");
1084 if (nvalue & STRIP_ROM_CHAR)
1085 malloc_strcat_wordlist(&nv, comma, "ROM_CHAR");
1086 if (nvalue & STRIP_ND_SPACE)
1087 malloc_strcat_wordlist(&nv, comma, "ND_SPACE");
1088 if (nvalue & STRIP_ALL_OFF)
1089 malloc_strcat_wordlist(&nv, comma, "ALL_OFF");
1090 if (nvalue & STRIP_OTHER)
1091 malloc_strcat_wordlist(&nv, comma, "OTHER");
1092
1093 *rv = nv;
1094 }
1095
1096 return nvalue;
1097 }
1098
set_mangle_inbound(const void * stuff)1099 static void set_mangle_inbound (const void *stuff)
1100 {
1101 const char *value = (const char *)stuff;
1102 char *nv = NULL;
1103 inbound_line_mangler = parse_mangle(value, inbound_line_mangler, &nv);
1104 set_string_var(MANGLE_INBOUND_VAR, nv);
1105 new_free(&nv);
1106 }
1107
set_mangle_outbound(const void * stuff)1108 static void set_mangle_outbound (const void *stuff)
1109 {
1110 const char *value = (const char *)stuff;
1111 char *nv = NULL;
1112 outbound_line_mangler = parse_mangle(value, outbound_line_mangler, &nv);
1113 set_string_var(MANGLE_OUTBOUND_VAR, nv);
1114 new_free(&nv);
1115 }
1116
set_mangle_logfiles(const void * stuff)1117 static void set_mangle_logfiles (const void *stuff)
1118 {
1119 const char *value = (const char *)stuff;
1120 char *nv = NULL;
1121 logfile_line_mangler = parse_mangle(value, logfile_line_mangler, &nv);
1122 set_string_var(MANGLE_LOGFILES_VAR, nv);
1123 new_free(&nv);
1124 }
1125
set_scroll(const void * stuff)1126 static void set_scroll (const void *stuff)
1127 {
1128 int value = *(const int *)stuff;
1129 char * whatever;
1130 int owd = window_display;
1131
1132 window_display = 0;
1133 if (value)
1134 {
1135 whatever = LOCAL_COPY("ONE");
1136 window_scroll(current_window, &whatever);
1137 }
1138 else
1139 {
1140 whatever = LOCAL_COPY("ZERO");
1141 window_scroll(current_window, &whatever);
1142 }
1143 window_display = owd;
1144 }
1145
update_all_status_wrapper(const void * stuff)1146 static void update_all_status_wrapper (const void *stuff)
1147 {
1148 update_all_status();
1149 }
1150
set_highlight_char(const void * stuff)1151 static void set_highlight_char (const void *stuff)
1152 {
1153 const char *s = (const char *)stuff;
1154 int len;
1155
1156 if (!s)
1157 s = empty_string;
1158 len = strlen(s);
1159
1160 if (!my_strnicmp(s, "BOLD", len))
1161 malloc_strcpy(&highlight_char, BOLD_TOG_STR);
1162 else if (!my_strnicmp(s, "INVERSE", len))
1163 malloc_strcpy(&highlight_char, REV_TOG_STR);
1164 else if (!my_strnicmp(s, "UNDERLINE", len))
1165 malloc_strcpy(&highlight_char, UND_TOG_STR);
1166 else
1167 malloc_strcpy(&highlight_char, s);
1168 }
1169
set_wserv_type(const void * stuff)1170 static void set_wserv_type (const void *stuff)
1171 {
1172 const char *s = (const char *)stuff;
1173
1174 if (!s)
1175 return; /* It's ok */
1176 if (!my_stricmp(s, "SCREEN"))
1177 return; /* It's ok */
1178 if (!my_stricmp(s, "XTERM"))
1179 return; /* It's ok */
1180
1181 say("SET WSERV_TYPE must be either SCREEN or XTERM");
1182 set_string_var(WSERV_TYPE_VAR, NULL);
1183 }
1184
1185
1186 /*******/
1187 typedef struct varstacklist
1188 {
1189 char * varname;
1190 char * value;
1191 struct varstacklist *next;
1192 } VarStack;
1193
1194 VarStack *set_stack = NULL;
1195
do_stack_set(int type,char * args)1196 void do_stack_set (int type, char *args)
1197 {
1198 VarStack *item;
1199 char *varname = NULL;
1200
1201 if (set_stack == NULL && (type == STACK_POP || type == STACK_LIST))
1202 {
1203 say("Set stack is empty!");
1204 return;
1205 }
1206
1207 if (STACK_PUSH == type)
1208 {
1209 varname = next_arg(args, &args);
1210 if (!varname)
1211 {
1212 say("Must specify a variable name to stack");
1213 return;
1214 }
1215 upper(varname);
1216
1217 item = (VarStack *)new_malloc(sizeof(VarStack));
1218 item->varname = malloc_strdup(varname);
1219 item->value = make_string_var(varname);
1220
1221 item->next = set_stack;
1222 set_stack = item;
1223 return;
1224 }
1225
1226 else if (STACK_POP == type)
1227 {
1228 VarStack *prev = NULL;
1229 enum VAR_TYPES var_index;
1230 int owd = window_display;
1231
1232 varname = next_arg(args, &args);
1233 if (!varname)
1234 {
1235 say("Must specify a variable name to stack");
1236 return;
1237 }
1238 upper(varname);
1239
1240 for (item = set_stack; item; prev = item, item = item->next)
1241 {
1242 /* If this is not it, go to the next one */
1243 if (my_stricmp(varname, item->varname))
1244 continue;
1245
1246 /* remove it from the list */
1247 if (prev == NULL)
1248 set_stack = item->next;
1249 else
1250 prev->next = item->next;
1251
1252 window_display = 0;
1253 var_index = get_variable_index(item->varname);
1254 if (var_index == NUMBER_OF_VARIABLES)
1255 return; /* Do nothing */
1256 set_var_value(var_index, item->value);
1257 window_display = owd;
1258
1259 new_free(&item->varname);
1260 new_free(&item->value);
1261 new_free(&item);
1262 return;
1263 }
1264
1265 say("%s is not on the Set stack!", varname);
1266 return;
1267 }
1268
1269 else if (STACK_LIST == type)
1270 {
1271 VarStack *prev = NULL;
1272
1273 for (item = set_stack; item; prev = item, item = item->next)
1274 say("Variable [%s] = %s", item->varname, item->value ? item->value : "<EMPTY>");
1275
1276 return;
1277 }
1278
1279 else
1280 say("Unknown STACK type ??");
1281 }
1282
1283