static inline retvalue add_patches(const char *diffindexfile, struct diffindex *n, const struct strlist *patches) { int i; assert (patches->count == n->patchcount); for (i = 0 ; i < n->patchcount; i++) { struct hashes hashes; const char *patchname; retvalue r; parse_sha1line(patches->values[i], &hashes, &patchname); if (hashes.hashes[cs_sha1sum].len == 0 || hashes.hashes[cs_length].len == 0 || *patchname == '\0') { r = RET_ERROR; } else r = checksums_initialize(&n->patches[i].checksums, hashes.hashes); ASSERT_NOT_NOTHING(r); if (RET_WAS_ERROR(r)) { fprintf(stderr, "Error parsing SHA1-Patches line %d in '%s':!\n'%s'\n", i, diffindexfile, patches->values[i]); return r; } n->patches[i].name = strdup(patchname); if (FAILEDTOALLOC(n)) return RET_ERROR_OOM; } return RET_OK; }
static inline retvalue add_history(const char *diffindexfile, struct diffindex *n, const struct strlist *history) { int i, j; for (i = 0 ; i < history->count ; i++) { struct hashes hashes; const char *patchname; struct checksums *checksums; retvalue r; parse_sha1line(history->values[i], &hashes, &patchname); if (hashes.hashes[cs_sha1sum].len == 0 || hashes.hashes[cs_length].len == 0 || *patchname == '\0') { r = RET_ERROR; } else r = checksums_initialize(&checksums, hashes.hashes); ASSERT_NOT_NOTHING(r); if (RET_WAS_ERROR(r)) { fprintf(stderr, "Error parsing SHA1-History line %d in '%s':!\n'%s'\n", i, diffindexfile, history->values[i]); return r; } j = 0; while (j < n->patchcount && strcmp(n->patches[j].name, patchname) != 0) j++; if (j >= n->patchcount) { fprintf(stderr, "'%s' lists '%s' in history but not in patches!\n", diffindexfile, patchname); checksums_free(checksums); continue; } if (n->patches[j].frompackages != NULL) { fprintf(stderr, "Warning: '%s' lists multiple histories for '%s'!\nOnly using last one!\n", diffindexfile, patchname); checksums_free(n->patches[j].frompackages); } n->patches[j].frompackages = checksums; } return RET_OK; }
static inline retvalue add_current(const char *diffindexfile, struct diffindex *n, const char *current) { struct hashes hashes; const char *p; retvalue r; parse_sha1line(current, &hashes, &p); if (hashes.hashes[cs_sha1sum].len == 0 || hashes.hashes[cs_length].len == 0 || *p != '\0') { r = RET_ERROR; } else r = checksums_initialize(&n->destination, hashes.hashes); ASSERT_NOT_NOTHING(r); if (RET_WAS_ERROR(r)) fprintf(stderr, "Error parsing SHA1-Current in '%s'!\n", diffindexfile); return r; }
retvalue signature_requirement_add(struct signature_requirement **list_p, const char *condition) { struct signature_requirement *req; const char *full_condition = condition; retvalue r; r = signature_init(false); if (RET_WAS_ERROR(r)) return r; if (condition == NULL || strcmp(condition, "blindtrust") == 0) return RET_NOTHING; /* no need to add the same condition multiple times */ for (req = *list_p ; req != NULL ; req = req->next) { if (strcmp(req->condition, condition) == 0) return RET_NOTHING; } req = malloc(sizeof_requirement(1)); if (FAILEDTOALLOC(req)) return RET_ERROR_OOM; req->next = NULL; req->condition = strdup(condition); if (FAILEDTOALLOC(req->condition)) { free(req); return RET_ERROR_OOM; } req->num_keys = 0; do { bool allow_subkeys, allow_bad; char *next_key IFSTUPIDCC(=NULL); r = parse_condition_part(&allow_subkeys, &allow_bad, full_condition, &condition, &next_key); ASSERT_NOT_NOTHING(r); if (RET_WAS_ERROR(r)) { signature_requirements_free(req); return r; } req->keys[req->num_keys].allow_bad = allow_bad; r = load_key(next_key, allow_subkeys, allow_bad, full_condition, &req->keys[req->num_keys].key, &req->keys[req->num_keys].subkey); free(next_key); if (RET_WAS_ERROR(r)) { signature_requirements_free(req); return r; } req->num_keys++; if (*condition != '\0') { struct signature_requirement *h; h = realloc(req, sizeof_requirement(req->num_keys+1)); if (FAILEDTOALLOC(h)) { signature_requirements_free(req); return r; } req = h; } else break; } while (true); req->next = *list_p; *list_p = req; return RET_OK; }
retvalue diffindex_read(const char *diffindexfile, struct diffindex **out_p) { retvalue r; char *chunk, *current; struct strlist history, patches; struct diffindex *n; r = readtextfile(diffindexfile, diffindexfile, &chunk, NULL); ASSERT_NOT_NOTHING(r); if (RET_WAS_ERROR(r)) return r; r = chunk_getextralinelist(chunk, "SHA1-History", &history); if (r == RET_NOTHING) { fprintf(stderr, "'%s' misses SHA1-History field\n", diffindexfile); r = RET_ERROR; } if (RET_WAS_ERROR(r)) { free(chunk); return r; } r = chunk_getextralinelist(chunk, "SHA1-Patches", &patches); if (r == RET_NOTHING) { fprintf(stderr, "'%s' misses SHA1-Patches field\n", diffindexfile); r = RET_ERROR; } if (RET_WAS_ERROR(r)) { free(chunk); strlist_done(&history); return r; } r = chunk_getvalue(chunk, "SHA1-Current", ¤t); free(chunk); if (r == RET_NOTHING) { fprintf(stderr, "'%s' misses SHA1-Current field\n", diffindexfile); r = RET_ERROR; } if (RET_WAS_ERROR(r)) { strlist_done(&history); strlist_done(&patches); return r; } n = calloc(1, sizeof(struct diffindex) + patches.count * sizeof(struct diffindex_patch)); if (FAILEDTOALLOC(n)) { strlist_done(&history); strlist_done(&patches); free(current); return r; } n->patchcount = patches.count; r = add_current(diffindexfile, n, current); if (RET_IS_OK(r)) r = add_patches(diffindexfile, n, &patches); if (RET_IS_OK(r)) r = add_history(diffindexfile, n, &history); ASSERT_NOT_NOTHING(r); strlist_done(&history); strlist_done(&patches); free(current); if (RET_IS_OK(r)) *out_p = n; else diffindex_free(n); return r; }