]> git.ipfire.org Git - thirdparty/dhcp.git/blame - server/db.c
Update license.
[thirdparty/dhcp.git] / server / db.c
CommitLineData
1358b874
TL
1/* db.c
2
3 Persistent database management routines for DHCPD... */
4
5/*
f39b6e00
TL
6 * Copyright (c) 1996-1999 Internet Software Consortium.
7 * Use is subject to license terms which appear in the file named
8 * ISC-LICENSE that should have accompanied this file when you
9 * received it. If a file named ISC-LICENSE did not accompany this
10 * file, or you are not sure the one you have is correct, you may
11 * obtain an applicable copy of the license at:
1358b874 12 *
f39b6e00 13 * http://www.isc.org/isc-license-1.0.html.
1358b874 14 *
f39b6e00
TL
15 * This file is part of the ISC DHCP distribution. The documentation
16 * associated with this file is listed in the file DOCUMENTATION,
17 * included in the top-level directory of this release.
1358b874 18 *
f39b6e00
TL
19 * Support and other services are available for ISC products - see
20 * http://www.isc.org for more information.
1358b874
TL
21 */
22
23#ifndef lint
24static char copyright[] =
f39b6e00 25"$Id: db.c,v 1.22 1999/03/16 05:50:43 mellon Exp $ Copyright (c) 1995, 1996 The Internet Software Consortium. All rights reserved.\n";
1358b874
TL
26#endif /* not lint */
27
28#include "dhcpd.h"
29
30FILE *db_file;
31
08804a9a
TL
32static int counting = 0;
33static int count = 0;
34TIME write_time;
35
1358b874
TL
36/* Write the specified lease to the current lease database file. */
37
38int write_lease (lease)
39 struct lease *lease;
40{
41 struct tm *t;
42 char tbuf [64];
a3115043 43 int errors = 0;
6fdff3b8 44 int i;
1358b874 45
08804a9a
TL
46 if (counting)
47 ++count;
1358b874 48 errno = 0;
a3115043
TL
49 fprintf (db_file, "lease %s {\n", piaddr (lease -> ip_addr));
50 if (errno) {
51 ++errors;
52 }
1358b874 53
3f165a40
TL
54 /* Note: the following is not a Y2K bug - it's a Y1.9K bug. Until
55 somebody invents a time machine, I think we can safely disregard
56 it. */
1358b874 57 t = gmtime (&lease -> starts);
f79741e8 58 sprintf (tbuf, "%d %d/%02d/%02d %02d:%02d:%02d;",
a3115043
TL
59 t -> tm_wday, t -> tm_year + 1900,
60 t -> tm_mon + 1, t -> tm_mday,
61 t -> tm_hour, t -> tm_min, t -> tm_sec);
62 errno = 0;
1358b874 63 fprintf (db_file, "\tstarts %s\n", tbuf);
a3115043
TL
64 if (errno) {
65 ++errors;
66 }
1358b874
TL
67
68 t = gmtime (&lease -> ends);
f79741e8 69 sprintf (tbuf, "%d %d/%02d/%02d %02d:%02d:%02d;",
a3115043
TL
70 t -> tm_wday, t -> tm_year + 1900,
71 t -> tm_mon + 1, t -> tm_mday,
72 t -> tm_hour, t -> tm_min, t -> tm_sec);
73 errno = 0;
1358b874 74 fprintf (db_file, "\tends %s", tbuf);
a3115043
TL
75 if (errno) {
76 ++errors;
77 }
1358b874 78
e2bfe7b3
TL
79 /* If this lease is billed to a class and is still valid,
80 write it out. */
81 if (lease -> billing_class && lease -> ends > cur_time)
82 if (!write_billing_class (lease -> billing_class))
83 ++errors;
84
1358b874 85 if (lease -> hardware_addr.hlen) {
a3115043
TL
86 errno = 0;
87 fprintf (db_file, "\n\thardware %s %s;",
1358b874
TL
88 hardware_types [lease -> hardware_addr.htype],
89 print_hw_addr (lease -> hardware_addr.htype,
90 lease -> hardware_addr.hlen,
91 lease -> hardware_addr.haddr));
a3115043
TL
92 if (errno) {
93 ++errors;
94 }
1358b874
TL
95 }
96 if (lease -> uid_len) {
97 int i;
a3115043 98 errno = 0;
17832ade 99 fprintf (db_file, "\n\tuid %2.2x", lease -> uid [0]);
a3115043
TL
100 if (errno) {
101 ++errors;
102 }
103 for (i = 1; i < lease -> uid_len; i++) {
104 errno = 0;
17832ade 105 fprintf (db_file, ":%2.2x", lease -> uid [i]);
a3115043
TL
106 if (errno) {
107 ++errors;
108 }
109 }
110 putc (';', db_file);
111 }
112 if (lease -> flags & BOOTP_LEASE) {
113 errno = 0;
114 fprintf (db_file, "\n\tdynamic-bootp;");
115 if (errno) {
4006d804
TL
116 ++errors;
117 }
118 }
119 if (lease -> flags & ABANDONED_LEASE) {
120 errno = 0;
121 fprintf (db_file, "\n\tabandoned;");
122 if (errno) {
a3115043 123 ++errors;
00d6d87c
TL
124 }
125 }
126 if (lease -> client_hostname) {
6fdff3b8
TL
127 for (i = 0; lease -> client_hostname [i]; i++)
128 if (lease -> client_hostname [i] < 33 ||
129 lease -> client_hostname [i] > 126)
130 goto bad_client_hostname;
00d6d87c 131 errno = 0;
200d216c 132 fprintf (db_file, "\n\tclient-hostname \"%s\";",
00d6d87c
TL
133 lease -> client_hostname);
134 if (errno) {
135 ++errors;
136 }
137 }
6fdff3b8 138 bad_client_hostname:
00d6d87c 139 if (lease -> hostname) {
6fdff3b8
TL
140 for (i = 0; lease -> hostname [i]; i++)
141 if (lease -> hostname [i] < 33 ||
142 lease -> hostname [i] > 126)
143 goto bad_hostname;
144 errno = 0;
00d6d87c 145 errno = 0;
355f034a 146 fprintf (db_file, "\n\thostname \"%s\";",
36b65b9c 147 lease -> hostname);
00d6d87c
TL
148 if (errno) {
149 ++errors;
a3115043
TL
150 }
151 }
6fdff3b8 152 bad_hostname:
a3115043
TL
153 errno = 0;
154 fputs ("\n}\n", db_file);
155 if (errno) {
156 ++errors;
1358b874 157 }
a3115043 158 if (errors)
8ae2d595 159 log_info ("write_lease: unable to write lease %s",
a3115043
TL
160 piaddr (lease -> ip_addr));
161 return !errors;
1358b874
TL
162}
163
e2bfe7b3
TL
164/* Write a spawned class to the database file. */
165
166int write_billing_class (class)
167 struct class *class;
168{
169 int errors = 0;
170 int i;
171
172 if (!class -> superclass) {
173 errno = 0;
174 fprintf (db_file, "\n\tbilling class \"%s\";", class -> name);
175 return !errno;
176 }
177
178 errno = 0;
179 fprintf (db_file, "\n\tbilling subclass \"%s\"",
180 class -> superclass -> name);
181 if (errno)
182 ++errors;
183
184 for (i = 0; i < class -> hash_string.len; i++)
185 if (!isascii (class -> hash_string.data [i]) ||
186 !isprint (class -> hash_string.data [i]))
187 break;
188 if (i == class -> hash_string.len) {
189 errno = 0;
190 fprintf (db_file, " \"%*.*s\";",
191 class -> hash_string.len,
192 class -> hash_string.len,
193 class -> hash_string.data);
194 if (errno)
195 ++errors;
196 } else {
197 errno = 0;
198 fprintf (db_file, " %2.2x", class -> hash_string.data [0]);
199 if (errno)
200 ++errors;
201 for (i = 1; i < class -> hash_string.len; i++) {
202 errno = 0;
203 fprintf (db_file, ":%2.2x",
204 class -> hash_string.data [i]);
205 if (errno)
206 ++errors;
207 }
208 errno = 0;
209 fprintf (db_file, ";");
210 if (errno)
211 ++errors;
212 }
213
214 class -> dirty = 0;
215 return !errors;
216}
217
1358b874
TL
218/* Commit any leases that have been written out... */
219
220int commit_leases ()
221{
a3115043
TL
222 /* Commit any outstanding writes to the lease database file.
223 We need to do this even if we're rewriting the file below,
224 just in case the rewrite fails. */
225 if (fflush (db_file) == EOF) {
8ae2d595 226 log_info ("commit_leases: unable to commit: %m");
a3115043
TL
227 return 0;
228 }
229 if (fsync (fileno (db_file)) < 0) {
8ae2d595 230 log_info ("commit_leases: unable to commit: %m");
a3115043
TL
231 return 0;
232 }
233
08804a9a
TL
234 /* If we've written more than a thousand leases or if
235 we haven't rewritten the lease database in over an
236 hour, rewrite it now. */
237 if (count > 1000 || (count && cur_time - write_time > 3600)) {
238 count = 0;
239 write_time = cur_time;
240 new_lease_file ();
08804a9a 241 }
1358b874
TL
242 return 1;
243}
244
245void db_startup ()
246{
247 /* Read in the existing lease file... */
248 read_leases ();
249
b16b7f33 250 GET_TIME (&write_time);
1358b874
TL
251 new_lease_file ();
252}
253
254void new_lease_file ()
255{
256 char newfname [512];
257 char backfname [512];
258 TIME t;
30856538 259 int db_fd;
1358b874
TL
260
261 /* If we already have an open database, close it. */
262 if (db_file) {
263 fclose (db_file);
264 }
265
266 /* Make a temporary lease file... */
b16b7f33
TL
267 GET_TIME (&t);
268 sprintf (newfname, "%s.%d", path_dhcpd_db, (int)t);
30856538
TL
269 db_fd = open (newfname, O_WRONLY | O_TRUNC | O_CREAT, 0664);
270 if (db_fd < 0) {
8ae2d595 271 log_fatal ("Can't create new lease file: %m");
30856538
TL
272 }
273 if ((db_file = fdopen (db_fd, "w")) == NULL) {
8ae2d595 274 log_fatal ("Can't fdopen new lease file!");
1358b874
TL
275 }
276
277 /* Write out all the leases that we know of... */
08804a9a 278 counting = 0;
1358b874
TL
279 write_leases ();
280
281 /* Get the old database out of the way... */
e2ac5814 282 sprintf (backfname, "%s~", path_dhcpd_db);
a3115043 283 if (unlink (backfname) < 0 && errno != ENOENT)
8ae2d595 284 log_fatal ("Can't remove old lease database backup %s: %m",
a3115043 285 backfname);
e2ac5814 286 if (link (path_dhcpd_db, backfname) < 0)
8ae2d595 287 log_fatal ("Can't backup lease database %s to %s: %m",
e2ac5814 288 path_dhcpd_db, backfname);
1358b874
TL
289
290 /* Move in the new file... */
e2ac5814 291 if (rename (newfname, path_dhcpd_db) < 0)
8ae2d595 292 log_fatal ("Can't install new lease database %s to %s: %m",
e2ac5814 293 newfname, path_dhcpd_db);
08804a9a
TL
294
295 counting = 1;
1358b874 296}