116c4d154dca43c662571129af31b27433b919a32Adam Lesinski/*
216c4d154dca43c662571129af31b27433b919a32Adam Lesinski * Copyright (C) 2009 The Android Open Source Project
316c4d154dca43c662571129af31b27433b919a32Adam Lesinski *
416c4d154dca43c662571129af31b27433b919a32Adam Lesinski * Licensed under the Apache License, Version 2.0 (the "License");
516c4d154dca43c662571129af31b27433b919a32Adam Lesinski * you may not use this file except in compliance with the License.
616c4d154dca43c662571129af31b27433b919a32Adam Lesinski * You may obtain a copy of the License at
716c4d154dca43c662571129af31b27433b919a32Adam Lesinski *
816c4d154dca43c662571129af31b27433b919a32Adam Lesinski *      http://www.apache.org/licenses/LICENSE-2.0
916c4d154dca43c662571129af31b27433b919a32Adam Lesinski *
1016c4d154dca43c662571129af31b27433b919a32Adam Lesinski * Unless required by applicable law or agreed to in writing, software
1116c4d154dca43c662571129af31b27433b919a32Adam Lesinski * distributed under the License is distributed on an "AS IS" BASIS,
1216c4d154dca43c662571129af31b27433b919a32Adam Lesinski * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1316c4d154dca43c662571129af31b27433b919a32Adam Lesinski * See the License for the specific language governing permissions and
1416c4d154dca43c662571129af31b27433b919a32Adam Lesinski * limitations under the License.
1516c4d154dca43c662571129af31b27433b919a32Adam Lesinski */
1616c4d154dca43c662571129af31b27433b919a32Adam Lesinski
1716c4d154dca43c662571129af31b27433b919a32Adam Lesinski#define LOG_TAG "backup_data"
1816c4d154dca43c662571129af31b27433b919a32Adam Lesinski
1916c4d154dca43c662571129af31b27433b919a32Adam Lesinski#include <stdio.h>
2016c4d154dca43c662571129af31b27433b919a32Adam Lesinski#include <string.h>
2116c4d154dca43c662571129af31b27433b919a32Adam Lesinski#include <unistd.h>
2216c4d154dca43c662571129af31b27433b919a32Adam Lesinski
2352eb4e01a49fe2e94555c000de38bbcbbb13401bMark Salyzyn#include <androidfw/BackupHelpers.h>
2452eb4e01a49fe2e94555c000de38bbcbbb13401bMark Salyzyn#include <log/log.h>
2552eb4e01a49fe2e94555c000de38bbcbbb13401bMark Salyzyn#include <utils/ByteOrder.h>
2616c4d154dca43c662571129af31b27433b919a32Adam Lesinski
2716c4d154dca43c662571129af31b27433b919a32Adam Lesinskinamespace android {
2816c4d154dca43c662571129af31b27433b919a32Adam Lesinski
292204f0bf56af53b588a01701b8cf9cd05b1b3ff9Andreas Gampestatic const bool kIsDebug = false;
3016c4d154dca43c662571129af31b27433b919a32Adam Lesinski
3116c4d154dca43c662571129af31b27433b919a32Adam Lesinski/*
3216c4d154dca43c662571129af31b27433b919a32Adam Lesinski * File Format (v1):
3316c4d154dca43c662571129af31b27433b919a32Adam Lesinski *
3416c4d154dca43c662571129af31b27433b919a32Adam Lesinski * All ints are stored little-endian.
3516c4d154dca43c662571129af31b27433b919a32Adam Lesinski *
3616c4d154dca43c662571129af31b27433b919a32Adam Lesinski *  - An app_header_v1 struct.
3716c4d154dca43c662571129af31b27433b919a32Adam Lesinski *  - The name of the package, utf-8, null terminated, padded to 4-byte boundary.
3816c4d154dca43c662571129af31b27433b919a32Adam Lesinski *  - A sequence of zero or more key/value paires (entities), each with
3916c4d154dca43c662571129af31b27433b919a32Adam Lesinski *      - A entity_header_v1 struct
4016c4d154dca43c662571129af31b27433b919a32Adam Lesinski *      - The key, utf-8, null terminated, padded to 4-byte boundary.
4116c4d154dca43c662571129af31b27433b919a32Adam Lesinski *      - The value, padded to 4 byte boundary
4216c4d154dca43c662571129af31b27433b919a32Adam Lesinski */
4316c4d154dca43c662571129af31b27433b919a32Adam Lesinski
4416c4d154dca43c662571129af31b27433b919a32Adam Lesinskiconst static int ROUND_UP[4] = { 0, 3, 2, 1 };
4516c4d154dca43c662571129af31b27433b919a32Adam Lesinski
4616c4d154dca43c662571129af31b27433b919a32Adam Lesinskistatic inline size_t
4716c4d154dca43c662571129af31b27433b919a32Adam Lesinskipadding_extra(size_t n)
4816c4d154dca43c662571129af31b27433b919a32Adam Lesinski{
4916c4d154dca43c662571129af31b27433b919a32Adam Lesinski    return ROUND_UP[n % 4];
5016c4d154dca43c662571129af31b27433b919a32Adam Lesinski}
5116c4d154dca43c662571129af31b27433b919a32Adam Lesinski
5216c4d154dca43c662571129af31b27433b919a32Adam LesinskiBackupDataWriter::BackupDataWriter(int fd)
5316c4d154dca43c662571129af31b27433b919a32Adam Lesinski    :m_fd(fd),
5416c4d154dca43c662571129af31b27433b919a32Adam Lesinski     m_status(NO_ERROR),
5516c4d154dca43c662571129af31b27433b919a32Adam Lesinski     m_entityCount(0)
5616c4d154dca43c662571129af31b27433b919a32Adam Lesinski{
57b048c33d5bdaec747195dfedf971d4d9155f5000Christopher Tate    m_pos = (ssize_t) lseek(fd, 0, SEEK_CUR);
582204f0bf56af53b588a01701b8cf9cd05b1b3ff9Andreas Gampe    if (kIsDebug) ALOGI("BackupDataWriter(%d) @ %ld", fd, (long)m_pos);
5916c4d154dca43c662571129af31b27433b919a32Adam Lesinski}
6016c4d154dca43c662571129af31b27433b919a32Adam Lesinski
6116c4d154dca43c662571129af31b27433b919a32Adam LesinskiBackupDataWriter::~BackupDataWriter()
6216c4d154dca43c662571129af31b27433b919a32Adam Lesinski{
6316c4d154dca43c662571129af31b27433b919a32Adam Lesinski}
6416c4d154dca43c662571129af31b27433b919a32Adam Lesinski
6516c4d154dca43c662571129af31b27433b919a32Adam Lesinski// Pad out anything they've previously written to the next 4 byte boundary.
6616c4d154dca43c662571129af31b27433b919a32Adam Lesinskistatus_t
6716c4d154dca43c662571129af31b27433b919a32Adam LesinskiBackupDataWriter::write_padding_for(int n)
6816c4d154dca43c662571129af31b27433b919a32Adam Lesinski{
6916c4d154dca43c662571129af31b27433b919a32Adam Lesinski    ssize_t amt;
7016c4d154dca43c662571129af31b27433b919a32Adam Lesinski    ssize_t paddingSize;
7116c4d154dca43c662571129af31b27433b919a32Adam Lesinski
7216c4d154dca43c662571129af31b27433b919a32Adam Lesinski    paddingSize = padding_extra(n);
7316c4d154dca43c662571129af31b27433b919a32Adam Lesinski    if (paddingSize > 0) {
7416c4d154dca43c662571129af31b27433b919a32Adam Lesinski        uint32_t padding = 0xbcbcbcbc;
752204f0bf56af53b588a01701b8cf9cd05b1b3ff9Andreas Gampe        if (kIsDebug) ALOGI("writing %zd padding bytes for %d", paddingSize, n);
7616c4d154dca43c662571129af31b27433b919a32Adam Lesinski        amt = write(m_fd, &padding, paddingSize);
7716c4d154dca43c662571129af31b27433b919a32Adam Lesinski        if (amt != paddingSize) {
7816c4d154dca43c662571129af31b27433b919a32Adam Lesinski            m_status = errno;
7916c4d154dca43c662571129af31b27433b919a32Adam Lesinski            return m_status;
8016c4d154dca43c662571129af31b27433b919a32Adam Lesinski        }
8116c4d154dca43c662571129af31b27433b919a32Adam Lesinski        m_pos += amt;
8216c4d154dca43c662571129af31b27433b919a32Adam Lesinski    }
8316c4d154dca43c662571129af31b27433b919a32Adam Lesinski    return NO_ERROR;
8416c4d154dca43c662571129af31b27433b919a32Adam Lesinski}
8516c4d154dca43c662571129af31b27433b919a32Adam Lesinski
8616c4d154dca43c662571129af31b27433b919a32Adam Lesinskistatus_t
8716c4d154dca43c662571129af31b27433b919a32Adam LesinskiBackupDataWriter::WriteEntityHeader(const String8& key, size_t dataSize)
8816c4d154dca43c662571129af31b27433b919a32Adam Lesinski{
8916c4d154dca43c662571129af31b27433b919a32Adam Lesinski    if (m_status != NO_ERROR) {
9016c4d154dca43c662571129af31b27433b919a32Adam Lesinski        return m_status;
9116c4d154dca43c662571129af31b27433b919a32Adam Lesinski    }
9216c4d154dca43c662571129af31b27433b919a32Adam Lesinski
9316c4d154dca43c662571129af31b27433b919a32Adam Lesinski    ssize_t amt;
9416c4d154dca43c662571129af31b27433b919a32Adam Lesinski
9516c4d154dca43c662571129af31b27433b919a32Adam Lesinski    amt = write_padding_for(m_pos);
9616c4d154dca43c662571129af31b27433b919a32Adam Lesinski    if (amt != 0) {
9716c4d154dca43c662571129af31b27433b919a32Adam Lesinski        return amt;
9816c4d154dca43c662571129af31b27433b919a32Adam Lesinski    }
9916c4d154dca43c662571129af31b27433b919a32Adam Lesinski
10016c4d154dca43c662571129af31b27433b919a32Adam Lesinski    String8 k;
10116c4d154dca43c662571129af31b27433b919a32Adam Lesinski    if (m_keyPrefix.length() > 0) {
10216c4d154dca43c662571129af31b27433b919a32Adam Lesinski        k = m_keyPrefix;
10316c4d154dca43c662571129af31b27433b919a32Adam Lesinski        k += ":";
10416c4d154dca43c662571129af31b27433b919a32Adam Lesinski        k += key;
10516c4d154dca43c662571129af31b27433b919a32Adam Lesinski    } else {
10616c4d154dca43c662571129af31b27433b919a32Adam Lesinski        k = key;
10716c4d154dca43c662571129af31b27433b919a32Adam Lesinski    }
1082204f0bf56af53b588a01701b8cf9cd05b1b3ff9Andreas Gampe    if (kIsDebug) {
109f5df700e6ce056ebfa322314d970e52d6facc35aAshok Bhat        ALOGD("Writing header: prefix='%s' key='%s' dataSize=%zu", m_keyPrefix.string(),
11016c4d154dca43c662571129af31b27433b919a32Adam Lesinski                key.string(), dataSize);
11116c4d154dca43c662571129af31b27433b919a32Adam Lesinski    }
11216c4d154dca43c662571129af31b27433b919a32Adam Lesinski
11316c4d154dca43c662571129af31b27433b919a32Adam Lesinski    entity_header_v1 header;
11416c4d154dca43c662571129af31b27433b919a32Adam Lesinski    ssize_t keyLen;
11516c4d154dca43c662571129af31b27433b919a32Adam Lesinski
11616c4d154dca43c662571129af31b27433b919a32Adam Lesinski    keyLen = k.length();
11716c4d154dca43c662571129af31b27433b919a32Adam Lesinski
11816c4d154dca43c662571129af31b27433b919a32Adam Lesinski    header.type = tolel(BACKUP_HEADER_ENTITY_V1);
11916c4d154dca43c662571129af31b27433b919a32Adam Lesinski    header.keyLen = tolel(keyLen);
12016c4d154dca43c662571129af31b27433b919a32Adam Lesinski    header.dataSize = tolel(dataSize);
12116c4d154dca43c662571129af31b27433b919a32Adam Lesinski
1222204f0bf56af53b588a01701b8cf9cd05b1b3ff9Andreas Gampe    if (kIsDebug) ALOGI("writing entity header, %zu bytes", sizeof(entity_header_v1));
12316c4d154dca43c662571129af31b27433b919a32Adam Lesinski    amt = write(m_fd, &header, sizeof(entity_header_v1));
12416c4d154dca43c662571129af31b27433b919a32Adam Lesinski    if (amt != sizeof(entity_header_v1)) {
12516c4d154dca43c662571129af31b27433b919a32Adam Lesinski        m_status = errno;
12616c4d154dca43c662571129af31b27433b919a32Adam Lesinski        return m_status;
12716c4d154dca43c662571129af31b27433b919a32Adam Lesinski    }
12816c4d154dca43c662571129af31b27433b919a32Adam Lesinski    m_pos += amt;
12916c4d154dca43c662571129af31b27433b919a32Adam Lesinski
1302204f0bf56af53b588a01701b8cf9cd05b1b3ff9Andreas Gampe    if (kIsDebug) ALOGI("writing entity header key, %zd bytes", keyLen+1);
13116c4d154dca43c662571129af31b27433b919a32Adam Lesinski    amt = write(m_fd, k.string(), keyLen+1);
13216c4d154dca43c662571129af31b27433b919a32Adam Lesinski    if (amt != keyLen+1) {
13316c4d154dca43c662571129af31b27433b919a32Adam Lesinski        m_status = errno;
13416c4d154dca43c662571129af31b27433b919a32Adam Lesinski        return m_status;
13516c4d154dca43c662571129af31b27433b919a32Adam Lesinski    }
13616c4d154dca43c662571129af31b27433b919a32Adam Lesinski    m_pos += amt;
13716c4d154dca43c662571129af31b27433b919a32Adam Lesinski
13816c4d154dca43c662571129af31b27433b919a32Adam Lesinski    amt = write_padding_for(keyLen+1);
13916c4d154dca43c662571129af31b27433b919a32Adam Lesinski
14016c4d154dca43c662571129af31b27433b919a32Adam Lesinski    m_entityCount++;
14116c4d154dca43c662571129af31b27433b919a32Adam Lesinski
14216c4d154dca43c662571129af31b27433b919a32Adam Lesinski    return amt;
14316c4d154dca43c662571129af31b27433b919a32Adam Lesinski}
14416c4d154dca43c662571129af31b27433b919a32Adam Lesinski
14516c4d154dca43c662571129af31b27433b919a32Adam Lesinskistatus_t
14616c4d154dca43c662571129af31b27433b919a32Adam LesinskiBackupDataWriter::WriteEntityData(const void* data, size_t size)
14716c4d154dca43c662571129af31b27433b919a32Adam Lesinski{
1482204f0bf56af53b588a01701b8cf9cd05b1b3ff9Andreas Gampe    if (kIsDebug) ALOGD("Writing data: size=%lu", (unsigned long) size);
14916c4d154dca43c662571129af31b27433b919a32Adam Lesinski
15016c4d154dca43c662571129af31b27433b919a32Adam Lesinski    if (m_status != NO_ERROR) {
1512204f0bf56af53b588a01701b8cf9cd05b1b3ff9Andreas Gampe        if (kIsDebug) {
15216c4d154dca43c662571129af31b27433b919a32Adam Lesinski            ALOGD("Not writing data - stream in error state %d (%s)", m_status, strerror(m_status));
15316c4d154dca43c662571129af31b27433b919a32Adam Lesinski        }
15416c4d154dca43c662571129af31b27433b919a32Adam Lesinski        return m_status;
15516c4d154dca43c662571129af31b27433b919a32Adam Lesinski    }
15616c4d154dca43c662571129af31b27433b919a32Adam Lesinski
15716c4d154dca43c662571129af31b27433b919a32Adam Lesinski    // We don't write padding here, because they're allowed to call this several
15816c4d154dca43c662571129af31b27433b919a32Adam Lesinski    // times with smaller buffers.  We write it at the end of WriteEntityHeader
15916c4d154dca43c662571129af31b27433b919a32Adam Lesinski    // instead.
16016c4d154dca43c662571129af31b27433b919a32Adam Lesinski    ssize_t amt = write(m_fd, data, size);
16116c4d154dca43c662571129af31b27433b919a32Adam Lesinski    if (amt != (ssize_t)size) {
16216c4d154dca43c662571129af31b27433b919a32Adam Lesinski        m_status = errno;
1632204f0bf56af53b588a01701b8cf9cd05b1b3ff9Andreas Gampe        if (kIsDebug) ALOGD("write returned error %d (%s)", m_status, strerror(m_status));
16416c4d154dca43c662571129af31b27433b919a32Adam Lesinski        return m_status;
16516c4d154dca43c662571129af31b27433b919a32Adam Lesinski    }
16616c4d154dca43c662571129af31b27433b919a32Adam Lesinski    m_pos += amt;
16716c4d154dca43c662571129af31b27433b919a32Adam Lesinski    return NO_ERROR;
16816c4d154dca43c662571129af31b27433b919a32Adam Lesinski}
16916c4d154dca43c662571129af31b27433b919a32Adam Lesinski
17016c4d154dca43c662571129af31b27433b919a32Adam Lesinskivoid
17116c4d154dca43c662571129af31b27433b919a32Adam LesinskiBackupDataWriter::SetKeyPrefix(const String8& keyPrefix)
17216c4d154dca43c662571129af31b27433b919a32Adam Lesinski{
17316c4d154dca43c662571129af31b27433b919a32Adam Lesinski    m_keyPrefix = keyPrefix;
17416c4d154dca43c662571129af31b27433b919a32Adam Lesinski}
17516c4d154dca43c662571129af31b27433b919a32Adam Lesinski
17616c4d154dca43c662571129af31b27433b919a32Adam Lesinski
17716c4d154dca43c662571129af31b27433b919a32Adam LesinskiBackupDataReader::BackupDataReader(int fd)
17816c4d154dca43c662571129af31b27433b919a32Adam Lesinski    :m_fd(fd),
17916c4d154dca43c662571129af31b27433b919a32Adam Lesinski     m_done(false),
18016c4d154dca43c662571129af31b27433b919a32Adam Lesinski     m_status(NO_ERROR),
18116c4d154dca43c662571129af31b27433b919a32Adam Lesinski     m_entityCount(0)
18216c4d154dca43c662571129af31b27433b919a32Adam Lesinski{
18316c4d154dca43c662571129af31b27433b919a32Adam Lesinski    memset(&m_header, 0, sizeof(m_header));
184b048c33d5bdaec747195dfedf971d4d9155f5000Christopher Tate    m_pos = (ssize_t) lseek(fd, 0, SEEK_CUR);
1852204f0bf56af53b588a01701b8cf9cd05b1b3ff9Andreas Gampe    if (kIsDebug) ALOGI("BackupDataReader(%d) @ %ld", fd, (long)m_pos);
18616c4d154dca43c662571129af31b27433b919a32Adam Lesinski}
18716c4d154dca43c662571129af31b27433b919a32Adam Lesinski
18816c4d154dca43c662571129af31b27433b919a32Adam LesinskiBackupDataReader::~BackupDataReader()
18916c4d154dca43c662571129af31b27433b919a32Adam Lesinski{
19016c4d154dca43c662571129af31b27433b919a32Adam Lesinski}
19116c4d154dca43c662571129af31b27433b919a32Adam Lesinski
19216c4d154dca43c662571129af31b27433b919a32Adam Lesinskistatus_t
19316c4d154dca43c662571129af31b27433b919a32Adam LesinskiBackupDataReader::Status()
19416c4d154dca43c662571129af31b27433b919a32Adam Lesinski{
19516c4d154dca43c662571129af31b27433b919a32Adam Lesinski    return m_status;
19616c4d154dca43c662571129af31b27433b919a32Adam Lesinski}
19716c4d154dca43c662571129af31b27433b919a32Adam Lesinski
19816c4d154dca43c662571129af31b27433b919a32Adam Lesinski#define CHECK_SIZE(actual, expected) \
19916c4d154dca43c662571129af31b27433b919a32Adam Lesinski    do { \
20016c4d154dca43c662571129af31b27433b919a32Adam Lesinski        if ((actual) != (expected)) { \
20116c4d154dca43c662571129af31b27433b919a32Adam Lesinski            if ((actual) == 0) { \
20216c4d154dca43c662571129af31b27433b919a32Adam Lesinski                m_status = EIO; \
20316c4d154dca43c662571129af31b27433b919a32Adam Lesinski                m_done = true; \
20416c4d154dca43c662571129af31b27433b919a32Adam Lesinski            } else { \
20516c4d154dca43c662571129af31b27433b919a32Adam Lesinski                m_status = errno; \
20616c4d154dca43c662571129af31b27433b919a32Adam Lesinski                ALOGD("CHECK_SIZE(a=%ld e=%ld) failed at line %d m_status='%s'", \
20716c4d154dca43c662571129af31b27433b919a32Adam Lesinski                    long(actual), long(expected), __LINE__, strerror(m_status)); \
20816c4d154dca43c662571129af31b27433b919a32Adam Lesinski            } \
20916c4d154dca43c662571129af31b27433b919a32Adam Lesinski            return m_status; \
21016c4d154dca43c662571129af31b27433b919a32Adam Lesinski        } \
21116c4d154dca43c662571129af31b27433b919a32Adam Lesinski    } while(0)
21216c4d154dca43c662571129af31b27433b919a32Adam Lesinski#define SKIP_PADDING() \
21316c4d154dca43c662571129af31b27433b919a32Adam Lesinski    do { \
21416c4d154dca43c662571129af31b27433b919a32Adam Lesinski        status_t err = skip_padding(); \
21516c4d154dca43c662571129af31b27433b919a32Adam Lesinski        if (err != NO_ERROR) { \
21616c4d154dca43c662571129af31b27433b919a32Adam Lesinski            ALOGD("SKIP_PADDING FAILED at line %d", __LINE__); \
21716c4d154dca43c662571129af31b27433b919a32Adam Lesinski            m_status = err; \
21816c4d154dca43c662571129af31b27433b919a32Adam Lesinski            return err; \
21916c4d154dca43c662571129af31b27433b919a32Adam Lesinski        } \
22016c4d154dca43c662571129af31b27433b919a32Adam Lesinski    } while(0)
22116c4d154dca43c662571129af31b27433b919a32Adam Lesinski
22216c4d154dca43c662571129af31b27433b919a32Adam Lesinskistatus_t
22316c4d154dca43c662571129af31b27433b919a32Adam LesinskiBackupDataReader::ReadNextHeader(bool* done, int* type)
22416c4d154dca43c662571129af31b27433b919a32Adam Lesinski{
22516c4d154dca43c662571129af31b27433b919a32Adam Lesinski    *done = m_done;
22616c4d154dca43c662571129af31b27433b919a32Adam Lesinski    if (m_status != NO_ERROR) {
22716c4d154dca43c662571129af31b27433b919a32Adam Lesinski        return m_status;
22816c4d154dca43c662571129af31b27433b919a32Adam Lesinski    }
22916c4d154dca43c662571129af31b27433b919a32Adam Lesinski
23016c4d154dca43c662571129af31b27433b919a32Adam Lesinski    int amt;
23116c4d154dca43c662571129af31b27433b919a32Adam Lesinski
23216c4d154dca43c662571129af31b27433b919a32Adam Lesinski    amt = skip_padding();
23316c4d154dca43c662571129af31b27433b919a32Adam Lesinski    if (amt == EIO) {
23416c4d154dca43c662571129af31b27433b919a32Adam Lesinski        *done = m_done = true;
23516c4d154dca43c662571129af31b27433b919a32Adam Lesinski        return NO_ERROR;
23616c4d154dca43c662571129af31b27433b919a32Adam Lesinski    }
23716c4d154dca43c662571129af31b27433b919a32Adam Lesinski    else if (amt != NO_ERROR) {
23816c4d154dca43c662571129af31b27433b919a32Adam Lesinski        return amt;
23916c4d154dca43c662571129af31b27433b919a32Adam Lesinski    }
24016c4d154dca43c662571129af31b27433b919a32Adam Lesinski    amt = read(m_fd, &m_header, sizeof(m_header));
24116c4d154dca43c662571129af31b27433b919a32Adam Lesinski    *done = m_done = (amt == 0);
24216c4d154dca43c662571129af31b27433b919a32Adam Lesinski    if (*done) {
24316c4d154dca43c662571129af31b27433b919a32Adam Lesinski        return NO_ERROR;
24416c4d154dca43c662571129af31b27433b919a32Adam Lesinski    }
24516c4d154dca43c662571129af31b27433b919a32Adam Lesinski    CHECK_SIZE(amt, sizeof(m_header));
24616c4d154dca43c662571129af31b27433b919a32Adam Lesinski    m_pos += sizeof(m_header);
24716c4d154dca43c662571129af31b27433b919a32Adam Lesinski    if (type) {
24816c4d154dca43c662571129af31b27433b919a32Adam Lesinski        *type = m_header.type;
24916c4d154dca43c662571129af31b27433b919a32Adam Lesinski    }
25016c4d154dca43c662571129af31b27433b919a32Adam Lesinski
25116c4d154dca43c662571129af31b27433b919a32Adam Lesinski    // validate and fix up the fields.
25216c4d154dca43c662571129af31b27433b919a32Adam Lesinski    m_header.type = fromlel(m_header.type);
25316c4d154dca43c662571129af31b27433b919a32Adam Lesinski    switch (m_header.type)
25416c4d154dca43c662571129af31b27433b919a32Adam Lesinski    {
25516c4d154dca43c662571129af31b27433b919a32Adam Lesinski        case BACKUP_HEADER_ENTITY_V1:
25616c4d154dca43c662571129af31b27433b919a32Adam Lesinski        {
25716c4d154dca43c662571129af31b27433b919a32Adam Lesinski            m_header.entity.keyLen = fromlel(m_header.entity.keyLen);
25816c4d154dca43c662571129af31b27433b919a32Adam Lesinski            if (m_header.entity.keyLen <= 0) {
25916c4d154dca43c662571129af31b27433b919a32Adam Lesinski                ALOGD("Entity header at %d has keyLen<=0: 0x%08x\n", (int)m_pos,
26016c4d154dca43c662571129af31b27433b919a32Adam Lesinski                        (int)m_header.entity.keyLen);
26116c4d154dca43c662571129af31b27433b919a32Adam Lesinski                m_status = EINVAL;
26216c4d154dca43c662571129af31b27433b919a32Adam Lesinski            }
26316c4d154dca43c662571129af31b27433b919a32Adam Lesinski            m_header.entity.dataSize = fromlel(m_header.entity.dataSize);
26416c4d154dca43c662571129af31b27433b919a32Adam Lesinski            m_entityCount++;
26516c4d154dca43c662571129af31b27433b919a32Adam Lesinski
26616c4d154dca43c662571129af31b27433b919a32Adam Lesinski            // read the rest of the header (filename)
26716c4d154dca43c662571129af31b27433b919a32Adam Lesinski            size_t size = m_header.entity.keyLen;
26816c4d154dca43c662571129af31b27433b919a32Adam Lesinski            char* buf = m_key.lockBuffer(size);
26916c4d154dca43c662571129af31b27433b919a32Adam Lesinski            if (buf == NULL) {
27016c4d154dca43c662571129af31b27433b919a32Adam Lesinski                m_status = ENOMEM;
27116c4d154dca43c662571129af31b27433b919a32Adam Lesinski                return m_status;
27216c4d154dca43c662571129af31b27433b919a32Adam Lesinski            }
27316c4d154dca43c662571129af31b27433b919a32Adam Lesinski            int amt = read(m_fd, buf, size+1);
27416c4d154dca43c662571129af31b27433b919a32Adam Lesinski            CHECK_SIZE(amt, (int)size+1);
27516c4d154dca43c662571129af31b27433b919a32Adam Lesinski            m_key.unlockBuffer(size);
27616c4d154dca43c662571129af31b27433b919a32Adam Lesinski            m_pos += size+1;
27716c4d154dca43c662571129af31b27433b919a32Adam Lesinski            SKIP_PADDING();
27816c4d154dca43c662571129af31b27433b919a32Adam Lesinski            m_dataEndPos = m_pos + m_header.entity.dataSize;
27916c4d154dca43c662571129af31b27433b919a32Adam Lesinski
28016c4d154dca43c662571129af31b27433b919a32Adam Lesinski            break;
28116c4d154dca43c662571129af31b27433b919a32Adam Lesinski        }
28216c4d154dca43c662571129af31b27433b919a32Adam Lesinski        default:
28316c4d154dca43c662571129af31b27433b919a32Adam Lesinski            ALOGD("Chunk header at %d has invalid type: 0x%08x",
28416c4d154dca43c662571129af31b27433b919a32Adam Lesinski                    (int)(m_pos - sizeof(m_header)), (int)m_header.type);
28516c4d154dca43c662571129af31b27433b919a32Adam Lesinski            m_status = EINVAL;
28616c4d154dca43c662571129af31b27433b919a32Adam Lesinski    }
28700adb8685ee996f9d2650d617c8c0e98f13ef406Mark Salyzyn
28816c4d154dca43c662571129af31b27433b919a32Adam Lesinski    return m_status;
28916c4d154dca43c662571129af31b27433b919a32Adam Lesinski}
29016c4d154dca43c662571129af31b27433b919a32Adam Lesinski
29116c4d154dca43c662571129af31b27433b919a32Adam Lesinskibool
29216c4d154dca43c662571129af31b27433b919a32Adam LesinskiBackupDataReader::HasEntities()
29316c4d154dca43c662571129af31b27433b919a32Adam Lesinski{
29416c4d154dca43c662571129af31b27433b919a32Adam Lesinski    return m_status == NO_ERROR && m_header.type == BACKUP_HEADER_ENTITY_V1;
29516c4d154dca43c662571129af31b27433b919a32Adam Lesinski}
29616c4d154dca43c662571129af31b27433b919a32Adam Lesinski
29716c4d154dca43c662571129af31b27433b919a32Adam Lesinskistatus_t
29816c4d154dca43c662571129af31b27433b919a32Adam LesinskiBackupDataReader::ReadEntityHeader(String8* key, size_t* dataSize)
29916c4d154dca43c662571129af31b27433b919a32Adam Lesinski{
30016c4d154dca43c662571129af31b27433b919a32Adam Lesinski    if (m_status != NO_ERROR) {
30116c4d154dca43c662571129af31b27433b919a32Adam Lesinski        return m_status;
30216c4d154dca43c662571129af31b27433b919a32Adam Lesinski    }
30316c4d154dca43c662571129af31b27433b919a32Adam Lesinski    if (m_header.type != BACKUP_HEADER_ENTITY_V1) {
30416c4d154dca43c662571129af31b27433b919a32Adam Lesinski        return EINVAL;
30516c4d154dca43c662571129af31b27433b919a32Adam Lesinski    }
30616c4d154dca43c662571129af31b27433b919a32Adam Lesinski    *key = m_key;
30716c4d154dca43c662571129af31b27433b919a32Adam Lesinski    *dataSize = m_header.entity.dataSize;
30816c4d154dca43c662571129af31b27433b919a32Adam Lesinski    return NO_ERROR;
30916c4d154dca43c662571129af31b27433b919a32Adam Lesinski}
31016c4d154dca43c662571129af31b27433b919a32Adam Lesinski
31116c4d154dca43c662571129af31b27433b919a32Adam Lesinskistatus_t
31216c4d154dca43c662571129af31b27433b919a32Adam LesinskiBackupDataReader::SkipEntityData()
31316c4d154dca43c662571129af31b27433b919a32Adam Lesinski{
31416c4d154dca43c662571129af31b27433b919a32Adam Lesinski    if (m_status != NO_ERROR) {
31516c4d154dca43c662571129af31b27433b919a32Adam Lesinski        return m_status;
31616c4d154dca43c662571129af31b27433b919a32Adam Lesinski    }
31716c4d154dca43c662571129af31b27433b919a32Adam Lesinski    if (m_header.type != BACKUP_HEADER_ENTITY_V1) {
31816c4d154dca43c662571129af31b27433b919a32Adam Lesinski        return EINVAL;
31916c4d154dca43c662571129af31b27433b919a32Adam Lesinski    }
32016c4d154dca43c662571129af31b27433b919a32Adam Lesinski    if (m_header.entity.dataSize > 0) {
32116c4d154dca43c662571129af31b27433b919a32Adam Lesinski        int pos = lseek(m_fd, m_dataEndPos, SEEK_SET);
32216c4d154dca43c662571129af31b27433b919a32Adam Lesinski        if (pos == -1) {
32316c4d154dca43c662571129af31b27433b919a32Adam Lesinski            return errno;
32416c4d154dca43c662571129af31b27433b919a32Adam Lesinski        }
32516c4d154dca43c662571129af31b27433b919a32Adam Lesinski        m_pos = pos;
32616c4d154dca43c662571129af31b27433b919a32Adam Lesinski    }
32716c4d154dca43c662571129af31b27433b919a32Adam Lesinski    SKIP_PADDING();
32816c4d154dca43c662571129af31b27433b919a32Adam Lesinski    return NO_ERROR;
32916c4d154dca43c662571129af31b27433b919a32Adam Lesinski}
33016c4d154dca43c662571129af31b27433b919a32Adam Lesinski
33116c4d154dca43c662571129af31b27433b919a32Adam Lesinskissize_t
33216c4d154dca43c662571129af31b27433b919a32Adam LesinskiBackupDataReader::ReadEntityData(void* data, size_t size)
33316c4d154dca43c662571129af31b27433b919a32Adam Lesinski{
33416c4d154dca43c662571129af31b27433b919a32Adam Lesinski    if (m_status != NO_ERROR) {
33516c4d154dca43c662571129af31b27433b919a32Adam Lesinski        return -1;
33616c4d154dca43c662571129af31b27433b919a32Adam Lesinski    }
33716c4d154dca43c662571129af31b27433b919a32Adam Lesinski    int remaining = m_dataEndPos - m_pos;
3382204f0bf56af53b588a01701b8cf9cd05b1b3ff9Andreas Gampe    if (kIsDebug) {
33925df5fba3afff403c749bab7d1d5652c3b929e06Andreas Gampe        ALOGD("ReadEntityData size=%zu m_pos=0x%zx m_dataEndPos=0x%zx remaining=%d\n",
3402204f0bf56af53b588a01701b8cf9cd05b1b3ff9Andreas Gampe                size, m_pos, m_dataEndPos, remaining);
3412204f0bf56af53b588a01701b8cf9cd05b1b3ff9Andreas Gampe    }
34216c4d154dca43c662571129af31b27433b919a32Adam Lesinski    if (remaining <= 0) {
34316c4d154dca43c662571129af31b27433b919a32Adam Lesinski        return 0;
34416c4d154dca43c662571129af31b27433b919a32Adam Lesinski    }
34516c4d154dca43c662571129af31b27433b919a32Adam Lesinski    if (((int)size) > remaining) {
34616c4d154dca43c662571129af31b27433b919a32Adam Lesinski        size = remaining;
34716c4d154dca43c662571129af31b27433b919a32Adam Lesinski    }
3482204f0bf56af53b588a01701b8cf9cd05b1b3ff9Andreas Gampe    if (kIsDebug) {
34925df5fba3afff403c749bab7d1d5652c3b929e06Andreas Gampe        ALOGD("   reading %zu bytes", size);
3502204f0bf56af53b588a01701b8cf9cd05b1b3ff9Andreas Gampe    }
35116c4d154dca43c662571129af31b27433b919a32Adam Lesinski    int amt = read(m_fd, data, size);
35216c4d154dca43c662571129af31b27433b919a32Adam Lesinski    if (amt < 0) {
35316c4d154dca43c662571129af31b27433b919a32Adam Lesinski        m_status = errno;
35416c4d154dca43c662571129af31b27433b919a32Adam Lesinski        return -1;
35516c4d154dca43c662571129af31b27433b919a32Adam Lesinski    }
35616c4d154dca43c662571129af31b27433b919a32Adam Lesinski    if (amt == 0) {
35716c4d154dca43c662571129af31b27433b919a32Adam Lesinski        m_status = EIO;
35816c4d154dca43c662571129af31b27433b919a32Adam Lesinski        m_done = true;
35916c4d154dca43c662571129af31b27433b919a32Adam Lesinski    }
36016c4d154dca43c662571129af31b27433b919a32Adam Lesinski    m_pos += amt;
36116c4d154dca43c662571129af31b27433b919a32Adam Lesinski    return amt;
36216c4d154dca43c662571129af31b27433b919a32Adam Lesinski}
36316c4d154dca43c662571129af31b27433b919a32Adam Lesinski
36416c4d154dca43c662571129af31b27433b919a32Adam Lesinskistatus_t
36516c4d154dca43c662571129af31b27433b919a32Adam LesinskiBackupDataReader::skip_padding()
36616c4d154dca43c662571129af31b27433b919a32Adam Lesinski{
36716c4d154dca43c662571129af31b27433b919a32Adam Lesinski    ssize_t amt;
36816c4d154dca43c662571129af31b27433b919a32Adam Lesinski    ssize_t paddingSize;
36916c4d154dca43c662571129af31b27433b919a32Adam Lesinski
37016c4d154dca43c662571129af31b27433b919a32Adam Lesinski    paddingSize = padding_extra(m_pos);
37116c4d154dca43c662571129af31b27433b919a32Adam Lesinski    if (paddingSize > 0) {
37216c4d154dca43c662571129af31b27433b919a32Adam Lesinski        uint32_t padding;
37316c4d154dca43c662571129af31b27433b919a32Adam Lesinski        amt = read(m_fd, &padding, paddingSize);
37416c4d154dca43c662571129af31b27433b919a32Adam Lesinski        CHECK_SIZE(amt, paddingSize);
37516c4d154dca43c662571129af31b27433b919a32Adam Lesinski        m_pos += amt;
37616c4d154dca43c662571129af31b27433b919a32Adam Lesinski    }
37716c4d154dca43c662571129af31b27433b919a32Adam Lesinski    return NO_ERROR;
37816c4d154dca43c662571129af31b27433b919a32Adam Lesinski}
37916c4d154dca43c662571129af31b27433b919a32Adam Lesinski
38016c4d154dca43c662571129af31b27433b919a32Adam Lesinski
38116c4d154dca43c662571129af31b27433b919a32Adam Lesinski} // namespace android
382