commit 28714985ea3c103b203f5a30baaaf582b4961595 from: Stefan Sperling date: Sat Nov 17 15:12:36 2018 UTC add got-read-tag libexec helper commit - f4a881ce8b200e5283247799c39abd2b578b8e75 commit + 28714985ea3c103b203f5a30baaaf582b4961595 blob - ca4265c6c9cffaefb598a20e1a7d751b1b8d97aa blob + f56d5677dd571b5ac1902a52d0f39389be75da6f --- libexec/Makefile +++ libexec/Makefile @@ -1,4 +1,4 @@ SUBDIR = got-read-blob got-read-commit got-read-object got-read-tree \ - got-read-pack + got-read-tag got-read-pack .include blob - /dev/null blob + 64fb2efe9db9a053c27290631e9ae5d09db1a820 (mode 644) --- /dev/null +++ libexec/got-read-tag/Makefile @@ -0,0 +1,20 @@ +.PATH:${.CURDIR}/../../lib + +PROG= got-read-tag +SRCS= got-read-tag.c delta.c error.c inflate.c object_parse.c \ + privsep.c sha1.c + +CPPFLAGS = -I${.CURDIR}/../../include -I${.CURDIR}/../../lib +LDADD = -lutil -lz +DPADD = ${LIBZ} ${LIBUTIL} + +# For now, default to installing binary in ~/bin +GROUP!=id -g -n +install: + ${INSTALL} ${INSTALL_COPY} -o ${USER} -g ${GROUP} \ + -m ${BINMODE} ${PROG} ${GOT_LIBEXECDIR}/${PROG} + +# Don't install man pages yet +NOMAN = Yes + +.include blob - /dev/null blob + b32627b648310e08162d05d9bc6e8d81921b2258 (mode 644) --- /dev/null +++ libexec/got-read-tag/got-read-tag.c @@ -0,0 +1,184 @@ +/* + * Copyright (c) 2018 Stefan Sperling + * + * 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 +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "got_error.h" +#include "got_object.h" + +#include "got_lib_delta.h" +#include "got_lib_inflate.h" +#include "got_lib_object.h" +#include "got_lib_object_parse.h" +#include "got_lib_privsep.h" + +static volatile sig_atomic_t sigint_received; + +static void +catch_sigint(int signo) +{ + sigint_received = 1; +} + +static const struct got_error * +read_tag_object(struct got_tag_object **tag, struct got_object *obj, + FILE *f) +{ + const struct got_error *err = NULL; + size_t len; + uint8_t *p; + + if (obj->flags & GOT_OBJ_FLAG_PACKED) + err = got_read_file_to_mem(&p, &len, f); + else + 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; + } + + /* Skip object header. */ + len -= obj->hdrlen; + err = got_object_parse_tag(tag, p + obj->hdrlen, len); + free(p); +done: + return err; +} + +int +main(int argc, char *argv[]) +{ + const struct got_error *err = NULL; + struct got_tag_object *tag = NULL; + struct imsgbuf ibuf; + size_t datalen; + + signal(SIGINT, catch_sigint); + + imsg_init(&ibuf, GOT_IMSG_FD_CHILD); + +#ifndef PROFILE + /* revoke access to most system calls */ + if (pledge("stdio recvfd", NULL) == -1) { + err = got_error_from_errno(); + got_privsep_send_error(&ibuf, err); + return 1; + } +#endif + + while (1) { + struct imsg imsg; + struct got_imsg_object iobj; + FILE *f = NULL; + struct got_object *obj = NULL; + + if (sigint_received) { + err = got_error(GOT_ERR_CANCELLED); + break; + } + + err = got_privsep_recv_imsg(&imsg, &ibuf, 0); + if (err) { + if (err->code == GOT_ERR_PRIVSEP_PIPE) + err = NULL; + break; + } + + if (imsg.hdr.type == GOT_IMSG_STOP) + break; + + if (imsg.hdr.type != GOT_IMSG_TAG_REQUEST) { + err = got_error(GOT_ERR_PRIVSEP_MSG); + goto done; + } + + datalen = imsg.hdr.len - IMSG_HEADER_SIZE; + if (datalen != sizeof(iobj)) { + err = got_error(GOT_ERR_PRIVSEP_LEN); + goto done; + } + + memcpy(&iobj, imsg.data, sizeof(iobj)); + if (iobj.type != GOT_OBJ_TYPE_TAG) { + err = got_error(GOT_ERR_OBJ_TYPE); + goto done; + } + + if (imsg.fd == -1) { + err = got_error(GOT_ERR_PRIVSEP_NO_FD); + goto done; + } + + obj = calloc(1, sizeof(*obj)); + if (obj == NULL) { + err = got_error_from_errno(); + goto done; + } + obj->type = iobj.type; + obj->hdrlen = iobj.hdrlen; + obj->size = iobj.size; + + /* Always assume file offset zero. */ + f = fdopen(imsg.fd, "rb"); + if (f == NULL) { + err = got_error_from_errno(); + goto done; + } + + err = read_tag_object(&tag, obj, f); + if (err) + goto done; + + err = got_privsep_send_tag(&ibuf, tag); +done: + if (f) + fclose(f); + else if (imsg.fd != -1) + close(imsg.fd); + imsg_free(&imsg); + if (obj) + got_object_close(obj); + if (err) + break; + } + + imsg_clear(&ibuf); + if (err) { + if (!sigint_received && err->code != GOT_ERR_PRIVSEP_PIPE) { + fprintf(stderr, "%s: %s\n", getprogname(), err->msg); + got_privsep_send_error(&ibuf, err); + } + } + close(GOT_IMSG_FD_CHILD); + return err ? 1 : 0; +}