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 ); }
// 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); }
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; }
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; }
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; } }
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; }
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]); } }
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 ); */ } }
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 ); }
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; }
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; }
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 }