about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/command/command.c2
-rw-r--r--src/command/commands.c68
-rw-r--r--src/config/accounts.c19
-rw-r--r--src/config/accounts.h4
-rw-r--r--src/xmpp/connection.c22
-rw-r--r--src/xmpp/xmpp.h2
6 files changed, 102 insertions, 15 deletions
diff --git a/src/command/command.c b/src/command/command.c
index e1833ede..8fe4f90e 100644
--- a/src/command/command.c
+++ b/src/command/command.c
@@ -99,7 +99,7 @@ static struct cmd_t command_defs[] =
           NULL  } } },
 
     { "/connect",
-        cmd_connect, parse_args, 1, 2, NULL,
+        cmd_connect, parse_args, 1, 5, NULL,
         { "/connect account [server]", "Login to a chat service.",
         { "/connect account [server]",
           "-------------------------",
diff --git a/src/command/commands.c b/src/command/commands.c
index b1bbfce8..8a6f6d7b 100644
--- a/src/command/commands.c
+++ b/src/command/commands.c
@@ -69,10 +69,72 @@ cmd_connect(gchar **args, struct cmd_help_t help)
         result = TRUE;
     } else {
         char *user = args[0];
-        char *altdomain = args[1];
+        char *opt1 = args[1];
+        char *opt1val = args[2];
+        char *opt2 = args[3];
+        char *opt2val = args[4];
         char *lower = g_utf8_strdown(user, -1);
         char *jid;
 
+        // parse options
+        char *altdomain = NULL;
+        int port = 0;
+        gboolean altdomain_set = FALSE;
+        gboolean port_set = FALSE;
+        if (opt1 != NULL) {
+            if (opt1val == NULL) {
+                cons_show("Usage: %s", help.usage);
+                cons_show("");
+                return TRUE;
+            }
+            if (strcmp(opt1, "server") == 0) {
+                altdomain = opt1val;
+                altdomain_set = TRUE;
+            } else if (strcmp(opt1, "port") == 0) {
+                if (_strtoi(opt1val, &port, 1, 65536) != 0) {
+                    port = 0;
+                    cons_show("Port must be in the range 1 to 65535.");
+                } else {
+                    port_set = TRUE;
+                }
+            } else {
+                cons_show("Usage: %s", help.usage);
+                cons_show("");
+                return TRUE;
+            }
+
+            if (opt2 != NULL) {
+                if (opt2val == NULL) {
+                    cons_show("Usage: %s", help.usage);
+                    cons_show("");
+                    return TRUE;
+                }
+                if (strcmp(opt2, "server") == 0) {
+                    if (altdomain_set) {
+                        cons_show("Usage: %s", help.usage);
+                        return TRUE;
+                    }
+                    altdomain = opt2val;
+                    altdomain_set = TRUE;
+                } else if (strcmp(opt2, "port") == 0) {
+                    if (port_set) {
+                        cons_show("Usage: %s", help.usage);
+                        return TRUE;
+                    }
+                    if (_strtoi(opt2val, &port, 1, 65536) != 0) {
+                        port = 0;
+                        cons_show("Port must be in the range 1 to 65535.");
+                    } else {
+                        port_set = TRUE;
+                    }
+                } else {
+                    cons_show("Usage: %s", help.usage);
+                    cons_show("");
+                    return TRUE;
+                }
+            }
+        }
+
         ProfAccount *account = accounts_get_account(lower);
         if (account != NULL) {
             jid = accounts_create_full_jid(account);
@@ -86,7 +148,7 @@ cmd_connect(gchar **args, struct cmd_help_t help)
             char *passwd = ui_ask_password();
             jid = strdup(lower);
             cons_show("Connecting as %s", jid);
-            conn_status = jabber_connect_with_details(jid, passwd, altdomain);
+            conn_status = jabber_connect_with_details(jid, passwd, altdomain, port);
             free(passwd);
         }
         g_free(lower);
@@ -140,7 +202,7 @@ cmd_account(gchar **args, struct cmd_help_t help)
         if (account_name == NULL) {
             cons_show("Usage: %s", help.usage);
         } else {
-            accounts_add(account_name, NULL);
+            accounts_add(account_name, NULL, 0);
             cons_show("Account created.");
             cons_show("");
         }
diff --git a/src/config/accounts.c b/src/config/accounts.c
index 2270e874..178f726f 100644
--- a/src/config/accounts.c
+++ b/src/config/accounts.c
@@ -43,6 +43,7 @@ static Autocomplete enabled_ac;
 static gchar *string_keys[] = {
     "jid",
     "server",
+    "port",
     "resource",
     "password",
     "presence.last",
@@ -118,7 +119,7 @@ _accounts_reset_enabled_search(void)
 }
 
 static void
-_accounts_add(const char *account_name, const char *altdomain)
+_accounts_add(const char *account_name, const char *altdomain, int port)
 {
     // set account name and resource
     const char *barejid = account_name;
@@ -139,6 +140,9 @@ _accounts_add(const char *account_name, const char *altdomain)
         if (altdomain != NULL) {
             g_key_file_set_string(accounts, account_name, "server", altdomain);
         }
+        if (port != 0) {
+            g_key_file_set_integer(accounts, account_name, "port", port);
+        }
 
         Jid *jidp = jid_create(barejid);
         GString *muc_service = g_string_new("conference.");
@@ -211,6 +215,9 @@ _accounts_get_account(const char * const name)
             account->server = NULL;
         }
 
+        int port = g_key_file_get_integer(accounts, name, "port", NULL);
+        account->port = port;
+
         gchar *resource = g_key_file_get_string(accounts, name, "resource", NULL);
         if (resource != NULL) {
             account->resource = strdup(resource);
@@ -436,6 +443,15 @@ _accounts_set_server(const char * const account_name, const char * const value)
 }
 
 static void
+_accounts_set_port(const char * const account_name, const int value)
+{
+    if (value != 0) {
+        g_key_file_set_integer(accounts, account_name, "port", value);
+        _save_accounts();
+    }
+}
+
+static void
 _accounts_set_resource(const char * const account_name, const char * const value)
 {
     if (accounts_account_exists(account_name)) {
@@ -736,6 +752,7 @@ accounts_init_module(void)
     accounts_account_exists = _accounts_account_exists;
     accounts_set_jid = _accounts_set_jid;
     accounts_set_server = _accounts_set_server;
+    accounts_set_port = _accounts_set_port;
     accounts_set_resource = _accounts_set_resource;
     accounts_set_password = _accounts_set_password;
     accounts_set_muc_service = _accounts_set_muc_service;
diff --git a/src/config/accounts.h b/src/config/accounts.h
index ccccefdf..8f7b5c37 100644
--- a/src/config/accounts.h
+++ b/src/config/accounts.h
@@ -33,6 +33,7 @@ typedef struct prof_account_t {
     gchar *password;
     gchar *resource;
     gchar *server;
+    int port;
     gchar *last_presence;
     gchar *login_presence;
     gint priority_online;
@@ -55,7 +56,7 @@ char * (*accounts_find_all)(char *prefix);
 char * (*accounts_find_enabled)(char *prefix);
 void (*accounts_reset_all_search)(void);
 void (*accounts_reset_enabled_search)(void);
-void (*accounts_add)(const char *jid, const char *altdomain);
+void (*accounts_add)(const char *jid, const char *altdomain, int port);
 gchar** (*accounts_get_list)(void);
 ProfAccount* (*accounts_get_account)(const char * const name);
 void (*accounts_free_account)(ProfAccount *account);
@@ -66,6 +67,7 @@ gboolean (*accounts_rename)(const char * const account_name,
 gboolean (*accounts_account_exists)(const char * const account_name);
 void (*accounts_set_jid)(const char * const account_name, const char * const value);
 void (*accounts_set_server)(const char * const account_name, const char * const value);
+void (*accounts_set_port)(const char * const account_name, const int value);
 void (*accounts_set_resource)(const char * const account_name, const char * const value);
 void (*accounts_set_password)(const char * const account_name, const char * const value);
 void (*accounts_set_muc_service)(const char * const account_name, const char * const value);
diff --git a/src/xmpp/connection.c b/src/xmpp/connection.c
index ad447767..dc015dd6 100644
--- a/src/xmpp/connection.c
+++ b/src/xmpp/connection.c
@@ -68,6 +68,7 @@ static struct {
     char *jid;
     char *passwd;
     char *altdomain;
+    int port;
 } saved_details;
 
 static GTimer *reconnect_timer;
@@ -80,7 +81,7 @@ static void _xmpp_file_logger(void * const userdata,
 static xmpp_log_t * _xmpp_get_file_logger();
 
 static jabber_conn_status_t _jabber_connect(const char * const fulljid,
-    const char * const passwd, const char * const altdomain);
+    const char * const passwd, const char * const altdomain, int port);
 static void _jabber_reconnect(void);
 
 static void _connection_handler(xmpp_conn_t * const conn,
@@ -123,7 +124,7 @@ _jabber_connect_with_account(const ProfAccount * const account)
     // connect with fulljid
     Jid *jidp = jid_create_from_bare_and_resource(account->jid, account->resource);
     jabber_conn_status_t result =
-      _jabber_connect(jidp->fulljid, account->password, account->server);
+      _jabber_connect(jidp->fulljid, account->password, account->server, account->port);
     jid_destroy(jidp);
 
     return result;
@@ -131,7 +132,7 @@ _jabber_connect_with_account(const ProfAccount * const account)
 
 static jabber_conn_status_t
 _jabber_connect_with_details(const char * const jid,
-    const char * const passwd, const char * const altdomain)
+    const char * const passwd, const char * const altdomain, int port)
 {
     assert(jid != NULL);
     assert(passwd != NULL);
@@ -144,6 +145,11 @@ _jabber_connect_with_details(const char * const jid,
     } else {
         saved_details.altdomain = NULL;
     }
+    if (port != 0) {
+        saved_details.port = port;
+    } else {
+        saved_details.port = 0;
+    }
 
     // use 'profanity' when no resourcepart in provided jid
     Jid *jidp = jid_create(jid);
@@ -158,7 +164,7 @@ _jabber_connect_with_details(const char * const jid,
 
     // connect with fulljid
     log_info("Connecting without account, JID: %s", saved_details.jid);
-    return _jabber_connect(saved_details.jid, passwd, saved_details.altdomain);
+    return _jabber_connect(saved_details.jid, passwd, saved_details.altdomain, saved_details.port);
 }
 
 static void
@@ -377,7 +383,7 @@ connection_error_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza,
 
 static jabber_conn_status_t
 _jabber_connect(const char * const fulljid, const char * const passwd,
-    const char * const altdomain)
+    const char * const altdomain, int port)
 {
     assert(fulljid != NULL);
     assert(passwd != NULL);
@@ -421,7 +427,7 @@ _jabber_connect(const char * const fulljid, const char * const passwd,
         xmpp_conn_disable_tls(jabber_conn.conn);
     }
 
-    int connect_status = xmpp_connect_client(jabber_conn.conn, altdomain, 0,
+    int connect_status = xmpp_connect_client(jabber_conn.conn, altdomain, port,
         _connection_handler, jabber_conn.ctx);
 
     if (connect_status == 0)
@@ -443,7 +449,7 @@ _jabber_reconnect(void)
     } else {
         char *fulljid = create_fulljid(account->jid, account->resource);
         log_debug("Attempting reconnect with account %s", account->name);
-        _jabber_connect(fulljid, saved_account.passwd, account->server);
+        _jabber_connect(fulljid, saved_account.passwd, account->server, account->port);
         free(fulljid);
         g_timer_start(reconnect_timer);
     }
@@ -468,7 +474,7 @@ _connection_handler(xmpp_conn_t * const conn,
         // 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);
+            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);
diff --git a/src/xmpp/xmpp.h b/src/xmpp/xmpp.h
index 87cde006..86f585e4 100644
--- a/src/xmpp/xmpp.h
+++ b/src/xmpp/xmpp.h
@@ -85,7 +85,7 @@ void roster_init_module(void);
 // connection functions
 void (*jabber_init)(const int disable_tls);
 jabber_conn_status_t (*jabber_connect_with_details)(const char * const jid,
-    const char * const passwd, const char * const altdomain);
+    const char * const passwd, const char * const altdomain, int port);
 jabber_conn_status_t (*jabber_connect_with_account)(const ProfAccount * const account);
 void (*jabber_disconnect)(void);
 void (*jabber_shutdown)(void);