1/*
2 * Copyright (C) 2009 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#ifndef _UTILS_BACKUP_HELPERS_H
18#define _UTILS_BACKUP_HELPERS_H
19
20#include <sys/stat.h>
21
22#include <utils/Errors.h>
23#include <utils/String8.h>
24#include <utils/KeyedVector.h>
25
26namespace android {
27
28enum {
29    BACKUP_HEADER_ENTITY_V1 = 0x61746144, // Data (little endian)
30};
31
32typedef struct {
33    int type; // BACKUP_HEADER_ENTITY_V1
34    int keyLen; // length of the key name, not including the null terminator
35    int dataSize; // size of the data, not including the padding, -1 means delete
36} entity_header_v1;
37
38struct SnapshotHeader {
39    int magic0;
40    int fileCount;
41    int magic1;
42    int totalSize;
43};
44
45struct FileState {
46    int modTime_sec;
47    int modTime_nsec;
48    int mode;
49    int size;
50    int crc32;
51    int nameLen;
52};
53
54struct FileRec {
55    String8 file;
56    bool deleted;
57    FileState s;
58};
59
60
61/**
62 * Writes the data.
63 *
64 * If an error occurs, it poisons this object and all write calls will fail
65 * with the error that occurred.
66 */
67class BackupDataWriter
68{
69public:
70    BackupDataWriter(int fd);
71    // does not close fd
72    ~BackupDataWriter();
73
74    status_t WriteEntityHeader(const String8& key, size_t dataSize);
75
76    /* Note: WriteEntityData will write arbitrary data into the file without
77     * validation or a previously-supplied header.  The full backup implementation
78     * uses it this way to generate a controlled binary stream that is not
79     * entity-structured.  If the implementation here is changed, either this
80     * use case must remain valid, or the full backup implementation should be
81     * adjusted to use some other appropriate mechanism.
82     */
83    status_t WriteEntityData(const void* data, size_t size);
84
85    void SetKeyPrefix(const String8& keyPrefix);
86
87private:
88    explicit BackupDataWriter();
89    status_t write_padding_for(int n);
90
91    int m_fd;
92    status_t m_status;
93    ssize_t m_pos;
94    int m_entityCount;
95    String8 m_keyPrefix;
96};
97
98/**
99 * Reads the data.
100 *
101 * If an error occurs, it poisons this object and all write calls will fail
102 * with the error that occurred.
103 */
104class BackupDataReader
105{
106public:
107    BackupDataReader(int fd);
108    // does not close fd
109    ~BackupDataReader();
110
111    status_t Status();
112    status_t ReadNextHeader(bool* done, int* type);
113
114    bool HasEntities();
115    status_t ReadEntityHeader(String8* key, size_t* dataSize);
116    status_t SkipEntityData(); // must be called with the pointer at the beginning of the data.
117    ssize_t ReadEntityData(void* data, size_t size);
118
119private:
120    explicit BackupDataReader();
121    status_t skip_padding();
122
123    int m_fd;
124    bool m_done;
125    status_t m_status;
126    ssize_t m_pos;
127    ssize_t m_dataEndPos;
128    int m_entityCount;
129    union {
130        int type;
131        entity_header_v1 entity;
132    } m_header;
133    String8 m_key;
134};
135
136int back_up_files(int oldSnapshotFD, BackupDataWriter* dataStream, int newSnapshotFD,
137        char const* const* files, char const* const *keys, int fileCount);
138
139int write_tarfile(const String8& packageName, const String8& domain,
140        const String8& rootPath, const String8& filePath, off_t* outSize,
141        BackupDataWriter* outputStream);
142
143class RestoreHelperBase
144{
145public:
146    RestoreHelperBase();
147    ~RestoreHelperBase();
148
149    status_t WriteFile(const String8& filename, BackupDataReader* in);
150    status_t WriteSnapshot(int fd);
151
152private:
153    void* m_buf;
154    bool m_loggedUnknownMetadata;
155    KeyedVector<String8,FileRec> m_files;
156};
157
158//#define TEST_BACKUP_HELPERS 1
159
160#if TEST_BACKUP_HELPERS
161int backup_helper_test_empty();
162int backup_helper_test_four();
163int backup_helper_test_files();
164int backup_helper_test_null_base();
165int backup_helper_test_missing_file();
166int backup_helper_test_data_writer();
167int backup_helper_test_data_reader();
168#endif
169
170} // namespace android
171
172#endif // _UTILS_BACKUP_HELPERS_H
173