Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/libexec/bootpd/tools/bootpef/bootpef.c
34898 views
1
/************************************************************************
2
Copyright 1988, 1991 by Carnegie Mellon University
3
4
All Rights Reserved
5
6
Permission to use, copy, modify, and distribute this software and its
7
documentation for any purpose and without fee is hereby granted, provided
8
that the above copyright notice appear in all copies and that both that
9
copyright notice and this permission notice appear in supporting
10
documentation, and that the name of Carnegie Mellon University not be used
11
in advertising or publicity pertaining to distribution of the software
12
without specific, written prior permission.
13
14
CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
15
SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
16
IN NO EVENT SHALL CMU BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
17
DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
18
PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
19
ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
20
SOFTWARE.
21
22
************************************************************************/
23
24
/*
25
* bootpef - BOOTP Extension File generator
26
* Makes an "Extension File" for each host entry that
27
* defines an and Extension File. (See RFC1497, tag 18.)
28
*
29
* HISTORY
30
* See ./Changes
31
*
32
* BUGS
33
* See ./ToDo
34
*/
35
36
37
38
#include <stdarg.h>
39
40
#include <sys/types.h>
41
#include <sys/time.h>
42
43
#include <netinet/in.h>
44
#include <arpa/inet.h> /* inet_ntoa */
45
46
#ifndef NO_UNISTD
47
#include <unistd.h>
48
#endif
49
#include <stdlib.h>
50
#include <stdio.h>
51
#include <string.h>
52
#include <errno.h>
53
#include <ctype.h>
54
#include <syslog.h>
55
56
#include "bootp.h"
57
#include "hash.h"
58
#include "hwaddr.h"
59
#include "bootpd.h"
60
#include "dovend.h"
61
#include "readfile.h"
62
#include "report.h"
63
#include "tzone.h"
64
#include "patchlevel.h"
65
66
#define BUFFERSIZE 0x4000
67
68
#ifndef CONFIG_FILE
69
#define CONFIG_FILE "/etc/bootptab"
70
#endif
71
72
73
74
/*
75
* Externals, forward declarations, and global variables
76
*/
77
78
static void mktagfile(struct host *);
79
static void usage(void) __dead2;
80
81
/*
82
* General
83
*/
84
85
char *progname;
86
char *chdir_path;
87
int debug = 0; /* Debugging flag (level) */
88
byte *buffer;
89
90
/*
91
* Globals below are associated with the bootp database file (bootptab).
92
*/
93
94
char *bootptab = CONFIG_FILE;
95
96
97
/*
98
* Print "usage" message and exit
99
*/
100
static void
101
usage(void)
102
{
103
fprintf(stderr,
104
"usage: $s [ -c chdir ] [-d level] [-f configfile] [host...]\n");
105
fprintf(stderr, "\t -c n\tset current directory\n");
106
fprintf(stderr, "\t -d n\tset debug level\n");
107
fprintf(stderr, "\t -f n\tconfig file name\n");
108
exit(1);
109
}
110
111
112
/*
113
* Initialization such as command-line processing is done and then the
114
* main server loop is started.
115
*/
116
int
117
main(int argc, char **argv)
118
{
119
struct host *hp;
120
char *stmp;
121
int n;
122
123
progname = strrchr(argv[0], '/');
124
if (progname) progname++;
125
else progname = argv[0];
126
127
/* Get work space for making tag 18 files. */
128
buffer = (byte *) malloc(BUFFERSIZE);
129
if (!buffer) {
130
report(LOG_ERR, "malloc failed");
131
exit(1);
132
}
133
/*
134
* Set defaults that might be changed by option switches.
135
*/
136
stmp = NULL;
137
138
/*
139
* Read switches.
140
*/
141
for (argc--, argv++; argc > 0; argc--, argv++) {
142
if (argv[0][0] != '-')
143
break;
144
switch (argv[0][1]) {
145
146
case 'c': /* chdir_path */
147
if (argv[0][2]) {
148
stmp = &(argv[0][2]);
149
} else {
150
argc--;
151
argv++;
152
stmp = argv[0];
153
}
154
if (!stmp || (stmp[0] != '/')) {
155
fprintf(stderr,
156
"bootpd: invalid chdir specification\n");
157
break;
158
}
159
chdir_path = stmp;
160
break;
161
162
case 'd': /* debug */
163
if (argv[0][2]) {
164
stmp = &(argv[0][2]);
165
} else if (argv[1] && argv[1][0] == '-') {
166
/*
167
* Backwards-compatible behavior:
168
* no parameter, so just increment the debug flag.
169
*/
170
debug++;
171
break;
172
} else {
173
argc--;
174
argv++;
175
stmp = argv[0];
176
}
177
if (!stmp || (sscanf(stmp, "%d", &n) != 1) || (n < 0)) {
178
fprintf(stderr,
179
"bootpd: invalid debug level\n");
180
break;
181
}
182
debug = n;
183
break;
184
185
case 'f': /* config file */
186
if (argv[0][2]) {
187
stmp = &(argv[0][2]);
188
} else {
189
argc--;
190
argv++;
191
stmp = argv[0];
192
}
193
bootptab = stmp;
194
break;
195
196
default:
197
fprintf(stderr, "bootpd: unknown switch: -%c\n",
198
argv[0][1]);
199
usage();
200
break;
201
}
202
}
203
204
/* Get the timezone. */
205
tzone_init();
206
207
/* Allocate hash tables. */
208
rdtab_init();
209
210
/*
211
* Read the bootptab file.
212
*/
213
readtab(1); /* force read */
214
215
/* Set the cwd (i.e. to /tftpboot) */
216
if (chdir_path) {
217
if (chdir(chdir_path) < 0)
218
report(LOG_ERR, "%s: chdir failed", chdir_path);
219
}
220
/* If there are host names on the command line, do only those. */
221
if (argc > 0) {
222
unsigned int tlen, hashcode;
223
224
while (argc) {
225
tlen = strlen(argv[0]);
226
hashcode = hash_HashFunction((u_char *)argv[0], tlen);
227
hp = (struct host *) hash_Lookup(nmhashtable,
228
hashcode,
229
nmcmp, argv[0]);
230
if (!hp) {
231
printf("%s: no matching entry\n", argv[0]);
232
exit(1);
233
}
234
if (!hp->flags.exten_file) {
235
printf("%s: no extension file\n", argv[0]);
236
exit(1);
237
}
238
mktagfile(hp);
239
argv++;
240
argc--;
241
}
242
exit(0);
243
}
244
/* No host names specified. Do them all. */
245
hp = (struct host *) hash_FirstEntry(nmhashtable);
246
while (hp != NULL) {
247
mktagfile(hp);
248
hp = (struct host *) hash_NextEntry(nmhashtable);
249
}
250
return (0);
251
}
252
253
254
255
/*
256
* Make a "TAG 18" file for this host.
257
* (Insert the RFC1497 options.)
258
*/
259
260
static void
261
mktagfile(struct host *hp)
262
{
263
FILE *fp;
264
int bytesleft, len;
265
byte *vp;
266
267
if (!hp->flags.exten_file)
268
return;
269
270
vp = buffer;
271
bytesleft = BUFFERSIZE;
272
bcopy(vm_rfc1048, vp, 4); /* Copy in the magic cookie */
273
vp += 4;
274
bytesleft -= 4;
275
276
/*
277
* The "extension file" options are appended by the following
278
* function (which is shared with bootpd.c).
279
*/
280
len = dovend_rfc1497(hp, vp, bytesleft);
281
vp += len;
282
bytesleft -= len;
283
284
if (bytesleft < 1) {
285
report(LOG_ERR, "%s: too much option data",
286
hp->exten_file->string);
287
return;
288
}
289
*vp++ = TAG_END;
290
bytesleft--;
291
292
/* Write the buffer to the extension file. */
293
printf("Updating \"%s\"\n", hp->exten_file->string);
294
if ((fp = fopen(hp->exten_file->string, "w")) == NULL) {
295
report(LOG_ERR, "error opening \"%s\": %s",
296
hp->exten_file->string, get_errmsg());
297
return;
298
}
299
len = vp - buffer;
300
if (len != fwrite(buffer, 1, len, fp)) {
301
report(LOG_ERR, "write failed on \"%s\" : %s",
302
hp->exten_file->string, get_errmsg());
303
}
304
fclose(fp);
305
306
} /* mktagfile */
307
308
/*
309
* Local Variables:
310
* tab-width: 4
311
* c-indent-level: 4
312
* c-argdecl-indent: 4
313
* c-continued-statement-offset: 4
314
* c-continued-brace-offset: -4
315
* c-label-offset: -4
316
* c-brace-offset: 0
317
* End:
318
*/
319
320