BackupHelpers.cpp revision 5d605dc56b036232e885f6ec36b888b729673060
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    }
4175d605dc56b036232e885f6ec36b888b729673060Joe 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);
4235d605dc56b036232e885f6ec36b888b729673060Joe Onorato    fd = open(filename.string(), O_CREAT|O_RDWR|O_TRUNC, mode);
4245d605dc56b036232e885f6ec36b888b729673060Joe Onorato    if (fd == -1) {
4255d605dc56b036232e885f6ec36b888b729673060Joe Onorato        LOGW("Could not open file %s -- %s", filename.string(), strerror(errno));
426d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato        return errno;
427d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato    }
428d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato
429d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato    while ((amt = in->ReadEntityData(buf, RESTORE_BUF_SIZE)) > 0) {
430d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato        err = write(fd, buf, amt);
431d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato        if (err != amt) {
432d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato            close(fd);
4335d605dc56b036232e885f6ec36b888b729673060Joe Onorato            LOGW("Error '%s' writing '%s'", strerror(errno), filename.string());
434d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato            return errno;
435d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato        }
436d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato        crc = crc32(crc, (Bytef*)buf, amt);
437d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato    }
438d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato
439d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato    close(fd);
440d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato
441d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato    // Record for the snapshot
442d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato    err = stat(filename.string(), &st);
443d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato    if (err != 0) {
444d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato        LOGW("Error stating file that we just created %s", filename.string());
445d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato        return errno;
446d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato    }
447d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato
448d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato    r.file = filename;
449d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato    r.deleted = false;
450d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato    r.s.modTime_sec = st.st_mtime;
451d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato    r.s.modTime_nsec = 0; // workaround sim breakage
452d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato    //r.s.modTime_nsec = st.st_mtime_nsec;
453d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato    r.s.size = st.st_size;
454d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato    r.s.crc32 = crc;
455d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato
456d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato    m_files.add(key, r);
457d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato
458d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato    return NO_ERROR;
459d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato}
460d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato
461d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onoratostatus_t
462d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe OnoratoRestoreHelperBase::WriteSnapshot(int fd)
463d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato{
464d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato    return write_snapshot_file(fd, m_files);;
465d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato}
466d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato
4673ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato#if TEST_BACKUP_HELPERS
4683ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
4693ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato#define SCRATCH_DIR "/data/backup_helper_test/"
4703ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
4713ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onoratostatic int
4723ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onoratowrite_text_file(const char* path, const char* data)
4733ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato{
4743ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    int amt;
4753ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    int fd;
4763ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    int len;
4773ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
4783ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    fd = creat(path, 0666);
4793ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    if (fd == -1) {
4803ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        fprintf(stderr, "creat %s failed\n", path);
4813ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        return errno;
4823ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    }
4833ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
4843ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    len = strlen(data);
4853ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    amt = write(fd, data, len);
4863ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    if (amt != len) {
4873ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        fprintf(stderr, "error (%s) writing to file %s\n", strerror(errno), path);
4883ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        return errno;
4893ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    }
4903ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
4913ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    close(fd);
4923ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
4933ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    return 0;
4943ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato}
4953ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
4963ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onoratostatic int
4973ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onoratocompare_file(const char* path, const unsigned char* data, int len)
4983ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato{
4993ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    int fd;
5003ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    int amt;
5013ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
5023ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    fd = open(path, O_RDONLY);
5033ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    if (fd == -1) {
5043ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        fprintf(stderr, "compare_file error (%s) opening %s\n", strerror(errno), path);
5053ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        return errno;
5063ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    }
5073ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
5083ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    unsigned char* contents = (unsigned char*)malloc(len);
5093ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    if (contents == NULL) {
5103ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        fprintf(stderr, "malloc(%d) failed\n", len);
5113ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        return ENOMEM;
5123ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    }
5133ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
5143ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    bool sizesMatch = true;
5153ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    amt = lseek(fd, 0, SEEK_END);
5163ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    if (amt != len) {
5173ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        fprintf(stderr, "compare_file file length should be %d, was %d\n", len, amt);
5183ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        sizesMatch = false;
5193ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    }
5203ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    lseek(fd, 0, SEEK_SET);
5213ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
5223ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    int readLen = amt < len ? amt : len;
5233ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    amt = read(fd, contents, readLen);
5243ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    if (amt != readLen) {
5253ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        fprintf(stderr, "compare_file read expected %d bytes but got %d\n", len, amt);
5263ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    }
5273ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
5283ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    bool contentsMatch = true;
5293ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    for (int i=0; i<readLen; i++) {
5303ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        if (data[i] != contents[i]) {
5313ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato            if (contentsMatch) {
5323ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato                fprintf(stderr, "compare_file contents are different: (index, expected, actual)\n");
5333ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato                contentsMatch = false;
5343ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato            }
5353ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato            fprintf(stderr, "  [%-2d] %02x %02x\n", i, data[i], contents[i]);
5363ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        }
5373ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    }
5383ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
5393ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    return contentsMatch && sizesMatch ? 0 : 1;
5403ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato}
5413ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
5423ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onoratoint
5433ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onoratobackup_helper_test_empty()
5443ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato{
5453ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    int err;
5463ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    int fd;
54723ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato    KeyedVector<String8,FileRec> snapshot;
5483ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    const char* filename = SCRATCH_DIR "backup_helper_test_empty.snap";
5493ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
5503ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    system("rm -r " SCRATCH_DIR);
5513ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    mkdir(SCRATCH_DIR, 0777);
5523ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
5533ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    // write
5543ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    fd = creat(filename, 0666);
5553ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    if (fd == -1) {
5563ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        fprintf(stderr, "error creating %s\n", filename);
5573ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        return 1;
5583ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    }
5593ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
5603ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    err = write_snapshot_file(fd, snapshot);
5613ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
5623ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    close(fd);
5633ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
5643ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    if (err != 0) {
5653ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        fprintf(stderr, "write_snapshot_file reported error %d (%s)\n", err, strerror(err));
5663ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        return err;
5673ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    }
5683ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
5693ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    static const unsigned char correct_data[] = {
5703ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        0x53, 0x6e, 0x61, 0x70,  0x00, 0x00, 0x00, 0x00,
5713ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        0x46, 0x69, 0x6c, 0x65,  0x10, 0x00, 0x00, 0x00
5723ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    };
5733ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
5743ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    err = compare_file(filename, correct_data, sizeof(correct_data));
5753ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    if (err != 0) {
5763ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        return err;
5773ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    }
5783ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
5793ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    // read
5803ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    fd = open(filename, O_RDONLY);
5813ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    if (fd == -1) {
5823ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        fprintf(stderr, "error opening for read %s\n", filename);
5833ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        return 1;
5843ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    }
5853ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
5863ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    KeyedVector<String8,FileState> readSnapshot;
5873ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    err = read_snapshot_file(fd, &readSnapshot);
5883ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    if (err != 0) {
5893ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        fprintf(stderr, "read_snapshot_file failed %d\n", err);
5903ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        return err;
5913ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    }
5923ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
5933ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    if (readSnapshot.size() != 0) {
5943ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        fprintf(stderr, "readSnapshot should be length 0\n");
5953ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        return 1;
5963ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    }
5973ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
5983ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    return 0;
5993ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato}
6003ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
6013ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onoratoint
6023ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onoratobackup_helper_test_four()
6033ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato{
6043ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    int err;
6053ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    int fd;
60623ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato    KeyedVector<String8,FileRec> snapshot;
6073ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    const char* filename = SCRATCH_DIR "backup_helper_test_four.snap";
6083ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
6093ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    system("rm -r " SCRATCH_DIR);
6103ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    mkdir(SCRATCH_DIR, 0777);
6113ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
6123ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    // write
6133ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    fd = creat(filename, 0666);
6143ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    if (fd == -1) {
6153ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        fprintf(stderr, "error opening %s\n", filename);
6163ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        return 1;
6173ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    }
6183ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
6193ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    String8 filenames[4];
6203ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    FileState states[4];
62123ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato    FileRec r;
622ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato    r.deleted = false;
6233ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
6243ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    states[0].modTime_sec = 0xfedcba98;
6253ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    states[0].modTime_nsec = 0xdeadbeef;
6263ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    states[0].size = 0xababbcbc;
6273ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    states[0].crc32 = 0x12345678;
6283ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    states[0].nameLen = -12;
62923ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato    r.s = states[0];
6303ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    filenames[0] = String8("bytes_of_padding");
63123ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato    snapshot.add(filenames[0], r);
6323ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
6333ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    states[1].modTime_sec = 0x93400031;
6343ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    states[1].modTime_nsec = 0xdeadbeef;
6353ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    states[1].size = 0x88557766;
6363ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    states[1].crc32 = 0x22334422;
6373ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    states[1].nameLen = -1;
63823ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato    r.s = states[1];
6393ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    filenames[1] = String8("bytes_of_padding3");
64023ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato    snapshot.add(filenames[1], r);
6413ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
6423ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    states[2].modTime_sec = 0x33221144;
6433ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    states[2].modTime_nsec = 0xdeadbeef;
6443ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    states[2].size = 0x11223344;
6453ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    states[2].crc32 = 0x01122334;
6463ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    states[2].nameLen = 0;
64723ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato    r.s = states[2];
6483ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    filenames[2] = String8("bytes_of_padding_2");
64923ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato    snapshot.add(filenames[2], r);
6503ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
6513ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    states[3].modTime_sec = 0x33221144;
6523ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    states[3].modTime_nsec = 0xdeadbeef;
6533ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    states[3].size = 0x11223344;
6543ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    states[3].crc32 = 0x01122334;
6553ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    states[3].nameLen = 0;
65623ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato    r.s = states[3];
6573ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    filenames[3] = String8("bytes_of_padding__1");
65823ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato    snapshot.add(filenames[3], r);
6593ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
6603ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    err = write_snapshot_file(fd, snapshot);
6613ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
6623ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    close(fd);
6633ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
6643ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    if (err != 0) {
6653ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        fprintf(stderr, "write_snapshot_file reported error %d (%s)\n", err, strerror(err));
6663ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        return err;
6673ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    }
6683ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
6693ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    static const unsigned char correct_data[] = {
6703ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        // header
6713ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        0x53, 0x6e, 0x61, 0x70,  0x04, 0x00, 0x00, 0x00,
6723ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        0x46, 0x69, 0x6c, 0x65,  0xac, 0x00, 0x00, 0x00,
6733ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
6743ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        // bytes_of_padding
6753ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        0x98, 0xba, 0xdc, 0xfe,  0xef, 0xbe, 0xad, 0xde,
6763ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        0xbc, 0xbc, 0xab, 0xab,  0x78, 0x56, 0x34, 0x12,
6773ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        0x10, 0x00, 0x00, 0x00,  0x62, 0x79, 0x74, 0x65,
6783ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        0x73, 0x5f, 0x6f, 0x66,  0x5f, 0x70, 0x61, 0x64,
6793ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        0x64, 0x69, 0x6e, 0x67,
6803ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
6813ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        // bytes_of_padding3
6823ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        0x31, 0x00, 0x40, 0x93,  0xef, 0xbe, 0xad, 0xde,
6833ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        0x66, 0x77, 0x55, 0x88,  0x22, 0x44, 0x33, 0x22,
6843ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        0x11, 0x00, 0x00, 0x00,  0x62, 0x79, 0x74, 0x65,
6853ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        0x73, 0x5f, 0x6f, 0x66,  0x5f, 0x70, 0x61, 0x64,
6863ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        0x64, 0x69, 0x6e, 0x67,  0x33, 0xab, 0xab, 0xab,
687f4c46b94b867f6a01bf7d0be18f667819338072fNicolas Catania
6883ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        // bytes of padding2
6893ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        0x44, 0x11, 0x22, 0x33,  0xef, 0xbe, 0xad, 0xde,
6903ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        0x44, 0x33, 0x22, 0x11,  0x34, 0x23, 0x12, 0x01,
6913ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        0x12, 0x00, 0x00, 0x00,  0x62, 0x79, 0x74, 0x65,
6923ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        0x73, 0x5f, 0x6f, 0x66,  0x5f, 0x70, 0x61, 0x64,
6933ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        0x64, 0x69, 0x6e, 0x67,  0x5f, 0x32, 0xab, 0xab,
694f4c46b94b867f6a01bf7d0be18f667819338072fNicolas Catania
6953ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        // bytes of padding3
6963ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        0x44, 0x11, 0x22, 0x33,  0xef, 0xbe, 0xad, 0xde,
6973ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        0x44, 0x33, 0x22, 0x11,  0x34, 0x23, 0x12, 0x01,
6983ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        0x13, 0x00, 0x00, 0x00,  0x62, 0x79, 0x74, 0x65,
6993ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        0x73, 0x5f, 0x6f, 0x66,  0x5f, 0x70, 0x61, 0x64,
7003ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        0x64, 0x69, 0x6e, 0x67,  0x5f, 0x5f, 0x31, 0xab
7013ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    };
7023ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
7033ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    err = compare_file(filename, correct_data, sizeof(correct_data));
7043ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    if (err != 0) {
7053ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        return err;
7063ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    }
707f4c46b94b867f6a01bf7d0be18f667819338072fNicolas Catania
7083ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    // read
7093ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    fd = open(filename, O_RDONLY);
7103ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    if (fd == -1) {
7113ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        fprintf(stderr, "error opening for read %s\n", filename);
7123ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        return 1;
7133ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    }
7143ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
7153ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
7163ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    KeyedVector<String8,FileState> readSnapshot;
7173ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    err = read_snapshot_file(fd, &readSnapshot);
7183ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    if (err != 0) {
7193ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        fprintf(stderr, "read_snapshot_file failed %d\n", err);
7203ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        return err;
7213ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    }
7223ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
7233ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    if (readSnapshot.size() != 4) {
7243ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        fprintf(stderr, "readSnapshot should be length 4 is %d\n", readSnapshot.size());
7253ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        return 1;
7263ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    }
7273ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
7283ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    bool matched = true;
7293ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    for (size_t i=0; i<readSnapshot.size(); i++) {
7303ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        const String8& name = readSnapshot.keyAt(i);
7313ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        const FileState state = readSnapshot.valueAt(i);
7323ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
7333ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        if (name != filenames[i] || states[i].modTime_sec != state.modTime_sec
7343ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato                || states[i].modTime_nsec != state.modTime_nsec
7353ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato                || states[i].size != state.size || states[i].crc32 != states[i].crc32) {
7363ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato            fprintf(stderr, "state %d expected={%d/%d, 0x%08x, 0x%08x, %3d} '%s'\n"
7373ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato                            "          actual={%d/%d, 0x%08x, 0x%08x, %3d} '%s'\n", i,
7383ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato                    states[i].modTime_sec, states[i].modTime_nsec, states[i].size, states[i].crc32,
7393ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato                    name.length(), filenames[i].string(),
7403ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato                    state.modTime_sec, state.modTime_nsec, state.size, state.crc32, state.nameLen,
7413ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato                    name.string());
7423ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato            matched = false;
7433ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        }
7443ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    }
745f4c46b94b867f6a01bf7d0be18f667819338072fNicolas Catania
7463ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    return matched ? 0 : 1;
7473ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato}
7483ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
7494535e40544aeb957d44fad75fbe5676effe03689Joe Onorato// hexdump -v -e '"    " 8/1 " 0x%02x," "\n"' data_writer.data
7504535e40544aeb957d44fad75fbe5676effe03689Joe Onoratoconst unsigned char DATA_GOLDEN_FILE[] = {
7512e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato     0x44, 0x61, 0x74, 0x61, 0x0b, 0x00, 0x00, 0x00,
7522e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato     0x0c, 0x00, 0x00, 0x00, 0x6e, 0x6f, 0x5f, 0x70,
7534535e40544aeb957d44fad75fbe5676effe03689Joe Onorato     0x61, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x5f, 0x00,
7542e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato     0x6e, 0x6f, 0x5f, 0x70, 0x61, 0x64, 0x64, 0x69,
7555f15d151b5101fadfe6cba1e8f4aa6367e8c603eJoe Onorato     0x6e, 0x67, 0x5f, 0x00, 0x44, 0x61, 0x74, 0x61,
7565f15d151b5101fadfe6cba1e8f4aa6367e8c603eJoe Onorato     0x0c, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00,
7574535e40544aeb957d44fad75fbe5676effe03689Joe Onorato     0x70, 0x61, 0x64, 0x64, 0x65, 0x64, 0x5f, 0x74,
7584535e40544aeb957d44fad75fbe5676effe03689Joe Onorato     0x6f, 0x5f, 0x5f, 0x33, 0x00, 0xbc, 0xbc, 0xbc,
7594535e40544aeb957d44fad75fbe5676effe03689Joe Onorato     0x70, 0x61, 0x64, 0x64, 0x65, 0x64, 0x5f, 0x74,
7605f15d151b5101fadfe6cba1e8f4aa6367e8c603eJoe Onorato     0x6f, 0x5f, 0x5f, 0x33, 0x00, 0xbc, 0xbc, 0xbc,
7612e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato     0x44, 0x61, 0x74, 0x61, 0x0d, 0x00, 0x00, 0x00,
7622e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato     0x0e, 0x00, 0x00, 0x00, 0x70, 0x61, 0x64, 0x64,
7632e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato     0x65, 0x64, 0x5f, 0x74, 0x6f, 0x5f, 0x32, 0x5f,
7642e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato     0x5f, 0x00, 0xbc, 0xbc, 0x70, 0x61, 0x64, 0x64,
7652e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato     0x65, 0x64, 0x5f, 0x74, 0x6f, 0x5f, 0x32, 0x5f,
7665f15d151b5101fadfe6cba1e8f4aa6367e8c603eJoe Onorato     0x5f, 0x00, 0xbc, 0xbc, 0x44, 0x61, 0x74, 0x61,
7674535e40544aeb957d44fad75fbe5676effe03689Joe Onorato     0x0a, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00,
7684535e40544aeb957d44fad75fbe5676effe03689Joe Onorato     0x70, 0x61, 0x64, 0x64, 0x65, 0x64, 0x5f, 0x74,
7694535e40544aeb957d44fad75fbe5676effe03689Joe Onorato     0x6f, 0x31, 0x00, 0xbc, 0x70, 0x61, 0x64, 0x64,
7705f15d151b5101fadfe6cba1e8f4aa6367e8c603eJoe Onorato     0x65, 0x64, 0x5f, 0x74, 0x6f, 0x31, 0x00
7715f15d151b5101fadfe6cba1e8f4aa6367e8c603eJoe Onorato
7724535e40544aeb957d44fad75fbe5676effe03689Joe Onorato};
7734535e40544aeb957d44fad75fbe5676effe03689Joe Onoratoconst int DATA_GOLDEN_FILE_SIZE = sizeof(DATA_GOLDEN_FILE);
7744535e40544aeb957d44fad75fbe5676effe03689Joe Onorato
7754535e40544aeb957d44fad75fbe5676effe03689Joe Onoratostatic int
7764535e40544aeb957d44fad75fbe5676effe03689Joe Onoratotest_write_header_and_entity(BackupDataWriter& writer, const char* str)
7774535e40544aeb957d44fad75fbe5676effe03689Joe Onorato{
7784535e40544aeb957d44fad75fbe5676effe03689Joe Onorato    int err;
7794535e40544aeb957d44fad75fbe5676effe03689Joe Onorato    String8 text(str);
7804535e40544aeb957d44fad75fbe5676effe03689Joe Onorato
7814535e40544aeb957d44fad75fbe5676effe03689Joe Onorato    err = writer.WriteEntityHeader(text, text.length()+1);
7824535e40544aeb957d44fad75fbe5676effe03689Joe Onorato    if (err != 0) {
7834535e40544aeb957d44fad75fbe5676effe03689Joe Onorato        fprintf(stderr, "WriteEntityHeader failed with %s\n", strerror(err));
7844535e40544aeb957d44fad75fbe5676effe03689Joe Onorato        return err;
7854535e40544aeb957d44fad75fbe5676effe03689Joe Onorato    }
7864535e40544aeb957d44fad75fbe5676effe03689Joe Onorato
7874535e40544aeb957d44fad75fbe5676effe03689Joe Onorato    err = writer.WriteEntityData(text.string(), text.length()+1);
7884535e40544aeb957d44fad75fbe5676effe03689Joe Onorato    if (err != 0) {
7894535e40544aeb957d44fad75fbe5676effe03689Joe Onorato        fprintf(stderr, "write failed for data '%s'\n", text.string());
7904535e40544aeb957d44fad75fbe5676effe03689Joe Onorato        return errno;
7914535e40544aeb957d44fad75fbe5676effe03689Joe Onorato    }
7924535e40544aeb957d44fad75fbe5676effe03689Joe Onorato
7934535e40544aeb957d44fad75fbe5676effe03689Joe Onorato    return err;
7944535e40544aeb957d44fad75fbe5676effe03689Joe Onorato}
7954535e40544aeb957d44fad75fbe5676effe03689Joe Onorato
7964535e40544aeb957d44fad75fbe5676effe03689Joe Onoratoint
7974535e40544aeb957d44fad75fbe5676effe03689Joe Onoratobackup_helper_test_data_writer()
7984535e40544aeb957d44fad75fbe5676effe03689Joe Onorato{
7994535e40544aeb957d44fad75fbe5676effe03689Joe Onorato    int err;
8004535e40544aeb957d44fad75fbe5676effe03689Joe Onorato    int fd;
8014535e40544aeb957d44fad75fbe5676effe03689Joe Onorato    const char* filename = SCRATCH_DIR "data_writer.data";
8024535e40544aeb957d44fad75fbe5676effe03689Joe Onorato
8034535e40544aeb957d44fad75fbe5676effe03689Joe Onorato    system("rm -r " SCRATCH_DIR);
8044535e40544aeb957d44fad75fbe5676effe03689Joe Onorato    mkdir(SCRATCH_DIR, 0777);
8054535e40544aeb957d44fad75fbe5676effe03689Joe Onorato    mkdir(SCRATCH_DIR "data", 0777);
806f4c46b94b867f6a01bf7d0be18f667819338072fNicolas Catania
8074535e40544aeb957d44fad75fbe5676effe03689Joe Onorato    fd = creat(filename, 0666);
8084535e40544aeb957d44fad75fbe5676effe03689Joe Onorato    if (fd == -1) {
8094535e40544aeb957d44fad75fbe5676effe03689Joe Onorato        fprintf(stderr, "error creating: %s\n", strerror(errno));
8104535e40544aeb957d44fad75fbe5676effe03689Joe Onorato        return errno;
8114535e40544aeb957d44fad75fbe5676effe03689Joe Onorato    }
8124535e40544aeb957d44fad75fbe5676effe03689Joe Onorato
8134535e40544aeb957d44fad75fbe5676effe03689Joe Onorato    BackupDataWriter writer(fd);
8144535e40544aeb957d44fad75fbe5676effe03689Joe Onorato
8154535e40544aeb957d44fad75fbe5676effe03689Joe Onorato    err = 0;
8164535e40544aeb957d44fad75fbe5676effe03689Joe Onorato    err |= test_write_header_and_entity(writer, "no_padding_");
8174535e40544aeb957d44fad75fbe5676effe03689Joe Onorato    err |= test_write_header_and_entity(writer, "padded_to__3");
8184535e40544aeb957d44fad75fbe5676effe03689Joe Onorato    err |= test_write_header_and_entity(writer, "padded_to_2__");
8194535e40544aeb957d44fad75fbe5676effe03689Joe Onorato    err |= test_write_header_and_entity(writer, "padded_to1");
8204535e40544aeb957d44fad75fbe5676effe03689Joe Onorato
8214535e40544aeb957d44fad75fbe5676effe03689Joe Onorato    close(fd);
8224535e40544aeb957d44fad75fbe5676effe03689Joe Onorato
8234535e40544aeb957d44fad75fbe5676effe03689Joe Onorato    err = compare_file(filename, DATA_GOLDEN_FILE, DATA_GOLDEN_FILE_SIZE);
8244535e40544aeb957d44fad75fbe5676effe03689Joe Onorato    if (err != 0) {
8254535e40544aeb957d44fad75fbe5676effe03689Joe Onorato        return err;
8264535e40544aeb957d44fad75fbe5676effe03689Joe Onorato    }
8274535e40544aeb957d44fad75fbe5676effe03689Joe Onorato
8284535e40544aeb957d44fad75fbe5676effe03689Joe Onorato    return err;
8294535e40544aeb957d44fad75fbe5676effe03689Joe Onorato}
8304535e40544aeb957d44fad75fbe5676effe03689Joe Onorato
8312e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onoratoint
8322e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onoratotest_read_header_and_entity(BackupDataReader& reader, const char* str)
8332e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato{
8342e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    int err;
8352e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    int bufSize = strlen(str)+1;
8362e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    char* buf = (char*)malloc(bufSize);
8372e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    String8 string;
8382e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    int cookie = 0x11111111;
8392e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    size_t actualSize;
8405f15d151b5101fadfe6cba1e8f4aa6367e8c603eJoe Onorato    bool done;
8415f15d151b5101fadfe6cba1e8f4aa6367e8c603eJoe Onorato    int type;
8422e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato
8432e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    // printf("\n\n---------- test_read_header_and_entity -- %s\n\n", str);
8442e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato
8455f15d151b5101fadfe6cba1e8f4aa6367e8c603eJoe Onorato    err = reader.ReadNextHeader(&done, &type);
8465f15d151b5101fadfe6cba1e8f4aa6367e8c603eJoe Onorato    if (done) {
8475f15d151b5101fadfe6cba1e8f4aa6367e8c603eJoe Onorato        fprintf(stderr, "should not be done yet\n");
8485f15d151b5101fadfe6cba1e8f4aa6367e8c603eJoe Onorato        goto finished;
8492e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    }
8502e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    if (err != 0) {
8515f15d151b5101fadfe6cba1e8f4aa6367e8c603eJoe Onorato        fprintf(stderr, "ReadNextHeader (for app header) failed with %s\n", strerror(err));
8525f15d151b5101fadfe6cba1e8f4aa6367e8c603eJoe Onorato        goto finished;
8532e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    }
8545f15d151b5101fadfe6cba1e8f4aa6367e8c603eJoe Onorato    if (type != BACKUP_HEADER_ENTITY_V1) {
8552e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato        err = EINVAL;
8565f15d151b5101fadfe6cba1e8f4aa6367e8c603eJoe Onorato        fprintf(stderr, "type=0x%08x expected 0x%08x\n", type, BACKUP_HEADER_ENTITY_V1);
8572e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    }
8582e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato
8592e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    err = reader.ReadEntityHeader(&string, &actualSize);
8602e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    if (err != 0) {
8612e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato        fprintf(stderr, "ReadEntityHeader failed with %s\n", strerror(err));
8625f15d151b5101fadfe6cba1e8f4aa6367e8c603eJoe Onorato        goto finished;
8632e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    }
8642e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    if (string != str) {
8652e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato        fprintf(stderr, "ReadEntityHeader expected key '%s' got '%s'\n", str, string.string());
8662e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato        err = EINVAL;
8675f15d151b5101fadfe6cba1e8f4aa6367e8c603eJoe Onorato        goto finished;
8682e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    }
8692e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    if ((int)actualSize != bufSize) {
8702e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato        fprintf(stderr, "ReadEntityHeader expected dataSize 0x%08x got 0x%08x\n", bufSize,
8712e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato                actualSize);
8722e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato        err = EINVAL;
8735f15d151b5101fadfe6cba1e8f4aa6367e8c603eJoe Onorato        goto finished;
8742e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    }
8752e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato
8762e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    err = reader.ReadEntityData(buf, bufSize);
8772e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    if (err != NO_ERROR) {
8782e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato        fprintf(stderr, "ReadEntityData failed with %s\n", strerror(err));
8795f15d151b5101fadfe6cba1e8f4aa6367e8c603eJoe Onorato        goto finished;
8802e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    }
8812e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato
8822e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    if (0 != memcmp(buf, str, bufSize)) {
8832e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato        fprintf(stderr, "ReadEntityData expected '%s' but got something starting with "
8845f15d151b5101fadfe6cba1e8f4aa6367e8c603eJoe Onorato                "%02x %02x %02x %02x  '%c%c%c%c'\n", str, buf[0], buf[1], buf[2], buf[3],
8855f15d151b5101fadfe6cba1e8f4aa6367e8c603eJoe Onorato                buf[0], buf[1], buf[2], buf[3]);
8862e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato        err = EINVAL;
8875f15d151b5101fadfe6cba1e8f4aa6367e8c603eJoe Onorato        goto finished;
8882e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    }
8892e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato
8902e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    // The next read will confirm whether it got the right amount of data.
8912e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato
8925f15d151b5101fadfe6cba1e8f4aa6367e8c603eJoe Onoratofinished:
8932e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    if (err != NO_ERROR) {
8942e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato        fprintf(stderr, "test_read_header_and_entity failed with %s\n", strerror(err));
8952e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    }
8962e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    free(buf);
8972e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    return err;
8982e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato}
8992e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato
9002e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onoratoint
9012e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onoratobackup_helper_test_data_reader()
9022e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato{
9032e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    int err;
9042e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    int fd;
9052e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    const char* filename = SCRATCH_DIR "data_reader.data";
9062e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato
9072e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    system("rm -r " SCRATCH_DIR);
9082e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    mkdir(SCRATCH_DIR, 0777);
9092e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    mkdir(SCRATCH_DIR "data", 0777);
910f4c46b94b867f6a01bf7d0be18f667819338072fNicolas Catania
9112e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    fd = creat(filename, 0666);
9122e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    if (fd == -1) {
9132e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato        fprintf(stderr, "error creating: %s\n", strerror(errno));
9142e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato        return errno;
9152e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    }
9162e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato
9172e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    err = write(fd, DATA_GOLDEN_FILE, DATA_GOLDEN_FILE_SIZE);
9182e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    if (err != DATA_GOLDEN_FILE_SIZE) {
9192e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato        fprintf(stderr, "Error \"%s\" writing golden file %s\n", strerror(errno), filename);
9202e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato        return errno;
9212e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    }
9222e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato
9232e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    close(fd);
9242e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato
9252e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    fd = open(filename, O_RDONLY);
9262e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    if (fd == -1) {
9272e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato        fprintf(stderr, "Error \"%s\" opening golden file %s for read\n", strerror(errno),
9282e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato                filename);
9292e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato        return errno;
9302e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    }
9312e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato
9322e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    {
9332e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato        BackupDataReader reader(fd);
9342e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato
9352e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato        err = 0;
9362e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato
9372e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato        if (err == NO_ERROR) {
9382e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato            err = test_read_header_and_entity(reader, "no_padding_");
9392e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato        }
9402e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato
9412e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato        if (err == NO_ERROR) {
9422e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato            err = test_read_header_and_entity(reader, "padded_to__3");
9432e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato        }
9442e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato
9452e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato        if (err == NO_ERROR) {
9462e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato            err = test_read_header_and_entity(reader, "padded_to_2__");
9472e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato        }
9482e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato
9492e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato        if (err == NO_ERROR) {
9502e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato            err = test_read_header_and_entity(reader, "padded_to1");
9512e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato        }
9522e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    }
9532e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato
9542e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    close(fd);
9552e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato
9562e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato    return err;
9572e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato}
9582e1da32203b7f6df76023f25a7382a31fad6b19dJoe Onorato
9593ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onoratostatic int
9603ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onoratoget_mod_time(const char* filename, struct timeval times[2])
9613ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato{
9623ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    int err;
9633ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    struct stat64 st;
9643ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    err = stat64(filename, &st);
9653ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    if (err != 0) {
9663ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        fprintf(stderr, "stat '%s' failed: %s\n", filename, strerror(errno));
9673ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        return errno;
9683ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    }
9693ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    times[0].tv_sec = st.st_atime;
9703ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    times[1].tv_sec = st.st_mtime;
971f4c46b94b867f6a01bf7d0be18f667819338072fNicolas Catania
972f4c46b94b867f6a01bf7d0be18f667819338072fNicolas Catania    // If st_atime is a macro then struct stat64 uses struct timespec
973f4c46b94b867f6a01bf7d0be18f667819338072fNicolas Catania    // to store the access and modif time values and typically
974f4c46b94b867f6a01bf7d0be18f667819338072fNicolas Catania    // st_*time_nsec is not defined. In glibc, this is controlled by
975f4c46b94b867f6a01bf7d0be18f667819338072fNicolas Catania    // __USE_MISC.
976f4c46b94b867f6a01bf7d0be18f667819338072fNicolas Catania#ifdef __USE_MISC
977f4c46b94b867f6a01bf7d0be18f667819338072fNicolas Catania#if !defined(st_atime) || defined(st_atime_nsec)
978f4c46b94b867f6a01bf7d0be18f667819338072fNicolas Catania#error "Check if this __USE_MISC conditional is still needed."
979f4c46b94b867f6a01bf7d0be18f667819338072fNicolas Catania#endif
980f4c46b94b867f6a01bf7d0be18f667819338072fNicolas Catania    times[0].tv_usec = st.st_atim.tv_nsec / 1000;
981f4c46b94b867f6a01bf7d0be18f667819338072fNicolas Catania    times[1].tv_usec = st.st_mtim.tv_nsec / 1000;
982f4c46b94b867f6a01bf7d0be18f667819338072fNicolas Catania#else
983f4c46b94b867f6a01bf7d0be18f667819338072fNicolas Catania    times[0].tv_usec = st.st_atime_nsec / 1000;
9843ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    times[1].tv_usec = st.st_mtime_nsec / 1000;
985f4c46b94b867f6a01bf7d0be18f667819338072fNicolas Catania#endif
986f4c46b94b867f6a01bf7d0be18f667819338072fNicolas Catania
9873ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    return 0;
9883ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato}
9893ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
9903ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onoratoint
9913ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onoratobackup_helper_test_files()
9923ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato{
9933ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    int err;
9943ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    int oldSnapshotFD;
9954535e40544aeb957d44fad75fbe5676effe03689Joe Onorato    int dataStreamFD;
9964535e40544aeb957d44fad75fbe5676effe03689Joe Onorato    int newSnapshotFD;
9973ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
9983ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    system("rm -r " SCRATCH_DIR);
9993ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    mkdir(SCRATCH_DIR, 0777);
10003ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    mkdir(SCRATCH_DIR "data", 0777);
10013ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
10023ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    write_text_file(SCRATCH_DIR "data/b", "b\nbb\n");
10033ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    write_text_file(SCRATCH_DIR "data/c", "c\ncc\n");
10043ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    write_text_file(SCRATCH_DIR "data/d", "d\ndd\n");
10053ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    write_text_file(SCRATCH_DIR "data/e", "e\nee\n");
10063ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    write_text_file(SCRATCH_DIR "data/f", "f\nff\n");
10073ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    write_text_file(SCRATCH_DIR "data/h", "h\nhh\n");
10083ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
10093ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    char const* files_before[] = {
101023ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato        SCRATCH_DIR "data/b",
101123ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato        SCRATCH_DIR "data/c",
101223ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato        SCRATCH_DIR "data/d",
101323ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato        SCRATCH_DIR "data/e",
101423ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato        SCRATCH_DIR "data/f"
101523ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato    };
101623ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato
101723ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato    char const* keys_before[] = {
10183ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        "data/b",
10193ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        "data/c",
10203ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        "data/d",
10213ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        "data/e",
10223ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        "data/f"
10233ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    };
10243ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
10254535e40544aeb957d44fad75fbe5676effe03689Joe Onorato    dataStreamFD = creat(SCRATCH_DIR "1.data", 0666);
10264535e40544aeb957d44fad75fbe5676effe03689Joe Onorato    if (dataStreamFD == -1) {
10274535e40544aeb957d44fad75fbe5676effe03689Joe Onorato        fprintf(stderr, "error creating: %s\n", strerror(errno));
10284535e40544aeb957d44fad75fbe5676effe03689Joe Onorato        return errno;
10294535e40544aeb957d44fad75fbe5676effe03689Joe Onorato    }
10304535e40544aeb957d44fad75fbe5676effe03689Joe Onorato
10313ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    newSnapshotFD = creat(SCRATCH_DIR "before.snap", 0666);
10323ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    if (newSnapshotFD == -1) {
10333ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        fprintf(stderr, "error creating: %s\n", strerror(errno));
10343ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        return errno;
10353ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    }
1036d2110dbce071a236b6176de344ca797b737542ebJoe Onorato
1037d2110dbce071a236b6176de344ca797b737542ebJoe Onorato    {
1038d2110dbce071a236b6176de344ca797b737542ebJoe Onorato        BackupDataWriter dataStream(dataStreamFD);
1039f4c46b94b867f6a01bf7d0be18f667819338072fNicolas Catania
104023ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato        err = back_up_files(-1, &dataStream, newSnapshotFD, files_before, keys_before, 5);
1041d2110dbce071a236b6176de344ca797b737542ebJoe Onorato        if (err != 0) {
1042d2110dbce071a236b6176de344ca797b737542ebJoe Onorato            return err;
1043d2110dbce071a236b6176de344ca797b737542ebJoe Onorato        }
10443ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    }
10453ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
10464535e40544aeb957d44fad75fbe5676effe03689Joe Onorato    close(dataStreamFD);
10473ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    close(newSnapshotFD);
10483ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
10493ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    sleep(3);
10503ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
10513ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    struct timeval d_times[2];
10523ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    struct timeval e_times[2];
10533ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
10543ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    err = get_mod_time(SCRATCH_DIR "data/d", d_times);
10553ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    err |= get_mod_time(SCRATCH_DIR "data/e", e_times);
10563ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    if (err != 0) {
10573ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        return err;
10583ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    }
10593ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
10603ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    write_text_file(SCRATCH_DIR "data/a", "a\naa\n");
10613ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    unlink(SCRATCH_DIR "data/c");
10623ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    write_text_file(SCRATCH_DIR "data/c", "c\ncc\n");
10633ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    write_text_file(SCRATCH_DIR "data/d", "dd\ndd\n");
10643ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    utimes(SCRATCH_DIR "data/d", d_times);
10653ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    write_text_file(SCRATCH_DIR "data/e", "z\nzz\n");
10663ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    utimes(SCRATCH_DIR "data/e", e_times);
10673ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    write_text_file(SCRATCH_DIR "data/g", "g\ngg\n");
10683ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    unlink(SCRATCH_DIR "data/f");
1069f4c46b94b867f6a01bf7d0be18f667819338072fNicolas Catania
10703ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    char const* files_after[] = {
107123ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato        SCRATCH_DIR "data/a", // added
107223ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato        SCRATCH_DIR "data/b", // same
107323ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato        SCRATCH_DIR "data/c", // different mod time
107423ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato        SCRATCH_DIR "data/d", // different size (same mod time)
107523ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato        SCRATCH_DIR "data/e", // different contents (same mod time, same size)
107623ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato        SCRATCH_DIR "data/g"  // added
107723ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato    };
107823ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato
107923ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato    char const* keys_after[] = {
10803ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        "data/a", // added
10813ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        "data/b", // same
10823ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        "data/c", // different mod time
10833ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        "data/d", // different size (same mod time)
10843ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        "data/e", // different contents (same mod time, same size)
10853ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        "data/g"  // added
10863ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    };
10873ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
10883ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    oldSnapshotFD = open(SCRATCH_DIR "before.snap", O_RDONLY);
10893ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    if (oldSnapshotFD == -1) {
10903ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        fprintf(stderr, "error opening: %s\n", strerror(errno));
10913ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        return errno;
10923ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    }
10933ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
10944535e40544aeb957d44fad75fbe5676effe03689Joe Onorato    dataStreamFD = creat(SCRATCH_DIR "2.data", 0666);
10954535e40544aeb957d44fad75fbe5676effe03689Joe Onorato    if (dataStreamFD == -1) {
10964535e40544aeb957d44fad75fbe5676effe03689Joe Onorato        fprintf(stderr, "error creating: %s\n", strerror(errno));
10974535e40544aeb957d44fad75fbe5676effe03689Joe Onorato        return errno;
10984535e40544aeb957d44fad75fbe5676effe03689Joe Onorato    }
10994535e40544aeb957d44fad75fbe5676effe03689Joe Onorato
11003ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    newSnapshotFD = creat(SCRATCH_DIR "after.snap", 0666);
11013ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    if (newSnapshotFD == -1) {
11023ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        fprintf(stderr, "error creating: %s\n", strerror(errno));
11033ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato        return errno;
11043ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    }
11053ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
1106d2110dbce071a236b6176de344ca797b737542ebJoe Onorato    {
1107d2110dbce071a236b6176de344ca797b737542ebJoe Onorato        BackupDataWriter dataStream(dataStreamFD);
1108f4c46b94b867f6a01bf7d0be18f667819338072fNicolas Catania
110923ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato        err = back_up_files(oldSnapshotFD, &dataStream, newSnapshotFD, files_after, keys_after, 6);
1110d2110dbce071a236b6176de344ca797b737542ebJoe Onorato        if (err != 0) {
1111d2110dbce071a236b6176de344ca797b737542ebJoe Onorato            return err;
1112d2110dbce071a236b6176de344ca797b737542ebJoe Onorato        }
1113d2110dbce071a236b6176de344ca797b737542ebJoe Onorato}
11143ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
11153ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    close(oldSnapshotFD);
11164535e40544aeb957d44fad75fbe5676effe03689Joe Onorato    close(dataStreamFD);
11173ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    close(newSnapshotFD);
1118f4c46b94b867f6a01bf7d0be18f667819338072fNicolas Catania
11193ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato    return 0;
11203ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato}
11213ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato
112223ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onoratoint
112323ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onoratobackup_helper_test_null_base()
112423ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato{
112523ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato    int err;
112623ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato    int oldSnapshotFD;
112723ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato    int dataStreamFD;
112823ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato    int newSnapshotFD;
112923ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato
113023ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato    system("rm -r " SCRATCH_DIR);
113123ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato    mkdir(SCRATCH_DIR, 0777);
113223ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato    mkdir(SCRATCH_DIR "data", 0777);
113323ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato
113423ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato    write_text_file(SCRATCH_DIR "data/a", "a\naa\n");
113523ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato
113623ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato    char const* files[] = {
113723ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato        SCRATCH_DIR "data/a",
113823ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato    };
113923ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato
114023ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato    char const* keys[] = {
114123ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato        "a",
114223ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato    };
114323ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato
114423ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato    dataStreamFD = creat(SCRATCH_DIR "null_base.data", 0666);
114523ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato    if (dataStreamFD == -1) {
114623ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato        fprintf(stderr, "error creating: %s\n", strerror(errno));
114723ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato        return errno;
114823ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato    }
114923ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato
115023ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato    newSnapshotFD = creat(SCRATCH_DIR "null_base.snap", 0666);
115123ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato    if (newSnapshotFD == -1) {
115223ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato        fprintf(stderr, "error creating: %s\n", strerror(errno));
115323ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato        return errno;
115423ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato    }
115523ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato
115623ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato    {
115723ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato        BackupDataWriter dataStream(dataStreamFD);
115823ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato
115923ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato        err = back_up_files(-1, &dataStream, newSnapshotFD, files, keys, 1);
116023ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato        if (err != 0) {
116123ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato            return err;
116223ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato        }
116323ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato    }
116423ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato
116523ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato    close(dataStreamFD);
116623ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato    close(newSnapshotFD);
116723ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato
116823ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato    return 0;
116923ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato}
117023ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato
1171ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onoratoint
1172ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onoratobackup_helper_test_missing_file()
1173ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato{
1174ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato    int err;
1175ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato    int oldSnapshotFD;
1176ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato    int dataStreamFD;
1177ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato    int newSnapshotFD;
1178ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato
1179ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato    system("rm -r " SCRATCH_DIR);
1180ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato    mkdir(SCRATCH_DIR, 0777);
1181ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato    mkdir(SCRATCH_DIR "data", 0777);
1182ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato
1183ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato    write_text_file(SCRATCH_DIR "data/b", "b\nbb\n");
1184ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato
1185ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato    char const* files[] = {
1186ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato        SCRATCH_DIR "data/a",
1187ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato        SCRATCH_DIR "data/b",
1188ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato        SCRATCH_DIR "data/c",
1189ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato    };
1190ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato
1191ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato    char const* keys[] = {
1192ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato        "a",
1193ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato        "b",
1194ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato        "c",
1195ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato    };
1196ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato
1197ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato    dataStreamFD = creat(SCRATCH_DIR "null_base.data", 0666);
1198ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato    if (dataStreamFD == -1) {
1199ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato        fprintf(stderr, "error creating: %s\n", strerror(errno));
1200ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato        return errno;
1201ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato    }
1202ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato
1203ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato    newSnapshotFD = creat(SCRATCH_DIR "null_base.snap", 0666);
1204ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato    if (newSnapshotFD == -1) {
1205ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato        fprintf(stderr, "error creating: %s\n", strerror(errno));
1206ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato        return errno;
1207ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato    }
1208ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato
1209ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato    {
1210ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato        BackupDataWriter dataStream(dataStreamFD);
1211ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato
1212ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato        err = back_up_files(-1, &dataStream, newSnapshotFD, files, keys, 1);
1213ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato        if (err != 0) {
1214ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato            return err;
1215ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato        }
1216ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato    }
1217ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato
1218ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato    close(dataStreamFD);
1219ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato    close(newSnapshotFD);
1220ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato
1221ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato    return 0;
1222ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato}
1223ce88cb15b52998e16c3ba548a4ec49117a835e21Joe Onorato
122423ecae3bbb60c5af940f3a22170d75eb6ac05b69Joe Onorato
12253ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato#endif // TEST_BACKUP_HELPERS
12264535e40544aeb957d44fad75fbe5676effe03689Joe Onorato
12274535e40544aeb957d44fad75fbe5676effe03689Joe Onorato}
1228