source: skype/skype.c @ f8674db

Last change on this file since f8674db was f8674db, checked in by Miklos Vajna <vmiklos@…>, at 2007-10-17T00:46:38Z

show topic if it was set before join

  • Property mode set to 100644
File size: 18.9 KB
Line 
1/*
2 *  skype.c - Skype plugin for BitlBee
3 *
4 *  Copyright (c) 2007 by Miklos Vajna <vmiklos@frugalware.org>
5 *
6 *  Several ideas are used from the BitlBee Jabber plugin, which is
7 *
8 *  Copyright (c) 2006 by Wilmer van der Gaast <wilmer@gaast.net>
9 *
10 *  This program is free software; you can redistribute it and/or modify
11 *  it under the terms of the GNU General Public License as published by
12 *  the Free Software Foundation; either version 2 of the License, or
13 *  (at your option) any later version.
14 *
15 *  This program is distributed in the hope that it will be useful,
16 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
17 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18 *  GNU General Public License for more details.
19 *
20 *  You should have received a copy of the GNU General Public License
21 *  along with this program; if not, write to the Free Software
22 *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
23 *  USA.
24 */
25
26#include <stdio.h>
27#include <poll.h>
28#include <bitlbee.h>
29#include <glib.h>
30
31#define SKYPE_PORT_DEFAULT "2727"
32
33/*
34 * Enumerations
35 */
36
37typedef enum
38{
39        SKYPE_CALL_RINGING = 1,
40        SKYPE_CALL_MISSED
41} skype_call_status;
42
43typedef enum
44{
45        SKYPE_FILETRANSFER_NEW = 1,
46        SKYPE_FILETRANSFER_FAILED
47} skype_filetransfer_status;
48
49/*
50 * Structures
51 */
52
53struct skype_data
54{
55        struct im_connection *ic;
56        char *username;
57        /* The effective file descriptor. We store it here so any function can
58         * write() to it. */
59        int fd;
60        /* File descriptor returned by bitlbee. we store it so we know when
61         * we're connected and when we aren't. */
62        int bfd;
63        /* When we receive a new message id, we query the properties, finally
64         * the chatname. Store the properties here so that we can use
65         * imcb_buddy_msg() when we got the chatname. */
66        char *handle;
67        char *body;
68        char *type;
69        /* This is necessary because we send a notification when we get the
70         * handle. So we store the state here and then we can send a
71         * notification about the handle is in a given status. */
72        skype_call_status call_status;
73        /* Same for file transfers. */
74        skype_filetransfer_status filetransfer_status;
75        /* Using /j #nick we want to have a groupchat with two people. Usually
76         * not (default). */
77        char* groupchat_with;
78        /* The user who invited us to the chat. */
79        char* adder;
80};
81
82struct skype_away_state
83{
84        char *code;
85        char *full_name;
86};
87
88struct skype_buddy_ask_data
89{
90        struct im_connection *ic;
91        char *handle;
92};
93
94/*
95 * Tables
96 */
97
98const struct skype_away_state skype_away_state_list[] =
99{
100        { "ONLINE",  "Online" },
101        { "SKYPEME",  "Skype Me" },
102        { "AWAY",   "Away" },
103        { "NA",    "Not available" },
104        { "DND",      "Do Not Disturb" },
105        { "INVISIBLE",      "Invisible" },
106        { "OFFLINE",      "Offline" },
107        { NULL, NULL}
108};
109
110/*
111 * Functions
112 */
113
114static void skype_init( account_t *acc )
115{
116        set_t *s;
117
118        s = set_add( &acc->set, "port", SKYPE_PORT_DEFAULT, set_eval_int, acc );
119        s->flags |= ACC_SET_OFFLINE_ONLY;
120
121        s = set_add( &acc->set, "server", NULL, set_eval_account, acc );
122        s->flags |= ACC_SET_NOSAVE | ACC_SET_OFFLINE_ONLY;
123}
124
125int skype_write( struct im_connection *ic, char *buf, int len )
126{
127        struct skype_data *sd = ic->proto_data;
128        struct pollfd pfd[1];
129
130        pfd[0].fd = sd->fd;
131        pfd[0].events = POLLOUT;
132
133        /* This poll is necessary or we'll get a SIGPIPE when we write() to
134         * sd->fd. */
135        poll(pfd, 1, 1000);
136        if(pfd[0].revents & POLLHUP)
137        {
138                imcb_error( ic, "Could not connect to server" );
139                imc_logout( ic, TRUE );
140                return FALSE;
141        }
142        write( sd->fd, buf, len );
143
144        return TRUE;
145}
146
147static void skype_buddy_ask_yes( gpointer w, struct skype_buddy_ask_data *bla )
148{
149        char *buf = g_strdup_printf("SET USER %s ISAUTHORIZED TRUE", bla->handle);
150        skype_write( bla->ic, buf, strlen( buf ) );
151        g_free(buf);
152        g_free(bla->handle);
153        g_free(bla);
154}
155
156static void skype_buddy_ask_no( gpointer w, struct skype_buddy_ask_data *bla )
157{
158        char *buf = g_strdup_printf("SET USER %s ISAUTHORIZED FALSE", bla->handle);
159        skype_write( bla->ic, buf, strlen( buf ) );
160        g_free(buf);
161        g_free(bla->handle);
162        g_free(bla);
163}
164
165void skype_buddy_ask( struct im_connection *ic, char *handle, char *message)
166{
167        struct skype_buddy_ask_data *bla = g_new0( struct skype_buddy_ask_data, 1 );
168        char *buf;
169
170        bla->ic = ic;
171        bla->handle = g_strdup(handle);
172
173        buf = g_strdup_printf( "The user %s wants to add you to his/her buddy list, saying: '%s'.", handle, message);
174        imcb_ask( ic, buf, bla, skype_buddy_ask_yes, skype_buddy_ask_no );
175        g_free( buf );
176}
177
178struct groupchat *skype_chat_by_name( struct im_connection *ic, char *name )
179{
180        struct groupchat *ret;
181
182        for( ret = ic->conversations; ret; ret = ret->next )
183        {
184                if(strcmp(name, ret->title ) == 0 )
185                        break;
186        }
187
188        return ret;
189}
190
191static gboolean skype_read_callback( gpointer data, gint fd, b_input_condition cond )
192{
193        struct im_connection *ic = data;
194        struct skype_data *sd = ic->proto_data;
195        char buf[1024];
196        int st;
197        char **lines, **lineptr, *line, *ptr;
198
199        if( !sd || sd->fd == -1 )
200                return FALSE;
201        /* Read the whole data. */
202        st = read( sd->fd, buf, sizeof( buf ) );
203        if( st > 0 )
204        {
205                buf[st] = '\0';
206                /* Then split it up to lines. */
207                lines = g_strsplit(buf, "\n", 0);
208                lineptr = lines;
209                while((line = *lineptr))
210                {
211                        if(!strlen(line))
212                                break;
213                        if(!strncmp(line, "USERS ", 6))
214                        {
215                                char **i;
216                                char **nicks;
217
218                                nicks = g_strsplit(line + 6, ", ", 0);
219                                i = nicks;
220                                while(*i)
221                                {
222                                        g_snprintf(buf, 1024, "GET USER %s ONLINESTATUS\n", *i);
223                                        skype_write( ic, buf, strlen( buf ) );
224                                        i++;
225                                }
226                                g_strfreev(nicks);
227                        }
228                        else if(!strncmp(line, "USER ", 5))
229                        {
230                                int flags = 0;
231                                char *status = strrchr(line, ' ');
232                                char *user = strchr(line, ' ');
233                                status++;
234                                ptr = strchr(++user, ' ');
235                                *ptr = '\0';
236                                ptr++;
237                                if(!strncmp(ptr, "ONLINESTATUS ", 13) &&
238                                                strcmp(user, sd->username) != 0
239                                                && strcmp(user, "echo123") != 0)
240                                {
241                                        ptr = g_strdup_printf("%s@skype.com", user);
242                                        imcb_add_buddy(ic, ptr, NULL);
243                                        if(strcmp(status, "OFFLINE") != 0)
244                                                flags |= OPT_LOGGED_IN;
245                                        if(strcmp(status, "ONLINE") != 0 && strcmp(status, "SKYPEME") != 0)
246                                                flags |= OPT_AWAY;
247                                        imcb_buddy_status(ic, ptr, flags, NULL, NULL);
248                                        g_free(ptr);
249                                }
250                                else if(!strncmp(ptr, "RECEIVEDAUTHREQUEST ", 20))
251                                {
252                                        char *message = ptr + 20;
253                                        if(strlen(message))
254                                                skype_buddy_ask(ic, user, message);
255                                }
256                                else if(!strncmp(ptr, "BUDDYSTATUS ", 12))
257                                {
258                                        char *st = ptr + 12;
259                                        if(!strcmp(st, "3"))
260                                        {
261                                                char *buf = g_strdup_printf("%s@skype.com", user);
262                                                imcb_add_buddy(ic, buf, NULL);
263                                                g_free(buf);
264                                        }
265                                }
266                        }
267                        else if(!strncmp(line, "CHATMESSAGE ", 12))
268                        {
269                                char *id = strchr(line, ' ');
270                                if(++id)
271                                {
272                                        char *info = strchr(id, ' ');
273                                        *info = '\0';
274                                        info++;
275                                        if(!strcmp(info, "STATUS RECEIVED"))
276                                        {
277                                                /* New message ID:
278                                                 * (1) Request its from field
279                                                 * (2) Request its body
280                                                 * (3) Request its type
281                                                 * (4) Query chatname
282                                                 */
283                                                g_snprintf(buf, 1024, "GET CHATMESSAGE %s FROM_HANDLE\n", id);
284                                                skype_write( ic, buf, strlen( buf ) );
285                                                g_snprintf(buf, 1024, "GET CHATMESSAGE %s BODY\n", id);
286                                                skype_write( ic, buf, strlen( buf ) );
287                                                g_snprintf(buf, 1024, "GET CHATMESSAGE %s TYPE\n", id);
288                                                skype_write( ic, buf, strlen( buf ) );
289                                                g_snprintf(buf, 1024, "GET CHATMESSAGE %s CHATNAME\n", id);
290                                                skype_write( ic, buf, strlen( buf ) );
291                                        }
292                                        else if(!strncmp(info, "FROM_HANDLE ", 12))
293                                        {
294                                                info += 12;
295                                                /* New from field value. Store
296                                                 * it, then we can later use it
297                                                 * when we got the message's
298                                                 * body. */
299                                                g_free(sd->handle);
300                                                sd->handle = g_strdup_printf("%s@skype.com", info);
301                                        }
302                                        else if(!strncmp(info, "EDITED_BY ", 10))
303                                        {
304                                                info += 10;
305                                                /* This is the same as
306                                                 * FROM_HANDLE, except that we
307                                                 * never request these lines
308                                                 * from Skype, we just get
309                                                 * them. */
310                                                g_free(sd->handle);
311                                                sd->handle = g_strdup_printf("%s@skype.com", info);
312                                        }
313                                        else if(!strncmp(info, "BODY ", 5))
314                                        {
315                                                info += 5;
316                                                g_free(sd->body);
317                                                sd->body = g_strdup(info);
318                                        }
319                                        else if(!strncmp(info, "TYPE ", 5))
320                                        {
321                                                info += 5;
322                                                g_free(sd->type);
323                                                sd->type = g_strdup(info);
324                                        }
325                                        else if(!strncmp(info, "CHATNAME ", 9))
326                                        {
327                                                info += 9;
328                                                if(sd->handle && sd->body && sd->type)
329                                                {
330                                                        struct groupchat *gc = skype_chat_by_name(ic, info);
331                                                        if(!strcmp(sd->type, "SAID"))
332                                                        {
333                                                                if(!gc)
334                                                                        /* Private message */
335                                                                        imcb_buddy_msg(ic, sd->handle, sd->body, 0, 0);
336                                                                else
337                                                                        /* Groupchat message */
338                                                                        imcb_chat_msg(gc, sd->handle, sd->body, 0, 0);
339                                                        }
340                                                        else if(!strcmp(sd->type, "SETTOPIC"))
341                                                        {
342                                                                if(gc)
343                                                                        imcb_chat_topic(gc, sd->handle, sd->body);
344                                                        }
345                                                        else if(!strcmp(sd->type, "LEFT"))
346                                                        {
347                                                                if(gc)
348                                                                        imcb_chat_remove_buddy(gc, sd->handle, NULL);
349                                                        }
350                                                }
351                                        }
352                                }
353                        }
354                        else if(!strncmp(line, "CALL ", 5))
355                        {
356                                char *id = strchr(line, ' ');
357                                if(++id)
358                                {
359                                        char *info = strchr(id, ' ');
360                                        *info = '\0';
361                                        info++;
362                                        if(!strcmp(info, "STATUS RINGING"))
363                                        {
364                                                g_snprintf(buf, 1024, "GET CALL %s PARTNER_HANDLE\n", id);
365                                                skype_write( ic, buf, strlen( buf ) );
366                                                sd->call_status = SKYPE_CALL_RINGING;
367                                        }
368                                        else if(!strcmp(info, "STATUS MISSED"))
369                                        {
370                                                g_snprintf(buf, 1024, "GET CALL %s PARTNER_HANDLE\n", id);
371                                                skype_write( ic, buf, strlen( buf ) );
372                                                sd->call_status = SKYPE_CALL_MISSED;
373                                        }
374                                        else if(!strncmp(info, "PARTNER_HANDLE ", 15))
375                                        {
376                                                info += 15;
377                                                if(sd->call_status) {
378                                                        switch(sd->call_status)
379                                                        {
380                                                                case SKYPE_CALL_RINGING:
381                                                                        imcb_log(ic, "The user %s is currently ringing you.", info);
382                                                                        break;
383                                                                case SKYPE_CALL_MISSED:
384                                                                        imcb_log(ic, "You have missed a call from user %s.", info);
385                                                                        break;
386                                                        }
387                                                        sd->call_status = 0;
388                                                }
389                                        }
390                                }
391                        }
392                        else if(!strncmp(line, "FILETRANSFER ", 13))
393                        {
394                                char *id = strchr(line, ' ');
395                                if(++id)
396                                {
397                                        char *info = strchr(id, ' ');
398                                        *info = '\0';
399                                        info++;
400                                        if(!strcmp(info, "STATUS NEW"))
401                                        {
402                                                g_snprintf(buf, 1024, "GET FILETRANSFER %s PARTNER_HANDLE\n", id);
403                                                skype_write( ic, buf, strlen( buf ) );
404                                                sd->filetransfer_status = SKYPE_FILETRANSFER_NEW;
405                                        }
406                                        else if(!strcmp(info, "STATUS FAILED"))
407                                        {
408                                                g_snprintf(buf, 1024, "GET FILETRANSFER %s PARTNER_HANDLE\n", id);
409                                                skype_write( ic, buf, strlen( buf ) );
410                                                sd->filetransfer_status = SKYPE_FILETRANSFER_FAILED;
411                                        }
412                                        else if(!strncmp(info, "PARTNER_HANDLE ", 15))
413                                        {
414                                                info += 15;
415                                                if(sd->filetransfer_status) {
416                                                        switch(sd->filetransfer_status)
417                                                        {
418                                                                case SKYPE_FILETRANSFER_NEW:
419                                                                        imcb_log(ic, "The user %s offered a new file for you.", info);
420                                                                        break;
421                                                                case SKYPE_FILETRANSFER_FAILED:
422                                                                        imcb_log(ic, "Failed to transfer file from user %s.", info);
423                                                                        break;
424                                                        }
425                                                        sd->filetransfer_status = 0;
426                                                }
427                                        }
428                                }
429                        }
430                        else if(!strncmp(line, "CHAT ", 5))
431                        {
432                                char *id = strchr(line, ' ');
433                                if(++id)
434                                {
435                                        char *info = strchr(id, ' ');
436                                        if(info)
437                                                *info = '\0';
438                                        info++;
439                                        if(!strcmp(info, "STATUS MULTI_SUBSCRIBED"))
440                                        {
441                                                imcb_chat_new( ic, id );
442                                                g_snprintf(buf, 1024, "GET CHAT %s ADDER\n", id);
443                                                skype_write(ic, buf, strlen(buf));
444                                                g_snprintf(buf, 1024, "GET CHAT %s TOPIC\n", id);
445                                                skype_write(ic, buf, strlen(buf));
446                                        }
447                                        else if(!strcmp(info, "STATUS DIALOG") && sd->groupchat_with)
448                                        {
449                                                struct groupchat *gc = imcb_chat_new( ic, id );
450                                                /* According to the docs this
451                                                 * is necessary. However it
452                                                 * does not seem the situation
453                                                 * and it would open an extra
454                                                 * window on our client, so
455                                                 * just leave it out. */
456                                                /*g_snprintf(buf, 1024, "OPEN CHAT %s\n", id);
457                                                skype_write(ic, buf, strlen(buf));*/
458                                                g_snprintf(buf, 1024, "%s@skype.com", sd->groupchat_with);
459                                                imcb_chat_add_buddy(gc, buf);
460                                                imcb_chat_add_buddy(gc, sd->username);
461                                                g_free(sd->groupchat_with);
462                                                sd->groupchat_with = NULL;
463                                                g_snprintf(buf, 1024, "GET CHAT %s ADDER\n", id);
464                                                skype_write(ic, buf, strlen(buf));
465                                                g_snprintf(buf, 1024, "GET CHAT %s TOPIC\n", id);
466                                                skype_write(ic, buf, strlen(buf));
467                                        }
468                                        else if(!strcmp(info, "STATUS UNSUBSCRIBED"))
469                                        {
470                                                struct groupchat *gc = skype_chat_by_name(ic, id);
471                                                if(gc)
472                                                        gc->data = (void*)FALSE;
473                                        }
474                                        else if(!strncmp(info, "ADDER ", 6))
475                                        {
476                                                info += 6;
477                                                g_free(sd->adder);
478                                                sd->adder = g_strdup_printf("%s@skype.com", info);
479                                        }
480                                        else if(!strncmp(info, "TOPIC ", 6))
481                                        {
482                                                info += 6;
483                                                struct groupchat *gc = skype_chat_by_name(ic, id);
484                                                if(gc && sd->adder)
485                                                {
486                                                        imcb_chat_topic(gc, sd->adder, info);
487                                                        g_free(sd->adder);
488                                                        sd->adder = NULL;
489                                                }
490                                        }
491                                        else if(!strncmp(info, "ACTIVEMEMBERS ", 14))
492                                        {
493                                                info += 14;
494                                                struct groupchat *gc = skype_chat_by_name(ic, id);
495                                                /* Hack! We set ->data to TRUE
496                                                 * while we're on the channel
497                                                 * so that we won't rejoin
498                                                 * after a /part. */
499                                                if(gc && !gc->data)
500                                                {
501                                                        char **members = g_strsplit(info, " ", 0);
502                                                        int i;
503                                                        for(i=0;members[i];i++)
504                                                        {
505                                                                if(!strcmp(members[i], sd->username))
506                                                                        continue;
507                                                                g_snprintf(buf, 1024, "%s@skype.com", members[i]);
508                                                                if(!g_list_find_custom(gc->in_room, buf, (GCompareFunc)strcmp))
509                                                                        imcb_chat_add_buddy(gc, buf);
510                                                        }
511                                                        imcb_chat_add_buddy(gc, sd->username);
512                                                        g_strfreev(members);
513                                                }
514                                        }
515                                }
516                        }
517                        lineptr++;
518                }
519                g_strfreev(lines);
520        }
521        else if( st == 0 || ( st < 0 && !sockerr_again() ) )
522        {
523                closesocket( sd->fd );
524                sd->fd = -1;
525
526                imcb_error( ic, "Error while reading from server" );
527                imc_logout( ic, TRUE );
528                return FALSE;
529        }
530        return TRUE;
531}
532
533gboolean skype_start_stream( struct im_connection *ic )
534{
535        struct skype_data *sd = ic->proto_data;
536        char *buf;
537        int st;
538
539        if(!sd)
540                return FALSE;
541
542        if( sd->bfd <= 0 )
543                sd->bfd = b_input_add( sd->fd, GAIM_INPUT_READ, skype_read_callback, ic );
544
545        /* This will download all buddies. */
546        buf = g_strdup_printf("SEARCH FRIENDS\n");
547        st = skype_write( ic, buf, strlen( buf ) );
548        g_free(buf);
549        buf = g_strdup_printf("SET USERSTATUS ONLINE\n");
550        skype_write( ic, buf, strlen( buf ) );
551        g_free(buf);
552        return st;
553}
554
555gboolean skype_connected( gpointer data, gint source, b_input_condition cond )
556{
557        struct im_connection *ic = data;
558        imcb_connected(ic);
559        return skype_start_stream(ic);
560}
561
562static void skype_login( account_t *acc )
563{
564        struct im_connection *ic = imcb_new( acc );
565        struct skype_data *sd = g_new0( struct skype_data, 1 );
566
567        ic->proto_data = sd;
568
569        imcb_log( ic, "Connecting" );
570        sd->fd = proxy_connect(acc->server, set_getint( &acc->set, "port" ), skype_connected, ic );
571        sd->username = g_strdup( acc->user );
572
573        sd->ic = ic;
574}
575
576static void skype_logout( struct im_connection *ic )
577{
578        struct skype_data *sd = ic->proto_data;
579        char *buf;
580
581        buf = g_strdup_printf("SET USERSTATUS OFFLINE\n");
582        skype_write( ic, buf, strlen( buf ) );
583        g_free(buf);
584
585        g_free(sd->username);
586        g_free(sd->handle);
587        g_free(sd);
588        ic->proto_data = NULL;
589}
590
591static int skype_buddy_msg( struct im_connection *ic, char *who, char *message, int flags )
592{
593        char *buf, *ptr, *nick;
594        int st;
595
596        nick = g_strdup(who);
597        ptr = strchr(nick, '@');
598        if(ptr)
599                *ptr = '\0';
600
601        buf = g_strdup_printf("MESSAGE %s %s\n", nick, message);
602        g_free(nick);
603        st = skype_write( ic, buf, strlen( buf ) );
604        g_free(buf);
605
606        return st;
607}
608
609const struct skype_away_state *skype_away_state_by_name( char *name )
610{
611        int i;
612
613        for( i = 0; skype_away_state_list[i].full_name; i ++ )
614                if( g_strcasecmp( skype_away_state_list[i].full_name, name ) == 0 )
615                        return( skype_away_state_list + i );
616
617        return NULL;
618}
619
620static void skype_set_away( struct im_connection *ic, char *state_txt, char *message )
621{
622        const struct skype_away_state *state;
623        char *buf;
624
625        if( strcmp( state_txt, GAIM_AWAY_CUSTOM ) == 0 )
626                state = skype_away_state_by_name( "Away" );
627        else
628                state = skype_away_state_by_name( state_txt );
629        buf = g_strdup_printf("SET USERSTATUS %s\n", state->code);
630        skype_write( ic, buf, strlen( buf ) );
631        g_free(buf);
632}
633
634static GList *skype_away_states( struct im_connection *ic )
635{
636        GList *l = NULL;
637        int i;
638       
639        for( i = 0; skype_away_state_list[i].full_name; i ++ )
640                l = g_list_append( l, (void*) skype_away_state_list[i].full_name );
641       
642        return l;
643}
644
645static void skype_add_buddy( struct im_connection *ic, char *who, char *group )
646{
647        char *buf, *nick, *ptr;
648
649        nick = g_strdup(who);
650        ptr = strchr(nick, '@');
651        if(ptr)
652                *ptr = '\0';
653        buf = g_strdup_printf("SET USER %s BUDDYSTATUS 2 Please authorize me\n", nick);
654        skype_write( ic, buf, strlen( buf ) );
655        g_free(nick);
656}
657
658static void skype_remove_buddy( struct im_connection *ic, char *who, char *group )
659{
660        char *buf, *nick, *ptr;
661
662        nick = g_strdup(who);
663        ptr = strchr(nick, '@');
664        if(ptr)
665                *ptr = '\0';
666        buf = g_strdup_printf("SET USER %s BUDDYSTATUS 1\n", nick);
667        skype_write( ic, buf, strlen( buf ) );
668        g_free(nick);
669}
670
671void skype_chat_msg( struct groupchat *gc, char *message, int flags )
672{
673        struct im_connection *ic = gc->ic;
674        char *buf;
675        buf = g_strdup_printf("CHATMESSAGE %s %s\n", gc->title, message);
676        skype_write( ic, buf, strlen( buf ) );
677        g_free(buf);
678}
679
680void skype_chat_leave( struct groupchat *gc )
681{
682        struct im_connection *ic = gc->ic;
683        char *buf;
684        buf = g_strdup_printf("ALTER CHAT %s LEAVE\n", gc->title);
685        skype_write( ic, buf, strlen( buf ) );
686        g_free(buf);
687        gc->data = (void*)TRUE;
688}
689
690void skype_chat_invite(struct groupchat *gc, char *who, char *message)
691{
692        struct im_connection *ic = gc->ic;
693        char *buf, *ptr, *nick;
694        nick = g_strdup(message);
695        ptr = strchr(nick, '@');
696        if(ptr)
697                *ptr = '\0';
698        buf = g_strdup_printf("ALTER CHAT %s ADDMEMBERS %s\n", gc->title, nick);
699        skype_write( ic, buf, strlen( buf ) );
700        g_free(buf);
701        g_free(nick);
702}
703
704void skype_chat_topic(struct groupchat *gc, char *message)
705{
706        struct im_connection *ic = gc->ic;
707        char *buf;
708        buf = g_strdup_printf("ALTER CHAT %s SETTOPIC %s\n", gc->title, message);
709        skype_write( ic, buf, strlen( buf ) );
710        g_free(buf);
711}
712
713struct groupchat *skype_chat_with(struct im_connection *ic, char *who)
714{
715        struct skype_data *sd = ic->proto_data;
716        char *ptr, *nick, *buf;
717        nick = g_strdup(who);
718        ptr = strchr(nick, '@');
719        if(ptr)
720                *ptr = '\0';
721        buf = g_strdup_printf("CHAT CREATE %s\n", nick);
722        skype_write(ic, buf, strlen(buf));
723        g_free(buf);
724        sd->groupchat_with = g_strdup(nick);
725        g_free(nick);
726        return(NULL);
727}
728
729void init_plugin(void)
730{
731        struct prpl *ret = g_new0( struct prpl, 1 );
732
733        ret->name = "skype";
734        ret->login = skype_login;
735        ret->init = skype_init;
736        ret->logout = skype_logout;
737        ret->buddy_msg = skype_buddy_msg;
738        ret->away_states = skype_away_states;
739        ret->set_away = skype_set_away;
740        ret->add_buddy = skype_add_buddy;
741        ret->remove_buddy = skype_remove_buddy;
742        ret->chat_msg = skype_chat_msg;
743        ret->chat_leave = skype_chat_leave;
744        ret->chat_invite = skype_chat_invite;
745        ret->chat_with = skype_chat_with;
746        ret->handle_cmp = g_strcasecmp;
747        ret->chat_topic = skype_chat_topic;
748        register_protocol( ret );
749}
Note: See TracBrowser for help on using the repository browser.