diff options
| author | VMiklos <vmiklos@frugalware.org> | 2007-08-19 15:37:45 +0200 | 
|---|---|---|
| committer | VMiklos <vmiklos@frugalware.org> | 2007-08-19 15:37:45 +0200 | 
| commit | f06e3ac0ed0aa7a1b616993512fbd0ed12d01e51 (patch) | |
| tree | bb794c359bf36195cf4f4c667ff93e5d38537a97 /skype/skype.c | |
initial commit
Diffstat (limited to 'skype/skype.c')
| -rw-r--r-- | skype/skype.c | 194 | 
1 files changed, 194 insertions, 0 deletions
| diff --git a/skype/skype.c b/skype/skype.c new file mode 100644 index 00000000..ff923806 --- /dev/null +++ b/skype/skype.c @@ -0,0 +1,194 @@ +/*  + * This is the most simple possible BitlBee plugin. To use, compile it as  + * a shared library and place it in the plugin directory:  + * + * gcc -o example.so -shared example.c `pkg-config --cflags bitlbee` + * cp example.so /usr/local/lib/bitlbee + */ +#include <stdio.h> +#include <bitlbee.h> + +#define SKYPE_PORT_DEFAULT "2727" + +struct skype_data +{ +	struct im_connection *ic; +	int fd; +	char *txq; +	int tx_len; +	int r_inpa, w_inpa; +}; + +static gboolean skype_write_callback( gpointer data, gint fd, b_input_condition cond ); +static gboolean skype_write_queue( struct im_connection *ic ); + +static void skype_init( account_t *acc ) +{ +	set_t *s; + +	s = set_add( &acc->set, "port", SKYPE_PORT_DEFAULT, set_eval_int, acc ); +	s->flags |= ACC_SET_OFFLINE_ONLY; + +	s = set_add( &acc->set, "server", NULL, set_eval_account, acc ); +	s->flags |= ACC_SET_NOSAVE | ACC_SET_OFFLINE_ONLY; +} + +int skype_write( struct im_connection *ic, char *buf, int len ) +{ +	struct skype_data *sd = ic->proto_data; +	gboolean ret; + +	if( sd->tx_len == 0 ) +	{ +		sd->tx_len = len; +		sd->txq = g_memdup( buf, len ); +		if( ( ret = skype_write_queue( ic ) ) && sd->tx_len > 0 ) +			sd->w_inpa = b_input_add( sd->fd, GAIM_INPUT_WRITE, skype_write_callback, ic ); +	} +	else +	{ +		sd->txq = g_renew( char, sd->txq, sd->tx_len + len ); +		memcpy( sd->txq + sd->tx_len, buf, len ); +		sd->tx_len += len; +		ret = TRUE; +	} +	return ret; +} + +static gboolean skype_write_callback( gpointer data, gint fd, b_input_condition cond ) +{ +	struct skype_data *sd = ((struct im_connection *)data)->proto_data; + +	return sd->fd != -1 && +		skype_write_queue( data ) && +		sd->tx_len > 0; +} + +static gboolean skype_write_queue( struct im_connection *ic ) +{ +	struct skype_data *sd = ic->proto_data; +	int st; + +	st = write( sd->fd, sd->txq, sd->tx_len ); + +	if( st == sd->tx_len ) +	{ +		/* We wrote everything, clear the buffer. */ +		g_free( sd->txq ); +		sd->txq = NULL; +		sd->tx_len = 0; + +		return TRUE; +	} +	else if( st == 0 || ( st < 0 && !sockerr_again() ) ) +	{ +		/* Set fd to -1 to make sure we won't write to it anymore. */ +		closesocket( sd->fd );  /* Shouldn't be necessary after errors? */ +		sd->fd = -1; + +		imcb_error( ic, "Short write() to server" ); +		imc_logout( ic, TRUE ); +		return FALSE; +	} +	else if( st > 0 ) +	{ +		char *s; + +		s = g_memdup( sd->txq + st, sd->tx_len - st ); +		sd->tx_len -= st; +		g_free( sd->txq ); +		sd->txq = s; + +		return TRUE; +	} +	else +	{ +		return TRUE; +	} +} + +gboolean skype_start_stream( struct im_connection *ic ) +{ +	char *buf; +	int st; + +	buf = g_strdup_printf("SEARCH FRIENDS"); +	st = skype_write( ic, buf, strlen( buf ) ); +	g_free(buf); +	return st; +} + +gboolean skype_connected( gpointer data, gint source, b_input_condition cond ) +{ +	struct im_connection *ic = data; + +	imcb_connected(ic); +	//imcb_add_buddy(ic, "vmiklos_dsd@skype.com", NULL); +	//imcb_buddy_status(ic, "vmiklos_dsd@skype.com", OPT_LOGGED_IN, NULL, NULL); +	return skype_start_stream(ic); +} + +static void skype_login( account_t *acc ) +{ +	struct im_connection *ic = imcb_new( acc ); +	struct skype_data *sd = g_new0( struct skype_data, 1 ); + +	ic->proto_data = sd; + +	imcb_log( ic, "Connecting" ); +	printf("%s:%d\n", acc->server, set_getint( &acc->set, "port")); +	sd->fd = proxy_connect(acc->server, set_getint( &acc->set, "port" ), skype_connected, ic ); +	printf("sd->fd: %d\n", sd->fd); +	if( sd->fd < 0 ) +	{ +		imcb_error( ic, "Could not connect to server" ); +		imc_logout( ic, TRUE ); +		return; +	} + +	sd->ic = ic; +} + +static void skype_logout( struct im_connection *ic ) +{ +	struct skype_data *sd = ic->proto_data; +	g_free(sd); +} + +static void skype_set_away( struct im_connection *ic, char *state_txt, char *message ) +{ +} + +static GList *skype_away_states( struct im_connection *ic ) +{ +	static GList *l = NULL; +	int i; + +	l = g_list_append( l, (void*)"Online" ); +	return l; +} + +static void skype_add_buddy( struct im_connection *ic, char *who, char *group ) +{ +} + +static void skype_remove_buddy( struct im_connection *ic, char *who, char *group ) +{ +} + +void init_plugin(void) +{ +	struct prpl *ret = g_new0( struct prpl, 1 ); + +	ret->name = "skype"; +	ret->login = skype_login; +	ret->init = skype_init; +	ret->logout = skype_logout; +	ret->away_states = skype_away_states; +	ret->add_buddy = skype_add_buddy; +	ret->remove_buddy = skype_remove_buddy; +	ret->away_states = skype_away_states; +	ret->set_away = skype_set_away; +	ret->handle_cmp = g_strcasecmp; +	register_protocol( ret ); +} | 
