ISC DHCP 4.4.2b1
A reference DHCPv4 and DHCPv6 implementation
keama.c
Go to the documentation of this file.
1/*
2 * Copyright(c) 2017-2019 by Internet Systems Consortium, Inc.("ISC")
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.
17 * 950 Charter Street
18 * Redwood City, CA 94063
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
51char *hook_library_path = NULL;
52char *input_file = NULL;
53char *output_file = NULL;
54FILE *input = NULL;
55FILE *output = NULL;
59
60static const char use_noarg[] = "No argument for command: %s";
61static const char bad_resolve[] = "Bad -r argument: %s";
62
63int
64main(int argc, char **argv) {
65 int i, fd;
66 char *inbuf = NULL;
67 size_t oldsize = 0;
68 size_t newsize = 0;
69 ssize_t cc;
70 struct parse *cfile;
71 size_t cnt = 0;
72
73 for (i = 1; i < argc; i++) {
74 if (strcmp(argv[i], "-4") == 0)
75 local_family = AF_INET;
76 else if (strcmp(argv[i], "-6") == 0)
77 local_family = AF_INET6;
78 else if (strcmp(argv[i], "-D") == 0)
80 else if (strcmp(argv[i], "-N") == 0)
82 else if (strcmp(argv[i], "-T") == 0)
83 json = ISC_TRUE;
84 else if (strcmp(argv[i], "-r") == 0) {
85 if (++i == argc)
86 usage(use_noarg, argv[i - 1]);
87 if (strcmp(argv[i], "perform") == 0)
89 else if (strcmp(argv[i], "fatal") == 0)
90 resolve = fatal;
91 else if (strcmp(argv[i], "pass") == 0)
92 resolve = pass;
93 else
94 usage(bad_resolve, argv[i]);
95 } else if (strcmp(argv[i], "-l") == 0) {
96 if (++i == argc)
97 usage(use_noarg, argv[i - 1]);
98 hook_library_path = argv[i];
99 } else if (strcmp(argv[i], "-i") == 0) {
100 if (++i == argc)
101 usage(use_noarg, argv[i - 1]);
102 input_file = argv[i];
103 } else if (strcmp(argv[i], "-o") == 0) {
104 if (++i == argc)
105 usage(use_noarg, argv[i - 1]);
106 output_file = argv[i];
107 } else
108 usage("Unknown command: %s", argv[i]);
109 }
110
111 if (!json && (local_family == 0))
112 usage("address family must be set using %s", "-4 or -6");
113
114 if (input_file == NULL) {
115 input_file = "--stdin--";
116 fd = fileno(stdin);
117 for (;;) {
118 if (newsize == 0)
119 newsize = 1024;
120 else {
121 oldsize = newsize;
122 newsize *= 4;
123 }
124 inbuf = (char *)realloc(inbuf, newsize);
125 if (inbuf == 0)
126 usage("out of memory reading standard "
127 "input: %s", strerror(errno));
128 cc = read(fd, inbuf + oldsize, newsize - oldsize);
129 if (cc < 0)
130 usage("error reading standard input: %s",
131 strerror(errno));
132 if (cc + oldsize < newsize) {
133 newsize = cc + oldsize;
134 break;
135 }
136 }
137 } else {
138 fd = open(input_file, O_RDONLY);
139 if (fd < 0)
140 usage("Cannot open '%s' for reading", input_file);
141 }
142
143 if (output_file) {
144 output = fopen(output_file, "w");
145 if (output == NULL)
146 usage("Cannot open '%s' for writing", output_file);
147 } else
148 output = stdout;
149
150 TAILQ_INIT(&parses);
151 cfile = new_parse(fd, inbuf, newsize, input_file, 0);
152 assert(cfile != NULL);
153
154 if (json) {
155 struct element *elem;
156
157 elem = json_parse(cfile);
158 if (elem != NULL) {
159 print(output, elem, 0, 0);
160 fprintf(output, "\n");
161 }
162 } else {
163 spaces_init();
164 options_init();
165 cnt = conf_file_parse(cfile);
166 if (cfile->stack_top > 0) {
167 print(output, cfile->stack[0], 0, 0);
168 fprintf(output, "\n");
169 }
170 }
171
172 end_parse(cfile);
173
174 exit(cnt);
175}
176
177void
178stackPush(struct parse *pc, struct element *elem)
179{
180 if (pc->stack_top + 2 >= pc->stack_size) {
181 size_t new_size = pc->stack_size + 10;
182 size_t amount = new_size * sizeof(struct element *);
183
184 pc->stack = (struct element **)realloc(pc->stack, amount);
185 if (pc->stack == NULL)
186 parse_error(pc, "can't resize element stack");
187 pc->stack_size = new_size;
188 }
189 pc->stack_top++;
190 pc->stack[pc->stack_top] = elem;
191}
192
193void
194parse_error(struct parse *cfile, const char *fmt, ...)
195{
196 va_list list;
197 char lexbuf[256];
198 char mbuf[1024];
199 char fbuf[1024];
200 unsigned i, lix;
201
202 snprintf(fbuf, sizeof(fbuf), "%s line %d: %s",
203 cfile->tlname, cfile->lexline, fmt);
204
205 va_start(list, fmt);
206 vsnprintf(mbuf, sizeof(mbuf), fbuf, list);
207 va_end(list);
208
209 lix = 0;
210 for (i = 0;
211 cfile->token_line[i] && i < (cfile->lexchar - 1); i++) {
212 if (lix < sizeof(lexbuf) - 1)
213 lexbuf[lix++] = ' ';
214 if (cfile->token_line[i] == '\t') {
215 for (; lix < (sizeof lexbuf) - 1 && (lix & 7); lix++)
216 lexbuf[lix] = ' ';
217 }
218 }
219 lexbuf[lix] = 0;
220
221 fprintf(stderr, "%s\n%s\n", mbuf, cfile->token_line);
222 if (cfile->lexchar < 81)
223 fprintf(stderr, "%s^\n", lexbuf);
224 exit(-1);
225}
isc_result_t end_parse(struct parse **cfile)
Definition: conflex.c:103
isc_result_t new_parse(struct parse **cfile, int file, char *inbuf, unsigned buflen, const char *name, int eolp)
Definition: conflex.c:41
void print(FILE *fp, const struct element *e, isc_boolean_t skip, unsigned indent)
Definition: data.c:919
#define TAILQ_INIT(head)
Definition: data.h:72
isc_boolean_t
Definition: data.h:150
#define ISC_TRUE
Definition: data.h:153
#define ISC_FALSE
Definition: data.h:152
struct element * json_parse(struct parse *cfile)
Definition: json.c:32
int local_family
Definition: keama.c:50
isc_boolean_t json
Definition: keama.c:58
char * hook_library_path
Definition: keama.c:51
int main(int argc, char **argv)
Definition: keama.c:64
char * output_file
Definition: keama.c:53
#define KEAMA_USAGE
Definition: keama.c:35
char * input_file
Definition: keama.c:52
isc_boolean_t use_isc_lifetimes
Definition: keama.c:56
void parse_error(struct parse *cfile, const char *fmt,...)
Definition: keama.c:194
FILE * output
Definition: keama.c:55
void stackPush(struct parse *pc, struct element *elem)
Definition: keama.c:178
FILE * input
Definition: keama.c:54
isc_boolean_t global_hr
Definition: keama.c:57
size_t conf_file_parse(struct parse *)
resolve
Definition: keama.h:34
@ pass
Definition: keama.h:37
@ perform
Definition: keama.h:35
@ fatal
Definition: keama.h:36
void options_init(void)
Definition: options.c:419
void spaces_init(void)
Definition: options.c:399
Definition: data.h:216
Definition: dhcpd.h:288
int lexline
Definition: dhcpd.h:289
size_t stack_size
Definition: keama.h:111
char * token_line
Definition: dhcpd.h:291
const char * tlname
Definition: dhcpd.h:294
size_t stack_top
Definition: keama.h:112
int lexchar
Definition: dhcpd.h:290
char * inbuf
Definition: dhcpd.h:328
struct element ** stack
Definition: keama.h:110