commit - f024663dea0dea05a0d4c17d2314f38f73e85bc6
commit + bd3d9e54cb422cb58d52b267c6a8afc3376842d2
blob - /dev/null
blob + 436c3e0854074e30dfdfca92ce23d908e5c94bbf (mode 644)
--- /dev/null
+++ lib/gitproto.c
+/*
+ * Copyright (c) 2019 Ori Bernstein <ori@openbsd.org>
+ * Copyright (c) 2021 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/queue.h>
+
+#include <ctype.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "got_error.h"
+#include "got_path.h"
+
+#include "got_lib_gitproto.h"
+
+#ifndef nitems
+#define nitems(_a) (sizeof((_a)) / sizeof((_a)[0]))
+#endif
+
+static const struct got_error *
+tokenize_refline(char **tokens, char *line, int len, int maxtokens)
+{
+ const struct got_error *err = NULL;
+ char *p;
+ size_t i, n = 0;
+
+ for (i = 0; i < maxtokens; i++)
+ tokens[i] = NULL;
+
+ for (i = 0; n < len && i < maxtokens; i++) {
+ while (isspace(*line)) {
+ line++;
+ n++;
+ }
+ p = line;
+ while (*line != '\0' && n < len &&
+ (!isspace(*line) || i == maxtokens - 1)) {
+ line++;
+ n++;
+ }
+ tokens[i] = strndup(p, line - p);
+ if (tokens[i] == NULL) {
+ err = got_error_from_errno("strndup");
+ goto done;
+ }
+ /* Skip \0 field-delimiter at end of token. */
+ while (line[0] == '\0' && n < len) {
+ line++;
+ n++;
+ }
+ }
+ if (i <= 2)
+ err = got_error(GOT_ERR_BAD_PACKET);
+done:
+ if (err) {
+ int j;
+ for (j = 0; j < i; j++) {
+ free(tokens[j]);
+ tokens[j] = NULL;
+ }
+ }
+ return err;
+}
+
+const struct got_error *
+got_gitproto_parse_refline(char **id_str, char **refname,
+ char **server_capabilities, char *line, int len)
+{
+ const struct got_error *err = NULL;
+ char *tokens[3];
+
+ err = tokenize_refline(tokens, line, len, nitems(tokens));
+ if (err)
+ return err;
+
+ if (tokens[0])
+ *id_str = tokens[0];
+ if (tokens[1])
+ *refname = tokens[1];
+ if (tokens[2]) {
+ char *p;
+ *server_capabilities = tokens[2];
+ p = strrchr(*server_capabilities, '\n');
+ if (p)
+ *p = '\0';
+ }
+
+ return NULL;
+}
+
+static const struct got_error *
+match_capability(char **my_capabilities, const char *capa,
+ const struct got_capability *mycapa)
+{
+ char *equalsign;
+ char *s;
+
+ equalsign = strchr(capa, '=');
+ if (equalsign) {
+ if (strncmp(capa, mycapa->key, equalsign - capa) != 0)
+ return NULL;
+ } else {
+ if (strcmp(capa, mycapa->key) != 0)
+ return NULL;
+ }
+
+ if (asprintf(&s, "%s %s%s%s",
+ *my_capabilities != NULL ? *my_capabilities : "",
+ mycapa->key,
+ mycapa->value != NULL ? "=" : "",
+ mycapa->value != NULL? mycapa->value : "") == -1)
+ return got_error_from_errno("asprintf");
+
+ free(*my_capabilities);
+ *my_capabilities = s;
+ return NULL;
+}
+
+static const struct got_error *
+add_symref(struct got_pathlist_head *symrefs, char *capa)
+{
+ const struct got_error *err = NULL;
+ char *colon, *name = NULL, *target = NULL;
+
+ /* Need at least "A:B" */
+ if (strlen(capa) < 3)
+ return NULL;
+
+ colon = strchr(capa, ':');
+ if (colon == NULL)
+ return NULL;
+
+ *colon = '\0';
+ name = strdup(capa);
+ if (name == NULL)
+ return got_error_from_errno("strdup");
+
+ target = strdup(colon + 1);
+ if (target == NULL) {
+ err = got_error_from_errno("strdup");
+ goto done;
+ }
+
+ /* We can't validate the ref itself here. The main process will. */
+ err = got_pathlist_append(symrefs, name, target);
+done:
+ if (err) {
+ free(name);
+ free(target);
+ }
+ return err;
+}
+
+const struct got_error *
+got_gitproto_match_capabilities(char **common_capabilities,
+ struct got_pathlist_head *symrefs, char *server_capabilities,
+ const struct got_capability my_capabilities[], size_t ncapa)
+{
+ const struct got_error *err = NULL;
+ char *capa, *equalsign;
+ size_t i;
+
+ *common_capabilities = NULL;
+ do {
+ capa = strsep(&server_capabilities, " ");
+ if (capa == NULL)
+ return NULL;
+
+ equalsign = strchr(capa, '=');
+ if (equalsign != NULL && symrefs != NULL &&
+ strncmp(capa, "symref", equalsign - capa) == 0) {
+ err = add_symref(symrefs, equalsign + 1);
+ if (err)
+ break;
+ continue;
+ }
+
+ for (i = 0; i < ncapa; i++) {
+ err = match_capability(common_capabilities,
+ capa, &my_capabilities[i]);
+ if (err)
+ break;
+ }
+ } while (capa);
+
+ if (*common_capabilities == NULL) {
+ *common_capabilities = strdup("");
+ if (*common_capabilities == NULL)
+ err = got_error_from_errno("strdup");
+ }
+ return err;
+}
blob - /dev/null
blob + cffe349e03b4a8a0cd9126b511ed9198af1c3c57 (mode 644)
--- /dev/null
+++ lib/got_lib_gitproto.h
+/*
+ * Copyright (c) 2019 Ori Bernstein <ori@openbsd.org>
+ * Copyright (c) 2021 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.
+ */
+
+#define GOT_CAPA_AGENT "agent"
+#define GOT_CAPA_OFS_DELTA "ofs-delta"
+#define GOT_CAPA_SIDE_BAND_64K "side-band-64k"
+#define GOT_CAPA_REPORT_STATUS "report-status"
+#define GOT_CAPA_DELETE_REFS "delete-refs"
+
+#define GOT_SIDEBAND_PACKFILE_DATA 1
+#define GOT_SIDEBAND_PROGRESS_INFO 2
+#define GOT_SIDEBAND_ERROR_INFO 3
+
+struct got_capability {
+ const char *key;
+ const char *value;
+};
+
+struct got_pathlist_head;
+
+const struct got_error *got_gitproto_parse_refline(char **id_str,
+ char **refname, char **server_capabilities, char *line, int len);
+const struct got_error *got_gitproto_match_capabilities(
+ char **common_capabilities,
+ struct got_pathlist_head *symrefs, char *server_capabilities,
+ const struct got_capability my_capabilities[], size_t ncapa);
blob - 322eb5182bf517fe519edba355c7eb691286ed23
blob + 7df6b00656bdfc711605a13a29e30f4b21aa2f3a
--- libexec/got-fetch-pack/Makefile
+++ libexec/got-fetch-pack/Makefile
PROG= got-fetch-pack
SRCS= got-fetch-pack.c error.c inflate.c object_parse.c \
- path.c privsep.c sha1.c pkt.c
+ path.c privsep.c sha1.c pkt.c gitproto.c
CPPFLAGS = -I${.CURDIR}/../../include -I${.CURDIR}/../../lib
LDADD = -lutil -lz
blob - 1b1a71e4dc4357b0153e9ebfa2b776af69bf006b
blob + 42a19bfb5390548d4249bd5c2f9432a6a853b121
--- libexec/got-fetch-pack/got-fetch-pack.c
+++ libexec/got-fetch-pack/got-fetch-pack.c
#include "got_lib_privsep.h"
#include "got_lib_pack.h"
#include "got_lib_pkt.h"
+#include "got_lib_gitproto.h"
#ifndef nitems
#define nitems(_a) (sizeof((_a)) / sizeof((_a)[0]))
static int chattygot;
static struct got_object_id zhash = {.sha1={0}};
+static const struct got_capability got_capabilities[] = {
+ { GOT_CAPA_AGENT, "got/" GOT_VERSION_STR },
+ { GOT_CAPA_OFS_DELTA, NULL },
+ { GOT_CAPA_SIDE_BAND_64K, NULL },
+};
+
static void
match_remote_ref(struct got_pathlist_head *have_refs,
struct got_object_id *my_id, char *refname)
/* Allow exact match. */
return (strcmp(refname, wanted_ref) == 0);
-}
-
-static const struct got_error *
-tokenize_refline(char **tokens, char *line, int len, int maxtokens)
-{
- const struct got_error *err = NULL;
- char *p;
- size_t i, n = 0;
-
- for (i = 0; i < maxtokens; i++)
- tokens[i] = NULL;
-
- for (i = 0; n < len && i < maxtokens; i++) {
- while (isspace(*line)) {
- line++;
- n++;
- }
- p = line;
- while (*line != '\0' && n < len &&
- (!isspace(*line) || i == maxtokens - 1)) {
- line++;
- n++;
- }
- tokens[i] = strndup(p, line - p);
- if (tokens[i] == NULL) {
- err = got_error_from_errno("strndup");
- goto done;
- }
- /* Skip \0 field-delimiter at end of token. */
- while (line[0] == '\0' && n < len) {
- line++;
- n++;
- }
- }
- if (i <= 2)
- err = got_error(GOT_ERR_BAD_PACKET);
-done:
- if (err) {
- int j;
- for (j = 0; j < i; j++) {
- free(tokens[j]);
- tokens[j] = NULL;
- }
- }
- return err;
-}
-
-static const struct got_error *
-parse_refline(char **id_str, char **refname, char **server_capabilities,
- char *line, int len)
-{
- const struct got_error *err = NULL;
- char *tokens[3];
-
- err = tokenize_refline(tokens, line, len, nitems(tokens));
- if (err)
- return err;
-
- if (tokens[0])
- *id_str = tokens[0];
- if (tokens[1])
- *refname = tokens[1];
- if (tokens[2]) {
- char *p;
- *server_capabilities = tokens[2];
- p = strrchr(*server_capabilities, '\n');
- if (p)
- *p = '\0';
- }
-
- return NULL;
-}
-
-#define GOT_CAPA_AGENT "agent"
-#define GOT_CAPA_OFS_DELTA "ofs-delta"
-#define GOT_CAPA_SIDE_BAND_64K "side-band-64k"
-
-#define GOT_SIDEBAND_PACKFILE_DATA 1
-#define GOT_SIDEBAND_PROGRESS_INFO 2
-#define GOT_SIDEBAND_ERROR_INFO 3
-
-
-struct got_capability {
- const char *key;
- const char *value;
-};
-static const struct got_capability got_capabilities[] = {
- { GOT_CAPA_AGENT, "got/" GOT_VERSION_STR },
- { GOT_CAPA_OFS_DELTA, NULL },
- { GOT_CAPA_SIDE_BAND_64K, NULL },
-};
-
-static const struct got_error *
-match_capability(char **my_capabilities, const char *capa,
- const struct got_capability *mycapa)
-{
- char *equalsign;
- char *s;
-
- equalsign = strchr(capa, '=');
- if (equalsign) {
- if (strncmp(capa, mycapa->key, equalsign - capa) != 0)
- return NULL;
- } else {
- if (strcmp(capa, mycapa->key) != 0)
- return NULL;
- }
-
- if (asprintf(&s, "%s %s%s%s",
- *my_capabilities != NULL ? *my_capabilities : "",
- mycapa->key,
- mycapa->value != NULL ? "=" : "",
- mycapa->value != NULL? mycapa->value : "") == -1)
- return got_error_from_errno("asprintf");
-
- free(*my_capabilities);
- *my_capabilities = s;
- return NULL;
-}
-
-static const struct got_error *
-add_symref(struct got_pathlist_head *symrefs, char *capa)
-{
- const struct got_error *err = NULL;
- char *colon, *name = NULL, *target = NULL;
-
- /* Need at least "A:B" */
- if (strlen(capa) < 3)
- return NULL;
-
- colon = strchr(capa, ':');
- if (colon == NULL)
- return NULL;
-
- *colon = '\0';
- name = strdup(capa);
- if (name == NULL)
- return got_error_from_errno("strdup");
-
- target = strdup(colon + 1);
- if (target == NULL) {
- err = got_error_from_errno("strdup");
- goto done;
- }
-
- /* We can't validate the ref itself here. The main process will. */
- err = got_pathlist_append(symrefs, name, target);
-done:
- if (err) {
- free(name);
- free(target);
- }
- return err;
}
static const struct got_error *
-match_capabilities(char **my_capabilities, struct got_pathlist_head *symrefs,
- char *server_capabilities)
-{
- const struct got_error *err = NULL;
- char *capa, *equalsign;
- size_t i;
-
- *my_capabilities = NULL;
- do {
- capa = strsep(&server_capabilities, " ");
- if (capa == NULL)
- return NULL;
-
- equalsign = strchr(capa, '=');
- if (equalsign != NULL &&
- strncmp(capa, "symref", equalsign - capa) == 0) {
- err = add_symref(symrefs, equalsign + 1);
- if (err)
- break;
- continue;
- }
-
- for (i = 0; i < nitems(got_capabilities); i++) {
- err = match_capability(my_capabilities,
- capa, &got_capabilities[i]);
- if (err)
- break;
- }
- } while (capa);
-
- if (*my_capabilities == NULL) {
- *my_capabilities = strdup("");
- if (*my_capabilities == NULL)
- err = got_error_from_errno("strdup");
- }
- return err;
-}
-
-static const struct got_error *
send_fetch_server_progress(struct imsgbuf *ibuf, const char *msg, size_t msglen)
{
if (msglen > MAX_IMSGSIZE - IMSG_HEADER_SIZE)
return got_privsep_flush_imsg(ibuf);
}
-
-
static const struct got_error *
fetch_progress(struct imsgbuf *ibuf, const char *buf, size_t len)
{
err = fetch_error(&buf[4], n - 4);
goto done;
}
- err = parse_refline(&id_str, &refname, &server_capabilities,
- buf, n);
+ err = got_gitproto_parse_refline(&id_str, &refname,
+ &server_capabilities, buf, n);
if (err)
goto done;
if (is_firstpkt) {
if (chattygot && server_capabilities[0] != '\0')
fprintf(stderr, "%s: server capabilities: %s\n",
getprogname(), server_capabilities);
- err = match_capabilities(&my_capabilities, &symrefs,
- server_capabilities);
+ err = got_gitproto_match_capabilities(&my_capabilities,
+ &symrefs, server_capabilities,
+ got_capabilities, nitems(got_capabilities));
if (err)
goto done;
if (chattygot)
blob - ddc73e59aea2891c17b777b954fffa3a0bec90c6
blob + c4d5d83a73cd53d7437213cdf349daaec168facd
--- libexec/got-send-pack/Makefile
+++ libexec/got-send-pack/Makefile
PROG= got-send-pack
SRCS= got-send-pack.c error.c inflate.c object_parse.c \
- path.c privsep.c sha1.c pkt.c
+ path.c privsep.c sha1.c pkt.c gitproto.c
CPPFLAGS = -I${.CURDIR}/../../include -I${.CURDIR}/../../lib
LDADD = -lutil -lz
blob - 059def3f0aaec687446cd952534fdb52768ea4d8
blob + fc22714cab99aae6b98600a9b4c3bfdb0815c41c
--- libexec/got-send-pack/got-send-pack.c
+++ libexec/got-send-pack/got-send-pack.c
#include "got_lib_privsep.h"
#include "got_lib_pack.h"
#include "got_lib_pkt.h"
+#include "got_lib_gitproto.h"
#ifndef nitems
#define nitems(_a) (sizeof((_a)) / sizeof((_a)[0]))
struct got_object *indexed;
static int chattygot;
-static const struct got_error *
-tokenize_refline(char **tokens, char *line, int len, int maxtokens)
-{
- const struct got_error *err = NULL;
- char *p;
- size_t i, n = 0;
-
- for (i = 0; i < maxtokens; i++)
- tokens[i] = NULL;
-
- for (i = 0; n < len && i < maxtokens; i++) {
- while (isspace(*line)) {
- line++;
- n++;
- }
- p = line;
- while (*line != '\0' && n < len &&
- (!isspace(*line) || i == maxtokens - 1)) {
- line++;
- n++;
- }
- tokens[i] = strndup(p, line - p);
- if (tokens[i] == NULL) {
- err = got_error_from_errno("strndup");
- goto done;
- }
- /* Skip \0 field-delimiter at end of token. */
- while (line[0] == '\0' && n < len) {
- line++;
- n++;
- }
- }
- if (i <= 2)
- err = got_error(GOT_ERR_NOT_REF);
-done:
- if (err) {
- int j;
- for (j = 0; j < i; j++) {
- free(tokens[j]);
- tokens[j] = NULL;
- }
- }
- return err;
-}
-
-static const struct got_error *
-parse_refline(char **id_str, char **refname, char **server_capabilities,
- char *line, int len)
-{
- const struct got_error *err = NULL;
- char *tokens[3];
-
- err = tokenize_refline(tokens, line, len, nitems(tokens));
- if (err)
- return err;
-
- if (tokens[0])
- *id_str = tokens[0];
- if (tokens[1])
- *refname = tokens[1];
- if (tokens[2]) {
- char *p;
- *server_capabilities = tokens[2];
- p = strrchr(*server_capabilities, '\n');
- if (p)
- *p = '\0';
- }
-
- return NULL;
-}
-
-#define GOT_CAPA_AGENT "agent"
-#define GOT_CAPA_OFS_DELTA "ofs-delta"
-#define GOT_CAPA_SIDE_BAND_64K "side-band-64k"
-#define GOT_CAPA_REPORT_STATUS "report-status"
-#define GOT_CAPA_DELETE_REFS "delete-refs"
-
-#define GOT_SIDEBAND_PACKFILE_DATA 1
-#define GOT_SIDEBAND_PROGRESS_INFO 2
-#define GOT_SIDEBAND_ERROR_INFO 3
-
-
-struct got_capability {
- const char *key;
- const char *value;
-};
static const struct got_capability got_capabilities[] = {
{ GOT_CAPA_AGENT, "got/" GOT_VERSION_STR },
{ GOT_CAPA_OFS_DELTA, NULL },
{ GOT_CAPA_REPORT_STATUS, NULL },
{ GOT_CAPA_DELETE_REFS, NULL },
};
-
-static const struct got_error *
-match_capability(char **my_capabilities, const char *capa,
- const struct got_capability *mycapa)
-{
- char *equalsign;
- char *s;
-
- equalsign = strchr(capa, '=');
- if (equalsign) {
- if (strncmp(capa, mycapa->key, equalsign - capa) != 0)
- return NULL;
- } else {
- if (strcmp(capa, mycapa->key) != 0)
- return NULL;
- }
-
- if (asprintf(&s, "%s %s%s%s",
- *my_capabilities != NULL ? *my_capabilities : "",
- mycapa->key,
- mycapa->value != NULL ? "=" : "",
- mycapa->value != NULL? mycapa->value : "") == -1)
- return got_error_from_errno("asprintf");
-
- free(*my_capabilities);
- *my_capabilities = s;
- return NULL;
-}
-
-static const struct got_error *
-match_capabilities(char **my_capabilities, char *server_capabilities)
-{
- const struct got_error *err = NULL;
- char *capa;
- size_t i;
-
- *my_capabilities = NULL;
- do {
- capa = strsep(&server_capabilities, " ");
- for (i = 0; capa != NULL && i < nitems(got_capabilities); i++) {
- err = match_capability(my_capabilities,
- capa, &got_capabilities[i]);
- if (err)
- goto done;
- }
- } while (capa);
-
- if (*my_capabilities == NULL) {
- *my_capabilities = strdup("");
- if (*my_capabilities == NULL) {
- err = got_error_from_errno("strdup");
- goto done;
- }
- }
-done:
- if (err) {
- free(*my_capabilities);
- *my_capabilities = NULL;
- }
- return err;
-}
static const struct got_error *
send_upload_progress(struct imsgbuf *ibuf, off_t bytes)
err = send_error(&buf[4], n - 4);
goto done;
}
- err = parse_refline(&id_str, &refname, &server_capabilities,
- buf, n);
+ err = got_gitproto_parse_refline(&id_str, &refname,
+ &server_capabilities, buf, n);
if (err)
goto done;
if (is_firstpkt) {
if (chattygot && server_capabilities[0] != '\0')
fprintf(stderr, "%s: server capabilities: %s\n",
getprogname(), server_capabilities);
- err = match_capabilities(&my_capabilities,
- server_capabilities);
+ err = got_gitproto_match_capabilities(&my_capabilities,
+ NULL, server_capabilities, got_capabilities,
+ nitems(got_capabilities));
if (err)
goto done;
if (chattygot)