commit 9ea49a139ac0c786f9f2e4a03c8fdcabbdcfb53d
parent a7b172257f8a12ec768cdad95013486ba761ab22
Author: Mohamed Aslan <maslan@sce.carleton.ca>
Date: Wed, 18 Jun 2014 02:21:14 -0400
return the responsibility of generating IDs back to the OBJDB layer
Diffstat:
M | cmd-log.c | | | 58 | ---------------------------------------------------------- |
M | objdb-fs.c | | | 170 | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--- |
M | objects.c | | | 129 | ++----------------------------------------------------------------------------- |
M | objects.h | | | 4 | ---- |
4 files changed, 168 insertions(+), 193 deletions(-)
diff --git a/cmd-log.c b/cmd-log.c
@@ -25,67 +25,9 @@
int
cmd_log(int argc, char **argv)
{
- char *x;
struct session s;
baseline_session_begin(&s, 0);
- struct commit tmp = {
- .id = "deadbeaf",
- .dir = "badcode",
- .n_parents = 0,
- .author.name = "mohamed",
- .author.email = "maslan@maslan.info",
- .committer.name = "mohamed",
- .committer.email = "maslan@maslan.info",
- .message = "Hello World!"
- };
- x = baseline_commit_serialize(&tmp);
- printf("%s", x);
-
- struct dirent ent2 = {
- .id = "02",
- .name = "dir2.txt",
- .type = T_DIR,
- .mode = 1777,
- .next = NULL
- };
- struct dirent ent1 = {
- .id = "01",
- .name = "file1.txt",
- .type = T_FILE,
- .mode = 777,
- .next = &ent2
- };
-/*
- struct dir d = {
- .id = "f0cd",
- .children = &ent1
- };
-*/
- //struct dir d = {.children = NULL};
- struct dir *d = baseline_dir_new();
- baseline_dir_append(d, &ent1);
- baseline_dir_append(d, &ent2);
- x = baseline_dir_serialize(d);
- printf("%s", x);
- x = baseline_gen_id(d, O_DIR);
- printf("%s\n", x);
- baseline_dir_free(d);
-
- struct file f1 = {
- .id = "00001",
- .loc = ON_MEM,
- };
- f1.buffer = strdup("hello");
- x = baseline_gen_id(&f1, O_FILE);
- printf("%s\n", x);
- struct file f2 = {
- .id = "00002",
- .loc = ON_FS,
- };
- f2.fd = open("hi.txt", O_RDONLY);
- x = baseline_gen_id(&f2, O_FILE);
- printf("%s\n", x);
baseline_session_end(&s);
return EXIT_SUCCESS;
diff --git a/objdb-fs.c b/objdb-fs.c
@@ -99,6 +99,168 @@ get_objdb_dir(struct objdb_ctx *ctx)
return db_dir_name;
}
+/*
+ * converts struct commit to char*
+ */
+char*
+commit_serialize(struct commit *comm)
+{
+ char *raw = NULL;
+
+ if (comm == NULL)
+ goto ret;
+ if (comm->n_parents == 0)
+ asprintf(&raw, "dir %s\nauthor %s <%s> %llu\ncommitter %s <%s> %llu\n%s\n",
+ comm->dir, comm->author.name, comm->author.email, comm->author.timestamp,
+ comm->committer.name, comm->committer.email, comm->committer.timestamp, comm->message);
+ else if (comm->n_parents == 1)
+ asprintf(&raw, "dir %s\nparent %s\nauthor %s <%s> %llu\ncommitter %s <%s> %llu\n%s\n",
+ comm->dir, comm->parents[0], comm->author.name, comm->author.email, comm->author.timestamp,
+ comm->committer.name, comm->committer.email, comm->committer.timestamp, comm->message);
+ /* TODO: support more than 1 parent */
+ret:
+ return raw;
+}
+
+/*
+ * converts struct dir to char*
+ */
+char*
+dir_serialize(struct dir *dir)
+{
+ char *entry = NULL, *raw = NULL, *ptr, ch = ' ';
+ size_t size = 1, newsize;
+ struct dirent *it;
+
+ if (dir == NULL)
+ goto ret;
+ raw = (char *)malloc(sizeof(char));
+ *raw = '\0';
+ if (dir->children == NULL)
+ goto ret;
+ for (it = dir->children ; it != NULL ; it = it->next) {
+ if (it->type == T_FILE)
+ ch = 'F';
+ else if (it->type == T_DIR)
+ ch = 'D';
+ /* assuming asprintf() uses realloc() */
+ /* free(entry); */
+ asprintf(&entry, "%c %s %06o %s\n", ch, it->id, it->mode, it->name);
+ /* allocation failed, need to do something! */
+ if (entry == NULL)
+ return NULL;
+ newsize = size + strlen(entry);
+ if ((ptr = realloc(raw, newsize)) == NULL) {
+ /* allocation failed, need to do something! */
+ return NULL;
+ }
+ raw = ptr;
+ size = newsize;
+ strlcat(raw, entry, size);
+ }
+ free(entry);
+ret:
+ return raw;
+}
+
+static char *
+file_gen_id(struct file *obj)
+{
+ char **objid = NULL, *ptr;
+ char buf[4096];
+ int i, n;
+ off_t offset;
+ u_int8_t digest[SHA256_DIGEST_LENGTH];
+ SHA2_CTX hash_ctx;
+
+ SHA256Init(&hash_ctx);
+ /* TODO: locking */
+ if (((struct file *)obj)->loc == ON_FS) {
+ /* save file offset */
+ offset = lseek(obj->fd, 0, SEEK_CUR);
+ do {
+ n = read(obj->fd, buf, sizeof(buf));
+ if (n == -1)
+ return NULL;
+ SHA256Update(&hash_ctx, buf, n);
+ if (n <= sizeof(buf))
+ break;
+ } while (1);
+ /* restore file offset */
+ lseek(obj->fd, offset, SEEK_SET);
+ }
+ else {
+ SHA256Update(&hash_ctx, obj->buffer, strlen(obj->buffer));
+ }
+ objid = &(obj->id);
+ SHA256Final(digest, &hash_ctx);
+ *objid = (char *)malloc(SHA256_DIGEST_LENGTH * 2 + 1);
+ for (i=0, ptr=*objid ; i<SHA256_DIGEST_LENGTH ; i++, ptr+=2) {
+ snprintf(ptr, 3, "%02x", digest[i]);
+ }
+ return *objid;
+}
+
+static char *
+commit_gen_id_and_serialize(struct commit *obj, char **raw)
+{
+ char **objid = NULL, *ptr, *serialized = NULL;
+ int i;
+ u_int8_t digest[SHA256_DIGEST_LENGTH];
+ SHA2_CTX hash_ctx;
+
+ SHA256Init(&hash_ctx);
+ serialized = commit_serialize(obj);
+ SHA256Update(&hash_ctx, serialized, strlen(serialized));
+ objid = &(obj->id);
+ SHA256Final(digest, &hash_ctx);
+ *objid = (char *)malloc(SHA256_DIGEST_LENGTH * 2 + 1);
+ for (i=0, ptr=*objid ; i<SHA256_DIGEST_LENGTH ; i++, ptr+=2) {
+ snprintf(ptr, 3, "%02x", digest[i]);
+ }
+ *raw = serialized;
+ return *objid;
+}
+
+static char *
+commit_gen_id(struct commit *obj)
+{
+ char *raw;
+ char *id = commit_gen_id_and_serialize(obj, &raw);
+ free(raw);
+ return id;
+}
+
+static char *
+dir_gen_id_and_serialize(struct dir *obj, char **raw)
+{
+ char **objid = NULL, *ptr, *serialized = NULL;
+ int i;
+ u_int8_t digest[SHA256_DIGEST_LENGTH];
+ SHA2_CTX hash_ctx;
+
+ SHA256Init(&hash_ctx);
+ serialized = dir_serialize(obj);
+ SHA256Update(&hash_ctx, serialized, strlen(serialized));
+ objid = &(obj->id);
+ SHA256Final(digest, &hash_ctx);
+ *objid = (char *)malloc(SHA256_DIGEST_LENGTH * 2 + 1);
+ for (i=0, ptr=*objid ; i<SHA256_DIGEST_LENGTH ; i++, ptr+=2) {
+ snprintf(ptr, 3, "%02x", digest[i]);
+ }
+ *raw = serialized;
+ return *objid;
+}
+
+static char *
+dir_gen_id(struct dir *obj)
+{
+ char *raw;
+ char *id = dir_gen_id_and_serialize(obj, &raw);
+ free(raw);
+ return id;
+}
+
static int
objdb_bl_open(struct objdb_ctx **ctx, const char *db_name, const char *db_path)
{
@@ -165,7 +327,7 @@ objdb_bl_insert_file(struct objdb_ctx *ctx, struct file *file)
goto ret;
}
asprintf(&full_path, "%s/%s", db_dir_name, "files");
- obj_hash = baseline_gen_id(file, O_FILE);
+ obj_hash = file_gen_id(file);
/* create a temp file */
asprintf(&tmp_file_name, "%s/tmp.XXXXXX", full_path);
if ((tmpfd = mkstemp(tmp_file_name)) == -1) {
@@ -221,8 +383,7 @@ objdb_bl_insert_dir(struct objdb_ctx *ctx, struct dir *dir)
goto ret;
}
asprintf(&full_path, "%s/%s", db_dir_name, "dirs");
- data = baseline_dir_serialize(dir);
- obj_hash = baseline_gen_id(dir, O_DIR);
+ obj_hash = dir_gen_id_and_serialize(dir, &data);
/* create a temp file */
asprintf(&tmp_file_name, "%s/tmp.XXXXXX", full_path);
@@ -274,8 +435,7 @@ objdb_bl_insert_commit(struct objdb_ctx *ctx, struct commit *comm)
goto ret;
}
asprintf(&full_path, "%s/%s", db_dir_name, "commits");
- data = baseline_commit_serialize(comm);
- obj_hash = baseline_gen_id(comm, O_COMMIT);
+ obj_hash = commit_gen_id_and_serialize(comm, &data);
/* create a temp file */
asprintf(&tmp_file_name, "%s/tmp.XXXXXX", full_path);
diff --git a/objects.c b/objects.c
@@ -16,14 +16,10 @@
#include <stdio.h>
#include <stdlib.h>
-#include <string.h>
-#include <unistd.h> /* read(2) */
-
-#include <sha2.h>
#include "objects.h"
-struct file *
+struct file*
baseline_file_new()
{
struct file *file = (struct file *)calloc(1, sizeof(struct file));
@@ -41,7 +37,7 @@ baseline_file_free(struct file *file)
free(file);
}
-struct commit *
+struct commit*
baseline_commit_new()
{
struct commit *comm = (struct commit *)calloc(1, sizeof(struct commit));
@@ -62,30 +58,7 @@ baseline_commit_free(struct commit *comm)
free(comm);
}
-/*
- * converts struct commit to char*
- */
-char*
-baseline_commit_serialize(struct commit *comm)
-{
- char *raw = NULL;
-
- if (comm == NULL)
- goto ret;
- if (comm->n_parents == 0)
- asprintf(&raw, "dir %s\nauthor %s <%s> %llu\ncommitter %s <%s> %llu\n%s\n",
- comm->dir, comm->author.name, comm->author.email, comm->author.timestamp,
- comm->committer.name, comm->committer.email, comm->committer.timestamp, comm->message);
- else if (comm->n_parents == 1)
- asprintf(&raw, "dir %s\nparent %s\nauthor %s <%s> %llu\ncommitter %s <%s> %llu\n%s\n",
- comm->dir, comm->parents[0], comm->author.name, comm->author.email, comm->author.timestamp,
- comm->committer.name, comm->committer.email, comm->committer.timestamp, comm->message);
- /* TODO: support more than 1 parent */
-ret:
- return raw;
-}
-
-struct dir *
+struct dir*
baseline_dir_new()
{
struct dir *dir = (struct dir *)calloc(1, sizeof(struct dir));
@@ -129,99 +102,3 @@ baseline_dir_append(struct dir *dir, struct dirent *ent)
ent->next = NULL;
}
-/*
- * converts struct dir to char*
- */
-char*
-baseline_dir_serialize(struct dir *dir)
-{
- char *entry = NULL, *raw = NULL, *ptr, ch = ' ';
- size_t size = 1, newsize;
- struct dirent *it;
-
- if (dir == NULL)
- goto ret;
- raw = (char *)malloc(sizeof(char));
- *raw = '\0';
- if (dir->children == NULL)
- goto ret;
- for (it = dir->children ; it != NULL ; it = it->next) {
- if (it->type == T_FILE)
- ch = 'F';
- else if (it->type == T_DIR)
- ch = 'D';
- /* assuming asprintf() uses realloc() */
- entry = NULL;
- asprintf(&entry, "%c %s %06o %s\n", ch, it->id, it->mode, it->name);
- /* allocation failed, need to do something! */
- if (entry == NULL)
- return NULL;
- newsize = size + strlen(entry);
- if ((ptr = realloc(raw, newsize)) == NULL) {
- /* allocation failed, need to do something! */
- return NULL;
- }
- raw = ptr;
- size = newsize;
- strlcat(raw, entry, size);
- }
- free(entry);
-ret:
- return raw;
-}
-
-char*
-baseline_gen_id(void *obj, enum objtype type)
-{
- char **objid = NULL, *ptr, *serialized = NULL;
- char buf[4096];
- int i, n;
- off_t offset;
- u_int8_t digest[SHA256_DIGEST_LENGTH];
- SHA2_CTX hash_ctx;
-
- SHA256Init(&hash_ctx);
- switch (type) {
- case O_COMMIT:
- serialized = baseline_commit_serialize((struct commit *)obj);
- SHA256Update(&hash_ctx, serialized, strlen(serialized));
- free(serialized);
- objid = &(((struct commit *)obj)->id);
- break;
- case O_DIR:
- serialized = baseline_dir_serialize((struct dir *)obj);
- SHA256Update(&hash_ctx, serialized, strlen(serialized));
- free(serialized);
- objid = &(((struct dir *)obj)->id);
- break;
- case O_FILE:
- if (((struct file *)obj)->loc == ON_FS) {
- /* save file offset */
- offset = lseek(((struct file *)obj)->fd, 0, SEEK_CUR);
- do {
- n = read(((struct file *)obj)->fd, buf, sizeof(buf));
- if (n == -1)
- return NULL;
- SHA256Update(&hash_ctx, buf, n);
- if (n <= sizeof(buf))
- break;
- } while (1);
- /* restore file offset */
- lseek(((struct file *)obj)->fd, offset, SEEK_SET);
- }
- else {
- SHA256Update(&hash_ctx, ((struct file *)obj)->buffer, strlen(((struct file *)obj)->buffer));
- }
- objid = &(((struct file *)obj)->id);
- break;
- default:
- break;
- }
- SHA256Final(digest, &hash_ctx);
- *objid = (char *)malloc(SHA256_DIGEST_LENGTH * 2 + 1);
- for (i=0, ptr=*objid ; i<SHA256_DIGEST_LENGTH ; i++, ptr+=2) {
- snprintf(ptr, 3, "%02x", digest[i]);
- }
- return *objid;
-}
-
diff --git a/objects.h b/objects.h
@@ -80,13 +80,9 @@ void baseline_file_free(struct file *);
/* commit ops */
struct commit* baseline_commit_new();
void baseline_commit_free(struct commit *);
-char* baseline_commit_serialize(struct commit *);
/* dir ops */
struct dir* baseline_dir_new();
void baseline_dir_free(struct dir *);
void baseline_dir_append(struct dir *, struct dirent *);
-char* baseline_dir_serialize(struct dir *);
-/* id ops */
-char *baseline_gen_id(void *, enum objtype);
#endif