commit - b36429aba0124d4bc92ec4dd7b285ace7abfcaee
commit + 7762fe12f8608c112ccb3bbada7235a2c4208fd0
blob - d0e80bc31edd85aea3d8e095d680ea7b47a23d0c
blob + be5add975f075e866935ce17ed6496c3e1439b20
--- lib/commit_graph.c
+++ lib/commit_graph.c
}
static const struct got_error *
-detect_changed_path(int *changed, struct got_commit_object *commit,
+detect_changed_path(int *changed, struct got_commit_object_mini *commit,
struct got_object_id *commit_id, const char *path,
struct got_repository *repo)
{
const struct got_error *err = NULL;
- struct got_commit_object *pcommit = NULL;
+ struct got_commit_object_mini *pcommit = NULL;
struct got_tree_object *tree = NULL, *ptree = NULL;
struct got_object_qid *pid;
*changed = 1; /* The path was created in this commit. */
free(obj_id);
} else {
- err = got_object_open_as_commit(&pcommit, repo, pid->id);
+ err = got_object_open_mini_commit(&pcommit, repo, pid->id);
if (err)
goto done;
if (ptree)
got_object_tree_close(ptree);
if (pcommit)
- got_object_commit_close(pcommit);
+ got_object_mini_commit_close(pcommit);
return err;
}
static const struct got_error *
advance_branch(struct got_commit_graph *graph,
struct got_commit_graph_node *node,
- struct got_object_id *commit_id, struct got_commit_object *commit,
+ struct got_object_id *commit_id, struct got_commit_object_mini *commit,
struct got_repository *repo)
{
const struct got_error *err;
static const struct got_error *
add_node(struct got_commit_graph_node **new_node,
struct got_commit_graph *graph, struct got_object_id *commit_id,
- struct got_commit_object *commit, struct got_commit_graph_node *child_node,
- struct got_repository *repo)
+ struct got_commit_object_mini *commit,
+ struct got_commit_graph_node *child_node, struct got_repository *repo)
{
const struct got_error *err = NULL;
struct got_commit_graph_node *node;
int first_parent_traversal, struct got_repository *repo)
{
const struct got_error *err = NULL;
- struct got_commit_object *commit;
+ struct got_commit_object_mini *commit;
*graph = NULL;
- err = got_object_open_as_commit(&commit, repo, commit_id);
+ err = got_object_open_mini_commit(&commit, repo, commit_id);
if (err)
return err;
*graph = alloc_graph(path);
if (*graph == NULL) {
- got_object_commit_close(commit);
+ got_object_mini_commit_close(commit);
return got_error_from_errno();
}
err = add_node(&(*graph)->head_node, *graph, commit_id, commit, NULL,
repo);
- got_object_commit_close(commit);
+ got_object_mini_commit_close(commit);
if (err) {
got_commit_graph_close(*graph);
*graph = NULL;
for (i = 0; i < arg.ntips; i++) {
struct got_object_id *commit_id;
struct got_commit_graph_node *child_node, *new_node;
- struct got_commit_object *commit;
+ struct got_commit_object_mini *commit;
int changed;
commit_id = &graph->tips[i].id;
child_node = graph->tips[i].node;
- err = got_object_open_as_commit(&commit, repo, commit_id);
+ err = got_object_open_mini_commit(&commit, repo, commit_id);
if (err)
break;
err = detect_changed_path(&changed, commit, commit_id,
graph->path, repo);
if (err) {
- got_object_commit_close(commit);
+ got_object_mini_commit_close(commit);
if (err->code != GOT_ERR_NO_OBJ)
break;
err = close_branch(graph, commit_id);
*changed_id = commit_id;
err = add_node(&new_node, graph, commit_id, commit, child_node,
repo);
- got_object_commit_close(commit);
+ got_object_mini_commit_close(commit);
if (err)
break;
if (new_node)
{
const struct got_error *err = NULL;
struct got_commit_graph_node *start_node;
- struct got_commit_object *commit;
+ struct got_commit_object_mini *commit;
int changed;
start_node = got_object_idset_get(graph->node_ids, id);
if (start_node == NULL)
return got_error(GOT_ERR_NO_OBJ);
- err = got_object_open_as_commit(&commit, repo, &start_node->id);
+ err = got_object_open_mini_commit(&commit, repo, &start_node->id);
if (err)
return err;
err = detect_changed_path(&changed, commit, &start_node->id,
graph->path, repo);
if (err) {
- got_object_commit_close(commit);
+ got_object_mini_commit_close(commit);
return err;
}
err = fetch_commits_from_open_branches(&ncommits,
&changed_id, graph, repo);
if (err) {
- got_object_commit_close(commit);
+ got_object_mini_commit_close(commit);
return err;
}
}
start_node = got_object_idset_get(graph->node_ids, changed_id);
}
- got_object_commit_close(commit);
+ got_object_mini_commit_close(commit);
graph->iter_node = start_node;
return NULL;
blob - fc8b2eef010a4a07760e360d7e9102d16791ddbd
blob + 95f019e89afcbce1f16aa9d9641ca1a175c5eec1
--- lib/got_lib_object.h
+++ lib/got_lib_object.h
uint8_t *read_buf;
struct got_object_id id;
};
+
+/* Small version of got_commit_object. Used by commit graph. */
+struct got_commit_object_mini {
+ struct got_object_id *tree_id;
+ unsigned int nparents;
+ struct got_object_id_queue parent_ids;
+ struct tm tm_committer; /* UTC */
+};
+
+const struct got_error *
+got_object_open_mini_commit(struct got_commit_object_mini **,
+ struct got_repository *, struct got_object_id *);
+void got_object_mini_commit_close(struct got_commit_object_mini *);
blob - b427544ee597fb40d4802b61166507af2c7f124e
blob + 99f5e6bdf1e4f1b801b6f3c9b5241f99b89c4231
--- lib/got_lib_object_parse.h
+++ lib/got_lib_object_parse.h
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
+const struct got_error *got_object_qid_alloc_partial(struct got_object_qid **);
struct got_commit_object *got_object_commit_alloc_partial(void);
+struct got_commit_object_mini *got_object_mini_commit_alloc_partial(void);
+const struct got_error *got_object_commit_add_parent(struct got_commit_object *,
+ const char *);
struct got_tree_entry *got_alloc_tree_entry_partial(void);
const struct got_error *got_object_read_header_privsep(struct got_object**,
struct got_repository *repo, int);
const struct got_error *got_object_read_commit_privsep(
struct got_commit_object **, struct got_object *, int,
struct got_repository *);
+const struct got_error *got_object_read_mini_commit_privsep(
+ struct got_commit_object_mini **, struct got_object *, int,
+ struct got_repository *);
const struct got_error *got_object_read_tree_privsep(struct got_tree_object **,
struct got_object *, int, struct got_repository *);
const struct got_error *got_object_parse_commit(struct got_commit_object **,
char *, size_t);
+const struct got_error *got_object_parse_mini_commit(
+ struct got_commit_object_mini **, char *, size_t);
const struct got_error *got_object_parse_tree(struct got_tree_object **,
uint8_t *, size_t);
const struct got_error *got_read_file_to_mem(uint8_t **, size_t *, FILE *);
struct got_object_id *);
const struct got_error *got_object_read_packed_commit_privsep(
struct got_commit_object **, struct got_object *, struct got_pack *);
+const struct got_error *got_object_read_packed_mini_commit_privsep(
+ struct got_commit_object_mini **, struct got_object *, struct got_pack *);
const struct got_error *got_object_read_packed_tree_privsep(
struct got_tree_object **, struct got_object *, struct got_pack *);
blob - b39f11fe79428dd8bc9691d9b8b2300171346459
blob + e343c376c6a64789812c5c88e965304898f5d7d4
--- lib/got_lib_privsep.h
+++ lib/got_lib_privsep.h
GOT_IMSG_COMMIT_REQUEST,
GOT_IMSG_COMMIT,
GOT_IMSG_COMMIT_LOGMSG,
+ GOT_IMSG_MINI_COMMIT_REQUEST,
+ GOT_IMSG_MINI_COMMIT,
GOT_IMSG_TREE_REQUEST,
GOT_IMSG_TREE,
GOT_IMSG_TREE_ENTRY,
*/
} __attribute__((__packed__));
+/* Structure for GOT_IMSG_MINI_COMMIT data. */
+struct got_imsg_commit_object_mini {
+ uint8_t tree_id[SHA1_DIGEST_LENGTH];
+ struct tm tm_committer;
+ int nparents;
+ /* Followed by 'nparents' SHA1_DIGEST_LENGTH length strings */
+} __attribute__((__packed__));
+
/* Structure for GOT_IMSG_TREE_ENTRY. */
struct got_imsg_tree_entry {
char id[SHA1_DIGEST_LENGTH];
struct imsgbuf *);
const struct got_error *got_privsep_send_commit(struct imsgbuf *,
struct got_commit_object *);
+const struct got_error *got_privsep_send_mini_commit(struct imsgbuf *,
+ struct got_commit_object_mini *);
const struct got_error *got_privsep_recv_commit(struct got_commit_object **,
struct imsgbuf *);
+const struct got_error *got_privsep_recv_mini_commit(
+ struct got_commit_object_mini **, struct imsgbuf *);
const struct got_error *got_privsep_recv_tree(struct got_tree_object **,
struct imsgbuf *);
const struct got_error *got_privsep_send_tree(struct imsgbuf *,
struct got_pack *, struct got_packidx *);
const struct got_error *got_privsep_send_packed_obj_req(struct imsgbuf *, int,
struct got_object_id *);
-const struct got_error *got_privsep_send_pack_child_ready(struct imsgbuf *);
+const struct got_error *got_privsep_send_mini_commit_req(struct imsgbuf *, int,
+ struct got_object *);
blob - c58c241572783b631a3bb336ed0daab98750a241
blob + de22dce4277a47abcc56218844d0eb77281f29be
--- lib/object.c
+++ lib/object.c
if (err == NULL) {
(*commit)->refcnt++;
err = got_repo_cache_commit(repo, &obj->id, *commit);
+ }
+
+ return err;
+}
+
+static const struct got_error *
+open_mini_commit(struct got_commit_object_mini **commit,
+ struct got_repository *repo, struct got_object *obj)
+{
+ const struct got_error *err = NULL;
+
+ *commit = NULL;
+
+ if (obj->type != GOT_OBJ_TYPE_COMMIT)
+ return got_error(GOT_ERR_OBJ_TYPE);
+
+ if (obj->flags & GOT_OBJ_FLAG_PACKED) {
+ struct got_pack *pack;
+ pack = got_repo_get_cached_pack(repo, obj->path_packfile);
+ if (pack == NULL) {
+ err = got_repo_cache_pack(&pack, repo,
+ obj->path_packfile, NULL);
+ if (err)
+ return err;
+ }
+ err = got_object_read_packed_mini_commit_privsep(commit, obj,
+ pack);
+ } else {
+ int fd;
+ err = open_loose_object(&fd, obj, repo);
+ if (err)
+ return err;
+ err = got_object_read_mini_commit_privsep(commit, obj, fd,
+ repo);
+ close(fd);
}
return err;
struct got_repository *repo, struct got_object *obj)
{
return open_commit(commit, repo, obj, 1);
+}
+
+const struct got_error *
+got_object_open_mini_commit(struct got_commit_object_mini **commit,
+ struct got_repository *repo, struct got_object_id *id)
+{
+ const struct got_error *err;
+ struct got_object *obj;
+
+ err = got_object_open(&obj, repo, id);
+ if (err)
+ return err;
+ if (got_object_get_type(obj) != GOT_OBJ_TYPE_COMMIT) {
+ err = got_error(GOT_ERR_OBJ_TYPE);
+ goto done;
+ }
+
+ err = open_mini_commit(commit, repo, obj);
+done:
+ got_object_close(obj);
+ return err;
}
const struct got_error *
return err;
}
-
static const struct got_error *
request_commit(struct got_commit_object **commit, struct got_repository *repo,
struct got_object *obj, int fd)
return err;
return got_privsep_recv_commit(commit, ibuf);
+}
+
+static const struct got_error *
+request_mini_commit(struct got_commit_object_mini **commit,
+ struct got_repository *repo, struct got_object *obj, int fd)
+{
+ const struct got_error *err = NULL;
+ struct imsgbuf *ibuf;
+
+ ibuf = repo->privsep_children[GOT_REPO_PRIVSEP_CHILD_COMMIT].ibuf;
+
+ err = got_privsep_send_mini_commit_req(ibuf, fd, obj);
+ if (err)
+ return err;
+
+ return got_privsep_recv_mini_commit(commit, ibuf);
}
const struct got_error *
}
const struct got_error *
+got_object_read_packed_mini_commit_privsep(struct got_commit_object_mini **commit,
+ struct got_object *obj, struct got_pack *pack)
+{
+ const struct got_error *err = NULL;
+
+ err = got_privsep_send_mini_commit_req(pack->privsep_child->ibuf, -1,
+ obj);
+ if (err)
+ return err;
+
+ return got_privsep_recv_mini_commit(commit, pack->privsep_child->ibuf);
+}
+
+const struct got_error *
got_object_read_commit_privsep(struct got_commit_object **commit,
struct got_object *obj, int obj_fd, struct got_repository *repo)
{
return request_commit(commit, repo, obj, obj_fd);
}
+const struct got_error *
+got_object_read_mini_commit_privsep(struct got_commit_object_mini **commit,
+ struct got_object *obj, int obj_fd, struct got_repository *repo)
+{
+ int imsg_fds[2];
+ pid_t pid;
+ struct imsgbuf *ibuf;
+
+ if (repo->privsep_children[GOT_REPO_PRIVSEP_CHILD_COMMIT].imsg_fd != -1)
+ return request_mini_commit(commit, repo, obj, obj_fd);
+
+ ibuf = calloc(1, sizeof(*ibuf));
+ if (ibuf == NULL)
+ return got_error_from_errno();
+
+ if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, imsg_fds) == -1)
+ return got_error_from_errno();
+
+ pid = fork();
+ if (pid == -1)
+ return got_error_from_errno();
+ else if (pid == 0) {
+ exec_privsep_child(imsg_fds, GOT_PATH_PROG_READ_COMMIT,
+ repo->path);
+ /* not reached */
+ }
+
+ close(imsg_fds[1]);
+ repo->privsep_children[GOT_REPO_PRIVSEP_CHILD_COMMIT].imsg_fd =
+ imsg_fds[0];
+ repo->privsep_children[GOT_REPO_PRIVSEP_CHILD_COMMIT].pid = pid;
+ imsg_init(ibuf, imsg_fds[0]);
+ repo->privsep_children[GOT_REPO_PRIVSEP_CHILD_COMMIT].ibuf = ibuf;
+
+ return request_mini_commit(commit, repo, obj, obj_fd);
+}
+
static const struct got_error *
request_tree(struct got_tree_object **tree, struct got_repository *repo,
struct got_object *obj, int fd)
blob - 07d52651602537e5df106ea314f3770df1ffb56f
blob + ebf46135eb8eed76cb6a8e760c20294fcdb3cc06
--- lib/object_parse.c
+++ lib/object_parse.c
#include "got_lib_sha1.h"
#include "got_lib_delta.h"
-#include "got_lib_privsep.h"
-#include "got_lib_pack.h"
#include "got_lib_inflate.h"
#include "got_lib_object.h"
+#include "got_lib_privsep.h"
+#include "got_lib_pack.h"
#include "got_lib_object_cache.h"
#include "got_lib_repository.h"
free(obj);
}
+const struct got_error *
+got_object_qid_alloc_partial(struct got_object_qid **qid)
+{
+ const struct got_error *err = NULL;
+
+ *qid = malloc(sizeof(**qid));
+ if (*qid == NULL)
+ return got_error_from_errno();
+
+ (*qid)->id = malloc(sizeof(*((*qid)->id)));
+ if ((*qid)->id == NULL) {
+ err = got_error_from_errno();
+ got_object_qid_free(*qid);
+ *qid = NULL;
+ }
+ return err;
+}
+
void
got_object_qid_free(struct got_object_qid *qid)
{
return commit;
}
+struct got_commit_object_mini *
+got_object_mini_commit_alloc_partial(void)
+{
+ struct got_commit_object_mini *commit;
+
+ commit = calloc(1, sizeof(*commit));
+ if (commit == NULL)
+ return NULL;
+ commit->tree_id = calloc(1, sizeof(*commit->tree_id));
+ if (commit->tree_id == NULL) {
+ free(commit);
+ return NULL;
+ }
+
+ SIMPLEQ_INIT(&commit->parent_ids);
+
+ return commit;
+}
+
const struct got_error *
got_object_commit_add_parent(struct got_commit_object *commit,
const char *id_str)
const struct got_error *err = NULL;
struct got_object_qid *qid;
- qid = malloc(sizeof(*qid));
- if (qid == NULL)
- return got_error_from_errno();
-
- qid->id = malloc(sizeof(*qid->id));
- if (qid->id == NULL) {
- err = got_error_from_errno();
- got_object_qid_free(qid);
+ err = got_object_qid_alloc_partial(&qid);
+ if (err)
return err;
+
+ if (!got_parse_sha1_digest(qid->id->sha1, id_str)) {
+ err = got_error(GOT_ERR_BAD_OBJ_DATA);
+ free(qid->id);
+ free(qid);
+ return err;
}
+ SIMPLEQ_INSERT_TAIL(&commit->parent_ids, qid, entry);
+ commit->nparents++;
+
+ return NULL;
+}
+
+const struct got_error *
+got_object_mini_commit_add_parent(struct got_commit_object_mini *commit,
+ const char *id_str)
+{
+ const struct got_error *err = NULL;
+ struct got_object_qid *qid;
+
+ err = got_object_qid_alloc_partial(&qid);
+ if (err)
+ return err;
+
if (!got_parse_sha1_digest(qid->id->sha1, id_str)) {
err = got_error(GOT_ERR_BAD_OBJ_DATA);
free(qid->id);
free(commit);
}
+void
+got_object_mini_commit_close(struct got_commit_object_mini *commit)
+{
+ struct got_object_qid *qid;
+
+ while (!SIMPLEQ_EMPTY(&commit->parent_ids)) {
+ qid = SIMPLEQ_FIRST(&commit->parent_ids);
+ SIMPLEQ_REMOVE_HEAD(&commit->parent_ids, entry);
+ got_object_qid_free(qid);
+ }
+
+ free(commit->tree_id);
+ free(commit);
+}
+
const struct got_error *
-got_object_parse_commit(struct got_commit_object **commit, char *buf, size_t len)
+got_object_parse_commit(struct got_commit_object **commit, char *buf,
+ size_t len)
{
const struct got_error *err = NULL;
char *s = buf;
size_t tlen;
ssize_t remain = (ssize_t)len;
-
+
*commit = got_object_commit_alloc_partial();
if (*commit == NULL)
return got_error_from_errno();
return err;
}
+const struct got_error *
+got_object_parse_mini_commit(struct got_commit_object_mini **commit, char *buf,
+ size_t len)
+{
+ const struct got_error *err = NULL;
+ char *s = buf;
+ size_t tlen;
+ ssize_t remain = (ssize_t)len;
+
+ *commit = got_object_mini_commit_alloc_partial();
+ if (*commit == NULL)
+ return got_error_from_errno();
+
+ tlen = strlen(GOT_COMMIT_TAG_TREE);
+ if (strncmp(s, GOT_COMMIT_TAG_TREE, tlen) == 0) {
+ remain -= tlen;
+ if (remain < SHA1_DIGEST_STRING_LENGTH) {
+ err = got_error(GOT_ERR_BAD_OBJ_DATA);
+ goto done;
+ }
+ s += tlen;
+ if (!got_parse_sha1_digest((*commit)->tree_id->sha1, s)) {
+ err = got_error(GOT_ERR_BAD_OBJ_DATA);
+ goto done;
+ }
+ remain -= SHA1_DIGEST_STRING_LENGTH;
+ s += SHA1_DIGEST_STRING_LENGTH;
+ } else {
+ err = got_error(GOT_ERR_BAD_OBJ_DATA);
+ goto done;
+ }
+
+ tlen = strlen(GOT_COMMIT_TAG_PARENT);
+ while (strncmp(s, GOT_COMMIT_TAG_PARENT, tlen) == 0) {
+ remain -= tlen;
+ if (remain < SHA1_DIGEST_STRING_LENGTH) {
+ err = got_error(GOT_ERR_BAD_OBJ_DATA);
+ goto done;
+ }
+ s += tlen;
+ err = got_object_mini_commit_add_parent(*commit, s);
+ if (err)
+ goto done;
+
+ remain -= SHA1_DIGEST_STRING_LENGTH;
+ s += SHA1_DIGEST_STRING_LENGTH;
+ }
+
+ tlen = strlen(GOT_COMMIT_TAG_AUTHOR);
+ if (strncmp(s, GOT_COMMIT_TAG_AUTHOR, tlen) == 0) {
+ char *p;
+ size_t slen;
+
+ remain -= tlen;
+ if (remain <= 0) {
+ err = got_error(GOT_ERR_BAD_OBJ_DATA);
+ goto done;
+ }
+ s += tlen;
+ p = strchr(s, '\n');
+ if (p == NULL) {
+ err = got_error(GOT_ERR_BAD_OBJ_DATA);
+ goto done;
+ }
+ *p = '\0';
+ slen = strlen(s);
+ s += slen + 1;
+ remain -= slen + 1;
+ }
+
+ tlen = strlen(GOT_COMMIT_TAG_COMMITTER);
+ if (strncmp(s, GOT_COMMIT_TAG_COMMITTER, tlen) == 0) {
+ char *p;
+ size_t slen;
+
+ remain -= tlen;
+ if (remain <= 0) {
+ err = got_error(GOT_ERR_BAD_OBJ_DATA);
+ goto done;
+ }
+ s += tlen;
+ p = strchr(s, '\n');
+ if (p == NULL) {
+ err = got_error(GOT_ERR_BAD_OBJ_DATA);
+ goto done;
+ }
+ *p = '\0';
+ slen = strlen(s);
+ err = parse_commit_time(&(*commit)->tm_committer, s);
+ if (err)
+ goto done;
+ s += slen + 1;
+ remain -= slen + 1;
+ }
+
+done:
+ if (err) {
+ got_object_mini_commit_close(*commit);
+ *commit = NULL;
+ }
+ return err;
+}
+
void
got_object_tree_entry_close(struct got_tree_entry *te)
{
blob - 2429a9462a3a8c43c3d457557c231213747aec54
blob + e0d4a53bb329a1f39e987e8ef293e4e850ef4b36
--- lib/privsep.c
+++ lib/privsep.c
return err;
}
+static void
+init_imsg_object(struct got_imsg_object *iobj, struct got_object *obj)
+{
+ memcpy(iobj->id, obj->id.sha1, sizeof(iobj->id));
+ iobj->type = obj->type;
+ iobj->flags = obj->flags;
+ iobj->hdrlen = obj->hdrlen;
+ iobj->size = obj->size;
+ if (iobj->flags & GOT_OBJ_FLAG_PACKED) {
+ iobj->pack_offset = obj->pack_offset;
+ iobj->pack_idx = obj->pack_idx;
+ }
+}
+
const struct got_error *
got_privsep_send_obj_req(struct imsgbuf *ibuf, int fd, struct got_object *obj)
{
return got_error(GOT_ERR_OBJ_TYPE);
}
- memcpy(iobj.id, obj->id.sha1, sizeof(iobj.id));
- iobj.type = obj->type;
- iobj.flags = obj->flags;
- iobj.hdrlen = obj->hdrlen;
- iobj.size = obj->size;
- if (iobj.flags & GOT_OBJ_FLAG_PACKED) {
- iobj.pack_offset = obj->pack_offset;
- iobj.pack_idx = obj->pack_idx;
- }
+ init_imsg_object(&iobj, obj);
iobjp = &iobj;
iobj_size = sizeof(iobj);
}
const struct got_error *
+got_privsep_send_mini_commit_req(struct imsgbuf *ibuf, int fd,
+ struct got_object *obj)
+{
+ struct got_imsg_object iobj, *iobjp;
+ size_t iobj_size;
+
+ if (obj->type != GOT_OBJ_TYPE_COMMIT)
+ return got_error(GOT_ERR_OBJ_TYPE);
+
+ init_imsg_object(&iobj, obj);
+
+ iobjp = &iobj;
+ iobj_size = sizeof(iobj);
+
+ if (imsg_compose(ibuf, GOT_IMSG_MINI_COMMIT_REQUEST, 0, 0, fd,
+ iobjp, iobj_size) == -1)
+ return got_error_from_errno();
+
+ return flush_imsg(ibuf);
+}
+
+const struct got_error *
got_privsep_send_blob_req(struct imsgbuf *ibuf, int infd)
{
if (imsg_compose(ibuf, GOT_IMSG_BLOB_REQUEST, 0, 0, infd, NULL, 0)
done:
free(buf);
return err;
+}
+
+const struct got_error *
+got_privsep_send_mini_commit(struct imsgbuf *ibuf,
+ struct got_commit_object_mini *commit)
+{
+ const struct got_error *err = NULL;
+ struct got_imsg_commit_object_mini icommit;
+ uint8_t *buf;
+ size_t len, total;
+ struct got_object_qid *qid;
+
+ memcpy(icommit.tree_id, commit->tree_id->sha1, sizeof(icommit.tree_id));
+ memcpy(&icommit.tm_committer, &commit->tm_committer,
+ sizeof(icommit.tm_committer));
+ icommit.nparents = commit->nparents;
+
+ total = sizeof(icommit) + icommit.nparents * SHA1_DIGEST_LENGTH;
+
+ buf = malloc(total);
+ if (buf == NULL)
+ return got_error_from_errno();
+
+ len = 0;
+ memcpy(buf + len, &icommit, sizeof(icommit));
+ len += sizeof(icommit);
+ SIMPLEQ_FOREACH(qid, &commit->parent_ids, entry) {
+ memcpy(buf + len, qid->id, SHA1_DIGEST_LENGTH);
+ len += SHA1_DIGEST_LENGTH;
+ }
+
+ if (imsg_compose(ibuf, GOT_IMSG_MINI_COMMIT, 0, 0, -1,
+ buf, len) == -1) {
+ err = got_error_from_errno();
+ }
+
+ free(buf);
+ if (err)
+ return err;
+ return flush_imsg(ibuf);
}
const struct got_error *
for (i = 0; i < icommit.nparents; i++) {
struct got_object_qid *qid;
- qid = calloc(1, sizeof(*qid));
- if (qid == NULL) {
- err = got_error_from_errno();
+ err = got_object_qid_alloc_partial(&qid);
+ if (err)
break;
- }
- qid->id = calloc(1, sizeof(*qid->id));
- if (qid->id == NULL) {
- err = got_error_from_errno();
- free(qid);
+
+ memcpy(qid->id, data + len + i * SHA1_DIGEST_LENGTH,
+ sizeof(*qid->id));
+ SIMPLEQ_INSERT_TAIL(&(*commit)->parent_ids, qid, entry);
+ (*commit)->nparents++;
+ }
+ break;
+ default:
+ err = got_error(GOT_ERR_PRIVSEP_MSG);
+ break;
+ }
+
+ imsg_free(&imsg);
+
+ return err;
+}
+
+const struct got_error *
+got_privsep_recv_mini_commit(struct got_commit_object_mini **commit,
+ struct imsgbuf *ibuf)
+{
+ const struct got_error *err = NULL;
+ struct imsg imsg;
+ struct got_imsg_commit_object_mini icommit;
+ size_t len, datalen;
+ int i;
+ const size_t min_datalen =
+ MIN(sizeof(struct got_imsg_error),
+ sizeof(struct got_imsg_commit_object_mini));
+ uint8_t *data;
+
+ *commit = NULL;
+
+ err = got_privsep_recv_imsg(&imsg, ibuf, min_datalen);
+ if (err)
+ return err;
+
+ data = imsg.data;
+ datalen = imsg.hdr.len - IMSG_HEADER_SIZE;
+ len = 0;
+
+ switch (imsg.hdr.type) {
+ case GOT_IMSG_ERROR:
+ err = recv_imsg_error(&imsg, datalen);
+ break;
+ case GOT_IMSG_MINI_COMMIT:
+ if (datalen < sizeof(icommit)) {
+ err = got_error(GOT_ERR_PRIVSEP_LEN);
+ break;
+ }
+
+ memcpy(&icommit, data, sizeof(icommit));
+ if (datalen != sizeof(icommit) +
+ icommit.nparents * SHA1_DIGEST_LENGTH) {
+ err = got_error(GOT_ERR_PRIVSEP_LEN);
+ break;
+ }
+ if (icommit.nparents < 0) {
+ err = got_error(GOT_ERR_PRIVSEP_LEN);
+ break;
+ }
+ len += sizeof(icommit);
+
+ *commit = got_object_mini_commit_alloc_partial();
+ if (*commit == NULL) {
+ err = got_error_from_errno();
+ break;
+ }
+
+ memcpy((*commit)->tree_id->sha1, icommit.tree_id,
+ SHA1_DIGEST_LENGTH);
+ memcpy(&(*commit)->tm_committer, &icommit.tm_committer,
+ sizeof((*commit)->tm_committer));
+
+ for (i = 0; i < icommit.nparents; i++) {
+ struct got_object_qid *qid;
+
+ err = got_object_qid_alloc_partial(&qid);
+ if (err)
break;
- }
memcpy(qid->id, data + len + i * SHA1_DIGEST_LENGTH,
sizeof(*qid->id));
blob - f6b5435605333d42433c5981a64efdc3cb4b18e6
blob + 49187ef259affaaff4c947f46d12fb23afb35738
--- libexec/got-read-commit/got-read-commit.c
+++ libexec/got-read-commit/got-read-commit.c
#include "got_lib_privsep.h"
static const struct got_error *
-read_commit_object(struct got_commit_object **commit, struct got_object *obj,
- FILE *f)
+read_commit_data(uint8_t **p, size_t *len, struct got_object *obj, FILE *f)
{
- const struct got_error *err = NULL;
- size_t len;
- uint8_t *p;
+ const struct got_error *err;
if (obj->flags & GOT_OBJ_FLAG_PACKED)
- err = got_read_file_to_mem(&p, &len, f);
+ err = got_read_file_to_mem(p, len, f);
else
- err = got_inflate_to_mem(&p, &len, f);
+ err = got_inflate_to_mem(p, len, f);
if (err)
return err;
- if (len < obj->hdrlen + obj->size) {
- err = got_error(GOT_ERR_BAD_OBJ_DATA);
- goto done;
+ if (*len < obj->hdrlen + obj->size) {
+ free(*p);
+ *p = NULL;
+ *len = 0;
+ return got_error(GOT_ERR_BAD_OBJ_DATA);
}
/* Skip object header. */
- len -= obj->hdrlen;
+ *len -= obj->hdrlen;
+ return NULL;
+}
+
+static const struct got_error *
+read_commit_object(struct got_commit_object **commit, struct got_object *obj,
+ FILE *f)
+{
+ const struct got_error *err;
+ uint8_t *p;
+ size_t len;
+
+ err = read_commit_data(&p, &len, obj, f);
+ if (err)
+ return err;
+
err = got_object_parse_commit(commit, p + obj->hdrlen, len);
free(p);
-done:
return err;
}
+static const struct got_error *
+read_commit_object_mini(struct got_commit_object_mini **commit,
+ struct got_object *obj, FILE *f)
+{
+ const struct got_error *err;
+ size_t len;
+ uint8_t *p;
+
+ err = read_commit_data(&p, &len, obj, f);
+ if (err)
+ return err;
+
+ err = got_object_parse_mini_commit(commit, p + obj->hdrlen, len);
+ free(p);
+ return err;
+}
+
int
main(int argc, char *argv[])
{
const struct got_error *err = NULL;
- struct got_commit_object *commit = NULL;
struct imsgbuf ibuf;
size_t datalen;
struct got_imsg_object iobj;
FILE *f = NULL;
struct got_object *obj = NULL;
+ int mini = 0;
err = got_privsep_recv_imsg(&imsg, &ibuf, 0);
if (err) {
if (imsg.hdr.type == GOT_IMSG_STOP)
break;
- if (imsg.hdr.type != GOT_IMSG_COMMIT_REQUEST) {
- err = got_error(GOT_ERR_PRIVSEP_MSG);
- goto done;
+ switch (imsg.hdr.type) {
+ case GOT_IMSG_COMMIT_REQUEST:
+ mini = 0;
+ break;
+ case GOT_IMSG_MINI_COMMIT_REQUEST:
+ mini = 1;
+ break;
+ default:
+ err = got_error(GOT_ERR_PRIVSEP_MSG);
+ goto done;
}
datalen = imsg.hdr.len - IMSG_HEADER_SIZE;
goto done;
}
- err = read_commit_object(&commit, obj, f);
- if (err)
- goto done;
-
- err = got_privsep_send_commit(&ibuf, commit);
+ if (mini) {
+ struct got_commit_object_mini *commit;
+ err = read_commit_object_mini(&commit, obj, f);
+ if (err)
+ goto done;
+ err = got_privsep_send_mini_commit(&ibuf, commit);
+ got_object_mini_commit_close(commit);
+ } else {
+ struct got_commit_object *commit;
+ err = read_commit_object(&commit, obj, f);
+ if (err)
+ goto done;
+ err = got_privsep_send_commit(&ibuf, commit);
+ got_object_commit_close(commit);
+ }
done:
if (f)
fclose(f);
blob - 010b14b5519db260c50522b9ffb8d93182af1675
blob + 1a4046e49b76e09595fd6cb02c2779592713c7c2
--- libexec/got-read-pack/got-read-pack.c
+++ libexec/got-read-pack/got-read-pack.c
if (obj)
got_object_close(obj);
got_object_commit_close(commit);
+ if (err) {
+ if (err->code == GOT_ERR_PRIVSEP_PIPE)
+ err = NULL;
+ else
+ got_privsep_send_error(ibuf, err);
+ }
+
+ return err;
+}
+
+static const struct got_error *
+mini_commit_request(struct imsg *imsg, struct imsgbuf *ibuf,
+ struct got_pack *pack, struct got_packidx *packidx,
+ struct got_object_cache *objcache)
+{
+ const struct got_error *err = NULL;
+ struct got_object *obj = NULL;
+ struct got_commit_object_mini *commit = NULL;
+ uint8_t *buf;
+ size_t len;
+
+ err = get_object(&obj, imsg, ibuf, pack, packidx, objcache,
+ GOT_OBJ_TYPE_COMMIT);
+ if (err)
+ return err;
+
+ err = got_packfile_extract_object_to_mem(&buf, &len, obj, pack);
+ if (err)
+ return err;
+
+ obj->size = len;
+ err = got_object_parse_mini_commit(&commit, buf, len);
+ free(buf);
+
+ err = got_privsep_send_mini_commit(ibuf, commit);
+ if (obj)
+ got_object_close(obj);
+ got_object_mini_commit_close(commit);
if (err) {
if (err->code == GOT_ERR_PRIVSEP_PIPE)
err = NULL;
err = commit_request(&imsg, &ibuf, pack, packidx,
&objcache);
break;
+ case GOT_IMSG_MINI_COMMIT_REQUEST:
+ err = mini_commit_request(&imsg, &ibuf, pack, packidx,
+ &objcache);
+ break;
case GOT_IMSG_TREE_REQUEST:
err = tree_request(&imsg, &ibuf, pack, packidx,
&objcache);