예제 #1
0
void
handle_incoming_message(char *from, char *message, gboolean priv)
{
#ifdef HAVE_LIBOTR
    gboolean was_decrypted = FALSE;
    char *newmessage;
    if (!priv) {
        newmessage = otr_decrypt_message(from, message, &was_decrypted);

        // internal OTR message
        if (newmessage == NULL) {
            return;
        }
    } else {
        newmessage = message;
    }

    ui_incoming_msg(from, newmessage, NULL, priv);
    ui_current_page_off();

    if (prefs_get_boolean(PREF_CHLOG) && !priv) {
        Jid *from_jid = jid_create(from);
        const char *jid = jabber_get_fulljid();
        Jid *jidp = jid_create(jid);

        if (!was_decrypted || (strcmp(prefs_get_string(PREF_OTR_LOG), "on") == 0)) {
            chat_log_chat(jidp->barejid, from_jid->barejid, newmessage, PROF_IN_LOG, NULL);
        } else if (strcmp(prefs_get_string(PREF_OTR_LOG), "redact") == 0) {
            chat_log_chat(jidp->barejid, from_jid->barejid, "[redacted]", PROF_IN_LOG, NULL);
        }

        jid_destroy(jidp);
        jid_destroy(from_jid);
    }

    if (!priv)
        otr_free_message(newmessage);
#else
    ui_incoming_msg(from, message, NULL, priv);
    ui_current_page_off();

    if (prefs_get_boolean(PREF_CHLOG) && !priv) {
        Jid *from_jid = jid_create(from);
        const char *jid = jabber_get_fulljid();
        Jid *jidp = jid_create(jid);
        chat_log_chat(jidp->barejid, from_jid->barejid, message, PROF_IN_LOG, NULL);
        jid_destroy(jidp);
        jid_destroy(from_jid);
    }
#endif
}
예제 #2
0
파일: chatwin.c 프로젝트: 0xPoly/profanity
static void
_chatwin_history(ProfChatWin *chatwin, const char *const contact)
{
    if (!chatwin->history_shown) {
        Jid *jid = jid_create(jabber_get_fulljid());
        GSList *history = chat_log_get_previous(jid->barejid, contact);
        jid_destroy(jid);
        GSList *curr = history;
        while (curr) {
            char *line = curr->data;
            // entry
            if (line[2] == ':') {
                char hh[3]; memcpy(hh, &line[0], 2); hh[2] = '\0'; int ihh = atoi(hh);
                char mm[3]; memcpy(mm, &line[3], 2); mm[2] = '\0'; int imm = atoi(mm);
                char ss[3]; memcpy(ss, &line[6], 2); ss[2] = '\0'; int iss = atoi(ss);
                GDateTime *timestamp = g_date_time_new_local(2000, 1, 1, ihh, imm, iss);
                win_print((ProfWin*)chatwin, '-', 0, timestamp, NO_COLOUR_DATE, 0, "", curr->data+11);
                g_date_time_unref(timestamp);
            // header
            } else {
                win_print((ProfWin*)chatwin, '-', 0, NULL, 0, 0, "", curr->data);
            }
            curr = g_slist_next(curr);
        }
        chatwin->history_shown = TRUE;

        g_slist_free_full(history, free);
    }
}
예제 #3
0
void
jabber_autoping_fail(void)
{
    if (jabber_conn.conn_status == JABBER_CONNECTED) {
        log_info("Closing connection");
        char *account_name = jabber_get_account_name();
        const char *fulljid = jabber_get_fulljid();
        plugins_on_disconnect(account_name, fulljid);
        accounts_set_last_activity(jabber_get_account_name());
        jabber_conn.conn_status = JABBER_DISCONNECTING;
        xmpp_disconnect(jabber_conn.conn);

        while (jabber_get_connection_status() == JABBER_DISCONNECTING) {
            jabber_process_events(10);
        }
        if (jabber_conn.conn) {
            xmpp_conn_release(jabber_conn.conn);
            jabber_conn.conn = NULL;
        }
        if (jabber_conn.ctx) {
            xmpp_ctx_free(jabber_conn.ctx);
            jabber_conn.ctx = NULL;
        }
    }

    FREE_SET_NULL(jabber_conn.presence_message);
    FREE_SET_NULL(jabber_conn.domain);

    jabber_conn.conn_status = JABBER_DISCONNECTED;
    _jabber_lost_connection();
}
예제 #4
0
void
jabber_disconnect(void)
{
    // if connected, send end stream and wait for response
    if (jabber_conn.conn_status == JABBER_CONNECTED) {
        char *account_name = jabber_get_account_name();
        const char *fulljid = jabber_get_fulljid();
        plugins_on_disconnect(account_name, fulljid);
        log_info("Closing connection");
        accounts_set_last_activity(jabber_get_account_name());
        jabber_conn.conn_status = JABBER_DISCONNECTING;
        xmpp_disconnect(jabber_conn.conn);

        while (jabber_get_connection_status() == JABBER_DISCONNECTING) {
            jabber_process_events(10);
        }
        _connection_free_saved_account();
        _connection_free_saved_details();
        _connection_free_session_data();
        if (jabber_conn.conn) {
            xmpp_conn_release(jabber_conn.conn);
            jabber_conn.conn = NULL;
        }
        if (jabber_conn.ctx) {
            xmpp_ctx_free(jabber_conn.ctx);
            jabber_conn.ctx = NULL;
        }
    }

    jabber_conn.conn_status = JABBER_STARTED;
    FREE_SET_NULL(jabber_conn.presence_message);
    FREE_SET_NULL(jabber_conn.domain);
}
예제 #5
0
파일: message.c 프로젝트: 0xPoly/profanity
static gboolean
_handle_carbons(xmpp_stanza_t *const stanza)
{
    xmpp_stanza_t *carbons = xmpp_stanza_get_child_by_ns(stanza, STANZA_NS_CARBONS);
    if (!carbons) {
        return FALSE;
    }

    char *name = xmpp_stanza_get_name(carbons);
    if ((g_strcmp0(name, "received") == 0) || (g_strcmp0(name, "sent")) == 0) {
        xmpp_stanza_t *forwarded = xmpp_stanza_get_child_by_ns(carbons, STANZA_NS_FORWARD);
        xmpp_stanza_t *message = xmpp_stanza_get_child_by_name(forwarded, STANZA_NAME_MESSAGE);

        xmpp_ctx_t *ctx = connection_get_ctx();

        gchar *to = xmpp_stanza_get_attribute(message, STANZA_ATTR_TO);
        gchar *from = xmpp_stanza_get_attribute(message, STANZA_ATTR_FROM);

        // happens when receive a carbon of a self sent message
        if (!to) to = from;

        Jid *jid_from = jid_create(from);
        Jid *jid_to = jid_create(to);
        Jid *my_jid = jid_create(jabber_get_fulljid());

        // check for and deal with message
        xmpp_stanza_t *body = xmpp_stanza_get_child_by_name(message, STANZA_NAME_BODY);
        if (body) {
            char *message_txt = xmpp_stanza_get_text(body);
            if (message_txt) {
                // check for pgp encrypted message
                char *enc_message = NULL;
                xmpp_stanza_t *x = xmpp_stanza_get_child_by_ns(message, STANZA_NS_ENCRYPTED);
                if (x) {
                    enc_message = xmpp_stanza_get_text(x);
                }

                // if we are the recipient, treat as standard incoming message
                if(g_strcmp0(my_jid->barejid, jid_to->barejid) == 0){
                    sv_ev_incoming_carbon(jid_from->barejid, jid_from->resourcepart, message_txt, enc_message);

                // else treat as a sent message
                } else {
                    sv_ev_outgoing_carbon(jid_to->barejid, message_txt, enc_message);
                }
                xmpp_free(ctx, message_txt);
                xmpp_free(ctx, enc_message);
            }
        }

        jid_destroy(jid_from);
        jid_destroy(jid_to);
        jid_destroy(my_jid);

        return TRUE;
    }

    return FALSE;
}
예제 #6
0
파일: log.c 프로젝트: User0815/profanity
void
chat_log_msg_in_delayed(const char * const barejid, const char * msg, GDateTime *timestamp)
{
    if (prefs_get_boolean(PREF_CHLOG)) {
        const char *jid = jabber_get_fulljid();
        Jid *jidp = jid_create(jid);
        _chat_log_chat(jidp->barejid, barejid, msg, PROF_IN_LOG, timestamp);
        jid_destroy(jidp);
    }
}
예제 #7
0
파일: log.c 프로젝트: User0815/profanity
void
chat_log_msg_in(const char * const barejid, const char * const msg)
{
    if (prefs_get_boolean(PREF_CHLOG)) {
        const char *jid = jabber_get_fulljid();
        Jid *jidp = jid_create(jid);
        _chat_log_chat(jidp->barejid, barejid, msg, PROF_IN_LOG, NULL);
        jid_destroy(jidp);
    }
}
예제 #8
0
void
sv_ev_room_message(const char * const room_jid, const char * const nick,
    const char * const message)
{
    ui_room_message(room_jid, nick, message);

    if (prefs_get_boolean(PREF_GRLOG)) {
        Jid *jid = jid_create(jabber_get_fulljid());
        groupchat_log_chat(jid->barejid, room_jid, nick, message);
        jid_destroy(jid);
    }
}
예제 #9
0
void
sv_ev_roster_received(void)
{
    if (prefs_get_boolean(PREF_ROSTER)) {
        ui_show_roster();
    }

    char *account_name = jabber_get_account_name();

#ifdef PROF_HAVE_LIBGPGME
    // check pgp key valid if specified
    ProfAccount *account = accounts_get_account(account_name);
    if (account && account->pgp_keyid) {
        char *err_str = NULL;
        if (!p_gpg_valid_key(account->pgp_keyid, &err_str)) {
            cons_show_error("Invalid PGP key ID specified: %s, %s", account->pgp_keyid, err_str);
        }
        free(err_str);
    }
    account_free(account);
#endif

    // send initial presence
    resource_presence_t conn_presence = accounts_get_login_presence(account_name);
    char *last_activity_str = accounts_get_last_activity(account_name);
    if (last_activity_str) {
        GDateTime *nowdt = g_date_time_new_now_utc();

        GTimeVal lasttv;
        gboolean res = g_time_val_from_iso8601(last_activity_str, &lasttv);
        if (res) {
            GDateTime *lastdt = g_date_time_new_from_timeval_utc(&lasttv);
            GTimeSpan diff_micros = g_date_time_difference(nowdt, lastdt);
            int diff_secs = (diff_micros / 1000) / 1000;
            if (prefs_get_boolean(PREF_LASTACTIVITY)) {
                cl_ev_presence_send(conn_presence, NULL, diff_secs);
            } else {
                cl_ev_presence_send(conn_presence, NULL, 0);
            }
            g_date_time_unref(lastdt);
        } else {
            cl_ev_presence_send(conn_presence, NULL, 0);
        }

        free(last_activity_str);
        g_date_time_unref(nowdt);
    } else {
        cl_ev_presence_send(conn_presence, NULL, 0);
    }

    const char *fulljid = jabber_get_fulljid();
    plugins_on_connect(account_name, fulljid);
}
예제 #10
0
void
handle_delayed_message(char *from, char *message, GTimeVal tv_stamp,
    gboolean priv)
{
    ui_incoming_msg(from, message, &tv_stamp, priv);

    if (prefs_get_boolean(PREF_CHLOG) && !priv) {
        Jid *from_jid = jid_create(from);
        const char *jid = jabber_get_fulljid();
        Jid *jidp = jid_create(jid);
        chat_log_chat(jidp->barejid, from_jid->barejid, message, PROF_IN_LOG, &tv_stamp);
        jid_destroy(jidp);
        jid_destroy(from_jid);
    }
}
예제 #11
0
파일: core.c 프로젝트: jesseadams/profanity
static void
_ui_draw_win_title(void)
{
    char new_win_title[100];

    GString *version_str = g_string_new("");

    if (prefs_get_boolean(PREF_TITLEBARVERSION)) {
        g_string_append(version_str, " ");
        g_string_append(version_str, PACKAGE_VERSION);
        if (strcmp(PACKAGE_STATUS, "development") == 0) {
#ifdef HAVE_GIT_VERSION
            g_string_append(version_str, "dev.");
            g_string_append(version_str, PROF_GIT_BRANCH);
            g_string_append(version_str, ".");
            g_string_append(version_str, PROF_GIT_REVISION);
#else
            g_string_append(version_str, "dev");
#endif
        }
    }

    jabber_conn_status_t status = jabber_get_connection_status();

    if (status == JABBER_CONNECTED) {
        const char * const jid = jabber_get_fulljid();
        gint unread = ui_unread();

        if (unread != 0) {
            snprintf(new_win_title, sizeof(new_win_title), "%c]0;%s%s (%d) - %s%c", '\033', "Profanity", version_str->str, unread, jid, '\007');
        } else {
            snprintf(new_win_title, sizeof(new_win_title), "%c]0;%s%s - %s%c", '\033', "Profanity", version_str->str, jid, '\007');
        }
    } else {
        snprintf(new_win_title, sizeof(new_win_title), "%c]0;%s%s%c", '\033', "Profanity", version_str->str, '\007');
    }

    g_string_free(version_str, TRUE);

    if (g_strcmp0(win_title, new_win_title) != 0) {
        // print to x-window title bar
        printf("%s", new_win_title);
        if (win_title != NULL) {
            free(win_title);
        }
        win_title = strdup(new_win_title);
    }
}
예제 #12
0
파일: log.c 프로젝트: User0815/profanity
void
chat_log_pgp_msg_in(const char * const barejid, const char * const msg)
{
    if (prefs_get_boolean(PREF_CHLOG)) {
        const char *jid = jabber_get_fulljid();
        Jid *jidp = jid_create(jid);
        char *pref_pgp_log = prefs_get_string(PREF_PGP_LOG);
        if (strcmp(pref_pgp_log, "on") == 0) {
            _chat_log_chat(jidp->barejid, barejid, msg, PROF_IN_LOG, NULL);
        } else if (strcmp(pref_pgp_log, "redact") == 0) {
            _chat_log_chat(jidp->barejid, barejid, "[redacted]", PROF_IN_LOG, NULL);
        }
        prefs_free_string(pref_pgp_log);
        jid_destroy(jidp);
    }
}
예제 #13
0
void
cl_ev_disconnect(void)
{
    const char *jid = jabber_get_fulljid();
    cons_show("%s logged out successfully.", jid);

    ui_disconnected();
    ui_close_all_wins();
    jabber_disconnect();
    roster_destroy();
    muc_invites_clear();
    chat_sessions_clear();
    tlscerts_clear_current();
#ifdef HAVE_LIBGPGME
    p_gpg_on_disconnect();
#endif
}
예제 #14
0
파일: roster.c 프로젝트: PMaynard/profanity
static int
_roster_set_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza,
    void * const userdata)
{
    xmpp_stanza_t *query =
        xmpp_stanza_get_child_by_name(stanza, STANZA_NAME_QUERY);
    xmpp_stanza_t *item =
        xmpp_stanza_get_child_by_name(query, STANZA_NAME_ITEM);

    if (item == NULL) {
        return 1;
    }

    // if from attribute exists and it is not current users barejid, ignore push
    Jid *my_jid = jid_create(jabber_get_fulljid());
    const char *from = xmpp_stanza_get_attribute(stanza, STANZA_ATTR_FROM);
    if (from && (strcmp(from, my_jid->barejid) != 0)) {
        jid_destroy(my_jid);
        return 1;
    }
    jid_destroy(my_jid);

    const char *barejid = xmpp_stanza_get_attribute(item, STANZA_ATTR_JID);
    gchar *barejid_lower = g_utf8_strdown(barejid, -1);
    const char *name = xmpp_stanza_get_attribute(item, STANZA_ATTR_NAME);
    const char *sub = xmpp_stanza_get_attribute(item, STANZA_ATTR_SUBSCRIPTION);
    const char *ask = xmpp_stanza_get_attribute(item, STANZA_ATTR_ASK);

    // do not set nickname to empty string, set to NULL instead
    if (name && (strlen(name) == 0)) {
        name = NULL;
    }

    // remove from roster
    if (g_strcmp0(sub, "remove") == 0) {
        // remove barejid and name
        if (name == NULL) {
            name = barejid_lower;
        }
        roster_remove(name, barejid_lower);
        ui_roster_remove(barejid_lower);

    // otherwise update local roster
    } else {

        // check for pending out subscriptions
        gboolean pending_out = FALSE;
        if (ask && (strcmp(ask, "subscribe") == 0)) {
            pending_out = TRUE;
        }

        GSList *groups = _get_groups_from_item(item);

        // update the local roster
        PContact contact = roster_get_contact(barejid_lower);
        if (contact == NULL) {
            gboolean added = roster_add(barejid_lower, name, groups, sub, pending_out);
            if (added) {
                ui_roster_add(barejid_lower, name);
            }
        } else {
            sv_ev_roster_update(barejid_lower, name, groups, sub, pending_out);
        }
    }

    g_free(barejid_lower);

    return 1;
}
예제 #15
0
파일: bookmark.c 프로젝트: mrshu/profanity
static int
_bookmark_handle_result(xmpp_conn_t * const conn,
    xmpp_stanza_t * const stanza, void * const userdata)
{
    xmpp_ctx_t *ctx = connection_get_ctx();
    char *id = (char *)userdata;
    xmpp_stanza_t *ptr;
    xmpp_stanza_t *nick;
    char *name;
    char *jid;
    char *autojoin;
    gboolean autojoin_val;
    Jid *my_jid;
    Bookmark *item;

    xmpp_timed_handler_delete(conn, _bookmark_handle_delete);
    g_free(id);

    name = xmpp_stanza_get_name(stanza);
    if (!name || strcmp(name, STANZA_NAME_IQ) != 0) {
        return 0;
    }

    ptr = xmpp_stanza_get_child_by_name(stanza, STANZA_NAME_QUERY);
    if (!ptr) {
        return 0;
    }
    ptr = xmpp_stanza_get_child_by_name(ptr, STANZA_NAME_STORAGE);
    if (!ptr) {
        return 0;
    }

    if (bookmark_ac == NULL) {
        bookmark_ac = autocomplete_new();
    }
    my_jid = jid_create(jabber_get_fulljid());

    ptr = xmpp_stanza_get_children(ptr);
    while (ptr) {
        name = xmpp_stanza_get_name(ptr);
        if (!name || strcmp(name, STANZA_NAME_CONFERENCE) != 0) {
            ptr = xmpp_stanza_get_next(ptr);
            continue;
        }
        jid = xmpp_stanza_get_attribute(ptr, STANZA_ATTR_JID);
        if (!jid) {
            ptr = xmpp_stanza_get_next(ptr);
            continue;
        }

        log_debug("Handle bookmark for %s", jid);

        name = NULL;
        nick = xmpp_stanza_get_child_by_name(ptr, "nick");
        if (nick) {
            char *tmp;
            tmp = xmpp_stanza_get_text(nick);
            if (tmp) {
                name = strdup(tmp);
                xmpp_free(ctx, tmp);
            }
        }

        autojoin = xmpp_stanza_get_attribute(ptr, "autojoin");
        if (autojoin && (strcmp(autojoin, "1") == 0 || strcmp(autojoin, "true") == 0)) {
            autojoin_val = TRUE;
        } else {
            autojoin_val = FALSE;
        }

        autocomplete_add(bookmark_ac, jid);
        item = malloc(sizeof(*item));
        item->jid = strdup(jid);
        item->nick = name;
        item->autojoin = autojoin_val;
        bookmark_list = g_list_append(bookmark_list, item);


        /* TODO: preference whether autojoin */
        if (autojoin_val) {
            if (autojoin_count < BOOKMARK_AUTOJOIN_MAX) {
                Jid *room_jid;

                ++autojoin_count;

                if (name == NULL) {
                    name = my_jid->localpart;
                }

                log_debug("Autojoin %s with nick=%s", jid, name);
                room_jid = jid_create_from_bare_and_resource(jid, name);
                if (!muc_room_is_active(room_jid)) {
                    presence_join_room(room_jid);
                    /* TODO: this should be removed after fixing #195 */
                    ui_room_join(room_jid);
                }
                jid_destroy(room_jid);
            } else {
                log_debug("Rejected autojoin %s (maximum has been reached)", jid);
            }
        }

        ptr = xmpp_stanza_get_next(ptr);
    }

    jid_destroy(my_jid);

    return 0;
}
예제 #16
0
파일: bookmark.c 프로젝트: 0xPoly/profanity
static int
_bookmark_handle_result(xmpp_conn_t *const conn,
    xmpp_stanza_t *const stanza, void *const userdata)
{
    xmpp_ctx_t *ctx = connection_get_ctx();
    char *id = (char *)userdata;
    xmpp_stanza_t *ptr;
    xmpp_stanza_t *nick;
    xmpp_stanza_t *password_st;
    char *name;
    char *jid;
    char *autojoin;
    char *password;
    gboolean autojoin_val;
    Jid *my_jid;
    Bookmark *item;

    xmpp_timed_handler_delete(conn, _bookmark_handle_delete);
    g_free(id);

    name = xmpp_stanza_get_name(stanza);
    if (!name || strcmp(name, STANZA_NAME_IQ) != 0) {
        return 0;
    }

    ptr = xmpp_stanza_get_child_by_name(stanza, STANZA_NAME_QUERY);
    if (!ptr) {
        return 0;
    }
    ptr = xmpp_stanza_get_child_by_name(ptr, STANZA_NAME_STORAGE);
    if (!ptr) {
        return 0;
    }

    if (bookmark_ac == NULL) {
        bookmark_ac = autocomplete_new();
    }
    my_jid = jid_create(jabber_get_fulljid());

    ptr = xmpp_stanza_get_children(ptr);
    while (ptr) {
        name = xmpp_stanza_get_name(ptr);
        if (!name || strcmp(name, STANZA_NAME_CONFERENCE) != 0) {
            ptr = xmpp_stanza_get_next(ptr);
            continue;
        }
        jid = xmpp_stanza_get_attribute(ptr, STANZA_ATTR_JID);
        if (!jid) {
            ptr = xmpp_stanza_get_next(ptr);
            continue;
        }

        log_debug("Handle bookmark for %s", jid);

        name = NULL;
        nick = xmpp_stanza_get_child_by_name(ptr, "nick");
        if (nick) {
            char *tmp;
            tmp = xmpp_stanza_get_text(nick);
            if (tmp) {
                name = strdup(tmp);
                xmpp_free(ctx, tmp);
            }
        }

        password = NULL;
        password_st = xmpp_stanza_get_child_by_name(ptr, "password");
        if (password_st) {
            char *tmp;
            tmp = xmpp_stanza_get_text(password_st);
            if (tmp) {
                password = strdup(tmp);
                xmpp_free(ctx, tmp);
            }
        }

        autojoin = xmpp_stanza_get_attribute(ptr, "autojoin");
        if (autojoin && (strcmp(autojoin, "1") == 0 || strcmp(autojoin, "true") == 0)) {
            autojoin_val = TRUE;
        } else {
            autojoin_val = FALSE;
        }

        autocomplete_add(bookmark_ac, jid);
        item = malloc(sizeof(*item));
        item->jid = strdup(jid);
        item->nick = name;
        item->password = password;
        item->autojoin = autojoin_val;
        bookmark_list = g_list_append(bookmark_list, item);

        if (autojoin_val) {
            Jid *room_jid;

            char *account_name = jabber_get_account_name();
            ProfAccount *account = accounts_get_account(account_name);
            if (name == NULL) {
                name = account->muc_nick;
            }

            log_debug("Autojoin %s with nick=%s", jid, name);
            room_jid = jid_create_from_bare_and_resource(jid, name);
            if (!muc_active(room_jid->barejid)) {
                presence_join_room(jid, name, password);
                muc_join(jid, name, password, TRUE);
            }
            jid_destroy(room_jid);
            account_free(account);
        }

        ptr = xmpp_stanza_get_next(ptr);
    }

    jid_destroy(my_jid);

    return 0;
}
예제 #17
0
void
sv_ev_room_message(const char *const room_jid, const char *const nick, const char *const message)
{
    if (prefs_get_boolean(PREF_GRLOG)) {
        Jid *jid = jid_create(jabber_get_fulljid());
        groupchat_log_chat(jid->barejid, room_jid, nick, message);
        jid_destroy(jid);
    }

    ProfMucWin *mucwin = wins_get_muc(room_jid);
    if (!mucwin) {
        return;
    }

    char *new_message = plugins_pre_room_message_display(room_jid, nick, message);
    char *mynick = muc_nick(mucwin->roomjid);

    gboolean mention = FALSE;
    char *message_lower = g_utf8_strdown(new_message, -1);
    char *mynick_lower = g_utf8_strdown(mynick, -1);
    if (g_strrstr(message_lower, mynick_lower)) {
        mention = TRUE;
    }
    g_free(message_lower);
    g_free(mynick_lower);

    GList *triggers = prefs_message_get_triggers(new_message);

    mucwin_message(mucwin, nick, new_message, mention, triggers);

    ProfWin *window = (ProfWin*)mucwin;
    int num = wins_get_num(window);
    gboolean is_current = FALSE;

    // currently in groupchat window
    if (wins_is_current(window)) {
        is_current = TRUE;
        status_bar_active(num);

        if ((g_strcmp0(mynick, nick) != 0) && (prefs_get_boolean(PREF_BEEP))) {
            beep();
        }

    // not currently on groupchat window
    } else {
        status_bar_new(num);

        if ((g_strcmp0(mynick, nick) != 0) && (prefs_get_boolean(PREF_FLASH))) {
            flash();
        }

        cons_show_incoming_room_message(nick, mucwin->roomjid, num, mention, triggers, mucwin->unread);

        mucwin->unread++;

        if (mention) {
            mucwin->unread_mentions = TRUE;
        }
        if (triggers) {
            mucwin->unread_triggers = TRUE;
        }
    }

    if (prefs_do_room_notify(is_current, mucwin->roomjid, mynick, nick, new_message, mention, triggers != NULL)) {
        Jid *jidp = jid_create(mucwin->roomjid);
        notify_room_message(nick, jidp->localpart, num, new_message);
        jid_destroy(jidp);
    }

    if (triggers) {
        g_list_free_full(triggers, free);
    }

    rosterwin_roster();

    plugins_post_room_message_display(room_jid, nick, new_message);
    free(new_message);
}
예제 #18
0
static void
_connection_handler(xmpp_conn_t * const conn,
    const xmpp_conn_event_t status, const int error,
    xmpp_stream_error_t * const stream_error, void * const userdata)
{
    // login success
    if (status == XMPP_CONN_CONNECT) {
        log_debug("Connection handler: XMPP_CONN_CONNECT");

        // logged in with account
        if (saved_account.name != NULL) {
            log_debug("Connection handler: logged in with account name: %s", saved_account.name);
            handle_login_account_success(saved_account.name);

        // logged in without account, use details to create new account
        } else {
            log_debug("Connection handler: logged in with jid: %s", saved_details.name);
            accounts_add(saved_details.name, saved_details.altdomain, saved_details.port);
            accounts_set_jid(saved_details.name, saved_details.jid);

            handle_login_account_success(saved_details.name);
            saved_account.name = strdup(saved_details.name);
            saved_account.passwd = strdup(saved_details.passwd);

            _connection_free_saved_details();
        }

        Jid *myJid = jid_create(jabber_get_fulljid());
        jabber_conn.domain = strdup(myJid->domainpart);
        jid_destroy(myJid);

        chat_sessions_init();

        roster_add_handlers();
        message_add_handlers();
        presence_add_handlers();
        iq_add_handlers();

        roster_request();
        bookmark_request();
        jabber_conn.conn_status = JABBER_CONNECTED;

        if (prefs_get_reconnect() != 0) {
            if (reconnect_timer != NULL) {
                g_timer_destroy(reconnect_timer);
                reconnect_timer = NULL;
            }
        }

    } else if (status == XMPP_CONN_DISCONNECT) {
        log_debug("Connection handler: XMPP_CONN_DISCONNECT");

        // lost connection for unkown reason
        if (jabber_conn.conn_status == JABBER_CONNECTED) {
            log_debug("Connection handler: Lost connection for unknown reason");
            handle_lost_connection();
            if (prefs_get_reconnect() != 0) {
                assert(reconnect_timer == NULL);
                reconnect_timer = g_timer_new();
                // free resources but leave saved_user untouched
                _connection_free_session_data();
            } else {
                _connection_free_saved_account();
                _connection_free_saved_details();
                _connection_free_session_data();
            }

        // login attempt failed
        } else if (jabber_conn.conn_status != JABBER_DISCONNECTING) {
            log_debug("Connection handler: Login failed");
            if (reconnect_timer == NULL) {
                log_debug("Connection handler: No reconnect timer");
                handle_failed_login();
                _connection_free_saved_account();
                _connection_free_saved_details();
                _connection_free_session_data();
            } else {
                log_debug("Connection handler: Restarting reconnect timer");
                if (prefs_get_reconnect() != 0) {
                    g_timer_start(reconnect_timer);
                }
                // free resources but leave saved_user untouched
                _connection_free_session_data();
            }
        }

        // close stream response from server after disconnect is handled too
        jabber_conn.conn_status = JABBER_DISCONNECTED;
    } else if (status == XMPP_CONN_FAIL) {
        log_debug("Connection handler: XMPP_CONN_FAIL");
    } else {
        log_error("Connection handler: Unknown status");
    }
}
예제 #19
0
static int
_muc_user_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza,
    void * const userdata)
{
    // handler still fires if error
    if (g_strcmp0(xmpp_stanza_get_type(stanza), STANZA_TYPE_ERROR) == 0) {
        return 1;
    }

    char *from = xmpp_stanza_get_attribute(stanza, STANZA_ATTR_FROM);
    Jid *from_jid = jid_create(from);
    if (from_jid == NULL || from_jid->resourcepart == NULL) {
        return 1;
    }

    char *from_room = from_jid->barejid;
    char *from_nick = from_jid->resourcepart;

    // handle self presence
    if (stanza_is_muc_self_presence(stanza, jabber_get_fulljid())) {
        char *type = xmpp_stanza_get_attribute(stanza, STANZA_ATTR_TYPE);
        char *new_nick = stanza_get_new_nick(stanza);

        if ((type != NULL) && (strcmp(type, STANZA_TYPE_UNAVAILABLE) == 0)) {

            // leave room if not self nick change
            if (new_nick != NULL) {
                muc_set_room_pending_nick_change(from_room, new_nick);
            } else {
                handle_leave_room(from_room);
            }

        // handle self nick change
        } else if (muc_is_room_pending_nick_change(from_room)) {
            muc_complete_room_nick_change(from_room, from_nick);
            handle_room_nick_change(from_room, from_nick);

        // handle roster complete
        } else if (!muc_get_roster_received(from_room)) {
            handle_room_roster_complete(from_room);

            // room configuration required
            if (stanza_muc_requires_config(stanza)) {
                handle_room_requires_config(from_room);
            }
        }

    // handle presence from room members
    } else {
        char *type = xmpp_stanza_get_attribute(stanza, STANZA_ATTR_TYPE);
        char *status_str;

        log_debug("Room presence received from %s", from_jid->fulljid);

        status_str = stanza_get_status(stanza, NULL);

        if ((type != NULL) && (strcmp(type, STANZA_TYPE_UNAVAILABLE) == 0)) {

            // handle nickname change
            if (stanza_is_room_nick_change(stanza)) {
                char *new_nick = stanza_get_new_nick(stanza);
                if (new_nick != NULL) {
                    muc_set_roster_pending_nick_change(from_room, new_nick, from_nick);
                    free(new_nick);
                }
            } else {
                handle_room_member_offline(from_room, from_nick, "offline", status_str);
            }
        } else {
            // send disco info for capabilities, if not cached
            if (stanza_contains_caps(stanza)) {
                log_info("Presence contains capabilities.");
                _handle_caps(stanza);
            }

            char *show_str = stanza_get_show(stanza, "online");
            if (!muc_get_roster_received(from_room)) {
                muc_add_to_roster(from_room, from_nick, show_str, status_str);
            } else {
                char *old_nick = muc_complete_roster_nick_change(from_room, from_nick);

                if (old_nick != NULL) {
                    muc_add_to_roster(from_room, from_nick, show_str, status_str);
                    handle_room_member_nick_change(from_room, old_nick, from_nick);
                    free(old_nick);
                } else {
                    if (!muc_nick_in_roster(from_room, from_nick)) {
                        handle_room_member_online(from_room, from_nick, show_str, status_str);
                    } else {
                        handle_room_member_presence(from_room, from_nick, show_str, status_str);
                    }
                }
            }

           free(show_str);
        }

        free(status_str);
    }

    jid_destroy(from_jid);

    return 1;
}
예제 #20
0
파일: core.c 프로젝트: jesseadams/profanity
static void
_win_handle_page(const wint_t * const ch)
{
    ProfWin *current = wins_get_current();
    int rows = getmaxy(stdscr);
    int y = getcury(current->win);

    int page_space = rows - 4;
    int *page_start = &(current->y_pos);

    if (prefs_get_boolean(PREF_MOUSE)) {
        MEVENT mouse_event;

        if (*ch == KEY_MOUSE) {
            if (getmouse(&mouse_event) == OK) {

#ifdef PLATFORM_CYGWIN
                if (mouse_event.bstate & BUTTON5_PRESSED) { // mouse wheel down
#else
                if (mouse_event.bstate & BUTTON2_PRESSED) { // mouse wheel down
#endif
                    *page_start += 4;

                    // only got half a screen, show full screen
                    if ((y - (*page_start)) < page_space)
                        *page_start = y - page_space;

                    // went past end, show full screen
                    else if (*page_start >= y)
                        *page_start = y - page_space;

                    current->paged = 1;
                    wins_refresh_current();
                } else if (mouse_event.bstate & BUTTON4_PRESSED) { // mouse wheel up
                    *page_start -= 4;

                    // went past beginning, show first page
                    if (*page_start < 0)
                        *page_start = 0;

                    current->paged = 1;
                    wins_refresh_current();
                }
            }
        }
    }

    // page up
    if (*ch == KEY_PPAGE) {
        *page_start -= page_space;

        // went past beginning, show first page
        if (*page_start < 0)
            *page_start = 0;

        current->paged = 1;
        wins_refresh_current();

    // page down
    } else if (*ch == KEY_NPAGE) {
        *page_start += page_space;

        // only got half a screen, show full screen
        if ((y - (*page_start)) < page_space)
            *page_start = y - page_space;

        // went past end, show full screen
        else if (*page_start >= y)
            *page_start = y - page_space;

        current->paged = 1;
        wins_refresh_current();
    }
}

static void
_win_show_history(WINDOW *win, int win_index, const char * const contact)
{
    ProfWin *window = wins_get_by_num(win_index);
    if (!window->history_shown) {
        GSList *history = NULL;
        Jid *jid = jid_create(jabber_get_fulljid());
        history = chat_log_get_previous(jid->barejid, contact, history);
        jid_destroy(jid);
        while (history != NULL) {
            wprintw(win, "%s\n", history->data);
            history = g_slist_next(history);
        }
        window->history_shown = 1;

        g_slist_free_full(history, free);
    }
}
예제 #21
0
void
handle_incoming_message(char *from, char *message, gboolean priv)
{
#ifdef HAVE_LIBOTR
    gboolean was_decrypted = FALSE;
    char *newmessage;

    prof_otrpolicy_t policy = otr_get_policy(from);
    char *whitespace_base = strstr(message,OTRL_MESSAGE_TAG_BASE);

    if (!priv) {
        //check for OTR whitespace (opportunistic or always)
        if (policy == PROF_OTRPOLICY_OPPORTUNISTIC || policy == PROF_OTRPOLICY_ALWAYS) {
            if (whitespace_base) {
                if (strstr(message, OTRL_MESSAGE_TAG_V2) || strstr(message, OTRL_MESSAGE_TAG_V1)) {
                    // Remove whitespace pattern for proper display in UI
                    // Handle both BASE+TAGV1/2(16+8) and BASE+TAGV1+TAGV2(16+8+8)
                    int tag_length	=	24;
                    if (strstr(message, OTRL_MESSAGE_TAG_V2) && strstr(message, OTRL_MESSAGE_TAG_V1)) {
                        tag_length = 32;
                    }
                    memmove(whitespace_base, whitespace_base+tag_length, tag_length);
                    char *otr_query_message = otr_start_query();
                    cons_show("OTR Whitespace pattern detected. Attempting to start OTR session...");
                    message_send(otr_query_message, from);
                }
            }
        }
        newmessage = otr_decrypt_message(from, message, &was_decrypted);

        // internal OTR message
        if (newmessage == NULL) {
            return;
        }
    } else {
        newmessage = message;
    }
    if (policy == PROF_OTRPOLICY_ALWAYS && !was_decrypted && !whitespace_base) {
        char *otr_query_message = otr_start_query();
        cons_show("Attempting to start OTR session...");
        message_send(otr_query_message, from);
    }

    ui_incoming_msg(from, newmessage, NULL, priv);

    if (prefs_get_boolean(PREF_CHLOG) && !priv) {
        Jid *from_jid = jid_create(from);
        const char *jid = jabber_get_fulljid();
        Jid *jidp = jid_create(jid);

        char *pref_otr_log = prefs_get_string(PREF_OTR_LOG);
        if (!was_decrypted || (strcmp(pref_otr_log, "on") == 0)) {
            chat_log_chat(jidp->barejid, from_jid->barejid, newmessage, PROF_IN_LOG, NULL);
        } else if (strcmp(pref_otr_log, "redact") == 0) {
            chat_log_chat(jidp->barejid, from_jid->barejid, "[redacted]", PROF_IN_LOG, NULL);
        }
        prefs_free_string(pref_otr_log);

        jid_destroy(jidp);
        jid_destroy(from_jid);
    }

    if (!priv)
        otr_free_message(newmessage);
#else
    ui_incoming_msg(from, message, NULL, priv);

    if (prefs_get_boolean(PREF_CHLOG) && !priv) {
        Jid *from_jid = jid_create(from);
        const char *jid = jabber_get_fulljid();
        Jid *jidp = jid_create(jid);
        chat_log_chat(jidp->barejid, from_jid->barejid, message, PROF_IN_LOG, NULL);
        jid_destroy(jidp);
        jid_destroy(from_jid);
    }
#endif
}