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 <errno.h>
2252eb4e01a49fe2e94555c000de38bbcbbb13401bMark Salyzyn#include <fcntl.h>
233ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato#include <stdio.h>
243ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato#include <stdlib.h>
2552eb4e01a49fe2e94555c000de38bbcbbb13401bMark Salyzyn#include <sys/stat.h>
2652eb4e01a49fe2e94555c000de38bbcbbb13401bMark Salyzyn#include <sys/types.h>
2752eb4e01a49fe2e94555c000de38bbcbbb13401bMark Salyzyn#include <sys/time.h>  // for utimes
2852eb4e01a49fe2e94555c000de38bbcbbb13401bMark Salyzyn#include <sys/uio.h>
293ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato#include <unistd.h>
30c825d3ebd6ca66e65e63fdc76f032e08aa2a8e22Joe Onorato#include <utime.h>
313ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato#include <zlib.h>
323ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
3352eb4e01a49fe2e94555c000de38bbcbbb13401bMark Salyzyn#include <log/log.h>
3452eb4e01a49fe2e94555c000de38bbcbbb13401bMark Salyzyn#include <utils/ByteOrder.h>
3552eb4e01a49fe2e94555c000de38bbcbbb13401bMark Salyzyn#include <utils/KeyedVector.h>
3652eb4e01a49fe2e94555c000de38bbcbbb13401bMark Salyzyn#include <utils/String8.h>
373ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
384535e40544aeb957d44fad75fbe5676effe03689Joe Onoratonamespace android {
393ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
403ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato#define MAGIC0 0x70616e53 // Snap
413ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato#define MAGIC1 0x656c6946 // File
423ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
43fbb92385f2fb0ae1146bb8f3d73547d90bda6db1Christopher Tate/*
44fbb92385f2fb0ae1146bb8f3d73547d90bda6db1Christopher Tate * File entity data format (v1):
45fbb92385f2fb0ae1146bb8f3d73547d90bda6db1Christopher Tate *
46fbb92385f2fb0ae1146bb8f3d73547d90bda6db1Christopher Tate *   - 4-byte version number of the metadata, little endian (0x00000001 for v1)
47fbb92385f2fb0ae1146bb8f3d73547d90bda6db1Christopher Tate *   - 12 bytes of metadata
48fbb92385f2fb0ae1146bb8f3d73547d90bda6db1Christopher Tate *   - the file data itself
49fbb92385f2fb0ae1146bb8f3d73547d90bda6db1Christopher Tate *
50fbb92385f2fb0ae1146bb8f3d73547d90bda6db1Christopher Tate * i.e. a 16-byte metadata header followed by the raw file data.  If the
51fbb92385f2fb0ae1146bb8f3d73547d90bda6db1Christopher Tate * restore code does not recognize the metadata version, it can still
52fbb92385f2fb0ae1146bb8f3d73547d90bda6db1Christopher Tate * interpret the file data itself correctly.
53fbb92385f2fb0ae1146bb8f3d73547d90bda6db1Christopher Tate *
54fbb92385f2fb0ae1146bb8f3d73547d90bda6db1Christopher Tate * file_metadata_v1:
55fbb92385f2fb0ae1146bb8f3d73547d90bda6db1Christopher Tate *
56fbb92385f2fb0ae1146bb8f3d73547d90bda6db1Christopher Tate *   - 4 byte version number === 0x00000001 (little endian)
57fbb92385f2fb0ae1146bb8f3d73547d90bda6db1Christopher Tate *   - 4-byte access mode (little-endian)
58fbb92385f2fb0ae1146bb8f3d73547d90bda6db1Christopher Tate *   - undefined (8 bytes)
59fbb92385f2fb0ae1146bb8f3d73547d90bda6db1Christopher Tate */
60fbb92385f2fb0ae1146bb8f3d73547d90bda6db1Christopher Tate
61fbb92385f2fb0ae1146bb8f3d73547d90bda6db1Christopher Tatestruct file_metadata_v1 {
62fbb92385f2fb0ae1146bb8f3d73547d90bda6db1Christopher Tate    int version;
63fbb92385f2fb0ae1146bb8f3d73547d90bda6db1Christopher Tate    int mode;
64fbb92385f2fb0ae1146bb8f3d73547d90bda6db1Christopher Tate    int undefined_1;
65fbb92385f2fb0ae1146bb8f3d73547d90bda6db1Christopher Tate    int undefined_2;
66fbb92385f2fb0ae1146bb8f3d73547d90bda6db1Christopher Tate};
67fbb92385f2fb0ae1146bb8f3d73547d90bda6db1Christopher Tate
68fbb92385f2fb0ae1146bb8f3d73547d90bda6db1Christopher Tateconst static int CURRENT_METADATA_VERSION = 1;
69fbb92385f2fb0ae1146bb8f3d73547d90bda6db1Christopher Tate
702204f0bf56af53b588a01701b8cf9cd05b1b3ff9Andreas Gampestatic const bool kIsDebug = false;
71568bc32344dce841c8f6958f1a65ff839a1b64c0Joe Onorato#if TEST_BACKUP_HELPERS
722204f0bf56af53b588a01701b8cf9cd05b1b3ff9Andreas Gampe#define LOGP(f, x...) if (kIsDebug) printf(f "\n", x)
734535e40544aeb957d44fad75fbe5676effe03689Joe Onorato#else
742204f0bf56af53b588a01701b8cf9cd05b1b3ff9Andreas Gampe#define LOGP(x...) if (kIsDebug) ALOGD(x)
75568bc32344dce841c8f6958f1a65ff839a1b64c0Joe Onorato#endif
76290bb011c5c1a9ba1f2116810b06cf52a9c36b3eJoe Onorato
773ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onoratoconst static int ROUND_UP[4] = { 0, 3, 2, 1 };
783ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
793ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onoratostatic inline int
803ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onoratoround_up(int n)
813ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato{
823ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    return n + ROUND_UP[n % 4];
833ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato}
843ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
853ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onoratostatic int
863ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onoratoread_snapshot_file(int fd, KeyedVector<String8,FileState>* snapshot)
873ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato{
883ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    int bytesRead = 0;
893ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    int amt;
903ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    SnapshotHeader header;
913ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
923ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    amt = read(fd, &header, sizeof(header));
933ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    if (amt != sizeof(header)) {
943ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        return errno;
953ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    }
963ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    bytesRead += amt;
973ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
983ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    if (header.magic0 != MAGIC0 || header.magic1 != MAGIC1) {
998564c8da817a845353d213acd8636b76f567b234Steve Block        ALOGW("read_snapshot_file header.magic0=0x%08x magic1=0x%08x", header.magic0, header.magic1);
1003ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        return 1;
1013ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    }
1023ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
1033ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    for (int i=0; i<header.fileCount; i++) {
1043ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        FileState file;
1053ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        char filenameBuf[128];
1063ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
10723ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato        amt = read(fd, &file, sizeof(FileState));
10823ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato        if (amt != sizeof(FileState)) {
1098564c8da817a845353d213acd8636b76f567b234Steve Block            ALOGW("read_snapshot_file FileState truncated/error with read at %d bytes\n", bytesRead);
1103ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato            return 1;
1113ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        }
1123ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        bytesRead += amt;
1133ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
1143ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        // filename is not NULL terminated, but it is padded
1153ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        int nameBufSize = round_up(file.nameLen);
1163ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        char* filename = nameBufSize <= (int)sizeof(filenameBuf)
1173ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato                ? filenameBuf
1183ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato                : (char*)malloc(nameBufSize);
1193ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        amt = read(fd, filename, nameBufSize);
1203ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        if (amt == nameBufSize) {
1213ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato            snapshot->add(String8(filename, file.nameLen), file);
1223ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        }
1233ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        bytesRead += amt;
1243ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        if (filename != filenameBuf) {
1253ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato            free(filename);
1263ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        }
1273ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        if (amt != nameBufSize) {
1288564c8da817a845353d213acd8636b76f567b234Steve Block            ALOGW("read_snapshot_file filename truncated/error with read at %d bytes\n", bytesRead);
1293ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato            return 1;
1303ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        }
1313ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    }
1323ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
1333ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    if (header.totalSize != bytesRead) {
1348564c8da817a845353d213acd8636b76f567b234Steve Block        ALOGW("read_snapshot_file length mismatch: header.totalSize=%d bytesRead=%d\n",
1353ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato                header.totalSize, bytesRead);
1363ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        return 1;
1373ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    }
1383ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
1393ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    return 0;
1403ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato}
1413ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
1423ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onoratostatic int
14323ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onoratowrite_snapshot_file(int fd, const KeyedVector<String8,FileRec>& snapshot)
1443ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato{
145ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato    int fileCount = 0;
1463ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    int bytesWritten = sizeof(SnapshotHeader);
1473ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    // preflight size
1483ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    const int N = snapshot.size();
1493ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    for (int i=0; i<N; i++) {
150ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato        const FileRec& g = snapshot.valueAt(i);
151ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato        if (!g.deleted) {
152ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato            const String8& name = snapshot.keyAt(i);
153ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato            bytesWritten += sizeof(FileState) + round_up(name.length());
154ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato            fileCount++;
155ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato        }
1563ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    }
1573ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
1584535e40544aeb957d44fad75fbe5676effe03689Joe Onorato    LOGP("write_snapshot_file fd=%d\n", fd);
1594535e40544aeb957d44fad75fbe5676effe03689Joe Onorato
1603ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    int amt;
161ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato    SnapshotHeader header = { MAGIC0, fileCount, MAGIC1, bytesWritten };
1623ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
1633ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    amt = write(fd, &header, sizeof(header));
1643ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    if (amt != sizeof(header)) {
1658564c8da817a845353d213acd8636b76f567b234Steve Block        ALOGW("write_snapshot_file error writing header %s", strerror(errno));
1663ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        return errno;
1673ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    }
1683ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
169ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato    for (int i=0; i<N; i++) {
17023ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato        FileRec r = snapshot.valueAt(i);
171ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato        if (!r.deleted) {
172ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato            const String8& name = snapshot.keyAt(i);
173ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato            int nameLen = r.s.nameLen = name.length();
1743ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
175ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato            amt = write(fd, &r.s, sizeof(FileState));
176ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato            if (amt != sizeof(FileState)) {
1778564c8da817a845353d213acd8636b76f567b234Steve Block                ALOGW("write_snapshot_file error writing header %s", strerror(errno));
178ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato                return 1;
179ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato            }
1803ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
181ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato            // filename is not NULL terminated, but it is padded
182ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato            amt = write(fd, name.string(), nameLen);
183ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato            if (amt != nameLen) {
1848564c8da817a845353d213acd8636b76f567b234Steve Block                ALOGW("write_snapshot_file error writing filename %s", strerror(errno));
1853ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato                return 1;
1863ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato            }
187ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato            int paddingLen = ROUND_UP[nameLen % 4];
188ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato            if (paddingLen != 0) {
189ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato                int padding = 0xabababab;
190ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato                amt = write(fd, &padding, paddingLen);
191ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato                if (amt != paddingLen) {
1928564c8da817a845353d213acd8636b76f567b234Steve Block                    ALOGW("write_snapshot_file error writing %d bytes of filename padding %s",
193ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato                            paddingLen, strerror(errno));
194ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato                    return 1;
195ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato                }
196ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato            }
1973ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        }
1983ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    }
1993ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
2003ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    return 0;
2013ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato}
2023ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
2033ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onoratostatic int
20433d0392d3e4c42a7d48e8bd1210a1525aca8c2d3Brian Carlstromwrite_delete_file(BackupDataWriter* dataStream, const String8& key)
20533d0392d3e4c42a7d48e8bd1210a1525aca8c2d3Brian Carlstrom{
20633d0392d3e4c42a7d48e8bd1210a1525aca8c2d3Brian Carlstrom    LOGP("write_delete_file %s\n", key.string());
20733d0392d3e4c42a7d48e8bd1210a1525aca8c2d3Brian Carlstrom    return dataStream->WriteEntityHeader(key, -1);
20833d0392d3e4c42a7d48e8bd1210a1525aca8c2d3Brian Carlstrom}
20933d0392d3e4c42a7d48e8bd1210a1525aca8c2d3Brian Carlstrom
21033d0392d3e4c42a7d48e8bd1210a1525aca8c2d3Brian Carlstromstatic int
211fbb92385f2fb0ae1146bb8f3d73547d90bda6db1Christopher Tatewrite_update_file(BackupDataWriter* dataStream, int fd, int mode, const String8& key,
21223ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato        char const* realFilename)
2133ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato{
214fbb92385f2fb0ae1146bb8f3d73547d90bda6db1Christopher Tate    LOGP("write_update_file %s (%s) : mode 0%o\n", realFilename, key.string(), mode);
2153ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
2163ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    const int bufsize = 4*1024;
217d2110dbce071a236b6176de344ca797b737542ebJoe Onorato    int err;
2183ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    int amt;
219d2110dbce071a236b6176de344ca797b737542ebJoe Onorato    int fileSize;
220d2110dbce071a236b6176de344ca797b737542ebJoe Onorato    int bytesLeft;
221fbb92385f2fb0ae1146bb8f3d73547d90bda6db1Christopher Tate    file_metadata_v1 metadata;
222d2110dbce071a236b6176de344ca797b737542ebJoe Onorato
223d2110dbce071a236b6176de344ca797b737542ebJoe Onorato    char* buf = (char*)malloc(bufsize);
224d2110dbce071a236b6176de344ca797b737542ebJoe Onorato
225fbb92385f2fb0ae1146bb8f3d73547d90bda6db1Christopher Tate    fileSize = lseek(fd, 0, SEEK_END);
226d2110dbce071a236b6176de344ca797b737542ebJoe Onorato    lseek(fd, 0, SEEK_SET);
227d2110dbce071a236b6176de344ca797b737542ebJoe Onorato
228fbb92385f2fb0ae1146bb8f3d73547d90bda6db1Christopher Tate    if (sizeof(metadata) != 16) {
2293762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("ERROR: metadata block is the wrong size!");
230fbb92385f2fb0ae1146bb8f3d73547d90bda6db1Christopher Tate    }
231fbb92385f2fb0ae1146bb8f3d73547d90bda6db1Christopher Tate
232fbb92385f2fb0ae1146bb8f3d73547d90bda6db1Christopher Tate    bytesLeft = fileSize + sizeof(metadata);
233d2110dbce071a236b6176de344ca797b737542ebJoe Onorato    err = dataStream->WriteEntityHeader(key, bytesLeft);
234d2110dbce071a236b6176de344ca797b737542ebJoe Onorato    if (err != 0) {
23563bcb79dd437e70593b63cc5a87baab3251c2183Christopher Tate        free(buf);
236d2110dbce071a236b6176de344ca797b737542ebJoe Onorato        return err;
237d2110dbce071a236b6176de344ca797b737542ebJoe Onorato    }
238d2110dbce071a236b6176de344ca797b737542ebJoe Onorato
239fbb92385f2fb0ae1146bb8f3d73547d90bda6db1Christopher Tate    // store the file metadata first
240fbb92385f2fb0ae1146bb8f3d73547d90bda6db1Christopher Tate    metadata.version = tolel(CURRENT_METADATA_VERSION);
241fbb92385f2fb0ae1146bb8f3d73547d90bda6db1Christopher Tate    metadata.mode = tolel(mode);
242fbb92385f2fb0ae1146bb8f3d73547d90bda6db1Christopher Tate    metadata.undefined_1 = metadata.undefined_2 = 0;
243fbb92385f2fb0ae1146bb8f3d73547d90bda6db1Christopher Tate    err = dataStream->WriteEntityData(&metadata, sizeof(metadata));
244fbb92385f2fb0ae1146bb8f3d73547d90bda6db1Christopher Tate    if (err != 0) {
24563bcb79dd437e70593b63cc5a87baab3251c2183Christopher Tate        free(buf);
246fbb92385f2fb0ae1146bb8f3d73547d90bda6db1Christopher Tate        return err;
247fbb92385f2fb0ae1146bb8f3d73547d90bda6db1Christopher Tate    }
248fbb92385f2fb0ae1146bb8f3d73547d90bda6db1Christopher Tate    bytesLeft -= sizeof(metadata); // bytesLeft should == fileSize now
249fbb92385f2fb0ae1146bb8f3d73547d90bda6db1Christopher Tate
250fbb92385f2fb0ae1146bb8f3d73547d90bda6db1Christopher Tate    // now store the file content
251d2110dbce071a236b6176de344ca797b737542ebJoe Onorato    while ((amt = read(fd, buf, bufsize)) != 0 && bytesLeft > 0) {
252d2110dbce071a236b6176de344ca797b737542ebJoe Onorato        bytesLeft -= amt;
253d2110dbce071a236b6176de344ca797b737542ebJoe Onorato        if (bytesLeft < 0) {
254d2110dbce071a236b6176de344ca797b737542ebJoe Onorato            amt += bytesLeft; // Plus a negative is minus.  Don't write more than we promised.
255d2110dbce071a236b6176de344ca797b737542ebJoe Onorato        }
256d2110dbce071a236b6176de344ca797b737542ebJoe Onorato        err = dataStream->WriteEntityData(buf, amt);
257d2110dbce071a236b6176de344ca797b737542ebJoe Onorato        if (err != 0) {
25863bcb79dd437e70593b63cc5a87baab3251c2183Christopher Tate            free(buf);
259d2110dbce071a236b6176de344ca797b737542ebJoe Onorato            return err;
260d2110dbce071a236b6176de344ca797b737542ebJoe Onorato        }
261d2110dbce071a236b6176de344ca797b737542ebJoe Onorato    }
262d2110dbce071a236b6176de344ca797b737542ebJoe Onorato    if (bytesLeft != 0) {
263d2110dbce071a236b6176de344ca797b737542ebJoe Onorato        if (bytesLeft > 0) {
264d2110dbce071a236b6176de344ca797b737542ebJoe Onorato            // Pad out the space we promised in the buffer.  We can't corrupt the buffer,
265d2110dbce071a236b6176de344ca797b737542ebJoe Onorato            // even though the data we're sending is probably bad.
266d2110dbce071a236b6176de344ca797b737542ebJoe Onorato            memset(buf, 0, bufsize);
267d2110dbce071a236b6176de344ca797b737542ebJoe Onorato            while (bytesLeft > 0) {
268d2110dbce071a236b6176de344ca797b737542ebJoe Onorato                amt = bytesLeft < bufsize ? bytesLeft : bufsize;
269d2110dbce071a236b6176de344ca797b737542ebJoe Onorato                bytesLeft -= amt;
270d2110dbce071a236b6176de344ca797b737542ebJoe Onorato                err = dataStream->WriteEntityData(buf, amt);
271d2110dbce071a236b6176de344ca797b737542ebJoe Onorato                if (err != 0) {
27263bcb79dd437e70593b63cc5a87baab3251c2183Christopher Tate                    free(buf);
273d2110dbce071a236b6176de344ca797b737542ebJoe Onorato                    return err;
274d2110dbce071a236b6176de344ca797b737542ebJoe Onorato                }
275d2110dbce071a236b6176de344ca797b737542ebJoe Onorato            }
276d2110dbce071a236b6176de344ca797b737542ebJoe Onorato        }
2773762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("write_update_file size mismatch for %s. expected=%d actual=%d."
27823ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato                " You aren't doing proper locking!", realFilename, fileSize, fileSize-bytesLeft);
279d2110dbce071a236b6176de344ca797b737542ebJoe Onorato    }
280d2110dbce071a236b6176de344ca797b737542ebJoe Onorato
28163bcb79dd437e70593b63cc5a87baab3251c2183Christopher Tate    free(buf);
282d2110dbce071a236b6176de344ca797b737542ebJoe Onorato    return NO_ERROR;
283d2110dbce071a236b6176de344ca797b737542ebJoe Onorato}
284d2110dbce071a236b6176de344ca797b737542ebJoe Onorato
285d2110dbce071a236b6176de344ca797b737542ebJoe Onoratostatic int
28623ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onoratowrite_update_file(BackupDataWriter* dataStream, const String8& key, char const* realFilename)
287d2110dbce071a236b6176de344ca797b737542ebJoe Onorato{
288d2110dbce071a236b6176de344ca797b737542ebJoe Onorato    int err;
289fbb92385f2fb0ae1146bb8f3d73547d90bda6db1Christopher Tate    struct stat st;
290fbb92385f2fb0ae1146bb8f3d73547d90bda6db1Christopher Tate
291fbb92385f2fb0ae1146bb8f3d73547d90bda6db1Christopher Tate    err = stat(realFilename, &st);
292fbb92385f2fb0ae1146bb8f3d73547d90bda6db1Christopher Tate    if (err < 0) {
293fbb92385f2fb0ae1146bb8f3d73547d90bda6db1Christopher Tate        return errno;
294fbb92385f2fb0ae1146bb8f3d73547d90bda6db1Christopher Tate    }
295fbb92385f2fb0ae1146bb8f3d73547d90bda6db1Christopher Tate
29623ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato    int fd = open(realFilename, O_RDONLY);
2973ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    if (fd == -1) {
298d2110dbce071a236b6176de344ca797b737542ebJoe Onorato        return errno;
2993ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    }
300fbb92385f2fb0ae1146bb8f3d73547d90bda6db1Christopher Tate
301fbb92385f2fb0ae1146bb8f3d73547d90bda6db1Christopher Tate    err = write_update_file(dataStream, fd, st.st_mode, key, realFilename);
302d2110dbce071a236b6176de344ca797b737542ebJoe Onorato    close(fd);
303d2110dbce071a236b6176de344ca797b737542ebJoe Onorato    return err;
304d2110dbce071a236b6176de344ca797b737542ebJoe Onorato}
305d2110dbce071a236b6176de344ca797b737542ebJoe Onorato
306d2110dbce071a236b6176de344ca797b737542ebJoe Onoratostatic int
30743a4a8c777fbb8f71540ac7fbe82674489ef557bChristopher Tatecompute_crc32(const char* file, FileRec* out) {
30843a4a8c777fbb8f71540ac7fbe82674489ef557bChristopher Tate    int fd = open(file, O_RDONLY);
30943a4a8c777fbb8f71540ac7fbe82674489ef557bChristopher Tate    if (fd < 0) {
31043a4a8c777fbb8f71540ac7fbe82674489ef557bChristopher Tate        return -1;
31143a4a8c777fbb8f71540ac7fbe82674489ef557bChristopher Tate    }
31243a4a8c777fbb8f71540ac7fbe82674489ef557bChristopher Tate
313d2110dbce071a236b6176de344ca797b737542ebJoe Onorato    const int bufsize = 4*1024;
314d2110dbce071a236b6176de344ca797b737542ebJoe Onorato    int amt;
3153ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
3163ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    char* buf = (char*)malloc(bufsize);
3173ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    int crc = crc32(0L, Z_NULL, 0);
3183ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
319d2110dbce071a236b6176de344ca797b737542ebJoe Onorato    lseek(fd, 0, SEEK_SET);
320d2110dbce071a236b6176de344ca797b737542ebJoe Onorato
3213ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    while ((amt = read(fd, buf, bufsize)) != 0) {
3223ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        crc = crc32(crc, (Bytef*)buf, amt);
3233ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    }
3243ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
32543a4a8c777fbb8f71540ac7fbe82674489ef557bChristopher Tate    close(fd);
32663bcb79dd437e70593b63cc5a87baab3251c2183Christopher Tate    free(buf);
32743a4a8c777fbb8f71540ac7fbe82674489ef557bChristopher Tate
32843a4a8c777fbb8f71540ac7fbe82674489ef557bChristopher Tate    out->s.crc32 = crc;
32943a4a8c777fbb8f71540ac7fbe82674489ef557bChristopher Tate    return NO_ERROR;
3303ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato}
3313ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
3323ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onoratoint
333d2110dbce071a236b6176de344ca797b737542ebJoe Onoratoback_up_files(int oldSnapshotFD, BackupDataWriter* dataStream, int newSnapshotFD,
33423ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato        char const* const* files, char const* const* keys, int fileCount)
3353ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato{
3363ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    int err;
3373ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    KeyedVector<String8,FileState> oldSnapshot;
33823ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato    KeyedVector<String8,FileRec> newSnapshot;
3393ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
3403ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    if (oldSnapshotFD != -1) {
3413ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        err = read_snapshot_file(oldSnapshotFD, &oldSnapshot);
3423ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        if (err != 0) {
3433ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato            // On an error, treat this as a full backup.
3443ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato            oldSnapshot.clear();
3453ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        }
3463ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    }
3473ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
3483ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    for (int i=0; i<fileCount; i++) {
34923ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato        String8 key(keys[i]);
35023ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato        FileRec r;
351d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato        char const* file = files[i];
352d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato        r.file = file;
3533ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        struct stat st;
3543ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
35523ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato        err = stat(file, &st);
3563ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        if (err != 0) {
35743a4a8c777fbb8f71540ac7fbe82674489ef557bChristopher Tate            // not found => treat as deleted
35843a4a8c777fbb8f71540ac7fbe82674489ef557bChristopher Tate            continue;
359ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato        } else {
360ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato            r.deleted = false;
361ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato            r.s.modTime_sec = st.st_mtime;
362ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato            r.s.modTime_nsec = 0; // workaround sim breakage
363ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato            //r.s.modTime_nsec = st.st_mtime_nsec;
36411b157790234d3d2f116ce4c7ed1d3d00fb78bc3Christopher Tate            r.s.mode = st.st_mode;
365ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato            r.s.size = st.st_size;
366ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato
367ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato            if (newSnapshot.indexOfKey(key) >= 0) {
368ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato                LOGP("back_up_files key already in use '%s'", key.string());
369ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato                return -1;
370ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato            }
37143a4a8c777fbb8f71540ac7fbe82674489ef557bChristopher Tate
37243a4a8c777fbb8f71540ac7fbe82674489ef557bChristopher Tate            // compute the CRC
37343a4a8c777fbb8f71540ac7fbe82674489ef557bChristopher Tate            if (compute_crc32(file, &r) != NO_ERROR) {
37443a4a8c777fbb8f71540ac7fbe82674489ef557bChristopher Tate                ALOGW("Unable to open file %s", file);
37543a4a8c777fbb8f71540ac7fbe82674489ef557bChristopher Tate                continue;
37643a4a8c777fbb8f71540ac7fbe82674489ef557bChristopher Tate            }
37723ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato        }
37823ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato        newSnapshot.add(key, r);
3793ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    }
3803ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
3813ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    int n = 0;
3823ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    int N = oldSnapshot.size();
3833ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    int m = 0;
38443a4a8c777fbb8f71540ac7fbe82674489ef557bChristopher Tate    int M = newSnapshot.size();
3853ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
38643a4a8c777fbb8f71540ac7fbe82674489ef557bChristopher Tate    while (n<N && m<M) {
3873ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        const String8& p = oldSnapshot.keyAt(n);
3883ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        const String8& q = newSnapshot.keyAt(m);
389ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato        FileRec& g = newSnapshot.editValueAt(m);
3903ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        int cmp = p.compare(q);
39143a4a8c777fbb8f71540ac7fbe82674489ef557bChristopher Tate        if (cmp < 0) {
39243a4a8c777fbb8f71540ac7fbe82674489ef557bChristopher Tate            // file present in oldSnapshot, but not present in newSnapshot
39323ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato            LOGP("file removed: %s", p.string());
39443a4a8c777fbb8f71540ac7fbe82674489ef557bChristopher Tate            write_delete_file(dataStream, p);
3953ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato            n++;
39643a4a8c777fbb8f71540ac7fbe82674489ef557bChristopher Tate        } else if (cmp > 0) {
397ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato            // file added
39843a4a8c777fbb8f71540ac7fbe82674489ef557bChristopher Tate            LOGP("file added: %s crc=0x%08x", g.file.string(), g.s.crc32);
399d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato            write_update_file(dataStream, q, g.file.string());
400ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato            m++;
40143a4a8c777fbb8f71540ac7fbe82674489ef557bChristopher Tate        } else {
40243a4a8c777fbb8f71540ac7fbe82674489ef557bChristopher Tate            // same file exists in both old and new; check whether to update
4033ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato            const FileState& f = oldSnapshot.valueAt(n);
404d2110dbce071a236b6176de344ca797b737542ebJoe Onorato
40543a4a8c777fbb8f71540ac7fbe82674489ef557bChristopher Tate            LOGP("%s", q.string());
40643a4a8c777fbb8f71540ac7fbe82674489ef557bChristopher Tate            LOGP("  old: modTime=%d,%d mode=%04o size=%-3d crc32=0x%08x",
40743a4a8c777fbb8f71540ac7fbe82674489ef557bChristopher Tate                    f.modTime_sec, f.modTime_nsec, f.mode, f.size, f.crc32);
40843a4a8c777fbb8f71540ac7fbe82674489ef557bChristopher Tate            LOGP("  new: modTime=%d,%d mode=%04o size=%-3d crc32=0x%08x",
40943a4a8c777fbb8f71540ac7fbe82674489ef557bChristopher Tate                    g.s.modTime_sec, g.s.modTime_nsec, g.s.mode, g.s.size, g.s.crc32);
41043a4a8c777fbb8f71540ac7fbe82674489ef557bChristopher Tate            if (f.modTime_sec != g.s.modTime_sec || f.modTime_nsec != g.s.modTime_nsec
41143a4a8c777fbb8f71540ac7fbe82674489ef557bChristopher Tate                    || f.mode != g.s.mode || f.size != g.s.size || f.crc32 != g.s.crc32) {
41243a4a8c777fbb8f71540ac7fbe82674489ef557bChristopher Tate                int fd = open(g.file.string(), O_RDONLY);
41343a4a8c777fbb8f71540ac7fbe82674489ef557bChristopher Tate                if (fd < 0) {
41443a4a8c777fbb8f71540ac7fbe82674489ef557bChristopher Tate                    ALOGE("Unable to read file for backup: %s", g.file.string());
41543a4a8c777fbb8f71540ac7fbe82674489ef557bChristopher Tate                } else {
416fbb92385f2fb0ae1146bb8f3d73547d90bda6db1Christopher Tate                    write_update_file(dataStream, fd, g.s.mode, p, g.file.string());
41743a4a8c777fbb8f71540ac7fbe82674489ef557bChristopher Tate                    close(fd);
418d2110dbce071a236b6176de344ca797b737542ebJoe Onorato                }
4193ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato            }
4203ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato            n++;
4213ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato            m++;
4223ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        }
4233ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    }
4243ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
4253ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    // these were deleted
4263ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    while (n<N) {
42743a4a8c777fbb8f71540ac7fbe82674489ef557bChristopher Tate        write_delete_file(dataStream, oldSnapshot.keyAt(n));
4283ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        n++;
4293ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    }
4303ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
4313ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    // these were added
43243a4a8c777fbb8f71540ac7fbe82674489ef557bChristopher Tate    while (m<M) {
4333ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        const String8& q = newSnapshot.keyAt(m);
43423ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato        FileRec& g = newSnapshot.editValueAt(m);
435d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato        write_update_file(dataStream, q, g.file.string());
4363ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        m++;
4373ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    }
4383ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
4393ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    err = write_snapshot_file(newSnapshotFD, newSnapshot);
4403ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
4413ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    return 0;
4423ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato}
4433ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
444a346f5458a4d9e9ea8159a38ae5f696f19cf125bGeorge Burgess IVstatic void calc_tar_checksum(char* buf, size_t buf_size) {
44583a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate    // [ 148 :   8 ] checksum -- to be calculated with this field as space chars
44683a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate    memset(buf + 148, ' ', 8);
44783a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate
44883a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate    uint16_t sum = 0;
44983a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate    for (uint8_t* p = (uint8_t*) buf; p < ((uint8_t*)buf) + 512; p++) {
45083a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate        sum += *p;
45183a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate    }
45283a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate
45383a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate    // Now write the real checksum value:
45483a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate    // [ 148 :   8 ]  checksum: 6 octal digits [leading zeroes], NUL, SPC
455a346f5458a4d9e9ea8159a38ae5f696f19cf125bGeorge Burgess IV    snprintf(buf + 148, buf_size - 148, "%06o", sum); // the trailing space is
456a346f5458a4d9e9ea8159a38ae5f696f19cf125bGeorge Burgess IV                                                      // already in place
45783a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate}
45883a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate
459dc92c82b4180e8067f1acd00a7db7935afce00ffChristopher Tate// Returns number of bytes written
460a346f5458a4d9e9ea8159a38ae5f696f19cf125bGeorge Burgess IVstatic int write_pax_header_entry(char* buf, size_t buf_size,
461a346f5458a4d9e9ea8159a38ae5f696f19cf125bGeorge Burgess IV                                  const char* key, const char* value) {
462dc92c82b4180e8067f1acd00a7db7935afce00ffChristopher Tate    // start with the size of "1 key=value\n"
463dc92c82b4180e8067f1acd00a7db7935afce00ffChristopher Tate    int len = strlen(key) + strlen(value) + 4;
464dc92c82b4180e8067f1acd00a7db7935afce00ffChristopher Tate    if (len > 9) len++;
465dc92c82b4180e8067f1acd00a7db7935afce00ffChristopher Tate    if (len > 99) len++;
466dc92c82b4180e8067f1acd00a7db7935afce00ffChristopher Tate    if (len > 999) len++;
467dc92c82b4180e8067f1acd00a7db7935afce00ffChristopher Tate    // since PATH_MAX is 4096 we don't expect to have to generate any single
468dc92c82b4180e8067f1acd00a7db7935afce00ffChristopher Tate    // header entry longer than 9999 characters
469dc92c82b4180e8067f1acd00a7db7935afce00ffChristopher Tate
470a346f5458a4d9e9ea8159a38ae5f696f19cf125bGeorge Burgess IV    return snprintf(buf, buf_size, "%d %s=%s\n", len, key, value);
471dc92c82b4180e8067f1acd00a7db7935afce00ffChristopher Tate}
472dc92c82b4180e8067f1acd00a7db7935afce00ffChristopher Tate
4737926a693c4a4f4d2a2d352343bca23e189c7420dChristopher Tate// Wire format to the backup manager service is chunked:  each chunk is prefixed by
4747926a693c4a4f4d2a2d352343bca23e189c7420dChristopher Tate// a 4-byte count of its size.  A chunk size of zero (four zero bytes) indicates EOD.
4757926a693c4a4f4d2a2d352343bca23e189c7420dChristopher Tatevoid send_tarfile_chunk(BackupDataWriter* writer, const char* buffer, size_t size) {
4767926a693c4a4f4d2a2d352343bca23e189c7420dChristopher Tate    uint32_t chunk_size_no = htonl(size);
4777926a693c4a4f4d2a2d352343bca23e189c7420dChristopher Tate    writer->WriteEntityData(&chunk_size_no, 4);
4787926a693c4a4f4d2a2d352343bca23e189c7420dChristopher Tate    if (size != 0) writer->WriteEntityData(buffer, size);
4797926a693c4a4f4d2a2d352343bca23e189c7420dChristopher Tate}
4807926a693c4a4f4d2a2d352343bca23e189c7420dChristopher Tate
4814a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tateint write_tarfile(const String8& packageName, const String8& domain,
48211ae768cf1b8348e761ad9c09e98788da1e591b1Christopher Tate        const String8& rootpath, const String8& filepath, off_t* outSize,
48311ae768cf1b8348e761ad9c09e98788da1e591b1Christopher Tate        BackupDataWriter* writer)
4844a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate{
4854a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate    // In the output stream everything is stored relative to the root
4864a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate    const char* relstart = filepath.string() + rootpath.length();
4874a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate    if (*relstart == '/') relstart++;     // won't be true when path == rootpath
4884a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate    String8 relpath(relstart);
4894a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate
49083a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate    // If relpath is empty, it means this is the top of one of the standard named
49183a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate    // domain directories, so we should just skip it
49283a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate    if (relpath.length() == 0) {
49311ae768cf1b8348e761ad9c09e98788da1e591b1Christopher Tate        *outSize = 0;
49483a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate        return 0;
49583a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate    }
49683a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate
4974a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate    // Too long a name for the ustar format?
4984a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate    //    "apps/" + packagename + '/' + domainpath < 155 chars
4994a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate    //    relpath < 100 chars
50083a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate    bool needExtended = false;
5014a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate    if ((5 + packageName.length() + 1 + domain.length() >= 155) || (relpath.length() >= 100)) {
50283a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate        needExtended = true;
5034a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate    }
5044a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate
5053f6c77b7caa02193205cb6ce180e0eb5a7579aa6Christopher Tate    // Non-7bit-clean path also means needing pax extended format
50675a99709accef8cf221fd436d646727e7c8dd1f1Christopher Tate    if (!needExtended) {
50775a99709accef8cf221fd436d646727e7c8dd1f1Christopher Tate        for (size_t i = 0; i < filepath.length(); i++) {
5083f6c77b7caa02193205cb6ce180e0eb5a7579aa6Christopher Tate            if ((filepath[i] & 0x80) != 0) {
50975a99709accef8cf221fd436d646727e7c8dd1f1Christopher Tate                needExtended = true;
51075a99709accef8cf221fd436d646727e7c8dd1f1Christopher Tate                break;
51175a99709accef8cf221fd436d646727e7c8dd1f1Christopher Tate            }
51275a99709accef8cf221fd436d646727e7c8dd1f1Christopher Tate        }
51375a99709accef8cf221fd436d646727e7c8dd1f1Christopher Tate    }
51475a99709accef8cf221fd436d646727e7c8dd1f1Christopher Tate
5154a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate    int err = 0;
5164a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate    struct stat64 s;
5174a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate    if (lstat64(filepath.string(), &s) != 0) {
5184a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate        err = errno;
5193762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("Error %d (%s) from lstat64(%s)", err, strerror(err), filepath.string());
5204a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate        return err;
5214a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate    }
5224a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate
52311ae768cf1b8348e761ad9c09e98788da1e591b1Christopher Tate    // very large files need a pax extended size header
52411ae768cf1b8348e761ad9c09e98788da1e591b1Christopher Tate    if (s.st_size > 077777777777LL) {
52511ae768cf1b8348e761ad9c09e98788da1e591b1Christopher Tate        needExtended = true;
52611ae768cf1b8348e761ad9c09e98788da1e591b1Christopher Tate    }
52711ae768cf1b8348e761ad9c09e98788da1e591b1Christopher Tate
52883a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate    String8 fullname;   // for pax later on
52983a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate    String8 prefix;
53083a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate
5314a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate    const int isdir = S_ISDIR(s.st_mode);
532e9e78ecd2c0ae5f48ed81fdfff4a89cb803fc409Christopher Tate    if (isdir) s.st_size = 0;   // directories get no actual data in the tar stream
5334a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate
53411ae768cf1b8348e761ad9c09e98788da1e591b1Christopher Tate    // Report the size, including a rough tar overhead estimation: 512 bytes for the
53511ae768cf1b8348e761ad9c09e98788da1e591b1Christopher Tate    // overall tar file-block header, plus 2 blocks if using the pax extended format,
53611ae768cf1b8348e761ad9c09e98788da1e591b1Christopher Tate    // plus the raw content size rounded up to a multiple of 512.
53711ae768cf1b8348e761ad9c09e98788da1e591b1Christopher Tate    *outSize = 512 + (needExtended ? 1024 : 0) + 512*((s.st_size + 511)/512);
53811ae768cf1b8348e761ad9c09e98788da1e591b1Christopher Tate
53911ae768cf1b8348e761ad9c09e98788da1e591b1Christopher Tate    // Measure case: we've returned the size; now return without moving data
54011ae768cf1b8348e761ad9c09e98788da1e591b1Christopher Tate    if (!writer) return 0;
54111ae768cf1b8348e761ad9c09e98788da1e591b1Christopher Tate
5424a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate    // !!! TODO: use mmap when possible to avoid churning the buffer cache
5434a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate    // !!! TODO: this will break with symlinks; need to use readlink(2)
5444a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate    int fd = open(filepath.string(), O_RDONLY);
5454a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate    if (fd < 0) {
5464a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate        err = errno;
5473762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("Error %d (%s) from open(%s)", err, strerror(err), filepath.string());
5484a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate        return err;
5494a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate    }
5504a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate
5514a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate    // read/write up to this much at a time.
5524a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate    const size_t BUFSIZE = 32 * 1024;
5537e1d395686a23c8638f72af190f125cf690618a3Iliyan Malchev    char* buf = (char *)calloc(1,BUFSIZE);
554a346f5458a4d9e9ea8159a38ae5f696f19cf125bGeorge Burgess IV    const size_t PAXHEADER_OFFSET = 512;
555a346f5458a4d9e9ea8159a38ae5f696f19cf125bGeorge Burgess IV    const size_t PAXHEADER_SIZE = 512;
556a346f5458a4d9e9ea8159a38ae5f696f19cf125bGeorge Burgess IV    const size_t PAXDATA_SIZE = BUFSIZE - (PAXHEADER_SIZE + PAXHEADER_OFFSET);
557a346f5458a4d9e9ea8159a38ae5f696f19cf125bGeorge Burgess IV    char* const paxHeader = buf + PAXHEADER_OFFSET; // use a different chunk of
558a346f5458a4d9e9ea8159a38ae5f696f19cf125bGeorge Burgess IV                                                    // it as separate scratch
559a346f5458a4d9e9ea8159a38ae5f696f19cf125bGeorge Burgess IV    char* const paxData = paxHeader + PAXHEADER_SIZE;
56083a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate
5614a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate    if (buf == NULL) {
5623762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("Out of mem allocating transfer buffer");
5634a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate        err = ENOMEM;
564294b512ecaa98a6a8ef12285ad14e7a4091b5d57Christopher Tate        goto done;
5654a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate    }
5664a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate
5674a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate    // Magic fields for the ustar file format
5684a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate    strcat(buf + 257, "ustar");
5694a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate    strcat(buf + 263, "00");
5704a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate
57183a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate    // [ 265 : 32 ] user name, ignored on restore
57283a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate    // [ 297 : 32 ] group name, ignored on restore
5734a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate
5744a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate    // [ 100 :   8 ] file mode
57583a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate    snprintf(buf + 100, 8, "%06o ", s.st_mode & ~S_IFMT);
5764a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate
5774a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate    // [ 108 :   8 ] uid -- ignored in Android format; uids are remapped at restore time
5784a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate    // [ 116 :   8 ] gid -- ignored in Android format
57900adb8685ee996f9d2650d617c8c0e98f13ef406Mark Salyzyn    snprintf(buf + 108, 8, "0%lo", (unsigned long)s.st_uid);
58000adb8685ee996f9d2650d617c8c0e98f13ef406Mark Salyzyn    snprintf(buf + 116, 8, "0%lo", (unsigned long)s.st_gid);
5814a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate
5824a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate    // [ 124 :  12 ] file size in bytes
58383a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate    snprintf(buf + 124, 12, "%011llo", (isdir) ? 0LL : s.st_size);
5844a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate
5854a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate    // [ 136 :  12 ] last mod time as a UTC time_t
58625df5fba3afff403c749bab7d1d5652c3b929e06Andreas Gampe    snprintf(buf + 136, 12, "%0lo", (unsigned long)s.st_mtime);
5874a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate
5884a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate    // [ 156 :   1 ] link/file type
5894a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate    uint8_t type;
5904a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate    if (isdir) {
5914a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate        type = '5';     // tar magic: '5' == directory
5924a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate    } else if (S_ISREG(s.st_mode)) {
5934a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate        type = '0';     // tar magic: '0' == normal file
5944a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate    } else {
5958564c8da817a845353d213acd8636b76f567b234Steve Block        ALOGW("Error: unknown file mode 0%o [%s]", s.st_mode, filepath.string());
5964a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate        goto cleanup;
5974a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate    }
5984a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate    buf[156] = type;
5994a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate
6004a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate    // [ 157 : 100 ] name of linked file [not implemented]
6014a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate
6024a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate    {
60383a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate        // Prefix and main relative path.  Path lengths have been preflighted.
60483a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate        if (packageName.length() > 0) {
60583a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate            prefix = "apps/";
60683a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate            prefix += packageName;
6074a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate        }
60883a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate        if (domain.length() > 0) {
60983a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate            prefix.appendPath(domain);
61083a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate        }
61183a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate
61283a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate        // pax extended means we don't put in a prefix field, and put a different
61383a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate        // string in the basic name field.  We can also construct the full path name
61483a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate        // out of the substrings we've now built.
61583a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate        fullname = prefix;
61683a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate        fullname.appendPath(relpath);
61783a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate
61883a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate        // ustar:
61983a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate        //    [   0 : 100 ]; file name/path
62083a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate        //    [ 345 : 155 ] filename path prefix
62183a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate        // We only use the prefix area if fullname won't fit in the path
62283a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate        if (fullname.length() > 100) {
62383a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate            strncpy(buf, relpath.string(), 100);
62483a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate            strncpy(buf + 345, prefix.string(), 155);
62583a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate        } else {
62683a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate            strncpy(buf, fullname.string(), 100);
62783a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate        }
62883a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate    }
62983a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate
63083a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate    // [ 329 : 8 ] and [ 337 : 8 ] devmajor/devminor, not used
63183a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate
6326215d3ff4b5dfa52a5d8b9a42e343051f31066a5Steve Block    ALOGI("   Name: %s", fullname.string());
63383a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate
63483a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate    // If we're using a pax extended header, build & write that here; lengths are
63583a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate    // already preflighted
63683a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate    if (needExtended) {
637dc92c82b4180e8067f1acd00a7db7935afce00ffChristopher Tate        char sizeStr[32];   // big enough for a 64-bit unsigned value in decimal
638dc92c82b4180e8067f1acd00a7db7935afce00ffChristopher Tate
63983a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate        // construct the pax extended header data block
640a346f5458a4d9e9ea8159a38ae5f696f19cf125bGeorge Burgess IV        memset(paxData, 0, PAXDATA_SIZE);
64183a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate
64283a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate        // size header -- calc len in digits by actually rendering the number
64383a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate        // to a string - brute force but simple
644a346f5458a4d9e9ea8159a38ae5f696f19cf125bGeorge Burgess IV        int paxLen = 0;
645f5df700e6ce056ebfa322314d970e52d6facc35aAshok Bhat        snprintf(sizeStr, sizeof(sizeStr), "%lld", (long long)s.st_size);
646a346f5458a4d9e9ea8159a38ae5f696f19cf125bGeorge Burgess IV        paxLen += write_pax_header_entry(paxData, PAXDATA_SIZE, "size", sizeStr);
64783a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate
64883a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate        // fullname was generated above with the ustar paths
649a346f5458a4d9e9ea8159a38ae5f696f19cf125bGeorge Burgess IV        paxLen += write_pax_header_entry(paxData + paxLen, PAXDATA_SIZE - paxLen,
650a346f5458a4d9e9ea8159a38ae5f696f19cf125bGeorge Burgess IV                "path", fullname.string());
65183a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate
65283a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate        // Now we know how big the pax data is
65383a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate
65483a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate        // Now build the pax *header* templated on the ustar header
65583a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate        memcpy(paxHeader, buf, 512);
65683a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate
65783a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate        String8 leaf = fullname.getPathLeaf();
65883a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate        memset(paxHeader, 0, 100);                  // rewrite the name area
65983a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate        snprintf(paxHeader, 100, "PaxHeader/%s", leaf.string());
66083a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate        memset(paxHeader + 345, 0, 155);            // rewrite the prefix area
66183a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate        strncpy(paxHeader + 345, prefix.string(), 155);
66283a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate
66383a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate        paxHeader[156] = 'x';                       // mark it as a pax extended header
66483a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate
66583a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate        // [ 124 :  12 ] size of pax extended header data
66683a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate        memset(paxHeader + 124, 0, 12);
667a346f5458a4d9e9ea8159a38ae5f696f19cf125bGeorge Burgess IV        snprintf(paxHeader + 124, 12, "%011o", (unsigned int)paxLen);
66883a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate
66983a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate        // Checksum and write the pax block header
670a346f5458a4d9e9ea8159a38ae5f696f19cf125bGeorge Burgess IV        calc_tar_checksum(paxHeader, PAXHEADER_SIZE);
6717926a693c4a4f4d2a2d352343bca23e189c7420dChristopher Tate        send_tarfile_chunk(writer, paxHeader, 512);
6724a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate
67383a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate        // Now write the pax data itself
67483a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate        int paxblocks = (paxLen + 511) / 512;
6757926a693c4a4f4d2a2d352343bca23e189c7420dChristopher Tate        send_tarfile_chunk(writer, paxData, 512 * paxblocks);
6764a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate    }
6774a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate
67883a7cdc56539d00933c2e25999620cec94c524b6Christopher Tate    // Checksum and write the 512-byte ustar file header block to the output
679a346f5458a4d9e9ea8159a38ae5f696f19cf125bGeorge Burgess IV    calc_tar_checksum(buf, BUFSIZE);
6807926a693c4a4f4d2a2d352343bca23e189c7420dChristopher Tate    send_tarfile_chunk(writer, buf, 512);
6814a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate
6824a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate    // Now write the file data itself, for real files.  We honor tar's convention that
6834a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate    // only full 512-byte blocks are sent to write().
6844a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate    if (!isdir) {
6854a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate        off64_t toWrite = s.st_size;
6864a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate        while (toWrite > 0) {
687f5df700e6ce056ebfa322314d970e52d6facc35aAshok Bhat            size_t toRead = toWrite;
688f5df700e6ce056ebfa322314d970e52d6facc35aAshok Bhat            if (toRead > BUFSIZE) {
689f5df700e6ce056ebfa322314d970e52d6facc35aAshok Bhat                toRead = BUFSIZE;
690f5df700e6ce056ebfa322314d970e52d6facc35aAshok Bhat            }
6914a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate            ssize_t nRead = read(fd, buf, toRead);
6924a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate            if (nRead < 0) {
6934a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate                err = errno;
6943762c311729fe9f3af085c14c5c1fb471d994c03Steve Block                ALOGE("Unable to read file [%s], err=%d (%s)", filepath.string(),
6954a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate                        err, strerror(err));
6964a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate                break;
6974a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate            } else if (nRead == 0) {
6983762c311729fe9f3af085c14c5c1fb471d994c03Steve Block                ALOGE("EOF but expect %lld more bytes in [%s]", (long long) toWrite,
6994a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate                        filepath.string());
7004a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate                err = EIO;
7014a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate                break;
7024a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate            }
7034a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate
7044a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate            // At EOF we might have a short block; NUL-pad that to a 512-byte multiple.  This
7054a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate            // depends on the OS guarantee that for ordinary files, read() will never return
7064a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate            // less than the number of bytes requested.
7074a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate            ssize_t partial = (nRead+512) % 512;
7084a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate            if (partial > 0) {
7094a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate                ssize_t remainder = 512 - partial;
7104a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate                memset(buf + nRead, 0, remainder);
7114a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate                nRead += remainder;
7124a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate            }
7137926a693c4a4f4d2a2d352343bca23e189c7420dChristopher Tate            send_tarfile_chunk(writer, buf, nRead);
7144a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate            toWrite -= nRead;
7154a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate        }
7164a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate    }
7174a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate
7184a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tatecleanup:
7198b2e2c8abc20de5ba3d938d8c559d0c5e2f9e356You Kim    free(buf);
7204a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tatedone:
7214a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate    close(fd);
7224a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate    return err;
7234a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate}
7244a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate// end tarfile
7254a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate
7264a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate
7274a627c71ff53a4fca1f961f4b1dcc0461df18a06Christopher Tate
728d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato#define RESTORE_BUF_SIZE (8*1024)
729d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato
730d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe OnoratoRestoreHelperBase::RestoreHelperBase()
731d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato{
732d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato    m_buf = malloc(RESTORE_BUF_SIZE);
73363bcb79dd437e70593b63cc5a87baab3251c2183Christopher Tate    m_loggedUnknownMetadata = false;
734d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato}
735d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato
736d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe OnoratoRestoreHelperBase::~RestoreHelperBase()
737d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato{
738d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato    free(m_buf);
739d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato}
740d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato
741d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onoratostatus_t
742d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe OnoratoRestoreHelperBase::WriteFile(const String8& filename, BackupDataReader* in)
743d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato{
744d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato    ssize_t err;
745d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato    size_t dataSize;
746d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato    String8 key;
747d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato    int fd;
748d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato    void* buf = m_buf;
749d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato    ssize_t amt;
750d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato    int mode;
751d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato    int crc;
752d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato    struct stat st;
753d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato    FileRec r;
754d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato
755d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato    err = in->ReadEntityHeader(&key, &dataSize);
756d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato    if (err != NO_ERROR) {
757d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato        return err;
758d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato    }
7595d605dc56b036232e885f6ec36b888b729673060Joe Onorato
760fbb92385f2fb0ae1146bb8f3d73547d90bda6db1Christopher Tate    // Get the metadata block off the head of the file entity and use that to
761fbb92385f2fb0ae1146bb8f3d73547d90bda6db1Christopher Tate    // set up the output file
762fbb92385f2fb0ae1146bb8f3d73547d90bda6db1Christopher Tate    file_metadata_v1 metadata;
763fbb92385f2fb0ae1146bb8f3d73547d90bda6db1Christopher Tate    amt = in->ReadEntityData(&metadata, sizeof(metadata));
764fbb92385f2fb0ae1146bb8f3d73547d90bda6db1Christopher Tate    if (amt != sizeof(metadata)) {
7658564c8da817a845353d213acd8636b76f567b234Steve Block        ALOGW("Could not read metadata for %s -- %ld / %s", filename.string(),
766fbb92385f2fb0ae1146bb8f3d73547d90bda6db1Christopher Tate                (long)amt, strerror(errno));
767fbb92385f2fb0ae1146bb8f3d73547d90bda6db1Christopher Tate        return EIO;
768fbb92385f2fb0ae1146bb8f3d73547d90bda6db1Christopher Tate    }
769fbb92385f2fb0ae1146bb8f3d73547d90bda6db1Christopher Tate    metadata.version = fromlel(metadata.version);
770fbb92385f2fb0ae1146bb8f3d73547d90bda6db1Christopher Tate    metadata.mode = fromlel(metadata.mode);
771fbb92385f2fb0ae1146bb8f3d73547d90bda6db1Christopher Tate    if (metadata.version > CURRENT_METADATA_VERSION) {
77263bcb79dd437e70593b63cc5a87baab3251c2183Christopher Tate        if (!m_loggedUnknownMetadata) {
77363bcb79dd437e70593b63cc5a87baab3251c2183Christopher Tate            m_loggedUnknownMetadata = true;
7748564c8da817a845353d213acd8636b76f567b234Steve Block            ALOGW("Restoring file with unsupported metadata version %d (currently %d)",
77563bcb79dd437e70593b63cc5a87baab3251c2183Christopher Tate                    metadata.version, CURRENT_METADATA_VERSION);
77663bcb79dd437e70593b63cc5a87baab3251c2183Christopher Tate        }
777fbb92385f2fb0ae1146bb8f3d73547d90bda6db1Christopher Tate    }
778fbb92385f2fb0ae1146bb8f3d73547d90bda6db1Christopher Tate    mode = metadata.mode;
779d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato
780d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato    // Write the file and compute the crc
781d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato    crc = crc32(0L, Z_NULL, 0);
7825d605dc56b036232e885f6ec36b888b729673060Joe Onorato    fd = open(filename.string(), O_CREAT|O_RDWR|O_TRUNC, mode);
7835d605dc56b036232e885f6ec36b888b729673060Joe Onorato    if (fd == -1) {
7848564c8da817a845353d213acd8636b76f567b234Steve Block        ALOGW("Could not open file %s -- %s", filename.string(), strerror(errno));
785d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato        return errno;
786d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato    }
78700adb8685ee996f9d2650d617c8c0e98f13ef406Mark Salyzyn
788d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato    while ((amt = in->ReadEntityData(buf, RESTORE_BUF_SIZE)) > 0) {
789d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato        err = write(fd, buf, amt);
790d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato        if (err != amt) {
791d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato            close(fd);
7928564c8da817a845353d213acd8636b76f567b234Steve Block            ALOGW("Error '%s' writing '%s'", strerror(errno), filename.string());
793d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato            return errno;
794d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato        }
795d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato        crc = crc32(crc, (Bytef*)buf, amt);
796d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato    }
797d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato
798d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato    close(fd);
799d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato
800d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato    // Record for the snapshot
801d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato    err = stat(filename.string(), &st);
802d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato    if (err != 0) {
8038564c8da817a845353d213acd8636b76f567b234Steve Block        ALOGW("Error stating file that we just created %s", filename.string());
804d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato        return errno;
805d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato    }
806d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato
807d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato    r.file = filename;
808d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato    r.deleted = false;
809d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato    r.s.modTime_sec = st.st_mtime;
810d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato    r.s.modTime_nsec = 0; // workaround sim breakage
811d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato    //r.s.modTime_nsec = st.st_mtime_nsec;
81211b157790234d3d2f116ce4c7ed1d3d00fb78bc3Christopher Tate    r.s.mode = st.st_mode;
813d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato    r.s.size = st.st_size;
814d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato    r.s.crc32 = crc;
815d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato
816d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato    m_files.add(key, r);
817d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato
818d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato    return NO_ERROR;
819d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato}
820d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato
821d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onoratostatus_t
822d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe OnoratoRestoreHelperBase::WriteSnapshot(int fd)
823d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato{
824d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato    return write_snapshot_file(fd, m_files);;
825d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato}
826d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato
8273ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato#if TEST_BACKUP_HELPERS
8283ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
8293ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato#define SCRATCH_DIR "/data/backup_helper_test/"
8303ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
8313ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onoratostatic int
8323ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onoratowrite_text_file(const char* path, const char* data)
8333ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato{
8343ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    int amt;
8353ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    int fd;
8363ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    int len;
8373ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
8383ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    fd = creat(path, 0666);
8393ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    if (fd == -1) {
8403ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        fprintf(stderr, "creat %s failed\n", path);
8413ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        return errno;
8423ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    }
8433ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
8443ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    len = strlen(data);
8453ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    amt = write(fd, data, len);
8463ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    if (amt != len) {
8473ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        fprintf(stderr, "error (%s) writing to file %s\n", strerror(errno), path);
8483ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        return errno;
8493ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    }
8503ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
8513ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    close(fd);
8523ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
8533ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    return 0;
8543ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato}
8553ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
8563ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onoratostatic int
8573ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onoratocompare_file(const char* path, const unsigned char* data, int len)
8583ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato{
8593ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    int fd;
8603ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    int amt;
8613ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
8623ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    fd = open(path, O_RDONLY);
8633ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    if (fd == -1) {
8643ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        fprintf(stderr, "compare_file error (%s) opening %s\n", strerror(errno), path);
8653ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        return errno;
8663ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    }
8673ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
8683ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    unsigned char* contents = (unsigned char*)malloc(len);
8693ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    if (contents == NULL) {
8703ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        fprintf(stderr, "malloc(%d) failed\n", len);
8713ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        return ENOMEM;
8723ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    }
8733ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
8743ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    bool sizesMatch = true;
8753ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    amt = lseek(fd, 0, SEEK_END);
8763ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    if (amt != len) {
8773ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        fprintf(stderr, "compare_file file length should be %d, was %d\n", len, amt);
8783ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        sizesMatch = false;
8793ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    }
8803ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    lseek(fd, 0, SEEK_SET);
8813ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
8823ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    int readLen = amt < len ? amt : len;
8833ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    amt = read(fd, contents, readLen);
8843ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    if (amt != readLen) {
8853ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        fprintf(stderr, "compare_file read expected %d bytes but got %d\n", len, amt);
8863ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    }
8873ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
8883ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    bool contentsMatch = true;
8893ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    for (int i=0; i<readLen; i++) {
8903ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        if (data[i] != contents[i]) {
8913ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato            if (contentsMatch) {
8923ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato                fprintf(stderr, "compare_file contents are different: (index, expected, actual)\n");
8933ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato                contentsMatch = false;
8943ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato            }
8953ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato            fprintf(stderr, "  [%-2d] %02x %02x\n", i, data[i], contents[i]);
8963ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        }
8973ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    }
8983ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
89963bcb79dd437e70593b63cc5a87baab3251c2183Christopher Tate    free(contents);
9003ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    return contentsMatch && sizesMatch ? 0 : 1;
9013ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato}
9023ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
9033ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onoratoint
9043ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onoratobackup_helper_test_empty()
9053ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato{
9063ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    int err;
9073ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    int fd;
90823ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato    KeyedVector<String8,FileRec> snapshot;
9093ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    const char* filename = SCRATCH_DIR "backup_helper_test_empty.snap";
9103ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
9113ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    system("rm -r " SCRATCH_DIR);
9123ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    mkdir(SCRATCH_DIR, 0777);
9133ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
9143ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    // write
9153ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    fd = creat(filename, 0666);
9163ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    if (fd == -1) {
9173ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        fprintf(stderr, "error creating %s\n", filename);
9183ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        return 1;
9193ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    }
9203ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
9213ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    err = write_snapshot_file(fd, snapshot);
9223ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
9233ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    close(fd);
9243ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
9253ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    if (err != 0) {
9263ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        fprintf(stderr, "write_snapshot_file reported error %d (%s)\n", err, strerror(err));
9273ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        return err;
9283ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    }
9293ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
9303ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    static const unsigned char correct_data[] = {
9313ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        0x53, 0x6e, 0x61, 0x70,  0x00, 0x00, 0x00, 0x00,
9323ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        0x46, 0x69, 0x6c, 0x65,  0x10, 0x00, 0x00, 0x00
9333ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    };
9343ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
9353ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    err = compare_file(filename, correct_data, sizeof(correct_data));
9363ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    if (err != 0) {
9373ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        return err;
9383ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    }
9393ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
9403ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    // read
9413ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    fd = open(filename, O_RDONLY);
9423ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    if (fd == -1) {
9433ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        fprintf(stderr, "error opening for read %s\n", filename);
9443ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        return 1;
9453ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    }
9463ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
9473ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    KeyedVector<String8,FileState> readSnapshot;
9483ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    err = read_snapshot_file(fd, &readSnapshot);
9493ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    if (err != 0) {
9503ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        fprintf(stderr, "read_snapshot_file failed %d\n", err);
9513ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        return err;
9523ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    }
9533ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
9543ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    if (readSnapshot.size() != 0) {
9553ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        fprintf(stderr, "readSnapshot should be length 0\n");
9563ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        return 1;
9573ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    }
9583ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
9593ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    return 0;
9603ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato}
9613ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
9623ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onoratoint
9633ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onoratobackup_helper_test_four()
9643ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato{
9653ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    int err;
9663ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    int fd;
96723ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato    KeyedVector<String8,FileRec> snapshot;
9683ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    const char* filename = SCRATCH_DIR "backup_helper_test_four.snap";
9693ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
9703ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    system("rm -r " SCRATCH_DIR);
9713ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    mkdir(SCRATCH_DIR, 0777);
9723ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
9733ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    // write
9743ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    fd = creat(filename, 0666);
9753ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    if (fd == -1) {
9763ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        fprintf(stderr, "error opening %s\n", filename);
9773ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        return 1;
9783ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    }
9793ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
9803ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    String8 filenames[4];
9813ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    FileState states[4];
98223ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato    FileRec r;
983ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato    r.deleted = false;
9843ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
9853ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    states[0].modTime_sec = 0xfedcba98;
9863ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    states[0].modTime_nsec = 0xdeadbeef;
98711b157790234d3d2f116ce4c7ed1d3d00fb78bc3Christopher Tate    states[0].mode = 0777; // decimal 511, hex 0x000001ff
9883ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    states[0].size = 0xababbcbc;
9893ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    states[0].crc32 = 0x12345678;
9903ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    states[0].nameLen = -12;
99123ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato    r.s = states[0];
9923ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    filenames[0] = String8("bytes_of_padding");
99323ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato    snapshot.add(filenames[0], r);
9943ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
9953ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    states[1].modTime_sec = 0x93400031;
9963ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    states[1].modTime_nsec = 0xdeadbeef;
99711b157790234d3d2f116ce4c7ed1d3d00fb78bc3Christopher Tate    states[1].mode = 0666; // decimal 438, hex 0x000001b6
9983ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    states[1].size = 0x88557766;
9993ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    states[1].crc32 = 0x22334422;
10003ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    states[1].nameLen = -1;
100123ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato    r.s = states[1];
10023ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    filenames[1] = String8("bytes_of_padding3");
100323ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato    snapshot.add(filenames[1], r);
10043ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
10053ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    states[2].modTime_sec = 0x33221144;
10063ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    states[2].modTime_nsec = 0xdeadbeef;
100711b157790234d3d2f116ce4c7ed1d3d00fb78bc3Christopher Tate    states[2].mode = 0744; // decimal 484, hex 0x000001e4
10083ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    states[2].size = 0x11223344;
10093ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    states[2].crc32 = 0x01122334;
10103ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    states[2].nameLen = 0;
101123ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato    r.s = states[2];
10123ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    filenames[2] = String8("bytes_of_padding_2");
101323ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato    snapshot.add(filenames[2], r);
10143ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
10153ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    states[3].modTime_sec = 0x33221144;
10163ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    states[3].modTime_nsec = 0xdeadbeef;
101711b157790234d3d2f116ce4c7ed1d3d00fb78bc3Christopher Tate    states[3].mode = 0755; // decimal 493, hex 0x000001ed
10183ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    states[3].size = 0x11223344;
10193ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    states[3].crc32 = 0x01122334;
10203ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    states[3].nameLen = 0;
102123ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato    r.s = states[3];
10223ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    filenames[3] = String8("bytes_of_padding__1");
102323ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato    snapshot.add(filenames[3], r);
10243ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
10253ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    err = write_snapshot_file(fd, snapshot);
10263ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
10273ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    close(fd);
10283ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
10293ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    if (err != 0) {
10303ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        fprintf(stderr, "write_snapshot_file reported error %d (%s)\n", err, strerror(err));
10313ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        return err;
10323ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    }
10333ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
10343ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    static const unsigned char correct_data[] = {
10353ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        // header
10363ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        0x53, 0x6e, 0x61, 0x70,  0x04, 0x00, 0x00, 0x00,
103711b157790234d3d2f116ce4c7ed1d3d00fb78bc3Christopher Tate        0x46, 0x69, 0x6c, 0x65,  0xbc, 0x00, 0x00, 0x00,
10383ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
10393ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        // bytes_of_padding
10403ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        0x98, 0xba, 0xdc, 0xfe,  0xef, 0xbe, 0xad, 0xde,
104111b157790234d3d2f116ce4c7ed1d3d00fb78bc3Christopher Tate        0xff, 0x01, 0x00, 0x00,  0xbc, 0xbc, 0xab, 0xab,
104211b157790234d3d2f116ce4c7ed1d3d00fb78bc3Christopher Tate        0x78, 0x56, 0x34, 0x12,  0x10, 0x00, 0x00, 0x00,
104311b157790234d3d2f116ce4c7ed1d3d00fb78bc3Christopher Tate        0x62, 0x79, 0x74, 0x65,  0x73, 0x5f, 0x6f, 0x66,
104411b157790234d3d2f116ce4c7ed1d3d00fb78bc3Christopher Tate        0x5f, 0x70, 0x61, 0x64,  0x64, 0x69, 0x6e, 0x67,
10453ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
10463ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        // bytes_of_padding3
10473ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        0x31, 0x00, 0x40, 0x93,  0xef, 0xbe, 0xad, 0xde,
104811b157790234d3d2f116ce4c7ed1d3d00fb78bc3Christopher Tate        0xb6, 0x01, 0x00, 0x00,  0x66, 0x77, 0x55, 0x88,
104911b157790234d3d2f116ce4c7ed1d3d00fb78bc3Christopher Tate        0x22, 0x44, 0x33, 0x22,  0x11, 0x00, 0x00, 0x00,
105011b157790234d3d2f116ce4c7ed1d3d00fb78bc3Christopher Tate        0x62, 0x79, 0x74, 0x65,  0x73, 0x5f, 0x6f, 0x66,
105111b157790234d3d2f116ce4c7ed1d3d00fb78bc3Christopher Tate        0x5f, 0x70, 0x61, 0x64,  0x64, 0x69, 0x6e, 0x67,
105211b157790234d3d2f116ce4c7ed1d3d00fb78bc3Christopher Tate        0x33, 0xab, 0xab, 0xab,
1053f4c46b94b867f6a01bf7d0be18f667819338072fNicolas Catania
10543ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        // bytes of padding2
10553ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        0x44, 0x11, 0x22, 0x33,  0xef, 0xbe, 0xad, 0xde,
105611b157790234d3d2f116ce4c7ed1d3d00fb78bc3Christopher Tate        0xe4, 0x01, 0x00, 0x00,  0x44, 0x33, 0x22, 0x11,
105711b157790234d3d2f116ce4c7ed1d3d00fb78bc3Christopher Tate        0x34, 0x23, 0x12, 0x01,  0x12, 0x00, 0x00, 0x00,
105811b157790234d3d2f116ce4c7ed1d3d00fb78bc3Christopher Tate        0x62, 0x79, 0x74, 0x65,  0x73, 0x5f, 0x6f, 0x66,
105911b157790234d3d2f116ce4c7ed1d3d00fb78bc3Christopher Tate        0x5f, 0x70, 0x61, 0x64,  0x64, 0x69, 0x6e, 0x67,
106011b157790234d3d2f116ce4c7ed1d3d00fb78bc3Christopher Tate        0x5f, 0x32, 0xab, 0xab,
1061f4c46b94b867f6a01bf7d0be18f667819338072fNicolas Catania
10623ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        // bytes of padding3
10633ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        0x44, 0x11, 0x22, 0x33,  0xef, 0xbe, 0xad, 0xde,
106411b157790234d3d2f116ce4c7ed1d3d00fb78bc3Christopher Tate        0xed, 0x01, 0x00, 0x00,  0x44, 0x33, 0x22, 0x11,
106511b157790234d3d2f116ce4c7ed1d3d00fb78bc3Christopher Tate        0x34, 0x23, 0x12, 0x01,  0x13, 0x00, 0x00, 0x00,
106611b157790234d3d2f116ce4c7ed1d3d00fb78bc3Christopher Tate        0x62, 0x79, 0x74, 0x65,  0x73, 0x5f, 0x6f, 0x66,
106711b157790234d3d2f116ce4c7ed1d3d00fb78bc3Christopher Tate        0x5f, 0x70, 0x61, 0x64,  0x64, 0x69, 0x6e, 0x67,
106811b157790234d3d2f116ce4c7ed1d3d00fb78bc3Christopher Tate        0x5f, 0x5f, 0x31, 0xab
10693ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    };
10703ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
10713ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    err = compare_file(filename, correct_data, sizeof(correct_data));
10723ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    if (err != 0) {
10733ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        return err;
10743ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    }
1075f4c46b94b867f6a01bf7d0be18f667819338072fNicolas Catania
10763ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    // read
10773ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    fd = open(filename, O_RDONLY);
10783ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    if (fd == -1) {
10793ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        fprintf(stderr, "error opening for read %s\n", filename);
10803ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        return 1;
10813ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    }
10823ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
10833ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
10843ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    KeyedVector<String8,FileState> readSnapshot;
10853ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    err = read_snapshot_file(fd, &readSnapshot);
10863ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    if (err != 0) {
10873ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        fprintf(stderr, "read_snapshot_file failed %d\n", err);
10883ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        return err;
10893ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    }
10903ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
10913ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    if (readSnapshot.size() != 4) {
109295ece35c2f8b86203e88b49d67cef8e80e107a2bKévin PETIT        fprintf(stderr, "readSnapshot should be length 4 is %zu\n", readSnapshot.size());
10933ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        return 1;
10943ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    }
10953ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
10963ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    bool matched = true;
10973ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    for (size_t i=0; i<readSnapshot.size(); i++) {
10983ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        const String8& name = readSnapshot.keyAt(i);
10993ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        const FileState state = readSnapshot.valueAt(i);
11003ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
11013ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        if (name != filenames[i] || states[i].modTime_sec != state.modTime_sec
110211b157790234d3d2f116ce4c7ed1d3d00fb78bc3Christopher Tate                || states[i].modTime_nsec != state.modTime_nsec || states[i].mode != state.mode
11033ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato                || states[i].size != state.size || states[i].crc32 != states[i].crc32) {
1104f5df700e6ce056ebfa322314d970e52d6facc35aAshok Bhat            fprintf(stderr, "state %zu expected={%d/%d, %04o, 0x%08x, 0x%08x, %3zu} '%s'\n"
1105f5df700e6ce056ebfa322314d970e52d6facc35aAshok Bhat                            "          actual={%d/%d, %04o, 0x%08x, 0x%08x, %3d} '%s'\n", i,
110611b157790234d3d2f116ce4c7ed1d3d00fb78bc3Christopher Tate                    states[i].modTime_sec, states[i].modTime_nsec, states[i].mode, states[i].size,
110711b157790234d3d2f116ce4c7ed1d3d00fb78bc3Christopher Tate                    states[i].crc32, name.length(), filenames[i].string(),
110811b157790234d3d2f116ce4c7ed1d3d00fb78bc3Christopher Tate                    state.modTime_sec, state.modTime_nsec, state.mode, state.size, state.crc32,
110911b157790234d3d2f116ce4c7ed1d3d00fb78bc3Christopher Tate                    state.nameLen, name.string());
11103ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato            matched = false;
11113ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        }
11123ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    }
1113f4c46b94b867f6a01bf7d0be18f667819338072fNicolas Catania
11143ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    return matched ? 0 : 1;
11153ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato}
11163ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
11174535e40544aeb957d44fad75fbe5676effe03689Joe Onorato// hexdump -v -e '"    " 8/1 " 0x%02x," "\n"' data_writer.data
11184535e40544aeb957d44fad75fbe5676effe03689Joe Onoratoconst unsigned char DATA_GOLDEN_FILE[] = {
11192e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato     0x44, 0x61, 0x74, 0x61, 0x0b, 0x00, 0x00, 0x00,
11202e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato     0x0c, 0x00, 0x00, 0x00, 0x6e, 0x6f, 0x5f, 0x70,
11214535e40544aeb957d44fad75fbe5676effe03689Joe Onorato     0x61, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x5f, 0x00,
11222e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato     0x6e, 0x6f, 0x5f, 0x70, 0x61, 0x64, 0x64, 0x69,
11235f15d151b5101fadfe6cba1e8f4aa6367e8c603eJoe Onorato     0x6e, 0x67, 0x5f, 0x00, 0x44, 0x61, 0x74, 0x61,
11245f15d151b5101fadfe6cba1e8f4aa6367e8c603eJoe Onorato     0x0c, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00,
11254535e40544aeb957d44fad75fbe5676effe03689Joe Onorato     0x70, 0x61, 0x64, 0x64, 0x65, 0x64, 0x5f, 0x74,
11264535e40544aeb957d44fad75fbe5676effe03689Joe Onorato     0x6f, 0x5f, 0x5f, 0x33, 0x00, 0xbc, 0xbc, 0xbc,
11274535e40544aeb957d44fad75fbe5676effe03689Joe Onorato     0x70, 0x61, 0x64, 0x64, 0x65, 0x64, 0x5f, 0x74,
11285f15d151b5101fadfe6cba1e8f4aa6367e8c603eJoe Onorato     0x6f, 0x5f, 0x5f, 0x33, 0x00, 0xbc, 0xbc, 0xbc,
11292e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato     0x44, 0x61, 0x74, 0x61, 0x0d, 0x00, 0x00, 0x00,
11302e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato     0x0e, 0x00, 0x00, 0x00, 0x70, 0x61, 0x64, 0x64,
11312e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato     0x65, 0x64, 0x5f, 0x74, 0x6f, 0x5f, 0x32, 0x5f,
11322e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato     0x5f, 0x00, 0xbc, 0xbc, 0x70, 0x61, 0x64, 0x64,
11332e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato     0x65, 0x64, 0x5f, 0x74, 0x6f, 0x5f, 0x32, 0x5f,
11345f15d151b5101fadfe6cba1e8f4aa6367e8c603eJoe Onorato     0x5f, 0x00, 0xbc, 0xbc, 0x44, 0x61, 0x74, 0x61,
11354535e40544aeb957d44fad75fbe5676effe03689Joe Onorato     0x0a, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00,
11364535e40544aeb957d44fad75fbe5676effe03689Joe Onorato     0x70, 0x61, 0x64, 0x64, 0x65, 0x64, 0x5f, 0x74,
11374535e40544aeb957d44fad75fbe5676effe03689Joe Onorato     0x6f, 0x31, 0x00, 0xbc, 0x70, 0x61, 0x64, 0x64,
11385f15d151b5101fadfe6cba1e8f4aa6367e8c603eJoe Onorato     0x65, 0x64, 0x5f, 0x74, 0x6f, 0x31, 0x00
11395f15d151b5101fadfe6cba1e8f4aa6367e8c603eJoe Onorato
11404535e40544aeb957d44fad75fbe5676effe03689Joe Onorato};
11414535e40544aeb957d44fad75fbe5676effe03689Joe Onoratoconst int DATA_GOLDEN_FILE_SIZE = sizeof(DATA_GOLDEN_FILE);
11424535e40544aeb957d44fad75fbe5676effe03689Joe Onorato
11434535e40544aeb957d44fad75fbe5676effe03689Joe Onoratostatic int
11444535e40544aeb957d44fad75fbe5676effe03689Joe Onoratotest_write_header_and_entity(BackupDataWriter& writer, const char* str)
11454535e40544aeb957d44fad75fbe5676effe03689Joe Onorato{
11464535e40544aeb957d44fad75fbe5676effe03689Joe Onorato    int err;
11474535e40544aeb957d44fad75fbe5676effe03689Joe Onorato    String8 text(str);
11484535e40544aeb957d44fad75fbe5676effe03689Joe Onorato
11494535e40544aeb957d44fad75fbe5676effe03689Joe Onorato    err = writer.WriteEntityHeader(text, text.length()+1);
11504535e40544aeb957d44fad75fbe5676effe03689Joe Onorato    if (err != 0) {
11514535e40544aeb957d44fad75fbe5676effe03689Joe Onorato        fprintf(stderr, "WriteEntityHeader failed with %s\n", strerror(err));
11524535e40544aeb957d44fad75fbe5676effe03689Joe Onorato        return err;
11534535e40544aeb957d44fad75fbe5676effe03689Joe Onorato    }
11544535e40544aeb957d44fad75fbe5676effe03689Joe Onorato
11554535e40544aeb957d44fad75fbe5676effe03689Joe Onorato    err = writer.WriteEntityData(text.string(), text.length()+1);
11564535e40544aeb957d44fad75fbe5676effe03689Joe Onorato    if (err != 0) {
11574535e40544aeb957d44fad75fbe5676effe03689Joe Onorato        fprintf(stderr, "write failed for data '%s'\n", text.string());
11584535e40544aeb957d44fad75fbe5676effe03689Joe Onorato        return errno;
11594535e40544aeb957d44fad75fbe5676effe03689Joe Onorato    }
11604535e40544aeb957d44fad75fbe5676effe03689Joe Onorato
11614535e40544aeb957d44fad75fbe5676effe03689Joe Onorato    return err;
11624535e40544aeb957d44fad75fbe5676effe03689Joe Onorato}
11634535e40544aeb957d44fad75fbe5676effe03689Joe Onorato
11644535e40544aeb957d44fad75fbe5676effe03689Joe Onoratoint
11654535e40544aeb957d44fad75fbe5676effe03689Joe Onoratobackup_helper_test_data_writer()
11664535e40544aeb957d44fad75fbe5676effe03689Joe Onorato{
11674535e40544aeb957d44fad75fbe5676effe03689Joe Onorato    int err;
11684535e40544aeb957d44fad75fbe5676effe03689Joe Onorato    int fd;
11694535e40544aeb957d44fad75fbe5676effe03689Joe Onorato    const char* filename = SCRATCH_DIR "data_writer.data";
11704535e40544aeb957d44fad75fbe5676effe03689Joe Onorato
11714535e40544aeb957d44fad75fbe5676effe03689Joe Onorato    system("rm -r " SCRATCH_DIR);
11724535e40544aeb957d44fad75fbe5676effe03689Joe Onorato    mkdir(SCRATCH_DIR, 0777);
11734535e40544aeb957d44fad75fbe5676effe03689Joe Onorato    mkdir(SCRATCH_DIR "data", 0777);
1174f4c46b94b867f6a01bf7d0be18f667819338072fNicolas Catania
11754535e40544aeb957d44fad75fbe5676effe03689Joe Onorato    fd = creat(filename, 0666);
11764535e40544aeb957d44fad75fbe5676effe03689Joe Onorato    if (fd == -1) {
11774535e40544aeb957d44fad75fbe5676effe03689Joe Onorato        fprintf(stderr, "error creating: %s\n", strerror(errno));
11784535e40544aeb957d44fad75fbe5676effe03689Joe Onorato        return errno;
11794535e40544aeb957d44fad75fbe5676effe03689Joe Onorato    }
11804535e40544aeb957d44fad75fbe5676effe03689Joe Onorato
11814535e40544aeb957d44fad75fbe5676effe03689Joe Onorato    BackupDataWriter writer(fd);
11824535e40544aeb957d44fad75fbe5676effe03689Joe Onorato
11834535e40544aeb957d44fad75fbe5676effe03689Joe Onorato    err = 0;
11844535e40544aeb957d44fad75fbe5676effe03689Joe Onorato    err |= test_write_header_and_entity(writer, "no_padding_");
11854535e40544aeb957d44fad75fbe5676effe03689Joe Onorato    err |= test_write_header_and_entity(writer, "padded_to__3");
11864535e40544aeb957d44fad75fbe5676effe03689Joe Onorato    err |= test_write_header_and_entity(writer, "padded_to_2__");
11874535e40544aeb957d44fad75fbe5676effe03689Joe Onorato    err |= test_write_header_and_entity(writer, "padded_to1");
11884535e40544aeb957d44fad75fbe5676effe03689Joe Onorato
11894535e40544aeb957d44fad75fbe5676effe03689Joe Onorato    close(fd);
11904535e40544aeb957d44fad75fbe5676effe03689Joe Onorato
11914535e40544aeb957d44fad75fbe5676effe03689Joe Onorato    err = compare_file(filename, DATA_GOLDEN_FILE, DATA_GOLDEN_FILE_SIZE);
11924535e40544aeb957d44fad75fbe5676effe03689Joe Onorato    if (err != 0) {
11934535e40544aeb957d44fad75fbe5676effe03689Joe Onorato        return err;
11944535e40544aeb957d44fad75fbe5676effe03689Joe Onorato    }
11954535e40544aeb957d44fad75fbe5676effe03689Joe Onorato
11964535e40544aeb957d44fad75fbe5676effe03689Joe Onorato    return err;
11974535e40544aeb957d44fad75fbe5676effe03689Joe Onorato}
11984535e40544aeb957d44fad75fbe5676effe03689Joe Onorato
11992e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onoratoint
12002e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onoratotest_read_header_and_entity(BackupDataReader& reader, const char* str)
12012e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato{
12022e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    int err;
1203f5df700e6ce056ebfa322314d970e52d6facc35aAshok Bhat    size_t bufSize = strlen(str)+1;
12042e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    char* buf = (char*)malloc(bufSize);
12052e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    String8 string;
12062e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    size_t actualSize;
12075f15d151b5101fadfe6cba1e8f4aa6367e8c603eJoe Onorato    bool done;
12085f15d151b5101fadfe6cba1e8f4aa6367e8c603eJoe Onorato    int type;
120911b157790234d3d2f116ce4c7ed1d3d00fb78bc3Christopher Tate    ssize_t nRead;
12102e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato
12112e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    // printf("\n\n---------- test_read_header_and_entity -- %s\n\n", str);
12122e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato
12135f15d151b5101fadfe6cba1e8f4aa6367e8c603eJoe Onorato    err = reader.ReadNextHeader(&done, &type);
12145f15d151b5101fadfe6cba1e8f4aa6367e8c603eJoe Onorato    if (done) {
12155f15d151b5101fadfe6cba1e8f4aa6367e8c603eJoe Onorato        fprintf(stderr, "should not be done yet\n");
12165f15d151b5101fadfe6cba1e8f4aa6367e8c603eJoe Onorato        goto finished;
12172e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    }
12182e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    if (err != 0) {
12195f15d151b5101fadfe6cba1e8f4aa6367e8c603eJoe Onorato        fprintf(stderr, "ReadNextHeader (for app header) failed with %s\n", strerror(err));
12205f15d151b5101fadfe6cba1e8f4aa6367e8c603eJoe Onorato        goto finished;
12212e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    }
12225f15d151b5101fadfe6cba1e8f4aa6367e8c603eJoe Onorato    if (type != BACKUP_HEADER_ENTITY_V1) {
12232e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato        err = EINVAL;
12245f15d151b5101fadfe6cba1e8f4aa6367e8c603eJoe Onorato        fprintf(stderr, "type=0x%08x expected 0x%08x\n", type, BACKUP_HEADER_ENTITY_V1);
12252e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    }
12262e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato
12272e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    err = reader.ReadEntityHeader(&string, &actualSize);
12282e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    if (err != 0) {
12292e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato        fprintf(stderr, "ReadEntityHeader failed with %s\n", strerror(err));
12305f15d151b5101fadfe6cba1e8f4aa6367e8c603eJoe Onorato        goto finished;
12312e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    }
12322e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    if (string != str) {
12332e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato        fprintf(stderr, "ReadEntityHeader expected key '%s' got '%s'\n", str, string.string());
12342e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato        err = EINVAL;
12355f15d151b5101fadfe6cba1e8f4aa6367e8c603eJoe Onorato        goto finished;
12362e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    }
1237f5df700e6ce056ebfa322314d970e52d6facc35aAshok Bhat    if (actualSize != bufSize) {
1238f5df700e6ce056ebfa322314d970e52d6facc35aAshok Bhat        fprintf(stderr, "ReadEntityHeader expected dataSize %zu got %zu\n",
1239f5df700e6ce056ebfa322314d970e52d6facc35aAshok Bhat                bufSize, actualSize);
12402e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato        err = EINVAL;
12415f15d151b5101fadfe6cba1e8f4aa6367e8c603eJoe Onorato        goto finished;
12422e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    }
12432e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato
124411b157790234d3d2f116ce4c7ed1d3d00fb78bc3Christopher Tate    nRead = reader.ReadEntityData(buf, bufSize);
124511b157790234d3d2f116ce4c7ed1d3d00fb78bc3Christopher Tate    if (nRead < 0) {
124611b157790234d3d2f116ce4c7ed1d3d00fb78bc3Christopher Tate        err = reader.Status();
12472e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato        fprintf(stderr, "ReadEntityData failed with %s\n", strerror(err));
12485f15d151b5101fadfe6cba1e8f4aa6367e8c603eJoe Onorato        goto finished;
12492e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    }
12502e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato
12512e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    if (0 != memcmp(buf, str, bufSize)) {
12522e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato        fprintf(stderr, "ReadEntityData expected '%s' but got something starting with "
12535f15d151b5101fadfe6cba1e8f4aa6367e8c603eJoe Onorato                "%02x %02x %02x %02x  '%c%c%c%c'\n", str, buf[0], buf[1], buf[2], buf[3],
12545f15d151b5101fadfe6cba1e8f4aa6367e8c603eJoe Onorato                buf[0], buf[1], buf[2], buf[3]);
12552e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato        err = EINVAL;
12565f15d151b5101fadfe6cba1e8f4aa6367e8c603eJoe Onorato        goto finished;
12572e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    }
12582e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato
12592e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    // The next read will confirm whether it got the right amount of data.
12602e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato
12615f15d151b5101fadfe6cba1e8f4aa6367e8c603eJoe Onoratofinished:
12622e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    if (err != NO_ERROR) {
12632e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato        fprintf(stderr, "test_read_header_and_entity failed with %s\n", strerror(err));
12642e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    }
126563bcb79dd437e70593b63cc5a87baab3251c2183Christopher Tate    free(buf);
12662e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    return err;
12672e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato}
12682e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato
12692e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onoratoint
12702e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onoratobackup_helper_test_data_reader()
12712e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato{
12722e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    int err;
12732e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    int fd;
12742e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    const char* filename = SCRATCH_DIR "data_reader.data";
12752e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato
12762e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    system("rm -r " SCRATCH_DIR);
12772e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    mkdir(SCRATCH_DIR, 0777);
12782e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    mkdir(SCRATCH_DIR "data", 0777);
1279f4c46b94b867f6a01bf7d0be18f667819338072fNicolas Catania
12802e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    fd = creat(filename, 0666);
12812e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    if (fd == -1) {
12822e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato        fprintf(stderr, "error creating: %s\n", strerror(errno));
12832e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato        return errno;
12842e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    }
12852e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato
12862e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    err = write(fd, DATA_GOLDEN_FILE, DATA_GOLDEN_FILE_SIZE);
12872e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    if (err != DATA_GOLDEN_FILE_SIZE) {
12882e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato        fprintf(stderr, "Error \"%s\" writing golden file %s\n", strerror(errno), filename);
12892e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato        return errno;
12902e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    }
12912e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato
12922e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    close(fd);
12932e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato
12942e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    fd = open(filename, O_RDONLY);
12952e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    if (fd == -1) {
12962e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato        fprintf(stderr, "Error \"%s\" opening golden file %s for read\n", strerror(errno),
12972e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato                filename);
12982e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato        return errno;
12992e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    }
13002e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato
13012e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    {
13022e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato        BackupDataReader reader(fd);
13032e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato
13042e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato        err = 0;
13052e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato
13062e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato        if (err == NO_ERROR) {
13072e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato            err = test_read_header_and_entity(reader, "no_padding_");
13082e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato        }
13092e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato
13102e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato        if (err == NO_ERROR) {
13112e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato            err = test_read_header_and_entity(reader, "padded_to__3");
13122e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato        }
13132e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato
13142e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato        if (err == NO_ERROR) {
13152e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato            err = test_read_header_and_entity(reader, "padded_to_2__");
13162e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato        }
13172e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato
13182e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato        if (err == NO_ERROR) {
13192e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato            err = test_read_header_and_entity(reader, "padded_to1");
13202e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato        }
13212e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    }
13222e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato
13232e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    close(fd);
13242e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato
13252e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    return err;
13262e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato}
13272e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato
13283ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onoratostatic int
13293ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onoratoget_mod_time(const char* filename, struct timeval times[2])
13303ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato{
13313ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    int err;
13323ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    struct stat64 st;
13333ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    err = stat64(filename, &st);
13343ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    if (err != 0) {
13353ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        fprintf(stderr, "stat '%s' failed: %s\n", filename, strerror(errno));
13363ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        return errno;
13373ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    }
13384da9dc5a62c65b123087a08e124c446ea3a476d1Elliott Hughes
13394da9dc5a62c65b123087a08e124c446ea3a476d1Elliott Hughes    times[0].tv_sec = st.st_atim.tv_sec;
1340f4c46b94b867f6a01bf7d0be18f667819338072fNicolas Catania    times[0].tv_usec = st.st_atim.tv_nsec / 1000;
13414da9dc5a62c65b123087a08e124c446ea3a476d1Elliott Hughes
13424da9dc5a62c65b123087a08e124c446ea3a476d1Elliott Hughes    times[1].tv_sec = st.st_mtim.tv_sec;
1343f4c46b94b867f6a01bf7d0be18f667819338072fNicolas Catania    times[1].tv_usec = st.st_mtim.tv_nsec / 1000;
1344f4c46b94b867f6a01bf7d0be18f667819338072fNicolas Catania
13453ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    return 0;
13463ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato}
13473ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
13483ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onoratoint
13493ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onoratobackup_helper_test_files()
13503ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato{
13513ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    int err;
13523ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    int oldSnapshotFD;
13534535e40544aeb957d44fad75fbe5676effe03689Joe Onorato    int dataStreamFD;
13544535e40544aeb957d44fad75fbe5676effe03689Joe Onorato    int newSnapshotFD;
13553ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
13563ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    system("rm -r " SCRATCH_DIR);
13573ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    mkdir(SCRATCH_DIR, 0777);
13583ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    mkdir(SCRATCH_DIR "data", 0777);
13593ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
13603ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    write_text_file(SCRATCH_DIR "data/b", "b\nbb\n");
13613ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    write_text_file(SCRATCH_DIR "data/c", "c\ncc\n");
13623ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    write_text_file(SCRATCH_DIR "data/d", "d\ndd\n");
13633ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    write_text_file(SCRATCH_DIR "data/e", "e\nee\n");
13643ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    write_text_file(SCRATCH_DIR "data/f", "f\nff\n");
13653ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    write_text_file(SCRATCH_DIR "data/h", "h\nhh\n");
13663ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
13673ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    char const* files_before[] = {
136823ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato        SCRATCH_DIR "data/b",
136923ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato        SCRATCH_DIR "data/c",
137023ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato        SCRATCH_DIR "data/d",
137123ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato        SCRATCH_DIR "data/e",
137223ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato        SCRATCH_DIR "data/f"
137323ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato    };
137423ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato
137523ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato    char const* keys_before[] = {
13763ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        "data/b",
13773ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        "data/c",
13783ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        "data/d",
13793ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        "data/e",
13803ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        "data/f"
13813ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    };
13823ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
13834535e40544aeb957d44fad75fbe5676effe03689Joe Onorato    dataStreamFD = creat(SCRATCH_DIR "1.data", 0666);
13844535e40544aeb957d44fad75fbe5676effe03689Joe Onorato    if (dataStreamFD == -1) {
13854535e40544aeb957d44fad75fbe5676effe03689Joe Onorato        fprintf(stderr, "error creating: %s\n", strerror(errno));
13864535e40544aeb957d44fad75fbe5676effe03689Joe Onorato        return errno;
13874535e40544aeb957d44fad75fbe5676effe03689Joe Onorato    }
13884535e40544aeb957d44fad75fbe5676effe03689Joe Onorato
13893ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    newSnapshotFD = creat(SCRATCH_DIR "before.snap", 0666);
13903ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    if (newSnapshotFD == -1) {
13913ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        fprintf(stderr, "error creating: %s\n", strerror(errno));
13923ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        return errno;
13933ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    }
1394d2110dbce071a236b6176de344ca797b737542ebJoe Onorato
1395d2110dbce071a236b6176de344ca797b737542ebJoe Onorato    {
1396d2110dbce071a236b6176de344ca797b737542ebJoe Onorato        BackupDataWriter dataStream(dataStreamFD);
1397f4c46b94b867f6a01bf7d0be18f667819338072fNicolas Catania
139823ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato        err = back_up_files(-1, &dataStream, newSnapshotFD, files_before, keys_before, 5);
1399d2110dbce071a236b6176de344ca797b737542ebJoe Onorato        if (err != 0) {
1400d2110dbce071a236b6176de344ca797b737542ebJoe Onorato            return err;
1401d2110dbce071a236b6176de344ca797b737542ebJoe Onorato        }
14023ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    }
14033ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
14044535e40544aeb957d44fad75fbe5676effe03689Joe Onorato    close(dataStreamFD);
14053ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    close(newSnapshotFD);
14063ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
14073ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    sleep(3);
14083ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
14093ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    struct timeval d_times[2];
14103ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    struct timeval e_times[2];
14113ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
14123ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    err = get_mod_time(SCRATCH_DIR "data/d", d_times);
14133ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    err |= get_mod_time(SCRATCH_DIR "data/e", e_times);
14143ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    if (err != 0) {
14153ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        return err;
14163ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    }
14173ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
14183ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    write_text_file(SCRATCH_DIR "data/a", "a\naa\n");
14193ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    unlink(SCRATCH_DIR "data/c");
14203ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    write_text_file(SCRATCH_DIR "data/c", "c\ncc\n");
14213ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    write_text_file(SCRATCH_DIR "data/d", "dd\ndd\n");
14223ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    utimes(SCRATCH_DIR "data/d", d_times);
14233ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    write_text_file(SCRATCH_DIR "data/e", "z\nzz\n");
14243ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    utimes(SCRATCH_DIR "data/e", e_times);
14253ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    write_text_file(SCRATCH_DIR "data/g", "g\ngg\n");
14263ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    unlink(SCRATCH_DIR "data/f");
1427f4c46b94b867f6a01bf7d0be18f667819338072fNicolas Catania
14283ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    char const* files_after[] = {
142923ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato        SCRATCH_DIR "data/a", // added
143023ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato        SCRATCH_DIR "data/b", // same
143123ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato        SCRATCH_DIR "data/c", // different mod time
143223ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato        SCRATCH_DIR "data/d", // different size (same mod time)
143323ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato        SCRATCH_DIR "data/e", // different contents (same mod time, same size)
143423ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato        SCRATCH_DIR "data/g"  // added
143523ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato    };
143623ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato
143723ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato    char const* keys_after[] = {
14383ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        "data/a", // added
14393ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        "data/b", // same
14403ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        "data/c", // different mod time
14413ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        "data/d", // different size (same mod time)
14423ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        "data/e", // different contents (same mod time, same size)
14433ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        "data/g"  // added
14443ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    };
14453ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
14463ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    oldSnapshotFD = open(SCRATCH_DIR "before.snap", O_RDONLY);
14473ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    if (oldSnapshotFD == -1) {
14483ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        fprintf(stderr, "error opening: %s\n", strerror(errno));
14493ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        return errno;
14503ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    }
14513ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
14524535e40544aeb957d44fad75fbe5676effe03689Joe Onorato    dataStreamFD = creat(SCRATCH_DIR "2.data", 0666);
14534535e40544aeb957d44fad75fbe5676effe03689Joe Onorato    if (dataStreamFD == -1) {
14544535e40544aeb957d44fad75fbe5676effe03689Joe Onorato        fprintf(stderr, "error creating: %s\n", strerror(errno));
14554535e40544aeb957d44fad75fbe5676effe03689Joe Onorato        return errno;
14564535e40544aeb957d44fad75fbe5676effe03689Joe Onorato    }
14574535e40544aeb957d44fad75fbe5676effe03689Joe Onorato
14583ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    newSnapshotFD = creat(SCRATCH_DIR "after.snap", 0666);
14593ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    if (newSnapshotFD == -1) {
14603ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        fprintf(stderr, "error creating: %s\n", strerror(errno));
14613ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        return errno;
14623ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    }
14633ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
1464d2110dbce071a236b6176de344ca797b737542ebJoe Onorato    {
1465d2110dbce071a236b6176de344ca797b737542ebJoe Onorato        BackupDataWriter dataStream(dataStreamFD);
1466f4c46b94b867f6a01bf7d0be18f667819338072fNicolas Catania
146723ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato        err = back_up_files(oldSnapshotFD, &dataStream, newSnapshotFD, files_after, keys_after, 6);
1468d2110dbce071a236b6176de344ca797b737542ebJoe Onorato        if (err != 0) {
1469d2110dbce071a236b6176de344ca797b737542ebJoe Onorato            return err;
1470d2110dbce071a236b6176de344ca797b737542ebJoe Onorato        }
1471d2110dbce071a236b6176de344ca797b737542ebJoe Onorato}
14723ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
14733ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    close(oldSnapshotFD);
14744535e40544aeb957d44fad75fbe5676effe03689Joe Onorato    close(dataStreamFD);
14753ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    close(newSnapshotFD);
1476f4c46b94b867f6a01bf7d0be18f667819338072fNicolas Catania
14773ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    return 0;
14783ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato}
14793ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
148023ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onoratoint
148123ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onoratobackup_helper_test_null_base()
148223ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato{
148323ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato    int err;
148423ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato    int dataStreamFD;
148523ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato    int newSnapshotFD;
148623ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato
148723ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato    system("rm -r " SCRATCH_DIR);
148823ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato    mkdir(SCRATCH_DIR, 0777);
148923ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato    mkdir(SCRATCH_DIR "data", 0777);
149023ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato
149123ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato    write_text_file(SCRATCH_DIR "data/a", "a\naa\n");
149223ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato
149323ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato    char const* files[] = {
149423ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato        SCRATCH_DIR "data/a",
149523ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato    };
149623ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato
149723ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato    char const* keys[] = {
149823ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato        "a",
149923ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato    };
150023ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato
150123ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato    dataStreamFD = creat(SCRATCH_DIR "null_base.data", 0666);
150223ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato    if (dataStreamFD == -1) {
150323ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato        fprintf(stderr, "error creating: %s\n", strerror(errno));
150423ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato        return errno;
150523ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato    }
150623ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato
150723ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato    newSnapshotFD = creat(SCRATCH_DIR "null_base.snap", 0666);
150823ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato    if (newSnapshotFD == -1) {
150923ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato        fprintf(stderr, "error creating: %s\n", strerror(errno));
151023ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato        return errno;
151123ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato    }
151223ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato
151323ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato    {
151423ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato        BackupDataWriter dataStream(dataStreamFD);
151523ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato
151623ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato        err = back_up_files(-1, &dataStream, newSnapshotFD, files, keys, 1);
151723ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato        if (err != 0) {
151823ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato            return err;
151923ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato        }
152023ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato    }
152123ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato
152223ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato    close(dataStreamFD);
152323ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato    close(newSnapshotFD);
152423ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato
152523ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato    return 0;
152623ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato}
152723ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato
1528ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onoratoint
1529ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onoratobackup_helper_test_missing_file()
1530ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato{
1531ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato    int err;
1532ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato    int dataStreamFD;
1533ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato    int newSnapshotFD;
1534ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato
1535ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato    system("rm -r " SCRATCH_DIR);
1536ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato    mkdir(SCRATCH_DIR, 0777);
1537ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato    mkdir(SCRATCH_DIR "data", 0777);
1538ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato
1539ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato    write_text_file(SCRATCH_DIR "data/b", "b\nbb\n");
1540ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato
1541ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato    char const* files[] = {
1542ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato        SCRATCH_DIR "data/a",
1543ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato        SCRATCH_DIR "data/b",
1544ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato        SCRATCH_DIR "data/c",
1545ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato    };
1546ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato
1547ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato    char const* keys[] = {
1548ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato        "a",
1549ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato        "b",
1550ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato        "c",
1551ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato    };
1552ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato
1553ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato    dataStreamFD = creat(SCRATCH_DIR "null_base.data", 0666);
1554ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato    if (dataStreamFD == -1) {
1555ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato        fprintf(stderr, "error creating: %s\n", strerror(errno));
1556ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato        return errno;
1557ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato    }
1558ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato
1559ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato    newSnapshotFD = creat(SCRATCH_DIR "null_base.snap", 0666);
1560ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato    if (newSnapshotFD == -1) {
1561ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato        fprintf(stderr, "error creating: %s\n", strerror(errno));
1562ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato        return errno;
1563ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato    }
1564ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato
1565ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato    {
1566ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato        BackupDataWriter dataStream(dataStreamFD);
1567ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato
1568ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato        err = back_up_files(-1, &dataStream, newSnapshotFD, files, keys, 1);
1569ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato        if (err != 0) {
1570ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato            return err;
1571ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato        }
1572ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato    }
1573ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato
1574ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato    close(dataStreamFD);
1575ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato    close(newSnapshotFD);
1576ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato
1577ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato    return 0;
1578ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato}
1579ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato
158023ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato
15813ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato#endif // TEST_BACKUP_HELPERS
15824535e40544aeb957d44fad75fbe5676effe03689Joe Onorato
15834535e40544aeb957d44fad75fbe5676effe03689Joe Onorato}
1584