コード例 #1
0
ファイル: account.c プロジェクト: jianingy/bitlbee-clone
account_t *account_get( irc_t *irc, char *id )
{
	account_t *a, *ret = NULL;
	char *handle, *s;
	int nr;
	
	/* This checks if the id string ends with (...) */
	if( ( handle = strchr( id, '(' ) ) && ( s = strchr( handle, ')' ) ) && s[1] == 0 )
	{
		struct prpl *proto;
		
		*s = *handle = 0;
		handle ++;
		
		if( ( proto = find_protocol( id ) ) )
		{
			for( a = irc->accounts; a; a = a->next )
				if( a->prpl == proto &&
				    a->prpl->handle_cmp( handle, a->user ) == 0 )
					ret = a;
		}
		
		/* Restore the string. */
		handle --;
		*handle = '(';
		*s = ')';
		
		if( ret )
			return ret;
	}
	
	if( sscanf( id, "%d", &nr ) == 1 && nr < 1000 )
	{
		for( a = irc->accounts; a; a = a->next )
			if( ( nr-- ) == 0 )
				return( a );
		
		return( NULL );
	}
	
	for( a = irc->accounts; a; a = a->next )
	{
		if( g_strcasecmp( id, a->prpl->name ) == 0 )
		{
			if( !ret )
				ret = a;
			else
				return( NULL ); /* We don't want to match more than one... */
		}
		else if( strstr( a->user, id ) )
		{
			if( !ret )
				ret = a;
			else
				return( NULL );
		}
	}
	
	return( ret );
}
コード例 #2
0
ファイル: ether_windows.cpp プロジェクト: tycho/sheepshaver
// Dispatch packet to protocol handler
static void ether_dispatch_packet(uint32 packet, uint32 length)
{
	// Get packet type
	uint16 type = ReadMacInt16(packet + 12);

	// Look for protocol
	NetProtocol *prot = find_protocol(type);
	if (prot == NULL)
		return;

	// No default handler
	if (prot->handler == 0)
		return;

	// Copy header to RHA
	Mac2Mac_memcpy(ether_data + ed_RHA, packet, 14);
	D(bug(" header %08lx%04lx %08lx%04lx %04lx\n", ReadMacInt32(ether_data + ed_RHA), ReadMacInt16(ether_data + ed_RHA + 4), ReadMacInt32(ether_data + ed_RHA + 6), ReadMacInt16(ether_data + ed_RHA + 10), ReadMacInt16(ether_data + ed_RHA + 12)));

	// Call protocol handler
	M68kRegisters r;
	r.d[0] = type;								// Packet type
	r.d[1] = length - 14;						// Remaining packet length (without header, for ReadPacket)
	r.a[0] = packet + 14;						// Pointer to packet (Mac address, for ReadPacket)
	r.a[3] = ether_data + ed_RHA + 14;			// Pointer behind header in RHA
	r.a[4] = ether_data + ed_ReadPacket;		// Pointer to ReadPacket/ReadRest routines
	D(bug(" calling protocol handler %08lx, type %08lx, length %08lx, data %08lx, rha %08lx, read_packet %08lx\n", prot->handler, r.d[0], r.d[1], r.a[0], r.a[3], r.a[4]));
	Execute68k(prot->handler, &r);
}
コード例 #3
0
ファイル: mgt_protocol.hpp プロジェクト: NingLeixueR/mwarepp
      bool run_task(uint32_t aipos, uint32_t aikey, const char* ap, uint32_t aplen)
      {
        m_premote2local_arr[aipos]->reset(ap, aplen);
        T_PHP* lphp;
        protocol_base<T_PHP>* lpb = find_protocol(m_promap_arr[aipos], m_premote2local_arr[aipos], lphp);
        if (lpb == nullptr)
        {
          /** print err log*/
        }
        else
        {
          T_PHP* lphp2 = m_plocal2remote_arr[aipos]->get_head();
          /** 触发逻辑 */
          lphp2->get_error() = lpb->run_task(aikey);
          

          /** 设置serr(server) */
          set_serr(lpb, lphp);
          m_plocal2remote_arr[aipos]->set_pack_head(lphp);
          /** 设置群发队列(server) */
          set_mass_send_arr(lpb, lphp2);

          //m_middle_arr[aipos]->send(lphp2->get_buffer(), lphp2->get_buffer_len());
          /** 回复 */
          send(m_middle_arr[aipos], lphp2);
        }
        return true;
      }
コード例 #4
0
ファイル: storage_xml.c プロジェクト: vmiklos/bitlbee
static xt_status handle_account( struct xt_node *node, gpointer data )
{
	struct xml_parsedata *xd = data;
	char *protocol, *handle, *server, *password = NULL, *autoconnect, *tag;
	char *pass_b64 = NULL;
	unsigned char *pass_cr = NULL;
	int pass_len;
	struct prpl *prpl = NULL;
	account_t *acc;
	struct xt_node *c;
	
	handle = xt_find_attr( node, "handle" );
	pass_b64 = xt_find_attr( node, "password" );
	server = xt_find_attr( node, "server" );
	autoconnect = xt_find_attr( node, "autoconnect" );
	tag = xt_find_attr( node, "tag" );
	
	protocol = xt_find_attr( node, "protocol" );
	if( protocol )
		prpl = find_protocol( protocol );
	
	if( !handle || !pass_b64 || !protocol || !prpl )
		return XT_ABORT;
	else if( ( pass_len = base64_decode( pass_b64, (unsigned char**) &pass_cr ) ) &&
	         arc_decode( pass_cr, pass_len, &password, xd->given_pass ) >= 0 )
	{
		acc = account_add( xd->irc->b, prpl, handle, password );
		if( server )
			set_setstr( &acc->set, "server", server );
		if( autoconnect )
			set_setstr( &acc->set, "auto_connect", autoconnect );
		if( tag )
			set_setstr( &acc->set, "tag", tag );
	}
	else
		return XT_ABORT;
	
	g_free( pass_cr );
	g_free( password );
	
	handle_settings( node, &acc->set );
	
	for( c = node->children; ( c = xt_find_node( c, "buddy" ) ); c = c->next )
	{
		char *handle, *nick;
		
		handle = xt_find_attr( c, "handle" );
		nick = xt_find_attr( c, "nick" );
		
		if( handle && nick )
			nick_set_raw( acc, handle, nick );
		else
			return XT_ABORT;
	}	
	return XT_HANDLED;
}
コード例 #5
0
ファイル: ether_windows.cpp プロジェクト: tycho/sheepshaver
int16 ether_attach_ph(uint16 type, uint32 handler)
{
	D(bug("ether_attach_ph type=0x%x, handler=0x%x\n",(int)type,handler));

	// Already attached?
	NetProtocol *p = find_protocol(type);
	if (p != NULL) {
		D(bug("ether_attach_ph: lapProtErr\n"));
		return lapProtErr;
	} else {
		// No, create and attach
		p = new NetProtocol;
		p->next = prot_list;
		p->type = type;
		p->handler = handler;
		prot_list = p;
		D(bug("ether_attach_ph: noErr\n"));
		return noErr;
	}
}
コード例 #6
0
ファイル: ether_windows.cpp プロジェクト: tycho/sheepshaver
int16 ether_detach_ph(uint16 type)
{
	D(bug("ether_detach_ph type=%08lx\n",(int)type));

	NetProtocol *p = find_protocol(type);
	if (p != NULL) {
		NetProtocol *previous = 0;
		NetProtocol *q = prot_list;
		while(q) {
			if (q == p) {
				if(previous) {
					previous->next = q->next;
				} else {
					prot_list = q->next;
				}
				delete p;
				return noErr;
			}
			previous = q;
			q = q->next;
		}
	}
	return lapProtErr;
}
コード例 #7
0
ファイル: root_commands.c プロジェクト: EionRobb/bitlbee
static void cmd_account(irc_t *irc, char **cmd)
{
	account_t *a;
	int len;

	if (global.conf->authmode == AUTHMODE_REGISTERED && !(irc->status & USTATUS_IDENTIFIED)) {
		irc_rootmsg(irc, "This server only accepts registered users");
		return;
	}

	len = strlen(cmd[1]);

	if (len >= 1 && g_strncasecmp(cmd[1], "add", len) == 0) {
		struct prpl *prpl;

		MIN_ARGS(3);

		if (!global.conf->allow_account_add) {
			irc_rootmsg(irc, "This server does not allow adding new accounts");
			return;
		}

		if (cmd[4] == NULL) {
			for (a = irc->b->accounts; a; a = a->next) {
				if (strcmp(a->pass, PASSWORD_PENDING) == 0) {
					irc_rootmsg(irc, "Enter password for account %s "
					            "first (use /OPER)", a->tag);
					return;
				}
			}

			irc->status |= OPER_HACK_ACCOUNT_PASSWORD;
		}

		prpl = find_protocol(cmd[2]);

		if (prpl == NULL) {
			if (is_protocol_disabled(cmd[2])) {
				irc_rootmsg(irc, "Protocol disabled in global config");
			} else {
				irc_rootmsg(irc, "Unknown protocol");
			}
			return;
		}

		for (a = irc->b->accounts; a; a = a->next) {
			if (a->prpl == prpl && prpl->handle_cmp(a->user, cmd[3]) == 0) {
				irc_rootmsg(irc, "Warning: You already have an account with "
				            "protocol `%s' and username `%s'. Are you accidentally "
				            "trying to add it twice?", prpl->name, cmd[3]);
			}
		}

		a = account_add(irc->b, prpl, cmd[3], cmd[4] ? cmd[4] : PASSWORD_PENDING);
		if (cmd[5]) {
			irc_rootmsg(irc, "Warning: Passing a servername/other flags to `account add' "
			            "is now deprecated. Use `account set' instead.");
			set_setstr(&a->set, "server", cmd[5]);
		}

		irc_rootmsg(irc, "Account successfully added with tag %s", a->tag);

		if (cmd[4] == NULL) {
			set_t *oauth = set_find(&a->set, "oauth");
			if (oauth && bool2int(set_value(oauth))) {
				*a->pass = '******';
				irc_rootmsg(irc, "No need to enter a password for this "
				            "account since it's using OAuth");
			} else {
				irc_rootmsg(irc, "You can now use the /OPER command to "
				            "enter the password");
				if (oauth) {
					irc_rootmsg(irc, "Alternatively, enable OAuth if "
					            "the account supports it: account %s "
					            "set oauth on", a->tag);
				}
			}
		}

		return;
	} else if (len >= 1 && g_strncasecmp(cmd[1], "list", len) == 0) {
		int i = 0;

		if (strchr(irc->umode, 'b')) {
			irc_rootmsg(irc, "Account list:");
		}

		for (a = irc->b->accounts; a; a = a->next) {
			char *con;

			if (a->ic && (a->ic->flags & OPT_LOGGED_IN)) {
				con = " (connected)";
			} else if (a->ic) {
				con = " (connecting)";
			} else if (a->reconnect) {
				con = " (awaiting reconnect)";
			} else {
				con = "";
			}

			irc_rootmsg(irc, "%2d (%s): %s, %s%s", i, a->tag, a->prpl->name, a->user, con);

			i++;
		}
		irc_rootmsg(irc, "End of account list");

		return;
	} else if (cmd[2]) {
		/* Try the following two only if cmd[2] == NULL */
	} else if (len >= 2 && g_strncasecmp(cmd[1], "on", len) == 0) {
		if (irc->b->accounts) {
			irc_rootmsg(irc, "Trying to get all accounts connected...");

			for (a = irc->b->accounts; a; a = a->next) {
				if (!a->ic && a->auto_connect) {
					if (strcmp(a->pass, PASSWORD_PENDING) == 0) {
						irc_rootmsg(irc, "Enter password for account %s "
						            "first (use /OPER)", a->tag);
					} else {
						account_on(irc->b, a);
					}
				}
			}
		} else {
			irc_rootmsg(irc, "No accounts known. Use `account add' to add one.");
		}

		return;
	} else if (len >= 2 && g_strncasecmp(cmd[1], "off", len) == 0) {
		irc_rootmsg(irc, "Deactivating all active (re)connections...");

		for (a = irc->b->accounts; a; a = a->next) {
			if (a->ic) {
				account_off(irc->b, a);
			} else if (a->reconnect) {
				cancel_auto_reconnect(a);
			}
		}

		return;
	}

	MIN_ARGS(2);
	len = strlen(cmd[2]);

	/* At least right now, don't accept on/off/set/del as account IDs even
	   if they're a proper match, since people not familiar with the new
	   syntax yet may get a confusing/nasty surprise. */
	if (g_strcasecmp(cmd[1], "on") == 0 ||
	    g_strcasecmp(cmd[1], "off") == 0 ||
	    g_strcasecmp(cmd[1], "set") == 0 ||
	    g_strcasecmp(cmd[1], "del") == 0 ||
	    (a = account_get(irc->b, cmd[1])) == NULL) {
		irc_rootmsg(irc, "Could not find account `%s'.", cmd[1]);

		return;
	}

	if (len >= 1 && g_strncasecmp(cmd[2], "del", len) == 0) {
		if (a->flags & ACC_FLAG_LOCKED) {
			irc_rootmsg(irc, "Account is locked, can't delete");
		}
		else if (a->ic) {
			irc_rootmsg(irc, "Account is still logged in, can't delete");
		} else {
			account_del(irc->b, a);
			irc_rootmsg(irc, "Account deleted");
		}
	} else if (len >= 2 && g_strncasecmp(cmd[2], "on", len) == 0) {
		if (a->ic) {
			irc_rootmsg(irc, "Account already online");
		} else if (strcmp(a->pass, PASSWORD_PENDING) == 0) {
			irc_rootmsg(irc, "Enter password for account %s "
			            "first (use /OPER)", a->tag);
		} else {
			account_on(irc->b, a);
		}
	} else if (len >= 2 && g_strncasecmp(cmd[2], "off", len) == 0) {
		if (a->ic) {
			account_off(irc->b, a);
		} else if (a->reconnect) {
			cancel_auto_reconnect(a);
			irc_rootmsg(irc, "Reconnect cancelled");
		} else {
			irc_rootmsg(irc, "Account already offline");
		}
	} else if (len >= 1 && g_strncasecmp(cmd[2], "set", len) == 0) {
		cmd_set_real(irc, cmd + 2, &a->set, cmd_account_set_checkflags);
	} else {
		irc_rootmsg(irc,
		            "Unknown command: %s [...] %s. Please use \x02help commands\x02 to get a list of available commands.", "account",
		            cmd[2]);
	}
}
コード例 #8
0
ファイル: storage_xml.c プロジェクト: shiplu/bitlbee
static void xml_start_element( GMarkupParseContext *ctx, const gchar *element_name, const gchar **attr_names, const gchar **attr_values, gpointer data, GError **error )
{
	struct xml_parsedata *xd = data;
	irc_t *irc = xd->irc;
	
	if( xd->unknown_tag > 0 )
	{
		xd->unknown_tag ++;
	}
	else if( g_strcasecmp( element_name, "user" ) == 0 )
	{
		char *nick = xml_attr( attr_names, attr_values, "nick" );
		char *pass = xml_attr( attr_names, attr_values, "password" );
		int st;
		
		if( !nick || !pass )
		{
			g_set_error( error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
			             "Missing attributes for %s element", element_name );
		}
		else if( ( st = md5_verify_password( xd->given_pass, pass ) ) == -1 )
		{
			xd->pass_st = XML_PASS_WRONG;
			g_set_error( error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
			             "Error while decoding password attribute" );
		}
		else if( st == 0 )
		{
			if( xd->pass_st != XML_PASS_CHECK_ONLY )
				xd->pass_st = XML_PASS_OK;
		}
		else
		{
			xd->pass_st = XML_PASS_WRONG;
			g_set_error( error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
			             "Password mismatch" );
		}
	}
	else if( xd->pass_st < XML_PASS_OK )
	{
		/* Let's not parse anything else if we only have to check
		   the password. */
	}
	else if( g_strcasecmp( element_name, "account" ) == 0 )
	{
		char *protocol, *handle, *server, *password = NULL, *autoconnect, *tag;
		char *pass_b64 = NULL;
		unsigned char *pass_cr = NULL;
		int pass_len;
		struct prpl *prpl = NULL;
		
		handle = xml_attr( attr_names, attr_values, "handle" );
		pass_b64 = xml_attr( attr_names, attr_values, "password" );
		server = xml_attr( attr_names, attr_values, "server" );
		autoconnect = xml_attr( attr_names, attr_values, "autoconnect" );
		tag = xml_attr( attr_names, attr_values, "tag" );
		
		protocol = xml_attr( attr_names, attr_values, "protocol" );
		if( protocol )
			prpl = find_protocol( protocol );
		
		if( !handle || !pass_b64 || !protocol )
			g_set_error( error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
			             "Missing attributes for %s element", element_name );
		else if( !prpl )
			g_set_error( error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
			             "Unknown protocol: %s", protocol );
		else if( ( pass_len = base64_decode( pass_b64, (unsigned char**) &pass_cr ) ) &&
		         arc_decode( pass_cr, pass_len, &password, xd->given_pass ) >= 0 )
		{
			xd->current_account = account_add( irc->b, prpl, handle, password );
			if( server )
				set_setstr( &xd->current_account->set, "server", server );
			if( autoconnect )
				set_setstr( &xd->current_account->set, "auto_connect", autoconnect );
			if( tag )
				set_setstr( &xd->current_account->set, "tag", tag );
		}
		else
		{
			/* Actually the _decode functions don't even return error codes,
			   but maybe they will later... */
			g_set_error( error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
			             "Error while decrypting account password" );
		}
		
		g_free( pass_cr );
		g_free( password );
	}
	else if( g_strcasecmp( element_name, "setting" ) == 0 )
	{
		char *setting;
		
		if( xd->current_setting )
		{
			g_free( xd->current_setting );
			xd->current_setting = NULL;
		}
		
		if( ( setting = xml_attr( attr_names, attr_values, "name" ) ) )
		{
			if( xd->current_channel != NULL )
				xd->current_set_head = &xd->current_channel->set;
			else if( xd->current_account != NULL )
				xd->current_set_head = &xd->current_account->set;
			else
				xd->current_set_head = &xd->irc->b->set;
			
			xd->current_setting = g_strdup( setting );
		}
		else
			g_set_error( error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
			             "Missing attributes for %s element", element_name );
	}
	else if( g_strcasecmp( element_name, "buddy" ) == 0 )
	{
		char *handle, *nick;
		
		handle = xml_attr( attr_names, attr_values, "handle" );
		nick = xml_attr( attr_names, attr_values, "nick" );
		
		if( xd->current_account && handle && nick )
		{
			nick_set_raw( xd->current_account, handle, nick );
		}
		else
		{
			g_set_error( error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
			             "Missing attributes for %s element", element_name );
		}
	}
	else if( g_strcasecmp( element_name, "channel" ) == 0 )
	{
		char *name, *type;
		
		name = xml_attr( attr_names, attr_values, "name" );
		type = xml_attr( attr_names, attr_values, "type" );
		
		if( !name || !type )
		{
			g_set_error( error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
			             "Missing attributes for %s element", element_name );
			return;
		}
		
		/* The channel may exist already, for example if it's &bitlbee.
		   Also, it's possible that the user just reconnected and the
		   IRC client already rejoined all channels it was in. They
		   should still get the right settings. */
		if( ( xd->current_channel = irc_channel_by_name( irc, name ) ) ||
		    ( xd->current_channel = irc_channel_new( irc, name ) ) )
			set_setstr(&xd->current_channel->set, "type", type );
	}
	/* Backward compatibility: Keep this around for a while for people
	   switching from BitlBee 1.2.4+. */
	else if( g_strcasecmp( element_name, "chat" ) == 0 )
	{
		char *handle, *channel;
		
		handle = xml_attr( attr_names, attr_values, "handle" );
		channel = xml_attr( attr_names, attr_values, "channel" );
		
		if( xd->current_account && handle && channel )
		{
			irc_channel_t *ic;
			
			if( ( ic = irc_channel_new( irc, channel ) ) &&
			    set_setstr( &ic->set, "type", "chat" ) &&
			    set_setstr( &ic->set, "chat_type", "room" ) &&
			    set_setstr( &ic->set, "account", xd->current_account->tag ) &&
			    set_setstr( &ic->set, "room", handle ) )
			{
				/* Try to pick up some settings where possible. */
				xd->current_channel = ic;
			}
			else if( ic )
				irc_channel_free( ic );
		}
		else
		{
			g_set_error( error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
			             "Missing attributes for %s element", element_name );
		}
	}
	else
	{
		xd->unknown_tag ++;
		irc_rootmsg( irc, "Warning: Unknown XML tag found in configuration file (%s). "
		                  "This may happen when downgrading BitlBee versions. "
		                  "This tag will be skipped and the information will be lost "
		                  "once you save your settings.", element_name );
		/*
		g_set_error( error, G_MARKUP_ERROR, G_MARKUP_ERROR_UNKNOWN_ELEMENT,
		             "Unkown element: %s", element_name );
		*/
	}
}
コード例 #9
0
ファイル: purple.c プロジェクト: GRMrGecko/bitlbee
void purple_initmodule()
{
	struct prpl funcs;
	GList *prots;
	GString *help;
	char *dir;
	
	if( B_EV_IO_READ != PURPLE_INPUT_READ ||
	    B_EV_IO_WRITE != PURPLE_INPUT_WRITE )
	{
		/* FIXME FIXME FIXME FIXME FIXME :-) */
		exit( 1 );
	}
	
	dir = g_strdup_printf( "%s/purple", global.conf->configdir );
	purple_util_set_user_dir( dir );
	g_free( dir );
	
	purple_debug_set_enabled( FALSE );
	purple_core_set_ui_ops( &bee_core_uiops );
	purple_eventloop_set_ui_ops( &glib_eventloops );
	if( !purple_core_init( "BitlBee") )
	{
		/* Initializing the core failed. Terminate. */
		fprintf( stderr, "libpurple initialization failed.\n" );
		abort();
	}
	
	if( proxytype != PROXY_NONE )
	{
		PurpleProxyInfo *pi = purple_global_proxy_get_info();
		switch( proxytype )
		{
		case PROXY_SOCKS4:
			purple_proxy_info_set_type( pi, PURPLE_PROXY_SOCKS4 );
			break;
		case PROXY_SOCKS5:
			purple_proxy_info_set_type( pi, PURPLE_PROXY_SOCKS5 );
			break;
		case PROXY_HTTP:
			purple_proxy_info_set_type( pi, PURPLE_PROXY_HTTP );
			break;
		} 
	 	purple_proxy_info_set_host( pi, proxyhost );
 		purple_proxy_info_set_port( pi, proxyport );
	 	purple_proxy_info_set_username( pi, proxyuser );
	 	purple_proxy_info_set_password( pi, proxypass );
	}
	
	purple_set_blist( purple_blist_new() );
	
	/* No, really. So far there were ui_ops for everything, but now suddenly
	   one needs to use signals for typing notification stuff. :-( */
	purple_signal_connect( purple_conversations_get_handle(), "buddy-typing",
	                       &funcs, PURPLE_CALLBACK(prplcb_buddy_typing), NULL );
	purple_signal_connect( purple_conversations_get_handle(), "buddy-typed",
	                       &funcs, PURPLE_CALLBACK(prplcb_buddy_typing), NULL );
	purple_signal_connect( purple_conversations_get_handle(), "buddy-typing-stopped",
	                       &funcs, PURPLE_CALLBACK(prplcb_buddy_typing), NULL );
	
	memset( &funcs, 0, sizeof( funcs ) );
	funcs.login = purple_login;
	funcs.init = purple_init;
	funcs.logout = purple_logout;
	funcs.buddy_msg = purple_buddy_msg;
	funcs.away_states = purple_away_states;
	funcs.set_away = purple_set_away;
	funcs.add_buddy = purple_add_buddy;
	funcs.remove_buddy = purple_remove_buddy;
	funcs.add_permit = purple_add_permit;
	funcs.add_deny = purple_add_deny;
	funcs.rem_permit = purple_rem_permit;
	funcs.rem_deny = purple_rem_deny;
	funcs.get_info = purple_get_info;
	funcs.keepalive = purple_keepalive;
	funcs.send_typing = purple_send_typing;
	funcs.handle_cmp = g_strcasecmp;
	/* TODO(wilmer): Set these only for protocols that support them? */
	funcs.chat_msg = purple_chat_msg;
	funcs.chat_with = purple_chat_with;
	funcs.chat_invite = purple_chat_invite;
	funcs.chat_leave = purple_chat_leave;
	funcs.chat_join = purple_chat_join;
	funcs.transfer_request = purple_transfer_request;
	
	help = g_string_new( "BitlBee libpurple module supports the following IM protocols:\n" );
	
	/* Add a protocol entry to BitlBee's structures for every protocol
	   supported by this libpurple instance. */	
	for( prots = purple_plugins_get_protocols(); prots; prots = prots->next )
	{
		PurplePlugin *prot = prots->data;
		struct prpl *ret;
		
		/* If we already have this one (as a native module), don't
		   add a libpurple duplicate. */
		if( find_protocol( prot->info->id ) )
			continue;
		
		ret = g_memdup( &funcs, sizeof( funcs ) );
		ret->name = ret->data = prot->info->id;
		if( strncmp( ret->name, "prpl-", 5 ) == 0 )
			ret->name += 5;
		register_protocol( ret );
		
		g_string_append_printf( help, "\n* %s (%s)", ret->name, prot->info->name );
		
		/* libpurple doesn't define a protocol called OSCAR, but we
		   need it to be compatible with normal BitlBee. */
		if( g_strcasecmp( prot->info->id, "prpl-aim" ) == 0 )
		{
			ret = g_memdup( &funcs, sizeof( funcs ) );
			ret->name = "oscar";
			ret->data = prot->info->id;
			register_protocol( ret );
		}
	}
	
	g_string_append( help, "\n\nFor used protocols, more information about available "
	                 "settings can be found using \x02help purple <protocol name>\x02 "
	                 "(create an account using that protocol first!)" );
	
	/* Add a simple dynamically-generated help item listing all
	   the supported protocols. */
	help_add_mem( &global.help, "purple", help->str );
	g_string_free( help, TRUE );
}
コード例 #10
0
ファイル: client.c プロジェクト: EQ4/musicd
int client_process(client_t *client)
{
  int result;

  while ((result = read_data(client)) > 0) { }
  if (result < 0) {
    return result;
  }

  if (!client->protocol) {
    /* The client has no protocol detected yet */

    find_protocol(client);

    if (!client->protocol) {
      musicd_log(LOG_ERROR, "client", "%s: unknown protocol, terminating",
                 client->address);
      return -1;
    }
    
    musicd_log(LOG_DEBUG, "client", "%s: protocol is '%s'",
                          client->address, client->protocol->name);
    
    /* Actually open the client to be processed with detected protocol */
    client->self = client->protocol->open(client);
  }

  if (client->state == CLIENT_STATE_WAIT_TASK) {
    /* Client was waiting for task to finish and now the task manager signaled
     * through the pipe. */
    client->state = CLIENT_STATE_NORMAL;
    task_free(client->wait_task);
    if (client->wait_callback(client->self, client->wait_data) < 0) {
      return -1;
    }
  }

  /* (Try to) purge the entire outgoing buffer. */

  if (string_size(client->outbuf) > 0) {
    /* There is outgoing data in buffer, try to write */
    result = write_data(client);
    if (result < 0) {
      return result;
    }
  }

  if (client->state == CLIENT_STATE_DRAIN) {
    if (string_size(client->outbuf) == 0) {
      /* Client was draining, and now it is done - terminate */
      return -1;
    }
  }

  /* If there was nothing to write but we have unprocessed data, process it. */

  if (string_size(client->inbuf) > 0) {
    result = client->protocol->process(client->self,
                                      string_string(client->inbuf),
                                      string_size(client->inbuf));
    if (result < 0) {
      return result;
    }

    string_remove_front(client->inbuf, result);
  } else if (client->state == CLIENT_STATE_FEED
          && string_size(client->outbuf) == 0) {

    /* There wasn't anything to process, we can push data to the client and the
     * outgoing buffer is empty. */

    result = client->protocol->feed(client->self);
    if (result < 0) {
      return result;
    }
  }

  return 0;
}
コード例 #11
0
ファイル: storage_xml.c プロジェクト: AaronVanGeffen/bitlbee
static xt_status handle_account(struct xt_node *node, gpointer data)
{
	struct xml_parsedata *xd = data;
	char *protocol, *handle, *server, *password = NULL, *autoconnect, *tag, *locked;
	char *pass_b64 = NULL;
	unsigned char *pass_cr = NULL;
	int pass_len, local = 0;
	struct prpl *prpl = NULL;
	account_t *acc;
	struct xt_node *c;

	handle = xt_find_attr(node, "handle");
	pass_b64 = xt_find_attr(node, "password");
	server = xt_find_attr(node, "server");
	autoconnect = xt_find_attr(node, "autoconnect");
	tag = xt_find_attr(node, "tag");
	locked = xt_find_attr(node, "locked");

	protocol = xt_find_attr(node, "protocol");
	if (protocol) {
		prpl = find_protocol(protocol);
		if (!prpl) {
			irc_rootmsg(xd->irc, "Error loading user config: Protocol not found: `%s'", protocol);
			return XT_ABORT;
		}
		local = protocol_account_islocal(protocol);
	}

	if (!handle || !pass_b64 || !protocol || !prpl) {
		return XT_ABORT;
	}

	pass_len = base64_decode(pass_b64, (unsigned char **) &pass_cr);
	if (xd->irc->auth_backend) {
		password = g_strdup((char *)pass_cr);
	} else {
		pass_len = arc_decode(pass_cr, pass_len, &password, xd->given_pass);
		if (pass_len < 0) {
			g_free(pass_cr);
			g_free(password);
			return XT_ABORT;
		}
	}

	acc = account_add(xd->irc->b, prpl, handle, password);
	if (server) {
		set_setstr(&acc->set, "server", server);
	}
	if (autoconnect) {
		set_setstr(&acc->set, "auto_connect", autoconnect);
	}
	if (tag) {
		set_setstr(&acc->set, "tag", tag);
	}
	if (local) {
		acc->flags |= ACC_FLAG_LOCAL;
	}
	if (locked && !g_strcasecmp(locked, "true")) {
		acc->flags |= ACC_FLAG_LOCKED;
	}

	g_free(pass_cr);
	g_free(password);

	handle_settings(node, &acc->set);

	for (c = node->children; (c = xt_find_node(c, "buddy")); c = c->next) {
		char *handle, *nick;

		handle = xt_find_attr(c, "handle");
		nick = xt_find_attr(c, "nick");

		if (handle && nick) {
			nick_set_raw(acc, handle, nick);
		} else {
			return XT_ABORT;
		}
	}
	return XT_HANDLED;
}
コード例 #12
0
ファイル: event.c プロジェクト: senseisimple/emulab-stable
void
tgevent_init(int argc, char *argv[])
{
	address_tuple_t	tuple;
	char *server = "localhost";
	char *port = NULL;
	char *ipaddr = NULL;
	char *myname = NULL;
	char *keyfile = NULL;
	char buf[BUFSIZ], ipbuf[BUFSIZ];
	struct sockaddr saddr, taddr;
	int c, gotsaddr = 0;

	progname = argv[0];
	memset(&saddr, 0, sizeof(saddr));
	memset(&taddr, 0, sizeof(taddr));
	
	while ((c = getopt(argc, argv, "s:p:S:T:P:R:N:l:E:k:")) != -1) {
		switch (c) {
		case 's':
			server = optarg;
			break;
		case 'p':
			port = optarg;
			break;
		case 'S':
			if (!ipport_atoaddr(optarg, &saddr))
				badaddr();
			gotsaddr = 1;
			break;
		case 'T':
			if (!ipport_atoaddr(optarg, &taddr))
				badaddr();
			break;
		case 'P':
			prot.prot = find_protocol(optarg);
			break;
		case 'R':
			if (strcmp(optarg, "server") == 0 ||
			    strcmp(optarg, "sink") == 0)
				prot.qos |= QOS_SERVER;
			break;
		case 'N':
			myname = optarg;
			break;
		case 'E':
			myexp = optarg;
			break;
		case 'l':
			logfile = optarg;
			break;
		case 'k':
			keyfile = optarg;
			break;

		default:
			usage();
		}
	}

	if (prot.prot == NULL)
		badprot();

	if (prot.qos & QOS_SERVER) {
		prot.src = taddr;
		prot.qos |= QOS_SRC;
	} else {
		prot.dst = taddr;
		prot.qos |= QOS_DST;
		/*
		 * Can specify source address to bind local interface
		 * of sender.
		 */
		if (gotsaddr) {
			prot.src = saddr;
			prot.qos |= QOS_SRC;
		}
	}

	argc -= optind;
	argv += optind;

#ifndef TESTING
	/*
	 * Get our IP address. Thats how we name ourselves to the
	 * Testbed Event System. 
	 */
	if (ipaddr == NULL) {
	    struct hostent	*he;
	    struct in_addr	myip;
	    
	    if (gethostname(buf, sizeof(buf)) < 0) {
		fatal("could not get hostname");
	    }

	    if (! (he = gethostbyname(buf))) {
		fatal("could not get IP address from hostname");
	    }
	    memcpy((char *)&myip, he->h_addr, he->h_length);
	    strcpy(ipbuf, inet_ntoa(myip));
	    ipaddr = ipbuf;
	}

	/*
	 * Convert server/port to elvin thing.
	 *
	 * XXX This elvin string stuff should be moved down a layer. 
	 */
	if (server) {
		snprintf(buf, sizeof(buf), "elvin://%s%s%s",
			 server,
			 (port ? ":"  : ""),
			 (port ? port : ""));
		server = buf;
	}

	/*
	 * Construct an address tuple for subscribing to events for
	 * this node.
	 */
	tuple = address_tuple_alloc();
	if (tuple == NULL) {
		fatal("could not allocate an address tuple");
	}
	/*
	 * Do not use the ipaddr if we have a pid/eid. This allows
	 * trafgens to work inside jails that have their own IP.
	 */
	if (myexp) {
		tuple->expt = myexp;
		tuple->host = ADDRESSTUPLE_ANY;
	}
	else {
		tuple->host = ipaddr;
		tuple->expt = ADDRESSTUPLE_ANY;
	}
	tuple->site      = ADDRESSTUPLE_ANY;
	tuple->group     = ADDRESSTUPLE_ANY;
	tuple->objtype   = TBDB_OBJECTTYPE_TRAFGEN;
	tuple->objname   = myname ? myname : ADDRESSTUPLE_ANY;
	tuple->eventtype = ADDRESSTUPLE_ANY;

	/*
	 * Register with the event system. 
	 */
	ehandle = event_register_withkeyfile(server, 0, keyfile);
	if (ehandle == NULL) {
		fatal("could not register with event system");
	}
	
	/*
	 * Subscribe to the event we specified above.
	 */
	if (!event_subscribe(ehandle, callback, tuple, NULL)) {
		fatal("could not subscribe to TRAFGEN events");
	}
	address_tuple_free(tuple);

	/*
	 * Also subscribe to the start time event which we use to
	 * synchronize connection setup.
	 */
	tuple = address_tuple_alloc();
	if (tuple == NULL) {
		fatal("could not allocate an address tuple");
	}
	tuple->host	 = ADDRESSTUPLE_ANY;
	tuple->site      = ADDRESSTUPLE_ANY;
	tuple->group     = ADDRESSTUPLE_ANY;
	tuple->expt      = myexp ? myexp : ADDRESSTUPLE_ANY;
	tuple->objtype	 = TBDB_OBJECTTYPE_TIME;
	tuple->objname   = ADDRESSTUPLE_ANY;
	tuple->eventtype = ADDRESSTUPLE_ANY;
	if (!event_subscribe(ehandle, callback, tuple, NULL)) {
		fatal("could not subscribe to TIME events");
	}
	address_tuple_free(tuple);
#endif
}