source: skype/skype.c @ adce2de

Last change on this file since adce2de was adce2de, checked in by VMiklos <vmiklos@…>, at 2007-08-19T17:35:34Z

download away statuses

  • Property mode set to 100644
File size: 5.0 KB
Line 
1/*
2 * This is the most simple possible BitlBee plugin. To use, compile it as
3 * a shared library and place it in the plugin directory:
4 *
5 * gcc -o example.so -shared example.c `pkg-config --cflags bitlbee`
6 * cp example.so /usr/local/lib/bitlbee
7 */
8#include <stdio.h>
9#include <bitlbee.h>
10
11#define SKYPE_PORT_DEFAULT "2727"
12
13struct skype_data
14{
15        struct im_connection *ic;
16        int fd;
17        char *txq;
18        int tx_len;
19        int r_inpa, w_inpa;
20};
21
22struct skype_away_state
23{
24        char *code;
25        char *full_name;
26};
27
28const struct skype_away_state skype_away_state_list[] =
29{
30        { "ONLINE",  "Online" },
31        { "SKYPEME",  "Skype Me" },
32        { "AWAY",   "Away" },
33        { "NA",    "Not available" },
34        { "DND",      "Do Not Disturb" },
35        { "INVISIBLE",      "Invisible" },
36        { "OFFLINE",      "Offline" }
37};
38
39static void skype_init( account_t *acc )
40{
41        set_t *s;
42
43        s = set_add( &acc->set, "port", SKYPE_PORT_DEFAULT, set_eval_int, acc );
44        s->flags |= ACC_SET_OFFLINE_ONLY;
45
46        s = set_add( &acc->set, "server", NULL, set_eval_account, acc );
47        s->flags |= ACC_SET_NOSAVE | ACC_SET_OFFLINE_ONLY;
48}
49
50int skype_write( struct im_connection *ic, char *buf, int len )
51{
52        struct skype_data *sd = ic->proto_data;
53
54        printf("write(): %s", buf);
55        write( sd->fd, buf, len );
56
57        // TODO: error handling
58
59        return TRUE;
60}
61
62static gboolean skype_read_callback( gpointer data, gint fd, b_input_condition cond )
63{
64        struct im_connection *ic = data;
65        struct skype_data *sd = ic->proto_data;
66        char buf[1024];
67        int st;
68        char **lines, **lineptr, *line, *ptr;
69
70        if( sd->fd == -1 )
71                return FALSE;
72        st = read( sd->fd, buf, sizeof( buf ) );
73        if( st > 0 )
74        {
75                buf[st] = '\0';
76                printf("read(): '%s'\n", buf);
77                lines = g_strsplit(buf, "\n", 0);
78                lineptr = lines;
79                while((line = *lineptr))
80                {
81                        if(!strlen(line))
82                                break;
83                        printf("skype_read_callback() new line: '%s'\n", line);
84                        if(!strncmp(line, "USERS ", 6))
85                        {
86                                char **i;
87                                char **nicks;
88
89                                nicks = g_strsplit(line + 6, ", ", 0);
90                                i = nicks;
91                                while(*i)
92                                {
93                                        g_snprintf(buf, 1024, "GET USER %s ONLINESTATUS\n", *i);
94                                        skype_write( ic, buf, strlen( buf ) );
95                                        i++;
96                                }
97                                g_strfreev(nicks);
98                        }
99                        else if(!strncmp(line, "USER ", 5))
100                        {
101                                int flags = 0;
102                                char *status = strrchr(line, ' ');
103                                char *user = strchr(line, ' ');
104                                status++;
105                                ptr = strchr(++user, ' ');
106                                *ptr = '\0';
107                                ptr = g_strdup_printf("%s@skype.com", user);
108                                imcb_add_buddy(ic, ptr, NULL);
109                                // TODO online can be away
110                                if(strcmp(status, "OFFLINE") != 0)
111                                        flags |= OPT_LOGGED_IN;
112                                if(strcmp(status, "ONLINE") != 0 && strcmp(status, "SKYPEME") != 0)
113                                        flags |= OPT_AWAY;
114                                imcb_buddy_status(ic, ptr, flags, NULL, NULL);
115                                g_free(ptr);
116                        }
117                        lineptr++;
118                }
119                g_strfreev(lines);
120        }
121        else if( st == 0 || ( st < 0 && !sockerr_again() ) )
122        {
123                closesocket( sd->fd );
124                sd->fd = -1;
125
126                imcb_error( ic, "Error while reading from server" );
127                imc_logout( ic, TRUE );
128                return FALSE;
129        }
130
131        /* EAGAIN/etc or a successful read. */
132        return TRUE;
133}
134
135gboolean skype_start_stream( struct im_connection *ic )
136{
137        struct skype_data *sd = ic->proto_data;
138        char *buf;
139        int st;
140
141        if( sd->r_inpa <= 0 )
142                sd->r_inpa = b_input_add( sd->fd, GAIM_INPUT_READ, skype_read_callback, ic );
143
144        // download buddies
145        buf = g_strdup_printf("SEARCH FRIENDS\n");
146        st = skype_write( ic, buf, strlen( buf ) );
147        g_free(buf);
148        return st;
149}
150
151gboolean skype_connected( gpointer data, gint source, b_input_condition cond )
152{
153        struct im_connection *ic = data;
154        struct skype_data *sd = ic->proto_data;
155
156        imcb_connected(ic);
157        if( sd->fd < 0 )
158        {
159                imcb_error( ic, "Could not connect to server" );
160                imc_logout( ic, TRUE );
161                return FALSE;
162        }
163        return skype_start_stream(ic);
164}
165
166static void skype_login( account_t *acc )
167{
168        struct im_connection *ic = imcb_new( acc );
169        struct skype_data *sd = g_new0( struct skype_data, 1 );
170
171        ic->proto_data = sd;
172
173        imcb_log( ic, "Connecting" );
174        printf("%s:%d\n", acc->server, set_getint( &acc->set, "port"));
175        sd->fd = proxy_connect(acc->server, set_getint( &acc->set, "port" ), skype_connected, ic );
176        printf("sd->fd: %d\n", sd->fd);
177
178        sd->ic = ic;
179}
180
181static void skype_logout( struct im_connection *ic )
182{
183        struct skype_data *sd = ic->proto_data;
184        g_free(sd);
185}
186
187static void skype_set_away( struct im_connection *ic, char *state_txt, char *message )
188{
189}
190
191static GList *skype_away_states( struct im_connection *ic )
192{
193        static GList *l = NULL;
194        int i;
195       
196        if( l == NULL )
197                for( i = 0; skype_away_state_list[i].full_name; i ++ )
198                        l = g_list_append( l, (void*) skype_away_state_list[i].full_name );
199       
200        return l;
201}
202
203static void skype_add_buddy( struct im_connection *ic, char *who, char *group )
204{
205}
206
207static void skype_remove_buddy( struct im_connection *ic, char *who, char *group )
208{
209}
210
211void init_plugin(void)
212{
213        struct prpl *ret = g_new0( struct prpl, 1 );
214
215        ret->name = "skype";
216        ret->login = skype_login;
217        ret->init = skype_init;
218        ret->logout = skype_logout;
219        ret->away_states = skype_away_states;
220        ret->add_buddy = skype_add_buddy;
221        ret->remove_buddy = skype_remove_buddy;
222        ret->away_states = skype_away_states;
223        ret->set_away = skype_set_away;
224        ret->handle_cmp = g_strcasecmp;
225        register_protocol( ret );
226}
Note: See TracBrowser for help on using the repository browser.