diff --git a/src/accounts.c b/src/accounts.c index 7a84397b..f471fbdb 100644 --- a/src/accounts.c +++ b/src/accounts.c @@ -24,6 +24,8 @@ #include #include + +#include "accounts.h" #include "files.h" #include "log.h" #include "prof_autocomplete.h" @@ -108,6 +110,54 @@ accounts_get_list(void) return g_key_file_get_groups(accounts, NULL); } +ProfAccount* +accounts_get_account(const char * const name) +{ + if (!g_key_file_has_group(accounts, name)) { + return NULL; + } else { + ProfAccount *account = malloc(sizeof(ProfAccount)); + account->name = strdup(name); + gchar *jid = g_key_file_get_string(accounts, name, "jid", NULL); + if (jid != NULL) { + account->jid = strdup(jid); + } else { + account->jid = strdup(name); + g_key_file_set_string(accounts, name, "jid", name); + _save_accounts(); + } + account->enabled = g_key_file_get_boolean(accounts, name, "enabled", NULL); + gchar *server = g_key_file_get_string(accounts, name, "server", NULL); + if (server != NULL) { + account->server = strdup(server); + } else { + account->server = NULL; + } + + return account; + } +} + +void +accounts_free_account(ProfAccount *account) +{ + if (account != NULL) { + if (account->name != NULL) { + free(account->name); + account->name = NULL; + } + if (account->jid != NULL) { + free(account->jid); + account->jid = NULL; + } + if (account->server != NULL) { + free(account->server); + account->server = NULL; + } + account = NULL; + } +} + static void _save_accounts(void) { diff --git a/src/accounts.h b/src/accounts.h index e8f34bbe..5d8c6460 100644 --- a/src/accounts.h +++ b/src/accounts.h @@ -23,6 +23,13 @@ #ifndef ACCOUNTS_H #define ACCOUNTS_H +typedef struct prof_account_t { + gchar *name; + gchar *jid; + gchar *server; + gboolean enabled; +} ProfAccount; + void accounts_load(void); void accounts_close(void); @@ -30,5 +37,7 @@ char * accounts_find_login(char *prefix); void accounts_reset_login_search(void); void accounts_add_login(const char *jid, const char *altdomain); gchar** accounts_get_list(void); +ProfAccount* accounts_get_account(const char * const name); +void accounts_free_account(ProfAccount *account); #endif diff --git a/src/command.c b/src/command.c index 21457e4f..b57ed0b8 100644 --- a/src/command.c +++ b/src/command.c @@ -910,6 +910,7 @@ _cmd_connect(gchar **args, struct cmd_help_t help) char *user = args[0]; char *altdomain = args[1]; char *lower = g_utf8_strdown(user, -1); + char *jid; status_bar_get_password(); status_bar_refresh(); @@ -918,18 +919,29 @@ _cmd_connect(gchar **args, struct cmd_help_t help) inp_get_password(passwd); inp_non_block(); - log_debug("Connecting as %s", lower); + ProfAccount *account = accounts_get_account(lower); + if (account != NULL) { + jid = strdup(account->jid); + log_debug("Connecting as %s", jid); + conn_status = jabber_connect_with_account(account, passwd); + } else { + jid = strdup(lower); + log_debug("Connecting as %s", jid); + conn_status = jabber_connect(jid, passwd, altdomain); + } - conn_status = jabber_connect(lower, passwd, altdomain); if (conn_status == JABBER_CONNECTING) { cons_show("Connecting..."); log_debug("Connecting..."); } if (conn_status == JABBER_DISCONNECTED) { cons_bad_show("Connection to server failed."); - log_debug("Connection using %s failed", lower); + log_debug("Connection for %s failed", jid); } + accounts_free_account(account); + free(jid); + result = TRUE; } diff --git a/src/jabber.c b/src/jabber.c index 93affb80..cdb29d15 100644 --- a/src/jabber.c +++ b/src/jabber.c @@ -47,6 +47,7 @@ static struct _jabber_conn_t { } jabber_conn; // for auto reconnect +static char *saved_account; static char *saved_user; static char *saved_password; static char *saved_altdomain; @@ -102,6 +103,46 @@ jabber_restart(void) jabber_conn.status = NULL; } +jabber_conn_status_t +jabber_connect_with_account(ProfAccount *account, const char * const passwd) +{ + saved_account = strdup(account->name); + if (saved_user == NULL) { + saved_user = strdup(account->jid); + } + if (saved_password == NULL) { + saved_password = strdup(passwd); + } + if (saved_altdomain == NULL) { + if (account->server != NULL) { + saved_altdomain = strdup(account->server); + } + } + + log_info("Connecting with account:%s, jid: %s", account->name, account->jid); + xmpp_initialize(); + + jabber_conn.log = _xmpp_get_file_logger(); + jabber_conn.ctx = xmpp_ctx_new(NULL, jabber_conn.log); + jabber_conn.conn = xmpp_conn_new(jabber_conn.ctx); + + xmpp_conn_set_jid(jabber_conn.conn, account->jid); + xmpp_conn_set_pass(jabber_conn.conn, passwd); + + if (jabber_conn.tls_disabled) + xmpp_conn_disable_tls(jabber_conn.conn); + + int connect_status = xmpp_connect_client(jabber_conn.conn, account->server, 0, + _connection_handler, jabber_conn.ctx); + + if (connect_status == 0) + jabber_conn.conn_status = JABBER_CONNECTING; + else + jabber_conn.conn_status = JABBER_DISCONNECTED; + + return jabber_conn.conn_status; +} + jabber_conn_status_t jabber_connect(const char * const user, const char * const passwd, const char * const altdomain) @@ -697,8 +738,13 @@ _connection_handler(xmpp_conn_t * const conn, // login success if (status == XMPP_CONN_CONNECT) { - const char *jid = xmpp_conn_get_jid(conn); - prof_handle_login_success(jid, saved_altdomain); + if (saved_account != NULL) { + prof_handle_login_account_success(saved_account); + } else { + const char *jid = xmpp_conn_get_jid(conn); + prof_handle_login_success(jid, saved_altdomain); + } + chat_sessions_init(); xmpp_handler_add(conn, _message_handler, NULL, STANZA_NAME_MESSAGE, NULL, ctx); diff --git a/src/jabber.h b/src/jabber.h index 31a1c20e..6a5cd19d 100644 --- a/src/jabber.h +++ b/src/jabber.h @@ -23,6 +23,8 @@ #ifndef JABBER_H #define JABBER_H +#include "accounts.h" + typedef enum { JABBER_STARTED, JABBER_CONNECTING, @@ -49,6 +51,8 @@ typedef enum { void jabber_init(const int disable_tls); jabber_conn_status_t jabber_connect(const char * const user, const char * const passwd, const char * const altdomain); +jabber_conn_status_t jabber_connect_with_account(ProfAccount *account, + const char * const passwd); void jabber_disconnect(void); void jabber_process_events(void); void jabber_join(const char * const room, const char * const nick); diff --git a/src/profanity.c b/src/profanity.c index c751b524..ebecd309 100644 --- a/src/profanity.c +++ b/src/profanity.c @@ -189,6 +189,22 @@ prof_handle_subscription(const char *from, jabber_subscr_t type) } } +void +prof_handle_login_account_success(char *account_name) +{ + ProfAccount *account = accounts_get_account(account_name); + + const char *msg = "logged in successfully."; + cons_show("%s %s", account->jid, msg); + title_bar_set_status(PRESENCE_ONLINE); + log_info("%s %s", account->jid, msg); + win_current_page_off(); + status_bar_print_message(account->jid); + status_bar_refresh(); + + accounts_free_account(account); +} + void prof_handle_login_success(const char *jid, const char *altdomain) { @@ -199,6 +215,7 @@ prof_handle_login_success(const char *jid, const char *altdomain) win_current_page_off(); status_bar_print_message(jid); status_bar_refresh(); + accounts_add_login(jid, altdomain); } diff --git a/src/profanity.h b/src/profanity.h index ce624f59..6b1f095d 100644 --- a/src/profanity.h +++ b/src/profanity.h @@ -28,6 +28,7 @@ void prof_run(const int disable_tls, char *log_level); void prof_handle_login_success(const char *jid, const char *altdomain); +void prof_handle_login_account_success(char *account_name); void prof_handle_lost_connection(void); void prof_handle_disconnect(const char * const jid); void prof_handle_failed_login(void);