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