source: skype/skype.c @ 67454bd

Last change on this file since 67454bd was 67454bd, checked in by Miklos Vajna <vmiklos@…>, at 2007-12-16T02:55:55Z

initial support for the info command
currently it prints only the full name

  • Property mode set to 100644
File size: 22.3 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        /* List, because of multiline messages. */
68        GList *body;
69        char *type;
70        /* This is necessary because we send a notification when we get the
71         * handle. So we store the state here and then we can send a
72         * notification about the handle is in a given status. */
73        skype_call_status call_status;
74        /* Same for file transfers. */
75        skype_filetransfer_status filetransfer_status;
76        /* Using /j #nick we want to have a groupchat with two people. Usually
77         * not (default). */
78        char* groupchat_with;
79        /* The user who invited us to the chat. */
80        char* adder;
81        /* If we are waiting for a confirmation about we changed the topic. */
82        int topic_wait;
83        /* These are used by the info command. */
84        char *info_fullname;
85        char *info_phonehome;
86        char *info_phoneoffice;
87        char *info_phonemobile;
88        char *info_nrbuddies;
89        char *info_tz;
90        char *info_seen;
91        char *info_birthday;
92        char *info_sex;
93        char *info_language;
94        char *info_country;
95        char *info_province;
96        char *info_city;
97        char *info_homepage;
98        char *info_about;
99};
100
101struct skype_away_state
102{
103        char *code;
104        char *full_name;
105};
106
107struct skype_buddy_ask_data
108{
109        struct im_connection *ic;
110        char *handle;
111};
112
113/*
114 * Tables
115 */
116
117const struct skype_away_state skype_away_state_list[] =
118{
119        { "ONLINE",  "Online" },
120        { "SKYPEME",  "Skype Me" },
121        { "AWAY",   "Away" },
122        { "NA",    "Not available" },
123        { "DND",      "Do Not Disturb" },
124        { "INVISIBLE",      "Invisible" },
125        { "OFFLINE",      "Offline" },
126        { NULL, NULL}
127};
128
129/*
130 * Functions
131 */
132
133static void skype_init( account_t *acc )
134{
135        set_t *s;
136
137        s = set_add( &acc->set, "port", SKYPE_PORT_DEFAULT, set_eval_int, acc );
138        s->flags |= ACC_SET_OFFLINE_ONLY;
139
140        s = set_add( &acc->set, "server", NULL, set_eval_account, acc );
141        s->flags |= ACC_SET_NOSAVE | ACC_SET_OFFLINE_ONLY;
142}
143
144int skype_write( struct im_connection *ic, char *buf, int len )
145{
146        struct skype_data *sd = ic->proto_data;
147        struct pollfd pfd[1];
148
149        pfd[0].fd = sd->fd;
150        pfd[0].events = POLLOUT;
151
152        /* This poll is necessary or we'll get a SIGPIPE when we write() to
153         * sd->fd. */
154        poll(pfd, 1, 1000);
155        if(pfd[0].revents & POLLHUP)
156        {
157                imcb_error( ic, "Could not connect to server" );
158                imc_logout( ic, TRUE );
159                return FALSE;
160        }
161        write( sd->fd, buf, len );
162
163        return TRUE;
164}
165
166static void skype_buddy_ask_yes( gpointer w, struct skype_buddy_ask_data *bla )
167{
168        char *buf = g_strdup_printf("SET USER %s ISAUTHORIZED TRUE", bla->handle);
169        skype_write( bla->ic, buf, strlen( buf ) );
170        g_free(buf);
171        g_free(bla->handle);
172        g_free(bla);
173}
174
175static void skype_buddy_ask_no( gpointer w, struct skype_buddy_ask_data *bla )
176{
177        char *buf = g_strdup_printf("SET USER %s ISAUTHORIZED FALSE", bla->handle);
178        skype_write( bla->ic, buf, strlen( buf ) );
179        g_free(buf);
180        g_free(bla->handle);
181        g_free(bla);
182}
183
184void skype_buddy_ask( struct im_connection *ic, char *handle, char *message)
185{
186        struct skype_buddy_ask_data *bla = g_new0( struct skype_buddy_ask_data, 1 );
187        char *buf;
188
189        bla->ic = ic;
190        bla->handle = g_strdup(handle);
191
192        buf = g_strdup_printf( "The user %s wants to add you to his/her buddy list, saying: '%s'.", handle, message);
193        imcb_ask( ic, buf, bla, skype_buddy_ask_yes, skype_buddy_ask_no );
194        g_free( buf );
195}
196
197struct groupchat *skype_chat_by_name( struct im_connection *ic, char *name )
198{
199        struct groupchat *ret;
200
201        for( ret = ic->groupchats; ret; ret = ret->next )
202        {
203                if(strcmp(name, ret->title ) == 0 )
204                        break;
205        }
206
207        return ret;
208}
209
210static gboolean skype_read_callback( gpointer data, gint fd, b_input_condition cond )
211{
212        struct im_connection *ic = data;
213        struct skype_data *sd = ic->proto_data;
214        char buf[1024];
215        int st;
216        char **lines, **lineptr, *line, *ptr;
217
218        if( !sd || sd->fd == -1 )
219                return FALSE;
220        /* Read the whole data. */
221        st = read( sd->fd, buf, sizeof( buf ) );
222        if( st > 0 )
223        {
224                buf[st] = '\0';
225                /* Then split it up to lines. */
226                lines = g_strsplit(buf, "\n", 0);
227                lineptr = lines;
228                while((line = *lineptr))
229                {
230                        if(!strlen(line))
231                                break;
232                        if(!strncmp(line, "USERS ", 6))
233                        {
234                                char **i;
235                                char **nicks;
236
237                                nicks = g_strsplit(line + 6, ", ", 0);
238                                i = nicks;
239                                while(*i)
240                                {
241                                        g_snprintf(buf, 1024, "GET USER %s ONLINESTATUS\n", *i);
242                                        skype_write( ic, buf, strlen( buf ) );
243                                        i++;
244                                }
245                                g_strfreev(nicks);
246                        }
247                        else if(!strncmp(line, "USER ", 5))
248                        {
249                                int flags = 0;
250                                char *status = strrchr(line, ' ');
251                                char *user = strchr(line, ' ');
252                                status++;
253                                ptr = strchr(++user, ' ');
254                                *ptr = '\0';
255                                ptr++;
256                                if(!strncmp(ptr, "ONLINESTATUS ", 13) &&
257                                                strcmp(user, sd->username) != 0
258                                                && strcmp(user, "echo123") != 0)
259                                {
260                                        ptr = g_strdup_printf("%s@skype.com", user);
261                                        imcb_add_buddy(ic, ptr, NULL);
262                                        if(strcmp(status, "OFFLINE") != 0)
263                                                flags |= OPT_LOGGED_IN;
264                                        if(strcmp(status, "ONLINE") != 0 && strcmp(status, "SKYPEME") != 0)
265                                                flags |= OPT_AWAY;
266                                        imcb_buddy_status(ic, ptr, flags, NULL, NULL);
267                                        g_free(ptr);
268                                }
269                                else if(!strncmp(ptr, "RECEIVEDAUTHREQUEST ", 20))
270                                {
271                                        char *message = ptr + 20;
272                                        if(strlen(message))
273                                                skype_buddy_ask(ic, user, message);
274                                }
275                                else if(!strncmp(ptr, "BUDDYSTATUS ", 12))
276                                {
277                                        char *st = ptr + 12;
278                                        if(!strcmp(st, "3"))
279                                        {
280                                                char *buf = g_strdup_printf("%s@skype.com", user);
281                                                imcb_add_buddy(ic, buf, NULL);
282                                                g_free(buf);
283                                        }
284                                }
285                                else if(!strncmp(ptr, "FULLNAME ", 9))
286                                        sd->info_fullname = g_strdup_printf("%s", ptr + 9);
287                                else if(!strncmp(ptr, "ABOUT ", 6))
288                                {
289                                        sd->info_about = g_strdup_printf("%s", ptr + 6);
290
291                                        GString *st = g_string_new("User Info\n");
292                                        g_string_append_printf(st, "Skype Name: %s\n", user);
293                                        if(sd->info_fullname)
294                                        {
295                                                g_string_append_printf(st, "Full Name: %s\n", sd->info_fullname);
296                                                g_free(sd->info_fullname);
297                                        }
298                                        imcb_log(ic, "%s", st->str);
299                                        g_string_free(st, TRUE);
300                                }
301                        }
302                        else if(!strncmp(line, "CHATMESSAGE ", 12))
303                        {
304                                char *id = strchr(line, ' ');
305                                if(++id)
306                                {
307                                        char *info = strchr(id, ' ');
308                                        *info = '\0';
309                                        info++;
310                                        if(!strcmp(info, "STATUS RECEIVED"))
311                                        {
312                                                /* New message ID:
313                                                 * (1) Request its from field
314                                                 * (2) Request its body
315                                                 * (3) Request its type
316                                                 * (4) Query chatname
317                                                 */
318                                                g_snprintf(buf, 1024, "GET CHATMESSAGE %s FROM_HANDLE\n", id);
319                                                skype_write( ic, buf, strlen( buf ) );
320                                                g_snprintf(buf, 1024, "GET CHATMESSAGE %s BODY\n", id);
321                                                skype_write( ic, buf, strlen( buf ) );
322                                                g_snprintf(buf, 1024, "GET CHATMESSAGE %s TYPE\n", id);
323                                                skype_write( ic, buf, strlen( buf ) );
324                                                g_snprintf(buf, 1024, "GET CHATMESSAGE %s CHATNAME\n", id);
325                                                skype_write( ic, buf, strlen( buf ) );
326                                        }
327                                        else if(!strncmp(info, "FROM_HANDLE ", 12))
328                                        {
329                                                info += 12;
330                                                /* New from field value. Store
331                                                 * it, then we can later use it
332                                                 * when we got the message's
333                                                 * body. */
334                                                g_free(sd->handle);
335                                                sd->handle = g_strdup_printf("%s@skype.com", info);
336                                        }
337                                        else if(!strncmp(info, "EDITED_BY ", 10))
338                                        {
339                                                info += 10;
340                                                /* This is the same as
341                                                 * FROM_HANDLE, except that we
342                                                 * never request these lines
343                                                 * from Skype, we just get
344                                                 * them. */
345                                                g_free(sd->handle);
346                                                sd->handle = g_strdup_printf("%s@skype.com", info);
347                                        }
348                                        else if(!strncmp(info, "BODY ", 5))
349                                        {
350                                                info += 5;
351                                                sd->body = g_list_append(sd->body, g_strdup(info));
352                                        }
353                                        else if(!strncmp(info, "TYPE ", 5))
354                                        {
355                                                info += 5;
356                                                g_free(sd->type);
357                                                sd->type = g_strdup(info);
358                                        }
359                                        else if(!strncmp(info, "CHATNAME ", 9))
360                                        {
361                                                info += 9;
362                                                if(sd->handle && sd->body && sd->type)
363                                                {
364                                                        struct groupchat *gc = skype_chat_by_name(ic, info);
365                                                        int i;
366                                                        for(i=0;i<g_list_length(sd->body);i++)
367                                                        {
368                                                                char *body = g_list_nth_data(sd->body, i);
369                                                                if(!strcmp(sd->type, "SAID"))
370                                                                {
371                                                                        if(!gc)
372                                                                                /* Private message */
373                                                                                imcb_buddy_msg(ic, sd->handle, body, 0, 0);
374                                                                        else
375                                                                                /* Groupchat message */
376                                                                                imcb_chat_msg(gc, sd->handle, body, 0, 0);
377                                                                }
378                                                                else if(!strcmp(sd->type, "SETTOPIC"))
379                                                                {
380                                                                        if(gc)
381                                                                                imcb_chat_topic(gc, sd->handle, body, 0);
382                                                                }
383                                                                else if(!strcmp(sd->type, "LEFT"))
384                                                                {
385                                                                        if(gc)
386                                                                                imcb_chat_remove_buddy(gc, sd->handle, NULL);
387                                                                }
388                                                        }
389                                                        g_list_free(sd->body);
390                                                        sd->body = NULL;
391                                                }
392                                        }
393                                }
394                        }
395                        else if(!strncmp(line, "CALL ", 5))
396                        {
397                                char *id = strchr(line, ' ');
398                                if(++id)
399                                {
400                                        char *info = strchr(id, ' ');
401                                        *info = '\0';
402                                        info++;
403                                        if(!strcmp(info, "STATUS RINGING"))
404                                        {
405                                                g_snprintf(buf, 1024, "GET CALL %s PARTNER_HANDLE\n", id);
406                                                skype_write( ic, buf, strlen( buf ) );
407                                                sd->call_status = SKYPE_CALL_RINGING;
408                                        }
409                                        else if(!strcmp(info, "STATUS MISSED"))
410                                        {
411                                                g_snprintf(buf, 1024, "GET CALL %s PARTNER_HANDLE\n", id);
412                                                skype_write( ic, buf, strlen( buf ) );
413                                                sd->call_status = SKYPE_CALL_MISSED;
414                                        }
415                                        else if(!strncmp(info, "PARTNER_HANDLE ", 15))
416                                        {
417                                                info += 15;
418                                                if(sd->call_status) {
419                                                        switch(sd->call_status)
420                                                        {
421                                                                case SKYPE_CALL_RINGING:
422                                                                        imcb_log(ic, "The user %s is currently ringing you.", info);
423                                                                        break;
424                                                                case SKYPE_CALL_MISSED:
425                                                                        imcb_log(ic, "You have missed a call from user %s.", info);
426                                                                        break;
427                                                        }
428                                                        sd->call_status = 0;
429                                                }
430                                        }
431                                }
432                        }
433                        else if(!strncmp(line, "FILETRANSFER ", 13))
434                        {
435                                char *id = strchr(line, ' ');
436                                if(++id)
437                                {
438                                        char *info = strchr(id, ' ');
439                                        *info = '\0';
440                                        info++;
441                                        if(!strcmp(info, "STATUS NEW"))
442                                        {
443                                                g_snprintf(buf, 1024, "GET FILETRANSFER %s PARTNER_HANDLE\n", id);
444                                                skype_write( ic, buf, strlen( buf ) );
445                                                sd->filetransfer_status = SKYPE_FILETRANSFER_NEW;
446                                        }
447                                        else if(!strcmp(info, "STATUS FAILED"))
448                                        {
449                                                g_snprintf(buf, 1024, "GET FILETRANSFER %s PARTNER_HANDLE\n", id);
450                                                skype_write( ic, buf, strlen( buf ) );
451                                                sd->filetransfer_status = SKYPE_FILETRANSFER_FAILED;
452                                        }
453                                        else if(!strncmp(info, "PARTNER_HANDLE ", 15))
454                                        {
455                                                info += 15;
456                                                if(sd->filetransfer_status) {
457                                                        switch(sd->filetransfer_status)
458                                                        {
459                                                                case SKYPE_FILETRANSFER_NEW:
460                                                                        imcb_log(ic, "The user %s offered a new file for you.", info);
461                                                                        break;
462                                                                case SKYPE_FILETRANSFER_FAILED:
463                                                                        imcb_log(ic, "Failed to transfer file from user %s.", info);
464                                                                        break;
465                                                        }
466                                                        sd->filetransfer_status = 0;
467                                                }
468                                        }
469                                }
470                        }
471                        else if(!strncmp(line, "CHAT ", 5))
472                        {
473                                char *id = strchr(line, ' ');
474                                if(++id)
475                                {
476                                        char *info = strchr(id, ' ');
477                                        if(info)
478                                                *info = '\0';
479                                        info++;
480                                        /* Remove fake chat if we created one in skype_chat_with() */
481                                        struct groupchat *gc = skype_chat_by_name(ic, "");
482                                        if(gc)
483                                                imcb_chat_free(gc);
484                                        if(!strcmp(info, "STATUS MULTI_SUBSCRIBED"))
485                                        {
486                                                imcb_chat_new( ic, id );
487                                                g_snprintf(buf, 1024, "GET CHAT %s ADDER\n", id);
488                                                skype_write(ic, buf, strlen(buf));
489                                                g_snprintf(buf, 1024, "GET CHAT %s TOPIC\n", id);
490                                                skype_write(ic, buf, strlen(buf));
491                                        }
492                                        else if(!strcmp(info, "STATUS DIALOG") && sd->groupchat_with)
493                                        {
494                                                gc = imcb_chat_new( ic, id );
495                                                /* According to the docs this
496                                                 * is necessary. However it
497                                                 * does not seem the situation
498                                                 * and it would open an extra
499                                                 * window on our client, so
500                                                 * just leave it out. */
501                                                /*g_snprintf(buf, 1024, "OPEN CHAT %s\n", id);
502                                                skype_write(ic, buf, strlen(buf));*/
503                                                g_snprintf(buf, 1024, "%s@skype.com", sd->groupchat_with);
504                                                imcb_chat_add_buddy(gc, buf);
505                                                imcb_chat_add_buddy(gc, sd->username);
506                                                g_free(sd->groupchat_with);
507                                                sd->groupchat_with = NULL;
508                                                g_snprintf(buf, 1024, "GET CHAT %s ADDER\n", id);
509                                                skype_write(ic, buf, strlen(buf));
510                                                g_snprintf(buf, 1024, "GET CHAT %s TOPIC\n", id);
511                                                skype_write(ic, buf, strlen(buf));
512                                        }
513                                        else if(!strcmp(info, "STATUS UNSUBSCRIBED"))
514                                        {
515                                                gc = skype_chat_by_name(ic, id);
516                                                if(gc)
517                                                        gc->data = (void*)FALSE;
518                                        }
519                                        else if(!strncmp(info, "ADDER ", 6))
520                                        {
521                                                info += 6;
522                                                g_free(sd->adder);
523                                                sd->adder = g_strdup_printf("%s@skype.com", info);
524                                        }
525                                        else if(!strncmp(info, "TOPIC ", 6))
526                                        {
527                                                info += 6;
528                                                gc = skype_chat_by_name(ic, id);
529                                                if(gc && (sd->adder || sd->topic_wait))
530                                                {
531                                                        if(sd->topic_wait)
532                                                        {
533                                                                sd->adder = g_strdup(sd->username);
534                                                                sd->topic_wait = 0;
535                                                        }
536                                                        imcb_chat_topic(gc, sd->adder, info, 0);
537                                                        g_free(sd->adder);
538                                                        sd->adder = NULL;
539                                                }
540                                        }
541                                        else if(!strncmp(info, "ACTIVEMEMBERS ", 14))
542                                        {
543                                                info += 14;
544                                                gc = skype_chat_by_name(ic, id);
545                                                /* Hack! We set ->data to TRUE
546                                                 * while we're on the channel
547                                                 * so that we won't rejoin
548                                                 * after a /part. */
549                                                if(gc && !gc->data)
550                                                {
551                                                        char **members = g_strsplit(info, " ", 0);
552                                                        int i;
553                                                        for(i=0;members[i];i++)
554                                                        {
555                                                                if(!strcmp(members[i], sd->username))
556                                                                        continue;
557                                                                g_snprintf(buf, 1024, "%s@skype.com", members[i]);
558                                                                if(!g_list_find_custom(gc->in_room, buf, (GCompareFunc)strcmp))
559                                                                        imcb_chat_add_buddy(gc, buf);
560                                                        }
561                                                        imcb_chat_add_buddy(gc, sd->username);
562                                                        g_strfreev(members);
563                                                }
564                                        }
565                                }
566                        }
567                        lineptr++;
568                }
569                g_strfreev(lines);
570        }
571        else if( st == 0 || ( st < 0 && !sockerr_again() ) )
572        {
573                closesocket( sd->fd );
574                sd->fd = -1;
575
576                imcb_error( ic, "Error while reading from server" );
577                imc_logout( ic, TRUE );
578                return FALSE;
579        }
580        return TRUE;
581}
582
583gboolean skype_start_stream( struct im_connection *ic )
584{
585        struct skype_data *sd = ic->proto_data;
586        char *buf;
587        int st;
588
589        if(!sd)
590                return FALSE;
591
592        if( sd->bfd <= 0 )
593                sd->bfd = b_input_add( sd->fd, GAIM_INPUT_READ, skype_read_callback, ic );
594
595        /* This will download all buddies. */
596        buf = g_strdup_printf("SEARCH FRIENDS\n");
597        st = skype_write( ic, buf, strlen( buf ) );
598        g_free(buf);
599        buf = g_strdup_printf("SET USERSTATUS ONLINE\n");
600        skype_write( ic, buf, strlen( buf ) );
601        g_free(buf);
602        return st;
603}
604
605gboolean skype_connected( gpointer data, gint source, b_input_condition cond )
606{
607        struct im_connection *ic = data;
608        imcb_connected(ic);
609        return skype_start_stream(ic);
610}
611
612static void skype_login( account_t *acc )
613{
614        struct im_connection *ic = imcb_new( acc );
615        struct skype_data *sd = g_new0( struct skype_data, 1 );
616
617        ic->proto_data = sd;
618
619        imcb_log( ic, "Connecting" );
620        sd->fd = proxy_connect(acc->server, set_getint( &acc->set, "port" ), skype_connected, ic );
621        sd->username = g_strdup( acc->user );
622
623        sd->ic = ic;
624}
625
626static void skype_logout( struct im_connection *ic )
627{
628        struct skype_data *sd = ic->proto_data;
629        char *buf;
630
631        buf = g_strdup_printf("SET USERSTATUS OFFLINE\n");
632        skype_write( ic, buf, strlen( buf ) );
633        g_free(buf);
634
635        g_free(sd->username);
636        g_free(sd->handle);
637        g_free(sd);
638        ic->proto_data = NULL;
639}
640
641static int skype_buddy_msg( struct im_connection *ic, char *who, char *message, int flags )
642{
643        char *buf, *ptr, *nick;
644        int st;
645
646        nick = g_strdup(who);
647        ptr = strchr(nick, '@');
648        if(ptr)
649                *ptr = '\0';
650
651        buf = g_strdup_printf("MESSAGE %s %s\n", nick, message);
652        g_free(nick);
653        st = skype_write( ic, buf, strlen( buf ) );
654        g_free(buf);
655
656        return st;
657}
658
659const struct skype_away_state *skype_away_state_by_name( char *name )
660{
661        int i;
662
663        for( i = 0; skype_away_state_list[i].full_name; i ++ )
664                if( g_strcasecmp( skype_away_state_list[i].full_name, name ) == 0 )
665                        return( skype_away_state_list + i );
666
667        return NULL;
668}
669
670static void skype_set_away( struct im_connection *ic, char *state_txt, char *message )
671{
672        const struct skype_away_state *state;
673        char *buf;
674
675        if( strcmp( state_txt, GAIM_AWAY_CUSTOM ) == 0 )
676                state = skype_away_state_by_name( "Away" );
677        else
678                state = skype_away_state_by_name( state_txt );
679        buf = g_strdup_printf("SET USERSTATUS %s\n", state->code);
680        skype_write( ic, buf, strlen( buf ) );
681        g_free(buf);
682}
683
684static GList *skype_away_states( struct im_connection *ic )
685{
686        static GList *l = NULL;
687        int i;
688       
689        if( l == NULL )
690                for( i = 0; skype_away_state_list[i].full_name; i ++ )
691                        l = g_list_append( l, (void*) skype_away_state_list[i].full_name );
692       
693        return l;
694}
695
696static void skype_add_buddy( struct im_connection *ic, char *who, char *group )
697{
698        char *buf, *nick, *ptr;
699
700        nick = g_strdup(who);
701        ptr = strchr(nick, '@');
702        if(ptr)
703                *ptr = '\0';
704        buf = g_strdup_printf("SET USER %s BUDDYSTATUS 2 Please authorize me\n", nick);
705        skype_write( ic, buf, strlen( buf ) );
706        g_free(nick);
707}
708
709static void skype_remove_buddy( struct im_connection *ic, char *who, char *group )
710{
711        char *buf, *nick, *ptr;
712
713        nick = g_strdup(who);
714        ptr = strchr(nick, '@');
715        if(ptr)
716                *ptr = '\0';
717        buf = g_strdup_printf("SET USER %s BUDDYSTATUS 1\n", nick);
718        skype_write( ic, buf, strlen( buf ) );
719        g_free(nick);
720}
721
722void skype_chat_msg( struct groupchat *gc, char *message, int flags )
723{
724        struct im_connection *ic = gc->ic;
725        char *buf;
726        buf = g_strdup_printf("CHATMESSAGE %s %s\n", gc->title, message);
727        skype_write( ic, buf, strlen( buf ) );
728        g_free(buf);
729}
730
731void skype_chat_leave( struct groupchat *gc )
732{
733        struct im_connection *ic = gc->ic;
734        char *buf;
735        buf = g_strdup_printf("ALTER CHAT %s LEAVE\n", gc->title);
736        skype_write( ic, buf, strlen( buf ) );
737        g_free(buf);
738        gc->data = (void*)TRUE;
739}
740
741void skype_chat_invite(struct groupchat *gc, char *who, char *message)
742{
743        struct im_connection *ic = gc->ic;
744        char *buf, *ptr, *nick;
745        nick = g_strdup(message);
746        ptr = strchr(nick, '@');
747        if(ptr)
748                *ptr = '\0';
749        buf = g_strdup_printf("ALTER CHAT %s ADDMEMBERS %s\n", gc->title, nick);
750        skype_write( ic, buf, strlen( buf ) );
751        g_free(buf);
752        g_free(nick);
753}
754
755void skype_chat_topic(struct groupchat *gc, char *message)
756{
757        struct im_connection *ic = gc->ic;
758        struct skype_data *sd = ic->proto_data;
759        char *buf;
760        buf = g_strdup_printf("ALTER CHAT %s SETTOPIC %s\n", gc->title, message);
761        skype_write( ic, buf, strlen( buf ) );
762        g_free(buf);
763        sd->topic_wait = 1;
764}
765
766struct groupchat *skype_chat_with(struct im_connection *ic, char *who)
767{
768        struct skype_data *sd = ic->proto_data;
769        char *ptr, *nick, *buf;
770        nick = g_strdup(who);
771        ptr = strchr(nick, '@');
772        if(ptr)
773                *ptr = '\0';
774        buf = g_strdup_printf("CHAT CREATE %s\n", nick);
775        skype_write(ic, buf, strlen(buf));
776        g_free(buf);
777        sd->groupchat_with = g_strdup(nick);
778        g_free(nick);
779        /* We create a fake chat for now. We will replace it with a real one in
780         * the real callback. */
781        return(imcb_chat_new( ic, "" ));
782}
783
784static void skype_get_info(struct im_connection *ic, char *who)
785{
786        char *ptr, *nick, *buf;
787        nick = g_strdup(who);
788        ptr = strchr(nick, '@');
789        if(ptr)
790                *ptr = '\0';
791        buf = g_strdup_printf("GET USER %s FULLNAME\n", nick);
792        skype_write(ic, buf, strlen(buf));
793        g_free(buf);
794        buf = g_strdup_printf("GET USER %s PHONE_HOME\n", nick);
795        skype_write(ic, buf, strlen(buf));
796        g_free(buf);
797        buf = g_strdup_printf("GET USER %s PHONE_OFFICE\n", nick);
798        skype_write(ic, buf, strlen(buf));
799        g_free(buf);
800        buf = g_strdup_printf("GET USER %s PHONE_MOBILE\n", nick);
801        skype_write(ic, buf, strlen(buf));
802        g_free(buf);
803        buf = g_strdup_printf("GET USER %s NROF_AUTHED_BUDDIES\n", nick);
804        skype_write(ic, buf, strlen(buf));
805        g_free(buf);
806        buf = g_strdup_printf("GET USER %s TIMEZONE\n", nick);
807        skype_write(ic, buf, strlen(buf));
808        g_free(buf);
809        buf = g_strdup_printf("GET USER %s LASTONLINETIMESTAMP\n", nick);
810        skype_write(ic, buf, strlen(buf));
811        g_free(buf);
812        buf = g_strdup_printf("GET USER %s BIRTHDAY\n", nick);
813        skype_write(ic, buf, strlen(buf));
814        g_free(buf);
815        buf = g_strdup_printf("GET USER %s SEX\n", nick);
816        skype_write(ic, buf, strlen(buf));
817        g_free(buf);
818        buf = g_strdup_printf("GET USER %s LANGUAGE\n", nick);
819        skype_write(ic, buf, strlen(buf));
820        g_free(buf);
821        buf = g_strdup_printf("GET USER %s COUNTRY\n", nick);
822        skype_write(ic, buf, strlen(buf));
823        g_free(buf);
824        buf = g_strdup_printf("GET USER %s PROVINCE\n", nick);
825        skype_write(ic, buf, strlen(buf));
826        g_free(buf);
827        buf = g_strdup_printf("GET USER %s CITY\n", nick);
828        skype_write(ic, buf, strlen(buf));
829        g_free(buf);
830        buf = g_strdup_printf("GET USER %s HOMEPAGE\n", nick);
831        skype_write(ic, buf, strlen(buf));
832        g_free(buf);
833        buf = g_strdup_printf("GET USER %s ABOUT\n", nick);
834        skype_write(ic, buf, strlen(buf));
835        g_free(buf);
836}
837
838void init_plugin(void)
839{
840        struct prpl *ret = g_new0( struct prpl, 1 );
841
842        ret->name = "skype";
843        ret->login = skype_login;
844        ret->init = skype_init;
845        ret->logout = skype_logout;
846        ret->buddy_msg = skype_buddy_msg;
847        ret->get_info = skype_get_info;
848        ret->away_states = skype_away_states;
849        ret->set_away = skype_set_away;
850        ret->add_buddy = skype_add_buddy;
851        ret->remove_buddy = skype_remove_buddy;
852        ret->chat_msg = skype_chat_msg;
853        ret->chat_leave = skype_chat_leave;
854        ret->chat_invite = skype_chat_invite;
855        ret->chat_with = skype_chat_with;
856        ret->handle_cmp = g_strcasecmp;
857        ret->chat_topic = skype_chat_topic;
858        register_protocol( ret );
859}
Note: See TracBrowser for help on using the repository browser.