source: skype/skype.c @ f06e3ac

Last change on this file since f06e3ac was f06e3ac, checked in by VMiklos <vmiklos@…>, at 2007-08-19T13:37:45Z

initial commit

  • Property mode set to 100644
File size: 4.3 KB
RevLine 
[f06e3ac]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
22static gboolean skype_write_callback( gpointer data, gint fd, b_input_condition cond );
23static gboolean skype_write_queue( struct im_connection *ic );
24
25static void skype_init( account_t *acc )
26{
27        set_t *s;
28
29        s = set_add( &acc->set, "port", SKYPE_PORT_DEFAULT, set_eval_int, acc );
30        s->flags |= ACC_SET_OFFLINE_ONLY;
31
32        s = set_add( &acc->set, "server", NULL, set_eval_account, acc );
33        s->flags |= ACC_SET_NOSAVE | ACC_SET_OFFLINE_ONLY;
34}
35
36int skype_write( struct im_connection *ic, char *buf, int len )
37{
38        struct skype_data *sd = ic->proto_data;
39        gboolean ret;
40
41        if( sd->tx_len == 0 )
42        {
43                sd->tx_len = len;
44                sd->txq = g_memdup( buf, len );
45                if( ( ret = skype_write_queue( ic ) ) && sd->tx_len > 0 )
46                        sd->w_inpa = b_input_add( sd->fd, GAIM_INPUT_WRITE, skype_write_callback, ic );
47        }
48        else
49        {
50                sd->txq = g_renew( char, sd->txq, sd->tx_len + len );
51                memcpy( sd->txq + sd->tx_len, buf, len );
52                sd->tx_len += len;
53                ret = TRUE;
54        }
55        return ret;
56}
57
58static gboolean skype_write_callback( gpointer data, gint fd, b_input_condition cond )
59{
60        struct skype_data *sd = ((struct im_connection *)data)->proto_data;
61
62        return sd->fd != -1 &&
63                skype_write_queue( data ) &&
64                sd->tx_len > 0;
65}
66
67static gboolean skype_write_queue( struct im_connection *ic )
68{
69        struct skype_data *sd = ic->proto_data;
70        int st;
71
72        st = write( sd->fd, sd->txq, sd->tx_len );
73
74        if( st == sd->tx_len )
75        {
76                /* We wrote everything, clear the buffer. */
77                g_free( sd->txq );
78                sd->txq = NULL;
79                sd->tx_len = 0;
80
81                return TRUE;
82        }
83        else if( st == 0 || ( st < 0 && !sockerr_again() ) )
84        {
85                /* Set fd to -1 to make sure we won't write to it anymore. */
86                closesocket( sd->fd );  /* Shouldn't be necessary after errors? */
87                sd->fd = -1;
88
89                imcb_error( ic, "Short write() to server" );
90                imc_logout( ic, TRUE );
91                return FALSE;
92        }
93        else if( st > 0 )
94        {
95                char *s;
96
97                s = g_memdup( sd->txq + st, sd->tx_len - st );
98                sd->tx_len -= st;
99                g_free( sd->txq );
100                sd->txq = s;
101
102                return TRUE;
103        }
104        else
105        {
106                return TRUE;
107        }
108}
109
110gboolean skype_start_stream( struct im_connection *ic )
111{
112        char *buf;
113        int st;
114
115        buf = g_strdup_printf("SEARCH FRIENDS");
116        st = skype_write( ic, buf, strlen( buf ) );
117        g_free(buf);
118        return st;
119}
120
121gboolean skype_connected( gpointer data, gint source, b_input_condition cond )
122{
123        struct im_connection *ic = data;
124
125        imcb_connected(ic);
126        //imcb_add_buddy(ic, "vmiklos_dsd@skype.com", NULL);
127        //imcb_buddy_status(ic, "vmiklos_dsd@skype.com", OPT_LOGGED_IN, NULL, NULL);
128        return skype_start_stream(ic);
129}
130
131static void skype_login( account_t *acc )
132{
133        struct im_connection *ic = imcb_new( acc );
134        struct skype_data *sd = g_new0( struct skype_data, 1 );
135
136        ic->proto_data = sd;
137
138        imcb_log( ic, "Connecting" );
139        printf("%s:%d\n", acc->server, set_getint( &acc->set, "port"));
140        sd->fd = proxy_connect(acc->server, set_getint( &acc->set, "port" ), skype_connected, ic );
141        printf("sd->fd: %d\n", sd->fd);
142        if( sd->fd < 0 )
143        {
144                imcb_error( ic, "Could not connect to server" );
145                imc_logout( ic, TRUE );
146                return;
147        }
148
149        sd->ic = ic;
150}
151
152static void skype_logout( struct im_connection *ic )
153{
154        struct skype_data *sd = ic->proto_data;
155        g_free(sd);
156}
157
158static void skype_set_away( struct im_connection *ic, char *state_txt, char *message )
159{
160}
161
162static GList *skype_away_states( struct im_connection *ic )
163{
164        static GList *l = NULL;
165        int i;
166
167        l = g_list_append( l, (void*)"Online" );
168        return l;
169}
170
171static void skype_add_buddy( struct im_connection *ic, char *who, char *group )
172{
173}
174
175static void skype_remove_buddy( struct im_connection *ic, char *who, char *group )
176{
177}
178
179void init_plugin(void)
180{
181        struct prpl *ret = g_new0( struct prpl, 1 );
182
183        ret->name = "skype";
184        ret->login = skype_login;
185        ret->init = skype_init;
186        ret->logout = skype_logout;
187        ret->away_states = skype_away_states;
188        ret->add_buddy = skype_add_buddy;
189        ret->remove_buddy = skype_remove_buddy;
190        ret->away_states = skype_away_states;
191        ret->set_away = skype_set_away;
192        ret->handle_cmp = g_strcasecmp;
193        register_protocol( ret );
194}
Note: See TracBrowser for help on using the repository browser.