示例#1
0
文件: mu-threader.c 项目: nd/mu
/* find a container for the given msgid; if it does not exist yet,
 * create a new one, and register it */
static MuContainer*
find_or_create (GHashTable *id_table, MuMsg *msg, guint docid)
{
	MuContainer *c;
	const char* msgid;

	g_return_val_if_fail (msg, NULL);
	g_return_val_if_fail (docid != 0, NULL);

	msgid = mu_msg_get_msgid (msg);
	if (!msgid)
		msgid = mu_msg_get_path (msg); /* fake it */

	c = g_hash_table_lookup (id_table, msgid);

	/* If id_table contains an empty MuContainer for this ID: * *
	 * Store this message in the MuContainer's message slot. */
	if (c) {
		if (!c->msg) {
			c->msg	  = mu_msg_ref (msg);
			c->docid  = docid;
			return c;
		} else {
			/* special case, not in the JWZ algorithm: the
			 * container exists already and has a message; this
			 * means that we are seeing *another message* with a
			 * message-id we already saw... create this message,
			 * and mark it as a duplicate, and a child of the one
			 * we saw before; use its path as a fake message-id
			 * */
			MuContainer *c2;
			const char* fake_msgid;

			fake_msgid = mu_msg_get_path (msg);

			c2	  = mu_container_new (msg, docid, fake_msgid);
			c2->flags = MU_CONTAINER_FLAG_DUP;
			c	  = mu_container_append_children (c, c2);

			g_hash_table_insert (id_table, (gpointer)fake_msgid, c2);

			return NULL; /* don't process this message further */
		}
	} else { /* Else: Create a new MuContainer object holding
		    this message; Index the MuContainer by
		    Message-ID in id_table. */
		c = mu_container_new (msg, docid, msgid);
		g_hash_table_insert (id_table, (gpointer)msgid, c);
		/* assert_no_duplicates (id_table); */

		return c;
	}
}
示例#2
0
文件: mu-msg.c 项目: akonring/mu
/* we need do to determine the
 *   /home/foo/Maildir/bar
 * from the /bar
 * that we got
 */
char*
get_target_mdir (MuMsg *msg, const char *target_maildir, GError **err)
{
	char *rootmaildir, *rv;
	const char *maildir;
	gboolean not_top_level;

	/* maildir is the maildir stored in the message, e.g. '/foo' */
	maildir = mu_msg_get_maildir(msg);
	if (!maildir) {
		mu_util_g_set_error (err, MU_ERROR_GMIME,
				     "message without maildir");
		return NULL;
	}

	/* the 'rootmaildir' is the filesystem path from root to
	 * maildir, ie.  /home/user/Maildir/foo */
	rootmaildir = mu_maildir_get_maildir_from_path (mu_msg_get_path(msg));
	if (!rootmaildir) {
		mu_util_g_set_error (err, MU_ERROR_GMIME,
				     "cannot determine maildir");
		return NULL;
	}

	/* we do a sanity check: verify that that maildir is a suffix of
	 * rootmaildir;*/
	not_top_level = TRUE;
	if (!g_str_has_suffix (rootmaildir, maildir) &&
	    /* special case for the top-level '/' maildir, and
	     * remember not_top_level */
	    (not_top_level = (g_strcmp0 (maildir, "/") != 0))) {
		g_set_error (err, MU_ERROR_DOMAIN, MU_ERROR_FILE,
			     "path is '%s', but maildir is '%s' ('%s')",
			     rootmaildir, mu_msg_get_maildir(msg),
			     mu_msg_get_path (msg));
		g_free (rootmaildir);
		return NULL;
	}

	/* if we're not at the top-level, remove the final '/' from
	 * the rootmaildir */
	if (not_top_level)
		rootmaildir[strlen(rootmaildir) -
			    strlen (mu_msg_get_maildir(msg))] = '\0';

	rv = g_strconcat (rootmaildir, target_maildir, NULL);
	g_free (rootmaildir);

	return rv;
}
示例#3
0
文件: mu-msg.c 项目: akonring/mu
gboolean
mu_msg_is_readable (MuMsg *self)
{
	g_return_val_if_fail (self, FALSE);

	return access (mu_msg_get_path (self), R_OK) == 0 ? TRUE : FALSE;
}
示例#4
0
文件: mu-cmd-server.c 项目: Popsch/mu
static MuError
move_msgid (MuStore *store, unsigned docid, const char* flagstr, GError **err)
{
	MuMsg *msg;
	MuError rv;
	MuFlags flags;

	rv  = MU_ERROR;
	msg = mu_store_get_msg (store, docid, err);

	if (!msg)
		goto leave;

	flags = flagstr ? get_flags (mu_msg_get_path(msg), flagstr) :
		mu_msg_get_flags (msg);
	if (flags == MU_FLAG_INVALID) {
		mu_util_g_set_error (err, MU_ERROR_IN_PARAMETERS,
				     "invalid flags");
		goto leave;
	}

	rv = do_move (store, docid, msg, NULL, flags, err);

leave:
	if (msg)
		mu_msg_unref (msg);
	if (rv != MU_OK)
		print_and_clear_g_error (err);

	return rv;
}
示例#5
0
文件: mu-cmd-server.c 项目: Popsch/mu
/* NOTE: this assumes there is only _one_ docid (message) for the
 * particular message id */
static unsigned
get_docid_from_msgid (MuQuery *query, const char *str, GError **err)
{
	gchar *querystr;
	unsigned docid;
	MuMsgIter *iter;

	querystr = g_strdup_printf ("msgid:%s", str);
	iter = mu_query_run (query, querystr, FALSE,
			     MU_MSG_FIELD_ID_NONE, FALSE, 1, err);
	g_free (querystr);

	docid = MU_STORE_INVALID_DOCID;
	if (!iter || mu_msg_iter_is_done (iter))
		mu_util_g_set_error (err, MU_ERROR_NO_MATCHES,
				     "could not find message %s", str);
	else {
		MuMsg *msg;
		msg = mu_msg_iter_get_msg_floating (iter);
		if (!mu_msg_is_readable(msg)) {
			mu_util_g_set_error (err, MU_ERROR_FILE_CANNOT_READ,
					     "'%s' is not readable",
					     mu_msg_get_path(msg));
		} else
			docid = mu_msg_iter_get_docid (iter);

		mu_msg_iter_destroy (iter);
	}

	return docid;
}
示例#6
0
文件: mu-msg-part.c 项目: otfrom/mu
gchar*
mu_msg_part_get_cache_path (MuMsg *msg, MuMsgOptions opts, guint partid,
			    GError **err)
{
	char *dirname, *filepath;
	const char* path;

	g_return_val_if_fail (msg, NULL);

	if (!mu_msg_load_msg_file (msg, NULL))
		return NULL;

	path = mu_msg_get_path (msg);

	/* g_compute_checksum_for_string may be better, but requires
	 * rel. new glib (2.16) */
        dirname = g_strdup_printf ("%s%c%x%c%u",
				   mu_util_cache_dir(), G_DIR_SEPARATOR,
				   g_str_hash (path), G_DIR_SEPARATOR,
				   partid);

	if (!mu_util_create_dir_maybe (dirname, 0700, FALSE)) {
		mu_util_g_set_error (err, MU_ERROR_FILE,
				     "failed to create dir %s", dirname);
		g_free (dirname);
		return NULL;
	}

	filepath = mu_msg_part_get_path (msg, opts, dirname, partid, err);
	g_free (dirname);

	return filepath;
}
示例#7
0
文件: mu-cmd-find.c 项目: migadu/mu
static JsonBuilder*
get_message_json (MuMsg *msg)
{
        JsonBuilder *builder = json_builder_new ();
  json_builder_begin_object (builder);

  json_add_recipients(builder, msg);
  json_add_subject(builder, msg);

        json_builder_set_member_name (builder, "msgid");
        json_builder_add_string_value (builder, mu_msg_get_msgid (msg));

        json_builder_set_member_name (builder, "date");
        json_builder_add_int_value (builder, (unsigned)mu_msg_get_date (msg));

  json_add_flags(builder, msg);

  json_builder_set_member_name (builder, "path");
  json_builder_add_string_value (builder, mu_msg_get_path (msg));

  json_builder_set_member_name (builder, "folder");
  json_builder_add_string_value (builder, mu_msg_get_maildir (msg));

  json_builder_set_member_name (builder, "size");
  json_builder_add_int_value (builder, (unsigned)mu_msg_get_size (msg));

  json_builder_end_object (builder);
  return builder;
}
示例#8
0
static void
add_row (GtkListStore * store, MuMsg *msg)
{
	GtkTreeIter treeiter;
	const gchar *datestr, *flagstr;
	gchar *from, *to;
	time_t timeval;

	timeval = mu_msg_get_date (msg);
	datestr = timeval == 0 ? "-" : mu_date_display_s (timeval);
	from = empty_or_display_contact (mu_msg_get_from (msg));
	to = empty_or_display_contact (mu_msg_get_to (msg));
	flagstr = mu_flags_to_str_s (mu_msg_get_flags (msg), MU_FLAG_TYPE_ANY);

	gtk_list_store_append (store, &treeiter);
	gtk_list_store_set (store, &treeiter,
			    MUG_COL_DATESTR, datestr,
			    MUG_COL_MAILDIR, mu_msg_get_maildir (msg),
			    MUG_COL_FLAGSSTR, flagstr,
			    MUG_COL_FROM, from,
			    MUG_COL_TO, to,
			    MUG_COL_SUBJECT, mu_msg_get_subject (msg),
			    MUG_COL_PATH, mu_msg_get_path (msg),
			    MUG_COL_PRIO, mu_msg_get_prio (msg),
			    MUG_COL_FLAGS, mu_msg_get_flags (msg),
			    MUG_COL_TIME, timeval, -1);
	g_free (from);
	g_free (to);
}
示例#9
0
static void
add_row (GtkTreeStore * store, MuMsg *msg, GtkTreeIter *treeiter)
{
	const gchar *datestr, *flagstr;
	gchar *from, *to;
	time_t timeval;

	timeval = mu_msg_get_date (msg);
	datestr = timeval == 0 ? "-" : mu_date_display_s (timeval);
	from = empty_or_display_contact (mu_msg_get_from (msg));
	to = empty_or_display_contact (mu_msg_get_to (msg));
	flagstr = mu_flags_to_str_s (mu_msg_get_flags (msg), MU_FLAG_TYPE_ANY);

 	/* if (0) { */
	/* 	GtkTreeIter myiter; */
	/* 	if (!gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL(store), */
	/* 						  &myiter, path)) */
	/* 		g_warning ("%s: cannot get iter for %s",
	 * 		__FUNCTION__, path); */
	/* } */

	gtk_tree_store_set (store, treeiter,
			    MUG_COL_DATESTR, datestr,
			    MUG_COL_MAILDIR, mu_msg_get_maildir (msg),
			    MUG_COL_FLAGSSTR, flagstr,
			    MUG_COL_FROM, from,
			    MUG_COL_TO, to,
			    MUG_COL_SUBJECT, mu_msg_get_subject (msg),
			    MUG_COL_PATH, mu_msg_get_path (msg),
			    MUG_COL_PRIO, mu_msg_get_prio (msg),
			    MUG_COL_FLAGS, mu_msg_get_flags (msg),
			    MUG_COL_TIME, timeval, -1);
	g_free (from);
	g_free (to);
}
示例#10
0
文件: mu-msg-json.c 项目: djcb/mu
struct _JsonNode*
mu_msg_to_json (MuMsg *msg, unsigned docid, const MuMsgIterThreadInfo *ti,
		MuMsgOptions opts)
{
	JsonNode	*node;
	JsonBuilder	*bob;

	time_t	t;
	size_t	s;

	g_return_val_if_fail (msg, NULL);
	g_return_val_if_fail (!((opts & MU_MSG_OPTION_HEADERS_ONLY) &&
				(opts & MU_MSG_OPTION_EXTRACT_IMAGES)),NULL);
	bob = json_builder_new ();
	bob = json_builder_begin_object (bob);

	if (ti)
		add_thread_info (bob, ti);

	add_string_member (bob, "subject", mu_msg_get_subject (msg));

	/* in the no-headers-only case (see below) we get a more complete list
	 * of contacts, so no need to get them here if that's the case */
	if (opts & MU_MSG_OPTION_HEADERS_ONLY)
		add_contacts (bob, msg);

	t = mu_msg_get_date (msg);
	if (t != (time_t)-1)
		add_int_member (bob, "date", t);

	s = mu_msg_get_size (msg);
	if (s != (size_t)-1)
		add_int_member (bob, "size", s);

	add_string_member (bob, "message-id", mu_msg_get_msgid (msg));
	add_string_member (bob, "mailing-list", mu_msg_get_mailing_list (msg));
	add_string_member (bob, "path", mu_msg_get_path (msg));
	add_string_member (bob, "maildir", mu_msg_get_maildir (msg));
	add_string_member (bob, "priority", mu_msg_prio_name(mu_msg_get_prio(msg)));

	add_flags (bob, msg);

	add_list_member (bob, "tags", mu_msg_get_tags(msg));
	add_list_member (bob, "references", mu_msg_get_references (msg));
	add_string_member (bob, "in-reply-to",
			   mu_msg_get_header (msg, "In-Reply-To"));

	/* headers are retrieved from the database, views from the
	 * message file file attr things can only be gotten from the
	 * file (ie., mu view), not from the database (mu find).  */
	if (!(opts & MU_MSG_OPTION_HEADERS_ONLY))
		add_file_parts (bob, msg, opts);

	bob  = json_builder_end_object (bob);
	node = json_builder_get_root (bob);

	g_clear_object (&bob);

	return node;
}
示例#11
0
文件: mu-cmd-server.c 项目: zakkak/mu
/*
 * 'move' moves a message to a different maildir and/or changes its
 * flags. parameters are *either* a 'docid:' or 'msgid:' pointing to
 * the message, a 'maildir:' for the target maildir, and a 'flags:'
 * parameter for the new flags.
 *
 * returns an (:update <new-msg-sexp>)
 *
 */
static MuError
cmd_move (ServerContext *ctx, GHashTable *args, GError **err)
{
	unsigned docid;
	MuMsg *msg;
	MuFlags flags;
	const char *maildir, *flagstr;
	gboolean new_name;

	/* check if the move is based on the message id; if so, handle
	 * it in move_msgid_maybe */
	if (move_msgid_maybe (ctx, args, err))
		return MU_OK;

	maildir	 = get_string_from_args (args, "maildir", TRUE, err);
	flagstr	 = get_string_from_args (args, "flags", TRUE, err);
	new_name = get_bool_from_args (args, "newname", TRUE, err);

	docid = determine_docid (ctx->query, args, err);
	if (docid == MU_STORE_INVALID_DOCID ||
	    !(msg = mu_store_get_msg (ctx->store, docid, err))) {
		print_and_clear_g_error (err);
		return MU_OK;
	}

	/* if maildir was not specified, take the current one */
	if (!maildir)
		maildir = mu_msg_get_maildir (msg);

	/* determine the real target flags, which come from the
	 * flags-parameter we received (ie., flagstr), if any, plus
	 * the existing message flags. */
	if (flagstr)
		flags = get_flags (mu_msg_get_path(msg), flagstr);
	else
		flags = mu_msg_get_flags (msg);

	if (flags == MU_FLAG_INVALID) {
		print_error (MU_ERROR_IN_PARAMETERS, "invalid flags");
		goto leave;
	}

	if ((do_move (ctx->store, docid, msg, maildir, flags, new_name, err)
	     != MU_OK))
		print_and_clear_g_error (err);

leave:
	mu_msg_unref (msg);
	return MU_OK;
}
示例#12
0
文件: mu-msg.c 项目: akonring/mu
time_t
mu_msg_get_timestamp (MuMsg *self)
{
	const char *path;
	struct stat statbuf;

	g_return_val_if_fail (self, 0);

	if (self->_file)
		return self->_file->_timestamp;

	path = mu_msg_get_path (self);
	if (!path || stat (path, &statbuf) < 0)
		return 0;

	return statbuf.st_mtime;
}
示例#13
0
static gboolean
exec_cmd (MuMsg *msg, MuMsgIter *iter, MuConfig *opts,  GError **err)
{
	gint status;
	char *cmdline, *escpath;
	gboolean rv;

	escpath = g_shell_quote (mu_msg_get_path (msg));
	cmdline = g_strdup_printf ("%s %s", opts->exec, escpath);

	rv = g_spawn_command_line_sync (cmdline, NULL, NULL, &status, err);

	g_free (cmdline);
	g_free (escpath);

	return rv;
}
示例#14
0
static gboolean
output_xml (MuMsg *msg, MuMsgIter *iter, MuConfig *opts, GError **err)
{
	g_print ("\t<message>\n");
	print_attr_xml ("from", mu_msg_get_from (msg));
	print_attr_xml ("to", mu_msg_get_to (msg));
	print_attr_xml ("cc", mu_msg_get_cc (msg));
	print_attr_xml ("subject", mu_msg_get_subject (msg));
	g_print ("\t\t<date>%u</date>\n",
		 (unsigned)mu_msg_get_date (msg));
	g_print ("\t\t<size>%u</size>\n", (unsigned)mu_msg_get_size (msg));
	print_attr_xml ("msgid", mu_msg_get_msgid (msg));
	print_attr_xml ("path", mu_msg_get_path (msg));
	print_attr_xml ("maildir", mu_msg_get_maildir (msg));
	g_print ("\t</message>\n");

	return TRUE;
}
示例#15
0
static gboolean
dump_container (MuContainer *c)
{
	const gchar* subject;

	if (!c) {
		g_print ("<empty>\n");
		return TRUE;
	}

	subject =  (c->msg) ? mu_msg_get_subject (c->msg) : "<none>";

	g_print ("[%s][%s m:%p p:%p docid:%u %s]\n",c->msgid, subject, (void*)c,
		 (void*)c->parent, c->docid,
		 c->msg ? mu_msg_get_path (c->msg) : "");

	return TRUE;
}
示例#16
0
文件: mu-msg.c 项目: bonega/mu
/*
 * move a msg to another maildir, trying to maintain 'integrity',
 * ie. msg in 'new/' will go to new/, one in cur/ goes to cur/. be
 * super-paranoid here...
 */
gboolean
mu_msg_move_to_maildir (MuMsg *self, const char *maildir,
			MuFlags flags, gboolean ignore_dups, GError **err)
{
	char *newfullpath;
	char *targetmdir;

	g_return_val_if_fail (self, FALSE);
	g_return_val_if_fail (maildir, FALSE);     /* i.e. "/inbox" */

	targetmdir = get_target_mdir (self, maildir, err);
	if (!targetmdir)
		return FALSE;

	newfullpath = mu_maildir_move_message (mu_msg_get_path (self),
					       targetmdir, flags,
					       ignore_dups, err);
	g_free (targetmdir);

	/* update the message path and the flags; they may have
	 * changed */
	if (newfullpath) {
		mu_msg_cache_set_str (self->_cache, MU_MSG_FIELD_ID_PATH, newfullpath,
				      TRUE); /* the cache will free the string */
		mu_msg_cache_set_str (self->_cache, MU_MSG_FIELD_ID_MAILDIR,
				      g_strdup(maildir), TRUE);
		/* the cache will free the string */

		/* the contentflags haven't changed, so make sure they persist */
		flags |= mu_msg_get_flags (self) &
			(MU_FLAG_HAS_ATTACH|MU_FLAG_ENCRYPTED|MU_FLAG_SIGNED);
		/* update the pseudo-flag as well */
		if (!(flags & MU_FLAG_NEW) && (flags & MU_FLAG_SEEN))
			flags &= ~MU_FLAG_UNREAD;
		else
			flags |= MU_FLAG_UNREAD;

		mu_msg_cache_set_num (self->_cache, MU_MSG_FIELD_ID_FLAGS, flags);
	}

	return newfullpath ? TRUE : FALSE;
}
示例#17
0
void
mu_msg_body_view_set_message_source (MuMsgBodyView *self, MuMsg *msg)
{
	const gchar *path;
	gchar *data;

	g_return_if_fail (MU_IS_MSG_BODY_VIEW(self));
	g_return_if_fail (msg);

	set_message (self, NULL);
	
	path = msg ? mu_msg_get_path (msg) : NULL;
	
	if (path && g_file_get_contents (path, &data, NULL, NULL)) {
		set_text (self, data);
		g_free (data);
	} else
		set_text (self, "");

	self->_priv->_view_mode = VIEW_MODE_SOURCE;
}
示例#18
0
文件: mu-msg.c 项目: tuxella/mu
/*
 * move a msg to another maildir, trying to maintain 'integrity',
 * ie. msg in 'new/' will go to new/, one in cur/ goes to cur/. be
 * super-paranoid here...
 */
gboolean
mu_msg_move_to_maildir (MuMsg *self, const char *maildir,
			MuFlags flags, gboolean ignore_dups, gboolean new_name,
			GError **err)
{
	char *newfullpath;
	char *targetmdir;

	g_return_val_if_fail (self, FALSE);
	g_return_val_if_fail (maildir, FALSE);     /* i.e. "/inbox" */

	/* targetmdir is the full path to maildir, i.e.,
	 * /home/foo/Maildir/inbox */
	targetmdir = get_target_mdir (self, maildir, err);
	if (!targetmdir)
		return FALSE;

	newfullpath = mu_maildir_move_message (mu_msg_get_path (self),
					       targetmdir, flags,
					       ignore_dups, new_name, err);
	/* update the message path and the flags; they may have
	 * changed */
	if (!newfullpath) {
		g_free (targetmdir);
		return FALSE;
	}

	/* clear the old backends */
	mu_msg_doc_destroy  (self->_doc);
	self->_doc = NULL;

	mu_msg_file_destroy (self->_file);

	/* and create a new one */
	self->_file = mu_msg_file_new (newfullpath, maildir, err);
	g_free (targetmdir);

	return self->_file ? TRUE : FALSE;
}
示例#19
0
文件: mu-cmd-server.c 项目: Popsch/mu
/*
 * creating a message object just to get a path seems a bit excessive
 * maybe mu_store_get_path could be added if this turns out to be a
 * problem
 *
 * NOTE: not re-entrant.
 */
static const char*
get_path_from_docid (MuStore *store, unsigned docid, GError **err)
{
	MuMsg *msg;
	const char* msgpath;
	static char path[PATH_MAX + 1];

	msg = mu_store_get_msg (store, docid, err);
	if (!msg)
		return NULL;

	msgpath = mu_msg_get_path (msg);
	if (!msgpath) {
		mu_msg_unref (msg);
		return NULL;
	}

	strncpy (path, msgpath, sizeof(path));

	mu_msg_unref (msg);
	return path;
}
示例#20
0
static gboolean
output_link (MuMsg *msg, MuMsgIter *iter, MuConfig *opts,  GError **err)
{
	return mu_maildir_link (mu_msg_get_path (msg),
				opts->linksdir, err);
}