aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRunxi Yu <me@runxiyu.org>2025-04-05 11:05:43 +0800
committerRunxi Yu <me@runxiyu.org>2025-04-05 11:07:05 +0800
commit84ec0dd08c75344513fb4c912f835cadf5b28e49 (patch)
tree60c49797b602eb39551829b5fa0cd7c02252195a
parentMakefile: Statically build Go (diff)
downloadforge-84ec0dd08c75344513fb4c912f835cadf5b28e49.tar.gz
forge-84ec0dd08c75344513fb4c912f835cadf5b28e49.tar.zst
forge-84ec0dd08c75344513fb4c912f835cadf5b28e49.zip
git2d: Separate the files a bit
-rw-r--r--Makefile2
-rw-r--r--git2d/main.c191
-rw-r--r--git2d/rw.c31
-rw-r--r--git2d/session.c143
-rw-r--r--git2d/x.h30
5 files changed, 206 insertions, 191 deletions
diff --git a/Makefile b/Makefile
index 05e072c..46488fb 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 7671b72..3f482ed 100644
--- a/git2d/main.c
+++ b/git2d/main.c
@@ -8,196 +8,7 @@
* libgit2 has a nice builtin per-repo cache that we could utilize this way.
*/
-#include <err.h>
-#include <errno.h>
-#include <git2.h>
-#include <pthread.h>
-#include <signal.h>
-#include <sys/socket.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <sys/un.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-#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 0000000..a3e40e1
--- /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 0000000..a0d98ee
--- /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 0000000..4be5186
--- /dev/null
+++ b/git2d/x.h
@@ -0,0 +1,30 @@
+#include <err.h>
+#include <errno.h>
+#include <git2.h>
+#include <pthread.h>
+#include <signal.h>
+#include <sys/socket.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/un.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#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