]> git.ipfire.org Git - thirdparty/dhcp.git/blame - keama/keama.c
copy rights update
[thirdparty/dhcp.git] / keama / keama.c
CommitLineData
0cd94b5e 1/*
49a7fb58 2 * Copyright(C) 2017-2022 Internet Systems Consortium, Inc.("ISC")
0cd94b5e
TM
3 *
4 * Permission to use, copy, modify, and distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
14 * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 *
16 * Internet Systems Consortium, Inc.
429a56d7
TM
17 * PO Box 360
18 * Newmarket, NH 03857 USA
0cd94b5e
TM
19 * <info@isc.org>
20 * https://www.isc.org/
21 *
22 */
23
24#include <sys/errno.h>
25#include <arpa/inet.h>
26#include <assert.h>
27#include <fcntl.h>
28#include <stdarg.h>
29#include <stdlib.h>
30#include <string.h>
31#include <unistd.h>
32
33#include "keama.h"
34
35#define KEAMA_USAGE "Usage: keama [-4|-6] [-D] [-N]" \
36 " [-r {perform|fatal|pass}\\n" \
37 " [-l hook-library-path]" \
38 " [-i input-file] [-o output-file]\n"
39
40static void
41usage(const char *sfmt, const char *sarg) {
42 if (sfmt != NULL) {
43 fprintf(stderr, sfmt, sarg);
44 fprintf(stderr, "\n");
45 }
46 fputs(KEAMA_USAGE, stderr);
47 exit(1);
48}
49
c666652e
FD
50enum resolve resolve;
51struct parses parses;
52
0cd94b5e
TM
53int local_family = 0;
54char *hook_library_path = NULL;
55char *input_file = NULL;
56char *output_file = NULL;
57FILE *input = NULL;
58FILE *output = NULL;
59isc_boolean_t use_isc_lifetimes = ISC_FALSE;
60isc_boolean_t global_hr = ISC_TRUE;
61isc_boolean_t json = ISC_FALSE;
62
63static const char use_noarg[] = "No argument for command: %s";
64static const char bad_resolve[] = "Bad -r argument: %s";
65
f6b8f48d 66int
0cd94b5e
TM
67main(int argc, char **argv) {
68 int i, fd;
69 char *inbuf = NULL;
70 size_t oldsize = 0;
71 size_t newsize = 0;
72 ssize_t cc;
73 struct parse *cfile;
74 size_t cnt = 0;
75
76 for (i = 1; i < argc; i++) {
77 if (strcmp(argv[i], "-4") == 0)
78 local_family = AF_INET;
79 else if (strcmp(argv[i], "-6") == 0)
80 local_family = AF_INET6;
81 else if (strcmp(argv[i], "-D") == 0)
82 use_isc_lifetimes = ISC_TRUE;
83 else if (strcmp(argv[i], "-N") == 0)
84 global_hr = ISC_FALSE;
85 else if (strcmp(argv[i], "-T") == 0)
86 json = ISC_TRUE;
87 else if (strcmp(argv[i], "-r") == 0) {
88 if (++i == argc)
89 usage(use_noarg, argv[i - 1]);
90 if (strcmp(argv[i], "perform") == 0)
91 resolve = perform;
92 else if (strcmp(argv[i], "fatal") == 0)
93 resolve = fatal;
94 else if (strcmp(argv[i], "pass") == 0)
95 resolve = pass;
96 else
97 usage(bad_resolve, argv[i]);
98 } else if (strcmp(argv[i], "-l") == 0) {
99 if (++i == argc)
100 usage(use_noarg, argv[i - 1]);
101 hook_library_path = argv[i];
102 } else if (strcmp(argv[i], "-i") == 0) {
103 if (++i == argc)
104 usage(use_noarg, argv[i - 1]);
105 input_file = argv[i];
106 } else if (strcmp(argv[i], "-o") == 0) {
107 if (++i == argc)
108 usage(use_noarg, argv[i - 1]);
109 output_file = argv[i];
f6b8f48d 110 } else
0cd94b5e
TM
111 usage("Unknown command: %s", argv[i]);
112 }
113
114 if (!json && (local_family == 0))
115 usage("address family must be set using %s", "-4 or -6");
116
117 if (input_file == NULL) {
118 input_file = "--stdin--";
119 fd = fileno(stdin);
120 for (;;) {
121 if (newsize == 0)
122 newsize = 1024;
123 else {
124 oldsize = newsize;
125 newsize *= 4;
126 }
127 inbuf = (char *)realloc(inbuf, newsize);
128 if (inbuf == 0)
129 usage("out of memory reading standard "
130 "input: %s", strerror(errno));
131 cc = read(fd, inbuf + oldsize, newsize - oldsize);
132 if (cc < 0)
133 usage("error reading standard input: %s",
134 strerror(errno));
135 if (cc + oldsize < newsize) {
136 newsize = cc + oldsize;
137 break;
138 }
139 }
140 } else {
141 fd = open(input_file, O_RDONLY);
142 if (fd < 0)
143 usage("Cannot open '%s' for reading", input_file);
144 }
145
146 if (output_file) {
147 output = fopen(output_file, "w");
148 if (output == NULL)
149 usage("Cannot open '%s' for writing", output_file);
150 } else
151 output = stdout;
152
153 TAILQ_INIT(&parses);
154 cfile = new_parse(fd, inbuf, newsize, input_file, 0);
155 assert(cfile != NULL);
156
157 if (json) {
158 struct element *elem;
159
160 elem = json_parse(cfile);
161 if (elem != NULL) {
162 print(output, elem, 0, 0);
163 fprintf(output, "\n");
164 }
165 } else {
166 spaces_init();
167 options_init();
168 cnt = conf_file_parse(cfile);
169 if (cfile->stack_top > 0) {
170 print(output, cfile->stack[0], 0, 0);
171 fprintf(output, "\n");
172 }
173 }
174
175 end_parse(cfile);
176
177 exit(cnt);
178}
179
180void
181stackPush(struct parse *pc, struct element *elem)
182{
183 if (pc->stack_top + 2 >= pc->stack_size) {
184 size_t new_size = pc->stack_size + 10;
185 size_t amount = new_size * sizeof(struct element *);
186
187 pc->stack = (struct element **)realloc(pc->stack, amount);
188 if (pc->stack == NULL)
189 parse_error(pc, "can't resize element stack");
190 pc->stack_size = new_size;
191 }
192 pc->stack_top++;
193 pc->stack[pc->stack_top] = elem;
194}
195
196void
197parse_error(struct parse *cfile, const char *fmt, ...)
198{
199 va_list list;
200 char lexbuf[256];
201 char mbuf[1024];
202 char fbuf[1024];
203 unsigned i, lix;
f6b8f48d 204
0cd94b5e
TM
205 snprintf(fbuf, sizeof(fbuf), "%s line %d: %s",
206 cfile->tlname, cfile->lexline, fmt);
f6b8f48d 207
0cd94b5e
TM
208 va_start(list, fmt);
209 vsnprintf(mbuf, sizeof(mbuf), fbuf, list);
210 va_end(list);
211
212 lix = 0;
213 for (i = 0;
214 cfile->token_line[i] && i < (cfile->lexchar - 1); i++) {
215 if (lix < sizeof(lexbuf) - 1)
216 lexbuf[lix++] = ' ';
217 if (cfile->token_line[i] == '\t') {
218 for (; lix < (sizeof lexbuf) - 1 && (lix & 7); lix++)
219 lexbuf[lix] = ' ';
220 }
221 }
222 lexbuf[lix] = 0;
223
224 fprintf(stderr, "%s\n%s\n", mbuf, cfile->token_line);
225 if (cfile->lexchar < 81)
226 fprintf(stderr, "%s^\n", lexbuf);
227 exit(-1);
228}