EXPORTED int mailbox_commit(struct mailbox *mailbox)
{
    /* XXX - ibuf for alignment? */
    static unsigned char buf[INDEX_HEADER_SIZE];
    int n, r;

    /* try to commit sub parts first */
#ifdef WITH_DAV
    r = mailbox_commit_dav(mailbox);
    if (r) return r;
#endif

#ifdef USE_SIEVE
    r = mailbox_commit_sieve(mailbox);
    if (r) return r;
#endif

    r = mailbox_commit_cache(mailbox);
    if (r) return r;

    r = mailbox_commit_quota(mailbox);
    if (r) return r;

    r = annotate_state_commit(&mailbox->annot_state);
    if (r) return r;

    r = mailbox_commit_header(mailbox);
    if (r) return r;

    if (!mailbox->i.dirty)
        return 0;

    if (!mboxname_isdeletedmailbox(mailbox_name(mailbox), NULL)) {
        mboxname_setmodseq(mailbox_name(mailbox),
                           mailbox->i.highestmodseq,
                           mailbox_mbtype(mailbox), /*flags*/0);
    }

    assert(mailbox_index_islocked(mailbox, 1));

    r = _commit_changes(mailbox);
    if (r) return r;

    /* always update xconvmodseq, it might have been done by annotations */
    r = mailbox_update_xconvmodseq(mailbox, mailbox->i.highestmodseq, /*force*/0);
    if (r) return r;

    mailbox_index_header_to_buf(&mailbox->i, buf);

    lseek(mailbox->index_fd, 0, SEEK_SET);
    n = retry_write(mailbox->index_fd, buf, mailbox->i.start_offset);
    if (n < 0 || fsync(mailbox->index_fd)) {
        xsyslog(LOG_ERR, "IOERROR: writing index header failed",
                         "mailbox=<%s>",
                         mailbox_name(mailbox));
        return IMAP_IOERROR;
    }

    if (config_auditlog && mailbox->modseq_dirty)
        syslog(LOG_NOTICE, "auditlog: modseq sessionid=<%s> "
               "mailbox=<%s> uniqueid=<%s> highestmodseq=<" MODSEQ_FMT
               "> deletedmodseq=<" MODSEQ_FMT ">",
            session_id(), mailbox_name(mailbox), mailbox_uniqueid(mailbox),
            mailbox->i.highestmodseq, mailbox->i.deletedmodseq);

    if (mailbox->modseq_dirty) {
        struct mboxevent *mboxevent = mboxevent_new(EVENT_MAILBOX_MODSEQ);
        mboxevent_extract_mailbox(mboxevent, mailbox);
        mboxevent_set_access(mboxevent, NULL, NULL, "", mailbox_name(mailbox), 0);
        mboxevent_notify(&mboxevent);
        mboxevent_free(&mboxevent);
    }

    /* remove all dirty flags! */
    mailbox->i.dirty = 0;
    mailbox->modseq_dirty = 0;
    mailbox->header_dirty = 0;

    /* label changes for later logging */
    mailbox->has_changed = 1;

    return 0;
}
EXPORTED int mailbox_commit(struct mailbox *mailbox)
{
     
    static unsigned char buf[INDEX_HEADER_SIZE];
    int n, r;

     
#ifdef WITH_DAV
    r = mailbox_commit_dav(mailbox);
    if (r) return r;
#endif

#ifdef USE_SIEVE
    r = mailbox_commit_sieve(mailbox);
    if (r) return r;
#endif

    r = mailbox_commit_cache(mailbox);
    if (r) return r;

    r = mailbox_commit_quota(mailbox);
    if (r) return r;

    r = annotate_state_commit(&mailbox->annot_state);
    if (r) return r;

    r = mailbox_commit_header(mailbox);
    if (r) return r;

    if (!mailbox->i.dirty)
        return 0;

    if (!mboxname_isdeletedmailbox(mailbox_name(mailbox), NULL)) {
        mboxname_setmodseq(mailbox_name(mailbox),
                           mailbox->i.highestmodseq,
                           mailbox_mbtype(mailbox),  0);
    }

    assert(mailbox_index_islocked(mailbox, 1));

    r = _commit_changes(mailbox);
    if (r) return r;

     
    r = mailbox_update_xconvmodseq(mailbox, mailbox->i.highestmodseq,  0);
    if (r) return r;

    mailbox_index_header_to_buf(&mailbox->i, buf);

    lseek(mailbox->index_fd, 0, SEEK_SET);
    n = retry_write(mailbox->index_fd, buf, mailbox->i.start_offset);
    if (n < 0 || fsync(mailbox->index_fd)) {
        xsyslog(LOG_ERR, "IOERROR: writing index header failed",
                         "mailbox=<%s>",
                         mailbox_name(mailbox));
        return IMAP_IOERROR;
    }

    if (config_auditlog && mailbox->modseq_dirty)
        syslog(LOG_NOTICE, "auditlog: modseq sessionid=<%s> "
               "mailbox=<%s> uniqueid=<%s> highestmodseq=<" MODSEQ_FMT
               "> deletedmodseq=<" MODSEQ_FMT ">",
            session_id(), mailbox_name(mailbox), mailbox_uniqueid(mailbox),
            mailbox->i.highestmodseq, mailbox->i.deletedmodseq);

    if (mailbox->modseq_dirty) {
        struct mboxevent *mboxevent = mboxevent_new(EVENT_MAILBOX_MODSEQ);
        mboxevent_extract_mailbox(mboxevent, mailbox);
        mboxevent_set_access(mboxevent, NULL, NULL, "", mailbox_name(mailbox), 0);
        mboxevent_notify(&mboxevent);
        mboxevent_free(&mboxevent);
    }

     
    mailbox->i.dirty = 0;
    mailbox->modseq_dirty = 0;
    mailbox->header_dirty = 0;

     
    mailbox->has_changed = 1;

    return 0;
}