diff options
Diffstat (limited to 'src/list.c')
-rw-r--r-- | src/list.c | 162 |
1 files changed, 162 insertions, 0 deletions
diff --git a/src/list.c b/src/list.c new file mode 100644 index 0000000..c5c8b90 --- /dev/null +++ b/src/list.c @@ -0,0 +1,162 @@ +#include <string.h> +#include <assert.h> +#include <stdlib.h> + +#include "list.h" +#include "context.h" +#include "md5util.h" +#include "dbstruct.h" +#include "util.h" +#include "dbutil.h" +#include "syrep.h" + +static int handle_file(struct syrep_db_context *c, const struct syrep_name *name, const struct syrep_md *md, const struct syrep_meta *meta) { + struct syrep_meta local_meta; + assert(c && name && md); + + if (!meta) { + int f; + if ((f = get_meta_by_name_md(c, name, md, &local_meta)) < 0) + return -1; + + if (f) + meta = &local_meta; + } + + if (!args.show_deleted_flag && meta->last_seen != c->version) + return 0; + + if (meta) { + if (!args.show_by_md_flag) { + char d[SYREP_DIGESTLENGTH*2+1]; + fhex(md->digest, SYREP_DIGESTLENGTH, d); + d[SYREP_DIGESTLENGTH*2] = 0; + + fprintf(stderr, "%s %s%s", d, name->path, meta->last_seen == c->version ? "\t\t" : "\t(deleted)"); + } else + fprintf(stderr, "\t%s%s", name->path, meta->last_seen == c->version ? "\t\t" : "\t(deleted)"); + + if (args.show_times_flag) + fprintf(stderr, "\t(first-seen: %u; last-seen: %u)\n", meta->first_seen, meta->last_seen); + else + fputc('\n', stderr); + } else { + char d[SYREP_DIGESTLENGTH*2+1]; + fhex(md->digest, SYREP_DIGESTLENGTH, d); + d[SYREP_DIGESTLENGTH*2] = 0; + + fprintf(stderr, "\t%s", name->path); + } + + return 0; +} + +int list(struct syrep_db_context *c) { + int r = -1, ret; + DBC *cursor = NULL; + DBT key, data; + + +#if 1 + + { + if ((ret = c->db_name_lastmd->cursor(c->db_name_lastmd, NULL, &cursor, 0)) != 0) { + c->db_name_lastmd->err(c->db_name_lastmd, ret, "db_name_lastmd"); + goto finish; + } + + memset(&key, 0, sizeof(key)); + memset(&data, 0, sizeof(data)); + + while ((ret = cursor->c_get(cursor, &key, &data, DB_NEXT)) == 0) { + struct syrep_name *name = (struct syrep_name*) key.data; + struct syrep_md *md = (struct syrep_md*) data.data; + + if (handle_file(c, name, md, NULL) < 0) + fprintf(stderr, "handle_file() failed\n"); + + } + + if (ret != DB_NOTFOUND) { + c->db_name_lastmd->err(c->db_name_lastmd, ret, "name_lastmd::c_get"); + goto finish; + } + + r = 0; + } + + goto finish; + +#endif + + if (args.show_by_md_flag) { + struct syrep_md previous_md; + memset(&previous_md, 0, sizeof(previous_md)); + + if ((ret = c->db_md_name->cursor(c->db_md_name, NULL, &cursor, 0)) != 0) { + c->db_md_name->err(c->db_md_name, ret, "md_name"); + goto finish; + } + + memset(&key, 0, sizeof(key)); + memset(&data, 0, sizeof(data)); + + while ((ret = cursor->c_get(cursor, &key, &data, DB_NEXT)) == 0) { + struct syrep_md *md = (struct syrep_md*) key.data; + struct syrep_name *name = (struct syrep_name*) data.data; + struct syrep_meta meta; + + if (memcmp(&previous_md, md, sizeof(previous_md))) { + char d[SYREP_DIGESTLENGTH*2+1]; + fhex(md->digest, SYREP_DIGESTLENGTH, d); + d[SYREP_DIGESTLENGTH*2] = 0; + fprintf(stderr, "%s:\n", d); + memcpy(&previous_md, md, sizeof(previous_md)); + } + + if ((ret = get_meta_by_name_md(c, name, md, &meta)) < 0) + goto finish; + + if (handle_file(c, name, md, &meta) < 0) + fprintf(stderr, "handle_file() failed\n"); + } + + if (ret != DB_NOTFOUND) { + c->db_md_name->err(c->db_md_name, ret, "md_name::c_get"); + goto finish; + } + + r = 0; + } else { + + if ((ret = c->db_id_meta->cursor(c->db_id_meta, NULL, &cursor, 0)) != 0) { + c->db_id_meta->err(c->db_id_meta, ret, "id_meta"); + goto finish; + } + + memset(&key, 0, sizeof(key)); + memset(&data, 0, sizeof(data)); + + while ((ret = cursor->c_get(cursor, &key, &data, DB_NEXT)) == 0) { + struct syrep_id *id = (struct syrep_id*) key.data; + + if (handle_file(c, &id->name, &id->md, (struct syrep_meta*) data.data) < 0) + fprintf(stderr, "handle_file() failed\n"); + + } + + if (ret != DB_NOTFOUND) { + c->db_id_meta->err(c->db_id_meta, ret, "id_meta::c_get"); + goto finish; + } + + r = 0; + } + +finish: + + if (cursor) + cursor->c_close(cursor); + + return r; +} |