~ubuntu-branches/ubuntu/feisty/irssi/feisty-backports

« back to all changes in this revision

Viewing changes to src/fe-common/irc/dcc/fe-dcc-chat.c

  • Committer: Bazaar Package Importer
  • Author(s): David Pashley
  • Date: 2005-12-10 21:25:51 UTC
  • Revision ID: james.westby@ubuntu.com-20051210212551-5qwm108g7inyu2f2
Tags: upstream-0.8.10
ImportĀ upstreamĀ versionĀ 0.8.10

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 fe-dcc-chat.c : irssi
 
3
 
 
4
    Copyright (C) 1999-2002 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
 
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
 
19
*/
 
20
 
 
21
#include "module.h"
 
22
#include "signals.h"
 
23
#include "commands.h"
 
24
#include "levels.h"
 
25
#include "settings.h"
 
26
 
 
27
#include "irc.h"
 
28
#include "irc-servers.h"
 
29
#include "irc-queries.h"
 
30
#include "dcc-chat.h"
 
31
 
 
32
#include "module-formats.h"
 
33
#include "printtext.h"
 
34
#include "fe-messages.h"
 
35
 
 
36
#include "chat-completion.h"
 
37
 
 
38
void fe_dcc_chat_messages_init(void);
 
39
void fe_dcc_chat_messages_deinit(void);
 
40
 
 
41
static int autocreate_dccquery;
 
42
 
 
43
static void dcc_request(CHAT_DCC_REC *dcc)
 
44
{
 
45
        if (!IS_DCC_CHAT(dcc)) return;
 
46
 
 
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);
 
51
}
 
52
 
 
53
static void dcc_connected(CHAT_DCC_REC *dcc)
 
54
{
 
55
        char *sender;
 
56
 
 
57
        if (!IS_DCC_CHAT(dcc)) return;
 
58
 
 
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);
 
63
 
 
64
        if (query_find(NULL, sender) == NULL) {
 
65
                if (!autocreate_dccquery)
 
66
                        completion_last_message_add(sender);
 
67
                else
 
68
                        irc_query_create(dcc->servertag, sender, TRUE);
 
69
        }
 
70
        g_free(sender);
 
71
}
 
72
 
 
73
static void dcc_closed(CHAT_DCC_REC *dcc)
 
74
{
 
75
        char *sender;
 
76
 
 
77
        if (!IS_DCC_CHAT(dcc)) return;
 
78
 
 
79
        sender = g_strconcat("=", dcc->id, NULL);
 
80
        printformat(dcc->server, NULL, MSGLEVEL_DCC,
 
81
                    IRCTXT_DCC_CHAT_DISCONNECTED, dcc->id);
 
82
        g_free(sender);
 
83
}
 
84
 
 
85
static void dcc_chat_msg(CHAT_DCC_REC *dcc, const char *msg)
 
86
{
 
87
        QUERY_REC *query;
 
88
        char *sender, *freemsg;
 
89
 
 
90
        g_return_if_fail(IS_DCC_CHAT(dcc));
 
91
        g_return_if_fail(msg != NULL);
 
92
 
 
93
        sender = g_strconcat("=", dcc->id, NULL);
 
94
        query = query_find(NULL, sender);
 
95
 
 
96
        if (settings_get_bool("emphasis"))
 
97
                msg = freemsg = expand_emphasis((WI_ITEM_REC *) query, msg);
 
98
        else
 
99
                freemsg = NULL;
 
100
 
 
101
        if (query == NULL)
 
102
                completion_last_message_add(sender);
 
103
        signal_emit("message dcc", 2, dcc, msg);
 
104
 
 
105
        g_free_not_null(freemsg);
 
106
        g_free(sender);
 
107
}
 
108
 
 
109
static void dcc_chat_action(CHAT_DCC_REC *dcc, const char *msg)
 
110
{
 
111
        char *sender;
 
112
 
 
113
        g_return_if_fail(IS_DCC_CHAT(dcc));
 
114
        g_return_if_fail(msg != NULL);
 
115
 
 
116
        sender = g_strconcat("=", dcc->id, NULL);
 
117
        if (query_find(NULL, sender) == NULL)
 
118
                completion_last_message_add(sender);
 
119
 
 
120
        signal_emit("message dcc action", 2, dcc, msg);
 
121
        g_free(sender);
 
122
}
 
123
 
 
124
static void dcc_chat_ctcp(CHAT_DCC_REC *dcc, const char *cmd, const char *data)
 
125
{
 
126
        g_return_if_fail(IS_DCC_CHAT(dcc));
 
127
 
 
128
        signal_emit("message dcc ctcp", 3, dcc, cmd, data);
 
129
}
 
130
 
 
131
static void dcc_error_ctcp(const char *type, const char *data,
 
132
                           const char *nick, const char *addr,
 
133
                           const char *target)
 
134
{
 
135
        printformat(NULL, NULL, MSGLEVEL_DCC,
 
136
                    IRCTXT_DCC_INVALID_CTCP, type, nick, addr, target);
 
137
}
 
138
 
 
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)
 
142
{
 
143
        char *type, *args;
 
144
        void *free_arg;
 
145
 
 
146
        g_return_if_fail(data != NULL);
 
147
 
 
148
        if (!cmd_get_params(data, &free_arg, 2 | PARAM_FLAG_GETREST,
 
149
                            &type, &args))
 
150
                return;
 
151
 
 
152
        printformat(NULL, NULL, MSGLEVEL_DCC, IRCTXT_DCC_UNKNOWN_CTCP,
 
153
                    type, nick, args);
 
154
        cmd_params_free(free_arg);
 
155
}
 
156
 
 
157
static void dcc_unknown_reply(IRC_SERVER_REC *server, const char *data,
 
158
                              const char *nick)
 
159
{
 
160
        char *type, *args;
 
161
        void *free_arg;
 
162
 
 
163
        g_return_if_fail(data != NULL);
 
164
 
 
165
        if (!cmd_get_params(data, &free_arg, 2 | PARAM_FLAG_GETREST,
 
166
                            &type, &args))
 
167
                return;
 
168
 
 
169
        printformat(NULL, NULL, MSGLEVEL_DCC, IRCTXT_DCC_UNKNOWN_REPLY,
 
170
                    type, nick, args);
 
171
        cmd_params_free(free_arg);
 
172
}
 
173
 
 
174
static void sig_dcc_destroyed(CHAT_DCC_REC *dcc)
 
175
{
 
176
        QUERY_REC *query;
 
177
        char *nick;
 
178
 
 
179
        if (!IS_DCC_CHAT(dcc)) return;
 
180
 
 
181
        nick = g_strconcat("=", dcc->id, NULL);
 
182
        query = query_find(NULL, nick);
 
183
        if (query != NULL) {
 
184
                /* DCC chat closed, close the query with it. */
 
185
                if (dcc->connection_lost) query->unwanted = TRUE;
 
186
                query_destroy(query);
 
187
        } else {
 
188
                /* remove nick from msg completion
 
189
                   since it won't work anymore */
 
190
                completion_last_message_remove(nick);
 
191
        }
 
192
 
 
193
        g_free(nick);
 
194
}
 
195
 
 
196
static void sig_query_destroyed(QUERY_REC *query)
 
197
{
 
198
        CHAT_DCC_REC *dcc;
 
199
 
 
200
        if (*query->name != '=')
 
201
                return;
 
202
 
 
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. */
 
206
                dcc_close(DCC(dcc));
 
207
        }
 
208
}
 
209
 
 
210
static void dcc_error_close_not_found(const char *type, const char *nick,
 
211
                                      const char *fname)
 
212
{
 
213
        g_return_if_fail(type != NULL);
 
214
        g_return_if_fail(nick != NULL);
 
215
        if (g_strcasecmp(type, "CHAT") != 0) return;
 
216
 
 
217
        printformat(NULL, NULL, MSGLEVEL_DCC,
 
218
                    IRCTXT_DCC_CHAT_NOT_FOUND, nick);
 
219
}
 
220
 
 
221
static void sig_dcc_list_print(CHAT_DCC_REC *dcc)
 
222
{
 
223
        if (!IS_DCC_CHAT(dcc)) return;
 
224
 
 
225
        printformat(NULL, NULL, MSGLEVEL_DCC, IRCTXT_DCC_LIST_LINE_CHAT,
 
226
                    dcc->id, "CHAT");
 
227
}
 
228
 
 
229
static void cmd_msg(const char *data, SERVER_REC *server, WI_ITEM_REC *item)
 
230
{
 
231
        CHAT_DCC_REC *dcc;
 
232
        GHashTable *optlist;
 
233
        char *text, *target;
 
234
        void *free_arg;
 
235
 
 
236
        g_return_if_fail(data != NULL);
 
237
 
 
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))
 
241
                return;
 
242
 
 
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);
 
248
        else
 
249
                dcc = NULL;
 
250
 
 
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);
 
257
 
 
258
                signal_emit("message dcc own", 2, dcc, text);
 
259
        }
 
260
 
 
261
        cmd_params_free(free_arg);
 
262
}
 
263
 
 
264
static void cmd_me(const char *data, SERVER_REC *server, WI_ITEM_REC *item)
 
265
{
 
266
        CHAT_DCC_REC *dcc;
 
267
 
 
268
        dcc = item_get_dcc(item);
 
269
        if (dcc != NULL)
 
270
                signal_emit("message dcc own_action", 2, dcc, data);
 
271
}
 
272
 
 
273
static void cmd_action(const char *data, SERVER_REC *server, WI_ITEM_REC *item)
 
274
{
 
275
        CHAT_DCC_REC *dcc;
 
276
        char *target, *text;
 
277
        void *free_arg;
 
278
 
 
279
        g_return_if_fail(data != NULL);
 
280
 
 
281
        if (*data != '=') {
 
282
                /* handle only DCC actions */
 
283
                return;
 
284
        }
 
285
 
 
286
        if (!cmd_get_params(data, &free_arg, 2 | PARAM_FLAG_GETREST,
 
287
                            &target, &text))
 
288
                return;
 
289
        if (*target == '\0' || *text == '\0')
 
290
                cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS);
 
291
 
 
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);
 
296
        } else {
 
297
                if (query_find(NULL, target) == NULL)
 
298
                        completion_last_message_add(target);
 
299
 
 
300
                signal_emit("message dcc own_action", 2, dcc, text);
 
301
        }
 
302
        cmd_params_free(free_arg);
 
303
}
 
304
 
 
305
static void cmd_ctcp(const char *data, SERVER_REC *server)
 
306
{
 
307
        CHAT_DCC_REC *dcc;
 
308
        char *target, *ctcpcmd, *ctcpdata;
 
309
        void *free_arg;
 
310
 
 
311
        g_return_if_fail(data != NULL);
 
312
        if (server == NULL || !server->connected)
 
313
                cmd_return_error(CMDERR_NOT_CONNECTED);
 
314
 
 
315
        if (!cmd_get_params(data, &free_arg, 3 | PARAM_FLAG_GETREST,
 
316
                            &target, &ctcpcmd, &ctcpdata))
 
317
                return;
 
318
        if (*target == '\0' || *ctcpcmd == '\0')
 
319
                cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS);
 
320
 
 
321
        if (*target != '=') {
 
322
                /* handle only DCC CTCPs */
 
323
                cmd_params_free(free_arg);
 
324
                return;
 
325
        }
 
326
 
 
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);
 
331
        } else {
 
332
                g_strup(ctcpcmd);
 
333
                signal_emit("message dcc own_ctcp", 3, dcc, ctcpcmd, ctcpdata);
 
334
        }
 
335
 
 
336
        cmd_params_free(free_arg);
 
337
}
 
338
 
 
339
static void read_settings(void)
 
340
{
 
341
        int level;
 
342
 
 
343
        level = settings_get_level("autocreate_query_level");
 
344
        autocreate_dccquery = (level & MSGLEVEL_DCCMSGS) != 0;
 
345
}
 
346
 
 
347
void fe_dcc_chat_init(void)
 
348
{
 
349
        read_settings();
 
350
        fe_dcc_chat_messages_init();
 
351
 
 
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);
 
370
}
 
371
 
 
372
void fe_dcc_chat_deinit(void)
 
373
{
 
374
        fe_dcc_chat_messages_deinit();
 
375
 
 
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);
 
394
}