ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid/trunk/src/conf_db.c
Revision: 1858
Committed: Thu Apr 25 15:00:52 2013 UTC (12 years, 4 months ago) by michael
Content type: text/x-csrc
File size: 22044 byte(s)
Log Message:
- Added basic support for libGeoIP
- Added exempt configuration option to resv{} blocks

File Contents

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

Properties

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