Commit Diff


commit - 257add310e4b16ae43b467b91f66b773da39f470
commit + cc8dff2ee1ef0ddea980fd71c953692343f8c94b
blob - 985c5323d767ed6d605af104b0c49c6272599d77 (mode 644)
blob + /dev/null
--- got/got.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright (c) 2020 Tracey Emery <tracey@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.
- */
-
-struct gotconfig_remote_repo {
-	TAILQ_ENTRY(gotconfig_remote_repo) entry;
-	char	*name;
-	char	*repository;
-	char	*server;
-	char	*protocol;
-	char	*user;
-};
-TAILQ_HEAD(gotconfig_remote_repo_list, gotconfig_remote_repo);
-
-struct gotconfig {
-	struct gotconfig_remote_repo_list remotes;
-	int nremotes;
-};
-
-/*
- * Parse individual gotconfig repository files
- */
-const struct got_error* gotconfig_parse(struct gotconfig **,
-    const char *filename);
-
-void gotconfig_free(struct gotconfig *);
blob - 2f21cabf60a5f58a82e88cc68ac7102a6ee66f11 (mode 644)
blob + /dev/null
--- got/parse.y
+++ /dev/null
@@ -1,674 +0,0 @@
-/*
- * Copyright (c) 2020 Tracey Emery <tracey@openbsd.org>
- * Copyright (c) 2004, 2005 Esben Norby <norby@openbsd.org>
- * Copyright (c) 2004 Ryan McBride <mcbride@openbsd.org>
- * Copyright (c) 2002, 2003, 2004 Henning Brauer <henning@openbsd.org>
- * Copyright (c) 2001 Markus Friedl.  All rights reserved.
- * Copyright (c) 2001 Daniel Hartmeier.  All rights reserved.
- * Copyright (c) 2001 Theo de Raadt.  All rights reserved.
- *
- * 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/types.h>
-#include <sys/queue.h>
-#include <sys/socket.h>
-#include <sys/stat.h>
-
-#include <netinet/in.h>
-
-#include <arpa/inet.h>
-
-#include <ctype.h>
-#include <err.h>
-#include <errno.h>
-#include <event.h>
-#include <ifaddrs.h>
-#include <imsg.h>
-#include <limits.h>
-#include <stdarg.h>
-#include <stdio.h>
-#include <string.h>
-#include <syslog.h>
-#include <unistd.h>
-
-#include "got_error.h"
-#include "got.h"
-
-static struct file {
-	FILE			*stream;
-	char			*name;
-	size_t	 		 ungetpos;
-	size_t			 ungetsize;
-	u_char			*ungetbuf;
-	int			 eof_reached;
-	int			 lineno;
-} *file;
-static const struct got_error*	newfile(struct file**, const char *);
-static void	closefile(struct file *);
-int		 yyparse(void);
-int		 yylex(void);
-int		 yyerror(const char *, ...)
-    __attribute__((__format__ (printf, 1, 2)))
-    __attribute__((__nonnull__ (1)));
-int		 kw_cmp(const void *, const void *);
-int		 lookup(char *);
-int		 igetc(void);
-int		 lgetc(int);
-void		 lungetc(int);
-int		 findeol(void);
-
-TAILQ_HEAD(symhead, sym)	 symhead = TAILQ_HEAD_INITIALIZER(symhead);
-struct sym {
-	TAILQ_ENTRY(sym)	 entry;
-	int			 used;
-	int			 persist;
-	char			*nam;
-	char			*val;
-};
-
-int	 symset(const char *, const char *, int);
-char	*symget(const char *);
-
-const struct got_error* gerror = NULL;
-struct gotconfig_remote_repo *remote;
-struct gotconfig gotconfig;
-static const struct got_error* new_remote(struct gotconfig_remote_repo **);
-
-typedef struct {
-	union {
-		int64_t		 number;
-		char		*string;
-	} v;
-	int lineno;
-} YYSTYPE;
-
-%}
-
-%token	ERROR
-%token	REMOTE REPOSITORY SERVER PROTOCOL USER
-%token	<v.string>	STRING
-%token	<v.number>	NUMBER
-
-%%
-
-grammar		: /* empty */
-		| grammar '\n'
-		| grammar remote '\n'
-		;
-remoteopts2	: remoteopts2 remoteopts1 nl
-	    	| remoteopts1 optnl
-		;
-remoteopts1	: REPOSITORY STRING {
-	    		remote->repository = strdup($2);
-			if (remote->repository == NULL) {
-				free($2);
-				yyerror("strdup");
-				YYERROR;
-			}
-			free($2);
-	    	}
-	    	| SERVER STRING {
-	    		remote->server = strdup($2);
-			if (remote->server == NULL) {
-				free($2);
-				yyerror("strdup");
-				YYERROR;
-			}
-			free($2);
-		}
-		| PROTOCOL STRING {
-	    		remote->protocol = strdup($2);
-			if (remote->protocol == NULL) {
-				free($2);
-				yyerror("strdup");
-				YYERROR;
-			}
-			free($2);
-		}
-		| USER STRING {
-	    		remote->user = strdup($2);
-			if (remote->user == NULL) {
-				free($2);
-				yyerror("strdup");
-				YYERROR;
-			}
-			free($2);
-		}
-	    	;
-remote		: REMOTE STRING {
-			static const struct got_error* error;
-
-			error = new_remote(&remote);
-			if (error) {
-				free($2);
-				yyerror("%s", error->msg);
-				YYERROR;
-			}
-			remote->name = strdup($2);
-			if (remote->name == NULL) {
-				free($2);
-				yyerror("strdup");
-				YYERROR;
-			}
-			free($2);
-		} '{' optnl remoteopts2 '}' {
-			TAILQ_INSERT_TAIL(&gotconfig.remotes, remote, entry);
-			gotconfig.nremotes++;
-		}
-		;
-optnl		: '\n' optnl
-		| /* empty */
-		;
-nl		: '\n' optnl
-		;
-%%
-
-struct keywords {
-	const char	*k_name;
-	int		 k_val;
-};
-
-int
-yyerror(const char *fmt, ...)
-{
-	va_list		 ap;
-	char		*msg;
-	char		*err = NULL;
-
-	va_start(ap, fmt);
-	if (vasprintf(&msg, fmt, ap) == -1) {
-		gerror =  got_error_from_errno("vasprintf");
-		return 0;
-	}
-	va_end(ap);
-	if (asprintf(&err, "%s:%d: %s", file->name, yylval.lineno, msg) == -1) {
-		gerror = got_error_from_errno("asprintf");
-		return(0);
-	}
-	gerror = got_error_msg(GOT_ERR_PARSE_Y_YY, strdup(err));
-	free(msg);
-	free(err);
-	return(0);
-}
-
-int
-kw_cmp(const void *k, const void *e)
-{
-	return (strcmp(k, ((const struct keywords *)e)->k_name));
-}
-
-int
-lookup(char *s)
-{
-	/* This has to be sorted always. */
-	static const struct keywords keywords[] = {
-		{"protocol",		PROTOCOL},
-		{"remote",		REMOTE},
-		{"repository",		REPOSITORY},
-		{"server",		SERVER},
-		{"user",		USER},
-	};
-	const struct keywords	*p;
-
-	p = bsearch(s, keywords, sizeof(keywords)/sizeof(keywords[0]),
-	    sizeof(keywords[0]), kw_cmp);
-
-	if (p)
-		return (p->k_val);
-	else
-		return (STRING);
-}
-
-#define START_EXPAND	1
-#define DONE_EXPAND	2
-
-static int	expanding;
-
-int
-igetc(void)
-{
-	int	c;
-
-	while (1) {
-		if (file->ungetpos > 0)
-			c = file->ungetbuf[--file->ungetpos];
-		else
-			c = getc(file->stream);
-
-		if (c == START_EXPAND)
-			expanding = 1;
-		else if (c == DONE_EXPAND)
-			expanding = 0;
-		else
-			break;
-	}
-	return (c);
-}
-
-int
-lgetc(int quotec)
-{
-	int		c, next;
-
-	if (quotec) {
-		c = igetc();
-		if (c == EOF) {
-			yyerror("reached end of file while parsing "
-			    "quoted string");
-		}
-		return (c);
-	}
-
-	c = igetc();
-	while (c == '\\') {
-		next = igetc();
-		if (next != '\n') {
-			c = next;
-			break;
-		}
-		yylval.lineno = file->lineno;
-		file->lineno++;
-	}
-
-	return (c);
-}
-
-void
-lungetc(int c)
-{
-	if (c == EOF)
-		return;
-
-	if (file->ungetpos >= file->ungetsize) {
-		void *p = reallocarray(file->ungetbuf, file->ungetsize, 2);
-		if (p == NULL)
-			err(1, "%s", __func__);
-		file->ungetbuf = p;
-		file->ungetsize *= 2;
-	}
-	file->ungetbuf[file->ungetpos++] = c;
-}
-
-int
-findeol(void)
-{
-	int	c;
-
-	/* Skip to either EOF or the first real EOL. */
-	while (1) {
-		c = lgetc(0);
-		if (c == '\n') {
-			file->lineno++;
-			break;
-		}
-		if (c == EOF)
-			break;
-	}
-	return (ERROR);
-}
-
-int
-yylex(void)
-{
-	unsigned char	 buf[8096];
-	unsigned char	*p, *val;
-	int		 quotec, next, c;
-	int		 token;
-
-top:
-	p = buf;
-	c = lgetc(0);
-	while (c == ' ' || c == '\t')
-		c = lgetc(0); /* nothing */
-
-	yylval.lineno = file->lineno;
-	if (c == '#') {
-		c = lgetc(0);
-		while (c != '\n' && c != EOF)
-			c = lgetc(0); /* nothing */
-	}
-	if (c == '$' && !expanding) {
-		while (1) {
-			c = lgetc(0);
-			if (c == EOF)
-				return (0);
-
-			if (p + 1 >= buf + sizeof(buf) - 1) {
-				yyerror("string too long");
-				return (findeol());
-			}
-			if (isalnum(c) || c == '_') {
-				*p++ = c;
-				continue;
-			}
-			*p = '\0';
-			lungetc(c);
-			break;
-		}
-		val = symget(buf);
-		if (val == NULL) {
-			yyerror("macro '%s' not defined", buf);
-			return (findeol());
-		}
-		p = val + strlen(val) - 1;
-		lungetc(DONE_EXPAND);
-		while (p >= val) {
-			lungetc(*p);
-			p--;
-		}
-		lungetc(START_EXPAND);
-		goto top;
-	}
-
-	switch (c) {
-	case '\'':
-	case '"':
-		quotec = c;
-		while (1) {
-			c = lgetc(quotec);
-			if (c == EOF)
-				return (0);
-			if (c == '\n') {
-				file->lineno++;
-				continue;
-			} else if (c == '\\') {
-				next = lgetc(quotec);
-				if (next == EOF)
-					return (0);
-				if (next == quotec || c == ' ' || c == '\t')
-					c = next;
-				else if (next == '\n') {
-					file->lineno++;
-					continue;
-				} else
-					lungetc(next);
-			} else if (c == quotec) {
-				*p = '\0';
-				break;
-			} else if (c == '\0') {
-				yyerror("syntax error");
-				return (findeol());
-			}
-			if (p + 1 >= buf + sizeof(buf) - 1) {
-				yyerror("string too long");
-				return (findeol());
-			}
-			*p++ = c;
-		}
-		yylval.v.string = strdup(buf);
-		if (yylval.v.string == NULL)
-			err(1, "%s", __func__);
-		return (STRING);
-	}
-
-#define allowed_to_end_number(x) \
-	(isspace(x) || x == ')' || x ==',' || x == '/' || x == '}' || x == '=')
-
-	if (c == '-' || isdigit(c)) {
-		do {
-			*p++ = c;
-			if ((unsigned)(p-buf) >= sizeof(buf)) {
-				yyerror("string too long");
-				return (findeol());
-			}
-			c = lgetc(0);
-		} while (c != EOF && isdigit(c));
-		lungetc(c);
-		if (p == buf + 1 && buf[0] == '-')
-			goto nodigits;
-		if (c == EOF || allowed_to_end_number(c)) {
-			const char *errstr = NULL;
-
-			*p = '\0';
-			yylval.v.number = strtonum(buf, LLONG_MIN,
-			    LLONG_MAX, &errstr);
-			if (errstr) {
-				yyerror("\"%s\" invalid number: %s",
-				    buf, errstr);
-				return (findeol());
-			}
-			return (NUMBER);
-		} else {
-nodigits:
-			while (p > buf + 1)
-				lungetc(*--p);
-			c = *--p;
-			if (c == '-')
-				return (c);
-		}
-	}
-
-#define allowed_in_string(x) \
-	(isalnum(x) || (ispunct(x) && x != '(' && x != ')' && \
-	x != '{' && x != '}' && \
-	x != '!' && x != '=' && x != '#' && \
-	x != ','))
-
-	if (isalnum(c) || c == ':' || c == '_') {
-		do {
-			*p++ = c;
-			if ((unsigned)(p-buf) >= sizeof(buf)) {
-				yyerror("string too long");
-				return (findeol());
-			}
-			c = lgetc(0);
-		} while (c != EOF && (allowed_in_string(c)));
-		lungetc(c);
-		*p = '\0';
-		token = lookup(buf);
-		if (token == STRING) {
-			yylval.v.string = strdup(buf);
-			if (yylval.v.string == NULL)
-				err(1, "%s", __func__);
-		}
-		return (token);
-	}
-	if (c == '\n') {
-		yylval.lineno = file->lineno;
-		file->lineno++;
-	}
-	if (c == EOF)
-		return (0);
-	return (c);
-}
-
-static const struct got_error*
-newfile(struct file **nfile, const char *name)
-{
-	const struct got_error* error = NULL;
-
-	(*nfile) = calloc(1, sizeof(struct file));
-	if ((*nfile) == NULL)
-		return got_error_from_errno2(__func__, "calloc");
-	(*nfile)->name = strdup(name);
-	if ((*nfile)->name == NULL) {
-		free(nfile);
-		return got_error_from_errno2(__func__, "strdup");
-	}
-	(*nfile)->stream = fopen((*nfile)->name, "r");
-	if ((*nfile)->stream == NULL) {
-		char *msg = NULL;
-		if (asprintf(&msg, "%s", (*nfile)->name) == -1)
-			return got_error_from_errno("asprintf");
-		error = got_error_msg(GOT_ERR_NO_CONFIG_FILE, msg);
-		free((*nfile)->name);
-		free((*nfile));
-		free(msg);
-		return error;
-	}
-	(*nfile)->lineno = 1;
-	(*nfile)->ungetsize = 16;
-	(*nfile)->ungetbuf = malloc((*nfile)->ungetsize);
-	if ((*nfile)->ungetbuf == NULL) {
-		fclose((*nfile)->stream);
-		free((*nfile)->name);
-		free((*nfile));
-		return got_error_from_errno2(__func__, "malloc");
-	}
-	return error;
-}
-
-static const struct got_error*
-new_remote(struct gotconfig_remote_repo **remote)
-{
-	const struct got_error *error = NULL;
-
-	*remote = calloc(1, sizeof(**remote));
-	if (*remote == NULL)
-	    error = got_error_from_errno("calloc");
-	return error;
-}
-
-static void
-closefile(struct file *file)
-{
-	fclose(file->stream);
-	free(file->name);
-	free(file->ungetbuf);
-	free(file);
-}
-
-const struct got_error*
-gotconfig_parse(struct gotconfig **conf, const char *filename)
-{
-	struct sym	*sym, *next;
-
-	*conf = NULL;
-
-	/*
-	 * We don't require that gotconfig exists
-	 * So, null gerror and goto done
-	 */
-	gerror = newfile(&file, filename);
-	if (gerror && gerror->code == GOT_ERR_NO_CONFIG_FILE) {
-		gerror = NULL;
-		goto done;
-	} else if (gerror)
-		return gerror;
-
-	TAILQ_INIT(&gotconfig.remotes);
-
-	yyparse();
-	closefile(file);
-
-	/* Free macros and check which have not been used. */
-	TAILQ_FOREACH_SAFE(sym, &symhead, entry, next) {
-		if (!sym->persist) {
-			free(sym->nam);
-			free(sym->val);
-			TAILQ_REMOVE(&symhead, sym, entry);
-			free(sym);
-		}
-	}
-done:
-	*conf = &gotconfig;
-	return gerror;
-}
-
-void
-gotconfig_free(struct gotconfig *conf)
-{
-	struct gotconfig_remote_repo *remote;
-
-	while (!TAILQ_EMPTY(&conf->remotes)) {
-		remote = TAILQ_FIRST(&conf->remotes);
-		TAILQ_REMOVE(&conf->remotes, remote, entry);
-		free(remote->name);
-		free(remote->repository);
-		free(remote->server);
-		free(remote->protocol);
-		free(remote->user);
-		free(remote);
-	}
-}
-
-int
-symset(const char *nam, const char *val, int persist)
-{
-	struct sym	*sym;
-
-	TAILQ_FOREACH(sym, &symhead, entry) {
-		if (strcmp(nam, sym->nam) == 0)
-			break;
-	}
-
-	if (sym != NULL) {
-		if (sym->persist == 1)
-			return (0);
-		else {
-			free(sym->nam);
-			free(sym->val);
-			TAILQ_REMOVE(&symhead, sym, entry);
-			free(sym);
-		}
-	}
-	sym = calloc(1, sizeof(*sym));
-	if (sym == NULL)
-		return (-1);
-
-	sym->nam = strdup(nam);
-	if (sym->nam == NULL) {
-		free(sym);
-		return (-1);
-	}
-	sym->val = strdup(val);
-	if (sym->val == NULL) {
-		free(sym->nam);
-		free(sym);
-		return (-1);
-	}
-	sym->used = 0;
-	sym->persist = persist;
-	TAILQ_INSERT_TAIL(&symhead, sym, entry);
-	return (0);
-}
-
-int
-cmdline_symset(char *s)
-{
-	char	*sym, *val;
-	int	ret;
-	size_t	len;
-
-	val = strrchr(s, '=');
-	if (val == NULL)
-		return (-1);
-
-	len = strlen(s) - strlen(val) + 1;
-	sym = malloc(len);
-	if (sym == NULL)
-		errx(1, "cmdline_symset: malloc");
-
-	strlcpy(sym, s, len);
-
-	ret = symset(sym, val + 1, 1);
-	free(sym);
-
-	return (ret);
-}
-
-char *
-symget(const char *nam)
-{
-	struct sym	*sym;
-
-	TAILQ_FOREACH(sym, &symhead, entry) {
-		if (strcmp(nam, sym->nam) == 0) {
-			sym->used = 1;
-			return (sym->val);
-		}
-	}
-	return (NULL);
-}