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 
26 namespace android {
27 
28 enum {
29     BACKUP_HEADER_ENTITY_V1 = 0x61746144, // Data (little endian)
30 };
31 
32 typedef 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 
38 struct SnapshotHeader {
39     int magic0;
40     int fileCount;
41     int magic1;
42     int totalSize;
43 };
44 
45 struct FileState {
46     int modTime_sec;
47     int modTime_nsec;
48     int mode;
49     int size;
50     int crc32;
51     int nameLen;
52 };
53 
54 struct 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  */
67 class BackupDataWriter
68 {
69 public:
70     explicit 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 
87 private:
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  */
104 class BackupDataReader
105 {
106 public:
107     explicit 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 
119 private:
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 
136 int back_up_files(int oldSnapshotFD, BackupDataWriter* dataStream, int newSnapshotFD,
137         char const* const* files, char const* const *keys, int fileCount);
138 
139 int write_tarfile(const String8& packageName, const String8& domain,
140         const String8& rootPath, const String8& filePath, off_t* outSize,
141         BackupDataWriter* outputStream);
142 
143 class RestoreHelperBase
144 {
145 public:
146     RestoreHelperBase();
147     ~RestoreHelperBase();
148 
149     status_t WriteFile(const String8& filename, BackupDataReader* in);
150     status_t WriteSnapshot(int fd);
151 
152 private:
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
161 int backup_helper_test_empty();
162 int backup_helper_test_four();
163 int backup_helper_test_files();
164 int backup_helper_test_null_base();
165 int backup_helper_test_missing_file();
166 int backup_helper_test_data_writer();
167 int backup_helper_test_data_reader();
168 #endif
169 
170 } // namespace android
171 
172 #endif // _UTILS_BACKUP_HELPERS_H
173