1 /************************************************************************
2 Copyright 1988, 1991 by Carnegie Mellon University
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.
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
22 $FreeBSD: src/libexec/bootpd/tools/bootpef/bootpef.c,v 1.6 1999/08/28 00:09:24 peter Exp $
23 $DragonFly: src/libexec/bootpd/tools/bootpef/bootpef.c,v 1.2 2003/06/17 04:27:07 dillon Exp $
25 ************************************************************************/
28 * bootpef - BOOTP Extension File generator
29 * Makes an "Extension File" for each host entry that
30 * defines an and Extension File. (See RFC1497, tag 18.)
47 #include <sys/types.h>
50 #include <netinet/in.h>
51 #include <arpa/inet.h> /* inet_ntoa */
65 /* Yes, memcpy is OK here (no overlapped copies). */
66 #define bcopy(a,b,c) memcpy(b,a,c)
67 #define bzero(p,l) memset(p,0,l)
68 #define bcmp(a,b,c) memcmp(a,b,c)
79 #include "patchlevel.h"
81 #define BUFFERSIZE 0x4000
84 #define CONFIG_FILE "/etc/bootptab"
90 * Externals, forward declarations, and global variables
99 static void mktagfile P((struct host *));
100 static void usage P((void));
111 int debug = 0; /* Debugging flag (level) */
115 * Globals below are associated with the bootp database file (bootptab).
118 char *bootptab = CONFIG_FILE;
122 * Print "usage" message and exit
128 "usage: $s [ -c chdir ] [-d level] [-f configfile] [host...]\n");
129 fprintf(stderr, "\t -c n\tset current directory\n");
130 fprintf(stderr, "\t -d n\tset debug level\n");
131 fprintf(stderr, "\t -f n\tconfig file name\n");
137 * Initialization such as command-line processing is done and then the
138 * main server loop is started.
149 progname = strrchr(argv[0], '/');
150 if (progname) progname++;
151 else progname = argv[0];
153 /* Get work space for making tag 18 files. */
154 buffer = (byte *) malloc(BUFFERSIZE);
156 report(LOG_ERR, "malloc failed");
160 * Set defaults that might be changed by option switches.
167 for (argc--, argv++; argc > 0; argc--, argv++) {
168 if (argv[0][0] != '-')
170 switch (argv[0][1]) {
172 case 'c': /* chdir_path */
174 stmp = &(argv[0][2]);
180 if (!stmp || (stmp[0] != '/')) {
182 "bootpd: invalid chdir specification\n");
188 case 'd': /* debug */
190 stmp = &(argv[0][2]);
191 } else if (argv[1] && argv[1][0] == '-') {
193 * Backwards-compatible behavior:
194 * no parameter, so just increment the debug flag.
203 if (!stmp || (sscanf(stmp, "%d", &n) != 1) || (n < 0)) {
205 "bootpd: invalid debug level\n");
211 case 'f': /* config file */
213 stmp = &(argv[0][2]);
223 fprintf(stderr, "bootpd: unknown switch: -%c\n",
230 /* Get the timezone. */
233 /* Allocate hash tables. */
237 * Read the bootptab file.
239 readtab(1); /* force read */
241 /* Set the cwd (i.e. to /tftpboot) */
243 if (chdir(chdir_path) < 0)
244 report(LOG_ERR, "%s: chdir failed", chdir_path);
246 /* If there are host names on the command line, do only those. */
248 unsigned int tlen, hashcode;
251 tlen = strlen(argv[0]);
252 hashcode = hash_HashFunction((u_char *)argv[0], tlen);
253 hp = (struct host *) hash_Lookup(nmhashtable,
257 printf("%s: no matching entry\n", argv[0]);
260 if (!hp->flags.exten_file) {
261 printf("%s: no extension file\n", argv[0]);
270 /* No host names specified. Do them all. */
271 hp = (struct host *) hash_FirstEntry(nmhashtable);
274 hp = (struct host *) hash_NextEntry(nmhashtable);
282 * Make a "TAG 18" file for this host.
283 * (Insert the RFC1497 options.)
294 if (!hp->flags.exten_file)
298 bytesleft = BUFFERSIZE;
299 bcopy(vm_rfc1048, vp, 4); /* Copy in the magic cookie */
304 * The "extension file" options are appended by the following
305 * function (which is shared with bootpd.c).
307 len = dovend_rfc1497(hp, vp, bytesleft);
312 report(LOG_ERR, "%s: too much option data",
313 hp->exten_file->string);
319 /* Write the buffer to the extension file. */
320 printf("Updating \"%s\"\n", hp->exten_file->string);
321 if ((fp = fopen(hp->exten_file->string, "w")) == NULL) {
322 report(LOG_ERR, "error opening \"%s\": %s",
323 hp->exten_file->string, get_errmsg());
327 if (len != fwrite(buffer, 1, len, fp)) {
328 report(LOG_ERR, "write failed on \"%s\" : %s",
329 hp->exten_file->string, get_errmsg());
339 * c-argdecl-indent: 4
340 * c-continued-statement-offset: 4
341 * c-continued-brace-offset: -4