about summary refs log tree commit diff stats
path: root/src/command
diff options
context:
space:
mode:
authorJames Booth <boothj5@gmail.com>2014-09-15 21:33:25 +0100
committerJames Booth <boothj5@gmail.com>2014-09-15 21:33:25 +0100
commit529b4f175b628b34485cf6679326149241723097 (patch)
treee7dae84f9b0571dfa3313a87fd859c86450bc814 /src/command
parentdc103d88d7f9b775926dde8939da26ab585237ed (diff)
downloadprofani-tty-529b4f175b628b34485cf6679326149241723097.tar.gz
Split /room and /form commands
Diffstat (limited to 'src/command')
-rw-r--r--src/command/command.c64
-rw-r--r--src/command/commands.c508
-rw-r--r--src/command/commands.h1
3 files changed, 287 insertions, 286 deletions
diff --git a/src/command/command.c b/src/command/command.c
index 91971911..d0b38f55 100644
--- a/src/command/command.c
+++ b/src/command/command.c
@@ -87,7 +87,7 @@ static char * _statuses_autocomplete(char *input, int *size);
 static char * _alias_autocomplete(char *input, int *size);
 static char * _join_autocomplete(char *input, int *size);
 static char * _log_autocomplete(char *input, int *size);
-static char * _room_autocomplete(char *input, int *size);
+static char * _form_autocomplete(char *input, int *size);
 
 GHashTable *commands = NULL;
 
@@ -306,18 +306,25 @@ static struct cmd_t command_defs[] =
           NULL } } },
 
     { "/room",
-        cmd_room, parse_args, 1, 3, NULL,
-        { "/room config accept|destroy|config|submit|cancel|set|add|remove [tag value]", "Room configuration.",
-        { "/room config accept|destroy|config|submit|cancel|set|add|remove [tag value]",
-          "---------------------------------------------------------------------------",
-          "config accept  - Accept default room configuration.",
-          "config destroy - Cancel default room configuration.",
-          "config config  - Edit room configuration.",
-          "config submit  - Cancel room configuration.",
-          "config cancel  - Cancel room configuration.",
-          "config set tag value    - Set room configuration field to value.",
-          "config add tag value    - Add value to room configuration field.",
-          "config remove tag value - Remove value from room configuration field.",
+        cmd_room, parse_args, 1, 1, NULL,
+        { "/room accept|destroy|config", "Room configuration.",
+        { "/room accept|destroy|config",
+          "---------------------------",
+          "accept  - Accept default room configuration.",
+          "destroy - Reject default room configuration.",
+          "config  - Edit room configuration.",
+          NULL } } },
+
+    { "/form",
+        cmd_form, parse_args, 1, 3, NULL,
+        { "/form submit|cancel|set|add|remove [tag value]", "Form manipulation.",
+        { "/form submit|cancel|set|add|remove [tag value]",
+          "----------------------------------------------",
+          "set tag value    - Set tagged form field to value.",
+          "add tag value    - Add value to tagged form field.",
+          "remove tag value - Remove value from tagged form field.",
+          "submit           - Submit the current form.",
+          "cancel           - Cancel changes to the current form.",
           NULL } } },
 
     { "/rooms",
@@ -961,6 +968,7 @@ static Autocomplete alias_ac;
 static Autocomplete aliases_ac;
 static Autocomplete join_property_ac;
 static Autocomplete room_ac;
+static Autocomplete form_ac;
 
 /*
  * Initialise command autocompleter and history
@@ -1216,11 +1224,13 @@ cmd_init(void)
     autocomplete_add(room_ac, "accept");
     autocomplete_add(room_ac, "destroy");
     autocomplete_add(room_ac, "config");
-    autocomplete_add(room_ac, "submit");
-    autocomplete_add(room_ac, "cancel");
-    autocomplete_add(room_ac, "set");
-    autocomplete_add(room_ac, "add");
-    autocomplete_add(room_ac, "remove");
+
+    form_ac = autocomplete_new();
+    autocomplete_add(form_ac, "submit");
+    autocomplete_add(form_ac, "cancel");
+    autocomplete_add(form_ac, "set");
+    autocomplete_add(form_ac, "add");
+    autocomplete_add(form_ac, "remove");
 
     cmd_history_init();
 }
@@ -1266,6 +1276,7 @@ cmd_uninit(void)
     autocomplete_free(aliases_ac);
     autocomplete_free(join_property_ac);
     autocomplete_free(room_ac);
+    autocomplete_free(form_ac);
 }
 
 gboolean
@@ -1390,6 +1401,7 @@ cmd_reset_autocomplete()
     autocomplete_reset(aliases_ac);
     autocomplete_reset(join_property_ac);
     autocomplete_reset(room_ac);
+    autocomplete_reset(form_ac);
     bookmark_autocomplete_reset();
 }
 
@@ -1639,8 +1651,8 @@ _cmd_complete_parameters(char *input, int *size)
         }
     }
 
-    gchar *cmds[] = { "/help", "/prefs", "/disco", "/close", "/wins" };
-    Autocomplete completers[] = { help_ac, prefs_ac, disco_ac, close_ac, wins_ac };
+    gchar *cmds[] = { "/help", "/prefs", "/disco", "/close", "/wins", "/room" };
+    Autocomplete completers[] = { help_ac, prefs_ac, disco_ac, close_ac, wins_ac, room_ac };
 
     for (i = 0; i < ARRAY_SIZE(cmds); i++) {
         result = autocomplete_param_with_ac(input, size, cmds[i], completers[i], TRUE);
@@ -1668,7 +1680,7 @@ _cmd_complete_parameters(char *input, int *size)
     g_hash_table_insert(ac_funcs, "/statuses",      _statuses_autocomplete);
     g_hash_table_insert(ac_funcs, "/alias",         _alias_autocomplete);
     g_hash_table_insert(ac_funcs, "/join",          _join_autocomplete);
-    g_hash_table_insert(ac_funcs, "/room",          _room_autocomplete);
+    g_hash_table_insert(ac_funcs, "/form",          _form_autocomplete);
 
     char parsed[*size+1];
     i = 0;
@@ -2079,7 +2091,7 @@ _theme_autocomplete(char *input, int *size)
 }
 
 static char *
-_room_autocomplete(char *input, int *size)
+_form_autocomplete(char *input, int *size)
 {
     char *result = NULL;
 
@@ -2087,22 +2099,22 @@ _room_autocomplete(char *input, int *size)
     if (current != NULL) {
         DataForm *form = current->form;
         if (form != NULL) {
-            result = autocomplete_param_with_ac(input, size, "/room set", form->tag_ac, TRUE);
+            result = autocomplete_param_with_ac(input, size, "/form set", form->tag_ac, TRUE);
             if (result != NULL) {
                 return result;
             }
-            result = autocomplete_param_with_ac(input, size, "/room add", form->tag_ac, TRUE);
+            result = autocomplete_param_with_ac(input, size, "/form add", form->tag_ac, TRUE);
             if (result != NULL) {
                 return result;
             }
-            result = autocomplete_param_with_ac(input, size, "/room remove", form->tag_ac, TRUE);
+            result = autocomplete_param_with_ac(input, size, "/form remove", form->tag_ac, TRUE);
             if (result != NULL) {
                 return result;
             }
         }
     }
 
-    result = autocomplete_param_with_ac(input, size, "/room", room_ac, TRUE);
+    result = autocomplete_param_with_ac(input, size, "/form", form_ac, TRUE);
     if (result != NULL) {
         return result;
     }
diff --git a/src/command/commands.c b/src/command/commands.c
index ed4cd153..20668eb5 100644
--- a/src/command/commands.c
+++ b/src/command/commands.c
@@ -1788,7 +1788,7 @@ cmd_decline(gchar **args, struct cmd_help_t help)
 }
 
 gboolean
-cmd_room(gchar **args, struct cmd_help_t help)
+cmd_form(gchar **args, struct cmd_help_t help)
 {
     jabber_conn_status_t conn_status = jabber_get_connection_status();
 
@@ -1797,310 +1797,298 @@ cmd_room(gchar **args, struct cmd_help_t help)
         return TRUE;
     }
 
-    // room command allowed in window
     win_type_t win_type = ui_current_win_type();
-    if (win_type != WIN_MUC && win_type != WIN_MUC_CONFIG) {
-        cons_show("Command '/room' does not apply to this window.");
+    if (win_type != WIN_MUC_CONFIG) {
+        cons_show("Command '/form' does not apply to this window.");
         return TRUE;
     }
 
-    // validate subcommand
-    if ((g_strcmp0(args[0], "accept") != 0) &&
-            (g_strcmp0(args[0], "destroy") != 0) &&
-            (g_strcmp0(args[0], "config") != 0) &&
-            (g_strcmp0(args[0], "submit") != 0) &&
+    if ((g_strcmp0(args[0], "submit") != 0) &&
+            (g_strcmp0(args[0], "cancel") != 0) &&
             (g_strcmp0(args[0], "set") != 0) &&
             (g_strcmp0(args[0], "add") != 0) &&
-            (g_strcmp0(args[0], "remove") != 0) &&
-            (g_strcmp0(args[0], "cancel") != 0)) {
+            (g_strcmp0(args[0], "remove") != 0)) {
         cons_show("Usage: %s", help.usage);
         return TRUE;
     }
 
-    // validate subcommand for window type
-    if (win_type == WIN_MUC &&
-            ((g_strcmp0(args[0], "submit") == 0) ||
-            (g_strcmp0(args[0], "cancel") == 0) ||
-            (g_strcmp0(args[0], "add") == 0) ||
-            (g_strcmp0(args[0], "remove") == 0) ||
-            (g_strcmp0(args[0], "set") == 0))) {
-        cons_show("Command '/room %s' only allowed in room configuration windows.", args[0]);
-        return TRUE;
-    }
-    if (win_type == WIN_MUC_CONFIG &&
-            ((g_strcmp0(args[0], "accept") == 0) ||
-            (g_strcmp0(args[0], "destroy") == 0) ||
-            (g_strcmp0(args[0], "config") == 0))) {
-        cons_show("Command '/room %s' only allowed in chat room windows.", args[0]);
-        return TRUE;
-    }
-
-    char *room = ui_current_recipient();
-    ProfWin *window = wins_get_by_recipient(room);
-    int num = wins_get_num(window);
+    char *recipient = ui_current_recipient();
+    ProfWin *current = wins_get_current();
+    gchar **split_recipient = g_strsplit(recipient, " ", 2);
+    char *room = split_recipient[0];
 
-    // commands available in room
-    if ((g_strcmp0(args[0], "accept") == 0) ||
-            (g_strcmp0(args[0], "destroy") == 0) ||
-            (g_strcmp0(args[0], "config") == 0)) {
+    if (g_strcmp0(args[0], "submit") == 0) {
+        iq_submit_room_config(room, current->form);
 
-        int ui_index = num;
-        if (ui_index == 10) {
-            ui_index = 0;
-        }
-
-        if (g_strcmp0(args[0], "accept") == 0) {
-            gboolean requires_config = muc_requires_config(room);
-            if (!requires_config) {
-                win_save_vprint(window, '!', NULL, 0, COLOUR_ROOMINFO, "", "Current room does not require configuration.");
-                return TRUE;
-            } else {
-                iq_confirm_instant_room(room);
-                muc_set_requires_config(room, FALSE);
-                win_save_vprint(window, '!', NULL, 0, COLOUR_ROOMINFO, "", "Room unlocked.");
-                cons_show("Room unlocked: %s (%d)", room, ui_index);
-                return TRUE;
-            }
-        }
-
-        if (g_strcmp0(args[0], "destroy") == 0) {
-            iq_destroy_instant_room(room);
+    }
+    if (g_strcmp0(args[0], "cancel") == 0) {
+        iq_room_config_cancel(room);
+    }
+    if (g_strcmp0(args[0], "set") == 0) {
+        char *tag = NULL;
+        char *value = NULL;
+        if (args[1] != NULL) {
+            tag = args[1];
+        } else {
+            ui_current_print_line("/room set command requires a field tag and value");
+            g_strfreev(split_recipient);
             return TRUE;
         }
-
-        if (g_strcmp0(args[0], "config") == 0) {
-            GString *win_title = g_string_new(room);
-            g_string_append(win_title, " config");
-            ProfWin *window = wins_get_by_recipient(win_title->str);
-            g_string_free(win_title, TRUE);
-            if (window != NULL) {
-                num = wins_get_num(window);
-                ui_switch_win(num);
-            } else {
-                iq_request_room_config_form(room);
-            }
+        if (args[2] != NULL) {
+            value = args[2];
+        } else {
+            ui_current_print_line("/room set command requires a field tag and value");
+            g_strfreev(split_recipient);
             return TRUE;
         }
-    }
-
-    // commands allowed in room config
-    if ((g_strcmp0(args[0], "submit") == 0) ||
-            (g_strcmp0(args[0], "cancel") == 0) ||
-            (g_strcmp0(args[0], "add") == 0) ||
-            (g_strcmp0(args[0], "remove") == 0) ||
-            (g_strcmp0(args[0], "set") == 0)) {
-
-        ProfWin *current = wins_get_current();
-        gchar **split_recipient = g_strsplit(room, " ", 2);
-        room = split_recipient[0];
-
-        if (g_strcmp0(args[0], "submit") == 0) {
-            iq_submit_room_config(room, current->form);
-
-        }
-        if (g_strcmp0(args[0], "cancel") == 0) {
-            iq_room_config_cancel(room);
-        }
-        if (g_strcmp0(args[0], "set") == 0) {
-            char *tag = NULL;
-            char *value = NULL;
-            if (args[1] != NULL) {
-                tag = args[1];
-            } else {
-                ui_current_print_line("/room set command requires a field tag and value");
-                g_strfreev(split_recipient);
-                return TRUE;
-            }
-            if (args[2] != NULL) {
-                value = args[2];
-            } else {
-                ui_current_print_line("/room set command requires a field tag and value");
-                g_strfreev(split_recipient);
-                return TRUE;
-            }
-            if (!form_tag_exists(current->form, tag)) {
-                ui_current_print_line("Form does not contain a field with tag %s", tag);
-            } else {
-                form_field_type_t field_type = form_get_field_type(current->form, tag);
-                gboolean valid = FALSE;
-                switch (field_type) {
-                case FIELD_TEXT_SINGLE:
-                case FIELD_TEXT_PRIVATE:
-                case FIELD_JID_SINGLE:
+        if (!form_tag_exists(current->form, tag)) {
+            ui_current_print_line("Form does not contain a field with tag %s", tag);
+        } else {
+            form_field_type_t field_type = form_get_field_type(current->form, tag);
+            gboolean valid = FALSE;
+            switch (field_type) {
+            case FIELD_TEXT_SINGLE:
+            case FIELD_TEXT_PRIVATE:
+            case FIELD_JID_SINGLE:
+                form_set_value(current->form, tag, value);
+                ui_current_print_line("%s set to %s", tag, value);
+                break;
+            case FIELD_BOOLEAN:
+                if (g_strcmp0(value, "on") == 0) {
+                    form_set_value(current->form, tag, "1");
+                    ui_current_print_line("%s set to %s", tag, value);
+                } else if (g_strcmp0(value, "off") == 0) {
+                    form_set_value(current->form, tag, "0");
+                    ui_current_print_line("%s set to %s", tag, value);
+                } else {
+                    ui_current_print_line("Value %s not valid for boolean field: %s", value, tag);
+                }
+                break;
+            case FIELD_LIST_SINGLE:
+                valid = form_field_contains_option(current->form, tag, value);
+                if (valid == TRUE) {
                     form_set_value(current->form, tag, value);
                     ui_current_print_line("%s set to %s", tag, value);
-                    break;
-                case FIELD_BOOLEAN:
-                    if (g_strcmp0(value, "on") == 0) {
-                        form_set_value(current->form, tag, "1");
-                        ui_current_print_line("%s set to %s", tag, value);
-                    } else if (g_strcmp0(value, "off") == 0) {
-                        form_set_value(current->form, tag, "0");
-                        ui_current_print_line("%s set to %s", tag, value);
-                    } else {
-                        ui_current_print_line("Value %s not valid for boolean field: %s", value, tag);
-                    }
-                    break;
-                case FIELD_LIST_SINGLE:
-                    valid = form_field_contains_option(current->form, tag, value);
-                    if (valid == TRUE) {
-                        form_set_value(current->form, tag, value);
-                        ui_current_print_line("%s set to %s", tag, value);
-                    } else {
-                        ui_current_print_line("Value %s not a valid option for field: %s", value, tag);
-                    }
-                    break;
-                default:
-                    ui_current_print_line("Set command not valid for field: %s", tag);
-                    break;
+                } else {
+                    ui_current_print_line("Value %s not a valid option for field: %s", value, tag);
                 }
+                break;
+            default:
+                ui_current_print_line("Set command not valid for field: %s", tag);
+                break;
             }
         }
+    }
 
-        if (g_strcmp0(args[0], "add") == 0) {
-            char *tag = NULL;
-            char *value = NULL;
-            if (args[1] != NULL) {
-                tag = args[1];
-            } else {
-                ui_current_print_line("/room add command requires a field tag and value");
-                g_strfreev(split_recipient);
-                return TRUE;
-            }
-            if (args[2] != NULL) {
-                value = args[2];
-            } else {
-                ui_current_print_line("/room add command requires a field tag and value");
-                g_strfreev(split_recipient);
-                return TRUE;
-            }
-            if (!form_tag_exists(current->form, tag)) {
-                ui_current_print_line("Form does not contain a field with tag %s", tag);
-            } else {
-                form_field_type_t field_type = form_get_field_type(current->form, tag);
-                gboolean valid = FALSE;
-                gboolean added = FALSE;
-                switch (field_type) {
-                case FIELD_LIST_MULTI:
-                    valid = form_field_contains_option(current->form, tag, value);
-                    if (valid) {
-                        added = form_add_unique_value(current->form, tag, value);
-                        if (added) {
-                            ui_current_print_line("Added %s to %s", value, tag);
-                        } else {
-                            ui_current_print_line("Value %s already selected for %s", value, tag);
-                        }
-                    } else {
-                        ui_current_print_line("Value %s not a valid option for field: %s", value, tag);
-                    }
-                    break;
-                case FIELD_TEXT_MULTI:
-                    form_add_value(current->form, tag, value);
-                    ui_current_print_line("Added %s to %s", value, tag);
-                    break;
-                case FIELD_JID_MULTI:
+    if (g_strcmp0(args[0], "add") == 0) {
+        char *tag = NULL;
+        char *value = NULL;
+        if (args[1] != NULL) {
+            tag = args[1];
+        } else {
+            ui_current_print_line("/room add command requires a field tag and value");
+            g_strfreev(split_recipient);
+            return TRUE;
+        }
+        if (args[2] != NULL) {
+            value = args[2];
+        } else {
+            ui_current_print_line("/room add command requires a field tag and value");
+            g_strfreev(split_recipient);
+            return TRUE;
+        }
+        if (!form_tag_exists(current->form, tag)) {
+            ui_current_print_line("Form does not contain a field with tag %s", tag);
+        } else {
+            form_field_type_t field_type = form_get_field_type(current->form, tag);
+            gboolean valid = FALSE;
+            gboolean added = FALSE;
+            switch (field_type) {
+            case FIELD_LIST_MULTI:
+                valid = form_field_contains_option(current->form, tag, value);
+                if (valid) {
                     added = form_add_unique_value(current->form, tag, value);
                     if (added) {
                         ui_current_print_line("Added %s to %s", value, tag);
                     } else {
-                        ui_current_print_line("JID %s already exists in %s", value, tag);
+                        ui_current_print_line("Value %s already selected for %s", value, tag);
                     }
-                    break;
-                default:
-                    ui_current_print_line("Add command not valid for field: %s", tag);
-                    break;
+                } else {
+                    ui_current_print_line("Value %s not a valid option for field: %s", value, tag);
                 }
+                break;
+            case FIELD_TEXT_MULTI:
+                form_add_value(current->form, tag, value);
+                ui_current_print_line("Added %s to %s", value, tag);
+                break;
+            case FIELD_JID_MULTI:
+                added = form_add_unique_value(current->form, tag, value);
+                if (added) {
+                    ui_current_print_line("Added %s to %s", value, tag);
+                } else {
+                    ui_current_print_line("JID %s already exists in %s", value, tag);
+                }
+                break;
+            default:
+                ui_current_print_line("Add command not valid for field: %s", tag);
+                break;
             }
         }
+    }
 
-        if (g_strcmp0(args[0], "remove") == 0) {
-            char *tag = NULL;
-            char *value = NULL;
-            if (args[1] != NULL) {
-                tag = args[1];
-            } else {
-                ui_current_print_line("/room remove command requires a field tag and value");
-                g_strfreev(split_recipient);
-                return TRUE;
-            }
-            if (args[2] != NULL) {
-                value = args[2];
-            } else {
-                ui_current_print_line("/room remove command requires a field tag and value");
-                g_strfreev(split_recipient);
-                return TRUE;
-            }
-            if (!form_tag_exists(current->form, tag)) {
-                ui_current_print_line("Form does not contain a field with tag %s", tag);
-            } else {
-                form_field_type_t field_type = form_get_field_type(current->form, tag);
-                gboolean valid = FALSE;
-                gboolean removed = FALSE;
-                switch (field_type) {
-                case FIELD_LIST_MULTI:
-                    valid = form_field_contains_option(current->form, tag, value);
-                    if (valid == TRUE) {
-                        removed = form_remove_value(current->form, tag, value);
-                        if (removed) {
-                            ui_current_print_line("Removed %s from %s", value, tag);
-                        } else {
-                            ui_current_print_line("Value %s is not currently set for %s", value, tag);
-                        }
-                    } else {
-                        ui_current_print_line("Value %s not a valid option for field: %s", value, tag);
-                    }
-                    break;
-                case FIELD_TEXT_MULTI:
-                    if (!g_str_has_prefix(value, "val")) {
-                        ui_current_print_line("No such value %s for %s", value, tag);
-                        break;
-                    }
-                    if (strlen(value) < 4) {
-                        ui_current_print_line("No such value %s for %s", value, tag);
-                        break;
-                    }
-
-                    int index = strtol(&value[3], NULL, 10);
-                    if ((index < 1) || (index > form_get_value_count(current->form, tag))) {
-                        ui_current_print_line("No such value %s for %s", value, tag);
-                        break;
-                    }
-
-                    removed = form_remove_text_multi_value(current->form, tag, index);
-                    if (removed) {
-                        ui_current_print_line("Removed %s from %s", value, tag);
-                    } else {
-                        ui_current_print_line("Could not remove %s from %s", value, tag);
-                    }
-                    break;
-                case FIELD_JID_MULTI:
+    if (g_strcmp0(args[0], "remove") == 0) {
+        char *tag = NULL;
+        char *value = NULL;
+        if (args[1] != NULL) {
+            tag = args[1];
+        } else {
+            ui_current_print_line("/room remove command requires a field tag and value");
+            g_strfreev(split_recipient);
+            return TRUE;
+        }
+        if (args[2] != NULL) {
+            value = args[2];
+        } else {
+            ui_current_print_line("/room remove command requires a field tag and value");
+            g_strfreev(split_recipient);
+            return TRUE;
+        }
+        if (!form_tag_exists(current->form, tag)) {
+            ui_current_print_line("Form does not contain a field with tag %s", tag);
+        } else {
+            form_field_type_t field_type = form_get_field_type(current->form, tag);
+            gboolean valid = FALSE;
+            gboolean removed = FALSE;
+            switch (field_type) {
+            case FIELD_LIST_MULTI:
+                valid = form_field_contains_option(current->form, tag, value);
+                if (valid == TRUE) {
                     removed = form_remove_value(current->form, tag, value);
                     if (removed) {
                         ui_current_print_line("Removed %s from %s", value, tag);
                     } else {
-                        ui_current_print_line("Field %s does not contain %s", tag, value);
+                        ui_current_print_line("Value %s is not currently set for %s", value, tag);
                     }
+                } else {
+                    ui_current_print_line("Value %s not a valid option for field: %s", value, tag);
+                }
+                break;
+            case FIELD_TEXT_MULTI:
+                if (!g_str_has_prefix(value, "val")) {
+                    ui_current_print_line("No such value %s for %s", value, tag);
+                    break;
+                }
+                if (strlen(value) < 4) {
+                    ui_current_print_line("No such value %s for %s", value, tag);
                     break;
-                default:
-                    ui_current_print_line("Remove command not valid for field: %s", tag);
+                }
+
+                int index = strtol(&value[3], NULL, 10);
+                if ((index < 1) || (index > form_get_value_count(current->form, tag))) {
+                    ui_current_print_line("No such value %s for %s", value, tag);
                     break;
                 }
+
+                removed = form_remove_text_multi_value(current->form, tag, index);
+                if (removed) {
+                    ui_current_print_line("Removed %s from %s", value, tag);
+                } else {
+                    ui_current_print_line("Could not remove %s from %s", value, tag);
+                }
+                break;
+            case FIELD_JID_MULTI:
+                removed = form_remove_value(current->form, tag, value);
+                if (removed) {
+                    ui_current_print_line("Removed %s from %s", value, tag);
+                } else {
+                    ui_current_print_line("Field %s does not contain %s", tag, value);
+                }
+                break;
+            default:
+                ui_current_print_line("Remove command not valid for field: %s", tag);
+                break;
             }
         }
+    }
 
-        if ((g_strcmp0(args[0], "submit") == 0) ||
-                (g_strcmp0(args[0], "cancel") == 0)) {
-            wins_close_current();
-            current = wins_get_by_recipient(room);
-            if (current == NULL) {
-                current = wins_get_console();
-            }
-            num = wins_get_num(current);
-            ui_switch_win(num);
+    if ((g_strcmp0(args[0], "submit") == 0) ||
+            (g_strcmp0(args[0], "cancel") == 0)) {
+        wins_close_current();
+        current = wins_get_by_recipient(room);
+        if (current == NULL) {
+            current = wins_get_console();
         }
+        int num = wins_get_num(current);
+        ui_switch_win(num);
+    }
+
+    g_strfreev(split_recipient);
+
+    return TRUE;
+}
+
+gboolean
+cmd_room(gchar **args, struct cmd_help_t help)
+{
+    jabber_conn_status_t conn_status = jabber_get_connection_status();
+
+    if (conn_status != JABBER_CONNECTED) {
+        cons_show("You are not currently connected.");
+        return TRUE;
+    }
+
+    win_type_t win_type = ui_current_win_type();
+    if (win_type != WIN_MUC) {
+        cons_show("Command '/room' does not apply to this window.");
+        return TRUE;
+    }
+
+    if ((g_strcmp0(args[0], "accept") != 0) &&
+            (g_strcmp0(args[0], "destroy") != 0) &&
+            (g_strcmp0(args[0], "config") != 0)) {
+        cons_show("Usage: %s", help.usage);
+        return TRUE;
+    }
+
+    char *room = ui_current_recipient();
+    ProfWin *window = wins_get_by_recipient(room);
+    int num = wins_get_num(window);
+
+    int ui_index = num;
+    if (ui_index == 10) {
+        ui_index = 0;
+    }
 
-        g_strfreev(split_recipient);
+    if (g_strcmp0(args[0], "accept") == 0) {
+        gboolean requires_config = muc_requires_config(room);
+        if (!requires_config) {
+            win_save_vprint(window, '!', NULL, 0, COLOUR_ROOMINFO, "", "Current room does not require configuration.");
+            return TRUE;
+        } else {
+            iq_confirm_instant_room(room);
+            muc_set_requires_config(room, FALSE);
+            win_save_vprint(window, '!', NULL, 0, COLOUR_ROOMINFO, "", "Room unlocked.");
+            cons_show("Room unlocked: %s (%d)", room, ui_index);
+            return TRUE;
+        }
+    }
 
+    if (g_strcmp0(args[0], "destroy") == 0) {
+        iq_destroy_instant_room(room);
+        return TRUE;
+    }
+
+    if (g_strcmp0(args[0], "config") == 0) {
+        GString *win_title = g_string_new(room);
+        g_string_append(win_title, " config");
+        ProfWin *window = wins_get_by_recipient(win_title->str);
+        g_string_free(win_title, TRUE);
+        if (window != NULL) {
+            num = wins_get_num(window);
+            ui_switch_win(num);
+        } else {
+            iq_request_room_config_form(room);
+        }
         return TRUE;
     }
 
diff --git a/src/command/commands.h b/src/command/commands.h
index 7eddc127..528c78aa 100644
--- a/src/command/commands.h
+++ b/src/command/commands.h
@@ -125,5 +125,6 @@ gboolean cmd_xa(gchar **args, struct cmd_help_t help);
 gboolean cmd_alias(gchar **args, struct cmd_help_t help);
 gboolean cmd_xmlconsole(gchar **args, struct cmd_help_t help);
 gboolean cmd_ping(gchar **args, struct cmd_help_t help);
+gboolean cmd_form(gchar **args, struct cmd_help_t help);
 
 #endif