Commit Diff


commit - 2f1457c6ccfe722888511926c09af843da3bee0d
commit + cfd923335bc72b12508df8bafe2f19ea43ddd4ad
blob - 5f1429f97e35fc3f76e9a1054a203794f783e4c7
blob + 9f8fd66bdc02da906718a52f5b0e4e0bb496cd15
--- libexec/got-read-gotconfig/gotconfig.h
+++ libexec/got-read-gotconfig/gotconfig.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020 Tracey Emery <tracey@openbsd.org>
+ * Copyright (c) 2020, 2021 Tracey Emery <tracey@openbsd.org>
  * Copyright (c) 2020 Stefan Sperling <stsp@openbsd.org>
  *
  * Permission to use, copy, modify, and distribute this software for any
@@ -15,6 +15,24 @@
  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
+struct fetch_repo {
+	char	*fetch_name;
+	char	*fetch_repository;
+	char	*fetch_server;
+	char	*fetch_protocol;
+	int	fetch_port;
+	struct	node_branch *fetch_branch;
+};
+
+struct send_repo {
+	char	*send_name;
+	char	*send_repository;
+	char	*send_server;
+	char	*send_protocol;
+	int	send_port;
+	struct	node_branch *send_branch;
+};
+
 struct node_branch {
 	char *branch_name;
 	struct node_branch *next;
@@ -38,6 +56,8 @@ struct gotconfig_remote_repo {
 	int	fetch_all_branches;
 	struct	node_branch *branch;
 	struct	node_ref *ref;
+	struct	fetch_repo *fetch_repo;
+	struct	send_repo *send_repo;
 };
 TAILQ_HEAD(gotconfig_remote_repo_list, gotconfig_remote_repo);
 
blob - 821eff3050b8f45ad0cd9b5475874eca2aa1117d
blob + e12f2c34c3e5addd43b684bada46247e724ecf1d
--- libexec/got-read-gotconfig/parse.y
+++ libexec/got-read-gotconfig/parse.y
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020 Tracey Emery <tracey@openbsd.org>
+ * Copyright (c) 2020, 2021 Tracey Emery <tracey@openbsd.org>
  * Copyright (c) 2020 Stefan Sperling <stsp@openbsd.org>
  * Copyright (c) 2004, 2005 Esben Norby <norby@openbsd.org>
  * Copyright (c) 2004 Ryan McBride <mcbride@openbsd.org>
@@ -81,6 +81,8 @@ static const struct got_error* gerror;
 static struct gotconfig_remote_repo *remote;
 static struct gotconfig gotconfig;
 static const struct got_error* new_remote(struct gotconfig_remote_repo **);
+static const struct got_error* new_fetch(struct fetch_repo **);
+static const struct got_error* new_send(struct send_repo **);
 
 typedef struct {
 	union {
@@ -96,7 +98,7 @@ typedef struct {
 
 %token	ERROR
 %token	REMOTE REPOSITORY SERVER PORT PROTOCOL MIRROR_REFERENCES BRANCH
-%token	AUTHOR FETCH_ALL_BRANCHES REFERENCE
+%token	AUTHOR FETCH_ALL_BRANCHES REFERENCE FETCH SEND
 %token	<v.string>	STRING
 %token	<v.number>	NUMBER
 %type	<v.number>	boolean portplain
@@ -230,8 +232,112 @@ remoteopts1	: REPOSITORY STRING {
 		}
 		| REFERENCE ref {
 			remote->ref = $2;
+		}
+		| FETCH fetch
+		| SEND send
+	   	;
+fetchopts2	: fetchopts2 fetchopts1 nl
+	   	| fetchopts1 optnl
+		;
+fetchopts1	: REPOSITORY STRING {
+	   		remote->fetch_repo->fetch_repository = strdup($2);
+			if (remote->fetch_repo->fetch_repository == NULL) {
+				free($2);
+				yyerror("strdup");
+				YYERROR;
+			}
+			free($2);
+	   	}
+	   	| SERVER STRING {
+	   		remote->fetch_repo->fetch_server = strdup($2);
+			if (remote->fetch_repo->fetch_server == NULL) {
+				free($2);
+				yyerror("strdup");
+				YYERROR;
+			}
+			free($2);
+		}
+		| PROTOCOL STRING {
+	   		remote->fetch_repo->fetch_protocol = strdup($2);
+			if (remote->fetch_repo->fetch_protocol == NULL) {
+				free($2);
+				yyerror("strdup");
+				YYERROR;
+			}
+			free($2);
+		}
+		| PORT portplain {
+			remote->fetch_repo->fetch_port = $2;
+		}
+		| BRANCH branch {
+			remote->fetch_repo->fetch_branch = $2;
+		}
+	   	;
+fetch		: {
+			static const struct got_error* error;
+
+			if (remote->fetch_repo != NULL) {
+				yyerror("fetch block already exists");
+				YYERROR;
+			}
+			error = new_fetch(&remote->fetch_repo);
+			if (error) {
+				yyerror("%s", error->msg);
+				YYERROR;
+			}
+		} '{' optnl fetchopts2 '}'
+       		;
+sendopts2	: sendopts2 sendopts1 nl
+	   	| sendopts1 optnl
+		;
+sendopts1	: REPOSITORY STRING {
+	   		remote->send_repo->send_repository = strdup($2);
+			if (remote->send_repo->send_repository == NULL) {
+				free($2);
+				yyerror("strdup");
+				YYERROR;
+			}
+			free($2);
+	   	}
+	   	| SERVER STRING {
+	   		remote->send_repo->send_server = strdup($2);
+			if (remote->send_repo->send_server == NULL) {
+				free($2);
+				yyerror("strdup");
+				YYERROR;
+			}
+			free($2);
 		}
+		| PROTOCOL STRING {
+	   		remote->send_repo->send_protocol = strdup($2);
+			if (remote->send_repo->send_protocol == NULL) {
+				free($2);
+				yyerror("strdup");
+				YYERROR;
+			}
+			free($2);
+		}
+		| PORT portplain {
+			remote->send_repo->send_port = $2;
+		}
+		| BRANCH branch {
+			remote->send_repo->send_branch = $2;
+		}
 	   	;
+send		: {
+			static const struct got_error* error;
+
+			if (remote->send_repo != NULL) {
+				yyerror("send block already exists");
+				YYERROR;
+			}
+			error = new_send(&remote->send_repo);
+			if (error) {
+				yyerror("%s", error->msg);
+				YYERROR;
+			}
+		} '{' optnl sendopts2 '}'
+       		;
 remote		: REMOTE STRING {
 			static const struct got_error* error;
 
@@ -314,6 +420,7 @@ lookup(char *s)
 	static const struct keywords keywords[] = {
 		{"author",		AUTHOR},
 		{"branch",		BRANCH},
+		{"fetch",		FETCH},
 		{"fetch-all-branches",	FETCH_ALL_BRANCHES},
 		{"mirror-references",	MIRROR_REFERENCES},
 		{"port",		PORT},
@@ -321,6 +428,7 @@ lookup(char *s)
 		{"reference",		REFERENCE},
 		{"remote",		REMOTE},
 		{"repository",		REPOSITORY},
+		{"send",		SEND},
 		{"server",		SERVER},
 	};
 	const struct keywords	*p;
@@ -657,6 +765,28 @@ new_remote(struct gotconfig_remote_repo **remote)
 
 	*remote = calloc(1, sizeof(**remote));
 	if (*remote == NULL)
+		error = got_error_from_errno("calloc");
+	return error;
+}
+
+static const struct got_error*
+new_fetch(struct fetch_repo **fetch_repo)
+{
+	const struct got_error *error = NULL;
+
+	*fetch_repo = calloc(1, sizeof(**fetch_repo));
+	if (*fetch_repo == NULL)
+		error = got_error_from_errno("calloc");
+	return error;
+}
+
+static const struct got_error*
+new_send(struct send_repo **send_repo)
+{
+	const struct got_error *error = NULL;
+
+	*send_repo = calloc(1, sizeof(**send_repo));
+	if (*send_repo == NULL)
 		error = got_error_from_errno("calloc");
 	return error;
 }
@@ -710,6 +840,18 @@ gotconfig_free(struct gotconfig *conf)
 	while (!TAILQ_EMPTY(&conf->remotes)) {
 		remote = TAILQ_FIRST(&conf->remotes);
 		TAILQ_REMOVE(&conf->remotes, remote, entry);
+		if (remote->fetch_repo != NULL) {
+			free(remote->fetch_repo->fetch_name);
+			free(remote->fetch_repo->fetch_repository);
+			free(remote->fetch_repo->fetch_server);
+			free(remote->fetch_repo->fetch_protocol);
+		}
+		if (remote->send_repo != NULL) {
+			free(remote->send_repo->send_name);
+			free(remote->send_repo->send_repository);
+			free(remote->send_repo->send_server);
+			free(remote->send_repo->send_protocol);
+		}
 		free(remote->name);
 		free(remote->repository);
 		free(remote->server);