BackupHelpers.cpp revision f5df700e6ce056ebfa322314d970e52d6facc35a
14535e40544aeb957d44fad75fbe5676effe03689Joe Onorato/*
24535e40544aeb957d44fad75fbe5676effe03689Joe Onorato * Copyright (C) 2009 The Android Open Source Project
34535e40544aeb957d44fad75fbe5676effe03689Joe Onorato *
44535e40544aeb957d44fad75fbe5676effe03689Joe Onorato * Licensed under the Apache License, Version 2.0 (the "License");
54535e40544aeb957d44fad75fbe5676effe03689Joe Onorato * you may not use this file except in compliance with the License.
64535e40544aeb957d44fad75fbe5676effe03689Joe Onorato * You may obtain a copy of the License at
74535e40544aeb957d44fad75fbe5676effe03689Joe Onorato *
84535e40544aeb957d44fad75fbe5676effe03689Joe Onorato *      http://www.apache.org/licenses/LICENSE-2.0
94535e40544aeb957d44fad75fbe5676effe03689Joe Onorato *
104535e40544aeb957d44fad75fbe5676effe03689Joe Onorato * Unless required by applicable law or agreed to in writing, software
114535e40544aeb957d44fad75fbe5676effe03689Joe Onorato * distributed under the License is distributed on an "AS IS" BASIS,
124535e40544aeb957d44fad75fbe5676effe03689Joe Onorato * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
134535e40544aeb957d44fad75fbe5676effe03689Joe Onorato * See the License for the specific language governing permissions and
144535e40544aeb957d44fad75fbe5676effe03689Joe Onorato * limitations under the License.
154535e40544aeb957d44fad75fbe5676effe03689Joe Onorato */
164535e40544aeb957d44fad75fbe5676effe03689Joe Onorato
173ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato#define LOG_TAG "file_backup_helper"
183ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
19b13b9bdad2baf6ad1ec2e56b6b7598fa20f55fc4Mathias Agopian#include <androidfw/BackupHelpers.h>
203ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
213ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato#include <utils/KeyedVector.h>
223ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato#include <utils/ByteOrder.h>
233ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato#include <utils/String8.h>
243ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
253ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato#include <errno.h>
263ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato#include <sys/types.h>
273ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato#include <sys/uio.h>
283ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato#include <sys/stat.h>
29f4c46b94b867f6a01bf7d0be18f667819338072fNicolas Catania#include <sys/time.h>  // for utimes
303ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato#include <stdio.h>
313ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato#include <stdlib.h>
323ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato#include <unistd.h>
33c825d3ebd6ca66e65e63fdc76f032e08aa2a8e22Joe Onorato#include <utime.h>
343ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato#include <fcntl.h>
353ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato#include <zlib.h>
363ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
373ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato#include <cutils/log.h>
383ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
394535e40544aeb957d44fad75fbe5676effe03689Joe Onoratonamespace android {
403ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
413ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato#define MAGIC0 0x70616e53 // Snap
423ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato#define MAGIC1 0x656c6946 // File
433ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
44fbb92385f2fb0ae1146bb8f3d73547d90bda6db1Christopher Tate/*
45fbb92385f2fb0ae1146bb8f3d73547d90bda6db1Christopher Tate * File entity data format (v1):
46fbb92385f2fb0ae1146bb8f3d73547d90bda6db1Christopher Tate *
47fbb92385f2fb0ae1146bb8f3d73547d90bda6db1Christopher Tate *   - 4-byte version number of the metadata, little endian (0x00000001 for v1)
48fbb92385f2fb0ae1146bb8f3d73547d90bda6db1Christopher Tate *   - 12 bytes of metadata
49fbb92385f2fb0ae1146bb8f3d73547d90bda6db1Christopher Tate *   - the file data itself
50fbb92385f2fb0ae1146bb8f3d73547d90bda6db1Christopher Tate *
51fbb92385f2fb0ae1146bb8f3d73547d90bda6db1Christopher Tate * i.e. a 16-byte metadata header followed by the raw file data.  If the
52fbb92385f2fb0ae1146bb8f3d73547d90bda6db1Christopher Tate * restore code does not recognize the metadata version, it can still
53fbb92385f2fb0ae1146bb8f3d73547d90bda6db1Christopher Tate * interpret the file data itself correctly.
54fbb92385f2fb0ae1146bb8f3d73547d90bda6db1Christopher Tate *
55fbb92385f2fb0ae1146bb8f3d73547d90bda6db1Christopher Tate * file_metadata_v1:
56fbb92385f2fb0ae1146bb8f3d73547d90bda6db1Christopher Tate *
57fbb92385f2fb0ae1146bb8f3d73547d90bda6db1Christopher Tate *   - 4 byte version number === 0x00000001 (little endian)
58fbb92385f2fb0ae1146bb8f3d73547d90bda6db1Christopher Tate *   - 4-byte access mode (little-endian)
59fbb92385f2fb0ae1146bb8f3d73547d90bda6db1Christopher Tate *   - undefined (8 bytes)
60fbb92385f2fb0ae1146bb8f3d73547d90bda6db1Christopher Tate */
61fbb92385f2fb0ae1146bb8f3d73547d90bda6db1Christopher Tate
62fbb92385f2fb0ae1146bb8f3d73547d90bda6db1Christopher Tatestruct file_metadata_v1 {
63fbb92385f2fb0ae1146bb8f3d73547d90bda6db1Christopher Tate    int version;
64fbb92385f2fb0ae1146bb8f3d73547d90bda6db1Christopher Tate    int mode;
65fbb92385f2fb0ae1146bb8f3d73547d90bda6db1Christopher Tate    int undefined_1;
66fbb92385f2fb0ae1146bb8f3d73547d90bda6db1Christopher Tate    int undefined_2;
67fbb92385f2fb0ae1146bb8f3d73547d90bda6db1Christopher Tate};
68fbb92385f2fb0ae1146bb8f3d73547d90bda6db1Christopher Tate
69fbb92385f2fb0ae1146bb8f3d73547d90bda6db1Christopher Tateconst static int CURRENT_METADATA_VERSION = 1;
70fbb92385f2fb0ae1146bb8f3d73547d90bda6db1Christopher Tate
71568bc32344dce841c8f6958f1a65ff839a1b64c0Joe Onorato#if 1
72568bc32344dce841c8f6958f1a65ff839a1b64c0Joe Onorato#define LOGP(f, x...)
73568bc32344dce841c8f6958f1a65ff839a1b64c0Joe Onorato#else
74568bc32344dce841c8f6958f1a65ff839a1b64c0Joe Onorato#if TEST_BACKUP_HELPERS
7523ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato#define LOGP(f, x...) printf(f "\n", x)
764535e40544aeb957d44fad75fbe5676effe03689Joe Onorato#else
775baa3a62a97544669fba6d65a11c07f252e654ddSteve Block#define LOGP(x...) ALOGD(x)
784535e40544aeb957d44fad75fbe5676effe03689Joe Onorato#endif
79568bc32344dce841c8f6958f1a65ff839a1b64c0Joe Onorato#endif
80290bb011c5c1a9ba1f2116810b06cf52a9c36b3eJoe Onorato
813ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onoratoconst static int ROUND_UP[4] = { 0, 3, 2, 1 };
823ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
833ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onoratostatic inline int
843ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onoratoround_up(int n)
853ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato{
863ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    return n + ROUND_UP[n % 4];
873ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato}
883ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
893ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onoratostatic int
903ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onoratoread_snapshot_file(int fd, KeyedVector<String8,FileState>* snapshot)
913ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato{
923ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    int bytesRead = 0;
933ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    int amt;
943ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    SnapshotHeader header;
953ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
963ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    amt = read(fd, &header, sizeof(header));
973ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    if (amt != sizeof(header)) {
983ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        return errno;
993ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    }
1003ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    bytesRead += amt;
1013ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
1023ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    if (header.magic0 != MAGIC0 || header.magic1 != MAGIC1) {
1038564c8da817a845353d213acd8636b76f567b234Steve Block        ALOGW("read_snapshot_file header.magic0=0x%08x magic1=0x%08x", header.magic0, header.magic1);
1043ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        return 1;
1053ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    }
1063ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
1073ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    for (int i=0; i<header.fileCount; i++) {
1083ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        FileState file;
1093ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        char filenameBuf[128];
1103ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
11123ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato        amt = read(fd, &file, sizeof(FileState));
11223ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato        if (amt != sizeof(FileState)) {
1138564c8da817a845353d213acd8636b76f567b234Steve Block            ALOGW("read_snapshot_file FileState truncated/error with read at %d bytes\n", bytesRead);
1143ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato            return 1;
1153ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        }
1163ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        bytesRead += amt;
1173ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
1183ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        // filename is not NULL terminated, but it is padded
1193ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        int nameBufSize = round_up(file.nameLen);
1203ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        char* filename = nameBufSize <= (int)sizeof(filenameBuf)
1213ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato                ? filenameBuf
1223ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato                : (char*)malloc(nameBufSize);
1233ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        amt = read(fd, filename, nameBufSize);
1243ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        if (amt == nameBufSize) {
1253ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato            snapshot->add(String8(filename, file.nameLen), file);
1263ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        }
1273ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        bytesRead += amt;
1283ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        if (filename != filenameBuf) {
1293ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato            free(filename);
1303ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        }
1313ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        if (amt != nameBufSize) {
1328564c8da817a845353d213acd8636b76f567b234Steve Block            ALOGW("read_snapshot_file filename truncated/error with read at %d bytes\n", bytesRead);
1333ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato            return 1;
1343ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        }
1353ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    }
1363ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
1373ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    if (header.totalSize != bytesRead) {
1388564c8da817a845353d213acd8636b76f567b234Steve Block        ALOGW("read_snapshot_file length mismatch: header.totalSize=%d bytesRead=%d\n",
1393ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato                header.totalSize, bytesRead);
1403ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        return 1;
1413ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    }
1423ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
1433ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    return 0;
1443ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato}
1453ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
1463ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onoratostatic int
14723ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onoratowrite_snapshot_file(int fd, const KeyedVector<String8,FileRec>& snapshot)
1483ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato{
149ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato    int fileCount = 0;
1503ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    int bytesWritten = sizeof(SnapshotHeader);
1513ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    // preflight size
1523ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    const int N = snapshot.size();
1533ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    for (int i=0; i<N; i++) {
154ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato        const FileRec& g = snapshot.valueAt(i);
155ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato        if (!g.deleted) {
156ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato            const String8& name = snapshot.keyAt(i);
157ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato            bytesWritten += sizeof(FileState) + round_up(name.length());
158ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato            fileCount++;
159ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato        }
1603ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    }
1613ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
1624535e40544aeb957d44fad75fbe5676effe03689Joe Onorato    LOGP("write_snapshot_file fd=%d\n", fd);
1634535e40544aeb957d44fad75fbe5676effe03689Joe Onorato
1643ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    int amt;
165ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato    SnapshotHeader header = { MAGIC0, fileCount, MAGIC1, bytesWritten };
1663ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
1673ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    amt = write(fd, &header, sizeof(header));
1683ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    if (amt != sizeof(header)) {
1698564c8da817a845353d213acd8636b76f567b234Steve Block        ALOGW("write_snapshot_file error writing header %s", strerror(errno));
1703ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        return errno;
1713ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    }
1723ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
173ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato    for (int i=0; i<N; i++) {
17423ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato        FileRec r = snapshot.valueAt(i);
175ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato        if (!r.deleted) {
176ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato            const String8& name = snapshot.keyAt(i);
177ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato            int nameLen = r.s.nameLen = name.length();
1783ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
179ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato            amt = write(fd, &r.s, sizeof(FileState));
180ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato            if (amt != sizeof(FileState)) {
1818564c8da817a845353d213acd8636b76f567b234Steve Block                ALOGW("write_snapshot_file error writing header %s", strerror(errno));
182ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato                return 1;
183ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato            }
1843ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
185ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato            // filename is not NULL terminated, but it is padded
186ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato            amt = write(fd, name.string(), nameLen);
187ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato            if (amt != nameLen) {
1888564c8da817a845353d213acd8636b76f567b234Steve Block                ALOGW("write_snapshot_file error writing filename %s", strerror(errno));
1893ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato                return 1;
1903ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato            }
191ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato            int paddingLen = ROUND_UP[nameLen % 4];
192ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato            if (paddingLen != 0) {
193ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato                int padding = 0xabababab;
194ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato                amt = write(fd, &padding, paddingLen);
195ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato                if (amt != paddingLen) {
1968564c8da817a845353d213acd8636b76f567b234Steve Block                    ALOGW("write_snapshot_file error writing %d bytes of filename padding %s",
197ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato                            paddingLen, strerror(errno));
198ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato                    return 1;
199ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato                }
200ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato            }
2013ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        }
2023ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    }
2033ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
2043ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    return 0;
2053ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato}
2063ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
2073ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onoratostatic int
208d2110dbce071a236b6176de344ca797b737542ebJoe Onoratowrite_delete_file(BackupDataWriter* dataStream, const String8& key)
2093ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato{
210290bb011c5c1a9ba1f2116810b06cf52a9c36b3eJoe Onorato    LOGP("write_delete_file %s\n", key.string());
211d2110dbce071a236b6176de344ca797b737542ebJoe Onorato    return dataStream->WriteEntityHeader(key, -1);
2123ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato}
2133ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
2143ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onoratostatic int
215fbb92385f2fb0ae1146bb8f3d73547d90bda6db1Christopher Tatewrite_update_file(BackupDataWriter* dataStream, int fd, int mode, const String8& key,
21623ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato        char const* realFilename)
2173ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato{
218fbb92385f2fb0ae1146bb8f3d73547d90bda6db1Christopher Tate    LOGP("write_update_file %s (%s) : mode 0%o\n", realFilename, key.string(), mode);
2193ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
2203ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    const int bufsize = 4*1024;
221d2110dbce071a236b6176de344ca797b737542ebJoe Onorato    int err;
2223ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    int amt;
223d2110dbce071a236b6176de344ca797b737542ebJoe Onorato    int fileSize;
224d2110dbce071a236b6176de344ca797b737542ebJoe Onorato    int bytesLeft;
225fbb92385f2fb0ae1146bb8f3d73547d90bda6db1Christopher Tate    file_metadata_v1 metadata;
226d2110dbce071a236b6176de344ca797b737542ebJoe Onorato
227d2110dbce071a236b6176de344ca797b737542ebJoe Onorato    char* buf = (char*)malloc(bufsize);
228d2110dbce071a236b6176de344ca797b737542ebJoe Onorato    int crc = crc32(0L, Z_NULL, 0);
229d2110dbce071a236b6176de344ca797b737542ebJoe Onorato
230d2110dbce071a236b6176de344ca797b737542ebJoe Onorato
231fbb92385f2fb0ae1146bb8f3d73547d90bda6db1Christopher Tate    fileSize = lseek(fd, 0, SEEK_END);
232d2110dbce071a236b6176de344ca797b737542ebJoe Onorato    lseek(fd, 0, SEEK_SET);
233d2110dbce071a236b6176de344ca797b737542ebJoe Onorato
234fbb92385f2fb0ae1146bb8f3d73547d90bda6db1Christopher Tate    if (sizeof(metadata) != 16) {
2353762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("ERROR: metadata block is the wrong size!");
236fbb92385f2fb0ae1146bb8f3d73547d90bda6db1Christopher Tate    }
237fbb92385f2fb0ae1146bb8f3d73547d90bda6db1Christopher Tate
238fbb92385f2fb0ae1146bb8f3d73547d90bda6db1Christopher Tate    bytesLeft = fileSize + sizeof(metadata);
239d2110dbce071a236b6176de344ca797b737542ebJoe Onorato    err = dataStream->WriteEntityHeader(key, bytesLeft);
240d2110dbce071a236b6176de344ca797b737542ebJoe Onorato    if (err != 0) {
24163bcb79dd437e70593b63cc5a87baab3251c2183Christopher Tate        free(buf);
242d2110dbce071a236b6176de344ca797b737542ebJoe Onorato        return err;
243d2110dbce071a236b6176de344ca797b737542ebJoe Onorato    }
244d2110dbce071a236b6176de344ca797b737542ebJoe Onorato
245fbb92385f2fb0ae1146bb8f3d73547d90bda6db1Christopher Tate    // store the file metadata first
246fbb92385f2fb0ae1146bb8f3d73547d90bda6db1Christopher Tate    metadata.version = tolel(CURRENT_METADATA_VERSION);
247fbb92385f2fb0ae1146bb8f3d73547d90bda6db1Christopher Tate    metadata.mode = tolel(mode);
248fbb92385f2fb0ae1146bb8f3d73547d90bda6db1Christopher Tate    metadata.undefined_1 = metadata.undefined_2 = 0;
249fbb92385f2fb0ae1146bb8f3d73547d90bda6db1Christopher Tate    err = dataStream->WriteEntityData(&metadata, sizeof(metadata));
250fbb92385f2fb0ae1146bb8f3d73547d90bda6db1Christopher Tate    if (err != 0) {
25163bcb79dd437e70593b63cc5a87baab3251c2183Christopher Tate        free(buf);
252fbb92385f2fb0ae1146bb8f3d73547d90bda6db1Christopher Tate        return err;
253fbb92385f2fb0ae1146bb8f3d73547d90bda6db1Christopher Tate    }
254fbb92385f2fb0ae1146bb8f3d73547d90bda6db1Christopher Tate    bytesLeft -= sizeof(metadata); // bytesLeft should == fileSize now
255fbb92385f2fb0ae1146bb8f3d73547d90bda6db1Christopher Tate
256fbb92385f2fb0ae1146bb8f3d73547d90bda6db1Christopher Tate    // now store the file content
257d2110dbce071a236b6176de344ca797b737542ebJoe Onorato    while ((amt = read(fd, buf, bufsize)) != 0 && bytesLeft > 0) {
258d2110dbce071a236b6176de344ca797b737542ebJoe Onorato        bytesLeft -= amt;
259d2110dbce071a236b6176de344ca797b737542ebJoe Onorato        if (bytesLeft < 0) {
260d2110dbce071a236b6176de344ca797b737542ebJoe Onorato            amt += bytesLeft; // Plus a negative is minus.  Don't write more than we promised.
261d2110dbce071a236b6176de344ca797b737542ebJoe Onorato        }
262d2110dbce071a236b6176de344ca797b737542ebJoe Onorato        err = dataStream->WriteEntityData(buf, amt);
263d2110dbce071a236b6176de344ca797b737542ebJoe Onorato        if (err != 0) {
26463bcb79dd437e70593b63cc5a87baab3251c2183Christopher Tate            free(buf);
265d2110dbce071a236b6176de344ca797b737542ebJoe Onorato            return err;
266d2110dbce071a236b6176de344ca797b737542ebJoe Onorato        }
267d2110dbce071a236b6176de344ca797b737542ebJoe Onorato    }
268d2110dbce071a236b6176de344ca797b737542ebJoe Onorato    if (bytesLeft != 0) {
269d2110dbce071a236b6176de344ca797b737542ebJoe Onorato        if (bytesLeft > 0) {
270d2110dbce071a236b6176de344ca797b737542ebJoe Onorato            // Pad out the space we promised in the buffer.  We can't corrupt the buffer,
271d2110dbce071a236b6176de344ca797b737542ebJoe Onorato            // even though the data we're sending is probably bad.
272d2110dbce071a236b6176de344ca797b737542ebJoe Onorato            memset(buf, 0, bufsize);
273d2110dbce071a236b6176de344ca797b737542ebJoe Onorato            while (bytesLeft > 0) {
274d2110dbce071a236b6176de344ca797b737542ebJoe Onorato                amt = bytesLeft < bufsize ? bytesLeft : bufsize;
275d2110dbce071a236b6176de344ca797b737542ebJoe Onorato                bytesLeft -= amt;
276d2110dbce071a236b6176de344ca797b737542ebJoe Onorato                err = dataStream->WriteEntityData(buf, amt);
277d2110dbce071a236b6176de344ca797b737542ebJoe Onorato                if (err != 0) {
27863bcb79dd437e70593b63cc5a87baab3251c2183Christopher Tate                    free(buf);
279d2110dbce071a236b6176de344ca797b737542ebJoe Onorato                    return err;
280d2110dbce071a236b6176de344ca797b737542ebJoe Onorato                }
281d2110dbce071a236b6176de344ca797b737542ebJoe Onorato            }
282d2110dbce071a236b6176de344ca797b737542ebJoe Onorato        }
2833762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("write_update_file size mismatch for %s. expected=%d actual=%d."
28423ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato                " You aren't doing proper locking!", realFilename, fileSize, fileSize-bytesLeft);
285d2110dbce071a236b6176de344ca797b737542ebJoe Onorato    }
286d2110dbce071a236b6176de344ca797b737542ebJoe Onorato
28763bcb79dd437e70593b63cc5a87baab3251c2183Christopher Tate    free(buf);
288d2110dbce071a236b6176de344ca797b737542ebJoe Onorato    return NO_ERROR;
289d2110dbce071a236b6176de344ca797b737542ebJoe Onorato}
290d2110dbce071a236b6176de344ca797b737542ebJoe Onorato
291d2110dbce071a236b6176de344ca797b737542ebJoe Onoratostatic int
29223ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onoratowrite_update_file(BackupDataWriter* dataStream, const String8& key, char const* realFilename)
293d2110dbce071a236b6176de344ca797b737542ebJoe Onorato{
294d2110dbce071a236b6176de344ca797b737542ebJoe Onorato    int err;
295fbb92385f2fb0ae1146bb8f3d73547d90bda6db1Christopher Tate    struct stat st;
296fbb92385f2fb0ae1146bb8f3d73547d90bda6db1Christopher Tate
297fbb92385f2fb0ae1146bb8f3d73547d90bda6db1Christopher Tate    err = stat(realFilename, &st);
298fbb92385f2fb0ae1146bb8f3d73547d90bda6db1Christopher Tate    if (err < 0) {
299fbb92385f2fb0ae1146bb8f3d73547d90bda6db1Christopher Tate        return errno;
300fbb92385f2fb0ae1146bb8f3d73547d90bda6db1Christopher Tate    }
301fbb92385f2fb0ae1146bb8f3d73547d90bda6db1Christopher Tate
30223ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato    int fd = open(realFilename, O_RDONLY);
3033ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    if (fd == -1) {
304d2110dbce071a236b6176de344ca797b737542ebJoe Onorato        return errno;
3053ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    }
306fbb92385f2fb0ae1146bb8f3d73547d90bda6db1Christopher Tate
307fbb92385f2fb0ae1146bb8f3d73547d90bda6db1Christopher Tate    err = write_update_file(dataStream, fd, st.st_mode, key, realFilename);
308d2110dbce071a236b6176de344ca797b737542ebJoe Onorato    close(fd);
309d2110dbce071a236b6176de344ca797b737542ebJoe Onorato    return err;
310d2110dbce071a236b6176de344ca797b737542ebJoe Onorato}
311d2110dbce071a236b6176de344ca797b737542ebJoe Onorato
312d2110dbce071a236b6176de344ca797b737542ebJoe Onoratostatic int
313d2110dbce071a236b6176de344ca797b737542ebJoe Onoratocompute_crc32(int fd)
314d2110dbce071a236b6176de344ca797b737542ebJoe Onorato{
315d2110dbce071a236b6176de344ca797b737542ebJoe Onorato    const int bufsize = 4*1024;
316d2110dbce071a236b6176de344ca797b737542ebJoe Onorato    int amt;
3173ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
3183ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    char* buf = (char*)malloc(bufsize);
3193ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    int crc = crc32(0L, Z_NULL, 0);
3203ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
321d2110dbce071a236b6176de344ca797b737542ebJoe Onorato    lseek(fd, 0, SEEK_SET);
322d2110dbce071a236b6176de344ca797b737542ebJoe Onorato
3233ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    while ((amt = read(fd, buf, bufsize)) != 0) {
3243ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        crc = crc32(crc, (Bytef*)buf, amt);
3253ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    }
3263ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
32763bcb79dd437e70593b63cc5a87baab3251c2183Christopher Tate    free(buf);
3283ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    return crc;
3293ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato}
3303ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
3313ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onoratoint
332d2110dbce071a236b6176de344ca797b737542ebJoe Onoratoback_up_files(int oldSnapshotFD, BackupDataWriter* dataStream, int newSnapshotFD,
33323ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato        char const* const* files, char const* const* keys, int fileCount)
3343ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato{
3353ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    int err;
3363ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    KeyedVector<String8,FileState> oldSnapshot;
33723ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato    KeyedVector<String8,FileRec> newSnapshot;
3383ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
3393ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    if (oldSnapshotFD != -1) {
3403ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        err = read_snapshot_file(oldSnapshotFD, &oldSnapshot);
3413ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        if (err != 0) {
3423ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato            // On an error, treat this as a full backup.
3433ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato            oldSnapshot.clear();
3443ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        }
3453ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    }
3463ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
3473ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    for (int i=0; i<fileCount; i++) {
34823ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato        String8 key(keys[i]);
34923ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato        FileRec r;
350d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato        char const* file = files[i];
351d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato        r.file = file;
3523ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        struct stat st;
3533ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
35423ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato        err = stat(file, &st);
3553ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        if (err != 0) {
356ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato            r.deleted = true;
357ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato        } else {
358ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato            r.deleted = false;
359ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato            r.s.modTime_sec = st.st_mtime;
360ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato            r.s.modTime_nsec = 0; // workaround sim breakage
361ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato            //r.s.modTime_nsec = st.st_mtime_nsec;
36211b157790234d3d2f116ce4c7ed1d3d00fb78bc3Christopher Tate            r.s.mode = st.st_mode;
363ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato            r.s.size = st.st_size;
364ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato            // we compute the crc32 later down below, when we already have the file open.
365ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato
366ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato            if (newSnapshot.indexOfKey(key) >= 0) {
367ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato                LOGP("back_up_files key already in use '%s'", key.string());
368ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato                return -1;
369ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato            }
37023ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato        }
37123ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato        newSnapshot.add(key, r);
3723ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    }
3733ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
3743ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    int n = 0;
3753ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    int N = oldSnapshot.size();
3763ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    int m = 0;
3773ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
3783ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    while (n<N && m<fileCount) {
3793ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        const String8& p = oldSnapshot.keyAt(n);
3803ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        const String8& q = newSnapshot.keyAt(m);
381ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato        FileRec& g = newSnapshot.editValueAt(m);
3823ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        int cmp = p.compare(q);
383ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato        if (g.deleted || cmp < 0) {
3843ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato            // file removed
38523ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato            LOGP("file removed: %s", p.string());
386ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato            g.deleted = true; // They didn't mention the file, but we noticed that it's gone.
387d2110dbce071a236b6176de344ca797b737542ebJoe Onorato            dataStream->WriteEntityHeader(p, -1);
3883ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato            n++;
3893ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        }
390ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato        else if (cmp > 0) {
391ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato            // file added
392d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato            LOGP("file added: %s", g.file.string());
393d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato            write_update_file(dataStream, q, g.file.string());
394ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato            m++;
395ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato        }
3963ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        else {
3973ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato            // both files exist, check them
3983ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato            const FileState& f = oldSnapshot.valueAt(n);
399d2110dbce071a236b6176de344ca797b737542ebJoe Onorato
400d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato            int fd = open(g.file.string(), O_RDONLY);
4010032ce80ac127e6bfb25d727162eee4af208dc77Christopher Tate            if (fd < 0) {
402d2110dbce071a236b6176de344ca797b737542ebJoe Onorato                // We can't open the file.  Don't report it as a delete either.  Let the
403d2110dbce071a236b6176de344ca797b737542ebJoe Onorato                // server keep the old version.  Maybe they'll be able to deal with it
404d2110dbce071a236b6176de344ca797b737542ebJoe Onorato                // on restore.
405d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato                LOGP("Unable to open file %s - skipping", g.file.string());
406d2110dbce071a236b6176de344ca797b737542ebJoe Onorato            } else {
40723ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato                g.s.crc32 = compute_crc32(fd);
408d2110dbce071a236b6176de344ca797b737542ebJoe Onorato
40923ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato                LOGP("%s", q.string());
41011b157790234d3d2f116ce4c7ed1d3d00fb78bc3Christopher Tate                LOGP("  new: modTime=%d,%d mode=%04o size=%-3d crc32=0x%08x",
41111b157790234d3d2f116ce4c7ed1d3d00fb78bc3Christopher Tate                        f.modTime_sec, f.modTime_nsec, f.mode, f.size, f.crc32);
41211b157790234d3d2f116ce4c7ed1d3d00fb78bc3Christopher Tate                LOGP("  old: modTime=%d,%d mode=%04o size=%-3d crc32=0x%08x",
41311b157790234d3d2f116ce4c7ed1d3d00fb78bc3Christopher Tate                        g.s.modTime_sec, g.s.modTime_nsec, g.s.mode, g.s.size, g.s.crc32);
41423ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato                if (f.modTime_sec != g.s.modTime_sec || f.modTime_nsec != g.s.modTime_nsec
41511b157790234d3d2f116ce4c7ed1d3d00fb78bc3Christopher Tate                        || f.mode != g.s.mode || f.size != g.s.size || f.crc32 != g.s.crc32) {
416fbb92385f2fb0ae1146bb8f3d73547d90bda6db1Christopher Tate                    write_update_file(dataStream, fd, g.s.mode, p, g.file.string());
417d2110dbce071a236b6176de344ca797b737542ebJoe Onorato                }
418d2110dbce071a236b6176de344ca797b737542ebJoe Onorato
419d2110dbce071a236b6176de344ca797b737542ebJoe Onorato                close(fd);
4203ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato            }
4213ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato            n++;
4223ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato            m++;
4233ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        }
4243ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    }
4253ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
4263ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    // these were deleted
4273ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    while (n<N) {
428d2110dbce071a236b6176de344ca797b737542ebJoe Onorato        dataStream->WriteEntityHeader(oldSnapshot.keyAt(n), -1);
4293ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        n++;
4303ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    }
4313ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
4323ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    // these were added
4333ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    while (m<fileCount) {
4343ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        const String8& q = newSnapshot.keyAt(m);
43523ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato        FileRec& g = newSnapshot.editValueAt(m);
436d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato        write_update_file(dataStream, q, g.file.string());
4373ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        m++;
4383ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    }
4393ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
4403ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    err = write_snapshot_file(newSnapshotFD, newSnapshot);
4413ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
4423ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    return 0;
4433ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato}
4443ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
4454a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate// Utility function, equivalent to stpcpy(): perform a strcpy, but instead of
4464a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate// returning the initial dest, return a pointer to the trailing NUL.
4474a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tatestatic char* strcpy_ptr(char* dest, const char* str) {
4484a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate    if (dest && str) {
4494a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate        while ((*dest = *str) != 0) {
4504a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate            dest++;
4514a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate            str++;
4524a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate        }
4534a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate    }
4544a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate    return dest;
4554a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate}
4564a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate
45783a7cdc56539d00933c2e25999620cec94c524b6Christopher Tatestatic void calc_tar_checksum(char* buf) {
45883a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate    // [ 148 :   8 ] checksum -- to be calculated with this field as space chars
45983a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate    memset(buf + 148, ' ', 8);
46083a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate
46183a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate    uint16_t sum = 0;
46283a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate    for (uint8_t* p = (uint8_t*) buf; p < ((uint8_t*)buf) + 512; p++) {
46383a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate        sum += *p;
46483a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate    }
46583a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate
46683a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate    // Now write the real checksum value:
46783a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate    // [ 148 :   8 ]  checksum: 6 octal digits [leading zeroes], NUL, SPC
46883a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate    sprintf(buf + 148, "%06o", sum); // the trailing space is already in place
46983a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate}
47083a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate
471dc92c82b4180e8067f1acd00a7db7935afce00ffChristopher Tate// Returns number of bytes written
472dc92c82b4180e8067f1acd00a7db7935afce00ffChristopher Tatestatic int write_pax_header_entry(char* buf, const char* key, const char* value) {
473dc92c82b4180e8067f1acd00a7db7935afce00ffChristopher Tate    // start with the size of "1 key=value\n"
474dc92c82b4180e8067f1acd00a7db7935afce00ffChristopher Tate    int len = strlen(key) + strlen(value) + 4;
475dc92c82b4180e8067f1acd00a7db7935afce00ffChristopher Tate    if (len > 9) len++;
476dc92c82b4180e8067f1acd00a7db7935afce00ffChristopher Tate    if (len > 99) len++;
477dc92c82b4180e8067f1acd00a7db7935afce00ffChristopher Tate    if (len > 999) len++;
478dc92c82b4180e8067f1acd00a7db7935afce00ffChristopher Tate    // since PATH_MAX is 4096 we don't expect to have to generate any single
479dc92c82b4180e8067f1acd00a7db7935afce00ffChristopher Tate    // header entry longer than 9999 characters
480dc92c82b4180e8067f1acd00a7db7935afce00ffChristopher Tate
481dc92c82b4180e8067f1acd00a7db7935afce00ffChristopher Tate    return sprintf(buf, "%d %s=%s\n", len, key, value);
482dc92c82b4180e8067f1acd00a7db7935afce00ffChristopher Tate}
483dc92c82b4180e8067f1acd00a7db7935afce00ffChristopher Tate
4847926a693c4a4f4d2a2d352343bca23e189c7420dChristopher Tate// Wire format to the backup manager service is chunked:  each chunk is prefixed by
4857926a693c4a4f4d2a2d352343bca23e189c7420dChristopher Tate// a 4-byte count of its size.  A chunk size of zero (four zero bytes) indicates EOD.
4867926a693c4a4f4d2a2d352343bca23e189c7420dChristopher Tatevoid send_tarfile_chunk(BackupDataWriter* writer, const char* buffer, size_t size) {
4877926a693c4a4f4d2a2d352343bca23e189c7420dChristopher Tate    uint32_t chunk_size_no = htonl(size);
4887926a693c4a4f4d2a2d352343bca23e189c7420dChristopher Tate    writer->WriteEntityData(&chunk_size_no, 4);
4897926a693c4a4f4d2a2d352343bca23e189c7420dChristopher Tate    if (size != 0) writer->WriteEntityData(buffer, size);
4907926a693c4a4f4d2a2d352343bca23e189c7420dChristopher Tate}
4917926a693c4a4f4d2a2d352343bca23e189c7420dChristopher Tate
4924a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tateint write_tarfile(const String8& packageName, const String8& domain,
4934a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate        const String8& rootpath, const String8& filepath, BackupDataWriter* writer)
4944a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate{
4954a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate    // In the output stream everything is stored relative to the root
4964a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate    const char* relstart = filepath.string() + rootpath.length();
4974a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate    if (*relstart == '/') relstart++;     // won't be true when path == rootpath
4984a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate    String8 relpath(relstart);
4994a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate
50083a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate    // If relpath is empty, it means this is the top of one of the standard named
50183a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate    // domain directories, so we should just skip it
50283a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate    if (relpath.length() == 0) {
50383a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate        return 0;
50483a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate    }
50583a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate
5064a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate    // Too long a name for the ustar format?
5074a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate    //    "apps/" + packagename + '/' + domainpath < 155 chars
5084a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate    //    relpath < 100 chars
50983a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate    bool needExtended = false;
5104a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate    if ((5 + packageName.length() + 1 + domain.length() >= 155) || (relpath.length() >= 100)) {
51183a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate        needExtended = true;
5124a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate    }
5134a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate
5143f6c77b7caa02193205cb6ce180e0eb5a7579aa6Christopher Tate    // Non-7bit-clean path also means needing pax extended format
51575a99709accef8cf221fd436d646727e7c8dd1f1Christopher Tate    if (!needExtended) {
51675a99709accef8cf221fd436d646727e7c8dd1f1Christopher Tate        for (size_t i = 0; i < filepath.length(); i++) {
5173f6c77b7caa02193205cb6ce180e0eb5a7579aa6Christopher Tate            if ((filepath[i] & 0x80) != 0) {
51875a99709accef8cf221fd436d646727e7c8dd1f1Christopher Tate                needExtended = true;
51975a99709accef8cf221fd436d646727e7c8dd1f1Christopher Tate                break;
52075a99709accef8cf221fd436d646727e7c8dd1f1Christopher Tate            }
52175a99709accef8cf221fd436d646727e7c8dd1f1Christopher Tate        }
52275a99709accef8cf221fd436d646727e7c8dd1f1Christopher Tate    }
52375a99709accef8cf221fd436d646727e7c8dd1f1Christopher Tate
5244a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate    int err = 0;
5254a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate    struct stat64 s;
5264a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate    if (lstat64(filepath.string(), &s) != 0) {
5274a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate        err = errno;
5283762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("Error %d (%s) from lstat64(%s)", err, strerror(err), filepath.string());
5294a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate        return err;
5304a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate    }
5314a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate
53283a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate    String8 fullname;   // for pax later on
53383a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate    String8 prefix;
53483a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate
5354a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate    const int isdir = S_ISDIR(s.st_mode);
536e9e78ecd2c0ae5f48ed81fdfff4a89cb803fc409Christopher Tate    if (isdir) s.st_size = 0;   // directories get no actual data in the tar stream
5374a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate
5384a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate    // !!! TODO: use mmap when possible to avoid churning the buffer cache
5394a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate    // !!! TODO: this will break with symlinks; need to use readlink(2)
5404a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate    int fd = open(filepath.string(), O_RDONLY);
5414a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate    if (fd < 0) {
5424a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate        err = errno;
5433762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("Error %d (%s) from open(%s)", err, strerror(err), filepath.string());
5444a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate        return err;
5454a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate    }
5464a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate
5474a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate    // read/write up to this much at a time.
5484a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate    const size_t BUFSIZE = 32 * 1024;
5497e1d395686a23c8638f72af190f125cf690618a3Iliyan Malchev    char* buf = (char *)calloc(1,BUFSIZE);
55083a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate    char* paxHeader = buf + 512;    // use a different chunk of it as separate scratch
55183a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate    char* paxData = buf + 1024;
55283a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate
5534a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate    if (buf == NULL) {
5543762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("Out of mem allocating transfer buffer");
5554a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate        err = ENOMEM;
556294b512ecaa98a6a8ef12285ad14e7a4091b5d57Christopher Tate        goto done;
5574a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate    }
5584a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate
5594a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate    // Magic fields for the ustar file format
5604a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate    strcat(buf + 257, "ustar");
5614a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate    strcat(buf + 263, "00");
5624a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate
56383a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate    // [ 265 : 32 ] user name, ignored on restore
56483a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate    // [ 297 : 32 ] group name, ignored on restore
5654a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate
5664a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate    // [ 100 :   8 ] file mode
56783a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate    snprintf(buf + 100, 8, "%06o ", s.st_mode & ~S_IFMT);
5684a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate
5694a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate    // [ 108 :   8 ] uid -- ignored in Android format; uids are remapped at restore time
5704a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate    // [ 116 :   8 ] gid -- ignored in Android format
57100adb8685ee996f9d2650d617c8c0e98f13ef406Mark Salyzyn    snprintf(buf + 108, 8, "0%lo", (unsigned long)s.st_uid);
57200adb8685ee996f9d2650d617c8c0e98f13ef406Mark Salyzyn    snprintf(buf + 116, 8, "0%lo", (unsigned long)s.st_gid);
5734a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate
5744a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate    // [ 124 :  12 ] file size in bytes
57583a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate    if (s.st_size > 077777777777LL) {
57683a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate        // very large files need a pax extended size header
57783a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate        needExtended = true;
57883a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate    }
57983a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate    snprintf(buf + 124, 12, "%011llo", (isdir) ? 0LL : s.st_size);
5804a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate
5814a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate    // [ 136 :  12 ] last mod time as a UTC time_t
5824a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate    snprintf(buf + 136, 12, "%0lo", s.st_mtime);
5834a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate
5844a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate    // [ 156 :   1 ] link/file type
5854a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate    uint8_t type;
5864a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate    if (isdir) {
5874a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate        type = '5';     // tar magic: '5' == directory
5884a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate    } else if (S_ISREG(s.st_mode)) {
5894a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate        type = '0';     // tar magic: '0' == normal file
5904a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate    } else {
5918564c8da817a845353d213acd8636b76f567b234Steve Block        ALOGW("Error: unknown file mode 0%o [%s]", s.st_mode, filepath.string());
5924a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate        goto cleanup;
5934a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate    }
5944a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate    buf[156] = type;
5954a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate
5964a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate    // [ 157 : 100 ] name of linked file [not implemented]
5974a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate
5984a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate    {
59983a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate        // Prefix and main relative path.  Path lengths have been preflighted.
60083a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate        if (packageName.length() > 0) {
60183a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate            prefix = "apps/";
60283a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate            prefix += packageName;
6034a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate        }
60483a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate        if (domain.length() > 0) {
60583a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate            prefix.appendPath(domain);
60683a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate        }
60783a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate
60883a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate        // pax extended means we don't put in a prefix field, and put a different
60983a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate        // string in the basic name field.  We can also construct the full path name
61083a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate        // out of the substrings we've now built.
61183a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate        fullname = prefix;
61283a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate        fullname.appendPath(relpath);
61383a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate
61483a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate        // ustar:
61583a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate        //    [   0 : 100 ]; file name/path
61683a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate        //    [ 345 : 155 ] filename path prefix
61783a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate        // We only use the prefix area if fullname won't fit in the path
61883a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate        if (fullname.length() > 100) {
61983a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate            strncpy(buf, relpath.string(), 100);
62083a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate            strncpy(buf + 345, prefix.string(), 155);
62183a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate        } else {
62283a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate            strncpy(buf, fullname.string(), 100);
62383a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate        }
62483a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate    }
62583a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate
62683a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate    // [ 329 : 8 ] and [ 337 : 8 ] devmajor/devminor, not used
62783a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate
6286215d3ff4b5dfa52a5d8b9a42e343051f31066a5Steve Block    ALOGI("   Name: %s", fullname.string());
62983a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate
63083a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate    // If we're using a pax extended header, build & write that here; lengths are
63183a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate    // already preflighted
63283a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate    if (needExtended) {
633dc92c82b4180e8067f1acd00a7db7935afce00ffChristopher Tate        char sizeStr[32];   // big enough for a 64-bit unsigned value in decimal
634dc92c82b4180e8067f1acd00a7db7935afce00ffChristopher Tate        char* p = paxData;
635dc92c82b4180e8067f1acd00a7db7935afce00ffChristopher Tate
63683a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate        // construct the pax extended header data block
63783a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate        memset(paxData, 0, BUFSIZE - (paxData - buf));
63883a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate        int len;
63983a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate
64083a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate        // size header -- calc len in digits by actually rendering the number
64183a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate        // to a string - brute force but simple
642f5df700e6ce056ebfa322314d970e52d6facc35aAshok Bhat        snprintf(sizeStr, sizeof(sizeStr), "%lld", (long long)s.st_size);
643dc92c82b4180e8067f1acd00a7db7935afce00ffChristopher Tate        p += write_pax_header_entry(p, "size", sizeStr);
64483a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate
64583a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate        // fullname was generated above with the ustar paths
646dc92c82b4180e8067f1acd00a7db7935afce00ffChristopher Tate        p += write_pax_header_entry(p, "path", fullname.string());
64783a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate
64883a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate        // Now we know how big the pax data is
64983a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate        int paxLen = p - paxData;
65083a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate
65183a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate        // Now build the pax *header* templated on the ustar header
65283a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate        memcpy(paxHeader, buf, 512);
65383a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate
65483a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate        String8 leaf = fullname.getPathLeaf();
65583a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate        memset(paxHeader, 0, 100);                  // rewrite the name area
65683a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate        snprintf(paxHeader, 100, "PaxHeader/%s", leaf.string());
65783a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate        memset(paxHeader + 345, 0, 155);            // rewrite the prefix area
65883a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate        strncpy(paxHeader + 345, prefix.string(), 155);
65983a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate
66083a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate        paxHeader[156] = 'x';                       // mark it as a pax extended header
66183a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate
66283a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate        // [ 124 :  12 ] size of pax extended header data
66383a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate        memset(paxHeader + 124, 0, 12);
664f5df700e6ce056ebfa322314d970e52d6facc35aAshok Bhat        snprintf(paxHeader + 124, 12, "%011o", (unsigned int)(p - paxData));
66583a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate
66683a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate        // Checksum and write the pax block header
66783a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate        calc_tar_checksum(paxHeader);
6687926a693c4a4f4d2a2d352343bca23e189c7420dChristopher Tate        send_tarfile_chunk(writer, paxHeader, 512);
6694a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate
67083a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate        // Now write the pax data itself
67183a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate        int paxblocks = (paxLen + 511) / 512;
6727926a693c4a4f4d2a2d352343bca23e189c7420dChristopher Tate        send_tarfile_chunk(writer, paxData, 512 * paxblocks);
6734a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate    }
6744a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate
67583a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate    // Checksum and write the 512-byte ustar file header block to the output
67683a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate    calc_tar_checksum(buf);
6777926a693c4a4f4d2a2d352343bca23e189c7420dChristopher Tate    send_tarfile_chunk(writer, buf, 512);
6784a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate
6794a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate    // Now write the file data itself, for real files.  We honor tar's convention that
6804a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate    // only full 512-byte blocks are sent to write().
6814a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate    if (!isdir) {
6824a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate        off64_t toWrite = s.st_size;
6834a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate        while (toWrite > 0) {
684f5df700e6ce056ebfa322314d970e52d6facc35aAshok Bhat            size_t toRead = toWrite;
685f5df700e6ce056ebfa322314d970e52d6facc35aAshok Bhat            if (toRead > BUFSIZE) {
686f5df700e6ce056ebfa322314d970e52d6facc35aAshok Bhat                toRead = BUFSIZE;
687f5df700e6ce056ebfa322314d970e52d6facc35aAshok Bhat            }
6884a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate            ssize_t nRead = read(fd, buf, toRead);
6894a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate            if (nRead < 0) {
6904a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate                err = errno;
6913762c311729fe9f3af085c14c5c1fb471d994c03Steve Block                ALOGE("Unable to read file [%s], err=%d (%s)", filepath.string(),
6924a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate                        err, strerror(err));
6934a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate                break;
6944a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate            } else if (nRead == 0) {
6953762c311729fe9f3af085c14c5c1fb471d994c03Steve Block                ALOGE("EOF but expect %lld more bytes in [%s]", (long long) toWrite,
6964a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate                        filepath.string());
6974a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate                err = EIO;
6984a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate                break;
6994a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate            }
7004a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate
7014a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate            // At EOF we might have a short block; NUL-pad that to a 512-byte multiple.  This
7024a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate            // depends on the OS guarantee that for ordinary files, read() will never return
7034a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate            // less than the number of bytes requested.
7044a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate            ssize_t partial = (nRead+512) % 512;
7054a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate            if (partial > 0) {
7064a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate                ssize_t remainder = 512 - partial;
7074a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate                memset(buf + nRead, 0, remainder);
7084a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate                nRead += remainder;
7094a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate            }
7107926a693c4a4f4d2a2d352343bca23e189c7420dChristopher Tate            send_tarfile_chunk(writer, buf, nRead);
7114a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate            toWrite -= nRead;
7124a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate        }
7134a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate    }
7144a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate
7154a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tatecleanup:
7168b2e2c8abc20de5ba3d938d8c559d0c5e2f9e356You Kim    free(buf);
7174a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tatedone:
7184a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate    close(fd);
7194a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate    return err;
7204a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate}
7214a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate// end tarfile
7224a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate
7234a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate
7244a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate
725d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato#define RESTORE_BUF_SIZE (8*1024)
726d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato
727d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe OnoratoRestoreHelperBase::RestoreHelperBase()
728d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato{
729d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato    m_buf = malloc(RESTORE_BUF_SIZE);
73063bcb79dd437e70593b63cc5a87baab3251c2183Christopher Tate    m_loggedUnknownMetadata = false;
731d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato}
732d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato
733d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe OnoratoRestoreHelperBase::~RestoreHelperBase()
734d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato{
735d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato    free(m_buf);
736d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato}
737d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato
738d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onoratostatus_t
739d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe OnoratoRestoreHelperBase::WriteFile(const String8& filename, BackupDataReader* in)
740d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato{
741d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato    ssize_t err;
742d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato    size_t dataSize;
743d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato    String8 key;
744d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato    int fd;
745d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato    void* buf = m_buf;
746d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato    ssize_t amt;
747d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato    int mode;
748d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato    int crc;
749d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato    struct stat st;
750d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato    FileRec r;
751d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato
752d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato    err = in->ReadEntityHeader(&key, &dataSize);
753d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato    if (err != NO_ERROR) {
754d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato        return err;
755d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato    }
7565d605dc56b036232e885f6ec36b888b729673060Joe Onorato
757fbb92385f2fb0ae1146bb8f3d73547d90bda6db1Christopher Tate    // Get the metadata block off the head of the file entity and use that to
758fbb92385f2fb0ae1146bb8f3d73547d90bda6db1Christopher Tate    // set up the output file
759fbb92385f2fb0ae1146bb8f3d73547d90bda6db1Christopher Tate    file_metadata_v1 metadata;
760fbb92385f2fb0ae1146bb8f3d73547d90bda6db1Christopher Tate    amt = in->ReadEntityData(&metadata, sizeof(metadata));
761fbb92385f2fb0ae1146bb8f3d73547d90bda6db1Christopher Tate    if (amt != sizeof(metadata)) {
7628564c8da817a845353d213acd8636b76f567b234Steve Block        ALOGW("Could not read metadata for %s -- %ld / %s", filename.string(),
763fbb92385f2fb0ae1146bb8f3d73547d90bda6db1Christopher Tate                (long)amt, strerror(errno));
764fbb92385f2fb0ae1146bb8f3d73547d90bda6db1Christopher Tate        return EIO;
765fbb92385f2fb0ae1146bb8f3d73547d90bda6db1Christopher Tate    }
766fbb92385f2fb0ae1146bb8f3d73547d90bda6db1Christopher Tate    metadata.version = fromlel(metadata.version);
767fbb92385f2fb0ae1146bb8f3d73547d90bda6db1Christopher Tate    metadata.mode = fromlel(metadata.mode);
768fbb92385f2fb0ae1146bb8f3d73547d90bda6db1Christopher Tate    if (metadata.version > CURRENT_METADATA_VERSION) {
76963bcb79dd437e70593b63cc5a87baab3251c2183Christopher Tate        if (!m_loggedUnknownMetadata) {
77063bcb79dd437e70593b63cc5a87baab3251c2183Christopher Tate            m_loggedUnknownMetadata = true;
7718564c8da817a845353d213acd8636b76f567b234Steve Block            ALOGW("Restoring file with unsupported metadata version %d (currently %d)",
77263bcb79dd437e70593b63cc5a87baab3251c2183Christopher Tate                    metadata.version, CURRENT_METADATA_VERSION);
77363bcb79dd437e70593b63cc5a87baab3251c2183Christopher Tate        }
774fbb92385f2fb0ae1146bb8f3d73547d90bda6db1Christopher Tate    }
775fbb92385f2fb0ae1146bb8f3d73547d90bda6db1Christopher Tate    mode = metadata.mode;
776d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato
777d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato    // Write the file and compute the crc
778d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato    crc = crc32(0L, Z_NULL, 0);
7795d605dc56b036232e885f6ec36b888b729673060Joe Onorato    fd = open(filename.string(), O_CREAT|O_RDWR|O_TRUNC, mode);
7805d605dc56b036232e885f6ec36b888b729673060Joe Onorato    if (fd == -1) {
7818564c8da817a845353d213acd8636b76f567b234Steve Block        ALOGW("Could not open file %s -- %s", filename.string(), strerror(errno));
782d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato        return errno;
783d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato    }
78400adb8685ee996f9d2650d617c8c0e98f13ef406Mark Salyzyn
785d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato    while ((amt = in->ReadEntityData(buf, RESTORE_BUF_SIZE)) > 0) {
786d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato        err = write(fd, buf, amt);
787d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato        if (err != amt) {
788d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato            close(fd);
7898564c8da817a845353d213acd8636b76f567b234Steve Block            ALOGW("Error '%s' writing '%s'", strerror(errno), filename.string());
790d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato            return errno;
791d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato        }
792d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato        crc = crc32(crc, (Bytef*)buf, amt);
793d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato    }
794d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato
795d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato    close(fd);
796d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato
797d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato    // Record for the snapshot
798d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato    err = stat(filename.string(), &st);
799d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato    if (err != 0) {
8008564c8da817a845353d213acd8636b76f567b234Steve Block        ALOGW("Error stating file that we just created %s", filename.string());
801d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato        return errno;
802d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato    }
803d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato
804d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato    r.file = filename;
805d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato    r.deleted = false;
806d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato    r.s.modTime_sec = st.st_mtime;
807d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato    r.s.modTime_nsec = 0; // workaround sim breakage
808d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato    //r.s.modTime_nsec = st.st_mtime_nsec;
80911b157790234d3d2f116ce4c7ed1d3d00fb78bc3Christopher Tate    r.s.mode = st.st_mode;
810d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato    r.s.size = st.st_size;
811d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato    r.s.crc32 = crc;
812d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato
813d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato    m_files.add(key, r);
814d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato
815d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato    return NO_ERROR;
816d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato}
817d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato
818d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onoratostatus_t
819d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe OnoratoRestoreHelperBase::WriteSnapshot(int fd)
820d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato{
821d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato    return write_snapshot_file(fd, m_files);;
822d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato}
823d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato
8243ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato#if TEST_BACKUP_HELPERS
8253ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
8263ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato#define SCRATCH_DIR "/data/backup_helper_test/"
8273ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
8283ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onoratostatic int
8293ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onoratowrite_text_file(const char* path, const char* data)
8303ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato{
8313ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    int amt;
8323ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    int fd;
8333ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    int len;
8343ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
8353ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    fd = creat(path, 0666);
8363ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    if (fd == -1) {
8373ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        fprintf(stderr, "creat %s failed\n", path);
8383ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        return errno;
8393ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    }
8403ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
8413ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    len = strlen(data);
8423ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    amt = write(fd, data, len);
8433ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    if (amt != len) {
8443ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        fprintf(stderr, "error (%s) writing to file %s\n", strerror(errno), path);
8453ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        return errno;
8463ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    }
8473ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
8483ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    close(fd);
8493ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
8503ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    return 0;
8513ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato}
8523ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
8533ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onoratostatic int
8543ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onoratocompare_file(const char* path, const unsigned char* data, int len)
8553ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato{
8563ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    int fd;
8573ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    int amt;
8583ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
8593ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    fd = open(path, O_RDONLY);
8603ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    if (fd == -1) {
8613ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        fprintf(stderr, "compare_file error (%s) opening %s\n", strerror(errno), path);
8623ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        return errno;
8633ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    }
8643ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
8653ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    unsigned char* contents = (unsigned char*)malloc(len);
8663ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    if (contents == NULL) {
8673ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        fprintf(stderr, "malloc(%d) failed\n", len);
8683ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        return ENOMEM;
8693ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    }
8703ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
8713ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    bool sizesMatch = true;
8723ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    amt = lseek(fd, 0, SEEK_END);
8733ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    if (amt != len) {
8743ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        fprintf(stderr, "compare_file file length should be %d, was %d\n", len, amt);
8753ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        sizesMatch = false;
8763ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    }
8773ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    lseek(fd, 0, SEEK_SET);
8783ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
8793ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    int readLen = amt < len ? amt : len;
8803ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    amt = read(fd, contents, readLen);
8813ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    if (amt != readLen) {
8823ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        fprintf(stderr, "compare_file read expected %d bytes but got %d\n", len, amt);
8833ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    }
8843ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
8853ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    bool contentsMatch = true;
8863ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    for (int i=0; i<readLen; i++) {
8873ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        if (data[i] != contents[i]) {
8883ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato            if (contentsMatch) {
8893ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato                fprintf(stderr, "compare_file contents are different: (index, expected, actual)\n");
8903ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato                contentsMatch = false;
8913ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato            }
8923ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato            fprintf(stderr, "  [%-2d] %02x %02x\n", i, data[i], contents[i]);
8933ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        }
8943ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    }
8953ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
89663bcb79dd437e70593b63cc5a87baab3251c2183Christopher Tate    free(contents);
8973ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    return contentsMatch && sizesMatch ? 0 : 1;
8983ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato}
8993ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
9003ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onoratoint
9013ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onoratobackup_helper_test_empty()
9023ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato{
9033ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    int err;
9043ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    int fd;
90523ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato    KeyedVector<String8,FileRec> snapshot;
9063ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    const char* filename = SCRATCH_DIR "backup_helper_test_empty.snap";
9073ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
9083ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    system("rm -r " SCRATCH_DIR);
9093ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    mkdir(SCRATCH_DIR, 0777);
9103ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
9113ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    // write
9123ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    fd = creat(filename, 0666);
9133ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    if (fd == -1) {
9143ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        fprintf(stderr, "error creating %s\n", filename);
9153ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        return 1;
9163ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    }
9173ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
9183ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    err = write_snapshot_file(fd, snapshot);
9193ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
9203ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    close(fd);
9213ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
9223ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    if (err != 0) {
9233ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        fprintf(stderr, "write_snapshot_file reported error %d (%s)\n", err, strerror(err));
9243ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        return err;
9253ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    }
9263ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
9273ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    static const unsigned char correct_data[] = {
9283ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        0x53, 0x6e, 0x61, 0x70,  0x00, 0x00, 0x00, 0x00,
9293ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        0x46, 0x69, 0x6c, 0x65,  0x10, 0x00, 0x00, 0x00
9303ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    };
9313ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
9323ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    err = compare_file(filename, correct_data, sizeof(correct_data));
9333ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    if (err != 0) {
9343ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        return err;
9353ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    }
9363ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
9373ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    // read
9383ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    fd = open(filename, O_RDONLY);
9393ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    if (fd == -1) {
9403ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        fprintf(stderr, "error opening for read %s\n", filename);
9413ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        return 1;
9423ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    }
9433ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
9443ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    KeyedVector<String8,FileState> readSnapshot;
9453ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    err = read_snapshot_file(fd, &readSnapshot);
9463ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    if (err != 0) {
9473ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        fprintf(stderr, "read_snapshot_file failed %d\n", err);
9483ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        return err;
9493ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    }
9503ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
9513ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    if (readSnapshot.size() != 0) {
9523ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        fprintf(stderr, "readSnapshot should be length 0\n");
9533ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        return 1;
9543ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    }
9553ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
9563ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    return 0;
9573ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato}
9583ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
9593ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onoratoint
9603ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onoratobackup_helper_test_four()
9613ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato{
9623ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    int err;
9633ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    int fd;
96423ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato    KeyedVector<String8,FileRec> snapshot;
9653ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    const char* filename = SCRATCH_DIR "backup_helper_test_four.snap";
9663ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
9673ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    system("rm -r " SCRATCH_DIR);
9683ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    mkdir(SCRATCH_DIR, 0777);
9693ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
9703ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    // write
9713ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    fd = creat(filename, 0666);
9723ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    if (fd == -1) {
9733ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        fprintf(stderr, "error opening %s\n", filename);
9743ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        return 1;
9753ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    }
9763ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
9773ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    String8 filenames[4];
9783ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    FileState states[4];
97923ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato    FileRec r;
980ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato    r.deleted = false;
9813ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
9823ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    states[0].modTime_sec = 0xfedcba98;
9833ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    states[0].modTime_nsec = 0xdeadbeef;
98411b157790234d3d2f116ce4c7ed1d3d00fb78bc3Christopher Tate    states[0].mode = 0777; // decimal 511, hex 0x000001ff
9853ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    states[0].size = 0xababbcbc;
9863ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    states[0].crc32 = 0x12345678;
9873ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    states[0].nameLen = -12;
98823ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato    r.s = states[0];
9893ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    filenames[0] = String8("bytes_of_padding");
99023ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato    snapshot.add(filenames[0], r);
9913ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
9923ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    states[1].modTime_sec = 0x93400031;
9933ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    states[1].modTime_nsec = 0xdeadbeef;
99411b157790234d3d2f116ce4c7ed1d3d00fb78bc3Christopher Tate    states[1].mode = 0666; // decimal 438, hex 0x000001b6
9953ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    states[1].size = 0x88557766;
9963ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    states[1].crc32 = 0x22334422;
9973ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    states[1].nameLen = -1;
99823ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato    r.s = states[1];
9993ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    filenames[1] = String8("bytes_of_padding3");
100023ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato    snapshot.add(filenames[1], r);
10013ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
10023ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    states[2].modTime_sec = 0x33221144;
10033ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    states[2].modTime_nsec = 0xdeadbeef;
100411b157790234d3d2f116ce4c7ed1d3d00fb78bc3Christopher Tate    states[2].mode = 0744; // decimal 484, hex 0x000001e4
10053ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    states[2].size = 0x11223344;
10063ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    states[2].crc32 = 0x01122334;
10073ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    states[2].nameLen = 0;
100823ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato    r.s = states[2];
10093ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    filenames[2] = String8("bytes_of_padding_2");
101023ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato    snapshot.add(filenames[2], r);
10113ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
10123ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    states[3].modTime_sec = 0x33221144;
10133ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    states[3].modTime_nsec = 0xdeadbeef;
101411b157790234d3d2f116ce4c7ed1d3d00fb78bc3Christopher Tate    states[3].mode = 0755; // decimal 493, hex 0x000001ed
10153ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    states[3].size = 0x11223344;
10163ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    states[3].crc32 = 0x01122334;
10173ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    states[3].nameLen = 0;
101823ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato    r.s = states[3];
10193ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    filenames[3] = String8("bytes_of_padding__1");
102023ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato    snapshot.add(filenames[3], r);
10213ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
10223ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    err = write_snapshot_file(fd, snapshot);
10233ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
10243ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    close(fd);
10253ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
10263ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    if (err != 0) {
10273ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        fprintf(stderr, "write_snapshot_file reported error %d (%s)\n", err, strerror(err));
10283ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        return err;
10293ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    }
10303ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
10313ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    static const unsigned char correct_data[] = {
10323ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        // header
10333ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        0x53, 0x6e, 0x61, 0x70,  0x04, 0x00, 0x00, 0x00,
103411b157790234d3d2f116ce4c7ed1d3d00fb78bc3Christopher Tate        0x46, 0x69, 0x6c, 0x65,  0xbc, 0x00, 0x00, 0x00,
10353ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
10363ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        // bytes_of_padding
10373ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        0x98, 0xba, 0xdc, 0xfe,  0xef, 0xbe, 0xad, 0xde,
103811b157790234d3d2f116ce4c7ed1d3d00fb78bc3Christopher Tate        0xff, 0x01, 0x00, 0x00,  0xbc, 0xbc, 0xab, 0xab,
103911b157790234d3d2f116ce4c7ed1d3d00fb78bc3Christopher Tate        0x78, 0x56, 0x34, 0x12,  0x10, 0x00, 0x00, 0x00,
104011b157790234d3d2f116ce4c7ed1d3d00fb78bc3Christopher Tate        0x62, 0x79, 0x74, 0x65,  0x73, 0x5f, 0x6f, 0x66,
104111b157790234d3d2f116ce4c7ed1d3d00fb78bc3Christopher Tate        0x5f, 0x70, 0x61, 0x64,  0x64, 0x69, 0x6e, 0x67,
10423ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
10433ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        // bytes_of_padding3
10443ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        0x31, 0x00, 0x40, 0x93,  0xef, 0xbe, 0xad, 0xde,
104511b157790234d3d2f116ce4c7ed1d3d00fb78bc3Christopher Tate        0xb6, 0x01, 0x00, 0x00,  0x66, 0x77, 0x55, 0x88,
104611b157790234d3d2f116ce4c7ed1d3d00fb78bc3Christopher Tate        0x22, 0x44, 0x33, 0x22,  0x11, 0x00, 0x00, 0x00,
104711b157790234d3d2f116ce4c7ed1d3d00fb78bc3Christopher Tate        0x62, 0x79, 0x74, 0x65,  0x73, 0x5f, 0x6f, 0x66,
104811b157790234d3d2f116ce4c7ed1d3d00fb78bc3Christopher Tate        0x5f, 0x70, 0x61, 0x64,  0x64, 0x69, 0x6e, 0x67,
104911b157790234d3d2f116ce4c7ed1d3d00fb78bc3Christopher Tate        0x33, 0xab, 0xab, 0xab,
1050f4c46b94b867f6a01bf7d0be18f667819338072fNicolas Catania
10513ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        // bytes of padding2
10523ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        0x44, 0x11, 0x22, 0x33,  0xef, 0xbe, 0xad, 0xde,
105311b157790234d3d2f116ce4c7ed1d3d00fb78bc3Christopher Tate        0xe4, 0x01, 0x00, 0x00,  0x44, 0x33, 0x22, 0x11,
105411b157790234d3d2f116ce4c7ed1d3d00fb78bc3Christopher Tate        0x34, 0x23, 0x12, 0x01,  0x12, 0x00, 0x00, 0x00,
105511b157790234d3d2f116ce4c7ed1d3d00fb78bc3Christopher Tate        0x62, 0x79, 0x74, 0x65,  0x73, 0x5f, 0x6f, 0x66,
105611b157790234d3d2f116ce4c7ed1d3d00fb78bc3Christopher Tate        0x5f, 0x70, 0x61, 0x64,  0x64, 0x69, 0x6e, 0x67,
105711b157790234d3d2f116ce4c7ed1d3d00fb78bc3Christopher Tate        0x5f, 0x32, 0xab, 0xab,
1058f4c46b94b867f6a01bf7d0be18f667819338072fNicolas Catania
10593ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        // bytes of padding3
10603ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        0x44, 0x11, 0x22, 0x33,  0xef, 0xbe, 0xad, 0xde,
106111b157790234d3d2f116ce4c7ed1d3d00fb78bc3Christopher Tate        0xed, 0x01, 0x00, 0x00,  0x44, 0x33, 0x22, 0x11,
106211b157790234d3d2f116ce4c7ed1d3d00fb78bc3Christopher Tate        0x34, 0x23, 0x12, 0x01,  0x13, 0x00, 0x00, 0x00,
106311b157790234d3d2f116ce4c7ed1d3d00fb78bc3Christopher Tate        0x62, 0x79, 0x74, 0x65,  0x73, 0x5f, 0x6f, 0x66,
106411b157790234d3d2f116ce4c7ed1d3d00fb78bc3Christopher Tate        0x5f, 0x70, 0x61, 0x64,  0x64, 0x69, 0x6e, 0x67,
106511b157790234d3d2f116ce4c7ed1d3d00fb78bc3Christopher Tate        0x5f, 0x5f, 0x31, 0xab
10663ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    };
10673ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
10683ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    err = compare_file(filename, correct_data, sizeof(correct_data));
10693ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    if (err != 0) {
10703ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        return err;
10713ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    }
1072f4c46b94b867f6a01bf7d0be18f667819338072fNicolas Catania
10733ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    // read
10743ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    fd = open(filename, O_RDONLY);
10753ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    if (fd == -1) {
10763ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        fprintf(stderr, "error opening for read %s\n", filename);
10773ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        return 1;
10783ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    }
10793ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
10803ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
10813ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    KeyedVector<String8,FileState> readSnapshot;
10823ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    err = read_snapshot_file(fd, &readSnapshot);
10833ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    if (err != 0) {
10843ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        fprintf(stderr, "read_snapshot_file failed %d\n", err);
10853ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        return err;
10863ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    }
10873ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
10883ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    if (readSnapshot.size() != 4) {
108995ece35c2f8b86203e88b49d67cef8e80e107a2bKévin PETIT        fprintf(stderr, "readSnapshot should be length 4 is %zu\n", readSnapshot.size());
10903ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        return 1;
10913ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    }
10923ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
10933ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    bool matched = true;
10943ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    for (size_t i=0; i<readSnapshot.size(); i++) {
10953ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        const String8& name = readSnapshot.keyAt(i);
10963ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        const FileState state = readSnapshot.valueAt(i);
10973ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
10983ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        if (name != filenames[i] || states[i].modTime_sec != state.modTime_sec
109911b157790234d3d2f116ce4c7ed1d3d00fb78bc3Christopher Tate                || states[i].modTime_nsec != state.modTime_nsec || states[i].mode != state.mode
11003ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato                || states[i].size != state.size || states[i].crc32 != states[i].crc32) {
1101f5df700e6ce056ebfa322314d970e52d6facc35aAshok Bhat            fprintf(stderr, "state %zu expected={%d/%d, %04o, 0x%08x, 0x%08x, %3zu} '%s'\n"
1102f5df700e6ce056ebfa322314d970e52d6facc35aAshok Bhat                            "          actual={%d/%d, %04o, 0x%08x, 0x%08x, %3d} '%s'\n", i,
110311b157790234d3d2f116ce4c7ed1d3d00fb78bc3Christopher Tate                    states[i].modTime_sec, states[i].modTime_nsec, states[i].mode, states[i].size,
110411b157790234d3d2f116ce4c7ed1d3d00fb78bc3Christopher Tate                    states[i].crc32, name.length(), filenames[i].string(),
110511b157790234d3d2f116ce4c7ed1d3d00fb78bc3Christopher Tate                    state.modTime_sec, state.modTime_nsec, state.mode, state.size, state.crc32,
110611b157790234d3d2f116ce4c7ed1d3d00fb78bc3Christopher Tate                    state.nameLen, name.string());
11073ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato            matched = false;
11083ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        }
11093ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    }
1110f4c46b94b867f6a01bf7d0be18f667819338072fNicolas Catania
11113ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    return matched ? 0 : 1;
11123ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato}
11133ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
11144535e40544aeb957d44fad75fbe5676effe03689Joe Onorato// hexdump -v -e '"    " 8/1 " 0x%02x," "\n"' data_writer.data
11154535e40544aeb957d44fad75fbe5676effe03689Joe Onoratoconst unsigned char DATA_GOLDEN_FILE[] = {
11162e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato     0x44, 0x61, 0x74, 0x61, 0x0b, 0x00, 0x00, 0x00,
11172e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato     0x0c, 0x00, 0x00, 0x00, 0x6e, 0x6f, 0x5f, 0x70,
11184535e40544aeb957d44fad75fbe5676effe03689Joe Onorato     0x61, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x5f, 0x00,
11192e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato     0x6e, 0x6f, 0x5f, 0x70, 0x61, 0x64, 0x64, 0x69,
11205f15d151b5101fadfe6cba1e8f4aa6367e8c603eJoe Onorato     0x6e, 0x67, 0x5f, 0x00, 0x44, 0x61, 0x74, 0x61,
11215f15d151b5101fadfe6cba1e8f4aa6367e8c603eJoe Onorato     0x0c, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00,
11224535e40544aeb957d44fad75fbe5676effe03689Joe Onorato     0x70, 0x61, 0x64, 0x64, 0x65, 0x64, 0x5f, 0x74,
11234535e40544aeb957d44fad75fbe5676effe03689Joe Onorato     0x6f, 0x5f, 0x5f, 0x33, 0x00, 0xbc, 0xbc, 0xbc,
11244535e40544aeb957d44fad75fbe5676effe03689Joe Onorato     0x70, 0x61, 0x64, 0x64, 0x65, 0x64, 0x5f, 0x74,
11255f15d151b5101fadfe6cba1e8f4aa6367e8c603eJoe Onorato     0x6f, 0x5f, 0x5f, 0x33, 0x00, 0xbc, 0xbc, 0xbc,
11262e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato     0x44, 0x61, 0x74, 0x61, 0x0d, 0x00, 0x00, 0x00,
11272e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato     0x0e, 0x00, 0x00, 0x00, 0x70, 0x61, 0x64, 0x64,
11282e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato     0x65, 0x64, 0x5f, 0x74, 0x6f, 0x5f, 0x32, 0x5f,
11292e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato     0x5f, 0x00, 0xbc, 0xbc, 0x70, 0x61, 0x64, 0x64,
11302e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato     0x65, 0x64, 0x5f, 0x74, 0x6f, 0x5f, 0x32, 0x5f,
11315f15d151b5101fadfe6cba1e8f4aa6367e8c603eJoe Onorato     0x5f, 0x00, 0xbc, 0xbc, 0x44, 0x61, 0x74, 0x61,
11324535e40544aeb957d44fad75fbe5676effe03689Joe Onorato     0x0a, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00,
11334535e40544aeb957d44fad75fbe5676effe03689Joe Onorato     0x70, 0x61, 0x64, 0x64, 0x65, 0x64, 0x5f, 0x74,
11344535e40544aeb957d44fad75fbe5676effe03689Joe Onorato     0x6f, 0x31, 0x00, 0xbc, 0x70, 0x61, 0x64, 0x64,
11355f15d151b5101fadfe6cba1e8f4aa6367e8c603eJoe Onorato     0x65, 0x64, 0x5f, 0x74, 0x6f, 0x31, 0x00
11365f15d151b5101fadfe6cba1e8f4aa6367e8c603eJoe Onorato
11374535e40544aeb957d44fad75fbe5676effe03689Joe Onorato};
11384535e40544aeb957d44fad75fbe5676effe03689Joe Onoratoconst int DATA_GOLDEN_FILE_SIZE = sizeof(DATA_GOLDEN_FILE);
11394535e40544aeb957d44fad75fbe5676effe03689Joe Onorato
11404535e40544aeb957d44fad75fbe5676effe03689Joe Onoratostatic int
11414535e40544aeb957d44fad75fbe5676effe03689Joe Onoratotest_write_header_and_entity(BackupDataWriter& writer, const char* str)
11424535e40544aeb957d44fad75fbe5676effe03689Joe Onorato{
11434535e40544aeb957d44fad75fbe5676effe03689Joe Onorato    int err;
11444535e40544aeb957d44fad75fbe5676effe03689Joe Onorato    String8 text(str);
11454535e40544aeb957d44fad75fbe5676effe03689Joe Onorato
11464535e40544aeb957d44fad75fbe5676effe03689Joe Onorato    err = writer.WriteEntityHeader(text, text.length()+1);
11474535e40544aeb957d44fad75fbe5676effe03689Joe Onorato    if (err != 0) {
11484535e40544aeb957d44fad75fbe5676effe03689Joe Onorato        fprintf(stderr, "WriteEntityHeader failed with %s\n", strerror(err));
11494535e40544aeb957d44fad75fbe5676effe03689Joe Onorato        return err;
11504535e40544aeb957d44fad75fbe5676effe03689Joe Onorato    }
11514535e40544aeb957d44fad75fbe5676effe03689Joe Onorato
11524535e40544aeb957d44fad75fbe5676effe03689Joe Onorato    err = writer.WriteEntityData(text.string(), text.length()+1);
11534535e40544aeb957d44fad75fbe5676effe03689Joe Onorato    if (err != 0) {
11544535e40544aeb957d44fad75fbe5676effe03689Joe Onorato        fprintf(stderr, "write failed for data '%s'\n", text.string());
11554535e40544aeb957d44fad75fbe5676effe03689Joe Onorato        return errno;
11564535e40544aeb957d44fad75fbe5676effe03689Joe Onorato    }
11574535e40544aeb957d44fad75fbe5676effe03689Joe Onorato
11584535e40544aeb957d44fad75fbe5676effe03689Joe Onorato    return err;
11594535e40544aeb957d44fad75fbe5676effe03689Joe Onorato}
11604535e40544aeb957d44fad75fbe5676effe03689Joe Onorato
11614535e40544aeb957d44fad75fbe5676effe03689Joe Onoratoint
11624535e40544aeb957d44fad75fbe5676effe03689Joe Onoratobackup_helper_test_data_writer()
11634535e40544aeb957d44fad75fbe5676effe03689Joe Onorato{
11644535e40544aeb957d44fad75fbe5676effe03689Joe Onorato    int err;
11654535e40544aeb957d44fad75fbe5676effe03689Joe Onorato    int fd;
11664535e40544aeb957d44fad75fbe5676effe03689Joe Onorato    const char* filename = SCRATCH_DIR "data_writer.data";
11674535e40544aeb957d44fad75fbe5676effe03689Joe Onorato
11684535e40544aeb957d44fad75fbe5676effe03689Joe Onorato    system("rm -r " SCRATCH_DIR);
11694535e40544aeb957d44fad75fbe5676effe03689Joe Onorato    mkdir(SCRATCH_DIR, 0777);
11704535e40544aeb957d44fad75fbe5676effe03689Joe Onorato    mkdir(SCRATCH_DIR "data", 0777);
1171f4c46b94b867f6a01bf7d0be18f667819338072fNicolas Catania
11724535e40544aeb957d44fad75fbe5676effe03689Joe Onorato    fd = creat(filename, 0666);
11734535e40544aeb957d44fad75fbe5676effe03689Joe Onorato    if (fd == -1) {
11744535e40544aeb957d44fad75fbe5676effe03689Joe Onorato        fprintf(stderr, "error creating: %s\n", strerror(errno));
11754535e40544aeb957d44fad75fbe5676effe03689Joe Onorato        return errno;
11764535e40544aeb957d44fad75fbe5676effe03689Joe Onorato    }
11774535e40544aeb957d44fad75fbe5676effe03689Joe Onorato
11784535e40544aeb957d44fad75fbe5676effe03689Joe Onorato    BackupDataWriter writer(fd);
11794535e40544aeb957d44fad75fbe5676effe03689Joe Onorato
11804535e40544aeb957d44fad75fbe5676effe03689Joe Onorato    err = 0;
11814535e40544aeb957d44fad75fbe5676effe03689Joe Onorato    err |= test_write_header_and_entity(writer, "no_padding_");
11824535e40544aeb957d44fad75fbe5676effe03689Joe Onorato    err |= test_write_header_and_entity(writer, "padded_to__3");
11834535e40544aeb957d44fad75fbe5676effe03689Joe Onorato    err |= test_write_header_and_entity(writer, "padded_to_2__");
11844535e40544aeb957d44fad75fbe5676effe03689Joe Onorato    err |= test_write_header_and_entity(writer, "padded_to1");
11854535e40544aeb957d44fad75fbe5676effe03689Joe Onorato
11864535e40544aeb957d44fad75fbe5676effe03689Joe Onorato    close(fd);
11874535e40544aeb957d44fad75fbe5676effe03689Joe Onorato
11884535e40544aeb957d44fad75fbe5676effe03689Joe Onorato    err = compare_file(filename, DATA_GOLDEN_FILE, DATA_GOLDEN_FILE_SIZE);
11894535e40544aeb957d44fad75fbe5676effe03689Joe Onorato    if (err != 0) {
11904535e40544aeb957d44fad75fbe5676effe03689Joe Onorato        return err;
11914535e40544aeb957d44fad75fbe5676effe03689Joe Onorato    }
11924535e40544aeb957d44fad75fbe5676effe03689Joe Onorato
11934535e40544aeb957d44fad75fbe5676effe03689Joe Onorato    return err;
11944535e40544aeb957d44fad75fbe5676effe03689Joe Onorato}
11954535e40544aeb957d44fad75fbe5676effe03689Joe Onorato
11962e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onoratoint
11972e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onoratotest_read_header_and_entity(BackupDataReader& reader, const char* str)
11982e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato{
11992e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    int err;
1200f5df700e6ce056ebfa322314d970e52d6facc35aAshok Bhat    size_t bufSize = strlen(str)+1;
12012e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    char* buf = (char*)malloc(bufSize);
12022e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    String8 string;
12032e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    int cookie = 0x11111111;
12042e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    size_t actualSize;
12055f15d151b5101fadfe6cba1e8f4aa6367e8c603eJoe Onorato    bool done;
12065f15d151b5101fadfe6cba1e8f4aa6367e8c603eJoe Onorato    int type;
120711b157790234d3d2f116ce4c7ed1d3d00fb78bc3Christopher Tate    ssize_t nRead;
12082e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato
12092e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    // printf("\n\n---------- test_read_header_and_entity -- %s\n\n", str);
12102e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato
12115f15d151b5101fadfe6cba1e8f4aa6367e8c603eJoe Onorato    err = reader.ReadNextHeader(&done, &type);
12125f15d151b5101fadfe6cba1e8f4aa6367e8c603eJoe Onorato    if (done) {
12135f15d151b5101fadfe6cba1e8f4aa6367e8c603eJoe Onorato        fprintf(stderr, "should not be done yet\n");
12145f15d151b5101fadfe6cba1e8f4aa6367e8c603eJoe Onorato        goto finished;
12152e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    }
12162e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    if (err != 0) {
12175f15d151b5101fadfe6cba1e8f4aa6367e8c603eJoe Onorato        fprintf(stderr, "ReadNextHeader (for app header) failed with %s\n", strerror(err));
12185f15d151b5101fadfe6cba1e8f4aa6367e8c603eJoe Onorato        goto finished;
12192e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    }
12205f15d151b5101fadfe6cba1e8f4aa6367e8c603eJoe Onorato    if (type != BACKUP_HEADER_ENTITY_V1) {
12212e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato        err = EINVAL;
12225f15d151b5101fadfe6cba1e8f4aa6367e8c603eJoe Onorato        fprintf(stderr, "type=0x%08x expected 0x%08x\n", type, BACKUP_HEADER_ENTITY_V1);
12232e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    }
12242e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato
12252e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    err = reader.ReadEntityHeader(&string, &actualSize);
12262e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    if (err != 0) {
12272e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato        fprintf(stderr, "ReadEntityHeader failed with %s\n", strerror(err));
12285f15d151b5101fadfe6cba1e8f4aa6367e8c603eJoe Onorato        goto finished;
12292e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    }
12302e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    if (string != str) {
12312e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato        fprintf(stderr, "ReadEntityHeader expected key '%s' got '%s'\n", str, string.string());
12322e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato        err = EINVAL;
12335f15d151b5101fadfe6cba1e8f4aa6367e8c603eJoe Onorato        goto finished;
12342e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    }
1235f5df700e6ce056ebfa322314d970e52d6facc35aAshok Bhat    if (actualSize != bufSize) {
1236f5df700e6ce056ebfa322314d970e52d6facc35aAshok Bhat        fprintf(stderr, "ReadEntityHeader expected dataSize %zu got %zu\n",
1237f5df700e6ce056ebfa322314d970e52d6facc35aAshok Bhat                bufSize, actualSize);
12382e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato        err = EINVAL;
12395f15d151b5101fadfe6cba1e8f4aa6367e8c603eJoe Onorato        goto finished;
12402e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    }
12412e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato
124211b157790234d3d2f116ce4c7ed1d3d00fb78bc3Christopher Tate    nRead = reader.ReadEntityData(buf, bufSize);
124311b157790234d3d2f116ce4c7ed1d3d00fb78bc3Christopher Tate    if (nRead < 0) {
124411b157790234d3d2f116ce4c7ed1d3d00fb78bc3Christopher Tate        err = reader.Status();
12452e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato        fprintf(stderr, "ReadEntityData failed with %s\n", strerror(err));
12465f15d151b5101fadfe6cba1e8f4aa6367e8c603eJoe Onorato        goto finished;
12472e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    }
12482e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato
12492e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    if (0 != memcmp(buf, str, bufSize)) {
12502e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato        fprintf(stderr, "ReadEntityData expected '%s' but got something starting with "
12515f15d151b5101fadfe6cba1e8f4aa6367e8c603eJoe Onorato                "%02x %02x %02x %02x  '%c%c%c%c'\n", str, buf[0], buf[1], buf[2], buf[3],
12525f15d151b5101fadfe6cba1e8f4aa6367e8c603eJoe Onorato                buf[0], buf[1], buf[2], buf[3]);
12532e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato        err = EINVAL;
12545f15d151b5101fadfe6cba1e8f4aa6367e8c603eJoe Onorato        goto finished;
12552e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    }
12562e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato
12572e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    // The next read will confirm whether it got the right amount of data.
12582e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato
12595f15d151b5101fadfe6cba1e8f4aa6367e8c603eJoe Onoratofinished:
12602e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    if (err != NO_ERROR) {
12612e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato        fprintf(stderr, "test_read_header_and_entity failed with %s\n", strerror(err));
12622e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    }
126363bcb79dd437e70593b63cc5a87baab3251c2183Christopher Tate    free(buf);
12642e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    return err;
12652e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato}
12662e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato
12672e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onoratoint
12682e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onoratobackup_helper_test_data_reader()
12692e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato{
12702e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    int err;
12712e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    int fd;
12722e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    const char* filename = SCRATCH_DIR "data_reader.data";
12732e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato
12742e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    system("rm -r " SCRATCH_DIR);
12752e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    mkdir(SCRATCH_DIR, 0777);
12762e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    mkdir(SCRATCH_DIR "data", 0777);
1277f4c46b94b867f6a01bf7d0be18f667819338072fNicolas Catania
12782e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    fd = creat(filename, 0666);
12792e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    if (fd == -1) {
12802e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato        fprintf(stderr, "error creating: %s\n", strerror(errno));
12812e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato        return errno;
12822e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    }
12832e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato
12842e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    err = write(fd, DATA_GOLDEN_FILE, DATA_GOLDEN_FILE_SIZE);
12852e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    if (err != DATA_GOLDEN_FILE_SIZE) {
12862e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato        fprintf(stderr, "Error \"%s\" writing golden file %s\n", strerror(errno), filename);
12872e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato        return errno;
12882e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    }
12892e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato
12902e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    close(fd);
12912e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato
12922e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    fd = open(filename, O_RDONLY);
12932e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    if (fd == -1) {
12942e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato        fprintf(stderr, "Error \"%s\" opening golden file %s for read\n", strerror(errno),
12952e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato                filename);
12962e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato        return errno;
12972e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    }
12982e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato
12992e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    {
13002e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato        BackupDataReader reader(fd);
13012e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato
13022e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato        err = 0;
13032e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato
13042e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato        if (err == NO_ERROR) {
13052e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato            err = test_read_header_and_entity(reader, "no_padding_");
13062e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato        }
13072e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato
13082e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato        if (err == NO_ERROR) {
13092e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato            err = test_read_header_and_entity(reader, "padded_to__3");
13102e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato        }
13112e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato
13122e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato        if (err == NO_ERROR) {
13132e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato            err = test_read_header_and_entity(reader, "padded_to_2__");
13142e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato        }
13152e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato
13162e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato        if (err == NO_ERROR) {
13172e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato            err = test_read_header_and_entity(reader, "padded_to1");
13182e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato        }
13192e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    }
13202e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato
13212e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    close(fd);
13222e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato
13232e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    return err;
13242e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato}
13252e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato
13263ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onoratostatic int
13273ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onoratoget_mod_time(const char* filename, struct timeval times[2])
13283ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato{
13293ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    int err;
13303ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    struct stat64 st;
13313ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    err = stat64(filename, &st);
13323ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    if (err != 0) {
13333ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        fprintf(stderr, "stat '%s' failed: %s\n", filename, strerror(errno));
13343ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        return errno;
13353ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    }
13363ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    times[0].tv_sec = st.st_atime;
13373ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    times[1].tv_sec = st.st_mtime;
1338f4c46b94b867f6a01bf7d0be18f667819338072fNicolas Catania
1339f4c46b94b867f6a01bf7d0be18f667819338072fNicolas Catania    // If st_atime is a macro then struct stat64 uses struct timespec
1340f4c46b94b867f6a01bf7d0be18f667819338072fNicolas Catania    // to store the access and modif time values and typically
1341f4c46b94b867f6a01bf7d0be18f667819338072fNicolas Catania    // st_*time_nsec is not defined. In glibc, this is controlled by
1342f4c46b94b867f6a01bf7d0be18f667819338072fNicolas Catania    // __USE_MISC.
1343f4c46b94b867f6a01bf7d0be18f667819338072fNicolas Catania#ifdef __USE_MISC
1344f4c46b94b867f6a01bf7d0be18f667819338072fNicolas Catania#if !defined(st_atime) || defined(st_atime_nsec)
1345f4c46b94b867f6a01bf7d0be18f667819338072fNicolas Catania#error "Check if this __USE_MISC conditional is still needed."
1346f4c46b94b867f6a01bf7d0be18f667819338072fNicolas Catania#endif
1347f4c46b94b867f6a01bf7d0be18f667819338072fNicolas Catania    times[0].tv_usec = st.st_atim.tv_nsec / 1000;
1348f4c46b94b867f6a01bf7d0be18f667819338072fNicolas Catania    times[1].tv_usec = st.st_mtim.tv_nsec / 1000;
1349f4c46b94b867f6a01bf7d0be18f667819338072fNicolas Catania#else
1350f4c46b94b867f6a01bf7d0be18f667819338072fNicolas Catania    times[0].tv_usec = st.st_atime_nsec / 1000;
13513ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    times[1].tv_usec = st.st_mtime_nsec / 1000;
1352f4c46b94b867f6a01bf7d0be18f667819338072fNicolas Catania#endif
1353f4c46b94b867f6a01bf7d0be18f667819338072fNicolas Catania
13543ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    return 0;
13553ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato}
13563ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
13573ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onoratoint
13583ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onoratobackup_helper_test_files()
13593ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato{
13603ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    int err;
13613ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    int oldSnapshotFD;
13624535e40544aeb957d44fad75fbe5676effe03689Joe Onorato    int dataStreamFD;
13634535e40544aeb957d44fad75fbe5676effe03689Joe Onorato    int newSnapshotFD;
13643ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
13653ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    system("rm -r " SCRATCH_DIR);
13663ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    mkdir(SCRATCH_DIR, 0777);
13673ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    mkdir(SCRATCH_DIR "data", 0777);
13683ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
13693ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    write_text_file(SCRATCH_DIR "data/b", "b\nbb\n");
13703ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    write_text_file(SCRATCH_DIR "data/c", "c\ncc\n");
13713ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    write_text_file(SCRATCH_DIR "data/d", "d\ndd\n");
13723ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    write_text_file(SCRATCH_DIR "data/e", "e\nee\n");
13733ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    write_text_file(SCRATCH_DIR "data/f", "f\nff\n");
13743ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    write_text_file(SCRATCH_DIR "data/h", "h\nhh\n");
13753ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
13763ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    char const* files_before[] = {
137723ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato        SCRATCH_DIR "data/b",
137823ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato        SCRATCH_DIR "data/c",
137923ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato        SCRATCH_DIR "data/d",
138023ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato        SCRATCH_DIR "data/e",
138123ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato        SCRATCH_DIR "data/f"
138223ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato    };
138323ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato
138423ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato    char const* keys_before[] = {
13853ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        "data/b",
13863ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        "data/c",
13873ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        "data/d",
13883ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        "data/e",
13893ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        "data/f"
13903ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    };
13913ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
13924535e40544aeb957d44fad75fbe5676effe03689Joe Onorato    dataStreamFD = creat(SCRATCH_DIR "1.data", 0666);
13934535e40544aeb957d44fad75fbe5676effe03689Joe Onorato    if (dataStreamFD == -1) {
13944535e40544aeb957d44fad75fbe5676effe03689Joe Onorato        fprintf(stderr, "error creating: %s\n", strerror(errno));
13954535e40544aeb957d44fad75fbe5676effe03689Joe Onorato        return errno;
13964535e40544aeb957d44fad75fbe5676effe03689Joe Onorato    }
13974535e40544aeb957d44fad75fbe5676effe03689Joe Onorato
13983ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    newSnapshotFD = creat(SCRATCH_DIR "before.snap", 0666);
13993ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    if (newSnapshotFD == -1) {
14003ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        fprintf(stderr, "error creating: %s\n", strerror(errno));
14013ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        return errno;
14023ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    }
1403d2110dbce071a236b6176de344ca797b737542ebJoe Onorato
1404d2110dbce071a236b6176de344ca797b737542ebJoe Onorato    {
1405d2110dbce071a236b6176de344ca797b737542ebJoe Onorato        BackupDataWriter dataStream(dataStreamFD);
1406f4c46b94b867f6a01bf7d0be18f667819338072fNicolas Catania
140723ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato        err = back_up_files(-1, &dataStream, newSnapshotFD, files_before, keys_before, 5);
1408d2110dbce071a236b6176de344ca797b737542ebJoe Onorato        if (err != 0) {
1409d2110dbce071a236b6176de344ca797b737542ebJoe Onorato            return err;
1410d2110dbce071a236b6176de344ca797b737542ebJoe Onorato        }
14113ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    }
14123ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
14134535e40544aeb957d44fad75fbe5676effe03689Joe Onorato    close(dataStreamFD);
14143ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    close(newSnapshotFD);
14153ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
14163ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    sleep(3);
14173ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
14183ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    struct timeval d_times[2];
14193ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    struct timeval e_times[2];
14203ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
14213ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    err = get_mod_time(SCRATCH_DIR "data/d", d_times);
14223ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    err |= get_mod_time(SCRATCH_DIR "data/e", e_times);
14233ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    if (err != 0) {
14243ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        return err;
14253ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    }
14263ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
14273ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    write_text_file(SCRATCH_DIR "data/a", "a\naa\n");
14283ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    unlink(SCRATCH_DIR "data/c");
14293ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    write_text_file(SCRATCH_DIR "data/c", "c\ncc\n");
14303ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    write_text_file(SCRATCH_DIR "data/d", "dd\ndd\n");
14313ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    utimes(SCRATCH_DIR "data/d", d_times);
14323ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    write_text_file(SCRATCH_DIR "data/e", "z\nzz\n");
14333ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    utimes(SCRATCH_DIR "data/e", e_times);
14343ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    write_text_file(SCRATCH_DIR "data/g", "g\ngg\n");
14353ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    unlink(SCRATCH_DIR "data/f");
1436f4c46b94b867f6a01bf7d0be18f667819338072fNicolas Catania
14373ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    char const* files_after[] = {
143823ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato        SCRATCH_DIR "data/a", // added
143923ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato        SCRATCH_DIR "data/b", // same
144023ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato        SCRATCH_DIR "data/c", // different mod time
144123ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato        SCRATCH_DIR "data/d", // different size (same mod time)
144223ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato        SCRATCH_DIR "data/e", // different contents (same mod time, same size)
144323ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato        SCRATCH_DIR "data/g"  // added
144423ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato    };
144523ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato
144623ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato    char const* keys_after[] = {
14473ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        "data/a", // added
14483ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        "data/b", // same
14493ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        "data/c", // different mod time
14503ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        "data/d", // different size (same mod time)
14513ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        "data/e", // different contents (same mod time, same size)
14523ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        "data/g"  // added
14533ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    };
14543ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
14553ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    oldSnapshotFD = open(SCRATCH_DIR "before.snap", O_RDONLY);
14563ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    if (oldSnapshotFD == -1) {
14573ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        fprintf(stderr, "error opening: %s\n", strerror(errno));
14583ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        return errno;
14593ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    }
14603ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
14614535e40544aeb957d44fad75fbe5676effe03689Joe Onorato    dataStreamFD = creat(SCRATCH_DIR "2.data", 0666);
14624535e40544aeb957d44fad75fbe5676effe03689Joe Onorato    if (dataStreamFD == -1) {
14634535e40544aeb957d44fad75fbe5676effe03689Joe Onorato        fprintf(stderr, "error creating: %s\n", strerror(errno));
14644535e40544aeb957d44fad75fbe5676effe03689Joe Onorato        return errno;
14654535e40544aeb957d44fad75fbe5676effe03689Joe Onorato    }
14664535e40544aeb957d44fad75fbe5676effe03689Joe Onorato
14673ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    newSnapshotFD = creat(SCRATCH_DIR "after.snap", 0666);
14683ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    if (newSnapshotFD == -1) {
14693ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        fprintf(stderr, "error creating: %s\n", strerror(errno));
14703ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        return errno;
14713ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    }
14723ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
1473d2110dbce071a236b6176de344ca797b737542ebJoe Onorato    {
1474d2110dbce071a236b6176de344ca797b737542ebJoe Onorato        BackupDataWriter dataStream(dataStreamFD);
1475f4c46b94b867f6a01bf7d0be18f667819338072fNicolas Catania
147623ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato        err = back_up_files(oldSnapshotFD, &dataStream, newSnapshotFD, files_after, keys_after, 6);
1477d2110dbce071a236b6176de344ca797b737542ebJoe Onorato        if (err != 0) {
1478d2110dbce071a236b6176de344ca797b737542ebJoe Onorato            return err;
1479d2110dbce071a236b6176de344ca797b737542ebJoe Onorato        }
1480d2110dbce071a236b6176de344ca797b737542ebJoe Onorato}
14813ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
14823ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    close(oldSnapshotFD);
14834535e40544aeb957d44fad75fbe5676effe03689Joe Onorato    close(dataStreamFD);
14843ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    close(newSnapshotFD);
1485f4c46b94b867f6a01bf7d0be18f667819338072fNicolas Catania
14863ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    return 0;
14873ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato}
14883ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
148923ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onoratoint
149023ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onoratobackup_helper_test_null_base()
149123ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato{
149223ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato    int err;
149323ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato    int oldSnapshotFD;
149423ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato    int dataStreamFD;
149523ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato    int newSnapshotFD;
149623ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato
149723ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato    system("rm -r " SCRATCH_DIR);
149823ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato    mkdir(SCRATCH_DIR, 0777);
149923ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato    mkdir(SCRATCH_DIR "data", 0777);
150023ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato
150123ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato    write_text_file(SCRATCH_DIR "data/a", "a\naa\n");
150223ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato
150323ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato    char const* files[] = {
150423ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato        SCRATCH_DIR "data/a",
150523ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato    };
150623ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato
150723ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato    char const* keys[] = {
150823ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato        "a",
150923ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato    };
151023ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato
151123ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato    dataStreamFD = creat(SCRATCH_DIR "null_base.data", 0666);
151223ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato    if (dataStreamFD == -1) {
151323ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato        fprintf(stderr, "error creating: %s\n", strerror(errno));
151423ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato        return errno;
151523ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato    }
151623ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato
151723ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato    newSnapshotFD = creat(SCRATCH_DIR "null_base.snap", 0666);
151823ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato    if (newSnapshotFD == -1) {
151923ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato        fprintf(stderr, "error creating: %s\n", strerror(errno));
152023ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato        return errno;
152123ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato    }
152223ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato
152323ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato    {
152423ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato        BackupDataWriter dataStream(dataStreamFD);
152523ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato
152623ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato        err = back_up_files(-1, &dataStream, newSnapshotFD, files, keys, 1);
152723ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato        if (err != 0) {
152823ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato            return err;
152923ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato        }
153023ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato    }
153123ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato
153223ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato    close(dataStreamFD);
153323ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato    close(newSnapshotFD);
153423ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato
153523ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato    return 0;
153623ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato}
153723ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato
1538ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onoratoint
1539ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onoratobackup_helper_test_missing_file()
1540ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato{
1541ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato    int err;
1542ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato    int oldSnapshotFD;
1543ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato    int dataStreamFD;
1544ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato    int newSnapshotFD;
1545ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato
1546ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato    system("rm -r " SCRATCH_DIR);
1547ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato    mkdir(SCRATCH_DIR, 0777);
1548ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato    mkdir(SCRATCH_DIR "data", 0777);
1549ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato
1550ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato    write_text_file(SCRATCH_DIR "data/b", "b\nbb\n");
1551ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato
1552ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato    char const* files[] = {
1553ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato        SCRATCH_DIR "data/a",
1554ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato        SCRATCH_DIR "data/b",
1555ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato        SCRATCH_DIR "data/c",
1556ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato    };
1557ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato
1558ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato    char const* keys[] = {
1559ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato        "a",
1560ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato        "b",
1561ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato        "c",
1562ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato    };
1563ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato
1564ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato    dataStreamFD = creat(SCRATCH_DIR "null_base.data", 0666);
1565ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato    if (dataStreamFD == -1) {
1566ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato        fprintf(stderr, "error creating: %s\n", strerror(errno));
1567ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato        return errno;
1568ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato    }
1569ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato
1570ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato    newSnapshotFD = creat(SCRATCH_DIR "null_base.snap", 0666);
1571ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato    if (newSnapshotFD == -1) {
1572ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato        fprintf(stderr, "error creating: %s\n", strerror(errno));
1573ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato        return errno;
1574ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato    }
1575ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato
1576ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato    {
1577ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato        BackupDataWriter dataStream(dataStreamFD);
1578ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato
1579ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato        err = back_up_files(-1, &dataStream, newSnapshotFD, files, keys, 1);
1580ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato        if (err != 0) {
1581ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato            return err;
1582ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato        }
1583ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato    }
1584ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato
1585ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato    close(dataStreamFD);
1586ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato    close(newSnapshotFD);
1587ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato
1588ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato    return 0;
1589ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato}
1590ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato
159123ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato
15923ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato#endif // TEST_BACKUP_HELPERS
15934535e40544aeb957d44fad75fbe5676effe03689Joe Onorato
15944535e40544aeb957d44fad75fbe5676effe03689Joe Onorato}
1595