~ubuntu-branches/ubuntu/trusty/irssi-plugin-xmpp/trusty

« back to all changes in this revision

Viewing changes to src/fe-common/xmpp-completion.c

  • Committer: Bazaar Package Importer
  • Author(s): David Ammouial
  • Date: 2009-05-12 12:14:44 UTC
  • mfrom: (1.1.3 upstream) (2.1.2 sid)
  • Revision ID: james.westby@ubuntu.com-20090512121444-5jeho5h3zsy4oij7
Tags: 0.13+cvs20090406-1
* New CVS snapshot, built against irssi-dev 0.8.13:
  - New features and bugfixes.
  - Fix segfault when successfully identified (Closes: #521227).
  - Fix build error (Closes: #527697)
* Depend on irssi >=0.8.13, build-depend on irssi-dev >=0.8.13.
* Bump Standards-Version to 3.8.1 (no changes needed).
* Add INTERNAL to documentation files.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*
2
 
 * $Id: xmpp-completion.c,v 1.20 2008/04/05 20:50:45 errtu Exp $
 
2
 * $Id: xmpp-completion.c,v 1.23 2008/09/28 07:27:55 cdidier Exp $
3
3
 *
4
4
 * Copyright (C) 2007 Colin DIDIER
5
5
 *
20
20
#include <string.h>
21
21
 
22
22
#include "module.h"
 
23
#include "channels.h"
23
24
#include "channels-setup.h"
24
25
#include "misc.h"
25
26
#include "settings.h"
27
28
#include "window-items.h"
28
29
 
29
30
#include "xmpp-servers.h"
30
 
#include "xmpp-channels.h"
31
 
#include "xmpp-channels.h"
32
31
#include "xmpp-commands.h"
33
 
#include "xmpp-rosters.h"
34
 
#include "xmpp-rosters-tools.h"
35
 
#include "xmpp-tools.h"
 
32
#include "rosters-tools.h"
 
33
#include "tools.h"
36
34
 
37
35
static char *
38
36
quoted_if_space(const char *name, const char *res)
58
56
 
59
57
        g_return_val_if_fail(IS_XMPP_SERVER(server), NULL);
60
58
        g_return_val_if_fail(nick != NULL, NULL);
61
 
 
62
59
        if (resource_name != NULL)
63
60
                len = strlen(resource_name);
64
 
 
65
61
        list = NULL;
66
 
 
67
 
        user = xmpp_rosters_find_user(server->roster, nick, NULL, NULL);
 
62
        user = rosters_find_user(server->roster, nick, NULL, NULL);
68
63
        if (user == NULL)
69
64
                return NULL;
70
 
 
71
65
        for(rl = user->resources; rl != NULL; rl = rl->next) {
72
66
                resource = rl->data;
73
67
                if (resource_name == NULL
76
70
                            quoted_if_space(nick, resource->name) :
77
71
                            g_strconcat(nick, "/", resource->name, NULL));
78
72
        }
79
 
 
 
73
        return list;
 
74
}
 
75
 
 
76
static GList *
 
77
get_jids(XMPP_SERVER_REC *server, const char *jid)
 
78
{
 
79
        GSList *gl, *ul;
 
80
        GList *list, *list_case, *offlist, *offlist_case;
 
81
        XMPP_ROSTER_USER_REC *user;
 
82
        int len;
 
83
 
 
84
        list = list_case = offlist = offlist_case = NULL;
 
85
        len = strlen(jid);
 
86
        for (gl = server->roster; gl != NULL; gl = gl->next) {
 
87
                for (ul = ((XMPP_ROSTER_GROUP_REC *)gl->data)->users;
 
88
                    ul != NULL ; ul = ul->next) {
 
89
                        user = (XMPP_ROSTER_USER_REC *)ul->data;
 
90
                        if (strncmp(user->jid, jid, len) == 0) {
 
91
                                if (user->resources != NULL)
 
92
                                        g_list_append(list, user->jid);
 
93
                                else 
 
94
                                        g_list_append(offlist, user->jid);
 
95
                        } else if (g_strncasecmp(user->jid, jid, len) == 0) {
 
96
                                if (user->resources != NULL)
 
97
                                        g_list_append(list_case, user->jid);
 
98
                                else
 
99
                                        g_list_append(offlist_case, user->jid);
 
100
                        }
 
101
                }
 
102
        }
 
103
        /* TODO: temporary list of jids */
 
104
        list = g_list_concat(list, list_case);
 
105
        list = g_list_concat(list, offlist);
 
106
        list = g_list_concat(list, offlist_case);
80
107
        return list;
81
108
}
82
109
 
91
118
        int len;
92
119
        gboolean pass2;
93
120
        
94
 
        g_return_val_if_fail(IS_XMPP_SERVER(server), NULL);
95
 
        g_return_val_if_fail(nick != NULL, NULL);
96
 
 
97
121
        len = strlen(nick);
98
 
 
99
122
        /* resources completion */
100
123
        resource = xmpp_extract_resource(nick);
101
124
        if (resource != NULL) {
102
125
                jid = xmpp_strip_resource(nick);
103
 
 
104
126
                list = get_resources(server, jid, resource, quoted);
105
 
 
106
127
                g_free(resource);
107
128
                g_free(jid);
108
 
 
109
129
                return list;
110
130
        }
111
 
 
112
131
        list = NULL;
113
132
        pass2 = FALSE;
114
 
 
115
133
again:
116
134
        /* first complete with online contacts
117
135
         * then complete with offline contacts */
118
136
        for (gl = server->roster; gl != NULL; gl = gl->next) {
119
 
 
120
137
                for (ul = ((XMPP_ROSTER_GROUP_REC *)gl->data)->users;
121
138
                    ul != NULL ; ul = ul->next) {
122
139
                        user = (XMPP_ROSTER_USER_REC *)ul->data;
123
 
 
124
140
                        if ((!pass2 && user->resources == NULL)
125
141
                            || (pass2 && user->resources != NULL))
126
142
                                continue;
127
 
 
128
143
                        if (complete_names && user->name != NULL
129
144
                            && g_strncasecmp(user->name, nick, len) == 0)
130
145
                                list = g_list_prepend(list, quoted ?
131
146
                                    quoted_if_space(user->name, NULL) :
132
147
                                    g_strdup(user->name));
133
 
 
134
148
                        if (g_strncasecmp(user->jid, nick, len) == 0)
135
149
                                list = g_list_prepend(list, quoted ?
136
150
                                    quoted_if_space(user->jid, NULL) :
137
151
                                    g_strdup(user->jid));
138
152
                }
139
153
        }
140
 
        
141
154
        if ((pass2 = !pass2))
142
155
                goto again;
143
 
 
 
156
        /* TODO: rewrite this function */
144
157
        return list;
145
158
}
146
159
 
153
166
        g_return_if_fail(list != NULL);
154
167
        g_return_if_fail(window != NULL);
155
168
        g_return_if_fail(word != NULL);
156
 
 
157
 
        server = XMPP_SERVER(window->active_server);
158
 
        if (server == NULL)
 
169
        if ((server = XMPP_SERVER(window->active_server)) == NULL)
159
170
                return;
160
 
 
161
171
        if (g_ascii_strncasecmp(linestart,
162
172
            settings_get_str("cmdchars"), 1) == 0) {
163
173
                *list = g_list_concat(*list, get_nicks(server, *word == '"' ?
164
174
                    word+1 : word , TRUE, TRUE));
165
 
 
166
 
        } else if (!IS_XMPP_CHANNEL(window->active))
 
175
        } else if (!IS_CHANNEL(window->active))
167
176
                *list = g_list_concat(*list, get_nicks(server, word, FALSE,
168
177
                    TRUE));
169
178
}
182
191
        g_return_if_fail(window != NULL);
183
192
        g_return_if_fail(word != NULL);
184
193
        g_return_if_fail(args != NULL);
185
 
 
186
194
        server = XMPP_SERVER(window->active_server);
187
195
        if (server == NULL)
188
196
                return;
189
 
 
190
197
        len = strlen(word);
191
198
        tmp = g_strsplit(args, " ", 2);
192
 
 
193
199
        /* complete nicks */
194
200
        if (tmp[0] == NULL)
195
201
                *list = g_list_concat(*list, get_nicks(server, *word == '"' ?
196
202
                    word+1 : word , TRUE, FALSE));
197
 
 
198
203
        /* complete groups */
199
204
        else if (tmp[0] != NULL && tmp[1] == NULL) {
200
205
                for (gl = server->roster; gl != NULL; gl = gl->next) {
201
206
                        group = (XMPP_ROSTER_GROUP_REC *)gl->data;
202
 
                        
203
207
                        if (group->name != NULL &&
204
208
                            g_ascii_strncasecmp(word, group->name, len) == 0)
205
209
                                *list = g_list_append(*list,
206
210
                                    g_strdup(group->name));
207
211
                }
208
212
        }
209
 
 
210
213
        g_strfreev(tmp);
211
 
 
212
214
        if (*list != NULL)
213
215
                signal_stop();
214
216
}
217
219
sig_complete_command_roster_others(GList **list, WINDOW_REC *window,
218
220
    const char *word, const char *args, int *want_space)
219
221
{
220
 
        GSList *gl;
221
222
        XMPP_SERVER_REC *server;
222
 
        XMPP_ROSTER_GROUP_REC *group;
223
223
        int len;
224
224
        char **tmp;
225
225
 
227
227
        g_return_if_fail(window != NULL);
228
228
        g_return_if_fail(word != NULL);
229
229
        g_return_if_fail(args != NULL);
230
 
 
231
 
        server = XMPP_SERVER(window->active_server);
232
 
        if (server == NULL)
 
230
        if ((server = XMPP_SERVER(window->active_server)) == NULL)
233
231
                return;
234
 
 
235
232
        len = strlen(word);
236
233
        tmp = g_strsplit(args, " ", 2);
237
 
 
238
234
        /* complete nicks */
239
235
        if (tmp[0] == NULL)
240
236
                *list = g_list_concat(*list, get_nicks(server, *word == '"' ?
241
237
                    word+1 : word , TRUE, FALSE));
242
 
 
243
 
        g_strfreev(tmp);
244
 
 
 
238
        g_strfreev(tmp);
 
239
        if (*list != NULL)
 
240
                signal_stop();
 
241
}
 
242
 
 
243
static void
 
244
sig_complete_command_presence(GList **list, WINDOW_REC *window,
 
245
    const char *word, const char *args, int *want_space)
 
246
{
 
247
        XMPP_SERVER_REC *server;
 
248
        int len;
 
249
        char **tmp;
 
250
 
 
251
        g_return_if_fail(list != NULL);
 
252
        g_return_if_fail(window != NULL);
 
253
        g_return_if_fail(word != NULL);
 
254
        g_return_if_fail(args != NULL);
 
255
        if ((server = XMPP_SERVER(window->active_server)) == NULL)
 
256
                return;
 
257
        len = strlen(word);
 
258
        tmp = g_strsplit(args, " ", 2);
 
259
        /* complete nicks */
 
260
        if (tmp[0] == NULL)
 
261
                *list = g_list_concat(*list, get_jids(server, *word == '"' ?
 
262
                    word+1 : word));
 
263
        g_strfreev(tmp);
245
264
        if (*list != NULL)
246
265
                signal_stop();
247
266
}
251
270
{
252
271
        GSList *tmp;
253
272
        GList *list;
254
 
        XMPP_CHANNEL_REC *channel;
 
273
        CHANNEL_REC *channel;
255
274
        CHANNEL_SETUP_REC *channel_setup;
256
275
        int len;
257
276
        
258
277
        g_return_val_if_fail(IS_XMPP_SERVER(server), NULL);
259
278
        g_return_val_if_fail(word != NULL, NULL);
260
 
 
261
279
        len = strlen(word);
262
280
        list = NULL;
263
 
 
264
 
        /* get joined channels */
265
281
        for (tmp = server->channels; tmp != NULL; tmp = tmp->next) {
266
 
                channel = XMPP_CHANNEL(tmp->data);
267
 
 
 
282
                channel = CHANNEL(tmp->data);
268
283
                if (channel != NULL &&
269
284
                    g_strncasecmp(channel->name, word, len) == 0)
270
285
                        list = g_list_append(list, g_strdup(channel->name));
271
286
        }
272
 
 
273
 
        /* get channels from setup */
274
287
        for (tmp = setupchannels; tmp != NULL; tmp = tmp->next) {
275
288
                channel_setup = tmp->data;
276
 
 
277
 
                if ((IS_XMPP_CHANNEL_SETUP(channel_setup)
 
289
                if ((PROTO_CHECK_CAST(channel_setup, CHANNEL_SETUP_REC,
 
290
                    chat_type, XMPP_PROTOCOL_NAME)
278
291
                    || *channel_setup->name != '#')
279
292
                    && g_strncasecmp(channel_setup->name, word, len) == 0
280
293
                    && glist_find_string(list, channel_setup->name) == NULL)
281
294
                        list = g_list_append(list,
282
295
                            g_strdup(channel_setup->name));
283
296
        }
284
 
 
285
297
        return list;
286
298
}
287
299
 
294
306
        g_return_if_fail(list != NULL);
295
307
        g_return_if_fail(window != NULL);
296
308
        g_return_if_fail(word != NULL);
297
 
 
298
309
        server = XMPP_SERVER(window->active_server);
299
310
        if (server == NULL)
300
311
                return;
301
 
 
302
312
        *list = get_channels(server, word);
303
 
 
304
313
        if (*list != NULL)
305
314
                signal_stop();
306
315
}
315
324
        g_return_if_fail(list != NULL);
316
325
        g_return_if_fail(window != NULL);
317
326
        g_return_if_fail(word != NULL);
318
 
 
319
327
        server = XMPP_SERVER(window->active_server);
320
328
        if (server == NULL)
321
329
                return;
322
 
 
323
330
        /* complete channels */
324
331
        tmp = g_strsplit(args, " ", 2);
325
332
        if (tmp[0] != NULL && tmp[1] == NULL)
326
333
                *list = get_channels(server, word);
327
334
        g_strfreev(tmp);
328
 
 
329
335
        if (*list != NULL)
330
336
                signal_stop();
331
337
}
340
346
        g_return_if_fail(list != NULL);
341
347
        g_return_if_fail(window != NULL);
342
348
        g_return_if_fail(word != NULL);
343
 
 
344
349
        server = XMPP_SERVER(window->active_server);
345
350
        if (server == NULL)
346
351
                return;
347
 
 
348
352
        len = strlen(word);
349
 
 
350
353
        if (g_strncasecmp(word,
351
354
            xmpp_presence_show[XMPP_PRESENCE_AWAY], len) == 0)
352
355
                *list = g_list_append(*list,
353
356
                    g_strdup(xmpp_presence_show[XMPP_PRESENCE_AWAY]));
354
 
 
355
357
        if (g_strncasecmp(word,
356
358
            xmpp_presence_show[XMPP_PRESENCE_XA], len) == 0)
357
359
                *list = g_list_append(*list,
358
360
                    g_strdup(xmpp_presence_show[XMPP_PRESENCE_XA]));
359
 
 
360
361
        if (g_strncasecmp(word,
361
362
            xmpp_presence_show[XMPP_PRESENCE_DND], len) == 0)
362
363
                *list = g_list_append(*list,
363
364
                    g_strdup(xmpp_presence_show[XMPP_PRESENCE_DND]));
364
 
 
365
365
        if (g_strncasecmp(word,
366
366
            xmpp_presence_show[XMPP_PRESENCE_CHAT], len) == 0)
367
367
                *list = g_list_append(*list,
368
368
                    g_strdup(xmpp_presence_show[XMPP_PRESENCE_CHAT]));
369
 
 
370
369
        if (g_strncasecmp(word,
371
 
            xmpp_presence_show[XMPP_PRESENCE_ONLINE_STR], len) == 0)
 
370
            xmpp_presence_show[XMPP_PRESENCE_ONLINE], len) == 0)
372
371
                *list = g_list_append(*list, g_strdup("online"));
373
 
 
374
372
        signal_stop();
375
373
}
376
374
 
377
375
void
378
376
xmpp_completion_init(void)
379
377
{
380
 
        signal_add("complete word", (SIGNAL_FUNC)sig_complete_word);
 
378
        signal_add("complete word", sig_complete_word);
381
379
        signal_add("complete command roster group",
382
 
            (SIGNAL_FUNC)sig_complete_command_roster_group);
 
380
            sig_complete_command_roster_group);
383
381
        signal_add("complete command roster add",
384
 
            (SIGNAL_FUNC)sig_complete_command_roster_others);
 
382
            sig_complete_command_roster_others);
385
383
        signal_add("complete command roster remove",
386
 
            (SIGNAL_FUNC)sig_complete_command_roster_others);
 
384
            sig_complete_command_roster_others);
387
385
        signal_add("complete command roster name",
388
 
            (SIGNAL_FUNC)sig_complete_command_roster_others);
389
 
        signal_add("complete command roster accept",
390
 
            (SIGNAL_FUNC)sig_complete_command_roster_others);
391
 
        signal_add("complete command roster deny",
392
 
            (SIGNAL_FUNC)sig_complete_command_roster_others);
393
 
        signal_add("complete command roster subscribe",
394
 
            (SIGNAL_FUNC)sig_complete_command_roster_others);
395
 
        signal_add("complete command roster unsubscribe",
396
 
            (SIGNAL_FUNC)sig_complete_command_roster_others);
397
 
        signal_add("complete command join",
398
 
            (SIGNAL_FUNC)sig_complete_command_channels);
399
 
        signal_add("complete command part",
400
 
            (SIGNAL_FUNC)sig_complete_command_channels);
401
 
        signal_add("complete command invite",
402
 
            (SIGNAL_FUNC)sig_complete_command_invite);
403
 
        signal_add("complete command away",
404
 
            (SIGNAL_FUNC)sig_complete_command_away);
 
386
            sig_complete_command_roster_others);
 
387
        signal_add("complete command presence accept",
 
388
            sig_complete_command_presence);
 
389
        signal_add("complete command presence deny",
 
390
            sig_complete_command_presence);
 
391
        signal_add("complete command presence subscribe",
 
392
            sig_complete_command_presence);
 
393
        signal_add("complete command presence unsubscribe",
 
394
            sig_complete_command_presence);
 
395
        signal_add("complete command join", sig_complete_command_channels);
 
396
        signal_add("complete command part", sig_complete_command_channels);
 
397
        signal_add("complete command invite", sig_complete_command_invite);
 
398
        signal_add("complete command away", sig_complete_command_away);
405
399
}
406
400
 
407
401
void
408
402
xmpp_completion_deinit(void)
409
403
{
410
 
        signal_remove("complete word", (SIGNAL_FUNC)sig_complete_word);
 
404
        signal_remove("complete word", sig_complete_word);
411
405
        signal_remove("complete command roster group",
412
 
            (SIGNAL_FUNC) sig_complete_command_roster_group);
 
406
             sig_complete_command_roster_group);
413
407
        signal_remove("complete command roster add",
414
 
            (SIGNAL_FUNC)sig_complete_command_roster_others);
 
408
            sig_complete_command_roster_others);
415
409
        signal_remove("complete command roster remove",
416
 
            (SIGNAL_FUNC)sig_complete_command_roster_others);
 
410
            sig_complete_command_roster_others);
417
411
        signal_remove("complete command roster name",
418
 
            (SIGNAL_FUNC)sig_complete_command_roster_others);
419
 
        signal_remove("complete command roster accept",
420
 
            (SIGNAL_FUNC)sig_complete_command_roster_others);
421
 
        signal_remove("complete command roster deny",
422
 
            (SIGNAL_FUNC)sig_complete_command_roster_others);
423
 
        signal_remove("complete command roster subscribe",
424
 
            (SIGNAL_FUNC)sig_complete_command_roster_others);
425
 
        signal_remove("complete command roster unsubscribe",
426
 
            (SIGNAL_FUNC)sig_complete_command_roster_others);
427
 
        signal_remove("complete command join",
428
 
            (SIGNAL_FUNC)sig_complete_command_channels);
429
 
        signal_remove("complete command part",
430
 
            (SIGNAL_FUNC)sig_complete_command_channels);
431
 
        signal_remove("complete command invite",
432
 
            (SIGNAL_FUNC)sig_complete_command_invite);
433
 
        signal_remove("complete command away",
434
 
            (SIGNAL_FUNC)sig_complete_command_away);
 
412
            sig_complete_command_roster_others);
 
413
        signal_remove("complete command presence accept",
 
414
            sig_complete_command_presence);
 
415
        signal_remove("complete command presence deny",
 
416
            sig_complete_command_presence);
 
417
        signal_remove("complete command presence subscribe",
 
418
            sig_complete_command_presence);
 
419
        signal_remove("complete command presence unsubscribe",
 
420
            sig_complete_command_presence);
 
421
        signal_remove("complete command join", sig_complete_command_channels);
 
422
        signal_remove("complete command part", sig_complete_command_channels);
 
423
        signal_remove("complete command invite", sig_complete_command_invite);
 
424
        signal_remove("complete command away", sig_complete_command_away);
435
425
}