"GOT", but the "O" is a cute, smiling pufferfish. Index | Thread | Search

From:
Stefan Sperling <stsp@stsp.name>
Subject:
Re: run gotadmin without libexec helpers
To:
gameoftrees@openbsd.org
Date:
Mon, 4 Sep 2023 12:23:39 +0200

Download raw body.

Thread
On Mon, Sep 04, 2023 at 02:02:39AM +0200, Stefan Sperling wrote:
> This patch makes gotadmin run without libexec helpers.

The previous version of this diff did not compile because I had
forgotten to add privsep_stubs.c to version control... sorry
about this.

I have also removed the setting of repo temp_fds during the listpack
command, where these extra files are really not needed.

-----------------------------------------------
 run gotadmin without libexec helpers
 
diff d71015b33dbfbef534be92e584006caddbf16aa6 0b279c733e6d85c0e5077240b259e1aae1de80a3
commit - d71015b33dbfbef534be92e584006caddbf16aa6
commit + 0b279c733e6d85c0e5077240b259e1aae1de80a3
blob - 4485f4876de9c6581701463287d7bb44c2dec812
blob + 9acdc69ed3951000e7f95a14946d9ebff610c83a
--- gotadmin/Makefile
+++ gotadmin/Makefile
@@ -7,11 +7,11 @@ SRCS=		gotadmin.c \
 		deflate.c delta.c delta_cache.c deltify.c error.c gotconfig.c \
 		inflate.c lockfile.c object.c object_cache.c object_create.c \
 		object_idset.c object_parse.c opentemp.c pack.c pack_create.c \
-		path.c privsep.c reference.c repository.c repository_admin.c \
+		path.c privsep_stub.c reference.c repository.c repository_admin.c \
 		worktree_open.c hash.c bloom.c murmurhash2.c ratelimit.c \
-		sigs.c buf.c date.c object_open_privsep.c \
-		read_gitconfig_privsep.c read_gotconfig_privsep.c \
-		pack_create_privsep.c pollfd.c reference_parse.c object_qid.c \
+		sigs.c buf.c date.c object_open_io.c pack_index.c \
+		gitconfig.c read_gitconfig.c read_gotconfig.c \
+		pack_create_io.c pollfd.c reference_parse.c object_qid.c \
 		dump.c load.c
 MAN =		${PROG}.1
 
blob - ac13af4d643c13b2ba5b2cdc4285db4bb2b2789c
blob + c52aa09a4fc002425c5bdfc908f1a5825e02c98c
--- gotadmin/gotadmin.c
+++ gotadmin/gotadmin.c
@@ -214,8 +214,6 @@ usage(int hflag, int status)
 static const struct got_error *
 apply_unveil(const char *repo_path, int repo_read_only)
 {
-	const struct got_error *err;
-
 #ifdef PROFILE
 	if (unveil("gmon.out", "rwc") != 0)
 		return got_error_from_errno2("unveil", "gmon.out");
@@ -226,10 +224,6 @@ apply_unveil(const char *repo_path, int repo_read_only
 	if (unveil(GOT_TMPDIR_STR, "rwc") != 0)
 		return got_error_from_errno2("unveil", GOT_TMPDIR_STR);
 
-	err = got_privsep_unveil_exec_helpers();
-	if (err != NULL)
-		return err;
-
 	if (unveil(NULL, NULL) != 0)
 		return got_error_from_errno("unveil");
 
@@ -346,11 +340,10 @@ cmd_info(int argc, char *argv[])
 	int ch, npackfiles, npackedobj, nobj;
 	off_t packsize, loose_size;
 	char scaled[FMT_SCALED_STRSIZE];
-	int *pack_fds = NULL;
+	int *pack_fds = NULL, *temp_fds = NULL;
 
 #ifndef PROFILE
-	if (pledge("stdio rpath wpath cpath flock proc exec sendfd unveil",
-	    NULL) == -1)
+	if (pledge("stdio rpath wpath cpath flock unveil", NULL) == -1)
 		err(1, "pledge");
 #endif
 
@@ -380,13 +373,16 @@ cmd_info(int argc, char *argv[])
 	error = got_repo_pack_fds_open(&pack_fds);
 	if (error != NULL)
 		goto done;
+	error = got_repo_temp_fds_open(&temp_fds);
+	if (error)
+		goto done;
 	error = got_repo_open(&repo, repo_path, NULL, pack_fds);
 	if (error)
 		goto done;
+	got_repo_temp_fds_set(repo, temp_fds);
 #ifndef PROFILE
 	/* Remove "cpath" promise. */
-	if (pledge("stdio rpath wpath flock proc exec sendfd unveil",
-	    NULL) == -1)
+	if (pledge("stdio rpath wpath flock unveil", NULL) == -1)
 		err(1, "pledge");
 #endif
 	error = apply_unveil(got_repo_get_path_git_dir(repo), 1);
@@ -447,6 +443,8 @@ cmd_info(int argc, char *argv[])
 done:
 	if (repo)
 		got_repo_close(repo);
+	if (temp_fds)
+		got_repo_temp_fds_close(temp_fds);
 	if (pack_fds) {
 		const struct got_error *pack_err =
 		    got_repo_pack_fds_close(pack_fds);
@@ -712,15 +710,14 @@ cmd_pack(int argc, char *argv[])
 	struct got_reflist_head exclude_refs;
 	struct got_reflist_head include_refs;
 	struct got_reflist_entry *re, *new;
-	int *pack_fds = NULL;
+	int *pack_fds = NULL, *temp_fds = NULL;
 
 	TAILQ_INIT(&exclude_args);
 	TAILQ_INIT(&exclude_refs);
 	TAILQ_INIT(&include_refs);
 
 #ifndef PROFILE
-	if (pledge("stdio rpath wpath cpath fattr flock proc exec sendfd unveil",
-	    NULL) == -1)
+	if (pledge("stdio rpath wpath cpath fattr flock unveil", NULL) == -1)
 		err(1, "pledge");
 #endif
 
@@ -766,9 +763,13 @@ cmd_pack(int argc, char *argv[])
 	error = got_repo_pack_fds_open(&pack_fds);
 	if (error != NULL)
 		goto done;
+	error = got_repo_temp_fds_open(&temp_fds);
+	if (error)
+		goto done;
 	error = got_repo_open(&repo, repo_path, NULL, pack_fds);
 	if (error)
 		goto done;
+	got_repo_temp_fds_set(repo, temp_fds);
 
 	error = apply_unveil(got_repo_get_path_git_dir(repo), 0);
 	if (error)
@@ -838,6 +839,8 @@ cmd_pack(int argc, char *argv[])
 done:
 	if (repo)
 		got_repo_close(repo);
+	if (temp_fds)
+		got_repo_temp_fds_close(temp_fds);
 	if (pack_fds) {
 		const struct got_error *pack_err =
 		    got_repo_pack_fds_close(pack_fds);
@@ -872,7 +875,7 @@ cmd_indexpack(int argc, char *argv[])
 	char *id_str = NULL;
 	struct got_pack_progress_arg ppa;
 	FILE *packfile = NULL;
-	int *pack_fds = NULL;
+	int *pack_fds = NULL, *temp_fds = NULL;
 
 	while ((ch = getopt(argc, argv, "")) != -1) {
 		switch (ch) {
@@ -893,17 +896,20 @@ cmd_indexpack(int argc, char *argv[])
 		return got_error_from_errno2("realpath", argv[0]);
 
 #ifndef PROFILE
-	if (pledge("stdio rpath wpath cpath fattr flock proc exec sendfd unveil",
-	    NULL) == -1)
+	if (pledge("stdio rpath wpath cpath fattr flock unveil", NULL) == -1)
 		err(1, "pledge");
 #endif
 
 	error = got_repo_pack_fds_open(&pack_fds);
 	if (error != NULL)
 		goto done;
+	error = got_repo_temp_fds_open(&temp_fds);
+	if (error)
+		goto done;
 	error = got_repo_open(&repo, packfile_path, NULL, pack_fds);
 	if (error)
 		goto done;
+	got_repo_temp_fds_set(repo, temp_fds);
 
 	error = apply_unveil(got_repo_get_path_git_dir(repo), 0);
 	if (error)
@@ -932,6 +938,8 @@ cmd_indexpack(int argc, char *argv[])
 done:
 	if (repo)
 		got_repo_close(repo);
+	if (temp_fds)
+		got_repo_temp_fds_close(temp_fds);
 	if (pack_fds) {
 		const struct got_error *pack_err =
 		    got_repo_pack_fds_close(pack_fds);
@@ -1054,8 +1062,7 @@ cmd_listpack(int argc, char *argv[])
 	int *pack_fds = NULL;
 
 #ifndef PROFILE
-	if (pledge("stdio rpath wpath cpath flock proc exec sendfd unveil",
-	    NULL) == -1)
+	if (pledge("stdio rpath wpath cpath flock unveil", NULL) == -1)
 		err(1, "pledge");
 #endif
 
@@ -1090,8 +1097,7 @@ cmd_listpack(int argc, char *argv[])
 		goto done;
 #ifndef PROFILE
 	/* Remove "cpath" promise. */
-	if (pledge("stdio rpath wpath flock proc exec sendfd unveil",
-	    NULL) == -1)
+	if (pledge("stdio rpath wpath flock unveil", NULL) == -1)
 		err(1, "pledge");
 #endif
 	error = apply_unveil(got_repo_get_path_git_dir(repo), 1);
@@ -1261,11 +1267,10 @@ cmd_cleanup(int argc, char *argv[])
 	char pack_before_scaled[FMT_SCALED_STRSIZE];
 	char pack_after_scaled[FMT_SCALED_STRSIZE];
 	char total_size_scaled[FMT_SCALED_STRSIZE];
-	int *pack_fds = NULL;
+	int *pack_fds = NULL, *temp_fds = NULL;
 
 #ifndef PROFILE
-	if (pledge("stdio rpath wpath cpath flock proc exec sendfd unveil",
-	    NULL) == -1)
+	if (pledge("stdio rpath wpath cpath flock unveil", NULL) == -1)
 		err(1, "pledge");
 #endif
 
@@ -1307,9 +1312,13 @@ cmd_cleanup(int argc, char *argv[])
 	error = got_repo_pack_fds_open(&pack_fds);
 	if (error != NULL)
 		goto done;
+	error = got_repo_temp_fds_open(&temp_fds);
+	if (error)
+		goto done;
 	error = got_repo_open(&repo, repo_path, NULL, pack_fds);
 	if (error)
 		goto done;
+	got_repo_temp_fds_set(repo, temp_fds);
 
 	error = apply_unveil(got_repo_get_path_git_dir(repo), 0);
 	if (error)
@@ -1386,6 +1395,8 @@ cmd_cleanup(int argc, char *argv[])
 done:
 	if (repo)
 		got_repo_close(repo);
+	if (temp_fds)
+		got_repo_temp_fds_close(temp_fds);
 	if (pack_fds) {
 		const struct got_error *pack_err =
 		    got_repo_pack_fds_close(pack_fds);
@@ -1417,7 +1428,7 @@ cmd_dump(int argc, char *argv[])
 	struct got_reflist_entry *re, *new;
 	const char *refname;
 	char *repo_path = NULL;
-	int *pack_fds = NULL;
+	int *pack_fds = NULL, *temp_fds = NULL;
 	int verbosity = 0;
 	int i, ch;
 
@@ -1426,8 +1437,7 @@ cmd_dump(int argc, char *argv[])
 	TAILQ_INIT(&include_refs);
 
 #ifndef PROFILE
-	if (pledge("stdio rpath wpath cpath flock proc exec sendfd unveil",
-	    NULL) == -1)
+	if (pledge("stdio rpath wpath cpath flock unveil", NULL) == -1)
 		err(1, "pledge");
 #endif
 
@@ -1465,9 +1475,13 @@ cmd_dump(int argc, char *argv[])
 	error = got_repo_pack_fds_open(&pack_fds);
 	if (error != NULL)
 		goto done;
+	error = got_repo_temp_fds_open(&temp_fds);
+	if (error)
+		goto done;
 	error = got_repo_open(&repo, repo_path, NULL, pack_fds);
 	if (error)
 		goto done;
+	got_repo_temp_fds_set(repo, temp_fds);
 
 	error = apply_unveil(got_repo_get_path_git_dir(repo), 1);
 	if (error)
@@ -1516,7 +1530,8 @@ cmd_dump(int argc, char *argv[])
  done:
 	if (repo)
 		got_repo_close(repo);
-
+	if (temp_fds)
+		got_repo_temp_fds_close(temp_fds);
 	if (pack_fds) {
 		const struct got_error *pack_err;
 
@@ -1664,7 +1679,7 @@ cmd_load(int argc, char *argv[])
 	struct got_pathlist_entry *pe;
 	struct got_pack_progress_arg ppa;
 	FILE *in = stdin;
-	int *pack_fds = NULL;
+	int *pack_fds = NULL, *temp_fds = NULL;
 	char *repo_path = NULL;
 	int list_refs_only = 0;
 	int noop = 0;
@@ -1675,8 +1690,7 @@ cmd_load(int argc, char *argv[])
 	TAILQ_INIT(&available_refs);
 
 #ifndef PROFILE
-	if (pledge("stdio rpath wpath cpath fattr flock proc exec "
-	    "sendfd unveil", NULL) == -1)
+	if (pledge("stdio rpath wpath cpath fattr flock unveil", NULL) == -1)
 		err(1, "pledge");
 #endif
 
@@ -1732,9 +1746,13 @@ cmd_load(int argc, char *argv[])
 	error = got_repo_pack_fds_open(&pack_fds);
 	if (error != NULL)
 		goto done;
+	error = got_repo_temp_fds_open(&temp_fds);
+	if (error)
+		goto done;
 	error = got_repo_open(&repo, repo_path, NULL, pack_fds);
 	if (error)
 		goto done;
+	got_repo_temp_fds_set(repo, temp_fds);
 
 	error = apply_unveil(got_repo_get_path_git_dir(repo), 0);
 	if (error)
@@ -1805,7 +1823,8 @@ cmd_load(int argc, char *argv[])
 
 	if (repo)
 		got_repo_close(repo);
-
+	if (temp_fds)
+		got_repo_temp_fds_close(temp_fds);
 	if (pack_fds) {
 		const struct got_error *pack_err;
 
blob - /dev/null
blob + e5c21b47893334094185748ac154995dee4065d6 (mode 644)
--- /dev/null
+++ gotadmin/privsep_stub.c
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2022 Stefan Sperling <stsp@openbsd.org>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <sys/types.h>
+#include <sys/time.h>
+#include <sys/queue.h>
+#include <sys/tree.h>
+#include <sys/uio.h>
+
+#include <sha1.h>
+#include <sha2.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <imsg.h>
+#include <limits.h>
+
+#include "got_error.h"
+#include "got_object.h"
+#include "got_path.h"
+
+#include "got_lib_delta.h"
+#include "got_lib_object.h"
+#include "got_lib_object_cache.h"
+#include "got_lib_pack.h"
+#include "got_lib_repository.h"
+#include "got_lib_privsep.h"
+
+const struct got_error *
+got_privsep_send_stop(int fd)
+{
+	return got_error(GOT_ERR_NOT_IMPL);
+}
+
+const struct got_error *
+got_privsep_wait_for_child(pid_t pid)
+{
+	return got_error(GOT_ERR_NOT_IMPL);
+}
+
+void
+got_privsep_exec_child(int imsg_fds[2], const char *path, const char *repo_path)
+{
+	fprintf(stderr, "%s: cannot run libexec helpers\n", getprogname());
+	exit(1);
+}
+
+const struct got_error *
+got_privsep_init_pack_child(struct imsgbuf *ibuf, struct got_pack *pack,
+    struct got_packidx *packidx)
+{
+	return got_error(GOT_ERR_NOT_IMPL);
+}
blob - 7175f86e3c1f00b9b4d870af1638dc3f1068d951
blob + a104bbf0b7040b724e51aa8ef10470b01598568f
--- include/got_repository_admin.h
+++ include/got_repository_admin.h
@@ -47,7 +47,7 @@ got_repo_find_pack(FILE **packfile, struct got_object_
     struct got_repository *repo, const char *packfile_path);
 
 /* A callback function which gets invoked with progress information to print. */
-typedef const struct got_error *(*got_pack_index_progress_cb)(void *arg,
+typedef const struct got_error *(*got_repo_pack_index_progress_cb)(void *arg,
     off_t packfile_size, int nobj_total, int nobj_indexed,
     int nobj_loose, int nobj_resolved);
 
@@ -55,7 +55,7 @@ typedef const struct got_error *(*got_pack_index_progr
 const struct got_error *
 got_repo_index_pack(FILE *packfile, struct got_object_id *pack_hash,
     struct got_repository *repo,
-    got_pack_index_progress_cb progress_cb, void *progress_arg,
+    got_repo_pack_index_progress_cb progress_cb, void *progress_arg,
     got_cancel_cb cancel_cb, void *cancel_arg);
 
 typedef const struct got_error *(*got_pack_list_cb)(void *arg,
blob - 8fcb52f1333aada44e211d3b89366979118e617d
blob + 38f24a35b625be0bff6f7c820ada870335f97270
--- lib/got_lib_pack_index.h
+++ lib/got_lib_pack_index.h
@@ -14,7 +14,7 @@
  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
-typedef const struct got_error *(got_pack_index_progress_cb)(void *,
+typedef const struct got_error *(*got_pack_index_progress_cb)(void *,
     uint32_t nobj_total, uint32_t nobj_indexed, uint32_t nobj_loose,
     uint32_t nobj_resolved);
 
blob - 544f59bad76e1479b2badc43c1532f06d70db9d9
blob + 11251a1e6b4f07ee1f5d6caa281cdd038493e023
--- lib/load.c
+++ lib/load.c
@@ -44,11 +44,13 @@
 #include "got_repository_load.h"
 
 #include "got_lib_delta.h"
+#include "got_lib_delta_cache.h"
 #include "got_lib_hash.h"
 #include "got_lib_object.h"
 #include "got_lib_object_cache.h"
 #include "got_lib_pack.h"
 #include "got_lib_ratelimit.h"
+#include "got_lib_pack_index.h"
 #include "got_lib_repository.h"
 #include "got_lib_privsep.h"
 
@@ -203,6 +205,39 @@ copypack(FILE *in, int outfd, off_t *tot,
 	return NULL;
 }
 
+struct pack_index_progress_arg {
+    off_t packfile_size;
+    got_load_progress_cb progress_cb;
+    void *progress_arg;
+    got_cancel_cb cancel_cb;
+    void *cancel_arg;
+    struct got_ratelimit *rl;
+};
+
+static const struct got_error *
+pack_index_progress(void *arg, uint32_t nobj_total, uint32_t nobj_indexed,
+    uint32_t nobj_loose, uint32_t nobj_resolved)
+{
+	const struct got_error *err = NULL;
+	struct pack_index_progress_arg *a = arg;
+
+	if (a->cancel_cb) {
+		err = a->cancel_cb(a->cancel_arg);
+		if (err)
+			return err;
+	}
+
+	if (nobj_indexed != 0) {
+		err = load_report_progress(a->progress_cb, a->progress_arg,
+		    a->rl, a->packfile_size, nobj_total, nobj_indexed,
+		    nobj_loose, nobj_resolved);
+		if (err)
+			return err;
+	}
+
+	return err;
+}
+
 const struct got_error *
 got_repo_load(FILE *in, struct got_pathlist_head *refs_found,
     struct got_repository *repo, int list_refs_only, int noop,
@@ -214,7 +249,6 @@ got_repo_load(FILE *in, struct got_pathlist_head *refs
 	struct got_object *obj;
 	struct got_packfile_hdr pack_hdr;
 	struct got_ratelimit rl;
-	struct imsgbuf idxibuf;
 	const char *repo_path;
 	char *packpath = NULL, *idxpath = NULL;
 	char *tmppackpath = NULL, *tmpidxpath = NULL;
@@ -226,11 +260,15 @@ got_repo_load(FILE *in, struct got_pathlist_head *refs
 	size_t i;
 	ssize_t n;
 	off_t packsiz;
-	int tmpfds[3] = {-1, -1, -1};
+	FILE *tempfiles[3] = { NULL, NULL, NULL };
 	int imsg_idxfds[2] = {-1, -1};
-	int ch, done, nobj, idxstatus;
-	pid_t idxpid;
+	int ch, nobj;
+	struct pack_index_progress_arg arg;
+	struct got_pack pack;
+	uint8_t pack_sha1_expected[SHA1_DIGEST_LENGTH];
 
+	memset(&pack, 0, sizeof(pack));
+
 	got_ratelimit_init(&rl, 0, 500);
 
 	repo_path = got_repo_get_path_git_dir(repo);
@@ -394,80 +432,54 @@ got_repo_load(FILE *in, struct got_pathlist_head *refs
 	if (nobj == 0)
 		goto done;
 
-	for (i = 0; i < nitems(tmpfds); i++) {
-		tmpfds[i] = got_opentempfd();
-		if (tmpfds[i] == -1) {
-			err = got_error_from_errno("got_opentempfd");
+	for (i = 0; i < nitems(tempfiles); i++) {
+		tempfiles[i] = got_opentemp();
+		if (tempfiles[i] == NULL) {
+			err = got_error_from_errno("got_opentemp");
 			goto done;
 		}
 	}
 
+
+	if (lseek(packfd, packsiz - SHA1_DIGEST_LENGTH, SEEK_SET) == -1) {
+		err = got_error_from_errno("lseek");
+		goto done;
+	}
+
+	n = read(packfd, pack_sha1_expected, SHA1_DIGEST_LENGTH);
+	if (n == -1) {
+		err = got_error_from_errno("read");
+		goto done;
+	}
+	if (n != SHA1_DIGEST_LENGTH) {
+		err = got_error(GOT_ERR_IO);
+		goto done;
+	}
+
 	if (lseek(packfd, 0, SEEK_SET) == -1) {
 		err = got_error_from_errno("lseek");
 		goto done;
 	}
 
-	if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, imsg_idxfds) == -1) {
-		err = got_error_from_errno("socketpair");
-		goto done;
-	}
-	idxpid = fork();
-	if (idxpid == -1) {
-		err= got_error_from_errno("fork");
-		goto done;
-	} else if (idxpid == 0)
-		got_privsep_exec_child(imsg_idxfds,
-		    GOT_PATH_PROG_INDEX_PACK, tmppackpath);
-	if (close(imsg_idxfds[1]) == -1) {
-		err = got_error_from_errno("close");
-		goto done;
-	}
-	imsg_idxfds[1] = -1;
-	imsg_init(&idxibuf, imsg_idxfds[0]);
+	arg.packfile_size = packsiz;
+	arg.progress_cb = progress_cb;
+	arg.progress_arg = progress_arg;
+	arg.cancel_cb = cancel_cb;
+	arg.cancel_arg = cancel_arg;
+	arg.rl = &rl;
 
-	err = got_privsep_send_index_pack_req(&idxibuf, id.sha1, packfd);
+	pack.fd = packfd;
+	pack.filesize = packsiz;
+	err = got_delta_cache_alloc(&pack.delta_cache);
 	if (err)
 		goto done;
-	packfd = -1;
 
-	err = got_privsep_send_index_pack_outfd(&idxibuf, idxfd);
+	err = got_pack_index(&pack, idxfd,
+	    tempfiles[0], tempfiles[1], tempfiles[2], pack_sha1_expected,
+	    pack_index_progress, &arg, &rl);
 	if (err)
 		goto done;
-	idxfd = -1;
 
-	for (i = 0; i < nitems(tmpfds); i++) {
-		err = got_privsep_send_tmpfd(&idxibuf, tmpfds[i]);
-		if (err != NULL)
-			goto done;
-		tmpfds[i] = -1;
-	}
-
-	done = 0;
-	while (!done) {
-		int nobj_total, nobj_indexed, nobj_loose, nobj_resolved;
-
-		err = got_privsep_recv_index_progress(&done, &nobj_total,
-		    &nobj_indexed, &nobj_loose, &nobj_resolved, &idxibuf);
-		if (err)
-			goto done;
-		if (nobj_indexed != 0) {
-			err = load_report_progress(progress_cb, progress_arg,
-			    &rl, packsiz, nobj_total, nobj_indexed,
-			    nobj_loose, nobj_resolved);
-			if (err)
-				goto done;
-		}
-	}
-	if (close(imsg_idxfds[0]) == -1) {
-		err = got_error_from_errno("close");
-		goto done;
-	}
-	imsg_idxfds[0] = -1;
-	if (waitpid(idxpid, &idxstatus, 0) == -1) {
-		err = got_error_from_errno("waitpid");
-		goto done;
-	}
-
 	if (noop)
 		goto done;
 
@@ -524,9 +536,11 @@ got_repo_load(FILE *in, struct got_pathlist_head *refs
 	if (imsg_idxfds[1] != -1 && close(imsg_idxfds[1]) == -1 && err == NULL)
 		err = got_error_from_errno("close");
 
-	for (i = 0; i < nitems(tmpfds); ++i)
-		if (tmpfds[i] != -1 && close(tmpfds[i]) == -1 && err == NULL)
-			err = got_error_from_errno("close");
+	for (i = 0; i < nitems(tempfiles); ++i) {
+		if (tempfiles[i] != NULL && fclose(tempfiles[i]) == EOF &&
+		    err == NULL)
+			err = got_error_from_errno("fclose");
+	}
 
 	return err;
 }
blob - ba7276ad6779e4b6a924ef8284b01c4bbdb79216
blob + cce18fb6b576d23d2081a21f54b3637c7e910aee
--- lib/repository_admin.c
+++ lib/repository_admin.c
@@ -46,15 +46,18 @@
 #include "got_path.h"
 
 #include "got_lib_delta.h"
+#include "got_lib_delta_cache.h"
 #include "got_lib_object.h"
 #include "got_lib_object_idset.h"
 #include "got_lib_object_cache.h"
+#include "got_lib_object_parse.h"
 #include "got_lib_pack.h"
 #include "got_lib_privsep.h"
 #include "got_lib_repository.h"
 #include "got_lib_ratelimit.h"
-#include "got_lib_pack_create.h"
 #include "got_lib_hash.h"
+#include "got_lib_pack_index.h"
+#include "got_lib_pack_create.h"
 #include "got_lib_lockfile.h"
 
 #ifndef nitems
@@ -271,29 +274,58 @@ done:
 	return err;
 }
 
+struct pack_index_progress_arg {
+    off_t packfile_size;
+    got_repo_pack_index_progress_cb progress_cb;
+    void *progress_arg;
+    got_cancel_cb cancel_cb;
+    void *cancel_arg;
+};
+
+static const struct got_error *
+pack_index_progress(void *arg, uint32_t nobj_total, uint32_t nobj_indexed,
+    uint32_t nobj_loose, uint32_t nobj_resolved)
+{
+	const struct got_error *err = NULL;
+	struct pack_index_progress_arg *a = arg;
+
+	if (a->cancel_cb) {
+		err = a->cancel_cb(a->cancel_arg);
+		if (err)
+			return err;
+	}
+
+	if (a->progress_cb) {
+		err = a->progress_cb(a->progress_arg, a->packfile_size,
+		    nobj_total, nobj_indexed, nobj_loose, nobj_resolved);
+	}
+
+	return err;
+}
+
 const struct got_error *
 got_repo_index_pack(FILE *packfile, struct got_object_id *pack_hash,
     struct got_repository *repo,
-    got_pack_index_progress_cb progress_cb, void *progress_arg,
+    got_repo_pack_index_progress_cb progress_cb, void *progress_arg,
     got_cancel_cb cancel_cb, void *cancel_arg)
 {
 	size_t i;
 	char *path;
-	int imsg_idxfds[2];
-	int npackfd = -1, idxfd = -1, nidxfd = -1;
-	int tmpfds[3];
-	int idxstatus, done = 0;
-	const struct got_error *err;
-	struct imsgbuf idxibuf;
-	pid_t idxpid;
+	int idxfd = -1;
+	FILE *tempfiles[3] = { NULL, NULL, NULL };
+	const struct got_error *err, *close_err;
 	char *tmpidxpath = NULL;
 	char *packfile_path = NULL, *idxpath = NULL, *id_str = NULL;
 	const char *repo_path = got_repo_get_path_git_dir(repo);
 	struct stat sb;
+	struct pack_index_progress_arg arg;
+	struct got_pack pack;
+	struct got_ratelimit rl;
 
-	for (i = 0; i < nitems(tmpfds); i++)
-		tmpfds[i] = -1;
+	memset(&pack, 0, sizeof(pack));
 
+	got_ratelimit_init(&rl, 0, 500);
+
 	if (asprintf(&path, "%s/%s/indexing.idx",
 	    repo_path, GOT_OBJECTS_PACK_DIR) == -1) {
 		err = got_error_from_errno("asprintf");
@@ -308,16 +340,10 @@ got_repo_index_pack(FILE *packfile, struct got_object_
 		goto done;
 	}
 
-	nidxfd = dup(idxfd);
-	if (nidxfd == -1) {
-		err = got_error_from_errno("dup");
-		goto done;
-	}
-
-	for (i = 0; i < nitems(tmpfds); i++) {
-		tmpfds[i] = got_opentempfd();
-		if (tmpfds[i] == -1) {
-			err = got_error_from_errno("got_opentempfd");
+	for (i = 0; i < nitems(tempfiles); i++) {
+		tempfiles[i] = got_opentemp();
+		if (tempfiles[i] == NULL) {
+			err = got_error_from_errno("got_opentemp");
 			goto done;
 		}
 	}
@@ -343,74 +369,23 @@ got_repo_index_pack(FILE *packfile, struct got_object_
 		goto done;
 	}
 
-	if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, imsg_idxfds) == -1) {
-		err = got_error_from_errno("socketpair");
-		goto done;
-	}
-	idxpid = fork();
-	if (idxpid == -1) {
-		err= got_error_from_errno("fork");
-		goto done;
-	} else if (idxpid == 0)
-		got_privsep_exec_child(imsg_idxfds,
-		    GOT_PATH_PROG_INDEX_PACK, packfile_path);
-	if (close(imsg_idxfds[1]) == -1) {
-		err = got_error_from_errno("close");
-		goto done;
-	}
-	imsg_init(&idxibuf, imsg_idxfds[0]);
+	arg.packfile_size = sb.st_size;
+	arg.progress_cb = progress_cb;
+	arg.progress_arg = progress_arg;
+	arg.cancel_cb = cancel_cb;
+	arg.cancel_arg = cancel_arg;
 
-	npackfd = dup(fileno(packfile));
-	if (npackfd == -1) {
-		err = got_error_from_errno("dup");
+	pack.fd = fileno(packfile);
+	pack.filesize = sb.st_size;
+	err = got_delta_cache_alloc(&pack.delta_cache);
+	if (err)
 		goto done;
-	}
-	err = got_privsep_send_index_pack_req(&idxibuf, pack_hash->sha1,
-	    npackfd);
-	if (err != NULL)
-		goto done;
-	npackfd = -1;
-	err = got_privsep_send_index_pack_outfd(&idxibuf, nidxfd);
-	if (err != NULL)
-		goto done;
-	nidxfd = -1;
-	for (i = 0; i < nitems(tmpfds); i++) {
-		err = got_privsep_send_tmpfd(&idxibuf, tmpfds[i]);
-		if (err != NULL)
-			goto done;
-		tmpfds[i] = -1;
-	}
-	done = 0;
-	while (!done) {
-		int nobj_total, nobj_indexed, nobj_loose, nobj_resolved;
 
-		if (cancel_cb) {
-			err = cancel_cb(cancel_arg);
-			if (err)
-				goto done;
-		}
-
-		err = got_privsep_recv_index_progress(&done, &nobj_total,
-		    &nobj_indexed, &nobj_loose, &nobj_resolved,
-		    &idxibuf);
-		if (err != NULL)
-			goto done;
-		if (nobj_indexed != 0) {
-			err = progress_cb(progress_arg, sb.st_size,
-			    nobj_total, nobj_indexed, nobj_loose,
-			    nobj_resolved);
-			if (err)
-				break;
-		}
-	}
-	if (close(imsg_idxfds[0]) == -1) {
-		err = got_error_from_errno("close");
+	err = got_pack_index(&pack, idxfd,
+	    tempfiles[0], tempfiles[1], tempfiles[2], pack_hash->sha1,
+	    pack_index_progress, &arg, &rl);
+	if (err)
 		goto done;
-	}
-	if (waitpid(idxpid, &idxstatus, 0) == -1) {
-		err = got_error_from_errno("waitpid");
-		goto done;
-	}
 
 	if (rename(tmpidxpath, idxpath) == -1) {
 		err = got_error_from_errno3("rename", tmpidxpath, idxpath);
@@ -420,15 +395,16 @@ got_repo_index_pack(FILE *packfile, struct got_object_
 	tmpidxpath = NULL;
 
 done:
+	close_err = got_pack_close(&pack);
+	if (close_err && err == NULL)
+		err = close_err;
 	if (tmpidxpath && unlink(tmpidxpath) == -1 && err == NULL)
 		err = got_error_from_errno2("unlink", tmpidxpath);
-	if (npackfd != -1 && close(npackfd) == -1 && err == NULL)
-		err = got_error_from_errno("close");
 	if (idxfd != -1 && close(idxfd) == -1 && err == NULL)
 		err = got_error_from_errno("close");
-	for (i = 0; i < nitems(tmpfds); i++) {
-		if (tmpfds[i] != -1 && close(tmpfds[i]) == -1 && err == NULL)
-			err = got_error_from_errno("close");
+	for (i = 0; i < nitems(tempfiles); i++) {
+		if (tempfiles[i] && fclose(tempfiles[i]) == EOF && err == NULL)
+			err = got_error_from_errno("fclose");
 	}
 	free(tmpidxpath);
 	free(idxpath);
@@ -725,8 +701,7 @@ get_loose_object_ids(struct got_object_idset **loose_i
 				err = got_error_from_errno("fstat");
 				goto done;
 			}
-			err = got_object_read_header_privsep(&obj, &id, repo,
-			    fd);
+			err = got_object_read_header(&obj, fd);
 			if (err)
 				goto done;
 			fd = -1; /* already closed */