BackupHelpers.cpp revision 2204f0bf56af53b588a01701b8cf9cd05b1b3ff9
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
712204f0bf56af53b588a01701b8cf9cd05b1b3ff9Andreas Gampestatic const bool kIsDebug = false;
72568bc32344dce841c8f6958f1a65ff839a1b64c0Joe Onorato#if TEST_BACKUP_HELPERS
732204f0bf56af53b588a01701b8cf9cd05b1b3ff9Andreas Gampe#define LOGP(f, x...) if (kIsDebug) printf(f "\n", x)
744535e40544aeb957d44fad75fbe5676effe03689Joe Onorato#else
752204f0bf56af53b588a01701b8cf9cd05b1b3ff9Andreas Gampe#define LOGP(x...) if (kIsDebug) ALOGD(x)
76568bc32344dce841c8f6958f1a65ff839a1b64c0Joe Onorato#endif
77290bb011c5c1a9ba1f2116810b06cf52a9c36b3eJoe Onorato
783ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onoratoconst static int ROUND_UP[4] = { 0, 3, 2, 1 };
793ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
803ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onoratostatic inline int
813ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onoratoround_up(int n)
823ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato{
833ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    return n + ROUND_UP[n % 4];
843ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato}
853ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
863ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onoratostatic int
873ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onoratoread_snapshot_file(int fd, KeyedVector<String8,FileState>* snapshot)
883ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato{
893ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    int bytesRead = 0;
903ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    int amt;
913ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    SnapshotHeader header;
923ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
933ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    amt = read(fd, &header, sizeof(header));
943ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    if (amt != sizeof(header)) {
953ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        return errno;
963ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    }
973ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    bytesRead += amt;
983ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
993ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    if (header.magic0 != MAGIC0 || header.magic1 != MAGIC1) {
1008564c8da817a845353d213acd8636b76f567b234Steve Block        ALOGW("read_snapshot_file header.magic0=0x%08x magic1=0x%08x", header.magic0, header.magic1);
1013ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        return 1;
1023ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    }
1033ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
1043ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    for (int i=0; i<header.fileCount; i++) {
1053ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        FileState file;
1063ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        char filenameBuf[128];
1073ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
10823ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato        amt = read(fd, &file, sizeof(FileState));
10923ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato        if (amt != sizeof(FileState)) {
1108564c8da817a845353d213acd8636b76f567b234Steve Block            ALOGW("read_snapshot_file FileState truncated/error with read at %d bytes\n", bytesRead);
1113ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato            return 1;
1123ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        }
1133ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        bytesRead += amt;
1143ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
1153ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        // filename is not NULL terminated, but it is padded
1163ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        int nameBufSize = round_up(file.nameLen);
1173ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        char* filename = nameBufSize <= (int)sizeof(filenameBuf)
1183ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato                ? filenameBuf
1193ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato                : (char*)malloc(nameBufSize);
1203ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        amt = read(fd, filename, nameBufSize);
1213ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        if (amt == nameBufSize) {
1223ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato            snapshot->add(String8(filename, file.nameLen), file);
1233ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        }
1243ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        bytesRead += amt;
1253ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        if (filename != filenameBuf) {
1263ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato            free(filename);
1273ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        }
1283ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        if (amt != nameBufSize) {
1298564c8da817a845353d213acd8636b76f567b234Steve Block            ALOGW("read_snapshot_file filename truncated/error with read at %d bytes\n", bytesRead);
1303ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato            return 1;
1313ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        }
1323ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    }
1333ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
1343ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    if (header.totalSize != bytesRead) {
1358564c8da817a845353d213acd8636b76f567b234Steve Block        ALOGW("read_snapshot_file length mismatch: header.totalSize=%d bytesRead=%d\n",
1363ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato                header.totalSize, bytesRead);
1373ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        return 1;
1383ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    }
1393ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
1403ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    return 0;
1413ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato}
1423ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
1433ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onoratostatic int
14423ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onoratowrite_snapshot_file(int fd, const KeyedVector<String8,FileRec>& snapshot)
1453ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato{
146ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato    int fileCount = 0;
1473ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    int bytesWritten = sizeof(SnapshotHeader);
1483ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    // preflight size
1493ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    const int N = snapshot.size();
1503ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    for (int i=0; i<N; i++) {
151ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato        const FileRec& g = snapshot.valueAt(i);
152ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato        if (!g.deleted) {
153ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato            const String8& name = snapshot.keyAt(i);
154ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato            bytesWritten += sizeof(FileState) + round_up(name.length());
155ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato            fileCount++;
156ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato        }
1573ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    }
1583ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
1594535e40544aeb957d44fad75fbe5676effe03689Joe Onorato    LOGP("write_snapshot_file fd=%d\n", fd);
1604535e40544aeb957d44fad75fbe5676effe03689Joe Onorato
1613ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    int amt;
162ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato    SnapshotHeader header = { MAGIC0, fileCount, MAGIC1, bytesWritten };
1633ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
1643ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    amt = write(fd, &header, sizeof(header));
1653ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    if (amt != sizeof(header)) {
1668564c8da817a845353d213acd8636b76f567b234Steve Block        ALOGW("write_snapshot_file error writing header %s", strerror(errno));
1673ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        return errno;
1683ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    }
1693ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
170ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato    for (int i=0; i<N; i++) {
17123ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato        FileRec r = snapshot.valueAt(i);
172ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato        if (!r.deleted) {
173ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato            const String8& name = snapshot.keyAt(i);
174ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato            int nameLen = r.s.nameLen = name.length();
1753ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
176ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato            amt = write(fd, &r.s, sizeof(FileState));
177ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato            if (amt != sizeof(FileState)) {
1788564c8da817a845353d213acd8636b76f567b234Steve Block                ALOGW("write_snapshot_file error writing header %s", strerror(errno));
179ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato                return 1;
180ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato            }
1813ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
182ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato            // filename is not NULL terminated, but it is padded
183ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato            amt = write(fd, name.string(), nameLen);
184ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato            if (amt != nameLen) {
1858564c8da817a845353d213acd8636b76f567b234Steve Block                ALOGW("write_snapshot_file error writing filename %s", strerror(errno));
1863ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato                return 1;
1873ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato            }
188ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato            int paddingLen = ROUND_UP[nameLen % 4];
189ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato            if (paddingLen != 0) {
190ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato                int padding = 0xabababab;
191ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato                amt = write(fd, &padding, paddingLen);
192ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato                if (amt != paddingLen) {
1938564c8da817a845353d213acd8636b76f567b234Steve Block                    ALOGW("write_snapshot_file error writing %d bytes of filename padding %s",
194ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato                            paddingLen, strerror(errno));
195ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato                    return 1;
196ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato                }
197ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato            }
1983ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        }
1993ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    }
2003ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
2013ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    return 0;
2023ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato}
2033ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
2043ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onoratostatic int
205fbb92385f2fb0ae1146bb8f3d73547d90bda6db1Christopher Tatewrite_update_file(BackupDataWriter* dataStream, int fd, int mode, const String8& key,
20623ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato        char const* realFilename)
2073ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato{
208fbb92385f2fb0ae1146bb8f3d73547d90bda6db1Christopher Tate    LOGP("write_update_file %s (%s) : mode 0%o\n", realFilename, key.string(), mode);
2093ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
2103ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    const int bufsize = 4*1024;
211d2110dbce071a236b6176de344ca797b737542ebJoe Onorato    int err;
2123ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    int amt;
213d2110dbce071a236b6176de344ca797b737542ebJoe Onorato    int fileSize;
214d2110dbce071a236b6176de344ca797b737542ebJoe Onorato    int bytesLeft;
215fbb92385f2fb0ae1146bb8f3d73547d90bda6db1Christopher Tate    file_metadata_v1 metadata;
216d2110dbce071a236b6176de344ca797b737542ebJoe Onorato
217d2110dbce071a236b6176de344ca797b737542ebJoe Onorato    char* buf = (char*)malloc(bufsize);
218d2110dbce071a236b6176de344ca797b737542ebJoe Onorato
219fbb92385f2fb0ae1146bb8f3d73547d90bda6db1Christopher Tate    fileSize = lseek(fd, 0, SEEK_END);
220d2110dbce071a236b6176de344ca797b737542ebJoe Onorato    lseek(fd, 0, SEEK_SET);
221d2110dbce071a236b6176de344ca797b737542ebJoe Onorato
222fbb92385f2fb0ae1146bb8f3d73547d90bda6db1Christopher Tate    if (sizeof(metadata) != 16) {
2233762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("ERROR: metadata block is the wrong size!");
224fbb92385f2fb0ae1146bb8f3d73547d90bda6db1Christopher Tate    }
225fbb92385f2fb0ae1146bb8f3d73547d90bda6db1Christopher Tate
226fbb92385f2fb0ae1146bb8f3d73547d90bda6db1Christopher Tate    bytesLeft = fileSize + sizeof(metadata);
227d2110dbce071a236b6176de344ca797b737542ebJoe Onorato    err = dataStream->WriteEntityHeader(key, bytesLeft);
228d2110dbce071a236b6176de344ca797b737542ebJoe Onorato    if (err != 0) {
22963bcb79dd437e70593b63cc5a87baab3251c2183Christopher Tate        free(buf);
230d2110dbce071a236b6176de344ca797b737542ebJoe Onorato        return err;
231d2110dbce071a236b6176de344ca797b737542ebJoe Onorato    }
232d2110dbce071a236b6176de344ca797b737542ebJoe Onorato
233fbb92385f2fb0ae1146bb8f3d73547d90bda6db1Christopher Tate    // store the file metadata first
234fbb92385f2fb0ae1146bb8f3d73547d90bda6db1Christopher Tate    metadata.version = tolel(CURRENT_METADATA_VERSION);
235fbb92385f2fb0ae1146bb8f3d73547d90bda6db1Christopher Tate    metadata.mode = tolel(mode);
236fbb92385f2fb0ae1146bb8f3d73547d90bda6db1Christopher Tate    metadata.undefined_1 = metadata.undefined_2 = 0;
237fbb92385f2fb0ae1146bb8f3d73547d90bda6db1Christopher Tate    err = dataStream->WriteEntityData(&metadata, sizeof(metadata));
238fbb92385f2fb0ae1146bb8f3d73547d90bda6db1Christopher Tate    if (err != 0) {
23963bcb79dd437e70593b63cc5a87baab3251c2183Christopher Tate        free(buf);
240fbb92385f2fb0ae1146bb8f3d73547d90bda6db1Christopher Tate        return err;
241fbb92385f2fb0ae1146bb8f3d73547d90bda6db1Christopher Tate    }
242fbb92385f2fb0ae1146bb8f3d73547d90bda6db1Christopher Tate    bytesLeft -= sizeof(metadata); // bytesLeft should == fileSize now
243fbb92385f2fb0ae1146bb8f3d73547d90bda6db1Christopher Tate
244fbb92385f2fb0ae1146bb8f3d73547d90bda6db1Christopher Tate    // now store the file content
245d2110dbce071a236b6176de344ca797b737542ebJoe Onorato    while ((amt = read(fd, buf, bufsize)) != 0 && bytesLeft > 0) {
246d2110dbce071a236b6176de344ca797b737542ebJoe Onorato        bytesLeft -= amt;
247d2110dbce071a236b6176de344ca797b737542ebJoe Onorato        if (bytesLeft < 0) {
248d2110dbce071a236b6176de344ca797b737542ebJoe Onorato            amt += bytesLeft; // Plus a negative is minus.  Don't write more than we promised.
249d2110dbce071a236b6176de344ca797b737542ebJoe Onorato        }
250d2110dbce071a236b6176de344ca797b737542ebJoe Onorato        err = dataStream->WriteEntityData(buf, amt);
251d2110dbce071a236b6176de344ca797b737542ebJoe Onorato        if (err != 0) {
25263bcb79dd437e70593b63cc5a87baab3251c2183Christopher Tate            free(buf);
253d2110dbce071a236b6176de344ca797b737542ebJoe Onorato            return err;
254d2110dbce071a236b6176de344ca797b737542ebJoe Onorato        }
255d2110dbce071a236b6176de344ca797b737542ebJoe Onorato    }
256d2110dbce071a236b6176de344ca797b737542ebJoe Onorato    if (bytesLeft != 0) {
257d2110dbce071a236b6176de344ca797b737542ebJoe Onorato        if (bytesLeft > 0) {
258d2110dbce071a236b6176de344ca797b737542ebJoe Onorato            // Pad out the space we promised in the buffer.  We can't corrupt the buffer,
259d2110dbce071a236b6176de344ca797b737542ebJoe Onorato            // even though the data we're sending is probably bad.
260d2110dbce071a236b6176de344ca797b737542ebJoe Onorato            memset(buf, 0, bufsize);
261d2110dbce071a236b6176de344ca797b737542ebJoe Onorato            while (bytesLeft > 0) {
262d2110dbce071a236b6176de344ca797b737542ebJoe Onorato                amt = bytesLeft < bufsize ? bytesLeft : bufsize;
263d2110dbce071a236b6176de344ca797b737542ebJoe Onorato                bytesLeft -= amt;
264d2110dbce071a236b6176de344ca797b737542ebJoe Onorato                err = dataStream->WriteEntityData(buf, amt);
265d2110dbce071a236b6176de344ca797b737542ebJoe Onorato                if (err != 0) {
26663bcb79dd437e70593b63cc5a87baab3251c2183Christopher Tate                    free(buf);
267d2110dbce071a236b6176de344ca797b737542ebJoe Onorato                    return err;
268d2110dbce071a236b6176de344ca797b737542ebJoe Onorato                }
269d2110dbce071a236b6176de344ca797b737542ebJoe Onorato            }
270d2110dbce071a236b6176de344ca797b737542ebJoe Onorato        }
2713762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("write_update_file size mismatch for %s. expected=%d actual=%d."
27223ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato                " You aren't doing proper locking!", realFilename, fileSize, fileSize-bytesLeft);
273d2110dbce071a236b6176de344ca797b737542ebJoe Onorato    }
274d2110dbce071a236b6176de344ca797b737542ebJoe Onorato
27563bcb79dd437e70593b63cc5a87baab3251c2183Christopher Tate    free(buf);
276d2110dbce071a236b6176de344ca797b737542ebJoe Onorato    return NO_ERROR;
277d2110dbce071a236b6176de344ca797b737542ebJoe Onorato}
278d2110dbce071a236b6176de344ca797b737542ebJoe Onorato
279d2110dbce071a236b6176de344ca797b737542ebJoe Onoratostatic int
28023ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onoratowrite_update_file(BackupDataWriter* dataStream, const String8& key, char const* realFilename)
281d2110dbce071a236b6176de344ca797b737542ebJoe Onorato{
282d2110dbce071a236b6176de344ca797b737542ebJoe Onorato    int err;
283fbb92385f2fb0ae1146bb8f3d73547d90bda6db1Christopher Tate    struct stat st;
284fbb92385f2fb0ae1146bb8f3d73547d90bda6db1Christopher Tate
285fbb92385f2fb0ae1146bb8f3d73547d90bda6db1Christopher Tate    err = stat(realFilename, &st);
286fbb92385f2fb0ae1146bb8f3d73547d90bda6db1Christopher Tate    if (err < 0) {
287fbb92385f2fb0ae1146bb8f3d73547d90bda6db1Christopher Tate        return errno;
288fbb92385f2fb0ae1146bb8f3d73547d90bda6db1Christopher Tate    }
289fbb92385f2fb0ae1146bb8f3d73547d90bda6db1Christopher Tate
29023ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato    int fd = open(realFilename, O_RDONLY);
2913ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    if (fd == -1) {
292d2110dbce071a236b6176de344ca797b737542ebJoe Onorato        return errno;
2933ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    }
294fbb92385f2fb0ae1146bb8f3d73547d90bda6db1Christopher Tate
295fbb92385f2fb0ae1146bb8f3d73547d90bda6db1Christopher Tate    err = write_update_file(dataStream, fd, st.st_mode, key, realFilename);
296d2110dbce071a236b6176de344ca797b737542ebJoe Onorato    close(fd);
297d2110dbce071a236b6176de344ca797b737542ebJoe Onorato    return err;
298d2110dbce071a236b6176de344ca797b737542ebJoe Onorato}
299d2110dbce071a236b6176de344ca797b737542ebJoe Onorato
300d2110dbce071a236b6176de344ca797b737542ebJoe Onoratostatic int
301d2110dbce071a236b6176de344ca797b737542ebJoe Onoratocompute_crc32(int fd)
302d2110dbce071a236b6176de344ca797b737542ebJoe Onorato{
303d2110dbce071a236b6176de344ca797b737542ebJoe Onorato    const int bufsize = 4*1024;
304d2110dbce071a236b6176de344ca797b737542ebJoe Onorato    int amt;
3053ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
3063ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    char* buf = (char*)malloc(bufsize);
3073ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    int crc = crc32(0L, Z_NULL, 0);
3083ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
309d2110dbce071a236b6176de344ca797b737542ebJoe Onorato    lseek(fd, 0, SEEK_SET);
310d2110dbce071a236b6176de344ca797b737542ebJoe Onorato
3113ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    while ((amt = read(fd, buf, bufsize)) != 0) {
3123ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        crc = crc32(crc, (Bytef*)buf, amt);
3133ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    }
3143ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
31563bcb79dd437e70593b63cc5a87baab3251c2183Christopher Tate    free(buf);
3163ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    return crc;
3173ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato}
3183ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
3193ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onoratoint
320d2110dbce071a236b6176de344ca797b737542ebJoe Onoratoback_up_files(int oldSnapshotFD, BackupDataWriter* dataStream, int newSnapshotFD,
32123ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato        char const* const* files, char const* const* keys, int fileCount)
3223ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato{
3233ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    int err;
3243ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    KeyedVector<String8,FileState> oldSnapshot;
32523ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato    KeyedVector<String8,FileRec> newSnapshot;
3263ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
3273ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    if (oldSnapshotFD != -1) {
3283ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        err = read_snapshot_file(oldSnapshotFD, &oldSnapshot);
3293ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        if (err != 0) {
3303ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato            // On an error, treat this as a full backup.
3313ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato            oldSnapshot.clear();
3323ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        }
3333ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    }
3343ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
3353ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    for (int i=0; i<fileCount; i++) {
33623ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato        String8 key(keys[i]);
33723ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato        FileRec r;
338d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato        char const* file = files[i];
339d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato        r.file = file;
3403ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        struct stat st;
3413ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
34223ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato        err = stat(file, &st);
3433ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        if (err != 0) {
344ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato            r.deleted = true;
345ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato        } else {
346ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato            r.deleted = false;
347ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato            r.s.modTime_sec = st.st_mtime;
348ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato            r.s.modTime_nsec = 0; // workaround sim breakage
349ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato            //r.s.modTime_nsec = st.st_mtime_nsec;
35011b157790234d3d2f116ce4c7ed1d3d00fb78bc3Christopher Tate            r.s.mode = st.st_mode;
351ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato            r.s.size = st.st_size;
352ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato            // we compute the crc32 later down below, when we already have the file open.
353ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato
354ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato            if (newSnapshot.indexOfKey(key) >= 0) {
355ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato                LOGP("back_up_files key already in use '%s'", key.string());
356ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato                return -1;
357ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato            }
35823ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato        }
35923ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato        newSnapshot.add(key, r);
3603ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    }
3613ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
3623ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    int n = 0;
3633ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    int N = oldSnapshot.size();
3643ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    int m = 0;
3653ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
3663ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    while (n<N && m<fileCount) {
3673ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        const String8& p = oldSnapshot.keyAt(n);
3683ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        const String8& q = newSnapshot.keyAt(m);
369ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato        FileRec& g = newSnapshot.editValueAt(m);
3703ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        int cmp = p.compare(q);
371ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato        if (g.deleted || cmp < 0) {
3723ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato            // file removed
37323ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato            LOGP("file removed: %s", p.string());
374ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato            g.deleted = true; // They didn't mention the file, but we noticed that it's gone.
375d2110dbce071a236b6176de344ca797b737542ebJoe Onorato            dataStream->WriteEntityHeader(p, -1);
3763ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato            n++;
3773ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        }
378ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato        else if (cmp > 0) {
379ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato            // file added
380d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato            LOGP("file added: %s", g.file.string());
381d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato            write_update_file(dataStream, q, g.file.string());
382ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato            m++;
383ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato        }
3843ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        else {
3853ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato            // both files exist, check them
3863ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato            const FileState& f = oldSnapshot.valueAt(n);
387d2110dbce071a236b6176de344ca797b737542ebJoe Onorato
388d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato            int fd = open(g.file.string(), O_RDONLY);
3890032ce80ac127e6bfb25d727162eee4af208dc77Christopher Tate            if (fd < 0) {
390d2110dbce071a236b6176de344ca797b737542ebJoe Onorato                // We can't open the file.  Don't report it as a delete either.  Let the
391d2110dbce071a236b6176de344ca797b737542ebJoe Onorato                // server keep the old version.  Maybe they'll be able to deal with it
392d2110dbce071a236b6176de344ca797b737542ebJoe Onorato                // on restore.
393d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato                LOGP("Unable to open file %s - skipping", g.file.string());
394d2110dbce071a236b6176de344ca797b737542ebJoe Onorato            } else {
39523ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato                g.s.crc32 = compute_crc32(fd);
396d2110dbce071a236b6176de344ca797b737542ebJoe Onorato
39723ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato                LOGP("%s", q.string());
39811b157790234d3d2f116ce4c7ed1d3d00fb78bc3Christopher Tate                LOGP("  new: modTime=%d,%d mode=%04o size=%-3d crc32=0x%08x",
39911b157790234d3d2f116ce4c7ed1d3d00fb78bc3Christopher Tate                        f.modTime_sec, f.modTime_nsec, f.mode, f.size, f.crc32);
40011b157790234d3d2f116ce4c7ed1d3d00fb78bc3Christopher Tate                LOGP("  old: modTime=%d,%d mode=%04o size=%-3d crc32=0x%08x",
40111b157790234d3d2f116ce4c7ed1d3d00fb78bc3Christopher Tate                        g.s.modTime_sec, g.s.modTime_nsec, g.s.mode, g.s.size, g.s.crc32);
40223ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato                if (f.modTime_sec != g.s.modTime_sec || f.modTime_nsec != g.s.modTime_nsec
40311b157790234d3d2f116ce4c7ed1d3d00fb78bc3Christopher Tate                        || f.mode != g.s.mode || f.size != g.s.size || f.crc32 != g.s.crc32) {
404fbb92385f2fb0ae1146bb8f3d73547d90bda6db1Christopher Tate                    write_update_file(dataStream, fd, g.s.mode, p, g.file.string());
405d2110dbce071a236b6176de344ca797b737542ebJoe Onorato                }
406d2110dbce071a236b6176de344ca797b737542ebJoe Onorato
407d2110dbce071a236b6176de344ca797b737542ebJoe Onorato                close(fd);
4083ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato            }
4093ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato            n++;
4103ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato            m++;
4113ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        }
4123ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    }
4133ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
4143ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    // these were deleted
4153ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    while (n<N) {
416d2110dbce071a236b6176de344ca797b737542ebJoe Onorato        dataStream->WriteEntityHeader(oldSnapshot.keyAt(n), -1);
4173ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        n++;
4183ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    }
4193ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
4203ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    // these were added
4213ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    while (m<fileCount) {
4223ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        const String8& q = newSnapshot.keyAt(m);
42323ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato        FileRec& g = newSnapshot.editValueAt(m);
424d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato        write_update_file(dataStream, q, g.file.string());
4253ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        m++;
4263ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    }
4273ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
4283ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    err = write_snapshot_file(newSnapshotFD, newSnapshot);
4293ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
4303ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    return 0;
4313ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato}
4323ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
43383a7cdc56539d00933c2e25999620cec94c524b6Christopher Tatestatic void calc_tar_checksum(char* buf) {
43483a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate    // [ 148 :   8 ] checksum -- to be calculated with this field as space chars
43583a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate    memset(buf + 148, ' ', 8);
43683a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate
43783a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate    uint16_t sum = 0;
43883a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate    for (uint8_t* p = (uint8_t*) buf; p < ((uint8_t*)buf) + 512; p++) {
43983a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate        sum += *p;
44083a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate    }
44183a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate
44283a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate    // Now write the real checksum value:
44383a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate    // [ 148 :   8 ]  checksum: 6 octal digits [leading zeroes], NUL, SPC
44483a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate    sprintf(buf + 148, "%06o", sum); // the trailing space is already in place
44583a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate}
44683a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate
447dc92c82b4180e8067f1acd00a7db7935afce00ffChristopher Tate// Returns number of bytes written
448dc92c82b4180e8067f1acd00a7db7935afce00ffChristopher Tatestatic int write_pax_header_entry(char* buf, const char* key, const char* value) {
449dc92c82b4180e8067f1acd00a7db7935afce00ffChristopher Tate    // start with the size of "1 key=value\n"
450dc92c82b4180e8067f1acd00a7db7935afce00ffChristopher Tate    int len = strlen(key) + strlen(value) + 4;
451dc92c82b4180e8067f1acd00a7db7935afce00ffChristopher Tate    if (len > 9) len++;
452dc92c82b4180e8067f1acd00a7db7935afce00ffChristopher Tate    if (len > 99) len++;
453dc92c82b4180e8067f1acd00a7db7935afce00ffChristopher Tate    if (len > 999) len++;
454dc92c82b4180e8067f1acd00a7db7935afce00ffChristopher Tate    // since PATH_MAX is 4096 we don't expect to have to generate any single
455dc92c82b4180e8067f1acd00a7db7935afce00ffChristopher Tate    // header entry longer than 9999 characters
456dc92c82b4180e8067f1acd00a7db7935afce00ffChristopher Tate
457dc92c82b4180e8067f1acd00a7db7935afce00ffChristopher Tate    return sprintf(buf, "%d %s=%s\n", len, key, value);
458dc92c82b4180e8067f1acd00a7db7935afce00ffChristopher Tate}
459dc92c82b4180e8067f1acd00a7db7935afce00ffChristopher Tate
4607926a693c4a4f4d2a2d352343bca23e189c7420dChristopher Tate// Wire format to the backup manager service is chunked:  each chunk is prefixed by
4617926a693c4a4f4d2a2d352343bca23e189c7420dChristopher Tate// a 4-byte count of its size.  A chunk size of zero (four zero bytes) indicates EOD.
4627926a693c4a4f4d2a2d352343bca23e189c7420dChristopher Tatevoid send_tarfile_chunk(BackupDataWriter* writer, const char* buffer, size_t size) {
4637926a693c4a4f4d2a2d352343bca23e189c7420dChristopher Tate    uint32_t chunk_size_no = htonl(size);
4647926a693c4a4f4d2a2d352343bca23e189c7420dChristopher Tate    writer->WriteEntityData(&chunk_size_no, 4);
4657926a693c4a4f4d2a2d352343bca23e189c7420dChristopher Tate    if (size != 0) writer->WriteEntityData(buffer, size);
4667926a693c4a4f4d2a2d352343bca23e189c7420dChristopher Tate}
4677926a693c4a4f4d2a2d352343bca23e189c7420dChristopher Tate
4684a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tateint write_tarfile(const String8& packageName, const String8& domain,
4694a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate        const String8& rootpath, const String8& filepath, BackupDataWriter* writer)
4704a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate{
4714a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate    // In the output stream everything is stored relative to the root
4724a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate    const char* relstart = filepath.string() + rootpath.length();
4734a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate    if (*relstart == '/') relstart++;     // won't be true when path == rootpath
4744a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate    String8 relpath(relstart);
4754a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate
47683a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate    // If relpath is empty, it means this is the top of one of the standard named
47783a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate    // domain directories, so we should just skip it
47883a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate    if (relpath.length() == 0) {
47983a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate        return 0;
48083a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate    }
48183a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate
4824a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate    // Too long a name for the ustar format?
4834a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate    //    "apps/" + packagename + '/' + domainpath < 155 chars
4844a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate    //    relpath < 100 chars
48583a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate    bool needExtended = false;
4864a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate    if ((5 + packageName.length() + 1 + domain.length() >= 155) || (relpath.length() >= 100)) {
48783a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate        needExtended = true;
4884a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate    }
4894a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate
4903f6c77b7caa02193205cb6ce180e0eb5a7579aa6Christopher Tate    // Non-7bit-clean path also means needing pax extended format
49175a99709accef8cf221fd436d646727e7c8dd1f1Christopher Tate    if (!needExtended) {
49275a99709accef8cf221fd436d646727e7c8dd1f1Christopher Tate        for (size_t i = 0; i < filepath.length(); i++) {
4933f6c77b7caa02193205cb6ce180e0eb5a7579aa6Christopher Tate            if ((filepath[i] & 0x80) != 0) {
49475a99709accef8cf221fd436d646727e7c8dd1f1Christopher Tate                needExtended = true;
49575a99709accef8cf221fd436d646727e7c8dd1f1Christopher Tate                break;
49675a99709accef8cf221fd436d646727e7c8dd1f1Christopher Tate            }
49775a99709accef8cf221fd436d646727e7c8dd1f1Christopher Tate        }
49875a99709accef8cf221fd436d646727e7c8dd1f1Christopher Tate    }
49975a99709accef8cf221fd436d646727e7c8dd1f1Christopher Tate
5004a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate    int err = 0;
5014a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate    struct stat64 s;
5024a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate    if (lstat64(filepath.string(), &s) != 0) {
5034a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate        err = errno;
5043762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("Error %d (%s) from lstat64(%s)", err, strerror(err), filepath.string());
5054a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate        return err;
5064a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate    }
5074a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate
50883a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate    String8 fullname;   // for pax later on
50983a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate    String8 prefix;
51083a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate
5114a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate    const int isdir = S_ISDIR(s.st_mode);
512e9e78ecd2c0ae5f48ed81fdfff4a89cb803fc409Christopher Tate    if (isdir) s.st_size = 0;   // directories get no actual data in the tar stream
5134a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate
5144a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate    // !!! TODO: use mmap when possible to avoid churning the buffer cache
5154a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate    // !!! TODO: this will break with symlinks; need to use readlink(2)
5164a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate    int fd = open(filepath.string(), O_RDONLY);
5174a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate    if (fd < 0) {
5184a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate        err = errno;
5193762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("Error %d (%s) from open(%s)", err, strerror(err), filepath.string());
5204a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate        return err;
5214a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate    }
5224a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate
5234a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate    // read/write up to this much at a time.
5244a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate    const size_t BUFSIZE = 32 * 1024;
5257e1d395686a23c8638f72af190f125cf690618a3Iliyan Malchev    char* buf = (char *)calloc(1,BUFSIZE);
52683a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate    char* paxHeader = buf + 512;    // use a different chunk of it as separate scratch
52783a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate    char* paxData = buf + 1024;
52883a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate
5294a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate    if (buf == NULL) {
5303762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("Out of mem allocating transfer buffer");
5314a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate        err = ENOMEM;
532294b512ecaa98a6a8ef12285ad14e7a4091b5d57Christopher Tate        goto done;
5334a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate    }
5344a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate
5354a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate    // Magic fields for the ustar file format
5364a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate    strcat(buf + 257, "ustar");
5374a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate    strcat(buf + 263, "00");
5384a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate
53983a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate    // [ 265 : 32 ] user name, ignored on restore
54083a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate    // [ 297 : 32 ] group name, ignored on restore
5414a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate
5424a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate    // [ 100 :   8 ] file mode
54383a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate    snprintf(buf + 100, 8, "%06o ", s.st_mode & ~S_IFMT);
5444a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate
5454a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate    // [ 108 :   8 ] uid -- ignored in Android format; uids are remapped at restore time
5464a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate    // [ 116 :   8 ] gid -- ignored in Android format
54700adb8685ee996f9d2650d617c8c0e98f13ef406Mark Salyzyn    snprintf(buf + 108, 8, "0%lo", (unsigned long)s.st_uid);
54800adb8685ee996f9d2650d617c8c0e98f13ef406Mark Salyzyn    snprintf(buf + 116, 8, "0%lo", (unsigned long)s.st_gid);
5494a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate
5504a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate    // [ 124 :  12 ] file size in bytes
55183a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate    if (s.st_size > 077777777777LL) {
55283a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate        // very large files need a pax extended size header
55383a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate        needExtended = true;
55483a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate    }
55583a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate    snprintf(buf + 124, 12, "%011llo", (isdir) ? 0LL : s.st_size);
5564a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate
5574a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate    // [ 136 :  12 ] last mod time as a UTC time_t
5584a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate    snprintf(buf + 136, 12, "%0lo", s.st_mtime);
5594a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate
5604a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate    // [ 156 :   1 ] link/file type
5614a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate    uint8_t type;
5624a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate    if (isdir) {
5634a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate        type = '5';     // tar magic: '5' == directory
5644a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate    } else if (S_ISREG(s.st_mode)) {
5654a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate        type = '0';     // tar magic: '0' == normal file
5664a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate    } else {
5678564c8da817a845353d213acd8636b76f567b234Steve Block        ALOGW("Error: unknown file mode 0%o [%s]", s.st_mode, filepath.string());
5684a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate        goto cleanup;
5694a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate    }
5704a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate    buf[156] = type;
5714a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate
5724a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate    // [ 157 : 100 ] name of linked file [not implemented]
5734a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate
5744a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate    {
57583a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate        // Prefix and main relative path.  Path lengths have been preflighted.
57683a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate        if (packageName.length() > 0) {
57783a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate            prefix = "apps/";
57883a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate            prefix += packageName;
5794a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate        }
58083a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate        if (domain.length() > 0) {
58183a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate            prefix.appendPath(domain);
58283a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate        }
58383a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate
58483a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate        // pax extended means we don't put in a prefix field, and put a different
58583a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate        // string in the basic name field.  We can also construct the full path name
58683a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate        // out of the substrings we've now built.
58783a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate        fullname = prefix;
58883a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate        fullname.appendPath(relpath);
58983a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate
59083a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate        // ustar:
59183a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate        //    [   0 : 100 ]; file name/path
59283a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate        //    [ 345 : 155 ] filename path prefix
59383a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate        // We only use the prefix area if fullname won't fit in the path
59483a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate        if (fullname.length() > 100) {
59583a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate            strncpy(buf, relpath.string(), 100);
59683a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate            strncpy(buf + 345, prefix.string(), 155);
59783a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate        } else {
59883a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate            strncpy(buf, fullname.string(), 100);
59983a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate        }
60083a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate    }
60183a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate
60283a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate    // [ 329 : 8 ] and [ 337 : 8 ] devmajor/devminor, not used
60383a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate
6046215d3ff4b5dfa52a5d8b9a42e343051f31066a5Steve Block    ALOGI("   Name: %s", fullname.string());
60583a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate
60683a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate    // If we're using a pax extended header, build & write that here; lengths are
60783a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate    // already preflighted
60883a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate    if (needExtended) {
609dc92c82b4180e8067f1acd00a7db7935afce00ffChristopher Tate        char sizeStr[32];   // big enough for a 64-bit unsigned value in decimal
610dc92c82b4180e8067f1acd00a7db7935afce00ffChristopher Tate        char* p = paxData;
611dc92c82b4180e8067f1acd00a7db7935afce00ffChristopher Tate
61283a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate        // construct the pax extended header data block
61383a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate        memset(paxData, 0, BUFSIZE - (paxData - buf));
61483a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate
61583a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate        // size header -- calc len in digits by actually rendering the number
61683a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate        // to a string - brute force but simple
617f5df700e6ce056ebfa322314d970e52d6facc35aAshok Bhat        snprintf(sizeStr, sizeof(sizeStr), "%lld", (long long)s.st_size);
618dc92c82b4180e8067f1acd00a7db7935afce00ffChristopher Tate        p += write_pax_header_entry(p, "size", sizeStr);
61983a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate
62083a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate        // fullname was generated above with the ustar paths
621dc92c82b4180e8067f1acd00a7db7935afce00ffChristopher Tate        p += write_pax_header_entry(p, "path", fullname.string());
62283a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate
62383a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate        // Now we know how big the pax data is
62483a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate        int paxLen = p - paxData;
62583a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate
62683a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate        // Now build the pax *header* templated on the ustar header
62783a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate        memcpy(paxHeader, buf, 512);
62883a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate
62983a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate        String8 leaf = fullname.getPathLeaf();
63083a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate        memset(paxHeader, 0, 100);                  // rewrite the name area
63183a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate        snprintf(paxHeader, 100, "PaxHeader/%s", leaf.string());
63283a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate        memset(paxHeader + 345, 0, 155);            // rewrite the prefix area
63383a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate        strncpy(paxHeader + 345, prefix.string(), 155);
63483a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate
63583a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate        paxHeader[156] = 'x';                       // mark it as a pax extended header
63683a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate
63783a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate        // [ 124 :  12 ] size of pax extended header data
63883a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate        memset(paxHeader + 124, 0, 12);
639f5df700e6ce056ebfa322314d970e52d6facc35aAshok Bhat        snprintf(paxHeader + 124, 12, "%011o", (unsigned int)(p - paxData));
64083a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate
64183a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate        // Checksum and write the pax block header
64283a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate        calc_tar_checksum(paxHeader);
6437926a693c4a4f4d2a2d352343bca23e189c7420dChristopher Tate        send_tarfile_chunk(writer, paxHeader, 512);
6444a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate
64583a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate        // Now write the pax data itself
64683a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate        int paxblocks = (paxLen + 511) / 512;
6477926a693c4a4f4d2a2d352343bca23e189c7420dChristopher Tate        send_tarfile_chunk(writer, paxData, 512 * paxblocks);
6484a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate    }
6494a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate
65083a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate    // Checksum and write the 512-byte ustar file header block to the output
65183a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate    calc_tar_checksum(buf);
6527926a693c4a4f4d2a2d352343bca23e189c7420dChristopher Tate    send_tarfile_chunk(writer, buf, 512);
6534a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate
6544a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate    // Now write the file data itself, for real files.  We honor tar's convention that
6554a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate    // only full 512-byte blocks are sent to write().
6564a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate    if (!isdir) {
6574a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate        off64_t toWrite = s.st_size;
6584a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate        while (toWrite > 0) {
659f5df700e6ce056ebfa322314d970e52d6facc35aAshok Bhat            size_t toRead = toWrite;
660f5df700e6ce056ebfa322314d970e52d6facc35aAshok Bhat            if (toRead > BUFSIZE) {
661f5df700e6ce056ebfa322314d970e52d6facc35aAshok Bhat                toRead = BUFSIZE;
662f5df700e6ce056ebfa322314d970e52d6facc35aAshok Bhat            }
6634a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate            ssize_t nRead = read(fd, buf, toRead);
6644a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate            if (nRead < 0) {
6654a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate                err = errno;
6663762c311729fe9f3af085c14c5c1fb471d994c03Steve Block                ALOGE("Unable to read file [%s], err=%d (%s)", filepath.string(),
6674a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate                        err, strerror(err));
6684a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate                break;
6694a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate            } else if (nRead == 0) {
6703762c311729fe9f3af085c14c5c1fb471d994c03Steve Block                ALOGE("EOF but expect %lld more bytes in [%s]", (long long) toWrite,
6714a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate                        filepath.string());
6724a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate                err = EIO;
6734a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate                break;
6744a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate            }
6754a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate
6764a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate            // At EOF we might have a short block; NUL-pad that to a 512-byte multiple.  This
6774a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate            // depends on the OS guarantee that for ordinary files, read() will never return
6784a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate            // less than the number of bytes requested.
6794a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate            ssize_t partial = (nRead+512) % 512;
6804a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate            if (partial > 0) {
6814a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate                ssize_t remainder = 512 - partial;
6824a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate                memset(buf + nRead, 0, remainder);
6834a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate                nRead += remainder;
6844a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate            }
6857926a693c4a4f4d2a2d352343bca23e189c7420dChristopher Tate            send_tarfile_chunk(writer, buf, nRead);
6864a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate            toWrite -= nRead;
6874a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate        }
6884a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate    }
6894a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate
6904a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tatecleanup:
6918b2e2c8abc20de5ba3d938d8c559d0c5e2f9e356You Kim    free(buf);
6924a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tatedone:
6934a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate    close(fd);
6944a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate    return err;
6954a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate}
6964a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate// end tarfile
6974a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate
6984a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate
6994a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate
700d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato#define RESTORE_BUF_SIZE (8*1024)
701d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato
702d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe OnoratoRestoreHelperBase::RestoreHelperBase()
703d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato{
704d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato    m_buf = malloc(RESTORE_BUF_SIZE);
70563bcb79dd437e70593b63cc5a87baab3251c2183Christopher Tate    m_loggedUnknownMetadata = false;
706d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato}
707d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato
708d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe OnoratoRestoreHelperBase::~RestoreHelperBase()
709d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato{
710d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato    free(m_buf);
711d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato}
712d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato
713d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onoratostatus_t
714d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe OnoratoRestoreHelperBase::WriteFile(const String8& filename, BackupDataReader* in)
715d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato{
716d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato    ssize_t err;
717d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato    size_t dataSize;
718d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato    String8 key;
719d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato    int fd;
720d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato    void* buf = m_buf;
721d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato    ssize_t amt;
722d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato    int mode;
723d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato    int crc;
724d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato    struct stat st;
725d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato    FileRec r;
726d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato
727d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato    err = in->ReadEntityHeader(&key, &dataSize);
728d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato    if (err != NO_ERROR) {
729d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato        return err;
730d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato    }
7315d605dc56b036232e885f6ec36b888b729673060Joe Onorato
732fbb92385f2fb0ae1146bb8f3d73547d90bda6db1Christopher Tate    // Get the metadata block off the head of the file entity and use that to
733fbb92385f2fb0ae1146bb8f3d73547d90bda6db1Christopher Tate    // set up the output file
734fbb92385f2fb0ae1146bb8f3d73547d90bda6db1Christopher Tate    file_metadata_v1 metadata;
735fbb92385f2fb0ae1146bb8f3d73547d90bda6db1Christopher Tate    amt = in->ReadEntityData(&metadata, sizeof(metadata));
736fbb92385f2fb0ae1146bb8f3d73547d90bda6db1Christopher Tate    if (amt != sizeof(metadata)) {
7378564c8da817a845353d213acd8636b76f567b234Steve Block        ALOGW("Could not read metadata for %s -- %ld / %s", filename.string(),
738fbb92385f2fb0ae1146bb8f3d73547d90bda6db1Christopher Tate                (long)amt, strerror(errno));
739fbb92385f2fb0ae1146bb8f3d73547d90bda6db1Christopher Tate        return EIO;
740fbb92385f2fb0ae1146bb8f3d73547d90bda6db1Christopher Tate    }
741fbb92385f2fb0ae1146bb8f3d73547d90bda6db1Christopher Tate    metadata.version = fromlel(metadata.version);
742fbb92385f2fb0ae1146bb8f3d73547d90bda6db1Christopher Tate    metadata.mode = fromlel(metadata.mode);
743fbb92385f2fb0ae1146bb8f3d73547d90bda6db1Christopher Tate    if (metadata.version > CURRENT_METADATA_VERSION) {
74463bcb79dd437e70593b63cc5a87baab3251c2183Christopher Tate        if (!m_loggedUnknownMetadata) {
74563bcb79dd437e70593b63cc5a87baab3251c2183Christopher Tate            m_loggedUnknownMetadata = true;
7468564c8da817a845353d213acd8636b76f567b234Steve Block            ALOGW("Restoring file with unsupported metadata version %d (currently %d)",
74763bcb79dd437e70593b63cc5a87baab3251c2183Christopher Tate                    metadata.version, CURRENT_METADATA_VERSION);
74863bcb79dd437e70593b63cc5a87baab3251c2183Christopher Tate        }
749fbb92385f2fb0ae1146bb8f3d73547d90bda6db1Christopher Tate    }
750fbb92385f2fb0ae1146bb8f3d73547d90bda6db1Christopher Tate    mode = metadata.mode;
751d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato
752d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato    // Write the file and compute the crc
753d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato    crc = crc32(0L, Z_NULL, 0);
7545d605dc56b036232e885f6ec36b888b729673060Joe Onorato    fd = open(filename.string(), O_CREAT|O_RDWR|O_TRUNC, mode);
7555d605dc56b036232e885f6ec36b888b729673060Joe Onorato    if (fd == -1) {
7568564c8da817a845353d213acd8636b76f567b234Steve Block        ALOGW("Could not open file %s -- %s", filename.string(), strerror(errno));
757d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato        return errno;
758d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato    }
75900adb8685ee996f9d2650d617c8c0e98f13ef406Mark Salyzyn
760d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato    while ((amt = in->ReadEntityData(buf, RESTORE_BUF_SIZE)) > 0) {
761d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato        err = write(fd, buf, amt);
762d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato        if (err != amt) {
763d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato            close(fd);
7648564c8da817a845353d213acd8636b76f567b234Steve Block            ALOGW("Error '%s' writing '%s'", strerror(errno), filename.string());
765d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato            return errno;
766d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato        }
767d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato        crc = crc32(crc, (Bytef*)buf, amt);
768d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato    }
769d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato
770d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato    close(fd);
771d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato
772d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato    // Record for the snapshot
773d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato    err = stat(filename.string(), &st);
774d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato    if (err != 0) {
7758564c8da817a845353d213acd8636b76f567b234Steve Block        ALOGW("Error stating file that we just created %s", filename.string());
776d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato        return errno;
777d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato    }
778d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato
779d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato    r.file = filename;
780d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato    r.deleted = false;
781d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato    r.s.modTime_sec = st.st_mtime;
782d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato    r.s.modTime_nsec = 0; // workaround sim breakage
783d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato    //r.s.modTime_nsec = st.st_mtime_nsec;
78411b157790234d3d2f116ce4c7ed1d3d00fb78bc3Christopher Tate    r.s.mode = st.st_mode;
785d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato    r.s.size = st.st_size;
786d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato    r.s.crc32 = crc;
787d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato
788d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato    m_files.add(key, r);
789d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato
790d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato    return NO_ERROR;
791d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato}
792d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato
793d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onoratostatus_t
794d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe OnoratoRestoreHelperBase::WriteSnapshot(int fd)
795d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato{
796d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato    return write_snapshot_file(fd, m_files);;
797d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato}
798d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato
7993ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato#if TEST_BACKUP_HELPERS
8003ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
8013ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato#define SCRATCH_DIR "/data/backup_helper_test/"
8023ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
8033ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onoratostatic int
8043ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onoratowrite_text_file(const char* path, const char* data)
8053ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato{
8063ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    int amt;
8073ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    int fd;
8083ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    int len;
8093ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
8103ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    fd = creat(path, 0666);
8113ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    if (fd == -1) {
8123ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        fprintf(stderr, "creat %s failed\n", path);
8133ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        return errno;
8143ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    }
8153ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
8163ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    len = strlen(data);
8173ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    amt = write(fd, data, len);
8183ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    if (amt != len) {
8193ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        fprintf(stderr, "error (%s) writing to file %s\n", strerror(errno), path);
8203ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        return errno;
8213ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    }
8223ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
8233ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    close(fd);
8243ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
8253ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    return 0;
8263ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato}
8273ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
8283ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onoratostatic int
8293ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onoratocompare_file(const char* path, const unsigned char* data, int len)
8303ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato{
8313ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    int fd;
8323ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    int amt;
8333ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
8343ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    fd = open(path, O_RDONLY);
8353ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    if (fd == -1) {
8363ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        fprintf(stderr, "compare_file error (%s) opening %s\n", strerror(errno), path);
8373ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        return errno;
8383ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    }
8393ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
8403ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    unsigned char* contents = (unsigned char*)malloc(len);
8413ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    if (contents == NULL) {
8423ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        fprintf(stderr, "malloc(%d) failed\n", len);
8433ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        return ENOMEM;
8443ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    }
8453ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
8463ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    bool sizesMatch = true;
8473ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    amt = lseek(fd, 0, SEEK_END);
8483ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    if (amt != len) {
8493ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        fprintf(stderr, "compare_file file length should be %d, was %d\n", len, amt);
8503ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        sizesMatch = false;
8513ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    }
8523ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    lseek(fd, 0, SEEK_SET);
8533ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
8543ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    int readLen = amt < len ? amt : len;
8553ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    amt = read(fd, contents, readLen);
8563ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    if (amt != readLen) {
8573ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        fprintf(stderr, "compare_file read expected %d bytes but got %d\n", len, amt);
8583ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    }
8593ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
8603ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    bool contentsMatch = true;
8613ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    for (int i=0; i<readLen; i++) {
8623ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        if (data[i] != contents[i]) {
8633ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato            if (contentsMatch) {
8643ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato                fprintf(stderr, "compare_file contents are different: (index, expected, actual)\n");
8653ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato                contentsMatch = false;
8663ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato            }
8673ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato            fprintf(stderr, "  [%-2d] %02x %02x\n", i, data[i], contents[i]);
8683ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        }
8693ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    }
8703ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
87163bcb79dd437e70593b63cc5a87baab3251c2183Christopher Tate    free(contents);
8723ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    return contentsMatch && sizesMatch ? 0 : 1;
8733ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato}
8743ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
8753ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onoratoint
8763ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onoratobackup_helper_test_empty()
8773ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato{
8783ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    int err;
8793ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    int fd;
88023ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato    KeyedVector<String8,FileRec> snapshot;
8813ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    const char* filename = SCRATCH_DIR "backup_helper_test_empty.snap";
8823ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
8833ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    system("rm -r " SCRATCH_DIR);
8843ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    mkdir(SCRATCH_DIR, 0777);
8853ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
8863ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    // write
8873ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    fd = creat(filename, 0666);
8883ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    if (fd == -1) {
8893ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        fprintf(stderr, "error creating %s\n", filename);
8903ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        return 1;
8913ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    }
8923ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
8933ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    err = write_snapshot_file(fd, snapshot);
8943ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
8953ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    close(fd);
8963ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
8973ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    if (err != 0) {
8983ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        fprintf(stderr, "write_snapshot_file reported error %d (%s)\n", err, strerror(err));
8993ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        return err;
9003ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    }
9013ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
9023ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    static const unsigned char correct_data[] = {
9033ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        0x53, 0x6e, 0x61, 0x70,  0x00, 0x00, 0x00, 0x00,
9043ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        0x46, 0x69, 0x6c, 0x65,  0x10, 0x00, 0x00, 0x00
9053ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    };
9063ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
9073ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    err = compare_file(filename, correct_data, sizeof(correct_data));
9083ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    if (err != 0) {
9093ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        return err;
9103ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    }
9113ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
9123ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    // read
9133ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    fd = open(filename, O_RDONLY);
9143ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    if (fd == -1) {
9153ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        fprintf(stderr, "error opening for read %s\n", filename);
9163ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        return 1;
9173ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    }
9183ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
9193ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    KeyedVector<String8,FileState> readSnapshot;
9203ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    err = read_snapshot_file(fd, &readSnapshot);
9213ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    if (err != 0) {
9223ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        fprintf(stderr, "read_snapshot_file failed %d\n", err);
9233ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        return err;
9243ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    }
9253ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
9263ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    if (readSnapshot.size() != 0) {
9273ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        fprintf(stderr, "readSnapshot should be length 0\n");
9283ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        return 1;
9293ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    }
9303ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
9313ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    return 0;
9323ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato}
9333ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
9343ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onoratoint
9353ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onoratobackup_helper_test_four()
9363ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato{
9373ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    int err;
9383ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    int fd;
93923ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato    KeyedVector<String8,FileRec> snapshot;
9403ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    const char* filename = SCRATCH_DIR "backup_helper_test_four.snap";
9413ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
9423ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    system("rm -r " SCRATCH_DIR);
9433ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    mkdir(SCRATCH_DIR, 0777);
9443ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
9453ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    // write
9463ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    fd = creat(filename, 0666);
9473ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    if (fd == -1) {
9483ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        fprintf(stderr, "error opening %s\n", filename);
9493ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        return 1;
9503ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    }
9513ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
9523ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    String8 filenames[4];
9533ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    FileState states[4];
95423ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato    FileRec r;
955ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato    r.deleted = false;
9563ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
9573ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    states[0].modTime_sec = 0xfedcba98;
9583ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    states[0].modTime_nsec = 0xdeadbeef;
95911b157790234d3d2f116ce4c7ed1d3d00fb78bc3Christopher Tate    states[0].mode = 0777; // decimal 511, hex 0x000001ff
9603ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    states[0].size = 0xababbcbc;
9613ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    states[0].crc32 = 0x12345678;
9623ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    states[0].nameLen = -12;
96323ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato    r.s = states[0];
9643ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    filenames[0] = String8("bytes_of_padding");
96523ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato    snapshot.add(filenames[0], r);
9663ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
9673ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    states[1].modTime_sec = 0x93400031;
9683ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    states[1].modTime_nsec = 0xdeadbeef;
96911b157790234d3d2f116ce4c7ed1d3d00fb78bc3Christopher Tate    states[1].mode = 0666; // decimal 438, hex 0x000001b6
9703ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    states[1].size = 0x88557766;
9713ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    states[1].crc32 = 0x22334422;
9723ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    states[1].nameLen = -1;
97323ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato    r.s = states[1];
9743ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    filenames[1] = String8("bytes_of_padding3");
97523ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato    snapshot.add(filenames[1], r);
9763ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
9773ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    states[2].modTime_sec = 0x33221144;
9783ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    states[2].modTime_nsec = 0xdeadbeef;
97911b157790234d3d2f116ce4c7ed1d3d00fb78bc3Christopher Tate    states[2].mode = 0744; // decimal 484, hex 0x000001e4
9803ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    states[2].size = 0x11223344;
9813ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    states[2].crc32 = 0x01122334;
9823ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    states[2].nameLen = 0;
98323ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato    r.s = states[2];
9843ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    filenames[2] = String8("bytes_of_padding_2");
98523ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato    snapshot.add(filenames[2], r);
9863ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
9873ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    states[3].modTime_sec = 0x33221144;
9883ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    states[3].modTime_nsec = 0xdeadbeef;
98911b157790234d3d2f116ce4c7ed1d3d00fb78bc3Christopher Tate    states[3].mode = 0755; // decimal 493, hex 0x000001ed
9903ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    states[3].size = 0x11223344;
9913ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    states[3].crc32 = 0x01122334;
9923ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    states[3].nameLen = 0;
99323ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato    r.s = states[3];
9943ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    filenames[3] = String8("bytes_of_padding__1");
99523ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato    snapshot.add(filenames[3], r);
9963ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
9973ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    err = write_snapshot_file(fd, snapshot);
9983ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
9993ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    close(fd);
10003ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
10013ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    if (err != 0) {
10023ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        fprintf(stderr, "write_snapshot_file reported error %d (%s)\n", err, strerror(err));
10033ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        return err;
10043ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    }
10053ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
10063ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    static const unsigned char correct_data[] = {
10073ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        // header
10083ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        0x53, 0x6e, 0x61, 0x70,  0x04, 0x00, 0x00, 0x00,
100911b157790234d3d2f116ce4c7ed1d3d00fb78bc3Christopher Tate        0x46, 0x69, 0x6c, 0x65,  0xbc, 0x00, 0x00, 0x00,
10103ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
10113ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        // bytes_of_padding
10123ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        0x98, 0xba, 0xdc, 0xfe,  0xef, 0xbe, 0xad, 0xde,
101311b157790234d3d2f116ce4c7ed1d3d00fb78bc3Christopher Tate        0xff, 0x01, 0x00, 0x00,  0xbc, 0xbc, 0xab, 0xab,
101411b157790234d3d2f116ce4c7ed1d3d00fb78bc3Christopher Tate        0x78, 0x56, 0x34, 0x12,  0x10, 0x00, 0x00, 0x00,
101511b157790234d3d2f116ce4c7ed1d3d00fb78bc3Christopher Tate        0x62, 0x79, 0x74, 0x65,  0x73, 0x5f, 0x6f, 0x66,
101611b157790234d3d2f116ce4c7ed1d3d00fb78bc3Christopher Tate        0x5f, 0x70, 0x61, 0x64,  0x64, 0x69, 0x6e, 0x67,
10173ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
10183ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        // bytes_of_padding3
10193ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        0x31, 0x00, 0x40, 0x93,  0xef, 0xbe, 0xad, 0xde,
102011b157790234d3d2f116ce4c7ed1d3d00fb78bc3Christopher Tate        0xb6, 0x01, 0x00, 0x00,  0x66, 0x77, 0x55, 0x88,
102111b157790234d3d2f116ce4c7ed1d3d00fb78bc3Christopher Tate        0x22, 0x44, 0x33, 0x22,  0x11, 0x00, 0x00, 0x00,
102211b157790234d3d2f116ce4c7ed1d3d00fb78bc3Christopher Tate        0x62, 0x79, 0x74, 0x65,  0x73, 0x5f, 0x6f, 0x66,
102311b157790234d3d2f116ce4c7ed1d3d00fb78bc3Christopher Tate        0x5f, 0x70, 0x61, 0x64,  0x64, 0x69, 0x6e, 0x67,
102411b157790234d3d2f116ce4c7ed1d3d00fb78bc3Christopher Tate        0x33, 0xab, 0xab, 0xab,
1025f4c46b94b867f6a01bf7d0be18f667819338072fNicolas Catania
10263ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        // bytes of padding2
10273ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        0x44, 0x11, 0x22, 0x33,  0xef, 0xbe, 0xad, 0xde,
102811b157790234d3d2f116ce4c7ed1d3d00fb78bc3Christopher Tate        0xe4, 0x01, 0x00, 0x00,  0x44, 0x33, 0x22, 0x11,
102911b157790234d3d2f116ce4c7ed1d3d00fb78bc3Christopher Tate        0x34, 0x23, 0x12, 0x01,  0x12, 0x00, 0x00, 0x00,
103011b157790234d3d2f116ce4c7ed1d3d00fb78bc3Christopher Tate        0x62, 0x79, 0x74, 0x65,  0x73, 0x5f, 0x6f, 0x66,
103111b157790234d3d2f116ce4c7ed1d3d00fb78bc3Christopher Tate        0x5f, 0x70, 0x61, 0x64,  0x64, 0x69, 0x6e, 0x67,
103211b157790234d3d2f116ce4c7ed1d3d00fb78bc3Christopher Tate        0x5f, 0x32, 0xab, 0xab,
1033f4c46b94b867f6a01bf7d0be18f667819338072fNicolas Catania
10343ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        // bytes of padding3
10353ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        0x44, 0x11, 0x22, 0x33,  0xef, 0xbe, 0xad, 0xde,
103611b157790234d3d2f116ce4c7ed1d3d00fb78bc3Christopher Tate        0xed, 0x01, 0x00, 0x00,  0x44, 0x33, 0x22, 0x11,
103711b157790234d3d2f116ce4c7ed1d3d00fb78bc3Christopher Tate        0x34, 0x23, 0x12, 0x01,  0x13, 0x00, 0x00, 0x00,
103811b157790234d3d2f116ce4c7ed1d3d00fb78bc3Christopher Tate        0x62, 0x79, 0x74, 0x65,  0x73, 0x5f, 0x6f, 0x66,
103911b157790234d3d2f116ce4c7ed1d3d00fb78bc3Christopher Tate        0x5f, 0x70, 0x61, 0x64,  0x64, 0x69, 0x6e, 0x67,
104011b157790234d3d2f116ce4c7ed1d3d00fb78bc3Christopher Tate        0x5f, 0x5f, 0x31, 0xab
10413ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    };
10423ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
10433ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    err = compare_file(filename, correct_data, sizeof(correct_data));
10443ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    if (err != 0) {
10453ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        return err;
10463ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    }
1047f4c46b94b867f6a01bf7d0be18f667819338072fNicolas Catania
10483ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    // read
10493ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    fd = open(filename, O_RDONLY);
10503ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    if (fd == -1) {
10513ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        fprintf(stderr, "error opening for read %s\n", filename);
10523ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        return 1;
10533ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    }
10543ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
10553ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
10563ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    KeyedVector<String8,FileState> readSnapshot;
10573ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    err = read_snapshot_file(fd, &readSnapshot);
10583ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    if (err != 0) {
10593ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        fprintf(stderr, "read_snapshot_file failed %d\n", err);
10603ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        return err;
10613ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    }
10623ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
10633ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    if (readSnapshot.size() != 4) {
106495ece35c2f8b86203e88b49d67cef8e80e107a2bKévin PETIT        fprintf(stderr, "readSnapshot should be length 4 is %zu\n", readSnapshot.size());
10653ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        return 1;
10663ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    }
10673ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
10683ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    bool matched = true;
10693ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    for (size_t i=0; i<readSnapshot.size(); i++) {
10703ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        const String8& name = readSnapshot.keyAt(i);
10713ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        const FileState state = readSnapshot.valueAt(i);
10723ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
10733ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        if (name != filenames[i] || states[i].modTime_sec != state.modTime_sec
107411b157790234d3d2f116ce4c7ed1d3d00fb78bc3Christopher Tate                || states[i].modTime_nsec != state.modTime_nsec || states[i].mode != state.mode
10753ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato                || states[i].size != state.size || states[i].crc32 != states[i].crc32) {
1076f5df700e6ce056ebfa322314d970e52d6facc35aAshok Bhat            fprintf(stderr, "state %zu expected={%d/%d, %04o, 0x%08x, 0x%08x, %3zu} '%s'\n"
1077f5df700e6ce056ebfa322314d970e52d6facc35aAshok Bhat                            "          actual={%d/%d, %04o, 0x%08x, 0x%08x, %3d} '%s'\n", i,
107811b157790234d3d2f116ce4c7ed1d3d00fb78bc3Christopher Tate                    states[i].modTime_sec, states[i].modTime_nsec, states[i].mode, states[i].size,
107911b157790234d3d2f116ce4c7ed1d3d00fb78bc3Christopher Tate                    states[i].crc32, name.length(), filenames[i].string(),
108011b157790234d3d2f116ce4c7ed1d3d00fb78bc3Christopher Tate                    state.modTime_sec, state.modTime_nsec, state.mode, state.size, state.crc32,
108111b157790234d3d2f116ce4c7ed1d3d00fb78bc3Christopher Tate                    state.nameLen, name.string());
10823ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato            matched = false;
10833ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        }
10843ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    }
1085f4c46b94b867f6a01bf7d0be18f667819338072fNicolas Catania
10863ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    return matched ? 0 : 1;
10873ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato}
10883ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
10894535e40544aeb957d44fad75fbe5676effe03689Joe Onorato// hexdump -v -e '"    " 8/1 " 0x%02x," "\n"' data_writer.data
10904535e40544aeb957d44fad75fbe5676effe03689Joe Onoratoconst unsigned char DATA_GOLDEN_FILE[] = {
10912e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato     0x44, 0x61, 0x74, 0x61, 0x0b, 0x00, 0x00, 0x00,
10922e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato     0x0c, 0x00, 0x00, 0x00, 0x6e, 0x6f, 0x5f, 0x70,
10934535e40544aeb957d44fad75fbe5676effe03689Joe Onorato     0x61, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x5f, 0x00,
10942e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato     0x6e, 0x6f, 0x5f, 0x70, 0x61, 0x64, 0x64, 0x69,
10955f15d151b5101fadfe6cba1e8f4aa6367e8c603eJoe Onorato     0x6e, 0x67, 0x5f, 0x00, 0x44, 0x61, 0x74, 0x61,
10965f15d151b5101fadfe6cba1e8f4aa6367e8c603eJoe Onorato     0x0c, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00,
10974535e40544aeb957d44fad75fbe5676effe03689Joe Onorato     0x70, 0x61, 0x64, 0x64, 0x65, 0x64, 0x5f, 0x74,
10984535e40544aeb957d44fad75fbe5676effe03689Joe Onorato     0x6f, 0x5f, 0x5f, 0x33, 0x00, 0xbc, 0xbc, 0xbc,
10994535e40544aeb957d44fad75fbe5676effe03689Joe Onorato     0x70, 0x61, 0x64, 0x64, 0x65, 0x64, 0x5f, 0x74,
11005f15d151b5101fadfe6cba1e8f4aa6367e8c603eJoe Onorato     0x6f, 0x5f, 0x5f, 0x33, 0x00, 0xbc, 0xbc, 0xbc,
11012e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato     0x44, 0x61, 0x74, 0x61, 0x0d, 0x00, 0x00, 0x00,
11022e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato     0x0e, 0x00, 0x00, 0x00, 0x70, 0x61, 0x64, 0x64,
11032e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato     0x65, 0x64, 0x5f, 0x74, 0x6f, 0x5f, 0x32, 0x5f,
11042e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato     0x5f, 0x00, 0xbc, 0xbc, 0x70, 0x61, 0x64, 0x64,
11052e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato     0x65, 0x64, 0x5f, 0x74, 0x6f, 0x5f, 0x32, 0x5f,
11065f15d151b5101fadfe6cba1e8f4aa6367e8c603eJoe Onorato     0x5f, 0x00, 0xbc, 0xbc, 0x44, 0x61, 0x74, 0x61,
11074535e40544aeb957d44fad75fbe5676effe03689Joe Onorato     0x0a, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00,
11084535e40544aeb957d44fad75fbe5676effe03689Joe Onorato     0x70, 0x61, 0x64, 0x64, 0x65, 0x64, 0x5f, 0x74,
11094535e40544aeb957d44fad75fbe5676effe03689Joe Onorato     0x6f, 0x31, 0x00, 0xbc, 0x70, 0x61, 0x64, 0x64,
11105f15d151b5101fadfe6cba1e8f4aa6367e8c603eJoe Onorato     0x65, 0x64, 0x5f, 0x74, 0x6f, 0x31, 0x00
11115f15d151b5101fadfe6cba1e8f4aa6367e8c603eJoe Onorato
11124535e40544aeb957d44fad75fbe5676effe03689Joe Onorato};
11134535e40544aeb957d44fad75fbe5676effe03689Joe Onoratoconst int DATA_GOLDEN_FILE_SIZE = sizeof(DATA_GOLDEN_FILE);
11144535e40544aeb957d44fad75fbe5676effe03689Joe Onorato
11154535e40544aeb957d44fad75fbe5676effe03689Joe Onoratostatic int
11164535e40544aeb957d44fad75fbe5676effe03689Joe Onoratotest_write_header_and_entity(BackupDataWriter& writer, const char* str)
11174535e40544aeb957d44fad75fbe5676effe03689Joe Onorato{
11184535e40544aeb957d44fad75fbe5676effe03689Joe Onorato    int err;
11194535e40544aeb957d44fad75fbe5676effe03689Joe Onorato    String8 text(str);
11204535e40544aeb957d44fad75fbe5676effe03689Joe Onorato
11214535e40544aeb957d44fad75fbe5676effe03689Joe Onorato    err = writer.WriteEntityHeader(text, text.length()+1);
11224535e40544aeb957d44fad75fbe5676effe03689Joe Onorato    if (err != 0) {
11234535e40544aeb957d44fad75fbe5676effe03689Joe Onorato        fprintf(stderr, "WriteEntityHeader failed with %s\n", strerror(err));
11244535e40544aeb957d44fad75fbe5676effe03689Joe Onorato        return err;
11254535e40544aeb957d44fad75fbe5676effe03689Joe Onorato    }
11264535e40544aeb957d44fad75fbe5676effe03689Joe Onorato
11274535e40544aeb957d44fad75fbe5676effe03689Joe Onorato    err = writer.WriteEntityData(text.string(), text.length()+1);
11284535e40544aeb957d44fad75fbe5676effe03689Joe Onorato    if (err != 0) {
11294535e40544aeb957d44fad75fbe5676effe03689Joe Onorato        fprintf(stderr, "write failed for data '%s'\n", text.string());
11304535e40544aeb957d44fad75fbe5676effe03689Joe Onorato        return errno;
11314535e40544aeb957d44fad75fbe5676effe03689Joe Onorato    }
11324535e40544aeb957d44fad75fbe5676effe03689Joe Onorato
11334535e40544aeb957d44fad75fbe5676effe03689Joe Onorato    return err;
11344535e40544aeb957d44fad75fbe5676effe03689Joe Onorato}
11354535e40544aeb957d44fad75fbe5676effe03689Joe Onorato
11364535e40544aeb957d44fad75fbe5676effe03689Joe Onoratoint
11374535e40544aeb957d44fad75fbe5676effe03689Joe Onoratobackup_helper_test_data_writer()
11384535e40544aeb957d44fad75fbe5676effe03689Joe Onorato{
11394535e40544aeb957d44fad75fbe5676effe03689Joe Onorato    int err;
11404535e40544aeb957d44fad75fbe5676effe03689Joe Onorato    int fd;
11414535e40544aeb957d44fad75fbe5676effe03689Joe Onorato    const char* filename = SCRATCH_DIR "data_writer.data";
11424535e40544aeb957d44fad75fbe5676effe03689Joe Onorato
11434535e40544aeb957d44fad75fbe5676effe03689Joe Onorato    system("rm -r " SCRATCH_DIR);
11444535e40544aeb957d44fad75fbe5676effe03689Joe Onorato    mkdir(SCRATCH_DIR, 0777);
11454535e40544aeb957d44fad75fbe5676effe03689Joe Onorato    mkdir(SCRATCH_DIR "data", 0777);
1146f4c46b94b867f6a01bf7d0be18f667819338072fNicolas Catania
11474535e40544aeb957d44fad75fbe5676effe03689Joe Onorato    fd = creat(filename, 0666);
11484535e40544aeb957d44fad75fbe5676effe03689Joe Onorato    if (fd == -1) {
11494535e40544aeb957d44fad75fbe5676effe03689Joe Onorato        fprintf(stderr, "error creating: %s\n", strerror(errno));
11504535e40544aeb957d44fad75fbe5676effe03689Joe Onorato        return errno;
11514535e40544aeb957d44fad75fbe5676effe03689Joe Onorato    }
11524535e40544aeb957d44fad75fbe5676effe03689Joe Onorato
11534535e40544aeb957d44fad75fbe5676effe03689Joe Onorato    BackupDataWriter writer(fd);
11544535e40544aeb957d44fad75fbe5676effe03689Joe Onorato
11554535e40544aeb957d44fad75fbe5676effe03689Joe Onorato    err = 0;
11564535e40544aeb957d44fad75fbe5676effe03689Joe Onorato    err |= test_write_header_and_entity(writer, "no_padding_");
11574535e40544aeb957d44fad75fbe5676effe03689Joe Onorato    err |= test_write_header_and_entity(writer, "padded_to__3");
11584535e40544aeb957d44fad75fbe5676effe03689Joe Onorato    err |= test_write_header_and_entity(writer, "padded_to_2__");
11594535e40544aeb957d44fad75fbe5676effe03689Joe Onorato    err |= test_write_header_and_entity(writer, "padded_to1");
11604535e40544aeb957d44fad75fbe5676effe03689Joe Onorato
11614535e40544aeb957d44fad75fbe5676effe03689Joe Onorato    close(fd);
11624535e40544aeb957d44fad75fbe5676effe03689Joe Onorato
11634535e40544aeb957d44fad75fbe5676effe03689Joe Onorato    err = compare_file(filename, DATA_GOLDEN_FILE, DATA_GOLDEN_FILE_SIZE);
11644535e40544aeb957d44fad75fbe5676effe03689Joe Onorato    if (err != 0) {
11654535e40544aeb957d44fad75fbe5676effe03689Joe Onorato        return err;
11664535e40544aeb957d44fad75fbe5676effe03689Joe Onorato    }
11674535e40544aeb957d44fad75fbe5676effe03689Joe Onorato
11684535e40544aeb957d44fad75fbe5676effe03689Joe Onorato    return err;
11694535e40544aeb957d44fad75fbe5676effe03689Joe Onorato}
11704535e40544aeb957d44fad75fbe5676effe03689Joe Onorato
11712e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onoratoint
11722e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onoratotest_read_header_and_entity(BackupDataReader& reader, const char* str)
11732e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato{
11742e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    int err;
1175f5df700e6ce056ebfa322314d970e52d6facc35aAshok Bhat    size_t bufSize = strlen(str)+1;
11762e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    char* buf = (char*)malloc(bufSize);
11772e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    String8 string;
11782e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    size_t actualSize;
11795f15d151b5101fadfe6cba1e8f4aa6367e8c603eJoe Onorato    bool done;
11805f15d151b5101fadfe6cba1e8f4aa6367e8c603eJoe Onorato    int type;
118111b157790234d3d2f116ce4c7ed1d3d00fb78bc3Christopher Tate    ssize_t nRead;
11822e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato
11832e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    // printf("\n\n---------- test_read_header_and_entity -- %s\n\n", str);
11842e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato
11855f15d151b5101fadfe6cba1e8f4aa6367e8c603eJoe Onorato    err = reader.ReadNextHeader(&done, &type);
11865f15d151b5101fadfe6cba1e8f4aa6367e8c603eJoe Onorato    if (done) {
11875f15d151b5101fadfe6cba1e8f4aa6367e8c603eJoe Onorato        fprintf(stderr, "should not be done yet\n");
11885f15d151b5101fadfe6cba1e8f4aa6367e8c603eJoe Onorato        goto finished;
11892e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    }
11902e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    if (err != 0) {
11915f15d151b5101fadfe6cba1e8f4aa6367e8c603eJoe Onorato        fprintf(stderr, "ReadNextHeader (for app header) failed with %s\n", strerror(err));
11925f15d151b5101fadfe6cba1e8f4aa6367e8c603eJoe Onorato        goto finished;
11932e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    }
11945f15d151b5101fadfe6cba1e8f4aa6367e8c603eJoe Onorato    if (type != BACKUP_HEADER_ENTITY_V1) {
11952e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato        err = EINVAL;
11965f15d151b5101fadfe6cba1e8f4aa6367e8c603eJoe Onorato        fprintf(stderr, "type=0x%08x expected 0x%08x\n", type, BACKUP_HEADER_ENTITY_V1);
11972e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    }
11982e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato
11992e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    err = reader.ReadEntityHeader(&string, &actualSize);
12002e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    if (err != 0) {
12012e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato        fprintf(stderr, "ReadEntityHeader failed with %s\n", strerror(err));
12025f15d151b5101fadfe6cba1e8f4aa6367e8c603eJoe Onorato        goto finished;
12032e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    }
12042e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    if (string != str) {
12052e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato        fprintf(stderr, "ReadEntityHeader expected key '%s' got '%s'\n", str, string.string());
12062e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato        err = EINVAL;
12075f15d151b5101fadfe6cba1e8f4aa6367e8c603eJoe Onorato        goto finished;
12082e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    }
1209f5df700e6ce056ebfa322314d970e52d6facc35aAshok Bhat    if (actualSize != bufSize) {
1210f5df700e6ce056ebfa322314d970e52d6facc35aAshok Bhat        fprintf(stderr, "ReadEntityHeader expected dataSize %zu got %zu\n",
1211f5df700e6ce056ebfa322314d970e52d6facc35aAshok Bhat                bufSize, actualSize);
12122e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato        err = EINVAL;
12135f15d151b5101fadfe6cba1e8f4aa6367e8c603eJoe Onorato        goto finished;
12142e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    }
12152e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato
121611b157790234d3d2f116ce4c7ed1d3d00fb78bc3Christopher Tate    nRead = reader.ReadEntityData(buf, bufSize);
121711b157790234d3d2f116ce4c7ed1d3d00fb78bc3Christopher Tate    if (nRead < 0) {
121811b157790234d3d2f116ce4c7ed1d3d00fb78bc3Christopher Tate        err = reader.Status();
12192e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato        fprintf(stderr, "ReadEntityData failed with %s\n", strerror(err));
12205f15d151b5101fadfe6cba1e8f4aa6367e8c603eJoe Onorato        goto finished;
12212e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    }
12222e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato
12232e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    if (0 != memcmp(buf, str, bufSize)) {
12242e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato        fprintf(stderr, "ReadEntityData expected '%s' but got something starting with "
12255f15d151b5101fadfe6cba1e8f4aa6367e8c603eJoe Onorato                "%02x %02x %02x %02x  '%c%c%c%c'\n", str, buf[0], buf[1], buf[2], buf[3],
12265f15d151b5101fadfe6cba1e8f4aa6367e8c603eJoe Onorato                buf[0], buf[1], buf[2], buf[3]);
12272e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato        err = EINVAL;
12285f15d151b5101fadfe6cba1e8f4aa6367e8c603eJoe Onorato        goto finished;
12292e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    }
12302e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato
12312e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    // The next read will confirm whether it got the right amount of data.
12322e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato
12335f15d151b5101fadfe6cba1e8f4aa6367e8c603eJoe Onoratofinished:
12342e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    if (err != NO_ERROR) {
12352e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato        fprintf(stderr, "test_read_header_and_entity failed with %s\n", strerror(err));
12362e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    }
123763bcb79dd437e70593b63cc5a87baab3251c2183Christopher Tate    free(buf);
12382e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    return err;
12392e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato}
12402e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato
12412e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onoratoint
12422e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onoratobackup_helper_test_data_reader()
12432e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato{
12442e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    int err;
12452e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    int fd;
12462e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    const char* filename = SCRATCH_DIR "data_reader.data";
12472e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato
12482e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    system("rm -r " SCRATCH_DIR);
12492e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    mkdir(SCRATCH_DIR, 0777);
12502e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    mkdir(SCRATCH_DIR "data", 0777);
1251f4c46b94b867f6a01bf7d0be18f667819338072fNicolas Catania
12522e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    fd = creat(filename, 0666);
12532e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    if (fd == -1) {
12542e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato        fprintf(stderr, "error creating: %s\n", strerror(errno));
12552e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato        return errno;
12562e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    }
12572e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato
12582e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    err = write(fd, DATA_GOLDEN_FILE, DATA_GOLDEN_FILE_SIZE);
12592e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    if (err != DATA_GOLDEN_FILE_SIZE) {
12602e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato        fprintf(stderr, "Error \"%s\" writing golden file %s\n", strerror(errno), filename);
12612e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato        return errno;
12622e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    }
12632e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato
12642e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    close(fd);
12652e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato
12662e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    fd = open(filename, O_RDONLY);
12672e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    if (fd == -1) {
12682e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato        fprintf(stderr, "Error \"%s\" opening golden file %s for read\n", strerror(errno),
12692e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato                filename);
12702e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato        return errno;
12712e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    }
12722e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato
12732e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    {
12742e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato        BackupDataReader reader(fd);
12752e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato
12762e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato        err = 0;
12772e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato
12782e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato        if (err == NO_ERROR) {
12792e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato            err = test_read_header_and_entity(reader, "no_padding_");
12802e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato        }
12812e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato
12822e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato        if (err == NO_ERROR) {
12832e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato            err = test_read_header_and_entity(reader, "padded_to__3");
12842e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato        }
12852e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato
12862e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato        if (err == NO_ERROR) {
12872e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato            err = test_read_header_and_entity(reader, "padded_to_2__");
12882e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato        }
12892e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato
12902e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato        if (err == NO_ERROR) {
12912e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato            err = test_read_header_and_entity(reader, "padded_to1");
12922e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato        }
12932e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    }
12942e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato
12952e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    close(fd);
12962e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato
12972e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    return err;
12982e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato}
12992e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato
13003ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onoratostatic int
13013ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onoratoget_mod_time(const char* filename, struct timeval times[2])
13023ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato{
13033ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    int err;
13043ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    struct stat64 st;
13053ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    err = stat64(filename, &st);
13063ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    if (err != 0) {
13073ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        fprintf(stderr, "stat '%s' failed: %s\n", filename, strerror(errno));
13083ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        return errno;
13093ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    }
13103ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    times[0].tv_sec = st.st_atime;
13113ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    times[1].tv_sec = st.st_mtime;
1312f4c46b94b867f6a01bf7d0be18f667819338072fNicolas Catania
1313f4c46b94b867f6a01bf7d0be18f667819338072fNicolas Catania    // If st_atime is a macro then struct stat64 uses struct timespec
1314f4c46b94b867f6a01bf7d0be18f667819338072fNicolas Catania    // to store the access and modif time values and typically
1315f4c46b94b867f6a01bf7d0be18f667819338072fNicolas Catania    // st_*time_nsec is not defined. In glibc, this is controlled by
1316f4c46b94b867f6a01bf7d0be18f667819338072fNicolas Catania    // __USE_MISC.
1317f4c46b94b867f6a01bf7d0be18f667819338072fNicolas Catania#ifdef __USE_MISC
1318f4c46b94b867f6a01bf7d0be18f667819338072fNicolas Catania#if !defined(st_atime) || defined(st_atime_nsec)
1319f4c46b94b867f6a01bf7d0be18f667819338072fNicolas Catania#error "Check if this __USE_MISC conditional is still needed."
1320f4c46b94b867f6a01bf7d0be18f667819338072fNicolas Catania#endif
1321f4c46b94b867f6a01bf7d0be18f667819338072fNicolas Catania    times[0].tv_usec = st.st_atim.tv_nsec / 1000;
1322f4c46b94b867f6a01bf7d0be18f667819338072fNicolas Catania    times[1].tv_usec = st.st_mtim.tv_nsec / 1000;
1323f4c46b94b867f6a01bf7d0be18f667819338072fNicolas Catania#else
1324f4c46b94b867f6a01bf7d0be18f667819338072fNicolas Catania    times[0].tv_usec = st.st_atime_nsec / 1000;
13253ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    times[1].tv_usec = st.st_mtime_nsec / 1000;
1326f4c46b94b867f6a01bf7d0be18f667819338072fNicolas Catania#endif
1327f4c46b94b867f6a01bf7d0be18f667819338072fNicolas Catania
13283ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    return 0;
13293ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato}
13303ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
13313ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onoratoint
13323ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onoratobackup_helper_test_files()
13333ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato{
13343ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    int err;
13353ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    int oldSnapshotFD;
13364535e40544aeb957d44fad75fbe5676effe03689Joe Onorato    int dataStreamFD;
13374535e40544aeb957d44fad75fbe5676effe03689Joe Onorato    int newSnapshotFD;
13383ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
13393ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    system("rm -r " SCRATCH_DIR);
13403ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    mkdir(SCRATCH_DIR, 0777);
13413ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    mkdir(SCRATCH_DIR "data", 0777);
13423ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
13433ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    write_text_file(SCRATCH_DIR "data/b", "b\nbb\n");
13443ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    write_text_file(SCRATCH_DIR "data/c", "c\ncc\n");
13453ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    write_text_file(SCRATCH_DIR "data/d", "d\ndd\n");
13463ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    write_text_file(SCRATCH_DIR "data/e", "e\nee\n");
13473ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    write_text_file(SCRATCH_DIR "data/f", "f\nff\n");
13483ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    write_text_file(SCRATCH_DIR "data/h", "h\nhh\n");
13493ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
13503ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    char const* files_before[] = {
135123ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato        SCRATCH_DIR "data/b",
135223ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato        SCRATCH_DIR "data/c",
135323ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato        SCRATCH_DIR "data/d",
135423ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato        SCRATCH_DIR "data/e",
135523ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato        SCRATCH_DIR "data/f"
135623ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato    };
135723ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato
135823ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato    char const* keys_before[] = {
13593ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        "data/b",
13603ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        "data/c",
13613ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        "data/d",
13623ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        "data/e",
13633ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        "data/f"
13643ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    };
13653ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
13664535e40544aeb957d44fad75fbe5676effe03689Joe Onorato    dataStreamFD = creat(SCRATCH_DIR "1.data", 0666);
13674535e40544aeb957d44fad75fbe5676effe03689Joe Onorato    if (dataStreamFD == -1) {
13684535e40544aeb957d44fad75fbe5676effe03689Joe Onorato        fprintf(stderr, "error creating: %s\n", strerror(errno));
13694535e40544aeb957d44fad75fbe5676effe03689Joe Onorato        return errno;
13704535e40544aeb957d44fad75fbe5676effe03689Joe Onorato    }
13714535e40544aeb957d44fad75fbe5676effe03689Joe Onorato
13723ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    newSnapshotFD = creat(SCRATCH_DIR "before.snap", 0666);
13733ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    if (newSnapshotFD == -1) {
13743ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        fprintf(stderr, "error creating: %s\n", strerror(errno));
13753ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        return errno;
13763ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    }
1377d2110dbce071a236b6176de344ca797b737542ebJoe Onorato
1378d2110dbce071a236b6176de344ca797b737542ebJoe Onorato    {
1379d2110dbce071a236b6176de344ca797b737542ebJoe Onorato        BackupDataWriter dataStream(dataStreamFD);
1380f4c46b94b867f6a01bf7d0be18f667819338072fNicolas Catania
138123ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato        err = back_up_files(-1, &dataStream, newSnapshotFD, files_before, keys_before, 5);
1382d2110dbce071a236b6176de344ca797b737542ebJoe Onorato        if (err != 0) {
1383d2110dbce071a236b6176de344ca797b737542ebJoe Onorato            return err;
1384d2110dbce071a236b6176de344ca797b737542ebJoe Onorato        }
13853ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    }
13863ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
13874535e40544aeb957d44fad75fbe5676effe03689Joe Onorato    close(dataStreamFD);
13883ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    close(newSnapshotFD);
13893ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
13903ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    sleep(3);
13913ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
13923ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    struct timeval d_times[2];
13933ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    struct timeval e_times[2];
13943ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
13953ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    err = get_mod_time(SCRATCH_DIR "data/d", d_times);
13963ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    err |= get_mod_time(SCRATCH_DIR "data/e", e_times);
13973ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    if (err != 0) {
13983ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        return err;
13993ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    }
14003ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
14013ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    write_text_file(SCRATCH_DIR "data/a", "a\naa\n");
14023ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    unlink(SCRATCH_DIR "data/c");
14033ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    write_text_file(SCRATCH_DIR "data/c", "c\ncc\n");
14043ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    write_text_file(SCRATCH_DIR "data/d", "dd\ndd\n");
14053ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    utimes(SCRATCH_DIR "data/d", d_times);
14063ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    write_text_file(SCRATCH_DIR "data/e", "z\nzz\n");
14073ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    utimes(SCRATCH_DIR "data/e", e_times);
14083ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    write_text_file(SCRATCH_DIR "data/g", "g\ngg\n");
14093ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    unlink(SCRATCH_DIR "data/f");
1410f4c46b94b867f6a01bf7d0be18f667819338072fNicolas Catania
14113ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    char const* files_after[] = {
141223ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato        SCRATCH_DIR "data/a", // added
141323ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato        SCRATCH_DIR "data/b", // same
141423ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato        SCRATCH_DIR "data/c", // different mod time
141523ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato        SCRATCH_DIR "data/d", // different size (same mod time)
141623ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato        SCRATCH_DIR "data/e", // different contents (same mod time, same size)
141723ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato        SCRATCH_DIR "data/g"  // added
141823ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato    };
141923ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato
142023ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato    char const* keys_after[] = {
14213ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        "data/a", // added
14223ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        "data/b", // same
14233ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        "data/c", // different mod time
14243ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        "data/d", // different size (same mod time)
14253ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        "data/e", // different contents (same mod time, same size)
14263ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        "data/g"  // added
14273ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    };
14283ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
14293ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    oldSnapshotFD = open(SCRATCH_DIR "before.snap", O_RDONLY);
14303ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    if (oldSnapshotFD == -1) {
14313ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        fprintf(stderr, "error opening: %s\n", strerror(errno));
14323ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        return errno;
14333ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    }
14343ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
14354535e40544aeb957d44fad75fbe5676effe03689Joe Onorato    dataStreamFD = creat(SCRATCH_DIR "2.data", 0666);
14364535e40544aeb957d44fad75fbe5676effe03689Joe Onorato    if (dataStreamFD == -1) {
14374535e40544aeb957d44fad75fbe5676effe03689Joe Onorato        fprintf(stderr, "error creating: %s\n", strerror(errno));
14384535e40544aeb957d44fad75fbe5676effe03689Joe Onorato        return errno;
14394535e40544aeb957d44fad75fbe5676effe03689Joe Onorato    }
14404535e40544aeb957d44fad75fbe5676effe03689Joe Onorato
14413ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    newSnapshotFD = creat(SCRATCH_DIR "after.snap", 0666);
14423ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    if (newSnapshotFD == -1) {
14433ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        fprintf(stderr, "error creating: %s\n", strerror(errno));
14443ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        return errno;
14453ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    }
14463ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
1447d2110dbce071a236b6176de344ca797b737542ebJoe Onorato    {
1448d2110dbce071a236b6176de344ca797b737542ebJoe Onorato        BackupDataWriter dataStream(dataStreamFD);
1449f4c46b94b867f6a01bf7d0be18f667819338072fNicolas Catania
145023ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato        err = back_up_files(oldSnapshotFD, &dataStream, newSnapshotFD, files_after, keys_after, 6);
1451d2110dbce071a236b6176de344ca797b737542ebJoe Onorato        if (err != 0) {
1452d2110dbce071a236b6176de344ca797b737542ebJoe Onorato            return err;
1453d2110dbce071a236b6176de344ca797b737542ebJoe Onorato        }
1454d2110dbce071a236b6176de344ca797b737542ebJoe Onorato}
14553ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
14563ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    close(oldSnapshotFD);
14574535e40544aeb957d44fad75fbe5676effe03689Joe Onorato    close(dataStreamFD);
14583ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    close(newSnapshotFD);
1459f4c46b94b867f6a01bf7d0be18f667819338072fNicolas Catania
14603ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    return 0;
14613ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato}
14623ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
146323ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onoratoint
146423ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onoratobackup_helper_test_null_base()
146523ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato{
146623ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato    int err;
146723ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato    int dataStreamFD;
146823ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato    int newSnapshotFD;
146923ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato
147023ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato    system("rm -r " SCRATCH_DIR);
147123ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato    mkdir(SCRATCH_DIR, 0777);
147223ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato    mkdir(SCRATCH_DIR "data", 0777);
147323ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato
147423ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato    write_text_file(SCRATCH_DIR "data/a", "a\naa\n");
147523ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato
147623ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato    char const* files[] = {
147723ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato        SCRATCH_DIR "data/a",
147823ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato    };
147923ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato
148023ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato    char const* keys[] = {
148123ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato        "a",
148223ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato    };
148323ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato
148423ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato    dataStreamFD = creat(SCRATCH_DIR "null_base.data", 0666);
148523ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato    if (dataStreamFD == -1) {
148623ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato        fprintf(stderr, "error creating: %s\n", strerror(errno));
148723ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato        return errno;
148823ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato    }
148923ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato
149023ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato    newSnapshotFD = creat(SCRATCH_DIR "null_base.snap", 0666);
149123ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato    if (newSnapshotFD == -1) {
149223ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato        fprintf(stderr, "error creating: %s\n", strerror(errno));
149323ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato        return errno;
149423ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato    }
149523ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato
149623ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato    {
149723ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato        BackupDataWriter dataStream(dataStreamFD);
149823ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato
149923ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato        err = back_up_files(-1, &dataStream, newSnapshotFD, files, keys, 1);
150023ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato        if (err != 0) {
150123ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato            return err;
150223ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato        }
150323ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato    }
150423ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato
150523ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato    close(dataStreamFD);
150623ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato    close(newSnapshotFD);
150723ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato
150823ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato    return 0;
150923ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato}
151023ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato
1511ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onoratoint
1512ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onoratobackup_helper_test_missing_file()
1513ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato{
1514ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato    int err;
1515ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato    int dataStreamFD;
1516ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato    int newSnapshotFD;
1517ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato
1518ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato    system("rm -r " SCRATCH_DIR);
1519ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato    mkdir(SCRATCH_DIR, 0777);
1520ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato    mkdir(SCRATCH_DIR "data", 0777);
1521ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato
1522ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato    write_text_file(SCRATCH_DIR "data/b", "b\nbb\n");
1523ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato
1524ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato    char const* files[] = {
1525ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato        SCRATCH_DIR "data/a",
1526ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato        SCRATCH_DIR "data/b",
1527ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato        SCRATCH_DIR "data/c",
1528ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato    };
1529ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato
1530ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato    char const* keys[] = {
1531ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato        "a",
1532ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato        "b",
1533ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato        "c",
1534ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato    };
1535ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato
1536ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato    dataStreamFD = creat(SCRATCH_DIR "null_base.data", 0666);
1537ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato    if (dataStreamFD == -1) {
1538ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato        fprintf(stderr, "error creating: %s\n", strerror(errno));
1539ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato        return errno;
1540ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato    }
1541ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato
1542ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato    newSnapshotFD = creat(SCRATCH_DIR "null_base.snap", 0666);
1543ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato    if (newSnapshotFD == -1) {
1544ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato        fprintf(stderr, "error creating: %s\n", strerror(errno));
1545ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato        return errno;
1546ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato    }
1547ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato
1548ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato    {
1549ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato        BackupDataWriter dataStream(dataStreamFD);
1550ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato
1551ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato        err = back_up_files(-1, &dataStream, newSnapshotFD, files, keys, 1);
1552ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato        if (err != 0) {
1553ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato            return err;
1554ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato        }
1555ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato    }
1556ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato
1557ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato    close(dataStreamFD);
1558ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato    close(newSnapshotFD);
1559ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato
1560ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato    return 0;
1561ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato}
1562ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato
156323ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato
15643ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato#endif // TEST_BACKUP_HELPERS
15654535e40544aeb957d44fad75fbe5676effe03689Joe Onorato
15664535e40544aeb957d44fad75fbe5676effe03689Joe Onorato}
1567