summaryrefslogtreecommitdiffstats
path: root/libs/utils/ObbFile.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'libs/utils/ObbFile.cpp')
-rw-r--r--libs/utils/ObbFile.cpp345
1 files changed, 0 insertions, 345 deletions
diff --git a/libs/utils/ObbFile.cpp b/libs/utils/ObbFile.cpp
deleted file mode 100644
index 21e06c8..0000000
--- a/libs/utils/ObbFile.cpp
+++ /dev/null
@@ -1,345 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <errno.h>
-#include <fcntl.h>
-#include <stdint.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-#define LOG_TAG "ObbFile"
-
-#include <androidfw/ObbFile.h>
-#include <utils/Compat.h>
-#include <utils/Log.h>
-
-//#define DEBUG 1
-
-#define kFooterTagSize 8 /* last two 32-bit integers */
-
-#define kFooterMinSize 33 /* 32-bit signature version (4 bytes)
- * 32-bit package version (4 bytes)
- * 32-bit flags (4 bytes)
- * 64-bit salt (8 bytes)
- * 32-bit package name size (4 bytes)
- * >=1-character package name (1 byte)
- * 32-bit footer size (4 bytes)
- * 32-bit footer marker (4 bytes)
- */
-
-#define kMaxBufSize 32768 /* Maximum file read buffer */
-
-#define kSignature 0x01059983U /* ObbFile signature */
-
-#define kSigVersion 1 /* We only know about signature version 1 */
-
-/* offsets in version 1 of the header */
-#define kPackageVersionOffset 4
-#define kFlagsOffset 8
-#define kSaltOffset 12
-#define kPackageNameLenOffset 20
-#define kPackageNameOffset 24
-
-/*
- * TEMP_FAILURE_RETRY is defined by some, but not all, versions of
- * <unistd.h>. (Alas, it is not as standard as we'd hoped!) So, if it's
- * not already defined, then define it here.
- */
-#ifndef TEMP_FAILURE_RETRY
-/* Used to retry syscalls that can return EINTR. */
-#define TEMP_FAILURE_RETRY(exp) ({ \
- typeof (exp) _rc; \
- do { \
- _rc = (exp); \
- } while (_rc == -1 && errno == EINTR); \
- _rc; })
-#endif
-
-
-namespace android {
-
-ObbFile::ObbFile()
- : mPackageName("")
- , mVersion(-1)
- , mFlags(0)
-{
- memset(mSalt, 0, sizeof(mSalt));
-}
-
-ObbFile::~ObbFile() {
-}
-
-bool ObbFile::readFrom(const char* filename)
-{
- int fd;
- bool success = false;
-
- fd = ::open(filename, O_RDONLY);
- if (fd < 0) {
- ALOGW("couldn't open file %s: %s", filename, strerror(errno));
- goto out;
- }
- success = readFrom(fd);
- close(fd);
-
- if (!success) {
- ALOGW("failed to read from %s (fd=%d)\n", filename, fd);
- }
-
-out:
- return success;
-}
-
-bool ObbFile::readFrom(int fd)
-{
- if (fd < 0) {
- ALOGW("attempt to read from invalid fd\n");
- return false;
- }
-
- return parseObbFile(fd);
-}
-
-bool ObbFile::parseObbFile(int fd)
-{
- off64_t fileLength = lseek64(fd, 0, SEEK_END);
-
- if (fileLength < kFooterMinSize) {
- if (fileLength < 0) {
- ALOGW("error seeking in ObbFile: %s\n", strerror(errno));
- } else {
- ALOGW("file is only %lld (less than %d minimum)\n", fileLength, kFooterMinSize);
- }
- return false;
- }
-
- ssize_t actual;
- size_t footerSize;
-
- {
- lseek64(fd, fileLength - kFooterTagSize, SEEK_SET);
-
- char *footer = new char[kFooterTagSize];
- actual = TEMP_FAILURE_RETRY(read(fd, footer, kFooterTagSize));
- if (actual != kFooterTagSize) {
- ALOGW("couldn't read footer signature: %s\n", strerror(errno));
- return false;
- }
-
- unsigned int fileSig = get4LE((unsigned char*)footer + sizeof(int32_t));
- if (fileSig != kSignature) {
- ALOGW("footer didn't match magic string (expected 0x%08x; got 0x%08x)\n",
- kSignature, fileSig);
- return false;
- }
-
- footerSize = get4LE((unsigned char*)footer);
- if (footerSize > (size_t)fileLength - kFooterTagSize
- || footerSize > kMaxBufSize) {
- ALOGW("claimed footer size is too large (0x%08zx; file size is 0x%08llx)\n",
- footerSize, fileLength);
- return false;
- }
-
- if (footerSize < (kFooterMinSize - kFooterTagSize)) {
- ALOGW("claimed footer size is too small (0x%zx; minimum size is 0x%x)\n",
- footerSize, kFooterMinSize - kFooterTagSize);
- return false;
- }
- }
-
- off64_t fileOffset = fileLength - footerSize - kFooterTagSize;
- if (lseek64(fd, fileOffset, SEEK_SET) != fileOffset) {
- ALOGW("seek %lld failed: %s\n", fileOffset, strerror(errno));
- return false;
- }
-
- mFooterStart = fileOffset;
-
- char* scanBuf = (char*)malloc(footerSize);
- if (scanBuf == NULL) {
- ALOGW("couldn't allocate scanBuf: %s\n", strerror(errno));
- return false;
- }
-
- actual = TEMP_FAILURE_RETRY(read(fd, scanBuf, footerSize));
- // readAmount is guaranteed to be less than kMaxBufSize
- if (actual != (ssize_t)footerSize) {
- ALOGI("couldn't read ObbFile footer: %s\n", strerror(errno));
- free(scanBuf);
- return false;
- }
-
-#ifdef DEBUG
- for (int i = 0; i < footerSize; ++i) {
- ALOGI("char: 0x%02x\n", scanBuf[i]);
- }
-#endif
-
- uint32_t sigVersion = get4LE((unsigned char*)scanBuf);
- if (sigVersion != kSigVersion) {
- ALOGW("Unsupported ObbFile version %d\n", sigVersion);
- free(scanBuf);
- return false;
- }
-
- mVersion = (int32_t) get4LE((unsigned char*)scanBuf + kPackageVersionOffset);
- mFlags = (int32_t) get4LE((unsigned char*)scanBuf + kFlagsOffset);
-
- memcpy(&mSalt, (unsigned char*)scanBuf + kSaltOffset, sizeof(mSalt));
-
- size_t packageNameLen = get4LE((unsigned char*)scanBuf + kPackageNameLenOffset);
- if (packageNameLen == 0
- || packageNameLen > (footerSize - kPackageNameOffset)) {
- ALOGW("bad ObbFile package name length (0x%04zx; 0x%04zx possible)\n",
- packageNameLen, footerSize - kPackageNameOffset);
- free(scanBuf);
- return false;
- }
-
- char* packageName = reinterpret_cast<char*>(scanBuf + kPackageNameOffset);
- mPackageName = String8(const_cast<char*>(packageName), packageNameLen);
-
- free(scanBuf);
-
-#ifdef DEBUG
- ALOGI("Obb scan succeeded: packageName=%s, version=%d\n", mPackageName.string(), mVersion);
-#endif
-
- return true;
-}
-
-bool ObbFile::writeTo(const char* filename)
-{
- int fd;
- bool success = false;
-
- fd = ::open(filename, O_WRONLY);
- if (fd < 0) {
- goto out;
- }
- success = writeTo(fd);
- close(fd);
-
-out:
- if (!success) {
- ALOGW("failed to write to %s: %s\n", filename, strerror(errno));
- }
- return success;
-}
-
-bool ObbFile::writeTo(int fd)
-{
- if (fd < 0) {
- return false;
- }
-
- lseek64(fd, 0, SEEK_END);
-
- if (mPackageName.size() == 0 || mVersion == -1) {
- ALOGW("tried to write uninitialized ObbFile data\n");
- return false;
- }
-
- unsigned char intBuf[sizeof(uint32_t)+1];
- memset(&intBuf, 0, sizeof(intBuf));
-
- put4LE(intBuf, kSigVersion);
- if (write(fd, &intBuf, sizeof(uint32_t)) != (ssize_t)sizeof(uint32_t)) {
- ALOGW("couldn't write signature version: %s\n", strerror(errno));
- return false;
- }
-
- put4LE(intBuf, mVersion);
- if (write(fd, &intBuf, sizeof(uint32_t)) != (ssize_t)sizeof(uint32_t)) {
- ALOGW("couldn't write package version\n");
- return false;
- }
-
- put4LE(intBuf, mFlags);
- if (write(fd, &intBuf, sizeof(uint32_t)) != (ssize_t)sizeof(uint32_t)) {
- ALOGW("couldn't write package version\n");
- return false;
- }
-
- if (write(fd, mSalt, sizeof(mSalt)) != (ssize_t)sizeof(mSalt)) {
- ALOGW("couldn't write salt: %s\n", strerror(errno));
- return false;
- }
-
- size_t packageNameLen = mPackageName.size();
- put4LE(intBuf, packageNameLen);
- if (write(fd, &intBuf, sizeof(uint32_t)) != (ssize_t)sizeof(uint32_t)) {
- ALOGW("couldn't write package name length: %s\n", strerror(errno));
- return false;
- }
-
- if (write(fd, mPackageName.string(), packageNameLen) != (ssize_t)packageNameLen) {
- ALOGW("couldn't write package name: %s\n", strerror(errno));
- return false;
- }
-
- put4LE(intBuf, kPackageNameOffset + packageNameLen);
- if (write(fd, &intBuf, sizeof(uint32_t)) != (ssize_t)sizeof(uint32_t)) {
- ALOGW("couldn't write footer size: %s\n", strerror(errno));
- return false;
- }
-
- put4LE(intBuf, kSignature);
- if (write(fd, &intBuf, sizeof(uint32_t)) != (ssize_t)sizeof(uint32_t)) {
- ALOGW("couldn't write footer magic signature: %s\n", strerror(errno));
- return false;
- }
-
- return true;
-}
-
-bool ObbFile::removeFrom(const char* filename)
-{
- int fd;
- bool success = false;
-
- fd = ::open(filename, O_RDWR);
- if (fd < 0) {
- goto out;
- }
- success = removeFrom(fd);
- close(fd);
-
-out:
- if (!success) {
- ALOGW("failed to remove signature from %s: %s\n", filename, strerror(errno));
- }
- return success;
-}
-
-bool ObbFile::removeFrom(int fd)
-{
- if (fd < 0) {
- return false;
- }
-
- if (!readFrom(fd)) {
- return false;
- }
-
- ftruncate(fd, mFooterStart);
-
- return true;
-}
-
-}