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