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
21 ************************************************************************/
23 #include <sys/cdefs.h>
25 __RCSID("$NetBSD: bootpef.c,v 1.8 2008/05/02 19:22:10 xtraeme Exp $");
30 * bootpef - BOOTP Extension File generator
31 * Makes an "Extension File" for each host entry that
32 * defines an and Extension File. (See RFC1497, tag 18.)
45 #include <sys/types.h>
48 #include <netinet/in.h>
49 #include <arpa/inet.h> /* inet_ntoa */
70 #include "patchlevel.h"
72 #define BUFFERSIZE 0x4000
75 #define CONFIG_FILE "/etc/bootptab"
81 * Externals, forward declarations, and global variables
84 static void mktagfile(struct host
*);
85 static void usage(void);
86 int main(int, char **);
95 int debug
= 0; /* Debugging flag (level) */
99 * Globals below are associated with the bootp database file (bootptab).
102 const char *bootptab
= CONFIG_FILE
;
106 * Print "usage" message and exit
112 "usage: %s [-c chdir] [-d level] [-f configfile] [host ...]\n",
114 fprintf(stderr
, "\t -c n\tset current directory\n");
115 fprintf(stderr
, "\t -d n\tset debug level\n");
116 fprintf(stderr
, "\t -f n\tconfig file name\n");
122 * Initialization such as command-line processing is done and then the
123 * main server loop is started.
126 main(int argc
, char **argv
)
132 progname
= strrchr(argv
[0], '/');
133 if (progname
) progname
++;
134 else progname
= argv
[0];
136 /* Get work space for making tag 18 files. */
137 buffer
= (byte
*) malloc(BUFFERSIZE
);
139 report(LOG_ERR
, "malloc failed");
143 * Set defaults that might be changed by option switches.
150 for (argc
--, argv
++; argc
> 0; argc
--, argv
++) {
151 if (argv
[0][0] != '-')
153 switch (argv
[0][1]) {
155 case 'c': /* chdir_path */
157 stmp
= &(argv
[0][2]);
163 if (!stmp
|| (stmp
[0] != '/')) {
165 "bootpd: invalid chdir specification\n");
171 case 'd': /* debug */
173 stmp
= &(argv
[0][2]);
174 } else if (argv
[1] && argv
[1][0] == '-') {
176 * Backwards-compatible behavior:
177 * no parameter, so just increment the debug flag.
186 if (!stmp
|| (sscanf(stmp
, "%d", &n
) != 1) || (n
< 0)) {
188 "bootpd: invalid debug level\n");
194 case 'f': /* config file */
196 stmp
= &(argv
[0][2]);
206 fprintf(stderr
, "bootpd: unknown switch: -%c\n",
213 /* Get the timezone. */
216 /* Allocate hash tables. */
220 * Read the bootptab file.
222 readtab(1); /* force read */
224 /* Set the cwd (i.e. to /tftpboot) */
226 if (chdir(chdir_path
) < 0)
227 report(LOG_ERR
, "%s: chdir failed", chdir_path
);
229 /* If there are host names on the command line, do only those. */
231 unsigned int tlen
, hashcode
;
234 tlen
= strlen(argv
[0]);
235 hashcode
= hash_HashFunction((u_char
*)argv
[0], tlen
);
236 hp
= (struct host
*) hash_Lookup(nmhashtable
,
240 printf("%s: no matching entry\n", argv
[0]);
243 if (!hp
->flags
.exten_file
) {
244 printf("%s: no extension file\n", argv
[0]);
253 /* No host names specified. Do them all. */
254 hp
= (struct host
*) hash_FirstEntry(nmhashtable
);
257 hp
= (struct host
*) hash_NextEntry(nmhashtable
);
265 * Make a "TAG 18" file for this host.
266 * (Insert the RFC1497 options.)
270 mktagfile(struct host
*hp
)
276 if (!hp
->flags
.exten_file
)
280 bytesleft
= BUFFERSIZE
;
281 bcopy(vm_rfc1048
, vp
, 4); /* Copy in the magic cookie */
286 * The "extension file" options are appended by the following
287 * function (which is shared with bootpd.c).
289 len
= dovend_rfc1497(hp
, vp
, bytesleft
);
294 report(LOG_ERR
, "%s: too much option data",
295 hp
->exten_file
->string
);
301 /* Write the buffer to the extension file. */
302 printf("Updating \"%s\"\n", hp
->exten_file
->string
);
303 if ((fp
= fopen(hp
->exten_file
->string
, "w")) == NULL
) {
304 report(LOG_ERR
, "error opening \"%s\": %s",
305 hp
->exten_file
->string
, get_errmsg());
309 if ((size_t)len
!= fwrite(buffer
, 1, len
, fp
)) {
310 report(LOG_ERR
, "write failed on \"%s\" : %s",
311 hp
->exten_file
->string
, get_errmsg());
321 * c-argdecl-indent: 4
322 * c-continued-statement-offset: 4
323 * c-continued-brace-offset: -4