* SUCH DAMAGE.
*/
+#include <ctype.h>
#include <errno.h>
#include <getopt.h>
#include <stdbool.h>
#include "compat.h"
+static bool
+ishexstring(const char *s) {
+ for (; *s != '\0'; s++)
+ if (!isxdigit(*s))
+ return false;
+ return true;
+}
+
int
tcappend(int argc, char **argv)
{
uuid_t uuid;
const char *errstr = NULL;
uint8_t flags = 0;
+ uint16_t category = 0;
int ch;
- while ((ch = getopt(argc, argv, "u:f:")) != -1) {
+ while ((ch = getopt(argc, argv, "u:f:c:")) != -1) {
switch (ch) {
case 'u':
if (strlen(optarg) == 1 && *optarg == '0') {
exit(1);
}
break;
+ case 'c':
+ category = strtonum(optarg, 0, UINT16_MAX, &errstr);
+ if (errstr != NULL) {
+ fprintf(stderr, "category number is %s: %s\n", errstr, optarg);
+ exit(1);
+ }
+ break;
}
}
};
for (int i = 1; i < argc; i++) {
- append = cache_from_tree(argv[i], cache.version);
+ if (strlen(argv[i]) == 40 && ishexstring(argv[i])) {
+ append.num_entries = 1;
+ if (append.version == 0) {
+ append.hashes = calloc(1, sizeof(trust_cache_hash0));
+ for (size_t j = 0; j < CS_CDHASH_LEN; j++)
+ sscanf(argv[i] + 2 * j, "%02hhx", &append.hashes[0][j]);
+ } else if (append.version == 1) {
+ append.entries = calloc(1, sizeof(struct trust_cache_entry1));
+ for (size_t j = 0; j < CS_CDHASH_LEN; j++)
+ sscanf(argv[i] + 2 * j, "%02hhx", &append.entries[0].cdhash[j]);
+ } else if (append.version == 2) {
+ append.entries2 = calloc(1, sizeof(struct trust_cache_entry2));
+ for (size_t j = 0; j < CS_CDHASH_LEN; j++)
+ sscanf(argv[i] + 2 * j, "%02hhx", &append.entries2[0].cdhash[j]);
+ }
+ } else {
+ append = cache_from_tree(argv[i], cache.version);
+ }
if (append.version == 0) {
if ((cache.hashes = realloc(cache.hashes, sizeof(trust_cache_hash0) *
(cache.num_entries + append.num_entries))) == NULL)
cache.entries[cache.num_entries + j].flags = flags != 0 ? flags : append.entries[j].flags;
memcpy(cache.entries[cache.num_entries + j].cdhash, append.entries[j].cdhash, CS_CDHASH_LEN);
}
+ } else if (append.version == 2) {
+ if ((cache.entries2 = realloc(cache.entries, sizeof(struct trust_cache_entry2) *
+ (cache.num_entries + append.num_entries))) == NULL)
+ exit(1);
+ for (uint32_t j = 0; j < append.num_entries; j++) {
+ cache.entries2[cache.num_entries + j].hash_type = append.entries[j].hash_type;
+ cache.entries2[cache.num_entries + j].flags = flags != 0 ? flags : append.entries[j].flags;
+ cache.entries2[cache.num_entries + j].category = category != 0 ? category : append.entries2[j].category;
+ memcpy(cache.entries2[cache.num_entries + j].cdhash, append.entries2[j].cdhash, CS_CDHASH_LEN);
+ }
}
free(append.hashes);
cache.num_entries += append.num_entries;
}
- if (cache.version == 1)
- qsort(cache.entries, cache.num_entries, sizeof(*cache.entries), ent_cmp);
- else if (cache.version == 0)
+ if (cache.version == 0)
qsort(cache.hashes, cache.num_entries, sizeof(*cache.hashes), hash_cmp);
+ else if (cache.version == 1)
+ qsort(cache.entries, cache.num_entries, sizeof(*cache.entries), ent_cmp);
+ else if (cache.version == 2)
+ qsort(cache.entries, cache.num_entries, sizeof(*cache.entries2), ent_cmp);
switch (keepuuid) {
case 0:
break;
}
- if ((f = fopen(argv[0], "wb")) == NULL) {
- fprintf(stderr, "%s: %s\n", argv[0], strerror(errno));
+ if (writetrustcache(cache, argv[0]) == -1)
return 1;
- }
-
- cache.version = htole32(cache.version);
- cache.num_entries = htole32(cache.num_entries);
- fwrite(&cache, sizeof(struct trust_cache) - sizeof(struct trust_cache_entry1*), 1, f);
- cache.version = le32toh(cache.version);
- cache.num_entries = le32toh(cache.num_entries);
-
- for (uint32_t i = 0; i < cache.num_entries; i++) {
- if (cache.version == 0)
- fwrite(&cache.hashes[i], sizeof(trust_cache_hash0), 1, f);
- else if (cache.version == 1)
- fwrite(&cache.entries[i], sizeof(struct trust_cache_entry1), 1, f);
- }
+ free(cache.entries);
return 0;
}