source: skype/skype.c @ 1323e36

Last change on this file since 1323e36 was 1323e36, checked in by VMiklos <vmiklos@…>, at 2007-08-19T13:57:32Z

basic read functions

  • Property mode set to 100644
File size: 5.1 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
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_read_callback( gpointer data, gint fd, b_input_condition cond )
68{
69        struct im_connection *ic = data;
70        struct skype_data *sd = ic->proto_data;
71        char buf[1024];
72        int st;
73
74        if( sd->fd == -1 )
75                return FALSE;
76        st = read( sd->fd, buf, sizeof( buf ) );
77        if( st > 0 )
78        {
79                buf[st] = '\0';
80                printf("read(): '%s'\n", buf);
81        }
82        else if( st == 0 || ( st < 0 && !sockerr_again() ) )
83        {
84                closesocket( sd->fd );
85                sd->fd = -1;
86
87                imcb_error( ic, "Error while reading from server" );
88                imc_logout( ic, TRUE );
89                return FALSE;
90        }
91
92        /* EAGAIN/etc or a successful read. */
93        return TRUE;
94}
95
96static gboolean skype_write_queue( struct im_connection *ic )
97{
98        struct skype_data *sd = ic->proto_data;
99        int st;
100
101        printf("sd->fd: %d\n", sd->fd);
102        st = write( sd->fd, sd->txq, sd->tx_len );
103
104        if( st == sd->tx_len )
105        {
106                /* We wrote everything, clear the buffer. */
107                g_free( sd->txq );
108                sd->txq = NULL;
109                sd->tx_len = 0;
110
111                return TRUE;
112        }
113        else if( st == 0 || ( st < 0 && !sockerr_again() ) )
114        {
115                /* Set fd to -1 to make sure we won't write to it anymore. */
116                closesocket( sd->fd );  /* Shouldn't be necessary after errors? */
117                sd->fd = -1;
118
119                imcb_error( ic, "Short write() to server" );
120                imc_logout( ic, TRUE );
121                return FALSE;
122        }
123        else if( st > 0 )
124        {
125                char *s;
126
127                s = g_memdup( sd->txq + st, sd->tx_len - st );
128                sd->tx_len -= st;
129                g_free( sd->txq );
130                sd->txq = s;
131
132                return TRUE;
133        }
134        else
135        {
136                return TRUE;
137        }
138}
139
140gboolean skype_start_stream( struct im_connection *ic )
141{
142        struct skype_data *sd = ic->proto_data;
143        char *buf;
144        int st;
145
146        if( sd->r_inpa <= 0 )
147                sd->r_inpa = b_input_add( sd->fd, GAIM_INPUT_READ, skype_read_callback, ic );
148
149        buf = g_strdup_printf("SEARCH FRIENDS");
150        st = skype_write( ic, buf, strlen( buf ) );
151        g_free(buf);
152        return st;
153}
154
155gboolean skype_connected( gpointer data, gint source, b_input_condition cond )
156{
157        struct im_connection *ic = data;
158        struct skype_data *sd = ic->proto_data;
159
160        imcb_connected(ic);
161        if( sd->fd < 0 )
162        {
163                imcb_error( ic, "Could not connect to server" );
164                imc_logout( ic, TRUE );
165                return;
166        }
167        //imcb_add_buddy(ic, "vmiklos_dsd@skype.com", NULL);
168        //imcb_buddy_status(ic, "vmiklos_dsd@skype.com", OPT_LOGGED_IN, NULL, NULL);
169        return skype_start_stream(ic);
170}
171
172static void skype_login( account_t *acc )
173{
174        struct im_connection *ic = imcb_new( acc );
175        struct skype_data *sd = g_new0( struct skype_data, 1 );
176
177        ic->proto_data = sd;
178
179        imcb_log( ic, "Connecting" );
180        printf("%s:%d\n", acc->server, set_getint( &acc->set, "port"));
181        sd->fd = proxy_connect(acc->server, set_getint( &acc->set, "port" ), skype_connected, ic );
182        printf("sd->fd: %d\n", sd->fd);
183
184        sd->ic = ic;
185}
186
187static void skype_logout( struct im_connection *ic )
188{
189        struct skype_data *sd = ic->proto_data;
190        g_free(sd);
191}
192
193static void skype_set_away( struct im_connection *ic, char *state_txt, char *message )
194{
195}
196
197static GList *skype_away_states( struct im_connection *ic )
198{
199        static GList *l = NULL;
200        int i;
201
202        l = g_list_append( l, (void*)"Online" );
203        return l;
204}
205
206static void skype_add_buddy( struct im_connection *ic, char *who, char *group )
207{
208}
209
210static void skype_remove_buddy( struct im_connection *ic, char *who, char *group )
211{
212}
213
214void init_plugin(void)
215{
216        struct prpl *ret = g_new0( struct prpl, 1 );
217
218        ret->name = "skype";
219        ret->login = skype_login;
220        ret->init = skype_init;
221        ret->logout = skype_logout;
222        ret->away_states = skype_away_states;
223        ret->add_buddy = skype_add_buddy;
224        ret->remove_buddy = skype_remove_buddy;
225        ret->away_states = skype_away_states;
226        ret->set_away = skype_set_away;
227        ret->handle_cmp = g_strcasecmp;
228        register_protocol( ret );
229}
Note: See TracBrowser for help on using the repository browser.