ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid/releases/8.1.0beta1/src/conf_db.c
Revision: 1628
Committed: Thu Nov 1 21:08:56 2012 UTC (13 years, 8 months ago) by michael
Content type: text/x-csrc
Original Path: ircd-hybrid/trunk/src/conf_db.c
File size: 24326 byte(s)
Log Message:
- flesh out new *line database handling
- simplify temporary bans

File Contents

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