static unsigned print_sexps (MuMsgIter *iter, gboolean threads, unsigned maxnum) { unsigned u; u = 0; while (!mu_msg_iter_is_done (iter) && u < maxnum && !MU_TERMINATE) { MuMsg *msg; msg = mu_msg_iter_get_msg_floating (iter); if (mu_msg_is_readable (msg)) { char *sexp; const MuMsgIterThreadInfo* ti; ti = threads ? mu_msg_iter_get_thread_info (iter) : NULL; sexp = mu_msg_to_sexp (msg, mu_msg_iter_get_docid (iter), ti, MU_MSG_OPTION_HEADERS_ONLY); print_expr ("%s", sexp); g_free (sexp); ++u; } mu_msg_iter_next (iter); } return u; }
/* 'add' adds a message to the database, and takes two parameters: * 'path', which is the full path to the message, and 'maildir', which * is the maildir this message lives in (e.g. "/inbox"). response with * an (:info ...) message with information about the newly added * message (details: see code below) */ static MuError cmd_add (ServerContext *ctx, GSList *args, GError **err) { unsigned docid; const char *maildir, *path; MuMsg *msg; gchar *sexp; GET_STRING_OR_ERROR_RETURN (args, "path", &path, err); GET_STRING_OR_ERROR_RETURN (args, "maildir", &maildir, err); docid = mu_store_add_path (ctx->store, path, maildir, err); if (docid == MU_STORE_INVALID_DOCID) print_and_clear_g_error (err); else { gchar *escpath; escpath = mu_str_escape_c_literal (path, TRUE); print_expr ("(:info add :path %s :docid %u)", escpath, docid); msg = mu_store_get_msg (ctx->store, docid, err); if (msg) { sexp = mu_msg_to_sexp (msg, docid, NULL, MU_MSG_OPTION_VERIFY); print_expr ("(:update %s :move nil)", sexp); mu_msg_unref(msg); g_free (sexp); } g_free (escpath); } return MU_OK; }
static gboolean view_msg_sexp (MuMsg *msg) { char *sexp; sexp = mu_msg_to_sexp (msg, 0, NULL, FALSE); fputs (sexp, stdout); g_free (sexp); return TRUE; }
static gboolean view_msg_sexp (MuMsg *msg, MuConfig *opts) { char *sexp; sexp = mu_msg_to_sexp (msg, 0, NULL, mu_config_get_msg_options(opts)); fputs (sexp, stdout); g_free (sexp); return TRUE; }
static gboolean view_msg_sexp (MuMsg *msg, MuConfig *opts) { char *sexp; sexp = mu_msg_to_sexp (msg, 0, NULL, MU_MSG_OPTION_NONE); fputs (sexp, stdout); g_free (sexp); return TRUE; }
static gboolean output_sexp (MuMsg *msg, MuMsgIter *iter, MuConfig *opts, GError **err) { char *sexp; const MuMsgIterThreadInfo *ti; ti = opts->threads ? mu_msg_iter_get_thread_info (iter) : NULL; sexp = mu_msg_to_sexp (msg, mu_msg_iter_get_docid (iter), ti, MU_MSG_OPTION_HEADERS_ONLY); fputs (sexp, stdout); g_free (sexp); return TRUE; }
/* 'compose' produces the un-changed *original* message sexp (ie., the message * to reply to, forward or edit) for a new message to compose). It takes two * parameters: 'type' with the compose type (either reply, forward or * edit/resend), and 'docid' for the message to reply to. Note, type:new does * not have an original message, and therefore does not need a docid * * In returns a (:compose <type> [:original <original-msg>] [:include] ) * message (detals: see code below) * * Note ':include' t or nil determines whether to include attachments */ static MuError cmd_compose (ServerContext *ctx, GHashTable *args, GError **err) { const gchar *typestr; char *sexp, *atts; unsigned ctype; MuMsgOptions opts; opts = get_encrypted_msg_opts (args); GET_STRING_OR_ERROR_RETURN (args, "type", &typestr, err); ctype = compose_type (typestr); if (ctype == INVALID_TYPE) { print_error (MU_ERROR_IN_PARAMETERS, "invalid type to compose"); return MU_OK; } if (ctype == REPLY || ctype == FORWARD || ctype == EDIT || ctype == RESEND) { MuMsg *msg; const char *docidstr; GET_STRING_OR_ERROR_RETURN (args, "docid", &docidstr, err); msg = mu_store_get_msg (ctx->store, atoi(docidstr), err); if (!msg) { print_and_clear_g_error (err); return MU_OK; } sexp = mu_msg_to_sexp (msg, atoi(docidstr), NULL, opts); atts = (ctype == FORWARD) ? include_attachments (msg, opts) : NULL; mu_msg_unref (msg); } else atts = sexp = NULL; print_expr ("(:compose %s :original %s :include %s)", typestr, sexp ? sexp : "nil", atts ? atts : "nil"); g_free (sexp); g_free (atts); return MU_OK; }
/* 'view' gets a full (including body etc.) sexp for some message, * identified by either docid: or msgid:; return a (:view <sexp>) */ static MuError cmd_view (ServerContext *ctx, GSList *args, GError **err) { MuMsg *msg; const gchar *path; char *sexp; MuMsgOptions opts; unsigned docid; opts = get_view_msg_opts (args); /* when 'path' is specified, get the message at path */ path = get_string_from_args (args, "path", FALSE, NULL); if (path) { docid = 0; msg = mu_msg_new_from_file (path, NULL, err); } else { docid = determine_docid (ctx->query, args, err); if (docid == MU_STORE_INVALID_DOCID) { print_and_clear_g_error (err); return MU_OK; } msg = mu_store_get_msg (ctx->store, docid, err); } if (!msg) { print_and_clear_g_error (err); return MU_OK; } sexp = mu_msg_to_sexp (msg, docid, NULL, opts); mu_msg_unref (msg); print_expr ("(:view %s)\n", sexp); g_free (sexp); return MU_OK; }
static MuError do_move (MuStore *store, unsigned docid, MuMsg *msg, const char *maildir, MuFlags flags, GError **err) { unsigned rv; gchar *sexp; gboolean different_mdir; if (!maildir) { maildir = mu_msg_get_maildir (msg); different_mdir = FALSE; } else /* are we moving to a different mdir, or is it just flags? */ different_mdir = (g_strcmp0 (maildir, mu_msg_get_maildir(msg)) != 0); if (!mu_msg_move_to_maildir (msg, maildir, flags, TRUE, err)) return MU_G_ERROR_CODE (err); /* note, after mu_msg_move_to_maildir, path will be the *new* * path, and flags and maildir fields will be updated as * wel */ rv = mu_store_update_msg (store, docid, msg, err); if (rv == MU_STORE_INVALID_DOCID) { mu_util_g_set_error (err, MU_ERROR_XAPIAN, "failed to store updated message"); print_and_clear_g_error (err); } sexp = mu_msg_to_sexp (msg, docid, NULL, MU_MSG_OPTION_VERIFY); /* note, the :move t thing is a hint to the frontend that it * could remove the particular header */ print_expr ("(:update %s :move %s)", sexp, different_mdir ? "t" : "nil"); g_free (sexp); return MU_OK; }