#include "filehash.h" #include #include #include struct filehash_t { const char *hash_program; const char **argv; unsigned max_per_invocation; unsigned next; }; filehash_t * filehash_new(const char *hash_program, unsigned max_per_invocation) { filehash_t *fh; fh = malloc(sizeof(filehash_t)); if (!fh) return NULL; *fh = (filehash_t){ .hash_program = strdup(hash_program), .max_per_invocation = max_per_invocation, .argv = reallocarray(NULL, 1 + max_per_invocation, sizeof(const char *)), }; if (!fh->argv) goto fail; for (int i = 0; i <= max_per_invocation; ++i) fh->argv[i] = NULL; if (!fh->hash_program) goto fail; return fh; fail: filehash_free(fh); return NULL; } #include static int run_hash(filehash_t *fh) { fputs(fh->hash_program, stderr); for (int i = 0; i < fh->next; ++i) { fputc(' ', stderr); fputs(fh->argv[i], stderr); } fputc('\n', stderr); return 0; } filehash_state_t filehash_send(filehash_t *fh, const char *file_name) { if (fh->next >= fh->max_per_invocation) return fhs_rejected; const char *copy = strdup(file_name); if (!copy) { warn("strdup"); return fhs_failure; } fh->argv[fh->next++] = copy; if (fh->next < fh->max_per_invocation) return fhs_accepts; if (run_hash(fh) == -1) return fhs_failure; return fhs_full; } void filehash_free(filehash_t *fh) { if (!fh) return; if (fh->argv) { for (int i = 0; i <= fh->max_per_invocation; ++i) free((void *)fh->argv[i]); free(fh->argv); } free((void *)fh->hash_program); free(fh); }