mail.c revision d172c364637944d667aa98eb5de0d4a3a97ab92a
2454dfa32c93c20a8522c6ed42fe057baaac9f9aStephan Bosch/* Copyright (c) 2002-2009 Dovecot authors, see the included COPYING file */
f8740ac53310cd28ba4ec6dc9e9ce6e9a3688f39Timo Sirainen
f8740ac53310cd28ba4ec6dc9e9ce6e9a3688f39Timo Sirainen#include "lib.h"
f8740ac53310cd28ba4ec6dc9e9ce6e9a3688f39Timo Sirainen#include "ioloop.h"
f8740ac53310cd28ba4ec6dc9e9ce6e9a3688f39Timo Sirainen#include "crc32.h"
fccd110b494a7e31f23d31d9e3bc3e986c9bb1a8Timo Sirainen#include "hostpid.h"
f8740ac53310cd28ba4ec6dc9e9ce6e9a3688f39Timo Sirainen#include "mail-storage-private.h"
f8740ac53310cd28ba4ec6dc9e9ce6e9a3688f39Timo Sirainen
f8740ac53310cd28ba4ec6dc9e9ce6e9a3688f39Timo Sirainen#include <time.h>
f8740ac53310cd28ba4ec6dc9e9ce6e9a3688f39Timo Sirainen
b7324e421e2132cbbf753e6fdbe675bbaecdf929Timo Sirainenstruct mail *mail_alloc(struct mailbox_transaction_context *t,
f8740ac53310cd28ba4ec6dc9e9ce6e9a3688f39Timo Sirainen enum mail_fetch_field wanted_fields,
f8740ac53310cd28ba4ec6dc9e9ce6e9a3688f39Timo Sirainen struct mailbox_header_lookup_ctx *wanted_headers)
f8740ac53310cd28ba4ec6dc9e9ce6e9a3688f39Timo Sirainen{
c9099b08b3cae8a849098ca776b4363c6d5f5f36Timo Sirainen return t->box->v.mail_alloc(t, wanted_fields, wanted_headers);
c9099b08b3cae8a849098ca776b4363c6d5f5f36Timo Sirainen}
c9099b08b3cae8a849098ca776b4363c6d5f5f36Timo Sirainen
c9099b08b3cae8a849098ca776b4363c6d5f5f36Timo Sirainenvoid mail_free(struct mail **mail)
c9099b08b3cae8a849098ca776b4363c6d5f5f36Timo Sirainen{
c9099b08b3cae8a849098ca776b4363c6d5f5f36Timo Sirainen struct mail_private *p = (struct mail_private *)*mail;
c9099b08b3cae8a849098ca776b4363c6d5f5f36Timo Sirainen
c9099b08b3cae8a849098ca776b4363c6d5f5f36Timo Sirainen p->v.free(*mail);
c9099b08b3cae8a849098ca776b4363c6d5f5f36Timo Sirainen *mail = NULL;
c9099b08b3cae8a849098ca776b4363c6d5f5f36Timo Sirainen}
f8740ac53310cd28ba4ec6dc9e9ce6e9a3688f39Timo Sirainen
f8740ac53310cd28ba4ec6dc9e9ce6e9a3688f39Timo Sirainenvoid mail_set_seq(struct mail *mail, uint32_t seq)
f8740ac53310cd28ba4ec6dc9e9ce6e9a3688f39Timo Sirainen{
f8740ac53310cd28ba4ec6dc9e9ce6e9a3688f39Timo Sirainen struct mail_private *p = (struct mail_private *)mail;
f8740ac53310cd28ba4ec6dc9e9ce6e9a3688f39Timo Sirainen
f8740ac53310cd28ba4ec6dc9e9ce6e9a3688f39Timo Sirainen p->v.set_seq(mail, seq);
f8740ac53310cd28ba4ec6dc9e9ce6e9a3688f39Timo Sirainen}
f8740ac53310cd28ba4ec6dc9e9ce6e9a3688f39Timo Sirainen
f8740ac53310cd28ba4ec6dc9e9ce6e9a3688f39Timo Sirainenbool mail_set_uid(struct mail *mail, uint32_t uid)
f8740ac53310cd28ba4ec6dc9e9ce6e9a3688f39Timo Sirainen{
f8740ac53310cd28ba4ec6dc9e9ce6e9a3688f39Timo Sirainen struct mail_private *p = (struct mail_private *)mail;
f8740ac53310cd28ba4ec6dc9e9ce6e9a3688f39Timo Sirainen
f8740ac53310cd28ba4ec6dc9e9ce6e9a3688f39Timo Sirainen return p->v.set_uid(mail, uid);
f8740ac53310cd28ba4ec6dc9e9ce6e9a3688f39Timo Sirainen}
f8740ac53310cd28ba4ec6dc9e9ce6e9a3688f39Timo Sirainen
f8740ac53310cd28ba4ec6dc9e9ce6e9a3688f39Timo Sirainenenum mail_flags mail_get_flags(struct mail *mail)
f8740ac53310cd28ba4ec6dc9e9ce6e9a3688f39Timo Sirainen{
f8740ac53310cd28ba4ec6dc9e9ce6e9a3688f39Timo Sirainen struct mail_private *p = (struct mail_private *)mail;
92f5ea24e989266539e97c6fe59ede0565aec6fdTimo Sirainen
f8740ac53310cd28ba4ec6dc9e9ce6e9a3688f39Timo Sirainen return p->v.get_flags(mail);
fb79b36eb34532dbe67caf99eefe3660b8c841e0Timo Sirainen}
7000810786f2959f02cd6d2f4151a9eb61ff5db8Timo Sirainen
47daf6e810a4c2dd52640092092900dbcb12f265Timo Sirainenuint64_t mail_get_modseq(struct mail *mail)
47daf6e810a4c2dd52640092092900dbcb12f265Timo Sirainen{
47daf6e810a4c2dd52640092092900dbcb12f265Timo Sirainen struct mail_private *p = (struct mail_private *)mail;
47daf6e810a4c2dd52640092092900dbcb12f265Timo Sirainen
92f5ea24e989266539e97c6fe59ede0565aec6fdTimo Sirainen return p->v.get_modseq(mail);
7000810786f2959f02cd6d2f4151a9eb61ff5db8Timo Sirainen}
47daf6e810a4c2dd52640092092900dbcb12f265Timo Sirainen
7000810786f2959f02cd6d2f4151a9eb61ff5db8Timo Sirainenconst char *const *mail_get_keywords(struct mail *mail)
cc23ad7b8ab96d93d5ab5139c431fcdd8d9e1d72Timo Sirainen{
cc23ad7b8ab96d93d5ab5139c431fcdd8d9e1d72Timo Sirainen struct mail_private *p = (struct mail_private *)mail;
cc23ad7b8ab96d93d5ab5139c431fcdd8d9e1d72Timo Sirainen
cc23ad7b8ab96d93d5ab5139c431fcdd8d9e1d72Timo Sirainen return p->v.get_keywords(mail);
cc23ad7b8ab96d93d5ab5139c431fcdd8d9e1d72Timo Sirainen}
cc23ad7b8ab96d93d5ab5139c431fcdd8d9e1d72Timo Sirainen
cc23ad7b8ab96d93d5ab5139c431fcdd8d9e1d72Timo Sirainenconst ARRAY_TYPE(keyword_indexes) *mail_get_keyword_indexes(struct mail *mail)
cc23ad7b8ab96d93d5ab5139c431fcdd8d9e1d72Timo Sirainen{
1c0020171b04d14adc4966ed963361abc9a86787Timo Sirainen struct mail_private *p = (struct mail_private *)mail;
1c0020171b04d14adc4966ed963361abc9a86787Timo Sirainen
1c0020171b04d14adc4966ed963361abc9a86787Timo Sirainen return p->v.get_keyword_indexes(mail);
1c0020171b04d14adc4966ed963361abc9a86787Timo Sirainen}
1c0020171b04d14adc4966ed963361abc9a86787Timo Sirainen
1c0020171b04d14adc4966ed963361abc9a86787Timo Sirainenint mail_get_parts(struct mail *mail, const struct message_part **parts_r)
1c0020171b04d14adc4966ed963361abc9a86787Timo Sirainen{
1c0020171b04d14adc4966ed963361abc9a86787Timo Sirainen struct mail_private *p = (struct mail_private *)mail;
92f9871ac981201fe0a47f6c909f790cce14b240Timo Sirainen
92f9871ac981201fe0a47f6c909f790cce14b240Timo Sirainen return p->v.get_parts(mail, parts_r);
1c0020171b04d14adc4966ed963361abc9a86787Timo Sirainen}
1c0020171b04d14adc4966ed963361abc9a86787Timo Sirainen
1c0020171b04d14adc4966ed963361abc9a86787Timo Sirainenint mail_get_date(struct mail *mail, time_t *date_r, int *timezone_r)
df8046c9a4f6bc2a478ad1e74504d50f3110c906Timo Sirainen{
df8046c9a4f6bc2a478ad1e74504d50f3110c906Timo Sirainen struct mail_private *p = (struct mail_private *)mail;
7000810786f2959f02cd6d2f4151a9eb61ff5db8Timo Sirainen int tz;
abb5d20d3155db02a1afec4066d52707ba9d4e52Timo Sirainen
abb5d20d3155db02a1afec4066d52707ba9d4e52Timo Sirainen if (timezone_r == NULL)
abb5d20d3155db02a1afec4066d52707ba9d4e52Timo Sirainen timezone_r = &tz;
df8046c9a4f6bc2a478ad1e74504d50f3110c906Timo Sirainen
df8046c9a4f6bc2a478ad1e74504d50f3110c906Timo Sirainen return p->v.get_date(mail, date_r, timezone_r);
df8046c9a4f6bc2a478ad1e74504d50f3110c906Timo Sirainen}
abb5d20d3155db02a1afec4066d52707ba9d4e52Timo Sirainen
abb5d20d3155db02a1afec4066d52707ba9d4e52Timo Sirainenint mail_get_received_date(struct mail *mail, time_t *date_r)
abb5d20d3155db02a1afec4066d52707ba9d4e52Timo Sirainen{
df8046c9a4f6bc2a478ad1e74504d50f3110c906Timo Sirainen struct mail_private *p = (struct mail_private *)mail;
df8046c9a4f6bc2a478ad1e74504d50f3110c906Timo Sirainen
df8046c9a4f6bc2a478ad1e74504d50f3110c906Timo Sirainen return p->v.get_received_date(mail, date_r);
df8046c9a4f6bc2a478ad1e74504d50f3110c906Timo Sirainen}
df8046c9a4f6bc2a478ad1e74504d50f3110c906Timo Sirainen
abb5d20d3155db02a1afec4066d52707ba9d4e52Timo Sirainenint mail_get_save_date(struct mail *mail, time_t *date_r)
abb5d20d3155db02a1afec4066d52707ba9d4e52Timo Sirainen{
abb5d20d3155db02a1afec4066d52707ba9d4e52Timo Sirainen struct mail_private *p = (struct mail_private *)mail;
df8046c9a4f6bc2a478ad1e74504d50f3110c906Timo Sirainen
df8046c9a4f6bc2a478ad1e74504d50f3110c906Timo Sirainen return p->v.get_save_date(mail, date_r);
df8046c9a4f6bc2a478ad1e74504d50f3110c906Timo Sirainen}
df8046c9a4f6bc2a478ad1e74504d50f3110c906Timo Sirainen
abb5d20d3155db02a1afec4066d52707ba9d4e52Timo Sirainenint mail_get_virtual_size(struct mail *mail, uoff_t *size_r)
7000810786f2959f02cd6d2f4151a9eb61ff5db8Timo Sirainen{
7000810786f2959f02cd6d2f4151a9eb61ff5db8Timo Sirainen struct mail_private *p = (struct mail_private *)mail;
abb5d20d3155db02a1afec4066d52707ba9d4e52Timo Sirainen
d6a7cb184cc882a90aa3d9312082e0029f354ff6Timo Sirainen return p->v.get_virtual_size(mail, size_r);
abb5d20d3155db02a1afec4066d52707ba9d4e52Timo Sirainen}
abb5d20d3155db02a1afec4066d52707ba9d4e52Timo Sirainen
2aee623fcad4b931c27435ceaa495c3d3edd69b6Aki Tuomiint mail_get_physical_size(struct mail *mail, uoff_t *size_r)
d6a7cb184cc882a90aa3d9312082e0029f354ff6Timo Sirainen{
d6a7cb184cc882a90aa3d9312082e0029f354ff6Timo Sirainen struct mail_private *p = (struct mail_private *)mail;
d6a7cb184cc882a90aa3d9312082e0029f354ff6Timo Sirainen
d6a7cb184cc882a90aa3d9312082e0029f354ff6Timo Sirainen return p->v.get_physical_size(mail, size_r);
d6a7cb184cc882a90aa3d9312082e0029f354ff6Timo Sirainen}
d6a7cb184cc882a90aa3d9312082e0029f354ff6Timo Sirainen
d6a7cb184cc882a90aa3d9312082e0029f354ff6Timo Sirainenint mail_get_first_header(struct mail *mail, const char *field,
d6a7cb184cc882a90aa3d9312082e0029f354ff6Timo Sirainen const char **value_r)
d6a7cb184cc882a90aa3d9312082e0029f354ff6Timo Sirainen{
d6a7cb184cc882a90aa3d9312082e0029f354ff6Timo Sirainen struct mail_private *p = (struct mail_private *)mail;
d6a7cb184cc882a90aa3d9312082e0029f354ff6Timo Sirainen
d6a7cb184cc882a90aa3d9312082e0029f354ff6Timo Sirainen return p->v.get_first_header(mail, field, FALSE, value_r);
d6a7cb184cc882a90aa3d9312082e0029f354ff6Timo Sirainen}
d6a7cb184cc882a90aa3d9312082e0029f354ff6Timo Sirainen
d6a7cb184cc882a90aa3d9312082e0029f354ff6Timo Sirainenint mail_get_first_header_utf8(struct mail *mail, const char *field,
d6a7cb184cc882a90aa3d9312082e0029f354ff6Timo Sirainen const char **value_r)
d6a7cb184cc882a90aa3d9312082e0029f354ff6Timo Sirainen{
f5e8a76a128d4e92f0641135183c164fd5c5ce5eTimo Sirainen struct mail_private *p = (struct mail_private *)mail;
f5e8a76a128d4e92f0641135183c164fd5c5ce5eTimo Sirainen
f5e8a76a128d4e92f0641135183c164fd5c5ce5eTimo Sirainen return p->v.get_first_header(mail, field, TRUE, value_r);
f5e8a76a128d4e92f0641135183c164fd5c5ce5eTimo Sirainen}
f5e8a76a128d4e92f0641135183c164fd5c5ce5eTimo Sirainen
f5e8a76a128d4e92f0641135183c164fd5c5ce5eTimo Sirainenint mail_get_headers(struct mail *mail, const char *field,
f5e8a76a128d4e92f0641135183c164fd5c5ce5eTimo Sirainen const char *const **value_r)
f5e8a76a128d4e92f0641135183c164fd5c5ce5eTimo Sirainen{
f5e8a76a128d4e92f0641135183c164fd5c5ce5eTimo Sirainen struct mail_private *p = (struct mail_private *)mail;
f5e8a76a128d4e92f0641135183c164fd5c5ce5eTimo Sirainen
f5e8a76a128d4e92f0641135183c164fd5c5ce5eTimo Sirainen return p->v.get_headers(mail, field, FALSE, value_r);
cc935aff970ed6c24d136cc560c7e705a49d536cTimo Sirainen}
cc935aff970ed6c24d136cc560c7e705a49d536cTimo Sirainen
cc935aff970ed6c24d136cc560c7e705a49d536cTimo Sirainenint mail_get_headers_utf8(struct mail *mail, const char *field,
92f9871ac981201fe0a47f6c909f790cce14b240Timo Sirainen const char *const **value_r)
92f9871ac981201fe0a47f6c909f790cce14b240Timo Sirainen{
cc935aff970ed6c24d136cc560c7e705a49d536cTimo Sirainen struct mail_private *p = (struct mail_private *)mail;
cc935aff970ed6c24d136cc560c7e705a49d536cTimo Sirainen
cc935aff970ed6c24d136cc560c7e705a49d536cTimo Sirainen return p->v.get_headers(mail, field, TRUE, value_r);
92f9871ac981201fe0a47f6c909f790cce14b240Timo Sirainen}
92f9871ac981201fe0a47f6c909f790cce14b240Timo Sirainen
cc935aff970ed6c24d136cc560c7e705a49d536cTimo Sirainenint mail_get_header_stream(struct mail *mail,
cc935aff970ed6c24d136cc560c7e705a49d536cTimo Sirainen struct mailbox_header_lookup_ctx *headers,
cc935aff970ed6c24d136cc560c7e705a49d536cTimo Sirainen struct istream **stream_r)
cc935aff970ed6c24d136cc560c7e705a49d536cTimo Sirainen{
cc935aff970ed6c24d136cc560c7e705a49d536cTimo Sirainen struct mail_private *p = (struct mail_private *)mail;
cc935aff970ed6c24d136cc560c7e705a49d536cTimo Sirainen
92f9871ac981201fe0a47f6c909f790cce14b240Timo Sirainen return p->v.get_header_stream(mail, headers, stream_r);
92f9871ac981201fe0a47f6c909f790cce14b240Timo Sirainen}
92f9871ac981201fe0a47f6c909f790cce14b240Timo Sirainen
92f9871ac981201fe0a47f6c909f790cce14b240Timo Sirainenint mail_get_stream(struct mail *mail, struct message_size *hdr_size,
cc935aff970ed6c24d136cc560c7e705a49d536cTimo Sirainen struct message_size *body_size, struct istream **stream_r)
92f9871ac981201fe0a47f6c909f790cce14b240Timo Sirainen{
92f9871ac981201fe0a47f6c909f790cce14b240Timo Sirainen struct mail_private *p = (struct mail_private *)mail;
cc935aff970ed6c24d136cc560c7e705a49d536cTimo Sirainen
cc935aff970ed6c24d136cc560c7e705a49d536cTimo Sirainen return p->v.get_stream(mail, hdr_size, body_size, stream_r);
cc935aff970ed6c24d136cc560c7e705a49d536cTimo Sirainen}
27e859cee42654bff801ba96677cfc4e4e0108c7Timo Sirainen
279c6b6d0b0a159c8533102e7e914db21dadcb03Timo Sirainenint mail_get_special(struct mail *mail, enum mail_fetch_field field,
279c6b6d0b0a159c8533102e7e914db21dadcb03Timo Sirainen const char **value_r)
279c6b6d0b0a159c8533102e7e914db21dadcb03Timo Sirainen{
279c6b6d0b0a159c8533102e7e914db21dadcb03Timo Sirainen struct mail_private *p = (struct mail_private *)mail;
279c6b6d0b0a159c8533102e7e914db21dadcb03Timo Sirainen
279c6b6d0b0a159c8533102e7e914db21dadcb03Timo Sirainen return p->v.get_special(mail, field, value_r);
279c6b6d0b0a159c8533102e7e914db21dadcb03Timo Sirainen}
279c6b6d0b0a159c8533102e7e914db21dadcb03Timo Sirainen
279c6b6d0b0a159c8533102e7e914db21dadcb03Timo Sirainenvoid mail_update_flags(struct mail *mail, enum modify_type modify_type,
279c6b6d0b0a159c8533102e7e914db21dadcb03Timo Sirainen enum mail_flags flags)
387f9e3b4120273ad0213206a0e9cc2dc0e62ccaTimo Sirainen{
27e859cee42654bff801ba96677cfc4e4e0108c7Timo Sirainen struct mail_private *p = (struct mail_private *)mail;
27e859cee42654bff801ba96677cfc4e4e0108c7Timo Sirainen
27e859cee42654bff801ba96677cfc4e4e0108c7Timo Sirainen p->v.update_flags(mail, modify_type, flags);
27e859cee42654bff801ba96677cfc4e4e0108c7Timo Sirainen}
071543cc13df9600d2e97aa35f28907be5a79477Timo Sirainen
27e859cee42654bff801ba96677cfc4e4e0108c7Timo Sirainenvoid mail_update_keywords(struct mail *mail, enum modify_type modify_type,
632018810af689442569cbb0139c55868923ccfeTimo Sirainen struct mail_keywords *keywords)
387f9e3b4120273ad0213206a0e9cc2dc0e62ccaTimo Sirainen{
632018810af689442569cbb0139c55868923ccfeTimo Sirainen struct mail_private *p = (struct mail_private *)mail;
632018810af689442569cbb0139c55868923ccfeTimo Sirainen
632018810af689442569cbb0139c55868923ccfeTimo Sirainen p->v.update_keywords(mail, modify_type, keywords);
632018810af689442569cbb0139c55868923ccfeTimo Sirainen}
632018810af689442569cbb0139c55868923ccfeTimo Sirainen
632018810af689442569cbb0139c55868923ccfeTimo Sirainenvoid mail_expunge(struct mail *mail)
632018810af689442569cbb0139c55868923ccfeTimo Sirainen{
632018810af689442569cbb0139c55868923ccfeTimo Sirainen struct mail_private *p = (struct mail_private *)mail;
632018810af689442569cbb0139c55868923ccfeTimo Sirainen
387f9e3b4120273ad0213206a0e9cc2dc0e62ccaTimo Sirainen p->v.expunge(mail);
632018810af689442569cbb0139c55868923ccfeTimo Sirainen}
632018810af689442569cbb0139c55868923ccfeTimo Sirainen
632018810af689442569cbb0139c55868923ccfeTimo Sirainenvoid mail_set_expunged(struct mail *mail)
632018810af689442569cbb0139c55868923ccfeTimo Sirainen{
8d3af185ae454653fad60e41c5f36edb1d45c868Timo Sirainen mail_storage_set_error(mail->box->storage, MAIL_ERROR_EXPUNGED,
8d3af185ae454653fad60e41c5f36edb1d45c868Timo Sirainen "Message was expunged");
8d3af185ae454653fad60e41c5f36edb1d45c868Timo Sirainen mail->expunged = TRUE;
8d3af185ae454653fad60e41c5f36edb1d45c868Timo Sirainen}
8d3af185ae454653fad60e41c5f36edb1d45c868Timo Sirainen
8d3af185ae454653fad60e41c5f36edb1d45c868Timo Sirainenvoid mail_set_cache_corrupted(struct mail *mail, enum mail_fetch_field field)
8d3af185ae454653fad60e41c5f36edb1d45c868Timo Sirainen{
8d3af185ae454653fad60e41c5f36edb1d45c868Timo Sirainen struct mail_private *p = (struct mail_private *)mail;
8d3af185ae454653fad60e41c5f36edb1d45c868Timo Sirainen
dea8bfa31729dbdde1b12718f1ef98fac4e99db9Timo Sirainen p->v.set_cache_corrupted(mail, field);
dea8bfa31729dbdde1b12718f1ef98fac4e99db9Timo Sirainen}
dea8bfa31729dbdde1b12718f1ef98fac4e99db9Timo Sirainen
dea8bfa31729dbdde1b12718f1ef98fac4e99db9Timo Sirainenconst char *mail_generate_guid_string(void)
dea8bfa31729dbdde1b12718f1ef98fac4e99db9Timo Sirainen{
dea8bfa31729dbdde1b12718f1ef98fac4e99db9Timo Sirainen static struct timespec ts = { 0, 0 };
dea8bfa31729dbdde1b12718f1ef98fac4e99db9Timo Sirainen static unsigned int pid = 0;
dea8bfa31729dbdde1b12718f1ef98fac4e99db9Timo Sirainen
dea8bfa31729dbdde1b12718f1ef98fac4e99db9Timo Sirainen /* we'll use the current time in nanoseconds as the initial 64bit
dea8bfa31729dbdde1b12718f1ef98fac4e99db9Timo Sirainen counter. */
dea8bfa31729dbdde1b12718f1ef98fac4e99db9Timo Sirainen if (ts.tv_sec == 0) {
dea8bfa31729dbdde1b12718f1ef98fac4e99db9Timo Sirainen if (clock_gettime(CLOCK_REALTIME, &ts) < 0)
dea8bfa31729dbdde1b12718f1ef98fac4e99db9Timo Sirainen i_fatal("clock_gettime() failed: %m");
dea8bfa31729dbdde1b12718f1ef98fac4e99db9Timo Sirainen pid = getpid();
dea8bfa31729dbdde1b12718f1ef98fac4e99db9Timo Sirainen } else if ((uint32_t)ts.tv_nsec < (uint32_t)-1) {
dea8bfa31729dbdde1b12718f1ef98fac4e99db9Timo Sirainen ts.tv_nsec++;
f8740ac53310cd28ba4ec6dc9e9ce6e9a3688f39Timo Sirainen } else {
f8740ac53310cd28ba4ec6dc9e9ce6e9a3688f39Timo Sirainen ts.tv_sec++;
f8740ac53310cd28ba4ec6dc9e9ce6e9a3688f39Timo Sirainen ts.tv_nsec = 0;
f8740ac53310cd28ba4ec6dc9e9ce6e9a3688f39Timo Sirainen }
f8740ac53310cd28ba4ec6dc9e9ce6e9a3688f39Timo Sirainen return t_strdup_printf("%04x%04lx%04x%s",
f8740ac53310cd28ba4ec6dc9e9ce6e9a3688f39Timo Sirainen (unsigned int)ts.tv_nsec,
f8740ac53310cd28ba4ec6dc9e9ce6e9a3688f39Timo Sirainen (unsigned long)ts.tv_sec,
f8740ac53310cd28ba4ec6dc9e9ce6e9a3688f39Timo Sirainen pid, my_hostname);
f8740ac53310cd28ba4ec6dc9e9ce6e9a3688f39Timo Sirainen}
f8740ac53310cd28ba4ec6dc9e9ce6e9a3688f39Timo Sirainen
f8740ac53310cd28ba4ec6dc9e9ce6e9a3688f39Timo Sirainenvoid mail_generate_guid_128(uint8_t guid[16])
f8740ac53310cd28ba4ec6dc9e9ce6e9a3688f39Timo Sirainen{
f8740ac53310cd28ba4ec6dc9e9ce6e9a3688f39Timo Sirainen static struct timespec ts = { 0, 0 };
f8740ac53310cd28ba4ec6dc9e9ce6e9a3688f39Timo Sirainen static uint8_t guid_static[8];
f8740ac53310cd28ba4ec6dc9e9ce6e9a3688f39Timo Sirainen uint32_t pid, host_crc;
f8740ac53310cd28ba4ec6dc9e9ce6e9a3688f39Timo Sirainen
f8740ac53310cd28ba4ec6dc9e9ce6e9a3688f39Timo Sirainen /* we'll use the current time in nanoseconds as the initial 64bit
f8740ac53310cd28ba4ec6dc9e9ce6e9a3688f39Timo Sirainen counter. */
f8740ac53310cd28ba4ec6dc9e9ce6e9a3688f39Timo Sirainen if (ts.tv_sec == 0) {
f8740ac53310cd28ba4ec6dc9e9ce6e9a3688f39Timo Sirainen if (clock_gettime(CLOCK_REALTIME, &ts) < 0)
fccd110b494a7e31f23d31d9e3bc3e986c9bb1a8Timo Sirainen i_fatal("clock_gettime() failed: %m");
fccd110b494a7e31f23d31d9e3bc3e986c9bb1a8Timo Sirainen pid = getpid();
fccd110b494a7e31f23d31d9e3bc3e986c9bb1a8Timo Sirainen host_crc = crc32_str(my_hostname);
f8740ac53310cd28ba4ec6dc9e9ce6e9a3688f39Timo Sirainen
f8740ac53310cd28ba4ec6dc9e9ce6e9a3688f39Timo Sirainen guid_static[0] = (pid & 0x000000ff);
f8740ac53310cd28ba4ec6dc9e9ce6e9a3688f39Timo Sirainen guid_static[1] = (pid & 0x0000ff00) >> 8;
f8740ac53310cd28ba4ec6dc9e9ce6e9a3688f39Timo Sirainen guid_static[2] = (pid & 0x00ff0000) >> 16;
f8740ac53310cd28ba4ec6dc9e9ce6e9a3688f39Timo Sirainen guid_static[3] = (pid & 0xff000000) >> 24;
fccd110b494a7e31f23d31d9e3bc3e986c9bb1a8Timo Sirainen guid_static[4] = (host_crc & 0x000000ff);
f8740ac53310cd28ba4ec6dc9e9ce6e9a3688f39Timo Sirainen guid_static[5] = (host_crc & 0x0000ff00) >> 8;
f8740ac53310cd28ba4ec6dc9e9ce6e9a3688f39Timo Sirainen guid_static[6] = (host_crc & 0x00ff0000) >> 16;
fccd110b494a7e31f23d31d9e3bc3e986c9bb1a8Timo Sirainen guid_static[7] = (host_crc & 0xff000000) >> 24;
f8740ac53310cd28ba4ec6dc9e9ce6e9a3688f39Timo Sirainen } else if ((uint32_t)ts.tv_nsec < (uint32_t)-1) {
f8740ac53310cd28ba4ec6dc9e9ce6e9a3688f39Timo Sirainen ts.tv_nsec++;
f8740ac53310cd28ba4ec6dc9e9ce6e9a3688f39Timo Sirainen } else {
f8740ac53310cd28ba4ec6dc9e9ce6e9a3688f39Timo Sirainen ts.tv_sec++;
f8740ac53310cd28ba4ec6dc9e9ce6e9a3688f39Timo Sirainen ts.tv_nsec = 0;
f8740ac53310cd28ba4ec6dc9e9ce6e9a3688f39Timo Sirainen }
f8740ac53310cd28ba4ec6dc9e9ce6e9a3688f39Timo Sirainen
fccd110b494a7e31f23d31d9e3bc3e986c9bb1a8Timo Sirainen guid[0] = (ts.tv_nsec & 0x000000ff);
f8740ac53310cd28ba4ec6dc9e9ce6e9a3688f39Timo Sirainen guid[1] = (ts.tv_nsec & 0x0000ff00) >> 8;
f8740ac53310cd28ba4ec6dc9e9ce6e9a3688f39Timo Sirainen guid[2] = (ts.tv_nsec & 0x00ff0000) >> 16;
f8740ac53310cd28ba4ec6dc9e9ce6e9a3688f39Timo Sirainen guid[3] = (ts.tv_nsec & 0xff000000) >> 24;
6de0cbb4a498ce0519b0f28e221164ce8d39736aTimo Sirainen guid[4] = (ts.tv_sec & 0x000000ff);
6de0cbb4a498ce0519b0f28e221164ce8d39736aTimo Sirainen guid[5] = (ts.tv_sec & 0x0000ff00) >> 8;
6de0cbb4a498ce0519b0f28e221164ce8d39736aTimo Sirainen guid[6] = (ts.tv_sec & 0x00ff0000) >> 16;
6de0cbb4a498ce0519b0f28e221164ce8d39736aTimo Sirainen guid[7] = (ts.tv_sec & 0xff000000) >> 24;
6de0cbb4a498ce0519b0f28e221164ce8d39736aTimo Sirainen memcpy(guid + 8, guid_static, 8);
6de0cbb4a498ce0519b0f28e221164ce8d39736aTimo Sirainen}
6de0cbb4a498ce0519b0f28e221164ce8d39736aTimo Sirainen