source: skype/skype.c @ c09d327

Last change on this file since c09d327 was c09d327, checked in by VMiklos <vmiklos@…>, at 2007-10-07T00:27:28Z

avoid nicks joining to a group chat multiple times

  • Property mode set to 100644
File size: 16.0 KB
RevLine 
[7daec06]1/*
2 *  skype.c - Skype plugin for BitlBee
3 *
4 *  Copyright (c) 2007 by Miklos Vajna <vmiklos@frugalware.org>
[f06e3ac]5 *
[7daec06]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.
[f06e3ac]24 */
[7daec06]25
[f06e3ac]26#include <stdio.h>
[ed2e37f]27#include <poll.h>
[f06e3ac]28#include <bitlbee.h>
[72aa7f0]29#include <glib.h>
[f06e3ac]30
31#define SKYPE_PORT_DEFAULT "2727"
32
[bbba374]33/*
34 * Enumerations
35 */
36
37typedef enum
38{
[df9255d]39        SKYPE_CALL_RINGING = 1,
[bbba374]40        SKYPE_CALL_MISSED
41} skype_call_status;
42
[df9255d]43typedef enum
44{
45        SKYPE_FILETRANSFER_NEW = 1,
46        SKYPE_FILETRANSFER_FAILED
47} skype_filetransfer_status;
48
[7daec06]49/*
50 * Structures
51 */
52
[f06e3ac]53struct skype_data
54{
55        struct im_connection *ic;
[a3d6427]56        char *username;
[368861e]57        /* The effective file descriptor. We store it here so any function can
58         * write() to it. */
[f06e3ac]59        int fd;
[368861e]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;
[2a0f99c]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
[c81d0ef]65         * imcb_buddy_msg() when we got the chatname. */
[77c1abe]66        char *handle;
[c81d0ef]67        char *body;
[2a0f99c]68        char *type;
[bbba374]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;
[df9255d]73        /* Same for file transfers. */
74        skype_filetransfer_status filetransfer_status;
[f06e3ac]75};
76
[adce2de]77struct skype_away_state
78{
79        char *code;
80        char *full_name;
81};
82
[7daec06]83struct skype_buddy_ask_data
84{
85        struct im_connection *ic;
86        char *handle;
87};
88
89/*
90 * Tables
91 */
92
[adce2de]93const struct skype_away_state skype_away_state_list[] =
94{
95        { "ONLINE",  "Online" },
96        { "SKYPEME",  "Skype Me" },
97        { "AWAY",   "Away" },
98        { "NA",    "Not available" },
99        { "DND",      "Do Not Disturb" },
100        { "INVISIBLE",      "Invisible" },
[23411c6]101        { "OFFLINE",      "Offline" },
102        { NULL, NULL}
[adce2de]103};
104
[7daec06]105/*
106 * Functions
107 */
[d3cbd17]108
[f06e3ac]109static void skype_init( account_t *acc )
110{
111        set_t *s;
112
113        s = set_add( &acc->set, "port", SKYPE_PORT_DEFAULT, set_eval_int, acc );
114        s->flags |= ACC_SET_OFFLINE_ONLY;
115
116        s = set_add( &acc->set, "server", NULL, set_eval_account, acc );
117        s->flags |= ACC_SET_NOSAVE | ACC_SET_OFFLINE_ONLY;
118}
119
120int skype_write( struct im_connection *ic, char *buf, int len )
121{
122        struct skype_data *sd = ic->proto_data;
[1fb89e3]123        struct pollfd pfd[1];
124
125        pfd[0].fd = sd->fd;
126        pfd[0].events = POLLOUT;
[f06e3ac]127
[7daec06]128        /* This poll is necessary or we'll get a SIGPIPE when we write() to
129         * sd->fd. */
[1fb89e3]130        poll(pfd, 1, 1000);
131        if(pfd[0].revents & POLLHUP)
132        {
133                imcb_error( ic, "Could not connect to server" );
134                imc_logout( ic, TRUE );
135                return FALSE;
136        }
[9fd4241]137        write( sd->fd, buf, len );
[f06e3ac]138
[9fd4241]139        return TRUE;
[f06e3ac]140}
141
[d3cbd17]142static void skype_buddy_ask_yes( gpointer w, struct skype_buddy_ask_data *bla )
143{
144        char *buf = g_strdup_printf("SET USER %s ISAUTHORIZED TRUE", bla->handle);
145        skype_write( bla->ic, buf, strlen( buf ) );
146        g_free(buf);
147        g_free(bla->handle);
148        g_free(bla);
149}
150
151static void skype_buddy_ask_no( gpointer w, struct skype_buddy_ask_data *bla )
152{
153        char *buf = g_strdup_printf("SET USER %s ISAUTHORIZED FALSE", bla->handle);
154        skype_write( bla->ic, buf, strlen( buf ) );
155        g_free(buf);
156        g_free(bla->handle);
157        g_free(bla);
158}
159
160void skype_buddy_ask( struct im_connection *ic, char *handle, char *message)
161{
162        struct skype_buddy_ask_data *bla = g_new0( struct skype_buddy_ask_data, 1 );
163        char *buf;
164
165        bla->ic = ic;
166        bla->handle = g_strdup(handle);
167
168        buf = g_strdup_printf( "The user %s wants to add you to his/her buddy list, saying: '%s'.", handle, message);
169        imcb_ask( ic, buf, bla, skype_buddy_ask_yes, skype_buddy_ask_no );
170        g_free( buf );
171}
172
[72aa7f0]173struct groupchat *skype_chat_by_name( struct im_connection *ic, char *name )
174{
175        struct groupchat *ret;
176
177        for( ret = ic->conversations; ret; ret = ret->next )
178        {
179                if(strcmp(name, ret->title ) == 0 )
180                        break;
181        }
182
183        return ret;
184}
185
[1323e36]186static gboolean skype_read_callback( gpointer data, gint fd, b_input_condition cond )
187{
188        struct im_connection *ic = data;
189        struct skype_data *sd = ic->proto_data;
190        char buf[1024];
191        int st;
[9fd4241]192        char **lines, **lineptr, *line, *ptr;
[1323e36]193
[98bca36]194        if( !sd || sd->fd == -1 )
[1323e36]195                return FALSE;
[7daec06]196        /* Read the whole data. */
[1323e36]197        st = read( sd->fd, buf, sizeof( buf ) );
198        if( st > 0 )
199        {
200                buf[st] = '\0';
[7daec06]201                /* Then split it up to lines. */
[9fd4241]202                lines = g_strsplit(buf, "\n", 0);
203                lineptr = lines;
204                while((line = *lineptr))
205                {
206                        if(!strlen(line))
207                                break;
208                        if(!strncmp(line, "USERS ", 6))
209                        {
210                                char **i;
211                                char **nicks;
212
213                                nicks = g_strsplit(line + 6, ", ", 0);
214                                i = nicks;
215                                while(*i)
216                                {
217                                        g_snprintf(buf, 1024, "GET USER %s ONLINESTATUS\n", *i);
218                                        skype_write( ic, buf, strlen( buf ) );
219                                        i++;
220                                }
221                                g_strfreev(nicks);
222                        }
223                        else if(!strncmp(line, "USER ", 5))
224                        {
[adce2de]225                                int flags = 0;
[be975f8]226                                char *status = strrchr(line, ' ');
227                                char *user = strchr(line, ' ');
[adce2de]228                                status++;
[be975f8]229                                ptr = strchr(++user, ' ');
230                                *ptr = '\0';
[6627d92]231                                ptr++;
[7daec06]232                                if(!strncmp(ptr, "ONLINESTATUS ", 13) &&
233                                                strcmp(user, sd->username) != 0
234                                                && strcmp(user, "echo123") != 0)
[a3d6427]235                                {
236                                        ptr = g_strdup_printf("%s@skype.com", user);
237                                        imcb_add_buddy(ic, ptr, NULL);
238                                        if(strcmp(status, "OFFLINE") != 0)
239                                                flags |= OPT_LOGGED_IN;
240                                        if(strcmp(status, "ONLINE") != 0 && strcmp(status, "SKYPEME") != 0)
241                                                flags |= OPT_AWAY;
242                                        imcb_buddy_status(ic, ptr, flags, NULL, NULL);
243                                        g_free(ptr);
244                                }
[d3cbd17]245                                else if(!strncmp(ptr, "RECEIVEDAUTHREQUEST ", 20))
246                                {
247                                        char *message = ptr + 20;
248                                        if(strlen(message))
249                                                skype_buddy_ask(ic, user, message);
250                                }
251                                else if(!strncmp(ptr, "BUDDYSTATUS ", 12))
252                                {
253                                        char *st = ptr + 12;
254                                        if(!strcmp(st, "3"))
255                                        {
256                                                char *buf = g_strdup_printf("%s@skype.com", user);
257                                                imcb_add_buddy(ic, buf, NULL);
258                                                g_free(buf);
259                                        }
260                                }
[9fd4241]261                        }
[77c1abe]262                        else if(!strncmp(line, "CHATMESSAGE ", 12))
263                        {
264                                char *id = strchr(line, ' ');
265                                if(++id)
266                                {
267                                        char *info = strchr(id, ' ');
268                                        *info = '\0';
269                                        info++;
270                                        if(!strcmp(info, "STATUS RECEIVED"))
271                                        {
[7daec06]272                                                /* New message ID:
273                                                 * (1) Request its from field
274                                                 * (2) Request its body
[2a0f99c]275                                                 * (3) Request its type
276                                                 * (4) Query chatname
[7daec06]277                                                 */
[77c1abe]278                                                g_snprintf(buf, 1024, "GET CHATMESSAGE %s FROM_HANDLE\n", id);
279                                                skype_write( ic, buf, strlen( buf ) );
280                                                g_snprintf(buf, 1024, "GET CHATMESSAGE %s BODY\n", id);
281                                                skype_write( ic, buf, strlen( buf ) );
[2a0f99c]282                                                g_snprintf(buf, 1024, "GET CHATMESSAGE %s TYPE\n", id);
283                                                skype_write( ic, buf, strlen( buf ) );
[c81d0ef]284                                                g_snprintf(buf, 1024, "GET CHATMESSAGE %s CHATNAME\n", id);
285                                                skype_write( ic, buf, strlen( buf ) );
[77c1abe]286                                        }
287                                        else if(!strncmp(info, "FROM_HANDLE ", 12))
288                                        {
289                                                info += 12;
[7daec06]290                                                /* New from field value. Store
291                                                 * it, then we can later use it
292                                                 * when we got the message's
293                                                 * body. */
[7613670]294                                                g_free(sd->handle);
[77c1abe]295                                                sd->handle = g_strdup_printf("%s@skype.com", info);
[5d1b0774]296                                        }
297                                        else if(!strncmp(info, "EDITED_BY ", 10))
298                                        {
299                                                info += 10;
300                                                /* This is the same as
301                                                 * FROM_HANDLE, except that we
302                                                 * never request these lines
303                                                 * from Skype, we just get
304                                                 * them. */
305                                                g_free(sd->handle);
306                                                sd->handle = g_strdup_printf("%s@skype.com", info);
[77c1abe]307                                        }
308                                        else if(!strncmp(info, "BODY ", 5))
309                                        {
310                                                info += 5;
[c81d0ef]311                                                g_free(sd->body);
312                                                sd->body = g_strdup(info);
313                                        }
[2a0f99c]314                                        else if(!strncmp(info, "TYPE ", 5))
315                                        {
316                                                info += 5;
317                                                g_free(sd->type);
318                                                sd->type = g_strdup(info);
319                                        }
[c81d0ef]320                                        else if(!strncmp(info, "CHATNAME ", 9))
321                                        {
322                                                info += 9;
[2a0f99c]323                                                if(sd->handle && sd->body && sd->type)
[7daec06]324                                                {
[31870ae]325                                                        struct groupchat *gc = skype_chat_by_name(ic, info);
[2a0f99c]326                                                        if(!strcmp(sd->type, "SAID"))
327                                                        {
328                                                                if(!gc)
329                                                                        /* Private message */
330                                                                        imcb_buddy_msg(ic, sd->handle, sd->body, 0, 0);
331                                                                else
332                                                                        /* Groupchat message */
333                                                                        imcb_chat_msg(gc, sd->handle, sd->body, 0, 0);
334                                                        }
335                                                        else if(!strcmp(sd->type, "SETTOPIC"))
336                                                        {
337                                                                if(gc)
338                                                                        imcb_log(ic, "%s changed the topic of %s to: %s", sd->handle, gc->title, sd->body);
[31870ae]339                                                        }
340                                                        else if(!strcmp(sd->type, "LEFT"))
341                                                        {
342                                                                if(gc)
343                                                                        imcb_chat_remove_buddy(gc, sd->handle, NULL);
[2a0f99c]344                                                        }
[7daec06]345                                                }
[77c1abe]346                                        }
347                                }
348                        }
[ecfbc5d]349                        else if(!strncmp(line, "CALL ", 5))
350                        {
351                                char *id = strchr(line, ' ');
352                                if(++id)
353                                {
354                                        char *info = strchr(id, ' ');
355                                        *info = '\0';
356                                        info++;
357                                        if(!strcmp(info, "STATUS RINGING"))
358                                        {
359                                                g_snprintf(buf, 1024, "GET CALL %s PARTNER_HANDLE\n", id);
360                                                skype_write( ic, buf, strlen( buf ) );
[bbba374]361                                                sd->call_status = SKYPE_CALL_RINGING;
362                                        }
363                                        else if(!strcmp(info, "STATUS MISSED"))
364                                        {
365                                                g_snprintf(buf, 1024, "GET CALL %s PARTNER_HANDLE\n", id);
366                                                skype_write( ic, buf, strlen( buf ) );
367                                                sd->call_status = SKYPE_CALL_MISSED;
[ecfbc5d]368                                        }
369                                        else if(!strncmp(info, "PARTNER_HANDLE ", 15))
370                                        {
371                                                info += 15;
[df9255d]372                                                if(sd->call_status) {
373                                                        switch(sd->call_status)
374                                                        {
375                                                                case SKYPE_CALL_RINGING:
376                                                                        imcb_log(ic, "The user %s is currently ringing you.", info);
377                                                                        break;
378                                                                case SKYPE_CALL_MISSED:
379                                                                        imcb_log(ic, "You have missed a call from user %s.", info);
380                                                                        break;
381                                                        }
382                                                        sd->call_status = 0;
383                                                }
384                                        }
385                                }
386                        }
387                        else if(!strncmp(line, "FILETRANSFER ", 13))
388                        {
389                                char *id = strchr(line, ' ');
390                                if(++id)
391                                {
392                                        char *info = strchr(id, ' ');
393                                        *info = '\0';
394                                        info++;
395                                        if(!strcmp(info, "STATUS NEW"))
396                                        {
397                                                g_snprintf(buf, 1024, "GET FILETRANSFER %s PARTNER_HANDLE\n", id);
398                                                skype_write( ic, buf, strlen( buf ) );
399                                                sd->filetransfer_status = SKYPE_FILETRANSFER_NEW;
400                                        }
401                                        else if(!strcmp(info, "STATUS FAILED"))
402                                        {
403                                                g_snprintf(buf, 1024, "GET FILETRANSFER %s PARTNER_HANDLE\n", id);
404                                                skype_write( ic, buf, strlen( buf ) );
405                                                sd->filetransfer_status = SKYPE_FILETRANSFER_FAILED;
406                                        }
407                                        else if(!strncmp(info, "PARTNER_HANDLE ", 15))
408                                        {
409                                                info += 15;
410                                                if(sd->filetransfer_status) {
411                                                        switch(sd->filetransfer_status)
412                                                        {
413                                                                case SKYPE_FILETRANSFER_NEW:
414                                                                        imcb_log(ic, "The user %s offered a new file for you.", info);
415                                                                        break;
416                                                                case SKYPE_FILETRANSFER_FAILED:
417                                                                        imcb_log(ic, "Failed to transfer file from user %s.", info);
418                                                                        break;
419                                                        }
420                                                        sd->filetransfer_status = 0;
[bbba374]421                                                }
[ecfbc5d]422                                        }
423                                }
424                        }
[2d07803]425                        else if(!strncmp(line, "CHAT ", 5))
426                        {
427                                char *id = strchr(line, ' ');
428                                if(++id)
429                                {
430                                        char *info = strchr(id, ' ');
431                                        *info = '\0';
432                                        info++;
[5a61e43f]433                                        if(!strcmp(info, "STATUS MULTI_SUBSCRIBED"))
[72aa7f0]434                                        {
435                                                struct groupchat *gc;
436                                                gc = imcb_chat_new( ic, id );
437                                        }
438                                        else if(!strncmp(info, "ACTIVEMEMBERS ", 14))
439                                        {
440                                                info += 14;
441                                                struct groupchat *gc = skype_chat_by_name(ic, id);
[349ee4a]442                                                if(gc)
[72aa7f0]443                                                {
[349ee4a]444                                                        char **members = g_strsplit(info, " ", 0);
445                                                        int i;
446                                                        for(i=0;members[i];i++)
447                                                        {
448                                                                if(!strcmp(members[i], sd->username))
449                                                                        continue;
450                                                                g_snprintf(buf, 1024, "%s@skype.com", members[i]);
[c09d327]451                                                                if(!g_list_find_custom(gc->in_room, buf, (GCompareFunc)strcmp))
452                                                                        imcb_chat_add_buddy(gc, buf);
[349ee4a]453                                                        }
454                                                        imcb_chat_add_buddy(gc, sd->username);
455                                                        g_strfreev(members);
[72aa7f0]456                                                }
457                                        }
[2d07803]458                                }
459                        }
[9fd4241]460                        lineptr++;
461                }
462                g_strfreev(lines);
[1323e36]463        }
464        else if( st == 0 || ( st < 0 && !sockerr_again() ) )
465        {
466                closesocket( sd->fd );
467                sd->fd = -1;
468
469                imcb_error( ic, "Error while reading from server" );
470                imc_logout( ic, TRUE );
471                return FALSE;
472        }
473        return TRUE;
474}
475
[f06e3ac]476gboolean skype_start_stream( struct im_connection *ic )
477{
[1323e36]478        struct skype_data *sd = ic->proto_data;
[f06e3ac]479        char *buf;
480        int st;
481
[1fb89e3]482        if(!sd)
483                return FALSE;
484
[368861e]485        if( sd->bfd <= 0 )
486                sd->bfd = b_input_add( sd->fd, GAIM_INPUT_READ, skype_read_callback, ic );
[1323e36]487
[7daec06]488        /* This will download all buddies. */
[9fd4241]489        buf = g_strdup_printf("SEARCH FRIENDS\n");
[f06e3ac]490        st = skype_write( ic, buf, strlen( buf ) );
491        g_free(buf);
[348a3a2]492        buf = g_strdup_printf("SET USERSTATUS ONLINE\n");
493        skype_write( ic, buf, strlen( buf ) );
494        g_free(buf);
[f06e3ac]495        return st;
496}
497
498gboolean skype_connected( gpointer data, gint source, b_input_condition cond )
499{
500        struct im_connection *ic = data;
[ed2e37f]501        imcb_connected(ic);
[f06e3ac]502        return skype_start_stream(ic);
503}
504
505static void skype_login( account_t *acc )
506{
507        struct im_connection *ic = imcb_new( acc );
508        struct skype_data *sd = g_new0( struct skype_data, 1 );
509
510        ic->proto_data = sd;
511
512        imcb_log( ic, "Connecting" );
513        sd->fd = proxy_connect(acc->server, set_getint( &acc->set, "port" ), skype_connected, ic );
[a3d6427]514        sd->username = g_strdup( acc->user );
[f06e3ac]515
516        sd->ic = ic;
517}
518
519static void skype_logout( struct im_connection *ic )
520{
521        struct skype_data *sd = ic->proto_data;
[98bca36]522        char *buf;
523
524        buf = g_strdup_printf("SET USERSTATUS OFFLINE\n");
525        skype_write( ic, buf, strlen( buf ) );
526        g_free(buf);
527
[a3d6427]528        g_free(sd->username);
[7613670]529        g_free(sd->handle);
[f06e3ac]530        g_free(sd);
[98bca36]531        ic->proto_data = NULL;
[f06e3ac]532}
533
[93ece66]534static int skype_buddy_msg( struct im_connection *ic, char *who, char *message, int flags )
535{
[77c1abe]536        char *buf, *ptr, *nick;
[93ece66]537        int st;
538
[cbec0d6]539        nick = g_strdup(who);
[77c1abe]540        ptr = strchr(nick, '@');
[0bb1b7f]541        if(ptr)
542                *ptr = '\0';
[93ece66]543
[77c1abe]544        buf = g_strdup_printf("MESSAGE %s %s\n", nick, message);
545        g_free(nick);
[93ece66]546        st = skype_write( ic, buf, strlen( buf ) );
547        g_free(buf);
548
549        return st;
550}
551
[23411c6]552const struct skype_away_state *skype_away_state_by_name( char *name )
553{
554        int i;
555
556        for( i = 0; skype_away_state_list[i].full_name; i ++ )
557                if( g_strcasecmp( skype_away_state_list[i].full_name, name ) == 0 )
558                        return( skype_away_state_list + i );
559
560        return NULL;
561}
562
[f06e3ac]563static void skype_set_away( struct im_connection *ic, char *state_txt, char *message )
564{
[23411c6]565        const struct skype_away_state *state;
566        char *buf;
567
568        if( strcmp( state_txt, GAIM_AWAY_CUSTOM ) == 0 )
569                state = skype_away_state_by_name( "Away" );
570        else
571                state = skype_away_state_by_name( state_txt );
572        buf = g_strdup_printf("SET USERSTATUS %s\n", state->code);
573        skype_write( ic, buf, strlen( buf ) );
574        g_free(buf);
[f06e3ac]575}
576
577static GList *skype_away_states( struct im_connection *ic )
578{
[23411c6]579        GList *l = NULL;
[adce2de]580        int i;
581       
[23411c6]582        for( i = 0; skype_away_state_list[i].full_name; i ++ )
583                l = g_list_append( l, (void*) skype_away_state_list[i].full_name );
[adce2de]584       
[f06e3ac]585        return l;
586}
587
588static void skype_add_buddy( struct im_connection *ic, char *who, char *group )
589{
[6627d92]590        char *buf, *nick, *ptr;
591
[cbec0d6]592        nick = g_strdup(who);
[6627d92]593        ptr = strchr(nick, '@');
594        if(ptr)
595                *ptr = '\0';
596        buf = g_strdup_printf("SET USER %s BUDDYSTATUS 2 Please authorize me\n", nick);
597        skype_write( ic, buf, strlen( buf ) );
598        g_free(nick);
[f06e3ac]599}
600
601static void skype_remove_buddy( struct im_connection *ic, char *who, char *group )
602{
[6627d92]603        char *buf, *nick, *ptr;
604
[cbec0d6]605        nick = g_strdup(who);
[6627d92]606        ptr = strchr(nick, '@');
607        if(ptr)
608                *ptr = '\0';
609        buf = g_strdup_printf("SET USER %s BUDDYSTATUS 1\n", nick);
610        skype_write( ic, buf, strlen( buf ) );
611        g_free(nick);
[f06e3ac]612}
613
[79e20f9]614void skype_chat_msg( struct groupchat *gc, char *message, int flags )
[66c9558]615{
[79e20f9]616        struct im_connection *ic = gc->ic;
617        char *buf;
618        buf = g_strdup_printf("CHATMESSAGE %s %s\n", gc->title, message);
619        skype_write( ic, buf, strlen( buf ) );
620        g_free(buf);
[66c9558]621}
622
[b01dc6c]623void skype_chat_leave( struct groupchat *gc )
624{
625        struct im_connection *ic = gc->ic;
626        char *buf;
627        buf = g_strdup_printf("ALTER CHAT %s LEAVE\n", gc->title);
628        skype_write( ic, buf, strlen( buf ) );
629        g_free(buf);
630}
631
[f06e3ac]632void init_plugin(void)
633{
634        struct prpl *ret = g_new0( struct prpl, 1 );
635
636        ret->name = "skype";
637        ret->login = skype_login;
638        ret->init = skype_init;
639        ret->logout = skype_logout;
[93ece66]640        ret->buddy_msg = skype_buddy_msg;
[f06e3ac]641        ret->away_states = skype_away_states;
[7daec06]642        ret->set_away = skype_set_away;
[f06e3ac]643        ret->add_buddy = skype_add_buddy;
644        ret->remove_buddy = skype_remove_buddy;
[66c9558]645        ret->chat_msg = skype_chat_msg;
[b01dc6c]646        ret->chat_leave = skype_chat_leave;
[f06e3ac]647        ret->handle_cmp = g_strcasecmp;
648        register_protocol( ret );
649}
Note: See TracBrowser for help on using the repository browser.