-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathmd5_u.c
130 lines (113 loc) · 2.95 KB
/
md5_u.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
/* md5 - toolbox
Copyright 2007-2015 PC GO Ld.
Copyright 2015-2019 Rivoreo
This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*/
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#ifdef _NO_OPENSSL
#include <md5.h>
#define MD5_Init MD5Init
#define MD5_Update MD5Update
#define MD5_Final MD5Final
#else
#include <openssl/md5.h>
#endif
#ifndef MD5_DIGEST_LENGTH
#define MD5_DIGEST_LENGTH 16
#endif
static int quiet = 0;
static void print_usage() {
fprintf(stderr,"Usage: md5"
#if defined _WIN32 && !defined _WIN32_WNT_NATIVE
".exe"
#endif
" [-q] <file> [...]\n");
}
static int do_md5(const char *path) {
unsigned int i;
int fd;
MD5_CTX md5_ctx;
unsigned char md5[MD5_DIGEST_LENGTH];
int no_close = 0;
//fd = strcmp(path, "-") == 0 ? dup(STDIN_FILENO) : open(path, O_RDONLY);
if(strcmp(path, "-") == 0) {
fd = STDIN_FILENO;
no_close = 1;
} else fd = open(path, O_RDONLY);
if(fd == -1) {
fprintf(stderr,"Could not open %s, %s\n", path, strerror(errno));
return -1;
}
MD5_Init(&md5_ctx);
while(1) {
char buf[4096];
ssize_t rlen = read(fd, buf, sizeof buf);
if(rlen == 0) break;
if(rlen < 0) {
int e = errno;
if(!no_close) close(fd);
fprintf(stderr,"Could not read %s, %s\n", path, strerror(e));
return -1;
}
MD5_Update(&md5_ctx, buf, rlen);
}
if(!no_close && close(fd) < 0) {
fprintf(stderr,"Could not close %s, %s\n", path, strerror(errno));
return -1;
}
MD5_Final(md5, &md5_ctx);
for(i = 0; i < (int)sizeof(md5); i++) printf("%02x", md5[i]);
if(quiet) putchar('\n'); else printf(" %s\n", path);
return 0;
}
int md5_main(int argc, char *argv[]) {
int i = 1, end_of_options = 0, ret = 0;
while(i < argc && !end_of_options) {
if(argv[i][0] == '-') {
int j;
const char *o = argv[i] + 1;
while(*o) switch(*o++) {
case 'q':
quiet = 1;
break;
case 'h':
print_usage();
return 0;
case '-':
if(*o) {
if(strcmp(o, "quiet") == 0) {
quiet = 1;
} else {
fprintf(stderr, "%s: Invalid option '%s'\n",
argv[0], argv[i]);
return -1;
}
} else end_of_options = 1;
goto move_argv;
default:
fprintf(stderr, "%s: Invalid option '-%c'\n", argv[0], o[-1]);
return -1;
}
move_argv:
for(j=i; j>0; j--) argv[j] = argv[j - 1];
argc--;
argv++;
} else i++;
}
if(argc < 2) {
print_usage();
return -1;
}
/* loop over the file args */
for (i = 1; i < argc; i++) {
if(do_md5(argv[i]) < 0) ret = 1;
}
return ret;
}