diff options
Diffstat (limited to 'src/command')
-rw-r--r-- | src/command/command.c | 1439 | ||||
-rw-r--r-- | src/command/command.h | 4 | ||||
-rw-r--r-- | src/command/commands.c | 975 | ||||
-rw-r--r-- | src/command/commands.h | 7 |
4 files changed, 1332 insertions, 1093 deletions
diff --git a/src/command/command.c b/src/command/command.c index 1441ef46..1871ea6c 100644 --- a/src/command/command.c +++ b/src/command/command.c @@ -1,7 +1,7 @@ /* * command.c * - * Copyright (C) 2012 - 2014 James Booth <boothj5@gmail.com> + * Copyright (C) 2012 - 2015 James Booth <boothj5@gmail.com> * * This file is part of Profanity. * @@ -36,6 +36,7 @@ #include <errno.h> #include <limits.h> #include <stdlib.h> +#include <stdio.h> #include <string.h> #include <glib.h> @@ -70,8 +71,6 @@ typedef char*(*autocompleter)(char*, int*); static gboolean _cmd_execute(const char * const command, const char * const inp); -static gboolean _cmd_execute_default(const char * inp); -static gboolean _cmd_execute_alias(const char * const inp, gboolean *ran); static char * _cmd_complete_parameters(const char * const input); @@ -101,6 +100,8 @@ static char * _role_autocomplete(const char * const input); static char * _resource_autocomplete(const char * const input); static char * _titlebar_autocomplete(const char * const input); static char * _inpblock_autocomplete(const char * const input); +static char * _time_autocomplete(const char * const input); +static char * _receipts_autocomplete(const char * const input); GHashTable *commands = NULL; @@ -111,18 +112,19 @@ static struct cmd_t command_defs[] = { { "/help", cmd_help, parse_args, 0, 1, NULL, - { "/help [area|command]", "Get help on using Profanity.", + { "/help [area|command]", "Help on using Profanity.", { "/help [area|command]", - "-------------------------", - "Use with no arguments to get a help summary.", - "Supply an area to see help for commands related to specific features.", - "Supply a command (without the leading slash) to see help for that command.", + "--------------------", + "Help on using Profanity.", + "", + "area : Summary help for commands in a certain area of functionality.", + "command : Full help for a specific command, for example '/help connect'.", "", - "Example : /help commands", - "Example : /help presence", - "Example : /help who", + "Use with no arguments to see a list of areas.", "", - "For more detailed help, see the user guide at http://www.profanity.im/userguide.html.", + "Example: /help commands", + "Example: /help presence", + "Example: /help who", NULL } } }, { "/about", @@ -135,15 +137,17 @@ static struct cmd_t command_defs[] = { "/connect", cmd_connect, parse_args, 0, 5, NULL, - { "/connect [account] [server value] [port value]", "Login to a chat service.", + { "/connect [account] [server value] [port value]", "Account login.", { "/connect [account] [server value] [port value]", "----------------------------------------------", - "Connect to an XMPP service using the specified account.", - "Use the server property to specify a server if required.", - "Change the default port (5222, or 5223 for SSL) with the port property.", - "An account is automatically created if one does not exist.", - "If no account is specified, then the default account is used." - "See the /account command for more details.", + "Login to a chat service.", + "", + "account : The local account you wish to connect with, or a JID if connecting for the first time.", + "server value : Supply a server if it is different to the domain part of your JID.", + "port value : The port to use if different to the default (5222, or 5223 for SSL).", + "", + "If no account is specified, the default is used if one is configured.", + "A local account is created with the JID as it's name if it doesn't already exist.", "", "Example: /connect", "Example: /connect myuser@gmail.com", @@ -162,48 +166,57 @@ static struct cmd_t command_defs[] = { "/msg", cmd_msg, parse_args_with_freetext, 1, 2, NULL, - { "/msg contact|nick [message]", "Start chat with user.", + { "/msg contact|nick [message]", "Start chat with a user.", { "/msg contact|nick [message]", "---------------------------", - "Open a chat window for the contact and send the message if one is supplied.", - "When in a chat room, supply a nickname to start private chat with a room member.", + "Send a one to one chat message, or a private message to a chat room occupant.", + "", + "contact : The contact's JID, or nickname if one has been set in your roster.", + "nick : A chat room occupant, to whom you wish to send a private message.", + "message : The message to send", + "", + "If the message is omitted, a new chat window will be opened without sending a message.", "Use quotes if the nickname includes spaces.", "", - "Example : /msg myfriend@server.com Hey, here's a message!", - "Example : /msg otherfriend@server.com", - "Example : /msg Bob Here is a private message", - "Example : /msg \"My Friend\" Hi, how are you?", + "Example: /msg myfriend@server.com Hey, here's a message!", + "Example: /msg otherfriend@server.com", + "Example: /msg Bob Here is a private message", + "Example: /msg \"My Friend\" Hi, how are you?", NULL } } }, { "/roster", cmd_roster, parse_args_with_freetext, 0, 3, NULL, - { "/roster [online|show|hide|by|size|add|remove|nick|clearnick] [offline|resource] [percent] [group|presence|none] [jid] [nickname]", "Manage your roster.", - { "/roster [online|show|hide|by|size|add|remove|nick|clearnick] [offline|resource] [percent] [group|presence|none] [jid] [nickname]", - "-------------------------------------------------------------------------------------------------------------------------", - "View, add to, and remove from your roster.", + { "/roster [command] [args..]", "Manage your roster.", + { "/roster [command] [args..]", + "--------------------------", + "Manage your roster, and roster display settings.", + "", + "command - online|show|hide|by|size|add|remove|nick|clearnick", + "", + "online : Show all online contacts in your roster.", + "show : Show the roster panel.", + "show offline : Show offline contacts in the roster panel.", + "show resource : Show contact's connected resources in the roster panel.", + "hide : Hide the roster panel.", + "hide offline : Hide offline contacts in the roster panel.", + "hide resource : Hide contact's connected resources in the roster panel.", + "by group : Group contacts in the roster panel by roster group.", + "by presence : Group contacts in the roster panel by presence.", + "by none : No grouping in the roster panel.", + "size : Percentage of the screen taken up by the roster (1-99).", + "add jid [nick] : Add a new item to the roster.", + "remove jid : Removes an item from the roster.", + "nick jid nick : Change a contacts nickname.", + "clearnick jid : Removes the current nickname.", + "", "Passing no arguments lists all contacts in your roster.", - "online - Show all online contacts in your roster.", - "show - Show the roster panel in the console window.", - "hide - Hide the roster panel.", - "show offline - Show offline contacts in the roster panel.", - "hide offline - Hide offline contacts in the roster panel.", - "show resource - Show contact's connected resources in the roster panel.", - "hide resource - Hide contact's connected resources in the roster panel.", - "by group - Group contacts in the roster panel by roster group.", - "by presence - Group contacts in the roster panel by presence.", - "by none - No grouping in the roster panel.", - "size - Percentage of the screen taken up by the roster (1-99).", - "add - Add a new item, jid is required, nickname is optional.", - "remove - Removes a contact, jid is required.", - "nick - Changes a contacts nickname, both jid and nickname are required,", - "clearnick - Removes the current nickname, jid is required.", - "", - "Example : /roster (show your roster)", - "Example : /roster add someone@contacts.org (add the contact)", - "Example : /roster add someone@contacts.org Buddy (add the contact with nickname 'Buddy')", - "Example : /roster remove someone@contacts.org (remove the contact)", - "Example : /roster nick myfriend@chat.org My Friend", - "Example : /roster clearnick kai@server.com (clears nickname)", + "", + "Example: /roster (show your roster)", + "Example: /roster add someone@contacts.org (add the contact)", + "Example: /roster add someone@contacts.org Buddy (add the contact with nickname 'Buddy')", + "Example: /roster remove someone@contacts.org (remove the contact)", + "Example: /roster nick myfriend@chat.org My Friend", + "Example: /roster clearnick kai@server.com (clears nickname)", NULL } } }, { "/group", @@ -212,31 +225,35 @@ static struct cmd_t command_defs[] = { "/group [show|add|remove] [group] [contact]", "------------------------------------------", "View, add to, and remove from roster groups.", + "", + "show group : List all roster items a group.", + "add group contact : Added a contact to a group.", + "remove group contact : Remove a contact from a group.", + "", "Passing no argument will list all roster groups.", - "The 'show' command takes 'group' as an argument, and lists all roster items in that group.", - "The 'add' command takes 'group' and 'contact' arguments, and adds the contact to the group.", - "The 'remove' command takes 'group' and 'contact' arguments and removes the contact from the group,", "", - "Example : /group", - "Example : /group show friends", - "Example : /group add friends newfriend@server.org", - "Example : /group add family Brother (using contacts nickname)", - "Example : /group remove colleagues boss@work.com", + "Example: /group", + "Example: /group show friends", + "Example: /group add friends newfriend@server.org", + "Example: /group add family Brother (using contacts nickname)", + "Example: /group remove colleagues boss@work.com", NULL } } }, { "/info", cmd_info, parse_args, 0, 1, NULL, - { "/info [contact|nick]", "Show basic information about a contact, room, or room member.", + { "/info [contact|nick]", "Show information about a contact, room, or room member.", { "/info [contact|nick]", "--------------------", - "Show basic information about a contact, room, or room member.", - "If in the console, a contact must be specified.", - "If in a chat window the parameter is not required, the current recipient will be used.", - "If in a chat room, providing no arguments will display information about the room.", - "If in a chat room, supplying a nick will show information about the occupant.", + "Show information about a contact, room, or room member.", "", - "Example : /info mybuddy@chat.server.org", - "Example : /info kai", + "contact : The contact you wish to view information about.", + "nick : When in a chat room, the occupant you wish to view information about.", + "", + "Passing no argument in a chat window will use the current recipient.", + "Passing no argument in a chat room will display information about the room.", + "", + "Example: /info mybuddy@chat.server.org", + "Example: /info kai", NULL } } }, { "/caps", @@ -244,14 +261,16 @@ static struct cmd_t command_defs[] = { "/caps [fulljid|nick]", "Find out a contacts client software capabilities.", { "/caps [fulljid|nick]", "--------------------", - "Find out a contact, or room members client software capabilities.", - "If in the console window or a regular chat window, a full JID is required.", - "If in a chat room, the nickname is required.", - "If in private chat, no parameter is required.", + "Find out a contacts, or room members client software capabilities.", + "", + "fulljid : If in the console or a chat window, the full JID for which you wish to see capabilities.", + "nick : If in a chat room, nickname for which you wish to see capabilities.", + "", + "If in private chat initiated from a chat room, no parameter is required.", "", - "Example : /caps mybuddy@chat.server.org/laptop (contact's laptop resource)", - "Example : /caps mybuddy@chat.server.org/phone (contact's phone resource)", - "Example : /caps bruce (room member)", + "Example: /caps mybuddy@chat.server.org/laptop (contact's laptop resource)", + "Example: /caps mybuddy@chat.server.org/phone (contact's phone resource)", + "Example: /caps bruce (room member)", NULL } } }, { "/software", @@ -259,15 +278,17 @@ static struct cmd_t command_defs[] = { "/software [fulljid|nick]", "Find out software version information about a contacts resource.", { "/software [fulljid|nick]", "------------------------", - "Find out a contact, or room members software version information, if such requests are supported.", - "If in the console window or a regular chat window, a full JID is required.", - "If in a chat room, the nickname is required.", - "If in private chat, no parameter is required.", + "Find out a contact, or room members software version information.", + "", + "fulljid : If in the console or a chat window, the full JID for which you wish to see software information.", + "nick : If in a chat room, nickname for which you wish to see software information.", + "", + "If in private chat initiated from a chat room, no parameter is required.", "If the contact's software does not support software version requests, nothing will be displayed.", "", - "Example : /software mybuddy@chat.server.org/laptop (contact's laptop resource)", - "Example : /software mybuddy@chat.server.org/phone (contact's phone resource)", - "Example : /software bruce (room member)", + "Example: /software mybuddy@chat.server.org/laptop (contact's laptop resource)", + "Example: /software mybuddy@chat.server.org/phone (contact's phone resource)", + "Example: /software bruce (room member)", NULL } } }, { "/status", @@ -276,39 +297,49 @@ static struct cmd_t command_defs[] = { "/status [contact|nick]", "----------------------", "Find out a contact, or room members presence information.", + "", + "contact : The contact who's presence you which to see.", + "nick : If in a chat room, the occupant who's presence you wish to see.", + "", "If in a chat window the parameter is not required, the current recipient will be used.", "", - "Example : /status buddy@server.com", - "Example : /status jon", + "Example: /status buddy@server.com", + "Example: /status jon", NULL } } }, { "/resource", cmd_resource, parse_args, 1, 2, &cons_resource_setting, - { "/resource set|off|title|message [resource]", "Set the contact's resource.", + { "/resource set|off|title|message [resource]", "Set the contact's resource, display settings.", { "/resource set|off|title|message [resource]", "------------------------------------------", - "Set the resource to use when chatting to a contact and manage resource display settings.", - "set resource - Set the resource.", - "off - Let the server choose which resource to route messages to.", - "title on|off - Show or hide the current resource in the titlebar.", - "message on|off - Show or hide the resource from which a message was recieved.", + "Override chat session resource, and manage resource display settings.", + "", + "set resource : Set the resource to which messages will be sent.", + "off : Let the server choose which resource to route messages to.", + "title on|off : Show or hide the current resource in the titlebar.", + "message on|off : Show or hide the resource when showing an incoming message.", NULL } } }, { "/join", - cmd_join, parse_args, 1, 5, NULL, - { "/join room[@server] [nick value] [password value]", "Join a chat room.", - { "/join room[@server] [nick value] [password value]", - "-------------------------------------------------", + cmd_join, parse_args, 0, 5, NULL, + { "/join [room] [nick value] [password value]", "Join a chat room.", + { "/join [room] [nick value] [password value]", + "-----------------------------------------", "Join a chat room at the conference server.", - "If nick is specified you will join with this nickname.", - "Otherwise the account preference 'muc.nick' will be used which by default is the localpart of your JID (before the @).", - "If no server is supplied, the account preference 'muc.service' is used, which is 'conference.<domain-part>' by default.", + "", + "room : Bare room JID (the chat server is determined by the 'muc.service' account property) or full room jid." + "nick value : Nickname to use in the room", + "password value : Password if the room requires it.", + "", + "If no room is supplied, a generated name will be used with the format private-chat-[UUID].", + "If no nickname is specified the account preference 'muc.nick' will be used which by default is the localpart of your JID.", "If the room doesn't exist, and the server allows it, a new one will be created.", "", - "Example : /join jdev@conference.jabber.org", - "Example : /join jdev@conference.jabber.org nick mynick", - "Example : /join private@conference.jabber.org nick mynick password mypassword", - "Example : /join jdev (as user@jabber.org will join jdev@conference.jabber.org)", + "Example: /join", + "Example: /join jdev@conference.jabber.org", + "Example: /join jdev@conference.jabber.org nick mynick", + "Example: /join private@conference.jabber.org nick mynick password mypassword", + "Example: /join jdev (as user@jabber.org will join jdev@conference.jabber.org)", NULL } } }, { "/leave", @@ -324,8 +355,10 @@ static struct cmd_t command_defs[] = { "/invite contact [message]", "Invite contact to chat room.", { "/invite contact [message]", "-------------------------", - "Send a direct invite to the specified contact to the current chat room.", - "If a message is supplied it will be sent as the reason for the invite.", + "Send a direct invite to the current chat room.", + "", + "contact : The contact you wish to invite", + "message : An optional message to send with the invite.", NULL } } }, { "/invites", @@ -333,9 +366,7 @@ static struct cmd_t command_defs[] = { "/invites", "Show outstanding chat room invites.", { "/invites", "--------", - "Show all rooms that you have been invited to, and have not yet been accepted or declind.", - "Use \"/join <room>\" to accept a room invitation.", - "Use \"/decline <room>\" to decline a room invitation.", + "Show all rooms that you have been invited to, and not accepted or declined.", NULL } } }, { "/decline", @@ -343,7 +374,9 @@ static struct cmd_t command_defs[] = { "/decline room", "Decline a chat room invite.", { "/decline room", "-------------", - "Decline invitation to a chat room, the room will no longer be in the list of outstanding invites.", + "Decline a chat room invitation.", + "", + "room : The room for the invite you wish to decline.", NULL } } }, { "/room", @@ -351,9 +384,11 @@ static struct cmd_t command_defs[] = { "/room accept|destroy|config", "Room configuration.", { "/room accept|destroy|config", "---------------------------", - "accept - Accept default room configuration.", - "destroy - Reject default room configuration.", - "config - Edit room configuration.", + "Chat room configuration.", + "", + "accept : Accept default room configuration.", + "destroy : Reject default room configuration.", + "config : Edit room configuration.", NULL } } }, { "/kick", @@ -361,8 +396,10 @@ static struct cmd_t command_defs[] = { "/kick nick [reason]", "Kick occupants from chat rooms.", { "/kick nick [reason]", "-------------------", - "nick - Nickname of the occupant to kick from the room.", - "reason - Optional reason for kicking the occupant.", + "Kick occupants from chat rooms.", + "", + "nick : Nickname of the occupant to kick from the room.", + "reason : Optional reason for kicking the occupant.", NULL } } }, { "/ban", @@ -370,8 +407,10 @@ static struct cmd_t command_defs[] = { "/ban jid [reason]", "Ban users from chat rooms.", { "/ban jid [reason]", "-----------------", - "jid - Bare JID of the user to ban from the room.", - "reason - Optional reason for banning the user.", + "Ban users from chat rooms.", + "", + "jid : Bare JID of the user to ban from the room.", + "reason : Optional reason for banning the user.", NULL } } }, { "/subject", @@ -379,8 +418,10 @@ static struct cmd_t command_defs[] = { "/subject set|clear [subject]", "Set or clear room subject.", { "/subject set|clear [subject]", "----------------------------", - "set subject - Set the room subject.", - "clear - Clear the room subject.", + "Set or clear room subject.", + "", + "set subject : Set the room subject.", + "clear : Clear the room subject.", NULL } } }, { "/affiliation", @@ -388,8 +429,11 @@ static struct cmd_t command_defs[] = { "/affiliation set|list [affiliation] [jid] [reason]", "Manage room affiliations.", { "/affiliation set|list [affiliation] [jid] [reason]", "--------------------------------------------------", - "set affiliation jid [reason]- Set the affiliation of user with jid, with an optional reason.", - "list [affiliation] - List all users with the specified affiliation, or all if none specified.", + "Manage room affiliations.", + "", + "set affiliation jid [reason]: Set the affiliation of user with jid, with an optional reason.", + "list [affiliation] : List all users with the specified affiliation, or all if none specified.", + "", "The affiliation may be one of owner, admin, member, outcast or none.", NULL } } }, @@ -398,20 +442,28 @@ static struct cmd_t command_defs[] = { "/role set|list [role] [nick] [reason]", "Manage room roles.", { "/role set|list [role] [nick] [reason]", "-------------------------------------", - "set role nick [reason] - Set the role of occupant with nick, with an optional reason.", - "list [role] - List all occupants with the specified role, or all if none specified.", + "Manage room roles.", + "", + "set role nick [reason] : Set the role of occupant with nick, with an optional reason.", + "list [role] : List all occupants with the specified role, or all if none specified.", + "", "The role may be one of moderator, participant, visitor or none.", NULL } } }, { "/occupants", - cmd_occupants, parse_args, 1, 2, cons_occupants_setting, - { "/occupants show|hide|default|size [show|hide] [percent]", "Show or hide room occupants.", - { "/occupants show|hide|default|size [show|hide] [percent]", - "-------------------------------------------------------", - "show - Show the occupants panel in chat rooms.", - "hide - Hide the occupants panel in chat rooms.", - "default - Whether occupants are shown by default in new rooms, 'show' or 'hide'", - "size - Percentage of the screen taken by the occupants list in rooms (1-99).", + cmd_occupants, parse_args, 1, 3, cons_occupants_setting, + { "/occupants show|hide|default|size [jid|show|hide|percent] [jid]", "Show or hide room occupants.", + { "/occupants show|hide|default|size [jid|show|hide|percent] [jid]", + "---------------------------------------------------------------", + "Show or hide room occupants, and occupants panel display settings.", + "", + "show : Show the occupants panel in current room.", + "hide : Hide the occupants panel in current room.", + "show jid : Show jid in the occupants panel in current room.", + "hide jid : Hide jid in the occupants panel in current room.", + "default show|hide : Whether occupants are shown by default in new rooms.", + "default show|hide jid : Whether occupants jids are shown by default in new rooms.", + "size percent : Percentage of the screen taken by the occupants list in rooms (1-99).", NULL } } }, { "/form", @@ -419,10 +471,12 @@ static struct cmd_t command_defs[] = { "/form show|submit|cancel|help [tag]", "Form handling.", { "/form show|submit|cancel|help [tag]", "-----------------------------------", - "show - Show the current form.", - "submit - Submit the current form.", - "cancel - Cancel changes to the current form.", - "help [tag] - Display help for form, or a specific field.", + "Form configuration.", + "", + "show : Show the current form.", + "submit : Submit the current form.", + "cancel : Cancel changes to the current form.", + "help [tag] : Display help for form, or a specific field.", NULL } } }, { "/rooms", @@ -431,45 +485,51 @@ static struct cmd_t command_defs[] = { "/rooms [conference-service]", "---------------------------", "List the chat rooms available at the specified conference service", - "If no argument is supplied, the account preference 'muc.service' is used, which is 'conference.<domain-part>' by default.", "", - "Example : /rooms conference.jabber.org", - "Example : /rooms (if logged in as me@server.org, is equivalent to /rooms conference.server.org)", + "conference-service : The conference service to query.", + "", + "If no argument is supplied, the account preference 'muc.service' is used, 'conference.<domain-part>' by default.", + "", + "Example: /rooms conference.jabber.org", + "Example: /rooms (if logged in as me@server.org, is equivalent to /rooms conference.server.org)", NULL } } }, { "/bookmark", cmd_bookmark, parse_args, 0, 8, NULL, - { "/bookmark [list|add|update|remove|join] [room@server] [nick value] [password value] [autojoin on|off]", "Manage bookmarks.", - { "/bookmark [list|add|update|remove|join] [room@server] [nick value] [password value] [autojoin on|off]", - "---------------------------------------------------------------------------------------------------", - "Manage bookmarks.", - "list: List all bookmarks.", - "add: Add a bookmark for room@server with the following optional properties:", - " nick: Nickname used in the chat room", - " password: Password for private rooms, note this may be stored in plaintext on your server", - " autojoin: Whether to join the room automatically on login \"on\" or \"off\".", - "update: Update any of the above properties associated with the bookmark.", - "remove: Remove the bookmark for room@server.", - "join: Join room@server using the properties associated with the bookmark.", - "When in a chat room, the /bookmark command with no arguments will bookmark the current room with the current settings, and set autojoin to \"on\".", + { "/bookmark [command] [args..]", "Manage bookmarks.", + { "/bookmark [command] [args..]", + "----------------------------", + "Manage bookmarks and join bookmarked rooms.", + "", + "command : list|add|update|remove|join", + "", + "list : List all bookmarks.", + "add room@server [prop value..] : Add a bookmark for room@server with the following optional properties:", + " nick value : Nickname used in the chat room", + " password value : Password if required, may be stored in plaintext on your server", + " autojoin on|off : Whether to join the room automatically on login.", + "update room@server [prop value..] : Update any of the above properties associated with the bookmark.", + "remove room@server : Remove the bookmark for room@server.", + "join room@server : Join room using the properties associated with the bookmark.", + "", + "In a chat room, /bookmark with no arguments will bookmark the current room, setting autojoin to \"on\".", NULL } } }, { "/disco", cmd_disco, parse_args, 1, 2, NULL, - { "/disco command entity", "Service discovery.", - { "/disco command entity", + { "/disco info|items entity", "Service discovery.", + { "/disco info|items entity", "---------------------", "Find out information about an entities supported services.", - "Command may be one of:", - "info: List protocols and features supported by an entity.", - "items: List items associated with an entity.", "", - "The entity must be a Jabber ID.", + "info : List protocols and features supported by an entity.", + "items : List items associated with an entity.", + "entity : Jabber ID.", "", - "Example : /disco info myserver.org", - "Example : /disco items myserver.org", - "Example : /disco items conference.jabber.org", - "Example : /disco info myfriend@server.com/laptop", + "Example: /disco info myserver.org", + "Example: /disco items myserver.org", + "Example: /disco items conference.jabber.org", + "Example: /disco info myfriend@server.com/laptop", NULL } } }, { "/nick", @@ -478,47 +538,52 @@ static struct cmd_t command_defs[] = { "/nick nickname", "--------------", "Change the name by which other members of a chat room see you.", - "This command is only valid when called within a chat room window.", "", - "Example : /nick kai hansen", - "Example : /nick bob", + "nickname : The new nickname.", + "", + "Example: /nick kai hansen", + "Example: /nick bob", NULL } } }, { "/win", cmd_win, parse_args, 1, 1, NULL, { "/win num", "View a window.", { "/win num", - "------------------", + "--------", "Show the contents of a specific window in the main window area.", + "", + "num - Window number to display.", NULL } } }, { "/wins", cmd_wins, parse_args, 0, 3, NULL, - { "/wins [tidy|prune|swap] [source] [target]", "List or tidy active windows.", - { "/wins [tidy|prune|swap] [source] [target]", - "-----------------------------------------", - "Passing no argument will list all currently active windows and information about their usage.", - "tidy : Shuffle windows so there are no gaps.", + { "/wins [tidy|prune|swap] [source target]", "List or tidy active windows.", + { "/wins [tidy|prune|swap] [source target]", + "---------------------------------------", + "Show a list of windows, or tidy or swap.", + "", + "tidy : Move windows so there are no gaps.", "prune : Close all windows with no unread messages, and then tidy as above.", "swap source target : Swap windows, target may be an empty position.", + "", + "Passing no argument will list all currently active windows and information about their usage.", NULL } } }, { "/sub", cmd_sub, parse_args, 1, 2, NULL, - { "/sub command [jid]", "Manage subscriptions.", - { "/sub command [jid]", - "------------------", - "command : One of the following,", - "request : Send a subscription request to the user to be informed of their", - " : presence.", - "allow : Approve a contact's subscription reqeust to see your presence.", - "deny : Remove subscription for a contact, or deny a request", - "show : Show subscriprion status for a contact.", - "sent : Show all sent subscription requests pending a response.", - "received : Show all received subscription requests awaiting your response.", - "", - "The optional 'jid' parameter only applys to 'request', 'allow', 'deny' and 'show'", - "If it is omitted the contact of the current window is used.", + { "/sub request|allow|deny|show|sent|received [jid]", "Manage subscriptions.", + { "/sub request|allow|deny|show|sent|received [jid]", + "------------------------------------------------", + "Manage subscriptions to contact presence.", + "", + "request [jid] : Send a subscription request to the user.", + "allow [jid] : Approve a contact's subscription request.", + "deny [jid] : Remove subscription for a contact, or deny a request", + "show [jid] : Show subscription status for a contact.", + "sent : Show all sent subscription requests pending a response.", + "received : Show all received subscription requests awaiting your response.", + "", + "If jid is omitted, the contact of the current window is used.", "", "Example: /sub request myfriend@jabber.org", "Example: /sub allow myfriend@jabber.org", @@ -531,9 +596,11 @@ static struct cmd_t command_defs[] = { "/tiny url", "Send url as tinyurl in current chat.", { "/tiny url", "---------", - "Send the url as a tiny url.", + "Send url as tinyurl in current chat.", + "", + "url : The url to make tiny.", "", - "Example : /tiny http://www.profanity.im", + "Example: /tiny http://www.profanity.im", NULL } } }, { "/who", @@ -541,31 +608,30 @@ static struct cmd_t command_defs[] = { "/who [status|role|affiliation] [group]", "Show contacts/room occupants with chosen status, role or affiliation", { "/who [status|role|affiliation] [group]", "--------------------------------------", - "Normal usage:", - "Status may be one of - online, offline, away, dnd, xa, chat, available, unavailable, or any where:", - "online : Contacts that are online, chat, away, xa, dnd", - "available : Contacts that are available for chat - online, chat.", - "unavailable : Contacts that are not available for chat - offline, away, xa, dnd.", - "any : Contacts with any status (same as calling with no argument).", + "Show contacts/room occupants with chosen status, role or affiliation", "", - "The group argument filters the list by that group.", - "", - "In a chat room, a role or affiliation may also be supplied instead of status.", - "Roles: moderator, participant, visitor", - "Affiliations: owner, admin, member", + "status : online|offline|away|dnd|xa|chat|available|unavailable|any", + " online : Contacts that are online, chat, away, xa, dnd", + " available : Contacts that are available for chat - online, chat.", + " unavailable : Contacts that are not available for chat - offline, away, xa, dnd.", + " any : Contacts with any status (same as calling with no argument).", + "role : moderator|participant|visitor", + "affiliation : owner|admin|member", + "group : Filter the results by the specified group.", NULL } } }, { "/close", cmd_close, parse_args, 0, 1, NULL, - { "/close [win|read|all]", "Close windows.", - { "/close [win|read|all]", + { "/close [num|read|all]", "Close windows.", + { "/close [num|read|all]", "---------------------", + "Close the current window, or a number of windows.", + "", + "num : Close the specified window.", + "all : Close all windows.", + "read : Close all windows that have no new messages.", + "", "Passing no argument will close the current window.", - "2,3,4,5,6,7,8,9 or 0 : Close the specified window.", - "all : Close all currently open windows.", - "read : Close all windows that have no new messages.", - "The console window cannot be closed.", - "If in a chat room, you will leave the room.", NULL } } }, { "/clear", @@ -588,8 +654,8 @@ static struct cmd_t command_defs[] = cmd_privileges, parse_args, 1, 1, &cons_privileges_setting, { "/privileges on|off", "Show occupant privileges in chat rooms.", { "/privileges on|off", - "---------------------------", - "If enabled the room roster will be broken down my role, and role information will be showin in the room.", + "------------------", + "If enabled the room occupants panel will be grouped by role, and role information will be shown in the room.", NULL } } }, { "/beep", @@ -607,7 +673,7 @@ static struct cmd_t command_defs[] = { "/presence on|off", "Show the contacts presence in the titlebar.", { "/presence on|off", "----------------", - "Switch display of the contacts presence on or off.", + "Switch display of the contacts presence in the titlebar on or off.", NULL } } }, { "/wrap", @@ -615,71 +681,61 @@ static struct cmd_t command_defs[] = { "/wrap on|off", "Word wrapping.", { "/wrap on|off", "------------", - "Enable or disable word wrapping.", + "Enable or disable word wrapping in the main window.", NULL } } }, { "/time", - cmd_time, parse_args, 1, 1, &cons_time_setting, - { "/time <format>", "Time display.", - { "/time <format>", - "---------------------", - "Configure the time format for the main window.", + cmd_time, parse_args, 1, 3, &cons_time_setting, + { "/time main|statusbar set|off [format]", "Time display.", + { "/time main|statusbar set|off [format]", + "---------------------------------", + "Configure time display preferences.", + "", + "main set <format> : Change strftime format to <format> in main window.", + "main off : Do not show time in main window.", + "statusbar set <format> : Change strftime format to <format> in statusbar.", + "statusbar off : Do not show time in status bar.", NULL } } }, { "/inpblock", cmd_inpblock, parse_args, 2, 2, &cons_inpblock_setting, - { "/inpblock timeout|dynamic [millis|on|off]", "Input blocking delay (dynamic or static).", + { "/inpblock timeout|dynamic [millis|on|off]", "Configure input blocking.", { "/inpblock timeout|dynamic [millis|on|off]", "-----------------------------------------", "How long to wait for input before checking for new messages or checking for state changes such as 'idle'.", - "timeout : Time to wait in milliseconds before reading input from the terminal buffer, defaults to 500.", - " : Valid values are 1-1000.", - "dynamic : Start with a 0 timeout and increase the value dynamically up to the specified 'timeout'.", - " : on|off", - "A higher timeout will result in less CPU usage, but a noticable delay for response to input.", - "A lower timeout will result in higher CPU usage, but faster response to input.", - "Using the dynamic setting, higher CPU usage will occur during activity, but over time the CPU usage will decrease whilst there is no activity.", + "", + "timeout millis : Time to wait (1-1000) in milliseconds before reading input from the terminal buffer, default: 1000.", + "dynamic on|off : Start with 0 millis and dynamically increase up to timeout when no activity, default: on.", NULL } } }, { "/notify", cmd_notify, parse_args, 2, 3, &cons_notify_setting, - { "/notify [type value]|[type setting value]", "Control various desktop noficiations.", + { "/notify [type value]|[type setting value]", "Control various desktop notifications.", { "/notify [type value]|[type setting value]", "-----------------------------------------", - "Settings for various desktop notifications where type is one of:", - "message : Notificaitons for regular messages.", - " : on|off", - "message current : Whether messages in the current window trigger notifications.", - " : on|off", - "message text : Show message text in message notifications.", - " : on|off", - "room : Notificaitons for chat room messages.", - " : on|off|mention", - "room current : Whether chat room messages in the current window trigger notifications.", - " : on|off", - "room text : Show message test in chat room message notifications.", - " : on|off", - "remind : Notification reminders of unread messages.", - " : where value is the reminder period in seconds,", - " : use 0 to disable.", - "typing : Notifications when contacts are typing.", - " : on|off", - "typing current : Whether typing notifications are triggerd for the current window.", - " : on|off", - "invite : Notifications for chat room invites.", - " : on|off", - "sub : Notifications for subscription requests.", - " : on|off", - "", - "Example : /notify message on (enable message notifications)", - "Example : /notify message text on (show message text in notifications)", - "Example : /notify room mention (enable chat room notifications only on mention)", - "Example : /notify room current off (disable room message notifications when window visible)", - "Example : /notify room text off (do not show message text in chat room notifications)", - "Example : /notify remind 10 (remind every 10 seconds)", - "Example : /notify remind 0 (switch off reminders)", - "Example : /notify typing on (enable typing notifications)", - "Example : /notify invite on (enable chat room invite notifications)", + "Settings for various kinds of desktop notifications.", + "", + "message on|off : Notifications for regular messages.", + "message current on|off : Whether messages in the current window trigger notifications.", + "message text on|off : Show message text in message notifications.", + "room on|off|mention : Notifications for chat room messages.", + "room current on|off : Whether chat room messages in the current window trigger notifications.", + "room text on|off : Show message text in chat room message notifications.", + "remind seconds : Notification reminder period for unread messages, use 0 to disable.", + "typing on|off : Notifications when contacts are typing.", + "typing current of|off : Whether typing notifications are triggered for the current window.", + "invite on|off : Notifications for chat room invites.", + "sub on|off : Notifications for subscription requests.", + "", + "Example: /notify message on (enable message notifications)", + "Example: /notify message text on (show message text in notifications)", + "Example: /notify room mention (enable chat room notifications only on mention)", + "Example: /notify room current off (disable room message notifications when window visible)", + "Example: /notify room text off (do not show message text in chat room notifications)", + "Example: /notify remind 10 (remind every 10 seconds)", + "Example: /notify remind 0 (switch off reminders)", + "Example: /notify typing on (enable typing notifications)", + "Example: /notify invite on (enable chat room invite notifications)", NULL } } }, { "/flash", @@ -687,8 +743,7 @@ static struct cmd_t command_defs[] = { "/flash on|off", "Terminal flash on new messages.", { "/flash on|off", "-------------", - "Make the terminal flash when incoming messages are received.", - "The flash will only occur if you are not in the chat window associated with the user sending the message.", + "Make the terminal flash when incoming messages are received in another window.", "If the terminal doesn't support flashing, it may attempt to beep.", NULL } } }, @@ -717,7 +772,7 @@ static struct cmd_t command_defs[] = "The setting can be overridden by the -a (--account) command line option.", "", "Example: /autoconnect set jc@stuntteam.org (autoconnect with the specified account).", - "Example: /autoconnect off (disable autoconnect).", + "Example: /autoconnect off (disable autoconnect).", NULL } } }, { "/vercheck", @@ -725,18 +780,18 @@ static struct cmd_t command_defs[] = { "/vercheck [on|off]", "Check for a new release.", { "/vercheck [on|off]", "------------------", - "Without a parameter will check for a new release.", - "Switching on or off will enable/disable a version check when Profanity starts, and each time the /about command is run.", + "Enable/disable a version check when Profanity starts, and each time the /about command is run.", NULL } } }, { "/titlebar", cmd_titlebar, parse_args, 2, 2, &cons_titlebar_setting, { "/titlebar show|goodbye on|off", "Manage the terminal window title.", { "/titlebar show|goodbye on|off", - "---------------------", + "-----------------------------", "Show or hide a title and exit message in the terminal window title.", - "show - Show current logged in user, and unread messages in the title.", - "goodbye - Show a message in the title when exiting profanity.", + "", + "show : Show current logged in user, and unread messages in the title.", + "goodbye : Show a message in the title when exiting profanity.", NULL } } }, { "/mouse", @@ -744,12 +799,7 @@ static struct cmd_t command_defs[] = { "/mouse on|off", "Use profanity mouse handling.", { "/mouse on|off", "-------------", - "If set to 'on', profanity will handle mouse actions, which enables scrolling the main window with the mouse wheel.", - "To select text, use the shift key while selcting an area.", - "If set to 'off', profanity leaves mouse handling to the terminal implementation.", - "This feature is experimental, certain mouse click events may occasionally freeze", - "Profanity until a key is pressed or another mouse event is received", - "The default is 'off'.", + "This feature is experimental, default is 'off'.", NULL } } }, { "/alias", @@ -758,12 +808,17 @@ static struct cmd_t command_defs[] = { "/alias add|remove|list [name value]", "-----------------------------------", "Add, remove or show command aliases.", - "The alias will be available as a command, the leading '/' will be added if not supplied.", - "Example : /alias add friends /who online friends", - "Example : /alias add /q /quit", - "Example : /alias a /away \"I'm in a meeting.\"", - "Example : /alias remove q", - "Example : /alias list", + "", + "add name value : Add a new command alias.", + "remove name : Remove a command alias.", + "list : List all aliases.", + "", + "Example: /alias add friends /who online friends", + "Example: /alias add /q /quit", + "Example: /alias a /away \"I'm in a meeting.\"", + "Example: /alias remove q", + "Example: /alias list", + "", "The above aliases will be available as /friends and /a", NULL } } }, @@ -792,29 +847,30 @@ static struct cmd_t command_defs[] = { "/states on|off", "Send chat states during a chat session.", { "/states on|off", "--------------", - "Sending of chat state notifications during chat sessions.", - "Such as whether you have become inactive, or have closed the chat window.", + "Send chat state notifications during chat sessions.", NULL } } }, { "/otr", cmd_otr, parse_args, 1, 3, NULL, - { "/otr gen|myfp|theirfp|start|end|trust|untrust|log|warn|libver|policy|secret|question|answer", "Off The Record encryption commands.", - { "/otr gen|myfp|theirfp|start|end|trust|untrust|log|warn|libver|policy|secret|question|answer", - "-------------------------------------------------------------------------------------------", - "gen - Generate your private key.", - "myfp - Show your fingerprint.", - "theirfp - Show contacts fingerprint.", - "start [contact] - Start an OTR session with the contact, or the current recipient if in a chat window and no argument supplied.", - "end - End the current OTR session,", - "trust - Indicate that you have verified the contact's fingerprint.", - "untrust - Indicate the the contact's fingerprint is not verified,", - "log - How to log OTR messages, options are 'on', 'off' and 'redact', with redaction being the default.", - "warn - Show when unencrypted messaging is being used in the title bar, options are 'on' and 'off' with 'on' being the default.", - "libver - Show which version of the libotr library is being used.", - "policy - manual, opportunistic or always.", - "secret [secret]- Verify a contacts identity using a shared secret.", - "question [question] [answer] - Verify a contacts identity using a question and expected anwser, if the question has spaces, surround with double quotes.", - "answer [answer] - Respond to a question answer verification request with your answer.", + { "/otr command [args..]", "Off The Record encryption commands.", + { "/otr command [args..]", + "---------------------", + "Off The Record encryption commands.", + "", + "gen : Generate your private key.", + "myfp : Show your fingerprint.", + "theirfp : Show contacts fingerprint.", + "start [contact] : Start an OTR session with contact, or current recipient if omitted.", + "end : End the current OTR session,", + "trust : Indicate that you have verified the contact's fingerprint.", + "untrust : Indicate the the contact's fingerprint is not verified,", + "log on|off|redact : OTR message logging, default: redact.", + "warn on|off : Show in the titlebar when unencrypted messaging is being used.", + "libver : Show which version of the libotr library is being used.", + "policy manual|opportunistic|always : Set the global OTR policy.", + "secret [secret] : Verify a contacts identity using a shared secret.", + "question [question] [answer] : Verify a contacts identity using a question and expected answer.", + "answer [answer] : Respond to a question answer verification request with your answer.", NULL } } }, { "/outtype", @@ -822,8 +878,7 @@ static struct cmd_t command_defs[] = { "/outtype on|off", "Send typing notification to recipient.", { "/outtype on|off", "---------------", - "Send an indication that you are typing to the chat recipient.", - "Chat states (/states) will be enabled if this setting is set.", + "Send typing notifications, chat states (/states) will be enabled if this setting is set.", NULL } } }, { "/gone", @@ -831,8 +886,7 @@ static struct cmd_t command_defs[] = { "/gone minutes", "Send 'gone' state to recipient after a period.", { "/gone minutes", "-------------", - "Send a 'gone' state to the recipient after the specified number of minutes." - "This indicates to the recipient's client that you have left the conversation.", + "Send a 'gone' state to the recipient after the specified number of minutes.", "A value of 0 will disable sending this chat state.", "Chat states (/states) will be enabled if this setting is set.", NULL } } }, @@ -848,15 +902,36 @@ static struct cmd_t command_defs[] = { "/log", cmd_log, parse_args, 1, 2, &cons_log_setting, - { "/log [property] [value]", "Manage system logging settings.", - { "/log [property] [value]", - "-----------------------", - "where : Show the current log file location.", - "Property may be one of:", - "rotate : Rotate log, accepts 'on' or 'off', defaults to 'on'.", - "maxsize : With rotate enabled, specifies the max log size, defaults to 1048580 (1MB).", - "shared : Share logs between all instances, accepts 'on' or 'off', defaults to 'on'.", - NULL } } }, + { "/log where|rotate|maxsize|shared [value]", "Manage system logging settings.", + { "/log where|rotate|maxsize|shared [value]", + "----------------------------------------", + "Manage profanity logging settings.", + "", + "where : Show the current log file location.", + "rotate on|off : Rotate log, default on.", + "maxsize bytes : With rotate enabled, specifies the max log size, defaults to 1048580 (1MB).", + "shared on|off : Share logs between all instances, default: on.", + NULL } } }, + + { "/carbons", + cmd_carbons, parse_args, 1, 1, &cons_carbons_setting, + { "/carbons on|off", "Message carbons.", + { "/carbons on|off", + "---------------", + "Enable or disable message carbons.", + "The message carbons feature ensures that both sides of all conversations are shared with all the user's clients that implement this protocol.", + NULL } } }, + + { "/receipts", + cmd_receipts, parse_args, 2, 2, &cons_receipts_setting, + { "/receipts send|request on|off", "Message delivery receipts.", + { "/receipts send|request on|off", + "-----------------------------", + "Enable or disable message delivery receipts. The interface will indicate when a message has been received.", + "", + "send on|off : Enable or disable sending of delivery receipts.", + "request on|off : Enable or disable sending of delivery receipt requests.", + NULL } } }, { "/reconnect", cmd_reconnect, parse_args, 1, 1, &cons_reconnect_setting, @@ -879,26 +954,25 @@ static struct cmd_t command_defs[] = { "/ping", cmd_ping, parse_args, 0, 1, NULL, { "/ping [target]", "Send ping IQ request.", - { "/ping [rarget]", + { "/ping [target]", "--------------", - "Sends an IQ ping stanza to the specificed target.", - "If no target is supplied, your chat server will be used.", + "Sends an IQ ping stanza to the specified target.", + "If no target is supplied, your chat server will be pinged.", NULL } } }, { "/autoaway", cmd_autoaway, parse_args_with_freetext, 2, 2, &cons_autoaway_setting, - { "/autoaway setting value", "Set auto idle/away properties.", - { "/autoaway setting value", - "-----------------------", - "'setting' may be one of 'mode', 'time', 'message' or 'check', with the following values:", - "", - "mode : idle - Sends idle time, whilst your status remains online.", - " away - Sends an away presence.", - " off - Disabled (default).", - "time : Number of minutes before the presence change is sent, the default is 15.", - "message : Optional message to send with the presence change.", - " : off - Disable message (default).", - "check : on|off, when enabled, checks for activity and sends online presence, default is 'on'.", + { "/autoaway mode|time|message|check value", "Set auto idle/away properties.", + { "/autoaway mode|time|message|check value", + "---------------------------------------", + "Manage autoway properties.", + "", + "mode idle : Sends idle time, status remains online.", + "mode away : Sends an away presence.", + "mode off : Disabled (default).", + "time minutes : Number of minutes before the presence change is sent, default: 15.", + "message text|off : Optional message to send with the presence change, default: off (disabled).", + "check on|off : When enabled, checks for activity and sends online presence, default: on.", "", "Example: /autoaway mode idle", "Example: /autoaway time 30", @@ -911,9 +985,11 @@ static struct cmd_t command_defs[] = { "/priority value", "Set priority for the current account.", { "/priority value", "---------------", - "Set priority for the current account, presence will be sent when calling this command.", - "See the /account command for more specific priority settings per presence status.", - "value : Number between -128 and 127. Default value is 0.", + "Set priority for the current account.", + "", + "value : Number between -128 and 127, default: 0.", + "", + "See the /account command for specific priority settings per presence status.", NULL } } }, { "/account", @@ -922,6 +998,7 @@ static struct cmd_t command_defs[] = { "/account [command] [account] [property] [value]", "-----------------------------------------------", "Commands for creating and managing accounts.", + "", "list : List all accounts.", "show account : Show information about an account.", "enable account : Enable the account, it will be used for autocomplete.", @@ -933,43 +1010,38 @@ static struct cmd_t command_defs[] = "set account property value : Set 'property' of 'account' to 'value'.", "clear account property value : Clear 'property' of 'account'.", "", - "When connected, the /account command can be called with no arguments, to show current account settings.", - "", - "The set command may use one of the following for 'property'.", - "jid : The Jabber ID of the account, the account name will be used if this property is not set.", - "server : The chat server, if different to the domainpart of the JID.", - "port : The port used for connecting if not the default (5222, or 5223 for SSL).", - "status : The presence status to use on login, use 'last' to use whatever your last status was.", - "online|chat|away", - "|xa|dnd : Priority for the specified presence.", - "resource : The resource to be used.", - "password : Password for the account, note this is currently stored in plaintext if set.", - "eval_password : Shell command evaluated to retrieve password for the account. Can be used to retrieve password from keyring.", - "muc : The default MUC chat service to use.", - "nick : The default nickname to use when joining chat rooms.", - "otr : Override global OTR policy for this account: manual, opportunistic or always.", - "", - "The clear command works for password, port and server", - "", - "Example : /account add work", - " : /account set work jid me@chatty", - " : /account set work server talk.chat.com", - " : /account set work port 5111", - " : /account set work resource desktop", - " : /account set work muc chatservice.mycompany.com", - " : /account set work nick dennis", - " : /account set work status dnd", - " : /account set work dnd -1", - " : /account set work online 10", - " : /account rename work gtalk", + "Account properties.", + "", + "jid : The Jabber ID of the account, account name will be used if not set.", + "server : The chat server, if different to the domainpart of the JID.", + "port : The port used for connecting if not the default (5222, or 5223 for SSL).", + "status : The presence status to use on login, use 'last' to use your last status before logging out.", + "online|chat|away|xa|dnd : Priority for the specified presence.", + "resource : The resource to be used.", + "password : Password for the account, note this is currently stored in plaintext if set.", + "eval_password : Shell command evaluated to retrieve password for the account. Can be used to retrieve password from keyring.", + "muc : The default MUC chat service to use.", + "nick : The default nickname to use when joining chat rooms.", + "otr : Override global OTR policy for this account: manual, opportunistic or always.", + "", + "Example: /account add me", + "Example: /account set me jid me@chatty", + "Example: /account set me server talk.chat.com", + "Example: /account set me port 5111", + "Example: /account set me muc chatservice.mycompany.com", + "Example: /account set me nick dennis", + "Example: /account set me status dnd", + "Example: /account set me dnd -1", + "Example: /account rename me gtalk", NULL } } }, { "/prefs", cmd_prefs, parse_args, 0, 1, NULL, - { "/prefs [area]", "Show configuration.", - { "/prefs [area]", - "-------------", - "Area is one of:", + { "/prefs [ui|desktop|chat|log|conn|presence]", "Show configuration.", + { "/prefs [ui|desktop|chat|log|conn|presence]", + "------------------------------------------", + "Show preferences for different areas of functionality.", + "", "ui : User interface preferences.", "desktop : Desktop notification preferences.", "chat : Chat state preferences.", @@ -977,22 +1049,22 @@ static struct cmd_t command_defs[] = "conn : Connection handling preferences.", "presence : Chat presence preferences.", "", - "No argument shows all categories.", + "No argument shows all preferences.", NULL } } }, { "/theme", cmd_theme, parse_args, 1, 2, &cons_theme_setting, - { "/theme list|set|colours [theme-name]", "Change colour theme.", - { "/theme list|set|colours [theme-name]", - "------------------------------------", - "Change the colour settings used.", + { "/theme list|load|colours [theme-name]", "Change colour theme.", + { "/theme list|load|colours [theme-name]", + "-------------------------------------", + "Load a theme, includes colours and UI options.", "", - "list : List all available themes.", - "set theme-name : Load the named theme.\"default\" will reset to the default colours.", - "colours : Show the colour values as rendered by the terminal.", + "list : List all available themes.", + "load theme-name : Load the named theme. 'default' will reset to the default theme.", + "colours : Show the colour values as rendered by the terminal.", "", - "Example : /theme list", - "Example : /theme set mycooltheme", + "Example: /theme list", + "Example: /theme load mycooltheme", NULL } } }, @@ -1001,12 +1073,23 @@ static struct cmd_t command_defs[] = { "/statuses console|chat|muc setting", "Set preferences for presence change messages.", { "/statuses console|chat|muc setting", "----------------------------------", - "Configure how presence changes are displayed in various windows.", - "Settings:", - " all - Show all presence changes.", - " online - Show only online/offline changes.", - " none - Don't show any presence changes.", + "Configure which presence changes are displayed in various windows.", + "", + "console : Configure what is displayed in the console window.", + "chat : Configure what is displayed in chat windows.", + "muc : Configure what is displayed in chat room windows.", + "", + "Available options are:", + "", + "all : Show all presence changes.", + "online : Show only online/offline changes.", + "none : Don't show any presence changes.", + "", "The default is 'all' for all windows.", + "", + "Example: /statuses console none", + "Example: /statuses chat online", + "Example: /statuses muc all", NULL } } }, { "/xmlconsole", @@ -1019,57 +1102,52 @@ static struct cmd_t command_defs[] = { "/away", cmd_away, parse_args_with_freetext, 0, 1, NULL, - { "/away [msg]", "Set status to away.", - { "/away [msg]", - "-----------", + { "/away [message]", "Set status to away.", + { "/away [message]", + "---------------", "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", + "Example: /away Gone for lunch", NULL } } }, { "/chat", cmd_chat, parse_args_with_freetext, 0, 1, NULL, - { "/chat [msg]", "Set status to chat (available for chat).", - { "/chat [msg]", - "-----------", + { "/chat [message]", "Set status to chat (available for chat).", + { "/chat [message]", + "---------------", "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!", + "Example: /chat Please talk to me!", NULL } } }, { "/dnd", cmd_dnd, parse_args_with_freetext, 0, 1, NULL, - { "/dnd [msg]", "Set status to dnd (do not disturb).", - { "/dnd [msg]", - "----------", + { "/dnd [message]", "Set status to dnd (do not disturb).", + { "/dnd [message]", + "--------------", "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", + "Example: /dnd I'm in the zone", NULL } } }, { "/online", cmd_online, parse_args_with_freetext, 0, 1, NULL, - { "/online [msg]", "Set status to online.", - { "/online [msg]", - "-------------", + { "/online [message]", "Set status to online.", + { "/online [message]", + "-----------------", "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!", + "Example: /online Up the Irons!", NULL } } }, { "/xa", cmd_xa, parse_args_with_freetext, 0, 1, NULL, - { "/xa [msg]", "Set status to xa (extended away).", - { "/xa [msg]", - "---------", + { "/xa [message]", "Set status to xa (extended away).", + { "/xa [message]", + "-------------", "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", + "Example: /xa This meeting is going to be a long one", NULL } } }, }; @@ -1121,8 +1199,12 @@ static Autocomplete form_ac; static Autocomplete form_field_multi_ac; static Autocomplete occupants_ac; static Autocomplete occupants_default_ac; +static Autocomplete occupants_show_ac; +static Autocomplete time_ac; +static Autocomplete time_statusbar_ac; static Autocomplete resource_ac; static Autocomplete inpblock_ac; +static Autocomplete receipts_ac; /* * Initialise command autocompleter and history @@ -1140,7 +1222,7 @@ cmd_init(void) autocomplete_add(help_ac, "basic"); autocomplete_add(help_ac, "chatting"); autocomplete_add(help_ac, "groupchat"); - autocomplete_add(help_ac, "presence"); + autocomplete_add(help_ac, "presences"); autocomplete_add(help_ac, "contacts"); autocomplete_add(help_ac, "service"); autocomplete_add(help_ac, "settings"); @@ -1163,7 +1245,7 @@ cmd_init(void) // load aliases GList *aliases = prefs_get_aliases(); GList *curr = aliases; - while (curr != NULL) { + while (curr) { ProfAlias *alias = curr->data; GString *ac_alias = g_string_new("/"); g_string_append(ac_alias, alias->name); @@ -1243,8 +1325,8 @@ cmd_init(void) autocomplete_add(autoconnect_ac, "off"); theme_ac = autocomplete_new(); + autocomplete_add(theme_ac, "load"); autocomplete_add(theme_ac, "list"); - autocomplete_add(theme_ac, "set"); autocomplete_add(theme_ac, "colours"); disco_ac = autocomplete_new(); @@ -1460,6 +1542,20 @@ cmd_init(void) autocomplete_add(occupants_default_ac, "show"); autocomplete_add(occupants_default_ac, "hide"); + occupants_show_ac = autocomplete_new(); + autocomplete_add(occupants_show_ac, "jid"); + + time_ac = autocomplete_new(); + autocomplete_add(time_ac, "minutes"); + autocomplete_add(time_ac, "seconds"); + autocomplete_add(time_ac, "off"); + autocomplete_add(time_ac, "statusbar"); + + time_statusbar_ac = autocomplete_new(); + autocomplete_add(time_statusbar_ac, "minutes"); + autocomplete_add(time_statusbar_ac, "seconds"); + autocomplete_add(time_statusbar_ac, "off"); + resource_ac = autocomplete_new(); autocomplete_add(resource_ac, "set"); autocomplete_add(resource_ac, "off"); @@ -1469,6 +1565,10 @@ cmd_init(void) inpblock_ac = autocomplete_new(); autocomplete_add(inpblock_ac, "timeout"); autocomplete_add(inpblock_ac, "dynamic"); + + receipts_ac = autocomplete_new(); + autocomplete_add(receipts_ac, "send"); + autocomplete_add(receipts_ac, "request"); } void @@ -1522,8 +1622,12 @@ cmd_uninit(void) autocomplete_free(form_field_multi_ac); autocomplete_free(occupants_ac); autocomplete_free(occupants_default_ac); + autocomplete_free(occupants_show_ac); + autocomplete_free(time_ac); + autocomplete_free(time_statusbar_ac); autocomplete_free(resource_ac); autocomplete_free(inpblock_ac); + autocomplete_free(receipts_ac); } gboolean @@ -1539,7 +1643,7 @@ cmd_exists(char *cmd) void cmd_autocomplete_add(char *value) { - if (commands_ac != NULL) { + if (commands_ac) { autocomplete_add(commands_ac, value); } } @@ -1547,41 +1651,45 @@ cmd_autocomplete_add(char *value) void cmd_autocomplete_add_form_fields(DataForm *form) { - if (form) { - GSList *fields = autocomplete_create_list(form->tag_ac); - GSList *curr_field = fields; - while (curr_field) { - GString *field_str = g_string_new("/"); - g_string_append(field_str, curr_field->data); - cmd_autocomplete_add(field_str->str); - g_string_free(field_str, TRUE); - curr_field = g_slist_next(curr_field); - } - g_slist_free_full(fields, free); + if (form == NULL) { + return; } + + GSList *fields = autocomplete_create_list(form->tag_ac); + GSList *curr_field = fields; + while (curr_field) { + GString *field_str = g_string_new("/"); + g_string_append(field_str, curr_field->data); + cmd_autocomplete_add(field_str->str); + g_string_free(field_str, TRUE); + curr_field = g_slist_next(curr_field); + } + g_slist_free_full(fields, free); } void cmd_autocomplete_remove_form_fields(DataForm *form) { - if (form) { - GSList *fields = autocomplete_create_list(form->tag_ac); - GSList *curr_field = fields; - while (curr_field) { - GString *field_str = g_string_new("/"); - g_string_append(field_str, curr_field->data); - cmd_autocomplete_remove(field_str->str); - g_string_free(field_str, TRUE); - curr_field = g_slist_next(curr_field); - } - g_slist_free_full(fields, free); + if (form == NULL) { + return; } + + GSList *fields = autocomplete_create_list(form->tag_ac); + GSList *curr_field = fields; + while (curr_field) { + GString *field_str = g_string_new("/"); + g_string_append(field_str, curr_field->data); + cmd_autocomplete_remove(field_str->str); + g_string_free(field_str, TRUE); + curr_field = g_slist_next(curr_field); + } + g_slist_free_full(fields, free); } void cmd_autocomplete_remove(char *value) { - if (commands_ac != NULL) { + if (commands_ac) { autocomplete_remove(commands_ac, value); } } @@ -1589,7 +1697,7 @@ cmd_autocomplete_remove(char *value) void cmd_alias_add(char *value) { - if (aliases_ac != NULL) { + if (aliases_ac) { autocomplete_add(aliases_ac, value); } } @@ -1597,7 +1705,7 @@ cmd_alias_add(char *value) void cmd_alias_remove(char *value) { - if (aliases_ac != NULL) { + if (aliases_ac) { autocomplete_remove(aliases_ac, value); } } @@ -1610,7 +1718,7 @@ cmd_autocomplete(const char * const input) if ((strncmp(input, "/", 1) == 0) && (!str_contains(input, strlen(input), ' '))) { char *found = NULL; found = autocomplete_complete(commands_ac, input, TRUE); - if (found != NULL) { + if (found) { return found; } @@ -1650,8 +1758,8 @@ cmd_reset_autocomplete() autocomplete_reset(autoaway_mode_ac); autocomplete_reset(autoconnect_ac); autocomplete_reset(theme_ac); - if (theme_load_ac != NULL) { - autocomplete_reset(theme_load_ac); + if (theme_load_ac) { + autocomplete_free(theme_load_ac); theme_load_ac = NULL; } autocomplete_reset(account_ac); @@ -1686,8 +1794,12 @@ cmd_reset_autocomplete() autocomplete_reset(form_field_multi_ac); autocomplete_reset(occupants_ac); autocomplete_reset(occupants_default_ac); + autocomplete_reset(occupants_show_ac); + autocomplete_reset(time_ac); + autocomplete_reset(time_statusbar_ac); autocomplete_reset(resource_ac); autocomplete_reset(inpblock_ac); + autocomplete_reset(receipts_ac); if (ui_current_win_type() == WIN_CHAT) { ProfChatWin *chatwin = wins_get_current_chat(); @@ -1724,11 +1836,6 @@ cmd_process_input(char *inp) gboolean result = FALSE; g_strstrip(inp); - // add line to history if something typed - if (strlen(inp) > 0) { - ui_inp_history_append(inp); - } - // just carry on if no input if (strlen(inp) == 0) { result = TRUE; @@ -1742,7 +1849,7 @@ cmd_process_input(char *inp) // call a default handler if input didn't start with '/' } else { - result = _cmd_execute_default(inp); + result = cmd_execute_default(inp); } return result; @@ -1782,7 +1889,7 @@ _cmd_execute(const char * const command, const char * const inp) Command *cmd = g_hash_table_lookup(commands, command); gboolean result = FALSE; - if (cmd != NULL) { + if (cmd) { gchar **args = cmd->parser(inp, cmd->min_args, cmd->max_args, &result); if (result == FALSE) { ui_invalid_command_usage(cmd->help.usage, cmd->setting_func); @@ -1794,145 +1901,15 @@ _cmd_execute(const char * const command, const char * const inp) } } else { gboolean ran_alias = FALSE; - gboolean alias_result = _cmd_execute_alias(inp, &ran_alias); + gboolean alias_result = cmd_execute_alias(inp, &ran_alias); if (!ran_alias) { - return _cmd_execute_default(inp); + return cmd_execute_default(inp); } else { return alias_result; } } } -static gboolean -_cmd_execute_alias(const char * const inp, gboolean *ran) -{ - if (inp[0] != '/') { - ran = FALSE; - return TRUE; - } else { - char *alias = strdup(inp+1); - char *value = prefs_get_alias(alias); - free(alias); - if (value != NULL) { - *ran = TRUE; - return cmd_process_input(value); - } else { - *ran = FALSE; - return TRUE; - } - } -} - -static gboolean -_cmd_execute_default(const char * inp) -{ - jabber_conn_status_t status = jabber_get_connection_status(); - - // handle escaped commands - treat as normal message - if (g_str_has_prefix(inp, "//")) { - inp++; - - // handle unknown commands - } else if ((inp[0] == '/') && (!g_str_has_prefix(inp, "/me "))) { - cons_show("Unknown command: %s", inp); - cons_alert(); - return TRUE; - } - - win_type_t win_type = ui_current_win_type(); - switch (win_type) - { - case WIN_MUC: - if (status != JABBER_CONNECTED) { - ui_current_print_line("You are not currently connected."); - } else { - ProfMucWin *mucwin = wins_get_current_muc(); - message_send_groupchat(mucwin->roomjid, inp); - } - break; - - case WIN_CHAT: - if (status != JABBER_CONNECTED) { - ui_current_print_line("You are not currently connected."); - } else { - ProfWin *current = wins_get_current(); - ProfChatWin *chatwin = (ProfChatWin*)current; - assert(chatwin->memcheck == PROFCHATWIN_MEMCHECK); -#ifdef HAVE_LIBOTR - prof_otrpolicy_t policy = otr_get_policy(chatwin->barejid); - if (policy == PROF_OTRPOLICY_ALWAYS && !otr_is_secure(chatwin->barejid)) { - cons_show_error("Failed to send message. Please check OTR policy"); - return TRUE; - } - if (otr_is_secure(chatwin->barejid)) { - char *encrypted = otr_encrypt_message(chatwin->barejid, inp); - if (encrypted != NULL) { - message_send_chat(chatwin->barejid, encrypted); - otr_free_message(encrypted); - if (prefs_get_boolean(PREF_CHLOG)) { - const char *jid = jabber_get_fulljid(); - Jid *jidp = jid_create(jid); - char *pref_otr_log = prefs_get_string(PREF_OTR_LOG); - if (strcmp(pref_otr_log, "on") == 0) { - chat_log_chat(jidp->barejid, chatwin->barejid, inp, PROF_OUT_LOG, NULL); - } else if (strcmp(pref_otr_log, "redact") == 0) { - chat_log_chat(jidp->barejid, chatwin->barejid, "[redacted]", PROF_OUT_LOG, NULL); - } - prefs_free_string(pref_otr_log); - jid_destroy(jidp); - } - - ui_outgoing_chat_msg("me", chatwin->barejid, inp); - } else { - cons_show_error("Failed to send message."); - } - } else { - message_send_chat(chatwin->barejid, inp); - if (prefs_get_boolean(PREF_CHLOG)) { - const char *jid = jabber_get_fulljid(); - Jid *jidp = jid_create(jid); - chat_log_chat(jidp->barejid, chatwin->barejid, inp, PROF_OUT_LOG, NULL); - jid_destroy(jidp); - } - - ui_outgoing_chat_msg("me", chatwin->barejid, inp); - } -#else - message_send_chat(chatwin->barejid, inp); - if (prefs_get_boolean(PREF_CHLOG)) { - const char *jid = jabber_get_fulljid(); - Jid *jidp = jid_create(jid); - chat_log_chat(jidp->barejid, chatwin->barejid, inp, PROF_OUT_LOG, NULL); - jid_destroy(jidp); - } - - ui_outgoing_chat_msg("me", chatwin->barejid, inp); -#endif - } - break; - - case WIN_PRIVATE: - if (status != JABBER_CONNECTED) { - ui_current_print_line("You are not currently connected."); - } else { - ProfPrivateWin *privatewin = wins_get_current_private(); - message_send_private(privatewin->fulljid, inp); - ui_outgoing_private_msg("me", privatewin->fulljid, inp); - } - break; - - case WIN_CONSOLE: - case WIN_XML: - cons_show("Unknown command: %s", inp); - break; - - default: - break; - } - - return TRUE; -} - static char * _cmd_complete_parameters(const char * const input) { @@ -1942,7 +1919,7 @@ _cmd_complete_parameters(const char * const input) // autocomplete boolean settings gchar *boolean_choices[] = { "/beep", "/intype", "/states", "/outtype", "/flash", "/splash", "/chlog", "/grlog", "/mouse", "/history", - "/vercheck", "/privileges", "/presence", "/wrap" }; + "/vercheck", "/privileges", "/presence", "/wrap", "/carbons" }; for (i = 0; i < ARRAY_SIZE(boolean_choices); i++) { result = autocomplete_param_with_func(input, boolean_choices[i], prefs_autocomplete_boolean_choice); @@ -1958,23 +1935,31 @@ _cmd_complete_parameters(const char * const input) if (nick_ac) { gchar *nick_choices[] = { "/msg", "/info", "/caps", "/status", "/software" } ; + // Remove quote character before and after names when doing autocomplete + char *unquoted = strip_arg_quotes(input); for (i = 0; i < ARRAY_SIZE(nick_choices); i++) { - result = autocomplete_param_with_ac(input, nick_choices[i], nick_ac, TRUE); + result = autocomplete_param_with_ac(unquoted, nick_choices[i], nick_ac, TRUE); if (result) { + free(unquoted); return result; } } + free(unquoted); } // otherwise autocomplete using roster } else { gchar *contact_choices[] = { "/msg", "/info", "/status" }; + // Remove quote character before and after names when doing autocomplete + char *unquoted = strip_arg_quotes(input); for (i = 0; i < ARRAY_SIZE(contact_choices); i++) { - result = autocomplete_param_with_func(input, contact_choices[i], roster_contact_autocomplete); + result = autocomplete_param_with_func(unquoted, contact_choices[i], roster_contact_autocomplete); if (result) { + free(unquoted); return result; } } + free(unquoted); gchar *resource_choices[] = { "/caps", "/software", "/ping" }; for (i = 0; i < ARRAY_SIZE(resource_choices); i++) { @@ -1998,8 +1983,8 @@ _cmd_complete_parameters(const char * const input) } } - gchar *cmds[] = { "/help", "/prefs", "/disco", "/close", "/wins", "/subject", "/room", }; - Autocomplete completers[] = { help_ac, prefs_ac, disco_ac, close_ac, wins_ac, subject_ac, room_ac, }; + gchar *cmds[] = { "/help", "/prefs", "/disco", "/close", "/wins", "/subject", "/room" }; + Autocomplete completers[] = { help_ac, prefs_ac, disco_ac, close_ac, wins_ac, subject_ac, room_ac }; for (i = 0; i < ARRAY_SIZE(cmds); i++) { result = autocomplete_param_with_ac(input, cmds[i], completers[i], TRUE); @@ -2034,6 +2019,8 @@ _cmd_complete_parameters(const char * const input) g_hash_table_insert(ac_funcs, "/resource", _resource_autocomplete); g_hash_table_insert(ac_funcs, "/titlebar", _titlebar_autocomplete); g_hash_table_insert(ac_funcs, "/inpblock", _inpblock_autocomplete); + g_hash_table_insert(ac_funcs, "/time", _time_autocomplete); + g_hash_table_insert(ac_funcs, "/receipts", _receipts_autocomplete); int len = strlen(input); char parsed[len+1]; @@ -2049,7 +2036,7 @@ _cmd_complete_parameters(const char * const input) parsed[i] = '\0'; char * (*ac_func)(const char * const) = g_hash_table_lookup(ac_funcs, parsed); - if (ac_func != NULL) { + if (ac_func) { result = ac_func(input); if (result) { g_hash_table_destroy(ac_funcs); @@ -2073,15 +2060,15 @@ _sub_autocomplete(const char * const input) { char *result = NULL; result = autocomplete_param_with_func(input, "/sub allow", presence_sub_request_find); - if (result != NULL) { + if (result) { return result; } result = autocomplete_param_with_func(input, "/sub deny", presence_sub_request_find); - if (result != NULL) { + if (result) { return result; } result = autocomplete_param_with_ac(input, "/sub", sub_ac, TRUE); - if (result != NULL) { + if (result) { return result; } @@ -2096,7 +2083,7 @@ _who_autocomplete(const char * const input) if (win_type == WIN_MUC) { result = autocomplete_param_with_ac(input, "/who", who_room_ac, TRUE); - if (result != NULL) { + if (result) { return result; } } else { @@ -2107,13 +2094,13 @@ _who_autocomplete(const char * const input) for (i = 0; i < ARRAY_SIZE(group_commands); i++) { result = autocomplete_param_with_func(input, group_commands[i], roster_group_autocomplete); - if (result != NULL) { + if (result) { return result; } } result = autocomplete_param_with_ac(input, "/who", who_roster_ac, TRUE); - if (result != NULL) { + if (result) { return result; } } @@ -2126,31 +2113,31 @@ _roster_autocomplete(const char * const input) { char *result = NULL; result = autocomplete_param_with_func(input, "/roster nick", roster_barejid_autocomplete); - if (result != NULL) { + if (result) { return result; } result = autocomplete_param_with_func(input, "/roster clearnick", roster_barejid_autocomplete); - if (result != NULL) { + if (result) { return result; } result = autocomplete_param_with_func(input, "/roster remove", roster_barejid_autocomplete); - if (result != NULL) { + if (result) { return result; } result = autocomplete_param_with_ac(input, "/roster show", roster_option_ac, TRUE); - if (result != NULL) { + if (result) { return result; } result = autocomplete_param_with_ac(input, "/roster hide", roster_option_ac, TRUE); - if (result != NULL) { + if (result) { return result; } result = autocomplete_param_with_ac(input, "/roster by", roster_by_ac, TRUE); - if (result != NULL) { + if (result) { return result; } result = autocomplete_param_with_ac(input, "/roster", roster_ac, TRUE); - if (result != NULL) { + if (result) { return result; } @@ -2162,28 +2149,28 @@ _group_autocomplete(const char * const input) { char *result = NULL; result = autocomplete_param_with_func(input, "/group show", roster_group_autocomplete); - if (result != NULL) { + if (result) { return result; } result = autocomplete_param_no_with_func(input, "/group add", 4, roster_contact_autocomplete); - if (result != NULL) { + if (result) { return result; } result = autocomplete_param_no_with_func(input, "/group remove", 4, roster_contact_autocomplete); - if (result != NULL) { + if (result) { return result; } result = autocomplete_param_with_func(input, "/group add", roster_group_autocomplete); - if (result != NULL) { + if (result) { return result; } result = autocomplete_param_with_func(input, "/group remove", roster_group_autocomplete); - if (result != NULL) { + if (result) { return result; } result = autocomplete_param_with_ac(input, "/group", group_ac, TRUE); - if (result != NULL) { + if (result) { return result; } @@ -2244,7 +2231,7 @@ _bookmark_autocomplete(const char * const input) found = autocomplete_param_with_ac(input, beginning->str, bookmark_property_ac, TRUE); } g_string_free(beginning, TRUE); - if (found != NULL) { + if (found) { g_strfreev(args); return found; } @@ -2253,15 +2240,15 @@ _bookmark_autocomplete(const char * const input) g_strfreev(args); found = autocomplete_param_with_func(input, "/bookmark remove", bookmark_find); - if (found != NULL) { + if (found) { return found; } found = autocomplete_param_with_func(input, "/bookmark join", bookmark_find); - if (found != NULL) { + if (found) { return found; } found = autocomplete_param_with_func(input, "/bookmark update", bookmark_find); - if (found != NULL) { + if (found) { return found; } @@ -2276,42 +2263,42 @@ _notify_autocomplete(const char * const input) char *result = NULL; result = autocomplete_param_with_func(input, "/notify room current", prefs_autocomplete_boolean_choice); - if (result != NULL) { + if (result) { return result; } result = autocomplete_param_with_func(input, "/notify message current", prefs_autocomplete_boolean_choice); - if (result != NULL) { + if (result) { return result; } result = autocomplete_param_with_func(input, "/notify typing current", prefs_autocomplete_boolean_choice); - if (result != NULL) { + if (result) { return result; } result = autocomplete_param_with_func(input, "/notify room text", prefs_autocomplete_boolean_choice); - if (result != NULL) { + if (result) { return result; } result = autocomplete_param_with_func(input, "/notify message text", prefs_autocomplete_boolean_choice); - if (result != NULL) { + if (result) { return result; } result = autocomplete_param_with_ac(input, "/notify room", notify_room_ac, TRUE); - if (result != NULL) { + if (result) { return result; } result = autocomplete_param_with_ac(input, "/notify message", notify_message_ac, TRUE); - if (result != NULL) { + if (result) { return result; } result = autocomplete_param_with_ac(input, "/notify typing", notify_typing_ac, TRUE); - if (result != NULL) { + if (result) { return result; } @@ -2319,13 +2306,13 @@ _notify_autocomplete(const char * const input) for (i = 0; i < ARRAY_SIZE(boolean_choices); i++) { result = autocomplete_param_with_func(input, boolean_choices[i], prefs_autocomplete_boolean_choice); - if (result != NULL) { + if (result) { return result; } } result = autocomplete_param_with_ac(input, "/notify", notify_ac, TRUE); - if (result != NULL) { + if (result) { return result; } @@ -2338,16 +2325,16 @@ _autoaway_autocomplete(const char * const input) char *result = NULL; result = autocomplete_param_with_ac(input, "/autoaway mode", autoaway_mode_ac, TRUE); - if (result != NULL) { + if (result) { return result; } result = autocomplete_param_with_func(input, "/autoaway check", prefs_autocomplete_boolean_choice); - if (result != NULL) { + if (result) { return result; } result = autocomplete_param_with_ac(input, "/autoaway", autoaway_ac, TRUE); - if (result != NULL) { + if (result) { return result; } @@ -2361,16 +2348,16 @@ _log_autocomplete(const char * const input) result = autocomplete_param_with_func(input, "/log rotate", prefs_autocomplete_boolean_choice); - if (result != NULL) { + if (result) { return result; } result = autocomplete_param_with_func(input, "/log shared", prefs_autocomplete_boolean_choice); - if (result != NULL) { + if (result) { return result; } result = autocomplete_param_with_ac(input, "/log", log_ac, TRUE); - if (result != NULL) { + if (result) { return result; } @@ -2383,12 +2370,12 @@ _autoconnect_autocomplete(const char * const input) char *result = NULL; result = autocomplete_param_with_func(input, "/autoconnect set", accounts_find_enabled); - if (result != NULL) { + if (result) { return result; } result = autocomplete_param_with_ac(input, "/autoconnect", autoconnect_ac, TRUE); - if (result != NULL) { + if (result) { return result; } @@ -2401,12 +2388,12 @@ _otr_autocomplete(const char * const input) char *found = NULL; found = autocomplete_param_with_func(input, "/otr start", roster_contact_autocomplete); - if (found != NULL) { + if (found) { return found; } found = autocomplete_param_with_ac(input, "/otr log", otr_log_ac, TRUE); - if (found != NULL) { + if (found) { return found; } @@ -2421,7 +2408,7 @@ _otr_autocomplete(const char * const input) found = autocomplete_param_with_func(input, beginning->str, roster_contact_autocomplete); g_string_free(beginning, TRUE); - if (found != NULL) { + if (found) { g_strfreev(args); return found; } @@ -2430,18 +2417,18 @@ _otr_autocomplete(const char * const input) g_strfreev(args); found = autocomplete_param_with_ac(input, "/otr policy", otr_policy_ac, TRUE); - if (found != NULL) { + if (found) { return found; } found = autocomplete_param_with_func(input, "/otr warn", prefs_autocomplete_boolean_choice); - if (found != NULL) { + if (found) { return found; } found = autocomplete_param_with_ac(input, "/otr", otr_ac, TRUE); - if (found != NULL) { + if (found) { return found; } @@ -2452,24 +2439,25 @@ static char * _theme_autocomplete(const char * const input) { char *result = NULL; - if ((strncmp(input, "/theme set ", 11) == 0) && (strlen(input) > 11)) { + if ((strncmp(input, "/theme load ", 12) == 0) && (strlen(input) > 12)) { if (theme_load_ac == NULL) { theme_load_ac = autocomplete_new(); GSList *themes = theme_list(); - while (themes != NULL) { - autocomplete_add(theme_load_ac, themes->data); - themes = g_slist_next(themes); + GSList *curr = themes; + while (curr) { + autocomplete_add(theme_load_ac, curr->data); + curr = g_slist_next(curr); } - g_slist_free(themes); + g_slist_free_full(themes, g_free); autocomplete_add(theme_load_ac, "default"); } - result = autocomplete_param_with_ac(input, "/theme set", theme_load_ac, TRUE); - if (result != NULL) { + result = autocomplete_param_with_ac(input, "/theme load", theme_load_ac, TRUE); + if (result) { return result; } } result = autocomplete_param_with_ac(input, "/theme", theme_ac, TRUE); - if (result != NULL) { + if (result) { return result; } @@ -2488,24 +2476,24 @@ _resource_autocomplete(const char * const input) if (contact) { Autocomplete ac = p_contact_resource_ac(contact); found = autocomplete_param_with_ac(input, "/resource set", ac, FALSE); - if (found != NULL) { + if (found) { return found; } } } found = autocomplete_param_with_func(input, "/resource title", prefs_autocomplete_boolean_choice); - if (found != NULL) { + if (found) { return found; } found = autocomplete_param_with_func(input, "/resource message", prefs_autocomplete_boolean_choice); - if (found != NULL) { + if (found) { return found; } found = autocomplete_param_with_ac(input, "/resource", resource_ac, FALSE); - if (found != NULL) { + if (found) { return found; } @@ -2518,17 +2506,17 @@ _titlebar_autocomplete(const char * const input) char *found = NULL; found = autocomplete_param_with_func(input, "/titlebar show", prefs_autocomplete_boolean_choice); - if (found != NULL) { + if (found) { return found; } found = autocomplete_param_with_func(input, "/titlebar goodbye", prefs_autocomplete_boolean_choice); - if (found != NULL) { + if (found) { return found; } found = autocomplete_param_with_ac(input, "/titlebar", titlebar_ac, FALSE); - if (found != NULL) { + if (found) { return found; } @@ -2541,12 +2529,12 @@ _inpblock_autocomplete(const char * const input) char *found = NULL; found = autocomplete_param_with_func(input, "/inpblock dynamic", prefs_autocomplete_boolean_choice); - if (found != NULL) { + if (found) { return found; } found = autocomplete_param_with_ac(input, "/inpblock", inpblock_ac, FALSE); - if (found != NULL) { + if (found) { return found; } @@ -2567,13 +2555,13 @@ _form_autocomplete(const char * const input) DataForm *form = confwin->form; if (form) { found = autocomplete_param_with_ac(input, "/form help", form->tag_ac, TRUE); - if (found != NULL) { + if (found) { return found; } } found = autocomplete_param_with_ac(input, "/form", form_ac, TRUE); - if (found != NULL) { + if (found) { return found; } @@ -2656,13 +2644,51 @@ _occupants_autocomplete(const char * const input) { char *found = NULL; + found = autocomplete_param_with_ac(input, "/occupants default show", occupants_show_ac, TRUE); + if (found) { + return found; + } + + found = autocomplete_param_with_ac(input, "/occupants default hide", occupants_show_ac, TRUE); + if (found) { + return found; + } + found = autocomplete_param_with_ac(input, "/occupants default", occupants_default_ac, TRUE); - if (found != NULL) { + if (found) { + return found; + } + + found = autocomplete_param_with_ac(input, "/occupants show", occupants_show_ac, TRUE); + if (found) { + return found; + } + + found = autocomplete_param_with_ac(input, "/occupants hide", occupants_show_ac, TRUE); + if (found) { return found; } found = autocomplete_param_with_ac(input, "/occupants", occupants_ac, TRUE); - if (found != NULL) { + if (found) { + return found; + } + + return NULL; +} + +static char * +_time_autocomplete(const char * const input) +{ + char *found = NULL; + + found = autocomplete_param_with_ac(input, "/time statusbar", time_statusbar_ac, TRUE); + if (found) { + return found; + } + + found = autocomplete_param_with_ac(input, "/time", time_ac, TRUE); + if (found) { return found; } @@ -2678,9 +2704,9 @@ _kick_autocomplete(const char * const input) ProfMucWin *mucwin = wins_get_current_muc(); Autocomplete nick_ac = muc_roster_ac(mucwin->roomjid); - if (nick_ac != NULL) { + if (nick_ac) { result = autocomplete_param_with_ac(input, "/kick", nick_ac, TRUE); - if (result != NULL) { + if (result) { return result; } } @@ -2698,9 +2724,9 @@ _ban_autocomplete(const char * const input) ProfMucWin *mucwin = wins_get_current_muc(); Autocomplete jid_ac = muc_roster_jid_ac(mucwin->roomjid); - if (jid_ac != NULL) { + if (jid_ac) { result = autocomplete_param_with_ac(input, "/ban", jid_ac, TRUE); - if (result != NULL) { + if (result) { return result; } } @@ -2729,7 +2755,7 @@ _affiliation_autocomplete(const char * const input) result = autocomplete_param_with_ac(input, beginning->str, jid_ac, TRUE); g_string_free(beginning, TRUE); - if (result != NULL) { + if (result) { g_strfreev(args); return result; } @@ -2739,17 +2765,17 @@ _affiliation_autocomplete(const char * const input) } result = autocomplete_param_with_ac(input, "/affiliation set", affiliation_ac, TRUE); - if (result != NULL) { + if (result) { return result; } result = autocomplete_param_with_ac(input, "/affiliation list", affiliation_ac, TRUE); - if (result != NULL) { + if (result) { return result; } result = autocomplete_param_with_ac(input, "/affiliation", privilege_cmd_ac, TRUE); - if (result != NULL) { + if (result) { return result; } @@ -2776,7 +2802,7 @@ _role_autocomplete(const char * const input) result = autocomplete_param_with_ac(input, beginning->str, nick_ac, TRUE); g_string_free(beginning, TRUE); - if (result != NULL) { + if (result) { g_strfreev(args); return result; } @@ -2786,17 +2812,17 @@ _role_autocomplete(const char * const input) } result = autocomplete_param_with_ac(input, "/role set", role_ac, TRUE); - if (result != NULL) { + if (result) { return result; } result = autocomplete_param_with_ac(input, "/role list", role_ac, TRUE); - if (result != NULL) { + if (result) { return result; } result = autocomplete_param_with_ac(input, "/role", privilege_cmd_ac, TRUE); - if (result != NULL) { + if (result) { return result; } @@ -2809,22 +2835,45 @@ _statuses_autocomplete(const char * const input) char *result = NULL; result = autocomplete_param_with_ac(input, "/statuses console", statuses_setting_ac, TRUE); - if (result != NULL) { + if (result) { return result; } result = autocomplete_param_with_ac(input, "/statuses chat", statuses_setting_ac, TRUE); - if (result != NULL) { + if (result) { return result; } result = autocomplete_param_with_ac(input, "/statuses muc", statuses_setting_ac, TRUE); - if (result != NULL) { + if (result) { return result; } result = autocomplete_param_with_ac(input, "/statuses", statuses_ac, TRUE); - if (result != NULL) { + if (result) { + return result; + } + + return NULL; +} + +static char * +_receipts_autocomplete(const char * const input) +{ + char *result = NULL; + + result = autocomplete_param_with_func(input, "/receipts send", prefs_autocomplete_boolean_choice); + if (result) { + return result; + } + + result = autocomplete_param_with_func(input, "/receipts request", prefs_autocomplete_boolean_choice); + if (result) { + return result; + } + + result = autocomplete_param_with_ac(input, "/receipts", receipts_ac, TRUE); + if (result) { return result; } @@ -2837,12 +2886,12 @@ _alias_autocomplete(const char * const input) char *result = NULL; result = autocomplete_param_with_ac(input, "/alias remove", aliases_ac, TRUE); - if (result != NULL) { + if (result) { return result; } result = autocomplete_param_with_ac(input, "/alias", alias_ac, TRUE); - if (result != NULL) { + if (result) { return result; } @@ -2860,7 +2909,7 @@ _connect_autocomplete(const char * const input) if ((strncmp(input, "/connect", 8) == 0) && (result == TRUE)) { GString *beginning = g_string_new("/connect "); g_string_append(beginning, args[0]); - if (args[1] != NULL && args[2] != NULL) { + if (args[1] && args[2]) { g_string_append(beginning, " "); g_string_append(beginning, args[1]); g_string_append(beginning, " "); @@ -2868,7 +2917,7 @@ _connect_autocomplete(const char * const input) } found = autocomplete_param_with_ac(input, beginning->str, connect_property_ac, TRUE); g_string_free(beginning, TRUE); - if (found != NULL) { + if (found) { g_strfreev(args); return found; } @@ -2877,7 +2926,7 @@ _connect_autocomplete(const char * const input) g_strfreev(args); found = autocomplete_param_with_func(input, "/connect", accounts_find_enabled); - if (found != NULL) { + if (found) { return found; } @@ -2891,7 +2940,7 @@ _join_autocomplete(const char * const input) gboolean result = FALSE; found = autocomplete_param_with_func(input, "/join", bookmark_find); - if (found != NULL) { + if (found) { return found; } @@ -2900,7 +2949,7 @@ _join_autocomplete(const char * const input) if ((strncmp(input, "/join", 5) == 0) && (result == TRUE)) { GString *beginning = g_string_new("/join "); g_string_append(beginning, args[0]); - if (args[1] != NULL && args[2] != NULL) { + if (args[1] && args[2]) { g_string_append(beginning, " "); g_string_append(beginning, args[1]); g_string_append(beginning, " "); @@ -2908,7 +2957,7 @@ _join_autocomplete(const char * const input) } found = autocomplete_param_with_ac(input, beginning->str, join_property_ac, TRUE); g_string_free(beginning, TRUE); - if (found != NULL) { + if (found) { g_strfreev(args); return found; } @@ -2935,14 +2984,14 @@ _account_autocomplete(const char * const input) g_string_append(beginning, args[2]); found = autocomplete_param_with_ac(input, beginning->str, otr_policy_ac, TRUE); g_string_free(beginning, TRUE); - if (found != NULL) { + if (found) { g_strfreev(args); return found; } } else { found = autocomplete_param_with_ac(input, beginning->str, account_set_ac, TRUE); g_string_free(beginning, TRUE); - if (found != NULL) { + if (found) { g_strfreev(args); return found; } @@ -2954,7 +3003,7 @@ _account_autocomplete(const char * const input) g_string_append(beginning, args[1]); found = autocomplete_param_with_ac(input, beginning->str, account_clear_ac, TRUE); g_string_free(beginning, TRUE); - if (found != NULL) { + if (found) { g_strfreev(args); return found; } @@ -2974,7 +3023,7 @@ _account_autocomplete(const char * const input) for (i = 0; i < ARRAY_SIZE(account_choice); i++) { found = autocomplete_param_with_func(input, account_choice[i], accounts_find_all); - if (found != NULL) { + if (found) { return found; } } @@ -2982,3 +3031,55 @@ _account_autocomplete(const char * const input) found = autocomplete_param_with_ac(input, "/account", account_ac, TRUE); return found; } + +static int +_cmp_command(Command *cmd1, Command *cmd2) +{ + return g_strcmp0(cmd1->cmd, cmd2->cmd); +} + +void +command_docgen(void) +{ + GList *cmds = NULL; + unsigned int i; + for (i = 0; i < ARRAY_SIZE(command_defs); i++) { + Command *pcmd = command_defs+i; + cmds = g_list_insert_sorted(cmds, pcmd, (GCompareFunc)_cmp_command); + } + + FILE *toc_fragment = fopen("toc_fragment.html", "w"); + FILE *main_fragment = fopen("main_fragment.html", "w"); + + fputs("<ul><li><ul><li>\n", toc_fragment); + fputs("<hr>\n", main_fragment); + + GList *curr = cmds; + while (curr) { + Command *pcmd = curr->data; + + fprintf(toc_fragment, "<a href=\"#%s\">%s</a>,\n", &pcmd->cmd[1], pcmd->cmd); + + fprintf(main_fragment, "<a name=\"%s\"></a>\n", &pcmd->cmd[1]); + fprintf(main_fragment, "<h4>%s</h4>\n", pcmd->cmd); + fputs("<p>Usage:</p>\n", main_fragment); + fprintf(main_fragment, "<p><pre><code>%s</code></pre></p>\n", pcmd->help.usage); + + fputs("<p>Details:</p>\n", main_fragment); + fputs("<p><pre><code>", main_fragment); + int i = 2; + while (pcmd->help.long_help[i]) { + fprintf(main_fragment, "%s\n", pcmd->help.long_help[i++]); + } + fputs("</code></pre></p>\n<a href=\"#top\"><h5>back to top</h5></a><br><hr>\n", main_fragment); + fputs("\n", main_fragment); + + curr = g_list_next(curr); + } + + fputs("</ul></ul>\n", toc_fragment); + + fclose(toc_fragment); + fclose(main_fragment); + g_list_free(cmds); +} diff --git a/src/command/command.h b/src/command/command.h index ffbccfa4..b500404b 100644 --- a/src/command/command.h +++ b/src/command/command.h @@ -1,7 +1,7 @@ /* * command.h * - * Copyright (C) 2012 - 2014 James Booth <boothj5@gmail.com> + * Copyright (C) 2012 - 2015 James Booth <boothj5@gmail.com> * * This file is part of Profanity. * @@ -66,4 +66,6 @@ void cmd_history_append(char *inp); char *cmd_history_previous(char *inp); char *cmd_history_next(char *inp); +void command_docgen(void); + #endif diff --git a/src/command/commands.c b/src/command/commands.c index 02910f99..c5350519 100644 --- a/src/command/commands.c +++ b/src/command/commands.c @@ -1,7 +1,7 @@ /* * commands.c * - * Copyright (C) 2012 - 2014 James Booth <boothj5@gmail.com> + * Copyright (C) 2012 - 2015 James Booth <boothj5@gmail.com> * * This file is part of Profanity. * @@ -38,10 +38,8 @@ #include <stdlib.h> #include <errno.h> #include <assert.h> +#include <uuid/uuid.h> #include <glib.h> -#ifdef HAVE_LIBOTR -#include <libotr/proto.h> -#endif #include "chat_session.h" #include "command/commands.h" @@ -67,12 +65,13 @@ #include "xmpp/bookmark.h" #include "ui/ui.h" #include "ui/windows.h" +#include "event/client_events.h" +#include "event/ui_events.h" static void _update_presence(const resource_presence_t presence, const char * const show, gchar **args); static gboolean _cmd_set_boolean_preference(gchar *arg, struct cmd_help_t help, const char * const display, preference_t pref); -static int _strtoi(char *str, int *saveptr, int min, int max); static void _cmd_show_filtered_help(char *heading, gchar *cmd_filter[], int filter_size); static gint _compare_commands(Command *a, Command *b); static void _who_room(gchar **args, struct cmd_help_t help); @@ -81,115 +80,178 @@ static void _who_roster(gchar **args, struct cmd_help_t help); extern GHashTable *commands; gboolean -cmd_connect(gchar **args, struct cmd_help_t help) +cmd_execute_default(const char * inp) { - gboolean result = FALSE; + // handle escaped commands - treat as normal message + if (g_str_has_prefix(inp, "//")) { + inp++; - jabber_conn_status_t conn_status = jabber_get_connection_status(); + // handle unknown commands + } else if ((inp[0] == '/') && (!g_str_has_prefix(inp, "/me "))) { + cons_show("Unknown command: %s", inp); + cons_alert(); + return TRUE; + } + + // handle non commands in non chat windows + ProfWin *current = wins_get_current(); + if (current->type != WIN_CHAT && current->type != WIN_MUC && current->type != WIN_PRIVATE) { + cons_show("Unknown command: %s", inp); + return TRUE; + } + + jabber_conn_status_t status = jabber_get_connection_status(); + if (status != JABBER_CONNECTED) { + ui_current_print_line("You are not currently connected."); + return TRUE; + } + + switch (current->type) { + case WIN_CHAT: + { + ProfChatWin *chatwin = wins_get_current_chat(); + cl_ev_send_msg(chatwin, inp); + break; + } + case WIN_PRIVATE: + { + ProfPrivateWin *privatewin = wins_get_current_private(); + cl_ev_send_priv_msg(privatewin, inp); + break; + } + case WIN_MUC: + { + ProfMucWin *mucwin = wins_get_current_muc(); + cl_ev_send_muc_msg(mucwin, inp); + break; + } + default: + break; + } + + return TRUE; +} + +gboolean +cmd_execute_alias(const char * const inp, gboolean *ran) +{ + if (inp[0] != '/') { + ran = FALSE; + return TRUE; + } + + char *alias = strdup(inp+1); + char *value = prefs_get_alias(alias); + free(alias); + if (value) { + *ran = TRUE; + return cmd_process_input(value); + } + *ran = FALSE; + return TRUE; +} + +gboolean +cmd_connect(gchar **args, struct cmd_help_t help) +{ + jabber_conn_status_t conn_status = jabber_get_connection_status(); if ((conn_status != JABBER_DISCONNECTED) && (conn_status != JABBER_STARTED)) { cons_show("You are either connected already, or a login is in process."); - result = TRUE; - } else { - gchar *opt_keys[] = { "server", "port", NULL }; - gboolean parsed; + return TRUE; + } - GHashTable *options = parse_options(&args[args[0] ? 1 : 0], opt_keys, &parsed); - if (!parsed) { - cons_show("Usage: %s", help.usage); + gchar *opt_keys[] = { "server", "port", NULL }; + gboolean parsed; + + GHashTable *options = parse_options(&args[args[0] ? 1 : 0], opt_keys, &parsed); + if (!parsed) { + cons_show("Usage: %s", help.usage); + cons_show(""); + return TRUE; + } + + char *altdomain = g_hash_table_lookup(options, "server"); + + int port = 0; + if (g_hash_table_contains(options, "port")) { + char *port_str = g_hash_table_lookup(options, "port"); + char *err_msg = NULL; + gboolean res = strtoi_range(port_str, &port, 1, 65535, &err_msg); + if (!res) { + cons_show(err_msg); cons_show(""); + free(err_msg); + port = 0; return TRUE; } + } - char *altdomain = g_hash_table_lookup(options, "server"); - - int port = 0; - if (g_hash_table_contains(options, "port")) { - char *port_str = g_hash_table_lookup(options, "port"); - if (_strtoi(port_str, &port, 1, 65535) != 0) { - port = 0; - cons_show(""); - return TRUE; - } + char *user = args[0]; + char *def = prefs_get_string(PREF_DEFAULT_ACCOUNT); + if (!user) { + if (def) { + user = def; + cons_show("Using default account %s.", user); + } else { + cons_show("No default account."); + g_free(def); + return TRUE; } + } - char *user = args[0]; - char *def = prefs_get_string(PREF_DEFAULT_ACCOUNT); - if(!user){ - if(def){ - user = def; - cons_show("Using default account %s.", user); + char *lower = g_utf8_strdown(user, -1); + char *jid; + g_free(def); + + // connect with account + ProfAccount *account = accounts_get_account(lower); + if (account) { + // use password if set + if (account->password) { + conn_status = cl_ev_connect_account(account); + + // use eval_password if set + } else if (account->eval_password) { + gboolean res = account_eval_password(account); + if (res) { + conn_status = cl_ev_connect_account(account); + free(account->password); + account->password = NULL; } else { - cons_show("No default account."); - g_free(def); + cons_show("Error evaluating password, see logs for details."); + g_free(lower); return TRUE; } - } - char *lower = g_utf8_strdown(user, -1); - char *jid; - g_free(def); - def = NULL; - - ProfAccount *account = accounts_get_account(lower); - if (account != NULL) { - jid = account_create_full_jid(account); - if(account->eval_password){ - // Evaluate as shell command to retrieve password - GString *cmd = g_string_append(g_string_new(account->eval_password), " 2>/dev/null"); - FILE *stream = popen(cmd->str, "r"); - g_string_free(cmd, TRUE); - if(stream){ - // Limit to READ_BUF_SIZE bytes to prevent overflows in the case of a poorly chosen command - account->password = g_malloc(READ_BUF_SIZE); - if(!account->password){ - log_error("Failed to allocate enough memory to read eval_password output"); - cons_show("Error evaluating password, see logs for details."); - return TRUE; - } - account->password = fgets(account->password, READ_BUF_SIZE, stream); - pclose(stream); - if(!account->password){ - log_error("No result from eval_password."); - cons_show("Error evaluating password, see logs for details."); - return TRUE; - } - g_strstrip(account->password); - } else { - log_error("popen failed when running eval_password."); - cons_show("Error evaluating password, see logs for details."); - return TRUE; - } - } else if (!account->password) { - account->password = ui_ask_password(); - } - cons_show("Connecting with account %s as %s", account->name, jid); - if(g_hash_table_contains(options, "port") || g_hash_table_contains(options, "server")) - cons_show("Ignoring extra connect options. Please set them with /account set"); - conn_status = jabber_connect_with_account(account); - account_free(account); + // no account password setting, prompt } else { - char *passwd = ui_ask_password(); - jid = strdup(lower); - cons_show("Connecting as %s", jid); - conn_status = jabber_connect_with_details(jid, passwd, altdomain, port); - free(passwd); - } - g_free(lower); - - if (conn_status == JABBER_DISCONNECTED) { - cons_show_error("Connection attempt for %s failed.", jid); - log_info("Connection attempt for %s failed", jid); + account->password = ui_ask_password(); + conn_status = cl_ev_connect_account(account); + free(account->password); + account->password = NULL; } - options_destroy(options); + jid = account_create_full_jid(account); - free(jid); + // connect with JID + } else { + jid = strdup(lower); + char *passwd = ui_ask_password(); + conn_status = cl_ev_connect_jid(jid, passwd, altdomain, port); + free(passwd); + } - result = TRUE; + if (conn_status == JABBER_DISCONNECTED) { + cons_show_error("Connection attempt for %s failed.", jid); + log_info("Connection attempt for %s failed", jid); } - return result; + options_destroy(options); + g_free(lower); + free(jid); + + return TRUE; } gboolean @@ -342,7 +404,7 @@ cmd_account(gchar **args, struct cmd_help_t help) } else { accounts_set_jid(account_name, jid->barejid); cons_show("Updated jid for account %s: %s", account_name, jid->barejid); - if (jid->resourcepart != NULL) { + if (jid->resourcepart) { accounts_set_resource(account_name, jid->resourcepart); cons_show("Updated resource for account %s: %s", account_name, jid->resourcepart); } @@ -355,8 +417,12 @@ cmd_account(gchar **args, struct cmd_help_t help) cons_show(""); } else if (strcmp(property, "port") == 0) { int port; - if (_strtoi(value, &port, 1, 65535) != 0) { + char *err_msg = NULL; + gboolean res = strtoi_range(value, &port, 1, 65535, &err_msg); + if (!res) { + cons_show(err_msg); cons_show(""); + free(err_msg); return TRUE; } else { accounts_set_port(account_name, port); @@ -368,7 +434,7 @@ cmd_account(gchar **args, struct cmd_help_t help) cons_show("Updated resource for account %s: %s", account_name, value); cons_show(""); } else if (strcmp(property, "password") == 0) { - if(accounts_get_account(account_name)->eval_password != NULL) { + if(accounts_get_account(account_name)->eval_password) { cons_show("Cannot set password when eval_password is set."); } else { accounts_set_password(account_name, value); @@ -376,7 +442,7 @@ cmd_account(gchar **args, struct cmd_help_t help) cons_show(""); } } else if (strcmp(property, "eval_password") == 0) { - if(accounts_get_account(account_name)->password != NULL) { + if(accounts_get_account(account_name)->password) { cons_show("Cannot set eval_password when password is set."); } else { accounts_set_eval_password(account_name, value); @@ -410,42 +476,46 @@ cmd_account(gchar **args, struct cmd_help_t help) } cons_show(""); } else if (valid_resource_presence_string(property)) { - int intval; - - if (_strtoi(value, &intval, -128, 127) == 0) { - resource_presence_t presence_type = resource_presence_from_string(property); - switch (presence_type) - { - case (RESOURCE_ONLINE): - accounts_set_priority_online(account_name, intval); - break; - case (RESOURCE_CHAT): - accounts_set_priority_chat(account_name, intval); - break; - case (RESOURCE_AWAY): - accounts_set_priority_away(account_name, intval); - break; - case (RESOURCE_XA): - accounts_set_priority_xa(account_name, intval); - break; - case (RESOURCE_DND): - accounts_set_priority_dnd(account_name, intval); - break; - } + int intval; + char *err_msg = NULL; + gboolean res = strtoi_range(value, &intval, -128, 127, &err_msg); + if (res) { + resource_presence_t presence_type = resource_presence_from_string(property); + switch (presence_type) + { + case (RESOURCE_ONLINE): + accounts_set_priority_online(account_name, intval); + break; + case (RESOURCE_CHAT): + accounts_set_priority_chat(account_name, intval); + break; + case (RESOURCE_AWAY): + accounts_set_priority_away(account_name, intval); + break; + case (RESOURCE_XA): + accounts_set_priority_xa(account_name, intval); + break; + case (RESOURCE_DND): + accounts_set_priority_dnd(account_name, intval); + break; + } - jabber_conn_status_t conn_status = jabber_get_connection_status(); - if (conn_status == JABBER_CONNECTED) { - char *connected_account = jabber_get_account_name(); - resource_presence_t last_presence = accounts_get_last_presence(connected_account); + jabber_conn_status_t conn_status = jabber_get_connection_status(); + if (conn_status == JABBER_CONNECTED) { + char *connected_account = jabber_get_account_name(); + resource_presence_t last_presence = accounts_get_last_presence(connected_account); - if (presence_type == last_presence) { - char *message = jabber_get_presence_message(); - presence_update(last_presence, message, 0); - } + if (presence_type == last_presence) { + char *message = jabber_get_presence_message(); + cl_ev_presence_send(last_presence, message, 0); } - cons_show("Updated %s priority for account %s: %s", property, account_name, value); - cons_show(""); } + cons_show("Updated %s priority for account %s: %s", property, account_name, value); + cons_show(""); + } else { + cons_show(err_msg); + free(err_msg); + } } else { cons_show("Invalid property: %s", property); cons_show(""); @@ -652,10 +722,14 @@ gboolean cmd_win(gchar **args, struct cmd_help_t help) { int num = atoi(args[0]); - gboolean switched = ui_switch_win(num); - if (switched == FALSE) { + + ProfWin *window = wins_get_by_num(num); + if (!window) { cons_show("Window %d does not exist.", num); + } else { + ui_ev_focus_win(window); } + return TRUE; } @@ -681,7 +755,7 @@ cmd_help(gchar **args, struct cmd_help_t help) } GList *curr = ordered_commands; - while (curr != NULL) { + while (curr) { Command *cmd = curr->data; cons_show("%-12s: %s", cmd->cmd, cmd->help.short_help); curr = g_list_next(curr); @@ -711,7 +785,7 @@ cmd_help(gchar **args, struct cmd_help_t help) "/rooms", "/tiny", "/who", "/nick", "/privileges", "/info", "/occupants" }; _cmd_show_filtered_help("Groupchat commands", filter, ARRAY_SIZE(filter)); - } else if (strcmp(args[0], "presence") == 0) { + } else if (strcmp(args[0], "presences") == 0) { gchar *filter[] = { "/autoaway", "/away", "/chat", "/dnd", "/online", "/priority", "/account", "/status", "/statuses", "/who", "/xa" }; @@ -727,7 +801,7 @@ cmd_help(gchar **args, struct cmd_help_t help) } else if (strcmp(args[0], "settings") == 0) { gchar *filter[] = { "/account", "/autoaway", "/autoping", "/autoconnect", "/beep", - "/chlog", "/flash", "/gone", "/grlog", "/history", "/intype", + "/carbons", "/chlog", "/flash", "/gone", "/grlog", "/history", "/intype", "/log", "/mouse", "/notify", "/outtype", "/prefs", "/priority", "/reconnect", "/roster", "/splash", "/states", "/statuses", "/theme", "/titlebar", "/vercheck", "/privileges", "/occupants", "/presence", "/wrap" }; @@ -743,12 +817,12 @@ cmd_help(gchar **args, struct cmd_help_t help) const gchar **help_text = NULL; Command *command = g_hash_table_lookup(commands, cmd_with_slash); - if (command != NULL) { + if (command) { help_text = command->help.long_help; } cons_show(""); - if (help_text != NULL) { + if (help_text) { ProfWin *console = wins_get_console(); ui_show_lines(console, help_text); } else { @@ -819,7 +893,7 @@ cmd_theme(gchar **args, struct cmd_help_t help) g_slist_free_full(themes, g_free); // load a theme - } else if (g_strcmp0(args[0], "set") == 0) { + } else if (g_strcmp0(args[0], "load") == 0) { if (args[1] == NULL) { cons_show("Usage: %s", help.usage); } else if (theme_load(args[1])) { @@ -854,13 +928,13 @@ cmd_theme(gchar **args, struct cmd_help_t help) static void _who_room(gchar **args, struct cmd_help_t help) { - if ((g_strv_length(args) == 2) && (args[1] != NULL)) { + if ((g_strv_length(args) == 2) && args[1]) { cons_show("Argument group is not applicable to chat rooms."); return; } // bad arg - if (args[0] != NULL && + if (args[0] && (g_strcmp0(args[0], "online") != 0) && (g_strcmp0(args[0], "available") != 0) && (g_strcmp0(args[0], "unavailable") != 0) && @@ -904,7 +978,7 @@ _who_room(gchar **args, struct cmd_help_t help) } else if (strcmp("available", presence) == 0) { GList *filtered = NULL; - while (occupants != NULL) { + while (occupants) { Occupant *occupant = occupants->data; if (muc_occupant_available(occupant)) { filtered = g_list_append(filtered, occupant); @@ -918,7 +992,7 @@ _who_room(gchar **args, struct cmd_help_t help) } else if (strcmp("unavailable", presence) == 0) { GList *filtered = NULL; - while (occupants != NULL) { + while (occupants) { Occupant *occupant = occupants->data; if (!muc_occupant_available(occupant)) { filtered = g_list_append(filtered, occupant); @@ -932,7 +1006,7 @@ _who_room(gchar **args, struct cmd_help_t help) } else { GList *filtered = NULL; - while (occupants != NULL) { + while (occupants) { Occupant *occupant = occupants->data; const char *presence_str = string_from_resource_presence(occupant->presence); if (strcmp(presence_str, presence) == 0) { @@ -986,7 +1060,7 @@ _who_roster(gchar **args, struct cmd_help_t help) char *presence = args[0]; // bad arg - if ((presence != NULL) + if (presence && (strcmp(presence, "online") != 0) && (strcmp(presence, "available") != 0) && (strcmp(presence, "unavailable") != 0) @@ -1001,13 +1075,13 @@ _who_roster(gchar **args, struct cmd_help_t help) } char *group = NULL; - if ((g_strv_length(args) == 2) && (args[1] != NULL)) { + if ((g_strv_length(args) == 2) && args[1]) { group = args[1]; } cons_show(""); GSList *list = NULL; - if (group != NULL) { + if (group) { list = roster_get_group(group); if (list == NULL) { cons_show("No such group: %s.", group); @@ -1023,7 +1097,7 @@ _who_roster(gchar **args, struct cmd_help_t help) // no arg, show all contacts if ((presence == NULL) || (g_strcmp0(presence, "any") == 0)) { - if (group != NULL) { + if (group) { if (list == NULL) { cons_show("No contacts in group %s.", group); } else { @@ -1043,15 +1117,16 @@ _who_roster(gchar **args, struct cmd_help_t help) } else if (strcmp("available", presence) == 0) { GSList *filtered = NULL; - while (list != NULL) { - PContact contact = list->data; + GSList *curr = list; + while (curr) { + PContact contact = curr->data; if (p_contact_is_available(contact)) { filtered = g_slist_append(filtered, contact); } - list = g_slist_next(list); + curr = g_slist_next(curr); } - if (group != NULL) { + if (group) { if (filtered == NULL) { cons_show("No contacts in group %s are %s.", group, presence); } else { @@ -1066,20 +1141,22 @@ _who_roster(gchar **args, struct cmd_help_t help) cons_show_contacts(filtered); } } + g_slist_free(filtered); // unavailable } else if (strcmp("unavailable", presence) == 0) { GSList *filtered = NULL; - while (list != NULL) { - PContact contact = list->data; + GSList *curr = list; + while (curr) { + PContact contact = curr->data; if (!p_contact_is_available(contact)) { filtered = g_slist_append(filtered, contact); } - list = g_slist_next(list); + curr = g_slist_next(curr); } - if (group != NULL) { + if (group) { if (filtered == NULL) { cons_show("No contacts in group %s are %s.", group, presence); } else { @@ -1094,20 +1171,22 @@ _who_roster(gchar **args, struct cmd_help_t help) cons_show_contacts(filtered); } } + g_slist_free(filtered); // online, available resources } else if (strcmp("online", presence) == 0) { GSList *filtered = NULL; - while (list != NULL) { - PContact contact = list->data; + GSList *curr = list; + while (curr) { + PContact contact = curr->data; if (p_contact_has_available_resource(contact)) { filtered = g_slist_append(filtered, contact); } - list = g_slist_next(list); + curr = g_slist_next(curr); } - if (group != NULL) { + if (group) { if (filtered == NULL) { cons_show("No contacts in group %s are %s.", group, presence); } else { @@ -1122,20 +1201,22 @@ _who_roster(gchar **args, struct cmd_help_t help) cons_show_contacts(filtered); } } + g_slist_free(filtered); // offline, no available resources } else if (strcmp("offline", presence) == 0) { GSList *filtered = NULL; - while (list != NULL) { - PContact contact = list->data; + GSList *curr = list; + while (curr) { + PContact contact = curr->data; if (!p_contact_has_available_resource(contact)) { filtered = g_slist_append(filtered, contact); } - list = g_slist_next(list); + curr = g_slist_next(curr); } - if (group != NULL) { + if (group) { if (filtered == NULL) { cons_show("No contacts in group %s are %s.", group, presence); } else { @@ -1150,20 +1231,22 @@ _who_roster(gchar **args, struct cmd_help_t help) cons_show_contacts(filtered); } } + g_slist_free(filtered); // show specific status } else { GSList *filtered = NULL; - while (list != NULL) { - PContact contact = list->data; + GSList *curr = list; + while (curr) { + PContact contact = curr->data; if (strcmp(p_contact_presence(contact), presence) == 0) { filtered = g_slist_append(filtered, contact); } - list = g_slist_next(list); + curr = g_slist_next(curr); } - if (group != NULL) { + if (group) { if (filtered == NULL) { cons_show("No contacts in group %s are %s.", group, presence); } else { @@ -1178,6 +1261,7 @@ _who_roster(gchar **args, struct cmd_help_t help) cons_show_contacts(filtered); } } + g_slist_free(filtered); } g_slist_free(list); @@ -1218,6 +1302,7 @@ cmd_msg(gchar **args, struct cmd_help_t help) return TRUE; } + // send private message when in MUC room if (win_type == WIN_MUC) { ProfMucWin *mucwin = wins_get_current_muc(); if (muc_roster_contains_nick(mucwin->roomjid, usr)) { @@ -1225,11 +1310,14 @@ cmd_msg(gchar **args, struct cmd_help_t help) g_string_append(full_jid, "/"); g_string_append(full_jid, usr); - if (msg != NULL) { - message_send_private(full_jid->str, msg); - ui_outgoing_private_msg("me", full_jid->str, msg); - } else { - ui_new_private_win(full_jid->str); + ProfPrivateWin *privwin = wins_get_private(full_jid->str); + if (!privwin) { + privwin = ui_ev_new_private_win(full_jid->str); + } + ui_ev_focus_win((ProfWin*)privwin); + + if (msg) { + cl_ev_send_priv_msg(privwin, msg); } g_string_free(full_jid, TRUE); @@ -1240,85 +1328,30 @@ cmd_msg(gchar **args, struct cmd_help_t help) return TRUE; + // send chat message } else { - // get barejid char *barejid = roster_barejid_from_name(usr); if (barejid == NULL) { barejid = usr; } - if (msg != NULL) { -#ifdef HAVE_LIBOTR - if (otr_is_secure(barejid)) { - char *encrypted = otr_encrypt_message(barejid, msg); - if (encrypted != NULL) { - message_send_chat(barejid, encrypted); - otr_free_message(encrypted); - ui_outgoing_chat_msg("me", barejid, msg); - - if (((win_type == WIN_CHAT) || (win_type == WIN_CONSOLE)) && prefs_get_boolean(PREF_CHLOG)) { - const char *jid = jabber_get_fulljid(); - Jid *jidp = jid_create(jid); - char *pref_otr_log = prefs_get_string(PREF_OTR_LOG); - if (strcmp(pref_otr_log, "on") == 0) { - chat_log_chat(jidp->barejid, barejid, msg, PROF_OUT_LOG, NULL); - } else if (strcmp(pref_otr_log, "redact") == 0) { - chat_log_chat(jidp->barejid, barejid, "[redacted]", PROF_OUT_LOG, NULL); - } - prefs_free_string(pref_otr_log); - jid_destroy(jidp); - } - } else { - cons_show_error("Failed to encrypt and send message,"); - } - } else { - prof_otrpolicy_t policy = otr_get_policy(barejid); - - if (policy == PROF_OTRPOLICY_ALWAYS) { - cons_show_error("Failed to send message. Please check OTR policy"); - return TRUE; - } else if (policy == PROF_OTRPOLICY_OPPORTUNISTIC) { - GString *otr_message = g_string_new(msg); - g_string_append(otr_message, OTRL_MESSAGE_TAG_BASE); - g_string_append(otr_message, OTRL_MESSAGE_TAG_V2); - message_send_chat(barejid, otr_message->str); - - g_string_free(otr_message, TRUE); - } else { - message_send_chat(barejid, msg); - } - ui_outgoing_chat_msg("me", barejid, msg); - - if (((win_type == WIN_CHAT) || (win_type == WIN_CONSOLE)) && prefs_get_boolean(PREF_CHLOG)) { - const char *jid = jabber_get_fulljid(); - Jid *jidp = jid_create(jid); - chat_log_chat(jidp->barejid, barejid, msg, PROF_OUT_LOG, NULL); - jid_destroy(jidp); - } - } - return TRUE; -#else - message_send_chat(barejid, msg); - ui_outgoing_chat_msg("me", barejid, msg); - - if (((win_type == WIN_CHAT) || (win_type == WIN_CONSOLE)) && prefs_get_boolean(PREF_CHLOG)) { - const char *jid = jabber_get_fulljid(); - Jid *jidp = jid_create(jid); - chat_log_chat(jidp->barejid, barejid, msg, PROF_OUT_LOG, NULL); - jid_destroy(jidp); - } - return TRUE; -#endif + ProfChatWin *chatwin = wins_get_chat(barejid); + if (!chatwin) { + chatwin = ui_ev_new_chat_win(barejid); + } + ui_ev_focus_win((ProfWin*)chatwin); - } else { // msg == NULL - ui_new_chat_win(barejid); + if (msg) { + cl_ev_send_msg(chatwin, msg); + } else { #ifdef HAVE_LIBOTR if (otr_is_secure(barejid)) { ui_gone_secure(barejid, otr_is_trusted(barejid)); } #endif - return TRUE; } + + return TRUE; } } @@ -1336,9 +1369,9 @@ cmd_group(gchar **args, struct cmd_help_t help) if (args[0] == NULL) { GSList *groups = roster_get_groups(); GSList *curr = groups; - if (curr != NULL) { + if (curr) { cons_show("Groups:"); - while (curr != NULL) { + while (curr) { cons_show(" %s", curr->data); curr = g_slist_next(curr); } @@ -1455,11 +1488,14 @@ cmd_roster(gchar **args, struct cmd_help_t help) // set roster size } else if (g_strcmp0(args[0], "size") == 0) { - int intval = 0; if (!args[1]) { cons_show("Usage: %s", help.usage); return TRUE; - } else if (_strtoi(args[1], &intval, 1, 99) == 0) { + } + int intval = 0; + char *err_msg = NULL; + gboolean res = strtoi_range(args[1], &intval, 1, 99, &err_msg); + if (res) { prefs_set_roster_size(intval); cons_show("Roster screen size set to: %d%%", intval); if (prefs_get_boolean(PREF_ROSTER)) { @@ -1467,6 +1503,8 @@ cmd_roster(gchar **args, struct cmd_help_t help) } return TRUE; } else { + cons_show(err_msg); + free(err_msg); return TRUE; } @@ -1701,35 +1739,35 @@ cmd_status(gchar **args, struct cmd_help_t help) switch (win_type) { case WIN_MUC: - if (usr != NULL) { + if (usr) { ProfMucWin *mucwin = wins_get_current_muc(); ProfWin *window = (ProfWin*) mucwin; Occupant *occupant = muc_roster_item(mucwin->roomjid, usr); if (occupant) { win_show_occupant(window, occupant); } else { - win_save_vprint(window, '-', NULL, 0, 0, "", "No such participant \"%s\" in room.", usr); + win_vprint(window, '-', NULL, 0, 0, "", "No such participant \"%s\" in room.", usr); } } else { ui_current_print_line("You must specify a nickname."); } break; case WIN_CHAT: - if (usr != NULL) { + if (usr) { ui_current_print_line("No parameter required when in chat."); } else { ProfChatWin *chatwin = wins_get_current_chat(); ProfWin *window = (ProfWin*) chatwin; PContact pcontact = roster_get_contact(chatwin->barejid); - if (pcontact != NULL) { + if (pcontact) { win_show_contact(window, pcontact); } else { - win_save_println(window, "Error getting contact info."); + win_println(window, "Error getting contact info."); } } break; case WIN_PRIVATE: - if (usr != NULL) { + if (usr) { ui_current_print_line("No parameter required when in chat."); } else { ProfPrivateWin *privatewin = wins_get_current_private(); @@ -1739,13 +1777,13 @@ cmd_status(gchar **args, struct cmd_help_t help) if (occupant) { win_show_occupant(window, occupant); } else { - win_save_println(window, "Error getting contact info."); + win_println(window, "Error getting contact info."); } jid_destroy(jid); } break; case WIN_CONSOLE: - if (usr != NULL) { + if (usr) { char *usr_jid = roster_barejid_from_name(usr); if (usr_jid == NULL) { usr_jid = usr; @@ -1790,7 +1828,7 @@ cmd_info(gchar **args, struct cmd_help_t help) } } else { ProfMucWin *mucwin = wins_get_current_muc(); - iq_room_info_request(mucwin->roomjid); + iq_room_info_request(mucwin->roomjid, TRUE); ui_show_room_info(mucwin); return TRUE; } @@ -1802,10 +1840,10 @@ cmd_info(gchar **args, struct cmd_help_t help) ProfChatWin *chatwin = wins_get_current_chat(); ProfWin *window = (ProfWin*) chatwin; PContact pcontact = roster_get_contact(chatwin->barejid); - if (pcontact != NULL) { + if (pcontact) { win_show_info(window, pcontact); } else { - win_save_println(window, "Error getting contact info."); + win_println(window, "Error getting contact info."); } } break; @@ -1820,7 +1858,7 @@ cmd_info(gchar **args, struct cmd_help_t help) if (occupant) { win_show_occupant_info(window, jid->barejid, occupant); } else { - win_save_println(window, "Error getting contact info."); + win_println(window, "Error getting contact info."); } jid_destroy(jid); } @@ -1832,7 +1870,7 @@ cmd_info(gchar **args, struct cmd_help_t help) usr_jid = usr; } pcontact = roster_get_contact(usr_jid); - if (pcontact != NULL) { + if (pcontact) { cons_show_info(pcontact); } else { cons_show("No such contact \"%s\" in roster.", usr); @@ -1864,7 +1902,7 @@ cmd_caps(gchar **args, struct cmd_help_t help) switch (win_type) { case WIN_MUC: - if (args[0] != NULL) { + if (args[0]) { ProfMucWin *mucwin = wins_get_current_muc(); occupant = muc_roster_item(mucwin->roomjid, args[0]); if (occupant) { @@ -1880,7 +1918,7 @@ cmd_caps(gchar **args, struct cmd_help_t help) break; case WIN_CHAT: case WIN_CONSOLE: - if (args[0] != NULL) { + if (args[0]) { Jid *jid = jid_create(args[0]); if (jid->fulljid == NULL) { @@ -1904,7 +1942,7 @@ cmd_caps(gchar **args, struct cmd_help_t help) } break; case WIN_PRIVATE: - if (args[0] != NULL) { + if (args[0]) { cons_show("No parameter needed to /caps when in private chat."); } else { ProfPrivateWin *privatewin = wins_get_current_private(); @@ -1939,7 +1977,7 @@ cmd_software(gchar **args, struct cmd_help_t help) switch (win_type) { case WIN_MUC: - if (args[0] != NULL) { + if (args[0]) { ProfMucWin *mucwin = wins_get_current_muc(); occupant = muc_roster_item(mucwin->roomjid, args[0]); if (occupant) { @@ -1955,7 +1993,7 @@ cmd_software(gchar **args, struct cmd_help_t help) break; case WIN_CHAT: case WIN_CONSOLE: - if (args[0] != NULL) { + if (args[0]) { Jid *jid = jid_create(args[0]); if (jid == NULL || jid->fulljid == NULL) { @@ -1969,7 +2007,7 @@ cmd_software(gchar **args, struct cmd_help_t help) } break; case WIN_PRIVATE: - if (args[0] != NULL) { + if (args[0]) { cons_show("No parameter needed to /software when in private chat."); } else { ProfPrivateWin *privatewin = wins_get_current_private(); @@ -1993,8 +2031,24 @@ cmd_join(gchar **args, struct cmd_help_t help) } if (args[0] == NULL) { - cons_show("Usage: %s", help.usage); - cons_show(""); + uuid_t uuid; + uuid_generate(uuid); + char *uuid_str = malloc(sizeof(char) * 37); + uuid_unparse_lower(uuid, uuid_str); + + char *account_name = jabber_get_account_name(); + ProfAccount *account = accounts_get_account(account_name); + + GString *room_str = g_string_new(""); + g_string_append_printf(room_str, "private-chat-%s@%s", uuid_str, account->muc_service); + + presence_join_room(room_str->str, account->muc_nick, NULL); + muc_join(room_str->str, account->muc_nick, NULL, FALSE); + + g_string_free(room_str, TRUE); + free(uuid_str); + account_free(account); + return TRUE; } @@ -2013,7 +2067,7 @@ cmd_join(gchar **args, struct cmd_help_t help) ProfAccount *account = accounts_get_account(account_name); // full room jid supplied (room@server) - if (room_arg->localpart != NULL) { + if (room_arg->localpart) { room = args[0]; // server not supplied (room), use account preference @@ -2041,10 +2095,15 @@ cmd_join(gchar **args, struct cmd_help_t help) options_destroy(options); // In the case that a nick wasn't provided by the optional args... - if (nick == NULL) { + if (!nick) { nick = account->muc_nick; } + // When no password, check for invite with password + if (!passwd) { + passwd = muc_invite_password(room); + } + if (!muc_active(room)) { presence_join_room(room, nick, passwd); muc_join(room, nick, passwd, FALSE); @@ -2083,7 +2142,7 @@ cmd_invite(gchar **args, struct cmd_help_t help) ProfMucWin *mucwin = wins_get_current_muc(); message_send_invite(mucwin->roomjid, usr_jid, reason); - if (reason != NULL) { + if (reason) { cons_show("Room invite sent, contact: %s, room: %s, reason: \"%s\".", contact, mucwin->roomjid, reason); } else { @@ -2368,7 +2427,7 @@ cmd_form(gchar **args, struct cmd_help_t help) if (g_strcmp0(args[0], "help") == 0) { char *tag = args[1]; - if (tag != NULL) { + if (tag) { ui_show_form_field_help(confwin, tag); } else { ui_show_form_help(confwin); @@ -2376,7 +2435,7 @@ cmd_form(gchar **args, struct cmd_help_t help) const gchar **help_text = NULL; Command *command = g_hash_table_lookup(commands, "/form"); - if (command != NULL) { + if (command) { help_text = command->help.long_help; } @@ -2400,12 +2459,11 @@ cmd_form(gchar **args, struct cmd_help_t help) cmd_autocomplete_remove_form_fields(confwin->form); } wins_close_current(); - ProfWin *current = (ProfWin*)wins_get_muc(confwin->roomjid); - if (current == NULL) { - current = wins_get_console(); + ProfWin *new_current = (ProfWin*)wins_get_muc(confwin->roomjid); + if (!new_current) { + new_current = wins_get_console(); } - int num = wins_get_num(current); - ui_switch_win(num); + ui_ev_focus_win(new_current); } return TRUE; @@ -2435,7 +2493,7 @@ cmd_kick(gchar **args, struct cmd_help_t help) char *reason = args[1]; iq_room_kick_occupant(mucwin->roomjid, nick, reason); } else { - win_save_vprint((ProfWin*) mucwin, '!', NULL, 0, 0, "", "Occupant does not exist: %s", nick); + win_vprint((ProfWin*) mucwin, '!', NULL, 0, 0, "", "Occupant does not exist: %s", nick); } } else { cons_show("Usage: %s", help.usage); @@ -2494,10 +2552,10 @@ cmd_subject(gchar **args, struct cmd_help_t help) if (args[0] == NULL) { char *subject = muc_subject(mucwin->roomjid); if (subject) { - win_save_vprint(window, '!', NULL, NO_EOL, THEME_ROOMINFO, "", "Room subject: "); - win_save_vprint(window, '!', NULL, NO_DATE, 0, "", "%s", subject); + win_vprint(window, '!', NULL, NO_EOL, THEME_ROOMINFO, "", "Room subject: "); + win_vprint(window, '!', NULL, NO_DATE, 0, "", "%s", subject); } else { - win_save_print(window, '!', NULL, 0, THEME_ROOMINFO, "", "Room has no subject"); + win_print(window, '!', NULL, 0, THEME_ROOMINFO, "", "Room has no subject"); } return TRUE; } @@ -2543,7 +2601,7 @@ cmd_affiliation(gchar **args, struct cmd_help_t help) } char *affiliation = args[1]; - if ((affiliation != NULL) && + if (affiliation && (g_strcmp0(affiliation, "owner") != 0) && (g_strcmp0(affiliation, "admin") != 0) && (g_strcmp0(affiliation, "member") != 0) && @@ -2562,7 +2620,7 @@ cmd_affiliation(gchar **args, struct cmd_help_t help) iq_room_affiliation_list(mucwin->roomjid, "member"); iq_room_affiliation_list(mucwin->roomjid, "outcast"); } else if (g_strcmp0(affiliation, "none") == 0) { - win_save_print((ProfWin*) mucwin, '!', NULL, 0, 0, "", "Cannot list users with no affiliation."); + win_print((ProfWin*) mucwin, '!', NULL, 0, 0, "", "Cannot list users with no affiliation."); } else { iq_room_affiliation_list(mucwin->roomjid, affiliation); } @@ -2613,7 +2671,7 @@ cmd_role(gchar **args, struct cmd_help_t help) } char *role = args[1]; - if ((role != NULL ) && + if (role && (g_strcmp0(role, "visitor") != 0) && (g_strcmp0(role, "participant") != 0) && (g_strcmp0(role, "moderator") != 0) && @@ -2630,7 +2688,7 @@ cmd_role(gchar **args, struct cmd_help_t help) iq_room_role_list(mucwin->roomjid, "participant"); iq_room_role_list(mucwin->roomjid, "visitor"); } else if (g_strcmp0(role, "none") == 0) { - win_save_print((ProfWin*) mucwin, '!', NULL, 0, 0, "", "Cannot list users with no role."); + win_print((ProfWin*) mucwin, '!', NULL, 0, 0, "", "Cannot list users with no role."); } else { iq_room_role_list(mucwin->roomjid, role); } @@ -2693,12 +2751,12 @@ cmd_room(gchar **args, struct cmd_help_t help) if (g_strcmp0(args[0], "accept") == 0) { gboolean requires_config = muc_requires_config(mucwin->roomjid); if (!requires_config) { - win_save_print(window, '!', NULL, 0, THEME_ROOMINFO, "", "Current room does not require configuration."); + win_print(window, '!', NULL, 0, THEME_ROOMINFO, "", "Current room does not require configuration."); return TRUE; } else { iq_confirm_instant_room(mucwin->roomjid); muc_set_requires_config(mucwin->roomjid, FALSE); - win_save_print(window, '!', NULL, 0, THEME_ROOMINFO, "", "Room unlocked."); + win_print(window, '!', NULL, 0, THEME_ROOMINFO, "", "Room unlocked."); return TRUE; } } @@ -2711,9 +2769,8 @@ cmd_room(gchar **args, struct cmd_help_t help) if (g_strcmp0(args[0], "config") == 0) { ProfMucConfWin *confwin = wins_get_muc_conf(mucwin->roomjid); - if (confwin != NULL) { - num = wins_get_num(window); - ui_switch_win(num); + if (confwin) { + ui_ev_focus_win((ProfWin*)confwin); } else { iq_request_room_config_form(mucwin->roomjid); } @@ -2734,26 +2791,44 @@ cmd_occupants(gchar **args, struct cmd_help_t help) } if (g_strcmp0(args[0], "size") == 0) { - int intval = 0; if (!args[1]) { cons_show("Usage: %s", help.usage); return TRUE; - } else if (_strtoi(args[1], &intval, 1, 99) == 0) { - prefs_set_occupants_size(intval); - cons_show("Occupants screen size set to: %d%%", intval); - wins_resize_all(); - return TRUE; + } else { + int intval = 0; + char *err_msg = NULL; + gboolean res = strtoi_range(args[1], &intval, 1, 99, &err_msg); + if (res) { + prefs_set_occupants_size(intval); + cons_show("Occupants screen size set to: %d%%", intval); + wins_resize_all(); + return TRUE; + } else { + cons_show(err_msg); + free(err_msg); + return TRUE; + } } } if (g_strcmp0(args[0], "default") == 0) { if (g_strcmp0(args[1], "show") == 0) { - cons_show("Occupant list enabled."); - prefs_set_boolean(PREF_OCCUPANTS, TRUE); + if (g_strcmp0(args[2], "jid") == 0) { + cons_show("Occupant jids enabled."); + prefs_set_boolean(PREF_OCCUPANTS_JID, TRUE); + } else { + cons_show("Occupant list enabled."); + prefs_set_boolean(PREF_OCCUPANTS, TRUE); + } return TRUE; } else if (g_strcmp0(args[1], "hide") == 0) { - cons_show("Occupant list disabled."); - prefs_set_boolean(PREF_OCCUPANTS, FALSE); + if (g_strcmp0(args[2], "jid") == 0) { + cons_show("Occupant jids disabled."); + prefs_set_boolean(PREF_OCCUPANTS_JID, FALSE); + } else { + cons_show("Occupant list disabled."); + prefs_set_boolean(PREF_OCCUPANTS, FALSE); + } return TRUE; } else { cons_show("Usage: %s", help.usage); @@ -2763,16 +2838,26 @@ cmd_occupants(gchar **args, struct cmd_help_t help) win_type_t win_type = ui_current_win_type(); if (win_type != WIN_MUC) { - cons_show("Cannot show/hide occupant list when not in chat room."); + cons_show("Cannot apply setting when not in chat room."); return TRUE; } ProfMucWin *mucwin = wins_get_current_muc(); if (g_strcmp0(args[0], "show") == 0) { - ui_room_show_occupants(mucwin->roomjid); + if (g_strcmp0(args[1], "jid") == 0) { + mucwin->showjid = TRUE; + ui_room_update_occupants(mucwin->roomjid); + } else { + ui_room_show_occupants(mucwin->roomjid); + } } else if (g_strcmp0(args[0], "hide") == 0) { - ui_room_hide_occupants(mucwin->roomjid); + if (g_strcmp0(args[1], "jid") == 0) { + mucwin->showjid = FALSE; + ui_room_update_occupants(mucwin->roomjid); + } else { + ui_room_hide_occupants(mucwin->roomjid); + } } else { cons_show("Usage: %s", help.usage); } @@ -2876,7 +2961,7 @@ cmd_bookmark(gchar **args, struct cmd_help_t help) char *password = g_hash_table_lookup(options, "password"); char *autojoin = g_hash_table_lookup(options, "autojoin"); - if (autojoin != NULL) { + if (autojoin) { if ((strcmp(autojoin, "on") != 0) && (strcmp(autojoin, "off") != 0)) { cons_show("Usage: %s", help.usage); cons_show(""); @@ -2924,7 +3009,7 @@ cmd_disco(gchar **args, struct cmd_help_t help) } GString *jid = g_string_new(""); - if (args[1] != NULL) { + if (args[1]) { jid = g_string_append(jid, args[1]); } else { Jid *jidp = jid_create(jabber_get_fulljid()); @@ -3040,82 +3125,48 @@ gboolean cmd_tiny(gchar **args, struct cmd_help_t help) { char *url = args[0]; - win_type_t win_type = ui_current_win_type(); - - if (!tinyurl_valid(url)) { - GString *error = g_string_new("/tiny, badly formed URL: "); - g_string_append(error, url); - cons_show_error(error->str); - if (win_type != WIN_CONSOLE) { - ui_current_error_line(error->str); - } - g_string_free(error, TRUE); - } else if (win_type != WIN_CONSOLE) { - char *tiny = tinyurl_get(url); + ProfWin *current = wins_get_current(); - if (tiny != NULL) { - if (win_type == WIN_CHAT) { - ProfChatWin *chatwin = wins_get_current_chat(); -#ifdef HAVE_LIBOTR - if (otr_is_secure(chatwin->barejid)) { - char *encrypted = otr_encrypt_message(chatwin->barejid, tiny); - if (encrypted != NULL) { - message_send_chat(chatwin->barejid, encrypted); - otr_free_message(encrypted); - if (prefs_get_boolean(PREF_CHLOG)) { - const char *jid = jabber_get_fulljid(); - Jid *jidp = jid_create(jid); - char *pref_otr_log = prefs_get_string(PREF_OTR_LOG); - if (strcmp(pref_otr_log, "on") == 0) { - chat_log_chat(jidp->barejid, chatwin->barejid, tiny, PROF_OUT_LOG, NULL); - } else if (strcmp(pref_otr_log, "redact") == 0) { - chat_log_chat(jidp->barejid, chatwin->barejid, "[redacted]", PROF_OUT_LOG, NULL); - } - prefs_free_string(pref_otr_log); - jid_destroy(jidp); - } + if (current->type != WIN_CHAT && current->type != WIN_MUC && current->type != WIN_PRIVATE) { + cons_show("/tiny can only be used in chat windows"); + return TRUE; + } - ui_outgoing_chat_msg("me", chatwin->barejid, tiny); - } else { - cons_show_error("Failed to send message."); - } - } else { - message_send_chat(chatwin->barejid, tiny); - if (prefs_get_boolean(PREF_CHLOG)) { - const char *jid = jabber_get_fulljid(); - Jid *jidp = jid_create(jid); - chat_log_chat(jidp->barejid, chatwin->barejid, tiny, PROF_OUT_LOG, NULL); - jid_destroy(jidp); - } + if (!tinyurl_valid(url)) { + win_vprint(current, '-', NULL, 0, THEME_ERROR, "", "/tiny, badly formed URL: %s", url); + return TRUE; + } - ui_outgoing_chat_msg("me", chatwin->barejid, tiny); - } -#else - message_send_chat(chatwin->barejid, tiny); - if (prefs_get_boolean(PREF_CHLOG)) { - const char *jid = jabber_get_fulljid(); - Jid *jidp = jid_create(jid); - chat_log_chat(jidp->barejid, chatwin->barejid, tiny, PROF_OUT_LOG, NULL); - jid_destroy(jidp); - } + char *tiny = tinyurl_get(url); + if (!tiny) { + win_print(current, '-', NULL, 0, THEME_ERROR, "", "Couldn't create tinyurl."); + return TRUE; + } - ui_outgoing_chat_msg("me", chatwin->barejid, tiny); -#endif - } else if (win_type == WIN_PRIVATE) { - ProfPrivateWin *privatewin = wins_get_current_private(); - message_send_private(tiny, privatewin->fulljid); - ui_outgoing_private_msg("me", privatewin->fulljid, tiny); - } else if (win_type == WIN_MUC) { - ProfMucWin *mucwin = wins_get_current_muc(); - message_send_groupchat(tiny, mucwin->roomjid); - } - free(tiny); - } else { - cons_show_error("Couldn't get tinyurl."); - } - } else { - cons_show("/tiny can only be used in chat windows"); + switch (current->type){ + case WIN_CHAT: + { + ProfChatWin *chatwin = wins_get_current_chat(); + cl_ev_send_msg(chatwin, tiny); + break; + } + case WIN_PRIVATE: + { + ProfPrivateWin *privatewin = wins_get_current_private(); + cl_ev_send_priv_msg(privatewin, tiny); + break; + } + case WIN_MUC: + { + ProfMucWin *mucwin = wins_get_current_muc(); + cl_ev_send_muc_msg(mucwin, tiny); + break; } + default: + break; + } + + free(tiny); return TRUE; } @@ -3135,7 +3186,7 @@ cmd_close(gchar **args, struct cmd_help_t help) int count = 0; if (args[0] == NULL) { - index = ui_current_win_index(); + index = wins_get_current_num(); } else if (strcmp(args[0], "all") == 0) { count = ui_close_all_wins(); if (count == 0) { @@ -3170,19 +3221,15 @@ cmd_close(gchar **args, struct cmd_help_t help) return TRUE; } - if (!ui_win_exists(index)) { + ProfWin *window = wins_get_by_num(index); + if (!window) { cons_show("Window is not open."); return TRUE; } // check for unsaved form if (ui_win_has_unsaved_form(index)) { - ProfWin *window = wins_get_current(); - if (wins_is_current(window)) { - ui_current_print_line("You have unsaved changes, use /form submit or /form cancel"); - } else { - cons_show("Cannot close form window with unsaved changes, use /form submit or /form cancel"); - } + ui_current_print_line("You have unsaved changes, use /form submit or /form cancel"); return TRUE; } @@ -3203,7 +3250,7 @@ cmd_leave(gchar **args, struct cmd_help_t help) { jabber_conn_status_t conn_status = jabber_get_connection_status(); win_type_t win_type = ui_current_win_type(); - int index = ui_current_win_index(); + int index = wins_get_current_num(); if (win_type != WIN_MUC) { cons_show("You can only use the /leave command in a chat room."); @@ -3257,10 +3304,46 @@ cmd_wrap(gchar **args, struct cmd_help_t help) gboolean cmd_time(gchar **args, struct cmd_help_t help) { - prefs_set_string(PREF_TIME, args[0]); - cons_show("Time format set to '%s'", args[0]); - wins_resize_all(); - return TRUE; + if (g_strcmp0(args[0], "statusbar") == 0) { + if (args[1] == NULL) { + cons_show("Current status bar time format is '%s'.", prefs_get_string(PREF_TIME_STATUSBAR)); + return TRUE; + } else if (g_strcmp0(args[1], "set") == 0 && args[2] != NULL) { + prefs_set_string(PREF_TIME_STATUSBAR, args[2]); + cons_show("Status bar time format set to '%s'.", args[2]); + ui_redraw(); + return TRUE; + } else if (g_strcmp0(args[1], "off") == 0) { + prefs_set_string(PREF_TIME_STATUSBAR, ""); + cons_show("Status bar time display disabled."); + ui_redraw(); + return TRUE; + } else { + cons_show("Usage: %s", help.usage); + return TRUE; + } + } else if (g_strcmp0(args[0], "main") == 0) { + if (args[1] == NULL) { + cons_show("Current time format is '%s'.", prefs_get_string(PREF_TIME)); + return TRUE; + } else if (g_strcmp0(args[1], "set") == 0 && args[2] != NULL) { + prefs_set_string(PREF_TIME, args[2]); + cons_show("Time format set to '%s'.", args[2]); + wins_resize_all(); + return TRUE; + } else if (g_strcmp0(args[1], "off") == 0) { + prefs_set_string(PREF_TIME, ""); + cons_show("Time display disabled."); + wins_resize_all(); + return TRUE; + } else { + cons_show("Usage: %s", help.usage); + return TRUE; + } + } else { + cons_show("Usage: %s", help.usage); + return TRUE; + } } gboolean @@ -3481,7 +3564,6 @@ cmd_inpblock(gchar **args, struct cmd_help_t help) { char *subcmd = args[0]; char *value = args[1]; - int intval; if (g_strcmp0(subcmd, "timeout") == 0) { if (value == NULL) { @@ -3489,10 +3571,16 @@ cmd_inpblock(gchar **args, struct cmd_help_t help) return TRUE; } - if (_strtoi(value, &intval, 1, 1000) == 0) { + int intval = 0; + char *err_msg = NULL; + gboolean res = strtoi_range(value, &intval, 1, 1000, &err_msg); + if (res) { cons_show("Input blocking set to %d milliseconds.", intval); prefs_set_inpblock(intval); ui_input_nonblocking(FALSE); + } else { + cons_show(err_msg); + free(err_msg); } return TRUE; @@ -3522,16 +3610,22 @@ cmd_log(gchar **args, struct cmd_help_t help) { char *subcmd = args[0]; char *value = args[1]; - int intval; if (strcmp(subcmd, "maxsize") == 0) { if (value == NULL) { cons_show("Usage: %s", help.usage); return TRUE; } - if (_strtoi(value, &intval, PREFS_MIN_LOG_SIZE, INT_MAX) == 0) { + + int intval = 0; + char *err_msg = NULL; + gboolean res = strtoi_range(value, &intval, PREFS_MIN_LOG_SIZE, INT_MAX, &err_msg); + if (res) { prefs_set_max_log_size(intval); cons_show("Log maxinum size set to %d bytes", intval); + } else { + cons_show(err_msg); + free(err_msg); } return TRUE; } @@ -3571,9 +3665,11 @@ gboolean cmd_reconnect(gchar **args, struct cmd_help_t help) { char *value = args[0]; - int intval; - if (_strtoi(value, &intval, 0, INT_MAX) == 0) { + int intval = 0; + char *err_msg = NULL; + gboolean res = strtoi_range(value, &intval, 0, INT_MAX, &err_msg); + if (res) { prefs_set_reconnect(intval); if (intval == 0) { cons_show("Reconnect disabled.", intval); @@ -3581,7 +3677,9 @@ cmd_reconnect(gchar **args, struct cmd_help_t help) cons_show("Reconnect interval set to %d seconds.", intval); } } else { + cons_show(err_msg); cons_show("Usage: %s", help.usage); + free(err_msg); } return TRUE; @@ -3591,9 +3689,11 @@ gboolean cmd_autoping(gchar **args, struct cmd_help_t help) { char *value = args[0]; - int intval; - if (_strtoi(value, &intval, 0, INT_MAX) == 0) { + int intval = 0; + char *err_msg = NULL; + gboolean res = strtoi_range(value, &intval, 0, INT_MAX, &err_msg); + if (res) { prefs_set_autoping(intval); iq_set_autoping(intval); if (intval == 0) { @@ -3602,7 +3702,9 @@ cmd_autoping(gchar **args, struct cmd_help_t help) cons_show("Autoping interval set to %d seconds.", intval); } } else { + cons_show(err_msg); cons_show("Usage: %s", help.usage); + free(err_msg); } return TRUE; @@ -3633,7 +3735,6 @@ cmd_autoaway(gchar **args, struct cmd_help_t help) { char *setting = args[0]; char *value = args[1]; - int minutesval; if ((strcmp(setting, "mode") != 0) && (strcmp(setting, "time") != 0) && (strcmp(setting, "message") != 0) && (strcmp(setting, "check") != 0)) { @@ -3654,9 +3755,15 @@ cmd_autoaway(gchar **args, struct cmd_help_t help) } if (strcmp(setting, "time") == 0) { - if (_strtoi(value, &minutesval, 1, INT_MAX) == 0) { + int minutesval = 0; + char *err_msg = NULL; + gboolean res = strtoi_range(value, &minutesval, 1, INT_MAX, &err_msg); + if (res) { prefs_set_autoaway_time(minutesval); cons_show("Auto away time set to: %d minutes.", minutesval); + } else { + cons_show(err_msg); + free(err_msg); } return TRUE; @@ -3693,13 +3800,18 @@ cmd_priority(gchar **args, struct cmd_help_t help) } char *value = args[0]; - int intval; - if (_strtoi(value, &intval, -128, 127) == 0) { + int intval = 0; + char *err_msg = NULL; + gboolean res = strtoi_range(value, &intval, -128, 127, &err_msg); + if (res) { accounts_set_priority_all(jabber_get_account_name(), intval); resource_presence_t last_presence = accounts_get_last_presence(jabber_get_account_name()); - presence_update(last_presence, jabber_get_presence_message(), 0); + cl_ev_presence_send(last_presence, jabber_get_presence_message(), 0); cons_show("Priority set to %d.", intval); + } else { + cons_show(err_msg); + free(err_msg); } return TRUE; @@ -3865,6 +3977,42 @@ cmd_history(gchar **args, struct cmd_help_t help) } gboolean +cmd_carbons(gchar **args, struct cmd_help_t help) +{ + gboolean result = _cmd_set_boolean_preference(args[0], help, + "Message carbons preference", PREF_CARBONS); + + jabber_conn_status_t conn_status = jabber_get_connection_status(); + + if (conn_status == JABBER_CONNECTED) { + // enable carbons + if (strcmp(args[0], "on") == 0) { + iq_enable_carbons(); + } + else if (strcmp(args[0], "off") == 0){ + iq_disable_carbons(); + } + } + + return result; +} + +gboolean +cmd_receipts(gchar **args, struct cmd_help_t help) +{ + if (g_strcmp0(args[0], "send") == 0) { + return _cmd_set_boolean_preference(args[1], help, + "Send delivery receipts", PREF_RECEIPTS_SEND); + } else if (g_strcmp0(args[0], "request") == 0) { + return _cmd_set_boolean_preference(args[1], help, + "Request delivery receipets", PREF_RECEIPTS_REQUEST); + } else { + cons_show("Usage: %s", help.usage); + return TRUE; + } +} + +gboolean cmd_away(gchar **args, struct cmd_help_t help) { _update_presence(RESOURCE_AWAY, "away", args); @@ -4013,14 +4161,18 @@ cmd_otr(gchar **args, struct cmd_help_t help) return TRUE; } else if (strcmp(args[0], "start") == 0) { - if (args[1] != NULL) { + if (args[1]) { char *contact = args[1]; char *barejid = roster_barejid_from_name(contact); if (barejid == NULL) { barejid = contact; } - ui_new_chat_win(barejid); + ProfChatWin *chatwin = wins_get_chat(barejid); + if (!chatwin) { + chatwin = ui_ev_new_chat_win(barejid); + } + ui_ev_focus_win((ProfWin*)chatwin); if (ui_current_win_is_otr()) { ui_current_print_formatted_line('!', 0, "You are already in an OTR session."); @@ -4029,7 +4181,7 @@ cmd_otr(gchar **args, struct cmd_help_t help) ui_current_print_formatted_line('!', 0, "You have not generated or loaded a private key, use '/otr gen'"); } else if (!otr_is_secure(barejid)) { char *otr_query_message = otr_start_query(); - message_send_chat(barejid, otr_query_message); + message_send_chat_encrypted(barejid, otr_query_message); } else { ui_gone_secure(barejid, otr_is_trusted(barejid)); } @@ -4047,7 +4199,7 @@ cmd_otr(gchar **args, struct cmd_help_t help) } else { ProfChatWin *chatwin = ui_get_current_chat(); char *otr_query_message = otr_start_query(); - message_send_chat(chatwin->barejid, otr_query_message); + message_send_chat_encrypted(chatwin->barejid, otr_query_message); } } } @@ -4175,7 +4327,7 @@ _update_presence(const resource_presence_t resource_presence, if (conn_status != JABBER_CONNECTED) { cons_show("You are not currently connected."); } else { - presence_update(resource_presence, msg, 0); + cl_ev_presence_send(resource_presence, msg, 0); ui_update_presence(resource_presence, msg, show); } } @@ -4213,27 +4365,6 @@ _cmd_set_boolean_preference(gchar *arg, struct cmd_help_t help, return TRUE; } -static int -_strtoi(char *str, int *saveptr, int min, int max) -{ - char *ptr; - int val; - - errno = 0; - val = (int)strtol(str, &ptr, 0); - if (errno != 0 || *str == '\0' || *ptr != '\0') { - cons_show("Could not convert \"%s\" to a number.", str); - return -1; - } else if (val < min || val > max) { - cons_show("Value %s out of range. Must be in %d..%d.", str, min, max); - return -1; - } - - *saveptr = val; - - return 0; -} - static void _cmd_show_filtered_help(char *heading, gchar *cmd_filter[], int filter_size) { @@ -4249,7 +4380,7 @@ _cmd_show_filtered_help(char *heading, gchar *cmd_filter[], int filter_size) } GList *curr = ordered_commands; - while (curr != NULL) { + while (curr) { Command *cmd = curr->data; cons_show("%-12s: %s", cmd->cmd, cmd->help.short_help); curr = g_list_next(curr); diff --git a/src/command/commands.h b/src/command/commands.h index f4e040a9..7b7e7c93 100644 --- a/src/command/commands.h +++ b/src/command/commands.h @@ -1,7 +1,7 @@ /* * commands.h * - * Copyright (C) 2012 - 2014 James Booth <boothj5@gmail.com> + * Copyright (C) 2012 - 2015 James Booth <boothj5@gmail.com> * * This file is part of Profanity. * @@ -62,6 +62,9 @@ typedef struct cmd_t { CommandHelp help; } Command; +gboolean cmd_execute_alias(const char * const inp, gboolean *ran); +gboolean cmd_execute_default(const char * inp); + gboolean cmd_about(gchar **args, struct cmd_help_t help); gboolean cmd_account(gchar **args, struct cmd_help_t help); gboolean cmd_autoaway(gchar **args, struct cmd_help_t help); @@ -85,6 +88,8 @@ gboolean cmd_grlog(gchar **args, struct cmd_help_t help); gboolean cmd_group(gchar **args, struct cmd_help_t help); gboolean cmd_help(gchar **args, struct cmd_help_t help); gboolean cmd_history(gchar **args, struct cmd_help_t help); +gboolean cmd_carbons(gchar **args, struct cmd_help_t help); +gboolean cmd_receipts(gchar **args, struct cmd_help_t help); gboolean cmd_info(gchar **args, struct cmd_help_t help); gboolean cmd_intype(gchar **args, struct cmd_help_t help); gboolean cmd_invite(gchar **args, struct cmd_help_t help); |