ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid/branches/8.2.x/src/conf_db.c
Revision: 7033
Committed: Sun Jan 3 14:37:29 2016 UTC (10 years, 9 months ago) by michael
Content type: text/x-csrc
File size: 19229 byte(s)
Log Message:
- Renamed MyCalloc to xcalloc

File Contents

# Content
1 /*
2 * ircd-hybrid: an advanced, lightweight Internet Relay Chat Daemon (ircd)
3 *
4 * Copyright (C) 1996-2009 by Andrew Church <achurch@achurch.org>
5 * Copyright (c) 2012-2016 ircd-hybrid development team
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
20 * USA
21 */
22
23 /*! \file conf_db.c
24 * \brief Includes file utilities for database handling
25 * \version $Id$
26 */
27
28
29 #include "stdinc.h"
30 #include "conf_db.h"
31 #include "memory.h"
32 #include "log.h"
33 #include "send.h"
34 #include "irc_string.h"
35 #include "conf.h"
36 #include "hostmask.h"
37 #include "resv.h"
38
39
40 /*! \brief Return the version number on the file. Return 0 if there is no version
41 * number or the number doesn't make sense (i.e. less than 1 or greater
42 * than FILE_VERSION).
43 *
44 * \param f dbFile Struct Member
45 * \return int 0 if failure, 1 > is the version number
46 */
47 static uint32_t
48 get_file_version(struct dbFILE *f)
49 {
50 uint32_t version = 0;
51
52 if (read_uint32(&version, f) == -1)
53 {
54 ilog(LOG_TYPE_IRCD, "Error reading version number on %s: %s",
55 f->filename, strerror(errno));
56 return 0;
57 }
58
59 if (version < 1)
60 {
61 ilog(LOG_TYPE_IRCD, "Invalid version number (%u) on %s",
62 version, f->filename);
63 return 0;
64 }
65
66 return version;
67 }
68
69 /*! \brief Write the current version number to the file.
70 * \param f dbFile Struct Member
71 * \param version Database version
72 * \return 0 on error, 1 on success.
73 */
74 static int
75 write_file_version(struct dbFILE *f, uint32_t version)
76 {
77 if (write_uint32(version, f) == -1)
78 {
79 ilog(LOG_TYPE_IRCD, "Error writing version number on %s",
80 f->filename);
81 return 0;
82 }
83
84 return 1;
85 }
86
87 /*! \brief Open the database for reading
88 * \param filename File to open as the database
89 * \return dbFile struct
90 */
91 static struct dbFILE *
92 open_db_read(const char *filename)
93 {
94 struct dbFILE *f = xcalloc(sizeof(*f));
95 FILE *fp = NULL;
96
97 strlcpy(f->filename, filename, sizeof(f->filename));
98
99 f->mode = 'r';
100 fp = fopen(f->filename, "rb");
101
102 if (!fp)
103 {
104 int errno_save = errno;
105
106 if (errno != ENOENT)
107 ilog(LOG_TYPE_IRCD, "Cannot read database file %s", f->filename);
108
109 xfree(f);
110 errno = errno_save;
111 return NULL;
112 }
113
114 f->fp = fp;
115 return f;
116 }
117
118 /*! \brief Open the database for writting
119 * \param filename File to open as the database
120 * \param version Database version
121 * \return dbFile struct
122 */
123 static struct dbFILE *
124 open_db_write(const char *filename, uint32_t version)
125 {
126 struct dbFILE *f = xcalloc(sizeof(*f));
127 int fd = 0;
128
129 strlcpy(f->filename, filename, sizeof(f->filename));
130
131 filename = f->filename;
132 f->mode = 'w';
133
134 snprintf(f->tempname, sizeof(f->tempname), "%s.new", filename);
135
136 if (f->tempname[0] == '\0' || !strcmp(f->tempname, filename))
137 {
138 ilog(LOG_TYPE_IRCD, "Opening database file %s for write: Filename too long",
139 filename);
140 xfree(f);
141 errno = ENAMETOOLONG;
142 return NULL;
143 }
144
145 remove(f->tempname);
146
147 /* Use open() to avoid people sneaking a new file in under us */
148 fd = open(f->tempname, O_WRONLY | O_CREAT | O_EXCL, 0666);
149 if (fd >= 0)
150 f->fp = fdopen(fd, "wb");
151
152 if (!f->fp || !write_file_version(f, version))
153 {
154 int errno_save = errno;
155 static int walloped = 0;
156
157 if (!walloped++)
158 sendto_realops_flags(UMODE_SERVNOTICE, L_ALL, SEND_NOTICE,
159 "Cannot create temporary database file %s",
160 f->tempname);
161
162 errno = errno_save;
163 ilog(LOG_TYPE_IRCD, "Cannot create temporary database file %s",
164 f->tempname);
165
166 if (f->fp)
167 fclose(f->fp);
168
169 remove(f->tempname);
170 xfree(f);
171
172 errno = errno_save;
173 return NULL;
174 }
175
176 return f;
177 }
178
179 /*! \brief Open a database file for reading (*mode == 'r') or writing (*mode == 'w').
180 * Return the stream pointer, or NULL on error. When opening for write, the
181 * file actually opened is a temporary file, which will be renamed to the
182 * original file on close.
183 *
184 * `version' is only used when opening a file for writing, and indicates the
185 * version number to write to the file.
186 *
187 * \param filename File to open as the database
188 * \param mode Mode for writting or reading
189 * \param version Database version
190 * \return dbFile struct
191 */
192 static struct dbFILE *
193 open_db(const char *filename, const char *mode, uint32_t version)
194 {
195 switch (*mode)
196 {
197 case 'r':
198 return open_db_read(filename);
199 break;
200 case 'w':
201 return open_db_write(filename, version);
202 break;
203 default:
204 errno = EINVAL;
205 return NULL;
206 }
207 }
208
209 /*! \brief Restore the database file to its condition before open_db(). This is
210 * identical to close_db() for files open for reading; however, for files
211 * open for writing, we discard the new temporary file instead of renaming
212 * it over the old file. The value of errno is preserved.
213 *
214 * \param dbFile struct
215 */
216 static void
217 restore_db(struct dbFILE *f)
218 {
219 int errno_save = errno;
220
221 if (f->fp)
222 fclose(f->fp);
223 if (f->mode == 'w' && f->tempname[0])
224 remove(f->tempname);
225
226 xfree(f);
227 errno = errno_save;
228 }
229
230 /*! \brief Close a database file. If the file was opened for write, moves the new
231 * file over the old one, and logs/wallops an error message if the rename()
232 * fails.
233 *
234 * \param dbFile struct
235 * \return -1 on error, 0 on success.
236 */
237 static int
238 close_db(struct dbFILE *f)
239 {
240 int res;
241
242 if (!f->fp)
243 {
244 errno = EINVAL;
245 return -1;
246 }
247
248 res = fclose(f->fp);
249 f->fp = NULL;
250
251 if (res != 0)
252 return -1;
253
254 if (f->mode == 'w' && f->tempname[0] && strcmp(f->tempname, f->filename))
255 {
256 if (rename(f->tempname, f->filename) < 0)
257 {
258 int errno_save = errno;
259
260 sendto_realops_flags(UMODE_SERVNOTICE, L_ALL, SEND_NOTICE, "Unable to move new "
261 "data to database file %s; new data NOT saved.",
262 f->filename);
263 errno = errno_save;
264 ilog(LOG_TYPE_IRCD, "Unable to move new data to database file %s; new "
265 "data NOT saved.", f->filename);
266 remove(f->tempname);
267 }
268 }
269
270 xfree(f);
271 return 0;
272 }
273
274 /*
275 * Read and write 2-, 4- and 8-byte quantities, and strings. All multibyte
276 * values are stored in big-endian order (most significant byte first).
277 * A string is stored with a 2-byte unsigned length (including the trailing
278 * \0) first; a length of 0 indicates that the string pointer is NULL.
279 * Written strings are truncated silently at 4294967294 bytes, and are always
280 * null-terminated.
281 */
282
283 /*! \brief Read a unsigned 8bit integer
284 *
285 * \param ret 16bit integer to read
286 * \param dbFile struct
287 * \return -1 on error, 0 otherwise.
288 */
289 int
290 read_uint16(uint16_t *ret, struct dbFILE *f)
291 {
292 int c1 = fgetc(f->fp);
293 int c2 = fgetc(f->fp);
294
295 if (c1 == EOF || c2 == EOF)
296 return -1;
297
298 *ret = c1 << 8 | c2;
299 return 0;
300 }
301
302 /*! \brief Write a unsigned 16bit integer
303 *
304 * \param val 16bit integer to write
305 * \param dbFile struct
306 * \return -1 on error, 0 otherwise.
307 */
308 int
309 write_uint16(uint16_t val, struct dbFILE *f)
310 {
311 if (fputc((val >> 8) & 0xFF, f->fp) == EOF ||
312 fputc(val & 0xFF, f->fp) == EOF)
313 return -1;
314
315 return 0;
316 }
317
318 /*! \brief Read a unsigned 32bit integer
319 *
320 * \param ret unsigned 32bit integer to read
321 * \param dbFile struct
322 * \return -1 on error, 0 otherwise.
323 */
324 int
325 read_uint32(uint32_t *ret, struct dbFILE *f)
326 {
327 int c1 = fgetc(f->fp);
328 int c2 = fgetc(f->fp);
329 int c3 = fgetc(f->fp);
330 int c4 = fgetc(f->fp);
331
332 if (c1 == EOF || c2 == EOF || c3 == EOF || c4 == EOF)
333 return -1;
334
335 *ret = c1 << 24 | c2 << 16 | c3 << 8 | c4;
336 return 0;
337 }
338
339
340 /*! \brief Write a unsigned 32bit integer
341 *
342 * \param val unsigned 32bit integer to write
343 * \param dbFile struct
344 * \return -1 on error, 0 otherwise.
345 */
346 int
347 write_uint32(uint32_t val, struct dbFILE *f)
348 {
349 if (fputc((val >> 24) & 0xFF, f->fp) == EOF)
350 return -1;
351 if (fputc((val >> 16) & 0xFF, f->fp) == EOF)
352 return -1;
353 if (fputc((val >> 8) & 0xFF, f->fp) == EOF)
354 return -1;
355 if (fputc((val) & 0xFF, f->fp) == EOF)
356 return -1;
357 return 0;
358 }
359
360 /*! \brief Read a unsigned 64bit integer
361 *
362 * \param ret unsigned 64bit integer to read
363 * \param dbFile struct
364 * \return -1 on error, 0 otherwise.
365 */
366 int
367 read_uint64(uint64_t *ret, struct dbFILE *f)
368 {
369 int64_t c1 = fgetc(f->fp);
370 int64_t c2 = fgetc(f->fp);
371 int64_t c3 = fgetc(f->fp);
372 int64_t c4 = fgetc(f->fp);
373 int64_t c5 = fgetc(f->fp);
374 int64_t c6 = fgetc(f->fp);
375 int64_t c7 = fgetc(f->fp);
376 int64_t c8 = fgetc(f->fp);
377
378 if (c1 == EOF || c2 == EOF || c3 == EOF || c4 == EOF ||
379 c5 == EOF || c6 == EOF || c7 == EOF || c8 == EOF)
380 return -1;
381
382 *ret = c1 << 56 | c2 << 48 | c3 << 40 | c4 << 32 |
383 c5 << 24 | c6 << 16 | c7 << 8 | c8;
384 return 0;
385 }
386
387
388 /*! \brief Write a unsigned 64bit integer
389 *
390 * \param val unsigned 64bit integer to write
391 * \param dbFile struct
392 * \return -1 on error, 0 otherwise.
393 */
394 int
395 write_uint64(uint64_t val, struct dbFILE *f)
396 {
397 if (fputc((val >> 56) & 0xFF, f->fp) == EOF)
398 return -1;
399 if (fputc((val >> 48) & 0xFF, f->fp) == EOF)
400 return -1;
401 if (fputc((val >> 40) & 0xFF, f->fp) == EOF)
402 return -1;
403 if (fputc((val >> 32) & 0xFF, f->fp) == EOF)
404 return -1;
405 if (fputc((val >> 24) & 0xFF, f->fp) == EOF)
406 return -1;
407 if (fputc((val >> 16) & 0xFF, f->fp) == EOF)
408 return -1;
409 if (fputc((val >> 8) & 0xFF, f->fp) == EOF)
410 return -1;
411 if (fputc((val) & 0xFF, f->fp) == EOF)
412 return -1;
413 return 0;
414 }
415
416 /*! \brief Read String
417 *
418 * \param ret string
419 * \param dbFile struct
420 * \return -1 on error, 0 otherwise.
421 */
422 int
423 read_string(char **ret, struct dbFILE *f)
424 {
425 char *s = NULL;
426 uint32_t len = 0;
427
428 if (read_uint32(&len, f) < 0)
429 return -1;
430
431 if (len == 0)
432 {
433 *ret = NULL;
434 return 0;
435 }
436
437 s = xcalloc(len);
438
439 if (len != fread(s, 1, len, f->fp))
440 {
441 xfree(s);
442 return -1;
443 }
444
445 *ret = s;
446 return 0;
447 }
448
449 /*! \brief Write String
450 *
451 * \param s string
452 * \param dbFile struct
453 * \return -1 on error, 0 otherwise.
454 */
455 int
456 write_string(const char *s, struct dbFILE *f)
457 {
458 uint32_t len = 0;
459
460 if (!s)
461 return write_uint32(0, f);
462
463 len = strlen(s);
464
465 if (len > 4294967294)
466 len = 4294967294;
467 if (write_uint32(len + 1, f) < 0)
468 return -1;
469 if (len > 0 && fwrite(s, 1, len, f->fp) != len)
470 return -1;
471 if (fputc(0, f->fp) == EOF)
472 return -1;
473
474 return 0;
475 }
476
477 #define SAFE_READ(x) do { \
478 if ((x) < 0) { \
479 break; \
480 } \
481 } while (0)
482
483 #define SAFE_WRITE(x,db) do { \
484 if ((x) < 0) { \
485 restore_db(f); \
486 ilog(LOG_TYPE_IRCD, "Write error on %s", db); \
487 return; \
488 } \
489 } while (0)
490
491 void
492 save_kline_database(const char *filename)
493 {
494 uint32_t i = 0;
495 uint32_t records = 0;
496 struct dbFILE *f = NULL;
497 dlink_node *ptr = NULL;
498
499 if (!(f = open_db(filename, "w", KLINE_DB_VERSION)))
500 return;
501
502 for (i = 0; i < ATABLE_SIZE; ++i)
503 {
504 DLINK_FOREACH(ptr, atable[i].head)
505 {
506 struct AddressRec *arec = ptr->data;
507
508 if (arec->type == CONF_KLINE && IsConfDatabase(arec->conf))
509 ++records;
510 }
511 }
512
513 SAFE_WRITE(write_uint32(records, f), filename);
514
515 for (i = 0; i < ATABLE_SIZE; ++i)
516 {
517 DLINK_FOREACH(ptr, atable[i].head)
518 {
519 struct AddressRec *arec = ptr->data;
520
521 if (arec->type == CONF_KLINE && IsConfDatabase(arec->conf))
522 {
523 SAFE_WRITE(write_string(arec->conf->user, f), filename);
524 SAFE_WRITE(write_string(arec->conf->host, f), filename);
525 SAFE_WRITE(write_string(arec->conf->reason, f), filename);
526 SAFE_WRITE(write_uint64(arec->conf->setat, f), filename);
527 SAFE_WRITE(write_uint64(arec->conf->until, f), filename);
528 }
529 }
530 }
531
532 close_db(f);
533 }
534
535 void
536 load_kline_database(const char *filename)
537 {
538 struct dbFILE *f = NULL;
539 struct MaskItem *conf = NULL;
540 char *field_1 = NULL;
541 char *field_2 = NULL;
542 char *field_3 = NULL;
543 uint32_t i = 0;
544 uint32_t records = 0;
545 uint64_t field_4 = 0;
546 uint64_t field_5 = 0;
547
548 if (!(f = open_db(filename, "r", KLINE_DB_VERSION)))
549 return;
550
551 if (get_file_version(f) < 1)
552 {
553 close_db(f);
554 return;
555 }
556
557 read_uint32(&records, f);
558
559 for (i = 0; i < records; ++i)
560 {
561 SAFE_READ(read_string(&field_1, f));
562 SAFE_READ(read_string(&field_2, f));
563 SAFE_READ(read_string(&field_3, f));
564 SAFE_READ(read_uint64(&field_4, f));
565 SAFE_READ(read_uint64(&field_5, f));
566
567 conf = conf_make(CONF_KLINE);
568 conf->user = field_1;
569 conf->host = field_2;
570 conf->reason = field_3;
571 conf->setat = field_4;
572 conf->until = field_5;
573 SetConfDatabase(conf);
574
575 add_conf_by_address(CONF_KLINE, conf);
576 }
577
578 close_db(f);
579 }
580
581 void
582 save_dline_database(const char *filename)
583 {
584 uint32_t i = 0;
585 uint32_t records = 0;
586 struct dbFILE *f = NULL;
587 dlink_node *ptr = NULL;
588
589 if (!(f = open_db(filename, "w", KLINE_DB_VERSION)))
590 return;
591
592 for (i = 0; i < ATABLE_SIZE; ++i)
593 {
594 DLINK_FOREACH(ptr, atable[i].head)
595 {
596 struct AddressRec *arec = ptr->data;
597
598 if (arec->type == CONF_DLINE && IsConfDatabase(arec->conf))
599 ++records;
600 }
601 }
602
603 SAFE_WRITE(write_uint32(records, f), filename);
604
605 for (i = 0; i < ATABLE_SIZE; ++i)
606 {
607 DLINK_FOREACH(ptr, atable[i].head)
608 {
609 struct AddressRec *arec = ptr->data;
610
611 if (arec->type == CONF_DLINE && IsConfDatabase(arec->conf))
612 {
613 SAFE_WRITE(write_string(arec->conf->host, f), filename);
614 SAFE_WRITE(write_string(arec->conf->reason, f), filename);
615 SAFE_WRITE(write_uint64(arec->conf->setat, f), filename);
616 SAFE_WRITE(write_uint64(arec->conf->until, f), filename);
617 }
618 }
619 }
620
621 close_db(f);
622 }
623
624 void
625 load_dline_database(const char *filename)
626 {
627 struct dbFILE *f = NULL;
628 struct MaskItem *conf = NULL;
629 char *field_1 = NULL;
630 char *field_2 = NULL;
631 uint32_t i = 0;
632 uint32_t records = 0;
633 uint64_t field_3 = 0;
634 uint64_t field_4 = 0;
635
636 if (!(f = open_db(filename, "r", KLINE_DB_VERSION)))
637 return;
638
639 if (get_file_version(f) < 1)
640 {
641 close_db(f);
642 return;
643 }
644
645 read_uint32(&records, f);
646
647 for (i = 0; i < records; ++i)
648 {
649 SAFE_READ(read_string(&field_1, f));
650 SAFE_READ(read_string(&field_2, f));
651 SAFE_READ(read_uint64(&field_3, f));
652 SAFE_READ(read_uint64(&field_4, f));
653
654 conf = conf_make(CONF_DLINE);
655 conf->host = field_1;
656 conf->reason = field_2;
657 conf->setat = field_3;
658 conf->until = field_4;
659 SetConfDatabase(conf);
660
661 add_conf_by_address(CONF_DLINE, conf);
662 }
663
664 close_db(f);
665 }
666
667 void
668 save_resv_database(const char *filename)
669 {
670 uint32_t records = 0;
671 struct dbFILE *f = NULL;
672 dlink_node *ptr = NULL;
673 struct MaskItem *conf = NULL;
674
675 if (!(f = open_db(filename, "w", KLINE_DB_VERSION)))
676 return;
677
678 DLINK_FOREACH(ptr, cresv_items.head)
679 {
680 conf = ptr->data;
681
682 if (IsConfDatabase(conf))
683 ++records;
684 }
685
686 DLINK_FOREACH(ptr, nresv_items.head)
687 {
688 conf = ptr->data;
689
690 if (IsConfDatabase(conf))
691 ++records;
692 }
693
694 SAFE_WRITE(write_uint32(records, f), filename);
695
696 DLINK_FOREACH(ptr, cresv_items.head)
697 {
698 conf = ptr->data;
699
700 if (!IsConfDatabase(conf))
701 continue;
702
703 SAFE_WRITE(write_string(conf->name, f), filename);
704 SAFE_WRITE(write_string(conf->reason, f), filename);
705 SAFE_WRITE(write_uint64(conf->setat, f), filename);
706 SAFE_WRITE(write_uint64(conf->until, f), filename);
707 }
708
709 DLINK_FOREACH(ptr, nresv_items.head)
710 {
711 conf = ptr->data;
712
713 if (!IsConfDatabase(conf))
714 continue;
715
716 SAFE_WRITE(write_string(conf->name, f), filename);
717 SAFE_WRITE(write_string(conf->reason, f), filename);
718 SAFE_WRITE(write_uint64(conf->setat, f), filename);
719 SAFE_WRITE(write_uint64(conf->until, f), filename);
720 }
721
722 close_db(f);
723 }
724
725 void
726 load_resv_database(const char *filename)
727 {
728 uint32_t i = 0;
729 uint32_t records = 0;
730 uint64_t tmp64_hold = 0, tmp64_setat = 0;
731 struct dbFILE *f = NULL;
732 char *name = NULL;
733 char *reason = NULL;
734 struct MaskItem *conf = NULL;
735
736 if (!(f = open_db(filename, "r", KLINE_DB_VERSION)))
737 return;
738
739 if (get_file_version(f) < 1)
740 {
741 close_db(f);
742 return;
743 }
744
745 read_uint32(&records, f);
746
747 for (i = 0; i < records; ++i)
748 {
749 SAFE_READ(read_string(&name, f));
750 SAFE_READ(read_string(&reason, f));
751 SAFE_READ(read_uint64(&tmp64_setat, f));
752 SAFE_READ(read_uint64(&tmp64_hold, f));
753
754 if ((conf = create_resv(name, reason, NULL)) == NULL)
755 continue;
756
757 conf->setat = tmp64_setat;
758 conf->until = tmp64_hold;
759 SetConfDatabase(conf);
760
761 xfree(name);
762 xfree(reason);
763 }
764
765 close_db(f);
766 }
767
768 void
769 save_xline_database(const char *filename)
770 {
771 uint32_t records = 0;
772 struct dbFILE *f = NULL;
773 dlink_node *ptr = NULL;
774 struct MaskItem *conf = NULL;
775
776 if (!(f = open_db(filename, "w", KLINE_DB_VERSION)))
777 return;
778
779 DLINK_FOREACH(ptr, gecos_items.head)
780 {
781 conf = ptr->data;
782
783 if (IsConfDatabase(conf))
784 ++records;
785 }
786
787 SAFE_WRITE(write_uint32(records, f), filename);
788
789 DLINK_FOREACH(ptr, gecos_items.head)
790 {
791 conf = ptr->data;
792
793 if (!IsConfDatabase(conf))
794 continue;
795
796 SAFE_WRITE(write_string(conf->name, f), filename);
797 SAFE_WRITE(write_string(conf->reason, f), filename);
798 SAFE_WRITE(write_uint64(conf->setat, f), filename);
799 SAFE_WRITE(write_uint64(conf->until, f), filename);
800 }
801
802 close_db(f);
803 }
804
805 void
806 load_xline_database(const char *filename)
807 {
808 uint32_t i = 0;
809 uint32_t records = 0;
810 uint64_t tmp64_hold = 0, tmp64_setat = 0;
811 struct dbFILE *f = NULL;
812 char *name = NULL;
813 char *reason = NULL;
814 struct MaskItem *conf = NULL;
815
816 if (!(f = open_db(filename, "r", KLINE_DB_VERSION)))
817 return;
818
819 if (get_file_version(f) < 1)
820 {
821 close_db(f);
822 return;
823 }
824
825 read_uint32(&records, f);
826
827 for (i = 0; i < records; ++i)
828 {
829 SAFE_READ(read_string(&name, f));
830 SAFE_READ(read_string(&reason, f));
831 SAFE_READ(read_uint64(&tmp64_setat, f));
832 SAFE_READ(read_uint64(&tmp64_hold, f));
833
834 conf = conf_make(CONF_XLINE);
835
836 SetConfDatabase(conf);
837
838 conf->name = name;
839 conf->reason = reason;
840 conf->setat = tmp64_setat;
841 conf->until = tmp64_hold;
842 }
843
844 close_db(f);
845 }
846
847 void
848 save_all_databases(void *unused)
849 {
850 save_kline_database(ConfigGeneral.klinefile);
851 save_dline_database(ConfigGeneral.dlinefile);
852 save_xline_database(ConfigGeneral.xlinefile);
853 save_resv_database(ConfigGeneral.resvfile);
854 }

Properties

Name Value
svn:eol-style native
svn:keywords Id Revision