00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include <stdio.h>
00022 #include "libavutil/avstring.h"
00023 #include "libavutil/md5.h"
00024 #include "libavutil/mem.h"
00025 #include "libavutil/error.h"
00026 #include "avformat.h"
00027 #include "avio.h"
00028 #include "url.h"
00029
00030 #define PRIV_SIZE 128
00031
00032 static int md5_open(URLContext *h, const char *filename, int flags)
00033 {
00034 if (PRIV_SIZE < av_md5_size) {
00035 av_log(NULL, AV_LOG_ERROR, "Insuffient size for MD5 context\n");
00036 return -1;
00037 }
00038
00039 if (!flags & AVIO_FLAG_WRITE)
00040 return AVERROR(EINVAL);
00041
00042 av_md5_init(h->priv_data);
00043
00044 return 0;
00045 }
00046
00047 static int md5_write(URLContext *h, const unsigned char *buf, int size)
00048 {
00049 av_md5_update(h->priv_data, buf, size);
00050 return size;
00051 }
00052
00053 static int md5_close(URLContext *h)
00054 {
00055 const char *filename = h->filename;
00056 uint8_t md5[16], buf[64];
00057 URLContext *out;
00058 int i, err = 0;
00059
00060 av_md5_final(h->priv_data, md5);
00061 for (i = 0; i < sizeof(md5); i++)
00062 snprintf(buf + i*2, 3, "%02x", md5[i]);
00063 buf[i*2] = '\n';
00064
00065 av_strstart(filename, "md5:", &filename);
00066
00067 if (*filename) {
00068 err = ffurl_open(&out, filename, AVIO_FLAG_WRITE);
00069 if (err)
00070 return err;
00071 err = ffurl_write(out, buf, i*2+1);
00072 ffurl_close(out);
00073 } else {
00074 if (fwrite(buf, 1, i*2+1, stdout) < i*2+1)
00075 err = AVERROR(errno);
00076 }
00077
00078 return err;
00079 }
00080
00081 static int md5_get_handle(URLContext *h)
00082 {
00083 return (intptr_t)h->priv_data;
00084 }
00085
00086 URLProtocol ff_md5_protocol = {
00087 .name = "md5",
00088 .url_open = md5_open,
00089 .url_write = md5_write,
00090 .url_close = md5_close,
00091 .url_get_file_handle = md5_get_handle,
00092 .priv_data_size = PRIV_SIZE,
00093 };