* mu: update the server command and (use 'cmd:' for commands)

This commit is contained in:
djcb 2013-05-20 05:11:49 +03:00
parent dfb6382c04
commit 2f5d6e246b
3 changed files with 57 additions and 71 deletions

View File

@ -19,14 +19,14 @@ In this man-page, we document the commands \fBmu server\fR accepts, as well as
their responses. In general, the commands sent to the server are of the form
.nf
<command> [<parameters>]*
cmd:<command> [<parameters>]*
.fi
where each of the parameters is prefixed by their name and a colon. For
example, to view a certain message, the command would be:
.nf
view docid:12345
cmd:view docid:12345
.fi
Parameters can be sent in any order, and parameters not used by a certain
@ -58,7 +58,7 @@ UTF-8 (in which the s-expressions are encoded).
Using the \fBadd\fR command, we can add a message to the database.
.nf
-> add path:<path> maildir:<maildir>
-> cmd:add path:<path> maildir:<maildir>
<- (:info add :path <path> :docid <docid>)
.fi
@ -73,7 +73,7 @@ e.g. set the subject, sender and recipient for a reply message.
Messages of type 'new' don't use the docid: parameter, the other ones do.
.nf
-> compose type:<reply|forward|edit|new> [docid:<docid>]
-> cmd:compose type:<reply|forward|edit|new> [docid:<docid>]
<- (:compose <reply|forward|edit|new> :original <s-exp> :include (<list-of-attachments))
.fi
@ -93,7 +93,7 @@ Using the \fBcompose\fR command, we can retrieve an s-expression with all known
contacts (name + e-mail address). For the details, see \fBmu-cfind(1)\fR.
.nf
-> contacts [personal:true|false] [after:<time_t>]
-> cmd:contacts [personal:true|false] [after:<time_t>]
<- (:contacts ((:name abc :mail foo@example.com ...) ...)
.fi
@ -103,7 +103,7 @@ contacts (name + e-mail address). For the details, see \fBmu-cfind(1)\fR.
Using the \fBextract\fR command we can save and open attachments.
.nf
-> extract action:<save|open|temp> index:<index> [path:<path>] [what:<what> [param:<param>]]
-> cmd:extract action:<save|open|temp> index:<index> [path:<path>] [what:<what> [param:<param>]]
.fi
If the action is 'save', the path argument is required; the attachment will
@ -135,7 +135,7 @@ to a shell command.
Using the \fBfind\fR command we can search for messages.
.nf
-> find query:"<query>" [threads:true|false] [sortfield:<sortfield>]
-> cmd:find query:"<query>" [threads:true|false] [sortfield:<sortfield>]
[reverse:true|false] [maxnum:<maxnum>]
.fi
The \fBquery\fR-parameter provides the search query; the
@ -179,7 +179,7 @@ registers 'my' email addresses; see the documentation for
\fBmu_store_set_my_addresses\fR.
.nf
-> index path:<path> [my-addresses:<comma-separated-list-of-email-addresses>]
-> cmd:index path:<path> [my-addresses:<comma-separated-list-of-email-addresses>]
.fi
As a response, it will send (for each 500 messages):
.nf
@ -197,7 +197,7 @@ and finally:
Using the \fBmkdir\fR command, we can create a new maildir.
.nf
-> mkdir path:<path>
-> cmd:mkdir path:<path>
<- (:info mkdir :message "<maildir> has been created")
.fi
@ -211,7 +211,7 @@ s-exp describing the updated message, so that it can be updated in the user
interface.
.nf
-> move docid:<docid>|msgid:<msgid> [maildir:<maildir>] [flags:<flags>]
-> cmd:move docid:<docid>|msgid:<msgid> [maildir:<maildir>] [flags:<flags>]
<- (:update <s-exp> :move t)
.fi
@ -225,7 +225,7 @@ of maildir and flags must be specified.
The \fBping\fR command provokes a \fBpong\fR response. It is used for the initial
handshake between \fBmu4e\fR and \fBmu server\fR.
.nf
-> ping
-> cmd:ping
<- (:pong "mu" :version <version> :doccount <doccount>)
.fi
@ -236,7 +236,7 @@ Using the \fBremove\fR command, we can remove the message from disk, and
update the database accordingly.
.nf
-> remove docid:<docid>
-> cmd:remove docid:<docid>
<- (:remove <docid>)
.fi
@ -257,18 +257,17 @@ If the optional parameter \fBauto-retrieve-key\fR is \fBtrue\fR, attempt to
retrieve public keys online automatically.
.nf
-> view docid:<docid>|msgid:<msgid> [extract-images:true] [use-agent:false] [auto-retrieve-key:false]
-> cmd:view docid:<docid>|msgid:<msgid> [extract-images:true] [use-agent:false] [auto-retrieve-key:false]
<- (:view <s-exp>)
.fi
or, alternatively:
.nf
-> view path:<path-to-msg> [extract-images:true] [use-agent:false] [auto-retrieve-key:false]
-> cmd:view path:<path-to-msg> [extract-images:true] [use-agent:false] [auto-retrieve-key:false]
<- (:view <s-exp>)
.fi
.SH AUTHOR
Dirk-Jan C. Binnema <djcb@djcbsoftware.nl>

View File

@ -166,11 +166,11 @@ print_and_clear_g_error (GError **err)
}
static GSList*
read_line_as_list (GError **err)
static GHashTable*
read_command_line (GError **err)
{
char *line;
GSList *lst;
GHashTable *hash;
GString *gstr;
line = NULL;
@ -190,43 +190,28 @@ read_line_as_list (GError **err)
} while (1);
line = g_string_free (gstr, FALSE);
lst = mu_str_esc_to_list (line);
hash = mu_str_parse_arglist (line, err);
g_free (line);
return lst;
return hash;
}
static const char*
get_string_from_args (GSList *args, const char *param, gboolean optional,
get_string_from_args (GHashTable *args, const char *param, gboolean optional,
GError **err)
{
size_t param_len;
const char *str;
param_len = strlen (param);
while (args) {
const char *arg;
arg = (const char*)args->data;
/* do we have this param */
if (arg && g_str_has_prefix (arg, param) &&
arg[param_len] == ':')
return (const char*) arg + param_len + 1;
args = g_slist_next (args);
}
if (!optional)
str = g_hash_table_lookup (args, param);
if (!str && !optional)
mu_util_g_set_error (err, MU_ERROR_IN_PARAMETERS,
"parameter '%s' not found", param);
return NULL;
return str;
}
static gboolean
get_bool_from_args (GSList *args, const char *param, gboolean optional, GError **err)
get_bool_from_args (GHashTable *args, const char *param, gboolean optional, GError **err)
{
const char *val;
@ -330,7 +315,7 @@ get_docids_from_msgids (MuQuery *query, const char *str, GError **err)
* locale the message with message-id in the database, and return its
* docid */
static unsigned
determine_docid (MuQuery *query, GSList *args, GError **err)
determine_docid (MuQuery *query, GHashTable *args, GError **err)
{
const char* docidstr, *msgidstr;
@ -379,7 +364,7 @@ typedef struct _ServerContext ServerContext;
* if function return non-MU_OK, the repl will print the error instead
*/
typedef MuError (*CmdFunc) (ServerContext*,GSList*,GError**);
typedef MuError (*CmdFunc) (ServerContext*,GHashTable*,GError**);
/* 'add' adds a message to the database, and takes two parameters:
* 'path', which is the full path to the message, and 'maildir', which
@ -388,7 +373,7 @@ typedef MuError (*CmdFunc) (ServerContext*,GSList*,GError**);
* message (details: see code below)
*/
static MuError
cmd_add (ServerContext *ctx, GSList *args, GError **err)
cmd_add (ServerContext *ctx, GHashTable *args, GError **err)
{
unsigned docid;
const char *maildir, *path;
@ -507,7 +492,7 @@ compose_type (const char *typestr)
* Note ':include' t or nil determines whether to include attachments
*/
static MuError
cmd_compose (ServerContext *ctx, GSList *args, GError **err)
cmd_compose (ServerContext *ctx, GHashTable *args, GError **err)
{
const gchar *typestr;
char *sexp, *atts;
@ -620,7 +605,7 @@ contacts_to_sexp (MuContacts *contacts, gboolean personal, time_t after)
static MuError
cmd_contacts (ServerContext *ctx, GSList *args, GError **err)
cmd_contacts (ServerContext *ctx, GHashTable *args, GError **err)
{
MuContacts *contacts;
char *sexp;
@ -680,7 +665,7 @@ print_sexps (MuMsgIter *iter, unsigned maxnum)
static MuError
save_part (MuMsg *msg, unsigned docid,
unsigned index, GSList *args, GError **err)
unsigned index, GHashTable *args, GError **err)
{
gboolean rv;
const gchar *path;
@ -740,7 +725,7 @@ leave:
static MuError
temp_part (MuMsg *msg, unsigned docid, unsigned index, GSList *args,
temp_part (MuMsg *msg, unsigned docid, unsigned index, GHashTable *args,
GError **err)
{
const char *what, *param;
@ -798,7 +783,7 @@ action_type (const char *actionstr)
/* 'extract' extracts some mime part from a message */
static MuError
cmd_extract (ServerContext *ctx, GSList *args, GError **err)
cmd_extract (ServerContext *ctx, GHashTable *args, GError **err)
{
MuMsg *msg;
int docid, index, action;
@ -843,7 +828,7 @@ cmd_extract (ServerContext *ctx, GSList *args, GError **err)
/* parse the find parameters, and return the values as out params */
static MuError
get_find_params (GSList *args, MuMsgFieldId *sortfield,
get_find_params (GHashTable *args, MuMsgFieldId *sortfield,
int *maxnum, MuQueryFlags *qflags, GError **err)
{
const char *maxnumstr, *sortfieldstr;
@ -897,7 +882,7 @@ get_find_params (GSList *args, MuMsgFieldId *sortfield,
* (:found <number of found messages>)
*/
static MuError
cmd_find (ServerContext *ctx, GSList *args, GError **err)
cmd_find (ServerContext *ctx, GHashTable *args, GError **err)
{
MuMsgIter *iter;
unsigned foundnum;
@ -949,7 +934,7 @@ cmd_find (ServerContext *ctx, GSList *args, GError **err)
#ifdef BUILD_GUILE
static MuError
cmd_guile (ServerContext *ctx, GSList *args, GError **err)
cmd_guile (ServerContext *ctx, GHashTable *args, GError **err)
{
const char *script, *file;
@ -966,7 +951,7 @@ cmd_guile (ServerContext *ctx, GSList *args, GError **err)
}
#else /*!BUILD_GUILE*/
static MuError
cmd_guile (ServerContext *ctx, GSList *args, GError **err)
cmd_guile (ServerContext *ctx, GHashTable *args, GError **err)
{
print_error (MU_ERROR_INTERNAL,
"this mu does not have guile support");
@ -1063,7 +1048,7 @@ index_and_cleanup (MuIndex *index, const char *path, GError **err)
* index ... ) messages while doing so (see the code)
*/
static MuError
cmd_index (ServerContext *ctx, GSList *args, GError **err)
cmd_index (ServerContext *ctx, GHashTable *args, GError **err)
{
MuIndex *index;
const char *argpath;
@ -1099,7 +1084,7 @@ leave:
/* 'mkdir' attempts to create a maildir directory at 'path:'; sends an
* (:info mkdir ...) message when it succeeds */
static MuError
cmd_mkdir (ServerContext *ctx, GSList *args, GError **err)
cmd_mkdir (ServerContext *ctx, GHashTable *args, GError **err)
{
const char *path;
@ -1214,7 +1199,7 @@ leave:
* would a message in inbox and sentbox with the same id. we set the
* flag on both */
static gboolean
move_msgid_maybe (ServerContext *ctx, GSList *args, GError **err)
move_msgid_maybe (ServerContext *ctx, GHashTable *args, GError **err)
{
GSList *docids, *cur;
const char *maildir = get_string_from_args (args, "maildir", TRUE, err);
@ -1252,7 +1237,7 @@ move_msgid_maybe (ServerContext *ctx, GSList *args, GError **err)
*
*/
static MuError
cmd_move (ServerContext *ctx, GSList *args, GError **err)
cmd_move (ServerContext *ctx, GHashTable *args, GError **err)
{
unsigned docid;
MuMsg *msg;
@ -1305,7 +1290,7 @@ leave:
* server using a (:pong ...) message (details: see code below)
*/
static MuError
cmd_ping (ServerContext *ctx, GSList *args, GError **err)
cmd_ping (ServerContext *ctx, GHashTable *args, GError **err)
{
unsigned doccount;
doccount = mu_store_count (ctx->store, err);
@ -1328,7 +1313,7 @@ cmd_ping (ServerContext *ctx, GSList *args, GError **err)
/* 'quit' takes no parameters, terminates this mu server */
static MuError
cmd_quit (ServerContext *ctx, GSList *args , GError **err)
cmd_quit (ServerContext *ctx, GHashTable *args , GError **err)
{
print_expr (";; quiting");
@ -1372,7 +1357,7 @@ get_path_from_docid (MuStore *store, unsigned docid, GError **err)
* (:remove ...) message when it succeeds
*/
static MuError
cmd_remove (ServerContext *ctx, GSList *args, GError **err)
cmd_remove (ServerContext *ctx, GHashTable *args, GError **err)
{
unsigned docid;
const char *path;
@ -1413,7 +1398,7 @@ cmd_remove (ServerContext *ctx, GSList *args, GError **err)
* message (details: see code below)
*/
static MuError
cmd_sent (ServerContext *ctx, GSList *args, GError **err)
cmd_sent (ServerContext *ctx, GHashTable *args, GError **err)
{
unsigned docid;
const char *maildir, *path;
@ -1436,7 +1421,7 @@ cmd_sent (ServerContext *ctx, GSList *args, GError **err)
}
static MuMsgOptions
get_view_msg_opts (GSList *args)
get_view_msg_opts (GHashTable *args)
{
MuMsgOptions opts;
@ -1458,7 +1443,7 @@ get_view_msg_opts (GSList *args)
* identified by either docid: or msgid:; return a (:view <sexp>)
*/
static MuError
cmd_view (ServerContext *ctx, GSList *args, GError **err)
cmd_view (ServerContext *ctx, GHashTable *args, GError **err)
{
MuMsg *msg;
const gchar *path;
@ -1504,7 +1489,7 @@ cmd_view (ServerContext *ctx, GSList *args, GError **err)
/*************************************************************************/
static MuError
handle_args (ServerContext *ctx, GSList *args, GError **err)
handle_args (ServerContext *ctx, GHashTable *args, GError **err)
{
unsigned u;
const char *cmd;
@ -1528,7 +1513,8 @@ handle_args (ServerContext *ctx, GSList *args, GError **err)
{ "view", cmd_view }
};
cmd = (const char*) args->data;
cmd = g_hash_table_lookup (args, "cmd");
/* ignore empty */
if (mu_str_is_empty (cmd))
@ -1536,7 +1522,7 @@ handle_args (ServerContext *ctx, GSList *args, GError **err)
for (u = 0; u != G_N_ELEMENTS (cmd_map); ++u)
if (g_strcmp0(cmd, cmd_map[u].cmd) == 0)
return cmd_map[u].func (ctx, g_slist_next(args), err);
return cmd_map[u].func (ctx, args, err);
mu_util_g_set_error (err, MU_ERROR_IN_PARAMETERS,
"unknown command '%s'", cmd ? cmd : "");
@ -1567,12 +1553,13 @@ mu_cmd_server (MuStore *store, MuConfig *opts/*unused*/, GError **err)
do_quit = FALSE;
while (!MU_TERMINATE && !do_quit) {
GSList *args;
GError *my_err = NULL;
GHashTable *args;
GError *my_err;
/* args will receive a the command as a list of
* strings. returning NULL indicates an error */
args = read_line_as_list (&my_err);
my_err = NULL;
args = read_command_line (&my_err);
if (!args || my_err) {
print_and_clear_g_error (&my_err);
continue;
@ -1587,7 +1574,7 @@ mu_cmd_server (MuStore *store, MuConfig *opts/*unused*/, GError **err)
print_and_clear_g_error (&my_err);
}
mu_str_free_list (args);
g_hash_table_destroy (args);
}
mu_store_flush (ctx.store);

View File

@ -3457,7 +3457,7 @@ started). It calls @t{mu4e-proc-ping}, and registers a (lambda) function for
@t{mu4e-proc-pong-func}, to handle the response.
@verbatim
-> ping
-> cmd:ping
<- (pong "mu" :version "x.x.x" :doccount 10000)
@end verbatim