blob: 1b1151d2331634c311c91d932ac72a24a3e45896 [file] [log] [blame] [raw]
/* 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;
}