15096e66d07db8041589518f8c5b0281d859d0817Vladimir Marko/* 25096e66d07db8041589518f8c5b0281d859d0817Vladimir Marko * Copyright (C) 2015 The Android Open Source Project 35096e66d07db8041589518f8c5b0281d859d0817Vladimir Marko * 45096e66d07db8041589518f8c5b0281d859d0817Vladimir Marko * Licensed under the Apache License, Version 2.0 (the "License"); 55096e66d07db8041589518f8c5b0281d859d0817Vladimir Marko * you may not use this file except in compliance with the License. 65096e66d07db8041589518f8c5b0281d859d0817Vladimir Marko * You may obtain a copy of the License at 75096e66d07db8041589518f8c5b0281d859d0817Vladimir Marko * 85096e66d07db8041589518f8c5b0281d859d0817Vladimir Marko * http://www.apache.org/licenses/LICENSE-2.0 95096e66d07db8041589518f8c5b0281d859d0817Vladimir Marko * 105096e66d07db8041589518f8c5b0281d859d0817Vladimir Marko * Unless required by applicable law or agreed to in writing, software 115096e66d07db8041589518f8c5b0281d859d0817Vladimir Marko * distributed under the License is distributed on an "AS IS" BASIS, 125096e66d07db8041589518f8c5b0281d859d0817Vladimir Marko * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 135096e66d07db8041589518f8c5b0281d859d0817Vladimir Marko * See the License for the specific language governing permissions and 145096e66d07db8041589518f8c5b0281d859d0817Vladimir Marko * limitations under the License. 155096e66d07db8041589518f8c5b0281d859d0817Vladimir Marko */ 165096e66d07db8041589518f8c5b0281d859d0817Vladimir Marko 175096e66d07db8041589518f8c5b0281d859d0817Vladimir Marko#include "file_magic.h" 185096e66d07db8041589518f8c5b0281d859d0817Vladimir Marko 195096e66d07db8041589518f8c5b0281d859d0817Vladimir Marko#include <fcntl.h> 205096e66d07db8041589518f8c5b0281d859d0817Vladimir Marko#include <sys/stat.h> 215096e66d07db8041589518f8c5b0281d859d0817Vladimir Marko#include <sys/types.h> 225096e66d07db8041589518f8c5b0281d859d0817Vladimir Marko 2357943810cfc789da890d73621741729da5feaaf8Andreas Gampe#include <android-base/logging.h> 2457943810cfc789da890d73621741729da5feaaf8Andreas Gampe#include <android-base/stringprintf.h> 2546ee31b67d7ee1bd085fbc240502053caa3cf8faAndreas Gampe 2643e10b031e3bb42df54adf8f0525a29d2b308a4eAndreas Gampe#include "base/unix_file/fd_file.h" 275096e66d07db8041589518f8c5b0281d859d0817Vladimir Marko 285096e66d07db8041589518f8c5b0281d859d0817Vladimir Markonamespace art { 295096e66d07db8041589518f8c5b0281d859d0817Vladimir Marko 3046ee31b67d7ee1bd085fbc240502053caa3cf8faAndreas Gampeusing android::base::StringPrintf; 3146ee31b67d7ee1bd085fbc240502053caa3cf8faAndreas Gampe 3243e10b031e3bb42df54adf8f0525a29d2b308a4eAndreas GampeFile OpenAndReadMagic(const char* filename, uint32_t* magic, std::string* error_msg) { 335096e66d07db8041589518f8c5b0281d859d0817Vladimir Marko CHECK(magic != nullptr); 3443e10b031e3bb42df54adf8f0525a29d2b308a4eAndreas Gampe File fd(filename, O_RDONLY, /* check_usage */ false); 3543e10b031e3bb42df54adf8f0525a29d2b308a4eAndreas Gampe if (fd.Fd() == -1) { 365096e66d07db8041589518f8c5b0281d859d0817Vladimir Marko *error_msg = StringPrintf("Unable to open '%s' : %s", filename, strerror(errno)); 3743e10b031e3bb42df54adf8f0525a29d2b308a4eAndreas Gampe return File(); 385096e66d07db8041589518f8c5b0281d859d0817Vladimir Marko } 39c12bf4c0b6e760f5f1e4255705ac5c3c90fa0c13Shubham Ajmera if (!ReadMagicAndReset(fd.Fd(), magic, error_msg)) { 40c12bf4c0b6e760f5f1e4255705ac5c3c90fa0c13Shubham Ajmera StringPrintf("Error in reading magic from file %s: %s", filename, error_msg->c_str()); 4143e10b031e3bb42df54adf8f0525a29d2b308a4eAndreas Gampe return File(); 425096e66d07db8041589518f8c5b0281d859d0817Vladimir Marko } 435096e66d07db8041589518f8c5b0281d859d0817Vladimir Marko return fd; 445096e66d07db8041589518f8c5b0281d859d0817Vladimir Marko} 455096e66d07db8041589518f8c5b0281d859d0817Vladimir Marko 46c12bf4c0b6e760f5f1e4255705ac5c3c90fa0c13Shubham Ajmerabool ReadMagicAndReset(int fd, uint32_t* magic, std::string* error_msg) { 47c12bf4c0b6e760f5f1e4255705ac5c3c90fa0c13Shubham Ajmera int n = TEMP_FAILURE_RETRY(read(fd, magic, sizeof(*magic))); 48c12bf4c0b6e760f5f1e4255705ac5c3c90fa0c13Shubham Ajmera if (n != sizeof(*magic)) { 49c12bf4c0b6e760f5f1e4255705ac5c3c90fa0c13Shubham Ajmera *error_msg = StringPrintf("Failed to find magic"); 50c12bf4c0b6e760f5f1e4255705ac5c3c90fa0c13Shubham Ajmera return false; 51c12bf4c0b6e760f5f1e4255705ac5c3c90fa0c13Shubham Ajmera } 52c12bf4c0b6e760f5f1e4255705ac5c3c90fa0c13Shubham Ajmera if (lseek(fd, 0, SEEK_SET) != 0) { 53c12bf4c0b6e760f5f1e4255705ac5c3c90fa0c13Shubham Ajmera *error_msg = StringPrintf("Failed to seek to beginning of file : %s", strerror(errno)); 54c12bf4c0b6e760f5f1e4255705ac5c3c90fa0c13Shubham Ajmera return false; 55c12bf4c0b6e760f5f1e4255705ac5c3c90fa0c13Shubham Ajmera } 56c12bf4c0b6e760f5f1e4255705ac5c3c90fa0c13Shubham Ajmera return true; 57c12bf4c0b6e760f5f1e4255705ac5c3c90fa0c13Shubham Ajmera} 58c12bf4c0b6e760f5f1e4255705ac5c3c90fa0c13Shubham Ajmera 595096e66d07db8041589518f8c5b0281d859d0817Vladimir Markobool IsZipMagic(uint32_t magic) { 605096e66d07db8041589518f8c5b0281d859d0817Vladimir Marko return (('P' == ((magic >> 0) & 0xff)) && 615096e66d07db8041589518f8c5b0281d859d0817Vladimir Marko ('K' == ((magic >> 8) & 0xff))); 625096e66d07db8041589518f8c5b0281d859d0817Vladimir Marko} 635096e66d07db8041589518f8c5b0281d859d0817Vladimir Marko 645096e66d07db8041589518f8c5b0281d859d0817Vladimir Marko} // namespace art 65