source: skype/skype.c @ d601f9b

Last change on this file since d601f9b was d601f9b, checked in by Miklos Vajna <vmiklos@…>, at 2007-10-16T23:09:09Z

use the new imcb_chat_topic() function
WARNING: this is not yet in the bitlbee release branch, i'll update the docs
when it'll be there

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