Bill Richardson | 2559338 | 2015-01-30 12:22:28 -0800 | [diff] [blame] | 1 | /* |
| 2 | * Copyright 2015 The Chromium OS Authors. All rights reserved. |
| 3 | * Use of this source code is governed by a BSD-style license that can be |
| 4 | * found in the LICENSE file. |
| 5 | */ |
| 6 | |
| 7 | #include <errno.h> |
| 8 | #include <fcntl.h> |
| 9 | #include <stdint.h> |
| 10 | #include <stdio.h> |
| 11 | #include <stdlib.h> |
| 12 | #include <string.h> |
| 13 | #include <sys/stat.h> |
| 14 | #include <sys/types.h> |
| 15 | #include <unistd.h> |
| 16 | |
| 17 | #include "file_type.h" |
| 18 | #include "futility.h" |
| 19 | #include "gbb_header.h" |
| 20 | |
| 21 | /* Human-readable strings */ |
| 22 | static const char * const type_strings[] = { |
| 23 | "unknown", |
| 24 | "VbPublicKey", |
| 25 | "VbKeyBlock", |
| 26 | "VbFirmwarePreamble", |
| 27 | "GBB", |
| 28 | "Chrome OS BIOS image", |
| 29 | "Cr-48 Chrome OS BIOS image", |
| 30 | "VbKernelPreamble", |
| 31 | "raw firmware", |
| 32 | "raw kernel", |
| 33 | "chromiumos disk image", |
Bill Richardson | 4805f18 | 2015-01-30 22:21:10 -0800 | [diff] [blame] | 34 | "VbPrivateKey", |
Bill Richardson | 2559338 | 2015-01-30 12:22:28 -0800 | [diff] [blame] | 35 | }; |
| 36 | BUILD_ASSERT(ARRAY_SIZE(type_strings) == NUM_FILE_TYPES); |
| 37 | |
| 38 | const char * const futil_file_type_str(enum futil_file_type type) |
| 39 | { |
David Riley | 05987b1 | 2015-02-05 19:22:49 -0800 | [diff] [blame] | 40 | if ((int) type < 0 || type >= NUM_FILE_TYPES) |
Bill Richardson | 2559338 | 2015-01-30 12:22:28 -0800 | [diff] [blame] | 41 | type = FILE_TYPE_UNKNOWN; |
| 42 | |
| 43 | return type_strings[type]; |
| 44 | } |
| 45 | |
| 46 | /* Try these in order so we recognize the larger objects first */ |
| 47 | enum futil_file_type (*recognizers[])(uint8_t *buf, uint32_t len) = { |
| 48 | &recognize_gpt, |
| 49 | &recognize_bios_image, |
| 50 | &recognize_gbb, |
| 51 | &recognize_vblock1, |
Bill Richardson | 4805f18 | 2015-01-30 22:21:10 -0800 | [diff] [blame] | 52 | &recognize_privkey, |
Bill Richardson | 2559338 | 2015-01-30 12:22:28 -0800 | [diff] [blame] | 53 | }; |
| 54 | |
| 55 | /* Try to figure out what we're looking at */ |
| 56 | enum futil_file_type futil_file_type_buf(uint8_t *buf, uint32_t len) |
| 57 | { |
| 58 | enum futil_file_type type; |
| 59 | int i; |
| 60 | |
| 61 | for (i = 0; i < ARRAY_SIZE(recognizers); i++) { |
| 62 | type = recognizers[i](buf, len); |
| 63 | if (type != FILE_TYPE_UNKNOWN) |
| 64 | return type; |
| 65 | } |
| 66 | |
| 67 | return FILE_TYPE_UNKNOWN; |
| 68 | } |
| 69 | |
| 70 | enum futil_file_err futil_file_type(const char *filename, |
| 71 | enum futil_file_type *type) |
| 72 | { |
| 73 | int ifd; |
| 74 | uint8_t *buf; |
| 75 | uint32_t buf_len; |
| 76 | struct stat sb; |
| 77 | enum futil_file_err err = FILE_ERR_NONE; |
| 78 | |
| 79 | *type = FILE_TYPE_UNKNOWN; |
| 80 | |
| 81 | ifd = open(filename, O_RDONLY); |
| 82 | if (ifd < 0) { |
| 83 | fprintf(stderr, "Can't open %s: %s\n", |
| 84 | filename, strerror(errno)); |
| 85 | return FILE_ERR_OPEN; |
| 86 | } |
| 87 | |
| 88 | if (0 != fstat(ifd, &sb)) { |
| 89 | fprintf(stderr, "Can't stat input file: %s\n", |
| 90 | strerror(errno)); |
| 91 | return FILE_ERR_STAT; |
| 92 | } |
| 93 | |
| 94 | if (S_ISREG(sb.st_mode) || S_ISBLK(sb.st_mode)) { |
| 95 | err = futil_map_file(ifd, MAP_RO, &buf, &buf_len); |
| 96 | if (err) { |
| 97 | close(ifd); |
| 98 | return err; |
| 99 | } |
| 100 | |
| 101 | *type = futil_file_type_buf(buf, buf_len); |
| 102 | |
| 103 | err = futil_unmap_file(ifd, MAP_RO, buf, buf_len); |
| 104 | if (err) { |
| 105 | close(ifd); |
| 106 | return err; |
| 107 | } |
| 108 | } else if (S_ISDIR(sb.st_mode)) { |
| 109 | err = FILE_ERR_DIR; |
| 110 | } else if (S_ISCHR(sb.st_mode)) { |
| 111 | err = FILE_ERR_CHR; |
| 112 | } else if (S_ISFIFO(sb.st_mode)) { |
| 113 | err = FILE_ERR_FIFO; |
| 114 | } else if (S_ISSOCK(sb.st_mode)) { |
| 115 | err = FILE_ERR_SOCK; |
| 116 | } |
| 117 | |
| 118 | if (close(ifd)) { |
| 119 | fprintf(stderr, "Error when closing %s: %s\n", |
| 120 | filename, strerror(errno)); |
| 121 | return FILE_ERR_CLOSE; |
| 122 | } |
| 123 | |
| 124 | return err; |
| 125 | } |