aboutsummaryrefslogtreecommitdiffstats
path: root/cmdline_bsum.c
blob: d2673142a9de8045950587ffe1f2ddf746c80e4c (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
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
/* See LICENSE file for copyright and license details. */
#include "common.h"


int
cmdline_bsum(int argc, char **argv, enum command command, struct config *config,
             const char **algostr, enum libhashsum_algorithm *algorithm, char **algostrbuf)
{
	const char *salt = NULL;
	char *arg;

	*algostrbuf = NULL;

	ARGBEGIN {
	case 'b': /* binary input (compat) */
	case 't': /* text input (compat) */
		config->hexinput = 0;
		break;

	case 'c':
		config->verify = 1;
		break;

	case 'w':
		config->warn_improper_format = 1;
		break;

	case 'z':
		config->format &= (enum format)~WITH_LF;
		config->format |= WITH_NUL;
		break;

	case 'l':
		if (command != BSUM)
			usage();
		arg = ARG();
		if      (!strcmp(arg, "224")) *algostr = "blake224", *algorithm = LIBHASHSUM_BLAKE224;
		else if (!strcmp(arg, "256")) *algostr = "blake256", *algorithm = LIBHASHSUM_BLAKE256;
		else if (!strcmp(arg, "384")) *algostr = "blake384", *algorithm = LIBHASHSUM_BLAKE384;
		else if (!strcmp(arg, "512")) *algostr = "blake512", *algorithm = LIBHASHSUM_BLAKE512;
		else
			eprintf("unsupport value on -l option, expected 224, 256, 384, or 512");
		break;

	case 'S':
		if (salt)
			usage();
		arg = ARG();
		if (!strncasecmp(arg, "0x", 2))
			arg = &arg[2];
		if (!*arg)
			usage();
		salt = arg;
		while (isxdigit(*arg))
			arg++;
		if (!*arg)
			eprintf("expected hexadecimal value for -S option");
		break;

	case 'x': /* (compat) */
		config->hexinput = 1;
		break;

	case 'L': /* (compat) */
		config->format &= (enum format)~FORMAT_MASK;
		config->format |= LOWERCASE_HEX;
		break;

	case 'U': /* (compat) */
		config->format &= (enum format)~FORMAT_MASK;
		config->format |= UPPERCASE_HEX;
		break;

	case 'B': /* (compat) */
		config->format &= (enum format)~FORMAT_MASK;
		config->format |= BINARY;
		break;

	case 'W':
		arg = parseopts(config, ARG(), &parseopt_vendor);
		if (*arg)
			eprintf("unsupported -W options: %s", arg);
		break;

	default:
		usage();
	} ARGEND;

	if (salt) {
		size_t expected_salt_len = 64; /* BLAKEb */
		if (*algorithm == LIBHASHSUM_BLAKE224 || *algorithm == LIBHASHSUM_BLAKE256)
			expected_salt_len = 32; /* BLAKEs */
		if (strlen(salt) != expected_salt_len)
			eprintf("salt for BLAKE%s is expected to be %zu hexadecimal characters long",
			        &(*algostr)[5], expected_salt_len);
		*algostrbuf = malloc(strlen(*algostr) + strlen(salt) + sizeof("[salt=]"));
		sprintf(*algostrbuf, "%s[salt=%s]", *algostr, salt);
		*algostr = *algostrbuf;
	}

	return argc;
}