static int mailbox_reconstruct_append(struct mailbox *mailbox, uint32_t uid, int isarchive,
                                      int has_snoozedannot, int flags)
{
    /* XXX - support archived */
    const char *fname;
    int r = 0;
    struct index_record record;
    struct stat sbuf;
    int make_changes = flags & RECONSTRUCT_MAKE_CHANGES;

    memset(&record, 0, sizeof(struct index_record));

    int remove_temp_spool_file = 0;
    int object_storage_enabled = 0;
#if defined ENABLE_OBJECTSTORE
    object_storage_enabled = config_getswitch(IMAPOPT_OBJECT_STORAGE_ENABLED);
#endif

    if (isarchive && !object_storage_enabled)
        fname = mailbox_archive_fname(mailbox, uid);
    else
        fname = mailbox_spool_fname(mailbox, uid);

#if defined ENABLE_OBJECTSTORE
    if (object_storage_enabled)
    {
        uint32_t i , count = 0;
        struct message *list = get_list_of_message (mailbox, &count);
        for (i = 0; i < count; i++) {
            if (uid == list[i].message_uid){

                record.uid = uid;
                record.guid = list[i].message_guid;
                remove_temp_spool_file = 1;
                r = objectstore_get(mailbox, &record, fname);
                break;
            }
        }
        discard_list();
    }
#endif

    /* possible if '0.' file exists */
    if (!uid) {
        /* filthy hack - copy the path to '1.' and replace 1 with 0 */
        char *hack;
        if (isarchive && !object_storage_enabled)
            fname = mailbox_archive_fname(mailbox, 1);
        else
            fname = mailbox_spool_fname(mailbox, 1);
        hack = (char *)fname;
        hack[strlen(fname)-2] = '0';
    }

    if (stat(fname, &sbuf) == -1) r = IMAP_MAILBOX_NONEXISTENT;
    else if (sbuf.st_size == 0) r = IMAP_MAILBOX_NONEXISTENT;

    /* no file, nothing to do! */
    if (r) {
        syslog(LOG_ERR, "%s uid %u not found", mailbox_name(mailbox), uid);
        printf("%s uid %u not found", mailbox_name(mailbox), uid);
        r = 0;

        if (make_changes)
            unlink(fname);

        goto out;
    }

    r = message_parse(fname, &record);
    if (r) goto out;

    if (isarchive)
        record.internal_flags |= FLAG_INTERNAL_ARCHIVED;

    if (has_snoozedannot)
        record.internal_flags |= FLAG_INTERNAL_SNOOZED;

    /* copy the timestamp from the file if not calculated */
    if (!record.internaldate)
        record.internaldate = sbuf.st_mtime;

    if (uid > mailbox->i.last_uid) {
        printf("%s uid %u found - adding\n", mailbox_name(mailbox), uid);
        syslog(LOG_ERR, "%s uid %u found - adding", mailbox_name(mailbox), uid);
        record.uid = uid;
    }
    else {
        char *oldfname;
        char *newfname;

        printf("%s uid %u rediscovered - appending\n", mailbox_name(mailbox), uid);
        syslog(LOG_ERR, "%s uid %u rediscovered - appending", mailbox_name(mailbox), uid);
        /* XXX - check firstexpunged? */
        record.uid = mailbox->i.last_uid + 1;

        if (!make_changes) {
            r = 0 ;
            goto out;
        }

        oldfname = xstrdup(fname);
        newfname = xstrdup(mailbox_record_fname(mailbox, &record));
        r = rename(oldfname, newfname);
        free(oldfname);
        free(newfname);
        if (r) {
            r = IMAP_IOERROR;
            goto out ;
        }
    }

    /* XXX - inform of changes */
    if (!make_changes){
        r = 0 ;
        goto out;
    }

    /* always allow reconstruct to add records, even if we'd hit GUID limits */
    record.ignorelimits = 1;

    r = mailbox_append_index_record(mailbox, &record);

    /* XXX - copy per-message annotations? */

out:
    if (remove_temp_spool_file)
        remove(fname);
    return r;
}
static int mailbox_reconstruct_append(struct mailbox *mailbox, uint32_t uid, int isarchive,
                                      int has_snoozedannot, int flags)
{
     
    const char *fname;
    int r = 0;
    struct index_record record;
    struct stat sbuf;
    int make_changes = flags & RECONSTRUCT_MAKE_CHANGES;

    memset(&record, 0, sizeof(struct index_record));

    int remove_temp_spool_file = 0;
    int object_storage_enabled = 0;
#if defined ENABLE_OBJECTSTORE
    object_storage_enabled = config_getswitch(IMAPOPT_OBJECT_STORAGE_ENABLED);
#endif

    if (isarchive && !object_storage_enabled)
        fname = mailbox_archive_fname(mailbox, uid);
    else
        fname = mailbox_spool_fname(mailbox, uid);

#if defined ENABLE_OBJECTSTORE
    if (object_storage_enabled)
    {
        uint32_t i , count = 0;
        struct message *list = get_list_of_message (mailbox, &count);
        for (i = 0; i < count; i++) {
            if (uid == list[i].message_uid){

                record.uid = uid;
                record.guid = list[i].message_guid;
                remove_temp_spool_file = 1;
                r = objectstore_get(mailbox, &record, fname);
                break;
            }
        }
        discard_list();
    }
#endif

     
    if (!uid) {
         
        char *hack;
        if (isarchive && !object_storage_enabled)
            fname = mailbox_archive_fname(mailbox, 1);
        else
            fname = mailbox_spool_fname(mailbox, 1);
        hack = (char *)fname;
        hack[strlen(fname)-2] = '0';
    }

    if (stat(fname, &sbuf) == -1) r = IMAP_MAILBOX_NONEXISTENT;
    else if (sbuf.st_size == 0) r = IMAP_MAILBOX_NONEXISTENT;

     
    if (r) {
        syslog(LOG_ERR, "%s uid %u not found", mailbox_name(mailbox), uid);
        printf("%s uid %u not found", mailbox_name(mailbox), uid);
        r = 0;

        if (make_changes)
            unlink(fname);

        goto out;
    }

    r = message_parse(fname, &record);
    if (r) goto out;

    if (isarchive)
        record.internal_flags |= FLAG_INTERNAL_ARCHIVED;

    if (has_snoozedannot)
        record.internal_flags |= FLAG_INTERNAL_SNOOZED;

     
    if (!record.internaldate)
        record.internaldate = sbuf.st_mtime;

    if (uid > mailbox->i.last_uid) {
        printf("%s uid %u found - adding\n", mailbox_name(mailbox), uid);
        syslog(LOG_ERR, "%s uid %u found - adding", mailbox_name(mailbox), uid);
        record.uid = uid;
    }
    else {
        char *oldfname;
        char *newfname;

        printf("%s uid %u rediscovered - appending\n", mailbox_name(mailbox), uid);
        syslog(LOG_ERR, "%s uid %u rediscovered - appending", mailbox_name(mailbox), uid);
         
        record.uid = mailbox->i.last_uid + 1;

        if (!make_changes) {
            r = 0 ;
            goto out;
        }

        oldfname = xstrdup(fname);
        newfname = xstrdup(mailbox_record_fname(mailbox, &record));
        r = rename(oldfname, newfname);
        free(oldfname);
        free(newfname);
        if (r) {
            r = IMAP_IOERROR;
            goto out ;
        }
    }

     
    if (!make_changes){
        r = 0 ;
        goto out;
    }

     
    record.ignorelimits = 1;

    r = mailbox_append_index_record(mailbox, &record);

     

out:
    if (remove_temp_spool_file)
        remove(fname);
    return r;
}