X-Git-Url: http://git.mutantstargoat.com/user/nuclear/?p=reposerve;a=blobdiff_plain;f=server%2Fsrc%2Frepo.c;h=6f81d90633add086c8bbc970aae52de497d1c969;hp=fee52e8c7ca7240119453e9ad4371c2e3527d175;hb=da7ca5e387cf4bb820ca48d13a5fc4376c2474b4;hpb=61f583d599f2e54da96c5d12d10701d2129a9fa3 diff --git a/server/src/repo.c b/server/src/repo.c index fee52e8..6f81d90 100644 --- a/server/src/repo.c +++ b/server/src/repo.c @@ -1,22 +1,25 @@ #include #include #include +#include +#include #include +#include "repo.h" +#include "md5.h" -struct repofile { - char *path; -}; - +static int add_file(const char *name, const char *path); +static void calc_chksum(FILE *fp, uint32_t *sum); static int proc_tree(git_repository *repo, git_tree *tree, const char *path); -static struct repofile *files; +static struct repo_file *files; static int num_files, max_files; +static const char *repo_path; int repo_init(const char *path) { int res = -1; git_repository *repo = 0; - git_tree *tree; + git_object *tree; git_libgit2_init(); @@ -28,14 +31,16 @@ int repo_init(const char *path) files = 0; num_files = max_files = 0; + repo_path = path; - if(git_revparse_single((git_object**)&tree, repo, "HEAD^{tree}") != 0) { + if(git_revparse_single(&tree, repo, "HEAD^{tree}") != 0) { fprintf(stderr, "repo_init: %s\n", git_error_last()->message); goto end; } - if(proc_tree(repo, tree, 0) == -1) { + if(proc_tree(repo, (git_tree*)tree, 0) == -1) { goto end; } + git_object_free(tree); res = 0; end: @@ -51,6 +56,10 @@ end: void repo_cleanup(void) { + int i; + for(i=0; i= num_files) return 0; - return files[idx].path; + return files + idx; } static int add_file(const char *name, const char *path) { - struct repofile *file; + struct repo_file *file; int pathlen; + struct stat st; + FILE *fp; if(num_files >= max_files) { int newmax = max_files ? max_files * 2 : 16; @@ -83,26 +94,59 @@ static int add_file(const char *name, const char *path) max_files = newmax; } - pathlen = strlen(name); + pathlen = strlen(repo_path) + strlen(name) + 1; if(path) { pathlen += strlen(path) + 1; } file = files + num_files; - if(!(file->path = malloc(pathlen + 1))) { + if(!(file->fullpath = malloc(pathlen + 1))) { fprintf(stderr, "repo_init: failed to allocate file path buffer\n"); return -1; } if(path) { - sprintf(file->path, "%s/%s", path, name); + sprintf(file->fullpath, "%s/%s/%s", repo_path, path, name); } else { - strcpy(file->path, name); + sprintf(file->fullpath, "%s/%s", repo_path, name); } + file->path = file->fullpath + strlen(repo_path) + 1; + + /* attempt to open the file */ + if(!(fp = fopen(file->fullpath, "rb"))) { + fprintf(stderr, "repo_init: failed to open file: %s: %s\n", file->fullpath, strerror(errno)); + free(file->fullpath); + return -1; + } + + /* get size & modification time */ + fstat(fileno(fp), &st); + file->size = st.st_size; + file->mtime = st.st_mtime; + + /* calculate md5 checksum */ + calc_chksum(fp, file->chksum); + + fclose(fp); num_files++; return 0; } +static void calc_chksum(FILE *fp, uint32_t *sum) +{ + static char buf[4096]; + int sz; + struct md5_state md; + + md5_begin(&md); + while((sz = fread(buf, 1, sizeof buf, fp)) > 0) { + md5_msg(&md, buf, sz); + } + md5_end(&md); + + memcpy(sum, md.sum, sizeof md.sum); +} + static int proc_tree(git_repository *repo, git_tree *tree, const char *path) { int i, count = git_tree_entrycount(tree); @@ -126,7 +170,7 @@ static int proc_tree(git_repository *repo, git_tree *tree, const char *path) case GIT_OBJECT_TREE: git_tree_entry_to_object(&obj, repo, ent); if(path) { - char *pathbuf = malloc(strlen(path) + strlen(name) + 1); + char *pathbuf = malloc(strlen(path) + strlen(name) + 2); if(!pathbuf) { fprintf(stderr, "repo_init: failed to allocate memory\n"); return -1;