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 $
24 ************************************************************************/
27 * bootpef - BOOTP Extension File generator
28 * Makes an "Extension File" for each host entry that
29 * defines an and Extension File. (See RFC1497, tag 18.)
46 #include <sys/types.h>
49 #include <netinet/in.h>
50 #include <arpa/inet.h> /* inet_ntoa */
64 /* Yes, memcpy is OK here (no overlapped copies). */
65 #define bcopy(a,b,c) memcpy(b,a,c)
66 #define bzero(p,l) memset(p,0,l)
67 #define bcmp(a,b,c) memcmp(a,b,c)
78 #include "patchlevel.h"
80 #define BUFFERSIZE 0x4000
83 #define CONFIG_FILE "/etc/bootptab"
89 * Externals, forward declarations, and global variables
98 static void mktagfile P((struct host *));
99 static void usage P((void));
110 int debug = 0; /* Debugging flag (level) */
114 * Globals below are associated with the bootp database file (bootptab).
117 char *bootptab = CONFIG_FILE;
121 * Print "usage" message and exit
127 "usage: $s [ -c chdir ] [-d level] [-f configfile] [host...]\n");
128 fprintf(stderr, "\t -c n\tset current directory\n");
129 fprintf(stderr, "\t -d n\tset debug level\n");
130 fprintf(stderr, "\t -f n\tconfig file name\n");
136 * Initialization such as command-line processing is done and then the
137 * main server loop is started.
148 progname = strrchr(argv[0], '/');
149 if (progname) progname++;
150 else progname = argv[0];
152 /* Get work space for making tag 18 files. */
153 buffer = (byte *) malloc(BUFFERSIZE);
155 report(LOG_ERR, "malloc failed");
159 * Set defaults that might be changed by option switches.
166 for (argc--, argv++; argc > 0; argc--, argv++) {
167 if (argv[0][0] != '-')
169 switch (argv[0][1]) {
171 case 'c': /* chdir_path */
173 stmp = &(argv[0][2]);
179 if (!stmp || (stmp[0] != '/')) {
181 "bootpd: invalid chdir specification\n");
187 case 'd': /* debug */
189 stmp = &(argv[0][2]);
190 } else if (argv[1] && argv[1][0] == '-') {
192 * Backwards-compatible behavior:
193 * no parameter, so just increment the debug flag.
202 if (!stmp || (sscanf(stmp, "%d", &n) != 1) || (n < 0)) {
204 "bootpd: invalid debug level\n");
210 case 'f': /* config file */
212 stmp = &(argv[0][2]);
222 fprintf(stderr, "bootpd: unknown switch: -%c\n",
229 /* Get the timezone. */
232 /* Allocate hash tables. */
236 * Read the bootptab file.
238 readtab(1); /* force read */
240 /* Set the cwd (i.e. to /tftpboot) */
242 if (chdir(chdir_path) < 0)
243 report(LOG_ERR, "%s: chdir failed", chdir_path);
245 /* If there are host names on the command line, do only those. */
247 unsigned int tlen, hashcode;
250 tlen = strlen(argv[0]);
251 hashcode = hash_HashFunction((u_char *)argv[0], tlen);
252 hp = (struct host *) hash_Lookup(nmhashtable,
256 printf("%s: no matching entry\n", argv[0]);
259 if (!hp->flags.exten_file) {
260 printf("%s: no extension file\n", argv[0]);
269 /* No host names specified. Do them all. */
270 hp = (struct host *) hash_FirstEntry(nmhashtable);
273 hp = (struct host *) hash_NextEntry(nmhashtable);
281 * Make a "TAG 18" file for this host.
282 * (Insert the RFC1497 options.)
293 if (!hp->flags.exten_file)
297 bytesleft = BUFFERSIZE;
298 bcopy(vm_rfc1048, vp, 4); /* Copy in the magic cookie */
303 * The "extension file" options are appended by the following
304 * function (which is shared with bootpd.c).
306 len = dovend_rfc1497(hp, vp, bytesleft);
311 report(LOG_ERR, "%s: too much option data",
312 hp->exten_file->string);
318 /* Write the buffer to the extension file. */
319 printf("Updating \"%s\"\n", hp->exten_file->string);
320 if ((fp = fopen(hp->exten_file->string, "w")) == NULL) {
321 report(LOG_ERR, "error opening \"%s\": %s",
322 hp->exten_file->string, get_errmsg());
326 if (len != fwrite(buffer, 1, len, fp)) {
327 report(LOG_ERR, "write failed on \"%s\" : %s",
328 hp->exten_file->string, get_errmsg());
338 * c-argdecl-indent: 4
339 * c-continued-statement-offset: 4
340 * c-continued-brace-offset: -4