116c4d154dca43c662571129af31b27433b919a32Adam Lesinski/*
216c4d154dca43c662571129af31b27433b919a32Adam Lesinski * Copyright (C) 2010 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#include <errno.h>
1816c4d154dca43c662571129af31b27433b919a32Adam Lesinski#include <fcntl.h>
1916c4d154dca43c662571129af31b27433b919a32Adam Lesinski#include <stdint.h>
2016c4d154dca43c662571129af31b27433b919a32Adam Lesinski#include <stdlib.h>
2116c4d154dca43c662571129af31b27433b919a32Adam Lesinski#include <string.h>
2216c4d154dca43c662571129af31b27433b919a32Adam Lesinski#include <unistd.h>
2316c4d154dca43c662571129af31b27433b919a32Adam Lesinski
2416c4d154dca43c662571129af31b27433b919a32Adam Lesinski#define LOG_TAG "ObbFile"
2516c4d154dca43c662571129af31b27433b919a32Adam Lesinski
2616c4d154dca43c662571129af31b27433b919a32Adam Lesinski#include <androidfw/ObbFile.h>
2716c4d154dca43c662571129af31b27433b919a32Adam Lesinski#include <utils/Compat.h>
2816c4d154dca43c662571129af31b27433b919a32Adam Lesinski#include <utils/Log.h>
2916c4d154dca43c662571129af31b27433b919a32Adam Lesinski
3016c4d154dca43c662571129af31b27433b919a32Adam Lesinski//#define DEBUG 1
3116c4d154dca43c662571129af31b27433b919a32Adam Lesinski
3216c4d154dca43c662571129af31b27433b919a32Adam Lesinski#define kFooterTagSize 8  /* last two 32-bit integers */
3316c4d154dca43c662571129af31b27433b919a32Adam Lesinski
3416c4d154dca43c662571129af31b27433b919a32Adam Lesinski#define kFooterMinSize 33 /* 32-bit signature version (4 bytes)
3516c4d154dca43c662571129af31b27433b919a32Adam Lesinski                           * 32-bit package version (4 bytes)
3616c4d154dca43c662571129af31b27433b919a32Adam Lesinski                           * 32-bit flags (4 bytes)
3716c4d154dca43c662571129af31b27433b919a32Adam Lesinski                           * 64-bit salt (8 bytes)
3816c4d154dca43c662571129af31b27433b919a32Adam Lesinski                           * 32-bit package name size (4 bytes)
3916c4d154dca43c662571129af31b27433b919a32Adam Lesinski                           * >=1-character package name (1 byte)
4016c4d154dca43c662571129af31b27433b919a32Adam Lesinski                           * 32-bit footer size (4 bytes)
4116c4d154dca43c662571129af31b27433b919a32Adam Lesinski                           * 32-bit footer marker (4 bytes)
4216c4d154dca43c662571129af31b27433b919a32Adam Lesinski                           */
4316c4d154dca43c662571129af31b27433b919a32Adam Lesinski
4416c4d154dca43c662571129af31b27433b919a32Adam Lesinski#define kMaxBufSize    32768 /* Maximum file read buffer */
4516c4d154dca43c662571129af31b27433b919a32Adam Lesinski
4616c4d154dca43c662571129af31b27433b919a32Adam Lesinski#define kSignature     0x01059983U /* ObbFile signature */
4716c4d154dca43c662571129af31b27433b919a32Adam Lesinski
4816c4d154dca43c662571129af31b27433b919a32Adam Lesinski#define kSigVersion    1 /* We only know about signature version 1 */
4916c4d154dca43c662571129af31b27433b919a32Adam Lesinski
5016c4d154dca43c662571129af31b27433b919a32Adam Lesinski/* offsets in version 1 of the header */
5116c4d154dca43c662571129af31b27433b919a32Adam Lesinski#define kPackageVersionOffset 4
5216c4d154dca43c662571129af31b27433b919a32Adam Lesinski#define kFlagsOffset          8
5316c4d154dca43c662571129af31b27433b919a32Adam Lesinski#define kSaltOffset           12
5416c4d154dca43c662571129af31b27433b919a32Adam Lesinski#define kPackageNameLenOffset 20
5516c4d154dca43c662571129af31b27433b919a32Adam Lesinski#define kPackageNameOffset    24
5616c4d154dca43c662571129af31b27433b919a32Adam Lesinski
5716c4d154dca43c662571129af31b27433b919a32Adam Lesinski/*
5816c4d154dca43c662571129af31b27433b919a32Adam Lesinski * TEMP_FAILURE_RETRY is defined by some, but not all, versions of
5916c4d154dca43c662571129af31b27433b919a32Adam Lesinski * <unistd.h>. (Alas, it is not as standard as we'd hoped!) So, if it's
6016c4d154dca43c662571129af31b27433b919a32Adam Lesinski * not already defined, then define it here.
6116c4d154dca43c662571129af31b27433b919a32Adam Lesinski */
6216c4d154dca43c662571129af31b27433b919a32Adam Lesinski#ifndef TEMP_FAILURE_RETRY
6316c4d154dca43c662571129af31b27433b919a32Adam Lesinski/* Used to retry syscalls that can return EINTR. */
6416c4d154dca43c662571129af31b27433b919a32Adam Lesinski#define TEMP_FAILURE_RETRY(exp) ({         \
6516c4d154dca43c662571129af31b27433b919a32Adam Lesinski    typeof (exp) _rc;                      \
6616c4d154dca43c662571129af31b27433b919a32Adam Lesinski    do {                                   \
6716c4d154dca43c662571129af31b27433b919a32Adam Lesinski        _rc = (exp);                       \
6816c4d154dca43c662571129af31b27433b919a32Adam Lesinski    } while (_rc == -1 && errno == EINTR); \
6916c4d154dca43c662571129af31b27433b919a32Adam Lesinski    _rc; })
7016c4d154dca43c662571129af31b27433b919a32Adam Lesinski#endif
7116c4d154dca43c662571129af31b27433b919a32Adam Lesinski
7216c4d154dca43c662571129af31b27433b919a32Adam Lesinski
7316c4d154dca43c662571129af31b27433b919a32Adam Lesinskinamespace android {
7416c4d154dca43c662571129af31b27433b919a32Adam Lesinski
7516c4d154dca43c662571129af31b27433b919a32Adam LesinskiObbFile::ObbFile()
7616c4d154dca43c662571129af31b27433b919a32Adam Lesinski        : mPackageName("")
7716c4d154dca43c662571129af31b27433b919a32Adam Lesinski        , mVersion(-1)
7816c4d154dca43c662571129af31b27433b919a32Adam Lesinski        , mFlags(0)
7916c4d154dca43c662571129af31b27433b919a32Adam Lesinski{
8016c4d154dca43c662571129af31b27433b919a32Adam Lesinski    memset(mSalt, 0, sizeof(mSalt));
8116c4d154dca43c662571129af31b27433b919a32Adam Lesinski}
8216c4d154dca43c662571129af31b27433b919a32Adam Lesinski
8316c4d154dca43c662571129af31b27433b919a32Adam LesinskiObbFile::~ObbFile() {
8416c4d154dca43c662571129af31b27433b919a32Adam Lesinski}
8516c4d154dca43c662571129af31b27433b919a32Adam Lesinski
8616c4d154dca43c662571129af31b27433b919a32Adam Lesinskibool ObbFile::readFrom(const char* filename)
8716c4d154dca43c662571129af31b27433b919a32Adam Lesinski{
8816c4d154dca43c662571129af31b27433b919a32Adam Lesinski    int fd;
8916c4d154dca43c662571129af31b27433b919a32Adam Lesinski    bool success = false;
9016c4d154dca43c662571129af31b27433b919a32Adam Lesinski
9116c4d154dca43c662571129af31b27433b919a32Adam Lesinski    fd = ::open(filename, O_RDONLY);
9216c4d154dca43c662571129af31b27433b919a32Adam Lesinski    if (fd < 0) {
9316c4d154dca43c662571129af31b27433b919a32Adam Lesinski        ALOGW("couldn't open file %s: %s", filename, strerror(errno));
9416c4d154dca43c662571129af31b27433b919a32Adam Lesinski        goto out;
9516c4d154dca43c662571129af31b27433b919a32Adam Lesinski    }
9616c4d154dca43c662571129af31b27433b919a32Adam Lesinski    success = readFrom(fd);
9716c4d154dca43c662571129af31b27433b919a32Adam Lesinski    close(fd);
9816c4d154dca43c662571129af31b27433b919a32Adam Lesinski
9916c4d154dca43c662571129af31b27433b919a32Adam Lesinski    if (!success) {
10016c4d154dca43c662571129af31b27433b919a32Adam Lesinski        ALOGW("failed to read from %s (fd=%d)\n", filename, fd);
10116c4d154dca43c662571129af31b27433b919a32Adam Lesinski    }
10216c4d154dca43c662571129af31b27433b919a32Adam Lesinski
10316c4d154dca43c662571129af31b27433b919a32Adam Lesinskiout:
10416c4d154dca43c662571129af31b27433b919a32Adam Lesinski    return success;
10516c4d154dca43c662571129af31b27433b919a32Adam Lesinski}
10616c4d154dca43c662571129af31b27433b919a32Adam Lesinski
10716c4d154dca43c662571129af31b27433b919a32Adam Lesinskibool ObbFile::readFrom(int fd)
10816c4d154dca43c662571129af31b27433b919a32Adam Lesinski{
10916c4d154dca43c662571129af31b27433b919a32Adam Lesinski    if (fd < 0) {
11016c4d154dca43c662571129af31b27433b919a32Adam Lesinski        ALOGW("attempt to read from invalid fd\n");
11116c4d154dca43c662571129af31b27433b919a32Adam Lesinski        return false;
11216c4d154dca43c662571129af31b27433b919a32Adam Lesinski    }
11316c4d154dca43c662571129af31b27433b919a32Adam Lesinski
11416c4d154dca43c662571129af31b27433b919a32Adam Lesinski    return parseObbFile(fd);
11516c4d154dca43c662571129af31b27433b919a32Adam Lesinski}
11616c4d154dca43c662571129af31b27433b919a32Adam Lesinski
11716c4d154dca43c662571129af31b27433b919a32Adam Lesinskibool ObbFile::parseObbFile(int fd)
11816c4d154dca43c662571129af31b27433b919a32Adam Lesinski{
11916c4d154dca43c662571129af31b27433b919a32Adam Lesinski    off64_t fileLength = lseek64(fd, 0, SEEK_END);
12016c4d154dca43c662571129af31b27433b919a32Adam Lesinski
12116c4d154dca43c662571129af31b27433b919a32Adam Lesinski    if (fileLength < kFooterMinSize) {
12216c4d154dca43c662571129af31b27433b919a32Adam Lesinski        if (fileLength < 0) {
12316c4d154dca43c662571129af31b27433b919a32Adam Lesinski            ALOGW("error seeking in ObbFile: %s\n", strerror(errno));
12416c4d154dca43c662571129af31b27433b919a32Adam Lesinski        } else {
12516c4d154dca43c662571129af31b27433b919a32Adam Lesinski            ALOGW("file is only %lld (less than %d minimum)\n", fileLength, kFooterMinSize);
12616c4d154dca43c662571129af31b27433b919a32Adam Lesinski        }
12716c4d154dca43c662571129af31b27433b919a32Adam Lesinski        return false;
12816c4d154dca43c662571129af31b27433b919a32Adam Lesinski    }
12916c4d154dca43c662571129af31b27433b919a32Adam Lesinski
13016c4d154dca43c662571129af31b27433b919a32Adam Lesinski    ssize_t actual;
13116c4d154dca43c662571129af31b27433b919a32Adam Lesinski    size_t footerSize;
13216c4d154dca43c662571129af31b27433b919a32Adam Lesinski
13316c4d154dca43c662571129af31b27433b919a32Adam Lesinski    {
13416c4d154dca43c662571129af31b27433b919a32Adam Lesinski        lseek64(fd, fileLength - kFooterTagSize, SEEK_SET);
13516c4d154dca43c662571129af31b27433b919a32Adam Lesinski
136e1aa223657dd1def8609b377afa86a024bfd4e14Elliott Hughes        char footer[kFooterTagSize];
13716c4d154dca43c662571129af31b27433b919a32Adam Lesinski        actual = TEMP_FAILURE_RETRY(read(fd, footer, kFooterTagSize));
13816c4d154dca43c662571129af31b27433b919a32Adam Lesinski        if (actual != kFooterTagSize) {
13916c4d154dca43c662571129af31b27433b919a32Adam Lesinski            ALOGW("couldn't read footer signature: %s\n", strerror(errno));
14016c4d154dca43c662571129af31b27433b919a32Adam Lesinski            return false;
14116c4d154dca43c662571129af31b27433b919a32Adam Lesinski        }
14216c4d154dca43c662571129af31b27433b919a32Adam Lesinski
14316c4d154dca43c662571129af31b27433b919a32Adam Lesinski        unsigned int fileSig = get4LE((unsigned char*)footer + sizeof(int32_t));
14416c4d154dca43c662571129af31b27433b919a32Adam Lesinski        if (fileSig != kSignature) {
14516c4d154dca43c662571129af31b27433b919a32Adam Lesinski            ALOGW("footer didn't match magic string (expected 0x%08x; got 0x%08x)\n",
14616c4d154dca43c662571129af31b27433b919a32Adam Lesinski                    kSignature, fileSig);
14716c4d154dca43c662571129af31b27433b919a32Adam Lesinski            return false;
14816c4d154dca43c662571129af31b27433b919a32Adam Lesinski        }
14916c4d154dca43c662571129af31b27433b919a32Adam Lesinski
15016c4d154dca43c662571129af31b27433b919a32Adam Lesinski        footerSize = get4LE((unsigned char*)footer);
15116c4d154dca43c662571129af31b27433b919a32Adam Lesinski        if (footerSize > (size_t)fileLength - kFooterTagSize
15216c4d154dca43c662571129af31b27433b919a32Adam Lesinski                || footerSize > kMaxBufSize) {
15316c4d154dca43c662571129af31b27433b919a32Adam Lesinski            ALOGW("claimed footer size is too large (0x%08zx; file size is 0x%08llx)\n",
15416c4d154dca43c662571129af31b27433b919a32Adam Lesinski                    footerSize, fileLength);
15516c4d154dca43c662571129af31b27433b919a32Adam Lesinski            return false;
15616c4d154dca43c662571129af31b27433b919a32Adam Lesinski        }
15716c4d154dca43c662571129af31b27433b919a32Adam Lesinski
15816c4d154dca43c662571129af31b27433b919a32Adam Lesinski        if (footerSize < (kFooterMinSize - kFooterTagSize)) {
15916c4d154dca43c662571129af31b27433b919a32Adam Lesinski            ALOGW("claimed footer size is too small (0x%zx; minimum size is 0x%x)\n",
16016c4d154dca43c662571129af31b27433b919a32Adam Lesinski                    footerSize, kFooterMinSize - kFooterTagSize);
16116c4d154dca43c662571129af31b27433b919a32Adam Lesinski            return false;
16216c4d154dca43c662571129af31b27433b919a32Adam Lesinski        }
16316c4d154dca43c662571129af31b27433b919a32Adam Lesinski    }
16416c4d154dca43c662571129af31b27433b919a32Adam Lesinski
16516c4d154dca43c662571129af31b27433b919a32Adam Lesinski    off64_t fileOffset = fileLength - footerSize - kFooterTagSize;
16616c4d154dca43c662571129af31b27433b919a32Adam Lesinski    if (lseek64(fd, fileOffset, SEEK_SET) != fileOffset) {
16716c4d154dca43c662571129af31b27433b919a32Adam Lesinski        ALOGW("seek %lld failed: %s\n", fileOffset, strerror(errno));
16816c4d154dca43c662571129af31b27433b919a32Adam Lesinski        return false;
16916c4d154dca43c662571129af31b27433b919a32Adam Lesinski    }
17016c4d154dca43c662571129af31b27433b919a32Adam Lesinski
17116c4d154dca43c662571129af31b27433b919a32Adam Lesinski    mFooterStart = fileOffset;
17216c4d154dca43c662571129af31b27433b919a32Adam Lesinski
17316c4d154dca43c662571129af31b27433b919a32Adam Lesinski    char* scanBuf = (char*)malloc(footerSize);
17416c4d154dca43c662571129af31b27433b919a32Adam Lesinski    if (scanBuf == NULL) {
17516c4d154dca43c662571129af31b27433b919a32Adam Lesinski        ALOGW("couldn't allocate scanBuf: %s\n", strerror(errno));
17616c4d154dca43c662571129af31b27433b919a32Adam Lesinski        return false;
17716c4d154dca43c662571129af31b27433b919a32Adam Lesinski    }
17816c4d154dca43c662571129af31b27433b919a32Adam Lesinski
17916c4d154dca43c662571129af31b27433b919a32Adam Lesinski    actual = TEMP_FAILURE_RETRY(read(fd, scanBuf, footerSize));
18016c4d154dca43c662571129af31b27433b919a32Adam Lesinski    // readAmount is guaranteed to be less than kMaxBufSize
18116c4d154dca43c662571129af31b27433b919a32Adam Lesinski    if (actual != (ssize_t)footerSize) {
18216c4d154dca43c662571129af31b27433b919a32Adam Lesinski        ALOGI("couldn't read ObbFile footer: %s\n", strerror(errno));
18316c4d154dca43c662571129af31b27433b919a32Adam Lesinski        free(scanBuf);
18416c4d154dca43c662571129af31b27433b919a32Adam Lesinski        return false;
18516c4d154dca43c662571129af31b27433b919a32Adam Lesinski    }
18616c4d154dca43c662571129af31b27433b919a32Adam Lesinski
18716c4d154dca43c662571129af31b27433b919a32Adam Lesinski#ifdef DEBUG
18816c4d154dca43c662571129af31b27433b919a32Adam Lesinski    for (int i = 0; i < footerSize; ++i) {
18916c4d154dca43c662571129af31b27433b919a32Adam Lesinski        ALOGI("char: 0x%02x\n", scanBuf[i]);
19016c4d154dca43c662571129af31b27433b919a32Adam Lesinski    }
19116c4d154dca43c662571129af31b27433b919a32Adam Lesinski#endif
19216c4d154dca43c662571129af31b27433b919a32Adam Lesinski
19316c4d154dca43c662571129af31b27433b919a32Adam Lesinski    uint32_t sigVersion = get4LE((unsigned char*)scanBuf);
19416c4d154dca43c662571129af31b27433b919a32Adam Lesinski    if (sigVersion != kSigVersion) {
19516c4d154dca43c662571129af31b27433b919a32Adam Lesinski        ALOGW("Unsupported ObbFile version %d\n", sigVersion);
19616c4d154dca43c662571129af31b27433b919a32Adam Lesinski        free(scanBuf);
19716c4d154dca43c662571129af31b27433b919a32Adam Lesinski        return false;
19816c4d154dca43c662571129af31b27433b919a32Adam Lesinski    }
19916c4d154dca43c662571129af31b27433b919a32Adam Lesinski
20016c4d154dca43c662571129af31b27433b919a32Adam Lesinski    mVersion = (int32_t) get4LE((unsigned char*)scanBuf + kPackageVersionOffset);
20116c4d154dca43c662571129af31b27433b919a32Adam Lesinski    mFlags = (int32_t) get4LE((unsigned char*)scanBuf + kFlagsOffset);
20216c4d154dca43c662571129af31b27433b919a32Adam Lesinski
20316c4d154dca43c662571129af31b27433b919a32Adam Lesinski    memcpy(&mSalt, (unsigned char*)scanBuf + kSaltOffset, sizeof(mSalt));
20416c4d154dca43c662571129af31b27433b919a32Adam Lesinski
20516c4d154dca43c662571129af31b27433b919a32Adam Lesinski    size_t packageNameLen = get4LE((unsigned char*)scanBuf + kPackageNameLenOffset);
20616c4d154dca43c662571129af31b27433b919a32Adam Lesinski    if (packageNameLen == 0
20716c4d154dca43c662571129af31b27433b919a32Adam Lesinski            || packageNameLen > (footerSize - kPackageNameOffset)) {
20816c4d154dca43c662571129af31b27433b919a32Adam Lesinski        ALOGW("bad ObbFile package name length (0x%04zx; 0x%04zx possible)\n",
20916c4d154dca43c662571129af31b27433b919a32Adam Lesinski                packageNameLen, footerSize - kPackageNameOffset);
21016c4d154dca43c662571129af31b27433b919a32Adam Lesinski        free(scanBuf);
21116c4d154dca43c662571129af31b27433b919a32Adam Lesinski        return false;
21216c4d154dca43c662571129af31b27433b919a32Adam Lesinski    }
21316c4d154dca43c662571129af31b27433b919a32Adam Lesinski
21416c4d154dca43c662571129af31b27433b919a32Adam Lesinski    char* packageName = reinterpret_cast<char*>(scanBuf + kPackageNameOffset);
21516c4d154dca43c662571129af31b27433b919a32Adam Lesinski    mPackageName = String8(const_cast<char*>(packageName), packageNameLen);
21616c4d154dca43c662571129af31b27433b919a32Adam Lesinski
21716c4d154dca43c662571129af31b27433b919a32Adam Lesinski    free(scanBuf);
21816c4d154dca43c662571129af31b27433b919a32Adam Lesinski
21916c4d154dca43c662571129af31b27433b919a32Adam Lesinski#ifdef DEBUG
22016c4d154dca43c662571129af31b27433b919a32Adam Lesinski    ALOGI("Obb scan succeeded: packageName=%s, version=%d\n", mPackageName.string(), mVersion);
22116c4d154dca43c662571129af31b27433b919a32Adam Lesinski#endif
22216c4d154dca43c662571129af31b27433b919a32Adam Lesinski
22316c4d154dca43c662571129af31b27433b919a32Adam Lesinski    return true;
22416c4d154dca43c662571129af31b27433b919a32Adam Lesinski}
22516c4d154dca43c662571129af31b27433b919a32Adam Lesinski
22616c4d154dca43c662571129af31b27433b919a32Adam Lesinskibool ObbFile::writeTo(const char* filename)
22716c4d154dca43c662571129af31b27433b919a32Adam Lesinski{
22816c4d154dca43c662571129af31b27433b919a32Adam Lesinski    int fd;
22916c4d154dca43c662571129af31b27433b919a32Adam Lesinski    bool success = false;
23016c4d154dca43c662571129af31b27433b919a32Adam Lesinski
23116c4d154dca43c662571129af31b27433b919a32Adam Lesinski    fd = ::open(filename, O_WRONLY);
23216c4d154dca43c662571129af31b27433b919a32Adam Lesinski    if (fd < 0) {
23316c4d154dca43c662571129af31b27433b919a32Adam Lesinski        goto out;
23416c4d154dca43c662571129af31b27433b919a32Adam Lesinski    }
23516c4d154dca43c662571129af31b27433b919a32Adam Lesinski    success = writeTo(fd);
23616c4d154dca43c662571129af31b27433b919a32Adam Lesinski    close(fd);
23716c4d154dca43c662571129af31b27433b919a32Adam Lesinski
23816c4d154dca43c662571129af31b27433b919a32Adam Lesinskiout:
23916c4d154dca43c662571129af31b27433b919a32Adam Lesinski    if (!success) {
24016c4d154dca43c662571129af31b27433b919a32Adam Lesinski        ALOGW("failed to write to %s: %s\n", filename, strerror(errno));
24116c4d154dca43c662571129af31b27433b919a32Adam Lesinski    }
24216c4d154dca43c662571129af31b27433b919a32Adam Lesinski    return success;
24316c4d154dca43c662571129af31b27433b919a32Adam Lesinski}
24416c4d154dca43c662571129af31b27433b919a32Adam Lesinski
24516c4d154dca43c662571129af31b27433b919a32Adam Lesinskibool ObbFile::writeTo(int fd)
24616c4d154dca43c662571129af31b27433b919a32Adam Lesinski{
24716c4d154dca43c662571129af31b27433b919a32Adam Lesinski    if (fd < 0) {
24816c4d154dca43c662571129af31b27433b919a32Adam Lesinski        return false;
24916c4d154dca43c662571129af31b27433b919a32Adam Lesinski    }
25016c4d154dca43c662571129af31b27433b919a32Adam Lesinski
25116c4d154dca43c662571129af31b27433b919a32Adam Lesinski    lseek64(fd, 0, SEEK_END);
25216c4d154dca43c662571129af31b27433b919a32Adam Lesinski
25316c4d154dca43c662571129af31b27433b919a32Adam Lesinski    if (mPackageName.size() == 0 || mVersion == -1) {
25416c4d154dca43c662571129af31b27433b919a32Adam Lesinski        ALOGW("tried to write uninitialized ObbFile data\n");
25516c4d154dca43c662571129af31b27433b919a32Adam Lesinski        return false;
25616c4d154dca43c662571129af31b27433b919a32Adam Lesinski    }
25716c4d154dca43c662571129af31b27433b919a32Adam Lesinski
25816c4d154dca43c662571129af31b27433b919a32Adam Lesinski    unsigned char intBuf[sizeof(uint32_t)+1];
25916c4d154dca43c662571129af31b27433b919a32Adam Lesinski    memset(&intBuf, 0, sizeof(intBuf));
26016c4d154dca43c662571129af31b27433b919a32Adam Lesinski
26116c4d154dca43c662571129af31b27433b919a32Adam Lesinski    put4LE(intBuf, kSigVersion);
26216c4d154dca43c662571129af31b27433b919a32Adam Lesinski    if (write(fd, &intBuf, sizeof(uint32_t)) != (ssize_t)sizeof(uint32_t)) {
26316c4d154dca43c662571129af31b27433b919a32Adam Lesinski        ALOGW("couldn't write signature version: %s\n", strerror(errno));
26416c4d154dca43c662571129af31b27433b919a32Adam Lesinski        return false;
26516c4d154dca43c662571129af31b27433b919a32Adam Lesinski    }
26616c4d154dca43c662571129af31b27433b919a32Adam Lesinski
26716c4d154dca43c662571129af31b27433b919a32Adam Lesinski    put4LE(intBuf, mVersion);
26816c4d154dca43c662571129af31b27433b919a32Adam Lesinski    if (write(fd, &intBuf, sizeof(uint32_t)) != (ssize_t)sizeof(uint32_t)) {
26916c4d154dca43c662571129af31b27433b919a32Adam Lesinski        ALOGW("couldn't write package version\n");
27016c4d154dca43c662571129af31b27433b919a32Adam Lesinski        return false;
27116c4d154dca43c662571129af31b27433b919a32Adam Lesinski    }
27216c4d154dca43c662571129af31b27433b919a32Adam Lesinski
27316c4d154dca43c662571129af31b27433b919a32Adam Lesinski    put4LE(intBuf, mFlags);
27416c4d154dca43c662571129af31b27433b919a32Adam Lesinski    if (write(fd, &intBuf, sizeof(uint32_t)) != (ssize_t)sizeof(uint32_t)) {
27516c4d154dca43c662571129af31b27433b919a32Adam Lesinski        ALOGW("couldn't write package version\n");
27616c4d154dca43c662571129af31b27433b919a32Adam Lesinski        return false;
27716c4d154dca43c662571129af31b27433b919a32Adam Lesinski    }
27816c4d154dca43c662571129af31b27433b919a32Adam Lesinski
27916c4d154dca43c662571129af31b27433b919a32Adam Lesinski    if (write(fd, mSalt, sizeof(mSalt)) != (ssize_t)sizeof(mSalt)) {
28016c4d154dca43c662571129af31b27433b919a32Adam Lesinski        ALOGW("couldn't write salt: %s\n", strerror(errno));
28116c4d154dca43c662571129af31b27433b919a32Adam Lesinski        return false;
28216c4d154dca43c662571129af31b27433b919a32Adam Lesinski    }
28316c4d154dca43c662571129af31b27433b919a32Adam Lesinski
28416c4d154dca43c662571129af31b27433b919a32Adam Lesinski    size_t packageNameLen = mPackageName.size();
28516c4d154dca43c662571129af31b27433b919a32Adam Lesinski    put4LE(intBuf, packageNameLen);
28616c4d154dca43c662571129af31b27433b919a32Adam Lesinski    if (write(fd, &intBuf, sizeof(uint32_t)) != (ssize_t)sizeof(uint32_t)) {
28716c4d154dca43c662571129af31b27433b919a32Adam Lesinski        ALOGW("couldn't write package name length: %s\n", strerror(errno));
28816c4d154dca43c662571129af31b27433b919a32Adam Lesinski        return false;
28916c4d154dca43c662571129af31b27433b919a32Adam Lesinski    }
29016c4d154dca43c662571129af31b27433b919a32Adam Lesinski
29116c4d154dca43c662571129af31b27433b919a32Adam Lesinski    if (write(fd, mPackageName.string(), packageNameLen) != (ssize_t)packageNameLen) {
29216c4d154dca43c662571129af31b27433b919a32Adam Lesinski        ALOGW("couldn't write package name: %s\n", strerror(errno));
29316c4d154dca43c662571129af31b27433b919a32Adam Lesinski        return false;
29416c4d154dca43c662571129af31b27433b919a32Adam Lesinski    }
29516c4d154dca43c662571129af31b27433b919a32Adam Lesinski
29616c4d154dca43c662571129af31b27433b919a32Adam Lesinski    put4LE(intBuf, kPackageNameOffset + packageNameLen);
29716c4d154dca43c662571129af31b27433b919a32Adam Lesinski    if (write(fd, &intBuf, sizeof(uint32_t)) != (ssize_t)sizeof(uint32_t)) {
29816c4d154dca43c662571129af31b27433b919a32Adam Lesinski        ALOGW("couldn't write footer size: %s\n", strerror(errno));
29916c4d154dca43c662571129af31b27433b919a32Adam Lesinski        return false;
30016c4d154dca43c662571129af31b27433b919a32Adam Lesinski    }
30116c4d154dca43c662571129af31b27433b919a32Adam Lesinski
30216c4d154dca43c662571129af31b27433b919a32Adam Lesinski    put4LE(intBuf, kSignature);
30316c4d154dca43c662571129af31b27433b919a32Adam Lesinski    if (write(fd, &intBuf, sizeof(uint32_t)) != (ssize_t)sizeof(uint32_t)) {
30416c4d154dca43c662571129af31b27433b919a32Adam Lesinski        ALOGW("couldn't write footer magic signature: %s\n", strerror(errno));
30516c4d154dca43c662571129af31b27433b919a32Adam Lesinski        return false;
30616c4d154dca43c662571129af31b27433b919a32Adam Lesinski    }
30716c4d154dca43c662571129af31b27433b919a32Adam Lesinski
30816c4d154dca43c662571129af31b27433b919a32Adam Lesinski    return true;
30916c4d154dca43c662571129af31b27433b919a32Adam Lesinski}
31016c4d154dca43c662571129af31b27433b919a32Adam Lesinski
31116c4d154dca43c662571129af31b27433b919a32Adam Lesinskibool ObbFile::removeFrom(const char* filename)
31216c4d154dca43c662571129af31b27433b919a32Adam Lesinski{
31316c4d154dca43c662571129af31b27433b919a32Adam Lesinski    int fd;
31416c4d154dca43c662571129af31b27433b919a32Adam Lesinski    bool success = false;
31516c4d154dca43c662571129af31b27433b919a32Adam Lesinski
31616c4d154dca43c662571129af31b27433b919a32Adam Lesinski    fd = ::open(filename, O_RDWR);
31716c4d154dca43c662571129af31b27433b919a32Adam Lesinski    if (fd < 0) {
31816c4d154dca43c662571129af31b27433b919a32Adam Lesinski        goto out;
31916c4d154dca43c662571129af31b27433b919a32Adam Lesinski    }
32016c4d154dca43c662571129af31b27433b919a32Adam Lesinski    success = removeFrom(fd);
32116c4d154dca43c662571129af31b27433b919a32Adam Lesinski    close(fd);
32216c4d154dca43c662571129af31b27433b919a32Adam Lesinski
32316c4d154dca43c662571129af31b27433b919a32Adam Lesinskiout:
32416c4d154dca43c662571129af31b27433b919a32Adam Lesinski    if (!success) {
32516c4d154dca43c662571129af31b27433b919a32Adam Lesinski        ALOGW("failed to remove signature from %s: %s\n", filename, strerror(errno));
32616c4d154dca43c662571129af31b27433b919a32Adam Lesinski    }
32716c4d154dca43c662571129af31b27433b919a32Adam Lesinski    return success;
32816c4d154dca43c662571129af31b27433b919a32Adam Lesinski}
32916c4d154dca43c662571129af31b27433b919a32Adam Lesinski
33016c4d154dca43c662571129af31b27433b919a32Adam Lesinskibool ObbFile::removeFrom(int fd)
33116c4d154dca43c662571129af31b27433b919a32Adam Lesinski{
33216c4d154dca43c662571129af31b27433b919a32Adam Lesinski    if (fd < 0) {
33316c4d154dca43c662571129af31b27433b919a32Adam Lesinski        return false;
33416c4d154dca43c662571129af31b27433b919a32Adam Lesinski    }
33516c4d154dca43c662571129af31b27433b919a32Adam Lesinski
33616c4d154dca43c662571129af31b27433b919a32Adam Lesinski    if (!readFrom(fd)) {
33716c4d154dca43c662571129af31b27433b919a32Adam Lesinski        return false;
33816c4d154dca43c662571129af31b27433b919a32Adam Lesinski    }
33916c4d154dca43c662571129af31b27433b919a32Adam Lesinski
34016c4d154dca43c662571129af31b27433b919a32Adam Lesinski    ftruncate(fd, mFooterStart);
34116c4d154dca43c662571129af31b27433b919a32Adam Lesinski
34216c4d154dca43c662571129af31b27433b919a32Adam Lesinski    return true;
34316c4d154dca43c662571129af31b27433b919a32Adam Lesinski}
34416c4d154dca43c662571129af31b27433b919a32Adam Lesinski
34516c4d154dca43c662571129af31b27433b919a32Adam Lesinski}
346