Further updated the documentation and a minor fix

fixed some errors found in the documentation and fully updated the internal
commands docs as well.

also updated the internal module to now respond to KILL_CMD so it can now be
signaled to terminate gracefully.
This commit is contained in:
Maurice ONeal 2019-11-18 19:20:30 -05:00
parent e7ea316bc0
commit f6ea7239a0
17 changed files with 220 additions and 193 deletions

View File

@ -1,6 +1,6 @@
# MRCI # # MRCI #
(Modular Remote Command Interpreter) is a command interpreter primarily designed to provide remote service to connected clients, whether text based or any kind of data. As the name implies, it is expandable via 3rd party modules by adding addtional commands that remote clients can run on the host. It has a fully feasured user account management system with access control to certain commands for certain users. All persistent data is handled by a SQLite database and all remote connections are handled via TCP and encrypted in SSL/TLS. (Modular Remote Command Interpreter) is a command interpreter primarily designed to provide any type of remote service to connected clients. As the name implies, it is expandable via 3rd party modules by adding addtional commands that remote clients can run on the host. It has a fully feasured user account management system with access control to certain commands for certain users. All persistent data is handled by a SQLite database and all remote connections are handled via TCP and encrypted in SSL/TLS.
### Usage ### ### Usage ###
@ -25,13 +25,13 @@ Usage: mrci <argument>
Internal module | -public_cmds, -user_cmds, -exempt_cmds, -run_cmd |: Internal module | -public_cmds, -user_cmds, -exempt_cmds, -run_cmd |:
-pipe {pipe_name/path} : the named pipe used to establish a data connection with the session. -pipe {pipe_name/path} : the named pipe used to establish a data connection with the session.
-mem_ses {key_name} : the shared memory key for the session. -mem_ses {key_name} : the shared memory key for the session object.
-mem_host {key_name} : the shared memory key for the host main process. -mem_host {key_name} : the shared memory key for the server object.
``` ```
Other than that, the host can only be managed via a connected client that supports text input/output so the host application is always listening for clients while running entirely in the background. By default the host listen for clients on address 0.0.0.0 and port 35516, effectively making it reachable on any network interface of the host platform via that specific port. The host can only be managed via a connected client that supports text input/output so the host application is always listening for clients while running entirely in the background. By default the host listen for clients on address 0.0.0.0 and port 35516, effectively making it reachable on any network interface of the host platform via that specific port.
Just like any linux based OS, the host will have an administrative user called root. This account can be used to modify anything on the host without restriction. The default password is randomized and set on the root user account on running the host for the first time. To find out what the default password is, run -help or -about. When logging in as root with the default password, the host will require you to change the password before continuing. Just like any linux based OS, the host will have an administrative user called root. This account can be used to modify anything on the host without restriction. The default password is randomized and set on the root user account upon running the host for the first time. To find out what the default password is, run -help or -about. When logging in as root with the default password, the host will require you to change the password before continuing.
### More Than Just a Command Interpreter ### ### More Than Just a Command Interpreter ###
@ -61,6 +61,7 @@ Because the host is modular, the things you can customize it to do is almost lim
* [4.1 Host Features](host_features.md) * [4.1 Host Features](host_features.md)
* [5.1 Async Commands](async.md) * [5.1 Async Commands](async.md)
* [6.1 Shared Memory](shared_data.md) * [6.1 Shared Memory](shared_data.md)
* [7.1 Internal Commands](intern_commands.md)
### Development Setup ### ### Development Setup ###

View File

@ -1,10 +1,10 @@
### 5.1 Async Commands ### ### 5.1 Async Commands ###
An async command is a virtual command that the host can use to send data to the client at any time while connected to the host. As the name implies, the occurance of a client receiving data from an async command is not always the result of running a regular command in the current session. This can occur for example when information in your account is changed by another client connected to the host; your client would not know about this change until an async command is sent notify it of the change. These commands can called directly or indirectly by a module. An async command is a virtual command that the host can use to send data to the client at any time while connected to the host. As the name implies, the occurance of a client receiving data from an async command is not always the result of running a regular command in the current session. This can occur for example when information in your account is changed by another client connected to the host; your client would not know about this change until an async command is sent notify it of the change. These commands can be called directly or indirectly by a module and are considered "virtual" commands because there is no defined objects attached to them. Instead, async commands are best identified by command id values 1-255.
Async commands are not only used send data to the client but also used internally within the host to help objects operating in different processes to communicate with each other. Some async commands in fact are considered internal only because the client should never see any data come from them at anytime. There is also data flow contriants for aysnc commands, meaning some gets blocked or has no effect if sent from a module when not expected to or sent using the [PRIV_IPC](type_ids.md) data type when expected to be sent via [PUB_IPC](type_ids.md). The list below shows the various data flow contriants each of these async commands have. Async commands are not only used to send data to the client but also used internally within the host to help objects operating in different processes to communicate with each other. Some async commands in fact are considered internal only because the client should never see any data come from them at anytime. There is also data flow contriants for aysnc commands, meaning some gets blocked if sent from the module or has no effect if sent with the unexpected [IPC](type_ids.md) type id. The list below shows the various data flow contriants each of these async commands have.
Here is a describtion of what those keywords mean: Here is a describtion of what the keywords in the list mean:
``` ```
client - this means the async command id will be used to forward client - this means the async command id will be used to forward
data of any type to client if needed. data of any type to client if needed.
@ -12,7 +12,7 @@ client - this means the async command id will be used to forward
internal - this means the async command will be responded by the internal - this means the async command will be responded by the
session object but the data will not be forwarded to the session object but the data will not be forwarded to the
client or converted to an entirely different async client or converted to an entirely different async
command. command before sending to the client.
public - this means the session objects will respond to this async public - this means the session objects will respond to this async
command if sent with PUB_IPC or PUB_IPC_WITH_FEEDBACK command if sent with PUB_IPC or PUB_IPC_WITH_FEEDBACK
@ -31,8 +31,6 @@ retricted - this means the session object will actively block this
async command from being sent from the module (any mode). async command from being sent from the module (any mode).
``` ```
These are considered "virtual" commands because there is no defined command objects attached to them. Instead, async commands are best identified by command id values 1-255.
``` ```
enum AsyncCommands : quint16 enum AsyncCommands : quint16
{ {

View File

@ -4,7 +4,7 @@ Other than transporting data to be processed by modules, the host have a few oth
### 4.2 Host Ranks ### ### 4.2 Host Ranks ###
Each user registered in the host must be assigned a host rank. The lower it's numeric value, the higher the level of access the user has in the host with 0 being invalid. By default, the host defines the ```root``` user with a host rank of 1; giving it the highest level of access possible in the host. The host also defines a default initial host rank of 2 for all new accounts that are created in the host. This can be re-configured at any time using the [host_config](internal_commands.md) internal command. Each user registered in the host must be assigned a host rank. The lower it's numeric value, the higher the level of access the user has in the host with 0 being invalid. By default, the host defines the ```root``` user with a host rank of 1; giving it the highest level of access possible in the host. The host also defines a default initial host rank of 2 for all new accounts that are created in the host. This can be re-configured at any time using the [host_config](intern_commands.md) internal command.
Some internal commands have the ability to change the user account information of other accounts. The host will in general not allow users of a lower level of access to any user information of higher access level. For example: a user of host rank ```1``` can force change another user's email address if that user's rank is ```2``` or higher but the rank ```2``` user can't do the same in reverse. Some internal commands have the ability to change the user account information of other accounts. The host will in general not allow users of a lower level of access to any user information of higher access level. For example: a user of host rank ```1``` can force change another user's email address if that user's rank is ```2``` or higher but the rank ```2``` user can't do the same in reverse.

View File

@ -1,16 +1,6 @@
### 7.1 Internal Commands ### ### 7.1 Internal Commands ###
The host is extendable via 3rd party modules but the host itself have it's own internal module that load commands with direct access to the host database and several internal power functions that external commands would otherwise not have direct access to. The host is extendable via 3rd party modules but the host itself is an internal module that load commands with direct access to the host database.
* [auth](intern_commands/auth.md) - login to the host using a registered user account name or email address.
* [ls_cmds](intern_commands/ls_cmds.md) - list all available commands for your current session.
* [my_info](intern_commands/my_info.md) - display information about your current session and your account.
* [recover_acct](intern_commands/recover_acct.md) - reset a user account password.
* [request_pw_reset](intern_commands/request_pw_reset.md) - request a password reset for a user account.
* [accept_ch](intern_commands/accept_ch.md) - accept an invite to a channel to become a regular member of it. * [accept_ch](intern_commands/accept_ch.md) - accept an invite to a channel to become a regular member of it.
@ -18,21 +8,21 @@ The host is extendable via 3rd party modules but the host itself have it's own i
* [add_ban](intern_commands/add_ban.md) - add an ip address to the host ban list. * [add_ban](intern_commands/add_ban.md) - add an ip address to the host ban list.
* [add_cert](intern_commands/add_cert.md) - install a new SSL/TLS cert into the host from a local cert and private key file. * [add_cert](intern_commands/add_cert.md) - install a new SSL/TLS cert into the host.
* [add_ch](intern_commands/add_ch.md) - create a new channel. * [add_ch](intern_commands/add_ch.md) - create a new channel.
* [add_group](intern_commands/add_group.md) - create a new host group. * [add_mod](intern_commands/add_mod.md) - add a new module to the host.
* [add_mod](intern_commands/add_mod.md) - upload a new module to install into the host. * [add_ranked_cmd](intern_commands/add_ranked_cmd.md) - assign a rank to a module's command name.
* [add_ranked_cmd](intern_commands/add_ranked_cmd.md) - assign a rank to a command object name.
* [add_rdonly_flag](intern_commands/add_rdonly_flag.md) - add a read only flag to a certain sub-channel and privilege level. * [add_rdonly_flag](intern_commands/add_rdonly_flag.md) - add a read only flag to a certain sub-channel and privilege level.
* [add_sub_ch](intern_commands/add_sub_ch.md) - create a new sub-channel within a channel. * [add_sub_ch](intern_commands/add_sub_ch.md) - create a new sub-channel within a channel.
* [cast](intern_commands/cast.md) - broadcast text/data to all sessions listening to any matching sub-channels. * [auth](intern_commands/auth.md) - login to the host using a registered user account name or email address.
* [cast](intern_commands/cast.md) - broadcast data to all sessions listening to any matching sub-channels.
* [cert_info](intern_commands/cert_info.md) - display detailed information about an installed SSL/TLS certificate. * [cert_info](intern_commands/cert_info.md) - display detailed information about an installed SSL/TLS certificate.
@ -42,8 +32,6 @@ The host is extendable via 3rd party modules but the host itself have it's own i
* [close_sub_ch](intern_commands/close_sub_ch.md) - close a sub-channel for your current session. * [close_sub_ch](intern_commands/close_sub_ch.md) - close a sub-channel for your current session.
* [cmd_info](intern_commands/cmd_info.md) - display detailed information about a command.
* [decline_ch](intern_commands/decline_ch.md) - decline an invite to a channel. * [decline_ch](intern_commands/decline_ch.md) - decline an invite to a channel.
* [find_ch](intern_commands/find_ch.md) - search for channels within the host based on the channel name or channel id. * [find_ch](intern_commands/find_ch.md) - search for channels within the host based on the channel name or channel id.
@ -52,19 +40,19 @@ The host is extendable via 3rd party modules but the host itself have it's own i
* [fs_cd](intern_commands/fs_cd.md) - display or change the current directory for the current session. * [fs_cd](intern_commands/fs_cd.md) - display or change the current directory for the current session.
* [fs_copy](intern_commands/fs_copy.md) - copy a file system object (file,directory,symlink) from one location to another. * [fs_copy](intern_commands/fs_copy.md) - copy a file or directory in the host file system.
* [fs_delete](intern_commands/fs_delete.md) - attempt to delete a file system object (file,directory,symlink) in the host. * [fs_delete](intern_commands/fs_delete.md) - delete a file or directory in the host file system.
* [fs_download](intern_commands/fs_download.md) - download a single file from the host. * [fs_download](intern_commands/fs_download.md) - download a single file from the host.
* [fs_info](intern_commands/fs_info.md) - get detailed information about a file system object (file,directory,symlink) in the host. * [fs_info](intern_commands/fs_info.md) - get detailed information about a file in the host file system.
* [fs_list](intern_commands/fs_list.md) - list all files or sub-directories in a directory. * [fs_list](intern_commands/fs_list.md) - list all files or sub-directories in a directory.
* [fs_mkpath](intern_commands/fs_mkpath.md) - attempt to create a directory and all sub-directories of a given path. * [fs_mkpath](intern_commands/fs_mkpath.md) - attempt to create a directory and all sub-directories of a given path.
* [fs_move](intern_commands/fs_move.md) - move/rename a file system object (file,directory,symlink) from one location to another. * [fs_move](intern_commands/fs_move.md) - move/rename a file or directory in the host file system.
* [fs_tree](intern_commands/fs_tree.md) - list all files and sub-directories of an entire directory tree. * [fs_tree](intern_commands/fs_tree.md) - list all files and sub-directories of an entire directory tree.
@ -78,11 +66,11 @@ The host is extendable via 3rd party modules but the host itself have it's own i
* [is_email_verified](intern_commands/is_email_verified.md) - check if your email address is verified. * [is_email_verified](intern_commands/is_email_verified.md) - check if your email address is verified.
* [lock_acct](intern_commands/lock_acct.md) - lock user account. * [lock_acct](intern_commands/lock_acct.md) - lock a user account.
* [ls_act_log](intern_commands/ls_act_log.md) - display or manage the client activity log. * [ls_act_log](intern_commands/ls_act_log.md) - display or manage the client activity log.
* [ls_auth_log](intern_commands/ls_auth_log.md) - display or manage the host authorization activity log. * [ls_auth_log](intern_commands/ls_auth_log.md) - display the host authorization activity log.
* [ls_bans](intern_commands/ls_bans.md) - display or manage the host ip address ban table. * [ls_bans](intern_commands/ls_bans.md) - display or manage the host ip address ban table.
@ -92,38 +80,38 @@ The host is extendable via 3rd party modules but the host itself have it's own i
* [ls_chs](intern_commands/ls_chs.md) - list all channels you are currently a member of and all pending invites. * [ls_chs](intern_commands/ls_chs.md) - list all channels you are currently a member of and all pending invites.
* [ls_dbg](intern_commands/ls_dbg.md) - display debug messages from the host instance and all session instances. * [ls_dbg](intern_commands/ls_dbg.md) - display all debug log messages.
* [ls_groups](intern_commands/ls_groups.md) - list all groups currently registered in the host. * [ls_mods](intern_commands/ls_mods.md) - list all available modules currently configured in the host.
* [ls_mods](intern_commands/ls_mods.md) - list all available modules currently installed in the host.
* [ls_open_chs](intern_commands/ls_open_chs.md) - list all of the sub-channels that are currently open. * [ls_open_chs](intern_commands/ls_open_chs.md) - list all of the sub-channels that are currently open.
* [ls_p2p](intern_commands/ls_p2p.md) - list all p2p connections and pending p2p request you currently have. * [ls_p2p](intern_commands/ls_p2p.md) - list all p2p connections and pending p2p request you currently have.
* [ls_ranked_cmds](intern_commands/ls_ranked_cmds.md) - list all command names with assigned host ranks. * [ls_ranked_cmds](intern_commands/ls_ranked_cmds.md) - list all module commands with assigned host ranks.
* [ls_rdonly_flags](intern_commands/ls_rdonly_flags.md) - list all read only flags currently present for a channel. * [ls_rdonly_flags](intern_commands/ls_rdonly_flags.md) - list all read only flags currently present for a channel.
* [ls_sub_chs](intern_commands/ls_sub_chs.md) - list all sub-channels within a channel you currently a member of. * [ls_sub_chs](intern_commands/ls_sub_chs.md) - list all sub-channels within a channel.
* [ls_users](intern_commands/ls_users.md) - list all users currently registered in the host database. * [ls_users](intern_commands/ls_users.md) - list all users currently registered in the host database.
* [open_sub_ch](intern_commands/open_sub_ch.md) - open a sub-channel to send/receive broadcasted data to/from other peers. * [my_info](intern_commands/my_info.md) - display information about your current session and your account.
* [p2p_close](intern_commands/p2p_close.md) - close the p2p connection with the client given in this command or decline a p2p request. * [open_sub_ch](intern_commands/open_sub_ch.md) - open a sub-channel to send/receive broadcasted data to/from peers.
* [p2p_open](intern_commands/p2p_open.md) - accept the p2p request you may have received from another client connected to the host. * [p2p_close](intern_commands/p2p_close.md) - close the p2p connection with the peer given in this command or decline a p2p request.
* [p2p_request](intern_commands/p2p_request.md) - send out a p2p request to the client session id given in this command. * [p2p_open](intern_commands/p2p_open.md) - accept the p2p request you may have received from another peer connected to the host.
* [pause](intern_commands/pause.md) - pause the current task that the command is running. * [p2p_request](intern_commands/p2p_request.md) - send out a p2p request to the peer session id given in this command.
* [ping_peers](intern_commands/ping_peers.md) - ping all peer sessions with any matching sub-channels to return information about themselves to you. * [ping_peers](intern_commands/ping_peers.md) - ping all peer sessions with any matching sub-channels to return information about themselves to you.
* [preview_email](intern_commands/preview_email.md) - preview the confirmation or password reset emails with dummy values. * [preview_email](intern_commands/preview_email.md) - preview the confirmation or password reset emails with dummy values.
* [recover_acct](intern_commands/recover_acct.md) - login to a user account using a temporary password.
* [remove_ch_member](intern_commands/remove_ch_member.md) - remove a user as a member of a channel you currently a member of or cancel an invite. * [remove_ch_member](intern_commands/remove_ch_member.md) - remove a user as a member of a channel you currently a member of or cancel an invite.
* [rename_ch](intern_commands/rename_ch.md) - rename a channel. * [rename_ch](intern_commands/rename_ch.md) - rename a channel.
@ -134,9 +122,9 @@ The host is extendable via 3rd party modules but the host itself have it's own i
* [request_new_user_name](intern_commands/request_new_user_name.md) - enable/disable a user name change request for a user on next login. * [request_new_user_name](intern_commands/request_new_user_name.md) - enable/disable a user name change request for a user on next login.
* [restart_host](intern_commands/restart_host.md) - re-start the host instance. * [request_pw_reset](intern_commands/request_pw_reset.md) - request a password reset for a user account.
* [resume](intern_commands/resume.md) - resumes the current task that the command is running. * [restart_host](intern_commands/restart_host.md) - re-start the host instance.
* [rm_acct](intern_commands/rm_acct.md) - delete a user account from the host database. * [rm_acct](intern_commands/rm_acct.md) - delete a user account from the host database.
@ -146,9 +134,9 @@ The host is extendable via 3rd party modules but the host itself have it's own i
* [rm_ch](intern_commands/rm_ch.md) - permanently remove a channel and all of it's sub-shannels from the host. * [rm_ch](intern_commands/rm_ch.md) - permanently remove a channel and all of it's sub-shannels from the host.
* [rm_mod](intern_commands/rm_mod.md) - uninstall a module from the host. * [rm_mod](intern_commands/rm_mod.md) - remove a module from the host.
* [rm_ranked_cmd](intern_commands/rm_ranked_cmd.md) - remove a rank from a command object name. * [rm_ranked_cmd](intern_commands/rm_ranked_cmd.md) - remove a rank from a module command name.
* [rm_rdonly_flag](intern_commands/rm_rdonly_flag.md) - remove a read only flag from a certain sub-channel privilege level combination. * [rm_rdonly_flag](intern_commands/rm_rdonly_flag.md) - remove a read only flag from a certain sub-channel privilege level combination.
@ -158,27 +146,21 @@ The host is extendable via 3rd party modules but the host itself have it's own i
* [set_disp_name](intern_commands/set_disp_name.md) - change your account display name. * [set_disp_name](intern_commands/set_disp_name.md) - change your account display name.
* [set_email](intern_commands/set_email.md) - change the user account email address. * [set_email](intern_commands/set_email.md) - set the user account email address.
* [set_email_template](intern_commands/set_email_template.md) - set the email template used by the host to send emails for user account resets and confirmations. * [set_email_template](intern_commands/set_email_template.md) - set the email template used by the host to send emails for user account resets and confirmations.
* [set_group](intern_commands/set_group.md) - change a user account's group. * [set_member_level](intern_commands/set_member_level.md) - set the user privilege levels of a channel member.
* [set_group_rank](intern_commands/set_group_rank.md) - set the host rank of a group. * [set_pw](intern_commands/set_pw.md) - update your account password.
* [set_member_level](intern_commands/set_member_level.md) - set the user privilege levels of a channel member. (lower the value, the higher the privilege)
* [set_pw](intern_commands/set_pw.md) - change your account password.
* [set_sub_ch_level](intern_commands/set_sub_ch_level.md) - set the lowest privilege level that members need to be in order to open a certain sub-channel. * [set_sub_ch_level](intern_commands/set_sub_ch_level.md) - set the lowest privilege level that members need to be in order to open a certain sub-channel.
* [set_user_name](intern_commands/set_user_name.md) - change your account user name. * [set_user_name](intern_commands/set_user_name.md) - change your account user name.
* [term](intern_commands/term.md) - terminate the current task that the command is running. * [set_user_rank](intern_commands/set_user_rank.md) - change a user account's host rank.
* [to_peer](intern_commands/to_peer.md) - send/receive any data directly with a client connected to the host that has accepted your p2p request or the peer's p2p request. * [to_peer](intern_commands/to_peer.md) - send/receive any data directly with a client connected to the host.
* [trans_group](intern_commands/trans_group.md) - transfer all user accounts from one group to another.
* [verify_email](intern_commands/verify_email.md) - verify your email address by sending a confirmation code to it. * [verify_email](intern_commands/verify_email.md) - verify your email address by sending a confirmation code to it.

View File

@ -37,12 +37,12 @@ notes:
* When the session calls the module in list mode (-public_cmds, -exempt_cmds or -user_cmds), it will only respond to frame type ids: [NEW_CMD](type_ids.md) or [ERR](type_ids.md) from the module; all other data types are ignored. Modules called in run mode (-run_cmd) on the other hand will open up all frame type ids. * When the session calls the module in list mode (-public_cmds, -exempt_cmds or -user_cmds), it will only respond to frame type ids: [NEW_CMD](type_ids.md) or [ERR](type_ids.md) from the module; all other data types are ignored. Modules called in run mode (-run_cmd) on the other hand will open up all frame type ids.
* When the session detects that the module successfully established a pipe connection, it will send a [HOST_VER](type_ids.md) frame to the module so the module can decide if it supports the host. If the host is not compatible or the module fails for what ever other reason, the module can send a useful error message ([ERR](type_ids.md) frame) and then terminate if needed. The error message will be added to the host debug log where it can be used by host admins to find out what went wrong. The HOST_VER frame is sent only when the module is called with the -public_cmds, -exempt_cmds or -user_cmds options. * When the session detects that the module successfully established a pipe connection, it will send a [HOST_VER](type_ids.md) frame to the module so the module can decide if it supports the host. If the host is not compatible or the module fails for what ever other reason, the module can send a useful error message [ERR](type_ids.md) and then terminate if needed. The error message will be added to the host debug log where it can be used by host admins to find out what went wrong. The HOST_VER frame is sent only when the module is called with the -public_cmds, -exempt_cmds or -user_cmds options.
* When the module sends a [NEW_CMD](type_ids.md) frame, the 16bit command id is needed but does not need to be valid, it just needs to be there as a place holder. The session will auto fill a valid ccommand id before sending the data to the client. A valid NEW_CMD frame must have a minimum of 259 bytes and a valid command name. the session will ignore all NEW_CMD frames the doesn't meet these requirements. See section [6.3](shared_data.md) for what would be considered a valid command name. * When the module sends a [NEW_CMD](type_ids.md) frame, the 16bit command id is needed but does not need to be valid, it just needs to be there as a place holder. The session will auto fill a valid command id before sending the data to the client. A valid NEW_CMD frame must have a minimum of 259 bytes and a valid command name. the session will ignore all NEW_CMD frames the doesn't meet these requirements. See section [6.3](shared_data.md) for what would be considered a valid command name.
* All modules are encouraged to terminate after sending all [NEW_CMD](type_ids.md) frames for the -public_cmds, -exempt_cmds or -user_cmds options. The session will force kill the module after 2 mins of being idle but it is still desired to terminate gracefully when finished.
* The session will call all modules with the -public_cmds when created for the first time or when the user logout so it doesn't matter if the command names returned to the session overlap with -exempt_cmd or -user_cmds. When a user is logged in, it will then call 2 instances of each module with the -exempt_cmds and -user_cmds options so the command names should not overlap when these options are active. * The session will call all modules with the -public_cmds when created for the first time or when the user logout so it doesn't matter if the command names returned to the session overlap with -exempt_cmd or -user_cmds. When a user is logged in, it will then call 2 instances of each module with the -exempt_cmds and -user_cmds options so the command names should not overlap when these options are active.
* Modules called with -run_cmd does not need to terminate after running the requested command, instead it must send an [IDLE](type_ids.md) frame to indicate that the command is finished. This is desired because not only it tells the client that the command is finished but it also makes it so the session doesn't need to recreate the module process on every subsequent call to the module. The session will send a [KILL_CMD](type_ids.md) to the module after 2 mins of being idle to give the module a chance to terminate gracefully; The module will have 3 seconds to do this before it is force killed. * Modules called with -run_cmd does not need to terminate after running the requested command, instead it must send an [IDLE](type_ids.md) frame to indicate that the command is finished. This is desired because not only it tells the client that the command is finished but it also makes it so the session doesn't need to recreate the module process on every subsequent call to the module.
* The session will send a [KILL_CMD](type_ids.md) to the module after 2 mins of being idle (all modes) to give the module a chance to terminate gracefully; The module will have 3 seconds to do this before it is force killed.

View File

@ -16,7 +16,13 @@ data_len - 3bytes - 24bit little endian integer size of the payload.
payload - variable - the actual data to be processed. payload - variable - the actual data to be processed.
``` ```
A full description of the type id's can be found in the [Type_IDs.md](type_ids.md) document. notes:
* A full description of the type id's can be found in the [Type_IDs.md](type_ids.md) document.
* Modules call commands via a command name but the host will assign a unique command id to all command names so clients can call them using a simple 2 byte integer instead of full text. The command ids can change as the modules change so it is recommended for clients to not depend on consistant command ids but depend on the [ASYNC_ADD_CMD](async.md) and [ASYNC_RM_CMD](async.md) async commands.
* The branch id is an id that can be assigned by the client itself to run muliple instances of the same command. Commands sent by a certain branch id will result in data sent back to the client from the module with that same branch id.
### 1.3 Versioning System ### ### 1.3 Versioning System ###
@ -64,8 +70,8 @@ notes:
* **reply** is a numeric value that the host returns in it's header to communicate to the client the result of it's evaluation of the client's header. * **reply** is a numeric value that the host returns in it's header to communicate to the client the result of it's evaluation of the client's header.
* reply = 1, means the client version is acceptable and it does not need to take any further action. * reply = 1, means the client is acceptable and it does not need to take any further action.
* reply = 2, means the client version is acceptable but the host will now send it's Pem formatted SSL cert data in a ```HOST_CERT``` mrci frame just after sending it's header. After receiving the cert, the client will then need to send a STARTTLS signal using this cert. * reply = 2, means the client is acceptable but the host will now send it's Pem formatted SSL cert data in a ```HOST_CERT``` mrci frame just after sending it's header. After receiving the cert, the client will then need to send a STARTTLS signal using this cert.
* reply = 4, means the host was unable to load the SSL cert associated with the common name sent by the client. The session will auto close at this point. * reply = 4, means the host was unable to find the SSL cert associated with the common name sent by the client. The session will auto close at this point.
* **sesId** is the session id. It is a unique 224bit sha3 hash generated against the current date and time of session creation (down to the msec) and the machine id. This can be used by the host and client to uniquely identify the current session or past sessions. * **sesId** is the session id. It is a unique 224bit sha3 hash generated against the current date and time of session creation (down to the msec) and the machine id. This can be used by the host and client to uniquely identify the current session or past sessions.

View File

@ -1,10 +1,12 @@
### 6.1 Session/Host Shared Memory ### ### 6.1 Session/Host Shared Memory ###
The host use shared shared memory segments to share data with the module processes so the modules can be made aware of various session data points like the currently logged in user id, user name, display name, etc. A shared memory segment is basically a block of memory where multiple processes have access to reading/writing data. The use of shared memory segments is entire optional so it does not need to be implemented to have a fully functional module. The host use shared shared memory segments to share data with the module processes so the modules can be made aware of various session data points like the currently logged in user id, user name, display name, etc. A shared memory segment is basically a block of memory where multiple processes have access to reading/writing data. The use of shared memory segments is entirely optional so it does not need to be implemented to have a fully functional module.
The session object creates the shared memory segment and assigns a text key unique to just the session. When the session object calls a new module process, it will pass the [-mem_ses](modules.md) option with the shared memory key that the module can then use to attach to the segment. The session will also pass the [-mem_host](modules.md) option unique to the TCPServer object to get data relevant to the sever object. The session object creates the shared memory segment and assigns a text key unique to just the session. When the session object calls a new module process, it will pass the [-mem_ses](modules.md) option with the shared memory key that the module can then use to attach to the segment. The session will also pass the [-mem_host](modules.md) option unique to the TCPServer object to get data relevant to the sever object.
As mentioned before, the share memory segments are just blocks of memory. sections 6.2 and 6.3 describes the format of the shared memory and where to find the data based on the memory offset. As mentioned before, the share memory segments are just blocks of memory. sections 6.2 and 6.3 describes the format of the shared memory and where to find the data based on the memory offset.
Also note, depending on the API used, lock and unlock functions must be used when reading/writing data with the shared memory segments as a way to prevent multiple process from reading/writing the shared data at the same time. Consider reading your API's documentation before attempting to use shared memory segments.
### 6.2 Session Shared Memory Offsets ### ### 6.2 Session Shared Memory Offsets ###

View File

@ -40,20 +40,20 @@ enum TypeID : quint8
### 3.2 Type Descriptions ### ### 3.2 Type Descriptions ###
```TEXT``` ```TEXT```
This is text that can be displayed directly to the user, pass command line arguments to be processed or used to carry text data within other data types. This is text that can be displayed directly to the user, passed as command line arguments to be processed or used to carry text data within other data types.
format: ```[UTF-16LE_string] (no BOM)``` format: ```[UTF-16LE_string] (no BOM)```
```GEN_FILE``` ```GEN_FILE```
This is a file transfer type id that can be used to transfer any file type (music, photos, documents, etc...). It operates in its own protocol of sorts. The 1st GEN_FILE frame received by the host or client is TEXT parameters similar to what you see in terminal command lines with at least one of the arguments listed below. The next set of GEN_FILE frames received by the host or client is then the binary data that needs to be written to an open file or streamed until the limit defined in -len is meet. This is a file transfer type id that can be used to transfer any file type (music, photos, documents, etc...). It operates in its own protocol of sorts. The 1st GEN_FILE frame received by the host or client is TEXT parameters similar to what you see in terminal command lines with at least one of the arguments listed below. The next set of GEN_FILE frames received by the host or client is then the binary data that needs to be written to an open file or streamed until the limit defined in -len is meet.
The host or the client can be set as the sender or receiver of the GEN_FILE binary data. Which ever is designated as the receiver by the TEXT parameters need to send an empty GEN_FILE frame to start the process. An example if this can be found in section 3.3. The host or the client can be set as the sender or receiver of the GEN_FILE binary data. Which ever is designated as the receiver by the TEXT parameters need to send an empty GEN_FILE frame to start the process. An example of this can be found in section 3.3.
arguments: arguments:
* **-len (int)** | this is the integer value of the file size or amount of bytes to read/write. * **-len (int)** | this is the integer value of the file size or amount of bytes to read/write.
* **-offset (int)** | this integer position tells where in the source or destination file to start reading/writing. * **-offset (int)** | this is a integer position that indicates where in the source or destination file to start reading/writing.
* **-client_file** (string) | this is the file path to the source/destination file in the client's file system. * **-client_file** (string) | this is the file path to the source/destination file in the client's file system.
@ -61,7 +61,7 @@ arguments:
* **-single_step** | the presents of this argument tells both the client and host to operate in single step mode. single step mode causes the receiver of the binary data whether host or client to send an empty GEN_FILE frame after successfully receiving the data. this then tells the sender to send the next GEN_FILE frame containing binary data for the file and the cycle continues until len is meet. if this argument is not found, the sender can simply send all GEN_FILE data without waiting for an empty GEN_FILE from the receiver. * **-single_step** | the presents of this argument tells both the client and host to operate in single step mode. single step mode causes the receiver of the binary data whether host or client to send an empty GEN_FILE frame after successfully receiving the data. this then tells the sender to send the next GEN_FILE frame containing binary data for the file and the cycle continues until len is meet. if this argument is not found, the sender can simply send all GEN_FILE data without waiting for an empty GEN_FILE from the receiver.
* **-to_host** | this argument should only come from host and it will define the client as the sender and the host as the receiver. * **-to_host** | this argument should only come from the host and it will define the client as the sender and the host as the receiver.
* **-from_host** | opposite affect to *-to_host*. it defines the host as the sender and the client as the receiver. * **-from_host** | opposite affect to *-to_host*. it defines the host as the sender and the client as the receiver.
@ -79,7 +79,7 @@ This id can be treated exactly like TEXT except this should tell the client to h
Also formatted exactly like TEXT but this indicates to the client that this is a large body of text that is recommended to be word wrapped when displaying to the user. It can contain line breaks so clients are also recommended to honor those line breaks. Also formatted exactly like TEXT but this indicates to the client that this is a large body of text that is recommended to be word wrapped when displaying to the user. It can contain line breaks so clients are also recommended to honor those line breaks.
```IDLE``` ```IDLE```
This doesn't carry any actual data, instead this indicates that the command-branch id that sent it has finished it's task. Modules that send this doesn't need to terminate it's process. This doesn't carry any actual data, instead this indicates that the command id and branch id that sent it has finished it's task. Modules that send this doesn't need to terminate it's process.
```KILL_CMD``` ```KILL_CMD```
This doesn't carry any actual data, instead can be sent by the client or session object to tell the command-branch id sent in the frame to terminate the module process. Modules that receive this need to send a IDLE frame if a command is still running and then terminate itself. The module will have 3 seconds to do this before it is force killed by the session. This doesn't carry any actual data, instead can be sent by the client or session object to tell the command-branch id sent in the frame to terminate the module process. Modules that receive this need to send a IDLE frame if a command is still running and then terminate itself. The module will have 3 seconds to do this before it is force killed by the session.
@ -113,10 +113,10 @@ This is a data structure used to by modules to run async commands on the local s
``` ```
```PUB_IPC``` ```PUB_IPC```
This is formatted exactly like PRIV_IPC except it is used by modules to run async commands on all connected peers in the host while avoiding a run on the local session object. This is formatted exactly like PRIV_IPC except it is used by modules to run async commands on all peer session objects in the host while avoiding a run on the local session object.
```PUB_IPC_WITH_FEEDBACK``` ```PUB_IPC_WITH_FEEDBACK```
This combines the functionality of PUB_IPC and PRIV_IPC. It runs async commands on all connected peers and on the local session object. This has the same functionality as PUB_IPC except it is also feedback into the local session object.
```FILE_INFO``` ```FILE_INFO```
This is a data structure that carries information about a file system object (file,dir,link). This is a data structure that carries information about a file system object (file,dir,link).
@ -171,7 +171,7 @@ This carry some user account and session information about a peer client connect
``` ```
```PING_PEERS``` ```PING_PEERS```
This formatted extactly as PEER_INFO except it can be used the ASYNC_LIMITED_CAST [async](async.md) command to tell all peer sessions that receive it to send PEER_INFO frame about you to their own clients and to return PEER_INFO frames about themselves to you. This is formatted extactly as PEER_INFO except it can be used the ASYNC_LIMITED_CAST [async](async.md) command to tell all peer sessions that receive it to send a PEER_INFO frame about you to their own clients and return PEER_INFO frames about themselves to you.
```MY_INFO``` ```MY_INFO```
This contains all of the information found in ```PEER_INFO``` for the local session but also includes the following: This contains all of the information found in ```PEER_INFO``` for the local session but also includes the following:

View File

@ -42,7 +42,7 @@ ModProcess::ModProcess(const QString &app, const QString &memSes, const QString
connect(this, SIGNAL(finished(int,QProcess::ExitStatus)), this, SLOT(onFinished(int,QProcess::ExitStatus))); connect(this, SIGNAL(finished(int,QProcess::ExitStatus)), this, SLOT(onFinished(int,QProcess::ExitStatus)));
connect(ipcServ, &QLocalServer::newConnection, this, &ModProcess::newIPCLink); connect(ipcServ, &QLocalServer::newConnection, this, &ModProcess::newIPCLink);
connect(idleTimer, &IdleTimer::timeout, this, &ModProcess::kill); connect(idleTimer, &IdleTimer::timeout, this, &ModProcess::killProc);
setProgram(app); setProgram(app);
} }
@ -383,6 +383,13 @@ void ModProcess::wrIpcFrame(quint8 typeId, const QByteArray &data)
} }
} }
void ModProcess::killProc()
{
wrIpcFrame(KILL_CMD, QByteArray());
QTimer::singleShot(3000, this, SLOT(kill()));
}
CmdProcess::CmdProcess(quint32 id, const QString &cmd, const QString &modApp, const QString &memSes, const QString &memHos, const QString &pipe, QObject *parent) : ModProcess(modApp, memSes, memHos, pipe, parent) CmdProcess::CmdProcess(quint32 id, const QString &cmd, const QString &modApp, const QString &memSes, const QString &memHos, const QString &pipe, QObject *parent) : ModProcess(modApp, memSes, memHos, pipe, parent)
{ {
cmdId = id; cmdId = id;
@ -397,18 +404,11 @@ void CmdProcess::setSessionParams(QSharedMemory *mem, char *sesId, char *wrableS
openWritableSubChs = wrableSubChs; openWritableSubChs = wrableSubChs;
} }
void CmdProcess::killCmd()
{
wrIpcFrame(KILL_CMD, QByteArray());
QTimer::singleShot(3000, this, SLOT(kill()));
}
void CmdProcess::killCmd16(quint16 id16) void CmdProcess::killCmd16(quint16 id16)
{ {
if (toCmdId16(cmdId) == id16) if (toCmdId16(cmdId) == id16)
{ {
killCmd(); killProc();
} }
} }
@ -416,7 +416,7 @@ void CmdProcess::killCmd32(quint32 id32)
{ {
if (cmdId == id32) if (cmdId == id32)
{ {
killCmd(); killProc();
} }
} }

View File

@ -86,6 +86,10 @@ public:
bool loadUserCmds(); bool loadUserCmds();
bool loadExemptCmds(); bool loadExemptCmds();
public slots:
void killProc();
signals: signals:
void cmdUnloaded(quint16 cmdId); void cmdUnloaded(quint16 cmdId);
@ -115,7 +119,6 @@ private:
private slots: private slots:
void killCmd();
void rdFromStdErr(); void rdFromStdErr();
void rdFromStdOut(); void rdFromStdOut();

View File

@ -47,59 +47,6 @@ QString IPHist::cmdName() {return "ls_act_log";}
QString ListDBG::cmdName() {return "ls_dbg";} QString ListDBG::cmdName() {return "ls_dbg";}
QString MyInfo::cmdName() {return "my_info";} QString MyInfo::cmdName() {return "my_info";}
QString ListCommands::parseMd(const QString &cmdName, int offset)
{
QFile file(":/docs/intern_commands/" + cmdName + ".md", this);
QByteArray data;
if (!file.open(QFile::ReadOnly))
{
qDebug() << "err: internal command: " << cmdName << " does not have a document file.";
}
else
{
data = file.readAll();
int targetTags = offset * 6;
int pos = -1;
int len = 0;
for (int i = 0, tags = 0; i < data.size(); ++i)
{
if (data[i] == '#')
{
++tags;
if (pos != -1)
{
break;
}
}
else if (tags == targetTags)
{
len++;
if (pos == -1)
{
pos = i;
}
}
}
data = data.mid(pos, len).trimmed();
if (offset == 2)
{
data.chop(3);
data.remove(0, 3);
}
}
file.close();
return data;
}
QString ListCommands::shortText(const QString &cmdName) QString ListCommands::shortText(const QString &cmdName)
{ {
return parseMd(cmdName, 1); return parseMd(cmdName, 1);

View File

@ -19,6 +19,7 @@
#include "../common.h" #include "../common.h"
#include "../cmd_object.h" #include "../cmd_object.h"
#include "../shell.h"
#include "table_viewer.h" #include "table_viewer.h"
class ListCommands : public CmdObject class ListCommands : public CmdObject
@ -30,7 +31,6 @@ private:
QStringList list; QStringList list;
QStringList genfileList; QStringList genfileList;
QString parseMd(const QString &cmdName, int offset);
QString shortText(const QString &cmdName); QString shortText(const QString &cmdName);
QString ioText(const QString &cmdName); QString ioText(const QString &cmdName);
QString longText(const QString &cmdName); QString longText(const QString &cmdName);

View File

@ -90,50 +90,50 @@
enum AsyncCommands : quint16 enum AsyncCommands : quint16
{ {
ASYNC_RDY = 1, ASYNC_RDY = 1, // client | none
ASYNC_SYS_MSG = 2, ASYNC_SYS_MSG = 2, // client | none
ASYNC_EXIT = 3, // internal only ASYNC_EXIT = 3, // internal | private
ASYNC_CAST = 4, ASYNC_CAST = 4, // client | public
ASYNC_MAXSES = 5, // internal only ASYNC_MAXSES = 5, // internal | private
ASYNC_LOGOUT = 6, // internal only ASYNC_LOGOUT = 6, // internal | private
ASYNC_USER_DELETED = 7, ASYNC_USER_DELETED = 7, // client | public
ASYNC_DISP_RENAMED = 8, // internal only ASYNC_DISP_RENAMED = 8, // internal | public
ASYNC_USER_RANK_CHANGED = 9, // internal only ASYNC_USER_RANK_CHANGED = 9, // internal | public
ASYNC_CMD_RANKS_CHANGED = 10, // internal only ASYNC_CMD_RANKS_CHANGED = 10, // internal | public
ASYNC_RESTART = 11, // internal only ASYNC_RESTART = 11, // internal | private
ASYNC_ENABLE_MOD = 12, // internal only ASYNC_ENABLE_MOD = 12, // internal | public
ASYNC_DISABLE_MOD = 13, // internal only ASYNC_DISABLE_MOD = 13, // internal | public
ASYNC_END_SESSION = 14, // internal only ASYNC_END_SESSION = 14, // internal | private
ASYNC_USER_LOGIN = 15, // internal only ASYNC_USER_LOGIN = 15, // internal | private
ASYNC_TO_PEER = 16, ASYNC_TO_PEER = 16, // client | public | retricted
ASYNC_LIMITED_CAST = 17, ASYNC_LIMITED_CAST = 17, // client | public
ASYNC_RW_MY_INFO = 18, // internal only ASYNC_RW_MY_INFO = 18, // internal | public
ASYNC_P2P = 19, ASYNC_P2P = 19, // client | public
ASYNC_CLOSE_P2P = 20, // internal only ASYNC_CLOSE_P2P = 20, // internal | public
ASYNC_NEW_CH_MEMBER = 21, ASYNC_NEW_CH_MEMBER = 21, // client | public
ASYNC_DEL_CH = 22, ASYNC_DEL_CH = 22, // client | public
ASYNC_RENAME_CH = 23, ASYNC_RENAME_CH = 23, // client | public
ASYNC_CH_ACT_FLAG = 24, ASYNC_CH_ACT_FLAG = 24, // internal | public
ASYNC_NEW_SUB_CH = 25, ASYNC_NEW_SUB_CH = 25, // client | public
ASYNC_RM_SUB_CH = 26, ASYNC_RM_SUB_CH = 26, // client | public
ASYNC_RENAME_SUB_CH = 27, ASYNC_RENAME_SUB_CH = 27, // client | public
ASYNC_INVITED_TO_CH = 28, ASYNC_INVITED_TO_CH = 28, // client | public
ASYNC_RM_CH_MEMBER = 29, ASYNC_RM_CH_MEMBER = 29, // client | public
ASYNC_INVITE_ACCEPTED = 30, ASYNC_INVITE_ACCEPTED = 30, // client | public
ASYNC_MEM_LEVEL_CHANGED = 31, ASYNC_MEM_LEVEL_CHANGED = 31, // client | public
ASYNC_SUB_CH_LEVEL_CHG = 32, ASYNC_SUB_CH_LEVEL_CHG = 32, // client | public
ASYNC_ADD_RDONLY = 33, ASYNC_ADD_RDONLY = 33, // client | public
ASYNC_RM_RDONLY = 34, ASYNC_RM_RDONLY = 34, // client | public
ASYNC_ADD_CMD = 35, ASYNC_ADD_CMD = 35, // client | none
ASYNC_RM_CMD = 36, ASYNC_RM_CMD = 36, // client | none
ASYNC_USER_RENAMED = 37, ASYNC_USER_RENAMED = 37, // internal | public
ASYNC_PING_PEERS = 38, // internal only ASYNC_PING_PEERS = 38, // internal | private
ASYNC_OPEN_SUBCH = 39, // internal only ASYNC_OPEN_SUBCH = 39, // internal | private
ASYNC_CLOSE_SUBCH = 40, // internal only ASYNC_CLOSE_SUBCH = 40, // internal | private
ASYNC_UPDATE_BANS = 41, // internal only ASYNC_UPDATE_BANS = 41, // internal | private
ASYNC_KEEP_ALIVE = 42, // internal only ASYNC_KEEP_ALIVE = 42, // internal | private
ASYNC_SET_DIR = 43, // internal only ASYNC_SET_DIR = 43, // internal | private
ASYNC_DEBUG_TEXT = 44 // internal only ASYNC_DEBUG_TEXT = 44 // internal | private
}; };
enum Flags : quint32 enum Flags : quint32

View File

@ -37,7 +37,7 @@
#include "shell.h" #include "shell.h"
#define APP_NAME "MRCI" #define APP_NAME "MRCI"
#define APP_VER "2.0.1" #define APP_VER "2.0.2"
#define APP_TARGET "mrci" #define APP_TARGET "mrci"
#ifdef Q_OS_WIN #ifdef Q_OS_WIN

View File

@ -213,7 +213,7 @@ ModProcess *Session::initModProc(const QString &modApp)
connect(proc, &ModProcess::dataToClient, this, &Session::dataToClient); connect(proc, &ModProcess::dataToClient, this, &Session::dataToClient);
connect(proc, &ModProcess::cmdUnloaded, this, &Session::killCmd16); connect(proc, &ModProcess::cmdUnloaded, this, &Session::killCmd16);
connect(this, &Session::killMods, proc, &ModProcess::kill); connect(this, &Session::killMods, proc, &ModProcess::killProc);
return proc; return proc;
} }

View File

@ -93,3 +93,85 @@ QString expandEnvVariables(const QString &txtIn)
return ret; return ret;
} }
QString parseMd(const QString &cmdName, int offset)
{
QFile file(":/docs/intern_commands/" + cmdName + ".md");
QByteArray data;
if (!file.open(QFile::ReadOnly))
{
qDebug() << "err: internal command: " << cmdName << " does not have a document file.";
}
else
{
data = file.readAll();
int targetTags = offset * 6;
int pos = -1;
int len = 0;
for (int i = 0, tags = 0; i < data.size(); ++i)
{
if (data[i] == '#')
{
++tags;
if (pos != -1)
{
break;
}
}
else if (tags == targetTags)
{
len++;
if (pos == -1)
{
pos = i;
}
}
}
data = data.mid(pos, len).trimmed();
if (offset == 2)
{
data.chop(3);
data.remove(0, 3);
}
}
file.close();
return data;
}
void updateInternCmdList(const QString &dst)
{
QString baseName = QFileInfo(dst).baseName();
QString path = QFileInfo(dst).path();
QFile file(dst);
QDir lister(path + "/" + baseName);
lister.mkpath(path + "/" + baseName);
lister.setSorting(QDir::Name);
if (file.open(QFile::WriteOnly | QFile::Truncate))
{
file.write("### 7.1 Internal Commands ###\n\n");
file.write("The host is extendable via 3rd party modules but the host itself is an internal module that load commands with direct access to the host database.\n\n");
QFileInfoList fileList = lister.entryInfoList();
for (auto&& info : fileList)
{
QString line = "* [" + info.baseName() + "](" + baseName + "/" + info.fileName() + ") - " + parseMd(info.baseName(), 1) + "\n\n";
file.write(line.toUtf8());
}
}
file.close();
}

View File

@ -18,8 +18,14 @@
// <http://www.gnu.org/licenses/>. // <http://www.gnu.org/licenses/>.
#include <QProcess> #include <QProcess>
#include <QFile>
#include <QDir>
#include <QFileInfoList>
#include <QDebug>
QStringList parseEnvVariables(const QString &txtIn); QStringList parseEnvVariables(const QString &txtIn);
QString expandEnvVariables(const QString &txtIn); QString expandEnvVariables(const QString &txtIn);
QString parseMd(const QString &cmdName, int offset);
void updateInternCmdList(const QString &dst);
#endif // SHELL_H #endif // SHELL_H