/* See LICENSE file for copyright and license details. */
#include "common.h"
void
writeall(int fd, const void *data, size_t n, const char *fname)
{
const char *text = data;
ssize_t r;
while (n) {
r = write(fd, text, n);
if (r < 0) {
if (errno == EINTR)
continue;
eprintf("write %s:", fname);
}
n -= (size_t)r;
text = &text[r];
}
}
char *
hex(char *out, const unsigned char *in, size_t n, const char *xdigits)
{
for (; n--; in++) {
*out++ = xdigits[(*in >> 4) & 15];
*out++ = xdigits[(*in >> 0) & 15];
}
return out;
}
void
format_result(struct algorithm *algorithm, const char *file, enum format format, int hexinput)
{
char *p;
size_t size = algorithm->hasher.hash_size + 1U;
size += (format & WITH_ALGOSTR) ? strlen(algorithm->algostr) + 1U : 0U;
size += (format & WITH_FILENAME) ? 2U + strlen(file) : 0U;
size += (format & WITH_NUL) ? 1U : 0U;
size += (format & WITH_LF) ? 1U : 0U;
size += ((format & FORMAT_MASK) != BINARY) ? algorithm->hasher.hash_size : 0U;
if (size > algorithm->result_size) {
algorithm->result = erealloc(algorithm->result, size);
algorithm->result_size = size;
}
algorithm->result_length = size - 1U;
p = algorithm->result;
if (format & WITH_ALGOSTR)
p = stpcpy(stpcpy(p, algorithm->algostr), ":");
switch (format & FORMAT_MASK) {
case BINARY:
p = mempcpy(p, algorithm->hasher.hash_output, algorithm->hasher.hash_size);
break;
case LOWERCASE_HEX:
p = hex(p, algorithm->hasher.hash_output, algorithm->hasher.hash_size, "0123456789abcdef");
break;
case UPPERCASE_HEX:
p = hex(p, algorithm->hasher.hash_output, algorithm->hasher.hash_size, "0123456789ABCDEF");
break;
default:
abort();
}
if (format & WITH_FILENAME)
p = stpcpy(stpcpy(p, hexinput ? " #" : " "), file);
if (format & WITH_NUL)
*p++ = '\0';
if (format & WITH_LF)
*p++ = '\n';
}