/*
 * Copyright (C) 2009 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#define LOG_TAG "file_backup_helper"

#include <androidfw/BackupHelpers.h>

#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/time.h>  // for utimes
#include <sys/uio.h>
#include <unistd.h>
#include <utime.h>
#include <zlib.h>

#include <log/log.h>
#include <utils/ByteOrder.h>
#include <utils/KeyedVector.h>
#include <utils/String8.h>

namespace android {

#define MAGIC0 0x70616e53 // Snap
#define MAGIC1 0x656c6946 // File

/*
 * File entity data format (v1):
 *
 *   - 4-byte version number of the metadata, little endian (0x00000001 for v1)
 *   - 12 bytes of metadata
 *   - the file data itself
 *
 * i.e. a 16-byte metadata header followed by the raw file data.  If the
 * restore code does not recognize the metadata version, it can still
 * interpret the file data itself correctly.
 *
 * file_metadata_v1:
 *
 *   - 4 byte version number === 0x00000001 (little endian)
 *   - 4-byte access mode (little-endian)
 *   - undefined (8 bytes)
 */

struct file_metadata_v1 {
    int version;
    int mode;
    int undefined_1;
    int undefined_2;
};

const static int CURRENT_METADATA_VERSION = 1;

static const bool kIsDebug = false;
#if TEST_BACKUP_HELPERS
#define LOGP(f, x...) if (kIsDebug) printf(f "\n", x)
#else
#define LOGP(x...) if (kIsDebug) ALOGD(x)
#endif

const static int ROUND_UP[4] = { 0, 3, 2, 1 };

static inline int
round_up(int n)
{
    return n + ROUND_UP[n % 4];
}

static int
read_snapshot_file(int fd, KeyedVector<String8,FileState>* snapshot)
{
    int bytesRead = 0;
    int amt;
    SnapshotHeader header;

    amt = read(fd, &header, sizeof(header));
    if (amt != sizeof(header)) {
        return errno;
    }
    bytesRead += amt;

    if (header.magic0 != MAGIC0 || header.magic1 != MAGIC1) {
        ALOGW("read_snapshot_file header.magic0=0x%08x magic1=0x%08x", header.magic0, header.magic1);
        return 1;
    }

    for (int i=0; i<header.fileCount; i++) {
        FileState file;
        char filenameBuf[128];

        amt = read(fd, &file, sizeof(FileState));
        if (amt != sizeof(FileState)) {
            ALOGW("read_snapshot_file FileState truncated/error with read at %d bytes\n", bytesRead);
            return 1;
        }
        bytesRead += amt;

        // filename is not NULL terminated, but it is padded
        int nameBufSize = round_up(file.nameLen);
        char* filename = nameBufSize <= (int)sizeof(filenameBuf)
                ? filenameBuf
                : (char*)malloc(nameBufSize);
        amt = read(fd, filename, nameBufSize);
        if (amt == nameBufSize) {
            snapshot->add(String8(filename, file.nameLen), file);
        }
        bytesRead += amt;
        if (filename != filenameBuf) {
            free(filename);
        }
        if (amt != nameBufSize) {
            ALOGW("read_snapshot_file filename truncated/error with read at %d bytes\n", bytesRead);
            return 1;
        }
    }

    if (header.totalSize != bytesRead) {
        ALOGW("read_snapshot_file length mismatch: header.totalSize=%d bytesRead=%d\n",
                header.totalSize, bytesRead);
        return 1;
    }

    return 0;
}

static int
write_snapshot_file(int fd, const KeyedVector<String8,FileRec>& snapshot)
{
    int fileCount = 0;
    int bytesWritten = sizeof(SnapshotHeader);
    // preflight size
    const int N = snapshot.size();
    for (int i=0; i<N; i++) {
        const FileRec& g = snapshot.valueAt(i);
        if (!g.deleted) {
            const String8& name = snapshot.keyAt(i);
            bytesWritten += sizeof(FileState) + round_up(name.length());
            fileCount++;
        }
    }

    LOGP("write_snapshot_file fd=%d\n", fd);

    int amt;
    SnapshotHeader header = { MAGIC0, fileCount, MAGIC1, bytesWritten };

    amt = write(fd, &header, sizeof(header));
    if (amt != sizeof(header)) {
        ALOGW("write_snapshot_file error writing header %s", strerror(errno));
        return errno;
    }

    for (int i=0; i<N; i++) {
        FileRec r = snapshot.valueAt(i);
        if (!r.deleted) {
            const String8& name = snapshot.keyAt(i);
            int nameLen = r.s.nameLen = name.length();

            amt = write(fd, &r.s, sizeof(FileState));
            if (amt != sizeof(FileState)) {
                ALOGW("write_snapshot_file error writing header %s", strerror(errno));
                return 1;
            }

            // filename is not NULL terminated, but it is padded
            amt = write(fd, name.string(), nameLen);
            if (amt != nameLen) {
                ALOGW("write_snapshot_file error writing filename %s", strerror(errno));
                return 1;
            }
            int paddingLen = ROUND_UP[nameLen % 4];
            if (paddingLen != 0) {
                int padding = 0xabababab;
                amt = write(fd, &padding, paddingLen);
                if (amt != paddingLen) {
                    ALOGW("write_snapshot_file error writing %d bytes of filename padding %s",
                            paddingLen, strerror(errno));
                    return 1;
                }
            }
        }
    }

    return 0;
}

static int
write_delete_file(BackupDataWriter* dataStream, const String8& key)
{
    LOGP("write_delete_file %s\n", key.string());
    return dataStream->WriteEntityHeader(key, -1);
}

static int
write_update_file(BackupDataWriter* dataStream, int fd, int mode, const String8& key,
        char const* realFilename)
{
    LOGP("write_update_file %s (%s) : mode 0%o\n", realFilename, key.string(), mode);

    const int bufsize = 4*1024;
    int err;
    int amt;
    int fileSize;
    int bytesLeft;
    file_metadata_v1 metadata;

    char* buf = (char*)malloc(bufsize);

    fileSize = lseek(fd, 0, SEEK_END);
    lseek(fd, 0, SEEK_SET);

    if (sizeof(metadata) != 16) {
        ALOGE("ERROR: metadata block is the wrong size!");
    }

    bytesLeft = fileSize + sizeof(metadata);
    err = dataStream->WriteEntityHeader(key, bytesLeft);
    if (err != 0) {
        free(buf);
        return err;
    }

    // store the file metadata first
    metadata.version = tolel(CURRENT_METADATA_VERSION);
    metadata.mode = tolel(mode);
    metadata.undefined_1 = metadata.undefined_2 = 0;
    err = dataStream->WriteEntityData(&metadata, sizeof(metadata));
    if (err != 0) {
        free(buf);
        return err;
    }
    bytesLeft -= sizeof(metadata); // bytesLeft should == fileSize now

    // now store the file content
    while ((amt = read(fd, buf, bufsize)) != 0 && bytesLeft > 0) {
        bytesLeft -= amt;
        if (bytesLeft < 0) {
            amt += bytesLeft; // Plus a negative is minus.  Don't write more than we promised.
        }
        err = dataStream->WriteEntityData(buf, amt);
        if (err != 0) {
            free(buf);
            return err;
        }
    }
    if (bytesLeft != 0) {
        if (bytesLeft > 0) {
            // Pad out the space we promised in the buffer.  We can't corrupt the buffer,
            // even though the data we're sending is probably bad.
            memset(buf, 0, bufsize);
            while (bytesLeft > 0) {
                amt = bytesLeft < bufsize ? bytesLeft : bufsize;
                bytesLeft -= amt;
                err = dataStream->WriteEntityData(buf, amt);
                if (err != 0) {
                    free(buf);
                    return err;
                }
            }
        }
        ALOGE("write_update_file size mismatch for %s. expected=%d actual=%d."
                " You aren't doing proper locking!", realFilename, fileSize, fileSize-bytesLeft);
    }

    free(buf);
    return NO_ERROR;
}

static int
write_update_file(BackupDataWriter* dataStream, const String8& key, char const* realFilename)
{
    int err;
    struct stat st;

    err = stat(realFilename, &st);
    if (err < 0) {
        return errno;
    }

    int fd = open(realFilename, O_RDONLY);
    if (fd == -1) {
        return errno;
    }

    err = write_update_file(dataStream, fd, st.st_mode, key, realFilename);
    close(fd);
    return err;
}

static int
compute_crc32(const char* file, FileRec* out) {
    int fd = open(file, O_RDONLY);
    if (fd < 0) {
        return -1;
    }

    const int bufsize = 4*1024;
    int amt;

    char* buf = (char*)malloc(bufsize);
    int crc = crc32(0L, Z_NULL, 0);

    lseek(fd, 0, SEEK_SET);

    while ((amt = read(fd, buf, bufsize)) != 0) {
        crc = crc32(crc, (Bytef*)buf, amt);
    }

    close(fd);
    free(buf);

    out->s.crc32 = crc;
    return NO_ERROR;
}

int
back_up_files(int oldSnapshotFD, BackupDataWriter* dataStream, int newSnapshotFD,
        char const* const* files, char const* const* keys, int fileCount)
{
    int err;
    KeyedVector<String8,FileState> oldSnapshot;
    KeyedVector<String8,FileRec> newSnapshot;

    if (oldSnapshotFD != -1) {
        err = read_snapshot_file(oldSnapshotFD, &oldSnapshot);
        if (err != 0) {
            // On an error, treat this as a full backup.
            oldSnapshot.clear();
        }
    }

    for (int i=0; i<fileCount; i++) {
        String8 key(keys[i]);
        FileRec r;
        char const* file = files[i];
        r.file = file;
        struct stat st;

        err = stat(file, &st);
        if (err != 0) {
            // not found => treat as deleted
            continue;
        } else {
            r.deleted = false;
            r.s.modTime_sec = st.st_mtime;
            r.s.modTime_nsec = 0; // workaround sim breakage
            //r.s.modTime_nsec = st.st_mtime_nsec;
            r.s.mode = st.st_mode;
            r.s.size = st.st_size;

            if (newSnapshot.indexOfKey(key) >= 0) {
                LOGP("back_up_files key already in use '%s'", key.string());
                return -1;
            }

            // compute the CRC
            if (compute_crc32(file, &r) != NO_ERROR) {
                ALOGW("Unable to open file %s", file);
                continue;
            }
        }
        newSnapshot.add(key, r);
    }

    int n = 0;
    int N = oldSnapshot.size();
    int m = 0;
    int M = newSnapshot.size();

    while (n<N && m<M) {
        const String8& p = oldSnapshot.keyAt(n);
        const String8& q = newSnapshot.keyAt(m);
        FileRec& g = newSnapshot.editValueAt(m);
        int cmp = p.compare(q);
        if (cmp < 0) {
            // file present in oldSnapshot, but not present in newSnapshot
            LOGP("file removed: %s", p.string());
            write_delete_file(dataStream, p);
            n++;
        } else if (cmp > 0) {
            // file added
            LOGP("file added: %s crc=0x%08x", g.file.string(), g.s.crc32);
            write_update_file(dataStream, q, g.file.string());
            m++;
        } else {
            // same file exists in both old and new; check whether to update
            const FileState& f = oldSnapshot.valueAt(n);

            LOGP("%s", q.string());
            LOGP("  old: modTime=%d,%d mode=%04o size=%-3d crc32=0x%08x",
                    f.modTime_sec, f.modTime_nsec, f.mode, f.size, f.crc32);
            LOGP("  new: modTime=%d,%d mode=%04o size=%-3d crc32=0x%08x",
                    g.s.modTime_sec, g.s.modTime_nsec, g.s.mode, g.s.size, g.s.crc32);
            if (f.modTime_sec != g.s.modTime_sec || f.modTime_nsec != g.s.modTime_nsec
                    || f.mode != g.s.mode || f.size != g.s.size || f.crc32 != g.s.crc32) {
                int fd = open(g.file.string(), O_RDONLY);
                if (fd < 0) {
                    ALOGE("Unable to read file for backup: %s", g.file.string());
                } else {
                    write_update_file(dataStream, fd, g.s.mode, p, g.file.string());
                    close(fd);
                }
            }
            n++;
            m++;
        }
    }

    // these were deleted
    while (n<N) {
        write_delete_file(dataStream, oldSnapshot.keyAt(n));
        n++;
    }

    // these were added
    while (m<M) {
        const String8& q = newSnapshot.keyAt(m);
        FileRec& g = newSnapshot.editValueAt(m);
        write_update_file(dataStream, q, g.file.string());
        m++;
    }

    err = write_snapshot_file(newSnapshotFD, newSnapshot);

    return 0;
}

static void calc_tar_checksum(char* buf, size_t buf_size) {
    // [ 148 :   8 ] checksum -- to be calculated with this field as space chars
    memset(buf + 148, ' ', 8);

    uint16_t sum = 0;
    for (uint8_t* p = (uint8_t*) buf; p < ((uint8_t*)buf) + 512; p++) {
        sum += *p;
    }

    // Now write the real checksum value:
    // [ 148 :   8 ]  checksum: 6 octal digits [leading zeroes], NUL, SPC
    snprintf(buf + 148, buf_size - 148, "%06o", sum); // the trailing space is
                                                      // already in place
}

// Returns number of bytes written
static int write_pax_header_entry(char* buf, size_t buf_size,
                                  const char* key, const char* value) {
    // start with the size of "1 key=value\n"
    int len = strlen(key) + strlen(value) + 4;
    if (len > 9) len++;
    if (len > 99) len++;
    if (len > 999) len++;
    // since PATH_MAX is 4096 we don't expect to have to generate any single
    // header entry longer than 9999 characters

    return snprintf(buf, buf_size, "%d %s=%s\n", len, key, value);
}

// Wire format to the backup manager service is chunked:  each chunk is prefixed by
// a 4-byte count of its size.  A chunk size of zero (four zero bytes) indicates EOD.
void send_tarfile_chunk(BackupDataWriter* writer, const char* buffer, size_t size) {
    uint32_t chunk_size_no = htonl(size);
    writer->WriteEntityData(&chunk_size_no, 4);
    if (size != 0) writer->WriteEntityData(buffer, size);
}

int write_tarfile(const String8& packageName, const String8& domain,
        const String8& rootpath, const String8& filepath, off64_t* outSize,
        BackupDataWriter* writer)
{
    // In the output stream everything is stored relative to the root
    const char* relstart = filepath.string() + rootpath.length();
    if (*relstart == '/') relstart++;     // won't be true when path == rootpath
    String8 relpath(relstart);

    // If relpath is empty, it means this is the top of one of the standard named
    // domain directories, so we should just skip it
    if (relpath.length() == 0) {
        *outSize = 0;
        return 0;
    }

    // Too long a name for the ustar format?
    //    "apps/" + packagename + '/' + domainpath < 155 chars
    //    relpath < 100 chars
    bool needExtended = false;
    if ((5 + packageName.length() + 1 + domain.length() >= 155) || (relpath.length() >= 100)) {
        needExtended = true;
    }

    // Non-7bit-clean path also means needing pax extended format
    if (!needExtended) {
        for (size_t i = 0; i < filepath.length(); i++) {
            if ((filepath[i] & 0x80) != 0) {
                needExtended = true;
                break;
            }
        }
    }

    int err = 0;
    struct stat64 s;
    if (lstat64(filepath.string(), &s) != 0) {
        err = errno;
        ALOGE("Error %d (%s) from lstat64(%s)", err, strerror(err), filepath.string());
        return err;
    }

    // very large files need a pax extended size header
    if (s.st_size > 077777777777LL) {
        needExtended = true;
    }

    String8 fullname;   // for pax later on
    String8 prefix;

    const int isdir = S_ISDIR(s.st_mode);
    if (isdir) s.st_size = 0;   // directories get no actual data in the tar stream

    // Report the size, including a rough tar overhead estimation: 512 bytes for the
    // overall tar file-block header, plus 2 blocks if using the pax extended format,
    // plus the raw content size rounded up to a multiple of 512.
    *outSize = 512 + (needExtended ? 1024 : 0) + 512*((s.st_size + 511)/512);

    // Measure case: we've returned the size; now return without moving data
    if (!writer) return 0;

    // !!! TODO: use mmap when possible to avoid churning the buffer cache
    // !!! TODO: this will break with symlinks; need to use readlink(2)
    int fd = open(filepath.string(), O_RDONLY);
    if (fd < 0) {
        err = errno;
        ALOGE("Error %d (%s) from open(%s)", err, strerror(err), filepath.string());
        return err;
    }

    // read/write up to this much at a time.
    const size_t BUFSIZE = 32 * 1024;
    char* buf = (char *)calloc(1,BUFSIZE);
    const size_t PAXHEADER_OFFSET = 512;
    const size_t PAXHEADER_SIZE = 512;
    const size_t PAXDATA_SIZE = BUFSIZE - (PAXHEADER_SIZE + PAXHEADER_OFFSET);
    char* const paxHeader = buf + PAXHEADER_OFFSET; // use a different chunk of
                                                    // it as separate scratch
    char* const paxData = paxHeader + PAXHEADER_SIZE;

    if (buf == NULL) {
        ALOGE("Out of mem allocating transfer buffer");
        err = ENOMEM;
        goto done;
    }

    // Magic fields for the ustar file format
    strcat(buf + 257, "ustar");
    strcat(buf + 263, "00");

    // [ 265 : 32 ] user name, ignored on restore
    // [ 297 : 32 ] group name, ignored on restore

    // [ 100 :   8 ] file mode
    snprintf(buf + 100, 8, "%06o ", s.st_mode & ~S_IFMT);

    // [ 108 :   8 ] uid -- ignored in Android format; uids are remapped at restore time
    // [ 116 :   8 ] gid -- ignored in Android format
    snprintf(buf + 108, 8, "0%lo", (unsigned long)s.st_uid);
    snprintf(buf + 116, 8, "0%lo", (unsigned long)s.st_gid);

    // [ 124 :  12 ] file size in bytes
    snprintf(buf + 124, 12, "%011llo", (isdir) ? 0LL : s.st_size);

    // [ 136 :  12 ] last mod time as a UTC time_t
    snprintf(buf + 136, 12, "%0lo", (unsigned long)s.st_mtime);

    // [ 156 :   1 ] link/file type
    uint8_t type;
    if (isdir) {
        type = '5';     // tar magic: '5' == directory
    } else if (S_ISREG(s.st_mode)) {
        type = '0';     // tar magic: '0' == normal file
    } else {
        ALOGW("Error: unknown file mode 0%o [%s]", s.st_mode, filepath.string());
        goto cleanup;
    }
    buf[156] = type;

    // [ 157 : 100 ] name of linked file [not implemented]

    {
        // Prefix and main relative path.  Path lengths have been preflighted.
        if (packageName.length() > 0) {
            prefix = "apps/";
            prefix += packageName;
        }
        if (domain.length() > 0) {
            prefix.appendPath(domain);
        }

        // pax extended means we don't put in a prefix field, and put a different
        // string in the basic name field.  We can also construct the full path name
        // out of the substrings we've now built.
        fullname = prefix;
        fullname.appendPath(relpath);

        // ustar:
        //    [   0 : 100 ]; file name/path
        //    [ 345 : 155 ] filename path prefix
        // We only use the prefix area if fullname won't fit in the path
        if (fullname.length() > 100) {
            strncpy(buf, relpath.string(), 100);
            strncpy(buf + 345, prefix.string(), 155);
        } else {
            strncpy(buf, fullname.string(), 100);
        }
    }

    // [ 329 : 8 ] and [ 337 : 8 ] devmajor/devminor, not used

    ALOGI("   Name: %s", fullname.string());

    // If we're using a pax extended header, build & write that here; lengths are
    // already preflighted
    if (needExtended) {
        char sizeStr[32];   // big enough for a 64-bit unsigned value in decimal

        // construct the pax extended header data block
        memset(paxData, 0, PAXDATA_SIZE);

        // size header -- calc len in digits by actually rendering the number
        // to a string - brute force but simple
        int paxLen = 0;
        snprintf(sizeStr, sizeof(sizeStr), "%lld", (long long)s.st_size);
        paxLen += write_pax_header_entry(paxData, PAXDATA_SIZE, "size", sizeStr);

        // fullname was generated above with the ustar paths
        paxLen += write_pax_header_entry(paxData + paxLen, PAXDATA_SIZE - paxLen,
                "path", fullname.string());

        // Now we know how big the pax data is

        // Now build the pax *header* templated on the ustar header
        memcpy(paxHeader, buf, 512);

        String8 leaf = fullname.getPathLeaf();
        memset(paxHeader, 0, 100);                  // rewrite the name area
        snprintf(paxHeader, 100, "PaxHeader/%s", leaf.string());
        memset(paxHeader + 345, 0, 155);            // rewrite the prefix area
        strncpy(paxHeader + 345, prefix.string(), 155);

        paxHeader[156] = 'x';                       // mark it as a pax extended header

        // [ 124 :  12 ] size of pax extended header data
        memset(paxHeader + 124, 0, 12);
        snprintf(paxHeader + 124, 12, "%011o", (unsigned int)paxLen);

        // Checksum and write the pax block header
        calc_tar_checksum(paxHeader, PAXHEADER_SIZE);
        send_tarfile_chunk(writer, paxHeader, 512);

        // Now write the pax data itself
        int paxblocks = (paxLen + 511) / 512;
        send_tarfile_chunk(writer, paxData, 512 * paxblocks);
    }

    // Checksum and write the 512-byte ustar file header block to the output
    calc_tar_checksum(buf, BUFSIZE);
    send_tarfile_chunk(writer, buf, 512);

    // Now write the file data itself, for real files.  We honor tar's convention that
    // only full 512-byte blocks are sent to write().
    if (!isdir) {
        off64_t toWrite = s.st_size;
        while (toWrite > 0) {
            size_t toRead = toWrite;
            if (toRead > BUFSIZE) {
                toRead = BUFSIZE;
            }
            ssize_t nRead = read(fd, buf, toRead);
            if (nRead < 0) {
                err = errno;
                ALOGE("Unable to read file [%s], err=%d (%s)", filepath.string(),
                        err, strerror(err));
                break;
            } else if (nRead == 0) {
                ALOGE("EOF but expect %lld more bytes in [%s]", (long long) toWrite,
                        filepath.string());
                err = EIO;
                break;
            }

            // At EOF we might have a short block; NUL-pad that to a 512-byte multiple.  This
            // depends on the OS guarantee that for ordinary files, read() will never return
            // less than the number of bytes requested.
            ssize_t partial = (nRead+512) % 512;
            if (partial > 0) {
                ssize_t remainder = 512 - partial;
                memset(buf + nRead, 0, remainder);
                nRead += remainder;
            }
            send_tarfile_chunk(writer, buf, nRead);
            toWrite -= nRead;
        }
    }

cleanup:
    free(buf);
done:
    close(fd);
    return err;
}
// end tarfile



#define RESTORE_BUF_SIZE (8*1024)

RestoreHelperBase::RestoreHelperBase()
{
    m_buf = malloc(RESTORE_BUF_SIZE);
    m_loggedUnknownMetadata = false;
}

RestoreHelperBase::~RestoreHelperBase()
{
    free(m_buf);
}

status_t
RestoreHelperBase::WriteFile(const String8& filename, BackupDataReader* in)
{
    ssize_t err;
    size_t dataSize;
    String8 key;
    int fd;
    void* buf = m_buf;
    ssize_t amt;
    int mode;
    int crc;
    struct stat st;
    FileRec r;

    err = in->ReadEntityHeader(&key, &dataSize);
    if (err != NO_ERROR) {
        return err;
    }

    // Get the metadata block off the head of the file entity and use that to
    // set up the output file
    file_metadata_v1 metadata;
    amt = in->ReadEntityData(&metadata, sizeof(metadata));
    if (amt != sizeof(metadata)) {
        ALOGW("Could not read metadata for %s -- %ld / %s", filename.string(),
                (long)amt, strerror(errno));
        return EIO;
    }
    metadata.version = fromlel(metadata.version);
    metadata.mode = fromlel(metadata.mode);
    if (metadata.version > CURRENT_METADATA_VERSION) {
        if (!m_loggedUnknownMetadata) {
            m_loggedUnknownMetadata = true;
            ALOGW("Restoring file with unsupported metadata version %d (currently %d)",
                    metadata.version, CURRENT_METADATA_VERSION);
        }
    }
    mode = metadata.mode;

    // Write the file and compute the crc
    crc = crc32(0L, Z_NULL, 0);
    fd = open(filename.string(), O_CREAT|O_RDWR|O_TRUNC, mode);
    if (fd == -1) {
        ALOGW("Could not open file %s -- %s", filename.string(), strerror(errno));
        return errno;
    }

    while ((amt = in->ReadEntityData(buf, RESTORE_BUF_SIZE)) > 0) {
        err = write(fd, buf, amt);
        if (err != amt) {
            close(fd);
            ALOGW("Error '%s' writing '%s'", strerror(errno), filename.string());
            return errno;
        }
        crc = crc32(crc, (Bytef*)buf, amt);
    }

    close(fd);

    // Record for the snapshot
    err = stat(filename.string(), &st);
    if (err != 0) {
        ALOGW("Error stating file that we just created %s", filename.string());
        return errno;
    }

    r.file = filename;
    r.deleted = false;
    r.s.modTime_sec = st.st_mtime;
    r.s.modTime_nsec = 0; // workaround sim breakage
    //r.s.modTime_nsec = st.st_mtime_nsec;
    r.s.mode = st.st_mode;
    r.s.size = st.st_size;
    r.s.crc32 = crc;

    m_files.add(key, r);

    return NO_ERROR;
}

status_t
RestoreHelperBase::WriteSnapshot(int fd)
{
    return write_snapshot_file(fd, m_files);;
}

#if TEST_BACKUP_HELPERS

#define SCRATCH_DIR "/data/backup_helper_test/"

static int
write_text_file(const char* path, const char* data)
{
    int amt;
    int fd;
    int len;

    fd = creat(path, 0666);
    if (fd == -1) {
        fprintf(stderr, "creat %s failed\n", path);
        return errno;
    }

    len = strlen(data);
    amt = write(fd, data, len);
    if (amt != len) {
        fprintf(stderr, "error (%s) writing to file %s\n", strerror(errno), path);
        return errno;
    }

    close(fd);

    return 0;
}

static int
compare_file(const char* path, const unsigned char* data, int len)
{
    int fd;
    int amt;

    fd = open(path, O_RDONLY);
    if (fd == -1) {
        fprintf(stderr, "compare_file error (%s) opening %s\n", strerror(errno), path);
        return errno;
    }

    unsigned char* contents = (unsigned char*)malloc(len);
    if (contents == NULL) {
        fprintf(stderr, "malloc(%d) failed\n", len);
        return ENOMEM;
    }

    bool sizesMatch = true;
    amt = lseek(fd, 0, SEEK_END);
    if (amt != len) {
        fprintf(stderr, "compare_file file length should be %d, was %d\n", len, amt);
        sizesMatch = false;
    }
    lseek(fd, 0, SEEK_SET);

    int readLen = amt < len ? amt : len;
    amt = read(fd, contents, readLen);
    if (amt != readLen) {
        fprintf(stderr, "compare_file read expected %d bytes but got %d\n", len, amt);
    }

    bool contentsMatch = true;
    for (int i=0; i<readLen; i++) {
        if (data[i] != contents[i]) {
            if (contentsMatch) {
                fprintf(stderr, "compare_file contents are different: (index, expected, actual)\n");
                contentsMatch = false;
            }
            fprintf(stderr, "  [%-2d] %02x %02x\n", i, data[i], contents[i]);
        }
    }

    free(contents);
    return contentsMatch && sizesMatch ? 0 : 1;
}

int
backup_helper_test_empty()
{
    int err;
    int fd;
    KeyedVector<String8,FileRec> snapshot;
    const char* filename = SCRATCH_DIR "backup_helper_test_empty.snap";

    system("rm -r " SCRATCH_DIR);
    mkdir(SCRATCH_DIR, 0777);

    // write
    fd = creat(filename, 0666);
    if (fd == -1) {
        fprintf(stderr, "error creating %s\n", filename);
        return 1;
    }

    err = write_snapshot_file(fd, snapshot);

    close(fd);

    if (err != 0) {
        fprintf(stderr, "write_snapshot_file reported error %d (%s)\n", err, strerror(err));
        return err;
    }

    static const unsigned char correct_data[] = {
        0x53, 0x6e, 0x61, 0x70,  0x00, 0x00, 0x00, 0x00,
        0x46, 0x69, 0x6c, 0x65,  0x10, 0x00, 0x00, 0x00
    };

    err = compare_file(filename, correct_data, sizeof(correct_data));
    if (err != 0) {
        return err;
    }

    // read
    fd = open(filename, O_RDONLY);
    if (fd == -1) {
        fprintf(stderr, "error opening for read %s\n", filename);
        return 1;
    }

    KeyedVector<String8,FileState> readSnapshot;
    err = read_snapshot_file(fd, &readSnapshot);
    if (err != 0) {
        fprintf(stderr, "read_snapshot_file failed %d\n", err);
        return err;
    }

    if (readSnapshot.size() != 0) {
        fprintf(stderr, "readSnapshot should be length 0\n");
        return 1;
    }

    return 0;
}

int
backup_helper_test_four()
{
    int err;
    int fd;
    KeyedVector<String8,FileRec> snapshot;
    const char* filename = SCRATCH_DIR "backup_helper_test_four.snap";

    system("rm -r " SCRATCH_DIR);
    mkdir(SCRATCH_DIR, 0777);

    // write
    fd = creat(filename, 0666);
    if (fd == -1) {
        fprintf(stderr, "error opening %s\n", filename);
        return 1;
    }

    String8 filenames[4];
    FileState states[4];
    FileRec r;
    r.deleted = false;

    states[0].modTime_sec = 0xfedcba98;
    states[0].modTime_nsec = 0xdeadbeef;
    states[0].mode = 0777; // decimal 511, hex 0x000001ff
    states[0].size = 0xababbcbc;
    states[0].crc32 = 0x12345678;
    states[0].nameLen = -12;
    r.s = states[0];
    filenames[0] = String8("bytes_of_padding");
    snapshot.add(filenames[0], r);

    states[1].modTime_sec = 0x93400031;
    states[1].modTime_nsec = 0xdeadbeef;
    states[1].mode = 0666; // decimal 438, hex 0x000001b6
    states[1].size = 0x88557766;
    states[1].crc32 = 0x22334422;
    states[1].nameLen = -1;
    r.s = states[1];
    filenames[1] = String8("bytes_of_padding3");
    snapshot.add(filenames[1], r);

    states[2].modTime_sec = 0x33221144;
    states[2].modTime_nsec = 0xdeadbeef;
    states[2].mode = 0744; // decimal 484, hex 0x000001e4
    states[2].size = 0x11223344;
    states[2].crc32 = 0x01122334;
    states[2].nameLen = 0;
    r.s = states[2];
    filenames[2] = String8("bytes_of_padding_2");
    snapshot.add(filenames[2], r);

    states[3].modTime_sec = 0x33221144;
    states[3].modTime_nsec = 0xdeadbeef;
    states[3].mode = 0755; // decimal 493, hex 0x000001ed
    states[3].size = 0x11223344;
    states[3].crc32 = 0x01122334;
    states[3].nameLen = 0;
    r.s = states[3];
    filenames[3] = String8("bytes_of_padding__1");
    snapshot.add(filenames[3], r);

    err = write_snapshot_file(fd, snapshot);

    close(fd);

    if (err != 0) {
        fprintf(stderr, "write_snapshot_file reported error %d (%s)\n", err, strerror(err));
        return err;
    }

    static const unsigned char correct_data[] = {
        // header
        0x53, 0x6e, 0x61, 0x70,  0x04, 0x00, 0x00, 0x00,
        0x46, 0x69, 0x6c, 0x65,  0xbc, 0x00, 0x00, 0x00,

        // bytes_of_padding
        0x98, 0xba, 0xdc, 0xfe,  0xef, 0xbe, 0xad, 0xde,
        0xff, 0x01, 0x00, 0x00,  0xbc, 0xbc, 0xab, 0xab,
        0x78, 0x56, 0x34, 0x12,  0x10, 0x00, 0x00, 0x00,
        0x62, 0x79, 0x74, 0x65,  0x73, 0x5f, 0x6f, 0x66,
        0x5f, 0x70, 0x61, 0x64,  0x64, 0x69, 0x6e, 0x67,

        // bytes_of_padding3
        0x31, 0x00, 0x40, 0x93,  0xef, 0xbe, 0xad, 0xde,
        0xb6, 0x01, 0x00, 0x00,  0x66, 0x77, 0x55, 0x88,
        0x22, 0x44, 0x33, 0x22,  0x11, 0x00, 0x00, 0x00,
        0x62, 0x79, 0x74, 0x65,  0x73, 0x5f, 0x6f, 0x66,
        0x5f, 0x70, 0x61, 0x64,  0x64, 0x69, 0x6e, 0x67,
        0x33, 0xab, 0xab, 0xab,

        // bytes of padding2
        0x44, 0x11, 0x22, 0x33,  0xef, 0xbe, 0xad, 0xde,
        0xe4, 0x01, 0x00, 0x00,  0x44, 0x33, 0x22, 0x11,
        0x34, 0x23, 0x12, 0x01,  0x12, 0x00, 0x00, 0x00,
        0x62, 0x79, 0x74, 0x65,  0x73, 0x5f, 0x6f, 0x66,
        0x5f, 0x70, 0x61, 0x64,  0x64, 0x69, 0x6e, 0x67,
        0x5f, 0x32, 0xab, 0xab,

        // bytes of padding3
        0x44, 0x11, 0x22, 0x33,  0xef, 0xbe, 0xad, 0xde,
        0xed, 0x01, 0x00, 0x00,  0x44, 0x33, 0x22, 0x11,
        0x34, 0x23, 0x12, 0x01,  0x13, 0x00, 0x00, 0x00,
        0x62, 0x79, 0x74, 0x65,  0x73, 0x5f, 0x6f, 0x66,
        0x5f, 0x70, 0x61, 0x64,  0x64, 0x69, 0x6e, 0x67,
        0x5f, 0x5f, 0x31, 0xab
    };

    err = compare_file(filename, correct_data, sizeof(correct_data));
    if (err != 0) {
        return err;
    }

    // read
    fd = open(filename, O_RDONLY);
    if (fd == -1) {
        fprintf(stderr, "error opening for read %s\n", filename);
        return 1;
    }


    KeyedVector<String8,FileState> readSnapshot;
    err = read_snapshot_file(fd, &readSnapshot);
    if (err != 0) {
        fprintf(stderr, "read_snapshot_file failed %d\n", err);
        return err;
    }

    if (readSnapshot.size() != 4) {
        fprintf(stderr, "readSnapshot should be length 4 is %zu\n", readSnapshot.size());
        return 1;
    }

    bool matched = true;
    for (size_t i=0; i<readSnapshot.size(); i++) {
        const String8& name = readSnapshot.keyAt(i);
        const FileState state = readSnapshot.valueAt(i);

        if (name != filenames[i] || states[i].modTime_sec != state.modTime_sec
                || states[i].modTime_nsec != state.modTime_nsec || states[i].mode != state.mode
                || states[i].size != state.size || states[i].crc32 != states[i].crc32) {
            fprintf(stderr, "state %zu expected={%d/%d, %04o, 0x%08x, 0x%08x, %3zu} '%s'\n"
                            "          actual={%d/%d, %04o, 0x%08x, 0x%08x, %3d} '%s'\n", i,
                    states[i].modTime_sec, states[i].modTime_nsec, states[i].mode, states[i].size,
                    states[i].crc32, name.length(), filenames[i].string(),
                    state.modTime_sec, state.modTime_nsec, state.mode, state.size, state.crc32,
                    state.nameLen, name.string());
            matched = false;
        }
    }

    return matched ? 0 : 1;
}

// hexdump -v -e '"    " 8/1 " 0x%02x," "\n"' data_writer.data
const unsigned char DATA_GOLDEN_FILE[] = {
     0x44, 0x61, 0x74, 0x61, 0x0b, 0x00, 0x00, 0x00,
     0x0c, 0x00, 0x00, 0x00, 0x6e, 0x6f, 0x5f, 0x70,
     0x61, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x5f, 0x00,
     0x6e, 0x6f, 0x5f, 0x70, 0x61, 0x64, 0x64, 0x69,
     0x6e, 0x67, 0x5f, 0x00, 0x44, 0x61, 0x74, 0x61,
     0x0c, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00,
     0x70, 0x61, 0x64, 0x64, 0x65, 0x64, 0x5f, 0x74,
     0x6f, 0x5f, 0x5f, 0x33, 0x00, 0xbc, 0xbc, 0xbc,
     0x70, 0x61, 0x64, 0x64, 0x65, 0x64, 0x5f, 0x74,
     0x6f, 0x5f, 0x5f, 0x33, 0x00, 0xbc, 0xbc, 0xbc,
     0x44, 0x61, 0x74, 0x61, 0x0d, 0x00, 0x00, 0x00,
     0x0e, 0x00, 0x00, 0x00, 0x70, 0x61, 0x64, 0x64,
     0x65, 0x64, 0x5f, 0x74, 0x6f, 0x5f, 0x32, 0x5f,
     0x5f, 0x00, 0xbc, 0xbc, 0x70, 0x61, 0x64, 0x64,
     0x65, 0x64, 0x5f, 0x74, 0x6f, 0x5f, 0x32, 0x5f,
     0x5f, 0x00, 0xbc, 0xbc, 0x44, 0x61, 0x74, 0x61,
     0x0a, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00,
     0x70, 0x61, 0x64, 0x64, 0x65, 0x64, 0x5f, 0x74,
     0x6f, 0x31, 0x00, 0xbc, 0x70, 0x61, 0x64, 0x64,
     0x65, 0x64, 0x5f, 0x74, 0x6f, 0x31, 0x00

};
const int DATA_GOLDEN_FILE_SIZE = sizeof(DATA_GOLDEN_FILE);

static int
test_write_header_and_entity(BackupDataWriter& writer, const char* str)
{
    int err;
    String8 text(str);

    err = writer.WriteEntityHeader(text, text.length()+1);
    if (err != 0) {
        fprintf(stderr, "WriteEntityHeader failed with %s\n", strerror(err));
        return err;
    }

    err = writer.WriteEntityData(text.string(), text.length()+1);
    if (err != 0) {
        fprintf(stderr, "write failed for data '%s'\n", text.string());
        return errno;
    }

    return err;
}

int
backup_helper_test_data_writer()
{
    int err;
    int fd;
    const char* filename = SCRATCH_DIR "data_writer.data";

    system("rm -r " SCRATCH_DIR);
    mkdir(SCRATCH_DIR, 0777);
    mkdir(SCRATCH_DIR "data", 0777);

    fd = creat(filename, 0666);
    if (fd == -1) {
        fprintf(stderr, "error creating: %s\n", strerror(errno));
        return errno;
    }

    BackupDataWriter writer(fd);

    err = 0;
    err |= test_write_header_and_entity(writer, "no_padding_");
    err |= test_write_header_and_entity(writer, "padded_to__3");
    err |= test_write_header_and_entity(writer, "padded_to_2__");
    err |= test_write_header_and_entity(writer, "padded_to1");

    close(fd);

    err = compare_file(filename, DATA_GOLDEN_FILE, DATA_GOLDEN_FILE_SIZE);
    if (err != 0) {
        return err;
    }

    return err;
}

int
test_read_header_and_entity(BackupDataReader& reader, const char* str)
{
    int err;
    size_t bufSize = strlen(str)+1;
    char* buf = (char*)malloc(bufSize);
    String8 string;
    size_t actualSize;
    bool done;
    int type;
    ssize_t nRead;

    // printf("\n\n---------- test_read_header_and_entity -- %s\n\n", str);

    err = reader.ReadNextHeader(&done, &type);
    if (done) {
        fprintf(stderr, "should not be done yet\n");
        goto finished;
    }
    if (err != 0) {
        fprintf(stderr, "ReadNextHeader (for app header) failed with %s\n", strerror(err));
        goto finished;
    }
    if (type != BACKUP_HEADER_ENTITY_V1) {
        err = EINVAL;
        fprintf(stderr, "type=0x%08x expected 0x%08x\n", type, BACKUP_HEADER_ENTITY_V1);
    }

    err = reader.ReadEntityHeader(&string, &actualSize);
    if (err != 0) {
        fprintf(stderr, "ReadEntityHeader failed with %s\n", strerror(err));
        goto finished;
    }
    if (string != str) {
        fprintf(stderr, "ReadEntityHeader expected key '%s' got '%s'\n", str, string.string());
        err = EINVAL;
        goto finished;
    }
    if (actualSize != bufSize) {
        fprintf(stderr, "ReadEntityHeader expected dataSize %zu got %zu\n",
                bufSize, actualSize);
        err = EINVAL;
        goto finished;
    }

    nRead = reader.ReadEntityData(buf, bufSize);
    if (nRead < 0) {
        err = reader.Status();
        fprintf(stderr, "ReadEntityData failed with %s\n", strerror(err));
        goto finished;
    }

    if (0 != memcmp(buf, str, bufSize)) {
        fprintf(stderr, "ReadEntityData expected '%s' but got something starting with "
                "%02x %02x %02x %02x  '%c%c%c%c'\n", str, buf[0], buf[1], buf[2], buf[3],
                buf[0], buf[1], buf[2], buf[3]);
        err = EINVAL;
        goto finished;
    }

    // The next read will confirm whether it got the right amount of data.

finished:
    if (err != NO_ERROR) {
        fprintf(stderr, "test_read_header_and_entity failed with %s\n", strerror(err));
    }
    free(buf);
    return err;
}

int
backup_helper_test_data_reader()
{
    int err;
    int fd;
    const char* filename = SCRATCH_DIR "data_reader.data";

    system("rm -r " SCRATCH_DIR);
    mkdir(SCRATCH_DIR, 0777);
    mkdir(SCRATCH_DIR "data", 0777);

    fd = creat(filename, 0666);
    if (fd == -1) {
        fprintf(stderr, "error creating: %s\n", strerror(errno));
        return errno;
    }

    err = write(fd, DATA_GOLDEN_FILE, DATA_GOLDEN_FILE_SIZE);
    if (err != DATA_GOLDEN_FILE_SIZE) {
        fprintf(stderr, "Error \"%s\" writing golden file %s\n", strerror(errno), filename);
        return errno;
    }

    close(fd);

    fd = open(filename, O_RDONLY);
    if (fd == -1) {
        fprintf(stderr, "Error \"%s\" opening golden file %s for read\n", strerror(errno),
                filename);
        return errno;
    }

    {
        BackupDataReader reader(fd);

        err = 0;

        if (err == NO_ERROR) {
            err = test_read_header_and_entity(reader, "no_padding_");
        }

        if (err == NO_ERROR) {
            err = test_read_header_and_entity(reader, "padded_to__3");
        }

        if (err == NO_ERROR) {
            err = test_read_header_and_entity(reader, "padded_to_2__");
        }

        if (err == NO_ERROR) {
            err = test_read_header_and_entity(reader, "padded_to1");
        }
    }

    close(fd);

    return err;
}

static int
get_mod_time(const char* filename, struct timeval times[2])
{
    int err;
    struct stat64 st;
    err = stat64(filename, &st);
    if (err != 0) {
        fprintf(stderr, "stat '%s' failed: %s\n", filename, strerror(errno));
        return errno;
    }

    times[0].tv_sec = st.st_atim.tv_sec;
    times[0].tv_usec = st.st_atim.tv_nsec / 1000;

    times[1].tv_sec = st.st_mtim.tv_sec;
    times[1].tv_usec = st.st_mtim.tv_nsec / 1000;

    return 0;
}

int
backup_helper_test_files()
{
    int err;
    int oldSnapshotFD;
    int dataStreamFD;
    int newSnapshotFD;

    system("rm -r " SCRATCH_DIR);
    mkdir(SCRATCH_DIR, 0777);
    mkdir(SCRATCH_DIR "data", 0777);

    write_text_file(SCRATCH_DIR "data/b", "b\nbb\n");
    write_text_file(SCRATCH_DIR "data/c", "c\ncc\n");
    write_text_file(SCRATCH_DIR "data/d", "d\ndd\n");
    write_text_file(SCRATCH_DIR "data/e", "e\nee\n");
    write_text_file(SCRATCH_DIR "data/f", "f\nff\n");
    write_text_file(SCRATCH_DIR "data/h", "h\nhh\n");

    char const* files_before[] = {
        SCRATCH_DIR "data/b",
        SCRATCH_DIR "data/c",
        SCRATCH_DIR "data/d",
        SCRATCH_DIR "data/e",
        SCRATCH_DIR "data/f"
    };

    char const* keys_before[] = {
        "data/b",
        "data/c",
        "data/d",
        "data/e",
        "data/f"
    };

    dataStreamFD = creat(SCRATCH_DIR "1.data", 0666);
    if (dataStreamFD == -1) {
        fprintf(stderr, "error creating: %s\n", strerror(errno));
        return errno;
    }

    newSnapshotFD = creat(SCRATCH_DIR "before.snap", 0666);
    if (newSnapshotFD == -1) {
        fprintf(stderr, "error creating: %s\n", strerror(errno));
        return errno;
    }

    {
        BackupDataWriter dataStream(dataStreamFD);

        err = back_up_files(-1, &dataStream, newSnapshotFD, files_before, keys_before, 5);
        if (err != 0) {
            return err;
        }
    }

    close(dataStreamFD);
    close(newSnapshotFD);

    sleep(3);

    struct timeval d_times[2];
    struct timeval e_times[2];

    err = get_mod_time(SCRATCH_DIR "data/d", d_times);
    err |= get_mod_time(SCRATCH_DIR "data/e", e_times);
    if (err != 0) {
        return err;
    }

    write_text_file(SCRATCH_DIR "data/a", "a\naa\n");
    unlink(SCRATCH_DIR "data/c");
    write_text_file(SCRATCH_DIR "data/c", "c\ncc\n");
    write_text_file(SCRATCH_DIR "data/d", "dd\ndd\n");
    utimes(SCRATCH_DIR "data/d", d_times);
    write_text_file(SCRATCH_DIR "data/e", "z\nzz\n");
    utimes(SCRATCH_DIR "data/e", e_times);
    write_text_file(SCRATCH_DIR "data/g", "g\ngg\n");
    unlink(SCRATCH_DIR "data/f");

    char const* files_after[] = {
        SCRATCH_DIR "data/a", // added
        SCRATCH_DIR "data/b", // same
        SCRATCH_DIR "data/c", // different mod time
        SCRATCH_DIR "data/d", // different size (same mod time)
        SCRATCH_DIR "data/e", // different contents (same mod time, same size)
        SCRATCH_DIR "data/g"  // added
    };

    char const* keys_after[] = {
        "data/a", // added
        "data/b", // same
        "data/c", // different mod time
        "data/d", // different size (same mod time)
        "data/e", // different contents (same mod time, same size)
        "data/g"  // added
    };

    oldSnapshotFD = open(SCRATCH_DIR "before.snap", O_RDONLY);
    if (oldSnapshotFD == -1) {
        fprintf(stderr, "error opening: %s\n", strerror(errno));
        return errno;
    }

    dataStreamFD = creat(SCRATCH_DIR "2.data", 0666);
    if (dataStreamFD == -1) {
        fprintf(stderr, "error creating: %s\n", strerror(errno));
        return errno;
    }

    newSnapshotFD = creat(SCRATCH_DIR "after.snap", 0666);
    if (newSnapshotFD == -1) {
        fprintf(stderr, "error creating: %s\n", strerror(errno));
        return errno;
    }

    {
        BackupDataWriter dataStream(dataStreamFD);

        err = back_up_files(oldSnapshotFD, &dataStream, newSnapshotFD, files_after, keys_after, 6);
        if (err != 0) {
            return err;
        }
}

    close(oldSnapshotFD);
    close(dataStreamFD);
    close(newSnapshotFD);

    return 0;
}

int
backup_helper_test_null_base()
{
    int err;
    int dataStreamFD;
    int newSnapshotFD;

    system("rm -r " SCRATCH_DIR);
    mkdir(SCRATCH_DIR, 0777);
    mkdir(SCRATCH_DIR "data", 0777);

    write_text_file(SCRATCH_DIR "data/a", "a\naa\n");

    char const* files[] = {
        SCRATCH_DIR "data/a",
    };

    char const* keys[] = {
        "a",
    };

    dataStreamFD = creat(SCRATCH_DIR "null_base.data", 0666);
    if (dataStreamFD == -1) {
        fprintf(stderr, "error creating: %s\n", strerror(errno));
        return errno;
    }

    newSnapshotFD = creat(SCRATCH_DIR "null_base.snap", 0666);
    if (newSnapshotFD == -1) {
        fprintf(stderr, "error creating: %s\n", strerror(errno));
        return errno;
    }

    {
        BackupDataWriter dataStream(dataStreamFD);

        err = back_up_files(-1, &dataStream, newSnapshotFD, files, keys, 1);
        if (err != 0) {
            return err;
        }
    }

    close(dataStreamFD);
    close(newSnapshotFD);

    return 0;
}

int
backup_helper_test_missing_file()
{
    int err;
    int dataStreamFD;
    int newSnapshotFD;

    system("rm -r " SCRATCH_DIR);
    mkdir(SCRATCH_DIR, 0777);
    mkdir(SCRATCH_DIR "data", 0777);

    write_text_file(SCRATCH_DIR "data/b", "b\nbb\n");

    char const* files[] = {
        SCRATCH_DIR "data/a",
        SCRATCH_DIR "data/b",
        SCRATCH_DIR "data/c",
    };

    char const* keys[] = {
        "a",
        "b",
        "c",
    };

    dataStreamFD = creat(SCRATCH_DIR "null_base.data", 0666);
    if (dataStreamFD == -1) {
        fprintf(stderr, "error creating: %s\n", strerror(errno));
        return errno;
    }

    newSnapshotFD = creat(SCRATCH_DIR "null_base.snap", 0666);
    if (newSnapshotFD == -1) {
        fprintf(stderr, "error creating: %s\n", strerror(errno));
        return errno;
    }

    {
        BackupDataWriter dataStream(dataStreamFD);

        err = back_up_files(-1, &dataStream, newSnapshotFD, files, keys, 1);
        if (err != 0) {
            return err;
        }
    }

    close(dataStreamFD);
    close(newSnapshotFD);

    return 0;
}


#endif // TEST_BACKUP_HELPERS

}
