ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid/trunk/src/conf_db.c
Revision: 3504
Committed: Sat May 10 19:51:29 2014 UTC (11 years, 3 months ago) by michael
Content type: text/x-csrc
File size: 22068 byte(s)
Log Message:
- Renamed MyMalloc() to MyCalloc()

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-2014 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., 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
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 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 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 = MyCalloc(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 MyFree(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 = MyCalloc(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 MyFree(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_ALL, 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 MyFree(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 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 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 MyFree(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 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_ALL, 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 MyFree(f);
271 return 0;
272 }
273
274 /*
275 * Read and write 2-, 4- and 8-byte quantities, pointers, and strings. All
276 * multibyte values are stored in big-endian order (most significant byte
277 * first). A pointer is stored as a byte, either 0 if NULL or 1 if not,
278 * and read pointers are returned as either (void *)0 or (void *)1. A
279 * string is stored with a 2-byte unsigned length (including the trailing
280 * \0) first; a length of 0 indicates that the string pointer is NULL.
281 * Written strings are truncated silently at 4294967294 bytes, and are always
282 * null-terminated.
283 */
284
285 /*! \brief Read a unsigned 8bit integer
286 *
287 * \param ret 8bit integer to read
288 * \param dbFile struct
289 * \return -1 on error, 0 otherwise.
290 */
291 int
292 read_uint8(uint8_t*ret, struct dbFILE *f)
293 {
294 int c = fgetc(f->fp);
295
296 if (c == EOF)
297 return -1;
298
299 *ret = c;
300 return 0;
301 }
302
303 /*! \brief Write a 8bit integer
304 *
305 * \param val 8bit integer to write
306 * \param dbFile struct
307 * \return -1 on error, 0 otherwise.
308 */
309 int
310 write_uint8(uint8_t val, struct dbFILE *f)
311 {
312 if (fputc(val, f->fp) == EOF)
313 return -1;
314
315 return 0;
316 }
317
318 /*! \brief Read a unsigned 8bit integer
319 *
320 * \param ret 16bit integer to read
321 * \param dbFile struct
322 * \return -1 on error, 0 otherwise.
323 */
324 int
325 read_uint16(uint16_t *ret, struct dbFILE *f)
326 {
327 int c1 = fgetc(f->fp);
328 int c2 = fgetc(f->fp);
329
330 if (c1 == EOF || c2 == EOF)
331 return -1;
332
333 *ret = c1 << 8 | c2;
334 return 0;
335 }
336
337 /*! \brief Write a unsigned 16bit integer
338 *
339 * \param val 16bit integer to write
340 * \param dbFile struct
341 * \return -1 on error, 0 otherwise.
342 */
343 int
344 write_uint16(uint16_t val, struct dbFILE *f)
345 {
346 if (fputc((val >> 8) & 0xFF, f->fp) == EOF ||
347 fputc(val & 0xFF, f->fp) == EOF)
348 return -1;
349
350 return 0;
351 }
352
353 /*! \brief Read a unsigned 32bit integer
354 *
355 * \param ret unsigned 32bit integer to read
356 * \param dbFile struct
357 * \return -1 on error, 0 otherwise.
358 */
359 int
360 read_uint32(uint32_t *ret, struct dbFILE *f)
361 {
362 int c1 = fgetc(f->fp);
363 int c2 = fgetc(f->fp);
364 int c3 = fgetc(f->fp);
365 int c4 = fgetc(f->fp);
366
367 if (c1 == EOF || c2 == EOF || c3 == EOF || c4 == EOF)
368 return -1;
369
370 *ret = c1 << 24 | c2 << 16 | c3 << 8 | c4;
371 return 0;
372 }
373
374
375 /*! \brief Write a unsigned 32bit integer
376 *
377 * \param val unsigned 32bit integer to write
378 * \param dbFile struct
379 * \return -1 on error, 0 otherwise.
380 */
381 int
382 write_uint32(uint32_t val, struct dbFILE *f)
383 {
384 if (fputc((val >> 24) & 0xFF, f->fp) == EOF)
385 return -1;
386 if (fputc((val >> 16) & 0xFF, f->fp) == EOF)
387 return -1;
388 if (fputc((val >> 8) & 0xFF, f->fp) == EOF)
389 return -1;
390 if (fputc((val) & 0xFF, f->fp) == EOF)
391 return -1;
392 return 0;
393 }
394
395 /*! \brief Read a unsigned 64bit integer
396 *
397 * \param ret unsigned 64bit integer to read
398 * \param dbFile struct
399 * \return -1 on error, 0 otherwise.
400 */
401 int
402 read_uint64(uint64_t *ret, struct dbFILE *f)
403 {
404 int64_t c1 = fgetc(f->fp);
405 int64_t c2 = fgetc(f->fp);
406 int64_t c3 = fgetc(f->fp);
407 int64_t c4 = fgetc(f->fp);
408 int64_t c5 = fgetc(f->fp);
409 int64_t c6 = fgetc(f->fp);
410 int64_t c7 = fgetc(f->fp);
411 int64_t c8 = fgetc(f->fp);
412
413 if (c1 == EOF || c2 == EOF || c3 == EOF || c4 == EOF ||
414 c5 == EOF || c6 == EOF || c7 == EOF || c8 == EOF)
415 return -1;
416
417 *ret = c1 << 56 | c2 << 48 | c3 << 40 | c4 << 32 |
418 c5 << 24 | c6 << 16 | c7 << 8 | c8;
419 return 0;
420 }
421
422
423 /*! \brief Write a unsigned 64bit integer
424 *
425 * \param val unsigned 64bit integer to write
426 * \param dbFile struct
427 * \return -1 on error, 0 otherwise.
428 */
429 int
430 write_uint64(uint64_t val, struct dbFILE *f)
431 {
432 if (fputc((val >> 56) & 0xFF, f->fp) == EOF)
433 return -1;
434 if (fputc((val >> 48) & 0xFF, f->fp) == EOF)
435 return -1;
436 if (fputc((val >> 40) & 0xFF, f->fp) == EOF)
437 return -1;
438 if (fputc((val >> 32) & 0xFF, f->fp) == EOF)
439 return -1;
440 if (fputc((val >> 24) & 0xFF, f->fp) == EOF)
441 return -1;
442 if (fputc((val >> 16) & 0xFF, f->fp) == EOF)
443 return -1;
444 if (fputc((val >> 8) & 0xFF, f->fp) == EOF)
445 return -1;
446 if (fputc((val) & 0xFF, f->fp) == EOF)
447 return -1;
448 return 0;
449 }
450
451 /*! \brief Read Pointer
452 *
453 * \param ret pointer to read
454 * \param dbFile struct
455 * \return -1 on error, 0 otherwise.
456 */
457 int
458 read_ptr(void **ret, struct dbFILE *f)
459 {
460 int c = fgetc(f->fp);
461
462 if (c == EOF)
463 return -1;
464
465 *ret = (c ? (void *)1 : (void *)0);
466 return 0;
467 }
468
469
470 /*! \brief Write Pointer
471 *
472 * \param ptr pointer to write
473 * \param dbFile struct
474 * \return -1 on error, 0 otherwise.
475 */
476 int
477 write_ptr(const void *ptr, struct dbFILE *f)
478 {
479 if (fputc(ptr ? 1 : 0, f->fp) == EOF)
480 return -1;
481 return 0;
482 }
483
484 /*! \brief Read String
485 *
486 * \param ret string
487 * \param dbFile struct
488 * \return -1 on error, 0 otherwise.
489 */
490 int
491 read_string(char **ret, struct dbFILE *f)
492 {
493 char *s = NULL;
494 uint32_t len = 0;
495
496 if (read_uint32(&len, f) < 0)
497 return -1;
498
499 if (len == 0)
500 {
501 *ret = NULL;
502 return 0;
503 }
504
505 s = MyCalloc(len);
506
507 if (len != fread(s, 1, len, f->fp))
508 {
509 MyFree(s);
510 return -1;
511 }
512
513 *ret = s;
514 return 0;
515 }
516
517 /*! \brief Write String
518 *
519 * \param s string
520 * \param dbFile struct
521 * \return -1 on error, 0 otherwise.
522 */
523 int
524 write_string(const char *s, struct dbFILE *f)
525 {
526 uint32_t len = 0;
527
528 if (!s)
529 return write_uint32(0, f);
530
531 len = strlen(s);
532
533 if (len > 4294967294)
534 len = 4294967294;
535 if (write_uint32(len + 1, f) < 0)
536 return -1;
537 if (len > 0 && fwrite(s, 1, len, f->fp) != len)
538 return -1;
539 if (fputc(0, f->fp) == EOF)
540 return -1;
541
542 return 0;
543 }
544
545 #define SAFE_READ(x) do { \
546 if ((x) < 0) { \
547 break; \
548 } \
549 } while (0)
550
551 #define SAFE_WRITE(x,db) do { \
552 if ((x) < 0) { \
553 restore_db(f); \
554 ilog(LOG_TYPE_IRCD, "Write error on %s", db); \
555 return; \
556 } \
557 } while (0)
558
559 void
560 save_kline_database(void)
561 {
562 uint32_t i = 0;
563 uint32_t records = 0;
564 struct dbFILE *f = NULL;
565 dlink_node *ptr = NULL;
566
567 if (!(f = open_db(KPATH, "w", KLINE_DB_VERSION)))
568 return;
569
570 for (i = 0; i < ATABLE_SIZE; ++i)
571 {
572 DLINK_FOREACH(ptr, atable[i].head)
573 {
574 struct AddressRec *arec = ptr->data;
575
576 if (arec->type == CONF_KLINE && IsConfDatabase(arec->conf))
577 ++records;
578 }
579 }
580
581 SAFE_WRITE(write_uint32(records, f), KPATH);
582
583 for (i = 0; i < ATABLE_SIZE; ++i)
584 {
585 DLINK_FOREACH(ptr, atable[i].head)
586 {
587 struct AddressRec *arec = ptr->data;
588
589 if (arec->type == CONF_KLINE && IsConfDatabase(arec->conf))
590 {
591 SAFE_WRITE(write_string(arec->conf->user, f), KPATH);
592 SAFE_WRITE(write_string(arec->conf->host, f), KPATH);
593 SAFE_WRITE(write_string(arec->conf->reason, f), KPATH);
594 SAFE_WRITE(write_uint64(arec->conf->setat, f), KPATH);
595 SAFE_WRITE(write_uint64(arec->conf->until, f), KPATH);
596 }
597 }
598 }
599
600 close_db(f);
601 }
602
603 void
604 load_kline_database(void)
605 {
606 struct dbFILE *f = NULL;
607 struct MaskItem *conf = NULL;
608 char *field_1 = NULL;
609 char *field_2 = NULL;
610 char *field_3 = NULL;
611 uint32_t i = 0;
612 uint32_t records = 0;
613 uint64_t field_4 = 0;
614 uint64_t field_5 = 0;
615
616 if (!(f = open_db(KPATH, "r", KLINE_DB_VERSION)))
617 return;
618
619 if (get_file_version(f) < 1)
620 {
621 close_db(f);
622 return;
623 }
624
625 read_uint32(&records, f);
626
627 for (i = 0; i < records; ++i)
628 {
629 SAFE_READ(read_string(&field_1, f));
630 SAFE_READ(read_string(&field_2, f));
631 SAFE_READ(read_string(&field_3, f));
632 SAFE_READ(read_uint64(&field_4, f));
633 SAFE_READ(read_uint64(&field_5, f));
634
635 conf = conf_make(CONF_KLINE);
636 conf->user = field_1;
637 conf->host = field_2;
638 conf->reason = field_3;
639 conf->setat = field_4;
640 conf->until = field_5;
641 SetConfDatabase(conf);
642
643 add_conf_by_address(CONF_KLINE, conf);
644 }
645
646 close_db(f);
647 }
648
649 void
650 save_dline_database(void)
651 {
652 uint32_t i = 0;
653 uint32_t records = 0;
654 struct dbFILE *f = NULL;
655 dlink_node *ptr = NULL;
656
657 if (!(f = open_db(DLPATH, "w", KLINE_DB_VERSION)))
658 return;
659
660 for (i = 0; i < ATABLE_SIZE; ++i)
661 {
662 DLINK_FOREACH(ptr, atable[i].head)
663 {
664 struct AddressRec *arec = ptr->data;
665
666 if (arec->type == CONF_DLINE && IsConfDatabase(arec->conf))
667 ++records;
668 }
669 }
670
671 SAFE_WRITE(write_uint32(records, f), DLPATH);
672
673 for (i = 0; i < ATABLE_SIZE; ++i)
674 {
675 DLINK_FOREACH(ptr, atable[i].head)
676 {
677 struct AddressRec *arec = ptr->data;
678
679 if (arec->type == CONF_DLINE && IsConfDatabase(arec->conf))
680 {
681 SAFE_WRITE(write_string(arec->conf->host, f), DLPATH);
682 SAFE_WRITE(write_string(arec->conf->reason, f), DLPATH);
683 SAFE_WRITE(write_uint64(arec->conf->setat, f), DLPATH);
684 SAFE_WRITE(write_uint64(arec->conf->until, f), DLPATH);
685 }
686 }
687 }
688
689 close_db(f);
690 }
691
692 void
693 load_dline_database(void)
694 {
695 struct dbFILE *f = NULL;
696 struct MaskItem *conf = NULL;
697 char *field_1 = NULL;
698 char *field_2 = NULL;
699 uint32_t i = 0;
700 uint32_t records = 0;
701 uint64_t field_3 = 0;
702 uint64_t field_4 = 0;
703
704 if (!(f = open_db(DLPATH, "r", KLINE_DB_VERSION)))
705 return;
706
707 if (get_file_version(f) < 1)
708 {
709 close_db(f);
710 return;
711 }
712
713 read_uint32(&records, f);
714
715 for (i = 0; i < records; ++i)
716 {
717 SAFE_READ(read_string(&field_1, f));
718 SAFE_READ(read_string(&field_2, f));
719 SAFE_READ(read_uint64(&field_3, f));
720 SAFE_READ(read_uint64(&field_4, f));
721
722 conf = conf_make(CONF_DLINE);
723 conf->host = field_1;
724 conf->reason = field_2;
725 conf->setat = field_3;
726 conf->until = field_4;
727 SetConfDatabase(conf);
728
729 add_conf_by_address(CONF_DLINE, conf);
730 }
731
732 close_db(f);
733 }
734
735 void
736 save_gline_database(void)
737 {
738 uint32_t i = 0;
739 uint32_t records = 0;
740 struct dbFILE *f = NULL;
741 dlink_node *ptr = NULL;
742
743 if (!(f = open_db(GPATH, "w", KLINE_DB_VERSION)))
744 return;
745
746 for (i = 0; i < ATABLE_SIZE; ++i)
747 {
748 DLINK_FOREACH(ptr, atable[i].head)
749 {
750 struct AddressRec *arec = ptr->data;
751
752 if (arec->type == CONF_GLINE && IsConfDatabase(arec->conf))
753 ++records;
754 }
755 }
756
757 SAFE_WRITE(write_uint32(records, f), GPATH);
758
759 for (i = 0; i < ATABLE_SIZE; ++i)
760 {
761 DLINK_FOREACH(ptr, atable[i].head)
762 {
763 struct AddressRec *arec = ptr->data;
764
765 if (arec->type == CONF_GLINE && IsConfDatabase(arec->conf))
766 {
767 SAFE_WRITE(write_string(arec->conf->user, f), GPATH);
768 SAFE_WRITE(write_string(arec->conf->host, f), GPATH);
769 SAFE_WRITE(write_string(arec->conf->reason, f), GPATH);
770 SAFE_WRITE(write_uint64(arec->conf->setat, f), GPATH);
771 SAFE_WRITE(write_uint64(arec->conf->until, f), GPATH);
772 }
773 }
774 }
775
776 close_db(f);
777 }
778
779 void
780 load_gline_database(void)
781 {
782 struct dbFILE *f = NULL;
783 struct MaskItem *conf = NULL;
784 char *field_1 = NULL;
785 char *field_2 = NULL;
786 char *field_3 = NULL;
787 uint32_t i = 0;
788 uint32_t records = 0;
789 uint64_t field_4 = 0;
790 uint64_t field_5 = 0;
791
792 if (!(f = open_db(GPATH, "r", KLINE_DB_VERSION)))
793 return;
794
795 if (get_file_version(f) < 1)
796 {
797 close_db(f);
798 return;
799 }
800
801 read_uint32(&records, f);
802
803 for (i = 0; i < records; ++i)
804 {
805 SAFE_READ(read_string(&field_1, f));
806 SAFE_READ(read_string(&field_2, f));
807 SAFE_READ(read_string(&field_3, f));
808 SAFE_READ(read_uint64(&field_4, f));
809 SAFE_READ(read_uint64(&field_5, f));
810
811 conf = conf_make(CONF_GLINE);
812 conf->user = field_1;
813 conf->host = field_2;
814 conf->reason = field_3;
815 conf->setat = field_4;
816 conf->until = field_5;
817 SetConfDatabase(conf);
818
819 add_conf_by_address(CONF_GLINE, conf);
820 }
821
822 close_db(f);
823 }
824
825 void
826 save_resv_database(void)
827 {
828 uint32_t records = 0;
829 struct dbFILE *f = NULL;
830 dlink_node *ptr = NULL;
831 struct MaskItem *conf = NULL;
832
833 if (!(f = open_db(RESVPATH, "w", KLINE_DB_VERSION)))
834 return;
835
836 DLINK_FOREACH(ptr, cresv_items.head)
837 {
838 conf = ptr->data;
839
840 if (IsConfDatabase(conf))
841 ++records;
842 }
843
844 DLINK_FOREACH(ptr, nresv_items.head)
845 {
846 conf = ptr->data;
847
848 if (IsConfDatabase(conf))
849 ++records;
850 }
851
852 SAFE_WRITE(write_uint32(records, f), RESVPATH);
853
854 DLINK_FOREACH(ptr, cresv_items.head)
855 {
856 conf = ptr->data;
857
858 if (!IsConfDatabase(conf))
859 continue;
860
861 SAFE_WRITE(write_string(conf->name, f), RESVPATH);
862 SAFE_WRITE(write_string(conf->reason, f), RESVPATH);
863 SAFE_WRITE(write_uint64(conf->setat, f), RESVPATH);
864 SAFE_WRITE(write_uint64(conf->until, f), RESVPATH);
865 }
866
867 DLINK_FOREACH(ptr, nresv_items.head)
868 {
869 conf = ptr->data;
870
871 if (!IsConfDatabase(conf))
872 continue;
873
874 SAFE_WRITE(write_string(conf->name, f), RESVPATH);
875 SAFE_WRITE(write_string(conf->reason, f), RESVPATH);
876 SAFE_WRITE(write_uint64(conf->setat, f), RESVPATH);
877 SAFE_WRITE(write_uint64(conf->until, f), RESVPATH);
878 }
879
880 close_db(f);
881 }
882
883 void
884 load_resv_database(void)
885 {
886 uint32_t i = 0;
887 uint32_t records = 0;
888 uint64_t tmp64_hold = 0, tmp64_setat = 0;
889 struct dbFILE *f = NULL;
890 char *name = NULL;
891 char *reason = NULL;
892 struct MaskItem *conf = NULL;
893
894 if (!(f = open_db(RESVPATH, "r", KLINE_DB_VERSION)))
895 return;
896
897 if (get_file_version(f) < 1)
898 {
899 close_db(f);
900 return;
901 }
902
903 read_uint32(&records, f);
904
905 for (i = 0; i < records; ++i)
906 {
907 SAFE_READ(read_string(&name, f));
908 SAFE_READ(read_string(&reason, f));
909 SAFE_READ(read_uint64(&tmp64_setat, f));
910 SAFE_READ(read_uint64(&tmp64_hold, f));
911
912 if ((conf = create_resv(name, reason, NULL)) == NULL)
913 continue;
914
915 conf->setat = tmp64_setat;
916 conf->until = tmp64_hold;
917 SetConfDatabase(conf);
918
919 MyFree(name);
920 MyFree(reason);
921 }
922
923 close_db(f);
924 }
925
926 void
927 save_xline_database(void)
928 {
929 uint32_t records = 0;
930 struct dbFILE *f = NULL;
931 dlink_node *ptr = NULL;
932 struct MaskItem *conf = NULL;
933
934 if (!(f = open_db(XPATH, "w", KLINE_DB_VERSION)))
935 return;
936
937 DLINK_FOREACH(ptr, xconf_items.head)
938 {
939 conf = ptr->data;
940
941 if (IsConfDatabase(conf))
942 ++records;
943 }
944
945 SAFE_WRITE(write_uint32(records, f), XPATH);
946
947 DLINK_FOREACH(ptr, xconf_items.head)
948 {
949 conf = ptr->data;
950
951 if (!IsConfDatabase(conf))
952 continue;
953
954 SAFE_WRITE(write_string(conf->name, f), XPATH);
955 SAFE_WRITE(write_string(conf->reason, f), XPATH);
956 SAFE_WRITE(write_uint64(conf->setat, f), XPATH);
957 SAFE_WRITE(write_uint64(conf->until, f), XPATH);
958 }
959
960 close_db(f);
961 }
962
963 void
964 load_xline_database(void)
965 {
966 uint32_t i = 0;
967 uint32_t records = 0;
968 uint64_t tmp64_hold = 0, tmp64_setat = 0;
969 struct dbFILE *f = NULL;
970 char *name = NULL;
971 char *reason = NULL;
972 struct MaskItem *conf = NULL;
973
974 if (!(f = open_db(XPATH, "r", KLINE_DB_VERSION)))
975 return;
976
977 if (get_file_version(f) < 1)
978 {
979 close_db(f);
980 return;
981 }
982
983 read_uint32(&records, f);
984
985 for (i = 0; i < records; ++i)
986 {
987 SAFE_READ(read_string(&name, f));
988 SAFE_READ(read_string(&reason, f));
989 SAFE_READ(read_uint64(&tmp64_setat, f));
990 SAFE_READ(read_uint64(&tmp64_hold, f));
991
992 conf = conf_make(CONF_XLINE);
993
994 SetConfDatabase(conf);
995
996 conf->name = name;
997 conf->reason = reason;
998 conf->setat = tmp64_setat;
999 conf->until = tmp64_hold;
1000 }
1001
1002 close_db(f);
1003 }
1004
1005 void
1006 save_all_databases(void *unused)
1007 {
1008 save_kline_database();
1009 save_dline_database();
1010 save_gline_database();
1011 save_xline_database();
1012 save_resv_database();
1013 }

Properties

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