1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
|
/*-
* SPDX-License-Identifier: AGPL-3.0-only
* SPDX-FileCopyrightText: Copyright (c) 2025 Runxi Yu <https://runxiyu.org>
*/
#include "x.h"
void *session(void *_conn)
{
int conn = *(int *)_conn;
free((int *)_conn);
int err;
conn_io_t io = {.fd = conn };
struct bare_reader reader = {
.buffer = &io,
.read = conn_read,
};
struct bare_writer writer = {
.buffer = &io,
.write = conn_write,
};
/* Repo path */
char path[4096] = { 0 };
err = bare_get_data(&reader, (uint8_t *) path, sizeof(path) - 1);
if (err != BARE_ERROR_NONE) {
goto close;
}
path[sizeof(path) - 1] = '\0';
fprintf(stderr, "session: path='%s'\n", path);
/* Command */
uint64_t cmd = 0;
err = bare_get_uint(&reader, &cmd);
if (err != BARE_ERROR_NONE) {
bare_put_uint(&writer, 2);
goto close;
}
fprintf(stderr, "session: cmd=%llu\n", (unsigned long long)cmd);
/* Repo init does not require opening an existing repo so let's just do it here */
if (cmd == 15) {
fprintf(stderr, "session: handling init for '%s'\n", path);
if (cmd_init_repo(path, &reader, &writer) != 0) {
}
goto close;
}
git_repository *repo = NULL;
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;
}
switch (cmd) {
case 1:
err = cmd_index(repo, &writer);
if (err != 0)
goto free_repo;
break;
case 2:
err = cmd_treeraw(repo, &reader, &writer);
if (err != 0)
goto free_repo;
break;
case 3:
err = cmd_resolve_ref(repo, &reader, &writer);
if (err != 0)
goto free_repo;
break;
case 4:
err = cmd_list_branches(repo, &writer);
if (err != 0)
goto free_repo;
break;
case 5:
err = cmd_format_patch(repo, &reader, &writer);
if (err != 0)
goto free_repo;
break;
case 6:
err = cmd_commit_diff(repo, &reader, &writer);
if (err != 0)
goto free_repo;
break;
case 7:
err = cmd_merge_base(repo, &reader, &writer);
if (err != 0)
goto free_repo;
break;
case 8:
err = cmd_log(repo, &reader, &writer);
if (err != 0)
goto free_repo;
break;
case 9:
err = cmd_tree_list_by_oid(repo, &reader, &writer);
if (err != 0)
goto free_repo;
break;
case 10:
err = cmd_write_tree(repo, &reader, &writer);
if (err != 0)
goto free_repo;
break;
case 11:
err = cmd_blob_write(repo, &reader, &writer);
if (err != 0)
goto free_repo;
break;
case 12:
err = cmd_commit_tree_oid(repo, &reader, &writer);
if (err != 0)
goto free_repo;
break;
case 13:
err = cmd_commit_create(repo, &reader, &writer);
if (err != 0)
goto free_repo;
break;
case 14:
err = cmd_update_ref(repo, &reader, &writer);
if (err != 0)
goto free_repo;
break;
case 0:
bare_put_uint(&writer, 3);
goto free_repo;
default:
bare_put_uint(&writer, 3);
goto free_repo;
}
free_repo:
git_repository_free(repo);
close:
close(conn);
return NULL;
}
|