4
Copyright (C) 1999-2002 Timo Sirainen
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.
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.
16
You should have received a copy of the GNU General Public License
17
along with this program; if not, write to the Free Software
18
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
28
#include "irc-servers.h"
29
#include "irc-queries.h"
32
#include "module-formats.h"
33
#include "printtext.h"
34
#include "fe-messages.h"
36
#include "chat-completion.h"
38
void fe_dcc_chat_messages_init(void);
39
void fe_dcc_chat_messages_deinit(void);
41
static int autocreate_dccquery;
43
static void dcc_request(CHAT_DCC_REC *dcc)
45
if (!IS_DCC_CHAT(dcc)) return;
47
printformat(dcc->server, NULL, MSGLEVEL_DCC,
48
ischannel(*dcc->target) ? IRCTXT_DCC_CHAT_CHANNEL :
49
IRCTXT_DCC_CHAT, dcc->id, dcc->addrstr,
50
dcc->port, dcc->target);
53
static void dcc_connected(CHAT_DCC_REC *dcc)
57
if (!IS_DCC_CHAT(dcc)) return;
59
sender = g_strconcat("=", dcc->id, NULL);
60
printformat(dcc->server, NULL, MSGLEVEL_DCC,
61
IRCTXT_DCC_CHAT_CONNECTED,
62
dcc->id, dcc->addrstr, dcc->port);
64
if (query_find(NULL, sender) == NULL) {
65
if (!autocreate_dccquery)
66
completion_last_message_add(sender);
68
irc_query_create(dcc->servertag, sender, TRUE);
73
static void dcc_closed(CHAT_DCC_REC *dcc)
77
if (!IS_DCC_CHAT(dcc)) return;
79
sender = g_strconcat("=", dcc->id, NULL);
80
printformat(dcc->server, NULL, MSGLEVEL_DCC,
81
IRCTXT_DCC_CHAT_DISCONNECTED, dcc->id);
85
static void dcc_chat_msg(CHAT_DCC_REC *dcc, const char *msg)
88
char *sender, *freemsg;
90
g_return_if_fail(IS_DCC_CHAT(dcc));
91
g_return_if_fail(msg != NULL);
93
sender = g_strconcat("=", dcc->id, NULL);
94
query = query_find(NULL, sender);
96
if (settings_get_bool("emphasis"))
97
msg = freemsg = expand_emphasis((WI_ITEM_REC *) query, msg);
102
completion_last_message_add(sender);
103
signal_emit("message dcc", 2, dcc, msg);
105
g_free_not_null(freemsg);
109
static void dcc_chat_action(CHAT_DCC_REC *dcc, const char *msg)
113
g_return_if_fail(IS_DCC_CHAT(dcc));
114
g_return_if_fail(msg != NULL);
116
sender = g_strconcat("=", dcc->id, NULL);
117
if (query_find(NULL, sender) == NULL)
118
completion_last_message_add(sender);
120
signal_emit("message dcc action", 2, dcc, msg);
124
static void dcc_chat_ctcp(CHAT_DCC_REC *dcc, const char *cmd, const char *data)
126
g_return_if_fail(IS_DCC_CHAT(dcc));
128
signal_emit("message dcc ctcp", 3, dcc, cmd, data);
131
static void dcc_error_ctcp(const char *type, const char *data,
132
const char *nick, const char *addr,
135
printformat(NULL, NULL, MSGLEVEL_DCC,
136
IRCTXT_DCC_INVALID_CTCP, type, nick, addr, target);
139
static void dcc_unknown_ctcp(IRC_SERVER_REC *server, const char *data,
140
const char *nick, const char *addr,
141
const char *target, CHAT_DCC_REC *chat)
146
g_return_if_fail(data != NULL);
148
if (!cmd_get_params(data, &free_arg, 2 | PARAM_FLAG_GETREST,
152
printformat(NULL, NULL, MSGLEVEL_DCC, IRCTXT_DCC_UNKNOWN_CTCP,
154
cmd_params_free(free_arg);
157
static void dcc_unknown_reply(IRC_SERVER_REC *server, const char *data,
163
g_return_if_fail(data != NULL);
165
if (!cmd_get_params(data, &free_arg, 2 | PARAM_FLAG_GETREST,
169
printformat(NULL, NULL, MSGLEVEL_DCC, IRCTXT_DCC_UNKNOWN_REPLY,
171
cmd_params_free(free_arg);
174
static void sig_dcc_destroyed(CHAT_DCC_REC *dcc)
179
if (!IS_DCC_CHAT(dcc)) return;
181
nick = g_strconcat("=", dcc->id, NULL);
182
query = query_find(NULL, nick);
184
/* DCC chat closed, close the query with it. */
185
if (dcc->connection_lost) query->unwanted = TRUE;
186
query_destroy(query);
188
/* remove nick from msg completion
189
since it won't work anymore */
190
completion_last_message_remove(nick);
196
static void sig_query_destroyed(QUERY_REC *query)
200
if (*query->name != '=')
203
dcc = dcc_chat_find_id(query->name+1);
204
if (dcc != NULL && !dcc->destroyed) {
205
/* DCC query window closed, close the dcc chat too. */
210
static void dcc_error_close_not_found(const char *type, const char *nick,
213
g_return_if_fail(type != NULL);
214
g_return_if_fail(nick != NULL);
215
if (g_strcasecmp(type, "CHAT") != 0) return;
217
printformat(NULL, NULL, MSGLEVEL_DCC,
218
IRCTXT_DCC_CHAT_NOT_FOUND, nick);
221
static void sig_dcc_list_print(CHAT_DCC_REC *dcc)
223
if (!IS_DCC_CHAT(dcc)) return;
225
printformat(NULL, NULL, MSGLEVEL_DCC, IRCTXT_DCC_LIST_LINE_CHAT,
229
static void cmd_msg(const char *data, SERVER_REC *server, WI_ITEM_REC *item)
236
g_return_if_fail(data != NULL);
238
if (!cmd_get_params(data, &free_arg, 2 | PARAM_FLAG_UNKNOWN_OPTIONS |
239
PARAM_FLAG_OPTIONS | PARAM_FLAG_GETREST, "msg",
240
&optlist, &target, &text))
243
/* handle only DCC messages */
244
if (strcmp(target, "*") == 0)
245
dcc = item_get_dcc(item);
246
else if (*target == '=')
247
dcc = dcc_chat_find_id(target+1);
251
if (dcc == NULL && *target == '=') {
252
printformat(NULL, NULL, MSGLEVEL_CLIENTERROR,
253
IRCTXT_DCC_CHAT_NOT_FOUND, target+1);
254
} else if (dcc != NULL) {
255
if (query_find(NULL, target) == NULL)
256
completion_last_message_add(target);
258
signal_emit("message dcc own", 2, dcc, text);
261
cmd_params_free(free_arg);
264
static void cmd_me(const char *data, SERVER_REC *server, WI_ITEM_REC *item)
268
dcc = item_get_dcc(item);
270
signal_emit("message dcc own_action", 2, dcc, data);
273
static void cmd_action(const char *data, SERVER_REC *server, WI_ITEM_REC *item)
279
g_return_if_fail(data != NULL);
282
/* handle only DCC actions */
286
if (!cmd_get_params(data, &free_arg, 2 | PARAM_FLAG_GETREST,
289
if (*target == '\0' || *text == '\0')
290
cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS);
292
dcc = dcc_chat_find_id(target+1);
293
if (dcc == NULL || dcc->sendbuf == NULL) {
294
printformat(NULL, NULL, MSGLEVEL_CLIENTERROR,
295
IRCTXT_DCC_CHAT_NOT_FOUND, target+1);
297
if (query_find(NULL, target) == NULL)
298
completion_last_message_add(target);
300
signal_emit("message dcc own_action", 2, dcc, text);
302
cmd_params_free(free_arg);
305
static void cmd_ctcp(const char *data, SERVER_REC *server)
308
char *target, *ctcpcmd, *ctcpdata;
311
g_return_if_fail(data != NULL);
312
if (server == NULL || !server->connected)
313
cmd_return_error(CMDERR_NOT_CONNECTED);
315
if (!cmd_get_params(data, &free_arg, 3 | PARAM_FLAG_GETREST,
316
&target, &ctcpcmd, &ctcpdata))
318
if (*target == '\0' || *ctcpcmd == '\0')
319
cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS);
321
if (*target != '=') {
322
/* handle only DCC CTCPs */
323
cmd_params_free(free_arg);
327
dcc = dcc_chat_find_id(target+1);
328
if (dcc == NULL || dcc->sendbuf == NULL) {
329
printformat(NULL, NULL, MSGLEVEL_CLIENTERROR,
330
IRCTXT_DCC_CHAT_NOT_FOUND, target+1);
333
signal_emit("message dcc own_ctcp", 3, dcc, ctcpcmd, ctcpdata);
336
cmd_params_free(free_arg);
339
static void read_settings(void)
343
level = settings_get_level("autocreate_query_level");
344
autocreate_dccquery = (level & MSGLEVEL_DCCMSGS) != 0;
347
void fe_dcc_chat_init(void)
350
fe_dcc_chat_messages_init();
352
signal_add("dcc request", (SIGNAL_FUNC) dcc_request);
353
signal_add("dcc connected", (SIGNAL_FUNC) dcc_connected);
354
signal_add("dcc closed", (SIGNAL_FUNC) dcc_closed);
355
signal_add("dcc chat message", (SIGNAL_FUNC) dcc_chat_msg);
356
signal_add("dcc ctcp action", (SIGNAL_FUNC) dcc_chat_action);
357
signal_add("default dcc ctcp", (SIGNAL_FUNC) dcc_chat_ctcp);
358
signal_add("dcc error ctcp", (SIGNAL_FUNC) dcc_error_ctcp);
359
signal_add("default ctcp msg dcc", (SIGNAL_FUNC) dcc_unknown_ctcp);
360
signal_add("default ctcp reply dcc", (SIGNAL_FUNC) dcc_unknown_reply);
361
signal_add("dcc destroyed", (SIGNAL_FUNC) sig_dcc_destroyed);
362
signal_add("query destroyed", (SIGNAL_FUNC) sig_query_destroyed);
363
signal_add("dcc list print", (SIGNAL_FUNC) sig_dcc_list_print);
364
command_bind("msg", NULL, (SIGNAL_FUNC) cmd_msg);
365
command_bind("me", NULL, (SIGNAL_FUNC) cmd_me);
366
command_bind("action", NULL, (SIGNAL_FUNC) cmd_action);
367
command_bind("ctcp", NULL, (SIGNAL_FUNC) cmd_ctcp);
368
signal_add("dcc error close not found", (SIGNAL_FUNC) dcc_error_close_not_found);
369
signal_add("setup changed", (SIGNAL_FUNC) read_settings);
372
void fe_dcc_chat_deinit(void)
374
fe_dcc_chat_messages_deinit();
376
signal_remove("dcc request", (SIGNAL_FUNC) dcc_request);
377
signal_remove("dcc connected", (SIGNAL_FUNC) dcc_connected);
378
signal_remove("dcc closed", (SIGNAL_FUNC) dcc_closed);
379
signal_remove("dcc chat message", (SIGNAL_FUNC) dcc_chat_msg);
380
signal_remove("dcc ctcp action", (SIGNAL_FUNC) dcc_chat_action);
381
signal_remove("default dcc ctcp", (SIGNAL_FUNC) dcc_chat_ctcp);
382
signal_remove("dcc error ctcp", (SIGNAL_FUNC) dcc_error_ctcp);
383
signal_remove("default ctcp msg dcc", (SIGNAL_FUNC) dcc_unknown_ctcp);
384
signal_remove("default ctcp reply dcc", (SIGNAL_FUNC) dcc_unknown_reply);
385
signal_remove("dcc destroyed", (SIGNAL_FUNC) sig_dcc_destroyed);
386
signal_remove("query destroyed", (SIGNAL_FUNC) sig_query_destroyed);
387
signal_remove("dcc list print", (SIGNAL_FUNC) sig_dcc_list_print);
388
command_unbind("msg", (SIGNAL_FUNC) cmd_msg);
389
command_unbind("me", (SIGNAL_FUNC) cmd_me);
390
command_unbind("action", (SIGNAL_FUNC) cmd_action);
391
command_unbind("ctcp", (SIGNAL_FUNC) cmd_ctcp);
392
signal_remove("dcc error close not found", (SIGNAL_FUNC) dcc_error_close_not_found);
393
signal_remove("setup changed", (SIGNAL_FUNC) read_settings);