123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183 |
- /*
- * 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 <errno.h>
- #include <fcntl.h>
- #include <stdint.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <sys/stat.h>
- #include <sys/types.h>
- #include <unistd.h>
- #include "file_type.h"
- #include "futility.h"
- #include "gbb_header.h"
- /* Description and functions to handle each file type */
- struct futil_file_type_s {
- /* Short name for this type */
- const char *name;
- /* Human-readable description */
- const char *desc;
- /* Functions to identify, display, and sign this type of file. */
- enum futil_file_type (*recognize)(uint8_t *buf, uint32_t len);
- int (*show)(const char *name, uint8_t *buf, uint32_t len, void *data);
- int (*sign)(const char *name, uint8_t *buf, uint32_t len, void *data);
- };
- /* Populate a list of file types and operator functions. */
- static const struct futil_file_type_s futil_file_types[] = {
- {"unknown", "not something we know about", 0, 0, 0},
- #define R_(x) x
- #define S_(x) x
- #define NONE 0
- #define FILE_TYPE(A, B, C, D, E, F) {B, C, D, E, F},
- #include "file_type.inc"
- #undef FILE_TYPE
- #undef NONE
- #undef S_
- #undef R_
- };
- const char * const futil_file_type_name(enum futil_file_type type)
- {
- return futil_file_types[type].name;
- }
- const char * const futil_file_type_desc(enum futil_file_type type)
- {
- return futil_file_types[type].desc;
- }
- /* Name to enum. Returns true on success. */
- int futil_str_to_file_type(const char *str, enum futil_file_type *type)
- {
- int i;
- for (i = 0; i < NUM_FILE_TYPES; i++)
- if (!strcasecmp(str, futil_file_types[i].name)) {
- *type = i;
- return 1;
- }
- *type = FILE_TYPE_UNKNOWN;
- return 0;
- }
- /* Print the list of type names and exit with the given value. */
- void print_file_types_and_exit(int retval)
- {
- int i;
- printf("\nValid file types are:\n\n");
- for (i = 0; i < NUM_FILE_TYPES; i++)
- printf(" %-20s%s\n", futil_file_types[i].name,
- futil_file_types[i].desc);
- printf("\n");
- exit(retval);
- }
- /* 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 < NUM_FILE_TYPES; i++) {
- if (futil_file_types[i].recognize) {
- type = futil_file_types[i].recognize(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));
- close(ifd);
- 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;
- }
- int futil_file_type_show(enum futil_file_type type,
- const char *filename,
- uint8_t *buf, uint32_t len)
- {
- if (futil_file_types[type].show)
- return futil_file_types[type].show(filename, buf, len, 0);
- fprintf(stderr, "Don't know how to show %s (type %s)\n",
- filename, futil_file_type_name(type));
- return 1;
- }
- int futil_file_type_sign(enum futil_file_type type,
- const char *filename,
- uint8_t *buf, uint32_t len)
- {
- if (futil_file_types[type].sign)
- return futil_file_types[type].sign(filename, buf, len, 0);
- fprintf(stderr, "Don't know how to sign %s (type %s)\n",
- filename, futil_file_type_name(type));
- return 1;
- }
|