commit - dee2c213ed24c0b0fa01f22f144e5088e2b028e0
commit + 3022d2728c5aaec4a574a76d30136d850fa5d154
blob - cc4f1837befaa2cccdec42ad171967f789314e22
blob + cea99150c7215d78de30a954486bf415f2000bb2
--- lib/got_lib_object_parse.h
+++ lib/got_lib_object_parse.h
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
+struct got_pathlist_head;
+
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_tree_entry *got_alloc_tree_entry_partial(void);
const struct got_error *got_object_parse_commit(struct got_commit_object **,
char *, size_t);
-const struct got_error *got_object_parse_tree(struct got_tree_object **,
+
+/*
+ * In a pathlist returned by got_object_parse_tree(), a pointer to the entry's
+ * name is stored in the pathlist element's path, while the pathlist element's
+ * data pointer points to a struct got_parsed_tree_entry.
+ */
+struct got_parsed_tree_entry {
+ mode_t mode; /* Mode parsed from tree buffer. */
+ uint8_t *id; /* Points to ID in parsed tree buffer. */
+};
+const struct got_error *got_object_parse_tree(struct got_pathlist_head *, int *,
uint8_t *, size_t);
+
const struct got_error *got_object_parse_tag(struct got_tag_object **,
uint8_t *, size_t);
const struct got_error *got_read_file_to_mem(uint8_t **, size_t *, FILE *);
blob - f1e7f2ad14684a954b1bc1e9b4a6195cc963c7c3
blob + a37a450e6e18733afec74aa1dc9cb427c9d27acb
--- lib/got_lib_privsep.h
+++ lib/got_lib_privsep.h
struct got_pack;
struct got_packidx;
+struct got_pathlist_head;
const struct got_error *got_privsep_wait_for_child(pid_t);
const struct got_error *got_privsep_send_stop(int);
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_tree_object *);
+ struct got_pathlist_head *, int);
const struct got_error *got_privsep_send_blob(struct imsgbuf *, size_t, size_t,
const uint8_t *);
const struct got_error *got_privsep_recv_blob(uint8_t **, size_t *, size_t *,
blob - 9a37c6f1d7c6414382484dbde632c0fb6bb7591e
blob + 912407084a50328b63f743b536ff77698ad6d979
--- lib/object_parse.c
+++ lib/object_parse.c
#include "got_lib_delta.h"
#include "got_lib_inflate.h"
#include "got_lib_object.h"
+#include "got_lib_object_parse.h"
#include "got_lib_object_cache.h"
#include "got_lib_pack.h"
#include "got_lib_privsep.h"
}
static const struct got_error *
-parse_tree_entry(struct got_tree_entry **te, size_t *elen, char *buf,
+parse_tree_entry(struct got_parsed_tree_entry **pte, const char **name,
+ size_t *elen, char *buf,
size_t maxlen)
{
char *p, *space;
const struct got_error *err = NULL;
+ *name = NULL;
*elen = 0;
- *te = got_alloc_tree_entry_partial();
- if (*te == NULL)
- return got_error_from_errno("got_alloc_tree_entry_partial");
+ *pte = malloc(sizeof(**pte));
+ if (*pte == NULL)
+ return got_error_from_errno("malloc");
*elen = strnlen(buf, maxlen) + 1;
if (*elen > maxlen) {
- free(*te);
- *te = NULL;
+ free(*pte);
+ *pte = NULL;
return got_error(GOT_ERR_BAD_OBJ_DATA);
}
space = memchr(buf, ' ', *elen);
if (space == NULL || space <= buf) {
err = got_error(GOT_ERR_BAD_OBJ_DATA);
- free(*te);
- *te = NULL;
+ free(*pte);
+ *pte = NULL;
return err;
}
- (*te)->mode = 0;
+ (*pte)->mode = 0;
p = buf;
while (p < space) {
if (*p < '0' && *p > '7') {
err = got_error(GOT_ERR_BAD_OBJ_DATA);
goto done;
}
- (*te)->mode <<= 3;
- (*te)->mode |= *p - '0';
+ (*pte)->mode <<= 3;
+ (*pte)->mode |= *p - '0';
p++;
}
- (*te)->name = strdup(space + 1);
if (*elen > maxlen || maxlen - *elen < SHA1_DIGEST_LENGTH) {
err = got_error(GOT_ERR_BAD_OBJ_DATA);
goto done;
}
+ *name = space + 1;
buf += *elen;
- memcpy((*te)->id->sha1, buf, SHA1_DIGEST_LENGTH);
+ (*pte)->id = buf;
*elen += SHA1_DIGEST_LENGTH;
done:
if (err) {
- got_object_tree_entry_close(*te);
- *te = NULL;
+ free(*pte);
+ *pte = NULL;
}
return err;
}
const struct got_error *
-got_object_parse_tree(struct got_tree_object **tree, uint8_t *buf, size_t len)
+got_object_parse_tree(struct got_pathlist_head *entries, int *nentries,
+ uint8_t *buf, size_t len)
{
- const struct got_error *err;
+ const struct got_error *err = NULL;
size_t remain = len;
- struct got_pathlist_head pathlist;
- struct got_pathlist_entry *pe;
- TAILQ_INIT(&pathlist);
-
- *tree = calloc(1, sizeof(**tree));
- if (*tree == NULL)
- return got_error_from_errno("calloc");
-
- SIMPLEQ_INIT(&(*tree)->entries.head);
-
+ *nentries = 0;
if (remain == 0)
return NULL; /* tree is empty */
while (remain > 0) {
- struct got_tree_entry *te;
+ struct got_parsed_tree_entry *pte;
struct got_pathlist_entry *new = NULL;
+ const char *name;
size_t elen;
- err = parse_tree_entry(&te, &elen, buf, remain);
+ err = parse_tree_entry(&pte, &name, &elen, buf, remain);
if (err)
goto done;
- err = got_pathlist_insert(&new, &pathlist, te->name, te);
+ err = got_pathlist_insert(&new, entries, name, pte);
if (err)
goto done;
if (new == NULL) {
}
buf += elen;
remain -= elen;
+ (*nentries)++;
}
if (remain != 0) {
- got_object_tree_close(*tree);
- *tree = NULL;
err = got_error(GOT_ERR_BAD_OBJ_DATA);
goto done;
}
-
- TAILQ_FOREACH(pe, &pathlist, entry) {
- struct got_tree_entry *te = pe->data;
- (*tree)->entries.nentries++;
- SIMPLEQ_INSERT_TAIL(&(*tree)->entries.head, te, entry);
+done:
+ if (err) {
+ got_pathlist_free(entries);
+ *nentries = 0;
}
-done:
- got_pathlist_free(&pathlist);
return err;
}
blob - 62a79cfc9798d9720d38528272f0681cb10d18d6
blob + 0de060802f8b78d6297fc9f7e91c7d607bf57a53
--- lib/privsep.c
+++ lib/privsep.c
#include "got_object.h"
#include "got_error.h"
+#include "got_path.h"
#include "got_lib_sha1.h"
#include "got_lib_delta.h"
}
const struct got_error *
-got_privsep_send_tree(struct imsgbuf *ibuf, struct got_tree_object *tree)
+got_privsep_send_tree(struct imsgbuf *ibuf, struct got_pathlist_head *entries,
+ int nentries)
{
const struct got_error *err = NULL;
struct got_imsg_tree_object itree;
- struct got_tree_entry *te;
+ struct got_pathlist_entry *pe;
size_t totlen;
int nimsg; /* number of imsg queued in ibuf */
- itree.nentries = tree->entries.nentries;
+ itree.nentries = nentries;
if (imsg_compose(ibuf, GOT_IMSG_TREE, 0, 0, -1, &itree, sizeof(itree))
== -1)
return got_error_from_errno("imsg_compose TREE");
totlen = sizeof(itree);
nimsg = 1;
- SIMPLEQ_FOREACH(te, &tree->entries.head, entry) {
- struct got_imsg_tree_entry *ite;
- uint8_t *buf = NULL;
- size_t len = sizeof(*ite) + strlen(te->name);
+ TAILQ_FOREACH(pe, entries, entry) {
+ const char *name = pe->path;
+ struct got_parsed_tree_entry *pte = pe->data;
+ struct ibuf *wbuf;
+ size_t namelen = strlen(name);
+ size_t len = sizeof(struct got_imsg_tree_object) + namelen;
if (len > MAX_IMSGSIZE)
return got_error(GOT_ERR_NO_SPACE);
nimsg = 0;
}
- buf = malloc(len);
- if (buf == NULL)
- return got_error_from_errno("malloc");
-
- ite = (struct got_imsg_tree_entry *)buf;
- memcpy(ite->id, te->id->sha1, sizeof(ite->id));
- ite->mode = te->mode;
- memcpy(buf + sizeof(*ite), te->name, strlen(te->name));
+ wbuf = imsg_create(ibuf, GOT_IMSG_TREE_ENTRY, 0, 0, len);
+ if (wbuf == NULL)
+ return got_error_from_errno("imsg_create TREE_ENTRY");
- if (imsg_compose(ibuf, GOT_IMSG_TREE_ENTRY, 0, 0, -1,
- buf, len) == -1)
- err = got_error_from_errno("imsg_compose TREE_ENTRY");
- free(buf);
+ /* Keep in sync with struct got_imsg_tree_object definition! */
+ if (imsg_add(wbuf, pte->id, SHA1_DIGEST_LENGTH) == -1)
+ err = got_error_from_errno("imsg_add TREE_ENTRY");
if (err)
return err;
+ if (imsg_add(wbuf, &pte->mode, sizeof(pte->mode)) == -1)
+ err = got_error_from_errno("imsg_add TREE_ENTRY");
+ if (err)
+ return err;
+
+ if (imsg_add(wbuf, name, namelen) == -1)
+ err = got_error_from_errno("imsg_add TREE_ENTRY");
+ if (err)
+ return err;
+
+ wbuf->fd = -1;
+ imsg_close(ibuf, wbuf);
+
totlen += len;
}
blob - d8c2e0f8683a4492064ae0e7be3d35a1c6b485f0
blob + f130a21a81e49ebf7483be526ba5b6ea351b3c91
--- libexec/got-read-pack/got-read-pack.c
+++ libexec/got-read-pack/got-read-pack.c
#include "got_error.h"
#include "got_object.h"
+#include "got_path.h"
#include "got_lib_delta.h"
#include "got_lib_delta_cache.h"
const struct got_error *err = NULL;
struct got_imsg_packed_object iobj;
struct got_object *obj = NULL;
- struct got_tree_object *tree = NULL;
+ struct got_pathlist_head entries;
+ int nentries = 0;
uint8_t *buf = NULL;
size_t len;
struct got_object_id id;
size_t datalen;
+ TAILQ_INIT(&entries);
+
datalen = imsg->hdr.len - IMSG_HEADER_SIZE;
if (datalen != sizeof(iobj))
return got_error(GOT_ERR_PRIVSEP_LEN);
goto done;
obj->size = len;
- err = got_object_parse_tree(&tree, buf, len);
+ err = got_object_parse_tree(&entries, &nentries, buf, len);
if (err)
goto done;
- err = got_privsep_send_tree(ibuf, tree);
+ err = got_privsep_send_tree(ibuf, &entries, nentries);
done:
+ got_pathlist_free(&entries);
free(buf);
got_object_close(obj);
- if (tree)
- got_object_tree_close(tree);
if (err) {
if (err->code == GOT_ERR_PRIVSEP_PIPE)
err = NULL;
blob - 78ffcce7e549655d0c7079dc856ef58d54c92163
blob + 3e24db2fa40abdd99961db56310f1a4814f29c71
--- libexec/got-read-tree/got-read-tree.c
+++ libexec/got-read-tree/got-read-tree.c
#include "got_error.h"
#include "got_object.h"
+#include "got_path.h"
#include "got_lib_delta.h"
#include "got_lib_inflate.h"
{
sigint_received = 1;
}
+
static const struct got_error *
-read_tree_object(struct got_tree_object **tree, FILE *f)
+read_tree_object(struct got_pathlist_head *entries, int *nentries,
+ uint8_t **p, FILE *f)
{
const struct got_error *err = NULL;
struct got_object *obj;
size_t len;
- uint8_t *p;
- err = got_inflate_to_mem(&p, &len, f);
+ err = got_inflate_to_mem(p, &len, f);
if (err)
return err;
- err = got_object_parse_header(&obj, p, len);
+ err = got_object_parse_header(&obj, *p, len);
if (err)
return err;
/* Skip object header. */
len -= obj->hdrlen;
- err = got_object_parse_tree(tree, p + obj->hdrlen, len);
+ err = got_object_parse_tree(entries, nentries, *p + obj->hdrlen, len);
done:
- free(p);
got_object_close(obj);
return err;
}
for (;;) {
struct imsg imsg;
FILE *f = NULL;
- struct got_tree_object *tree = NULL;
+ struct got_pathlist_head entries;
+ int nentries = 0;
+ uint8_t *buf = NULL;
+ TAILQ_INIT(&entries);
+
if (sigint_received) {
err = got_error(GOT_ERR_CANCELLED);
break;
goto done;
}
- err = read_tree_object(&tree, f);
+ err = read_tree_object(&entries, &nentries, &buf, f);
if (err)
goto done;
- err = got_privsep_send_tree(&ibuf, tree);
+ err = got_privsep_send_tree(&ibuf, &entries, nentries);
done:
+ got_pathlist_free(&entries);
+ free(buf);
if (f) {
if (fclose(f) != 0 && err == NULL)
err = got_error_from_errno("fclose");