Bug Summary

File:irc/core/irc.c
Location:line 385, column 2
Description:Branch condition evaluates to an uninitialized value.

Annotated Source Code

1/*
2 irc.c : irssi
3
4 Copyright (C) 1999 Timo Sirainen
5
6 This program 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 2 of the License, or
9 (at your option) any later version.
10
11 This program 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 along
17 with this program; if not, write to the Free Software Foundation, Inc.,
18 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19*/
20
21#include "module.h"
22#include "modules.h"
23#include "network.h"
24#include "net-sendbuffer.h"
25#include "rawlog.h"
26#include "misc.h"
27
28#include "irc-servers.h"
29#include "irc-channels.h"
30#include "servers-redirect.h"
31
32char *current_server_event;
33static int signal_default_event;
34static int signal_server_event;
35static int signal_server_incoming;
36
37#ifdef BLOCKING_SOCKETS
38# define MAX_SOCKET_READS5 1
39#else
40# define MAX_SOCKET_READS5 5
41#endif
42
43/* The core of the irc_send_cmd* functions. If `raw' is TRUE, the `cmd'
44 won't be checked at all if it's 512 bytes or not, or if it contains
45 line feeds or not. Use with extreme caution! */
46void irc_send_cmd_full(IRC_SERVER_REC *server, const char *cmd,
47 int send_now, int immediate, int raw)
48{
49 char str[513];
50 int len;
51
52 g_return_if_fail(server != NULL)do{ if (server != ((void *)0)) { } else { g_return_if_fail_warning
(((gchar*) 0), __PRETTY_FUNCTION__, "server != NULL"); return
; }; }while (0)
;
53 g_return_if_fail(cmd != NULL)do{ if (cmd != ((void *)0)) { } else { g_return_if_fail_warning
(((gchar*) 0), __PRETTY_FUNCTION__, "cmd != NULL"); return; }
; }while (0)
;
54
55 if (server->connection_lost)
56 return;
57
58 len = strlen(cmd);
59 if (server->cmdcount == 0)
60 irc_servers_start_cmd_timeout();
61 server->cmdcount++;
62
63 if (!raw) {
64 /* check that we don't send any longer commands
65 than 510 bytes (2 bytes for CR+LF) */
66 strncpy(str, cmd, 510);
67 if (len > 510) len = 510;
68 str[len] = '\0';
69 cmd = str;
70 }
71
72 if (send_now) {
73 rawlog_output(server->rawlog, cmd);
74 server_redirect_command(server, cmd, server->redirect_next);
75 server->redirect_next = NULL((void *)0);
76 }
77
78 if (!raw) {
79 /* Add CR+LF to command */
80 str[len++] = 13;
81 str[len++] = 10;
82 str[len] = '\0';
83 }
84
85 if (send_now) {
86 irc_server_send_data(server, cmd, len);
87 } else {
88
89 /* add to queue */
90 if (immediate) {
91 server->cmdqueue = g_slist_prepend(server->cmdqueue,
92 server->redirect_next);
93 server->cmdqueue = g_slist_prepend(server->cmdqueue,
94 g_strdup(cmd));
95 } else {
96 server->cmdqueue = g_slist_append(server->cmdqueue,
97 g_strdup(cmd));
98 server->cmdqueue = g_slist_append(server->cmdqueue,
99 server->redirect_next);
100 }
101 }
102 server->redirect_next = NULL((void *)0);
103}
104
105/* Send command to IRC server */
106void irc_send_cmd(IRC_SERVER_REC *server, const char *cmd)
107{
108 GTimeVal now;
109 int send_now;
110
111 g_get_current_time(&now);
112 send_now = g_timeval_cmp(&now, &server->wait_cmd) >= 0 &&
113 (server->cmdcount < server->max_cmds_at_once ||
114 server->cmd_queue_speed <= 0);
115
116 irc_send_cmd_full(server, cmd, send_now, FALSE(0), FALSE(0));
117}
118
119/* Send command to IRC server */
120void irc_send_cmdv(IRC_SERVER_REC *server, const char *cmd, ...)
121{
122 va_list args;
123 char *str;
124
125 va_start(args, cmd)__builtin_va_start((args), (cmd));
126
127 str = g_strdup_vprintf(cmd, args);
128 irc_send_cmd(server, str);
129 g_free(str);
130
131 va_end(args)__builtin_va_end(args);
132}
133
134/* Send command to server immediately bypassing all flood protections
135 and queues. */
136void irc_send_cmd_now(IRC_SERVER_REC *server, const char *cmd)
137{
138 g_return_if_fail(cmd != NULL)do{ if (cmd != ((void *)0)) { } else { g_return_if_fail_warning
(((gchar*) 0), __PRETTY_FUNCTION__, "cmd != NULL"); return; }
; }while (0)
;
139
140 irc_send_cmd_full(server, cmd, TRUE(!(0)), TRUE(!(0)), FALSE(0));
141}
142
143/* Send command to server putting it at the beginning of the queue of
144 commands to send -- it will go out as soon as possible in accordance
145 to the flood protection settings. */
146void irc_send_cmd_first(IRC_SERVER_REC *server, const char *cmd)
147{
148 g_return_if_fail(cmd != NULL)do{ if (cmd != ((void *)0)) { } else { g_return_if_fail_warning
(((gchar*) 0), __PRETTY_FUNCTION__, "cmd != NULL"); return; }
; }while (0)
;
149
150 irc_send_cmd_full(server, cmd, FALSE(0), TRUE(!(0)), FALSE(0));
151}
152
153static char *split_nicks(const char *cmd, char **pre, char **nicks, char **post, int arg)
154{
155 char *p;
156
157 *pre = g_strdup(cmd);
158 *post = *nicks = NULL((void *)0);
159 for (p = *pre; *p != '\0'; p++) {
160 if (*p != ' ')
161 continue;
162
163 if (arg == 1) {
164 /* text after nicks */
165 *p++ = '\0';
166 while (*p == ' ') p++;
167 *post = p;
168 break;
169 }
170
171 /* find nicks */
172 while (p[1] == ' ') p++;
173 if (--arg == 1) {
174 *p = '\0';
175 *nicks = p+1;
176 }
177 }
178
179 return *pre;
180}
181
182void irc_send_cmd_split(IRC_SERVER_REC *server, const char *cmd,
183 int nickarg, int max_nicks)
184{
185 char *str, *pre, *post, *nicks;
186 char **nicklist, **tmp;
187 GString *nickstr;
188 int count;
189
190 g_return_if_fail(server != NULL)do{ if (server != ((void *)0)) { } else { g_return_if_fail_warning
(((gchar*) 0), __PRETTY_FUNCTION__, "server != NULL"); return
; }; }while (0)
;
191 g_return_if_fail(cmd != NULL)do{ if (cmd != ((void *)0)) { } else { g_return_if_fail_warning
(((gchar*) 0), __PRETTY_FUNCTION__, "cmd != NULL"); return; }
; }while (0)
;
192
193 str = split_nicks(cmd, &pre, &nicks, &post, nickarg);
194 if (nicks == NULL((void *)0)) {
195 /* no nicks given? */
196 g_free(str);
197 return;
198 }
199
200 /* split the nicks */
201 nickstr = g_string_new(NULL((void *)0));
202 nicklist = g_strsplit(nicks, ",", -1); count = 0;
203
204 tmp = nicklist;
205 for (;; tmp++) {
206 if (*tmp != NULL((void *)0)) {
207 g_string_append_printf(nickstr, "%s,", *tmp);
208 if (++count < max_nicks)
209 continue;
210 }
211
212 count = 0;
213 if (nickstr->len > 0)
214 g_string_truncate(nickstr, nickstr->len-1);
215 irc_send_cmdv(server, post == NULL((void *)0) ? "%s %s" : "%s %s %s",
216 pre, nickstr->str, post);
217 g_string_truncate(nickstr, 0);
218
219 if (*tmp == NULL((void *)0) || tmp[1] == NULL((void *)0))
220 break;
221 }
222 g_strfreev(nicklist);
223 g_string_free(nickstr, TRUE(!(0)));
224
225 g_free(str);
226}
227
228/* Get next parameter */
229char *event_get_param(char **data)
230{
231 char *pos;
232
233 g_return_val_if_fail(data != NULL, NULL)do{ if (data != ((void *)0)) { } else { g_return_if_fail_warning
(((gchar*) 0), __PRETTY_FUNCTION__, "data != NULL"); return (
((void *)0)); }; }while (0)
;
234 g_return_val_if_fail(*data != NULL, NULL)do{ if (*data != ((void *)0)) { } else { g_return_if_fail_warning
(((gchar*) 0), __PRETTY_FUNCTION__, "*data != NULL"); return
(((void *)0)); }; }while (0)
;
235
236 if (**data == ':') {
237 /* last parameter */
238 pos = *data;
239 *data += strlen(*data);
240 return pos+1;
241 }
242
243 pos = *data;
244 while (**data != '\0' && **data != ' ') (*data)++;
245 if (**data == ' ') *(*data)++ = '\0';
246
247 return pos;
248}
249
250/* Get count parameters from data */
251char *event_get_params(const char *data, int count, ...)
252{
253 char **str, *tmp, *duprec, *datad;
254 gboolean rest;
255 va_list args;
256
257 g_return_val_if_fail(data != NULL, NULL)do{ if (data != ((void *)0)) { } else { g_return_if_fail_warning
(((gchar*) 0), __PRETTY_FUNCTION__, "data != NULL"); return (
((void *)0)); }; }while (0)
;
258
259 va_start(args, count)__builtin_va_start((args), (count));
260 duprec = datad = g_strdup(data);
261
262 rest = count & PARAM_FLAG_GETREST0x00002000;
263 count = PARAM_WITHOUT_FLAGS(count)((count) & 0x00000fff);
264
265 while (count-- > 0) {
266 str = (char **) va_arg(args, char **)__builtin_va_arg((args), char **);
267 if (count == 0 && rest) {
268 /* put the rest to last parameter */
269 tmp = *datad == ':' ? datad+1 : datad;
270 } else {
271 tmp = event_get_param(&datad);
272 }
273 if (str != NULL((void *)0)) *str = tmp;
274 }
275 va_end(args)__builtin_va_end(args);
276
277 return duprec;
278}
279
280static void irc_server_event(IRC_SERVER_REC *server, const char *line,
281 const char *nick, const char *address)
282{
283 const char *signal;
284 char *event, *args;
285
286 g_return_if_fail(line != NULL)do{ if (line != ((void *)0)) { } else { g_return_if_fail_warning
(((gchar*) 0), __PRETTY_FUNCTION__, "line != NULL"); return;
}; }while (0)
;
287
288 /* split event / args */
289 event = g_strconcat("event ", line, NULL((void *)0));
290 args = strchr(event+6, ' ');
291 if (args != NULL((void *)0)) *args++ = '\0'; else args = "";
292 while (*args == ' ') args++;
293 g_strdown(event);
294
295 /* check if event needs to be redirected */
296 signal = server_redirect_get_signal(server, nick, event, args);
297 if (signal == NULL((void *)0))
298 signal = event;
299 else
300 rawlog_redirect(server->rawlog, signal);
301
302 /* emit it */
303 current_server_event = event+6;
304 if (!signal_emit(signal, 4, server, args, nick, address))
305 signal_emit_id(signal_default_event, 4, server, line, nick, address);
306 current_server_event = NULL((void *)0);
307
308 g_free(event);
309}
310
311static char *irc_parse_prefix(char *line, char **nick, char **address)
312{
313 char *p;
314
315 *nick = *address = NULL((void *)0);
316
317 /* :<nick> [["!" <user>] "@" <host>] SPACE */
318
319 if (*line != ':')
320 return line;
321
322 *nick = ++line; p = NULL((void *)0);
323 while (*line != '\0' && *line != ' ') {
324 if (*line == '!' || *line == '@') {
325 p = line;
326 if (*line == '!')
327 break;
328 }
329 line++;
330 }
331
332 if (p != NULL((void *)0)) {
333 line = p;
334 *line++ = '\0';
335 *address = line;
336 while (*line != '\0' && *line != ' ')
337 line++;
338 }
339
340 if (*line == ' ') {
341 *line++ = '\0';
342 while (*line == ' ') line++;
343 }
344
345 return line;
346}
347
348/* Parse command line sent by server */
349static void irc_parse_incoming_line(IRC_SERVER_REC *server, char *line)
350{
351 char *nick, *address;
352
353 g_return_if_fail(server != NULL)do{ if (server != ((void *)0)) { } else { g_return_if_fail_warning
(((gchar*) 0), __PRETTY_FUNCTION__, "server != NULL"); return
; }; }while (0)
;
354 g_return_if_fail(line != NULL)do{ if (line != ((void *)0)) { } else { g_return_if_fail_warning
(((gchar*) 0), __PRETTY_FUNCTION__, "line != NULL"); return;
}; }while (0)
;
355
356 line = irc_parse_prefix(line, &nick, &address);
357 if (*line != '\0')
358 signal_emit_id(signal_server_event, 4, server, line, nick, address);
359}
360
361/* input function: handle incoming server messages */
362static void irc_parse_incoming(SERVER_REC *server)
363{
364 char *str;
365 int count;
366 int ret;
367
368 g_return_if_fail(server != NULL)do{ if (server != ((void *)0)) { } else { g_return_if_fail_warning
(((gchar*) 0), __PRETTY_FUNCTION__, "server != NULL"); return
; }; }while (0)
;
[1] Taking true branch
[2] Loop condition is false. Exiting loop
369
370 /* Some commands can send huge replies and irssi might handle them
371 too slowly, so read only a few times from the socket before
372 letting other tasks to run. */
373 count = 0;
374 server_ref(server);
375 while (!server->disconnected &&
[3] Loop condition is false. Execution continues on line 385
376 (ret = net_sendbuffer_receive_line(server->handle, &str, count < MAX_SOCKET_READS5)) > 0) {
377 rawlog_input(server->rawlog, str);
378 signal_emit_id(signal_server_incoming, 2, server, str);
379
380 if (server->connection_lost)
381 server_disconnect(server);
382
383 count++;
384 }
385 if (ret == -1) {
[4] Branch condition evaluates to an uninitialized value
386 /* connection lost */
387 server->connection_lost = TRUE(!(0));
388 server_disconnect(server);
389 }
390 server_unref(server);
391}
392
393static void irc_init_server(IRC_SERVER_REC *server)
394{
395 g_return_if_fail(server != NULL)do{ if (server != ((void *)0)) { } else { g_return_if_fail_warning
(((gchar*) 0), __PRETTY_FUNCTION__, "server != NULL"); return
; }; }while (0)
;
396
397 if (!IS_IRC_SERVER(server)(((IRC_SERVER_REC *) chat_protocol_check_cast(((SERVER_REC *)
module_check_cast(server, __builtin_offsetof(SERVER_REC, type
), "SERVER")), __builtin_offsetof(IRC_SERVER_REC, chat_type),
"IRC")) ? (!(0)) : (0))
)
398 return;
399
400 server->readtag =
401 g_input_add(net_sendbuffer_handle(server->handle),
402 G_INPUT_READ(1 << 0),
403 (GInputFunction) irc_parse_incoming, server);
404}
405
406void irc_irc_init(void)
407{
408 signal_add("server event", (SIGNAL_FUNC) irc_server_event)signal_add_full("irc/core", 0, ("server event"), (SIGNAL_FUNC
) ((SIGNAL_FUNC) irc_server_event), ((void *)0))
;
409 signal_add("server connected", (SIGNAL_FUNC) irc_init_server)signal_add_full("irc/core", 0, ("server connected"), (SIGNAL_FUNC
) ((SIGNAL_FUNC) irc_init_server), ((void *)0))
;
410 signal_add("server incoming", (SIGNAL_FUNC) irc_parse_incoming_line)signal_add_full("irc/core", 0, ("server incoming"), (SIGNAL_FUNC
) ((SIGNAL_FUNC) irc_parse_incoming_line), ((void *)0))
;
411
412 current_server_event = NULL((void *)0);
413 signal_default_event = signal_get_uniq_id("default event")module_get_uniq_id_str("signals", "default event");
414 signal_server_event = signal_get_uniq_id("server event")module_get_uniq_id_str("signals", "server event");
415 signal_server_incoming = signal_get_uniq_id("server incoming")module_get_uniq_id_str("signals", "server incoming");
416}
417
418void irc_irc_deinit(void)
419{
420 signal_remove("server event", (SIGNAL_FUNC) irc_server_event)signal_remove_full(("server event"), (SIGNAL_FUNC) ((SIGNAL_FUNC
) irc_server_event), ((void *)0))
;
421 signal_remove("server connected", (SIGNAL_FUNC) irc_init_server)signal_remove_full(("server connected"), (SIGNAL_FUNC) ((SIGNAL_FUNC
) irc_init_server), ((void *)0))
;
422 signal_remove("server incoming", (SIGNAL_FUNC) irc_parse_incoming_line)signal_remove_full(("server incoming"), (SIGNAL_FUNC) ((SIGNAL_FUNC
) irc_parse_incoming_line), ((void *)0))
;
423}