static int mailbox_cacherecord_internal(struct mailbox *mailbox,
                                        const struct index_record *record,
                                        enum mbcache_rewrite_t rewrite)
{
    struct mappedfile *cachefile;
    bit32 crc = 0;
    int r = IMAP_IOERROR;

    /* we do something nasty here to work around lazy loading while still
     * giving const protection to records which are only used for read */
    struct index_record *backdoor = (struct index_record *)record;

    /* do we already have a record loaded? */
    if (record->crec.len)
        return 0;

    /* make sure there's a file to read from */
    cachefile = mailbox_cachefile(mailbox, record);
    if (!cachefile)
        goto err;

    /* do we have an offset? */
    if (!record->cache_offset)
        goto err;

    /* try to parse the cache record */
    r = cache_parserecord(cachefile, record->cache_offset, &backdoor->crec);
    if (r) goto err;

    /* old-style record */
    if (!record->cache_crc)
        goto err;

    crc = crc32_buf(cache_buf(record));
    if (crc != record->cache_crc)
        r = IMAP_MAILBOX_CHECKSUM;

    if (r) goto err;
    return 0;

err:
    if (!cachefile)
        xsyslog(LOG_ERR, "IOERROR: missing cache file",
                         "mailbox=<%s> uid=<%u>",
                         mailbox_name(mailbox), record->uid);
    else if (!record->cache_offset)
        xsyslog(LOG_ERR, "IOERROR: missing cache offset",
                         "mailbox=<%s> uid=<%u>",
                         mailbox_name(mailbox), record->uid);
    else if (r)
        xsyslog(LOG_ERR, "IOERROR invalid cache record",
                         "mailbox=<%s> uid=<%u> error=<%s> crc=<%d> cache_offset=<%llu>",
                         mailbox_name(mailbox), record->uid, error_message(r),
                         crc, (unsigned long long) record->cache_offset);

    if (rewrite == MBCACHE_NOPARSE)
        return r;

    /* parse the file again */

    /* parse directly into the cache for this record */
    const char *fname = mailbox_record_fname(mailbox, record);
    if (!fname) {
        xsyslog(LOG_ERR, "IOERROR: no spool file",
                         "mailbox=<%s> uid=<%u>",
                         mailbox_name(mailbox), record->uid);
        return IMAP_IOERROR;
    }

    /* parse into the file and zero the cache offset */
    r = message_parse(fname, backdoor);
    if (r) {
        xsyslog(LOG_ERR, "IOERROR: failed to parse message",
                         "mailbox=<%s> uid=<%u>",
                         mailbox_name(mailbox), record->uid);
        return r;
    }
    backdoor->cache_offset = 0;

    if (rewrite == MBCACHE_REWRITE) {
        r = mailbox_append_cache(mailbox, backdoor);
        if (r) {
            xsyslog(LOG_ERR, "IOERROR: failed to append cache",
                             "mailbox=<%s> uid=<%u>",
                             mailbox_name(mailbox), record->uid);
            return r;
        }
    }

    return 0;
}
static int mailbox_cacherecord_internal(struct mailbox *mailbox,
                                        const struct index_record *record,
                                        enum mbcache_rewrite_t rewrite)
{
    struct mappedfile *cachefile;
    bit32 crc = 0;
    int r = IMAP_IOERROR;

     
    struct index_record *backdoor = (struct index_record *)record;

     
    if (record->crec.len)
        return 0;

     
    cachefile = mailbox_cachefile(mailbox, record);
    if (!cachefile)
        goto err;

     
    if (!record->cache_offset)
        goto err;

     
    r = cache_parserecord(cachefile, record->cache_offset, &backdoor->crec);
    if (r) goto err;

     
    if (!record->cache_crc)
        goto err;

    crc = crc32_buf(cache_buf(record));
    if (crc != record->cache_crc)
        r = IMAP_MAILBOX_CHECKSUM;

    if (r) goto err;
    return 0;

err:
    if (!cachefile)
        xsyslog(LOG_ERR, "IOERROR: missing cache file",
                         "mailbox=<%s> uid=<%u>",
                         mailbox_name(mailbox), record->uid);
    else if (!record->cache_offset)
        xsyslog(LOG_ERR, "IOERROR: missing cache offset",
                         "mailbox=<%s> uid=<%u>",
                         mailbox_name(mailbox), record->uid);
    else if (r)
        xsyslog(LOG_ERR, "IOERROR invalid cache record",
                         "mailbox=<%s> uid=<%u> error=<%s> crc=<%d> cache_offset=<%llu>",
                         mailbox_name(mailbox), record->uid, error_message(r),
                         crc, (unsigned long long) record->cache_offset);

    if (rewrite == MBCACHE_NOPARSE)
        return r;

     

     
    const char *fname = mailbox_record_fname(mailbox, record);
    if (!fname) {
        xsyslog(LOG_ERR, "IOERROR: no spool file",
                         "mailbox=<%s> uid=<%u>",
                         mailbox_name(mailbox), record->uid);
        return IMAP_IOERROR;
    }

     
    r = message_parse(fname, backdoor);
    if (r) {
        xsyslog(LOG_ERR, "IOERROR: failed to parse message",
                         "mailbox=<%s> uid=<%u>",
                         mailbox_name(mailbox), record->uid);
        return r;
    }
    backdoor->cache_offset = 0;

    if (rewrite == MBCACHE_REWRITE) {
        r = mailbox_append_cache(mailbox, backdoor);
        if (r) {
            xsyslog(LOG_ERR, "IOERROR: failed to append cache",
                             "mailbox=<%s> uid=<%u>",
                             mailbox_name(mailbox), record->uid);
            return r;
        }
    }

    return 0;
}