Blame


1 b61ceafc 2022-10-13 thomas /*
2 b61ceafc 2022-10-13 thomas * Copyright (c) 2018, 2019, 2022 Stefan Sperling <stsp@openbsd.org>
3 b61ceafc 2022-10-13 thomas *
4 b61ceafc 2022-10-13 thomas * Permission to use, copy, modify, and distribute this software for any
5 b61ceafc 2022-10-13 thomas * purpose with or without fee is hereby granted, provided that the above
6 b61ceafc 2022-10-13 thomas * copyright notice and this permission notice appear in all copies.
7 b61ceafc 2022-10-13 thomas *
8 b61ceafc 2022-10-13 thomas * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 b61ceafc 2022-10-13 thomas * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 b61ceafc 2022-10-13 thomas * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 b61ceafc 2022-10-13 thomas * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 b61ceafc 2022-10-13 thomas * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 b61ceafc 2022-10-13 thomas * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 b61ceafc 2022-10-13 thomas * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 b61ceafc 2022-10-13 thomas */
16 b61ceafc 2022-10-13 thomas
17 b61ceafc 2022-10-13 thomas #include <sys/mman.h>
18 b61ceafc 2022-10-13 thomas #include <sys/queue.h>
19 b61ceafc 2022-10-13 thomas #include <sys/types.h>
20 b61ceafc 2022-10-13 thomas #include <sys/stat.h>
21 b61ceafc 2022-10-13 thomas #include <sys/socket.h>
22 b61ceafc 2022-10-13 thomas #include <sys/uio.h>
23 b61ceafc 2022-10-13 thomas
24 b61ceafc 2022-10-13 thomas #include <errno.h>
25 b61ceafc 2022-10-13 thomas #include <imsg.h>
26 b61ceafc 2022-10-13 thomas #include <stdio.h>
27 b61ceafc 2022-10-13 thomas #include <stdint.h>
28 b61ceafc 2022-10-13 thomas #include <stdlib.h>
29 b61ceafc 2022-10-13 thomas #include <string.h>
30 b61ceafc 2022-10-13 thomas #include <limits.h>
31 b61ceafc 2022-10-13 thomas #include <unistd.h>
32 b61ceafc 2022-10-13 thomas
33 b61ceafc 2022-10-13 thomas #include "got_error.h"
34 b61ceafc 2022-10-13 thomas #include "got_object.h"
35 b61ceafc 2022-10-13 thomas #include "got_repository.h"
36 b61ceafc 2022-10-13 thomas #include "got_opentemp.h"
37 b61ceafc 2022-10-13 thomas #include "got_path.h"
38 b61ceafc 2022-10-13 thomas
39 b61ceafc 2022-10-13 thomas #include "got_lib_delta.h"
40 b61ceafc 2022-10-13 thomas #include "got_lib_object.h"
41 b61ceafc 2022-10-13 thomas #include "got_lib_privsep.h"
42 b61ceafc 2022-10-13 thomas #include "got_lib_object_cache.h"
43 b61ceafc 2022-10-13 thomas #include "got_lib_pack.h"
44 b61ceafc 2022-10-13 thomas #include "got_lib_repository.h"
45 b61ceafc 2022-10-13 thomas
46 b61ceafc 2022-10-13 thomas static const struct got_error *
47 b61ceafc 2022-10-13 thomas request_packed_object(struct got_object **obj, struct got_pack *pack, int idx,
48 b61ceafc 2022-10-13 thomas struct got_object_id *id)
49 b61ceafc 2022-10-13 thomas {
50 b61ceafc 2022-10-13 thomas const struct got_error *err = NULL;
51 b61ceafc 2022-10-13 thomas struct imsgbuf *ibuf = pack->privsep_child->ibuf;
52 b61ceafc 2022-10-13 thomas
53 b61ceafc 2022-10-13 thomas err = got_privsep_send_packed_obj_req(ibuf, idx, id);
54 b61ceafc 2022-10-13 thomas if (err)
55 b61ceafc 2022-10-13 thomas return err;
56 b61ceafc 2022-10-13 thomas
57 b61ceafc 2022-10-13 thomas err = got_privsep_recv_obj(obj, ibuf);
58 b61ceafc 2022-10-13 thomas if (err)
59 b61ceafc 2022-10-13 thomas return err;
60 b61ceafc 2022-10-13 thomas
61 b61ceafc 2022-10-13 thomas memcpy(&(*obj)->id, id, sizeof((*obj)->id));
62 b61ceafc 2022-10-13 thomas
63 b61ceafc 2022-10-13 thomas return NULL;
64 b61ceafc 2022-10-13 thomas }
65 b61ceafc 2022-10-13 thomas
66 b61ceafc 2022-10-13 thomas /* Create temporary files used during delta application. */
67 b61ceafc 2022-10-13 thomas static const struct got_error *
68 b61ceafc 2022-10-13 thomas pack_child_send_tempfiles(struct imsgbuf *ibuf, struct got_pack *pack)
69 b61ceafc 2022-10-13 thomas {
70 b61ceafc 2022-10-13 thomas const struct got_error *err;
71 b61ceafc 2022-10-13 thomas int basefd = -1, accumfd = -1;
72 b61ceafc 2022-10-13 thomas
73 b61ceafc 2022-10-13 thomas /*
74 b61ceafc 2022-10-13 thomas * For performance reasons, the child will keep reusing the
75 b61ceafc 2022-10-13 thomas * same temporary files during every object request.
76 b61ceafc 2022-10-13 thomas * Opening and closing new files for every object request is
77 b61ceafc 2022-10-13 thomas * too expensive during operations such as 'gotadmin pack'.
78 b61ceafc 2022-10-13 thomas */
79 b61ceafc 2022-10-13 thomas if (pack->child_has_tempfiles)
80 b61ceafc 2022-10-13 thomas return NULL;
81 b61ceafc 2022-10-13 thomas
82 b61ceafc 2022-10-13 thomas basefd = dup(pack->basefd);
83 b61ceafc 2022-10-13 thomas if (basefd == -1)
84 b61ceafc 2022-10-13 thomas return got_error_from_errno("dup");
85 b61ceafc 2022-10-13 thomas
86 b61ceafc 2022-10-13 thomas accumfd = dup(pack->accumfd);
87 b61ceafc 2022-10-13 thomas if (accumfd == -1) {
88 b61ceafc 2022-10-13 thomas err = got_error_from_errno("dup");
89 b61ceafc 2022-10-13 thomas goto done;
90 b61ceafc 2022-10-13 thomas }
91 b61ceafc 2022-10-13 thomas
92 b61ceafc 2022-10-13 thomas err = got_privsep_send_tmpfd(ibuf, basefd);
93 b61ceafc 2022-10-13 thomas if (err)
94 b61ceafc 2022-10-13 thomas goto done;
95 b61ceafc 2022-10-13 thomas
96 b61ceafc 2022-10-13 thomas err = got_privsep_send_tmpfd(ibuf, accumfd);
97 b61ceafc 2022-10-13 thomas done:
98 b61ceafc 2022-10-13 thomas if (err) {
99 b61ceafc 2022-10-13 thomas if (basefd != -1)
100 b61ceafc 2022-10-13 thomas close(basefd);
101 b61ceafc 2022-10-13 thomas if (accumfd != -1)
102 b61ceafc 2022-10-13 thomas close(accumfd);
103 b61ceafc 2022-10-13 thomas } else
104 b61ceafc 2022-10-13 thomas pack->child_has_tempfiles = 1;
105 b61ceafc 2022-10-13 thomas return NULL;
106 b61ceafc 2022-10-13 thomas }
107 b61ceafc 2022-10-13 thomas
108 b61ceafc 2022-10-13 thomas static const struct got_error *
109 b61ceafc 2022-10-13 thomas request_packed_object_raw(uint8_t **outbuf, off_t *size, size_t *hdrlen,
110 b61ceafc 2022-10-13 thomas int outfd, struct got_pack *pack, int idx, struct got_object_id *id)
111 b61ceafc 2022-10-13 thomas {
112 b61ceafc 2022-10-13 thomas const struct got_error *err = NULL;
113 b61ceafc 2022-10-13 thomas struct imsgbuf *ibuf = pack->privsep_child->ibuf;
114 b61ceafc 2022-10-13 thomas int outfd_child;
115 b61ceafc 2022-10-13 thomas
116 b61ceafc 2022-10-13 thomas err = pack_child_send_tempfiles(ibuf, pack);
117 b61ceafc 2022-10-13 thomas if (err)
118 b61ceafc 2022-10-13 thomas return err;
119 b61ceafc 2022-10-13 thomas
120 b61ceafc 2022-10-13 thomas outfd_child = dup(outfd);
121 b61ceafc 2022-10-13 thomas if (outfd_child == -1)
122 b61ceafc 2022-10-13 thomas return got_error_from_errno("dup");
123 b61ceafc 2022-10-13 thomas
124 b61ceafc 2022-10-13 thomas err = got_privsep_send_packed_raw_obj_req(ibuf, idx, id);
125 b61ceafc 2022-10-13 thomas if (err) {
126 b61ceafc 2022-10-13 thomas close(outfd_child);
127 b61ceafc 2022-10-13 thomas return err;
128 b61ceafc 2022-10-13 thomas }
129 b61ceafc 2022-10-13 thomas
130 b61ceafc 2022-10-13 thomas err = got_privsep_send_raw_obj_outfd(ibuf, outfd_child);
131 b61ceafc 2022-10-13 thomas if (err)
132 b61ceafc 2022-10-13 thomas return err;
133 b61ceafc 2022-10-13 thomas
134 b61ceafc 2022-10-13 thomas err = got_privsep_recv_raw_obj(outbuf, size, hdrlen, ibuf);
135 b61ceafc 2022-10-13 thomas if (err)
136 b61ceafc 2022-10-13 thomas return err;
137 b61ceafc 2022-10-13 thomas
138 b61ceafc 2022-10-13 thomas return NULL;
139 b61ceafc 2022-10-13 thomas }
140 b61ceafc 2022-10-13 thomas
141 b61ceafc 2022-10-13 thomas static const struct got_error *
142 b61ceafc 2022-10-13 thomas read_packed_object_privsep(struct got_object **obj,
143 b61ceafc 2022-10-13 thomas struct got_repository *repo, struct got_pack *pack,
144 b61ceafc 2022-10-13 thomas struct got_packidx *packidx, int idx, struct got_object_id *id)
145 b61ceafc 2022-10-13 thomas {
146 b61ceafc 2022-10-13 thomas const struct got_error *err = NULL;
147 b61ceafc 2022-10-13 thomas
148 b61ceafc 2022-10-13 thomas if (pack->privsep_child == NULL) {
149 b61ceafc 2022-10-13 thomas err = got_pack_start_privsep_child(pack, packidx);
150 b61ceafc 2022-10-13 thomas if (err)
151 b61ceafc 2022-10-13 thomas return err;
152 b61ceafc 2022-10-13 thomas }
153 b61ceafc 2022-10-13 thomas
154 b61ceafc 2022-10-13 thomas return request_packed_object(obj, pack, idx, id);
155 b61ceafc 2022-10-13 thomas }
156 b61ceafc 2022-10-13 thomas
157 b61ceafc 2022-10-13 thomas static const struct got_error *
158 b61ceafc 2022-10-13 thomas read_packed_object_raw_privsep(uint8_t **outbuf, off_t *size, size_t *hdrlen,
159 b61ceafc 2022-10-13 thomas int outfd, struct got_pack *pack, struct got_packidx *packidx, int idx,
160 b61ceafc 2022-10-13 thomas struct got_object_id *id)
161 b61ceafc 2022-10-13 thomas {
162 b61ceafc 2022-10-13 thomas const struct got_error *err = NULL;
163 b61ceafc 2022-10-13 thomas
164 b61ceafc 2022-10-13 thomas if (pack->privsep_child == NULL) {
165 b61ceafc 2022-10-13 thomas err = got_pack_start_privsep_child(pack, packidx);
166 b61ceafc 2022-10-13 thomas if (err)
167 b61ceafc 2022-10-13 thomas return err;
168 b61ceafc 2022-10-13 thomas }
169 b61ceafc 2022-10-13 thomas
170 b61ceafc 2022-10-13 thomas return request_packed_object_raw(outbuf, size, hdrlen, outfd, pack,
171 b61ceafc 2022-10-13 thomas idx, id);
172 b61ceafc 2022-10-13 thomas }
173 b61ceafc 2022-10-13 thomas
174 b61ceafc 2022-10-13 thomas const struct got_error *
175 b61ceafc 2022-10-13 thomas got_object_open_packed(struct got_object **obj, struct got_object_id *id,
176 b61ceafc 2022-10-13 thomas struct got_repository *repo)
177 b61ceafc 2022-10-13 thomas {
178 b61ceafc 2022-10-13 thomas const struct got_error *err = NULL;
179 b61ceafc 2022-10-13 thomas struct got_pack *pack = NULL;
180 b61ceafc 2022-10-13 thomas struct got_packidx *packidx = NULL;
181 b61ceafc 2022-10-13 thomas int idx;
182 b61ceafc 2022-10-13 thomas char *path_packfile;
183 b61ceafc 2022-10-13 thomas
184 b61ceafc 2022-10-13 thomas err = got_repo_search_packidx(&packidx, &idx, repo, id);
185 b61ceafc 2022-10-13 thomas if (err)
186 b61ceafc 2022-10-13 thomas return err;
187 b61ceafc 2022-10-13 thomas
188 b61ceafc 2022-10-13 thomas err = got_packidx_get_packfile_path(&path_packfile,
189 b61ceafc 2022-10-13 thomas packidx->path_packidx);
190 b61ceafc 2022-10-13 thomas if (err)
191 b61ceafc 2022-10-13 thomas return err;
192 b61ceafc 2022-10-13 thomas
193 b61ceafc 2022-10-13 thomas pack = got_repo_get_cached_pack(repo, path_packfile);
194 b61ceafc 2022-10-13 thomas if (pack == NULL) {
195 b61ceafc 2022-10-13 thomas err = got_repo_cache_pack(&pack, repo, path_packfile, packidx);
196 b61ceafc 2022-10-13 thomas if (err)
197 b61ceafc 2022-10-13 thomas goto done;
198 b61ceafc 2022-10-13 thomas }
199 b61ceafc 2022-10-13 thomas
200 b61ceafc 2022-10-13 thomas err = read_packed_object_privsep(obj, repo, pack, packidx, idx, id);
201 b61ceafc 2022-10-13 thomas if (err)
202 b61ceafc 2022-10-13 thomas goto done;
203 b61ceafc 2022-10-13 thomas done:
204 b61ceafc 2022-10-13 thomas free(path_packfile);
205 b61ceafc 2022-10-13 thomas return err;
206 b61ceafc 2022-10-13 thomas }
207 b61ceafc 2022-10-13 thomas
208 b61ceafc 2022-10-13 thomas const struct got_error *
209 b61ceafc 2022-10-13 thomas got_object_open_from_packfile(struct got_object **obj, struct got_object_id *id,
210 b61ceafc 2022-10-13 thomas struct got_pack *pack, struct got_packidx *packidx, int obj_idx,
211 b61ceafc 2022-10-13 thomas struct got_repository *repo)
212 b61ceafc 2022-10-13 thomas {
213 b61ceafc 2022-10-13 thomas return read_packed_object_privsep(obj, repo, pack, packidx,
214 b61ceafc 2022-10-13 thomas obj_idx, id);
215 b61ceafc 2022-10-13 thomas }
216 b61ceafc 2022-10-13 thomas
217 b61ceafc 2022-10-13 thomas const struct got_error *
218 b61ceafc 2022-10-13 thomas got_object_read_raw_delta(uint64_t *base_size, uint64_t *result_size,
219 b61ceafc 2022-10-13 thomas off_t *delta_size, off_t *delta_compressed_size, off_t *delta_offset,
220 b61ceafc 2022-10-13 thomas off_t *delta_out_offset, struct got_object_id **base_id, int delta_cache_fd,
221 b61ceafc 2022-10-13 thomas struct got_packidx *packidx, int obj_idx, struct got_object_id *id,
222 b61ceafc 2022-10-13 thomas struct got_repository *repo)
223 b61ceafc 2022-10-13 thomas {
224 b61ceafc 2022-10-13 thomas const struct got_error *err = NULL;
225 b61ceafc 2022-10-13 thomas struct got_pack *pack = NULL;
226 b61ceafc 2022-10-13 thomas char *path_packfile;
227 b61ceafc 2022-10-13 thomas
228 b61ceafc 2022-10-13 thomas *base_size = 0;
229 b61ceafc 2022-10-13 thomas *result_size = 0;
230 b61ceafc 2022-10-13 thomas *delta_size = 0;
231 b61ceafc 2022-10-13 thomas *delta_compressed_size = 0;
232 b61ceafc 2022-10-13 thomas *delta_offset = 0;
233 b61ceafc 2022-10-13 thomas *delta_out_offset = 0;
234 b61ceafc 2022-10-13 thomas
235 b61ceafc 2022-10-13 thomas err = got_packidx_get_packfile_path(&path_packfile,
236 b61ceafc 2022-10-13 thomas packidx->path_packidx);
237 b61ceafc 2022-10-13 thomas if (err)
238 b61ceafc 2022-10-13 thomas return err;
239 b61ceafc 2022-10-13 thomas
240 b61ceafc 2022-10-13 thomas pack = got_repo_get_cached_pack(repo, path_packfile);
241 b61ceafc 2022-10-13 thomas if (pack == NULL) {
242 b61ceafc 2022-10-13 thomas err = got_repo_cache_pack(&pack, repo, path_packfile, packidx);
243 b61ceafc 2022-10-13 thomas if (err)
244 b61ceafc 2022-10-13 thomas return err;
245 b61ceafc 2022-10-13 thomas }
246 b61ceafc 2022-10-13 thomas
247 b61ceafc 2022-10-13 thomas if (pack->privsep_child == NULL) {
248 b61ceafc 2022-10-13 thomas err = got_pack_start_privsep_child(pack, packidx);
249 b61ceafc 2022-10-13 thomas if (err)
250 b61ceafc 2022-10-13 thomas return err;
251 b61ceafc 2022-10-13 thomas }
252 b61ceafc 2022-10-13 thomas
253 b61ceafc 2022-10-13 thomas if (!pack->child_has_delta_outfd) {
254 b61ceafc 2022-10-13 thomas int outfd_child;
255 b61ceafc 2022-10-13 thomas outfd_child = dup(delta_cache_fd);
256 b61ceafc 2022-10-13 thomas if (outfd_child == -1)
257 b61ceafc 2022-10-13 thomas return got_error_from_errno("dup");
258 b61ceafc 2022-10-13 thomas err = got_privsep_send_raw_delta_outfd(
259 b61ceafc 2022-10-13 thomas pack->privsep_child->ibuf, outfd_child);
260 b61ceafc 2022-10-13 thomas if (err)
261 b61ceafc 2022-10-13 thomas return err;
262 b61ceafc 2022-10-13 thomas pack->child_has_delta_outfd = 1;
263 b61ceafc 2022-10-13 thomas }
264 b61ceafc 2022-10-13 thomas
265 b61ceafc 2022-10-13 thomas err = got_privsep_send_raw_delta_req(pack->privsep_child->ibuf,
266 b61ceafc 2022-10-13 thomas obj_idx, id);
267 b61ceafc 2022-10-13 thomas if (err)
268 b61ceafc 2022-10-13 thomas return err;
269 b61ceafc 2022-10-13 thomas
270 b61ceafc 2022-10-13 thomas return got_privsep_recv_raw_delta(base_size, result_size, delta_size,
271 b61ceafc 2022-10-13 thomas delta_compressed_size, delta_offset, delta_out_offset, base_id,
272 b61ceafc 2022-10-13 thomas pack->privsep_child->ibuf);
273 b61ceafc 2022-10-13 thomas }
274 b61ceafc 2022-10-13 thomas
275 b61ceafc 2022-10-13 thomas static const struct got_error *
276 b61ceafc 2022-10-13 thomas request_object(struct got_object **obj, struct got_object_id *id,
277 b61ceafc 2022-10-13 thomas struct got_repository *repo, int fd)
278 b61ceafc 2022-10-13 thomas {
279 b61ceafc 2022-10-13 thomas const struct got_error *err = NULL;
280 b61ceafc 2022-10-13 thomas struct imsgbuf *ibuf;
281 b61ceafc 2022-10-13 thomas
282 b61ceafc 2022-10-13 thomas ibuf = repo->privsep_children[GOT_REPO_PRIVSEP_CHILD_OBJECT].ibuf;
283 b61ceafc 2022-10-13 thomas
284 b61ceafc 2022-10-13 thomas err = got_privsep_send_obj_req(ibuf, fd, id);
285 b61ceafc 2022-10-13 thomas if (err)
286 b61ceafc 2022-10-13 thomas return err;
287 b61ceafc 2022-10-13 thomas
288 b61ceafc 2022-10-13 thomas return got_privsep_recv_obj(obj, ibuf);
289 b61ceafc 2022-10-13 thomas }
290 b61ceafc 2022-10-13 thomas
291 b61ceafc 2022-10-13 thomas static const struct got_error *
292 b61ceafc 2022-10-13 thomas request_raw_object(uint8_t **outbuf, off_t *size, size_t *hdrlen, int outfd,
293 b61ceafc 2022-10-13 thomas struct got_object_id *id, struct got_repository *repo, int infd)
294 b61ceafc 2022-10-13 thomas {
295 b61ceafc 2022-10-13 thomas const struct got_error *err = NULL;
296 b61ceafc 2022-10-13 thomas struct imsgbuf *ibuf;
297 b61ceafc 2022-10-13 thomas int outfd_child;
298 b61ceafc 2022-10-13 thomas
299 b61ceafc 2022-10-13 thomas ibuf = repo->privsep_children[GOT_REPO_PRIVSEP_CHILD_OBJECT].ibuf;
300 b61ceafc 2022-10-13 thomas
301 b61ceafc 2022-10-13 thomas outfd_child = dup(outfd);
302 b61ceafc 2022-10-13 thomas if (outfd_child == -1)
303 b61ceafc 2022-10-13 thomas return got_error_from_errno("dup");
304 b61ceafc 2022-10-13 thomas
305 b61ceafc 2022-10-13 thomas err = got_privsep_send_raw_obj_req(ibuf, infd, id);
306 b61ceafc 2022-10-13 thomas if (err)
307 b61ceafc 2022-10-13 thomas return err;
308 b61ceafc 2022-10-13 thomas
309 b61ceafc 2022-10-13 thomas err = got_privsep_send_raw_obj_outfd(ibuf, outfd_child);
310 b61ceafc 2022-10-13 thomas if (err)
311 b61ceafc 2022-10-13 thomas return err;
312 b61ceafc 2022-10-13 thomas
313 b61ceafc 2022-10-13 thomas return got_privsep_recv_raw_obj(outbuf, size, hdrlen, ibuf);
314 b61ceafc 2022-10-13 thomas }
315 b61ceafc 2022-10-13 thomas
316 b61ceafc 2022-10-13 thomas static const struct got_error *
317 54c22772 2022-10-13 thomas start_child(struct got_repository *repo, int type)
318 b61ceafc 2022-10-13 thomas {
319 b61ceafc 2022-10-13 thomas const struct got_error *err = NULL;
320 b61ceafc 2022-10-13 thomas int imsg_fds[2];
321 b61ceafc 2022-10-13 thomas pid_t pid;
322 b61ceafc 2022-10-13 thomas struct imsgbuf *ibuf;
323 54c22772 2022-10-13 thomas const char *prog_path;
324 54c22772 2022-10-13 thomas
325 54c22772 2022-10-13 thomas switch (type) {
326 54c22772 2022-10-13 thomas case GOT_REPO_PRIVSEP_CHILD_OBJECT:
327 54c22772 2022-10-13 thomas prog_path = GOT_PATH_PROG_READ_OBJECT;
328 54c22772 2022-10-13 thomas break;
329 54c22772 2022-10-13 thomas case GOT_REPO_PRIVSEP_CHILD_TREE:
330 54c22772 2022-10-13 thomas prog_path = GOT_PATH_PROG_READ_TREE;
331 54c22772 2022-10-13 thomas break;
332 54c22772 2022-10-13 thomas case GOT_REPO_PRIVSEP_CHILD_COMMIT:
333 54c22772 2022-10-13 thomas prog_path = GOT_PATH_PROG_READ_COMMIT;
334 54c22772 2022-10-13 thomas break;
335 54c22772 2022-10-13 thomas case GOT_REPO_PRIVSEP_CHILD_BLOB:
336 54c22772 2022-10-13 thomas prog_path = GOT_PATH_PROG_READ_BLOB;
337 54c22772 2022-10-13 thomas break;
338 54c22772 2022-10-13 thomas case GOT_REPO_PRIVSEP_CHILD_TAG:
339 54c22772 2022-10-13 thomas prog_path = GOT_PATH_PROG_READ_TAG;
340 54c22772 2022-10-13 thomas break;
341 54c22772 2022-10-13 thomas default:
342 54c22772 2022-10-13 thomas return got_error(GOT_ERR_OBJ_TYPE);
343 54c22772 2022-10-13 thomas }
344 b61ceafc 2022-10-13 thomas
345 b61ceafc 2022-10-13 thomas ibuf = calloc(1, sizeof(*ibuf));
346 b61ceafc 2022-10-13 thomas if (ibuf == NULL)
347 b61ceafc 2022-10-13 thomas return got_error_from_errno("calloc");
348 b61ceafc 2022-10-13 thomas
349 b61ceafc 2022-10-13 thomas if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, imsg_fds) == -1) {
350 b61ceafc 2022-10-13 thomas err = got_error_from_errno("socketpair");
351 b61ceafc 2022-10-13 thomas free(ibuf);
352 b61ceafc 2022-10-13 thomas return err;
353 b61ceafc 2022-10-13 thomas }
354 b61ceafc 2022-10-13 thomas
355 b61ceafc 2022-10-13 thomas pid = fork();
356 b61ceafc 2022-10-13 thomas if (pid == -1) {
357 b61ceafc 2022-10-13 thomas err = got_error_from_errno("fork");
358 b61ceafc 2022-10-13 thomas free(ibuf);
359 b61ceafc 2022-10-13 thomas return err;
360 b61ceafc 2022-10-13 thomas }
361 b61ceafc 2022-10-13 thomas else if (pid == 0) {
362 54c22772 2022-10-13 thomas got_privsep_exec_child(imsg_fds, prog_path, repo->path);
363 b61ceafc 2022-10-13 thomas /* not reached */
364 b61ceafc 2022-10-13 thomas }
365 b61ceafc 2022-10-13 thomas
366 b61ceafc 2022-10-13 thomas if (close(imsg_fds[1]) == -1) {
367 b61ceafc 2022-10-13 thomas err = got_error_from_errno("close");
368 b61ceafc 2022-10-13 thomas free(ibuf);
369 b61ceafc 2022-10-13 thomas return err;
370 b61ceafc 2022-10-13 thomas }
371 b61ceafc 2022-10-13 thomas
372 54c22772 2022-10-13 thomas repo->privsep_children[type].imsg_fd = imsg_fds[0];
373 54c22772 2022-10-13 thomas repo->privsep_children[type].pid = pid;
374 b61ceafc 2022-10-13 thomas imsg_init(ibuf, imsg_fds[0]);
375 54c22772 2022-10-13 thomas repo->privsep_children[type].ibuf = ibuf;
376 b61ceafc 2022-10-13 thomas
377 b61ceafc 2022-10-13 thomas return NULL;
378 b61ceafc 2022-10-13 thomas }
379 b61ceafc 2022-10-13 thomas
380 b61ceafc 2022-10-13 thomas const struct got_error *
381 b61ceafc 2022-10-13 thomas got_object_read_header_privsep(struct got_object **obj,
382 b61ceafc 2022-10-13 thomas struct got_object_id *id, struct got_repository *repo, int obj_fd)
383 b61ceafc 2022-10-13 thomas {
384 b61ceafc 2022-10-13 thomas const struct got_error *err;
385 b61ceafc 2022-10-13 thomas
386 b61ceafc 2022-10-13 thomas if (repo->privsep_children[GOT_REPO_PRIVSEP_CHILD_OBJECT].imsg_fd != -1)
387 b61ceafc 2022-10-13 thomas return request_object(obj, id, repo, obj_fd);
388 b61ceafc 2022-10-13 thomas
389 54c22772 2022-10-13 thomas err = start_child(repo, GOT_REPO_PRIVSEP_CHILD_OBJECT);
390 54c22772 2022-10-13 thomas if (err)
391 b61ceafc 2022-10-13 thomas return err;
392 b61ceafc 2022-10-13 thomas
393 b61ceafc 2022-10-13 thomas return request_object(obj, id, repo, obj_fd);
394 b61ceafc 2022-10-13 thomas }
395 b61ceafc 2022-10-13 thomas
396 b61ceafc 2022-10-13 thomas static const struct got_error *
397 b61ceafc 2022-10-13 thomas read_object_raw_privsep(uint8_t **outbuf, off_t *size, size_t *hdrlen,
398 b61ceafc 2022-10-13 thomas int outfd, struct got_object_id *id, struct got_repository *repo,
399 b61ceafc 2022-10-13 thomas int obj_fd)
400 b61ceafc 2022-10-13 thomas {
401 b61ceafc 2022-10-13 thomas const struct got_error *err;
402 b61ceafc 2022-10-13 thomas
403 b61ceafc 2022-10-13 thomas if (repo->privsep_children[GOT_REPO_PRIVSEP_CHILD_OBJECT].imsg_fd != -1)
404 b61ceafc 2022-10-13 thomas return request_raw_object(outbuf, size, hdrlen, outfd, id,
405 b61ceafc 2022-10-13 thomas repo, obj_fd);
406 b61ceafc 2022-10-13 thomas
407 54c22772 2022-10-13 thomas err = start_child(repo, GOT_REPO_PRIVSEP_CHILD_OBJECT);
408 b61ceafc 2022-10-13 thomas if (err)
409 b61ceafc 2022-10-13 thomas return err;
410 b61ceafc 2022-10-13 thomas
411 b61ceafc 2022-10-13 thomas return request_raw_object(outbuf, size, hdrlen, outfd, id, repo,
412 b61ceafc 2022-10-13 thomas obj_fd);
413 b61ceafc 2022-10-13 thomas }
414 b61ceafc 2022-10-13 thomas
415 b61ceafc 2022-10-13 thomas const struct got_error *
416 b61ceafc 2022-10-13 thomas got_object_open(struct got_object **obj, struct got_repository *repo,
417 b61ceafc 2022-10-13 thomas struct got_object_id *id)
418 b61ceafc 2022-10-13 thomas {
419 b61ceafc 2022-10-13 thomas const struct got_error *err = NULL;
420 b61ceafc 2022-10-13 thomas int fd;
421 b61ceafc 2022-10-13 thomas
422 b61ceafc 2022-10-13 thomas *obj = got_repo_get_cached_object(repo, id);
423 b61ceafc 2022-10-13 thomas if (*obj != NULL) {
424 b61ceafc 2022-10-13 thomas (*obj)->refcnt++;
425 b61ceafc 2022-10-13 thomas return NULL;
426 b61ceafc 2022-10-13 thomas }
427 b61ceafc 2022-10-13 thomas
428 b61ceafc 2022-10-13 thomas err = got_object_open_packed(obj, id, repo);
429 b61ceafc 2022-10-13 thomas if (err && err->code != GOT_ERR_NO_OBJ)
430 b61ceafc 2022-10-13 thomas return err;
431 b61ceafc 2022-10-13 thomas if (*obj) {
432 b61ceafc 2022-10-13 thomas (*obj)->refcnt++;
433 b61ceafc 2022-10-13 thomas return got_repo_cache_object(repo, id, *obj);
434 b61ceafc 2022-10-13 thomas }
435 b61ceafc 2022-10-13 thomas
436 b61ceafc 2022-10-13 thomas err = got_object_open_loose_fd(&fd, id, repo);
437 b61ceafc 2022-10-13 thomas if (err) {
438 b61ceafc 2022-10-13 thomas if (err->code == GOT_ERR_ERRNO && errno == ENOENT)
439 b61ceafc 2022-10-13 thomas err = got_error_no_obj(id);
440 b61ceafc 2022-10-13 thomas return err;
441 b61ceafc 2022-10-13 thomas }
442 b61ceafc 2022-10-13 thomas
443 b61ceafc 2022-10-13 thomas err = got_object_read_header_privsep(obj, id, repo, fd);
444 b61ceafc 2022-10-13 thomas if (err)
445 b61ceafc 2022-10-13 thomas return err;
446 b61ceafc 2022-10-13 thomas
447 b61ceafc 2022-10-13 thomas memcpy((*obj)->id.sha1, id->sha1, SHA1_DIGEST_LENGTH);
448 b61ceafc 2022-10-13 thomas
449 b61ceafc 2022-10-13 thomas (*obj)->refcnt++;
450 b61ceafc 2022-10-13 thomas return got_repo_cache_object(repo, id, *obj);
451 b61ceafc 2022-10-13 thomas }
452 b61ceafc 2022-10-13 thomas
453 b61ceafc 2022-10-13 thomas /* *outfd must be initialized to -1 by caller */
454 b61ceafc 2022-10-13 thomas const struct got_error *
455 b61ceafc 2022-10-13 thomas got_object_raw_open(struct got_raw_object **obj, int *outfd,
456 b61ceafc 2022-10-13 thomas struct got_repository *repo, struct got_object_id *id)
457 b61ceafc 2022-10-13 thomas {
458 b61ceafc 2022-10-13 thomas const struct got_error *err = NULL;
459 b61ceafc 2022-10-13 thomas struct got_packidx *packidx = NULL;
460 b61ceafc 2022-10-13 thomas int idx;
461 b61ceafc 2022-10-13 thomas uint8_t *outbuf = NULL;
462 b61ceafc 2022-10-13 thomas off_t size = 0;
463 b61ceafc 2022-10-13 thomas size_t hdrlen = 0;
464 b61ceafc 2022-10-13 thomas char *path_packfile = NULL;
465 b61ceafc 2022-10-13 thomas
466 b61ceafc 2022-10-13 thomas *obj = got_repo_get_cached_raw_object(repo, id);
467 b61ceafc 2022-10-13 thomas if (*obj != NULL) {
468 b61ceafc 2022-10-13 thomas (*obj)->refcnt++;
469 b61ceafc 2022-10-13 thomas return NULL;
470 b61ceafc 2022-10-13 thomas }
471 b61ceafc 2022-10-13 thomas
472 b61ceafc 2022-10-13 thomas if (*outfd == -1) {
473 b61ceafc 2022-10-13 thomas *outfd = got_opentempfd();
474 b61ceafc 2022-10-13 thomas if (*outfd == -1)
475 b61ceafc 2022-10-13 thomas return got_error_from_errno("got_opentempfd");
476 b61ceafc 2022-10-13 thomas }
477 b61ceafc 2022-10-13 thomas
478 b61ceafc 2022-10-13 thomas err = got_repo_search_packidx(&packidx, &idx, repo, id);
479 b61ceafc 2022-10-13 thomas if (err == NULL) {
480 b61ceafc 2022-10-13 thomas struct got_pack *pack = NULL;
481 b61ceafc 2022-10-13 thomas
482 b61ceafc 2022-10-13 thomas err = got_packidx_get_packfile_path(&path_packfile,
483 b61ceafc 2022-10-13 thomas packidx->path_packidx);
484 b61ceafc 2022-10-13 thomas if (err)
485 b61ceafc 2022-10-13 thomas goto done;
486 b61ceafc 2022-10-13 thomas
487 b61ceafc 2022-10-13 thomas pack = got_repo_get_cached_pack(repo, path_packfile);
488 b61ceafc 2022-10-13 thomas if (pack == NULL) {
489 b61ceafc 2022-10-13 thomas err = got_repo_cache_pack(&pack, repo, path_packfile,
490 b61ceafc 2022-10-13 thomas packidx);
491 b61ceafc 2022-10-13 thomas if (err)
492 b61ceafc 2022-10-13 thomas goto done;
493 b61ceafc 2022-10-13 thomas }
494 b61ceafc 2022-10-13 thomas err = read_packed_object_raw_privsep(&outbuf, &size, &hdrlen,
495 b61ceafc 2022-10-13 thomas *outfd, pack, packidx, idx, id);
496 b61ceafc 2022-10-13 thomas if (err)
497 b61ceafc 2022-10-13 thomas goto done;
498 b61ceafc 2022-10-13 thomas } else if (err->code == GOT_ERR_NO_OBJ) {
499 b61ceafc 2022-10-13 thomas int fd;
500 b61ceafc 2022-10-13 thomas
501 b61ceafc 2022-10-13 thomas err = got_object_open_loose_fd(&fd, id, repo);
502 b61ceafc 2022-10-13 thomas if (err)
503 b61ceafc 2022-10-13 thomas goto done;
504 b61ceafc 2022-10-13 thomas err = read_object_raw_privsep(&outbuf, &size, &hdrlen, *outfd,
505 b61ceafc 2022-10-13 thomas id, repo, fd);
506 b61ceafc 2022-10-13 thomas if (err)
507 b61ceafc 2022-10-13 thomas goto done;
508 b61ceafc 2022-10-13 thomas }
509 b61ceafc 2022-10-13 thomas
510 b61ceafc 2022-10-13 thomas *obj = calloc(1, sizeof(**obj));
511 b61ceafc 2022-10-13 thomas if (*obj == NULL) {
512 b61ceafc 2022-10-13 thomas err = got_error_from_errno("calloc");
513 b61ceafc 2022-10-13 thomas goto done;
514 b61ceafc 2022-10-13 thomas }
515 b61ceafc 2022-10-13 thomas (*obj)->fd = -1;
516 b61ceafc 2022-10-13 thomas
517 b61ceafc 2022-10-13 thomas if (outbuf) {
518 b61ceafc 2022-10-13 thomas (*obj)->data = outbuf;
519 b61ceafc 2022-10-13 thomas } else {
520 b61ceafc 2022-10-13 thomas struct stat sb;
521 b61ceafc 2022-10-13 thomas if (fstat(*outfd, &sb) == -1) {
522 b61ceafc 2022-10-13 thomas err = got_error_from_errno("fstat");
523 b61ceafc 2022-10-13 thomas goto done;
524 b61ceafc 2022-10-13 thomas }
525 b61ceafc 2022-10-13 thomas
526 b61ceafc 2022-10-13 thomas if (sb.st_size != hdrlen + size) {
527 b61ceafc 2022-10-13 thomas err = got_error(GOT_ERR_PRIVSEP_LEN);
528 b61ceafc 2022-10-13 thomas goto done;
529 b61ceafc 2022-10-13 thomas }
530 b61ceafc 2022-10-13 thomas #ifndef GOT_PACK_NO_MMAP
531 b61ceafc 2022-10-13 thomas if (hdrlen + size > 0) {
532 b61ceafc 2022-10-13 thomas (*obj)->data = mmap(NULL, hdrlen + size, PROT_READ,
533 b61ceafc 2022-10-13 thomas MAP_PRIVATE, *outfd, 0);
534 b61ceafc 2022-10-13 thomas if ((*obj)->data == MAP_FAILED) {
535 b61ceafc 2022-10-13 thomas if (errno != ENOMEM) {
536 b61ceafc 2022-10-13 thomas err = got_error_from_errno("mmap");
537 b61ceafc 2022-10-13 thomas goto done;
538 b61ceafc 2022-10-13 thomas }
539 b61ceafc 2022-10-13 thomas (*obj)->data = NULL;
540 b61ceafc 2022-10-13 thomas } else {
541 b61ceafc 2022-10-13 thomas (*obj)->fd = *outfd;
542 b61ceafc 2022-10-13 thomas *outfd = -1;
543 b61ceafc 2022-10-13 thomas }
544 b61ceafc 2022-10-13 thomas }
545 b61ceafc 2022-10-13 thomas #endif
546 b61ceafc 2022-10-13 thomas if (*outfd != -1) {
547 b61ceafc 2022-10-13 thomas (*obj)->f = fdopen(*outfd, "r");
548 b61ceafc 2022-10-13 thomas if ((*obj)->f == NULL) {
549 b61ceafc 2022-10-13 thomas err = got_error_from_errno("fdopen");
550 b61ceafc 2022-10-13 thomas goto done;
551 b61ceafc 2022-10-13 thomas }
552 b61ceafc 2022-10-13 thomas *outfd = -1;
553 b61ceafc 2022-10-13 thomas }
554 b61ceafc 2022-10-13 thomas }
555 b61ceafc 2022-10-13 thomas (*obj)->hdrlen = hdrlen;
556 b61ceafc 2022-10-13 thomas (*obj)->size = size;
557 b61ceafc 2022-10-13 thomas err = got_repo_cache_raw_object(repo, id, *obj);
558 b61ceafc 2022-10-13 thomas done:
559 b61ceafc 2022-10-13 thomas free(path_packfile);
560 b61ceafc 2022-10-13 thomas if (err) {
561 b61ceafc 2022-10-13 thomas if (*obj) {
562 b61ceafc 2022-10-13 thomas got_object_raw_close(*obj);
563 b61ceafc 2022-10-13 thomas *obj = NULL;
564 b61ceafc 2022-10-13 thomas }
565 b61ceafc 2022-10-13 thomas free(outbuf);
566 b61ceafc 2022-10-13 thomas } else
567 b61ceafc 2022-10-13 thomas (*obj)->refcnt++;
568 b61ceafc 2022-10-13 thomas return err;
569 b61ceafc 2022-10-13 thomas }
570 b61ceafc 2022-10-13 thomas
571 b61ceafc 2022-10-13 thomas static const struct got_error *
572 b61ceafc 2022-10-13 thomas request_packed_commit(struct got_commit_object **commit, struct got_pack *pack,
573 b61ceafc 2022-10-13 thomas int pack_idx, struct got_object_id *id)
574 b61ceafc 2022-10-13 thomas {
575 b61ceafc 2022-10-13 thomas const struct got_error *err = NULL;
576 b61ceafc 2022-10-13 thomas
577 b61ceafc 2022-10-13 thomas err = got_privsep_send_commit_req(pack->privsep_child->ibuf, -1, id,
578 b61ceafc 2022-10-13 thomas pack_idx);
579 b61ceafc 2022-10-13 thomas if (err)
580 b61ceafc 2022-10-13 thomas return err;
581 b61ceafc 2022-10-13 thomas
582 b61ceafc 2022-10-13 thomas err = got_privsep_recv_commit(commit, pack->privsep_child->ibuf);
583 b61ceafc 2022-10-13 thomas if (err)
584 b61ceafc 2022-10-13 thomas return err;
585 b61ceafc 2022-10-13 thomas
586 b61ceafc 2022-10-13 thomas (*commit)->flags |= GOT_COMMIT_FLAG_PACKED;
587 b61ceafc 2022-10-13 thomas return NULL;
588 b61ceafc 2022-10-13 thomas }
589 b61ceafc 2022-10-13 thomas
590 b61ceafc 2022-10-13 thomas static const struct got_error *
591 b61ceafc 2022-10-13 thomas read_packed_commit_privsep(struct got_commit_object **commit,
592 b61ceafc 2022-10-13 thomas struct got_pack *pack, struct got_packidx *packidx, int idx,
593 b61ceafc 2022-10-13 thomas struct got_object_id *id)
594 b61ceafc 2022-10-13 thomas {
595 b61ceafc 2022-10-13 thomas const struct got_error *err = NULL;
596 b61ceafc 2022-10-13 thomas
597 b61ceafc 2022-10-13 thomas if (pack->privsep_child)
598 b61ceafc 2022-10-13 thomas return request_packed_commit(commit, pack, idx, id);
599 b61ceafc 2022-10-13 thomas
600 b61ceafc 2022-10-13 thomas err = got_pack_start_privsep_child(pack, packidx);
601 b61ceafc 2022-10-13 thomas if (err)
602 b61ceafc 2022-10-13 thomas return err;
603 b61ceafc 2022-10-13 thomas
604 b61ceafc 2022-10-13 thomas return request_packed_commit(commit, pack, idx, id);
605 b61ceafc 2022-10-13 thomas }
606 b61ceafc 2022-10-13 thomas
607 b61ceafc 2022-10-13 thomas static const struct got_error *
608 b61ceafc 2022-10-13 thomas request_commit(struct got_commit_object **commit, struct got_repository *repo,
609 b61ceafc 2022-10-13 thomas int fd, struct got_object_id *id)
610 b61ceafc 2022-10-13 thomas {
611 b61ceafc 2022-10-13 thomas const struct got_error *err = NULL;
612 b61ceafc 2022-10-13 thomas struct imsgbuf *ibuf;
613 b61ceafc 2022-10-13 thomas
614 b61ceafc 2022-10-13 thomas ibuf = repo->privsep_children[GOT_REPO_PRIVSEP_CHILD_COMMIT].ibuf;
615 b61ceafc 2022-10-13 thomas
616 b61ceafc 2022-10-13 thomas err = got_privsep_send_commit_req(ibuf, fd, id, -1);
617 b61ceafc 2022-10-13 thomas if (err)
618 b61ceafc 2022-10-13 thomas return err;
619 b61ceafc 2022-10-13 thomas
620 b61ceafc 2022-10-13 thomas return got_privsep_recv_commit(commit, ibuf);
621 b61ceafc 2022-10-13 thomas }
622 b61ceafc 2022-10-13 thomas
623 b61ceafc 2022-10-13 thomas static const struct got_error *
624 b61ceafc 2022-10-13 thomas read_commit_privsep(struct got_commit_object **commit, int obj_fd,
625 b61ceafc 2022-10-13 thomas struct got_object_id *id, struct got_repository *repo)
626 b61ceafc 2022-10-13 thomas {
627 b61ceafc 2022-10-13 thomas const struct got_error *err;
628 b61ceafc 2022-10-13 thomas
629 b61ceafc 2022-10-13 thomas if (repo->privsep_children[GOT_REPO_PRIVSEP_CHILD_COMMIT].imsg_fd != -1)
630 b61ceafc 2022-10-13 thomas return request_commit(commit, repo, obj_fd, id);
631 b61ceafc 2022-10-13 thomas
632 54c22772 2022-10-13 thomas err = start_child(repo, GOT_REPO_PRIVSEP_CHILD_COMMIT);
633 54c22772 2022-10-13 thomas if (err)
634 b61ceafc 2022-10-13 thomas return err;
635 b61ceafc 2022-10-13 thomas
636 b61ceafc 2022-10-13 thomas return request_commit(commit, repo, obj_fd, id);
637 b61ceafc 2022-10-13 thomas }
638 b61ceafc 2022-10-13 thomas
639 b61ceafc 2022-10-13 thomas static const struct got_error *
640 b61ceafc 2022-10-13 thomas open_commit(struct got_commit_object **commit,
641 b61ceafc 2022-10-13 thomas struct got_repository *repo, struct got_object_id *id, int check_cache)
642 b61ceafc 2022-10-13 thomas {
643 b61ceafc 2022-10-13 thomas const struct got_error *err = NULL;
644 b61ceafc 2022-10-13 thomas struct got_packidx *packidx = NULL;
645 b61ceafc 2022-10-13 thomas int idx;
646 b61ceafc 2022-10-13 thomas char *path_packfile = NULL;
647 b61ceafc 2022-10-13 thomas
648 b61ceafc 2022-10-13 thomas if (check_cache) {
649 b61ceafc 2022-10-13 thomas *commit = got_repo_get_cached_commit(repo, id);
650 b61ceafc 2022-10-13 thomas if (*commit != NULL) {
651 b61ceafc 2022-10-13 thomas (*commit)->refcnt++;
652 b61ceafc 2022-10-13 thomas return NULL;
653 b61ceafc 2022-10-13 thomas }
654 b61ceafc 2022-10-13 thomas } else
655 b61ceafc 2022-10-13 thomas *commit = NULL;
656 b61ceafc 2022-10-13 thomas
657 b61ceafc 2022-10-13 thomas err = got_repo_search_packidx(&packidx, &idx, repo, id);
658 b61ceafc 2022-10-13 thomas if (err == NULL) {
659 b61ceafc 2022-10-13 thomas struct got_pack *pack = NULL;
660 b61ceafc 2022-10-13 thomas
661 b61ceafc 2022-10-13 thomas err = got_packidx_get_packfile_path(&path_packfile,
662 b61ceafc 2022-10-13 thomas packidx->path_packidx);
663 b61ceafc 2022-10-13 thomas if (err)
664 b61ceafc 2022-10-13 thomas return err;
665 b61ceafc 2022-10-13 thomas
666 b61ceafc 2022-10-13 thomas pack = got_repo_get_cached_pack(repo, path_packfile);
667 b61ceafc 2022-10-13 thomas if (pack == NULL) {
668 b61ceafc 2022-10-13 thomas err = got_repo_cache_pack(&pack, repo, path_packfile,
669 b61ceafc 2022-10-13 thomas packidx);
670 b61ceafc 2022-10-13 thomas if (err)
671 b61ceafc 2022-10-13 thomas goto done;
672 b61ceafc 2022-10-13 thomas }
673 b61ceafc 2022-10-13 thomas err = read_packed_commit_privsep(commit, pack,
674 b61ceafc 2022-10-13 thomas packidx, idx, id);
675 b61ceafc 2022-10-13 thomas } else if (err->code == GOT_ERR_NO_OBJ) {
676 b61ceafc 2022-10-13 thomas int fd;
677 b61ceafc 2022-10-13 thomas
678 b61ceafc 2022-10-13 thomas err = got_object_open_loose_fd(&fd, id, repo);
679 b61ceafc 2022-10-13 thomas if (err)
680 b61ceafc 2022-10-13 thomas return err;
681 b61ceafc 2022-10-13 thomas err = read_commit_privsep(commit, fd, id, repo);
682 b61ceafc 2022-10-13 thomas }
683 b61ceafc 2022-10-13 thomas
684 b61ceafc 2022-10-13 thomas if (err == NULL) {
685 b61ceafc 2022-10-13 thomas (*commit)->refcnt++;
686 b61ceafc 2022-10-13 thomas err = got_repo_cache_commit(repo, id, *commit);
687 b61ceafc 2022-10-13 thomas }
688 b61ceafc 2022-10-13 thomas done:
689 b61ceafc 2022-10-13 thomas free(path_packfile);
690 b61ceafc 2022-10-13 thomas return err;
691 b61ceafc 2022-10-13 thomas }
692 b61ceafc 2022-10-13 thomas
693 b61ceafc 2022-10-13 thomas const struct got_error *
694 b61ceafc 2022-10-13 thomas got_object_open_as_commit(struct got_commit_object **commit,
695 b61ceafc 2022-10-13 thomas struct got_repository *repo, struct got_object_id *id)
696 b61ceafc 2022-10-13 thomas {
697 b61ceafc 2022-10-13 thomas *commit = got_repo_get_cached_commit(repo, id);
698 b61ceafc 2022-10-13 thomas if (*commit != NULL) {
699 b61ceafc 2022-10-13 thomas (*commit)->refcnt++;
700 b61ceafc 2022-10-13 thomas return NULL;
701 b61ceafc 2022-10-13 thomas }
702 b61ceafc 2022-10-13 thomas
703 b61ceafc 2022-10-13 thomas return open_commit(commit, repo, id, 0);
704 b61ceafc 2022-10-13 thomas }
705 b61ceafc 2022-10-13 thomas
706 b61ceafc 2022-10-13 thomas const struct got_error *
707 b61ceafc 2022-10-13 thomas got_object_commit_open(struct got_commit_object **commit,
708 b61ceafc 2022-10-13 thomas struct got_repository *repo, struct got_object *obj)
709 b61ceafc 2022-10-13 thomas {
710 b61ceafc 2022-10-13 thomas return open_commit(commit, repo, got_object_get_id(obj), 1);
711 b61ceafc 2022-10-13 thomas }
712 b61ceafc 2022-10-13 thomas
713 b61ceafc 2022-10-13 thomas static const struct got_error *
714 b61ceafc 2022-10-13 thomas request_packed_tree(struct got_tree_object **tree, struct got_pack *pack,
715 b61ceafc 2022-10-13 thomas int pack_idx, struct got_object_id *id)
716 b61ceafc 2022-10-13 thomas {
717 b61ceafc 2022-10-13 thomas const struct got_error *err = NULL;
718 b61ceafc 2022-10-13 thomas
719 b61ceafc 2022-10-13 thomas err = got_privsep_send_tree_req(pack->privsep_child->ibuf, -1, id,
720 b61ceafc 2022-10-13 thomas pack_idx);
721 b61ceafc 2022-10-13 thomas if (err)
722 b61ceafc 2022-10-13 thomas return err;
723 b61ceafc 2022-10-13 thomas
724 b61ceafc 2022-10-13 thomas return got_privsep_recv_tree(tree, pack->privsep_child->ibuf);
725 b61ceafc 2022-10-13 thomas }
726 b61ceafc 2022-10-13 thomas
727 b61ceafc 2022-10-13 thomas static const struct got_error *
728 b61ceafc 2022-10-13 thomas read_packed_tree_privsep(struct got_tree_object **tree,
729 b61ceafc 2022-10-13 thomas struct got_pack *pack, struct got_packidx *packidx, int idx,
730 b61ceafc 2022-10-13 thomas struct got_object_id *id)
731 b61ceafc 2022-10-13 thomas {
732 b61ceafc 2022-10-13 thomas const struct got_error *err = NULL;
733 b61ceafc 2022-10-13 thomas
734 b61ceafc 2022-10-13 thomas if (pack->privsep_child)
735 b61ceafc 2022-10-13 thomas return request_packed_tree(tree, pack, idx, id);
736 b61ceafc 2022-10-13 thomas
737 b61ceafc 2022-10-13 thomas err = got_pack_start_privsep_child(pack, packidx);
738 b61ceafc 2022-10-13 thomas if (err)
739 b61ceafc 2022-10-13 thomas return err;
740 b61ceafc 2022-10-13 thomas
741 b61ceafc 2022-10-13 thomas return request_packed_tree(tree, pack, idx, id);
742 b61ceafc 2022-10-13 thomas }
743 b61ceafc 2022-10-13 thomas
744 b61ceafc 2022-10-13 thomas static const struct got_error *
745 b61ceafc 2022-10-13 thomas request_tree(struct got_tree_object **tree, struct got_repository *repo,
746 b61ceafc 2022-10-13 thomas int fd, struct got_object_id *id)
747 b61ceafc 2022-10-13 thomas {
748 b61ceafc 2022-10-13 thomas const struct got_error *err = NULL;
749 b61ceafc 2022-10-13 thomas struct imsgbuf *ibuf;
750 b61ceafc 2022-10-13 thomas
751 b61ceafc 2022-10-13 thomas ibuf = repo->privsep_children[GOT_REPO_PRIVSEP_CHILD_TREE].ibuf;
752 b61ceafc 2022-10-13 thomas
753 b61ceafc 2022-10-13 thomas err = got_privsep_send_tree_req(ibuf, fd, id, -1);
754 b61ceafc 2022-10-13 thomas if (err)
755 b61ceafc 2022-10-13 thomas return err;
756 b61ceafc 2022-10-13 thomas
757 b61ceafc 2022-10-13 thomas return got_privsep_recv_tree(tree, ibuf);
758 b61ceafc 2022-10-13 thomas }
759 b61ceafc 2022-10-13 thomas
760 b61ceafc 2022-10-13 thomas static const struct got_error *
761 b61ceafc 2022-10-13 thomas read_tree_privsep(struct got_tree_object **tree, int obj_fd,
762 b61ceafc 2022-10-13 thomas struct got_object_id *id, struct got_repository *repo)
763 b61ceafc 2022-10-13 thomas {
764 b61ceafc 2022-10-13 thomas const struct got_error *err;
765 b61ceafc 2022-10-13 thomas
766 b61ceafc 2022-10-13 thomas if (repo->privsep_children[GOT_REPO_PRIVSEP_CHILD_TREE].imsg_fd != -1)
767 b61ceafc 2022-10-13 thomas return request_tree(tree, repo, obj_fd, id);
768 b61ceafc 2022-10-13 thomas
769 54c22772 2022-10-13 thomas err = start_child(repo, GOT_REPO_PRIVSEP_CHILD_TREE);
770 54c22772 2022-10-13 thomas if (err)
771 b61ceafc 2022-10-13 thomas return err;
772 b61ceafc 2022-10-13 thomas
773 b61ceafc 2022-10-13 thomas return request_tree(tree, repo, obj_fd, id);
774 b61ceafc 2022-10-13 thomas }
775 b61ceafc 2022-10-13 thomas
776 b61ceafc 2022-10-13 thomas static const struct got_error *
777 b61ceafc 2022-10-13 thomas open_tree(struct got_tree_object **tree, struct got_repository *repo,
778 b61ceafc 2022-10-13 thomas struct got_object_id *id, int check_cache)
779 b61ceafc 2022-10-13 thomas {
780 b61ceafc 2022-10-13 thomas const struct got_error *err = NULL;
781 b61ceafc 2022-10-13 thomas struct got_packidx *packidx = NULL;
782 b61ceafc 2022-10-13 thomas int idx;
783 b61ceafc 2022-10-13 thomas char *path_packfile = NULL;
784 b61ceafc 2022-10-13 thomas
785 b61ceafc 2022-10-13 thomas if (check_cache) {
786 b61ceafc 2022-10-13 thomas *tree = got_repo_get_cached_tree(repo, id);
787 b61ceafc 2022-10-13 thomas if (*tree != NULL) {
788 b61ceafc 2022-10-13 thomas (*tree)->refcnt++;
789 b61ceafc 2022-10-13 thomas return NULL;
790 b61ceafc 2022-10-13 thomas }
791 b61ceafc 2022-10-13 thomas } else
792 b61ceafc 2022-10-13 thomas *tree = NULL;
793 b61ceafc 2022-10-13 thomas
794 b61ceafc 2022-10-13 thomas err = got_repo_search_packidx(&packidx, &idx, repo, id);
795 b61ceafc 2022-10-13 thomas if (err == NULL) {
796 b61ceafc 2022-10-13 thomas struct got_pack *pack = NULL;
797 b61ceafc 2022-10-13 thomas
798 b61ceafc 2022-10-13 thomas err = got_packidx_get_packfile_path(&path_packfile,
799 b61ceafc 2022-10-13 thomas packidx->path_packidx);
800 b61ceafc 2022-10-13 thomas if (err)
801 b61ceafc 2022-10-13 thomas return err;
802 b61ceafc 2022-10-13 thomas
803 b61ceafc 2022-10-13 thomas pack = got_repo_get_cached_pack(repo, path_packfile);
804 b61ceafc 2022-10-13 thomas if (pack == NULL) {
805 b61ceafc 2022-10-13 thomas err = got_repo_cache_pack(&pack, repo, path_packfile,
806 b61ceafc 2022-10-13 thomas packidx);
807 b61ceafc 2022-10-13 thomas if (err)
808 b61ceafc 2022-10-13 thomas goto done;
809 b61ceafc 2022-10-13 thomas }
810 b61ceafc 2022-10-13 thomas err = read_packed_tree_privsep(tree, pack,
811 b61ceafc 2022-10-13 thomas packidx, idx, id);
812 b61ceafc 2022-10-13 thomas } else if (err->code == GOT_ERR_NO_OBJ) {
813 b61ceafc 2022-10-13 thomas int fd;
814 b61ceafc 2022-10-13 thomas
815 b61ceafc 2022-10-13 thomas err = got_object_open_loose_fd(&fd, id, repo);
816 b61ceafc 2022-10-13 thomas if (err)
817 b61ceafc 2022-10-13 thomas return err;
818 b61ceafc 2022-10-13 thomas err = read_tree_privsep(tree, fd, id, repo);
819 b61ceafc 2022-10-13 thomas }
820 b61ceafc 2022-10-13 thomas
821 b61ceafc 2022-10-13 thomas if (err == NULL) {
822 b61ceafc 2022-10-13 thomas (*tree)->refcnt++;
823 b61ceafc 2022-10-13 thomas err = got_repo_cache_tree(repo, id, *tree);
824 b61ceafc 2022-10-13 thomas }
825 b61ceafc 2022-10-13 thomas done:
826 b61ceafc 2022-10-13 thomas free(path_packfile);
827 b61ceafc 2022-10-13 thomas return err;
828 b61ceafc 2022-10-13 thomas }
829 b61ceafc 2022-10-13 thomas
830 b61ceafc 2022-10-13 thomas const struct got_error *
831 b61ceafc 2022-10-13 thomas got_object_open_as_tree(struct got_tree_object **tree,
832 b61ceafc 2022-10-13 thomas struct got_repository *repo, struct got_object_id *id)
833 b61ceafc 2022-10-13 thomas {
834 b61ceafc 2022-10-13 thomas *tree = got_repo_get_cached_tree(repo, id);
835 b61ceafc 2022-10-13 thomas if (*tree != NULL) {
836 b61ceafc 2022-10-13 thomas (*tree)->refcnt++;
837 b61ceafc 2022-10-13 thomas return NULL;
838 b61ceafc 2022-10-13 thomas }
839 b61ceafc 2022-10-13 thomas
840 b61ceafc 2022-10-13 thomas return open_tree(tree, repo, id, 0);
841 b61ceafc 2022-10-13 thomas }
842 b61ceafc 2022-10-13 thomas
843 b61ceafc 2022-10-13 thomas const struct got_error *
844 b61ceafc 2022-10-13 thomas got_object_tree_open(struct got_tree_object **tree,
845 b61ceafc 2022-10-13 thomas struct got_repository *repo, struct got_object *obj)
846 b61ceafc 2022-10-13 thomas {
847 b61ceafc 2022-10-13 thomas return open_tree(tree, repo, got_object_get_id(obj), 1);
848 b61ceafc 2022-10-13 thomas }
849 b61ceafc 2022-10-13 thomas
850 b61ceafc 2022-10-13 thomas static const struct got_error *
851 b61ceafc 2022-10-13 thomas request_packed_blob(uint8_t **outbuf, size_t *size, size_t *hdrlen, int outfd,
852 b61ceafc 2022-10-13 thomas struct got_pack *pack, struct got_packidx *packidx, int idx,
853 b61ceafc 2022-10-13 thomas struct got_object_id *id)
854 b61ceafc 2022-10-13 thomas {
855 b61ceafc 2022-10-13 thomas const struct got_error *err = NULL;
856 b61ceafc 2022-10-13 thomas struct imsgbuf *ibuf = pack->privsep_child->ibuf;
857 b61ceafc 2022-10-13 thomas int outfd_child;
858 b61ceafc 2022-10-13 thomas
859 b61ceafc 2022-10-13 thomas err = pack_child_send_tempfiles(ibuf, pack);
860 b61ceafc 2022-10-13 thomas if (err)
861 b61ceafc 2022-10-13 thomas return err;
862 b61ceafc 2022-10-13 thomas
863 b61ceafc 2022-10-13 thomas outfd_child = dup(outfd);
864 b61ceafc 2022-10-13 thomas if (outfd_child == -1)
865 b61ceafc 2022-10-13 thomas return got_error_from_errno("dup");
866 b61ceafc 2022-10-13 thomas
867 b61ceafc 2022-10-13 thomas err = got_privsep_send_blob_req(pack->privsep_child->ibuf, -1, id, idx);
868 b61ceafc 2022-10-13 thomas if (err)
869 b61ceafc 2022-10-13 thomas return err;
870 b61ceafc 2022-10-13 thomas
871 b61ceafc 2022-10-13 thomas err = got_privsep_send_blob_outfd(pack->privsep_child->ibuf,
872 b61ceafc 2022-10-13 thomas outfd_child);
873 b61ceafc 2022-10-13 thomas if (err) {
874 b61ceafc 2022-10-13 thomas return err;
875 b61ceafc 2022-10-13 thomas }
876 b61ceafc 2022-10-13 thomas
877 b61ceafc 2022-10-13 thomas err = got_privsep_recv_blob(outbuf, size, hdrlen,
878 b61ceafc 2022-10-13 thomas pack->privsep_child->ibuf);
879 b61ceafc 2022-10-13 thomas if (err)
880 b61ceafc 2022-10-13 thomas return err;
881 b61ceafc 2022-10-13 thomas
882 b61ceafc 2022-10-13 thomas if (lseek(outfd, SEEK_SET, 0) == -1)
883 b61ceafc 2022-10-13 thomas err = got_error_from_errno("lseek");
884 b61ceafc 2022-10-13 thomas
885 b61ceafc 2022-10-13 thomas return err;
886 b61ceafc 2022-10-13 thomas }
887 b61ceafc 2022-10-13 thomas
888 b61ceafc 2022-10-13 thomas static const struct got_error *
889 b61ceafc 2022-10-13 thomas read_packed_blob_privsep(uint8_t **outbuf, size_t *size, size_t *hdrlen,
890 b61ceafc 2022-10-13 thomas int outfd, struct got_pack *pack, struct got_packidx *packidx, int idx,
891 b61ceafc 2022-10-13 thomas struct got_object_id *id)
892 b61ceafc 2022-10-13 thomas {
893 b61ceafc 2022-10-13 thomas const struct got_error *err = NULL;
894 b61ceafc 2022-10-13 thomas
895 b61ceafc 2022-10-13 thomas if (pack->privsep_child == NULL) {
896 b61ceafc 2022-10-13 thomas err = got_pack_start_privsep_child(pack, packidx);
897 b61ceafc 2022-10-13 thomas if (err)
898 b61ceafc 2022-10-13 thomas return err;
899 b61ceafc 2022-10-13 thomas }
900 b61ceafc 2022-10-13 thomas
901 b61ceafc 2022-10-13 thomas return request_packed_blob(outbuf, size, hdrlen, outfd, pack, packidx,
902 b61ceafc 2022-10-13 thomas idx, id);
903 b61ceafc 2022-10-13 thomas }
904 b61ceafc 2022-10-13 thomas
905 b61ceafc 2022-10-13 thomas static const struct got_error *
906 b61ceafc 2022-10-13 thomas request_blob(uint8_t **outbuf, size_t *size, size_t *hdrlen, int outfd,
907 b61ceafc 2022-10-13 thomas int infd, struct got_object_id *id, struct imsgbuf *ibuf)
908 b61ceafc 2022-10-13 thomas {
909 b61ceafc 2022-10-13 thomas const struct got_error *err = NULL;
910 b61ceafc 2022-10-13 thomas int outfd_child;
911 b61ceafc 2022-10-13 thomas
912 b61ceafc 2022-10-13 thomas outfd_child = dup(outfd);
913 b61ceafc 2022-10-13 thomas if (outfd_child == -1)
914 b61ceafc 2022-10-13 thomas return got_error_from_errno("dup");
915 b61ceafc 2022-10-13 thomas
916 b61ceafc 2022-10-13 thomas err = got_privsep_send_blob_req(ibuf, infd, id, -1);
917 b61ceafc 2022-10-13 thomas if (err)
918 b61ceafc 2022-10-13 thomas return err;
919 b61ceafc 2022-10-13 thomas
920 b61ceafc 2022-10-13 thomas err = got_privsep_send_blob_outfd(ibuf, outfd_child);
921 b61ceafc 2022-10-13 thomas if (err)
922 b61ceafc 2022-10-13 thomas return err;
923 b61ceafc 2022-10-13 thomas
924 b61ceafc 2022-10-13 thomas err = got_privsep_recv_blob(outbuf, size, hdrlen, ibuf);
925 b61ceafc 2022-10-13 thomas if (err)
926 b61ceafc 2022-10-13 thomas return err;
927 b61ceafc 2022-10-13 thomas
928 b61ceafc 2022-10-13 thomas if (lseek(outfd, SEEK_SET, 0) == -1)
929 b61ceafc 2022-10-13 thomas return got_error_from_errno("lseek");
930 b61ceafc 2022-10-13 thomas
931 b61ceafc 2022-10-13 thomas return err;
932 b61ceafc 2022-10-13 thomas }
933 b61ceafc 2022-10-13 thomas
934 b61ceafc 2022-10-13 thomas static const struct got_error *
935 b61ceafc 2022-10-13 thomas read_blob_privsep(uint8_t **outbuf, size_t *size, size_t *hdrlen,
936 b61ceafc 2022-10-13 thomas int outfd, int infd, struct got_object_id *id, struct got_repository *repo)
937 b61ceafc 2022-10-13 thomas {
938 b61ceafc 2022-10-13 thomas const struct got_error *err;
939 b61ceafc 2022-10-13 thomas struct imsgbuf *ibuf;
940 b61ceafc 2022-10-13 thomas
941 b61ceafc 2022-10-13 thomas if (repo->privsep_children[GOT_REPO_PRIVSEP_CHILD_BLOB].imsg_fd != -1) {
942 b61ceafc 2022-10-13 thomas ibuf = repo->privsep_children[GOT_REPO_PRIVSEP_CHILD_BLOB].ibuf;
943 b61ceafc 2022-10-13 thomas return request_blob(outbuf, size, hdrlen, outfd, infd, id,
944 b61ceafc 2022-10-13 thomas ibuf);
945 b61ceafc 2022-10-13 thomas }
946 b61ceafc 2022-10-13 thomas
947 54c22772 2022-10-13 thomas err = start_child(repo, GOT_REPO_PRIVSEP_CHILD_BLOB);
948 54c22772 2022-10-13 thomas if (err)
949 b61ceafc 2022-10-13 thomas return err;
950 b61ceafc 2022-10-13 thomas
951 54c22772 2022-10-13 thomas ibuf = repo->privsep_children[GOT_REPO_PRIVSEP_CHILD_BLOB].ibuf;
952 b61ceafc 2022-10-13 thomas return request_blob(outbuf, size, hdrlen, outfd, infd, id, ibuf);
953 b61ceafc 2022-10-13 thomas }
954 b61ceafc 2022-10-13 thomas
955 b61ceafc 2022-10-13 thomas static const struct got_error *
956 b61ceafc 2022-10-13 thomas open_blob(struct got_blob_object **blob, struct got_repository *repo,
957 b61ceafc 2022-10-13 thomas struct got_object_id *id, size_t blocksize, int outfd)
958 b61ceafc 2022-10-13 thomas {
959 b61ceafc 2022-10-13 thomas const struct got_error *err = NULL;
960 b61ceafc 2022-10-13 thomas struct got_packidx *packidx = NULL;
961 b61ceafc 2022-10-13 thomas int idx, dfd = -1;
962 b61ceafc 2022-10-13 thomas char *path_packfile = NULL;
963 b61ceafc 2022-10-13 thomas uint8_t *outbuf;
964 b61ceafc 2022-10-13 thomas size_t size, hdrlen;
965 b61ceafc 2022-10-13 thomas struct stat sb;
966 b61ceafc 2022-10-13 thomas
967 b61ceafc 2022-10-13 thomas *blob = calloc(1, sizeof(**blob));
968 b61ceafc 2022-10-13 thomas if (*blob == NULL)
969 b61ceafc 2022-10-13 thomas return got_error_from_errno("calloc");
970 b61ceafc 2022-10-13 thomas
971 b61ceafc 2022-10-13 thomas (*blob)->read_buf = malloc(blocksize);
972 b61ceafc 2022-10-13 thomas if ((*blob)->read_buf == NULL) {
973 b61ceafc 2022-10-13 thomas err = got_error_from_errno("malloc");
974 b61ceafc 2022-10-13 thomas goto done;
975 b61ceafc 2022-10-13 thomas }
976 b61ceafc 2022-10-13 thomas
977 b61ceafc 2022-10-13 thomas if (ftruncate(outfd, 0L) == -1) {
978 b61ceafc 2022-10-13 thomas err = got_error_from_errno("ftruncate");
979 b61ceafc 2022-10-13 thomas goto done;
980 b61ceafc 2022-10-13 thomas }
981 b61ceafc 2022-10-13 thomas if (lseek(outfd, SEEK_SET, 0) == -1) {
982 b61ceafc 2022-10-13 thomas err = got_error_from_errno("lseek");
983 b61ceafc 2022-10-13 thomas goto done;
984 b61ceafc 2022-10-13 thomas }
985 b61ceafc 2022-10-13 thomas
986 b61ceafc 2022-10-13 thomas err = got_repo_search_packidx(&packidx, &idx, repo, id);
987 b61ceafc 2022-10-13 thomas if (err == NULL) {
988 b61ceafc 2022-10-13 thomas struct got_pack *pack = NULL;
989 b61ceafc 2022-10-13 thomas
990 b61ceafc 2022-10-13 thomas err = got_packidx_get_packfile_path(&path_packfile,
991 b61ceafc 2022-10-13 thomas packidx->path_packidx);
992 b61ceafc 2022-10-13 thomas if (err)
993 b61ceafc 2022-10-13 thomas goto done;
994 b61ceafc 2022-10-13 thomas
995 b61ceafc 2022-10-13 thomas pack = got_repo_get_cached_pack(repo, path_packfile);
996 b61ceafc 2022-10-13 thomas if (pack == NULL) {
997 b61ceafc 2022-10-13 thomas err = got_repo_cache_pack(&pack, repo, path_packfile,
998 b61ceafc 2022-10-13 thomas packidx);
999 b61ceafc 2022-10-13 thomas if (err)
1000 b61ceafc 2022-10-13 thomas goto done;
1001 b61ceafc 2022-10-13 thomas }
1002 b61ceafc 2022-10-13 thomas err = read_packed_blob_privsep(&outbuf, &size, &hdrlen, outfd,
1003 b61ceafc 2022-10-13 thomas pack, packidx, idx, id);
1004 b61ceafc 2022-10-13 thomas } else if (err->code == GOT_ERR_NO_OBJ) {
1005 b61ceafc 2022-10-13 thomas int infd;
1006 b61ceafc 2022-10-13 thomas
1007 b61ceafc 2022-10-13 thomas err = got_object_open_loose_fd(&infd, id, repo);
1008 b61ceafc 2022-10-13 thomas if (err)
1009 b61ceafc 2022-10-13 thomas goto done;
1010 b61ceafc 2022-10-13 thomas err = read_blob_privsep(&outbuf, &size, &hdrlen, outfd, infd,
1011 b61ceafc 2022-10-13 thomas id, repo);
1012 b61ceafc 2022-10-13 thomas }
1013 b61ceafc 2022-10-13 thomas if (err)
1014 b61ceafc 2022-10-13 thomas goto done;
1015 b61ceafc 2022-10-13 thomas
1016 b61ceafc 2022-10-13 thomas if (hdrlen > size) {
1017 b61ceafc 2022-10-13 thomas err = got_error(GOT_ERR_BAD_OBJ_HDR);
1018 b61ceafc 2022-10-13 thomas goto done;
1019 b61ceafc 2022-10-13 thomas }
1020 b61ceafc 2022-10-13 thomas
1021 b61ceafc 2022-10-13 thomas if (outbuf) {
1022 b61ceafc 2022-10-13 thomas (*blob)->f = fmemopen(outbuf, size, "rb");
1023 b61ceafc 2022-10-13 thomas if ((*blob)->f == NULL) {
1024 b61ceafc 2022-10-13 thomas err = got_error_from_errno("fmemopen");
1025 b61ceafc 2022-10-13 thomas free(outbuf);
1026 b61ceafc 2022-10-13 thomas goto done;
1027 b61ceafc 2022-10-13 thomas }
1028 b61ceafc 2022-10-13 thomas (*blob)->data = outbuf;
1029 b61ceafc 2022-10-13 thomas } else {
1030 b61ceafc 2022-10-13 thomas if (fstat(outfd, &sb) == -1) {
1031 b61ceafc 2022-10-13 thomas err = got_error_from_errno("fstat");
1032 b61ceafc 2022-10-13 thomas goto done;
1033 b61ceafc 2022-10-13 thomas }
1034 b61ceafc 2022-10-13 thomas
1035 b61ceafc 2022-10-13 thomas if (sb.st_size != size) {
1036 b61ceafc 2022-10-13 thomas err = got_error(GOT_ERR_PRIVSEP_LEN);
1037 b61ceafc 2022-10-13 thomas goto done;
1038 b61ceafc 2022-10-13 thomas }
1039 b61ceafc 2022-10-13 thomas
1040 b61ceafc 2022-10-13 thomas dfd = dup(outfd);
1041 b61ceafc 2022-10-13 thomas if (dfd == -1) {
1042 b61ceafc 2022-10-13 thomas err = got_error_from_errno("dup");
1043 b61ceafc 2022-10-13 thomas goto done;
1044 b61ceafc 2022-10-13 thomas }
1045 b61ceafc 2022-10-13 thomas
1046 b61ceafc 2022-10-13 thomas (*blob)->f = fdopen(dfd, "rb");
1047 b61ceafc 2022-10-13 thomas if ((*blob)->f == NULL) {
1048 b61ceafc 2022-10-13 thomas err = got_error_from_errno("fdopen");
1049 b61ceafc 2022-10-13 thomas close(dfd);
1050 b61ceafc 2022-10-13 thomas dfd = -1;
1051 b61ceafc 2022-10-13 thomas goto done;
1052 b61ceafc 2022-10-13 thomas }
1053 b61ceafc 2022-10-13 thomas }
1054 b61ceafc 2022-10-13 thomas
1055 b61ceafc 2022-10-13 thomas (*blob)->hdrlen = hdrlen;
1056 b61ceafc 2022-10-13 thomas (*blob)->blocksize = blocksize;
1057 b61ceafc 2022-10-13 thomas memcpy(&(*blob)->id.sha1, id->sha1, SHA1_DIGEST_LENGTH);
1058 b61ceafc 2022-10-13 thomas
1059 b61ceafc 2022-10-13 thomas done:
1060 b61ceafc 2022-10-13 thomas free(path_packfile);
1061 b61ceafc 2022-10-13 thomas if (err) {
1062 b61ceafc 2022-10-13 thomas if (*blob) {
1063 b61ceafc 2022-10-13 thomas got_object_blob_close(*blob);
1064 b61ceafc 2022-10-13 thomas *blob = NULL;
1065 b61ceafc 2022-10-13 thomas }
1066 b61ceafc 2022-10-13 thomas }
1067 b61ceafc 2022-10-13 thomas return err;
1068 b61ceafc 2022-10-13 thomas }
1069 b61ceafc 2022-10-13 thomas
1070 b61ceafc 2022-10-13 thomas const struct got_error *
1071 b61ceafc 2022-10-13 thomas got_object_open_as_blob(struct got_blob_object **blob,
1072 b61ceafc 2022-10-13 thomas struct got_repository *repo, struct got_object_id *id, size_t blocksize,
1073 b61ceafc 2022-10-13 thomas int outfd)
1074 b61ceafc 2022-10-13 thomas {
1075 b61ceafc 2022-10-13 thomas return open_blob(blob, repo, id, blocksize, outfd);
1076 b61ceafc 2022-10-13 thomas }
1077 b61ceafc 2022-10-13 thomas
1078 b61ceafc 2022-10-13 thomas const struct got_error *
1079 b61ceafc 2022-10-13 thomas got_object_blob_open(struct got_blob_object **blob,
1080 b61ceafc 2022-10-13 thomas struct got_repository *repo, struct got_object *obj, size_t blocksize,
1081 b61ceafc 2022-10-13 thomas int outfd)
1082 b61ceafc 2022-10-13 thomas {
1083 b61ceafc 2022-10-13 thomas return open_blob(blob, repo, got_object_get_id(obj), blocksize, outfd);
1084 b61ceafc 2022-10-13 thomas }
1085 b61ceafc 2022-10-13 thomas
1086 b61ceafc 2022-10-13 thomas static const struct got_error *
1087 b61ceafc 2022-10-13 thomas request_packed_tag(struct got_tag_object **tag, struct got_pack *pack,
1088 b61ceafc 2022-10-13 thomas int pack_idx, struct got_object_id *id)
1089 b61ceafc 2022-10-13 thomas {
1090 b61ceafc 2022-10-13 thomas const struct got_error *err = NULL;
1091 b61ceafc 2022-10-13 thomas
1092 b61ceafc 2022-10-13 thomas err = got_privsep_send_tag_req(pack->privsep_child->ibuf, -1, id,
1093 b61ceafc 2022-10-13 thomas pack_idx);
1094 b61ceafc 2022-10-13 thomas if (err)
1095 b61ceafc 2022-10-13 thomas return err;
1096 b61ceafc 2022-10-13 thomas
1097 b61ceafc 2022-10-13 thomas return got_privsep_recv_tag(tag, pack->privsep_child->ibuf);
1098 b61ceafc 2022-10-13 thomas }
1099 b61ceafc 2022-10-13 thomas
1100 b61ceafc 2022-10-13 thomas static const struct got_error *
1101 b61ceafc 2022-10-13 thomas read_packed_tag_privsep(struct got_tag_object **tag,
1102 b61ceafc 2022-10-13 thomas struct got_pack *pack, struct got_packidx *packidx, int idx,
1103 b61ceafc 2022-10-13 thomas struct got_object_id *id)
1104 b61ceafc 2022-10-13 thomas {
1105 b61ceafc 2022-10-13 thomas const struct got_error *err = NULL;
1106 b61ceafc 2022-10-13 thomas
1107 b61ceafc 2022-10-13 thomas if (pack->privsep_child)
1108 b61ceafc 2022-10-13 thomas return request_packed_tag(tag, pack, idx, id);
1109 b61ceafc 2022-10-13 thomas
1110 b61ceafc 2022-10-13 thomas err = got_pack_start_privsep_child(pack, packidx);
1111 b61ceafc 2022-10-13 thomas if (err)
1112 b61ceafc 2022-10-13 thomas return err;
1113 b61ceafc 2022-10-13 thomas
1114 b61ceafc 2022-10-13 thomas return request_packed_tag(tag, pack, idx, id);
1115 b61ceafc 2022-10-13 thomas }
1116 b61ceafc 2022-10-13 thomas
1117 b61ceafc 2022-10-13 thomas static const struct got_error *
1118 b61ceafc 2022-10-13 thomas request_tag(struct got_tag_object **tag, struct got_repository *repo,
1119 b61ceafc 2022-10-13 thomas int fd, struct got_object_id *id)
1120 b61ceafc 2022-10-13 thomas {
1121 b61ceafc 2022-10-13 thomas const struct got_error *err = NULL;
1122 b61ceafc 2022-10-13 thomas struct imsgbuf *ibuf;
1123 b61ceafc 2022-10-13 thomas
1124 b61ceafc 2022-10-13 thomas ibuf = repo->privsep_children[GOT_REPO_PRIVSEP_CHILD_TAG].ibuf;
1125 b61ceafc 2022-10-13 thomas
1126 b61ceafc 2022-10-13 thomas err = got_privsep_send_tag_req(ibuf, fd, id, -1);
1127 b61ceafc 2022-10-13 thomas if (err)
1128 b61ceafc 2022-10-13 thomas return err;
1129 b61ceafc 2022-10-13 thomas
1130 b61ceafc 2022-10-13 thomas return got_privsep_recv_tag(tag, ibuf);
1131 b61ceafc 2022-10-13 thomas }
1132 b61ceafc 2022-10-13 thomas
1133 b61ceafc 2022-10-13 thomas static const struct got_error *
1134 b61ceafc 2022-10-13 thomas read_tag_privsep(struct got_tag_object **tag, int obj_fd,
1135 b61ceafc 2022-10-13 thomas struct got_object_id *id, struct got_repository *repo)
1136 b61ceafc 2022-10-13 thomas {
1137 b61ceafc 2022-10-13 thomas const struct got_error *err;
1138 b61ceafc 2022-10-13 thomas
1139 b61ceafc 2022-10-13 thomas if (repo->privsep_children[GOT_REPO_PRIVSEP_CHILD_TAG].imsg_fd != -1)
1140 b61ceafc 2022-10-13 thomas return request_tag(tag, repo, obj_fd, id);
1141 b61ceafc 2022-10-13 thomas
1142 54c22772 2022-10-13 thomas err = start_child(repo, GOT_REPO_PRIVSEP_CHILD_TAG);
1143 54c22772 2022-10-13 thomas if (err)
1144 b61ceafc 2022-10-13 thomas return err;
1145 b61ceafc 2022-10-13 thomas
1146 b61ceafc 2022-10-13 thomas return request_tag(tag, repo, obj_fd, id);
1147 b61ceafc 2022-10-13 thomas }
1148 b61ceafc 2022-10-13 thomas
1149 b61ceafc 2022-10-13 thomas static const struct got_error *
1150 b61ceafc 2022-10-13 thomas open_tag(struct got_tag_object **tag, struct got_repository *repo,
1151 b61ceafc 2022-10-13 thomas struct got_object_id *id, int check_cache)
1152 b61ceafc 2022-10-13 thomas {
1153 b61ceafc 2022-10-13 thomas const struct got_error *err = NULL;
1154 b61ceafc 2022-10-13 thomas struct got_packidx *packidx = NULL;
1155 b61ceafc 2022-10-13 thomas int idx;
1156 b61ceafc 2022-10-13 thomas char *path_packfile = NULL;
1157 b61ceafc 2022-10-13 thomas struct got_object *obj = NULL;
1158 b61ceafc 2022-10-13 thomas int obj_type = GOT_OBJ_TYPE_ANY;
1159 b61ceafc 2022-10-13 thomas
1160 b61ceafc 2022-10-13 thomas if (check_cache) {
1161 b61ceafc 2022-10-13 thomas *tag = got_repo_get_cached_tag(repo, id);
1162 b61ceafc 2022-10-13 thomas if (*tag != NULL) {
1163 b61ceafc 2022-10-13 thomas (*tag)->refcnt++;
1164 b61ceafc 2022-10-13 thomas return NULL;
1165 b61ceafc 2022-10-13 thomas }
1166 b61ceafc 2022-10-13 thomas } else
1167 b61ceafc 2022-10-13 thomas *tag = NULL;
1168 b61ceafc 2022-10-13 thomas
1169 b61ceafc 2022-10-13 thomas err = got_repo_search_packidx(&packidx, &idx, repo, id);
1170 b61ceafc 2022-10-13 thomas if (err == NULL) {
1171 b61ceafc 2022-10-13 thomas struct got_pack *pack = NULL;
1172 b61ceafc 2022-10-13 thomas
1173 b61ceafc 2022-10-13 thomas err = got_packidx_get_packfile_path(&path_packfile,
1174 b61ceafc 2022-10-13 thomas packidx->path_packidx);
1175 b61ceafc 2022-10-13 thomas if (err)
1176 b61ceafc 2022-10-13 thomas return err;
1177 b61ceafc 2022-10-13 thomas
1178 b61ceafc 2022-10-13 thomas pack = got_repo_get_cached_pack(repo, path_packfile);
1179 b61ceafc 2022-10-13 thomas if (pack == NULL) {
1180 b61ceafc 2022-10-13 thomas err = got_repo_cache_pack(&pack, repo, path_packfile,
1181 b61ceafc 2022-10-13 thomas packidx);
1182 b61ceafc 2022-10-13 thomas if (err)
1183 b61ceafc 2022-10-13 thomas goto done;
1184 b61ceafc 2022-10-13 thomas }
1185 b61ceafc 2022-10-13 thomas
1186 b61ceafc 2022-10-13 thomas /* Beware of "lightweight" tags: Check object type first. */
1187 b61ceafc 2022-10-13 thomas err = read_packed_object_privsep(&obj, repo, pack, packidx,
1188 b61ceafc 2022-10-13 thomas idx, id);
1189 b61ceafc 2022-10-13 thomas if (err)
1190 b61ceafc 2022-10-13 thomas goto done;
1191 b61ceafc 2022-10-13 thomas obj_type = obj->type;
1192 b61ceafc 2022-10-13 thomas got_object_close(obj);
1193 b61ceafc 2022-10-13 thomas if (obj_type != GOT_OBJ_TYPE_TAG) {
1194 b61ceafc 2022-10-13 thomas err = got_error(GOT_ERR_OBJ_TYPE);
1195 b61ceafc 2022-10-13 thomas goto done;
1196 b61ceafc 2022-10-13 thomas }
1197 b61ceafc 2022-10-13 thomas err = read_packed_tag_privsep(tag, pack, packidx, idx, id);
1198 b61ceafc 2022-10-13 thomas } else if (err->code == GOT_ERR_NO_OBJ) {
1199 b61ceafc 2022-10-13 thomas int fd;
1200 b61ceafc 2022-10-13 thomas
1201 b61ceafc 2022-10-13 thomas err = got_object_open_loose_fd(&fd, id, repo);
1202 b61ceafc 2022-10-13 thomas if (err)
1203 b61ceafc 2022-10-13 thomas return err;
1204 b61ceafc 2022-10-13 thomas err = got_object_read_header_privsep(&obj, id, repo, fd);
1205 b61ceafc 2022-10-13 thomas if (err)
1206 b61ceafc 2022-10-13 thomas return err;
1207 b61ceafc 2022-10-13 thomas obj_type = obj->type;
1208 b61ceafc 2022-10-13 thomas got_object_close(obj);
1209 b61ceafc 2022-10-13 thomas if (obj_type != GOT_OBJ_TYPE_TAG)
1210 b61ceafc 2022-10-13 thomas return got_error(GOT_ERR_OBJ_TYPE);
1211 b61ceafc 2022-10-13 thomas
1212 b61ceafc 2022-10-13 thomas err = got_object_open_loose_fd(&fd, id, repo);
1213 b61ceafc 2022-10-13 thomas if (err)
1214 b61ceafc 2022-10-13 thomas return err;
1215 b61ceafc 2022-10-13 thomas err = read_tag_privsep(tag, fd, id, repo);
1216 b61ceafc 2022-10-13 thomas }
1217 b61ceafc 2022-10-13 thomas
1218 b61ceafc 2022-10-13 thomas if (err == NULL) {
1219 b61ceafc 2022-10-13 thomas (*tag)->refcnt++;
1220 b61ceafc 2022-10-13 thomas err = got_repo_cache_tag(repo, id, *tag);
1221 b61ceafc 2022-10-13 thomas }
1222 b61ceafc 2022-10-13 thomas done:
1223 b61ceafc 2022-10-13 thomas free(path_packfile);
1224 b61ceafc 2022-10-13 thomas return err;
1225 b61ceafc 2022-10-13 thomas }
1226 b61ceafc 2022-10-13 thomas
1227 b61ceafc 2022-10-13 thomas const struct got_error *
1228 b61ceafc 2022-10-13 thomas got_object_open_as_tag(struct got_tag_object **tag,
1229 b61ceafc 2022-10-13 thomas struct got_repository *repo, struct got_object_id *id)
1230 b61ceafc 2022-10-13 thomas {
1231 b61ceafc 2022-10-13 thomas *tag = got_repo_get_cached_tag(repo, id);
1232 b61ceafc 2022-10-13 thomas if (*tag != NULL) {
1233 b61ceafc 2022-10-13 thomas (*tag)->refcnt++;
1234 b61ceafc 2022-10-13 thomas return NULL;
1235 b61ceafc 2022-10-13 thomas }
1236 b61ceafc 2022-10-13 thomas
1237 b61ceafc 2022-10-13 thomas return open_tag(tag, repo, id, 0);
1238 b61ceafc 2022-10-13 thomas }
1239 b61ceafc 2022-10-13 thomas
1240 b61ceafc 2022-10-13 thomas const struct got_error *
1241 b61ceafc 2022-10-13 thomas got_object_tag_open(struct got_tag_object **tag,
1242 b61ceafc 2022-10-13 thomas struct got_repository *repo, struct got_object *obj)
1243 b61ceafc 2022-10-13 thomas {
1244 b61ceafc 2022-10-13 thomas return open_tag(tag, repo, got_object_get_id(obj), 1);
1245 b61ceafc 2022-10-13 thomas }
1246 b61ceafc 2022-10-13 thomas
1247 b61ceafc 2022-10-13 thomas const struct got_error *
1248 b61ceafc 2022-10-13 thomas got_traverse_packed_commits(struct got_object_id_queue *traversed_commits,
1249 b61ceafc 2022-10-13 thomas struct got_object_id *commit_id, const char *path,
1250 b61ceafc 2022-10-13 thomas struct got_repository *repo)
1251 b61ceafc 2022-10-13 thomas {
1252 b61ceafc 2022-10-13 thomas const struct got_error *err = NULL;
1253 b61ceafc 2022-10-13 thomas struct got_pack *pack = NULL;
1254 b61ceafc 2022-10-13 thomas struct got_packidx *packidx = NULL;
1255 b61ceafc 2022-10-13 thomas char *path_packfile = NULL;
1256 b61ceafc 2022-10-13 thomas struct got_commit_object *changed_commit = NULL;
1257 b61ceafc 2022-10-13 thomas struct got_object_id *changed_commit_id = NULL;
1258 b61ceafc 2022-10-13 thomas int idx;
1259 b61ceafc 2022-10-13 thomas
1260 b61ceafc 2022-10-13 thomas err = got_repo_search_packidx(&packidx, &idx, repo, commit_id);
1261 b61ceafc 2022-10-13 thomas if (err) {
1262 b61ceafc 2022-10-13 thomas if (err->code != GOT_ERR_NO_OBJ)
1263 b61ceafc 2022-10-13 thomas return err;
1264 b61ceafc 2022-10-13 thomas return NULL;
1265 b61ceafc 2022-10-13 thomas }
1266 b61ceafc 2022-10-13 thomas
1267 b61ceafc 2022-10-13 thomas err = got_packidx_get_packfile_path(&path_packfile,
1268 b61ceafc 2022-10-13 thomas packidx->path_packidx);
1269 b61ceafc 2022-10-13 thomas if (err)
1270 b61ceafc 2022-10-13 thomas return err;
1271 b61ceafc 2022-10-13 thomas
1272 b61ceafc 2022-10-13 thomas pack = got_repo_get_cached_pack(repo, path_packfile);
1273 b61ceafc 2022-10-13 thomas if (pack == NULL) {
1274 b61ceafc 2022-10-13 thomas err = got_repo_cache_pack(&pack, repo, path_packfile, packidx);
1275 b61ceafc 2022-10-13 thomas if (err)
1276 b61ceafc 2022-10-13 thomas goto done;
1277 b61ceafc 2022-10-13 thomas }
1278 b61ceafc 2022-10-13 thomas
1279 b61ceafc 2022-10-13 thomas if (pack->privsep_child == NULL) {
1280 b61ceafc 2022-10-13 thomas err = got_pack_start_privsep_child(pack, packidx);
1281 b61ceafc 2022-10-13 thomas if (err)
1282 b61ceafc 2022-10-13 thomas goto done;
1283 b61ceafc 2022-10-13 thomas }
1284 b61ceafc 2022-10-13 thomas
1285 b61ceafc 2022-10-13 thomas err = got_privsep_send_commit_traversal_request(
1286 b61ceafc 2022-10-13 thomas pack->privsep_child->ibuf, commit_id, idx, path);
1287 b61ceafc 2022-10-13 thomas if (err)
1288 b61ceafc 2022-10-13 thomas goto done;
1289 b61ceafc 2022-10-13 thomas
1290 b61ceafc 2022-10-13 thomas err = got_privsep_recv_traversed_commits(&changed_commit,
1291 b61ceafc 2022-10-13 thomas &changed_commit_id, traversed_commits, pack->privsep_child->ibuf);
1292 b61ceafc 2022-10-13 thomas if (err)
1293 b61ceafc 2022-10-13 thomas goto done;
1294 b61ceafc 2022-10-13 thomas
1295 b61ceafc 2022-10-13 thomas if (changed_commit) {
1296 b61ceafc 2022-10-13 thomas /*
1297 b61ceafc 2022-10-13 thomas * Cache the commit in which the path was changed.
1298 b61ceafc 2022-10-13 thomas * This commit might be opened again soon.
1299 b61ceafc 2022-10-13 thomas */
1300 b61ceafc 2022-10-13 thomas changed_commit->refcnt++;
1301 b61ceafc 2022-10-13 thomas err = got_repo_cache_commit(repo, changed_commit_id,
1302 b61ceafc 2022-10-13 thomas changed_commit);
1303 b61ceafc 2022-10-13 thomas got_object_commit_close(changed_commit);
1304 b61ceafc 2022-10-13 thomas }
1305 b61ceafc 2022-10-13 thomas done:
1306 b61ceafc 2022-10-13 thomas free(path_packfile);
1307 b61ceafc 2022-10-13 thomas free(changed_commit_id);
1308 b61ceafc 2022-10-13 thomas return err;
1309 b61ceafc 2022-10-13 thomas }
1310 b61ceafc 2022-10-13 thomas
1311 b61ceafc 2022-10-13 thomas const struct got_error *
1312 b61ceafc 2022-10-13 thomas got_object_enumerate(int *found_all_objects,
1313 b61ceafc 2022-10-13 thomas got_object_enumerate_commit_cb cb_commit,
1314 b61ceafc 2022-10-13 thomas got_object_enumerate_tree_cb cb_tree, void *cb_arg,
1315 b61ceafc 2022-10-13 thomas struct got_object_id **ours, int nours,
1316 b61ceafc 2022-10-13 thomas struct got_object_id **theirs, int ntheirs,
1317 b61ceafc 2022-10-13 thomas struct got_packidx *packidx, struct got_repository *repo)
1318 b61ceafc 2022-10-13 thomas {
1319 b61ceafc 2022-10-13 thomas const struct got_error *err = NULL;
1320 b61ceafc 2022-10-13 thomas struct got_pack *pack;
1321 b61ceafc 2022-10-13 thomas char *path_packfile = NULL;
1322 b61ceafc 2022-10-13 thomas
1323 b61ceafc 2022-10-13 thomas err = got_packidx_get_packfile_path(&path_packfile,
1324 b61ceafc 2022-10-13 thomas packidx->path_packidx);
1325 b61ceafc 2022-10-13 thomas if (err)
1326 b61ceafc 2022-10-13 thomas return err;
1327 b61ceafc 2022-10-13 thomas
1328 b61ceafc 2022-10-13 thomas pack = got_repo_get_cached_pack(repo, path_packfile);
1329 b61ceafc 2022-10-13 thomas if (pack == NULL) {
1330 b61ceafc 2022-10-13 thomas err = got_repo_cache_pack(&pack, repo, path_packfile, packidx);
1331 b61ceafc 2022-10-13 thomas if (err)
1332 b61ceafc 2022-10-13 thomas goto done;
1333 b61ceafc 2022-10-13 thomas }
1334 b61ceafc 2022-10-13 thomas
1335 b61ceafc 2022-10-13 thomas if (pack->privsep_child == NULL) {
1336 b61ceafc 2022-10-13 thomas err = got_pack_start_privsep_child(pack, packidx);
1337 b61ceafc 2022-10-13 thomas if (err)
1338 b61ceafc 2022-10-13 thomas goto done;
1339 b61ceafc 2022-10-13 thomas }
1340 b61ceafc 2022-10-13 thomas
1341 b61ceafc 2022-10-13 thomas err = got_privsep_send_object_enumeration_request(
1342 b61ceafc 2022-10-13 thomas pack->privsep_child->ibuf);
1343 b61ceafc 2022-10-13 thomas if (err)
1344 b61ceafc 2022-10-13 thomas goto done;
1345 b61ceafc 2022-10-13 thomas
1346 b61ceafc 2022-10-13 thomas err = got_privsep_send_object_idlist(pack->privsep_child->ibuf,
1347 b61ceafc 2022-10-13 thomas ours, nours);
1348 b61ceafc 2022-10-13 thomas if (err)
1349 b61ceafc 2022-10-13 thomas goto done;
1350 b61ceafc 2022-10-13 thomas err = got_privsep_send_object_idlist_done(pack->privsep_child->ibuf);
1351 b61ceafc 2022-10-13 thomas if (err)
1352 b61ceafc 2022-10-13 thomas goto done;
1353 b61ceafc 2022-10-13 thomas
1354 b61ceafc 2022-10-13 thomas err = got_privsep_send_object_idlist(pack->privsep_child->ibuf,
1355 b61ceafc 2022-10-13 thomas theirs, ntheirs);
1356 b61ceafc 2022-10-13 thomas if (err)
1357 b61ceafc 2022-10-13 thomas goto done;
1358 b61ceafc 2022-10-13 thomas err = got_privsep_send_object_idlist_done(pack->privsep_child->ibuf);
1359 b61ceafc 2022-10-13 thomas if (err)
1360 b61ceafc 2022-10-13 thomas goto done;
1361 b61ceafc 2022-10-13 thomas
1362 b61ceafc 2022-10-13 thomas err = got_privsep_recv_enumerated_objects(found_all_objects,
1363 b61ceafc 2022-10-13 thomas pack->privsep_child->ibuf, cb_commit, cb_tree, cb_arg, repo);
1364 b61ceafc 2022-10-13 thomas done:
1365 b61ceafc 2022-10-13 thomas free(path_packfile);
1366 b61ceafc 2022-10-13 thomas return err;
1367 b61ceafc 2022-10-13 thomas }