1
0
mirror of https://github.com/profanity-im/profanity.git synced 2024-11-03 19:37:16 -05:00
profanity/src/command.c

1004 lines
30 KiB
C
Raw Normal View History

/*
2012-02-20 15:07:38 -05:00
* command.c
*
* Copyright (C) 2012 James Booth <boothj5@gmail.com>
*
2012-02-20 15:07:38 -05:00
* This file is part of Profanity.
*
* Profanity is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Profanity is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Profanity. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include <stdlib.h>
2012-08-25 20:50:50 -04:00
#include <string.h>
2012-04-23 20:02:22 -04:00
#include <glib.h>
2012-02-09 18:15:53 -05:00
#include "command.h"
2012-08-25 20:50:50 -04:00
#include "common.h"
#include "contact.h"
2012-08-25 20:50:50 -04:00
#include "contact_list.h"
#include "chat_log.h"
2012-02-26 20:44:09 -05:00
#include "history.h"
2012-02-09 18:15:53 -05:00
#include "jabber.h"
2012-08-25 20:50:50 -04:00
#include "log.h"
#include "preferences.h"
2012-06-04 18:59:09 -04:00
#include "prof_autocomplete.h"
2012-07-27 20:36:08 -04:00
#include "tinyurl.h"
2012-08-25 20:50:50 -04:00
#include "ui.h"
2012-02-09 18:15:53 -05:00
/*
2012-08-22 18:57:34 -04:00
* Command structure
*
* cmd - The command string including leading '/'
2012-08-11 20:39:51 -04:00
* func - The function to execute for the command
2012-08-22 18:57:34 -04:00
* help - A help struct containing usage info etc
2012-08-11 20:39:51 -04:00
*/
struct cmd_t {
const gchar *cmd;
gboolean (*func)(const char * const inp, struct cmd_help_t help);
struct cmd_help_t help;
};
2012-08-14 19:42:38 -04:00
static struct cmd_t * _cmd_get_command(const char * const command);
static void _update_presence(const jabber_presence_t presence,
const char * const show, const char * const inp);
2012-10-21 18:37:20 -04:00
static gboolean _cmd_set_boolean_preference(const char * const inp,
struct cmd_help_t help, const char * const cmd_str, const char * const display,
2012-08-22 19:30:11 -04:00
void (*set_func)(gboolean));
// command prototypes
2012-08-11 20:39:51 -04:00
static gboolean _cmd_quit(const char * const inp, struct cmd_help_t help);
static gboolean _cmd_help(const char * const inp, struct cmd_help_t help);
static gboolean _cmd_about(const char * const inp, struct cmd_help_t help);
2012-08-11 20:39:51 -04:00
static gboolean _cmd_prefs(const char * const inp, struct cmd_help_t help);
static gboolean _cmd_who(const char * const inp, struct cmd_help_t help);
static gboolean _cmd_connect(const char * const inp, struct cmd_help_t help);
static gboolean _cmd_msg(const char * const inp, struct cmd_help_t help);
static gboolean _cmd_tiny(const char * const inp, struct cmd_help_t help);
static gboolean _cmd_close(const char * const inp, struct cmd_help_t help);
static gboolean _cmd_set_beep(const char * const inp, struct cmd_help_t help);
static gboolean _cmd_set_notify(const char * const inp, struct cmd_help_t help);
static gboolean _cmd_set_typing(const char * const inp, struct cmd_help_t help);
2012-08-11 20:39:51 -04:00
static gboolean _cmd_set_flash(const char * const inp, struct cmd_help_t help);
static gboolean _cmd_set_showsplash(const char * const inp, struct cmd_help_t help);
static gboolean _cmd_set_chlog(const char * const inp, struct cmd_help_t help);
2012-10-14 13:26:08 -04:00
static gboolean _cmd_set_history(const char * const inp, struct cmd_help_t help);
static gboolean _cmd_set_remind(const char * const inp, struct cmd_help_t help);
2012-08-11 20:39:51 -04:00
static gboolean _cmd_away(const char * const inp, struct cmd_help_t help);
static gboolean _cmd_online(const char * const inp, struct cmd_help_t help);
static gboolean _cmd_dnd(const char * const inp, struct cmd_help_t help);
static gboolean _cmd_chat(const char * const inp, struct cmd_help_t help);
static gboolean _cmd_xa(const char * const inp, struct cmd_help_t help);
2012-04-23 20:02:22 -04:00
2012-08-22 18:57:34 -04:00
/*
* The commands are broken down into three groups:
* Main commands
* Commands to change preferences
* Commands to change users status
*/
static struct cmd_t main_commands[] =
2012-08-11 20:39:51 -04:00
{
{ "/help",
_cmd_help,
{ "/help [area|command]", "Show help summary, or help on a specific area or command",
{ "/help [area|command]",
"--------------------",
"Show help options.",
"Specify an area (basic, status, settings, navigation) for more help on that area.",
2012-08-14 19:31:24 -04:00
"Specify the command if you want more detailed help on a specific command.",
2012-08-14 17:50:38 -04:00
"",
2012-08-14 19:31:24 -04:00
"Example : /help connect",
"Example : /help settings",
2012-08-14 18:22:12 -04:00
NULL } } },
{ "/about",
_cmd_about,
{ "/about", "About Profanity",
{ "/about",
"------",
"Show versioning and license information.",
NULL } } },
{ "/connect",
_cmd_connect,
2012-08-14 17:50:38 -04:00
{ "/connect user@host", "Login to jabber.",
2012-08-14 19:31:24 -04:00
{ "/connect user@host",
"------------------",
"Connect to the jabber server at host using the username user.",
"Profanity should work with any XMPP (Jabber) compliant chat host.",
"You can use tab completion to autocomplete any logins you have used before.",
"",
"Example: /connect myuser@gmail.com",
2012-08-14 18:22:12 -04:00
NULL } } },
{ "/prefs",
_cmd_prefs,
2012-08-14 17:50:38 -04:00
{ "/prefs", "Show current preferences.",
2012-08-14 19:31:24 -04:00
{ "/prefs",
"------",
"List all current user preference settings.",
"User preferences are stored at:",
"",
" ~/.profanity/config",
"",
"Preference changes made using the various commands take effect immediately,",
"you will need to restart Profanity for config file edits to take effect.",
2012-08-14 18:22:12 -04:00
NULL } } },
2012-08-11 20:39:51 -04:00
{ "/msg",
_cmd_msg,
2012-08-14 17:50:38 -04:00
{ "/msg user@host mesg", "Send mesg to user.",
2012-08-14 19:31:24 -04:00
{ "/msg user@host mesg",
"-------------------",
"Send a message to the user specified.",
"Use tab completion to autocomplete online contacts.",
"If there is no current chat with the recipient, a new chat window",
"will be opened, and highlighted in the status bar at the bottom.",
"pressing the corresponding F key will take you to that window.",
"This command can be called from any window, including chat with other users.",
"",
"Example : /msg boothj5@gmail.com Hey, here's a message!",
2012-08-14 18:22:12 -04:00
NULL } } },
2012-08-11 20:39:51 -04:00
{ "/tiny",
_cmd_tiny,
2012-08-14 17:50:38 -04:00
{ "/tiny url", "Send url as tinyurl in current chat.",
2012-08-14 19:31:24 -04:00
{ "/tiny url",
"---------",
"Send the url as a tiny url.",
"This command can only be called when in a chat window,",
"not from the console.",
"",
"Example : /tiny http://www.google.com",
2012-08-14 18:22:12 -04:00
NULL } } },
2012-08-11 20:39:51 -04:00
{ "/who",
2012-08-11 20:39:51 -04:00
_cmd_who,
{ "/who [status]", "Show contacts with chosen status.",
{ "/who [status]",
"-------------",
"Show contacts with the specified status, no status shows all contacts.",
"Possible statuses are: online, offline, away, dnd, xa, chat.",
"online includes: chat, dnd, away, xa.",
2012-08-14 18:22:12 -04:00
NULL } } },
2012-08-11 20:39:51 -04:00
{ "/close",
_cmd_close,
2012-08-14 17:50:38 -04:00
{ "/close", "Close current chat window.",
2012-08-14 19:31:24 -04:00
{ "/close",
"------",
"Close the current chat window, no message is sent to the recipient,",
"The chat window will become available for new chats.",
2012-08-14 18:22:12 -04:00
NULL } } },
{ "/quit",
_cmd_quit,
2012-08-14 17:50:38 -04:00
{ "/quit", "Quit Profanity.",
2012-08-14 19:31:24 -04:00
{ "/quit",
"-----",
"Logout of any current sessions, and quit Profanity.",
2012-08-14 18:22:12 -04:00
NULL } } }
2012-08-11 16:26:24 -04:00
};
static struct cmd_t setting_commands[] =
2012-08-11 20:39:51 -04:00
{
{ "/beep",
_cmd_set_beep,
2012-08-14 17:50:38 -04:00
{ "/beep on|off", "Enable/disable sound notifications.",
2012-08-14 19:31:24 -04:00
{ "/beep on|off",
"------------",
"Switch the terminal bell on or off.",
"The bell will sound when incoming messages are received.",
"If the terminal does not support sounds, it may attempt to",
"flash the screen instead.",
"",
"Config file section : [ui]",
"Config file value : beep=true|false",
2012-08-14 18:22:12 -04:00
NULL } } },
2012-08-11 20:39:51 -04:00
{ "/notify",
_cmd_set_notify,
{ "/notify on|off", "Enable/disable message notifications.",
2012-08-14 19:31:24 -04:00
{ "/notify on|off",
"--------------",
"Switch the message notifications on or off.",
2012-08-14 19:31:24 -04:00
"The notification will appear for all incoming messages.",
"The desktop environment must support desktop notifications.",
"",
"Config file section : [ui]",
"Config file value : notify=true|false",
2012-08-14 18:22:12 -04:00
NULL } } },
2012-08-11 20:39:51 -04:00
{ "/typing",
_cmd_set_typing,
{ "/typing on|off", "Enable/disable typing notifications.",
{ "/typing on|off",
"--------------",
2012-08-15 19:56:27 -04:00
"Switch typing notifications on or off for incoming messages",
"If desktop notifications are also enabled you will receive them",
2012-08-15 19:56:27 -04:00
"for when users are typing a message to you.",
"",
"Config file section : [ui]",
"Config file value : typing=true|false",
NULL } } },
{ "/remind",
_cmd_set_remind,
{ "/remind seconds", "Set message reminder period in seconds.",
{ "/remind seconds",
"--------------",
"Set the period for new message reminders as desktop notifications.",
"The value is in seconds, a setting of 0 will disable the feature.",
"The desktop environment must support desktop notifications.",
"",
"Config file section : [ui]",
"Config file value : remind=seconds",
NULL } } },
{ "/flash",
2012-08-11 20:39:51 -04:00
_cmd_set_flash,
2012-08-14 17:50:38 -04:00
{ "/flash on|off", "Enable/disable screen flash notifications.",
2012-08-14 19:31:24 -04:00
{ "/flash on|off",
"-------------",
"Make the terminal flash when incoming messages are recieved.",
"The flash will only occur if you are not in the chat window associated",
"with the user sending the message.",
"The terminal must support flashing, if it doesn't it may attempt to beep.",
"",
"Config file section : [ui]",
"Config file value : flash=true|false",
2012-08-14 18:22:12 -04:00
NULL } } },
2012-08-11 20:39:51 -04:00
{ "/showsplash",
_cmd_set_showsplash,
2012-08-14 17:50:38 -04:00
{ "/showsplash on|off", "Enable/disable splash logo on startup.",
2012-08-14 19:31:24 -04:00
{ "/showsplash on|off",
"------------------",
"Switch on or off the ascii logo on start up.",
"",
"Config file section : [ui]",
"Config file value : showsplash=true|false",
2012-08-14 18:22:12 -04:00
NULL } } },
2012-08-11 20:39:51 -04:00
{ "/chlog",
2012-08-11 20:39:51 -04:00
_cmd_set_chlog,
2012-08-14 17:50:38 -04:00
{ "/chlog on|off", "Enable/disable chat logging.",
2012-08-14 19:31:24 -04:00
{ "/chlog on|off",
"-------------",
"Switch chat logging on or off.",
"Chat logs are stored in the ~/.profanoty/log directory.",
"A folder is created for each login that you have used with Profanity.",
"Within in those folders, a log file is created for each user you chat to.",
"",
"For example if you are logged in as someuser@chatserv.com, and you chat",
"to myfriend@chatserv.com, the following chat log will be created:",
"",
" ~/.profanity/log/someuser_at_chatserv.com/myfriend_at_chatserv.com",
2012-10-14 13:26:08 -04:00
NULL } } },
{ "/history",
2012-10-14 13:26:08 -04:00
_cmd_set_history,
{ "/history on|off", "Enable/disable chat history.",
{ "/history on|off",
"-------------",
"Switch chat history on or off, requires chlog to be enabled.",
"When history is enabled, previous messages are shown in chat windows.",
"The last day of messages are shown, or if you have had profanity open",
"for more than a day, messages will be shown from the day which",
"you started profanity.",
2012-08-14 18:22:12 -04:00
NULL } } }
2012-08-11 16:26:24 -04:00
};
static struct cmd_t status_commands[] =
2012-08-11 20:39:51 -04:00
{
{ "/away",
_cmd_away,
2012-08-14 17:50:38 -04:00
{ "/away [msg]", "Set status to away.",
2012-08-14 19:31:24 -04:00
{ "/away [msg]",
"-----------",
"Set your status to \"away\" with the optional message.",
"Your current status can be found in the top right of the screen.",
"",
"Example : /away Gone for lunch",
2012-08-14 18:22:12 -04:00
NULL } } },
2012-08-11 20:39:51 -04:00
{ "/chat",
_cmd_chat,
2012-08-14 17:50:38 -04:00
{ "/chat [msg]", "Set status to chat (available for chat).",
2012-08-14 19:31:24 -04:00
{ "/chat [msg]",
"-----------",
"Set your status to \"chat\", meaning \"available for chat\",",
"with the optional message.",
"Your current status can be found in the top right of the screen.",
"",
"Example : /chat Please talk to me!",
2012-08-14 18:22:12 -04:00
NULL } } },
2012-08-11 20:39:51 -04:00
{ "/dnd",
_cmd_dnd,
2012-08-14 17:50:38 -04:00
{ "/dnd [msg]", "Set status to dnd (do not disturb.",
2012-08-14 19:31:24 -04:00
{ "/dnd [msg]",
"----------",
"Set your status to \"dnd\", meaning \"do not disturb\",",
"with the optional message.",
"Your current status can be found in the top right of the screen.",
"",
"Example : /dnd I'm in the zone",
2012-08-14 18:22:12 -04:00
NULL } } },
2012-08-11 20:39:51 -04:00
{ "/online",
2012-08-11 20:39:51 -04:00
_cmd_online,
2012-08-14 17:50:38 -04:00
{ "/online [msg]", "Set status to online.",
2012-08-14 19:31:24 -04:00
{ "/online [msg]",
"-------------",
"Set your status to \"online\" with the optional message.",
"Your current status can be found in the top right of the screen.",
"",
"Example : /online Up the Irons!",
2012-08-14 18:22:12 -04:00
NULL } } },
2012-08-11 20:39:51 -04:00
{ "/xa",
_cmd_xa,
2012-08-14 17:50:38 -04:00
{ "/xa [msg]", "Set status to xa (extended away).",
2012-08-14 19:31:24 -04:00
{ "/xa [msg]",
"---------",
"Set your status to \"xa\", meaning \"extended away\",",
"with the optional message.",
"Your current status can be found in the top right of the screen.",
"",
"Example : /xa This meeting is going to be a long one",
NULL } } },
};
static PAutocomplete commands_ac;
2012-10-21 18:37:20 -04:00
static PAutocomplete help_ac;
2012-08-22 18:57:34 -04:00
/*
* Initialise command autocompleter and history
*/
2012-07-24 18:19:48 -04:00
void
2012-08-22 19:30:11 -04:00
cmd_init(void)
2012-04-30 19:24:31 -04:00
{
log_info("Initialising commands");
2012-06-04 18:59:09 -04:00
commands_ac = p_autocomplete_new();
2012-10-21 18:37:20 -04:00
help_ac = p_autocomplete_new();
p_autocomplete_add(help_ac, strdup("basic"));
p_autocomplete_add(help_ac, strdup("status"));
p_autocomplete_add(help_ac, strdup("settings"));
p_autocomplete_add(help_ac, strdup("navigation"));
2012-06-04 18:59:09 -04:00
unsigned int i;
2012-08-11 16:26:24 -04:00
for (i = 0; i < ARRAY_SIZE(main_commands); i++) {
struct cmd_t *pcmd = main_commands+i;
2012-10-21 19:29:39 -04:00
p_autocomplete_add(commands_ac, (gchar *)strdup(pcmd->cmd));
p_autocomplete_add(help_ac, (gchar *)strdup(pcmd->cmd+1));
2012-08-11 16:26:24 -04:00
}
for (i = 0; i < ARRAY_SIZE(setting_commands); i++) {
struct cmd_t *pcmd = setting_commands+i;
2012-10-21 19:29:39 -04:00
p_autocomplete_add(commands_ac, (gchar *)strdup(pcmd->cmd));
p_autocomplete_add(help_ac, (gchar *)strdup(pcmd->cmd+1));
2012-08-11 16:26:24 -04:00
}
for (i = 0; i < ARRAY_SIZE(status_commands); i++) {
struct cmd_t *pcmd = status_commands+i;
2012-10-21 19:29:39 -04:00
p_autocomplete_add(commands_ac, (gchar *)strdup(pcmd->cmd));
p_autocomplete_add(help_ac, (gchar *)strdup(pcmd->cmd+1));
2012-06-04 18:59:09 -04:00
}
2012-04-30 19:24:31 -04:00
history_init();
}
2012-10-21 19:29:39 -04:00
void
cmd_close(void)
{
p_autocomplete_clear(commands_ac);
p_autocomplete_clear(help_ac);
}
2012-08-22 19:44:14 -04:00
// Command autocompletion functions
2012-07-24 18:19:48 -04:00
char *
cmd_complete(char *inp)
2012-06-04 18:59:09 -04:00
{
return p_autocomplete_complete(commands_ac, inp);
}
2012-07-24 18:19:48 -04:00
void
2012-08-22 19:30:11 -04:00
cmd_reset_completer(void)
2012-06-04 18:59:09 -04:00
{
p_autocomplete_reset(commands_ac);
}
2012-08-22 19:44:14 -04:00
// Command help
2012-10-21 18:37:20 -04:00
char *
2012-10-21 18:39:42 -04:00
cmd_help_complete(char *inp)
2012-10-21 18:37:20 -04:00
{
return p_autocomplete_complete(help_ac, inp);
}
void
2012-10-21 18:39:42 -04:00
cmd_help_reset_completer(void)
2012-10-21 18:37:20 -04:00
{
p_autocomplete_reset(help_ac);
}
2012-08-22 19:44:14 -04:00
GSList *
2012-08-22 19:30:11 -04:00
cmd_get_basic_help(void)
{
GSList *result = NULL;
unsigned int i;
for (i = 0; i < ARRAY_SIZE(main_commands); i++) {
result = g_slist_append(result, &((main_commands+i)->help));
}
return result;
}
GSList *
2012-08-22 19:30:11 -04:00
cmd_get_settings_help(void)
{
GSList *result = NULL;
unsigned int i;
for (i = 0; i < ARRAY_SIZE(setting_commands); i++) {
result = g_slist_append(result, &((setting_commands+i)->help));
}
return result;
}
GSList *
2012-08-22 19:30:11 -04:00
cmd_get_status_help(void)
{
GSList *result = NULL;
unsigned int i;
for (i = 0; i < ARRAY_SIZE(status_commands); i++) {
result = g_slist_append(result, &((status_commands+i)->help));
}
return result;
}
2012-08-22 19:44:14 -04:00
// Command execution
2012-08-22 19:41:22 -04:00
gboolean
cmd_execute(const char * const command, const char * const inp)
2012-08-14 19:42:38 -04:00
{
struct cmd_t *cmd = _cmd_get_command(command);
2012-08-14 19:42:38 -04:00
if (cmd != NULL) {
return (cmd->func(inp, cmd->help));
} else {
2012-08-22 19:41:22 -04:00
return cmd_execute_default(inp);
2012-08-14 19:42:38 -04:00
}
2012-02-18 18:09:21 -05:00
}
2012-08-22 19:41:22 -04:00
gboolean
cmd_execute_default(const char * const inp)
{
if (win_in_chat()) {
char *recipient = win_get_recipient();
jabber_send(inp, recipient);
if (prefs_get_chlog()) {
const char *jid = jabber_get_jid();
chat_log_chat(jid, recipient, inp, OUT);
}
2012-08-22 19:41:22 -04:00
win_show_outgoing_msg("me", recipient, inp);
free(recipient);
} else {
cons_bad_command(inp);
}
return TRUE;
}
2012-08-22 19:44:14 -04:00
// The command functions
2012-08-22 19:41:22 -04:00
2012-07-24 18:19:48 -04:00
static gboolean
2012-08-11 20:39:51 -04:00
_cmd_connect(const char * const inp, struct cmd_help_t help)
2012-02-18 18:09:21 -05:00
{
2012-04-23 20:02:22 -04:00
gboolean result = FALSE;
jabber_conn_status_t conn_status = jabber_get_connection_status();
2012-02-18 18:09:21 -05:00
if ((conn_status != JABBER_DISCONNECTED) && (conn_status != JABBER_STARTED)) {
2012-05-09 20:22:47 -04:00
cons_show("You are either connected already, or a login is in process.");
2012-02-19 20:42:29 -05:00
result = TRUE;
} else if (strlen(inp) < 10) {
2012-10-03 17:19:46 -04:00
cons_show("Usage: %s", help.usage);
2012-02-19 20:42:29 -05:00
result = TRUE;
2012-02-18 18:09:21 -05:00
} else {
char *user, *lower;
2012-02-18 18:09:21 -05:00
user = strndup(inp+9, strlen(inp)-9);
lower = g_utf8_strdown(user, -1);
2012-02-18 18:09:21 -05:00
status_bar_get_password();
status_bar_refresh();
2012-02-19 15:16:33 -05:00
char passwd[21];
2012-02-19 20:42:29 -05:00
inp_block();
2012-02-18 18:09:21 -05:00
inp_get_password(passwd);
2012-02-19 20:42:29 -05:00
inp_non_block();
2012-08-18 22:43:18 -04:00
log_debug("Connecting as %s", lower);
conn_status = jabber_connect(lower, passwd);
2012-08-18 22:43:18 -04:00
if (conn_status == JABBER_CONNECTING) {
2012-02-29 19:43:44 -05:00
cons_show("Connecting...");
log_debug("Connecting...");
2012-08-18 22:43:18 -04:00
}
if (conn_status == JABBER_DISCONNECTED) {
cons_bad_show("Connection to server failed.");
log_debug("Connection using %s failed", lower);
2012-08-18 22:43:18 -04:00
}
2012-02-19 20:42:29 -05:00
result = TRUE;
2012-02-18 18:09:21 -05:00
}
2012-02-18 18:09:21 -05:00
return result;
}
2012-07-24 18:19:48 -04:00
static gboolean
2012-08-11 20:39:51 -04:00
_cmd_quit(const char * const inp, struct cmd_help_t help)
2012-02-09 18:15:53 -05:00
{
log_info("Profanity is shutting down...");
exit(0);
return FALSE;
2012-02-09 18:15:53 -05:00
}
2012-07-24 18:19:48 -04:00
static gboolean
2012-08-11 20:39:51 -04:00
_cmd_help(const char * const inp, struct cmd_help_t help)
2012-02-09 18:15:53 -05:00
{
2012-08-14 18:22:12 -04:00
if (strcmp(inp, "/help") == 0) {
cons_help();
} else if (strcmp(inp, "/help basic") == 0) {
cons_basic_help();
} else if (strcmp(inp, "/help status") == 0) {
cons_status_help();
2012-10-22 19:00:10 -04:00
} else if (strcmp(inp, "/help settings") == 0) {
cons_settings_help();
} else if (strcmp(inp, "/help navigation") == 0) {
cons_navigation_help();
2012-08-14 18:22:12 -04:00
} else {
2012-08-14 19:42:38 -04:00
char *cmd = strndup(inp+6, strlen(inp)-6);
2012-08-14 18:22:12 -04:00
char cmd_with_slash[1 + strlen(cmd) + 1];
sprintf(cmd_with_slash, "/%s", cmd);
const gchar **help_text = NULL;
2012-08-14 19:42:38 -04:00
struct cmd_t *command = _cmd_get_command(cmd_with_slash);
2012-08-14 18:22:12 -04:00
2012-08-14 19:42:38 -04:00
if (command != NULL) {
help_text = command->help.long_help;
2012-08-14 18:22:12 -04:00
}
2012-08-14 18:22:12 -04:00
cons_show("");
if (help_text != NULL) {
2012-08-14 19:42:38 -04:00
int i;
2012-08-14 18:22:12 -04:00
for (i = 0; help_text[i] != NULL; i++) {
cons_show(help_text[i]);
}
} else {
cons_show("No such command.");
}
cons_show("");
}
2012-02-09 18:15:53 -05:00
return TRUE;
}
static gboolean
_cmd_about(const char * const inp, struct cmd_help_t help)
{
cons_about();
return TRUE;
}
2012-07-24 18:19:48 -04:00
static gboolean
2012-08-11 20:39:51 -04:00
_cmd_prefs(const char * const inp, struct cmd_help_t help)
2012-07-19 18:43:50 -04:00
{
cons_prefs();
return TRUE;
}
2012-07-24 18:19:48 -04:00
static gboolean
2012-08-11 20:39:51 -04:00
_cmd_who(const char * const inp, struct cmd_help_t help)
2012-03-07 19:46:24 -05:00
{
jabber_conn_status_t conn_status = jabber_get_connection_status();
if (conn_status != JABBER_CONNECTED) {
2012-05-09 20:22:47 -04:00
cons_show("You are not currently connected.");
} else {
// copy input
char inp_cpy[strlen(inp) + 1];
strcpy(inp_cpy, inp);
// get show
strtok(inp_cpy, " ");
char *show = strtok(NULL, " ");
// bad arg
if ((show != NULL)
&& (strcmp(show, "online") != 0)
&& (strcmp(show, "offline") != 0)
&& (strcmp(show, "away") != 0)
&& (strcmp(show, "chat") != 0)
&& (strcmp(show, "xa") != 0)
&& (strcmp(show, "dnd") != 0)) {
cons_show("Usage: %s", help.usage);
// valid arg
} else {
GSList *list = get_contact_list();
// no arg, show all contacts
if (show == NULL) {
cons_show("All contacts:");
cons_show_contacts(list);
// online, show all status that indicate online
} else if (strcmp("online", show) == 0) {
cons_show("Contacts (%s):", show);
GSList *filtered = NULL;
while (list != NULL) {
PContact contact = list->data;
const char * const contact_show = (p_contact_show(contact));
if ((strcmp(contact_show, "online") == 0)
|| (strcmp(contact_show, "away") == 0)
|| (strcmp(contact_show, "dnd") == 0)
|| (strcmp(contact_show, "xa") == 0)
|| (strcmp(contact_show, "chat") == 0)) {
filtered = g_slist_append(filtered, contact);
}
list = g_slist_next(list);
}
cons_show_contacts(filtered);
// show specific status
} else {
cons_show("Contacts (%s):", show);
GSList *filtered = NULL;
while (list != NULL) {
PContact contact = list->data;
if (strcmp(p_contact_show(contact), show) == 0) {
filtered = g_slist_append(filtered, contact);
}
list = g_slist_next(list);
}
cons_show_contacts(filtered);
}
}
}
2012-03-07 19:46:24 -05:00
return TRUE;
}
2012-07-24 18:19:48 -04:00
static gboolean
2012-08-11 20:39:51 -04:00
_cmd_msg(const char * const inp, struct cmd_help_t help)
2012-02-09 18:15:53 -05:00
{
char *usr = NULL;
char *msg = NULL;
jabber_conn_status_t conn_status = jabber_get_connection_status();
2012-02-19 20:42:29 -05:00
if (conn_status != JABBER_CONNECTED) {
2012-05-09 20:22:47 -04:00
cons_show("You are not currently connected.");
2012-02-19 20:42:29 -05:00
} else {
// copy input
2012-02-19 20:42:29 -05:00
char inp_cpy[strlen(inp) + 1];
strcpy(inp_cpy, inp);
// get user
strtok(inp_cpy, " ");
usr = strtok(NULL, " ");
if ((usr != NULL) && (strlen(inp) > (5 + strlen(usr) + 1))) {
2012-03-08 20:06:55 -05:00
// get message
2012-02-19 20:42:29 -05:00
msg = strndup(inp+5+strlen(usr)+1, strlen(inp)-(5+strlen(usr)+1));
2012-02-19 20:42:29 -05:00
if (msg != NULL) {
jabber_send(msg, usr);
win_show_outgoing_msg("me", usr, msg);
if (prefs_get_chlog()) {
const char *jid = jabber_get_jid();
chat_log_chat(jid, usr, msg, OUT);
}
2012-02-19 20:42:29 -05:00
} else {
2012-10-03 17:19:46 -04:00
cons_show("Usage: %s", help.usage);
2012-02-19 20:42:29 -05:00
}
2012-02-18 19:17:36 -05:00
} else {
2012-10-03 17:19:46 -04:00
cons_show("Usage: %s", help.usage);
2012-02-09 18:15:53 -05:00
}
}
return TRUE;
}
2012-07-27 20:36:08 -04:00
static gboolean
2012-08-11 20:39:51 -04:00
_cmd_tiny(const char * const inp, struct cmd_help_t help)
2012-07-27 20:36:08 -04:00
{
2012-07-29 16:32:04 -04:00
if (strlen(inp) > 6) {
char *url = strndup(inp+6, strlen(inp)-6);
if (!tinyurl_valid(url)) {
GString *error = g_string_new("/tiny, badly formed URL: ");
g_string_append(error, url);
cons_bad_show(error->str);
if (win_in_chat()) {
win_bad_show(error->str);
}
2012-07-29 16:32:04 -04:00
g_string_free(error, TRUE);
free(url);
} else if (win_in_chat()) {
char *tiny = tinyurl_get(url);
char *recipient = win_get_recipient();
jabber_send(tiny, recipient);
if (prefs_get_chlog()) {
const char *jid = jabber_get_jid();
chat_log_chat(jid, recipient, tiny, OUT);
}
2012-07-29 16:32:04 -04:00
win_show_outgoing_msg("me", recipient, tiny);
free(recipient);
free(tiny);
free(url);
} else {
cons_bad_command(inp);
free(url);
}
2012-07-27 20:36:08 -04:00
} else {
2012-10-03 17:19:46 -04:00
cons_show("Usage: %s", help.usage);
if (win_in_chat()) {
2012-08-11 20:39:51 -04:00
char usage[strlen(help.usage + 8)];
sprintf(usage, "Usage: %s", help.usage);
win_show(usage);
}
2012-07-27 20:36:08 -04:00
}
return TRUE;
}
2012-07-24 18:19:48 -04:00
static gboolean
2012-08-11 20:39:51 -04:00
_cmd_close(const char * const inp, struct cmd_help_t help)
2012-02-09 18:15:53 -05:00
{
2012-02-29 19:40:51 -05:00
if (!win_close_win())
2012-02-18 19:17:36 -05:00
cons_bad_command(inp);
2012-02-09 18:15:53 -05:00
return TRUE;
}
2012-07-24 18:19:48 -04:00
static gboolean
2012-08-11 20:39:51 -04:00
_cmd_set_beep(const char * const inp, struct cmd_help_t help)
2012-04-23 20:24:54 -04:00
{
2012-08-22 19:30:11 -04:00
return _cmd_set_boolean_preference(inp, help, "/beep",
"Sound", prefs_set_beep);
2012-04-23 20:24:54 -04:00
}
2012-07-24 18:19:48 -04:00
static gboolean
2012-08-11 20:39:51 -04:00
_cmd_set_notify(const char * const inp, struct cmd_help_t help)
2012-06-28 18:45:37 -04:00
{
return _cmd_set_boolean_preference(inp, help, "/notify",
2012-08-22 19:30:11 -04:00
"Desktop notifications", prefs_set_notify);
2012-06-28 18:45:37 -04:00
}
static gboolean
_cmd_set_typing(const char * const inp, struct cmd_help_t help)
{
return _cmd_set_boolean_preference(inp, help, "/typing",
2012-08-22 19:30:11 -04:00
"Incoming typing notifications", prefs_set_typing);
}
2012-07-24 18:19:48 -04:00
static gboolean
2012-08-11 20:39:51 -04:00
_cmd_set_flash(const char * const inp, struct cmd_help_t help)
2012-04-23 20:39:23 -04:00
{
return _cmd_set_boolean_preference(inp, help, "/flash",
2012-08-22 19:30:11 -04:00
"Screen flash", prefs_set_flash);
2012-04-23 20:39:23 -04:00
}
2012-07-24 18:19:48 -04:00
static gboolean
2012-08-11 20:39:51 -04:00
_cmd_set_showsplash(const char * const inp, struct cmd_help_t help)
2012-06-03 18:02:13 -04:00
{
return _cmd_set_boolean_preference(inp, help, "/showsplash",
2012-08-22 19:30:11 -04:00
"Splash screen", prefs_set_showsplash);
2012-06-03 18:02:13 -04:00
}
2012-07-24 18:19:48 -04:00
static gboolean
2012-08-11 20:39:51 -04:00
_cmd_set_chlog(const char * const inp, struct cmd_help_t help)
{
return _cmd_set_boolean_preference(inp, help, "/chlog",
2012-08-22 19:30:11 -04:00
"Chat logging", prefs_set_chlog);
}
2012-10-14 13:26:08 -04:00
static gboolean
_cmd_set_history(const char * const inp, struct cmd_help_t help)
{
return _cmd_set_boolean_preference(inp, help, "/history",
2012-10-14 13:26:08 -04:00
"Chat history", prefs_set_history);
}
static gboolean
_cmd_set_remind(const char * const inp, struct cmd_help_t help)
{
if ((strncmp(inp, "/remind ", 8) != 0) || (strlen(inp) < 9)) {
2012-10-03 17:19:46 -04:00
cons_show("Usage: %s", help.usage);
} else {
// copy input
char inp_cpy[strlen(inp) + 1];
strcpy(inp_cpy, inp);
// get period
strtok(inp_cpy, " ");
char *period_str = strtok(NULL, " ");
gint period = atoi(period_str);
prefs_set_remind(period);
2012-10-03 17:06:04 -04:00
if (period == 0) {
cons_show("Message reminders disabled.");
} else if (period == 1) {
cons_show("Message reminder period set to 1 second.");
} else {
cons_show("Message reminder period set to %d seconds.", period);
}
}
return TRUE;
}
2012-07-24 18:19:48 -04:00
static gboolean
2012-08-11 20:39:51 -04:00
_cmd_away(const char * const inp, struct cmd_help_t help)
{
2012-05-28 18:40:11 -04:00
_update_presence(PRESENCE_AWAY, "away", inp);
return TRUE;
}
2012-07-24 18:19:48 -04:00
static gboolean
2012-08-11 20:39:51 -04:00
_cmd_online(const char * const inp, struct cmd_help_t help)
2012-05-27 15:36:31 -04:00
{
2012-05-28 18:40:11 -04:00
_update_presence(PRESENCE_ONLINE, "online", inp);
2012-05-27 15:36:31 -04:00
return TRUE;
}
2012-07-24 18:19:48 -04:00
static gboolean
2012-08-11 20:39:51 -04:00
_cmd_dnd(const char * const inp, struct cmd_help_t help)
2012-05-27 18:00:04 -04:00
{
2012-05-28 18:40:11 -04:00
_update_presence(PRESENCE_DND, "dnd", inp);
2012-05-27 18:00:04 -04:00
return TRUE;
}
2012-07-24 18:19:48 -04:00
static gboolean
2012-08-11 20:39:51 -04:00
_cmd_chat(const char * const inp, struct cmd_help_t help)
2012-05-27 18:00:04 -04:00
{
2012-05-28 18:40:11 -04:00
_update_presence(PRESENCE_CHAT, "chat", inp);
2012-05-27 18:00:04 -04:00
return TRUE;
}
2012-07-24 18:19:48 -04:00
static gboolean
2012-08-11 20:39:51 -04:00
_cmd_xa(const char * const inp, struct cmd_help_t help)
2012-05-27 18:00:04 -04:00
{
2012-05-28 18:40:11 -04:00
_update_presence(PRESENCE_XA, "xa", inp);
2012-05-27 18:00:04 -04:00
return TRUE;
}
2012-08-22 19:44:14 -04:00
// helper function for status change commands
2012-07-24 18:19:48 -04:00
static void
_update_presence(const jabber_presence_t presence,
2012-05-28 18:40:11 -04:00
const char * const show, const char * const inp)
2012-05-28 16:51:05 -04:00
{
2012-05-28 18:40:11 -04:00
char *msg;
if (strlen(inp) > strlen(show) + 2) {
msg = strndup(inp+(strlen(show) + 2), strlen(inp)-(strlen(show) + 2));
} else {
msg = NULL;
}
jabber_conn_status_t conn_status = jabber_get_connection_status();
2012-05-28 16:51:05 -04:00
if (conn_status != JABBER_CONNECTED) {
cons_show("You are not currently connected.");
} else {
2012-05-28 18:40:11 -04:00
jabber_update_presence(presence, msg);
2012-05-28 16:51:05 -04:00
title_bar_set_status(presence);
2012-05-28 18:40:11 -04:00
if (msg != NULL) {
2012-10-03 17:19:46 -04:00
cons_show("Status set to %s, \"%s\"", show, msg);
2012-05-28 18:40:11 -04:00
free(msg);
} else {
2012-10-03 17:19:46 -04:00
cons_show("Status set to %s", show);
2012-05-28 18:40:11 -04:00
}
2012-05-28 16:51:05 -04:00
}
2012-05-28 18:40:11 -04:00
}
2012-08-22 19:30:11 -04:00
2012-08-22 19:44:14 -04:00
// helper function for boolean preference commands
2012-08-22 19:30:11 -04:00
static gboolean
_cmd_set_boolean_preference(const char * const inp, struct cmd_help_t help,
const char * const cmd_str, const char * const display,
2012-08-22 19:30:11 -04:00
void (*set_func)(gboolean))
{
GString *on = g_string_new(cmd_str);
g_string_append(on, " on");
2012-08-22 19:30:11 -04:00
GString *off = g_string_new(cmd_str);
g_string_append(off, " off");
GString *enabled = g_string_new(display);
g_string_append(enabled, " enabled.");
GString *disabled = g_string_new(display);
g_string_append(disabled, " disabled.");
if (strcmp(inp, on->str) == 0) {
cons_show(enabled->str);
set_func(TRUE);
} else if (strcmp(inp, off->str) == 0) {
cons_show(disabled->str);
set_func(FALSE);
} else {
char usage[strlen(help.usage + 8)];
sprintf(usage, "Usage: %s", help.usage);
cons_show(usage);
}
2012-08-22 19:30:11 -04:00
g_string_free(on, TRUE);
g_string_free(off, TRUE);
g_string_free(enabled, TRUE);
g_string_free(disabled, TRUE);
return TRUE;
}
2012-08-22 19:44:14 -04:00
// helper to get command by string
2012-08-22 19:41:22 -04:00
static struct cmd_t *
_cmd_get_command(const char * const command)
{
unsigned int i;
for (i = 0; i < ARRAY_SIZE(main_commands); i++) {
struct cmd_t *pcmd = main_commands+i;
if (strcmp(pcmd->cmd, command) == 0) {
return pcmd;
}
}
for (i = 0; i < ARRAY_SIZE(setting_commands); i++) {
struct cmd_t *pcmd = setting_commands+i;
if (strcmp(pcmd->cmd, command) == 0) {
return pcmd;
}
}
for (i = 0; i < ARRAY_SIZE(status_commands); i++) {
struct cmd_t *pcmd = status_commands+i;
if (strcmp(pcmd->cmd, command) == 0) {
return pcmd;
}
}
return NULL;
}