BackupHelpers.cpp revision d2d9ceb7305d593c1b767bbb05de0082a9af4109
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
198ae2335a3c93d0c00e998fdec18f64dfe43b94cbMathias Agopian#include <utils/BackupHelpers.h>
203ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
213ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato#include <utils/KeyedVector.h>
223ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato#include <utils/ByteOrder.h>
233ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato#include <utils/String8.h>
243ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
253ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato#include <errno.h>
263ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato#include <sys/types.h>
273ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato#include <sys/uio.h>
283ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato#include <sys/stat.h>
29f4c46b94b867f6a01bf7d0be18f667819338072fNicolas Catania#include <sys/time.h>  // for utimes
303ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato#include <stdio.h>
313ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato#include <stdlib.h>
323ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato#include <unistd.h>
33c825d3ebd6ca66e65e63fdc76f032e08aa2a8e22Joe Onorato#include <utime.h>
343ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato#include <fcntl.h>
353ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato#include <zlib.h>
363ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
373ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato#include <cutils/log.h>
383ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
394535e40544aeb957d44fad75fbe5676effe03689Joe Onoratonamespace android {
403ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
413ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato#define MAGIC0 0x70616e53 // Snap
423ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato#define MAGIC1 0x656c6946 // File
433ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
4423ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato#if 1 // TEST_BACKUP_HELPERS
4523ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato#define LOGP(f, x...) printf(f "\n", x)
464535e40544aeb957d44fad75fbe5676effe03689Joe Onorato#else
47290bb011c5c1a9ba1f2116810b06cf52a9c36b3eJoe Onorato#define LOGP(x...) LOGD(x)
484535e40544aeb957d44fad75fbe5676effe03689Joe Onorato#endif
49290bb011c5c1a9ba1f2116810b06cf52a9c36b3eJoe Onorato
503ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onoratoconst static int ROUND_UP[4] = { 0, 3, 2, 1 };
513ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
523ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onoratostatic inline int
533ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onoratoround_up(int n)
543ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato{
553ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    return n + ROUND_UP[n % 4];
563ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato}
573ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
583ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onoratostatic int
593ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onoratoread_snapshot_file(int fd, KeyedVector<String8,FileState>* snapshot)
603ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato{
613ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    int bytesRead = 0;
623ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    int amt;
633ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    SnapshotHeader header;
643ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
653ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    amt = read(fd, &header, sizeof(header));
663ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    if (amt != sizeof(header)) {
673ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        return errno;
683ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    }
693ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    bytesRead += amt;
703ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
713ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    if (header.magic0 != MAGIC0 || header.magic1 != MAGIC1) {
723ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        LOGW("read_snapshot_file header.magic0=0x%08x magic1=0x%08x", header.magic0, header.magic1);
733ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        return 1;
743ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    }
753ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
763ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    for (int i=0; i<header.fileCount; i++) {
773ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        FileState file;
783ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        char filenameBuf[128];
793ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
8023ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato        amt = read(fd, &file, sizeof(FileState));
8123ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato        if (amt != sizeof(FileState)) {
823ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato            LOGW("read_snapshot_file FileState truncated/error with read at %d bytes\n", bytesRead);
833ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato            return 1;
843ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        }
853ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        bytesRead += amt;
863ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
873ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        // filename is not NULL terminated, but it is padded
883ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        int nameBufSize = round_up(file.nameLen);
893ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        char* filename = nameBufSize <= (int)sizeof(filenameBuf)
903ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato                ? filenameBuf
913ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato                : (char*)malloc(nameBufSize);
923ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        amt = read(fd, filename, nameBufSize);
933ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        if (amt == nameBufSize) {
943ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato            snapshot->add(String8(filename, file.nameLen), file);
953ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        }
963ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        bytesRead += amt;
973ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        if (filename != filenameBuf) {
983ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato            free(filename);
993ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        }
1003ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        if (amt != nameBufSize) {
1013ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato            LOGW("read_snapshot_file filename truncated/error with read at %d bytes\n", bytesRead);
1023ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato            return 1;
1033ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        }
1043ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    }
1053ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
1063ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    if (header.totalSize != bytesRead) {
1073ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        LOGW("read_snapshot_file length mismatch: header.totalSize=%d bytesRead=%d\n",
1083ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato                header.totalSize, bytesRead);
1093ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        return 1;
1103ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    }
1113ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
1123ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    return 0;
1133ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato}
1143ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
1153ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onoratostatic int
11623ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onoratowrite_snapshot_file(int fd, const KeyedVector<String8,FileRec>& snapshot)
1173ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato{
118ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato    int fileCount = 0;
1193ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    int bytesWritten = sizeof(SnapshotHeader);
1203ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    // preflight size
1213ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    const int N = snapshot.size();
1223ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    for (int i=0; i<N; i++) {
123ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato        const FileRec& g = snapshot.valueAt(i);
124ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato        if (!g.deleted) {
125ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato            const String8& name = snapshot.keyAt(i);
126ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato            bytesWritten += sizeof(FileState) + round_up(name.length());
127ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato            fileCount++;
128ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato        }
1293ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    }
1303ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
1314535e40544aeb957d44fad75fbe5676effe03689Joe Onorato    LOGP("write_snapshot_file fd=%d\n", fd);
1324535e40544aeb957d44fad75fbe5676effe03689Joe Onorato
1333ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    int amt;
134ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato    SnapshotHeader header = { MAGIC0, fileCount, MAGIC1, bytesWritten };
1353ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
1363ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    amt = write(fd, &header, sizeof(header));
1373ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    if (amt != sizeof(header)) {
1383ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        LOGW("write_snapshot_file error writing header %s", strerror(errno));
1393ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        return errno;
1403ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    }
1413ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
142ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato    for (int i=0; i<N; i++) {
14323ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato        FileRec r = snapshot.valueAt(i);
144ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato        if (!r.deleted) {
145ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato            const String8& name = snapshot.keyAt(i);
146ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato            int nameLen = r.s.nameLen = name.length();
1473ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
148ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato            amt = write(fd, &r.s, sizeof(FileState));
149ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato            if (amt != sizeof(FileState)) {
150ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato                LOGW("write_snapshot_file error writing header %s", strerror(errno));
151ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato                return 1;
152ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato            }
1533ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
154ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato            // filename is not NULL terminated, but it is padded
155ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato            amt = write(fd, name.string(), nameLen);
156ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato            if (amt != nameLen) {
157ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato                LOGW("write_snapshot_file error writing filename %s", strerror(errno));
1583ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato                return 1;
1593ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato            }
160ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato            int paddingLen = ROUND_UP[nameLen % 4];
161ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato            if (paddingLen != 0) {
162ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato                int padding = 0xabababab;
163ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato                amt = write(fd, &padding, paddingLen);
164ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato                if (amt != paddingLen) {
165ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato                    LOGW("write_snapshot_file error writing %d bytes of filename padding %s",
166ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato                            paddingLen, strerror(errno));
167ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato                    return 1;
168ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato                }
169ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato            }
1703ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        }
1713ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    }
1723ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
1733ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    return 0;
1743ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato}
1753ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
1763ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onoratostatic int
177d2110dbce071a236b6176de344ca797b737542ebJoe Onoratowrite_delete_file(BackupDataWriter* dataStream, const String8& key)
1783ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato{
179290bb011c5c1a9ba1f2116810b06cf52a9c36b3eJoe Onorato    LOGP("write_delete_file %s\n", key.string());
180d2110dbce071a236b6176de344ca797b737542ebJoe Onorato    return dataStream->WriteEntityHeader(key, -1);
1813ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato}
1823ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
1833ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onoratostatic int
184d2110dbce071a236b6176de344ca797b737542ebJoe Onoratowrite_update_file(BackupDataWriter* dataStream, int fd, const String8& key,
18523ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato        char const* realFilename)
1863ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato{
18723ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato    LOGP("write_update_file %s (%s)\n", realFilename, key.string());
1883ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
1893ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    const int bufsize = 4*1024;
190d2110dbce071a236b6176de344ca797b737542ebJoe Onorato    int err;
1913ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    int amt;
192d2110dbce071a236b6176de344ca797b737542ebJoe Onorato    int fileSize;
193d2110dbce071a236b6176de344ca797b737542ebJoe Onorato    int bytesLeft;
194d2110dbce071a236b6176de344ca797b737542ebJoe Onorato
195d2110dbce071a236b6176de344ca797b737542ebJoe Onorato    char* buf = (char*)malloc(bufsize);
196d2110dbce071a236b6176de344ca797b737542ebJoe Onorato    int crc = crc32(0L, Z_NULL, 0);
197d2110dbce071a236b6176de344ca797b737542ebJoe Onorato
198d2110dbce071a236b6176de344ca797b737542ebJoe Onorato
199d2110dbce071a236b6176de344ca797b737542ebJoe Onorato    bytesLeft = fileSize = lseek(fd, 0, SEEK_END);
200d2110dbce071a236b6176de344ca797b737542ebJoe Onorato    lseek(fd, 0, SEEK_SET);
201d2110dbce071a236b6176de344ca797b737542ebJoe Onorato
202d2110dbce071a236b6176de344ca797b737542ebJoe Onorato    err = dataStream->WriteEntityHeader(key, bytesLeft);
203d2110dbce071a236b6176de344ca797b737542ebJoe Onorato    if (err != 0) {
204d2110dbce071a236b6176de344ca797b737542ebJoe Onorato        return err;
205d2110dbce071a236b6176de344ca797b737542ebJoe Onorato    }
206d2110dbce071a236b6176de344ca797b737542ebJoe Onorato
207d2110dbce071a236b6176de344ca797b737542ebJoe Onorato    while ((amt = read(fd, buf, bufsize)) != 0 && bytesLeft > 0) {
208d2110dbce071a236b6176de344ca797b737542ebJoe Onorato        bytesLeft -= amt;
209d2110dbce071a236b6176de344ca797b737542ebJoe Onorato        if (bytesLeft < 0) {
210d2110dbce071a236b6176de344ca797b737542ebJoe Onorato            amt += bytesLeft; // Plus a negative is minus.  Don't write more than we promised.
211d2110dbce071a236b6176de344ca797b737542ebJoe Onorato        }
212d2110dbce071a236b6176de344ca797b737542ebJoe Onorato        err = dataStream->WriteEntityData(buf, amt);
213d2110dbce071a236b6176de344ca797b737542ebJoe Onorato        if (err != 0) {
214d2110dbce071a236b6176de344ca797b737542ebJoe Onorato            return err;
215d2110dbce071a236b6176de344ca797b737542ebJoe Onorato        }
216d2110dbce071a236b6176de344ca797b737542ebJoe Onorato    }
217d2110dbce071a236b6176de344ca797b737542ebJoe Onorato    if (bytesLeft != 0) {
218d2110dbce071a236b6176de344ca797b737542ebJoe Onorato        if (bytesLeft > 0) {
219d2110dbce071a236b6176de344ca797b737542ebJoe Onorato            // Pad out the space we promised in the buffer.  We can't corrupt the buffer,
220d2110dbce071a236b6176de344ca797b737542ebJoe Onorato            // even though the data we're sending is probably bad.
221d2110dbce071a236b6176de344ca797b737542ebJoe Onorato            memset(buf, 0, bufsize);
222d2110dbce071a236b6176de344ca797b737542ebJoe Onorato            while (bytesLeft > 0) {
223d2110dbce071a236b6176de344ca797b737542ebJoe Onorato                amt = bytesLeft < bufsize ? bytesLeft : bufsize;
224d2110dbce071a236b6176de344ca797b737542ebJoe Onorato                bytesLeft -= amt;
225d2110dbce071a236b6176de344ca797b737542ebJoe Onorato                err = dataStream->WriteEntityData(buf, amt);
226d2110dbce071a236b6176de344ca797b737542ebJoe Onorato                if (err != 0) {
227d2110dbce071a236b6176de344ca797b737542ebJoe Onorato                    return err;
228d2110dbce071a236b6176de344ca797b737542ebJoe Onorato                }
229d2110dbce071a236b6176de344ca797b737542ebJoe Onorato            }
230d2110dbce071a236b6176de344ca797b737542ebJoe Onorato        }
231d2110dbce071a236b6176de344ca797b737542ebJoe Onorato        LOGE("write_update_file size mismatch for %s. expected=%d actual=%d."
23223ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato                " You aren't doing proper locking!", realFilename, fileSize, fileSize-bytesLeft);
233d2110dbce071a236b6176de344ca797b737542ebJoe Onorato    }
234d2110dbce071a236b6176de344ca797b737542ebJoe Onorato
235d2110dbce071a236b6176de344ca797b737542ebJoe Onorato    free(buf);
2363ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
237d2110dbce071a236b6176de344ca797b737542ebJoe Onorato    return NO_ERROR;
238d2110dbce071a236b6176de344ca797b737542ebJoe Onorato}
239d2110dbce071a236b6176de344ca797b737542ebJoe Onorato
240d2110dbce071a236b6176de344ca797b737542ebJoe Onoratostatic int
24123ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onoratowrite_update_file(BackupDataWriter* dataStream, const String8& key, char const* realFilename)
242d2110dbce071a236b6176de344ca797b737542ebJoe Onorato{
243d2110dbce071a236b6176de344ca797b737542ebJoe Onorato    int err;
24423ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato    int fd = open(realFilename, O_RDONLY);
2453ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    if (fd == -1) {
246d2110dbce071a236b6176de344ca797b737542ebJoe Onorato        return errno;
2473ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    }
248d2110dbce071a236b6176de344ca797b737542ebJoe Onorato    err = write_update_file(dataStream, fd, key, realFilename);
249d2110dbce071a236b6176de344ca797b737542ebJoe Onorato    close(fd);
250d2110dbce071a236b6176de344ca797b737542ebJoe Onorato    return err;
251d2110dbce071a236b6176de344ca797b737542ebJoe Onorato}
252d2110dbce071a236b6176de344ca797b737542ebJoe Onorato
253d2110dbce071a236b6176de344ca797b737542ebJoe Onoratostatic int
254d2110dbce071a236b6176de344ca797b737542ebJoe Onoratocompute_crc32(int fd)
255d2110dbce071a236b6176de344ca797b737542ebJoe Onorato{
256d2110dbce071a236b6176de344ca797b737542ebJoe Onorato    const int bufsize = 4*1024;
257d2110dbce071a236b6176de344ca797b737542ebJoe Onorato    int amt;
2583ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
2593ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    char* buf = (char*)malloc(bufsize);
2603ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    int crc = crc32(0L, Z_NULL, 0);
2613ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
262d2110dbce071a236b6176de344ca797b737542ebJoe Onorato    lseek(fd, 0, SEEK_SET);
263d2110dbce071a236b6176de344ca797b737542ebJoe Onorato
2643ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    while ((amt = read(fd, buf, bufsize)) != 0) {
2653ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        crc = crc32(crc, (Bytef*)buf, amt);
2663ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    }
2673ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
2683ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    free(buf);
2693ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
2703ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    return crc;
2713ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato}
2723ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
2733ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onoratoint
274d2110dbce071a236b6176de344ca797b737542ebJoe Onoratoback_up_files(int oldSnapshotFD, BackupDataWriter* dataStream, int newSnapshotFD,
27523ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato        char const* const* files, char const* const* keys, int fileCount)
2763ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato{
2773ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    int err;
2783ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    KeyedVector<String8,FileState> oldSnapshot;
27923ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato    KeyedVector<String8,FileRec> newSnapshot;
2803ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
2813ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    if (oldSnapshotFD != -1) {
2823ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        err = read_snapshot_file(oldSnapshotFD, &oldSnapshot);
2833ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        if (err != 0) {
2843ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato            // On an error, treat this as a full backup.
2853ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato            oldSnapshot.clear();
2863ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        }
2873ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    }
2883ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
2893ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    for (int i=0; i<fileCount; i++) {
29023ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato        String8 key(keys[i]);
29123ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato        FileRec r;
292d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato        char const* file = files[i];
293d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato        r.file = file;
2943ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        struct stat st;
2953ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
29623ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato        err = stat(file, &st);
2973ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        if (err != 0) {
29823ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato            LOGW("Error stating file %s", file);
299ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato            r.deleted = true;
300ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato        } else {
301ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato            r.deleted = false;
302ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato            r.s.modTime_sec = st.st_mtime;
303ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato            r.s.modTime_nsec = 0; // workaround sim breakage
304ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato            //r.s.modTime_nsec = st.st_mtime_nsec;
305ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato            r.s.size = st.st_size;
306ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato            // we compute the crc32 later down below, when we already have the file open.
307ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato
308ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato            if (newSnapshot.indexOfKey(key) >= 0) {
309ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato                LOGP("back_up_files key already in use '%s'", key.string());
310ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato                return -1;
311ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato            }
31223ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato        }
31323ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato        newSnapshot.add(key, r);
3143ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    }
3153ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
3163ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    int n = 0;
3173ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    int N = oldSnapshot.size();
3183ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    int m = 0;
3193ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
3203ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    while (n<N && m<fileCount) {
3213ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        const String8& p = oldSnapshot.keyAt(n);
3223ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        const String8& q = newSnapshot.keyAt(m);
323ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato        FileRec& g = newSnapshot.editValueAt(m);
3243ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        int cmp = p.compare(q);
325ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato        if (g.deleted || cmp < 0) {
3263ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato            // file removed
32723ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato            LOGP("file removed: %s", p.string());
328ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato            g.deleted = true; // They didn't mention the file, but we noticed that it's gone.
329d2110dbce071a236b6176de344ca797b737542ebJoe Onorato            dataStream->WriteEntityHeader(p, -1);
3303ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato            n++;
3313ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        }
332ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato        else if (cmp > 0) {
333ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato            // file added
334d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato            LOGP("file added: %s", g.file.string());
335d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato            write_update_file(dataStream, q, g.file.string());
336ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato            m++;
337ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato        }
3383ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        else {
3393ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato            // both files exist, check them
3403ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato            const FileState& f = oldSnapshot.valueAt(n);
341d2110dbce071a236b6176de344ca797b737542ebJoe Onorato
342d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato            int fd = open(g.file.string(), O_RDONLY);
3430032ce80ac127e6bfb25d727162eee4af208dc77Christopher Tate            if (fd < 0) {
344d2110dbce071a236b6176de344ca797b737542ebJoe Onorato                // We can't open the file.  Don't report it as a delete either.  Let the
345d2110dbce071a236b6176de344ca797b737542ebJoe Onorato                // server keep the old version.  Maybe they'll be able to deal with it
346d2110dbce071a236b6176de344ca797b737542ebJoe Onorato                // on restore.
347d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato                LOGP("Unable to open file %s - skipping", g.file.string());
348d2110dbce071a236b6176de344ca797b737542ebJoe Onorato            } else {
34923ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato                g.s.crc32 = compute_crc32(fd);
350d2110dbce071a236b6176de344ca797b737542ebJoe Onorato
35123ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato                LOGP("%s", q.string());
35223ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato                LOGP("  new: modTime=%d,%d size=%-3d crc32=0x%08x",
353d2110dbce071a236b6176de344ca797b737542ebJoe Onorato                        f.modTime_sec, f.modTime_nsec, f.size, f.crc32);
35423ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato                LOGP("  old: modTime=%d,%d size=%-3d crc32=0x%08x",
35523ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato                        g.s.modTime_sec, g.s.modTime_nsec, g.s.size, g.s.crc32);
35623ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato                if (f.modTime_sec != g.s.modTime_sec || f.modTime_nsec != g.s.modTime_nsec
35723ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato                        || f.size != g.s.size || f.crc32 != g.s.crc32) {
358d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato                    write_update_file(dataStream, fd, p, g.file.string());
359d2110dbce071a236b6176de344ca797b737542ebJoe Onorato                }
360d2110dbce071a236b6176de344ca797b737542ebJoe Onorato
361d2110dbce071a236b6176de344ca797b737542ebJoe Onorato                close(fd);
3623ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato            }
3633ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato            n++;
3643ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato            m++;
3653ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        }
3663ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    }
3673ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
3683ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    // these were deleted
3693ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    while (n<N) {
370d2110dbce071a236b6176de344ca797b737542ebJoe Onorato        dataStream->WriteEntityHeader(oldSnapshot.keyAt(n), -1);
3713ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        n++;
3723ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    }
3733ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
3743ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    // these were added
3753ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    while (m<fileCount) {
3763ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        const String8& q = newSnapshot.keyAt(m);
37723ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato        FileRec& g = newSnapshot.editValueAt(m);
378d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato        write_update_file(dataStream, q, g.file.string());
3793ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        m++;
3803ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    }
3813ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
3823ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    err = write_snapshot_file(newSnapshotFD, newSnapshot);
3833ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
3843ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    return 0;
3853ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato}
3863ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
387d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato#define RESTORE_BUF_SIZE (8*1024)
388d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato
389d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe OnoratoRestoreHelperBase::RestoreHelperBase()
390d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato{
391d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato    m_buf = malloc(RESTORE_BUF_SIZE);
392d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato}
393d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato
394d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe OnoratoRestoreHelperBase::~RestoreHelperBase()
395d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato{
396d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato    free(m_buf);
397d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato}
398d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato
399d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onoratostatus_t
400d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe OnoratoRestoreHelperBase::WriteFile(const String8& filename, BackupDataReader* in)
401d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato{
402d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato    ssize_t err;
403d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato    size_t dataSize;
404d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato    String8 key;
405d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato    int fd;
406d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato    void* buf = m_buf;
407d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato    ssize_t amt;
408d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato    int mode;
409d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato    int crc;
410d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato    struct stat st;
411d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato    FileRec r;
412d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato
413d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato    err = in->ReadEntityHeader(&key, &dataSize);
414d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato    if (err != NO_ERROR) {
415d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato        return err;
416d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato    }
417d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato
418d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato    // TODO: World readable/writable for now.
419d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato    mode = 0666;
420d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato
421d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato    // Write the file and compute the crc
422d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato    crc = crc32(0L, Z_NULL, 0);
423d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato    fd = open(filename.string(), O_CREAT|O_RDWR, mode);
424d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato    if (fd != -1) {
425d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato        return errno;
426d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato    }
427d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato
428d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato    while ((amt = in->ReadEntityData(buf, RESTORE_BUF_SIZE)) > 0) {
429d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato        err = write(fd, buf, amt);
430d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato        if (err != amt) {
431d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato            close(fd);
432d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato            return errno;
433d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato        }
434d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato        crc = crc32(crc, (Bytef*)buf, amt);
435d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato    }
436d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato
437d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato    close(fd);
438d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato
439d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato    // Record for the snapshot
440d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato    err = stat(filename.string(), &st);
441d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato    if (err != 0) {
442d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato        LOGW("Error stating file that we just created %s", filename.string());
443d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato        return errno;
444d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato    }
445d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato
446d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato    r.file = filename;
447d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato    r.deleted = false;
448d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato    r.s.modTime_sec = st.st_mtime;
449d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato    r.s.modTime_nsec = 0; // workaround sim breakage
450d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato    //r.s.modTime_nsec = st.st_mtime_nsec;
451d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato    r.s.size = st.st_size;
452d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato    r.s.crc32 = crc;
453d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato
454d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato    m_files.add(key, r);
455d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato
456d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato    return NO_ERROR;
457d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato}
458d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato
459d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onoratostatus_t
460d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe OnoratoRestoreHelperBase::WriteSnapshot(int fd)
461d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato{
462d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato    return write_snapshot_file(fd, m_files);;
463d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato}
464d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato
4653ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato#if TEST_BACKUP_HELPERS
4663ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
4673ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato#define SCRATCH_DIR "/data/backup_helper_test/"
4683ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
4693ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onoratostatic int
4703ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onoratowrite_text_file(const char* path, const char* data)
4713ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato{
4723ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    int amt;
4733ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    int fd;
4743ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    int len;
4753ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
4763ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    fd = creat(path, 0666);
4773ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    if (fd == -1) {
4783ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        fprintf(stderr, "creat %s failed\n", path);
4793ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        return errno;
4803ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    }
4813ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
4823ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    len = strlen(data);
4833ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    amt = write(fd, data, len);
4843ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    if (amt != len) {
4853ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        fprintf(stderr, "error (%s) writing to file %s\n", strerror(errno), path);
4863ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        return errno;
4873ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    }
4883ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
4893ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    close(fd);
4903ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
4913ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    return 0;
4923ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato}
4933ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
4943ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onoratostatic int
4953ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onoratocompare_file(const char* path, const unsigned char* data, int len)
4963ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato{
4973ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    int fd;
4983ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    int amt;
4993ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
5003ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    fd = open(path, O_RDONLY);
5013ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    if (fd == -1) {
5023ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        fprintf(stderr, "compare_file error (%s) opening %s\n", strerror(errno), path);
5033ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        return errno;
5043ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    }
5053ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
5063ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    unsigned char* contents = (unsigned char*)malloc(len);
5073ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    if (contents == NULL) {
5083ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        fprintf(stderr, "malloc(%d) failed\n", len);
5093ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        return ENOMEM;
5103ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    }
5113ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
5123ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    bool sizesMatch = true;
5133ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    amt = lseek(fd, 0, SEEK_END);
5143ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    if (amt != len) {
5153ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        fprintf(stderr, "compare_file file length should be %d, was %d\n", len, amt);
5163ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        sizesMatch = false;
5173ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    }
5183ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    lseek(fd, 0, SEEK_SET);
5193ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
5203ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    int readLen = amt < len ? amt : len;
5213ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    amt = read(fd, contents, readLen);
5223ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    if (amt != readLen) {
5233ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        fprintf(stderr, "compare_file read expected %d bytes but got %d\n", len, amt);
5243ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    }
5253ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
5263ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    bool contentsMatch = true;
5273ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    for (int i=0; i<readLen; i++) {
5283ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        if (data[i] != contents[i]) {
5293ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato            if (contentsMatch) {
5303ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato                fprintf(stderr, "compare_file contents are different: (index, expected, actual)\n");
5313ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato                contentsMatch = false;
5323ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato            }
5333ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato            fprintf(stderr, "  [%-2d] %02x %02x\n", i, data[i], contents[i]);
5343ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        }
5353ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    }
5363ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
5373ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    return contentsMatch && sizesMatch ? 0 : 1;
5383ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato}
5393ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
5403ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onoratoint
5413ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onoratobackup_helper_test_empty()
5423ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato{
5433ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    int err;
5443ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    int fd;
54523ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato    KeyedVector<String8,FileRec> snapshot;
5463ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    const char* filename = SCRATCH_DIR "backup_helper_test_empty.snap";
5473ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
5483ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    system("rm -r " SCRATCH_DIR);
5493ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    mkdir(SCRATCH_DIR, 0777);
5503ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
5513ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    // write
5523ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    fd = creat(filename, 0666);
5533ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    if (fd == -1) {
5543ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        fprintf(stderr, "error creating %s\n", filename);
5553ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        return 1;
5563ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    }
5573ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
5583ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    err = write_snapshot_file(fd, snapshot);
5593ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
5603ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    close(fd);
5613ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
5623ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    if (err != 0) {
5633ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        fprintf(stderr, "write_snapshot_file reported error %d (%s)\n", err, strerror(err));
5643ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        return err;
5653ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    }
5663ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
5673ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    static const unsigned char correct_data[] = {
5683ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        0x53, 0x6e, 0x61, 0x70,  0x00, 0x00, 0x00, 0x00,
5693ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        0x46, 0x69, 0x6c, 0x65,  0x10, 0x00, 0x00, 0x00
5703ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    };
5713ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
5723ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    err = compare_file(filename, correct_data, sizeof(correct_data));
5733ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    if (err != 0) {
5743ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        return err;
5753ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    }
5763ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
5773ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    // read
5783ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    fd = open(filename, O_RDONLY);
5793ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    if (fd == -1) {
5803ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        fprintf(stderr, "error opening for read %s\n", filename);
5813ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        return 1;
5823ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    }
5833ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
5843ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    KeyedVector<String8,FileState> readSnapshot;
5853ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    err = read_snapshot_file(fd, &readSnapshot);
5863ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    if (err != 0) {
5873ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        fprintf(stderr, "read_snapshot_file failed %d\n", err);
5883ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        return err;
5893ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    }
5903ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
5913ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    if (readSnapshot.size() != 0) {
5923ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        fprintf(stderr, "readSnapshot should be length 0\n");
5933ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        return 1;
5943ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    }
5953ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
5963ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    return 0;
5973ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato}
5983ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
5993ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onoratoint
6003ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onoratobackup_helper_test_four()
6013ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato{
6023ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    int err;
6033ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    int fd;
60423ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato    KeyedVector<String8,FileRec> snapshot;
6053ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    const char* filename = SCRATCH_DIR "backup_helper_test_four.snap";
6063ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
6073ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    system("rm -r " SCRATCH_DIR);
6083ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    mkdir(SCRATCH_DIR, 0777);
6093ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
6103ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    // write
6113ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    fd = creat(filename, 0666);
6123ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    if (fd == -1) {
6133ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        fprintf(stderr, "error opening %s\n", filename);
6143ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        return 1;
6153ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    }
6163ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
6173ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    String8 filenames[4];
6183ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    FileState states[4];
61923ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato    FileRec r;
620ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato    r.deleted = false;
6213ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
6223ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    states[0].modTime_sec = 0xfedcba98;
6233ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    states[0].modTime_nsec = 0xdeadbeef;
6243ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    states[0].size = 0xababbcbc;
6253ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    states[0].crc32 = 0x12345678;
6263ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    states[0].nameLen = -12;
62723ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato    r.s = states[0];
6283ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    filenames[0] = String8("bytes_of_padding");
62923ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato    snapshot.add(filenames[0], r);
6303ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
6313ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    states[1].modTime_sec = 0x93400031;
6323ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    states[1].modTime_nsec = 0xdeadbeef;
6333ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    states[1].size = 0x88557766;
6343ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    states[1].crc32 = 0x22334422;
6353ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    states[1].nameLen = -1;
63623ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato    r.s = states[1];
6373ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    filenames[1] = String8("bytes_of_padding3");
63823ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato    snapshot.add(filenames[1], r);
6393ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
6403ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    states[2].modTime_sec = 0x33221144;
6413ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    states[2].modTime_nsec = 0xdeadbeef;
6423ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    states[2].size = 0x11223344;
6433ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    states[2].crc32 = 0x01122334;
6443ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    states[2].nameLen = 0;
64523ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato    r.s = states[2];
6463ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    filenames[2] = String8("bytes_of_padding_2");
64723ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato    snapshot.add(filenames[2], r);
6483ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
6493ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    states[3].modTime_sec = 0x33221144;
6503ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    states[3].modTime_nsec = 0xdeadbeef;
6513ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    states[3].size = 0x11223344;
6523ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    states[3].crc32 = 0x01122334;
6533ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    states[3].nameLen = 0;
65423ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato    r.s = states[3];
6553ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    filenames[3] = String8("bytes_of_padding__1");
65623ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato    snapshot.add(filenames[3], r);
6573ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
6583ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    err = write_snapshot_file(fd, snapshot);
6593ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
6603ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    close(fd);
6613ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
6623ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    if (err != 0) {
6633ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        fprintf(stderr, "write_snapshot_file reported error %d (%s)\n", err, strerror(err));
6643ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        return err;
6653ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    }
6663ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
6673ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    static const unsigned char correct_data[] = {
6683ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        // header
6693ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        0x53, 0x6e, 0x61, 0x70,  0x04, 0x00, 0x00, 0x00,
6703ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        0x46, 0x69, 0x6c, 0x65,  0xac, 0x00, 0x00, 0x00,
6713ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
6723ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        // bytes_of_padding
6733ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        0x98, 0xba, 0xdc, 0xfe,  0xef, 0xbe, 0xad, 0xde,
6743ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        0xbc, 0xbc, 0xab, 0xab,  0x78, 0x56, 0x34, 0x12,
6753ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        0x10, 0x00, 0x00, 0x00,  0x62, 0x79, 0x74, 0x65,
6763ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        0x73, 0x5f, 0x6f, 0x66,  0x5f, 0x70, 0x61, 0x64,
6773ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        0x64, 0x69, 0x6e, 0x67,
6783ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
6793ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        // bytes_of_padding3
6803ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        0x31, 0x00, 0x40, 0x93,  0xef, 0xbe, 0xad, 0xde,
6813ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        0x66, 0x77, 0x55, 0x88,  0x22, 0x44, 0x33, 0x22,
6823ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        0x11, 0x00, 0x00, 0x00,  0x62, 0x79, 0x74, 0x65,
6833ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        0x73, 0x5f, 0x6f, 0x66,  0x5f, 0x70, 0x61, 0x64,
6843ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        0x64, 0x69, 0x6e, 0x67,  0x33, 0xab, 0xab, 0xab,
685f4c46b94b867f6a01bf7d0be18f667819338072fNicolas Catania
6863ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        // bytes of padding2
6873ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        0x44, 0x11, 0x22, 0x33,  0xef, 0xbe, 0xad, 0xde,
6883ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        0x44, 0x33, 0x22, 0x11,  0x34, 0x23, 0x12, 0x01,
6893ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        0x12, 0x00, 0x00, 0x00,  0x62, 0x79, 0x74, 0x65,
6903ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        0x73, 0x5f, 0x6f, 0x66,  0x5f, 0x70, 0x61, 0x64,
6913ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        0x64, 0x69, 0x6e, 0x67,  0x5f, 0x32, 0xab, 0xab,
692f4c46b94b867f6a01bf7d0be18f667819338072fNicolas Catania
6933ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        // bytes of padding3
6943ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        0x44, 0x11, 0x22, 0x33,  0xef, 0xbe, 0xad, 0xde,
6953ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        0x44, 0x33, 0x22, 0x11,  0x34, 0x23, 0x12, 0x01,
6963ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        0x13, 0x00, 0x00, 0x00,  0x62, 0x79, 0x74, 0x65,
6973ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        0x73, 0x5f, 0x6f, 0x66,  0x5f, 0x70, 0x61, 0x64,
6983ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        0x64, 0x69, 0x6e, 0x67,  0x5f, 0x5f, 0x31, 0xab
6993ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    };
7003ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
7013ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    err = compare_file(filename, correct_data, sizeof(correct_data));
7023ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    if (err != 0) {
7033ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        return err;
7043ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    }
705f4c46b94b867f6a01bf7d0be18f667819338072fNicolas Catania
7063ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    // read
7073ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    fd = open(filename, O_RDONLY);
7083ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    if (fd == -1) {
7093ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        fprintf(stderr, "error opening for read %s\n", filename);
7103ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        return 1;
7113ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    }
7123ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
7133ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
7143ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    KeyedVector<String8,FileState> readSnapshot;
7153ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    err = read_snapshot_file(fd, &readSnapshot);
7163ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    if (err != 0) {
7173ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        fprintf(stderr, "read_snapshot_file failed %d\n", err);
7183ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        return err;
7193ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    }
7203ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
7213ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    if (readSnapshot.size() != 4) {
7223ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        fprintf(stderr, "readSnapshot should be length 4 is %d\n", readSnapshot.size());
7233ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        return 1;
7243ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    }
7253ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
7263ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    bool matched = true;
7273ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    for (size_t i=0; i<readSnapshot.size(); i++) {
7283ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        const String8& name = readSnapshot.keyAt(i);
7293ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        const FileState state = readSnapshot.valueAt(i);
7303ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
7313ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        if (name != filenames[i] || states[i].modTime_sec != state.modTime_sec
7323ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato                || states[i].modTime_nsec != state.modTime_nsec
7333ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato                || states[i].size != state.size || states[i].crc32 != states[i].crc32) {
7343ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato            fprintf(stderr, "state %d expected={%d/%d, 0x%08x, 0x%08x, %3d} '%s'\n"
7353ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato                            "          actual={%d/%d, 0x%08x, 0x%08x, %3d} '%s'\n", i,
7363ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato                    states[i].modTime_sec, states[i].modTime_nsec, states[i].size, states[i].crc32,
7373ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato                    name.length(), filenames[i].string(),
7383ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato                    state.modTime_sec, state.modTime_nsec, state.size, state.crc32, state.nameLen,
7393ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato                    name.string());
7403ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato            matched = false;
7413ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        }
7423ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    }
743f4c46b94b867f6a01bf7d0be18f667819338072fNicolas Catania
7443ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    return matched ? 0 : 1;
7453ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato}
7463ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
7474535e40544aeb957d44fad75fbe5676effe03689Joe Onorato// hexdump -v -e '"    " 8/1 " 0x%02x," "\n"' data_writer.data
7484535e40544aeb957d44fad75fbe5676effe03689Joe Onoratoconst unsigned char DATA_GOLDEN_FILE[] = {
7492e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato     0x44, 0x61, 0x74, 0x61, 0x0b, 0x00, 0x00, 0x00,
7502e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato     0x0c, 0x00, 0x00, 0x00, 0x6e, 0x6f, 0x5f, 0x70,
7514535e40544aeb957d44fad75fbe5676effe03689Joe Onorato     0x61, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x5f, 0x00,
7522e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato     0x6e, 0x6f, 0x5f, 0x70, 0x61, 0x64, 0x64, 0x69,
7535f15d151b5101fadfe6cba1e8f4aa6367e8c603eJoe Onorato     0x6e, 0x67, 0x5f, 0x00, 0x44, 0x61, 0x74, 0x61,
7545f15d151b5101fadfe6cba1e8f4aa6367e8c603eJoe Onorato     0x0c, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00,
7554535e40544aeb957d44fad75fbe5676effe03689Joe Onorato     0x70, 0x61, 0x64, 0x64, 0x65, 0x64, 0x5f, 0x74,
7564535e40544aeb957d44fad75fbe5676effe03689Joe Onorato     0x6f, 0x5f, 0x5f, 0x33, 0x00, 0xbc, 0xbc, 0xbc,
7574535e40544aeb957d44fad75fbe5676effe03689Joe Onorato     0x70, 0x61, 0x64, 0x64, 0x65, 0x64, 0x5f, 0x74,
7585f15d151b5101fadfe6cba1e8f4aa6367e8c603eJoe Onorato     0x6f, 0x5f, 0x5f, 0x33, 0x00, 0xbc, 0xbc, 0xbc,
7592e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato     0x44, 0x61, 0x74, 0x61, 0x0d, 0x00, 0x00, 0x00,
7602e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato     0x0e, 0x00, 0x00, 0x00, 0x70, 0x61, 0x64, 0x64,
7612e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato     0x65, 0x64, 0x5f, 0x74, 0x6f, 0x5f, 0x32, 0x5f,
7622e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato     0x5f, 0x00, 0xbc, 0xbc, 0x70, 0x61, 0x64, 0x64,
7632e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato     0x65, 0x64, 0x5f, 0x74, 0x6f, 0x5f, 0x32, 0x5f,
7645f15d151b5101fadfe6cba1e8f4aa6367e8c603eJoe Onorato     0x5f, 0x00, 0xbc, 0xbc, 0x44, 0x61, 0x74, 0x61,
7654535e40544aeb957d44fad75fbe5676effe03689Joe Onorato     0x0a, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00,
7664535e40544aeb957d44fad75fbe5676effe03689Joe Onorato     0x70, 0x61, 0x64, 0x64, 0x65, 0x64, 0x5f, 0x74,
7674535e40544aeb957d44fad75fbe5676effe03689Joe Onorato     0x6f, 0x31, 0x00, 0xbc, 0x70, 0x61, 0x64, 0x64,
7685f15d151b5101fadfe6cba1e8f4aa6367e8c603eJoe Onorato     0x65, 0x64, 0x5f, 0x74, 0x6f, 0x31, 0x00
7695f15d151b5101fadfe6cba1e8f4aa6367e8c603eJoe Onorato
7704535e40544aeb957d44fad75fbe5676effe03689Joe Onorato};
7714535e40544aeb957d44fad75fbe5676effe03689Joe Onoratoconst int DATA_GOLDEN_FILE_SIZE = sizeof(DATA_GOLDEN_FILE);
7724535e40544aeb957d44fad75fbe5676effe03689Joe Onorato
7734535e40544aeb957d44fad75fbe5676effe03689Joe Onoratostatic int
7744535e40544aeb957d44fad75fbe5676effe03689Joe Onoratotest_write_header_and_entity(BackupDataWriter& writer, const char* str)
7754535e40544aeb957d44fad75fbe5676effe03689Joe Onorato{
7764535e40544aeb957d44fad75fbe5676effe03689Joe Onorato    int err;
7774535e40544aeb957d44fad75fbe5676effe03689Joe Onorato    String8 text(str);
7784535e40544aeb957d44fad75fbe5676effe03689Joe Onorato
7794535e40544aeb957d44fad75fbe5676effe03689Joe Onorato    err = writer.WriteEntityHeader(text, text.length()+1);
7804535e40544aeb957d44fad75fbe5676effe03689Joe Onorato    if (err != 0) {
7814535e40544aeb957d44fad75fbe5676effe03689Joe Onorato        fprintf(stderr, "WriteEntityHeader failed with %s\n", strerror(err));
7824535e40544aeb957d44fad75fbe5676effe03689Joe Onorato        return err;
7834535e40544aeb957d44fad75fbe5676effe03689Joe Onorato    }
7844535e40544aeb957d44fad75fbe5676effe03689Joe Onorato
7854535e40544aeb957d44fad75fbe5676effe03689Joe Onorato    err = writer.WriteEntityData(text.string(), text.length()+1);
7864535e40544aeb957d44fad75fbe5676effe03689Joe Onorato    if (err != 0) {
7874535e40544aeb957d44fad75fbe5676effe03689Joe Onorato        fprintf(stderr, "write failed for data '%s'\n", text.string());
7884535e40544aeb957d44fad75fbe5676effe03689Joe Onorato        return errno;
7894535e40544aeb957d44fad75fbe5676effe03689Joe Onorato    }
7904535e40544aeb957d44fad75fbe5676effe03689Joe Onorato
7914535e40544aeb957d44fad75fbe5676effe03689Joe Onorato    return err;
7924535e40544aeb957d44fad75fbe5676effe03689Joe Onorato}
7934535e40544aeb957d44fad75fbe5676effe03689Joe Onorato
7944535e40544aeb957d44fad75fbe5676effe03689Joe Onoratoint
7954535e40544aeb957d44fad75fbe5676effe03689Joe Onoratobackup_helper_test_data_writer()
7964535e40544aeb957d44fad75fbe5676effe03689Joe Onorato{
7974535e40544aeb957d44fad75fbe5676effe03689Joe Onorato    int err;
7984535e40544aeb957d44fad75fbe5676effe03689Joe Onorato    int fd;
7994535e40544aeb957d44fad75fbe5676effe03689Joe Onorato    const char* filename = SCRATCH_DIR "data_writer.data";
8004535e40544aeb957d44fad75fbe5676effe03689Joe Onorato
8014535e40544aeb957d44fad75fbe5676effe03689Joe Onorato    system("rm -r " SCRATCH_DIR);
8024535e40544aeb957d44fad75fbe5676effe03689Joe Onorato    mkdir(SCRATCH_DIR, 0777);
8034535e40544aeb957d44fad75fbe5676effe03689Joe Onorato    mkdir(SCRATCH_DIR "data", 0777);
804f4c46b94b867f6a01bf7d0be18f667819338072fNicolas Catania
8054535e40544aeb957d44fad75fbe5676effe03689Joe Onorato    fd = creat(filename, 0666);
8064535e40544aeb957d44fad75fbe5676effe03689Joe Onorato    if (fd == -1) {
8074535e40544aeb957d44fad75fbe5676effe03689Joe Onorato        fprintf(stderr, "error creating: %s\n", strerror(errno));
8084535e40544aeb957d44fad75fbe5676effe03689Joe Onorato        return errno;
8094535e40544aeb957d44fad75fbe5676effe03689Joe Onorato    }
8104535e40544aeb957d44fad75fbe5676effe03689Joe Onorato
8114535e40544aeb957d44fad75fbe5676effe03689Joe Onorato    BackupDataWriter writer(fd);
8124535e40544aeb957d44fad75fbe5676effe03689Joe Onorato
8134535e40544aeb957d44fad75fbe5676effe03689Joe Onorato    err = 0;
8144535e40544aeb957d44fad75fbe5676effe03689Joe Onorato    err |= test_write_header_and_entity(writer, "no_padding_");
8154535e40544aeb957d44fad75fbe5676effe03689Joe Onorato    err |= test_write_header_and_entity(writer, "padded_to__3");
8164535e40544aeb957d44fad75fbe5676effe03689Joe Onorato    err |= test_write_header_and_entity(writer, "padded_to_2__");
8174535e40544aeb957d44fad75fbe5676effe03689Joe Onorato    err |= test_write_header_and_entity(writer, "padded_to1");
8184535e40544aeb957d44fad75fbe5676effe03689Joe Onorato
8194535e40544aeb957d44fad75fbe5676effe03689Joe Onorato    close(fd);
8204535e40544aeb957d44fad75fbe5676effe03689Joe Onorato
8214535e40544aeb957d44fad75fbe5676effe03689Joe Onorato    err = compare_file(filename, DATA_GOLDEN_FILE, DATA_GOLDEN_FILE_SIZE);
8224535e40544aeb957d44fad75fbe5676effe03689Joe Onorato    if (err != 0) {
8234535e40544aeb957d44fad75fbe5676effe03689Joe Onorato        return err;
8244535e40544aeb957d44fad75fbe5676effe03689Joe Onorato    }
8254535e40544aeb957d44fad75fbe5676effe03689Joe Onorato
8264535e40544aeb957d44fad75fbe5676effe03689Joe Onorato    return err;
8274535e40544aeb957d44fad75fbe5676effe03689Joe Onorato}
8284535e40544aeb957d44fad75fbe5676effe03689Joe Onorato
8292e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onoratoint
8302e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onoratotest_read_header_and_entity(BackupDataReader& reader, const char* str)
8312e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato{
8322e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    int err;
8332e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    int bufSize = strlen(str)+1;
8342e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    char* buf = (char*)malloc(bufSize);
8352e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    String8 string;
8362e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    int cookie = 0x11111111;
8372e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    size_t actualSize;
8385f15d151b5101fadfe6cba1e8f4aa6367e8c603eJoe Onorato    bool done;
8395f15d151b5101fadfe6cba1e8f4aa6367e8c603eJoe Onorato    int type;
8402e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato
8412e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    // printf("\n\n---------- test_read_header_and_entity -- %s\n\n", str);
8422e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato
8435f15d151b5101fadfe6cba1e8f4aa6367e8c603eJoe Onorato    err = reader.ReadNextHeader(&done, &type);
8445f15d151b5101fadfe6cba1e8f4aa6367e8c603eJoe Onorato    if (done) {
8455f15d151b5101fadfe6cba1e8f4aa6367e8c603eJoe Onorato        fprintf(stderr, "should not be done yet\n");
8465f15d151b5101fadfe6cba1e8f4aa6367e8c603eJoe Onorato        goto finished;
8472e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    }
8482e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    if (err != 0) {
8495f15d151b5101fadfe6cba1e8f4aa6367e8c603eJoe Onorato        fprintf(stderr, "ReadNextHeader (for app header) failed with %s\n", strerror(err));
8505f15d151b5101fadfe6cba1e8f4aa6367e8c603eJoe Onorato        goto finished;
8512e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    }
8525f15d151b5101fadfe6cba1e8f4aa6367e8c603eJoe Onorato    if (type != BACKUP_HEADER_ENTITY_V1) {
8532e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato        err = EINVAL;
8545f15d151b5101fadfe6cba1e8f4aa6367e8c603eJoe Onorato        fprintf(stderr, "type=0x%08x expected 0x%08x\n", type, BACKUP_HEADER_ENTITY_V1);
8552e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    }
8562e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato
8572e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    err = reader.ReadEntityHeader(&string, &actualSize);
8582e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    if (err != 0) {
8592e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato        fprintf(stderr, "ReadEntityHeader failed with %s\n", strerror(err));
8605f15d151b5101fadfe6cba1e8f4aa6367e8c603eJoe Onorato        goto finished;
8612e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    }
8622e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    if (string != str) {
8632e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato        fprintf(stderr, "ReadEntityHeader expected key '%s' got '%s'\n", str, string.string());
8642e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato        err = EINVAL;
8655f15d151b5101fadfe6cba1e8f4aa6367e8c603eJoe Onorato        goto finished;
8662e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    }
8672e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    if ((int)actualSize != bufSize) {
8682e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato        fprintf(stderr, "ReadEntityHeader expected dataSize 0x%08x got 0x%08x\n", bufSize,
8692e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato                actualSize);
8702e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato        err = EINVAL;
8715f15d151b5101fadfe6cba1e8f4aa6367e8c603eJoe Onorato        goto finished;
8722e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    }
8732e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato
8742e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    err = reader.ReadEntityData(buf, bufSize);
8752e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    if (err != NO_ERROR) {
8762e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato        fprintf(stderr, "ReadEntityData failed with %s\n", strerror(err));
8775f15d151b5101fadfe6cba1e8f4aa6367e8c603eJoe Onorato        goto finished;
8782e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    }
8792e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato
8802e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    if (0 != memcmp(buf, str, bufSize)) {
8812e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato        fprintf(stderr, "ReadEntityData expected '%s' but got something starting with "
8825f15d151b5101fadfe6cba1e8f4aa6367e8c603eJoe Onorato                "%02x %02x %02x %02x  '%c%c%c%c'\n", str, buf[0], buf[1], buf[2], buf[3],
8835f15d151b5101fadfe6cba1e8f4aa6367e8c603eJoe Onorato                buf[0], buf[1], buf[2], buf[3]);
8842e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato        err = EINVAL;
8855f15d151b5101fadfe6cba1e8f4aa6367e8c603eJoe Onorato        goto finished;
8862e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    }
8872e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato
8882e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    // The next read will confirm whether it got the right amount of data.
8892e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato
8905f15d151b5101fadfe6cba1e8f4aa6367e8c603eJoe Onoratofinished:
8912e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    if (err != NO_ERROR) {
8922e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato        fprintf(stderr, "test_read_header_and_entity failed with %s\n", strerror(err));
8932e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    }
8942e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    free(buf);
8952e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    return err;
8962e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato}
8972e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato
8982e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onoratoint
8992e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onoratobackup_helper_test_data_reader()
9002e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato{
9012e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    int err;
9022e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    int fd;
9032e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    const char* filename = SCRATCH_DIR "data_reader.data";
9042e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato
9052e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    system("rm -r " SCRATCH_DIR);
9062e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    mkdir(SCRATCH_DIR, 0777);
9072e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    mkdir(SCRATCH_DIR "data", 0777);
908f4c46b94b867f6a01bf7d0be18f667819338072fNicolas Catania
9092e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    fd = creat(filename, 0666);
9102e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    if (fd == -1) {
9112e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato        fprintf(stderr, "error creating: %s\n", strerror(errno));
9122e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato        return errno;
9132e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    }
9142e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato
9152e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    err = write(fd, DATA_GOLDEN_FILE, DATA_GOLDEN_FILE_SIZE);
9162e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    if (err != DATA_GOLDEN_FILE_SIZE) {
9172e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato        fprintf(stderr, "Error \"%s\" writing golden file %s\n", strerror(errno), filename);
9182e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato        return errno;
9192e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    }
9202e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato
9212e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    close(fd);
9222e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato
9232e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    fd = open(filename, O_RDONLY);
9242e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    if (fd == -1) {
9252e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato        fprintf(stderr, "Error \"%s\" opening golden file %s for read\n", strerror(errno),
9262e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato                filename);
9272e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato        return errno;
9282e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    }
9292e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato
9302e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    {
9312e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato        BackupDataReader reader(fd);
9322e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato
9332e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato        err = 0;
9342e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato
9352e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato        if (err == NO_ERROR) {
9362e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato            err = test_read_header_and_entity(reader, "no_padding_");
9372e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato        }
9382e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato
9392e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato        if (err == NO_ERROR) {
9402e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato            err = test_read_header_and_entity(reader, "padded_to__3");
9412e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato        }
9422e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato
9432e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato        if (err == NO_ERROR) {
9442e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato            err = test_read_header_and_entity(reader, "padded_to_2__");
9452e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato        }
9462e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato
9472e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato        if (err == NO_ERROR) {
9482e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato            err = test_read_header_and_entity(reader, "padded_to1");
9492e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato        }
9502e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    }
9512e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato
9522e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    close(fd);
9532e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato
9542e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    return err;
9552e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato}
9562e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato
9573ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onoratostatic int
9583ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onoratoget_mod_time(const char* filename, struct timeval times[2])
9593ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato{
9603ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    int err;
9613ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    struct stat64 st;
9623ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    err = stat64(filename, &st);
9633ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    if (err != 0) {
9643ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        fprintf(stderr, "stat '%s' failed: %s\n", filename, strerror(errno));
9653ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        return errno;
9663ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    }
9673ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    times[0].tv_sec = st.st_atime;
9683ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    times[1].tv_sec = st.st_mtime;
969f4c46b94b867f6a01bf7d0be18f667819338072fNicolas Catania
970f4c46b94b867f6a01bf7d0be18f667819338072fNicolas Catania    // If st_atime is a macro then struct stat64 uses struct timespec
971f4c46b94b867f6a01bf7d0be18f667819338072fNicolas Catania    // to store the access and modif time values and typically
972f4c46b94b867f6a01bf7d0be18f667819338072fNicolas Catania    // st_*time_nsec is not defined. In glibc, this is controlled by
973f4c46b94b867f6a01bf7d0be18f667819338072fNicolas Catania    // __USE_MISC.
974f4c46b94b867f6a01bf7d0be18f667819338072fNicolas Catania#ifdef __USE_MISC
975f4c46b94b867f6a01bf7d0be18f667819338072fNicolas Catania#if !defined(st_atime) || defined(st_atime_nsec)
976f4c46b94b867f6a01bf7d0be18f667819338072fNicolas Catania#error "Check if this __USE_MISC conditional is still needed."
977f4c46b94b867f6a01bf7d0be18f667819338072fNicolas Catania#endif
978f4c46b94b867f6a01bf7d0be18f667819338072fNicolas Catania    times[0].tv_usec = st.st_atim.tv_nsec / 1000;
979f4c46b94b867f6a01bf7d0be18f667819338072fNicolas Catania    times[1].tv_usec = st.st_mtim.tv_nsec / 1000;
980f4c46b94b867f6a01bf7d0be18f667819338072fNicolas Catania#else
981f4c46b94b867f6a01bf7d0be18f667819338072fNicolas Catania    times[0].tv_usec = st.st_atime_nsec / 1000;
9823ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    times[1].tv_usec = st.st_mtime_nsec / 1000;
983f4c46b94b867f6a01bf7d0be18f667819338072fNicolas Catania#endif
984f4c46b94b867f6a01bf7d0be18f667819338072fNicolas Catania
9853ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    return 0;
9863ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato}
9873ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
9883ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onoratoint
9893ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onoratobackup_helper_test_files()
9903ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato{
9913ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    int err;
9923ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    int oldSnapshotFD;
9934535e40544aeb957d44fad75fbe5676effe03689Joe Onorato    int dataStreamFD;
9944535e40544aeb957d44fad75fbe5676effe03689Joe Onorato    int newSnapshotFD;
9953ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
9963ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    system("rm -r " SCRATCH_DIR);
9973ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    mkdir(SCRATCH_DIR, 0777);
9983ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    mkdir(SCRATCH_DIR "data", 0777);
9993ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
10003ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    write_text_file(SCRATCH_DIR "data/b", "b\nbb\n");
10013ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    write_text_file(SCRATCH_DIR "data/c", "c\ncc\n");
10023ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    write_text_file(SCRATCH_DIR "data/d", "d\ndd\n");
10033ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    write_text_file(SCRATCH_DIR "data/e", "e\nee\n");
10043ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    write_text_file(SCRATCH_DIR "data/f", "f\nff\n");
10053ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    write_text_file(SCRATCH_DIR "data/h", "h\nhh\n");
10063ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
10073ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    char const* files_before[] = {
100823ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato        SCRATCH_DIR "data/b",
100923ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato        SCRATCH_DIR "data/c",
101023ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato        SCRATCH_DIR "data/d",
101123ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato        SCRATCH_DIR "data/e",
101223ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato        SCRATCH_DIR "data/f"
101323ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato    };
101423ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato
101523ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato    char const* keys_before[] = {
10163ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        "data/b",
10173ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        "data/c",
10183ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        "data/d",
10193ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        "data/e",
10203ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        "data/f"
10213ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    };
10223ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
10234535e40544aeb957d44fad75fbe5676effe03689Joe Onorato    dataStreamFD = creat(SCRATCH_DIR "1.data", 0666);
10244535e40544aeb957d44fad75fbe5676effe03689Joe Onorato    if (dataStreamFD == -1) {
10254535e40544aeb957d44fad75fbe5676effe03689Joe Onorato        fprintf(stderr, "error creating: %s\n", strerror(errno));
10264535e40544aeb957d44fad75fbe5676effe03689Joe Onorato        return errno;
10274535e40544aeb957d44fad75fbe5676effe03689Joe Onorato    }
10284535e40544aeb957d44fad75fbe5676effe03689Joe Onorato
10293ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    newSnapshotFD = creat(SCRATCH_DIR "before.snap", 0666);
10303ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    if (newSnapshotFD == -1) {
10313ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        fprintf(stderr, "error creating: %s\n", strerror(errno));
10323ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        return errno;
10333ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    }
1034d2110dbce071a236b6176de344ca797b737542ebJoe Onorato
1035d2110dbce071a236b6176de344ca797b737542ebJoe Onorato    {
1036d2110dbce071a236b6176de344ca797b737542ebJoe Onorato        BackupDataWriter dataStream(dataStreamFD);
1037f4c46b94b867f6a01bf7d0be18f667819338072fNicolas Catania
103823ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato        err = back_up_files(-1, &dataStream, newSnapshotFD, files_before, keys_before, 5);
1039d2110dbce071a236b6176de344ca797b737542ebJoe Onorato        if (err != 0) {
1040d2110dbce071a236b6176de344ca797b737542ebJoe Onorato            return err;
1041d2110dbce071a236b6176de344ca797b737542ebJoe Onorato        }
10423ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    }
10433ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
10444535e40544aeb957d44fad75fbe5676effe03689Joe Onorato    close(dataStreamFD);
10453ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    close(newSnapshotFD);
10463ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
10473ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    sleep(3);
10483ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
10493ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    struct timeval d_times[2];
10503ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    struct timeval e_times[2];
10513ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
10523ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    err = get_mod_time(SCRATCH_DIR "data/d", d_times);
10533ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    err |= get_mod_time(SCRATCH_DIR "data/e", e_times);
10543ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    if (err != 0) {
10553ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        return err;
10563ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    }
10573ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
10583ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    write_text_file(SCRATCH_DIR "data/a", "a\naa\n");
10593ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    unlink(SCRATCH_DIR "data/c");
10603ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    write_text_file(SCRATCH_DIR "data/c", "c\ncc\n");
10613ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    write_text_file(SCRATCH_DIR "data/d", "dd\ndd\n");
10623ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    utimes(SCRATCH_DIR "data/d", d_times);
10633ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    write_text_file(SCRATCH_DIR "data/e", "z\nzz\n");
10643ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    utimes(SCRATCH_DIR "data/e", e_times);
10653ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    write_text_file(SCRATCH_DIR "data/g", "g\ngg\n");
10663ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    unlink(SCRATCH_DIR "data/f");
1067f4c46b94b867f6a01bf7d0be18f667819338072fNicolas Catania
10683ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    char const* files_after[] = {
106923ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato        SCRATCH_DIR "data/a", // added
107023ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato        SCRATCH_DIR "data/b", // same
107123ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato        SCRATCH_DIR "data/c", // different mod time
107223ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato        SCRATCH_DIR "data/d", // different size (same mod time)
107323ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato        SCRATCH_DIR "data/e", // different contents (same mod time, same size)
107423ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato        SCRATCH_DIR "data/g"  // added
107523ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato    };
107623ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato
107723ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato    char const* keys_after[] = {
10783ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        "data/a", // added
10793ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        "data/b", // same
10803ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        "data/c", // different mod time
10813ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        "data/d", // different size (same mod time)
10823ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        "data/e", // different contents (same mod time, same size)
10833ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        "data/g"  // added
10843ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    };
10853ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
10863ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    oldSnapshotFD = open(SCRATCH_DIR "before.snap", O_RDONLY);
10873ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    if (oldSnapshotFD == -1) {
10883ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        fprintf(stderr, "error opening: %s\n", strerror(errno));
10893ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        return errno;
10903ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    }
10913ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
10924535e40544aeb957d44fad75fbe5676effe03689Joe Onorato    dataStreamFD = creat(SCRATCH_DIR "2.data", 0666);
10934535e40544aeb957d44fad75fbe5676effe03689Joe Onorato    if (dataStreamFD == -1) {
10944535e40544aeb957d44fad75fbe5676effe03689Joe Onorato        fprintf(stderr, "error creating: %s\n", strerror(errno));
10954535e40544aeb957d44fad75fbe5676effe03689Joe Onorato        return errno;
10964535e40544aeb957d44fad75fbe5676effe03689Joe Onorato    }
10974535e40544aeb957d44fad75fbe5676effe03689Joe Onorato
10983ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    newSnapshotFD = creat(SCRATCH_DIR "after.snap", 0666);
10993ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    if (newSnapshotFD == -1) {
11003ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        fprintf(stderr, "error creating: %s\n", strerror(errno));
11013ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        return errno;
11023ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    }
11033ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
1104d2110dbce071a236b6176de344ca797b737542ebJoe Onorato    {
1105d2110dbce071a236b6176de344ca797b737542ebJoe Onorato        BackupDataWriter dataStream(dataStreamFD);
1106f4c46b94b867f6a01bf7d0be18f667819338072fNicolas Catania
110723ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato        err = back_up_files(oldSnapshotFD, &dataStream, newSnapshotFD, files_after, keys_after, 6);
1108d2110dbce071a236b6176de344ca797b737542ebJoe Onorato        if (err != 0) {
1109d2110dbce071a236b6176de344ca797b737542ebJoe Onorato            return err;
1110d2110dbce071a236b6176de344ca797b737542ebJoe Onorato        }
1111d2110dbce071a236b6176de344ca797b737542ebJoe Onorato}
11123ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
11133ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    close(oldSnapshotFD);
11144535e40544aeb957d44fad75fbe5676effe03689Joe Onorato    close(dataStreamFD);
11153ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    close(newSnapshotFD);
1116f4c46b94b867f6a01bf7d0be18f667819338072fNicolas Catania
11173ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    return 0;
11183ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato}
11193ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
112023ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onoratoint
112123ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onoratobackup_helper_test_null_base()
112223ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato{
112323ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato    int err;
112423ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato    int oldSnapshotFD;
112523ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato    int dataStreamFD;
112623ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato    int newSnapshotFD;
112723ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato
112823ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato    system("rm -r " SCRATCH_DIR);
112923ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato    mkdir(SCRATCH_DIR, 0777);
113023ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato    mkdir(SCRATCH_DIR "data", 0777);
113123ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato
113223ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato    write_text_file(SCRATCH_DIR "data/a", "a\naa\n");
113323ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato
113423ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato    char const* files[] = {
113523ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato        SCRATCH_DIR "data/a",
113623ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato    };
113723ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato
113823ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato    char const* keys[] = {
113923ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato        "a",
114023ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato    };
114123ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato
114223ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato    dataStreamFD = creat(SCRATCH_DIR "null_base.data", 0666);
114323ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato    if (dataStreamFD == -1) {
114423ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato        fprintf(stderr, "error creating: %s\n", strerror(errno));
114523ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato        return errno;
114623ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato    }
114723ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato
114823ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato    newSnapshotFD = creat(SCRATCH_DIR "null_base.snap", 0666);
114923ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato    if (newSnapshotFD == -1) {
115023ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato        fprintf(stderr, "error creating: %s\n", strerror(errno));
115123ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato        return errno;
115223ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato    }
115323ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato
115423ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato    {
115523ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato        BackupDataWriter dataStream(dataStreamFD);
115623ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato
115723ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato        err = back_up_files(-1, &dataStream, newSnapshotFD, files, keys, 1);
115823ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato        if (err != 0) {
115923ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato            return err;
116023ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato        }
116123ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato    }
116223ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato
116323ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato    close(dataStreamFD);
116423ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato    close(newSnapshotFD);
116523ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato
116623ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato    return 0;
116723ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato}
116823ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato
1169ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onoratoint
1170ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onoratobackup_helper_test_missing_file()
1171ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato{
1172ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato    int err;
1173ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato    int oldSnapshotFD;
1174ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato    int dataStreamFD;
1175ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato    int newSnapshotFD;
1176ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato
1177ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato    system("rm -r " SCRATCH_DIR);
1178ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato    mkdir(SCRATCH_DIR, 0777);
1179ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato    mkdir(SCRATCH_DIR "data", 0777);
1180ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato
1181ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato    write_text_file(SCRATCH_DIR "data/b", "b\nbb\n");
1182ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato
1183ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato    char const* files[] = {
1184ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato        SCRATCH_DIR "data/a",
1185ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato        SCRATCH_DIR "data/b",
1186ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato        SCRATCH_DIR "data/c",
1187ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato    };
1188ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato
1189ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato    char const* keys[] = {
1190ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato        "a",
1191ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato        "b",
1192ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato        "c",
1193ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato    };
1194ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato
1195ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato    dataStreamFD = creat(SCRATCH_DIR "null_base.data", 0666);
1196ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato    if (dataStreamFD == -1) {
1197ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato        fprintf(stderr, "error creating: %s\n", strerror(errno));
1198ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato        return errno;
1199ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato    }
1200ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato
1201ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato    newSnapshotFD = creat(SCRATCH_DIR "null_base.snap", 0666);
1202ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato    if (newSnapshotFD == -1) {
1203ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato        fprintf(stderr, "error creating: %s\n", strerror(errno));
1204ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato        return errno;
1205ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato    }
1206ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato
1207ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato    {
1208ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato        BackupDataWriter dataStream(dataStreamFD);
1209ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato
1210ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato        err = back_up_files(-1, &dataStream, newSnapshotFD, files, keys, 1);
1211ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato        if (err != 0) {
1212ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato            return err;
1213ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato        }
1214ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato    }
1215ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato
1216ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato    close(dataStreamFD);
1217ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato    close(newSnapshotFD);
1218ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato
1219ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato    return 0;
1220ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato}
1221ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato
122223ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato
12233ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato#endif // TEST_BACKUP_HELPERS
12244535e40544aeb957d44fad75fbe5676effe03689Joe Onorato
12254535e40544aeb957d44fad75fbe5676effe03689Joe Onorato}
1226