static void purple_login(account_t *acc) { struct im_connection *ic = imcb_new(acc); struct purple_data *pd; if ((local_bee != NULL && local_bee != acc->bee) || (global.conf->runmode == RUNMODE_DAEMON && !getenv("BITLBEE_DEBUG"))) { imcb_error(ic, "Daemon mode detected. Do *not* try to use libpurple in daemon mode! " "Please use inetd or ForkDaemon mode instead."); imc_logout(ic, FALSE); return; } local_bee = acc->bee; /* For now this is needed in the _connected() handlers if using GLib event handling, to make sure we're not handling events on dead connections. */ purple_connections = g_slist_prepend(purple_connections, ic); ic->proto_data = pd = g_new0(struct purple_data, 1); pd->account = purple_account_new(acc->user, (char *) acc->prpl->data); pd->input_requests = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, g_free); pd->next_request_id = 0; purple_account_set_password(pd->account, acc->pass); purple_sync_settings(acc, pd->account); purple_account_set_enabled(pd->account, "BitlBee", TRUE); if (set_getbool(&acc->set, "mail_notifications") && set_getstr(&acc->set, "mail_notifications_handle")) { imcb_add_buddy(ic, set_getstr(&acc->set, "mail_notifications_handle"), NULL); } }
/** * Implements #prpl->login(). This logins an account in. * * @param acc The #account_t. **/ static void steam_login(account_t *acc) { SteamData *sata; SteamApiReq *req; gchar *str; sata = steam_data_new(acc); imcb_log(sata->ic, "Connecting"); if ((sata->api->token == NULL) || (sata->api->sessid == NULL)) { str = set_getstr(&acc->set, "cgid"); g_free(sata->api->cgid); sata->api->cgid = g_strdup(str); str = set_getstr(&acc->set, "esid"); g_free(sata->api->esid); sata->api->esid = g_strdup(str); imcb_log(sata->ic, "Requesting authentication key"); req = steam_api_req_new(sata->api, steam_cb_key, sata); steam_api_req_key(req, acc->user); return; } imcb_log(sata->ic, "Sending logon request"); req = steam_api_req_new(sata->api, steam_cb_logon, sata); steam_api_req_logon(req); }
static gboolean bee_irc_user_msg(bee_t *bee, bee_user_t *bu, const char *msg_, guint32 flags, time_t sent_at) { irc_t *irc = bee->ui_data; irc_user_t *iu = (irc_user_t *) bu->ui_data; irc_user_t *src_iu = iu; irc_user_t *dst_iu = irc->user; const char *dst; char *prefix = NULL; char *wrapped, *ts = NULL; char *msg = g_strdup(msg_); char *message_type = "PRIVMSG"; GSList *l; if (sent_at > 0 && set_getbool(&irc->b->set, "display_timestamps")) { ts = irc_format_timestamp(irc, sent_at); } dst = irc_user_msgdest(iu); if (flags & OPT_SELFMESSAGE) { char *setting = set_getstr(&irc->b->set, "self_messages"); if (is_bool(setting)) { if (bool2int(setting)) { /* set to true, send it with src/dst flipped */ dst_iu = iu; src_iu = irc->user; if (dst == irc->user->nick) { dst = dst_iu->nick; } } else { /* set to false, skip the message completely */ goto cleanup; } } else if (g_strncasecmp(setting, "prefix", 6) == 0) { /* third state, prefix, loosely imitates the znc privmsg_prefix module */ g_free(msg); if (g_strncasecmp(msg_, "/me ", 4) == 0) { msg = g_strdup_printf("/me -> %s", msg_ + 4); } else { msg = g_strdup_printf("-> %s", msg_); } if (g_strcasecmp(setting, "prefix_notice") == 0) { message_type = "NOTICE"; } } } if (dst != dst_iu->nick) { /* if not messaging directly (control channel), call user by name */ prefix = g_strdup_printf("%s%s%s", dst_iu->nick, set_getstr(&bee->set, "to_char"), ts ? : ""); } else {
void Skype_login (account_t* account) { im_connection* connection = imcb_new(account); SkypeData* skype = g_new0(struct SkypeData, 1); connection->proto_data = skype; imcb_log(connection, "Connecting"); skype->ssl = ssl_connect( set_getstr(&account->set, "server"), set_getint(&account->set, "port"), Skype_connected, connection ); skype->fd = skype->ssl ? ssl_getfd(skype->ssl) : -1; skype->username = g_strdup(account->user); skype->connection = connection; if (set_getbool(&account->set, "skypeconsole")) { imcb_add_buddy(connection, "skypeconsole", NULL); } }
void imcb_notify_email(struct im_connection *ic, char *format, ...) { const char *handle; va_list params; char *msg; if (!set_getbool(&ic->acc->set, "mail_notifications")) { return; } va_start(params, format); msg = g_strdup_vprintf(format, params); va_end(params); /* up to the protocol to set_add this if they want to use this */ handle = set_getstr(&ic->acc->set, "mail_notifications_handle"); if (handle != NULL) { imcb_buddy_msg(ic, handle, msg, 0, 0); } else { imcb_log(ic, "%s", msg); } g_free(msg); }
/* IM->UI callbacks */ void imcb_buddy_status(struct im_connection *ic, const char *handle, int flags, const char *state, const char *message) { bee_t *bee = ic->bee; bee_user_t *bu, *old; if (!(bu = bee_user_by_handle(bee, ic, handle))) { if (g_strcasecmp(set_getstr(&ic->bee->set, "handle_unknown"), "add") == 0) { bu = bee_user_new(bee, ic, handle, BEE_USER_LOCAL); } else { if (g_strcasecmp(set_getstr(&ic->bee->set, "handle_unknown"), "ignore") != 0) { imcb_log(ic, "imcb_buddy_status() for unknown handle %s:\n" "flags = %d, state = %s, message = %s", handle, flags, state ? state : "NULL", message ? message : "NULL"); } return; } } /* May be nice to give the UI something to compare against. */ old = g_memdup(bu, sizeof(bee_user_t)); /* TODO(wilmer): OPT_AWAY, or just state == NULL ? */ bu->flags = flags; bu->status_msg = g_strdup(message); if (state && *state) { bu->status = g_strdup(state); } else if (flags & OPT_AWAY) { bu->status = g_strdup("Away"); } else { bu->status = NULL; } if (bu->status == NULL && (flags & OPT_MOBILE) && set_getbool(&bee->set, "mobile_is_away")) { bu->flags |= BEE_USER_AWAY; bu->status = g_strdup("Mobile"); } if (bee->ui->user_status) { bee->ui->user_status(bee, bu, old); } g_free(old->status_msg); g_free(old->status); g_free(old); }
static int cmd_set_real(irc_t *irc, char **cmd, set_t **head, cmd_set_checkflags checkflags) { char *set_name = NULL, *value = NULL; gboolean del = FALSE; if (cmd[1] && g_strncasecmp(cmd[1], "-del", 4) == 0) { MIN_ARGS(2, 0); set_name = cmd[2]; del = TRUE; } else { set_name = cmd[1]; value = cmd[2]; } if (set_name && (value || del)) { set_t *s = set_find(head, set_name); int st; if (s && s->flags & SET_LOCKED) { irc_rootmsg(irc, "This setting can not be changed"); return 0; } if (s && checkflags && checkflags(irc, s) == 0) { return 0; } if (del) { st = set_reset(head, set_name); } else { st = set_setstr(head, set_name, value); } if (set_getstr(head, set_name) == NULL && set_find(head, set_name)) { /* This happens when changing the passwd, for example. Showing these msgs instead gives slightly clearer feedback. */ if (st) { irc_rootmsg(irc, "Setting changed successfully"); } else { irc_rootmsg(irc, "Failed to change setting"); } } else { cmd_showset(irc, head, set_name); } } else if (set_name) { cmd_showset(irc, head, set_name); } else { set_t *s = *head; while (s) { if (set_isvisible(s)) { cmd_showset(irc, &s, s->key); } s = s->next; } } return 1; }
static xt_status jabber_do_iq_auth( struct im_connection *ic, struct xt_node *node, struct xt_node *orig ) { struct jabber_data *jd = ic->proto_data; struct xt_node *reply, *query; xt_status st; char *s; if( !( query = xt_find_node( node->children, "query" ) ) ) { imcb_log( ic, "Warning: Received incomplete IQ packet while authenticating" ); imc_logout( ic, FALSE ); return XT_HANDLED; } /* Time to authenticate ourselves! */ reply = xt_new_node( "query", NULL, NULL ); xt_add_attr( reply, "xmlns", XMLNS_AUTH ); xt_add_child( reply, xt_new_node( "username", jd->username, NULL ) ); xt_add_child( reply, xt_new_node( "resource", set_getstr( &ic->acc->set, "resource" ), NULL ) ); if( xt_find_node( query->children, "digest" ) && ( s = xt_find_attr( jd->xt->root, "id" ) ) ) { /* We can do digest authentication, it seems, and of course we prefer that. */ sha1_state_t sha; char hash_hex[41]; unsigned char hash[20]; int i; sha1_init( &sha ); sha1_append( &sha, (unsigned char*) s, strlen( s ) ); sha1_append( &sha, (unsigned char*) ic->acc->pass, strlen( ic->acc->pass ) ); sha1_finish( &sha, hash ); for( i = 0; i < 20; i ++ ) sprintf( hash_hex + i * 2, "%02x", hash[i] ); xt_add_child( reply, xt_new_node( "digest", hash_hex, NULL ) ); } else if( xt_find_node( query->children, "password" ) ) { /* We'll have to stick with plaintext. Let's hope we're using SSL/TLS... */ xt_add_child( reply, xt_new_node( "password", ic->acc->pass, NULL ) ); } else { xt_free_node( reply ); imcb_error( ic, "Can't find suitable authentication method" ); imc_logout( ic, FALSE ); return XT_ABORT; } reply = jabber_make_packet( "iq", "set", NULL, reply ); jabber_cache_add( ic, reply, jabber_finish_iq_auth ); st = jabber_write_packet( ic, reply ); return st ? XT_HANDLED : XT_ABORT; }
static gboolean bee_irc_user_new(bee_t *bee, bee_user_t *bu) { irc_user_t *iu; irc_t *irc = (irc_t *) bee->ui_data; char nick[MAX_NICK_LENGTH + 1], *s; memset(nick, 0, MAX_NICK_LENGTH + 1); strncpy(nick, nick_get(bu), MAX_NICK_LENGTH); bu->ui_data = iu = irc_user_new(irc, nick); iu->bu = bu; if (set_getbool(&irc->b->set, "private")) { iu->last_channel = NULL; } else { iu->last_channel = irc_channel_with_user(irc, iu); } if ((s = strchr(bu->handle, '@'))) { iu->host = g_strdup(s + 1); iu->user = g_strndup(bu->handle, s - bu->handle); } else { iu->user = g_strdup(bu->handle); if (bu->ic->acc->server) { iu->host = g_strdup(bu->ic->acc->server); } else { char *s; for (s = bu->ic->acc->tag; g_ascii_isalnum(*s); s++) { ; } /* Only use the tag if we got to the end of the string. (So allow alphanumerics only. Hopefully not too restrictive.) */ if (*s) { iu->host = g_strdup(bu->ic->acc->prpl->name); } else { iu->host = g_strdup(bu->ic->acc->tag); } } } while ((s = strchr(iu->user, ' '))) { *s = '_'; } if (bu->flags & BEE_USER_LOCAL) { char *s = set_getstr(&bee->set, "handle_unknown"); if (strcmp(s, "add_private") == 0) { iu->last_channel = NULL; } else if (strcmp(s, "add_channel") == 0) { iu->last_channel = irc->default_channel; } } iu->f = &irc_user_im_funcs; return TRUE; }
int set_getbool( set_t **head, char *key ) { char *s = set_getstr( head, key ); if( !s ) return 0; return bool2int( s ); }
/** * Callback for getting the friends ids. */ static void twitter_http_get_friends_ids(struct http_request *req) { struct im_connection *ic; struct xt_parser *parser; struct twitter_xml_list *txl; struct twitter_data *td; ic = req->data; // Check if the connection is still active. if (!g_slist_find(twitter_connections, ic)) return; td = ic->proto_data; // Check if the HTTP request went well. More strict checks as this is // the first request we do in a session. if (req->status_code == 401) { imcb_error(ic, "Authentication failure"); imc_logout(ic, FALSE); return; } else if (req->status_code != 200) { // It didn't go well, output the error and return. imcb_error(ic, "Could not retrieve %s: %s", TWITTER_FRIENDS_IDS_URL, twitter_parse_error(req)); imc_logout(ic, TRUE); return; } else { td->http_fails = 0; } /* Create the room now that we "logged in". */ if (!td->timeline_gc && g_strcasecmp(set_getstr(&ic->acc->set, "mode"), "chat") == 0) twitter_groupchat_init(ic); txl = g_new0(struct twitter_xml_list, 1); txl->list = td->follow_ids; // Parse the data. parser = xt_new(NULL, txl); xt_feed(parser, req->reply_body, req->body_size); twitter_xt_get_friends_id_list(parser->root, txl); xt_free(parser); td->follow_ids = txl->list; if (txl->next_cursor) /* These were just numbers. Up to 4000 in a response AFAIK so if we get here we may be using a spammer account. \o/ */ twitter_get_friends_ids(ic, txl->next_cursor); else /* Now to convert all those numbers into names.. */ twitter_get_users_lookup(ic); txl->list = NULL; txl_free(txl); }
/** * Implemented #SteamApiFunc for #steam_api_req_key(). * * @param req The #SteamApiReq. * @param data The user defined data, which is #SteamData. **/ static void steam_cb_key(SteamApiReq *req, gpointer data) { SteamData *sata = data; account_t *acc; gchar *ac; gchar *cc; if (steam_req_error(sata, req, TRUE)) return; acc = sata->ic->acc; ac = set_getstr(&acc->set, "authcode"); cc = set_getstr(&acc->set, "captcha"); imcb_log(sata->ic, "Requesting authentication token"); req = steam_api_req_new(req->api, steam_cb_auth, sata); steam_api_req_auth(req, acc->user, acc->pass, ac, cc); }
void jabber_si_transfer_request(struct im_connection *ic, file_transfer_t *ft, char *who) { struct jabber_transfer *tf; struct jabber_data *jd = ic->proto_data; struct jabber_buddy *bud; char *server = jd->server, *s; if ((s = strchr(who, '=')) && jabber_chat_by_jid(ic, s + 1)) { bud = jabber_buddy_by_ext_jid(ic, who, 0); } else { bud = jabber_buddy_by_jid(ic, who, 0); } if (bud == NULL) { imcb_file_canceled(ic, ft, "Couldn't find buddy (BUG?)"); return; } imcb_log(ic, "Trying to send %s(%zd bytes) to %s", ft->file_name, ft->file_size, who); tf = g_new0(struct jabber_transfer, 1); tf->ic = ic; tf->ft = ft; tf->fd = -1; tf->ft->data = tf; tf->ft->free = jabber_si_free_transfer; tf->bud = bud; ft->write = jabber_bs_send_write; jd->filetransfers = g_slist_prepend(jd->filetransfers, tf); /* query buddy's features and server's streaming proxies if necessary */ if (!tf->bud->features) { jabber_iq_query_features(ic, bud->full_jid); } /* If <auto> is not set don't check for proxies */ if ((jd->have_streamhosts != 1) && (jd->streamhosts == NULL) && (strstr(set_getstr(&ic->acc->set, "proxy"), "<auto>") != NULL)) { jd->have_streamhosts = 0; jabber_iq_query_server(ic, server, XMLNS_DISCO_ITEMS); } else if (jd->streamhosts != NULL) { jd->have_streamhosts = 1; } /* if we had to do a query, wait for the result. * Otherwise fire away. */ if (!tf->bud->features || jd->have_streamhosts != 1) { tf->disco_timeout = b_timeout_add(500, jabber_si_waitfor_disco, tf); } else { jabber_si_transfer_start(tf); } }
/** * Creates a new #SteamData with an #account_t. The returned #SteamData * should be freed with #steam_data_free() when no longer needed. * * @param acc The #account_t. * * @return The #SteamData or NULL on error. **/ SteamData *steam_data_new(account_t *acc) { SteamData *sata; g_return_val_if_fail(acc != NULL, NULL); sata = g_new0(SteamData, 1); sata->api = steam_api_new(); sata->ic = imcb_new(acc); sata->ic->proto_data = sata; sata->api->umqid = g_strdup(set_getstr(&acc->set, "umqid")); sata->api->token = g_strdup(set_getstr(&acc->set, "token")); sata->api->sessid = g_strdup(set_getstr(&acc->set, "sessid")); sata->game_status = set_getbool(&acc->set, "game_status"); steam_api_rehash(sata->api); return sata; }
static query_t *query_default( irc_t *irc ) { query_t *q; if( g_strcasecmp( set_getstr( &irc->set, "query_order" ), "fifo" ) == 0 ) q = irc->queries; else for( q = irc->queries; q && q->next; q = q->next ); return( q ); }
static struct groupchat *jabber_chat_join_( struct im_connection *ic, const char *room, const char *nick, const char *password, set_t **sets ) { if( strchr( room, '@' ) == NULL ) imcb_error( ic, "Invalid room name: %s", room ); else if( jabber_chat_by_jid( ic, room ) ) imcb_error( ic, "Already present in chat `%s'", room ); else return jabber_chat_join( ic, room, nick, set_getstr( sets, "password" ) ); return NULL; }
/* This generates an unfinished md5_state_t variable. Every time we generate an ID, we finish the state by adding a sequence number and take the hash. */ static void jabber_generate_id_hash( struct jabber_data *jd ) { md5_byte_t binbuf[4]; char *s; md5_init( &jd->cached_id_prefix ); md5_append( &jd->cached_id_prefix, (unsigned char *) jd->username, strlen( jd->username ) ); md5_append( &jd->cached_id_prefix, (unsigned char *) jd->server, strlen( jd->server ) ); s = set_getstr( &jd->ic->acc->set, "resource" ); md5_append( &jd->cached_id_prefix, (unsigned char *) s, strlen( s ) ); random_bytes( binbuf, 4 ); md5_append( &jd->cached_id_prefix, binbuf, 4 ); }
int set_getint( set_t **head, char *key ) { char *s = set_getstr( head, key ); int i = 0; if( !s ) return 0; if( sscanf( s, "%d", &i ) != 1 ) return 0; return i; }
static struct groupchat *jabber_chat_join_(struct im_connection *ic, const char *room, const char *nick, const char *password, set_t **sets) { struct jabber_data *jd = ic->proto_data; char *final_nick; /* Ignore the passed nick parameter if we have our own default */ if (!(final_nick = set_getstr(sets, "nick")) && !(final_nick = set_getstr(&ic->acc->set, "display_name"))) { /* Well, whatever, actually use the provided default, then */ final_nick = (char *) nick; } if (jd->flags & JFLAG_HIPCHAT && jd->muc_host && !g_str_has_suffix(room, jd->muc_host)) { char *guessed_name = hipchat_guess_channel_name(ic, room); if (guessed_name) { set_setstr(sets, "room", guessed_name); g_free(guessed_name); /* call this same function again with the fixed name */ return jabber_chat_join_(ic, set_getstr(sets, "room"), nick, password, sets); } } if (strchr(room, '@') == NULL) { imcb_error(ic, "%s is not a valid Jabber room name. Maybe you mean %s@conference.%s?", room, room, jd->server); } else if (jabber_chat_by_jid(ic, room)) { imcb_error(ic, "Already present in chat `%s'", room); } else { /* jabber_chat_join without the underscore is the conference.c one */ return jabber_chat_join(ic, room, final_nick, set_getstr(sets, "password")); } return NULL; }
static struct groupchat *jabber_chat_join_(struct im_connection *ic, const char *room, const char *nick, const char *password, set_t **sets) { struct jabber_data *jd = ic->proto_data; char *final_nick; /* Ignore the passed nick parameter if we have our own default */ if (!(final_nick = set_getstr(sets, "nick")) && !(final_nick = set_getstr(&ic->acc->set, "display_name"))) { /* Well, whatever, actually use the provided default, then */ final_nick = (char *) nick; } if (strchr(room, '@') == NULL) { imcb_error(ic, "%s is not a valid Jabber room name. Maybe you mean %s@conference.%s?", room, room, jd->server); } else if (jabber_chat_by_jid(ic, room)) { imcb_error(ic, "Already present in chat `%s'", room); } else { return jabber_chat_join(ic, room, final_nick, set_getstr(sets, "password")); } return NULL; }
static gboolean bee_irc_user_new( bee_t *bee, bee_user_t *bu ) { irc_user_t *iu; irc_t *irc = (irc_t*) bee->ui_data; char nick[MAX_NICK_LENGTH+1], *s; memset( nick, 0, MAX_NICK_LENGTH + 1 ); strcpy( nick, nick_get( bu ) ); bu->ui_data = iu = irc_user_new( irc, nick ); iu->bu = bu; if( set_getbool( &irc->b->set, "private" ) ) iu->last_channel = NULL; else iu->last_channel = irc_channel_with_user( irc, iu ); if( ( s = strchr( bu->handle, '@' ) ) ) { iu->host = g_strdup( s + 1 ); iu->user = g_strndup( bu->handle, s - bu->handle ); } else { iu->user = g_strdup( bu->handle ); if( bu->ic->acc->server ) iu->host = g_strdup( bu->ic->acc->server ); else iu->host = g_strdup( bu->ic->acc->prpl->name ); } while( ( s = strchr( iu->user, ' ' ) ) ) *s = '_'; if( bu->flags & BEE_USER_LOCAL ) { char *s = set_getstr( &bee->set, "handle_unknown" ); if( strcmp( s, "add_private" ) == 0 ) iu->last_channel = NULL; else if( strcmp( s, "add_channel" ) == 0 ) iu->last_channel = irc->default_channel; } iu->f = &irc_user_im_funcs; return TRUE; }
static void twitter_oauth_start(struct im_connection *ic) { struct twitter_data *td = ic->proto_data; const char *url = set_getstr(&ic->acc->set, "base_url"); imcb_log(ic, "Requesting OAuth request token"); if (!strstr(url, "twitter.com") && !strstr(url, "identi.ca")) imcb_log(ic, "Warning: OAuth only works with identi.ca and " "Twitter."); td->oauth_info = oauth_request_token(get_oauth_service(ic), twitter_oauth_callback, ic); /* We need help from the user to complete OAuth login, so don't time out on this login. */ ic->flags |= OPT_SLOW_LOGIN; }
char *irc_format_timestamp(irc_t *irc, time_t msg_ts) { time_t now_ts = time(NULL); struct tm now, msg; char *set; /* If the timestamp is <= 0 or less than a minute ago, discard it as it doesn't seem to add to much useful info and/or might be noise. */ if (msg_ts <= 0 || msg_ts > now_ts - 60) { return NULL; } set = set_getstr(&irc->b->set, "timezone"); if (strcmp(set, "local") == 0) { localtime_r(&now_ts, &now); localtime_r(&msg_ts, &msg); } else { int hr, min = 0, sign = 60; if (set[0] == '-') { sign *= -1; set++; } else if (set[0] == '+') { set++; } if (sscanf(set, "%d:%d", &hr, &min) >= 1) { msg_ts += sign * (hr * 60 + min); now_ts += sign * (hr * 60 + min); } gmtime_r(&now_ts, &now); gmtime_r(&msg_ts, &msg); } if (msg.tm_year == now.tm_year && msg.tm_yday == now.tm_yday) { return g_strdup_printf("\x02[\x02\x02\x02%02d:%02d:%02d\x02]\x02 ", msg.tm_hour, msg.tm_min, msg.tm_sec); } else { return g_strdup_printf("\x02[\x02\x02\x02%04d-%02d-%02d " "%02d:%02d:%02d\x02]\x02 ", msg.tm_year + 1900, msg.tm_mon + 1, msg.tm_mday, msg.tm_hour, msg.tm_min, msg.tm_sec); } }
static gboolean bee_irc_user_msg( bee_t *bee, bee_user_t *bu, const char *msg_, time_t sent_at ) { irc_t *irc = bee->ui_data; irc_user_t *iu = (irc_user_t *) bu->ui_data; const char *dst; char *prefix = NULL; char *wrapped, *ts = NULL; char *msg = g_strdup( msg_ ); GSList *l; if( sent_at > 0 && set_getbool( &irc->b->set, "display_timestamps" ) ) ts = irc_format_timestamp( irc, sent_at ); dst = irc_user_msgdest( iu ); if( dst != irc->user->nick ) { /* if not messaging directly, call user by name */ prefix = g_strdup_printf( "%s%s%s", irc->user->nick, set_getstr( &bee->set, "to_char" ), ts ? : "" ); }
static void omegle_add_permit(struct im_connection *ic, char *who) { struct bee_user *bu = bee_user_by_handle(ic->bee, ic, who); struct omegle_buddy_data *bd = bu->data; account_t *acc = ic->acc; char *host = set_getstr(&acc->set, "host"); if (bd->connecting || bd->session_id) return; bd->connecting = TRUE; if (host) { omegle_normal_start_convo(ic, who, g_strdup(host)); } else { omegle_get(bu, "omegle.com", "/status", omegle_normal_chose_server); } }
static void cmd_showset(irc_t *irc, set_t **head, char *key) { set_t *set; char *val; if ((val = set_getstr(head, key))) { irc_rootmsg(irc, "%s = `%s'", key, val); } else if (!(set = set_find(head, key))) { irc_rootmsg(irc, "Setting `%s' does not exist.", key); if (*head == irc->b->set) { irc_rootmsg(irc, "It might be an account or channel setting. " "See \x02help account set\x02 and \x02help channel set\x02."); } } else if (set->flags & SET_PASSWORD) { irc_rootmsg(irc, "%s = `********' (hidden)", key); } else { irc_rootmsg(irc, "%s is empty", key); } }
/** * Add a buddy if it is not already added, set the status to logged in. */ static void twitter_add_buddy(struct im_connection *ic, char *name, const char *fullname) { struct twitter_data *td = ic->proto_data; // Check if the buddy is already in the buddy list. if (!bee_user_by_handle(ic->bee, ic, name)) { char *mode = set_getstr(&ic->acc->set, "mode"); // The buddy is not in the list, add the buddy and set the status to logged in. imcb_add_buddy(ic, name, NULL); imcb_rename_buddy(ic, name, fullname); if (g_strcasecmp(mode, "chat") == 0) { /* Necessary so that nicks always get translated to the exact Twitter username. */ imcb_buddy_nick_hint(ic, name, name); imcb_chat_add_buddy(td->timeline_gc, name); } else if (g_strcasecmp(mode, "many") == 0) imcb_buddy_status(ic, name, OPT_LOGGED_IN, NULL, NULL); } }
static void skype_parse_chatmessage_said_emoted(struct im_connection *ic, struct groupchat *gc, char *body) { struct skype_data *sd = ic->proto_data; char buf[IRC_LINE_SIZE]; if (!strcmp(sd->type, "SAID")) { if (!sd->is_edit) g_snprintf(buf, IRC_LINE_SIZE, "%s", body); else { g_snprintf(buf, IRC_LINE_SIZE, "%s %s", set_getstr(&ic->acc->set, "edit_prefix"), body); sd->is_edit = 0; } } else g_snprintf(buf, IRC_LINE_SIZE, "/me %s", body); if (!gc) /* Private message */ imcb_buddy_msg(ic, sd->handle, buf, 0, 0); else /* Groupchat message */ imcb_chat_msg(gc, sd->handle, buf, 0, 0); }
/* Whenever presence information is updated, call this function to inform the server. */ int presence_send_update( struct im_connection *ic ) { struct jabber_data *jd = ic->proto_data; struct xt_node *node, *cap; char *show = jd->away_state->code; char *status = jd->away_message; struct groupchat *c; int st; node = jabber_make_packet( "presence", NULL, NULL, NULL ); xt_add_child( node, xt_new_node( "priority", set_getstr( &ic->acc->set, "priority" ), NULL ) ); if( show && *show ) xt_add_child( node, xt_new_node( "show", show, NULL ) ); if( status ) xt_add_child( node, xt_new_node( "status", status, NULL ) ); /* This makes the packet slightly bigger, but clients interested in capabilities can now cache the discovery info. This reduces the usual post-login iq-flood. See XEP-0115. At least libpurple and Trillian seem to do this right. */ cap = xt_new_node( "c", NULL, NULL ); xt_add_attr( cap, "xmlns", XMLNS_CAPS ); xt_add_attr( cap, "node", "http://bitlbee.org/xmpp/caps" ); xt_add_attr( cap, "ver", BITLBEE_VERSION ); /* The XEP wants this hashed, but nobody's doing that. */ xt_add_child( node, cap ); st = jabber_write_packet( ic, node ); /* Have to send this update to all groupchats too, the server won't do this automatically. */ for( c = ic->groupchats; c && st; c = c->next ) { struct jabber_chat *jc = c->data; xt_add_attr( node, "to", jc->my_full_jid ); st = jabber_write_packet( ic, node ); } xt_free_node( node ); return st; }
static void purple_sync_settings( account_t *acc, PurpleAccount *pa ) { PurplePlugin *prpl = purple_plugins_find_with_id( pa->protocol_id ); PurplePluginProtocolInfo *pi = prpl->info->extra_info; GList *i; for( i = pi->protocol_options; i; i = i->next ) { PurpleAccountOption *o = i->data; const char *name; set_t *s; name = purple_account_option_get_setting( o ); s = set_find( &acc->set, name ); if( s->value == NULL ) continue; switch( purple_account_option_get_type( o ) ) { case PURPLE_PREF_STRING: case PURPLE_PREF_STRING_LIST: purple_account_set_string( pa, name, set_getstr( &acc->set, name ) ); break; case PURPLE_PREF_INT: purple_account_set_int( pa, name, set_getint( &acc->set, name ) ); break; case PURPLE_PREF_BOOLEAN: purple_account_set_bool( pa, name, set_getbool( &acc->set, name ) ); break; default: break; } } if( pi->options & OPT_PROTO_MAIL_CHECK ) purple_account_set_check_mail( pa, set_getbool( &acc->set, "mail_notifications" ) ); }