1 /* md5wrap.cc: wrapper functions to allow easy use of MD5 from C++.
3 * Copyright (C) 2006,2010,2012,2013,2015 Olly Betts
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
22 #ifdef HAVE_POSIX_FADVISE
24 # define _POSIX_C_SOURCE 200112L // for posix_fadvise from fcntl.h
25 # define _DEFAULT_SOURCE 1 // Needed to get lstat() for glibc >= 2.20
26 # define _BSD_SOURCE 1 // Needed to get lstat() for glibc < 2.20
32 #include "safefcntl.h"
33 #include "safeerrno.h"
34 #include "safeunistd.h"
42 md5_file(const string
&file_name
, string
&md5
, bool try_noatime
)
44 mode_t mode
= O_RDONLY
;
45 #if defined O_NOATIME && O_NOATIME != 0
46 if (try_noatime
) mode
|= O_NOATIME
;
51 int fd
= open(file_name
.c_str(), mode
);
52 #if defined O_NOATIME && O_NOATIME != 0
53 if (fd
< 0 && (mode
& O_NOATIME
)) {
55 fd
= open(file_name
.c_str(), mode
);
58 if (fd
< 0) return false;
60 #ifdef HAVE_POSIX_FADVISE
61 posix_fadvise(fd
, 0, 0, POSIX_FADV_NOREUSE
); // or POSIX_FADV_SEQUENTIAL
67 unsigned char blk
[4096];
70 int c
= read(fd
, blk
, sizeof(blk
));
73 if (errno
== EINTR
) continue;
77 MD5Update(&md5_ctx
, blk
, c
);
80 #ifdef HAVE_POSIX_FADVISE
81 posix_fadvise(fd
, 0, 0, POSIX_FADV_DONTNEED
);
86 MD5Final(blk
, &md5_ctx
);
87 md5
.assign(reinterpret_cast<const char *>(blk
), 16);
93 md5_block(const char * p
, size_t len
, string
&md5
)
95 unsigned char blk
[16];
99 MD5Update(&md5_ctx
, reinterpret_cast<const unsigned char *>(p
), len
);
100 MD5Final(blk
, &md5_ctx
);
101 md5
.assign(reinterpret_cast<const char *>(blk
), 16);