1/* 2 * Copyright (c) 2002 Fabrice Bellard 3 * Copyright (c) 2013 Michael Niedermayer 4 * Copyright (c) 2013 James Almer 5 * 6 * This file is part of FFmpeg. 7 * 8 * FFmpeg is free software; you can redistribute it and/or 9 * modify it under the terms of the GNU Lesser General Public 10 * License as published by the Free Software Foundation; either 11 * version 2.1 of the License, or (at your option) any later version. 12 * 13 * FFmpeg is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 * Lesser General Public License for more details. 17 * 18 * You should have received a copy of the GNU Lesser General Public 19 * License along with FFmpeg; if not, write to the Free Software 20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 21 */ 22 23#include "config.h" 24#include "libavutil/avstring.h" 25#include "libavutil/error.h" 26#include "libavutil/hash.h" 27 28#include <errno.h> 29#include <fcntl.h> 30#include <stdio.h> 31#include <string.h> 32#include <sys/stat.h> 33 34#if HAVE_IO_H 35#include <io.h> 36#endif 37#if HAVE_UNISTD_H 38#include <unistd.h> 39#endif 40 41#define SIZE 65536 42 43static struct AVHashContext *hash; 44static int out_b64; 45 46static void usage(void) 47{ 48 int i = 0; 49 const char *name; 50 51 printf("usage: ffhash [b64:]algorithm [input]...\n"); 52 printf("Supported hash algorithms:"); 53 do { 54 name = av_hash_names(i); 55 if (name) 56 printf(" %s", name); 57 i++; 58 } while(name); 59 printf("\n"); 60} 61 62static void finish(void) 63{ 64 char res[2 * AV_HASH_MAX_SIZE + 4]; 65 66 printf("%s=", av_hash_get_name(hash)); 67 if (out_b64) { 68 av_hash_final_b64(hash, res, sizeof(res)); 69 printf("b64:%s", res); 70 } else { 71 av_hash_final_hex(hash, res, sizeof(res)); 72 printf("0x%s", res); 73 } 74} 75 76static int check(char *file) 77{ 78 uint8_t buffer[SIZE]; 79 int fd, flags = O_RDONLY; 80 int ret = 0; 81 82#ifdef O_BINARY 83 flags |= O_BINARY; 84#endif 85 if (file) fd = open(file, flags); 86 else fd = 0; 87 if (fd == -1) { 88 printf("%s=OPEN-FAILED: %s:", av_hash_get_name(hash), strerror(errno)); 89 ret = 1; 90 goto end; 91 } 92 93 av_hash_init(hash); 94 for (;;) { 95 int size = read(fd, buffer, SIZE); 96 if (size < 0) { 97 int err = errno; 98 close(fd); 99 finish(); 100 printf("+READ-FAILED: %s", strerror(err)); 101 ret = 2; 102 goto end; 103 } else if(!size) 104 break; 105 av_hash_update(hash, buffer, size); 106 } 107 close(fd); 108 109 finish(); 110end: 111 if (file) 112 printf(" *%s", file); 113 printf("\n"); 114 115 return ret; 116} 117 118int main(int argc, char **argv) 119{ 120 int i; 121 int ret = 0; 122 const char *hash_name; 123 124 if (argc == 1) { 125 usage(); 126 return 0; 127 } 128 129 hash_name = argv[1]; 130 out_b64 = av_strstart(hash_name, "b64:", &hash_name); 131 if ((ret = av_hash_alloc(&hash, hash_name)) < 0) { 132 switch(ret) { 133 case AVERROR(EINVAL): 134 printf("Invalid hash type: %s\n", hash_name); 135 break; 136 case AVERROR(ENOMEM): 137 printf("%s\n", strerror(errno)); 138 break; 139 } 140 return 1; 141 } 142 143 for (i = 2; i < argc; i++) 144 ret |= check(argv[i]); 145 146 if (argc < 3) 147 ret |= check(NULL); 148 149 av_hash_freep(&hash); 150 151 return ret; 152} 153