Skip to content

Commit

Permalink
mailbox.c: store INTERNALDATE as nanoseconds since epoch
Browse files Browse the repository at this point in the history
  • Loading branch information
ksmurchison committed Jan 15, 2025
1 parent e162801 commit 5d8190f
Show file tree
Hide file tree
Showing 23 changed files with 202 additions and 114 deletions.
8 changes: 5 additions & 3 deletions cunit/annotate.testc
Original file line number Diff line number Diff line change
Expand Up @@ -2002,12 +2002,14 @@ static int create_messages(struct mailbox *mailbox, int count)
struct appendstate as;
quota_t qdiffs[QUOTA_NUMRESOURCES] = QUOTA_DIFFS_DONTCARE_INITIALIZER;
FILE *fp;
time_t internaldate = time(NULL);
struct timespec internaldate;
struct body *body = NULL;
struct buf buf = BUF_INITIALIZER;

clock_gettime(CLOCK_REALTIME, &internaldate);

/* Write the message to the filesystem */
if (!(fp = append_newstage(mailbox_name(mailbox), internaldate, 0, &stage))) {
if (!(fp = append_newstage(mailbox_name(mailbox), internaldate.tv_sec, 0, &stage))) {
fprintf(stderr, "append_newstage(%s) failed", mailbox_name(mailbox));
return IMAP_IOERROR;
}
Expand All @@ -2028,7 +2030,7 @@ static int create_messages(struct mailbox *mailbox, int count)
strerror(errno));
return r;
}
r = append_fromstage(&as, &body, stage, internaldate, 0, NULL, 0, NULL);
r = append_fromstage(&as, &body, stage, &internaldate, 0, NULL, 0, NULL);
if (r) {
fprintf(stderr, "append_fromstage(%s) failed: %s", mailbox_name(mailbox),
error_message(r));
Expand Down
22 changes: 15 additions & 7 deletions imap/append.c
Original file line number Diff line number Diff line change
Expand Up @@ -935,7 +935,7 @@ static int findstage_cb(const conv_guidrec_t *rec, void *vrock)
*/
EXPORTED int append_fromstage_full(struct appendstate *as, struct body **body,
struct stagemsg *stage,
time_t internaldate, time_t savedate,
struct timespec *internaldate, time_t savedate,
modseq_t createdmodseq,
const strarray_t *flags, int nolink,
struct entryattlist **user_annotsp)
Expand Down Expand Up @@ -1057,8 +1057,6 @@ EXPORTED int append_fromstage_full(struct appendstate *as, struct body **body,
msgrec = msgrecord_new(mailbox);
r = msgrecord_set_uid(msgrec, uid);
if (r) goto out;
r = msgrecord_set_internaldate(msgrec, internaldate);
if (r) goto out;
r = msgrecord_set_createdmodseq(msgrec, createdmodseq);
if (r) goto out;
r = msgrecord_set_bodystructure(msgrec, *body);
Expand All @@ -1069,9 +1067,12 @@ EXPORTED int append_fromstage_full(struct appendstate *as, struct body **body,
}

/* And make sure it has a timestamp */
r = msgrecord_get_internaldate(msgrec, &internaldate);
if (!r && !internaldate)
r = msgrecord_set_internaldate(msgrec, time(NULL));
struct timespec now;
if (!internaldate) {
clock_gettime(CLOCK_REALTIME, &now);
internaldate = &now;
}
r = msgrecord_set_internaldate(msgrec, internaldate);
if (r) goto out;

/* should we archive it straight away? */
Expand Down Expand Up @@ -1252,7 +1253,7 @@ EXPORTED int append_removestage(struct stagemsg *stage)
EXPORTED int append_fromstream(struct appendstate *as, struct body **body,
struct protstream *messagefile,
unsigned long size,
time_t internaldate,
struct timespec *internaldate,
const strarray_t *flags)
{
struct mailbox *mailbox = as->mailbox;
Expand All @@ -1268,6 +1269,13 @@ EXPORTED int append_fromstream(struct appendstate *as, struct body **body,
msgrec = msgrecord_new(mailbox);
r = msgrecord_set_uid(msgrec, as->baseuid + as->nummsg);
if (r) goto out;

/* And make sure it has a timestamp */
struct timespec now;
if (!internaldate) {
clock_gettime(CLOCK_REALTIME, &now);
internaldate = &now;
}
r = msgrecord_set_internaldate(msgrec, internaldate);
if (r) goto out;

Expand Down
4 changes: 2 additions & 2 deletions imap/append.h
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ extern FILE *append_newstage_full(const char *mailboxname, time_t internaldate,
/* adds a new mailbox to the stage initially created by append_newstage() */
extern int append_fromstage_full(struct appendstate *mailbox, struct body **body,
struct stagemsg *stage,
time_t internaldate, time_t savedate,
struct timespec *internaldate, time_t savedate,
modseq_t createdmodseq,
const strarray_t *flags, int nolink,
struct entryattlist **annotations);
Expand All @@ -133,7 +133,7 @@ extern int append_removestage(struct stagemsg *stage);

extern int append_fromstream(struct appendstate *as, struct body **body,
struct protstream *messagefile,
unsigned long size, time_t internaldate,
unsigned long size, struct timespec *internaldate,
const strarray_t *flags);

extern int append_copy(struct mailbox *mailbox,
Expand Down
2 changes: 1 addition & 1 deletion imap/caldav_alarm.c
Original file line number Diff line number Diff line change
Expand Up @@ -1521,7 +1521,7 @@ static int move_to_mailboxid(struct mailbox *srcmbox,
if (r) goto done;

/* Append the message to the mailbox */
r = append_fromstage_full(&as, &body, stage, record->internaldate.tv_sec,
r = append_fromstage_full(&as, &body, stage, &record->internaldate,
savedate, 0, flags, 0, &annots);
if (r) {
append_abort(&as);
Expand Down
10 changes: 6 additions & 4 deletions imap/carddav_db.c
Original file line number Diff line number Diff line change
Expand Up @@ -1210,7 +1210,7 @@ static int _carddav_store(struct mailbox *mailbox, struct buf *vcard,
char *header;
quota_t qdiffs[QUOTA_NUMRESOURCES] = QUOTA_DIFFS_DONTCARE_INITIALIZER;
struct appendstate as;
time_t now = time(0);
struct timespec now;
char *freeme = NULL;
char datestr[80];
static int64_t vcard_max_size = -1;
Expand All @@ -1223,8 +1223,10 @@ static int _carddav_store(struct mailbox *mailbox, struct buf *vcard,

init_internal();

clock_gettime(CLOCK_REALTIME, &now);

/* Prepare to stage the message */
if (!(f = append_newstage(mailbox_name(mailbox), now, 0, &stage))) {
if (!(f = append_newstage(mailbox_name(mailbox), now.tv_sec, 0, &stage))) {
syslog(LOG_ERR, "append_newstage(%s) failed", mailbox_name(mailbox));
return -1;
}
Expand All @@ -1243,7 +1245,7 @@ static int _carddav_store(struct mailbox *mailbox, struct buf *vcard,
if (!resource) resource = freeme = strconcat(uid, ".vcf", (char *)NULL);
mbuserid = mboxname_to_userid(mailbox_name(mailbox));

time_to_rfc5322(now, datestr, sizeof(datestr));
time_to_rfc5322(now.tv_sec, datestr, sizeof(datestr));

/* XXX This needs to be done via an LDAP/DB lookup */
header = charset_encode_mimeheader(mbuserid, 0, 0);
Expand Down Expand Up @@ -1299,7 +1301,7 @@ static int _carddav_store(struct mailbox *mailbox, struct buf *vcard,

struct body *body = NULL;

r = append_fromstage(&as, &body, stage, now, createdmodseq, flags, 0, annots);
r = append_fromstage(&as, &body, stage, &now, createdmodseq, flags, 0, annots);
if (body) {
message_free_body(body);
free(body);
Expand Down
8 changes: 4 additions & 4 deletions imap/cyr_virusscan.c
Original file line number Diff line number Diff line change
Expand Up @@ -717,7 +717,7 @@ static void append_notifications(const struct buf *template)
if (i_mbox->msgs) {
FILE *f = NULL;
struct infected_msg *msg;
time_t t;
struct timespec now;
struct protstream *pout;
struct appendstate as;
struct body *body = NULL;
Expand All @@ -739,8 +739,8 @@ static void append_notifications(const struct buf *template)
goto user_done;
}

t = time(NULL);
put_notification_headers(f, outgoing_count++, t, owner);
clock_gettime(CLOCK_REALTIME, &now);
put_notification_headers(f, outgoing_count++, now.tv_sec, owner);

first = 1;
while ((msg = i_mbox->msgs)) {
Expand Down Expand Up @@ -804,7 +804,7 @@ static void append_notifications(const struct buf *template)
if (!r) {
pout = prot_new(fd, 0);
prot_rewind(pout);
r = append_fromstream(&as, &body, pout, msgsize, t, NULL);
r = append_fromstream(&as, &body, pout, msgsize, &now, NULL);
/* n.b. append_fromstream calls append_abort itself if it fails */
if (!r) r = append_commit(&as);

Expand Down
2 changes: 1 addition & 1 deletion imap/dav_util.c
Original file line number Diff line number Diff line change
Expand Up @@ -257,7 +257,7 @@ EXPORTED int dav_store_resource(struct transaction_t *txn,
}

/* Append the message to the mailbox */
if ((r = append_fromstage(&as, &body, stage, now,
if ((r = append_fromstage(&as, &body, stage, NULL,
createdmodseq, flaglist, 0, &annots))) {
syslog(LOG_ERR, "append_fromstage(%s) failed: %s",
mailbox_name(mailbox), error_message(r));
Expand Down
12 changes: 7 additions & 5 deletions imap/http_jmap.c
Original file line number Diff line number Diff line change
Expand Up @@ -1025,7 +1025,7 @@ static int jmap_upload(struct transaction_t *txn)
struct stagemsg *stage = NULL;
FILE *f = NULL;
const char **hdr;
time_t now = time(NULL);
struct timespec now;
struct appendstate as;
char *accountid = NULL;
char *normalisedtype = NULL;
Expand Down Expand Up @@ -1079,8 +1079,10 @@ static int jmap_upload(struct transaction_t *txn)
goto done;
}

clock_gettime(CLOCK_REALTIME, &now);

/* Prepare to stage the message */
if (!(f = append_newstage(mailbox_name(mailbox), now, 0, &stage))) {
if (!(f = append_newstage(mailbox_name(mailbox), now.tv_sec, 0, &stage))) {
syslog(LOG_ERR, "append_newstage(%s) failed", mailbox_name(mailbox));
txn->error.desc = "append_newstage() failed";
ret = HTTP_SERVER_ERROR;
Expand Down Expand Up @@ -1156,7 +1158,7 @@ static int jmap_upload(struct transaction_t *txn)
}
else {
char datestr[80];
time_to_rfc5322(now, datestr, sizeof(datestr));
time_to_rfc5322(now.tv_sec, datestr, sizeof(datestr));
fprintf(f, "Date: %s\r\n", datestr);
}

Expand Down Expand Up @@ -1203,7 +1205,7 @@ static int jmap_upload(struct transaction_t *txn)
/* Append the message to the mailbox */
strarray_append(&flags, "\\Deleted");
strarray_append(&flags, "\\Expunged"); // custom flag to insta-expunge!
r = append_fromstage(&as, &body, stage, now, 0, &flags, 0, /*annots*/NULL);
r = append_fromstage(&as, &body, stage, &now, 0, &flags, 0, /*annots*/NULL);

if (r) {
append_abort(&as);
Expand Down Expand Up @@ -1231,7 +1233,7 @@ static int jmap_upload(struct transaction_t *txn)
}

char datestr[RFC3339_DATETIME_MAX];
time_to_rfc3339(now + 86400, datestr, RFC3339_DATETIME_MAX);
time_to_rfc3339(now.tv_sec + 86400, datestr, RFC3339_DATETIME_MAX);

char blob_id[JMAP_BLOBID_SIZE];
jmap_set_blobid(rawmessage ? &body->guid : &body->content_guid, blob_id);
Expand Down
9 changes: 6 additions & 3 deletions imap/imapd.c
Original file line number Diff line number Diff line change
Expand Up @@ -254,7 +254,7 @@ struct appendstage {
struct stagemsg *stage;
FILE *f;
strarray_t flags;
time_t internaldate;
struct timespec internaldate;
int binary;
struct entryattlist *annotations;
};
Expand Down Expand Up @@ -4310,6 +4310,9 @@ static int cmd_append(char *tag, char *name, const char *cur_name, int isreplace
curstage = xzmalloc(sizeof(*curstage));
ptrarray_push(&stages, curstage);

/* Initialize the internaldate to "now" */
clock_gettime(CLOCK_REALTIME, &curstage->internaldate);

/* Set limit on the total number of bytes allowed for mailbox+append-opts */
maxargssize_mark = prot_bytes_in(imapd_in) + (maxargssize - strlen(name));

Expand Down Expand Up @@ -4349,7 +4352,7 @@ static int cmd_append(char *tag, char *name, const char *cur_name, int isreplace
/* Parse internaldate */
if (c == '\"' && !arg.s[0]) {
prot_ungetc(c, imapd_in);
c = getdatetime(&(curstage->internaldate));
c = getdatetime(&(curstage->internaldate.tv_sec));
if (c != ' ') {
parseerr = "Invalid date-time in Append command";
r = IMAP_PROTOCOL_ERROR;
Expand Down Expand Up @@ -4517,7 +4520,7 @@ static int cmd_append(char *tag, char *name, const char *cur_name, int isreplace
}
if (!r) {
r = append_fromstage(&appendstate, &body, curstage->stage,
curstage->internaldate, /*createdmodseq*/0,
&curstage->internaldate, /*createdmodseq*/0,
&curstage->flags, 0,
&curstage->annotations);
}
Expand Down
3 changes: 2 additions & 1 deletion imap/jmap_backup.c
Original file line number Diff line number Diff line change
Expand Up @@ -562,7 +562,8 @@ static int recreate_resource(message_t *msg, struct mailbox *tomailbox,
strarray_add(flags, "$restored");

/* append the message to the mailbox. */
r = append_fromstage(&as, &body, stage, record->internaldate.tv_sec,
r = append_fromstage(&as, &body, stage,
(struct timespec *) &record->internaldate,
is_update ? record->createdmodseq : 0,
flags, /*nolink*/0, &annots);

Expand Down
Loading

0 comments on commit 5d8190f

Please sign in to comment.