From 84ec0dd08c75344513fb4c912f835cadf5b28e49 Mon Sep 17 00:00:00 2001 From: Runxi Yu Date: Sat, 05 Apr 2025 11:05:43 +0800 Subject: [PATCH] git2d: Separate the files a bit --- Makefile | 2 +- git2d/main.c | 191 +---------------------------------------------------- git2d/rw.c | 31 +++++++++++++++++++++++++++++++ git2d/session.c | 143 +++++++++++++++++++++++++++++++++++++++++++++++++++++ git2d/x.h | 30 ++++++++++++++++++++++++++++++ diff --git a/Makefile b/Makefile index 05e072c4d53012c763002e717c5b6119bf151a03..46488fb1b021610bccdc8335d7f7206a1624121b 100644 --- a/Makefile +++ b/Makefile @@ -28,7 +28,7 @@ utils/colb: hookc/hookc: -git2d/git2d: git2d/main.c git2d/bare.c git2d/utf8.c +git2d/git2d: git2d/*.c $(CC) $(CFLAGS) -o git2d/git2d $^ $(shell pkg-config --cflags --libs libgit2) -lpthread clean: diff --git a/git2d/main.c b/git2d/main.c index 7671b72e3562449db1a8899990a759b58ed93801..3f482edb35c051d70bb09f31a1b0d464c9562fc9 100644 --- a/git2d/main.c +++ b/git2d/main.c @@ -8,196 +8,7 @@ * TODO: Pool repositories (and take care of thread safety) * libgit2 has a nice builtin per-repo cache that we could utilize this way. */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "bare.h" - -typedef struct { - int fd; -} conn_io_t; - -static bare_error -conn_read(void *buffer, void *dst, uint64_t sz) -{ - conn_io_t *io = buffer; - ssize_t rsz = read(io->fd, dst, sz); - return (rsz == (ssize_t) sz) ? BARE_ERROR_NONE : BARE_ERROR_READ_FAILED; -} - -static bare_error -conn_write(void *buffer, const void *src, uint64_t sz) -{ - conn_io_t *io = buffer; - const uint8_t *data = src; - uint64_t total = 0; - - while (total < sz) { - ssize_t written = write(io->fd, data + total, sz - total); - if (written < 0) { - if (errno == EINTR) - continue; - return BARE_ERROR_WRITE_FAILED; - } - if (written == 0) - break; - total += written; - } - - return (total == sz) ? BARE_ERROR_NONE : BARE_ERROR_WRITE_FAILED; -} - -void * -session(void *_conn) -{ - int conn = *(int *)_conn; - free((int *)_conn); - - int err; - git_repository *repo = NULL; - - char path[4096] = {0}; - conn_io_t io = {.fd = conn }; - struct bare_reader reader = { - .buffer = &io, - .read = conn_read, - }; - struct bare_writer writer = { - .buffer = &io, - .write = conn_write, - }; - - err = bare_get_data(&reader, (uint8_t *) path, sizeof(path) - 1); - if (err != BARE_ERROR_NONE) { - goto close; - } - path[sizeof(path) - 1] = '\0'; - - err = git_repository_open_ext(&repo, path, GIT_REPOSITORY_OPEN_NO_SEARCH | GIT_REPOSITORY_OPEN_BARE | GIT_REPOSITORY_OPEN_NO_DOTGIT, NULL); - if (err != 0) { - bare_put_uint(&writer, 1); - goto close; - } - - git_object *obj = NULL; - err = git_revparse_single(&obj, repo, "HEAD^{tree}"); - if (err != 0) { - bare_put_uint(&writer, 2); - goto free_repo; - } - git_tree *tree = (git_tree *) obj; - - /* README */ - - git_tree_entry *entry = NULL; - err = git_tree_entry_bypath(&entry, tree, "README.md"); - if (err != 0) { - bare_put_uint(&writer, 3); - goto free_tree; - } - - git_otype objtype = git_tree_entry_type(entry); - if (objtype != GIT_OBJECT_BLOB) { - bare_put_uint(&writer, 4); - goto free_tree_entry; - } - - git_object *obj2 = NULL; - err = git_tree_entry_to_object(&obj2, repo, entry); - if (err != 0) { - bare_put_uint(&writer, 5); - goto free_tree_entry; - } - - git_blob *blob = (git_blob *) obj2; - const void *content = git_blob_rawcontent(blob); - if (content == NULL) { - bare_put_uint(&writer, 6); - goto free_blob; - } - - bare_put_uint(&writer, 0); - bare_put_data(&writer, content, git_blob_rawsize(blob)); - - /* Commits */ - - git_revwalk *walker = NULL; - if (git_revwalk_new(&walker, repo) != 0) { - bare_put_uint(&writer, 7); - goto free_blob; - } - - if (git_revwalk_push_head(walker) != 0) { - bare_put_uint(&writer, 8); - goto free_blob; - } - - int count = 0; - git_oid oid; - while (count < 3 && git_revwalk_next(&oid, walker) == 0) { - git_commit *commit = NULL; - if (git_commit_lookup(&commit, repo, &oid) != 0) - break; - - const char *msg = git_commit_summary(commit); - const git_signature *author = git_commit_author(commit); - - /* ID */ - bare_put_data(&writer, oid.id, GIT_OID_RAWSZ); - - /* Title */ - size_t msg_len = msg ? strlen(msg) : 0; - bare_put_data(&writer, (const uint8_t *)(msg ? msg : ""), msg_len); - - /* Author's name */ - const char *author_name = author ? author->name : ""; - bare_put_data(&writer, (const uint8_t *)author_name, strlen(author_name)); - - /* Author's email */ - const char *author_email = author ? author->email : ""; - bare_put_data(&writer, (const uint8_t *)author_email, strlen(author_email)); - - /* Author's date */ - time_t time = git_commit_time(commit); - char timebuf[64]; - struct tm *tm = localtime(&time); - if (tm) - strftime(timebuf, sizeof(timebuf), "%Y-%m-%d %H:%M:%S", tm); - else - strcpy(timebuf, "unknown"); - bare_put_data(&writer, (const uint8_t *)timebuf, strlen(timebuf)); - - git_commit_free(commit); - count++; - } - - git_revwalk_free(walker); - -free_blob: - git_blob_free(blob); -free_tree_entry: - git_tree_entry_free(entry); -free_tree: - git_tree_free(tree); -free_repo: - git_repository_free(repo); - -close: - close(conn); - - return NULL; -} +#include "x.h" int main(int argc, char **argv) diff --git a/git2d/rw.c b/git2d/rw.c new file mode 100644 index 0000000000000000000000000000000000000000..a3e40e177c09eb0674e5b79ad2525208e9b11aad --- /dev/null +++ b/git2d/rw.c @@ -0,0 +1,31 @@ +#include "x.h" + +bare_error +conn_read(void *buffer, void *dst, uint64_t sz) +{ + conn_io_t *io = buffer; + ssize_t rsz = read(io->fd, dst, sz); + return (rsz == (ssize_t) sz) ? BARE_ERROR_NONE : BARE_ERROR_READ_FAILED; +} + +bare_error +conn_write(void *buffer, const void *src, uint64_t sz) +{ + conn_io_t *io = buffer; + const uint8_t *data = src; + uint64_t total = 0; + + while (total < sz) { + ssize_t written = write(io->fd, data + total, sz - total); + if (written < 0) { + if (errno == EINTR) + continue; + return BARE_ERROR_WRITE_FAILED; + } + if (written == 0) + break; + total += written; + } + + return (total == sz) ? BARE_ERROR_NONE : BARE_ERROR_WRITE_FAILED; +} diff --git a/git2d/session.c b/git2d/session.c new file mode 100644 index 0000000000000000000000000000000000000000..a0d98ee9f340050d55a842d6d59c41d44ece66cf --- /dev/null +++ b/git2d/session.c @@ -0,0 +1,143 @@ +#include "x.h" + +void * +session(void *_conn) +{ + int conn = *(int *)_conn; + free((int *)_conn); + + int err; + git_repository *repo = NULL; + + char path[4096] = {0}; + conn_io_t io = {.fd = conn }; + struct bare_reader reader = { + .buffer = &io, + .read = conn_read, + }; + struct bare_writer writer = { + .buffer = &io, + .write = conn_write, + }; + + err = bare_get_data(&reader, (uint8_t *) path, sizeof(path) - 1); + if (err != BARE_ERROR_NONE) { + goto close; + } + path[sizeof(path) - 1] = '\0'; + + err = git_repository_open_ext(&repo, path, GIT_REPOSITORY_OPEN_NO_SEARCH | GIT_REPOSITORY_OPEN_BARE | GIT_REPOSITORY_OPEN_NO_DOTGIT, NULL); + if (err != 0) { + bare_put_uint(&writer, 1); + goto close; + } + + git_object *obj = NULL; + err = git_revparse_single(&obj, repo, "HEAD^{tree}"); + if (err != 0) { + bare_put_uint(&writer, 2); + goto free_repo; + } + git_tree *tree = (git_tree *) obj; + + /* README */ + + git_tree_entry *entry = NULL; + err = git_tree_entry_bypath(&entry, tree, "README.md"); + if (err != 0) { + bare_put_uint(&writer, 3); + goto free_tree; + } + + git_otype objtype = git_tree_entry_type(entry); + if (objtype != GIT_OBJECT_BLOB) { + bare_put_uint(&writer, 4); + goto free_tree_entry; + } + + git_object *obj2 = NULL; + err = git_tree_entry_to_object(&obj2, repo, entry); + if (err != 0) { + bare_put_uint(&writer, 5); + goto free_tree_entry; + } + + git_blob *blob = (git_blob *) obj2; + const void *content = git_blob_rawcontent(blob); + if (content == NULL) { + bare_put_uint(&writer, 6); + goto free_blob; + } + + bare_put_uint(&writer, 0); + bare_put_data(&writer, content, git_blob_rawsize(blob)); + + /* Commits */ + + git_revwalk *walker = NULL; + if (git_revwalk_new(&walker, repo) != 0) { + bare_put_uint(&writer, 7); + goto free_blob; + } + + if (git_revwalk_push_head(walker) != 0) { + bare_put_uint(&writer, 8); + goto free_blob; + } + + int count = 0; + git_oid oid; + while (count < 3 && git_revwalk_next(&oid, walker) == 0) { + git_commit *commit = NULL; + if (git_commit_lookup(&commit, repo, &oid) != 0) + break; + + const char *msg = git_commit_summary(commit); + const git_signature *author = git_commit_author(commit); + + /* ID */ + bare_put_data(&writer, oid.id, GIT_OID_RAWSZ); + + /* Title */ + size_t msg_len = msg ? strlen(msg) : 0; + bare_put_data(&writer, (const uint8_t *)(msg ? msg : ""), msg_len); + + /* Author's name */ + const char *author_name = author ? author->name : ""; + bare_put_data(&writer, (const uint8_t *)author_name, strlen(author_name)); + + /* Author's email */ + const char *author_email = author ? author->email : ""; + bare_put_data(&writer, (const uint8_t *)author_email, strlen(author_email)); + + /* Author's date */ + time_t time = git_commit_time(commit); + char timebuf[64]; + struct tm *tm = localtime(&time); + if (tm) + strftime(timebuf, sizeof(timebuf), "%Y-%m-%d %H:%M:%S", tm); + else + strcpy(timebuf, "unknown"); + bare_put_data(&writer, (const uint8_t *)timebuf, strlen(timebuf)); + + git_commit_free(commit); + count++; + } + + git_revwalk_free(walker); + +free_blob: + git_blob_free(blob); +free_tree_entry: + git_tree_entry_free(entry); +free_tree: + git_tree_free(tree); +free_repo: + git_repository_free(repo); + +close: + close(conn); + + return NULL; +} + diff --git a/git2d/x.h b/git2d/x.h new file mode 100644 index 0000000000000000000000000000000000000000..4be51861fe9547edc09781f4e3c1da2c1a6dbf8a --- /dev/null +++ b/git2d/x.h @@ -0,0 +1,30 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "bare.h" + +#ifndef X_H +#define X_H + +typedef struct { + int fd; +} conn_io_t; + + +bare_error conn_read(void *buffer, void *dst, uint64_t sz); +bare_error conn_write(void *buffer, const void *src, uint64_t sz); + +void * session(void *_conn); + +#endif // X_H -- 2.48.1