void* prplcb_request_input(const char *title, const char *primary, const char *secondary, const char *default_value, gboolean multiline, gboolean masked, gchar *hint, const char *ok_text, GCallback ok_cb, const char *cancel_text, GCallback cancel_cb, PurpleAccount *account, const char *who, PurpleConversation *conv, void *user_data) { struct im_connection *ic = purple_ic_by_pa(account); struct purple_data *pd = ic->proto_data; struct request_input_data *ri = g_new0(struct request_input_data, 1); guint id = pd->next_request_id++; ri->id = id; ri->ic = ic; ri->buddy = g_strdup_printf("%s_%u", PURPLE_REQUEST_HANDLE, id); ri->data_callback = (ri_callback_t) ok_cb; ri->user_data = user_data; g_hash_table_insert(pd->input_requests, GUINT_TO_POINTER(id), ri); imcb_add_buddy(ic, ri->buddy, NULL); if (title && *title) { imcb_buddy_msg(ic, ri->buddy, title, 0, 0); } if (primary && *primary) { imcb_buddy_msg(ic, ri->buddy, primary, 0, 0); } if (secondary && *secondary) { imcb_buddy_msg(ic, ri->buddy, secondary, 0, 0); } return ri; }
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); } }
static void prplcb_blist_update( PurpleBuddyList *list, PurpleBlistNode *node ) { if( node->type == PURPLE_BLIST_BUDDY_NODE ) { PurpleBuddy *bud = (PurpleBuddy*) node; PurpleGroup *group = purple_buddy_get_group( bud ); struct im_connection *ic = purple_ic_by_pa( bud->account ); PurpleStatus *as; int flags = 0; if( ic == NULL ) return; if( bud->server_alias ) imcb_rename_buddy( ic, bud->name, bud->server_alias ); else if( bud->alias ) imcb_rename_buddy( ic, bud->name, bud->alias ); if( group ) imcb_add_buddy( ic, bud->name, purple_group_get_name( group ) ); flags |= purple_presence_is_online( bud->presence ) ? OPT_LOGGED_IN : 0; flags |= purple_presence_is_available( bud->presence ) ? 0 : OPT_AWAY; as = purple_presence_get_active_status( bud->presence ); imcb_buddy_status( ic, bud->name, flags, purple_status_get_name( as ), purple_status_get_attr_string( as, "message" ) ); imcb_buddy_times( ic, bud->name, purple_presence_get_login_time( bud->presence ), purple_presence_get_idle_time( bud->presence ) ); } }
static void steam_cb_friends(SteamApiReq *req, gpointer data) { bee_user_t *bu; gchar sid[STEAM_ID_STRMAX]; GList *l; SteamData *sata = data; SteamUser *user; SteamUserInfo *info; struct im_connection *ic = sata->ic; if (steam_req_error(sata, req, TRUE)) { return; } if (!(ic->flags & BEE_USER_ONLINE)) { imcb_connected(ic); } for (l = req->infs->head; l != NULL; l = l->next) { info = l->data; STEAM_ID_STR(info->id, sid); /* Attempt to grab the buddy before adding */ bu = bee_user_by_handle(sata->ic->bee, sata->ic, sid); if (bu == NULL) { imcb_add_buddy(sata->ic, sid, NULL); imcb_buddy_nick_hint(sata->ic, sid, info->nick); imcb_rename_buddy(sata->ic, sid, info->fullname); } bu = bee_user_by_handle(sata->ic->bee, sata->ic, sid); if (G_UNLIKELY(bu == NULL)) { continue; } user = bu->data; user->vtime = info->vtime; switch (info->rel) { case STEAM_USER_REL_FRIEND: steam_user_status(sata, info, bu); break; case STEAM_USER_REL_IGNORE: ic->deny = g_slist_prepend(ic->deny, g_strdup(bu->handle)); break; } if (info->unread > 0) { req = steam_api_req_new(req->api, steam_cb_msgs, sata); steam_api_req_msgs(req, info->id, info->vtime); } } req = steam_api_req_new(req->api, steam_cb_poll, sata); steam_api_req_poll(req); }
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); } }
/* Update the group of each user in this group */ static void skype_group_users(struct im_connection *ic, struct skype_group *sg) { int i; for (i = 0; i < g_list_length(sg->users); i++) { char *user = g_list_nth_data(sg->users, i); char *buf = g_strdup_printf("*****@*****.**", user); imcb_add_buddy(ic, buf, sg->name); g_free(buf); } }
static void jabber_add_buddy( struct im_connection *ic, char *who, char *group ) { struct jabber_data *jd = ic->proto_data; if( g_strcasecmp( who, JABBER_XMLCONSOLE_HANDLE ) == 0 ) { jd->flags |= JFLAG_XMLCONSOLE; imcb_add_buddy( ic, JABBER_XMLCONSOLE_HANDLE, NULL ); return; } if( jabber_add_to_roster( ic, who, NULL, group ) ) presence_send_request( ic, who, "subscribe" ); }
static void prplcb_blist_new( PurpleBlistNode *node ) { if( node->type == PURPLE_BLIST_BUDDY_NODE ) { PurpleBuddy *bud = (PurpleBuddy*) node; struct im_connection *ic = purple_ic_by_pa( bud->account ); if( ic == NULL ) return; imcb_add_buddy( ic, bud->name, NULL ); prplcb_blist_update( NULL, node ); } }
void sasl_oauth2_init( struct im_connection *ic ) { struct jabber_data *jd = ic->proto_data; char *msg, *url; imcb_log( ic, "Starting OAuth authentication" ); /* Temporary contact, just used to receive the OAuth response. */ imcb_add_buddy( ic, JABBER_OAUTH_HANDLE, NULL ); url = oauth2_url( jd->oauth2_service ); msg = g_strdup_printf( "Open this URL in your browser to authenticate: %s", url ); imcb_buddy_msg( ic, JABBER_OAUTH_HANDLE, msg, 0, 0 ); imcb_buddy_msg( ic, JABBER_OAUTH_HANDLE, "Respond to this message with the returned " "authorization token.", 0, 0 ); g_free( msg ); g_free( url ); }
static xt_status jabber_parse_roster( struct im_connection *ic, struct xt_node *node, struct xt_node *orig ) { struct xt_node *query, *c; int initial = ( orig != NULL ); if( !( query = xt_find_node( node->children, "query" ) ) ) { imcb_log( ic, "Warning: Received NULL roster packet" ); return XT_HANDLED; } c = query->children; while( ( c = xt_find_node( c, "item" ) ) ) { struct xt_node *group = xt_find_node( c->children, "group" ); char *jid = xt_find_attr( c, "jid" ); char *name = xt_find_attr( c, "name" ); char *sub = xt_find_attr( c, "subscription" ); if( jid && sub ) { if( ( strcmp( sub, "both" ) == 0 || strcmp( sub, "to" ) == 0 ) ) { imcb_add_buddy( ic, jid, ( group && group->text_len ) ? group->text : NULL ); if( name ) imcb_rename_buddy( ic, jid, name ); } else if( strcmp( sub, "remove" ) == 0 ) { jabber_buddy_remove_bare( ic, jid ); imcb_remove_buddy( ic, jid, NULL ); } } c = c->next; } if( initial ) imcb_connected( ic ); return XT_HANDLED; }
/** * 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 xt_status jabber_add_to_roster_callback( struct im_connection *ic, struct xt_node *node, struct xt_node *orig ) { char *s, *jid = NULL; struct xt_node *c; if( ( c = xt_find_node( orig->children, "query" ) ) && ( c = xt_find_node( c->children, "item" ) ) && ( jid = xt_find_attr( c, "jid" ) ) && ( s = xt_find_attr( node, "type" ) ) && strcmp( s, "result" ) == 0 ) { if( bee_user_by_handle( ic->bee, ic, jid ) == NULL ) imcb_add_buddy( ic, jid, NULL ); } else { imcb_log( ic, "Error while adding `%s' to your contact list.", jid ? jid : "(unknown handle)" ); } return XT_HANDLED; }
/* Not really the same syntax as the normal pkt_ functions, but this isn't called by the xmltree parser directly and this way I can add some extra parameters so we won't have to repeat too many things done by the caller already. */ void jabber_chat_pkt_presence(struct im_connection *ic, struct jabber_buddy *bud, struct xt_node *node) { struct groupchat *chat; struct xt_node *c; char *type = xt_find_attr(node, "type"); struct jabber_data *jd = ic->proto_data; struct jabber_chat *jc; char *s; if ((chat = jabber_chat_by_jid(ic, bud->bare_jid)) == NULL) { /* How could this happen?? We could do kill( self, 11 ) now or just wait for the OS to do it. :-) */ return; } jc = chat->data; if (type == NULL && !(bud->flags & JBFLAG_IS_CHATROOM)) { bud->flags |= JBFLAG_IS_CHATROOM; /* If this one wasn't set yet, this buddy just joined the chat. Slightly hackish way of finding out eh? ;-) */ /* This is pretty messy... Here it sets ext_jid to the real JID of the participant. Works for non-anonymized channels. Might break if someone joins a chat twice, though. */ for (c = node->children; (c = xt_find_node(c, "x")); c = c->next) { if ((s = xt_find_attr(c, "xmlns")) && (strcmp(s, XMLNS_MUC_USER) == 0)) { struct xt_node *item; item = xt_find_node(c->children, "item"); if ((s = xt_find_attr(item, "jid"))) { /* Yay, found what we need. :-) */ bud->ext_jid = jabber_normalize(s); break; } } } /* Make up some other handle, if necessary. */ if (bud->ext_jid == NULL) { if (bud == jc->me) { bud->ext_jid = g_strdup(jd->me); } else { int i; /* Don't want the nick to be at the end, so let's think of some slightly different notation to use for anonymous groupchat participants in BitlBee. */ bud->ext_jid = g_strdup_printf("%s=%s", bud->resource, bud->bare_jid); /* And strip any unwanted characters. */ for (i = 0; bud->resource[i]; i++) { if (bud->ext_jid[i] == '=' || bud->ext_jid[i] == '@') { bud->ext_jid[i] = '_'; } } /* Some program-specific restrictions. */ imcb_clean_handle(ic, bud->ext_jid); } bud->flags |= JBFLAG_IS_ANONYMOUS; } if (bud != jc->me && bud->flags & JBFLAG_IS_ANONYMOUS) { /* If JIDs are anonymized, add them to the local list for the duration of this chat. */ imcb_add_buddy(ic, bud->ext_jid, NULL); imcb_buddy_nick_hint(ic, bud->ext_jid, bud->resource); } if (bud == jc->me && jc->invite != NULL) { char *msg = g_strdup_printf("Please join me in room %s", jc->name); jabber_chat_invite(chat, jc->invite, msg); g_free(jc->invite); g_free(msg); jc->invite = NULL; } s = strchr(bud->ext_jid, '/'); if (s) { *s = 0; /* Should NEVER be NULL, but who knows... */ } imcb_chat_add_buddy(chat, bud->ext_jid); if (s) { *s = '/'; } } else if (type) { /* type can only be NULL or "unavailable" in this function */ if ((bud->flags & JBFLAG_IS_CHATROOM) && bud->ext_jid) { char *reason = NULL; char *status = NULL; char *status_text = NULL; if ((c = xt_find_node_by_attr(node->children, "x", "xmlns", XMLNS_MUC_USER))) { struct xt_node *c2 = c->children; while ((c2 = xt_find_node(c2, "status"))) { char *code = xt_find_attr(c2, "code"); if (g_strcmp0(code, "301") == 0) { status = "Banned"; break; } else if (g_strcmp0(code, "303") == 0) { /* This could be handled in a cleverer way, * but let's just show a literal part/join for now */ status = "Changing nicks"; break; } else if (g_strcmp0(code, "307") == 0) { status = "Kicked"; break; } c2 = c2->next; } /* Sometimes the status message is in presence/x/item/reason */ if ((c2 = xt_find_path(c, "item/reason")) && c2->text && c2->text_len) { status_text = c2->text; } } /* Sometimes the status message is right inside <presence> */ if ((c = xt_find_node(node->children, "status")) && c->text && c->text_len) { status_text = c->text; } if (status_text && status) { reason = g_strdup_printf("%s: %s", status, status_text); } else { reason = g_strdup(status_text ? : status); } s = strchr(bud->ext_jid, '/'); if (s) { *s = 0; } imcb_chat_remove_buddy(chat, bud->ext_jid, reason); if (bud != jc->me && bud->flags & JBFLAG_IS_ANONYMOUS) { imcb_remove_buddy(ic, bud->ext_jid, reason); } if (s) { *s = '/'; } g_free(reason); } if (bud == jc->me) { jabber_chat_free(chat); } }
/** * Login method. Since the twitter API works with separate HTTP request we * only save the user and pass to the twitter_data object. */ static void twitter_login(account_t * acc) { struct im_connection *ic = imcb_new(acc); struct twitter_data *td; char name[strlen(acc->user) + 9]; url_t url; char *s; if (!url_set(&url, set_getstr(&ic->acc->set, "base_url")) || (url.proto != PROTO_HTTP && url.proto != PROTO_HTTPS)) { imcb_error(ic, "Incorrect API base URL: %s", set_getstr(&ic->acc->set, "base_url")); imc_logout(ic, FALSE); return; } if (!strstr(url.host, "twitter.com") && set_getbool(&ic->acc->set, "stream")) { imcb_error(ic, "Warning: The streaming API is only supported by Twitter, " "and you seem to be connecting to a different service."); } imcb_log(ic, "Connecting"); twitter_connections = g_slist_append(twitter_connections, ic); td = g_new0(struct twitter_data, 1); ic->proto_data = td; td->user = g_strdup(acc->user); td->url_ssl = url.proto == PROTO_HTTPS; td->url_port = url.port; td->url_host = g_strdup(url.host); if (strcmp(url.file, "/") != 0) td->url_path = g_strdup(url.file); else { td->url_path = g_strdup(""); if (g_str_has_suffix(url.host, "twitter.com")) /* May fire for people who turned on HTTPS. */ imcb_error(ic, "Warning: Twitter requires a version number in API calls " "now. Try resetting the base_url account setting."); } /* Hacky string mangling: Turn identi.ca into identi.ca and api.twitter.com into twitter, and try to be sensible if we get anything else. */ td->prefix = g_strdup(url.host); if (g_str_has_suffix(td->prefix, ".com")) td->prefix[strlen(url.host) - 4] = '\0'; if ((s = strrchr(td->prefix, '.')) && strlen(s) > 4) { /* If we have at least 3 chars after the last dot, cut off the rest. (mostly a www/api prefix or sth) */ s = g_strdup(s + 1); g_free(td->prefix); td->prefix = s; } if (strstr(acc->pass, "oauth_token=")) td->oauth_info = oauth_from_string(acc->pass, get_oauth_service(ic)); sprintf(name, "%s_%s", td->prefix, acc->user); imcb_add_buddy(ic, name, NULL); imcb_buddy_status(ic, name, OPT_LOGGED_IN, NULL, NULL); td->log = g_new0(struct twitter_log_data, TWITTER_LOG_LENGTH); td->log_id = -1; s = set_getstr(&ic->acc->set, "mode"); if (g_strcasecmp(s, "one") == 0) td->flags |= TWITTER_MODE_ONE; else if (g_strcasecmp(s, "many") == 0) td->flags |= TWITTER_MODE_MANY; else td->flags |= TWITTER_MODE_CHAT; twitter_login_finish(ic); }
static void skype_parse_user(struct im_connection *ic, char *line) { int flags = 0; char *ptr; struct skype_data *sd = ic->proto_data; char *user = strchr(line, ' '); char *status = strrchr(line, ' '); status++; ptr = strchr(++user, ' '); if (!ptr) return; *ptr = '\0'; ptr++; if (!strncmp(ptr, "ONLINESTATUS ", 13)) { if (!strlen(user) || !strcmp(user, sd->username)) return; if (!set_getbool(&ic->acc->set, "test_join") && !strcmp(user, "echo123")) return; ptr = g_strdup_printf("*****@*****.**", user); imcb_add_buddy(ic, ptr, skype_group_by_username(ic, user)); if (strcmp(status, "OFFLINE") && (strcmp(status, "SKYPEOUT") || !set_getbool(&ic->acc->set, "skypeout_offline"))) flags |= OPT_LOGGED_IN; if (strcmp(status, "ONLINE") && strcmp(status, "SKYPEME")) flags |= OPT_AWAY; imcb_buddy_status(ic, ptr, flags, NULL, NULL); g_free(ptr); } else if (!strncmp(ptr, "RECEIVEDAUTHREQUEST ", 20)) { char *message = ptr + 20; if (strlen(message)) skype_buddy_ask(ic, user, message); } else if (!strncmp(ptr, "BUDDYSTATUS ", 12)) { char *st = ptr + 12; if (!strcmp(st, "3")) { char *buf = g_strdup_printf("*****@*****.**", user); imcb_add_buddy(ic, buf, skype_group_by_username(ic, user)); g_free(buf); } } else if (!strncmp(ptr, "MOOD_TEXT ", 10)) { char *buf = g_strdup_printf("*****@*****.**", user); bee_user_t *bu = bee_user_by_handle(ic->bee, ic, buf); g_free(buf); buf = ptr + 10; if (bu) imcb_buddy_status(ic, bu->handle, bu->flags, NULL, *buf ? buf : NULL); if (set_getbool(&ic->acc->set, "show_moods")) imcb_log(ic, "User `%s' changed mood text to `%s'", user, buf); } else if (!strncmp(ptr, "FULLNAME ", 9)) { char *name = ptr + 9; if (sd->is_info) { sd->is_info = FALSE; sd->info_fullname = g_strdup(name); } else { char *buf = g_strdup_printf("*****@*****.**", user); imcb_rename_buddy(ic, buf, name); g_free(buf); } } else if (!strncmp(ptr, "PHONE_HOME ", 11)) sd->info_phonehome = g_strdup(ptr + 11); else if (!strncmp(ptr, "PHONE_OFFICE ", 13)) sd->info_phoneoffice = g_strdup(ptr + 13); else if (!strncmp(ptr, "PHONE_MOBILE ", 13)) sd->info_phonemobile = g_strdup(ptr + 13); else if (!strncmp(ptr, "NROF_AUTHED_BUDDIES ", 20)) sd->info_nrbuddies = g_strdup(ptr + 20); else if (!strncmp(ptr, "TIMEZONE ", 9)) sd->info_tz = g_strdup(ptr + 9); else if (!strncmp(ptr, "LASTONLINETIMESTAMP ", 20)) sd->info_seen = g_strdup(ptr + 20); else if (!strncmp(ptr, "SEX ", 4)) sd->info_sex = g_strdup(ptr + 4); else if (!strncmp(ptr, "LANGUAGE ", 9)) sd->info_language = g_strdup(ptr + 9); else if (!strncmp(ptr, "COUNTRY ", 8)) sd->info_country = g_strdup(ptr + 8); else if (!strncmp(ptr, "PROVINCE ", 9)) sd->info_province = g_strdup(ptr + 9); else if (!strncmp(ptr, "CITY ", 5)) sd->info_city = g_strdup(ptr + 5); else if (!strncmp(ptr, "HOMEPAGE ", 9)) sd->info_homepage = g_strdup(ptr + 9); else if (!strncmp(ptr, "ABOUT ", 6)) { /* Support multiple about lines. */ if (!sd->info_about) sd->info_about = g_strdup(ptr + 6); else { GString *st = g_string_new(sd->info_about); g_string_append_printf(st, "\n%s", ptr + 6); g_free(sd->info_about); sd->info_about = g_strdup(st->str); g_string_free(st, TRUE); } } else if (!strncmp(ptr, "BIRTHDAY ", 9)) { sd->info_birthday = g_strdup(ptr + 9); GString *st = g_string_new("Contact Information\n"); g_string_append_printf(st, "Skype Name: %s\n", user); if (sd->info_fullname) { if (strlen(sd->info_fullname)) g_string_append_printf(st, "Full Name: %s\n", sd->info_fullname); g_free(sd->info_fullname); sd->info_fullname = NULL; } if (sd->info_phonehome) { if (strlen(sd->info_phonehome)) g_string_append_printf(st, "Home Phone: %s\n", sd->info_phonehome); g_free(sd->info_phonehome); sd->info_phonehome = NULL; } if (sd->info_phoneoffice) { if (strlen(sd->info_phoneoffice)) g_string_append_printf(st, "Office Phone: %s\n", sd->info_phoneoffice); g_free(sd->info_phoneoffice); sd->info_phoneoffice = NULL; } if (sd->info_phonemobile) { if (strlen(sd->info_phonemobile)) g_string_append_printf(st, "Mobile Phone: %s\n", sd->info_phonemobile); g_free(sd->info_phonemobile); sd->info_phonemobile = NULL; } g_string_append_printf(st, "Personal Information\n"); if (sd->info_nrbuddies) { if (strlen(sd->info_nrbuddies)) g_string_append_printf(st, "Contacts: %s\n", sd->info_nrbuddies); g_free(sd->info_nrbuddies); sd->info_nrbuddies = NULL; } if (sd->info_tz) { if (strlen(sd->info_tz)) { char ib[256]; time_t t = time(NULL); t += atoi(sd->info_tz)-(60*60*24); struct tm *gt = gmtime(&t); strftime(ib, 256, "%H:%M:%S", gt); g_string_append_printf(st, "Local Time: %s\n", ib); } g_free(sd->info_tz); sd->info_tz = NULL; } if (sd->info_seen) { if (strlen(sd->info_seen)) { char ib[256]; time_t it = atoi(sd->info_seen); struct tm *tm = localtime(&it); strftime(ib, 256, ("%Y. %m. %d. %H:%M"), tm); g_string_append_printf(st, "Last Seen: %s\n", ib); } g_free(sd->info_seen); sd->info_seen = NULL; } if (sd->info_birthday) { if (strlen(sd->info_birthday) && strcmp(sd->info_birthday, "0")) { char ib[256]; struct tm tm; strptime(sd->info_birthday, "%Y%m%d", &tm); strftime(ib, 256, "%B %d, %Y", &tm); g_string_append_printf(st, "Birthday: %s\n", ib); strftime(ib, 256, "%Y", &tm); int year = atoi(ib); time_t t = time(NULL); struct tm *lt = localtime(&t); g_string_append_printf(st, "Age: %d\n", lt->tm_year+1900-year); } g_free(sd->info_birthday); sd->info_birthday = NULL; } if (sd->info_sex) { if (strlen(sd->info_sex)) { char *iptr = sd->info_sex; while (*iptr++) *iptr = tolower(*iptr); g_string_append_printf(st, "Gender: %s\n", sd->info_sex); } g_free(sd->info_sex); sd->info_sex = NULL; } if (sd->info_language) { if (strlen(sd->info_language)) { char *iptr = strchr(sd->info_language, ' '); if (iptr) iptr++; else iptr = sd->info_language; g_string_append_printf(st, "Language: %s\n", iptr); } g_free(sd->info_language); sd->info_language = NULL; } if (sd->info_country) { if (strlen(sd->info_country)) { char *iptr = strchr(sd->info_country, ' '); if (iptr) iptr++; else iptr = sd->info_country; g_string_append_printf(st, "Country: %s\n", iptr); } g_free(sd->info_country); sd->info_country = NULL; } if (sd->info_province) { if (strlen(sd->info_province)) g_string_append_printf(st, "Region: %s\n", sd->info_province); g_free(sd->info_province); sd->info_province = NULL; } if (sd->info_city) { if (strlen(sd->info_city)) g_string_append_printf(st, "City: %s\n", sd->info_city); g_free(sd->info_city); sd->info_city = NULL; } if (sd->info_homepage) { if (strlen(sd->info_homepage)) g_string_append_printf(st, "Homepage: %s\n", sd->info_homepage); g_free(sd->info_homepage); sd->info_homepage = NULL; } if (sd->info_about) { if (strlen(sd->info_about)) g_string_append_printf(st, "%s\n", sd->info_about); g_free(sd->info_about); sd->info_about = NULL; } imcb_log(ic, "%s", st->str); g_string_free(st, TRUE); } }
/** * Processes a #SteamApiMsg. * * @param sata The #SteamData. * @param msg The #SteamUserMsg. * @param time The timestamp (UTC) of the message, or 0 for now. **/ static void steam_user_msg(SteamData *sata, SteamUserMsg *msg, gint64 time) { SteamUserInfo *info = msg->info; bee_user_t *bu; gchar *str; guint32 f; gchar sid[STEAM_ID_STR_MAX]; STEAM_ID_STR(info->id, sid); STEAM_UTIL_DEBUGLN("Incoming message from %s (Type: %u, Act: %u)", sid, msg->type, info->act); switch (msg->type) { case STEAM_USER_MSG_TYPE_EMOTE: case STEAM_USER_MSG_TYPE_SAYTEXT: bu = imcb_buddy_by_handle(sata->ic, sid); if ((bu != NULL) && (bu->flags & OPT_TYPING)) imcb_buddy_typing(sata->ic, sid, 0); if (msg->type == STEAM_USER_MSG_TYPE_EMOTE) str = g_strconcat("/me ", msg->text, NULL); else str = g_strdup(msg->text); imcb_buddy_msg(sata->ic, sid, str, 0, time); g_free(str); return; case STEAM_USER_MSG_TYPE_LEFT_CONV: imcb_buddy_typing(sata->ic, sid, 0); return; case STEAM_USER_MSG_TYPE_RELATIONSHIP: goto relationship; case STEAM_USER_MSG_TYPE_TYPING: bu = imcb_buddy_by_handle(sata->ic, sid); if (G_UNLIKELY(bu == NULL)) return; f = (bu->flags & OPT_TYPING) ? 0 : OPT_TYPING; imcb_buddy_typing(sata->ic, sid, f); return; default: steam_user_status(sata, info, NULL); return; } relationship: switch (info->act) { case STEAM_USER_ACT_REMOVE: case STEAM_USER_ACT_IGNORE: imcb_remove_buddy(sata->ic, sid, NULL); return; case STEAM_USER_ACT_REQUEST: imcb_ask_auth(sata->ic, sid, info->nick); return; case STEAM_USER_ACT_ADD: imcb_add_buddy(sata->ic, sid, NULL); imcb_buddy_nick_hint(sata->ic, sid, info->nick); imcb_rename_buddy(sata->ic, sid, info->fullname); steam_user_status(sata, info, NULL); return; default: return; } }
/* Separate this from jabber_login() so we can do OAuth first if necessary. Putting this in io.c would probably be more correct. */ void jabber_connect( struct im_connection *ic ) { account_t *acc = ic->acc; struct jabber_data *jd = ic->proto_data; int i; char *connect_to; struct ns_srv_reply **srvl = NULL, *srv = NULL; /* Figure out the hostname to connect to. */ if( acc->server && *acc->server ) connect_to = acc->server; else if( ( srvl = srv_lookup( "xmpp-client", "tcp", jd->server ) ) || ( srvl = srv_lookup( "jabber-client", "tcp", jd->server ) ) ) { /* Find the lowest-priority one. These usually come back in random/shuffled order. Not looking at weights etc for now. */ srv = *srvl; for( i = 1; srvl[i]; i ++ ) if( srvl[i]->prio < srv->prio ) srv = srvl[i]; connect_to = srv->name; } else connect_to = jd->server; imcb_log( ic, "Connecting" ); for( i = 0; jabber_port_list[i] > 0; i ++ ) if( set_getint( &acc->set, "port" ) == jabber_port_list[i] ) break; if( jabber_port_list[i] == 0 ) { imcb_log( ic, "Illegal port number" ); imc_logout( ic, FALSE ); return; } /* For non-SSL connections we can try to use the port # from the SRV reply, but let's not do that when using SSL, SSL usually runs on non-standard ports... */ if( set_getbool( &acc->set, "ssl" ) ) { jd->ssl = ssl_connect( connect_to, set_getint( &acc->set, "port" ), FALSE, jabber_connected_ssl, ic ); jd->fd = jd->ssl ? ssl_getfd( jd->ssl ) : -1; } else { jd->fd = proxy_connect( connect_to, srv ? srv->port : set_getint( &acc->set, "port" ), jabber_connected_plain, ic ); } srv_free( srvl ); if( jd->fd == -1 ) { imcb_error( ic, "Could not connect to server" ); imc_logout( ic, TRUE ); return; } if( set_getbool( &acc->set, "xmlconsole" ) ) { jd->flags |= JFLAG_XMLCONSOLE; /* Shouldn't really do this at this stage already, maybe. But I think this shouldn't break anything. */ imcb_add_buddy( ic, JABBER_XMLCONSOLE_HANDLE, NULL ); } jabber_generate_id_hash( jd ); }
/* Separate this from jabber_login() so we can do OAuth first if necessary. Putting this in io.c would probably be more correct. */ void jabber_connect(struct im_connection *ic) { account_t *acc = ic->acc; struct jabber_data *jd = ic->proto_data; int i; char *connect_to; struct ns_srv_reply **srvl = NULL, *srv = NULL; /* Figure out the hostname to connect to. */ if (acc->server && *acc->server) { connect_to = acc->server; } else if ((srvl = srv_lookup("xmpp-client", "tcp", jd->server)) || (srvl = srv_lookup("jabber-client", "tcp", jd->server))) { /* Find the lowest-priority one. These usually come back in random/shuffled order. Not looking at weights etc for now. */ srv = *srvl; for (i = 1; srvl[i]; i++) { if (srvl[i]->prio < srv->prio) { srv = srvl[i]; } } connect_to = srv->name; } else { connect_to = jd->server; } imcb_log(ic, "Connecting"); for (i = 0; jabber_port_list[i] > 0; i++) { if (set_getint(&acc->set, "port") == jabber_port_list[i]) { break; } } if (jabber_port_list[i] == 0) { imcb_log(ic, "Illegal port number"); imc_logout(ic, FALSE); return; } /* For non-SSL connections we can try to use the port # from the SRV reply, but let's not do that when using SSL, SSL usually runs on non-standard ports... */ if (set_getbool(&acc->set, "ssl")) { jd->ssl = ssl_connect(connect_to, set_getint(&acc->set, "port"), set_getbool(&acc->set, "tls_verify"), jabber_connected_ssl, ic); jd->fd = jd->ssl ? ssl_getfd(jd->ssl) : -1; } else { jd->fd = proxy_connect(connect_to, srv ? srv->port : set_getint(&acc->set, "port"), jabber_connected_plain, ic); } srv_free(srvl); if (jd->fd == -1) { imcb_error(ic, "Could not connect to server"); imc_logout(ic, TRUE); return; } if (set_getbool(&acc->set, "xmlconsole")) { jabber_xmlconsole_enable(ic); } if (set_getbool(&acc->set, "mail_notifications")) { /* It's gmail specific, but it checks for server support before enabling it */ jd->flags |= JFLAG_GMAILNOTIFY; if (set_getstr(&acc->set, "mail_notifications_handle")) { imcb_add_buddy(ic, set_getstr(&acc->set, "mail_notifications_handle"), NULL); } } jabber_generate_id_hash(jd); }