Blame


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