mu: use sha-1 for fallback msgid
We were using a hash based on the path, but it's better to have something that's constant even if the path chnages.
This commit is contained in:
@ -37,29 +37,29 @@
|
|||||||
using namespace Mu;
|
using namespace Mu;
|
||||||
|
|
||||||
static gboolean init_file_metadata (MuMsgFile *self, const char* path,
|
static gboolean init_file_metadata (MuMsgFile *self, const char* path,
|
||||||
const char *mdir, GError **err);
|
const char *mdir, GError **err);
|
||||||
static gboolean init_mime_msg (MuMsgFile *msg, const char *path, GError **err);
|
static gboolean init_mime_msg (MuMsgFile *msg, const char *path, GError **err);
|
||||||
|
|
||||||
MuMsgFile*
|
MuMsgFile*
|
||||||
Mu::mu_msg_file_new (const char* filepath, const char *mdir, GError **err)
|
Mu::mu_msg_file_new (const char* filepath, const char *mdir, GError **err)
|
||||||
{
|
{
|
||||||
MuMsgFile *self;
|
MuMsgFile *self;
|
||||||
|
|
||||||
g_return_val_if_fail (filepath, NULL);
|
g_return_val_if_fail (filepath, NULL);
|
||||||
|
|
||||||
self = g_new0(MuMsgFile, 1);
|
self = g_new0(MuMsgFile, 1);
|
||||||
|
|
||||||
if (!init_file_metadata (self, filepath, mdir, err)) {
|
if (!init_file_metadata (self, filepath, mdir, err)) {
|
||||||
mu_msg_file_destroy (self);
|
mu_msg_file_destroy (self);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!init_mime_msg (self, filepath, err)) {
|
if (!init_mime_msg (self, filepath, err)) {
|
||||||
mu_msg_file_destroy (self);
|
mu_msg_file_destroy (self);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -116,6 +116,30 @@ init_file_metadata (MuMsgFile *self, const char* path, const gchar* mdir,
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static char*
|
||||||
|
calculate_sha1 (FILE *file)
|
||||||
|
{
|
||||||
|
std::array<uint8_t, 4096> buf{};
|
||||||
|
char *sha1{};
|
||||||
|
GChecksum *checksum{g_checksum_new(G_CHECKSUM_SHA256)};
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
const auto n = ::fread(buf.data(), 1, buf.size(), file);
|
||||||
|
if (n == 0)
|
||||||
|
break;
|
||||||
|
g_checksum_update (checksum, buf.data(), n);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (::ferror(file))
|
||||||
|
g_warning ("error reading file");
|
||||||
|
else
|
||||||
|
sha1 = g_strdup(g_checksum_get_string(checksum));
|
||||||
|
|
||||||
|
g_checksum_free(checksum);
|
||||||
|
|
||||||
|
return sha1;
|
||||||
|
}
|
||||||
|
|
||||||
static GMimeStream*
|
static GMimeStream*
|
||||||
get_mime_stream (MuMsgFile *self, const char *path, GError **err)
|
get_mime_stream (MuMsgFile *self, const char *path, GError **err)
|
||||||
{
|
{
|
||||||
@ -140,6 +164,14 @@ get_mime_stream (MuMsgFile *self, const char *path, GError **err)
|
|||||||
}
|
}
|
||||||
|
|
||||||
return stream;
|
return stream;
|
||||||
|
self->_sha1 = calculate_sha1(file);
|
||||||
|
if (!self->_sha1) {
|
||||||
|
::fclose(file);
|
||||||
|
g_set_error (err, MU_ERROR_DOMAIN, MU_ERROR_FILE,
|
||||||
|
"failed to get sha-1 for %s", path);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
@ -649,16 +681,15 @@ address_type (MuMsgFieldId mfid)
|
|||||||
static gchar*
|
static gchar*
|
||||||
get_msgid (MuMsgFile *self, gboolean *do_free)
|
get_msgid (MuMsgFile *self, gboolean *do_free)
|
||||||
{
|
{
|
||||||
const char *msgid;
|
const char *msgid{g_mime_message_get_message_id (self->_mime_msg)};
|
||||||
|
if (msgid && strlen(msgid) < MU_STORE_MAX_TERM_LENGTH) {
|
||||||
msgid = g_mime_message_get_message_id (self->_mime_msg);
|
*do_free = FALSE;
|
||||||
if (msgid && strlen(msgid) < MU_STORE_MAX_TERM_LENGTH) {
|
return (char*)msgid;
|
||||||
return (char*)msgid;
|
}
|
||||||
} else { /* if there is none, fake it */
|
// if there's no valid message-id, synthesize one;
|
||||||
*do_free = TRUE;
|
// based on the contents so it stays valid if moved around.
|
||||||
return g_strdup_printf ("%016" PRIx64 "@fake-msgid",
|
*do_free = TRUE;
|
||||||
mu_util_get_hash (self->_path));
|
return g_strdup_printf ("%s@mu", self->_sha1);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
char*
|
char*
|
||||||
|
|||||||
@ -36,6 +36,7 @@ struct MuMsgFile {
|
|||||||
size_t _size;
|
size_t _size;
|
||||||
char *_path;
|
char *_path;
|
||||||
char *_maildir;
|
char *_maildir;
|
||||||
|
char *_sha1;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user