Blame


1 2c251c14 2020-01-15 tracey /*
2 c34ec417 2020-06-22 tracey * Copyright (c) 2019, 2020 Tracey Emery <tracey@openbsd.org>
3 c34ec417 2020-06-22 tracey * Copyright (c) 2004, 2005 Esben Norby <norby@openbsd.org>
4 c34ec417 2020-06-22 tracey * Copyright (c) 2004 Ryan McBride <mcbride@openbsd.org>
5 2c251c14 2020-01-15 tracey * Copyright (c) 2002, 2003, 2004 Henning Brauer <henning@openbsd.org>
6 2c251c14 2020-01-15 tracey * Copyright (c) 2001 Markus Friedl. All rights reserved.
7 2c251c14 2020-01-15 tracey * Copyright (c) 2001 Daniel Hartmeier. All rights reserved.
8 2c251c14 2020-01-15 tracey * Copyright (c) 2001 Theo de Raadt. All rights reserved.
9 2c251c14 2020-01-15 tracey *
10 2c251c14 2020-01-15 tracey * Permission to use, copy, modify, and distribute this software for any
11 2c251c14 2020-01-15 tracey * purpose with or without fee is hereby granted, provided that the above
12 2c251c14 2020-01-15 tracey * copyright notice and this permission notice appear in all copies.
13 2c251c14 2020-01-15 tracey *
14 2c251c14 2020-01-15 tracey * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
15 2c251c14 2020-01-15 tracey * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
16 2c251c14 2020-01-15 tracey * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
17 2c251c14 2020-01-15 tracey * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
18 2c251c14 2020-01-15 tracey * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
19 2c251c14 2020-01-15 tracey * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
20 2c251c14 2020-01-15 tracey * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
21 2c251c14 2020-01-15 tracey */
22 2c251c14 2020-01-15 tracey
23 2c251c14 2020-01-15 tracey %{
24 2c251c14 2020-01-15 tracey #include <sys/types.h>
25 2c251c14 2020-01-15 tracey #include <sys/queue.h>
26 c34ec417 2020-06-22 tracey #include <sys/socket.h>
27 c34ec417 2020-06-22 tracey #include <sys/stat.h>
28 2c251c14 2020-01-15 tracey
29 c34ec417 2020-06-22 tracey #include <netinet/in.h>
30 c34ec417 2020-06-22 tracey
31 c34ec417 2020-06-22 tracey #include <arpa/inet.h>
32 c34ec417 2020-06-22 tracey
33 2c251c14 2020-01-15 tracey #include <ctype.h>
34 2c251c14 2020-01-15 tracey #include <err.h>
35 c34ec417 2020-06-22 tracey #include <errno.h>
36 c34ec417 2020-06-22 tracey #include <event.h>
37 c34ec417 2020-06-22 tracey #include <ifaddrs.h>
38 c34ec417 2020-06-22 tracey #include <imsg.h>
39 2c251c14 2020-01-15 tracey #include <limits.h>
40 2c251c14 2020-01-15 tracey #include <stdarg.h>
41 2c251c14 2020-01-15 tracey #include <stdio.h>
42 2c251c14 2020-01-15 tracey #include <string.h>
43 c34ec417 2020-06-22 tracey #include <syslog.h>
44 c34ec417 2020-06-22 tracey #include <unistd.h>
45 2c251c14 2020-01-15 tracey
46 c34ec417 2020-06-22 tracey #include "got_error.h"
47 2c251c14 2020-01-15 tracey #include "gotweb.h"
48 2c251c14 2020-01-15 tracey
49 2c251c14 2020-01-15 tracey TAILQ_HEAD(files, file) files = TAILQ_HEAD_INITIALIZER(files);
50 2c251c14 2020-01-15 tracey static struct file {
51 2c251c14 2020-01-15 tracey TAILQ_ENTRY(file) entry;
52 2c251c14 2020-01-15 tracey FILE *stream;
53 2c251c14 2020-01-15 tracey char *name;
54 c34ec417 2020-06-22 tracey size_t ungetpos;
55 c34ec417 2020-06-22 tracey size_t ungetsize;
56 c34ec417 2020-06-22 tracey u_char *ungetbuf;
57 c34ec417 2020-06-22 tracey int eof_reached;
58 2c251c14 2020-01-15 tracey int lineno;
59 2c251c14 2020-01-15 tracey } *file, *topfile;
60 c34ec417 2020-06-22 tracey static const struct got_error* pushfile(struct file**, const char *);
61 2c251c14 2020-01-15 tracey int popfile(void);
62 2c251c14 2020-01-15 tracey int yyparse(void);
63 2c251c14 2020-01-15 tracey int yylex(void);
64 2c251c14 2020-01-15 tracey int yyerror(const char *, ...)
65 2c251c14 2020-01-15 tracey __attribute__((__format__ (printf, 1, 2)))
66 2c251c14 2020-01-15 tracey __attribute__((__nonnull__ (1)));
67 2c251c14 2020-01-15 tracey int kw_cmp(const void *, const void *);
68 2c251c14 2020-01-15 tracey int lookup(char *);
69 c34ec417 2020-06-22 tracey int igetc(void);
70 2c251c14 2020-01-15 tracey int lgetc(int);
71 c34ec417 2020-06-22 tracey void lungetc(int);
72 2c251c14 2020-01-15 tracey int findeol(void);
73 2c251c14 2020-01-15 tracey
74 c34ec417 2020-06-22 tracey TAILQ_HEAD(symhead, sym) symhead = TAILQ_HEAD_INITIALIZER(symhead);
75 c34ec417 2020-06-22 tracey struct sym {
76 c34ec417 2020-06-22 tracey TAILQ_ENTRY(sym) entry;
77 c34ec417 2020-06-22 tracey int used;
78 c34ec417 2020-06-22 tracey int persist;
79 c34ec417 2020-06-22 tracey char *nam;
80 c34ec417 2020-06-22 tracey char *val;
81 c34ec417 2020-06-22 tracey };
82 2c251c14 2020-01-15 tracey
83 c34ec417 2020-06-22 tracey int symset(const char *, const char *, int);
84 c34ec417 2020-06-22 tracey char *symget(const char *);
85 2c251c14 2020-01-15 tracey
86 c34ec417 2020-06-22 tracey const struct got_error* gerror = NULL;
87 f71c0a3a 2020-06-23 tracey struct gotweb_config *gw_conf;
88 c34ec417 2020-06-22 tracey
89 2c251c14 2020-01-15 tracey typedef struct {
90 2c251c14 2020-01-15 tracey union {
91 c34ec417 2020-06-22 tracey int64_t number;
92 c34ec417 2020-06-22 tracey char *string;
93 2c251c14 2020-01-15 tracey } v;
94 2c251c14 2020-01-15 tracey int lineno;
95 2c251c14 2020-01-15 tracey } YYSTYPE;
96 2c251c14 2020-01-15 tracey
97 2c251c14 2020-01-15 tracey %}
98 2c251c14 2020-01-15 tracey
99 2c251c14 2020-01-15 tracey %token GOT_WWW_PATH GOT_MAX_REPOS GOT_SITE_NAME GOT_SITE_OWNER GOT_SITE_LINK
100 2c251c14 2020-01-15 tracey %token GOT_LOGO GOT_LOGO_URL GOT_SHOW_REPO_OWNER GOT_SHOW_REPO_AGE
101 2c251c14 2020-01-15 tracey %token GOT_SHOW_REPO_DESCRIPTION GOT_MAX_REPOS_DISPLAY GOT_REPOS_PATH
102 2c251c14 2020-01-15 tracey %token GOT_MAX_COMMITS_DISPLAY ON ERROR GOT_SHOW_SITE_OWNER
103 2c251c14 2020-01-15 tracey %token GOT_SHOW_REPO_CLONEURL
104 c34ec417 2020-06-22 tracey %token <v.string> STRING
105 c34ec417 2020-06-22 tracey %token <v.number> NUMBER
106 c34ec417 2020-06-22 tracey %type <v.number> boolean
107 2c251c14 2020-01-15 tracey %%
108 2c251c14 2020-01-15 tracey
109 2c251c14 2020-01-15 tracey grammar : /* empty */
110 2c251c14 2020-01-15 tracey | grammar '\n'
111 2c251c14 2020-01-15 tracey | grammar main '\n'
112 2c251c14 2020-01-15 tracey ;
113 2c251c14 2020-01-15 tracey
114 c34ec417 2020-06-22 tracey boolean : STRING {
115 2c251c14 2020-01-15 tracey if (strcasecmp($1, "true") == 0 ||
116 2c251c14 2020-01-15 tracey strcasecmp($1, "yes") == 0)
117 2c251c14 2020-01-15 tracey $$ = 1;
118 2c251c14 2020-01-15 tracey else if (strcasecmp($1, "false") == 0 ||
119 2c251c14 2020-01-15 tracey strcasecmp($1, "off") == 0 ||
120 2c251c14 2020-01-15 tracey strcasecmp($1, "no") == 0)
121 2c251c14 2020-01-15 tracey $$ = 0;
122 2c251c14 2020-01-15 tracey else {
123 2c251c14 2020-01-15 tracey yyerror("invalid boolean value '%s'", $1);
124 2c251c14 2020-01-15 tracey free($1);
125 2c251c14 2020-01-15 tracey YYERROR;
126 2c251c14 2020-01-15 tracey }
127 2c251c14 2020-01-15 tracey free($1);
128 2c251c14 2020-01-15 tracey }
129 c34ec417 2020-06-22 tracey | ON { $$ = 1; }
130 2c251c14 2020-01-15 tracey ;
131 2c251c14 2020-01-15 tracey main : GOT_REPOS_PATH STRING {
132 f71c0a3a 2020-06-23 tracey gw_conf->got_repos_path = strdup($2);
133 9f6f3943 2020-09-24 tracey if (gw_conf->got_repos_path == NULL) {
134 c34ec417 2020-06-22 tracey free($2);
135 c34ec417 2020-06-22 tracey yyerror("strdup");
136 c34ec417 2020-06-22 tracey YYERROR;
137 c34ec417 2020-06-22 tracey }
138 ff21961d 2020-07-29 tracey free($2);
139 54415d85 2020-01-15 tracey }
140 9f6f3943 2020-09-24 tracey | GOT_WWW_PATH STRING {
141 9f6f3943 2020-09-24 tracey gw_conf->got_www_path = strdup($2);
142 9f6f3943 2020-09-24 tracey if (gw_conf->got_www_path == NULL) {
143 9f6f3943 2020-09-24 tracey free($2);
144 9f6f3943 2020-09-24 tracey yyerror("strdup");
145 9f6f3943 2020-09-24 tracey YYERROR;
146 9f6f3943 2020-09-24 tracey }
147 9f6f3943 2020-09-24 tracey free($2);
148 9f6f3943 2020-09-24 tracey }
149 2c251c14 2020-01-15 tracey | GOT_MAX_REPOS NUMBER {
150 2c251c14 2020-01-15 tracey if ($2 > 0)
151 f71c0a3a 2020-06-23 tracey gw_conf->got_max_repos = $2;
152 2c251c14 2020-01-15 tracey }
153 2c251c14 2020-01-15 tracey | GOT_SITE_NAME STRING {
154 f71c0a3a 2020-06-23 tracey gw_conf->got_site_name = strdup($2);
155 f71c0a3a 2020-06-23 tracey if (gw_conf->got_site_name == NULL) {
156 c34ec417 2020-06-22 tracey free($2);
157 c34ec417 2020-06-22 tracey yyerror("strdup");
158 c34ec417 2020-06-22 tracey YYERROR;
159 c34ec417 2020-06-22 tracey }
160 ff21961d 2020-07-29 tracey free($2);
161 2c251c14 2020-01-15 tracey }
162 2c251c14 2020-01-15 tracey | GOT_SITE_OWNER STRING {
163 f71c0a3a 2020-06-23 tracey gw_conf->got_site_owner = strdup($2);
164 f71c0a3a 2020-06-23 tracey if (gw_conf->got_site_owner == NULL) {
165 c34ec417 2020-06-22 tracey free($2);
166 c34ec417 2020-06-22 tracey yyerror("strdup");
167 c34ec417 2020-06-22 tracey YYERROR;
168 c34ec417 2020-06-22 tracey }
169 ff21961d 2020-07-29 tracey free($2);
170 2c251c14 2020-01-15 tracey }
171 2c251c14 2020-01-15 tracey | GOT_SITE_LINK STRING {
172 f71c0a3a 2020-06-23 tracey gw_conf->got_site_link = strdup($2);
173 f71c0a3a 2020-06-23 tracey if (gw_conf->got_site_link == NULL) {
174 c34ec417 2020-06-22 tracey free($2);
175 c34ec417 2020-06-22 tracey yyerror("strdup");
176 c34ec417 2020-06-22 tracey YYERROR;
177 c34ec417 2020-06-22 tracey }
178 ff21961d 2020-07-29 tracey free($2);
179 2c251c14 2020-01-15 tracey }
180 2c251c14 2020-01-15 tracey | GOT_LOGO STRING {
181 f71c0a3a 2020-06-23 tracey gw_conf->got_logo = strdup($2);
182 f71c0a3a 2020-06-23 tracey if (gw_conf->got_logo== NULL) {
183 c34ec417 2020-06-22 tracey free($2);
184 c34ec417 2020-06-22 tracey yyerror("strdup");
185 c34ec417 2020-06-22 tracey YYERROR;
186 c34ec417 2020-06-22 tracey }
187 ff21961d 2020-07-29 tracey free($2);
188 2c251c14 2020-01-15 tracey }
189 2c251c14 2020-01-15 tracey | GOT_LOGO_URL STRING {
190 f71c0a3a 2020-06-23 tracey gw_conf->got_logo_url = strdup($2);
191 f71c0a3a 2020-06-23 tracey if (gw_conf->got_logo_url== NULL) {
192 c34ec417 2020-06-22 tracey free($2);
193 c34ec417 2020-06-22 tracey yyerror("strdup");
194 c34ec417 2020-06-22 tracey YYERROR;
195 c34ec417 2020-06-22 tracey }
196 ff21961d 2020-07-29 tracey free($2);
197 2c251c14 2020-01-15 tracey }
198 2c251c14 2020-01-15 tracey | GOT_SHOW_SITE_OWNER boolean {
199 f71c0a3a 2020-06-23 tracey gw_conf->got_show_site_owner = $2;
200 2c251c14 2020-01-15 tracey }
201 2c251c14 2020-01-15 tracey | GOT_SHOW_REPO_OWNER boolean {
202 f71c0a3a 2020-06-23 tracey gw_conf->got_show_repo_owner = $2;
203 2c251c14 2020-01-15 tracey }
204 c34ec417 2020-06-22 tracey | GOT_SHOW_REPO_AGE boolean {
205 f71c0a3a 2020-06-23 tracey gw_conf->got_show_repo_age = $2;
206 c34ec417 2020-06-22 tracey }
207 2c251c14 2020-01-15 tracey | GOT_SHOW_REPO_DESCRIPTION boolean {
208 f71c0a3a 2020-06-23 tracey gw_conf->got_show_repo_description = $2;
209 2c251c14 2020-01-15 tracey }
210 2c251c14 2020-01-15 tracey | GOT_SHOW_REPO_CLONEURL boolean {
211 f71c0a3a 2020-06-23 tracey gw_conf->got_show_repo_cloneurl = $2;
212 2c251c14 2020-01-15 tracey }
213 2c251c14 2020-01-15 tracey | GOT_MAX_REPOS_DISPLAY NUMBER {
214 2c251c14 2020-01-15 tracey if ($2 > 0)
215 f71c0a3a 2020-06-23 tracey gw_conf->got_max_repos_display = $2;
216 2c251c14 2020-01-15 tracey }
217 2c251c14 2020-01-15 tracey | GOT_MAX_COMMITS_DISPLAY NUMBER {
218 2c251c14 2020-01-15 tracey if ($2 > 0)
219 f71c0a3a 2020-06-23 tracey gw_conf->got_max_commits_display = $2;
220 2c251c14 2020-01-15 tracey }
221 54415d85 2020-01-15 tracey ;
222 2c251c14 2020-01-15 tracey %%
223 2c251c14 2020-01-15 tracey
224 2c251c14 2020-01-15 tracey struct keywords {
225 2c251c14 2020-01-15 tracey const char *k_name;
226 2c251c14 2020-01-15 tracey int k_val;
227 2c251c14 2020-01-15 tracey };
228 2c251c14 2020-01-15 tracey
229 2c251c14 2020-01-15 tracey int
230 2c251c14 2020-01-15 tracey yyerror(const char *fmt, ...)
231 2c251c14 2020-01-15 tracey {
232 2c251c14 2020-01-15 tracey va_list ap;
233 c34ec417 2020-06-22 tracey char *msg;
234 c34ec417 2020-06-22 tracey char *err = NULL;
235 2c251c14 2020-01-15 tracey
236 2c251c14 2020-01-15 tracey va_start(ap, fmt);
237 c34ec417 2020-06-22 tracey if (vasprintf(&msg, fmt, ap) == -1) {
238 c34ec417 2020-06-22 tracey gerror = got_error_from_errno("vasprintf");
239 c34ec417 2020-06-22 tracey return 0;
240 c34ec417 2020-06-22 tracey }
241 2c251c14 2020-01-15 tracey va_end(ap);
242 c34ec417 2020-06-22 tracey if (asprintf(&err, "%s:%d: %s", file->name, yylval.lineno, msg) == -1) {
243 c34ec417 2020-06-22 tracey gerror = got_error_from_errno("asprintf");
244 c34ec417 2020-06-22 tracey return(0);
245 c34ec417 2020-06-22 tracey }
246 257add31 2020-09-09 stsp gerror = got_error_msg(GOT_ERR_PARSE_CONFIG, strdup(err));
247 2c251c14 2020-01-15 tracey free(msg);
248 c34ec417 2020-06-22 tracey free(err);
249 c34ec417 2020-06-22 tracey return(0);
250 2c251c14 2020-01-15 tracey }
251 2c251c14 2020-01-15 tracey
252 2c251c14 2020-01-15 tracey int
253 2c251c14 2020-01-15 tracey kw_cmp(const void *k, const void *e)
254 2c251c14 2020-01-15 tracey {
255 2c251c14 2020-01-15 tracey return (strcmp(k, ((const struct keywords *)e)->k_name));
256 2c251c14 2020-01-15 tracey }
257 2c251c14 2020-01-15 tracey
258 2c251c14 2020-01-15 tracey int
259 2c251c14 2020-01-15 tracey lookup(char *s)
260 2c251c14 2020-01-15 tracey {
261 c34ec417 2020-06-22 tracey /* This has to be sorted always. */
262 2c251c14 2020-01-15 tracey static const struct keywords keywords[] = {
263 2c251c14 2020-01-15 tracey { "got_logo", GOT_LOGO },
264 2c251c14 2020-01-15 tracey { "got_logo_url", GOT_LOGO_URL },
265 2c251c14 2020-01-15 tracey { "got_max_commits_display", GOT_MAX_COMMITS_DISPLAY },
266 2c251c14 2020-01-15 tracey { "got_max_repos", GOT_MAX_REPOS },
267 2c251c14 2020-01-15 tracey { "got_max_repos_display", GOT_MAX_REPOS_DISPLAY },
268 2c251c14 2020-01-15 tracey { "got_repos_path", GOT_REPOS_PATH },
269 2c251c14 2020-01-15 tracey { "got_show_repo_age", GOT_SHOW_REPO_AGE },
270 2c251c14 2020-01-15 tracey { "got_show_repo_cloneurl", GOT_SHOW_REPO_CLONEURL },
271 2c251c14 2020-01-15 tracey { "got_show_repo_description", GOT_SHOW_REPO_DESCRIPTION },
272 2c251c14 2020-01-15 tracey { "got_show_repo_owner", GOT_SHOW_REPO_OWNER },
273 2c251c14 2020-01-15 tracey { "got_show_site_owner", GOT_SHOW_SITE_OWNER },
274 2c251c14 2020-01-15 tracey { "got_site_link", GOT_SITE_LINK },
275 2c251c14 2020-01-15 tracey { "got_site_name", GOT_SITE_NAME },
276 2c251c14 2020-01-15 tracey { "got_site_owner", GOT_SITE_OWNER },
277 9f6f3943 2020-09-24 tracey { "got_www_path", GOT_WWW_PATH },
278 2c251c14 2020-01-15 tracey };
279 2c251c14 2020-01-15 tracey const struct keywords *p;
280 2c251c14 2020-01-15 tracey
281 2c251c14 2020-01-15 tracey p = bsearch(s, keywords, sizeof(keywords)/sizeof(keywords[0]),
282 2c251c14 2020-01-15 tracey sizeof(keywords[0]), kw_cmp);
283 2c251c14 2020-01-15 tracey
284 2c251c14 2020-01-15 tracey if (p)
285 2c251c14 2020-01-15 tracey return (p->k_val);
286 2c251c14 2020-01-15 tracey else
287 2c251c14 2020-01-15 tracey return (STRING);
288 2c251c14 2020-01-15 tracey }
289 2c251c14 2020-01-15 tracey
290 c34ec417 2020-06-22 tracey #define START_EXPAND 1
291 c34ec417 2020-06-22 tracey #define DONE_EXPAND 2
292 2c251c14 2020-01-15 tracey
293 c34ec417 2020-06-22 tracey static int expanding;
294 2c251c14 2020-01-15 tracey
295 2c251c14 2020-01-15 tracey int
296 c34ec417 2020-06-22 tracey igetc(void)
297 2c251c14 2020-01-15 tracey {
298 c34ec417 2020-06-22 tracey int c;
299 2c251c14 2020-01-15 tracey
300 c34ec417 2020-06-22 tracey while (1) {
301 c34ec417 2020-06-22 tracey if (file->ungetpos > 0)
302 c34ec417 2020-06-22 tracey c = file->ungetbuf[--file->ungetpos];
303 c34ec417 2020-06-22 tracey else
304 c34ec417 2020-06-22 tracey c = getc(file->stream);
305 c34ec417 2020-06-22 tracey
306 c34ec417 2020-06-22 tracey if (c == START_EXPAND)
307 c34ec417 2020-06-22 tracey expanding = 1;
308 c34ec417 2020-06-22 tracey else if (c == DONE_EXPAND)
309 c34ec417 2020-06-22 tracey expanding = 0;
310 c34ec417 2020-06-22 tracey else
311 c34ec417 2020-06-22 tracey break;
312 2c251c14 2020-01-15 tracey }
313 c34ec417 2020-06-22 tracey return (c);
314 c34ec417 2020-06-22 tracey }
315 2c251c14 2020-01-15 tracey
316 c34ec417 2020-06-22 tracey int
317 c34ec417 2020-06-22 tracey lgetc(int quotec)
318 c34ec417 2020-06-22 tracey {
319 c34ec417 2020-06-22 tracey int c, next;
320 2c251c14 2020-01-15 tracey
321 2c251c14 2020-01-15 tracey if (quotec) {
322 c34ec417 2020-06-22 tracey if ((c = igetc()) == EOF) {
323 2c251c14 2020-01-15 tracey yyerror("reached end of file while parsing "
324 2c251c14 2020-01-15 tracey "quoted string");
325 2c251c14 2020-01-15 tracey if (file == topfile || popfile() == EOF)
326 2c251c14 2020-01-15 tracey return (EOF);
327 2c251c14 2020-01-15 tracey return (quotec);
328 2c251c14 2020-01-15 tracey }
329 2c251c14 2020-01-15 tracey return (c);
330 2c251c14 2020-01-15 tracey }
331 2c251c14 2020-01-15 tracey
332 c34ec417 2020-06-22 tracey while ((c = igetc()) == '\\') {
333 c34ec417 2020-06-22 tracey next = igetc();
334 2c251c14 2020-01-15 tracey if (next != '\n') {
335 2c251c14 2020-01-15 tracey c = next;
336 2c251c14 2020-01-15 tracey break;
337 2c251c14 2020-01-15 tracey }
338 2c251c14 2020-01-15 tracey yylval.lineno = file->lineno;
339 2c251c14 2020-01-15 tracey file->lineno++;
340 2c251c14 2020-01-15 tracey }
341 2c251c14 2020-01-15 tracey
342 c34ec417 2020-06-22 tracey if (c == EOF) {
343 c34ec417 2020-06-22 tracey /*
344 c34ec417 2020-06-22 tracey * Fake EOL when hit EOF for the first time. This gets line
345 c34ec417 2020-06-22 tracey * count right if last line in included file is syntactically
346 c34ec417 2020-06-22 tracey * invalid and has no newline.
347 c34ec417 2020-06-22 tracey */
348 c34ec417 2020-06-22 tracey if (file->eof_reached == 0) {
349 c34ec417 2020-06-22 tracey file->eof_reached = 1;
350 c34ec417 2020-06-22 tracey return ('\n');
351 c34ec417 2020-06-22 tracey }
352 c34ec417 2020-06-22 tracey while (c == EOF) {
353 c34ec417 2020-06-22 tracey if (file == topfile || popfile() == EOF)
354 c34ec417 2020-06-22 tracey return (EOF);
355 c34ec417 2020-06-22 tracey c = igetc();
356 c34ec417 2020-06-22 tracey }
357 2c251c14 2020-01-15 tracey }
358 2c251c14 2020-01-15 tracey return (c);
359 2c251c14 2020-01-15 tracey }
360 2c251c14 2020-01-15 tracey
361 c34ec417 2020-06-22 tracey void
362 2c251c14 2020-01-15 tracey lungetc(int c)
363 2c251c14 2020-01-15 tracey {
364 2c251c14 2020-01-15 tracey if (c == EOF)
365 c34ec417 2020-06-22 tracey return;
366 c34ec417 2020-06-22 tracey
367 c34ec417 2020-06-22 tracey if (file->ungetpos >= file->ungetsize) {
368 c34ec417 2020-06-22 tracey void *p = reallocarray(file->ungetbuf, file->ungetsize, 2);
369 c34ec417 2020-06-22 tracey if (p == NULL)
370 c34ec417 2020-06-22 tracey err(1, "%s", __func__);
371 c34ec417 2020-06-22 tracey file->ungetbuf = p;
372 c34ec417 2020-06-22 tracey file->ungetsize *= 2;
373 2c251c14 2020-01-15 tracey }
374 c34ec417 2020-06-22 tracey file->ungetbuf[file->ungetpos++] = c;
375 2c251c14 2020-01-15 tracey }
376 2c251c14 2020-01-15 tracey
377 2c251c14 2020-01-15 tracey int
378 2c251c14 2020-01-15 tracey findeol(void)
379 2c251c14 2020-01-15 tracey {
380 2c251c14 2020-01-15 tracey int c;
381 2c251c14 2020-01-15 tracey
382 c34ec417 2020-06-22 tracey /* Skip to either EOF or the first real EOL. */
383 2c251c14 2020-01-15 tracey while (1) {
384 c34ec417 2020-06-22 tracey c = lgetc(0);
385 2c251c14 2020-01-15 tracey if (c == '\n') {
386 2c251c14 2020-01-15 tracey file->lineno++;
387 2c251c14 2020-01-15 tracey break;
388 2c251c14 2020-01-15 tracey }
389 2c251c14 2020-01-15 tracey if (c == EOF)
390 2c251c14 2020-01-15 tracey break;
391 2c251c14 2020-01-15 tracey }
392 2c251c14 2020-01-15 tracey return (ERROR);
393 2c251c14 2020-01-15 tracey }
394 2c251c14 2020-01-15 tracey
395 2c251c14 2020-01-15 tracey int
396 2c251c14 2020-01-15 tracey yylex(void)
397 2c251c14 2020-01-15 tracey {
398 c34ec417 2020-06-22 tracey unsigned char buf[8096];
399 c34ec417 2020-06-22 tracey unsigned char *p, *val;
400 c34ec417 2020-06-22 tracey int quotec, next, c;
401 c34ec417 2020-06-22 tracey int token;
402 2c251c14 2020-01-15 tracey
403 c34ec417 2020-06-22 tracey top:
404 2c251c14 2020-01-15 tracey p = buf;
405 2c251c14 2020-01-15 tracey while ((c = lgetc(0)) == ' ' || c == '\t')
406 2c251c14 2020-01-15 tracey ; /* nothing */
407 2c251c14 2020-01-15 tracey
408 2c251c14 2020-01-15 tracey yylval.lineno = file->lineno;
409 2c251c14 2020-01-15 tracey if (c == '#')
410 2c251c14 2020-01-15 tracey while ((c = lgetc(0)) != '\n' && c != EOF)
411 2c251c14 2020-01-15 tracey ; /* nothing */
412 c34ec417 2020-06-22 tracey if (c == '$' && !expanding) {
413 c34ec417 2020-06-22 tracey while (1) {
414 c34ec417 2020-06-22 tracey if ((c = lgetc(0)) == EOF)
415 c34ec417 2020-06-22 tracey return (0);
416 2c251c14 2020-01-15 tracey
417 c34ec417 2020-06-22 tracey if (p + 1 >= buf + sizeof(buf) - 1) {
418 c34ec417 2020-06-22 tracey yyerror("string too long");
419 c34ec417 2020-06-22 tracey return (findeol());
420 c34ec417 2020-06-22 tracey }
421 c34ec417 2020-06-22 tracey if (isalnum(c) || c == '_') {
422 c34ec417 2020-06-22 tracey *p++ = c;
423 c34ec417 2020-06-22 tracey continue;
424 c34ec417 2020-06-22 tracey }
425 c34ec417 2020-06-22 tracey *p = '\0';
426 c34ec417 2020-06-22 tracey lungetc(c);
427 c34ec417 2020-06-22 tracey break;
428 c34ec417 2020-06-22 tracey }
429 c34ec417 2020-06-22 tracey val = symget(buf);
430 c34ec417 2020-06-22 tracey if (val == NULL) {
431 c34ec417 2020-06-22 tracey yyerror("macro '%s' not defined", buf);
432 c34ec417 2020-06-22 tracey return (findeol());
433 c34ec417 2020-06-22 tracey }
434 c34ec417 2020-06-22 tracey p = val + strlen(val) - 1;
435 c34ec417 2020-06-22 tracey lungetc(DONE_EXPAND);
436 c34ec417 2020-06-22 tracey while (p >= val) {
437 c34ec417 2020-06-22 tracey lungetc(*p);
438 c34ec417 2020-06-22 tracey p--;
439 c34ec417 2020-06-22 tracey }
440 c34ec417 2020-06-22 tracey lungetc(START_EXPAND);
441 c34ec417 2020-06-22 tracey goto top;
442 c34ec417 2020-06-22 tracey }
443 c34ec417 2020-06-22 tracey
444 2c251c14 2020-01-15 tracey switch (c) {
445 2c251c14 2020-01-15 tracey case '\'':
446 2c251c14 2020-01-15 tracey case '"':
447 2c251c14 2020-01-15 tracey quotec = c;
448 2c251c14 2020-01-15 tracey while (1) {
449 2c251c14 2020-01-15 tracey if ((c = lgetc(quotec)) == EOF)
450 2c251c14 2020-01-15 tracey return (0);
451 2c251c14 2020-01-15 tracey if (c == '\n') {
452 2c251c14 2020-01-15 tracey file->lineno++;
453 2c251c14 2020-01-15 tracey continue;
454 2c251c14 2020-01-15 tracey } else if (c == '\\') {
455 2c251c14 2020-01-15 tracey if ((next = lgetc(quotec)) == EOF)
456 2c251c14 2020-01-15 tracey return (0);
457 c34ec417 2020-06-22 tracey if (next == quotec || c == ' ' || c == '\t')
458 2c251c14 2020-01-15 tracey c = next;
459 2c251c14 2020-01-15 tracey else if (next == '\n') {
460 2c251c14 2020-01-15 tracey file->lineno++;
461 2c251c14 2020-01-15 tracey continue;
462 2c251c14 2020-01-15 tracey } else
463 2c251c14 2020-01-15 tracey lungetc(next);
464 2c251c14 2020-01-15 tracey } else if (c == quotec) {
465 2c251c14 2020-01-15 tracey *p = '\0';
466 2c251c14 2020-01-15 tracey break;
467 2c251c14 2020-01-15 tracey } else if (c == '\0') {
468 2c251c14 2020-01-15 tracey yyerror("syntax error");
469 2c251c14 2020-01-15 tracey return (findeol());
470 2c251c14 2020-01-15 tracey }
471 2c251c14 2020-01-15 tracey if (p + 1 >= buf + sizeof(buf) - 1) {
472 2c251c14 2020-01-15 tracey yyerror("string too long");
473 2c251c14 2020-01-15 tracey return (findeol());
474 2c251c14 2020-01-15 tracey }
475 2c251c14 2020-01-15 tracey *p++ = c;
476 2c251c14 2020-01-15 tracey }
477 2c251c14 2020-01-15 tracey yylval.v.string = strdup(buf);
478 2c251c14 2020-01-15 tracey if (yylval.v.string == NULL)
479 c34ec417 2020-06-22 tracey err(1, "%s", __func__);
480 2c251c14 2020-01-15 tracey return (STRING);
481 2c251c14 2020-01-15 tracey }
482 2c251c14 2020-01-15 tracey
483 2c251c14 2020-01-15 tracey #define allowed_to_end_number(x) \
484 2c251c14 2020-01-15 tracey (isspace(x) || x == ')' || x ==',' || x == '/' || x == '}' || x == '=')
485 2c251c14 2020-01-15 tracey
486 2c251c14 2020-01-15 tracey if (c == '-' || isdigit(c)) {
487 2c251c14 2020-01-15 tracey do {
488 2c251c14 2020-01-15 tracey *p++ = c;
489 c34ec417 2020-06-22 tracey if ((unsigned)(p-buf) >= sizeof(buf)) {
490 2c251c14 2020-01-15 tracey yyerror("string too long");
491 2c251c14 2020-01-15 tracey return (findeol());
492 2c251c14 2020-01-15 tracey }
493 2c251c14 2020-01-15 tracey } while ((c = lgetc(0)) != EOF && isdigit(c));
494 2c251c14 2020-01-15 tracey lungetc(c);
495 2c251c14 2020-01-15 tracey if (p == buf + 1 && buf[0] == '-')
496 2c251c14 2020-01-15 tracey goto nodigits;
497 2c251c14 2020-01-15 tracey if (c == EOF || allowed_to_end_number(c)) {
498 2c251c14 2020-01-15 tracey const char *errstr = NULL;
499 2c251c14 2020-01-15 tracey
500 2c251c14 2020-01-15 tracey *p = '\0';
501 2c251c14 2020-01-15 tracey yylval.v.number = strtonum(buf, LLONG_MIN,
502 2c251c14 2020-01-15 tracey LLONG_MAX, &errstr);
503 2c251c14 2020-01-15 tracey if (errstr) {
504 2c251c14 2020-01-15 tracey yyerror("\"%s\" invalid number: %s",
505 2c251c14 2020-01-15 tracey buf, errstr);
506 2c251c14 2020-01-15 tracey return (findeol());
507 2c251c14 2020-01-15 tracey }
508 2c251c14 2020-01-15 tracey return (NUMBER);
509 2c251c14 2020-01-15 tracey } else {
510 2c251c14 2020-01-15 tracey nodigits:
511 2c251c14 2020-01-15 tracey while (p > buf + 1)
512 2c251c14 2020-01-15 tracey lungetc(*--p);
513 2c251c14 2020-01-15 tracey c = *--p;
514 2c251c14 2020-01-15 tracey if (c == '-')
515 2c251c14 2020-01-15 tracey return (c);
516 2c251c14 2020-01-15 tracey }
517 2c251c14 2020-01-15 tracey }
518 2c251c14 2020-01-15 tracey
519 2c251c14 2020-01-15 tracey #define allowed_in_string(x) \
520 2c251c14 2020-01-15 tracey (isalnum(x) || (ispunct(x) && x != '(' && x != ')' && \
521 c34ec417 2020-06-22 tracey x != '{' && x != '}' && \
522 c34ec417 2020-06-22 tracey x != '!' && x != '=' && x != '#' && \
523 2c251c14 2020-01-15 tracey x != ','))
524 2c251c14 2020-01-15 tracey
525 c34ec417 2020-06-22 tracey if (isalnum(c) || c == ':' || c == '_') {
526 2c251c14 2020-01-15 tracey do {
527 2c251c14 2020-01-15 tracey *p++ = c;
528 c34ec417 2020-06-22 tracey if ((unsigned)(p-buf) >= sizeof(buf)) {
529 2c251c14 2020-01-15 tracey yyerror("string too long");
530 2c251c14 2020-01-15 tracey return (findeol());
531 2c251c14 2020-01-15 tracey }
532 2c251c14 2020-01-15 tracey } while ((c = lgetc(0)) != EOF && (allowed_in_string(c)));
533 2c251c14 2020-01-15 tracey lungetc(c);
534 2c251c14 2020-01-15 tracey *p = '\0';
535 2c251c14 2020-01-15 tracey if ((token = lookup(buf)) == STRING)
536 2c251c14 2020-01-15 tracey if ((yylval.v.string = strdup(buf)) == NULL)
537 c34ec417 2020-06-22 tracey err(1, "%s", __func__);
538 2c251c14 2020-01-15 tracey return (token);
539 2c251c14 2020-01-15 tracey }
540 2c251c14 2020-01-15 tracey if (c == '\n') {
541 2c251c14 2020-01-15 tracey yylval.lineno = file->lineno;
542 2c251c14 2020-01-15 tracey file->lineno++;
543 2c251c14 2020-01-15 tracey }
544 2c251c14 2020-01-15 tracey if (c == EOF)
545 2c251c14 2020-01-15 tracey return (0);
546 2c251c14 2020-01-15 tracey return (c);
547 2c251c14 2020-01-15 tracey }
548 2c251c14 2020-01-15 tracey
549 c34ec417 2020-06-22 tracey static const struct got_error*
550 c34ec417 2020-06-22 tracey pushfile(struct file **nfile, const char *name)
551 2c251c14 2020-01-15 tracey {
552 c34ec417 2020-06-22 tracey const struct got_error* error = NULL;
553 2c251c14 2020-01-15 tracey
554 c34ec417 2020-06-22 tracey if (((*nfile) = calloc(1, sizeof(struct file))) == NULL)
555 c34ec417 2020-06-22 tracey return got_error_from_errno2(__func__, "calloc");
556 c34ec417 2020-06-22 tracey if (((*nfile)->name = strdup(name)) == NULL) {
557 2c251c14 2020-01-15 tracey free(nfile);
558 c34ec417 2020-06-22 tracey return got_error_from_errno2(__func__, "strdup");
559 2c251c14 2020-01-15 tracey }
560 c34ec417 2020-06-22 tracey if (((*nfile)->stream = fopen((*nfile)->name, "r")) == NULL) {
561 c34ec417 2020-06-22 tracey char *msg = NULL;
562 c34ec417 2020-06-22 tracey if (asprintf(&msg, "%s", (*nfile)->name) == -1)
563 c34ec417 2020-06-22 tracey return got_error_from_errno("asprintf");
564 c34ec417 2020-06-22 tracey error = got_error_msg(GOT_ERR_NO_CONFIG_FILE, msg);
565 c34ec417 2020-06-22 tracey free((*nfile)->name);
566 c34ec417 2020-06-22 tracey free((*nfile));
567 c34ec417 2020-06-22 tracey free(msg);
568 c34ec417 2020-06-22 tracey return error;
569 2c251c14 2020-01-15 tracey }
570 c34ec417 2020-06-22 tracey (*nfile)->lineno = TAILQ_EMPTY(&files) ? 1 : 0;
571 c34ec417 2020-06-22 tracey (*nfile)->ungetsize = 16;
572 c34ec417 2020-06-22 tracey (*nfile)->ungetbuf = malloc((*nfile)->ungetsize);
573 c34ec417 2020-06-22 tracey if ((*nfile)->ungetbuf == NULL) {
574 c34ec417 2020-06-22 tracey fclose((*nfile)->stream);
575 c34ec417 2020-06-22 tracey free((*nfile)->name);
576 c34ec417 2020-06-22 tracey free((*nfile));
577 c34ec417 2020-06-22 tracey return got_error_from_errno2(__func__, "malloc");
578 c34ec417 2020-06-22 tracey }
579 c34ec417 2020-06-22 tracey TAILQ_INSERT_TAIL(&files, (*nfile), entry);
580 c34ec417 2020-06-22 tracey return error;
581 2c251c14 2020-01-15 tracey }
582 2c251c14 2020-01-15 tracey
583 2c251c14 2020-01-15 tracey int
584 2c251c14 2020-01-15 tracey popfile(void)
585 2c251c14 2020-01-15 tracey {
586 c34ec417 2020-06-22 tracey struct file *prev = NULL;
587 2c251c14 2020-01-15 tracey
588 2c251c14 2020-01-15 tracey TAILQ_REMOVE(&files, file, entry);
589 2c251c14 2020-01-15 tracey fclose(file->stream);
590 2c251c14 2020-01-15 tracey free(file->name);
591 c34ec417 2020-06-22 tracey free(file->ungetbuf);
592 2c251c14 2020-01-15 tracey free(file);
593 2c251c14 2020-01-15 tracey file = prev;
594 2c251c14 2020-01-15 tracey return (file ? 0 : EOF);
595 2c251c14 2020-01-15 tracey }
596 2c251c14 2020-01-15 tracey
597 2c251c14 2020-01-15 tracey const struct got_error*
598 c34ec417 2020-06-22 tracey parse_gotweb_config(struct gotweb_config **gconf, const char *filename)
599 2c251c14 2020-01-15 tracey {
600 f71c0a3a 2020-06-23 tracey gw_conf = malloc(sizeof(struct gotweb_config));
601 f71c0a3a 2020-06-23 tracey if (gw_conf == NULL) {
602 f71c0a3a 2020-06-23 tracey gerror = got_error_from_errno("malloc");
603 f71c0a3a 2020-06-23 tracey goto done;
604 f71c0a3a 2020-06-23 tracey }
605 f71c0a3a 2020-06-23 tracey gw_conf->got_repos_path = strdup(D_GOTPATH);
606 f71c0a3a 2020-06-23 tracey if (gw_conf->got_repos_path == NULL) {
607 9f6f3943 2020-09-24 tracey gerror = got_error_from_errno("strdup");
608 9f6f3943 2020-09-24 tracey goto done;
609 9f6f3943 2020-09-24 tracey }
610 9f6f3943 2020-09-24 tracey gw_conf->got_www_path = strdup(D_GOTWWW);
611 9f6f3943 2020-09-24 tracey if (gw_conf->got_www_path == NULL) {
612 c34ec417 2020-06-22 tracey gerror = got_error_from_errno("strdup");
613 2c251c14 2020-01-15 tracey goto done;
614 2c251c14 2020-01-15 tracey }
615 f71c0a3a 2020-06-23 tracey gw_conf->got_site_name = strdup(D_SITENAME);
616 f71c0a3a 2020-06-23 tracey if (gw_conf->got_site_name == NULL) {
617 c34ec417 2020-06-22 tracey gerror = got_error_from_errno("strdup");
618 c34ec417 2020-06-22 tracey goto done;
619 c34ec417 2020-06-22 tracey }
620 f71c0a3a 2020-06-23 tracey gw_conf->got_site_owner = strdup(D_SITEOWNER);
621 f71c0a3a 2020-06-23 tracey if (gw_conf->got_site_owner == NULL) {
622 c34ec417 2020-06-22 tracey gerror = got_error_from_errno("strdup");
623 c34ec417 2020-06-22 tracey goto done;
624 c34ec417 2020-06-22 tracey }
625 f71c0a3a 2020-06-23 tracey gw_conf->got_site_link = strdup(D_SITELINK);
626 f71c0a3a 2020-06-23 tracey if (gw_conf->got_site_link == NULL) {
627 c34ec417 2020-06-22 tracey gerror = got_error_from_errno("strdup");
628 c34ec417 2020-06-22 tracey goto done;
629 c34ec417 2020-06-22 tracey }
630 f71c0a3a 2020-06-23 tracey gw_conf->got_logo = strdup(D_GOTLOGO);
631 f71c0a3a 2020-06-23 tracey if (gw_conf->got_logo == NULL) {
632 c34ec417 2020-06-22 tracey gerror = got_error_from_errno("strdup");
633 c34ec417 2020-06-22 tracey goto done;
634 c34ec417 2020-06-22 tracey }
635 f71c0a3a 2020-06-23 tracey gw_conf->got_logo_url = strdup(D_GOTURL);
636 f71c0a3a 2020-06-23 tracey if (gw_conf->got_logo_url == NULL) {
637 c34ec417 2020-06-22 tracey gerror = got_error_from_errno("strdup");
638 c34ec417 2020-06-22 tracey goto done;
639 c34ec417 2020-06-22 tracey }
640 f71c0a3a 2020-06-23 tracey gw_conf->got_show_site_owner = D_SHOWSOWNER;
641 f71c0a3a 2020-06-23 tracey gw_conf->got_show_repo_owner = D_SHOWROWNER;
642 f71c0a3a 2020-06-23 tracey gw_conf->got_show_repo_age = D_SHOWAGE;
643 f71c0a3a 2020-06-23 tracey gw_conf->got_show_repo_description = D_SHOWDESC;
644 f71c0a3a 2020-06-23 tracey gw_conf->got_show_repo_cloneurl = D_SHOWURL;
645 f71c0a3a 2020-06-23 tracey gw_conf->got_max_repos = D_MAXREPO;
646 f71c0a3a 2020-06-23 tracey gw_conf->got_max_repos_display = D_MAXREPODISP;
647 f71c0a3a 2020-06-23 tracey gw_conf->got_max_commits_display = D_MAXCOMMITDISP;
648 c34ec417 2020-06-22 tracey
649 c34ec417 2020-06-22 tracey /*
650 c34ec417 2020-06-22 tracey * We don't require that the gotweb config file exists
651 c34ec417 2020-06-22 tracey * So reset gerror if it doesn't exist and goto done.
652 c34ec417 2020-06-22 tracey */
653 c34ec417 2020-06-22 tracey gerror = pushfile(&file, filename);
654 c34ec417 2020-06-22 tracey if (gerror && gerror->code == GOT_ERR_NO_CONFIG_FILE) {
655 c34ec417 2020-06-22 tracey gerror = NULL;
656 c34ec417 2020-06-22 tracey goto done;
657 c34ec417 2020-06-22 tracey } else if (gerror)
658 c34ec417 2020-06-22 tracey return gerror;
659 2c251c14 2020-01-15 tracey topfile = file;
660 2c251c14 2020-01-15 tracey
661 2c251c14 2020-01-15 tracey yyparse();
662 2c251c14 2020-01-15 tracey popfile();
663 2c251c14 2020-01-15 tracey done:
664 f71c0a3a 2020-06-23 tracey *gconf = gw_conf;
665 c34ec417 2020-06-22 tracey return gerror;
666 2c251c14 2020-01-15 tracey }
667 c34ec417 2020-06-22 tracey
668 c34ec417 2020-06-22 tracey int
669 c34ec417 2020-06-22 tracey symset(const char *nam, const char *val, int persist)
670 c34ec417 2020-06-22 tracey {
671 c34ec417 2020-06-22 tracey struct sym *sym;
672 c34ec417 2020-06-22 tracey
673 c34ec417 2020-06-22 tracey TAILQ_FOREACH(sym, &symhead, entry) {
674 c34ec417 2020-06-22 tracey if (strcmp(nam, sym->nam) == 0)
675 c34ec417 2020-06-22 tracey break;
676 c34ec417 2020-06-22 tracey }
677 c34ec417 2020-06-22 tracey
678 c34ec417 2020-06-22 tracey if (sym != NULL) {
679 c34ec417 2020-06-22 tracey if (sym->persist == 1)
680 c34ec417 2020-06-22 tracey return (0);
681 c34ec417 2020-06-22 tracey else {
682 c34ec417 2020-06-22 tracey free(sym->nam);
683 c34ec417 2020-06-22 tracey free(sym->val);
684 c34ec417 2020-06-22 tracey TAILQ_REMOVE(&symhead, sym, entry);
685 c34ec417 2020-06-22 tracey free(sym);
686 c34ec417 2020-06-22 tracey }
687 c34ec417 2020-06-22 tracey }
688 c34ec417 2020-06-22 tracey if ((sym = calloc(1, sizeof(*sym))) == NULL)
689 c34ec417 2020-06-22 tracey return (-1);
690 c34ec417 2020-06-22 tracey
691 c34ec417 2020-06-22 tracey sym->nam = strdup(nam);
692 c34ec417 2020-06-22 tracey if (sym->nam == NULL) {
693 c34ec417 2020-06-22 tracey free(sym);
694 c34ec417 2020-06-22 tracey return (-1);
695 c34ec417 2020-06-22 tracey }
696 c34ec417 2020-06-22 tracey sym->val = strdup(val);
697 c34ec417 2020-06-22 tracey if (sym->val == NULL) {
698 c34ec417 2020-06-22 tracey free(sym->nam);
699 c34ec417 2020-06-22 tracey free(sym);
700 c34ec417 2020-06-22 tracey return (-1);
701 c34ec417 2020-06-22 tracey }
702 c34ec417 2020-06-22 tracey sym->used = 0;
703 c34ec417 2020-06-22 tracey sym->persist = persist;
704 c34ec417 2020-06-22 tracey TAILQ_INSERT_TAIL(&symhead, sym, entry);
705 c34ec417 2020-06-22 tracey return (0);
706 c34ec417 2020-06-22 tracey }
707 c34ec417 2020-06-22 tracey
708 c34ec417 2020-06-22 tracey int
709 c34ec417 2020-06-22 tracey cmdline_symset(char *s)
710 c34ec417 2020-06-22 tracey {
711 c34ec417 2020-06-22 tracey char *sym, *val;
712 c34ec417 2020-06-22 tracey int ret;
713 c34ec417 2020-06-22 tracey size_t len;
714 c34ec417 2020-06-22 tracey
715 c34ec417 2020-06-22 tracey if ((val = strrchr(s, '=')) == NULL)
716 c34ec417 2020-06-22 tracey return (-1);
717 c34ec417 2020-06-22 tracey
718 c34ec417 2020-06-22 tracey len = strlen(s) - strlen(val) + 1;
719 c34ec417 2020-06-22 tracey if ((sym = malloc(len)) == NULL)
720 c34ec417 2020-06-22 tracey errx(1, "cmdline_symset: malloc");
721 c34ec417 2020-06-22 tracey
722 c34ec417 2020-06-22 tracey strlcpy(sym, s, len);
723 c34ec417 2020-06-22 tracey
724 c34ec417 2020-06-22 tracey ret = symset(sym, val + 1, 1);
725 c34ec417 2020-06-22 tracey free(sym);
726 c34ec417 2020-06-22 tracey
727 c34ec417 2020-06-22 tracey return (ret);
728 c34ec417 2020-06-22 tracey }
729 c34ec417 2020-06-22 tracey
730 c34ec417 2020-06-22 tracey char *
731 c34ec417 2020-06-22 tracey symget(const char *nam)
732 c34ec417 2020-06-22 tracey {
733 c34ec417 2020-06-22 tracey struct sym *sym;
734 c34ec417 2020-06-22 tracey
735 c34ec417 2020-06-22 tracey TAILQ_FOREACH(sym, &symhead, entry) {
736 c34ec417 2020-06-22 tracey if (strcmp(nam, sym->nam) == 0) {
737 c34ec417 2020-06-22 tracey sym->used = 1;
738 c34ec417 2020-06-22 tracey return (sym->val);
739 c34ec417 2020-06-22 tracey }
740 c34ec417 2020-06-22 tracey }
741 c34ec417 2020-06-22 tracey return (NULL);
742 c34ec417 2020-06-22 tracey }