diff options
Diffstat (limited to 'src/makepatch.c')
-rw-r--r-- | src/makepatch.c | 72 |
1 files changed, 72 insertions, 0 deletions
diff --git a/src/makepatch.c b/src/makepatch.c new file mode 100644 index 0000000..1ddeb93 --- /dev/null +++ b/src/makepatch.c @@ -0,0 +1,72 @@ +#include <assert.h> +#include <unistd.h> +#include <string.h> + +#include "package.h" +#include "makepatch.h" +#include "diff.h" +#include "dbutil.h" +#include "md5util.h" + +struct cb_info { + struct syrep_db_context *c1; + struct syrep_db_context *c2; + const char *root; +}; + +static int cb(DB *ddb, struct syrep_name *name, struct diff_entry *de, void *p) { + struct cb_info *cb_info = p; + struct syrep_md md; + char path[PATH_MAX+1]; + char d[SYREP_DIGESTLENGTH*2+1]; + int f; + + assert(ddb && name && de && p); + + if (de->action != DIFF_COPY && de->action != DIFF_CONFLICT) + return 0; + + if ((f = get_current_md_by_name(cb_info->c1, name, &md)) < 0) + return -1; + + if (!f) + return 0; + + fhex(md.digest, SYREP_DIGESTLENGTH, d); + d[SYREP_DIGESTLENGTH*2] = 0; + + snprintf(path, sizeof(path), "%s/%s", cb_info->root, name->path); + + fprintf(stderr, "Adding %s (%s) to patch.\n", name->path, d); + + if (!package_get_item(cb_info->c1->package, d, 0)) + if (package_add_file(cb_info->c1->package, d, path) < 0) + return -1; + + return 0; +} + +int makepatch(struct syrep_db_context *c1, struct syrep_db_context *c2, const char *root) { + struct cb_info cb_info; + DB *ddb = NULL; + int r = -1; + + memset(&cb_info, 0, sizeof(cb_info)); + cb_info.c1 = c1; + cb_info.c2 = c2; + cb_info.root = root; + + if (!(ddb = make_diff(c1, c2))) + goto finish; + + if (diff_foreach(ddb, cb, &cb_info) < 0) + goto finish; + + r = 0; + +finish: + if (ddb) + ddb->close(ddb, 0); + + return r; +} |