/* * Copyright 2015 The Chromium OS Authors. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #include #include #include #include #include #include #include #include #include #include "file_type.h" #include "futility.h" #include "gbb_header.h" /* Human-readable strings */ static const char * const type_strings[] = { "unknown", "VbPublicKey", "VbKeyBlock", "VbFirmwarePreamble", "GBB", "Chrome OS BIOS image", "Cr-48 Chrome OS BIOS image", "VbKernelPreamble", "raw firmware", "raw kernel", "chromiumos disk image", "VbPrivateKey", }; BUILD_ASSERT(ARRAY_SIZE(type_strings) == NUM_FILE_TYPES); const char * const futil_file_type_str(enum futil_file_type type) { if (type < 0 || type >= NUM_FILE_TYPES) type = FILE_TYPE_UNKNOWN; return type_strings[type]; } /* Try these in order so we recognize the larger objects first */ enum futil_file_type (*recognizers[])(uint8_t *buf, uint32_t len) = { &recognize_gpt, &recognize_bios_image, &recognize_gbb, &recognize_vblock1, &recognize_privkey, }; /* Try to figure out what we're looking at */ enum futil_file_type futil_file_type_buf(uint8_t *buf, uint32_t len) { enum futil_file_type type; int i; for (i = 0; i < ARRAY_SIZE(recognizers); i++) { type = recognizers[i](buf, len); if (type != FILE_TYPE_UNKNOWN) return type; } return FILE_TYPE_UNKNOWN; } enum futil_file_err futil_file_type(const char *filename, enum futil_file_type *type) { int ifd; uint8_t *buf; uint32_t buf_len; struct stat sb; enum futil_file_err err = FILE_ERR_NONE; *type = FILE_TYPE_UNKNOWN; ifd = open(filename, O_RDONLY); if (ifd < 0) { fprintf(stderr, "Can't open %s: %s\n", filename, strerror(errno)); return FILE_ERR_OPEN; } if (0 != fstat(ifd, &sb)) { fprintf(stderr, "Can't stat input file: %s\n", strerror(errno)); return FILE_ERR_STAT; } if (S_ISREG(sb.st_mode) || S_ISBLK(sb.st_mode)) { err = futil_map_file(ifd, MAP_RO, &buf, &buf_len); if (err) { close(ifd); return err; } *type = futil_file_type_buf(buf, buf_len); err = futil_unmap_file(ifd, MAP_RO, buf, buf_len); if (err) { close(ifd); return err; } } else if (S_ISDIR(sb.st_mode)) { err = FILE_ERR_DIR; } else if (S_ISCHR(sb.st_mode)) { err = FILE_ERR_CHR; } else if (S_ISFIFO(sb.st_mode)) { err = FILE_ERR_FIFO; } else if (S_ISSOCK(sb.st_mode)) { err = FILE_ERR_SOCK; } if (close(ifd)) { fprintf(stderr, "Error when closing %s: %s\n", filename, strerror(errno)); return FILE_ERR_CLOSE; } return err; }