aboutsummaryrefslogtreecommitdiffstats
path: root/write.c
blob: b3eaa56c1421e1f252811b643ccd98bb96b04d5e (plain) (blame)
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
/* 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';
}