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; }
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); } }
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; }
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); } }
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); } }
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(); }
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."); } }
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); }
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); } }
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; } }
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); }