summaryrefslogtreecommitdiffstats
path: root/src/makepatch.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/makepatch.c')
-rw-r--r--src/makepatch.c72
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;
+}