Example #1
0
int
ui_close_read_wins(void)
{
    int count = 0;
    jabber_conn_status_t conn_status = connection_get_status();

    GList *win_nums = wins_get_nums();
    GList *curr = win_nums;

    while (curr) {
        int num = GPOINTER_TO_INT(curr->data);
        if ((num != 1) && (ui_win_unread(num) == 0) && (!ui_win_has_unsaved_form(num))) {
            if (conn_status == JABBER_CONNECTED) {
                ui_close_connected_win(num);
            }
            ui_close_win(num);
            count++;
        }
        curr = g_list_next(curr);
    }

    g_list_free(curr);
    g_list_free(win_nums);

    return count;
}
Example #2
0
static void
_ui_draw_term_title(void)
{
    char new_win_title[100];
    jabber_conn_status_t status = connection_get_status();

    if (status == JABBER_CONNECTED) {
        const char * const jid = connection_get_fulljid();
        gint unread = wins_get_total_unread();

        if (unread != 0) {
            snprintf(new_win_title, sizeof(new_win_title),
                "/bin/echo -n \"%c]0;%s (%d) - %s%c\"", '\033', "Profanity",
                unread, jid, '\007');
        } else {
            snprintf(new_win_title, sizeof(new_win_title),
                "/bin/echo -n \"%c]0;%s - %s%c\"", '\033', "Profanity", jid,
                '\007');
        }
    } else {
        snprintf(new_win_title, sizeof(new_win_title), "/bin/echo -n \"%c]0;%s%c\"", '\033',
            "Profanity", '\007');
    }
    if (g_strcmp0(win_title, new_win_title) != 0) {
        // print to x-window title bar
        int res = system(new_win_title);
        if (res == -1) {
            log_error("Error writing terminal window title.");
        }
        if (win_title) {
            free(win_title);
        }
        win_title = strdup(new_win_title);
    }
}
Example #3
0
char*
win_get_title(ProfWin *window)
{
    if (window == NULL) {
        return strdup(CONS_WIN_TITLE);
    }
    if (window->type == WIN_CONSOLE) {
        return strdup(CONS_WIN_TITLE);
    }
    if (window->type == WIN_CHAT) {
        ProfChatWin *chatwin = (ProfChatWin*) window;
        assert(chatwin->memcheck == PROFCHATWIN_MEMCHECK);
        jabber_conn_status_t conn_status = connection_get_status();
        if (conn_status == JABBER_CONNECTED) {
            PContact contact = roster_get_contact(chatwin->barejid);
            if (contact) {
                const char *name = p_contact_name_or_jid(contact);
                return strdup(name);
            } else {
                return strdup(chatwin->barejid);
            }
        } else {
            return strdup(chatwin->barejid);
        }
    }
    if (window->type == WIN_MUC) {
        ProfMucWin *mucwin = (ProfMucWin*) window;
        assert(mucwin->memcheck == PROFMUCWIN_MEMCHECK);
        return strdup(mucwin->roomjid);
    }
    if (window->type == WIN_MUC_CONFIG) {
        ProfMucConfWin *confwin = (ProfMucConfWin*) window;
        assert(confwin->memcheck == PROFCONFWIN_MEMCHECK);
        GString *title = g_string_new(confwin->roomjid);
        g_string_append(title, " config");
        if (confwin->form->modified) {
            g_string_append(title, " *");
        }
        char *title_str = title->str;
        g_string_free(title, FALSE);
        return title_str;
    }
    if (window->type == WIN_PRIVATE) {
        ProfPrivateWin *privatewin = (ProfPrivateWin*) window;
        assert(privatewin->memcheck == PROFPRIVATEWIN_MEMCHECK);
        return strdup(privatewin->fulljid);
    }
    if (window->type == WIN_XML) {
        return strdup(XML_WIN_TITLE);
    }
    if (window->type == WIN_PLUGIN) {
        ProfPluginWin *pluginwin = (ProfPluginWin*) window;
        assert(pluginwin->memcheck == PROFPLUGINWIN_MEMCHECK);
        return strdup(pluginwin->tag);
    }

    return NULL;
}
Example #4
0
void
api_disco_add_feature(char *plugin_name, char *feature)
{
    if (feature == NULL) {
        return;
    }

    disco_add_feature(plugin_name, feature);

    caps_reset_ver();

    // resend presence to update server's disco info data for this client
    if (connection_get_status() == JABBER_CONNECTED) {
        resource_presence_t last_presence = accounts_get_last_presence(session_get_account_name());
        cl_ev_presence_send(last_presence, connection_get_presence_msg(), 0);
    }
}
Example #5
0
void
caps_remove_feature(char *feature)
{
    if (!g_hash_table_contains(prof_features, feature)) {
        return;
    }

    g_hash_table_remove(prof_features, feature);

    caps_reset_ver();

    // resend presence to update server's disco info data for this client
    if (connection_get_status() == JABBER_CONNECTED) {
        resource_presence_t last_presence = accounts_get_last_presence(session_get_account_name());
        cl_ev_presence_send(last_presence, connection_get_presence_msg(), 0);
    }
}
Example #6
0
static void
_shutdown(void)
{
    if (prefs_get_boolean(PREF_WINTITLE_SHOW)) {
        if (prefs_get_boolean(PREF_WINTITLE_GOODBYE)) {
            ui_goodbye_title();
        } else {
            ui_clear_win_title();
        }
    }

    jabber_conn_status_t conn_status = connection_get_status();
    if (conn_status == JABBER_CONNECTED) {
        cl_ev_disconnect();
    }
#ifdef HAVE_GTK
    tray_shutdown();
#endif
    session_shutdown();
    plugins_on_shutdown();
    muc_close();
    caps_close();
#ifdef HAVE_LIBOTR
    otr_shutdown();
#endif
#ifdef HAVE_LIBGPGME
    p_gpg_close();
#endif
    chat_log_close();
    theme_close();
    accounts_close();
    tlscerts_close();
    log_stderr_close();
    log_close();
    plugins_shutdown();
    cmd_uninit();
    ui_close();
    prefs_close();
}
Example #7
0
void
ui_prune_wins(void)
{
    jabber_conn_status_t conn_status = connection_get_status();
    gboolean pruned = FALSE;

    GSList *wins = wins_get_prune_wins();
    if (wins) {
        pruned = TRUE;
    }

    GSList *curr = wins;
    while (curr) {
        ProfWin *window = curr->data;
        if (window->type == WIN_CHAT) {
            if (conn_status == JABBER_CONNECTED) {
                ProfChatWin *chatwin = (ProfChatWin*)window;
                chat_session_remove(chatwin->barejid);
            }
        }

        int num = wins_get_num(window);
        ui_close_win(num);

        curr = g_slist_next(curr);
    }

    if (wins) {
        g_slist_free(wins);
    }

    wins_tidy();
    if (pruned) {
        cons_show("Windows pruned.");
    } else {
        cons_show("No prune needed.");
    }
}
Example #8
0
int
protocol_recv_request_send_reply (struct connection *conn)
{
  int r;
  struct request request;
  uint16_t cmd, flags;
  uint32_t magic, count, error = 0;
  uint64_t offset;
  char *buf = NULL;
  CLEANUP_EXTENTS_FREE struct nbdkit_extents *extents = NULL;

  /* Read the request packet. */
  {
    ACQUIRE_LOCK_FOR_CURRENT_SCOPE (&conn->read_lock);
    r = connection_get_status (conn);
    if (r <= 0)
      return r;
    r = conn->recv (conn, &request, sizeof request);
    if (r == -1) {
      nbdkit_error ("read request: %m");
      return connection_set_status (conn, -1);
    }
    if (r == 0) {
      debug ("client closed input socket, closing connection");
      return connection_set_status (conn, 0); /* disconnect */
    }

    magic = be32toh (request.magic);
    if (magic != NBD_REQUEST_MAGIC) {
      nbdkit_error ("invalid request: 'magic' field is incorrect (0x%x)",
                    magic);
      return connection_set_status (conn, -1);
    }

    flags = be16toh (request.flags);
    cmd = be16toh (request.type);

    offset = be64toh (request.offset);
    count = be32toh (request.count);

    if (cmd == NBD_CMD_DISC) {
      debug ("client sent %s, closing connection", name_of_nbd_cmd (cmd));
      return connection_set_status (conn, 0); /* disconnect */
    }

    /* Validate the request. */
    if (!validate_request (conn, cmd, flags, offset, count, &error)) {
      if (cmd == NBD_CMD_WRITE &&
          skip_over_write_buffer (conn->sockin, count) < 0)
        return connection_set_status (conn, -1);
      goto send_reply;
    }

    /* Get the data buffer used for either read or write requests.
     * This is a common per-thread data buffer, it must not be freed.
     */
    if (cmd == NBD_CMD_READ || cmd == NBD_CMD_WRITE) {
      buf = threadlocal_buffer ((size_t) count);
      if (buf == NULL) {
        error = ENOMEM;
        if (cmd == NBD_CMD_WRITE &&
            skip_over_write_buffer (conn->sockin, count) < 0)
          return connection_set_status (conn, -1);
        goto send_reply;
      }
    }

    /* Allocate the extents list for block status only. */
    if (cmd == NBD_CMD_BLOCK_STATUS) {
      extents = nbdkit_extents_new (offset, conn->exportsize);
      if (extents == NULL) {
        error = ENOMEM;
        goto send_reply;
      }
    }

    /* Receive the write data buffer. */
    if (cmd == NBD_CMD_WRITE) {
      r = conn->recv (conn, buf, count);
      if (r == 0) {
        errno = EBADMSG;
        r = -1;
      }
      if (r == -1) {
        nbdkit_error ("read data: %s: %m", name_of_nbd_cmd (cmd));
        return connection_set_status (conn, -1);
      }
    }
  }

  /* Perform the request.  Only this part happens inside the request lock. */
  if (quit || !connection_get_status (conn)) {
    error = ESHUTDOWN;
  }
  else {
    lock_request (conn);
    error = handle_request (conn, cmd, flags, offset, count, buf, extents);
    assert ((int) error >= 0);
    unlock_request (conn);
  }

  /* Send the reply packet. */
 send_reply:
  if (connection_get_status (conn) < 0)
    return -1;

  if (error != 0) {
    /* Since we're about to send only the limited NBD_E* errno to the
     * client, don't lose the information about what really happened
     * on the server side.  Make sure there is a way for the operator
     * to retrieve the real error.
     */
    debug ("sending error reply: %s", strerror (error));
  }

  /* Currently we prefer to send simple replies for everything except
   * where we have to (ie. NBD_CMD_READ and NBD_CMD_BLOCK_STATUS when
   * structured_replies have been negotiated).  However this prevents
   * us from sending human-readable error messages to the client, so
   * we should reconsider this in future.
   */
  if (conn->structured_replies &&
      (cmd == NBD_CMD_READ || cmd == NBD_CMD_BLOCK_STATUS)) {
    if (!error) {
      if (cmd == NBD_CMD_READ)
        return send_structured_reply_read (conn, request.handle, cmd,
                                           buf, count, offset);
      else /* NBD_CMD_BLOCK_STATUS */
        return send_structured_reply_block_status (conn, request.handle,
                                                   cmd, flags,
                                                   count, offset,
                                                   extents);
    }
    else
      return send_structured_reply_error (conn, request.handle, cmd, flags,
                                          error);
  }
  else
    return send_simple_reply (conn, request.handle, cmd, buf, count, error);
}
Example #9
0
static void
_show_contact_presence(ProfChatWin *chatwin)
{
    int bracket_attrs = theme_attrs(THEME_TITLE_BRACKET);
    char *resource = NULL;

    ChatSession *session = chat_session_get(chatwin->barejid);
    if (chatwin->resource_override) {
        resource = chatwin->resource_override;
    } else if (session && session->resource) {
        resource = session->resource;
    }
    if (resource && prefs_get_boolean(PREF_RESOURCE_TITLE)) {
        wprintw(win, "/");
        wprintw(win, resource);
    }

    if (prefs_get_boolean(PREF_PRESENCE)) {
        theme_item_t presence_colour = THEME_TITLE_OFFLINE;
        const char *presence = "offline";

        jabber_conn_status_t conn_status = connection_get_status();
        if (conn_status == JABBER_CONNECTED) {
            PContact contact = roster_get_contact(chatwin->barejid);
            if (contact) {
                if (resource) {
                    Resource *resourcep = p_contact_get_resource(contact, resource);
                    if (resourcep) {
                        presence = string_from_resource_presence(resourcep->presence);
                    }
                } else {
                    presence = p_contact_presence(contact);
                }
            }
        }

        presence_colour = THEME_TITLE_ONLINE;
        if (g_strcmp0(presence, "offline") == 0) {
            presence_colour = THEME_TITLE_OFFLINE;
        } else if (g_strcmp0(presence, "away") == 0) {
            presence_colour = THEME_TITLE_AWAY;
        } else if (g_strcmp0(presence, "xa") == 0) {
            presence_colour = THEME_TITLE_XA;
        } else if (g_strcmp0(presence, "chat") == 0) {
            presence_colour = THEME_TITLE_CHAT;
        } else if (g_strcmp0(presence, "dnd") == 0) {
            presence_colour = THEME_TITLE_DND;
        }

        int presence_attrs = theme_attrs(presence_colour);
        wprintw(win, " ");
        wattron(win, bracket_attrs);
        wprintw(win, "[");
        wattroff(win, bracket_attrs);
        wattron(win, presence_attrs);
        wprintw(win, presence);
        wattroff(win, presence_attrs);
        wattron(win, bracket_attrs);
        wprintw(win, "]");
        wattroff(win, bracket_attrs);
    }
}
Example #10
0
ProfAccount*
accounts_get_account(const char *const name)
{
    if (!g_key_file_has_group(accounts, name)) {
        return NULL;
    } else {
        gchar *jid = g_key_file_get_string(accounts, name, "jid", NULL);

        // fix accounts that have no jid property by setting to name
        if (jid == NULL) {
            g_key_file_set_string(accounts, name, "jid", name);
            _save_accounts();
        }

        gchar *password = g_key_file_get_string(accounts, name, "password", NULL);
        gchar *eval_password = g_key_file_get_string(accounts, name, "eval_password", NULL);
        gboolean enabled = g_key_file_get_boolean(accounts, name, "enabled", NULL);

        gchar *server = g_key_file_get_string(accounts, name, "server", NULL);
        gchar *resource = g_key_file_get_string(accounts, name, "resource", NULL);
        int port = g_key_file_get_integer(accounts, name, "port", NULL);

        gchar *last_presence = g_key_file_get_string(accounts, name, "presence.last", NULL);
        gchar *login_presence = g_key_file_get_string(accounts, name, "presence.login", NULL);

        int priority_online = g_key_file_get_integer(accounts, name, "priority.online", NULL);
        int priority_chat = g_key_file_get_integer(accounts, name, "priority.chat", NULL);
        int priority_away = g_key_file_get_integer(accounts, name, "priority.away", NULL);
        int priority_xa = g_key_file_get_integer(accounts, name, "priority.xa", NULL);
        int priority_dnd = g_key_file_get_integer(accounts, name, "priority.dnd", NULL);

        gchar *muc_service = NULL;
        if (g_key_file_has_key(accounts, name, "muc.service", NULL)) {
            muc_service = g_key_file_get_string(accounts, name, "muc.service", NULL);
        } else {
            jabber_conn_status_t conn_status = connection_get_status();
            if (conn_status == JABBER_CONNECTED) {
                char* conf_jid = connection_jid_for_feature(XMPP_FEATURE_MUC);
                if (conf_jid) {
                    muc_service = strdup(conf_jid);
                }
            }
        }
        gchar *muc_nick = g_key_file_get_string(accounts, name, "muc.nick", NULL);

        gchar *otr_policy = NULL;
        if (g_key_file_has_key(accounts, name, "otr.policy", NULL)) {
            otr_policy = g_key_file_get_string(accounts, name, "otr.policy", NULL);
        }

        gsize length;
        GList *otr_manual = NULL;
        gchar **manual = g_key_file_get_string_list(accounts, name, "otr.manual", &length, NULL);
        if (manual) {
            int i = 0;
            for (i = 0; i < length; i++) {
                otr_manual = g_list_append(otr_manual, strdup(manual[i]));
            }
            g_strfreev(manual);
        }

        GList *otr_opportunistic = NULL;
        gchar **opportunistic = g_key_file_get_string_list(accounts, name, "otr.opportunistic", &length, NULL);
        if (opportunistic) {
            int i = 0;
            for (i = 0; i < length; i++) {
                otr_opportunistic = g_list_append(otr_opportunistic, strdup(opportunistic[i]));
            }
            g_strfreev(opportunistic);
        }

        GList *otr_always = NULL;
        gchar **always = g_key_file_get_string_list(accounts, name, "otr.always", &length, NULL);
        if (always) {
            int i = 0;
            for (i = 0; i < length; i++) {
                otr_always = g_list_append(otr_always, strdup(always[i]));
            }
            g_strfreev(always);
        }

        gchar *pgp_keyid = NULL;
        if (g_key_file_has_key(accounts, name, "pgp.keyid", NULL)) {
            pgp_keyid = g_key_file_get_string(accounts, name, "pgp.keyid", NULL);
        }

        gchar *startscript = NULL;
        if (g_key_file_has_key(accounts, name, "script.start", NULL)) {
            startscript = g_key_file_get_string(accounts, name, "script.start", NULL);
        }

        gchar *theme = NULL;
        if (g_key_file_has_key(accounts, name, "theme", NULL)) {
            theme = g_key_file_get_string(accounts, name, "theme", NULL);
        }

        gchar *tls_policy = g_key_file_get_string(accounts, name, "tls.policy", NULL);
        if (tls_policy && ((g_strcmp0(tls_policy, "force") != 0) &&
                (g_strcmp0(tls_policy, "allow") != 0) &&
                (g_strcmp0(tls_policy, "disable") != 0) &&
                (g_strcmp0(tls_policy, "legacy") != 0))) {
            g_free(tls_policy);
            tls_policy = NULL;
        }

        ProfAccount *new_account = account_new(name, jid, password, eval_password, enabled,
            server, port, resource, last_presence, login_presence,
            priority_online, priority_chat, priority_away, priority_xa,
            priority_dnd, muc_service, muc_nick, otr_policy, otr_manual,
            otr_opportunistic, otr_always, pgp_keyid, startscript, theme, tls_policy);

        g_free(jid);
        g_free(password);
        g_free(eval_password);
        g_free(server);
        g_free(resource);
        g_free(last_presence);
        g_free(login_presence);
        g_free(muc_service);
        g_free(muc_nick);
        g_free(otr_policy);
        g_free(pgp_keyid);
        g_free(startscript);
        g_free(theme);
        g_free(tls_policy);

        return new_account;
    }
}
Example #11
0
void
presence_send(const resource_presence_t presence_type, const int idle, char *signed_status)
{
    if (connection_get_status() != JABBER_CONNECTED) {
        log_warning("Error setting presence, not connected.");
        return;
    }

    char *msg = connection_get_presence_msg();
    if (msg) {
        log_debug("Updating presence: %s, \"%s\"", string_from_resource_presence(presence_type), msg);
    } else {
        log_debug("Updating presence: %s", string_from_resource_presence(presence_type));
    }

    const int pri = accounts_get_priority_for_presence_type(session_get_account_name(), presence_type);
    connection_set_priority(pri);

    xmpp_ctx_t * const ctx = connection_get_ctx();
    xmpp_stanza_t *presence = xmpp_presence_new(ctx);

    char *id = create_unique_id("presence");
    xmpp_stanza_set_id(presence, id);
    free(id);

    const char *show = stanza_get_presence_string_from_type(presence_type);
    stanza_attach_show(ctx, presence, show);

    stanza_attach_status(ctx, presence, msg);

    if (signed_status) {
        xmpp_stanza_t *x = xmpp_stanza_new(ctx);
        xmpp_stanza_set_name(x, STANZA_NAME_X);
        xmpp_stanza_set_ns(x, STANZA_NS_SIGNED);

        xmpp_stanza_t *signed_text = xmpp_stanza_new(ctx);
        xmpp_stanza_set_text(signed_text, signed_status);

        xmpp_stanza_add_child(x, signed_text);
        xmpp_stanza_release(signed_text);

        xmpp_stanza_add_child(presence, x);
        xmpp_stanza_release(x);
    }

    stanza_attach_priority(ctx, presence, pri);

    if (idle > 0) {
        stanza_attach_last_activity(ctx, presence, idle);
    }

    stanza_attach_caps(ctx, presence);

    _send_presence_stanza(presence);
    _send_room_presence(presence);

    xmpp_stanza_release(presence);

    // set last presence for account
    const char *last = show;
    if (last == NULL) {
        last = STANZA_TEXT_ONLINE;
    }

    char *account = session_get_account_name();
    accounts_set_last_presence(account, last);
    accounts_set_last_status(account, msg);
}