mirror of
https://github.com/NishiOwO/ircservices5.git
synced 2025-04-21 16:54:38 +00:00
Add files via upload
This commit is contained in:
parent
580cb48284
commit
9a5d7a4e1b
50
lang/Makefile
Normal file
50
lang/Makefile
Normal file
@ -0,0 +1,50 @@
|
||||
# Makefile for language module
|
||||
|
||||
include ../Makefile.inc
|
||||
|
||||
|
||||
LANGOBJS = de en_us es fr hu ja_euc ja_sjis nl ru tr
|
||||
LANGSRCS = $(LANGOBJS:%=%.l)
|
||||
|
||||
LANGCOMP = ./langcomp
|
||||
#LANGCOMP = ./langcomp -w
|
||||
|
||||
|
||||
all: $(LANGOBJS)
|
||||
|
||||
|
||||
install: all
|
||||
mkdir -p "$(INSTALL_PREFIX)$(DATDEST)/languages"
|
||||
cp $(LANGOBJS) "$(INSTALL_PREFIX)$(DATDEST)/languages"
|
||||
|
||||
|
||||
clean:
|
||||
rm -f $(LANGOBJS) langcomp
|
||||
|
||||
spotless: clean
|
||||
rm -f langstrs.h
|
||||
|
||||
|
||||
$(LANGOBJS): %: %.l langcomp index
|
||||
$(LANGCOMP) $<
|
||||
|
||||
ja_jis.l: ja_euc.l jconv.pl
|
||||
perl jconv.pl -jis <ja_euc.l >$@
|
||||
ja_sjis.l: ja_euc.l jconv.pl
|
||||
perl jconv.pl -sjis <ja_euc.l >$@
|
||||
|
||||
langcomp: langcomp.c
|
||||
$(CC) $(CFLAGS) langcomp.c -o $@
|
||||
|
||||
|
||||
langstrs.h: index make-langstrs-h.pl
|
||||
perl make-langstrs-h.pl >$@.new
|
||||
@if cmp $@ $@.new >/dev/null 2>&1 ; then \
|
||||
echo "$@ unchanged" ; \
|
||||
rm -f $@.new ; \
|
||||
else \
|
||||
mv -f $@.new $@ ; \
|
||||
fi
|
||||
|
||||
index: en_us.l
|
||||
grep '^[A-Z]' <en_us.l >$@
|
5184
lang/en_us.l
Normal file
5184
lang/en_us.l
Normal file
File diff suppressed because it is too large
Load Diff
1240
lang/index
Normal file
1240
lang/index
Normal file
File diff suppressed because it is too large
Load Diff
4818
lang/ja_euc.l
Normal file
4818
lang/ja_euc.l
Normal file
File diff suppressed because it is too large
Load Diff
4818
lang/ja_sjis.l
Normal file
4818
lang/ja_sjis.l
Normal file
File diff suppressed because it is too large
Load Diff
33
lang/jconv.pl
Normal file
33
lang/jconv.pl
Normal file
@ -0,0 +1,33 @@
|
||||
#!/usr/bin/perl
|
||||
|
||||
binmode STDIN;
|
||||
binmode STDOUT;
|
||||
undef $/;
|
||||
$text = <STDIN>;
|
||||
if ($ARGV[0] eq "-jis") {
|
||||
$text =~ s/EUC/JIS/g;
|
||||
$text =~ s/euc-jp/iso-2022-jp/g;
|
||||
$text =~ s#([\241-\376])([\241-\376])#
|
||||
"\033\$B".pack("cc",ord($1)&127,ord($2)&127)."\033(B"#eg;
|
||||
# The language name (the only thing before the STRFTIME_* strings)
|
||||
# shouldn't have its %'s escaped; all other strings should, because
|
||||
# they go through sprintf().
|
||||
$pos = index($text, "STRFTIME");
|
||||
$pos = length($text) if $pos == 0;
|
||||
$t1 = substr($text, 0, $pos);
|
||||
$t2 = substr($text, $pos, length($text)-$pos);
|
||||
$t2 =~ s#(\033\$B.)%(\033\(B)#\1%%\2#g;
|
||||
$t2 =~ s#(\033\$B)%(.\033\(B)#\1%%\2#g;
|
||||
$text = $t1 . $t2;
|
||||
$text =~ s#\033\(B\033\$B##g;
|
||||
} elsif ($ARGV[0] eq "-sjis") {
|
||||
$text =~ s/EUC/SJIS/g;
|
||||
$text =~ s/euc-jp/shift_jis/g;
|
||||
$text =~ s#([\241-\376])([\241-\376])#
|
||||
$x = 0201+(ord($1)-0241)/2;
|
||||
$y = 0100+(ord($2)-0241)+((ord($1)-0241)%2)*94;
|
||||
$x += 0100 if $x >= 0240;
|
||||
$y++ if $y >= 0177;
|
||||
pack("cc",$x,$y)#eg;
|
||||
}
|
||||
print $text;
|
309
lang/langcomp.c
Normal file
309
lang/langcomp.c
Normal file
@ -0,0 +1,309 @@
|
||||
/* Compiler for language definition files.
|
||||
*
|
||||
* IRC Services is copyright (c) 1996-2009 Andrew Church.
|
||||
* E-mail: <achurch@achurch.org>
|
||||
* Parts written by Andrew Kempe and others.
|
||||
* This program is free but copyrighted software; see the file GPL.txt for
|
||||
* details.
|
||||
*/
|
||||
|
||||
/*
|
||||
* A language definition file contains all strings which Services sends to
|
||||
* users in a particular language. A language file may contain comments
|
||||
* (lines beginning with "#"--note that inline comments are not allowed!)
|
||||
* and blank lines. All other lines must adhere to the following format:
|
||||
*
|
||||
* Each string definition begins with the C name of a message (as defined
|
||||
* in the file "index"--see below). This must be alone on a line, preceded
|
||||
* and followed by no blank space. Following this line are zero or more
|
||||
* lines of text; each line of text must begin with exactly one tab
|
||||
* character, which is discarded. Newlines are retained in the strings,
|
||||
* except the last newline in the text, which is discarded. A message with
|
||||
* no text is replaced by a null pointer in the array (not an empty
|
||||
* string).
|
||||
*
|
||||
* All messages in the program are listed, one per line, in the "index"
|
||||
* file. No comments or blank lines are permitted in that file. The index
|
||||
* file can be generated from a language file with a command like:
|
||||
* grep '^[A-Z]' en_us.l >index
|
||||
*
|
||||
* This program takes one parameter, the name of the language file. It
|
||||
* generates a compiled language file whose name is created by removing any
|
||||
* extension on the source file on the input filename.
|
||||
*
|
||||
* You may also pass a "-w" option to print warnings for missing strings.
|
||||
*
|
||||
* This program isn't very flexible, because it doesn't need to be, but
|
||||
* anyone who wants to try making it more flexible is welcome to.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
/* CR/LF values--used instead of '\r' and '\n' to avoid platform-dependent
|
||||
* messiness */
|
||||
#define CR ((char)13)
|
||||
#define LF ((char)10)
|
||||
|
||||
int numstrings = 0; /* Number of strings we should have */
|
||||
char **stringnames; /* Names of the strings (from index file) */
|
||||
char **strings; /* Strings we have loaded */
|
||||
|
||||
int linenum = 0; /* Current line number in input file */
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
/* Read the index file and load numstrings and stringnames. Return -1 on
|
||||
* error, 0 on success. */
|
||||
|
||||
static int read_index_file(void)
|
||||
{
|
||||
FILE *f;
|
||||
char buf[256];
|
||||
int i;
|
||||
|
||||
if (!(f = fopen("index", "r"))) {
|
||||
perror("fopen(index)");
|
||||
return -1;
|
||||
}
|
||||
while (fgets(buf, sizeof(buf), f))
|
||||
numstrings++;
|
||||
if (!(stringnames = calloc(sizeof(char *), numstrings))) {
|
||||
perror("calloc(stringnames)");
|
||||
return -1;
|
||||
}
|
||||
if (!(strings = calloc(sizeof(char *), numstrings))) {
|
||||
perror("calloc(strings)");
|
||||
return -1;
|
||||
}
|
||||
fseek(f, 0, SEEK_SET);
|
||||
i = 0;
|
||||
while (fgets(buf, sizeof(buf), f)) {
|
||||
if (buf[strlen(buf)-1] == LF)
|
||||
buf[strlen(buf)-1] = 0;
|
||||
if (buf[strlen(buf)-1] == CR)
|
||||
buf[strlen(buf)-1] = 0;
|
||||
if (!(stringnames[i++] = strdup(buf))) {
|
||||
perror("strdup()");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
fclose(f);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
/* Return the index of a string name in stringnames, or -1 if not found. */
|
||||
|
||||
static int stringnum(const char *name)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < numstrings; i++) {
|
||||
if (strcmp(stringnames[i], name) == 0)
|
||||
return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
/* Read a non-comment, non-blank line from the input file. Return NULL at
|
||||
* end of file. */
|
||||
|
||||
static char *readline(FILE *f)
|
||||
{
|
||||
static char buf[1024];
|
||||
char *s;
|
||||
|
||||
do {
|
||||
if (!(fgets(buf, sizeof(buf), f)))
|
||||
return NULL;
|
||||
linenum++;
|
||||
} while (*buf == '#' || *buf == CR || *buf == LF);
|
||||
s = buf + strlen(buf)-1;
|
||||
if (*s == LF)
|
||||
*s-- = 0;
|
||||
if (*s == CR)
|
||||
*s = 0;
|
||||
return buf;
|
||||
}
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
/* Write a 32-bit value to a file in big-endian order. Returns 0 on
|
||||
* success, -1 on error.
|
||||
*/
|
||||
|
||||
static int fput32(long val, FILE *f)
|
||||
{
|
||||
if (fputc(val>>24, f) == EOF ||
|
||||
fputc(val>>16, f) == EOF ||
|
||||
fputc(val>> 8, f) == EOF ||
|
||||
fputc(val , f) == EOF
|
||||
) {
|
||||
return -1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
int main(int ac, char **av)
|
||||
{
|
||||
char *filename = NULL, *s;
|
||||
char langname[254], outfile[256];
|
||||
FILE *in, *out;
|
||||
int warn = 0;
|
||||
int retval = 0;
|
||||
int curstring = -2, i;
|
||||
char *line;
|
||||
int maxerr = 50; /* Max errors before we bail out */
|
||||
long pos, totalsize;
|
||||
|
||||
if (ac >= 2 && strcmp(av[1], "-w") == 0) {
|
||||
warn = 1;
|
||||
av[1] = av[2];
|
||||
ac--;
|
||||
}
|
||||
if (ac != 2) {
|
||||
fprintf(stderr, "Usage: %s [-w] <lang-file>\n", av[0]);
|
||||
return 1;
|
||||
}
|
||||
filename = av[1];
|
||||
s = strrchr(filename, '.');
|
||||
if (!s)
|
||||
s = filename + strlen(filename);
|
||||
if (s-filename > sizeof(langname)-3)
|
||||
s = filename + sizeof(langname)-1;
|
||||
strncpy(langname, filename, s-filename);
|
||||
langname[s-filename] = 0;
|
||||
sprintf(outfile, "%s", langname);
|
||||
|
||||
if (read_index_file() < 0)
|
||||
return 1;
|
||||
if (!(in = fopen(filename, "r"))) {
|
||||
perror(filename);
|
||||
return 1;
|
||||
}
|
||||
if (!(out = fopen(outfile, "w"))) {
|
||||
perror(outfile);
|
||||
return 1;
|
||||
}
|
||||
|
||||
while (maxerr > 0 && (line = readline(in)) != NULL) {
|
||||
if (*line == '\t') {
|
||||
if (curstring == -2) {
|
||||
fprintf(stderr, "%s:%d: Junk at beginning of file\n",
|
||||
filename, linenum);
|
||||
retval = 1;
|
||||
} else if (curstring >= 0) {
|
||||
line++;
|
||||
i = strings[curstring] ? strlen(strings[curstring]) : 0;
|
||||
if (!(strings[curstring] =
|
||||
realloc(strings[curstring], i+strlen(line)+2))) {
|
||||
fprintf(stderr, "%s:%d: Out of memory!\n",
|
||||
filename, linenum);
|
||||
return 2;
|
||||
}
|
||||
sprintf(strings[curstring]+i, "%s\n", line);
|
||||
}
|
||||
|
||||
} else {
|
||||
if ((curstring = stringnum(line)) < 0) {
|
||||
fprintf(stderr, "%s:%d: Unknown string name `%s'\n",
|
||||
filename, linenum, line);
|
||||
retval = 1;
|
||||
maxerr--;
|
||||
} else if (strings[curstring]) {
|
||||
fprintf(stderr, "%s:%d: Duplicate occurrence of string `%s'\n",
|
||||
filename, linenum, line);
|
||||
retval = 1;
|
||||
maxerr--;
|
||||
} else {
|
||||
if (!(strings[curstring] = malloc(1))) {
|
||||
fprintf(stderr, "%s:%d: Out of memory!\n",
|
||||
filename, linenum);
|
||||
return 2;
|
||||
}
|
||||
*strings[curstring] = 0;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
fclose(in);
|
||||
|
||||
if (retval != 0) {
|
||||
if (maxerr == 0)
|
||||
fprintf(stderr, "%s:%d: Too many errors!\n", filename, linenum);
|
||||
fclose(out);
|
||||
unlink(outfile);
|
||||
return retval;
|
||||
}
|
||||
|
||||
totalsize = 0;
|
||||
for (i = 0; i < numstrings; i++) {
|
||||
if (strings[i]) {
|
||||
if (*strings[i])
|
||||
strings[i][strlen(strings[i])-1] = 0; /* kill last \n */
|
||||
if (*strings[i])
|
||||
totalsize += strlen(strings[i]) + 1;
|
||||
} else if (warn) {
|
||||
fprintf(stderr, "%s: String `%s' missing\n", filename,
|
||||
stringnames[i]);
|
||||
}
|
||||
}
|
||||
|
||||
if (fput32(numstrings, out) < 0 || fput32(totalsize, out) < 0) {
|
||||
perror("fwrite()");
|
||||
retval = 1;
|
||||
}
|
||||
for (i = 0; i < numstrings && retval == 0; i++) {
|
||||
if (strings[i] && *strings[i]) {
|
||||
if (fwrite(strings[i], strlen(strings[i])+1, 1, out) != 1) {
|
||||
perror("fwrite()");
|
||||
retval = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
pos = 0;
|
||||
for (i = 0; i < numstrings && retval == 0; i++) {
|
||||
if (strings[i] && *strings[i]) {
|
||||
if (fput32(pos, out) < 0) {
|
||||
perror("fwrite()");
|
||||
retval = 1;
|
||||
}
|
||||
pos += strlen(strings[i]) + 1;
|
||||
} else {
|
||||
if (fput32(-1, out) < 0) {
|
||||
perror("fwrite()");
|
||||
retval = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (fclose(out) == EOF && retval == 0) {
|
||||
perror("fclose()");
|
||||
retval = 1;
|
||||
}
|
||||
if (retval)
|
||||
unlink(outfile);
|
||||
return retval;
|
||||
}
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* c-file-style: "stroustrup"
|
||||
* c-file-offsets: ((case-label . *) (statement-case-intro . *))
|
||||
* indent-tabs-mode: nil
|
||||
* End:
|
||||
*
|
||||
* vim: expandtab shiftwidth=4:
|
||||
*/
|
2487
lang/langstrs.h
Normal file
2487
lang/langstrs.h
Normal file
File diff suppressed because it is too large
Load Diff
22
lang/make-langstrs-h.pl
Normal file
22
lang/make-langstrs-h.pl
Normal file
@ -0,0 +1,22 @@
|
||||
#!/usr/bin/perl
|
||||
|
||||
print STDERR "Generating langstrs.h... ";
|
||||
|
||||
$i = 0;
|
||||
@list = ();
|
||||
open F, "<index" or die "index: $!\n";
|
||||
while (<F>) {
|
||||
chop;
|
||||
push @list, $_;
|
||||
printf "#define %-32s %d\n", $_, $i++;
|
||||
}
|
||||
close F;
|
||||
|
||||
print "\n#define NUM_BASE_STRINGS $i\n";
|
||||
print "\n#ifdef LANGSTR_ARRAY\n";
|
||||
print "static const char * const base_langstrs[] = {\n";
|
||||
foreach $s (@list) {
|
||||
print " \"$s\",\n";
|
||||
}
|
||||
print "};\n#endif\n";
|
||||
print STDERR "$i strings\n";
|
107
tools/Makefile
Normal file
107
tools/Makefile
Normal file
@ -0,0 +1,107 @@
|
||||
# Makefile for Services tools directory.
|
||||
#
|
||||
# IRC Services is copyright (c) 1996-2009 Andrew Church.
|
||||
# E-mail: <achurch@achurch.org>
|
||||
# Parts written by Andrew Kempe and others.
|
||||
# This program is free but copyrighted software; see the file GPL.txt for
|
||||
# details.
|
||||
|
||||
include ../Makefile.inc
|
||||
TOPDIR = ..
|
||||
CFLAGS_CONVERT_DB = $(CFLAGS) -I$(TOPDIR) -DCONVERT_DB
|
||||
|
||||
###########################################################################
|
||||
|
||||
ifneq ($(VSNPRINTF_O),)
|
||||
CONVERT_DB_VSNPRINTF_O = $(TOPDIR)/vsnprintf.o
|
||||
endif
|
||||
|
||||
# These aren't "modules" in the real sense; this is just a convenient way
|
||||
# to list the object files that handle each database format.
|
||||
CONVERT_DB_MODULES = \
|
||||
convert-cygnus.o \
|
||||
convert-epona.o \
|
||||
convert-hybserv.o \
|
||||
convert-magick.o \
|
||||
convert-ptlink.o \
|
||||
convert-sirv.o \
|
||||
convert-trircd.o \
|
||||
convert-ver8.o
|
||||
|
||||
CONVERT_DB_OBJS = convert-db.o $(CONVERT_DB_MODULES) \
|
||||
fileutil-x.o misc-x.o xml-export-x.o $(TOPDIR)/compat.o \
|
||||
$(CONVERT_DB_VSNPRINTF_O)
|
||||
|
||||
.c.o:
|
||||
$(CC) $(CFLAGS_CONVERT_DB) -c $< -o $@
|
||||
|
||||
###########################################################################
|
||||
|
||||
.PHONY: all install clean spotless
|
||||
|
||||
all: convert-db$(EXE_SUFFIX) $(PROGRAM)-chk
|
||||
|
||||
install:
|
||||
$(INSTALL_EXE) convert-db$(EXE_SUFFIX) "$(INSTALL_PREFIX)$(DATDEST)/convert-db$(EXE_SUFFIX)"
|
||||
$(INSTALL_EXE) $(PROGRAM)-chk "$(INSTALL_PREFIX)$(BINDEST)/$(PROGRAM)-chk"
|
||||
|
||||
clean:
|
||||
rm -f *.o convert-db$(EXE_SUFFIX) $(PROGRAM)-chk
|
||||
|
||||
spotless: clean
|
||||
|
||||
###########################################################################
|
||||
|
||||
convert-db$(EXE_SUFFIX): $(CONVERT_DB_OBJS)
|
||||
$(CC) $(LFLAGS) $(CONVERT_DB_OBJS) $(LIBS) -o $@
|
||||
|
||||
$(PROGRAM)-chk: ircservices-chk.in Makefile $(TOPDIR)/Makefile.inc
|
||||
PROGRAM=`echo "$(PROGRAM)" | sed 's,/,\\\\/,g'` ; \
|
||||
BINDEST=`echo "$(BINDEST)" | sed 's,/,\\\\/,g'` ; \
|
||||
DATDEST=`echo "$(DATDEST)" | sed 's,/,\\\\/,g'` ; \
|
||||
sed -e "s/@BINDEST@/$$BINDEST/g" -e "s/@DATDEST@/$$DATDEST/g" -e "s/@PROGRAM@/$$PROGRAM/g" <ircservices-chk.in >$(PROGRAM)-chk
|
||||
chmod a+x $(PROGRAM)-chk
|
||||
|
||||
|
||||
$(CONVERT_DB_OBJS): Makefile $(TOPDIR)/Makefile.inc convert-db.h \
|
||||
$(TOPDIR)/services.h $(TOPDIR)/encrypt.h \
|
||||
$(TOPDIR)/modules/database/fileutil.h \
|
||||
$(TOPDIR)/modules/nickserv/nickserv.h \
|
||||
$(TOPDIR)/modules/chanserv/chanserv.h \
|
||||
$(TOPDIR)/modules/memoserv/memoserv.h \
|
||||
$(TOPDIR)/modules/operserv/operserv.h \
|
||||
$(TOPDIR)/modules/operserv/maskdata.h \
|
||||
$(TOPDIR)/modules/operserv/news.h \
|
||||
$(TOPDIR)/modules/statserv/statserv.h
|
||||
|
||||
convert-db.o: convert-db.c $(TOPDIR)/language.h $(TOPDIR)/modules/misc/xml.h \
|
||||
$(TOPDIR)/modules/nickserv/util.c $(TOPDIR)/modules/chanserv/util.c
|
||||
|
||||
convert-cygnus.o: convert-cygnus.c
|
||||
convert-epona.o: convert-epona.c
|
||||
convert-magick.o: convert-magick.c
|
||||
convert-ptlink.o: convert-ptlink.c $(TOPDIR)/language.h
|
||||
convert-sirv.o: convert-sirv.c
|
||||
convert-trircd.o: convert-trircd.c
|
||||
convert-ver8.o: convert-ver8.c
|
||||
|
||||
fileutil-x.o: $(TOPDIR)/modules/database/fileutil.c $(TOPDIR)/services.h \
|
||||
$(TOPDIR)/modules/database/fileutil.h
|
||||
$(CC) $(CFLAGS_CONVERT_DB) -c $< -o $@
|
||||
misc-x.o: $(TOPDIR)/misc.c $(TOPDIR)/services.h
|
||||
$(CC) $(CFLAGS_CONVERT_DB) -c $< -o $@
|
||||
xml-export-x.o: $(TOPDIR)/modules/misc/xml-export.c $(TOPDIR)/services.h \
|
||||
$(TOPDIR)/language.h \
|
||||
$(TOPDIR)/modules/nickserv/nickserv.h \
|
||||
$(TOPDIR)/modules/chanserv/chanserv.h \
|
||||
$(TOPDIR)/modules/memoserv/memoserv.h \
|
||||
$(TOPDIR)/modules/operserv/operserv.h \
|
||||
$(TOPDIR)/modules/operserv/maskdata.h \
|
||||
$(TOPDIR)/modules/operserv/news.h \
|
||||
$(TOPDIR)/modules/statserv/statserv.h
|
||||
$(CC) $(CFLAGS_CONVERT_DB) -c $< -o $@
|
||||
|
||||
$(TOPDIR)/compat.o $(TOPDIR)/misc.o $(TOPDIR)/vsnprintf.o:
|
||||
$(MAKE) -C $(TOPDIR) $(notdir $@)
|
||||
|
||||
###########################################################################
|
1449
tools/convert-cygnus.c
Normal file
1449
tools/convert-cygnus.c
Normal file
File diff suppressed because it is too large
Load Diff
943
tools/convert-db.c
Normal file
943
tools/convert-db.c
Normal file
@ -0,0 +1,943 @@
|
||||
/* Convert other programs' databases to XML.
|
||||
*
|
||||
* IRC Services is copyright (c) 1996-2009 Andrew Church.
|
||||
* E-mail: <achurch@achurch.org>
|
||||
* Parts written by Andrew Kempe and others.
|
||||
* This program is free but copyrighted software; see the file GPL.txt for
|
||||
* details.
|
||||
*/
|
||||
|
||||
#define CONVERT_DB_MAIN
|
||||
#define STANDALONE_NICKSERV
|
||||
#define STANDALONE_CHANSERV
|
||||
#include "convert-db.h"
|
||||
#include "language.h"
|
||||
#include "modules/misc/xml.h"
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
/* Data read in. */
|
||||
|
||||
NickGroupInfo *ngi_list;
|
||||
NickInfo *ni_list;
|
||||
ChannelInfo *ci_list;
|
||||
NewsItem *news_list;
|
||||
MaskData *md_list[256];
|
||||
ServerStats *ss_list;
|
||||
int32 maxusercnt;
|
||||
time_t maxusertime;
|
||||
Password supass;
|
||||
int no_supass = 1;
|
||||
|
||||
/* Symbols needed for core's misc.c. */
|
||||
char **RejectEmail = NULL;
|
||||
int RejectEmail_count = 0;
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
/* NULL-terminated list of supported database types. */
|
||||
|
||||
extern DBTypeInfo ALL_DB_TYPES();
|
||||
static DBTypeInfo *dbtypes[] = {
|
||||
ALL_DB_TYPES(&),
|
||||
NULL
|
||||
};
|
||||
|
||||
/*************************************************************************/
|
||||
/*************************** Exported routines ***************************/
|
||||
/*************************************************************************/
|
||||
|
||||
/* Safe memory allocation and string duplication (from memory.c). */
|
||||
|
||||
void *smalloc(long size)
|
||||
{
|
||||
void *ptr;
|
||||
if (!size)
|
||||
size = 1;
|
||||
ptr = malloc(size);
|
||||
if (!ptr) {
|
||||
fprintf(stderr, "Out of memory\n");
|
||||
exit(1);
|
||||
}
|
||||
return ptr;
|
||||
}
|
||||
|
||||
void *scalloc(long els, long elsize)
|
||||
{
|
||||
void *ptr;
|
||||
if (!(els*elsize))
|
||||
els = elsize = 1;
|
||||
ptr = calloc(els, elsize);
|
||||
if (!ptr) {
|
||||
fprintf(stderr, "Out of memory\n");
|
||||
exit(1);
|
||||
}
|
||||
return ptr;
|
||||
}
|
||||
|
||||
void *srealloc(void *ptr, long size)
|
||||
{
|
||||
if (!size)
|
||||
size = 1;
|
||||
ptr = realloc(ptr, size);
|
||||
if (!ptr) {
|
||||
fprintf(stderr, "Out of memory\n");
|
||||
exit(1);
|
||||
}
|
||||
return ptr;
|
||||
}
|
||||
|
||||
char *sstrdup(const char *s)
|
||||
{
|
||||
int len = strlen(s)+1;
|
||||
char *d = smalloc(len);
|
||||
memcpy(d, s, len);
|
||||
return d;
|
||||
}
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
/* Initialize or clear a Password structure (from encrypt.c). */
|
||||
|
||||
void init_password(Password *password)
|
||||
{
|
||||
memset(password, 0, sizeof(*password));
|
||||
password->cipher = NULL;
|
||||
}
|
||||
|
||||
void clear_password(Password *password)
|
||||
{
|
||||
memset(password, 0, sizeof(*password));
|
||||
free((char *)password->cipher);
|
||||
password->cipher = NULL;
|
||||
}
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
/* NickInfo/NickGroupInfo allocation (from modules/nickserv/util.c). The
|
||||
* NickInfo and NickGroupInfo (if appropriate) are added into their
|
||||
* respective hash tables. Always succeeds (if the memory allocations
|
||||
* fail, aborts the program).
|
||||
*/
|
||||
|
||||
#include "modules/nickserv/util.c"
|
||||
|
||||
NickInfo *makenick(const char *nick, NickGroupInfo **nickgroup_ret)
|
||||
{
|
||||
NickInfo *ni = new_nickinfo();
|
||||
strbcpy(ni->nick, nick);
|
||||
if (nickgroup_ret) {
|
||||
NickGroupInfo *ngi = new_nickgroupinfo(ni->nick);
|
||||
while (get_nickgroupinfo(ngi->id)) {
|
||||
/* We assume that eventually we'll find one that's not in use */
|
||||
ngi->id = rand() + rand();
|
||||
if (ngi->id == 0)
|
||||
ngi->id = 1;
|
||||
}
|
||||
ni->nickgroup = ngi->id;
|
||||
ARRAY_EXTEND(ngi->nicks);
|
||||
strbcpy(ngi->nicks[0], nick);
|
||||
add_nickgroupinfo(ngi);
|
||||
*nickgroup_ret = ngi;
|
||||
}
|
||||
add_nickinfo(ni);
|
||||
return ni;
|
||||
}
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
/* ChannelInfo allocation. The channel is added to the hash table. */
|
||||
|
||||
#include "modules/chanserv/util.c"
|
||||
|
||||
ChannelInfo *makechan(const char *name)
|
||||
{
|
||||
ChannelInfo *ci = new_channelinfo();
|
||||
strbcpy(ci->name, name);
|
||||
add_channelinfo(ci);
|
||||
return ci;
|
||||
}
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
/* Open a (Services pre-5.0 style) data file and check the version number.
|
||||
* Prints an error message and exits with 1 if either the file cannot be
|
||||
* opened or the version number is wrong. If `version_ret' is non-NULL,
|
||||
* the version number is stored there.
|
||||
*/
|
||||
|
||||
dbFILE *open_db_ver(const char *dir, const char *name, int32 min_version,
|
||||
int32 max_version, int32 *version_ret)
|
||||
{
|
||||
char filename[PATH_MAX+1];
|
||||
dbFILE *f;
|
||||
int32 ver;
|
||||
|
||||
snprintf(filename, sizeof(filename), "%s/%s", dir, name);
|
||||
f = open_db(filename, "r", 0);
|
||||
if (!f) {
|
||||
fprintf(stderr, "Can't open %s for reading: %s\n", filename,
|
||||
strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
if (read_int32(&ver, f) < 0) {
|
||||
fprintf(stderr, "Error reading version number on %s\n", filename);
|
||||
exit(1);
|
||||
}
|
||||
if (ver < min_version || ver > max_version) {
|
||||
fprintf(stderr, "Wrong version number on %s\n", filename);
|
||||
exit(1);
|
||||
}
|
||||
if (version_ret)
|
||||
*version_ret = ver;
|
||||
return f;
|
||||
}
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
/* Retrieve the NickGroupInfo structure for the given nick. Returns NULL
|
||||
* if the nick does not exist or is forbidden (i.e. has no NickGroupInfo).
|
||||
*/
|
||||
|
||||
NickGroupInfo *get_nickgroupinfo_by_nick(const char *nick)
|
||||
{
|
||||
NickInfo *ni = get_nickinfo(nick);
|
||||
return ni ? get_nickgroupinfo(ni->nickgroup) : NULL;
|
||||
}
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
/* Set the OperServ privilege level (os_priv) for the nickgroup associated
|
||||
* with `nick' to `level', if it is not already greater than `level'. Does
|
||||
* nothing if `nick' is NULL or does not have an associated nickgroup.
|
||||
*/
|
||||
|
||||
void set_os_priv(const char *nick, int16 level)
|
||||
{
|
||||
NickGroupInfo *ngi;
|
||||
|
||||
if (!nick)
|
||||
return;
|
||||
ngi = get_nickgroupinfo_by_nick(nick);
|
||||
if (ngi && ngi->os_priv < level)
|
||||
ngi->os_priv = level;
|
||||
}
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
/* Return the Services 5.0 channel access level that corresponds to the
|
||||
* given pre-5.0 level. Code taken from modules/database/version4.c
|
||||
* (convert_old_level()).
|
||||
*/
|
||||
|
||||
int16 convert_acclev(int16 old)
|
||||
{
|
||||
if (old < 0)
|
||||
return -convert_acclev(-old); /* avoid negative division */
|
||||
else if (old <= 25)
|
||||
return old*10; /* 0.. 25 -> 0..250 (10x) */
|
||||
else if (old <= 50)
|
||||
return 200 + old*2; /* 25.. 50 -> 250..300 ( 2x) */
|
||||
else if (old <= 100)
|
||||
return 280 + old*2/5; /* 50.. 100 -> 300..320 ( 0.4x) */
|
||||
else if (old <= 1000)
|
||||
return 300 + old/5; /* 100..1000 -> 320..500 ( 0.2x) */
|
||||
else if (old <= 2000)
|
||||
return 400 + old/10; /* 1000..2000 -> 500..600 ( 0.1x) */
|
||||
else
|
||||
return 500 + old/20; /* 2000..9999 -> 600..999 ( 0.05x) */
|
||||
}
|
||||
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
|
||||
/* Replacements for database functions. add_*() functions are defined as
|
||||
* macros in convert-db.h. */
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
static NickGroupInfo *ngi_iter;
|
||||
|
||||
NickGroupInfo *get_nickgroupinfo(uint32 id)
|
||||
{
|
||||
NickGroupInfo *ngi;
|
||||
if (!id)
|
||||
return NULL;
|
||||
LIST_SEARCH_SCALAR(ngi_list, id, id, ngi);
|
||||
return ngi;
|
||||
}
|
||||
|
||||
NickGroupInfo *first_nickgroupinfo(void)
|
||||
{
|
||||
ngi_iter = ngi_list;
|
||||
return next_nickgroupinfo();
|
||||
}
|
||||
|
||||
NickGroupInfo *next_nickgroupinfo(void)
|
||||
{
|
||||
NickGroupInfo *retval = ngi_iter;
|
||||
if (ngi_iter)
|
||||
ngi_iter = ngi_iter->next;
|
||||
return retval;
|
||||
}
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
static NickInfo *ni_iter;
|
||||
|
||||
NickInfo *get_nickinfo(const char *nick)
|
||||
{
|
||||
NickInfo *ni;
|
||||
LIST_SEARCH(ni_list, nick, nick, stricmp, ni);
|
||||
return ni;
|
||||
}
|
||||
|
||||
NickInfo *first_nickinfo(void)
|
||||
{
|
||||
ni_iter = ni_list;
|
||||
return next_nickinfo();
|
||||
}
|
||||
|
||||
NickInfo *next_nickinfo(void)
|
||||
{
|
||||
NickInfo *retval = ni_iter;
|
||||
if (ni_iter)
|
||||
ni_iter = ni_iter->next;
|
||||
return retval;
|
||||
}
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
static ChannelInfo *ci_iter;
|
||||
|
||||
ChannelInfo *get_channelinfo(const char *channel)
|
||||
{
|
||||
ChannelInfo *ci;
|
||||
LIST_SEARCH(ci_list, name, channel, stricmp, ci);
|
||||
return ci;
|
||||
}
|
||||
|
||||
ChannelInfo *first_channelinfo(void)
|
||||
{
|
||||
ci_iter = ci_list;
|
||||
return next_channelinfo();
|
||||
}
|
||||
|
||||
ChannelInfo *next_channelinfo(void)
|
||||
{
|
||||
ChannelInfo *retval = ci_iter;
|
||||
if (ci_iter)
|
||||
ci_iter = ci_iter->next;
|
||||
return retval;
|
||||
}
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
static NewsItem *news_iter;
|
||||
|
||||
NewsItem *first_news(void)
|
||||
{
|
||||
news_iter = news_list;
|
||||
return next_news();
|
||||
}
|
||||
|
||||
NewsItem *next_news(void)
|
||||
{
|
||||
NewsItem *retval = news_iter;
|
||||
if (news_iter)
|
||||
news_iter = news_iter->next;
|
||||
return retval;
|
||||
}
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
static MaskData *md_iter[256];
|
||||
|
||||
MaskData *first_maskdata(uint8 type)
|
||||
{
|
||||
md_iter[type] = md_list[type];
|
||||
return next_maskdata(type);
|
||||
}
|
||||
|
||||
MaskData *next_maskdata(uint8 type)
|
||||
{
|
||||
MaskData *retval = md_iter[type];
|
||||
if (md_iter[type])
|
||||
md_iter[type] = md_iter[type]->next;
|
||||
return retval;
|
||||
}
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
static ServerStats *ss_iter;
|
||||
|
||||
ServerStats *first_serverstats(void)
|
||||
{
|
||||
ss_iter = ss_list;
|
||||
return next_serverstats();
|
||||
}
|
||||
|
||||
ServerStats *next_serverstats(void)
|
||||
{
|
||||
ServerStats *retval = ss_iter;
|
||||
if (ss_iter)
|
||||
ss_iter = ss_iter->next;
|
||||
return retval;
|
||||
}
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
int get_operserv_data(int what, void *ptr)
|
||||
{
|
||||
switch (what) {
|
||||
case OSDATA_MAXUSERCNT:
|
||||
*(int32 *)ptr = maxusercnt;
|
||||
break;
|
||||
case OSDATA_MAXUSERTIME:
|
||||
*(time_t *)ptr = maxusertime;
|
||||
break;
|
||||
case OSDATA_SUPASS:
|
||||
*(Password **)ptr = no_supass ? NULL : &supass;
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
|
||||
/* Perform sanity checks on the data after it's been read in. */
|
||||
|
||||
static void sanity_check_nicks(void);
|
||||
static void sanity_check_nickgroups(void);
|
||||
static void sanity_check_channels(void);
|
||||
static void sanity_check_maskdata(void);
|
||||
|
||||
static void sanity_checks(void)
|
||||
{
|
||||
sanity_check_nicks();
|
||||
sanity_check_nickgroups();
|
||||
sanity_check_channels();
|
||||
sanity_check_maskdata();
|
||||
}
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
static void sanity_check_nicks(void)
|
||||
{
|
||||
NickInfo *ni;
|
||||
NickGroupInfo *ngi;
|
||||
char *s;
|
||||
int i;
|
||||
|
||||
for (ni = first_nickinfo(); ni; ni = next_nickinfo()) {
|
||||
|
||||
/* Forbidden nicks should have no other data associated with them. */
|
||||
if (ni->status & NS_VERBOTEN) {
|
||||
ni->status &= ~(NS_VERBOTEN);
|
||||
ni->last_usermask = NULL;
|
||||
ni->last_realmask = NULL;
|
||||
ni->last_realname = NULL;
|
||||
ni->last_quit = NULL;
|
||||
ni->last_seen = 0;
|
||||
if (ni->nickgroup) {
|
||||
fprintf(stderr, "BUG: Forbidden nickname %s associated with"
|
||||
" nickgroup %u! Clearing nickgroup field.\n",
|
||||
ni->nick, ni->nickgroup);
|
||||
ni->nickgroup = 0;
|
||||
}
|
||||
ni->id_stamp = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* The nick isn't a forbidden nick. First make sure it has the
|
||||
* right nickgroup. */
|
||||
if (!ni->nickgroup) {
|
||||
fprintf(stderr, "BUG: Nickname %s has no nickgroup! Deleting.\n",
|
||||
ni->nick);
|
||||
del_nickinfo(ni);
|
||||
continue;
|
||||
}
|
||||
ngi = get_nickgroupinfo(ni->nickgroup);
|
||||
if (!ngi) {
|
||||
fprintf(stderr, "BUG: Nickname %s points to nonexistent nickgroup"
|
||||
" %u! Deleting.\n", ni->nick, ni->nickgroup);
|
||||
del_nickinfo(ni);
|
||||
} else {
|
||||
/* Nicknames in the nicks[] array should match those in the
|
||||
* NickInfo structure, so use strcmp() (this keeps us from
|
||||
* having to worry about irc_stricmp() idiosyncrasies). */
|
||||
ARRAY_SEARCH_PLAIN(ngi->nicks, ni->nick, strcmp, i);
|
||||
if (i >= ngi->nicks_count) {
|
||||
fprintf(stderr, "BUG: Nickname %s points to nickgroup %u,"
|
||||
" but the nickgroup doesn't contain the nickname!"
|
||||
" Deleting.\n", ni->nick, ni->nickgroup);
|
||||
del_nickinfo(ni);
|
||||
}
|
||||
}
|
||||
|
||||
/* Clear unknown flags. */
|
||||
ni->status &= NS_PERMANENT;
|
||||
|
||||
/* Make sure usermasks actually have non-empty user and host parts. */
|
||||
if (ni->last_usermask) {
|
||||
s = strchr(ni->last_usermask, '@');
|
||||
if (!s || s==ni->last_usermask || !s[1]) {
|
||||
fprintf(stderr, "Last usermask for nickname %s isn't a valid"
|
||||
" user@host mask, clearing.\n", ni->nick);
|
||||
ni->last_usermask = NULL;
|
||||
}
|
||||
}
|
||||
if (ni->last_realmask) {
|
||||
s = strchr(ni->last_realmask, '@');
|
||||
if (!s || s==ni->last_realmask || !s[1]) {
|
||||
fprintf(stderr, "Last real usermask for nickname %s isn't"
|
||||
" a valid user@host mask, clearing.\n", ni->nick);
|
||||
ni->last_realmask = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* Make sure last-seen time is not earlier than registered time.
|
||||
* Allow zero, to accommodate cases where the nickname was
|
||||
* registered by an outside entity without the user actually
|
||||
* logging on. */
|
||||
if (ni->last_seen && ni->last_seen < ni->time_registered) {
|
||||
fprintf(stderr, "Last-seen time for nickname %s is earlier than"
|
||||
" registration time! Setting last-seen time to"
|
||||
" registration time.\n", ni->nick);
|
||||
ni->last_seen = ni->time_registered;
|
||||
}
|
||||
|
||||
} /* for all nicks */
|
||||
}
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
static void sanity_check_nickgroups(void)
|
||||
{
|
||||
NickInfo *ni;
|
||||
NickGroupInfo *ngi;
|
||||
char *s;
|
||||
int i;
|
||||
|
||||
for (ngi = first_nickgroupinfo(); ngi; ngi = next_nickgroupinfo()) {
|
||||
|
||||
/* Make sure nickgroups don't contain extra nicks. */
|
||||
ARRAY_FOREACH(i, ngi->nicks) {
|
||||
ni = get_nickinfo(ngi->nicks[i]);
|
||||
if (!ni) {
|
||||
fprintf(stderr, "BUG: Nickgroup %u contains nonexistent"
|
||||
" nickname %s! Removing nickname from group.\n",
|
||||
ngi->id, ngi->nicks[i]);
|
||||
ARRAY_REMOVE(ngi->nicks, i);
|
||||
if (ngi->mainnick >= i)
|
||||
ngi->mainnick--;
|
||||
i--; /* to make sure we don't skip any */
|
||||
}
|
||||
}
|
||||
|
||||
/* Check for empty nickgroups (possibly from extraneous nickname
|
||||
* removal above). */
|
||||
if (ngi->nicks_count == 0) {
|
||||
fprintf(stderr, "Removing empty nickgroup %u.\n", ngi->id);
|
||||
del_nickgroupinfo(ngi);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Make sure main nick is a valid index. */
|
||||
if (ngi->mainnick >= ngi->nicks_count) {
|
||||
fprintf(stderr, "Invalid main nick index in nickgroup %u,"
|
||||
" resetting.\n", ngi->id);
|
||||
ngi->mainnick = 0;
|
||||
}
|
||||
|
||||
/* If an authcode is set, make sure the reason is valid. If not,
|
||||
* clear the auth-related fields. */
|
||||
if (ngi->authcode && (ngi->authreason < NICKAUTH_MIN
|
||||
|| ngi->authreason > NICKAUTH_MAX)) {
|
||||
fprintf(stderr, "Authentication code set for nickgroup %u but"
|
||||
" reason code invalid, setting to SETAUTH.\n", ngi->id);
|
||||
ngi->authreason = NICKAUTH_SETAUTH;
|
||||
} else {
|
||||
ngi->authset = 0;
|
||||
ngi->authreason = 0;
|
||||
}
|
||||
|
||||
/* Clear all unknown flags. */
|
||||
ngi->flags &= NF_ALLFLAGS;
|
||||
|
||||
/* Make sure language setting is in range. */
|
||||
if ((ngi->language < 0 || ngi->language >= NUM_LANGS)
|
||||
&& ngi->language != LANG_DEFAULT
|
||||
) {
|
||||
fprintf(stderr, "Invalid language set for nickgroup %u,"
|
||||
" resetting to default.\n", ngi->id);
|
||||
ngi->language = LANG_DEFAULT;
|
||||
}
|
||||
|
||||
/* Make sure access, autojoin, and ignore counts are non-negative. */
|
||||
if (ngi->access_count < 0) {
|
||||
fprintf(stderr, "BUG: Access entry count for nickgroup %u is"
|
||||
" negative! Clearing.\n", ngi->id);
|
||||
ngi->access = NULL;
|
||||
ngi->access_count = 0;
|
||||
}
|
||||
if (ngi->ajoin_count < 0) {
|
||||
fprintf(stderr, "BUG: Autojoin entry count for nickgroup %u is"
|
||||
" negative! Clearing.\n", ngi->id);
|
||||
ngi->ajoin = NULL;
|
||||
ngi->ajoin_count = 0;
|
||||
}
|
||||
if (ngi->ignore_count < 0) {
|
||||
fprintf(stderr, "BUG: Ignore entry count for nickgroup %u is"
|
||||
" negative! Clearing.\n", ngi->id);
|
||||
ngi->ignore = NULL;
|
||||
ngi->ignore_count = 0;
|
||||
}
|
||||
|
||||
/* Make sure all access entries have non-empty user and host parts. */
|
||||
ARRAY_FOREACH (i, ngi->access) {
|
||||
if (!ngi->access[i]
|
||||
|| !(s = strchr(ngi->access[i], '@'))
|
||||
|| s == ngi->access[i]
|
||||
|| !s[1]
|
||||
) {
|
||||
fprintf(stderr, "Access entry %d for nickgroup %u %s,"
|
||||
" deleting.\n", i, ngi->id,
|
||||
!ngi->access[i] ? "is empty"
|
||||
: "isn't a valid user@host mask");
|
||||
ARRAY_REMOVE(ngi->access, i);
|
||||
i--;
|
||||
}
|
||||
}
|
||||
|
||||
/* Make sure memo count is non-negative. */
|
||||
if (ngi->memos.memos_count < 0) {
|
||||
fprintf(stderr, "BUG: Memo count for nickgroup %u is negative!"
|
||||
" Clearing.\n", ngi->id);
|
||||
ngi->memos.memos = NULL;
|
||||
ngi->memos.memos_count = 0;
|
||||
}
|
||||
|
||||
/* Clear unknown flags from memos. */
|
||||
ARRAY_FOREACH (i, ngi->memos.memos)
|
||||
ngi->memos.memos[i].flags &= MF_ALLFLAGS;
|
||||
|
||||
} /* for all nickgroups */
|
||||
}
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
static void sanity_check_channels(void)
|
||||
{
|
||||
ChannelInfo *ci;
|
||||
char *s;
|
||||
int i;
|
||||
|
||||
for (ci = first_channelinfo(); ci; ci = next_channelinfo()) {
|
||||
|
||||
/* Forbidden channels should have no other data associated with
|
||||
* them. */
|
||||
if (ci->flags & CF_VERBOTEN) {
|
||||
ci->founder = 0;
|
||||
ci->successor = 0;
|
||||
init_password(&ci->founderpass);
|
||||
ci->desc = NULL;
|
||||
ci->url = NULL;
|
||||
ci->email = NULL;
|
||||
ci->last_used = 0;
|
||||
ci->last_topic = NULL;
|
||||
memset(ci->last_topic_setter, 0, sizeof(ci->last_topic_setter));
|
||||
ci->last_topic_time = 0;
|
||||
ci->flags &= ~(CF_VERBOTEN);
|
||||
reset_levels(ci);
|
||||
ci->access = NULL;
|
||||
ci->access_count = 0;
|
||||
ci->akick = NULL;
|
||||
ci->akick_count = 0;
|
||||
ci->mlock.on = NULL;
|
||||
ci->mlock.off = NULL;
|
||||
ci->mlock.limit = 0;
|
||||
ci->mlock.key = NULL;
|
||||
ci->mlock.link = NULL;
|
||||
ci->mlock.flood = NULL;
|
||||
ci->mlock.joindelay = 0;
|
||||
ci->mlock.joinrate1 = 0;
|
||||
ci->mlock.joinrate2 = 0;
|
||||
ci->entry_message = NULL;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Channel is not forbidden. First make sure it has a (valid)
|
||||
* founder. */
|
||||
if (!ci->founder) {
|
||||
fprintf(stderr, "BUG: Channel %s has no founder! Deleting.\n",
|
||||
ci->name);
|
||||
del_channelinfo(ci);
|
||||
} else if (!get_nickgroupinfo(ci->founder)) {
|
||||
fprintf(stderr, "BUG: Channel %s founder nickgroup %u is"
|
||||
" missing! Deleting channel.\n", ci->name, ci->founder);
|
||||
del_channelinfo(ci);
|
||||
}
|
||||
|
||||
/* Make sure that the successor is valid if set. */
|
||||
if (ci->successor && !get_nickgroupinfo(ci->successor)) {
|
||||
fprintf(stderr, "BUG: Channel %s successor nickgroup %u is"
|
||||
" missing! Clearing.", ci->name, ci->successor);
|
||||
ci->successor = 0;
|
||||
}
|
||||
|
||||
/* Make sure last-used time is not earlier than registered time.
|
||||
* Allow zero, to accommodate cases where the channel was
|
||||
* registered by an outside entity. */
|
||||
if (ci->last_used && ci->last_used < ci->time_registered) {
|
||||
fprintf(stderr, "Last-used time for channel %s is earlier than"
|
||||
" registration time! Setting last-used time to"
|
||||
" registration time.\n", ci->name);
|
||||
ci->last_used = ci->time_registered;
|
||||
}
|
||||
|
||||
/* If there is no saved topic, clear the topic setter and time. */
|
||||
if (!ci->last_topic) {
|
||||
memset(ci->last_topic_setter, 0, sizeof(ci->last_topic_setter));
|
||||
ci->last_topic_time = 0;
|
||||
}
|
||||
|
||||
/* Clear unknown flags. */
|
||||
ci->flags &= CF_ALLFLAGS;
|
||||
|
||||
/* Check privilege level settings for vaility. */
|
||||
for (i = 0; i < CA_SIZE; i++) {
|
||||
if (ci->levels[i] != ACCLEV_DEFAULT
|
||||
&& ci->levels[i] != ACCLEV_INVALID
|
||||
&& ci->levels[i] != ACCLEV_FOUNDER
|
||||
&& (ci->levels[i] < ACCLEV_MIN
|
||||
|| ci->levels[i] > ACCLEV_MAX)
|
||||
) {
|
||||
fprintf(stderr, "Privilege level %d on channel %s is"
|
||||
"invalid, resetting to default.\n", i, ci->name);
|
||||
ci->levels[i] = ACCLEV_DEFAULT;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Check access level nickgroups and levels for validity. */
|
||||
ARRAY_FOREACH (i, ci->access) {
|
||||
if (!ci->access[i].nickgroup)
|
||||
continue;
|
||||
if (!get_nickgroupinfo(ci->access[i].nickgroup)) {
|
||||
fprintf(stderr, "BUG: Channel %s access entry %d has an"
|
||||
" invalid nickgroup! Clearing.\n", ci->name, i);
|
||||
ci->access[i].nickgroup = 0;
|
||||
ci->access[i].level = 0;
|
||||
} else if (ci->access[i].level < ACCLEV_MIN
|
||||
|| ci->access[i].level > ACCLEV_MAX) {
|
||||
fprintf(stderr, "BUG: Channel %s access entry %d has an"
|
||||
"out-of-range level (%d)! Clearing.\n",
|
||||
ci->name, i, ci->access[i].level);
|
||||
ci->access[i].nickgroup = 0;
|
||||
ci->access[i].level = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Make sure all autokick entries have non-empty user and host
|
||||
* parts. */
|
||||
ARRAY_FOREACH (i, ci->akick) {
|
||||
if (!ci->akick[i].mask)
|
||||
continue;
|
||||
s = strchr(ci->akick[i].mask, '@');
|
||||
if (!s || s==ci->akick[i].mask || !s[1]) {
|
||||
fprintf(stderr, "Autokick entry %d for channel %s isn't a"
|
||||
" valid user@host mask, deleting.\n", i, ci->name);
|
||||
ci->akick[i].mask = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
} /* for all channels */
|
||||
|
||||
/* Check that channel successors and access list entries have valid
|
||||
* nickgroup IDs, and that access levels are in range */
|
||||
for (ci = first_channelinfo(); ci; ci = next_channelinfo()) {
|
||||
if (ci->flags & CF_VERBOTEN)
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
static void sanity_check_maskdata(void)
|
||||
{
|
||||
MaskData *md;
|
||||
char *s;
|
||||
int i;
|
||||
|
||||
/* Make sure all MaskData entries actually have masks allocated. */
|
||||
for (i = 0; i < 256; i++) {
|
||||
for (md = first_maskdata(i); md; md = next_maskdata(i)) {
|
||||
if (!md->mask)
|
||||
del_maskdata(i, md);
|
||||
}
|
||||
}
|
||||
|
||||
/* Make sure every autokill has a valid user@host mask and a reason. */
|
||||
for (md = first_maskdata(MD_AKILL); md; md = next_maskdata(MD_AKILL)) {
|
||||
s = strchr(md->mask, '@');
|
||||
if (!s || s==md->mask || !s[1]) {
|
||||
fprintf(stderr, "Autokill %s isn't a valid user@host mask,"
|
||||
" deleting.\n", md->mask);
|
||||
del_maskdata(MD_AKILL, md);
|
||||
continue;
|
||||
}
|
||||
if (!md->reason)
|
||||
md->reason = "Reason unknown";
|
||||
}
|
||||
}
|
||||
|
||||
/*************************************************************************/
|
||||
/****************************** Main program *****************************/
|
||||
/*************************************************************************/
|
||||
|
||||
void usage(const char *progname)
|
||||
{
|
||||
int i;
|
||||
|
||||
fprintf(stderr, "Usage: %s [-v] [+program-name] [options...] dir\n"
|
||||
"The following program names are known:\n", progname);
|
||||
for (i = 0; dbtypes[i]; i++)
|
||||
fprintf(stderr, " %s\n", dbtypes[i]->id);
|
||||
fprintf(stderr,
|
||||
"See the manual for options available for each database type.\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
int main(int ac, char **av)
|
||||
{
|
||||
int newac = 0; /* For passing to processing function */
|
||||
char **newav;
|
||||
char *dir = NULL; /* Source data file directory */
|
||||
int verbose = 0; /* Verbose output? */
|
||||
void (*load)(const char *, int, int, char **) = NULL;
|
||||
int i;
|
||||
char oldpath[PATH_MAX+1], newpath[PATH_MAX+1];
|
||||
|
||||
#if CLEAN_COMPILE
|
||||
free_nickinfo(NULL);
|
||||
free_nickgroupinfo(NULL);
|
||||
free_channelinfo(NULL);
|
||||
#endif
|
||||
|
||||
init_password(&supass);
|
||||
|
||||
/* Parse command-line parameters */
|
||||
newac = 1;
|
||||
newav = malloc(sizeof(*newav) * ac);
|
||||
newav[0] = av[0];
|
||||
for (i = 1; i < ac; i++) {
|
||||
if (strcmp(av[i],"-v") == 0) {
|
||||
verbose++;
|
||||
} else if (strcmp(av[i],"-h") == 0
|
||||
|| strcmp(av[i],"-?") == 0
|
||||
|| strcmp(av[i],"-help") == 0
|
||||
|| strcmp(av[i],"--help") == 0) {
|
||||
usage(av[0]);
|
||||
} else if (av[i][0] == '+') {
|
||||
int j;
|
||||
for (j = 0; dbtypes[j]; j++) {
|
||||
if (stricmp(av[i]+1, dbtypes[j]->id) == 0) {
|
||||
load = dbtypes[j]->load;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!load) {
|
||||
fprintf(stderr, "Unknown database type `%s'\n", av[i]+1);
|
||||
usage(av[0]);
|
||||
}
|
||||
} else if (av[i][0] == '-') {
|
||||
newav[newac++] = av[i];
|
||||
} else {
|
||||
if (dir) {
|
||||
fprintf(stderr, "Only one source directory may be specified\n");
|
||||
usage(av[0]);
|
||||
}
|
||||
dir = av[i];
|
||||
}
|
||||
}
|
||||
|
||||
/* Make sure that we have a source directory and that it's valid */
|
||||
if (!dir) {
|
||||
fprintf(stderr, "Directory name must be specified\n");
|
||||
usage(av[0]);
|
||||
}
|
||||
if (access(dir, R_OK) < 0) {
|
||||
perror(dir);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* If the source directory name is relative, make it absolute */
|
||||
if (*dir != '/') {
|
||||
if (!getcwd(oldpath, sizeof(oldpath))) {
|
||||
perror("Unable to read current directory name");
|
||||
fprintf(stderr, "Try using an absolute pathname for the source directory.\n");
|
||||
return 1;
|
||||
}
|
||||
if (strlen(oldpath) + 1 + strlen(dir) + 1 > sizeof(newpath)) {
|
||||
fprintf(stderr, "Source directory pathname too long\n");
|
||||
return 1;
|
||||
}
|
||||
sprintf(newpath, "%s/%s", oldpath, dir);
|
||||
dir = newpath;
|
||||
}
|
||||
|
||||
/* If we weren't given a database type, try to figure one out */
|
||||
if (!load) {
|
||||
for (i = 0; dbtypes[i]; i++) {
|
||||
const char *s;
|
||||
if ((s = dbtypes[i]->check(dir)) != NULL) {
|
||||
fprintf(stderr, "Found %s databases\n", s);
|
||||
load = dbtypes[i]->load;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!load) {
|
||||
fprintf(stderr, "Can't determine database type; use +name option\n");
|
||||
usage(av[0]);
|
||||
}
|
||||
}
|
||||
|
||||
/* Actually load the databases. If an error occurs, load() will abort the
|
||||
* program for us */
|
||||
load(dir, verbose, newac, newav);
|
||||
if (verbose)
|
||||
fprintf(stderr, "Data files successfully loaded.\n");
|
||||
|
||||
/* Do sanity checks. */
|
||||
if (verbose)
|
||||
fprintf(stderr, "Checking data integrity...\n");
|
||||
sanity_checks();
|
||||
|
||||
/* Write the database to standard output in XML format */
|
||||
if (verbose)
|
||||
fprintf(stderr, "Writing converted data...\n");
|
||||
xml_export((xml_writefunc_t)fprintf, stdout);
|
||||
|
||||
/* Success */
|
||||
if (verbose)
|
||||
fprintf(stderr, "Done.\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* c-file-style: "stroustrup"
|
||||
* c-file-offsets: ((case-label . *) (statement-case-intro . *))
|
||||
* indent-tabs-mode: nil
|
||||
* End:
|
||||
*
|
||||
* vim: expandtab shiftwidth=4:
|
||||
*/
|
183
tools/convert-db.h
Normal file
183
tools/convert-db.h
Normal file
@ -0,0 +1,183 @@
|
||||
/* External declarations for convert-db.
|
||||
*
|
||||
* IRC Services is copyright (c) 1996-2009 Andrew Church.
|
||||
* E-mail: <achurch@achurch.org>
|
||||
* Parts written by Andrew Kempe and others.
|
||||
* This program is free but copyrighted software; see the file GPL.txt for
|
||||
* details.
|
||||
*/
|
||||
|
||||
#ifndef CONVERT_DB_H
|
||||
#define CONVERT_DB_H
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
/* Common includes. */
|
||||
|
||||
#include "services.h"
|
||||
#include "language.h"
|
||||
#include "encrypt.h"
|
||||
#include "modules/database/fileutil.h"
|
||||
#include "modules/nickserv/nickserv.h"
|
||||
#include "modules/chanserv/chanserv.h"
|
||||
#include "modules/memoserv/memoserv.h"
|
||||
#include "modules/operserv/operserv.h"
|
||||
#include "modules/operserv/maskdata.h"
|
||||
#include "modules/operserv/news.h"
|
||||
#include "modules/statserv/statserv.h"
|
||||
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
|
||||
/* Structure with information about each supported database type. */
|
||||
|
||||
typedef struct {
|
||||
/* Identifier (used with +xyz command-line option) */
|
||||
const char *id;
|
||||
/* Routine to check whether databases for this program are in the given
|
||||
* directory; returns a program/database-type name for use in the
|
||||
* "Found XYZ databases" message if databases are found, NULL if not */
|
||||
const char *(*check)(const char *dir);
|
||||
/* Routine to load databases from the given directory; prints an
|
||||
* appropriate error message and calls exit(1) if an error occurs.
|
||||
* ac/av are loaded with all option arguments passed to the program
|
||||
* not parsed out by the main code; av[0] will contain the program
|
||||
* name as usual */
|
||||
void (*load)(const char *dir, int verbose, int ac, char **av);
|
||||
} DBTypeInfo;
|
||||
|
||||
/* List of all available types. This macro is used twice in convert-db.c:
|
||||
* once with an empty PREFIX to declare all of the structures extern, and
|
||||
* once more with a PREFIX of & to define an array of pointers to the
|
||||
* structures. */
|
||||
|
||||
#define ALL_DB_TYPES(PREFIX) \
|
||||
PREFIX dbtype_anope, \
|
||||
PREFIX dbtype_auspice, \
|
||||
PREFIX dbtype_bolivia, \
|
||||
PREFIX dbtype_cygnus, \
|
||||
PREFIX dbtype_daylight, \
|
||||
PREFIX dbtype_epona, \
|
||||
PREFIX dbtype_hybserv, \
|
||||
PREFIX dbtype_ircs_1_2, \
|
||||
PREFIX dbtype_magick_14b2, \
|
||||
PREFIX dbtype_ptlink, \
|
||||
PREFIX dbtype_sirv, \
|
||||
PREFIX dbtype_trircd_4_26, \
|
||||
PREFIX dbtype_wrecked_1_2
|
||||
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
|
||||
/* Converted data. */
|
||||
extern NickGroupInfo *ngi_list;
|
||||
extern NickInfo *ni_list;
|
||||
extern ChannelInfo *ci_list;
|
||||
extern NewsItem *news_list;
|
||||
extern MaskData *md_list[256];
|
||||
extern ServerStats *ss_list;
|
||||
extern int32 maxusercnt;
|
||||
extern time_t maxusertime;
|
||||
extern Password supass;
|
||||
extern int no_supass;
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
/* Safe memory allocation and string duplication. */
|
||||
extern void *smalloc(long size);
|
||||
extern void *scalloc(long els, long elsize);
|
||||
extern void *srealloc(void *ptr, long size);
|
||||
extern char *sstrdup(const char *s);
|
||||
/* Initialize or clear a Password structure. */
|
||||
extern void init_password(Password *password);
|
||||
extern void clear_password(Password *password);
|
||||
|
||||
/* Allocate a new, initialized NickInfo (and possibly NickGroupInfo)
|
||||
* structure. */
|
||||
extern NickInfo *makenick(const char *nick, NickGroupInfo **nickgroup_ret);
|
||||
/* Allocate a new, initialized ChannelInfo structure. */
|
||||
extern ChannelInfo *makechan(const char *name);
|
||||
|
||||
/* Open a (Services pre-5.0 style) data file and check the version number.
|
||||
* Prints an error message and exits with 1 if either the file cannot be
|
||||
* opened or the version number is wrong. If `version_ret' is non-NULL,
|
||||
* the version number is stored there. */
|
||||
extern dbFILE *open_db_ver(const char *dir, const char *name,
|
||||
int32 min_version, int32 max_version,
|
||||
int32 *version_ret);
|
||||
|
||||
|
||||
/* Retrieve the NickGroupInfo structure for the given nick. Returns NULL
|
||||
* if the nick does not exist or is forbidden (i.e. has no NickGroupInfo). */
|
||||
extern NickGroupInfo *get_nickgroupinfo_by_nick(const char *nick);
|
||||
|
||||
/* Set the OperServ privilege level (os_priv) for the nickgroup associated
|
||||
* with `nick' to `level', if it is not already greater than `level'. Does
|
||||
* nothing if `nick' is NULL or does not have an associated nickgroup. */
|
||||
extern void set_os_priv(const char *nick, int16 level);
|
||||
|
||||
/* Return the Services 5.0 channel access level that corresponds to the
|
||||
* given pre-5.0 level. */
|
||||
extern int16 convert_acclev(int16 old);
|
||||
|
||||
/* Add or remove various things to or from the appropriate lists. */
|
||||
#define add_nickgroupinfo(ngi) LIST_INSERT((ngi), ngi_list)
|
||||
#define add_nickinfo(ni) LIST_INSERT((ni), ni_list)
|
||||
#define add_channelinfo(ci) LIST_INSERT((ci), ci_list)
|
||||
#define add_news(news) LIST_INSERT((news), news_list)
|
||||
#define add_maskdata(type,md) LIST_INSERT((md), md_list[(type)])
|
||||
#define add_serverstats(ss) LIST_INSERT((ss), ss_list)
|
||||
#define del_nickgroupinfo(ngi) LIST_REMOVE((ngi), ngi_list)
|
||||
#define del_nickinfo(ni) LIST_REMOVE((ni), ni_list)
|
||||
#define del_channelinfo(ci) LIST_REMOVE((ci), ci_list)
|
||||
#define del_news(news) LIST_REMOVE((news), news_list)
|
||||
#define del_maskdata(type,md) LIST_REMOVE((md), md_list[(type)])
|
||||
#define del_serverstats(ss) LIST_REMOVE((ss), ss_list)
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
#ifdef CONVERT_DB_MAIN
|
||||
|
||||
/* Macro to handle write errors. */
|
||||
#define SAFE(x) do { \
|
||||
if ((x) < 0) { \
|
||||
fprintf(stderr, "Write error on %s: %s\n", \
|
||||
f->filename, strerror(errno)); \
|
||||
exit(1); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#else /* !CONVERT_DB_MAIN */
|
||||
|
||||
/* Macro to handle read errors. */
|
||||
#define SAFE(x) do { \
|
||||
if ((x) < 0) { \
|
||||
fprintf(stderr, "Read error on %s\n", f->filename); \
|
||||
exit(1); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
/* Macro to read in a variable in machine format. */
|
||||
#define read_variable(var,f) (read_db((f),&(var),sizeof(var)) == sizeof(var))
|
||||
|
||||
#endif /* CONVERT_DB_MAIN */
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
/* Miscellaneous externs. */
|
||||
|
||||
extern void usage(const char *progname);
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
#endif /* CONVERT_DB_H */
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* c-file-style: "stroustrup"
|
||||
* c-file-offsets: ((case-label . *) (statement-case-intro . *))
|
||||
* indent-tabs-mode: nil
|
||||
* End:
|
||||
*
|
||||
* vim: expandtab shiftwidth=4:
|
||||
*/
|
966
tools/convert-epona.c
Normal file
966
tools/convert-epona.c
Normal file
@ -0,0 +1,966 @@
|
||||
/* Conversion routines for Epona/Anope databases (version 1.3.0 and later).
|
||||
*
|
||||
* IRC Services is copyright (c) 1996-2009 Andrew Church.
|
||||
* E-mail: <achurch@achurch.org>
|
||||
* Parts written by Andrew Kempe and others.
|
||||
* This program is free but copyrighted software; see the file GPL.txt for
|
||||
* details.
|
||||
*/
|
||||
|
||||
#include "convert-db.h"
|
||||
|
||||
#if NICKMAX < 32
|
||||
# error NICKMAX too small (must be >=32)
|
||||
#elif CHANMAX < 64
|
||||
# error CHANMAX too small (must be >=64)
|
||||
#elif PASSMAX < 32
|
||||
# error PASSMAX too small (must be >=32)
|
||||
#endif
|
||||
|
||||
/* Server type selected with -ircd=XXX */
|
||||
static enum servertype_enum {
|
||||
IRCD_UNKNOWN = 0,
|
||||
IRCD_BAHAMUT, /* or dreamforge, solidircd */
|
||||
IRCD_INSPIRCD,
|
||||
IRCD_PLEXUS,
|
||||
IRCD_PTLINK,
|
||||
IRCD_RAGE,
|
||||
IRCD_SHADOW,
|
||||
IRCD_ULTIMATE2,
|
||||
IRCD_ULTIMATE3,
|
||||
IRCD_UNREAL,
|
||||
IRCD_VIAGRA,
|
||||
} servertype = IRCD_UNKNOWN;
|
||||
|
||||
/* Encryption type selected with -encryption=XXXX */
|
||||
static enum enctype_enum {
|
||||
ENC_UNKNOWN = 0, /* Pre-1.7.18: use nick/channel flags to select cipher */
|
||||
ENC_NONE,
|
||||
ENC_MD5,
|
||||
ENC_SHA1,
|
||||
} enctype = ENC_UNKNOWN;
|
||||
|
||||
/* Option names for -ircd=XXXX */
|
||||
static struct {
|
||||
const char *name;
|
||||
enum servertype_enum type;
|
||||
} servertype_names[] = {
|
||||
{ "bahamut", IRCD_BAHAMUT },
|
||||
{ "dreamforge", IRCD_BAHAMUT }, /* +R/+r only */
|
||||
{ "hybrid", IRCD_UNKNOWN }, /* no special modes */
|
||||
{ "inspircd", IRCD_INSPIRCD },
|
||||
{ "plexus", IRCD_PLEXUS },
|
||||
{ "ptlink", IRCD_PTLINK },
|
||||
{ "rageircd", IRCD_RAGE },
|
||||
{ "ratbox", IRCD_UNKNOWN }, /* no special modes */
|
||||
{ "shadowircd", IRCD_SHADOW },
|
||||
{ "solidircd", IRCD_BAHAMUT }, /* shared modes */
|
||||
{ "ultimate2", IRCD_ULTIMATE2 },
|
||||
{ "ultimate3", IRCD_ULTIMATE3 },
|
||||
{ "unreal31", IRCD_UNREAL },
|
||||
{ "unreal32", IRCD_UNREAL },
|
||||
{ "viagra", IRCD_VIAGRA },
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
static void epona_load_nick(const char *dir)
|
||||
{
|
||||
dbFILE *f;
|
||||
int32 ver;
|
||||
int i, j, c;
|
||||
int16 tmp16;
|
||||
int32 tmp32;
|
||||
NickInfo *ni;
|
||||
NickGroupInfo *ngi;
|
||||
char *s;
|
||||
|
||||
f = open_db_ver(dir, "nick.db", 13, 13, &ver);
|
||||
|
||||
/* Nick cores (nick core = nickname + NickGroupInfo) */
|
||||
for (i = 0; i < 1024; i++) {
|
||||
while ((c = getc_db(f)) == 1) {
|
||||
char nickbuf[32];
|
||||
SAFE(read_string(&s, f));
|
||||
ni = makenick(s, &ngi);
|
||||
SAFE(read_string(&s, f));
|
||||
/* For some reason nick cores can get null passwords (???) */
|
||||
if (!s) {
|
||||
fprintf(stderr, "Warning: nick `%s' has null password."
|
||||
" Setting password to nickname.\n", ni->nick);
|
||||
s = ni->nick;
|
||||
}
|
||||
init_password(&ngi->pass);
|
||||
strbcpy(ngi->pass.password, s);
|
||||
SAFE(read_string(&ngi->email, f));
|
||||
SAFE(read_string(&s, f)); /* greet */
|
||||
SAFE(read_int32(&tmp32, f)); /* icq */
|
||||
SAFE(read_string(&ngi->url, f));
|
||||
SAFE(read_int32(&tmp32, f)); /* flags */
|
||||
if (tmp32 & 0x00000001)
|
||||
ngi->flags |= NF_KILLPROTECT;
|
||||
if (tmp32 & 0x00000002)
|
||||
ngi->flags |= NF_SECURE;
|
||||
if (tmp32 & 0x00000008)
|
||||
ngi->flags |= NF_MEMO_HARDMAX;
|
||||
if (tmp32 & 0x00000010)
|
||||
ngi->flags |= NF_MEMO_SIGNON;
|
||||
if (tmp32 & 0x00000020)
|
||||
ngi->flags |= NF_MEMO_RECEIVE;
|
||||
if (tmp32 & 0x00000040)
|
||||
ngi->flags |= NF_PRIVATE;
|
||||
if (tmp32 & 0x00000080)
|
||||
ngi->flags |= NF_HIDE_EMAIL;
|
||||
if (tmp32 & 0x00000100)
|
||||
ngi->flags |= NF_HIDE_MASK;
|
||||
if (tmp32 & 0x00000200)
|
||||
ngi->flags |= NF_HIDE_QUIT;
|
||||
if (tmp32 & 0x00000400)
|
||||
ngi->flags |= NF_KILL_QUICK;
|
||||
if (tmp32 & 0x00000800)
|
||||
ngi->flags |= NF_KILL_IMMED;
|
||||
if (tmp32 & 0x0000A000) /* NI_SERVICES_{ADMIN,ROOT} */
|
||||
ngi->os_priv = NP_SERVADMIN;
|
||||
else if (tmp32 & 0x00001000) /* NI_SERVICES_OPER */
|
||||
ngi->os_priv = NP_SERVOPER;
|
||||
if (enctype == ENC_UNKNOWN && (tmp32 & 0x00004000))
|
||||
ngi->pass.cipher = sstrdup("md5");
|
||||
else if (enctype == ENC_MD5)
|
||||
ngi->pass.cipher = sstrdup("md5");
|
||||
else if (enctype == ENC_SHA1)
|
||||
ngi->pass.cipher = sstrdup("sha1");
|
||||
else
|
||||
ngi->pass.cipher = NULL;
|
||||
if (tmp32 & 0x00080000)
|
||||
ngi->flags |= NF_NOOP;
|
||||
SAFE(read_int16(&tmp16, f));
|
||||
switch (tmp16) {
|
||||
case 0: ngi->language = LANG_EN_US; break;
|
||||
case 2: ngi->language = LANG_JA_EUC; break;
|
||||
case 3: ngi->language = LANG_JA_SJIS; break;
|
||||
case 4: ngi->language = LANG_ES; break;
|
||||
case 5: ngi->language = LANG_PT; break;
|
||||
case 6: ngi->language = LANG_FR; break;
|
||||
case 7: ngi->language = LANG_TR; break;
|
||||
case 8: ngi->language = LANG_IT; break;
|
||||
case 9: ngi->language = LANG_DE; break;
|
||||
case 10: /* Catalan */ break;
|
||||
case 11: /* Greek */ break;
|
||||
case 12: ngi->language = LANG_NL; break;
|
||||
}
|
||||
SAFE(read_int16(&ngi->access_count, f));
|
||||
if (ngi->access_count) {
|
||||
char **access;
|
||||
access = scalloc(sizeof(char *), ngi->access_count);
|
||||
ngi->access = access;
|
||||
for (j = 0; j < ngi->access_count; j++, access++)
|
||||
SAFE(read_string(access, f));
|
||||
}
|
||||
SAFE(read_int16(&ngi->memos.memos_count, f));
|
||||
SAFE(read_int16(&ngi->memos.memomax, f));
|
||||
if (ngi->memos.memos_count) {
|
||||
Memo *memos;
|
||||
memos = scalloc(sizeof(Memo), ngi->memos.memos_count);
|
||||
ngi->memos.memos = memos;
|
||||
for (j = 0; j < ngi->memos.memos_count; j++, memos++) {
|
||||
SAFE(read_uint32(&memos->number, f));
|
||||
SAFE(read_int16(&tmp16, f));
|
||||
if (tmp16 & 1)
|
||||
memos->flags |= MF_UNREAD;
|
||||
SAFE(read_int32(&tmp32, f));
|
||||
memos->time = tmp32;
|
||||
SAFE(read_buffer(nickbuf, f));
|
||||
strbcpy(memos->sender, nickbuf);
|
||||
SAFE(read_string(&memos->text, f));
|
||||
}
|
||||
}
|
||||
SAFE(read_int16(&tmp16, f)); /* channelcount */
|
||||
SAFE(read_int16(&tmp16, f)); /* channelmax */
|
||||
} /* while (getc_db(f) == 1) */
|
||||
if (c != 0) {
|
||||
fprintf(stderr, "%s is corrupt, aborting.\n", f->filename);
|
||||
exit(1);
|
||||
}
|
||||
} /* for (i) */
|
||||
|
||||
/* Nick aliases */
|
||||
for (i = 0; i < 1024; i++) {
|
||||
while ((c = getc_db(f)) == 1) {
|
||||
int islink = 0;
|
||||
SAFE(read_string(&s, f)); /* nick */
|
||||
ni = get_nickinfo(s);
|
||||
if (!ni) {
|
||||
islink = 1;
|
||||
ni = makenick(s, NULL);
|
||||
}
|
||||
SAFE(read_string(&ni->last_usermask, f));
|
||||
if (!ni->last_usermask)
|
||||
ni->last_usermask = (char *)"@";
|
||||
SAFE(read_string(&ni->last_realname, f));
|
||||
if (!ni->last_realname)
|
||||
ni->last_realname = (char *)"";
|
||||
SAFE(read_string(&ni->last_quit, f));
|
||||
SAFE(read_int32(&tmp32, f));
|
||||
ni->time_registered = tmp32;
|
||||
SAFE(read_int32(&tmp32, f));
|
||||
ni->last_seen = tmp32;
|
||||
SAFE(read_int16(&tmp16, f)); /* status */
|
||||
if (tmp16 & 0x0002) {
|
||||
ni->status |= NS_VERBOTEN;
|
||||
ni->nickgroup = 0;
|
||||
}
|
||||
if (tmp16 & 0x0004)
|
||||
ni->status |= NS_NOEXPIRE;
|
||||
SAFE(read_string(&s, f));
|
||||
if (islink) {
|
||||
NickInfo *root = get_nickinfo(s);
|
||||
if (!root) {
|
||||
fprintf(stderr,
|
||||
"Warning: nick alias %s has no core, discarding\n",
|
||||
ni->nick);
|
||||
continue;
|
||||
}
|
||||
ni->nickgroup = root->nickgroup;
|
||||
ngi = get_nickgroupinfo(ni->nickgroup);
|
||||
if (ngi) {
|
||||
ARRAY_EXTEND(ngi->nicks);
|
||||
strbcpy(ngi->nicks[ngi->nicks_count-1], ni->nick);
|
||||
} else {
|
||||
fprintf(stderr, "Warning: Nick group %d for nick %s not"
|
||||
" found -- program bug? Output may be corrupt.",
|
||||
ni->nickgroup, ni->nick);
|
||||
}
|
||||
} else {
|
||||
if (stricmp(s, ni->nick) != 0) {
|
||||
fprintf(stderr, "Warning: display %s for nick alias %s"
|
||||
" different from nick core\n", s, ni->nick);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (c != 0) {
|
||||
fprintf(stderr, "%s is corrupt, aborting.\n", f->filename);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
close_db(f);
|
||||
}
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
static struct {
|
||||
int32 flag;
|
||||
char mode;
|
||||
} epona_cmodes_common[] = {
|
||||
{ 0x00000001, 'i' },
|
||||
{ 0x00000002, 'm' },
|
||||
{ 0x00000004, 'n' },
|
||||
{ 0x00000008, 'p' },
|
||||
{ 0x00000010, 's' },
|
||||
{ 0x00000020, 't' },
|
||||
{ 0x00000040, 'k' },
|
||||
{ 0x00000080, 'l' },
|
||||
{ 0, 0 }
|
||||
}, epona_cmodes_none[] = { /* for servers with no special modes */
|
||||
{ 0, 0 }
|
||||
}, epona_cmodes_bahamut[] = { /* also for dreamforge, solidircd */
|
||||
{ 0x00000100, 'R' },
|
||||
{ 0x00000200, 0 }, /* 'r', never set in mlock */
|
||||
{ 0x00000400, 'c' },
|
||||
{ 0x00000800, 'M' },
|
||||
{ 0x00001000, 'j' },
|
||||
{ 0x00002000, 'S' },
|
||||
{ 0x00004000, 'N' },
|
||||
{ 0x00008000, 'O' },
|
||||
{ 0, 0 }
|
||||
}, epona_cmodes_inspircd[] = {
|
||||
{ 0x00000100, 'R' },
|
||||
{ 0x00000200, 0 }, /* 'r', never set in mlock */
|
||||
{ 0x00000400, 'c' },
|
||||
{ 0x00000800, 'A' },
|
||||
{ 0x00001000, 'H' },
|
||||
{ 0x00002000, 'K' },
|
||||
{ 0x00004000, 'L' },
|
||||
{ 0x00008000, 'O' },
|
||||
{ 0x00010000, 'Q' },
|
||||
{ 0x00020000, 'S' },
|
||||
{ 0x00040000, 'V' },
|
||||
{ 0x00080000, 'f' },
|
||||
{ 0x00100000, 'G' },
|
||||
{ 0x00200000, 'C' },
|
||||
{ 0x00400000, 'u' },
|
||||
{ 0x00800000, 'z' },
|
||||
{ 0x01000000, 'N' },
|
||||
{ 0, 0 }
|
||||
}, epona_cmodes_plexus[] = {
|
||||
{ 0x00000400, 'a' },
|
||||
{ 0x00000800, 'Z' },
|
||||
{ 0x00001000, 'M' },
|
||||
{ 0x00002000, 'c' },
|
||||
{ 0x00004000, 'O' },
|
||||
{ 0x00008000, 'R' },
|
||||
{ 0x00010000, 'N' },
|
||||
{ 0, 0 }
|
||||
}, epona_cmodes_ptlink[] = {
|
||||
{ 0x00000100, 'R' },
|
||||
{ 0x00000200, 0 }, /* 'r', never set in mlock */
|
||||
{ 0x00000400, 'A' },
|
||||
{ 0x00000800, 'B' },
|
||||
{ 0x00001000, 'c' },
|
||||
{ 0x00002000, 'd' },
|
||||
{ 0x00004000, 'f' },
|
||||
{ 0x00008000, 'K' },
|
||||
{ 0x00010000, 'O' },
|
||||
{ 0x00020000, 'q' },
|
||||
{ 0x00040000, 'S' },
|
||||
{ 0x00080000, 'N' },
|
||||
{ 0, 0 }
|
||||
}, epona_cmodes_rage[] = {
|
||||
{ 0x00000100, 'R' },
|
||||
{ 0x00000200, 0 }, /* 'r', never set in mlock */
|
||||
{ 0x00000400, 'c' },
|
||||
{ 0x00000800, 'M' },
|
||||
{ 0x00001000, 'N' },
|
||||
{ 0x00002000, 'S' },
|
||||
{ 0x00004000, 'C' },
|
||||
{ 0x00008000, 'A' },
|
||||
{ 0x00010000, 'O' },
|
||||
{ 0, 0 }
|
||||
}, epona_cmodes_shadow[] = {
|
||||
{ 0x00000100, 'K' },
|
||||
{ 0x00000200, 'A' },
|
||||
{ 0x00000400, 0 }, /* 'r', never set in mlock */
|
||||
{ 0x00000800, 'z' },
|
||||
{ 0x00001000, 'S' },
|
||||
{ 0x00002000, 'c' },
|
||||
{ 0x00004000, 'E' },
|
||||
{ 0x00008000, 'F' },
|
||||
{ 0x00010000, 'G' },
|
||||
{ 0x00020000, 'L' },
|
||||
{ 0x00040000, 'N' },
|
||||
{ 0x00080000, 'O' },
|
||||
{ 0x00100000, 'P' },
|
||||
{ 0x00200000, 'R' },
|
||||
{ 0x00400000, 'T' },
|
||||
{ 0x00800000, 'V' },
|
||||
{ 0, 0 }
|
||||
}, epona_cmodes_ultimate2[] = {
|
||||
{ 0x00000100, 'R' },
|
||||
{ 0x00000200, 0 }, /* 'r', never set in mlock */
|
||||
{ 0x00000400, 'f' },
|
||||
{ 0x00000800, 'x' },
|
||||
{ 0x00001000, 'A' },
|
||||
{ 0x00002000, 'I' },
|
||||
{ 0x00004000, 'K' },
|
||||
{ 0x00008000, 'L' },
|
||||
{ 0x00010000, 'O' },
|
||||
{ 0x00020000, 'S' },
|
||||
{ 0, 0 }
|
||||
}, epona_cmodes_ultimate3[] = {
|
||||
{ 0x00000100, 'R' },
|
||||
{ 0x00000200, 0 }, /* 'r', never set in mlock */
|
||||
{ 0x00000400, 'c' },
|
||||
{ 0x00000800, 'A' },
|
||||
{ 0x00001000, 'N' },
|
||||
{ 0x00002000, 'S' },
|
||||
{ 0x00004000, 'K' },
|
||||
{ 0x00008000, 'O' },
|
||||
{ 0x00010000, 'q' },
|
||||
{ 0x00020000, 'M' },
|
||||
{ 0, 0 }
|
||||
}, epona_cmodes_unreal[] = {
|
||||
{ 0x00000100, 'R' },
|
||||
{ 0x00000200, 0 }, /* 'r', never set in mlock */
|
||||
{ 0x00000400, 'c' },
|
||||
{ 0x00000800, 'A' },
|
||||
{ 0x00001000, 'H' },
|
||||
{ 0x00002000, 'K' },
|
||||
{ 0x00004000, 'L' },
|
||||
{ 0x00008000, 'O' },
|
||||
{ 0x00010000, 'Q' },
|
||||
{ 0x00020000, 'S' },
|
||||
{ 0x00040000, 'V' },
|
||||
{ 0x00080000, 'f' },
|
||||
{ 0x00100000, 'G' },
|
||||
{ 0x00200000, 'C' },
|
||||
{ 0x00800000, 'z' },
|
||||
{ 0x01000000, 'N' },
|
||||
{ 0x02000000, 'M' },
|
||||
{ 0x04000000, 'T' },
|
||||
{ 0, 0 }
|
||||
}, epona_cmodes_viagra[] = {
|
||||
{ 0x00000100, 'R' },
|
||||
{ 0x00000200, 0 }, /* 'r', never set in mlock */
|
||||
{ 0x00000400, 'c' },
|
||||
{ 0x00000800, 'M' },
|
||||
{ 0x00001000, 'H' },
|
||||
{ 0x00008000, 'O' },
|
||||
{ 0x00020000, 'S' },
|
||||
{ 0x01000000, 'N' },
|
||||
{ 0x02000000, 'P' },
|
||||
{ 0x04000000, 'x' },
|
||||
{ 0, 0 }
|
||||
}, *epona_cmode_index[] = {
|
||||
/* IRCD_UNKNOWN */ epona_cmodes_none,
|
||||
/* IRCD_BAHAMUT */ epona_cmodes_bahamut,
|
||||
/* IRCD_INSPIRCD */ epona_cmodes_inspircd,
|
||||
/* IRCD_PLEXUS */ epona_cmodes_plexus,
|
||||
/* IRCD_PTLINK */ epona_cmodes_ptlink,
|
||||
/* IRCD_RAGE */ epona_cmodes_rage,
|
||||
/* IRCD_SHADOW */ epona_cmodes_shadow,
|
||||
/* IRCD_ULTIMATE2 */ epona_cmodes_ultimate2,
|
||||
/* IRCD_ULTIMATE3 */ epona_cmodes_ultimate3,
|
||||
/* IRCD_UNREAL */ epona_cmodes_unreal,
|
||||
/* IRCD_VIAGRA */ epona_cmodes_viagra,
|
||||
};
|
||||
|
||||
/************************************/
|
||||
|
||||
static void epona_load_chan(const char *dir)
|
||||
{
|
||||
dbFILE *f;
|
||||
int32 ver;
|
||||
int i, j, c;
|
||||
ChannelInfo *ci;
|
||||
NickInfo *ni;
|
||||
int32 tmp32, mlock_on, mlock_off;
|
||||
char *on, *off;
|
||||
MemoInfo tmpmi;
|
||||
|
||||
f = open_db_ver(dir, "chan.db", 14, 17, &ver);
|
||||
|
||||
for (i = 0; i < 256; i++) {
|
||||
int16 tmp16;
|
||||
char *s;
|
||||
|
||||
while ((c = getc_db(f)) == 1) {
|
||||
char namebuf[64], passbuf[32], nickbuf[32];
|
||||
SAFE(read_buffer(namebuf, f));
|
||||
ci = makechan(namebuf);
|
||||
SAFE(read_string(&s, f));
|
||||
if (s) {
|
||||
ni = get_nickinfo(s);
|
||||
if (!ni) {
|
||||
fprintf(stderr,
|
||||
"Warning: Founder %s for channel %s not found\n",
|
||||
s, ci->name);
|
||||
} else if (!ni->nickgroup) {
|
||||
fprintf(stderr, "Warning: Founder %s for channel %s is a"
|
||||
" forbidden nick\n", s, ci->name);
|
||||
} else {
|
||||
ci->founder = ni->nickgroup;
|
||||
}
|
||||
}
|
||||
SAFE(read_string(&s, f));
|
||||
if (s) {
|
||||
ni = get_nickinfo(s);
|
||||
if (!ni) {
|
||||
fprintf(stderr, "Warning: Successor %s for channel %s"
|
||||
" not found\n", s, ci->name);
|
||||
} else if (!ni->nickgroup) {
|
||||
fprintf(stderr, "Warning: Successor %s for channel %s"
|
||||
" is a forbidden nick\n", s, ci->name);
|
||||
} else if (ni->nickgroup == ci->founder) {
|
||||
fprintf(stderr, "Warning: Successor %s for channel %s"
|
||||
" is the same as the founder, clearing\n",
|
||||
s, ci->name);
|
||||
} else {
|
||||
ci->successor = ni->nickgroup;
|
||||
}
|
||||
}
|
||||
SAFE(read_buffer(passbuf, f));
|
||||
init_password(&ci->founderpass);
|
||||
memcpy(ci->founderpass.password, passbuf, sizeof(passbuf));
|
||||
SAFE(read_string(&ci->desc, f));
|
||||
if (!ci->desc)
|
||||
ci->desc = (char *)"";
|
||||
SAFE(read_string(&ci->url, f));
|
||||
SAFE(read_string(&ci->email, f));
|
||||
SAFE(read_int32(&tmp32, f));
|
||||
ci->time_registered = tmp32;
|
||||
SAFE(read_int32(&tmp32, f));
|
||||
ci->last_used = tmp32;
|
||||
SAFE(read_string(&ci->last_topic, f));
|
||||
SAFE(read_buffer(nickbuf, f));
|
||||
strbcpy(ci->last_topic_setter, nickbuf);
|
||||
SAFE(read_int32(&tmp32, f));
|
||||
ci->last_topic_time = tmp32;
|
||||
SAFE(read_int32(&tmp32, f)); /* flags */
|
||||
if (tmp32 & 0x00000001)
|
||||
ci->flags |= CF_KEEPTOPIC;
|
||||
if (tmp32 & 0x00000002)
|
||||
ci->flags |= CF_SECUREOPS;
|
||||
if (tmp32 & 0x00000004)
|
||||
ci->flags |= CF_PRIVATE;
|
||||
if (tmp32 & 0x00000008)
|
||||
ci->flags |= CF_TOPICLOCK;
|
||||
if (tmp32 & 0x00000010)
|
||||
ci->flags |= CF_RESTRICTED;
|
||||
if (tmp32 & 0x00000040)
|
||||
ci->flags |= CF_SECURE;
|
||||
if (tmp32 & 0x00000080)
|
||||
ci->flags |= CF_VERBOTEN;
|
||||
if (enctype == ENC_UNKNOWN && (tmp32 & 0x00000100))
|
||||
ci->founderpass.cipher = sstrdup("md5");
|
||||
else if (enctype == ENC_MD5)
|
||||
ci->founderpass.cipher = sstrdup("md5");
|
||||
else if (enctype == ENC_SHA1)
|
||||
ci->founderpass.cipher = sstrdup("sha1");
|
||||
else
|
||||
ci->founderpass.cipher = NULL;
|
||||
if (tmp32 & 0x00000200)
|
||||
ci->flags |= CF_NOEXPIRE;
|
||||
if (tmp32 & 0x00000800)
|
||||
ci->flags |= CF_OPNOTICE;
|
||||
if (tmp32 & 0x00010000) {
|
||||
ci->flags |= CF_SUSPENDED;
|
||||
strbcpy(ci->suspend_who, "<unknown>");
|
||||
ci->suspend_reason =
|
||||
(char *)"Unknown (imported from Anope Services)";
|
||||
ci->suspend_time = time(NULL);
|
||||
ci->suspend_expires = 0;
|
||||
}
|
||||
SAFE(read_string(&s, f)); /* forbidby */
|
||||
SAFE(read_string(&s, f)); /* forbidreason */
|
||||
SAFE(read_int16(&tmp16, f)); /* bantype */
|
||||
|
||||
SAFE(read_int16(&tmp16, f));
|
||||
for (j = tmp16; j > 0; j--)
|
||||
SAFE(read_int16(&tmp16, f));
|
||||
|
||||
SAFE(read_int16(&ci->access_count, f));
|
||||
if (ci->access_count) {
|
||||
ci->access = scalloc(ci->access_count, sizeof(ChanAccess));
|
||||
for (j = 0; j < ci->access_count; j++) {
|
||||
SAFE(read_int16(&tmp16, f)); /* in_use */
|
||||
if (tmp16) {
|
||||
SAFE(read_int16(&ci->access[j].level, f));
|
||||
SAFE(read_string(&s, f));
|
||||
SAFE(read_int32(&tmp32, f)); /* last used */
|
||||
ci->access[j].level =
|
||||
convert_acclev(ci->access[j].level);
|
||||
if (s) {
|
||||
ni = get_nickinfo(s);
|
||||
if (ni)
|
||||
ci->access[j].nickgroup = ni->nickgroup;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SAFE(read_int16(&ci->akick_count, f));
|
||||
if (ci->akick_count) {
|
||||
ci->akick = scalloc(ci->akick_count, sizeof(AutoKick));
|
||||
for (j = 0; j < ci->akick_count; j++) {
|
||||
int16 is_nick = 0;
|
||||
SAFE(read_int16(&tmp16, f)); /* in_use */
|
||||
if (ver > 14) {
|
||||
is_nick = tmp16 & 2;
|
||||
tmp16 &= 1;
|
||||
}
|
||||
if (tmp16) {
|
||||
if (ver == 14)
|
||||
SAFE(read_int16(&is_nick, f));
|
||||
SAFE(read_string(&s, f));
|
||||
if (is_nick && s) {
|
||||
ci->akick[j].mask = smalloc(strlen(s)+5);
|
||||
sprintf(ci->akick[j].mask, "%s!*@*", s);
|
||||
} else {
|
||||
ci->akick[j].mask = s;
|
||||
}
|
||||
SAFE(read_string(&s, f));
|
||||
if (ci->akick[j].mask)
|
||||
ci->akick[j].reason = s;
|
||||
SAFE(read_string(&s, f));
|
||||
if (ci->akick[j].mask)
|
||||
strbcpy(ci->akick[j].who, s);
|
||||
SAFE(read_int32(&tmp32, f));
|
||||
if (ci->akick[j].mask)
|
||||
ci->akick[j].set = tmp32;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SAFE(read_int32(&mlock_on, f));
|
||||
SAFE(read_int32(&mlock_off, f));
|
||||
ci->mlock.on = on = scalloc(64, 1);
|
||||
ci->mlock.off = off = scalloc(64, 1);
|
||||
for (j = 0; epona_cmodes_common[j].flag != 0; j++) {
|
||||
if (mlock_on & epona_cmodes_common[j].flag)
|
||||
*on++ = epona_cmodes_common[j].mode;
|
||||
if (mlock_off & epona_cmodes_common[j].flag)
|
||||
*off++ = epona_cmodes_common[j].mode;
|
||||
}
|
||||
for (j = 0; epona_cmode_index[servertype][j].flag != 0; j++) {
|
||||
if (mlock_on & epona_cmode_index[servertype][j].flag)
|
||||
*on++ = epona_cmode_index[servertype][j].mode;
|
||||
if (mlock_off & epona_cmode_index[servertype][j].flag)
|
||||
*off++ = epona_cmode_index[servertype][j].mode;
|
||||
}
|
||||
SAFE(read_int32(&ci->mlock.limit, f));
|
||||
SAFE(read_string(&ci->mlock.key, f));
|
||||
SAFE(read_string(&ci->mlock.flood, f));
|
||||
if (ver >= 17) {
|
||||
char *s;
|
||||
SAFE(read_string(&s, f));
|
||||
if (s) {
|
||||
unsigned long rate1, rate2;
|
||||
if (sscanf(s, "%lu:%lu", &rate1, &rate2) == 2
|
||||
&& rate1 > 0 && rate1 < 0x7FFFFFFFUL
|
||||
&& rate2 > 0 && rate2 < 0x7FFFFFFFUL
|
||||
) {
|
||||
ci->mlock.joinrate1 = rate1;
|
||||
ci->mlock.joinrate2 = rate2;
|
||||
} else {
|
||||
fprintf(stderr, "MLOCK +j setting for %s is"
|
||||
" invalid, discarding", ci->name);
|
||||
}
|
||||
free(s);
|
||||
}
|
||||
}
|
||||
SAFE(read_string(&ci->mlock.link, f));
|
||||
|
||||
SAFE(read_int16(&tmpmi.memos_count, f));
|
||||
SAFE(read_int16(&tmp16, f)); /* memomax */
|
||||
if (tmpmi.memos_count) {
|
||||
Memo *memos;
|
||||
memos = scalloc(sizeof(Memo), tmpmi.memos_count);
|
||||
tmpmi.memos = memos;
|
||||
for (j = 0; j < tmpmi.memos_count; j++, memos++) {
|
||||
SAFE(read_uint32(&memos->number, f));
|
||||
SAFE(read_int16(&tmp16, f));
|
||||
if (tmp16 & 1)
|
||||
memos->flags |= MF_UNREAD;
|
||||
SAFE(read_int32(&tmp32, f));
|
||||
memos->time = tmp32;
|
||||
SAFE(read_buffer(nickbuf, f));
|
||||
strbcpy(memos->sender, nickbuf);
|
||||
SAFE(read_string(&memos->text, f));
|
||||
}
|
||||
}
|
||||
|
||||
SAFE(read_string(&ci->entry_message, f));
|
||||
|
||||
/* BotServ-related */
|
||||
SAFE(read_string(&s, f));
|
||||
SAFE(read_int32(&tmp32, f));
|
||||
SAFE(read_int16(&tmp16, f));
|
||||
for (j = tmp16; j > 0; j--)
|
||||
SAFE(read_int16(&tmp16, f));
|
||||
SAFE(read_int16(&tmp16, f));
|
||||
SAFE(read_int16(&tmp16, f));
|
||||
SAFE(read_int16(&tmp16, f));
|
||||
SAFE(read_int16(&tmp16, f));
|
||||
SAFE(read_int16(&tmp16, f));
|
||||
SAFE(read_int16(&tmp16, f));
|
||||
for (j = tmp16; j > 0; j--) {
|
||||
SAFE(read_int16(&tmp16, f));
|
||||
if (tmp16) {
|
||||
SAFE(read_string(&s, f));
|
||||
SAFE(read_int16(&tmp16, f));
|
||||
}
|
||||
}
|
||||
|
||||
if (!(ci->flags & CF_VERBOTEN) && !ci->founder) {
|
||||
fprintf(stderr, "Ignoring channel %s (missing founder)\n",
|
||||
ci->name);
|
||||
del_channelinfo(ci);
|
||||
}
|
||||
|
||||
} /* while (getc_db(f) == 1) */
|
||||
if (c != 0) {
|
||||
fprintf(stderr, "%s is corrupt, aborting.\n", f->filename);
|
||||
exit(1);
|
||||
}
|
||||
} /* for (i) */
|
||||
close_db(f);
|
||||
}
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
static void epona_load_oper(const char *dir)
|
||||
{
|
||||
dbFILE *f;
|
||||
int32 ver;
|
||||
int16 i, n, tmp16;
|
||||
int32 tmp32;
|
||||
char *s;
|
||||
MaskData *md;
|
||||
|
||||
f = open_db_ver(dir, "oper.db", 11, 13, &ver);
|
||||
if (ver == 12) {
|
||||
fprintf(stderr, "Unsupported version number (%d) on oper.db.\n"
|
||||
"Are you using a beta version of Epona?\n", ver);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* stats */
|
||||
SAFE(read_int32(&maxusercnt, f));
|
||||
SAFE(read_int32(&tmp32, f));
|
||||
maxusertime = tmp32;
|
||||
/* akills */
|
||||
SAFE(read_int16(&n, f));
|
||||
md = scalloc(sizeof(*md), n);
|
||||
for (i = 0; i < n; i++) {
|
||||
char *user, *host;
|
||||
SAFE(read_string(&user, f));
|
||||
SAFE(read_string(&host, f));
|
||||
s = smalloc(strlen(user)+strlen(host)+2);
|
||||
sprintf(s, "%s@%s", user, host);
|
||||
md[i].mask = s;
|
||||
SAFE(read_string(&s, f));
|
||||
strbcpy(md[i].who, s);
|
||||
SAFE(read_string(&md[i].reason, f));
|
||||
SAFE(read_int32(&tmp32, f));
|
||||
md[i].time = tmp32;
|
||||
SAFE(read_int32(&tmp32, f));
|
||||
md[i].expires = tmp32;
|
||||
if (md[i].mask)
|
||||
add_maskdata(MD_AKILL, &md[i]);
|
||||
}
|
||||
/* sglines */
|
||||
SAFE(read_int16(&n, f));
|
||||
md = scalloc(sizeof(*md), n);
|
||||
for (i = 0; i < n; i++) {
|
||||
SAFE(read_string(&md[i].mask, f));
|
||||
SAFE(read_string(&s, f));
|
||||
strbcpy(md[i].who, s);
|
||||
SAFE(read_string(&md[i].reason, f));
|
||||
SAFE(read_int32(&tmp32, f));
|
||||
md[i].time = tmp32;
|
||||
SAFE(read_int32(&tmp32, f));
|
||||
md[i].expires = tmp32;
|
||||
if (md[i].mask)
|
||||
add_maskdata(MD_SGLINE, &md[i]);
|
||||
}
|
||||
if (ver >= 13) {
|
||||
/* sqlines */
|
||||
SAFE(read_int16(&n, f));
|
||||
md = scalloc(sizeof(*md), n);
|
||||
for (i = 0; i < n; i++) {
|
||||
SAFE(read_string(&md[i].mask, f));
|
||||
SAFE(read_string(&s, f));
|
||||
strbcpy(md[i].who, s);
|
||||
SAFE(read_string(&md[i].reason, f));
|
||||
SAFE(read_int32(&tmp32, f));
|
||||
md[i].time = tmp32;
|
||||
SAFE(read_int32(&tmp32, f));
|
||||
md[i].expires = tmp32;
|
||||
if (md[i].mask)
|
||||
add_maskdata(MD_SQLINE, &md[i]);
|
||||
}
|
||||
}
|
||||
/* szlines */
|
||||
SAFE(read_int16(&n, f));
|
||||
md = scalloc(sizeof(*md), n);
|
||||
for (i = 0; i < n; i++) {
|
||||
SAFE(read_string(&md[i].mask, f));
|
||||
SAFE(read_string(&s, f));
|
||||
strbcpy(md[i].who, s);
|
||||
SAFE(read_string(&md[i].reason, f));
|
||||
SAFE(read_int32(&tmp32, f));
|
||||
md[i].time = tmp32;
|
||||
SAFE(read_int32(&tmp32, f));
|
||||
md[i].expires = tmp32;
|
||||
if (md[i].mask)
|
||||
add_maskdata(MD_SZLINE, &md[i]);
|
||||
}
|
||||
if (ver >= 13) {
|
||||
/* proxy (open-relay) host cache */
|
||||
for (i = 0; i < 1024; i++) {
|
||||
int8 c;
|
||||
if (read_int8(&c, f) < 0) /* 1.7 doesn't save this data */
|
||||
break;
|
||||
while (c) {
|
||||
SAFE(read_string(&s, f)); /* host */
|
||||
SAFE(read_int16(&tmp16, f)); /* status */
|
||||
SAFE(read_int32(&tmp32, f)); /* used */
|
||||
SAFE(read_int8(&c, f));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
close_db(f);
|
||||
}
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
static void epona_load_exception(const char *dir)
|
||||
{
|
||||
dbFILE *f;
|
||||
int32 ver;
|
||||
int16 i, n;
|
||||
int32 tmp32;
|
||||
MaskData *md;
|
||||
|
||||
f = open_db_ver(dir, "exception.db", 9, 9, &ver);
|
||||
SAFE(read_int16(&n, f));
|
||||
md = scalloc(sizeof(*md), n);
|
||||
for (i = 0; i < n; i++) {
|
||||
char nickbuf[32];
|
||||
SAFE(read_string(&md[i].mask, f));
|
||||
SAFE(read_int16(&md[i].limit, f));
|
||||
SAFE(read_buffer(nickbuf, f));
|
||||
strbcpy(md[i].who, nickbuf);
|
||||
SAFE(read_string(&md[i].reason, f));
|
||||
SAFE(read_int32(&tmp32, f));
|
||||
md[i].time = tmp32;
|
||||
SAFE(read_int32(&tmp32, f));
|
||||
md[i].expires = tmp32;
|
||||
md[i].num = i;
|
||||
if (md[i].mask)
|
||||
add_maskdata(MD_EXCEPTION, &md[i]);
|
||||
}
|
||||
close_db(f);
|
||||
}
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
static void epona_load_news(const char *dir)
|
||||
{
|
||||
dbFILE *f;
|
||||
int32 ver;
|
||||
int16 i, n;
|
||||
int32 tmp32;
|
||||
NewsItem *news;
|
||||
|
||||
f = open_db_ver(dir, "news.db", 9, 9, &ver);
|
||||
SAFE(read_int16(&n, f));
|
||||
news = scalloc(sizeof(*news), n);
|
||||
for (i = 0; i < n; i++) {
|
||||
char nickbuf[32];
|
||||
SAFE(read_int16(&news[i].type, f));
|
||||
SAFE(read_int32(&news[i].num, f));
|
||||
SAFE(read_string(&news[i].text, f));
|
||||
SAFE(read_buffer(nickbuf, f));
|
||||
strbcpy(news[i].who, nickbuf);
|
||||
SAFE(read_int32(&tmp32, f));
|
||||
news[i].time = tmp32;
|
||||
add_news(&news[i]);
|
||||
}
|
||||
close_db(f);
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
|
||||
static const char *check_epona(const char *dir)
|
||||
{
|
||||
char buf[PATH_MAX+1];
|
||||
|
||||
snprintf(buf, sizeof(buf), "%s/bot.db", dir);
|
||||
if (access(buf, R_OK) == 0) {
|
||||
FILE *f;
|
||||
snprintf(buf, sizeof(buf), "%s/chan.db", dir);
|
||||
f = fopen(buf, "rb");
|
||||
if (f) {
|
||||
int32 ver;
|
||||
ver = fgetc(f)<<24;
|
||||
ver |= fgetc(f)<<16;
|
||||
ver |= fgetc(f)<< 8;
|
||||
ver |= fgetc(f);
|
||||
fclose(f);
|
||||
switch (ver) {
|
||||
case 14: return "Epona 1.3.x";
|
||||
case 15: return "Epona 1.4.0";
|
||||
case 16: return "Epona 1.4.1-1.4.14 / Anope";
|
||||
case 17: return "Epona 1.4.15+";
|
||||
}
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void load_epona(const char *dir, int verbose, int ac, char **av)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 1; i < ac; i++) {
|
||||
if (strncmp(av[i],"-ircd=",6) == 0) {
|
||||
const char *ircd = av[i]+6;
|
||||
int j;
|
||||
for (j = 0; servertype_names[j].name != NULL; j++) {
|
||||
if (stricmp(servertype_names[j].name, ircd) == 0)
|
||||
break;
|
||||
}
|
||||
if (servertype_names[j].name) {
|
||||
servertype = servertype_names[j].type;
|
||||
} else {
|
||||
fprintf(stderr, "Unrecognized IRC server type %s\n", ircd);
|
||||
fprintf(stderr, "Valid IRC server types are:\n");
|
||||
for (j = 0; servertype_names[j].name != NULL; j++)
|
||||
fprintf(stderr, " %s\n", servertype_names[j].name);
|
||||
exit(1);
|
||||
}
|
||||
} else if (strncmp(av[i],"-encryption=",12) == 0) {
|
||||
const char *encryption = av[i]+12;
|
||||
/* Allow Anope module names as well */
|
||||
if (strnicmp(encryption, "enc_", 4) == 0) {
|
||||
encryption += 4;
|
||||
}
|
||||
if (stricmp(encryption, "none") == 0) {
|
||||
enctype = ENC_NONE;
|
||||
} else if (stricmp(encryption, "md5") == 0
|
||||
|| stricmp(encryption, "old") == 0) {
|
||||
enctype = ENC_MD5;
|
||||
} else if (stricmp(encryption, "sha1") == 0) {
|
||||
enctype = ENC_SHA1;
|
||||
} else {
|
||||
fprintf(stderr, "Unsupported encryption type %s\n",
|
||||
encryption);
|
||||
fprintf(stderr, "Supported encryption types are:"
|
||||
" none, md5, old, sha1\n");
|
||||
exit(1);
|
||||
}
|
||||
} else {
|
||||
fprintf(stderr, "Unrecognized option %s\n", av[i]);
|
||||
usage(av[0]);
|
||||
}
|
||||
}
|
||||
|
||||
if (verbose)
|
||||
fprintf(stderr, "Loading nick.db...\n");
|
||||
epona_load_nick(dir);
|
||||
if (verbose)
|
||||
fprintf(stderr, "Loading chan.db...\n");
|
||||
epona_load_chan(dir);
|
||||
if (verbose)
|
||||
fprintf(stderr, "Loading oper.db...\n");
|
||||
epona_load_oper(dir);
|
||||
if (verbose)
|
||||
fprintf(stderr, "Loading exception.db...\n");
|
||||
epona_load_exception(dir);
|
||||
if (verbose)
|
||||
fprintf(stderr, "Loading news.db...\n");
|
||||
epona_load_news(dir);
|
||||
}
|
||||
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
|
||||
DBTypeInfo dbtype_epona = {
|
||||
"epona",
|
||||
check_epona,
|
||||
load_epona
|
||||
};
|
||||
|
||||
|
||||
DBTypeInfo dbtype_anope = {
|
||||
"anope",
|
||||
check_epona,
|
||||
load_epona
|
||||
};
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* c-file-style: "stroustrup"
|
||||
* c-file-offsets: ((case-label . *) (statement-case-intro . *))
|
||||
* indent-tabs-mode: nil
|
||||
* End:
|
||||
*
|
||||
* vim: expandtab shiftwidth=4:
|
||||
*/
|
1062
tools/convert-hybserv.c
Normal file
1062
tools/convert-hybserv.c
Normal file
File diff suppressed because it is too large
Load Diff
696
tools/convert-magick.c
Normal file
696
tools/convert-magick.c
Normal file
@ -0,0 +1,696 @@
|
||||
/* Conversion routines for Magick 1.4b2 and Wrecked 1.2 databases.
|
||||
*
|
||||
* IRC Services is copyright (c) 1996-2009 Andrew Church.
|
||||
* E-mail: <achurch@achurch.org>
|
||||
* Parts written by Andrew Kempe and others.
|
||||
* This program is free but copyrighted software; see the file GPL.txt for
|
||||
* details.
|
||||
*/
|
||||
|
||||
#include "convert-db.h"
|
||||
|
||||
#if NICKMAX < 32
|
||||
# error NICKMAX too small (must be >=32)
|
||||
#elif CHANMAX < 64
|
||||
# error CHANMAX too small (must be >=64)
|
||||
#elif PASSMAX < 32
|
||||
# error PASSMAX too small (must be >=32)
|
||||
#endif
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
static void m14_load_nick(const char *dir, int32 version)
|
||||
{
|
||||
dbFILE *f;
|
||||
long i, j;
|
||||
int c;
|
||||
NickInfo *ni;
|
||||
NickGroupInfo *ngi;
|
||||
struct oldni_ {
|
||||
struct oldni_ *next, *prev;
|
||||
char nick[32];
|
||||
char pass[32];
|
||||
char *email;
|
||||
char *url;
|
||||
char *usermask;
|
||||
char *realname;
|
||||
time_t reg;
|
||||
time_t seen;
|
||||
long naccess;
|
||||
char **access;
|
||||
long nignore;
|
||||
char **ignore;
|
||||
long flags;
|
||||
long resv[4];
|
||||
} oldni;
|
||||
|
||||
f = open_db_ver(dir, "nick.db", version, version, NULL);
|
||||
for (i = 33; i < 256; i++) {
|
||||
while ((c = getc_db(f)) == 1) {
|
||||
SAFE(read_variable(oldni, f));
|
||||
if (version == 6) {
|
||||
time_t last_signon;
|
||||
long uin;
|
||||
SAFE(read_variable(last_signon, f));
|
||||
SAFE(read_variable(uin, f));
|
||||
}
|
||||
if (oldni.email)
|
||||
SAFE(read_string(&oldni.email, f));
|
||||
if (oldni.url)
|
||||
SAFE(read_string(&oldni.url, f));
|
||||
SAFE(read_string(&oldni.usermask, f));
|
||||
SAFE(read_string(&oldni.realname, f));
|
||||
ni = makenick(oldni.nick, &ngi);
|
||||
ni->last_usermask = oldni.usermask;
|
||||
ni->last_realname = oldni.realname;
|
||||
ni->last_quit = NULL;
|
||||
ni->time_registered = oldni.reg;
|
||||
ni->last_seen = oldni.seen;
|
||||
init_password(&ngi->pass);
|
||||
strbcpy(ngi->pass.password, oldni.pass);
|
||||
ngi->url = oldni.url;
|
||||
ngi->email = oldni.email;
|
||||
ngi->access_count = oldni.naccess;
|
||||
ngi->ignore_count = oldni.nignore;
|
||||
if (version == 5)
|
||||
oldni.flags &= 0x000000FF;
|
||||
if (oldni.flags & 0x00000001)
|
||||
ngi->flags |= NF_KILLPROTECT;
|
||||
if (oldni.flags & 0x00000002)
|
||||
ngi->flags |= NF_SECURE;
|
||||
if (oldni.flags & 0x00000004) {
|
||||
ni->status |= NS_VERBOTEN;
|
||||
ni->nickgroup = 0;
|
||||
}
|
||||
if (oldni.flags & 0x00004008)
|
||||
ni->status |= NS_NOEXPIRE;
|
||||
if (oldni.flags & 0x00000010)
|
||||
ngi->flags |= NF_PRIVATE;
|
||||
if (oldni.flags & 0x00000020) {
|
||||
strbcpy(ngi->suspend_who, "<unknown>");
|
||||
ngi->suspend_reason = (char *)(
|
||||
version==6 ? "Unknown (imported from Wrecked IRC Services)"
|
||||
: "Unknown (imported from Magick IRC Services)"
|
||||
);
|
||||
ngi->suspend_time = time(NULL);
|
||||
ngi->suspend_expires = 0;
|
||||
ngi->flags |= NF_SUSPENDED;
|
||||
}
|
||||
if (oldni.flags & 0x00000080) {
|
||||
ni->status |= 0x8000; /* Flag: this is a linked nick */
|
||||
ni->nickgroup = 0;
|
||||
}
|
||||
if (oldni.flags & 0x00000100)
|
||||
ngi->memos.memomax = 0;
|
||||
if (oldni.flags & 0x00000200)
|
||||
ngi->flags |= NF_HIDE_EMAIL;
|
||||
ngi->access = smalloc(ngi->access_count * sizeof(char *));
|
||||
for (j = 0; j < ngi->access_count; j++)
|
||||
SAFE(read_string(&ngi->access[j], f));
|
||||
ngi->ignore = smalloc(ngi->ignore_count * sizeof(char *));
|
||||
for (j = 0; j < ngi->ignore_count; j++)
|
||||
SAFE(read_string(&ngi->ignore[j], f));
|
||||
} /* while more entries */
|
||||
if (c != 0) {
|
||||
fprintf(stderr, "%s is corrupt, aborting.\n", f->filename);
|
||||
exit(1);
|
||||
}
|
||||
} /* for 33..256 */
|
||||
close_db(f);
|
||||
|
||||
/* Resolve links */
|
||||
for (ni = first_nickinfo(); ni; ni = next_nickinfo()) {
|
||||
NickInfo *ni2;
|
||||
const char *last_nick;
|
||||
if (ni->status & 0x8000) {
|
||||
ni->status &= ~0x8000;
|
||||
ni2 = ni;
|
||||
/* Find root nick (this will actually stop at the first nick
|
||||
* in the path to the root that isn't marked as linked, but
|
||||
* that's okay because such a nick will already have its
|
||||
* nickgroup ID set correctly) */
|
||||
do {
|
||||
last_nick = ni2->last_usermask;
|
||||
ni2 = get_nickinfo(last_nick);
|
||||
} while (ni2 && (ni2->status & 0x8000));
|
||||
/* Set nickgroup and last usermask field, or delete nick if an
|
||||
* error occurred */
|
||||
if (ni2 == ni) {
|
||||
fprintf(stderr,
|
||||
"Warning: dropping nick %s with circular link\n",
|
||||
ni->nick);
|
||||
del_nickinfo(ni);
|
||||
} else if (!ni2) {
|
||||
fprintf(stderr, "Warning: dropping nick %s linked to"
|
||||
" nonexistent nick %s\n", ni->nick, last_nick);
|
||||
del_nickinfo(ni);
|
||||
} else {
|
||||
ngi = get_nickgroupinfo(ni->nickgroup);
|
||||
if (ngi)
|
||||
del_nickgroupinfo(ngi);
|
||||
ni->nickgroup = ni2->nickgroup;
|
||||
ni->last_usermask = ni2->last_usermask;
|
||||
ngi = get_nickgroupinfo(ni->nickgroup);
|
||||
if (ngi) {
|
||||
ARRAY_EXTEND(ngi->nicks);
|
||||
strbcpy(ngi->nicks[ngi->nicks_count-1], ni->nick);
|
||||
} else if (ni->nickgroup != 0) {
|
||||
fprintf(stderr, "Warning: Nick group %d for nick %s not"
|
||||
" found -- program bug? Output may be corrupt.",
|
||||
ni->nickgroup, ni->nick);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
static int16 magick_convert_level(int16 lev) {
|
||||
if (lev >= 20)
|
||||
return lev-10;
|
||||
else if (lev >= 5)
|
||||
return lev/2;
|
||||
else if (lev >= 1)
|
||||
return (lev+1)/2;
|
||||
else
|
||||
return lev;
|
||||
};
|
||||
|
||||
static int16 wrecked_convert_level(int16 lev) {
|
||||
if (lev >= 25)
|
||||
return lev-15;
|
||||
else if (lev >= 15)
|
||||
return (lev-5)/10;
|
||||
else if (lev >= 10)
|
||||
return 4;
|
||||
else if (lev >= 5)
|
||||
return 3;
|
||||
else if (lev >= 1)
|
||||
return (lev+1) / 2;
|
||||
else
|
||||
return lev;
|
||||
};
|
||||
|
||||
|
||||
static void m14_load_chan(const char *dir, int32 version)
|
||||
{
|
||||
char *s;
|
||||
dbFILE *f;
|
||||
long i, j;
|
||||
int c;
|
||||
int16 tmp16;
|
||||
int16 (*my_convert_level)(int16);
|
||||
ChannelInfo *ci;
|
||||
NickInfo *ni;
|
||||
struct access_ {
|
||||
short level;
|
||||
short is_nick;
|
||||
char *name;
|
||||
} access;
|
||||
struct akick_ {
|
||||
short is_nick;
|
||||
short pad;
|
||||
char *name;
|
||||
char *reason;
|
||||
} akick;
|
||||
struct oldci_ {
|
||||
struct oldci_ *next, *prev;
|
||||
char name[64];
|
||||
char founder[32];
|
||||
char pass[32];
|
||||
char *desc;
|
||||
char *url;
|
||||
time_t reg;
|
||||
time_t used;
|
||||
long naccess;
|
||||
struct access_ *access;
|
||||
long nakick;
|
||||
struct akick_ *akick;
|
||||
char mlock_on[64], mlock_off[64];
|
||||
long mlock_limit;
|
||||
char *mlock_key;
|
||||
char *topic;
|
||||
char topic_setter[32];
|
||||
time_t topic_time;
|
||||
long flags;
|
||||
short *levels;
|
||||
long resv[3];
|
||||
} oldci;
|
||||
|
||||
if (version == 6)
|
||||
my_convert_level = wrecked_convert_level;
|
||||
else
|
||||
my_convert_level = magick_convert_level;
|
||||
|
||||
f = open_db_ver(dir, "chan.db", version, version, NULL);
|
||||
for (i = 33; i < 256; i++) {
|
||||
while ((c = getc_db(f)) == 1) {
|
||||
SAFE(read_variable(oldci, f));
|
||||
SAFE(read_string(&oldci.desc, f));
|
||||
if (oldci.url)
|
||||
SAFE(read_string(&oldci.url, f));
|
||||
if (oldci.mlock_key)
|
||||
SAFE(read_string(&oldci.mlock_key, f));
|
||||
if (oldci.topic)
|
||||
SAFE(read_string(&oldci.topic, f));
|
||||
ci = makechan(oldci.name);
|
||||
if (*oldci.founder) {
|
||||
ni = get_nickinfo(oldci.founder);
|
||||
if (!ni) {
|
||||
fprintf(stderr,
|
||||
"Warning: Founder %s for channel %s not found\n",
|
||||
oldci.founder, oldci.name);
|
||||
} else if (ni->status & NS_VERBOTEN) {
|
||||
fprintf(stderr, "Warning: Founder %s for channel %s is a"
|
||||
" forbidden nick\n", oldci.founder, oldci.name);
|
||||
} else if (!ni->nickgroup) {
|
||||
fprintf(stderr, "Warning: Founder %s for channel %s has"
|
||||
" an invalid nickname record (bug?)\n",
|
||||
oldci.founder, oldci.name);
|
||||
} else {
|
||||
ci->founder = ni->nickgroup;
|
||||
}
|
||||
}
|
||||
init_password(&ci->founderpass);
|
||||
strbcpy(ci->founderpass.password, oldci.pass);
|
||||
ci->desc = oldci.desc;
|
||||
ci->url = oldci.url;
|
||||
ci->time_registered = oldci.reg;
|
||||
ci->last_used = oldci.used;
|
||||
ci->access_count = oldci.naccess;
|
||||
ci->akick_count = oldci.nakick;
|
||||
ci->mlock.on = scalloc(64, 1);
|
||||
strscpy(ci->mlock.on, oldci.mlock_on, 64);
|
||||
ci->mlock.off = scalloc(64, 1);
|
||||
strscpy(ci->mlock.off, oldci.mlock_off, 64);
|
||||
ci->mlock.limit = oldci.mlock_limit;
|
||||
ci->mlock.key = oldci.mlock_key;
|
||||
ci->last_topic = oldci.topic;
|
||||
strbcpy(ci->last_topic_setter, oldci.topic_setter);
|
||||
ci->last_topic_time = oldci.topic_time;
|
||||
if (version == 5)
|
||||
oldci.flags &= 0x000003FF;
|
||||
if (oldci.flags & 0x00000001)
|
||||
ci->flags |= CF_KEEPTOPIC;
|
||||
if (oldci.flags & 0x00000002)
|
||||
ci->flags |= CF_SECUREOPS;
|
||||
if (oldci.flags & 0x00000004)
|
||||
ci->flags |= CF_PRIVATE;
|
||||
if (oldci.flags & 0x00000008)
|
||||
ci->flags |= CF_TOPICLOCK;
|
||||
if (oldci.flags & 0x00000010)
|
||||
ci->flags |= CF_RESTRICTED;
|
||||
if (oldci.flags & 0x00000020)
|
||||
ci->flags |= CF_LEAVEOPS;
|
||||
if (oldci.flags & 0x00000040)
|
||||
ci->flags |= CF_SECURE;
|
||||
if (oldci.flags & 0x00000080)
|
||||
ci->flags |= CF_VERBOTEN;
|
||||
if (oldci.flags & 0x00000100) {
|
||||
ci->flags |= CF_SUSPENDED;
|
||||
strbcpy(ci->suspend_who, "<unknown>");
|
||||
ci->suspend_reason = (char *)(
|
||||
version==6 ? "Unknown (imported from Wrecked IRC Services)"
|
||||
: "Unknown (imported from Magick IRC Services)"
|
||||
);
|
||||
ci->suspend_time = time(NULL);
|
||||
ci->suspend_expires = 0;
|
||||
}
|
||||
if (oldci.flags & 0x00000400)
|
||||
ci->flags |= CF_NOEXPIRE;
|
||||
|
||||
ci->access = scalloc(sizeof(ChanAccess), ci->access_count);
|
||||
for (j = 0; j < oldci.naccess; j++) {
|
||||
SAFE(read_variable(access, f));
|
||||
ci->access[j].nickgroup = (access.is_nick == 1); /* in_use */
|
||||
ci->access[j].level =
|
||||
convert_acclev(my_convert_level(access.level));
|
||||
}
|
||||
for (j = 0; j < oldci.naccess; j++) {
|
||||
SAFE(read_string(&s, f));
|
||||
if (!s) {
|
||||
ci->access[j].nickgroup = 0;
|
||||
continue;
|
||||
}
|
||||
if (ci->access[j].nickgroup) {
|
||||
ni = get_nickinfo(s);
|
||||
ci->access[j].nickgroup = ni ? ni->nickgroup : 0;
|
||||
}
|
||||
}
|
||||
|
||||
ci->akick = scalloc(sizeof(AutoKick), oldci.nakick);
|
||||
for (j = 0; j < oldci.nakick; j++) {
|
||||
SAFE(read_variable(akick, f));
|
||||
/* `lastused' field temporarily used to hold `is_nick' */
|
||||
ci->akick[j].lastused = akick.is_nick;
|
||||
ci->akick[j].reason = akick.reason;
|
||||
strbcpy(ci->akick[j].who, "<unknown>");
|
||||
ci->akick[j].set = time(NULL);
|
||||
}
|
||||
for (j = 0; j < oldci.nakick; j++) {
|
||||
SAFE(read_string(&ci->akick[j].mask, f));
|
||||
if (ci->akick[j].lastused) { /* was `is_nick' */
|
||||
char *s = smalloc(strlen(ci->akick[j].mask)+5);
|
||||
sprintf(s, "%s!*@*", ci->akick[j].mask);
|
||||
free(ci->akick[j].mask);
|
||||
ci->akick[j].mask = s;
|
||||
}
|
||||
ci->akick[j].lastused = 0;
|
||||
if (ci->akick[j].reason) {
|
||||
SAFE(read_string(&ci->akick[j].reason, f));
|
||||
if (!ci->akick[j].mask && ci->akick[j].reason)
|
||||
ci->akick[j].reason = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
SAFE(read_int16(&tmp16, f));
|
||||
for (j = tmp16; j > 0; j--)
|
||||
SAFE(read_int16(&tmp16, f));
|
||||
|
||||
/* Remove from list if founder does not exist and channel is
|
||||
* not forbidden */
|
||||
if (!(ci->flags & CF_VERBOTEN) && !ci->founder) {
|
||||
fprintf(stderr, "Ignoring channel %s (missing founder)\n",
|
||||
ci->name);
|
||||
del_channelinfo(ci);
|
||||
}
|
||||
|
||||
} /* while more entries */
|
||||
|
||||
if (c != 0) {
|
||||
fprintf(stderr, "%s is corrupt, aborting.\n", f->filename);
|
||||
exit(1);
|
||||
}
|
||||
} /* for 33..256 */
|
||||
|
||||
close_db(f);
|
||||
}
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
static void m14_load_memo(const char *dir, int32 version)
|
||||
{
|
||||
char *s;
|
||||
dbFILE *f;
|
||||
struct memo_ {
|
||||
char sender[32];
|
||||
long number;
|
||||
time_t time;
|
||||
char *text;
|
||||
long resv[4];
|
||||
} memo;
|
||||
struct memolist_ {
|
||||
struct memolist_ *next, *prev;
|
||||
char nick[32];
|
||||
long n_memos;
|
||||
Memo *memos;
|
||||
long resv[4];
|
||||
} memolist;
|
||||
NickGroupInfo *ngi;
|
||||
Memo *m = NULL;
|
||||
long i, j, flags = 0;
|
||||
int c;
|
||||
|
||||
f = open_db_ver(dir, "memo.db", version, version, NULL);
|
||||
for (i = 33; i < 256; i++) {
|
||||
while ((c = getc_db(f)) == 1) {
|
||||
SAFE(read_variable(memolist, f));
|
||||
ngi = get_nickgroupinfo_by_nick(memolist.nick);
|
||||
if (ngi) {
|
||||
ngi->memos.memos_count = memolist.n_memos;
|
||||
m = scalloc(sizeof(*m), ngi->memos.memos_count);
|
||||
ngi->memos.memos = m;
|
||||
}
|
||||
for (j = 0; j < memolist.n_memos; j++) {
|
||||
SAFE(read_variable(memo, f));
|
||||
if (version == 6) {
|
||||
SAFE(read_variable(flags, f));
|
||||
flags = memo.resv[0] & 1;
|
||||
}
|
||||
if (ngi) {
|
||||
m[j].number = memo.number;
|
||||
if (flags & 1)
|
||||
m[j].flags |= MF_UNREAD;
|
||||
m[j].time = memo.time;
|
||||
strbcpy(m[j].sender, memo.sender);
|
||||
}
|
||||
}
|
||||
for (j = 0; j < memolist.n_memos; j++) {
|
||||
SAFE(read_string(&s, f));
|
||||
if (ngi)
|
||||
m[j].text = s;
|
||||
}
|
||||
}
|
||||
if (c != 0) {
|
||||
fprintf(stderr, "%s is corrupt, aborting.\n", f->filename);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
close_db(f);
|
||||
}
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
static void m14_load_sop(const char *dir, int32 version)
|
||||
{
|
||||
char nick[32];
|
||||
dbFILE *f;
|
||||
int16 n, i;
|
||||
|
||||
f = open_db_ver(dir, "sop.db", version, version, NULL);
|
||||
SAFE(read_int16(&n, f));
|
||||
for (i = 0; i < n; i++) {
|
||||
SAFE(read_buffer(nick, f));
|
||||
set_os_priv(nick, NP_SERVADMIN);
|
||||
}
|
||||
close_db(f);
|
||||
}
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
static void m14_load_akill(const char *dir, int32 version)
|
||||
{
|
||||
dbFILE *f;
|
||||
int16 i, n;
|
||||
MaskData *md;
|
||||
struct akill_ {
|
||||
char *mask;
|
||||
char *reason;
|
||||
char who[32];
|
||||
time_t time;
|
||||
} akill;
|
||||
|
||||
f = open_db_ver(dir, "akill.db", version, version, NULL);
|
||||
SAFE(read_int16(&n, f));
|
||||
md = scalloc(sizeof(*md), n);
|
||||
for (i = 0; i < n; i++) {
|
||||
SAFE(read_variable(akill, f));
|
||||
strbcpy(md[i].who, akill.who);
|
||||
md[i].time = akill.time;
|
||||
md[i].expires = 0;
|
||||
}
|
||||
for (i = 0; i < n; i++) {
|
||||
SAFE(read_string(&md[i].mask, f));
|
||||
SAFE(read_string(&md[i].reason, f));
|
||||
add_maskdata(MD_AKILL, &md[i]);
|
||||
}
|
||||
close_db(f);
|
||||
}
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
static void m14_load_clone(const char *dir, int32 version)
|
||||
{
|
||||
dbFILE *f;
|
||||
int16 i, n;
|
||||
MaskData *md;
|
||||
struct allow_ {
|
||||
char *host;
|
||||
int amount;
|
||||
char *reason;
|
||||
char who[32];
|
||||
time_t time;
|
||||
} allow;
|
||||
|
||||
f = open_db_ver(dir, "clone.db", version, version, NULL);
|
||||
SAFE(read_int16(&n, f));
|
||||
md = scalloc(sizeof(*md), n);
|
||||
for (i = 0; i < n; i++) {
|
||||
SAFE(read_variable(allow, f));
|
||||
strbcpy(md[i].who, allow.who);
|
||||
md[i].limit = allow.amount;
|
||||
md[i].time = allow.time;
|
||||
md[i].expires = 0;
|
||||
md[i].num = i+1;
|
||||
}
|
||||
for (i = 0; i < n; i++) {
|
||||
SAFE(read_string(&md[i].mask, f));
|
||||
SAFE(read_string(&md[i].reason, f));
|
||||
add_maskdata(MD_EXCEPTION, &md[i]);
|
||||
}
|
||||
close_db(f);
|
||||
}
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
static void m14_load_message(const char *dir, int32 version)
|
||||
{
|
||||
dbFILE *f;
|
||||
int16 i, n;
|
||||
NewsItem *news;
|
||||
struct message_ {
|
||||
char *text;
|
||||
int type;
|
||||
char who[32];
|
||||
time_t time;
|
||||
} msg;
|
||||
|
||||
f = open_db_ver(dir, "message.db", version, version, NULL);
|
||||
SAFE(read_int16(&n, f));
|
||||
news = scalloc(sizeof(*news), n);
|
||||
for (i = 0; i < n; i++) {
|
||||
SAFE(read_variable(msg, f));
|
||||
news[i].type = msg.type;
|
||||
strbcpy(news[i].who, msg.who);
|
||||
news[i].time = msg.time;
|
||||
}
|
||||
for (i = 0; i < n; i++) {
|
||||
SAFE(read_string(&news[i].text, f));
|
||||
add_news(&news[i]);
|
||||
}
|
||||
close_db(f);
|
||||
}
|
||||
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
|
||||
static const char *check_magick_14b2(const char *dir)
|
||||
{
|
||||
FILE *f;
|
||||
char buf[PATH_MAX+1];
|
||||
|
||||
snprintf(buf, sizeof(buf), "%s/message.db", dir);
|
||||
f = fopen(buf, "rb");
|
||||
if (f) {
|
||||
int ver;
|
||||
ver = fgetc(f)<<24;
|
||||
ver |= fgetc(f)<<16;
|
||||
ver |= fgetc(f)<<8;
|
||||
ver |= fgetc(f);
|
||||
fclose(f);
|
||||
if (ver == 5)
|
||||
return "Magick 1.4b2";
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void load_magick_14b2(const char *dir, int verbose, int ac,
|
||||
char **av)
|
||||
{
|
||||
if (ac > 1) {
|
||||
fprintf(stderr, "Unrecognized option %s\n", av[1]);
|
||||
usage(av[0]);
|
||||
}
|
||||
if (verbose)
|
||||
fprintf(stderr, "Loading nick.db...\n");
|
||||
m14_load_nick(dir, 5);
|
||||
if (verbose)
|
||||
fprintf(stderr, "Loading chan.db...\n");
|
||||
m14_load_chan(dir, 5);
|
||||
if (verbose)
|
||||
fprintf(stderr, "Loading memo.db...\n");
|
||||
m14_load_memo(dir, 5);
|
||||
if (verbose)
|
||||
fprintf(stderr, "Loading sop.db...\n");
|
||||
m14_load_sop(dir, 5);
|
||||
if (verbose)
|
||||
fprintf(stderr, "Loading akill.db...\n");
|
||||
m14_load_akill(dir, 5);
|
||||
if (verbose)
|
||||
fprintf(stderr, "Loading clone.db...\n");
|
||||
m14_load_clone(dir, 5);
|
||||
if (verbose)
|
||||
fprintf(stderr, "Loading message.db...\n");
|
||||
m14_load_message(dir, 5);
|
||||
}
|
||||
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
|
||||
static const char *check_wrecked_1_2(const char *dir)
|
||||
{
|
||||
FILE *f;
|
||||
char buf[PATH_MAX+1];
|
||||
|
||||
snprintf(buf, sizeof(buf), "%s/message.db", dir);
|
||||
f = fopen(buf, "rb");
|
||||
if (f) {
|
||||
int ver;
|
||||
ver = fgetc(f)<<24;
|
||||
ver |= fgetc(f)<<16;
|
||||
ver |= fgetc(f)<<8;
|
||||
ver |= fgetc(f);
|
||||
fclose(f);
|
||||
if (ver == 6)
|
||||
return "Wrecked 1.2.0";
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void load_wrecked_1_2(const char *dir, int verbose, int ac,
|
||||
char **av)
|
||||
{
|
||||
if (ac > 1) {
|
||||
fprintf(stderr, "Unrecognized option %s\n", av[1]);
|
||||
usage(av[0]);
|
||||
}
|
||||
if (verbose)
|
||||
fprintf(stderr, "Loading nick.db...\n");
|
||||
m14_load_nick(dir, 6);
|
||||
if (verbose)
|
||||
fprintf(stderr, "Loading chan.db...\n");
|
||||
m14_load_chan(dir, 6);
|
||||
if (verbose)
|
||||
fprintf(stderr, "Loading memo.db...\n");
|
||||
m14_load_memo(dir, 6);
|
||||
if (verbose)
|
||||
fprintf(stderr, "Loading sop.db...\n");
|
||||
m14_load_sop(dir, 6);
|
||||
if (verbose)
|
||||
fprintf(stderr, "Loading akill.db...\n");
|
||||
m14_load_akill(dir, 6);
|
||||
if (verbose)
|
||||
fprintf(stderr, "Loading clone.db...\n");
|
||||
m14_load_clone(dir, 6);
|
||||
if (verbose)
|
||||
fprintf(stderr, "Loading message.db...\n");
|
||||
m14_load_message(dir, 6);
|
||||
}
|
||||
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
|
||||
DBTypeInfo dbtype_magick_14b2 = {
|
||||
"magick-1.4",
|
||||
check_magick_14b2,
|
||||
load_magick_14b2
|
||||
};
|
||||
|
||||
DBTypeInfo dbtype_wrecked_1_2 = {
|
||||
"wrecked-1.2",
|
||||
check_wrecked_1_2,
|
||||
load_wrecked_1_2
|
||||
};
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* c-file-style: "stroustrup"
|
||||
* c-file-offsets: ((case-label . *) (statement-case-intro . *))
|
||||
* indent-tabs-mode: nil
|
||||
* End:
|
||||
*
|
||||
* vim: expandtab shiftwidth=4:
|
||||
*/
|
782
tools/convert-ptlink.c
Normal file
782
tools/convert-ptlink.c
Normal file
@ -0,0 +1,782 @@
|
||||
/* Conversion routines for PTlink >= 2.13.x databases.
|
||||
*
|
||||
* IRC Services is copyright (c) 1996-2009 Andrew Church.
|
||||
* E-mail: <achurch@achurch.org>
|
||||
* Parts written by Andrew Kempe and others.
|
||||
* This program is free but copyrighted software; see the file GPL.txt for
|
||||
* details.
|
||||
*/
|
||||
|
||||
#include "convert-db.h"
|
||||
|
||||
#if NICKMAX < 32
|
||||
# error NICKMAX too small (must be >=32)
|
||||
#elif CHANMAX < 64
|
||||
# error CHANMAX too small (must be >=64)
|
||||
#elif PASSMAX < 32
|
||||
# error PASSMAX too small (must be >=32)
|
||||
#endif
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
static void ptlink_load_nick(const char *dir)
|
||||
{
|
||||
char filename[PATH_MAX+1];
|
||||
dbFILE *f;
|
||||
int i, j, c, delete;
|
||||
int16 tmp16, ver;
|
||||
int32 tmp32, total, count;
|
||||
NickInfo *ni;
|
||||
NickGroupInfo *ngi;
|
||||
char *s;
|
||||
signed char ch;
|
||||
|
||||
snprintf(filename, sizeof(filename), "%s/nick.db", dir);
|
||||
if (!(f = open_db(filename, "r", 0)))
|
||||
return;
|
||||
SAFE(read_int8(&ch, f));
|
||||
SAFE(read_int16(&ver, f));
|
||||
if (ch != -1 || ver < 6 || ver > 11) {
|
||||
fprintf(stderr, "Wrong version number on %s\n", filename);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
SAFE(read_int32(&total, f));
|
||||
count = 0;
|
||||
#if CLEAN_COMPILE
|
||||
c = 0;
|
||||
#endif
|
||||
for (i = 0; i < 256; i++) {
|
||||
while (ver >= 10 || (c = getc_db(f)) == 1) {
|
||||
char nickbuf[32], passbuf[32], authbuf[16];
|
||||
if (ver >= 9) {
|
||||
int res = read_int32(&tmp32, f); /* SUID (broken) / SNID */
|
||||
if (res < 0) {
|
||||
if (ver >= 10) /* v10: no more int8 markers */
|
||||
break;
|
||||
else
|
||||
SAFE(res);
|
||||
}
|
||||
}
|
||||
SAFE(read_buffer(nickbuf, f));
|
||||
/* The source (v2.26-eol.1) claims that duplicate nicknames can
|
||||
* get stored in the database for unknown reasons, so watch for
|
||||
* and delete them as needed */
|
||||
delete = (get_nickinfo(nickbuf) != NULL);
|
||||
ni = makenick(nickbuf, &ngi);
|
||||
/* Use the SNID (file version 11) as a nickname group ID only
|
||||
* if it's nonzero and unique. Never use the SUID (versions 9
|
||||
* and 10) as the source code claims that it's broken. */
|
||||
if (ver >= 11 && tmp32 && !get_nickgroupinfo(tmp32))
|
||||
ni->nickgroup = ngi->id = (uint32)tmp32;
|
||||
SAFE(read_buffer(passbuf, f));
|
||||
init_password(&ngi->pass);
|
||||
memcpy(ngi->pass.password, passbuf, sizeof(passbuf));
|
||||
if (ver >= 7)
|
||||
SAFE(read_buffer(authbuf, f));
|
||||
SAFE(read_string(&ngi->url, f));
|
||||
if (ver >= 7)
|
||||
SAFE(read_string(&s, f)); /* temporary, unauthed E-mail */
|
||||
else
|
||||
s = NULL;
|
||||
SAFE(read_string(&ngi->email, f));
|
||||
if (s) {
|
||||
ngi->last_email = ngi->email;
|
||||
ngi->email = s;
|
||||
}
|
||||
SAFE(read_string(&s, f)); /* icq_number */
|
||||
SAFE(read_string(&s, f)); /* location */
|
||||
SAFE(read_string(&ni->last_usermask, f));
|
||||
if (!ni->last_usermask)
|
||||
ni->last_usermask = (char *)"@";
|
||||
SAFE(read_string(&ni->last_realname, f));
|
||||
if (!ni->last_realname)
|
||||
ni->last_realname = (char *)"";
|
||||
SAFE(read_string(&ni->last_quit, f));
|
||||
SAFE(read_int32(&tmp32, f));
|
||||
ni->time_registered = tmp32;
|
||||
SAFE(read_int32(&tmp32, f)); /* last_identify */
|
||||
SAFE(read_int32(&tmp32, f));
|
||||
ni->last_seen = tmp32;
|
||||
if (ver >= 7)
|
||||
SAFE(read_int32(&tmp32, f)); /* last_email_request */
|
||||
SAFE(read_int32(&tmp32, f)); /* birth_date */
|
||||
SAFE(read_int16(&tmp16, f)); /* status */
|
||||
if (tmp16 & 0x0002) {
|
||||
ni->status |= NS_VERBOTEN;
|
||||
del_nickgroupinfo(ngi);
|
||||
ni->nickgroup = 0;
|
||||
}
|
||||
if (tmp16 & 0x0004)
|
||||
ni->status |= NS_NOEXPIRE;
|
||||
SAFE(read_int16(&tmp16, f)); /* crypt_method */
|
||||
switch (tmp16) {
|
||||
case 0: break;
|
||||
case 2: ngi->pass.cipher = sstrdup("unix-crypt"); break;
|
||||
case 3: ngi->pass.cipher = sstrdup("md5"); break;
|
||||
case 1:
|
||||
fprintf(stderr, "%s: `%s' password encrypted with"
|
||||
" unsupported method JP2, resetting password"
|
||||
" to nickname", filename, nickbuf);
|
||||
/* fall through */
|
||||
default:
|
||||
if (tmp16 != 1) {
|
||||
fprintf(stderr, "%s: `%s' password encrypted with"
|
||||
" unsupported method %d, resetting password"
|
||||
" to nickname", filename, nickbuf, tmp16);
|
||||
}
|
||||
strbcpy(ngi->pass.password, nickbuf);
|
||||
break;
|
||||
}
|
||||
SAFE(read_int32(&tmp32, f)); /* news_mask */
|
||||
SAFE(read_int16(&tmp16, f)); /* news_status */
|
||||
SAFE(read_string(&ni->last_realmask, f)); /* link */
|
||||
SAFE(read_int16(&tmp16, f)); /* linkcount */
|
||||
if (ni->last_realmask) {
|
||||
ni->nickgroup = 0;
|
||||
SAFE(read_int16(&tmp16, f)); /* channelcount */
|
||||
} else {
|
||||
SAFE(read_int32(&tmp32, f)); /* flags */
|
||||
if (tmp32 & 0x00000001)
|
||||
ngi->flags |= NF_KILLPROTECT;
|
||||
if (tmp32 & 0x00004002)
|
||||
ngi->flags |= 0x80000000; /* suspended */
|
||||
if (tmp32 & 0x00000008)
|
||||
ngi->flags |= NF_MEMO_HARDMAX;
|
||||
if (tmp32 & 0x00000010)
|
||||
ngi->flags |= NF_MEMO_SIGNON;
|
||||
if (tmp32 & 0x00000020)
|
||||
ngi->flags |= NF_MEMO_RECEIVE;
|
||||
if (tmp32 & 0x00000040)
|
||||
ngi->flags |= NF_PRIVATE;
|
||||
if (tmp32 & 0x00000080)
|
||||
ngi->flags |= NF_HIDE_EMAIL;
|
||||
if (tmp32 & 0x00000100)
|
||||
ngi->flags |= NF_HIDE_MASK;
|
||||
if (tmp32 & 0x00000200)
|
||||
ngi->flags |= NF_HIDE_QUIT;
|
||||
if (tmp32 & 0x00000400)
|
||||
ngi->flags |= NF_KILL_QUICK;
|
||||
if (tmp32 & 0x00000800)
|
||||
ngi->flags |= NF_KILL_IMMED;
|
||||
SAFE(read_int32(&tmp32, f)); /* online */
|
||||
if (ngi->flags & 0x80000000) {
|
||||
ngi->flags &= ~0x80000000;
|
||||
SAFE(read_int32(&tmp32, f)); /* expires */
|
||||
strbcpy(ngi->suspend_who, "<unknown>");
|
||||
ngi->suspend_reason =
|
||||
(char *)"Unknown (imported from PTlink IRC Services)";
|
||||
ngi->suspend_time = time(NULL);
|
||||
ngi->suspend_expires = tmp32;
|
||||
ngi->flags |= NF_SUSPENDED;
|
||||
}
|
||||
SAFE(read_int16(&ngi->ajoin_count, f));
|
||||
ngi->ajoin = scalloc(sizeof(char *), ngi->ajoin_count);
|
||||
for (j = 0; j < ngi->ajoin_count; j++)
|
||||
SAFE(read_string(&ngi->ajoin[j], f));
|
||||
SAFE(read_int16(&ngi->memos.memos_count, f));
|
||||
SAFE(read_int16(&ngi->memos.memomax, f));
|
||||
if (ngi->memos.memos_count) {
|
||||
Memo *memos;
|
||||
memos = scalloc(sizeof(*memos), ngi->memos.memos_count);
|
||||
ngi->memos.memos = memos;
|
||||
for (j = 0; j < ngi->memos.memos_count; j++, memos++) {
|
||||
SAFE(read_uint32(&memos->number, f));
|
||||
SAFE(read_int16(&tmp16, f));
|
||||
if (tmp16 & 1)
|
||||
memos->flags |= MF_UNREAD;
|
||||
SAFE(read_int32(&tmp32, f));
|
||||
memos->time = tmp32;
|
||||
SAFE(read_buffer(nickbuf, f));
|
||||
strbcpy(memos->sender, nickbuf);
|
||||
SAFE(read_string(&memos->text, f));
|
||||
}
|
||||
}
|
||||
SAFE(read_int16(&tmp16, f)); /* notes.count */
|
||||
j = tmp16;
|
||||
SAFE(read_int16(&tmp16, f)); /* notes.max */
|
||||
while (j--) /* notes.note[] */
|
||||
SAFE(read_string(&s, f));
|
||||
SAFE(read_int16(&tmp16, f)); /* channelcount */
|
||||
SAFE(read_int16(&tmp16, f)); /* channelmax */
|
||||
SAFE(read_int16(&tmp16, f));
|
||||
switch (tmp16) {
|
||||
case 0: ngi->language = LANG_EN_US; break;
|
||||
case 1: ngi->language = LANG_PT; break;
|
||||
case 2: ngi->language = LANG_TR; break;
|
||||
case 3: ngi->language = LANG_DE; break;
|
||||
case 4: ngi->language = LANG_IT; break;
|
||||
}
|
||||
}
|
||||
if (delete) {
|
||||
del_nickgroupinfo(ngi);
|
||||
del_nickinfo(ni);
|
||||
}
|
||||
count++;
|
||||
} /* while (getc_db(f) == 1) */
|
||||
if (ver < 10 && c != 0) {
|
||||
fprintf(stderr, "%s is corrupt, aborting.\n", f->filename);
|
||||
exit(1);
|
||||
}
|
||||
} /* for (i) */
|
||||
close_db(f);
|
||||
if (count != total) {
|
||||
fprintf(stderr, "%s: warning: expected %d nicks, got %d\n",
|
||||
filename, total, count);
|
||||
fprintf(stderr, " This means that your data files may be corrupt."
|
||||
" It may also be the\n"
|
||||
" result of a bug in some versions of PTlink Services.\n");
|
||||
}
|
||||
|
||||
/* Resolve links */
|
||||
for (ni = first_nickinfo(); ni; ni = next_nickinfo()) {
|
||||
NickInfo *ni2;
|
||||
const char *last_nick;
|
||||
if (ni->last_realmask) {
|
||||
ni2 = ni;
|
||||
/* Find root nick (this will actually stop at the first nick
|
||||
* in the path to the root that isn't marked as linked, but
|
||||
* that's okay because such a nick will already have its
|
||||
* nickgroup ID set correctly) */
|
||||
do {
|
||||
last_nick = ni2->last_realmask;
|
||||
ni2 = get_nickinfo(last_nick);
|
||||
} while (ni2 && ni2 != ni && ni2->last_realmask);
|
||||
ni->last_realmask = NULL;
|
||||
/* Set nickgroup, or delete nick if an error occurred */
|
||||
if (ni2 == ni) {
|
||||
fprintf(stderr,
|
||||
"Warning: dropping nick %s with circular link\n",
|
||||
ni->nick);
|
||||
del_nickinfo(ni);
|
||||
} else if (!ni2) {
|
||||
fprintf(stderr, "Warning: dropping nick %s linked to"
|
||||
" nonexistent nick %s\n", ni->nick, last_nick);
|
||||
del_nickinfo(ni);
|
||||
} else {
|
||||
ngi = get_nickgroupinfo(ni->nickgroup);
|
||||
if (ngi)
|
||||
del_nickgroupinfo(ngi);
|
||||
ni->nickgroup = ni2->nickgroup;
|
||||
ngi = get_nickgroupinfo(ni->nickgroup);
|
||||
if (ngi) {
|
||||
ARRAY_EXTEND(ngi->nicks);
|
||||
strbcpy(ngi->nicks[ngi->nicks_count-1], ni->nick);
|
||||
} else if (ni->nickgroup != 0) {
|
||||
fprintf(stderr, "Warning: Nick group %d for nick %s not"
|
||||
" found -- program bug? Output may be corrupt.",
|
||||
ni->nickgroup, ni->nick);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
static struct {
|
||||
int32 flag;
|
||||
char mode;
|
||||
} ptlink_cmodes[] = {
|
||||
{ 0x00000001, 'i' },
|
||||
{ 0x00000002, 'm' },
|
||||
{ 0x00000004, 'n' },
|
||||
{ 0x00000008, 'p' },
|
||||
{ 0x00000010, 's' },
|
||||
{ 0x00000020, 't' },
|
||||
{ 0x00000040, 'k' },
|
||||
{ 0x00000080, 'l' },
|
||||
{ 0x00000200, 'R' },
|
||||
{ 0x00000400, 'c' },
|
||||
{ 0x00001000, 'O' },
|
||||
{ 0x00002000, 'A' },
|
||||
{ 0x00008000, 0 }, /* Like Unreal 'f': no dup lines within 10 secs */
|
||||
{ 0, 0 }
|
||||
};
|
||||
|
||||
static void ptlink_load_chan(const char *dir)
|
||||
{
|
||||
char filename[PATH_MAX+1];
|
||||
dbFILE *f;
|
||||
int i, j, c, C_MAX;
|
||||
ChannelInfo *ci;
|
||||
NickInfo *ni;
|
||||
signed char ch;
|
||||
int16 tmp16, ver;
|
||||
int32 tmp32, total, count, mlock_on, mlock_off;
|
||||
char *on, *off;
|
||||
MemoInfo tmpmi;
|
||||
|
||||
snprintf(filename, sizeof(filename), "%s/chan.db", dir);
|
||||
if (!(f = open_db(filename, "r", 0)))
|
||||
return;
|
||||
SAFE(read_int8(&ch, f));
|
||||
SAFE(read_int16(&ver, f));
|
||||
if (ch != -1 || ver < 7 || ver > 10) {
|
||||
fprintf(stderr, "Wrong version number on %s\n", filename);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (ver >= 9)
|
||||
SAFE(read_int32(&total, f));
|
||||
count = 0;
|
||||
|
||||
C_MAX = (ver<9 ? 256 : 65535);
|
||||
for (i = 0; i < C_MAX; i++) {
|
||||
char *s;
|
||||
|
||||
while ((c = getc_db(f)) == 1) {
|
||||
char namebuf[64], passbuf[32], nickbuf[32];
|
||||
if (ver >= 10)
|
||||
SAFE(read_int32(&tmp32, f)); /* SCID */
|
||||
SAFE(read_buffer(namebuf, f));
|
||||
ci = makechan(namebuf);
|
||||
SAFE(read_string(&s, f));
|
||||
if (s) {
|
||||
ni = get_nickinfo(s);
|
||||
if (!ni) {
|
||||
fprintf(stderr,
|
||||
"Warning: Founder %s for channel %s not found\n",
|
||||
s, ci->name);
|
||||
} else if (!ni->nickgroup) {
|
||||
fprintf(stderr, "Warning: Founder %s for channel %s is a"
|
||||
" forbidden nick\n", s, ci->name);
|
||||
} else {
|
||||
ci->founder = ni->nickgroup;
|
||||
}
|
||||
}
|
||||
SAFE(read_string(&s, f));
|
||||
if (s) {
|
||||
ni = get_nickinfo(s);
|
||||
if (!ni) {
|
||||
fprintf(stderr, "Warning: Successor %s for channel %s"
|
||||
" not found\n", s, ci->name);
|
||||
} else if (!ni->nickgroup) {
|
||||
fprintf(stderr, "Warning: Successor %s for channel %s"
|
||||
" is a forbidden nick\n", s, ci->name);
|
||||
} else if (ni->nickgroup == ci->founder) {
|
||||
fprintf(stderr, "Warning: Successor %s for channel %s"
|
||||
" is the same as the founder, clearing\n",
|
||||
s, ci->name);
|
||||
} else {
|
||||
ci->successor = ni->nickgroup;
|
||||
}
|
||||
}
|
||||
SAFE(read_int16(&tmp16, f)); /* maxusers */
|
||||
SAFE(read_int32(&tmp32, f)); /* maxtime */
|
||||
SAFE(read_buffer(passbuf, f));
|
||||
init_password(&ci->founderpass);
|
||||
memcpy(ci->founderpass.password, passbuf, sizeof(passbuf));
|
||||
SAFE(read_string(&ci->desc, f));
|
||||
if (!ci->desc)
|
||||
ci->desc = (char *)"";
|
||||
SAFE(read_string(&ci->url, f));
|
||||
SAFE(read_string(&ci->email, f));
|
||||
SAFE(read_int32(&tmp32, f));
|
||||
ci->time_registered = tmp32;
|
||||
SAFE(read_int32(&tmp32, f));
|
||||
ci->last_used = tmp32;
|
||||
SAFE(read_string(&ci->last_topic, f));
|
||||
SAFE(read_buffer(nickbuf, f));
|
||||
strbcpy(ci->last_topic_setter, nickbuf);
|
||||
SAFE(read_int32(&tmp32, f));
|
||||
ci->last_topic_time = tmp32;
|
||||
SAFE(read_int32(&tmp32, f)); /* flags */
|
||||
if (tmp32 & 0x00000001)
|
||||
ci->flags |= CF_KEEPTOPIC;
|
||||
if (tmp32 & 0x00000002)
|
||||
ci->flags |= CF_SECUREOPS;
|
||||
if (tmp32 & 0x00000004)
|
||||
ci->flags |= CF_PRIVATE;
|
||||
if (tmp32 & 0x00000008)
|
||||
ci->flags |= CF_TOPICLOCK;
|
||||
if (tmp32 & 0x00000010)
|
||||
ci->flags |= CF_RESTRICTED;
|
||||
if (tmp32 & 0x00000020)
|
||||
ci->flags |= CF_LEAVEOPS;
|
||||
if (tmp32 & 0x00000080)
|
||||
ci->flags |= CF_VERBOTEN;
|
||||
if (tmp32 & 0x00000200)
|
||||
ci->flags |= CF_NOEXPIRE;
|
||||
if (tmp32 & 0x00000800)
|
||||
ci->flags |= CF_OPNOTICE;
|
||||
SAFE(read_int16(&tmp16, f)); /* crypt_method */
|
||||
switch (tmp16) {
|
||||
case 0: break;
|
||||
case 2: ci->founderpass.cipher = sstrdup("unix-crypt"); break;
|
||||
case 3: ci->founderpass.cipher = sstrdup("md5"); break;
|
||||
case 1:
|
||||
fprintf(stderr, "%s: `%s' password encrypted with"
|
||||
" unsupported method JP2, resetting password"
|
||||
" to channel name", filename, namebuf);
|
||||
/* fall through */
|
||||
default:
|
||||
if (tmp16 != 1) {
|
||||
fprintf(stderr, "%s: `%s' password encrypted with"
|
||||
" unsupported method %d, resetting password"
|
||||
" to channel name", filename, namebuf, tmp16);
|
||||
}
|
||||
strbcpy(ci->founderpass.password, namebuf);
|
||||
break;
|
||||
}
|
||||
if (tmp32 & 0x1000)
|
||||
SAFE(read_int32(&tmp32, f)); /* drop_time */
|
||||
|
||||
SAFE(read_int16(&tmp16, f)); /* levels[] */
|
||||
for (j = tmp16; j > 0; j--)
|
||||
SAFE(read_int16(&tmp16, f));
|
||||
|
||||
SAFE(read_int16(&ci->access_count, f));
|
||||
if (ci->access_count) {
|
||||
ci->access = scalloc(ci->access_count, sizeof(ChanAccess));
|
||||
for (j = 0; j < ci->access_count; j++) {
|
||||
SAFE(read_int16(&tmp16, f)); /* in_use */
|
||||
if (tmp16) {
|
||||
SAFE(read_int16(&ci->access[j].level, f));
|
||||
SAFE(read_string(&s, f));
|
||||
ci->access[j].level =
|
||||
convert_acclev(ci->access[j].level);
|
||||
if (s) {
|
||||
ni = get_nickinfo(s);
|
||||
if (ni)
|
||||
ci->access[j].nickgroup = ni->nickgroup;
|
||||
}
|
||||
SAFE(read_string(&s, f)); /* who */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SAFE(read_int16(&ci->akick_count, f));
|
||||
if (ci->akick_count) {
|
||||
ci->akick = scalloc(ci->akick_count, sizeof(AutoKick));
|
||||
for (j = 0; j < ci->akick_count; j++) {
|
||||
SAFE(read_int16(&tmp16, f)); /* in_use */
|
||||
if (tmp16) {
|
||||
SAFE(read_string(&ci->akick[j].mask, f));
|
||||
SAFE(read_string(&ci->akick[j].reason, f));
|
||||
SAFE(read_string(&s, f)); /* who */
|
||||
strbcpy(ci->akick[j].who, s);
|
||||
ci->akick[j].set = time(NULL);
|
||||
SAFE(read_int32(&tmp32, f)); /* last_kick */
|
||||
ci->akick[j].lastused = tmp32;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (ver < 8) {
|
||||
SAFE(read_int16(&tmp16, f));
|
||||
mlock_on = (int32)tmp16 & 0xFFFF;
|
||||
SAFE(read_int16(&tmp16, f));
|
||||
mlock_off = (int32)tmp16 & 0xFFFF;
|
||||
} else {
|
||||
SAFE(read_int32(&mlock_on, f));
|
||||
SAFE(read_int32(&mlock_off, f));
|
||||
}
|
||||
ci->mlock.on = on = scalloc(64, 1);
|
||||
ci->mlock.off = off = scalloc(64, 1);
|
||||
for (j = 0; ptlink_cmodes[j].flag != 0; j++) {
|
||||
if (mlock_on & ptlink_cmodes[j].flag)
|
||||
*on++ = ptlink_cmodes[j].mode;
|
||||
if (mlock_off & ptlink_cmodes[j].flag)
|
||||
*off++ = ptlink_cmodes[j].mode;
|
||||
}
|
||||
*on = 0;
|
||||
*off = 0;
|
||||
SAFE(read_int32(&ci->mlock.limit, f));
|
||||
SAFE(read_string(&ci->mlock.key, f));
|
||||
|
||||
SAFE(read_int16(&tmpmi.memos_count, f));
|
||||
SAFE(read_int16(&tmp16, f)); /* memomax */
|
||||
if (tmpmi.memos_count) {
|
||||
Memo *memos;
|
||||
memos = scalloc(sizeof(Memo), tmpmi.memos_count);
|
||||
tmpmi.memos = memos;
|
||||
for (j = 0; j < tmpmi.memos_count; j++, memos++) {
|
||||
SAFE(read_uint32(&memos->number, f));
|
||||
SAFE(read_int16(&tmp16, f));
|
||||
if (tmp16 & 1)
|
||||
memos->flags |= MF_UNREAD;
|
||||
SAFE(read_int32(&tmp32, f));
|
||||
memos->time = tmp32;
|
||||
SAFE(read_buffer(nickbuf, f));
|
||||
strbcpy(memos->sender, nickbuf);
|
||||
SAFE(read_string(&memos->text, f));
|
||||
}
|
||||
}
|
||||
|
||||
SAFE(read_string(&ci->entry_message, f));
|
||||
|
||||
if (!(ci->flags & CF_VERBOTEN) && !ci->founder) {
|
||||
fprintf(stderr, "Ignoring channel %s (missing founder)\n",
|
||||
ci->name);
|
||||
del_channelinfo(ci);
|
||||
}
|
||||
|
||||
count++;
|
||||
|
||||
} /* while (getc_db(f) == 1) */
|
||||
|
||||
if (c != 0) {
|
||||
fprintf(stderr, "%s is corrupt, aborting.\n", f->filename);
|
||||
exit(1);
|
||||
}
|
||||
} /* for (i) */
|
||||
close_db(f);
|
||||
|
||||
if (ver >= 9 && count != total) {
|
||||
fprintf(stderr, "%s: warning: expected %d channels, got %d\n",
|
||||
filename, total, count);
|
||||
fprintf(stderr, " This means that your data files may be corrupt."
|
||||
" It may also be the\n"
|
||||
" result of a bug in some versions of PTlink Services.\n");
|
||||
}
|
||||
}
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
static void ptlink_load_oper(const char *dir)
|
||||
{
|
||||
char filename[PATH_MAX+1];
|
||||
dbFILE *f;
|
||||
int16 i, n, tmp16;
|
||||
int32 tmp32;
|
||||
char *s;
|
||||
signed char ch;
|
||||
|
||||
snprintf(filename, sizeof(filename), "%s/oper.db", dir);
|
||||
if (!(f = open_db(filename, "r", 0)))
|
||||
return;
|
||||
SAFE(read_int8(&ch, f));
|
||||
SAFE(read_int16(&tmp16, f));
|
||||
if (ch != -1 || tmp16 < 1 || tmp16 > 2) {
|
||||
fprintf(stderr, "Wrong version number on %s\n", filename);
|
||||
exit(1);
|
||||
}
|
||||
SAFE(read_int16(&n, f));
|
||||
for (i = 0; i < n; i++) {
|
||||
SAFE(read_string(&s, f));
|
||||
set_os_priv(s, NP_SERVADMIN);
|
||||
}
|
||||
SAFE(read_int16(&n, f));
|
||||
for (i = 0; i < n; i++) {
|
||||
SAFE(read_string(&s, f));
|
||||
set_os_priv(s, NP_SERVOPER);
|
||||
}
|
||||
SAFE(read_int32(&maxusercnt, f));
|
||||
SAFE(read_int32(&tmp32, f));
|
||||
maxusertime = tmp32;
|
||||
close_db(f);
|
||||
}
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
static void ptlink_load_akill(const char *dir)
|
||||
{
|
||||
char filename[PATH_MAX+1];
|
||||
dbFILE *f;
|
||||
int16 tmp16, i, n;
|
||||
int32 tmp32;
|
||||
signed char ch;
|
||||
MaskData *md;
|
||||
|
||||
snprintf(filename, sizeof(filename), "%s/akill.db", dir);
|
||||
if (!(f = open_db(filename, "r", 0)))
|
||||
return;
|
||||
SAFE(read_int8(&ch, f));
|
||||
SAFE(read_int16(&tmp16, f));
|
||||
if (ch != -1 || tmp16 != 1) {
|
||||
fprintf(stderr, "Wrong version number on %s\n", filename);
|
||||
exit(1);
|
||||
}
|
||||
SAFE(read_int16(&n, f));
|
||||
md = scalloc(sizeof(*md), n);
|
||||
for (i = 0; i < n; i++) {
|
||||
char nickbuf[32];
|
||||
SAFE(read_string(&md[i].mask, f));
|
||||
SAFE(read_string(&md[i].reason, f));
|
||||
SAFE(read_buffer(nickbuf, f));
|
||||
strbcpy(md[i].who, nickbuf);
|
||||
SAFE(read_int32(&tmp32, f));
|
||||
md[i].time = tmp32;
|
||||
SAFE(read_int32(&tmp32, f));
|
||||
md[i].expires = tmp32;
|
||||
if (md[i].mask)
|
||||
add_maskdata(MD_AKILL, &md[i]);
|
||||
}
|
||||
close_db(f);
|
||||
}
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
static void ptlink_load_sqline(const char *dir)
|
||||
{
|
||||
char filename[PATH_MAX+1];
|
||||
dbFILE *f;
|
||||
int16 tmp16, i, n;
|
||||
int32 tmp32;
|
||||
signed char ch;
|
||||
MaskData *md;
|
||||
|
||||
snprintf(filename, sizeof(filename), "%s/sqline.db", dir);
|
||||
if (!(f = open_db(filename, "r", 0)))
|
||||
return;
|
||||
SAFE(read_int8(&ch, f));
|
||||
SAFE(read_int16(&tmp16, f));
|
||||
if (ch != -1 || tmp16 != 1) {
|
||||
fprintf(stderr, "Wrong version number on %s\n", filename);
|
||||
exit(1);
|
||||
}
|
||||
SAFE(read_int16(&n, f));
|
||||
md = scalloc(sizeof(*md), n);
|
||||
for (i = 0; i < n; i++) {
|
||||
char nickbuf[32];
|
||||
SAFE(read_string(&md[i].mask, f));
|
||||
SAFE(read_string(&md[i].reason, f));
|
||||
SAFE(read_buffer(nickbuf, f));
|
||||
strbcpy(md[i].who, nickbuf);
|
||||
SAFE(read_int32(&tmp32, f));
|
||||
md[i].time = tmp32;
|
||||
SAFE(read_int32(&tmp32, f));
|
||||
md[i].expires = tmp32;
|
||||
if (md[i].mask)
|
||||
add_maskdata(MD_SQLINE, &md[i]);
|
||||
}
|
||||
close_db(f);
|
||||
}
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
static void ptlink_load_sxline(const char *dir)
|
||||
{
|
||||
char filename[PATH_MAX+1];
|
||||
dbFILE *f;
|
||||
int16 tmp16, i, n;
|
||||
int32 tmp32;
|
||||
signed char ch;
|
||||
MaskData *md;
|
||||
|
||||
snprintf(filename, sizeof(filename), "%s/sxline.db", dir);
|
||||
if (!(f = open_db(filename, "r", 0)))
|
||||
return;
|
||||
SAFE(read_int8(&ch, f));
|
||||
SAFE(read_int16(&tmp16, f));
|
||||
if (ch != -1 || tmp16 != 1) {
|
||||
fprintf(stderr, "Wrong version number on %s\n", filename);
|
||||
exit(1);
|
||||
}
|
||||
SAFE(read_int16(&n, f));
|
||||
md = scalloc(sizeof(*md), n);
|
||||
for (i = 0; i < n; i++) {
|
||||
char nickbuf[32];
|
||||
SAFE(read_string(&md[i].mask, f));
|
||||
SAFE(read_string(&md[i].reason, f));
|
||||
SAFE(read_buffer(nickbuf, f));
|
||||
strbcpy(md[i].who, nickbuf);
|
||||
SAFE(read_int32(&tmp32, f));
|
||||
md[i].time = tmp32;
|
||||
SAFE(read_int32(&tmp32, f));
|
||||
md[i].expires = tmp32;
|
||||
if (md[i].mask)
|
||||
add_maskdata(MD_SGLINE, &md[i]);
|
||||
}
|
||||
close_db(f);
|
||||
}
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
static void ptlink_load_news(const char *dir)
|
||||
{
|
||||
char filename[PATH_MAX+1];
|
||||
dbFILE *f;
|
||||
int16 tmp16, i, n;
|
||||
int32 tmp32;
|
||||
signed char ch;
|
||||
NewsItem *news;
|
||||
|
||||
snprintf(filename, sizeof(filename), "%s/news.db", dir);
|
||||
if (!(f = open_db(filename, "r", 0)))
|
||||
return;
|
||||
SAFE(read_int8(&ch, f));
|
||||
SAFE(read_int16(&tmp16, f));
|
||||
if (ch != -1 || tmp16 != 1) {
|
||||
fprintf(stderr, "Wrong version number on %s\n", filename);
|
||||
exit(1);
|
||||
}
|
||||
SAFE(read_int16(&n, f));
|
||||
news = scalloc(sizeof(*news), n);
|
||||
for (i = 0; i < n; i++) {
|
||||
char nickbuf[32];
|
||||
SAFE(read_int16(&news[i].type, f));
|
||||
SAFE(read_int32(&news[i].num, f));
|
||||
SAFE(read_string(&news[i].text, f));
|
||||
SAFE(read_buffer(nickbuf, f));
|
||||
strbcpy(news[i].who, nickbuf);
|
||||
SAFE(read_int32(&tmp32, f));
|
||||
news[i].time = tmp32;
|
||||
add_news(&news[i]);
|
||||
}
|
||||
close_db(f);
|
||||
}
|
||||
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
|
||||
static const char *check_ptlink(const char *dir)
|
||||
{
|
||||
char buf[PATH_MAX+1];
|
||||
|
||||
snprintf(buf, sizeof(buf), "%s/vline.db", dir);
|
||||
if (access(buf, R_OK) == 0)
|
||||
return "PTlink";
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void load_ptlink(const char *dir, int verbose, int ac, char **av)
|
||||
{
|
||||
if (ac > 1) {
|
||||
fprintf(stderr, "Unrecognized option %s\n", av[1]);
|
||||
usage(av[0]);
|
||||
}
|
||||
if (verbose)
|
||||
fprintf(stderr, "Loading nick.db...\n");
|
||||
ptlink_load_nick(dir);
|
||||
if (verbose)
|
||||
fprintf(stderr, "Loading chan.db...\n");
|
||||
ptlink_load_chan(dir);
|
||||
if (verbose)
|
||||
fprintf(stderr, "Loading oper.db...\n");
|
||||
ptlink_load_oper(dir);
|
||||
if (verbose)
|
||||
fprintf(stderr, "Loading akill.db...\n");
|
||||
ptlink_load_akill(dir);
|
||||
if (verbose)
|
||||
fprintf(stderr, "Loading sqline.db...\n");
|
||||
ptlink_load_sqline(dir);
|
||||
if (verbose)
|
||||
fprintf(stderr, "Loading sxline.db...\n");
|
||||
ptlink_load_sxline(dir);
|
||||
if (verbose)
|
||||
fprintf(stderr, "Loading news.db...\n");
|
||||
ptlink_load_news(dir);
|
||||
}
|
||||
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
|
||||
DBTypeInfo dbtype_ptlink = {
|
||||
"ptlink",
|
||||
check_ptlink,
|
||||
load_ptlink
|
||||
};
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* c-file-style: "stroustrup"
|
||||
* c-file-offsets: ((case-label . *) (statement-case-intro . *))
|
||||
* indent-tabs-mode: nil
|
||||
* End:
|
||||
*
|
||||
* vim: expandtab shiftwidth=4:
|
||||
*/
|
1230
tools/convert-sirv.c
Normal file
1230
tools/convert-sirv.c
Normal file
File diff suppressed because it is too large
Load Diff
836
tools/convert-trircd.c
Normal file
836
tools/convert-trircd.c
Normal file
@ -0,0 +1,836 @@
|
||||
/* Conversion routines for trircd Services program (version 4.26).
|
||||
*
|
||||
* IRC Services is copyright (c) 1996-2009 Andrew Church.
|
||||
* E-mail: <achurch@achurch.org>
|
||||
* Parts written by Andrew Kempe and others.
|
||||
* This program is free but copyrighted software; see the file GPL.txt for
|
||||
* details.
|
||||
*/
|
||||
|
||||
#include "convert-db.h"
|
||||
|
||||
#if NICKMAX < 32
|
||||
# error NICKMAX too small (must be >=32)
|
||||
#elif CHANMAX < 64
|
||||
# error CHANMAX too small (must be >=64)
|
||||
#elif PASSMAX < 32
|
||||
# error PASSMAX too small (must be >=32)
|
||||
#endif
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
static void trircd_load_nick(const char *dir)
|
||||
{
|
||||
dbFILE *f;
|
||||
int i, j, c;
|
||||
int16 tmp16;
|
||||
int32 tmp32;
|
||||
NickInfo *ni;
|
||||
NickGroupInfo *ngi;
|
||||
|
||||
f = open_db_ver(dir, "nick.db", 22, 25, NULL);
|
||||
for (i = 0; i < 256; i++) {
|
||||
while ((c = getc_db(f)) == 1) {
|
||||
char nickbuf[32], passbuf[32];
|
||||
SAFE(read_buffer(nickbuf, f));
|
||||
ni = makenick(nickbuf, &ngi);
|
||||
SAFE(read_buffer(passbuf, f));
|
||||
init_password(&ngi->pass);
|
||||
memcpy(ngi->pass.password, passbuf, sizeof(passbuf));
|
||||
SAFE(read_string(&ngi->url, f));
|
||||
SAFE(read_string(&ngi->email, f));
|
||||
SAFE(read_string(&ni->last_usermask, f));
|
||||
if (!ni->last_usermask)
|
||||
ni->last_usermask = (char *)"@";
|
||||
SAFE(read_string(&ni->last_realname, f));
|
||||
if (!ni->last_realname)
|
||||
ni->last_realname = (char *)"";
|
||||
SAFE(read_string(&ni->last_quit, f));
|
||||
SAFE(read_int32(&tmp32, f));
|
||||
ni->time_registered = tmp32;
|
||||
SAFE(read_int32(&tmp32, f));
|
||||
ni->last_seen = tmp32;
|
||||
SAFE(read_int16(&tmp16, f)); /* status */
|
||||
if (tmp16 & 0x0001)
|
||||
ngi->pass.cipher = sstrdup("md5");
|
||||
if (tmp16 & 0x0002) {
|
||||
ni->status |= NS_VERBOTEN;
|
||||
del_nickgroupinfo(ngi);
|
||||
ni->nickgroup = 0;
|
||||
}
|
||||
if (tmp16 & 0x0004)
|
||||
ni->status |= NS_NOEXPIRE;
|
||||
SAFE(read_string(&ni->last_realmask, f)); /* link */
|
||||
SAFE(read_int16(&tmp16, f)); /* linkcount */
|
||||
if (ni->last_realmask) {
|
||||
ni->nickgroup = 0;
|
||||
SAFE(read_int16(&tmp16, f)); /* channelcount */
|
||||
} else {
|
||||
void *tmpptr;
|
||||
SAFE(read_int32(&tmp32, f)); /* flags */
|
||||
if (tmp32 & 0x00000001)
|
||||
ngi->flags |= NF_KILLPROTECT;
|
||||
if (tmp32 & 0x00000002)
|
||||
ngi->flags |= NF_SECURE;
|
||||
if (tmp32 & 0x00000008)
|
||||
ngi->flags |= NF_MEMO_HARDMAX;
|
||||
if (tmp32 & 0x00000010)
|
||||
ngi->flags |= NF_MEMO_SIGNON;
|
||||
if (tmp32 & 0x00000020)
|
||||
ngi->flags |= NF_MEMO_RECEIVE;
|
||||
if (tmp32 & 0x00000040)
|
||||
ngi->flags |= NF_PRIVATE;
|
||||
if (tmp32 & 0x00000080)
|
||||
ngi->flags |= NF_HIDE_EMAIL;
|
||||
if (tmp32 & 0x00000100)
|
||||
ngi->flags |= NF_HIDE_MASK;
|
||||
if (tmp32 & 0x00000200)
|
||||
ngi->flags |= NF_HIDE_QUIT;
|
||||
if (tmp32 & 0x00000400)
|
||||
ngi->flags |= NF_KILL_QUICK;
|
||||
if (tmp32 & 0x00000800)
|
||||
ngi->flags |= NF_KILL_IMMED;
|
||||
if (tmp32 & 0x80000000)
|
||||
ngi->flags |= NF_MEMO_FWD | NF_MEMO_FWDCOPY;
|
||||
SAFE(read_ptr(&tmpptr, f));
|
||||
if (tmpptr) {
|
||||
SAFE(read_buffer(nickbuf, f));
|
||||
strbcpy(ngi->suspend_who, nickbuf);
|
||||
SAFE(read_string(&ngi->suspend_reason, f));
|
||||
SAFE(read_int32(&tmp32, f));
|
||||
ngi->suspend_time = tmp32;
|
||||
SAFE(read_int32(&tmp32, f));
|
||||
ngi->suspend_expires = tmp32;
|
||||
ngi->flags |= NF_SUSPENDED;
|
||||
}
|
||||
SAFE(read_int16(&ngi->access_count, f));
|
||||
if (ngi->access_count) {
|
||||
char **access;
|
||||
access = scalloc(sizeof(char *), ngi->access_count);
|
||||
ngi->access = access;
|
||||
for (j = 0; j < ngi->access_count; j++, access++)
|
||||
SAFE(read_string(access, f));
|
||||
}
|
||||
SAFE(read_int16(&ngi->memos.memos_count, f));
|
||||
SAFE(read_int16(&ngi->memos.memomax, f));
|
||||
if (ngi->memos.memos_count) {
|
||||
Memo *memos;
|
||||
memos = scalloc(sizeof(Memo), ngi->memos.memos_count);
|
||||
ngi->memos.memos = memos;
|
||||
for (j = 0; j < ngi->memos.memos_count; j++, memos++) {
|
||||
SAFE(read_uint32(&memos->number, f));
|
||||
SAFE(read_int16(&tmp16, f));
|
||||
if (tmp16 & 1)
|
||||
memos->flags |= MF_UNREAD;
|
||||
SAFE(read_int32(&tmp32, f));
|
||||
memos->time = tmp32;
|
||||
SAFE(read_buffer(nickbuf, f));
|
||||
strbcpy(memos->sender, nickbuf);
|
||||
SAFE(read_string(&memos->text, f));
|
||||
}
|
||||
}
|
||||
SAFE(read_int16(&tmp16, f)); /* channelcount */
|
||||
SAFE(read_int16(&tmp16, f)); /* channelmax */
|
||||
SAFE(read_int16(&ngi->language, f));
|
||||
}
|
||||
} /* while (getc_db(f) == 1) */
|
||||
if (c != 0) {
|
||||
fprintf(stderr, "%s is corrupt, aborting.\n", f->filename);
|
||||
exit(1);
|
||||
}
|
||||
} /* for (i) */
|
||||
close_db(f);
|
||||
|
||||
/* Resolve links */
|
||||
for (ni = first_nickinfo(); ni; ni = next_nickinfo()) {
|
||||
NickInfo *ni2;
|
||||
const char *last_nick;
|
||||
if (ni->last_realmask) {
|
||||
ni2 = ni;
|
||||
/* Find root nick (this will actually stop at the first nick
|
||||
* in the path to the root that isn't marked as linked, but
|
||||
* that's okay because such a nick will already have its
|
||||
* nickgroup ID set correctly) */
|
||||
do {
|
||||
last_nick = ni2->last_realmask;
|
||||
ni2 = get_nickinfo(last_nick);
|
||||
} while (ni2 && ni2 != ni && ni2->last_realmask);
|
||||
ni->last_realmask = NULL;
|
||||
/* Set nickgroup, or delete nick if an error occurred */
|
||||
if (ni2 == ni) {
|
||||
fprintf(stderr,
|
||||
"Warning: dropping nick %s with circular link\n",
|
||||
ni->nick);
|
||||
del_nickinfo(ni);
|
||||
} else if (!ni2) {
|
||||
fprintf(stderr, "Warning: dropping nick %s linked to"
|
||||
" nonexistent nick %s\n", ni->nick, last_nick);
|
||||
del_nickinfo(ni);
|
||||
} else {
|
||||
ngi = get_nickgroupinfo(ni->nickgroup);
|
||||
if (ngi)
|
||||
del_nickgroupinfo(ngi);
|
||||
ni->nickgroup = ni2->nickgroup;
|
||||
ngi = get_nickgroupinfo(ni->nickgroup);
|
||||
if (ngi) {
|
||||
ARRAY_EXTEND(ngi->nicks);
|
||||
strbcpy(ngi->nicks[ngi->nicks_count-1], ni->nick);
|
||||
} else if (ni->nickgroup != 0) {
|
||||
fprintf(stderr, "Warning: Nick group %d for nick %s not"
|
||||
" found -- program bug? Output may be corrupt.",
|
||||
ni->nickgroup, ni->nick);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
static void trircd_load_ajoin(const char *dir)
|
||||
{
|
||||
dbFILE *f;
|
||||
int c;
|
||||
int16 j, tmp16;
|
||||
int32 tmp32;
|
||||
void *tmpptr;
|
||||
char *s;
|
||||
NickGroupInfo *ngi;
|
||||
|
||||
f = open_db_ver(dir, "ajoin.db", 25, 25, NULL);
|
||||
while ((c = getc_db(f)) == 1) {
|
||||
int is_root; /* is this a root nick (should we store data)? */
|
||||
char nickbuf[32];
|
||||
|
||||
SAFE(read_buffer(nickbuf, f));
|
||||
ngi = get_nickgroupinfo_by_nick(nickbuf);
|
||||
is_root = ngi && stricmp(nickbuf, ngi_mainnick(ngi)) == 0;
|
||||
SAFE(read_int16(&tmp16, f)); /* ajoincount */
|
||||
if (is_root) {
|
||||
ngi->ajoin_count = tmp16;
|
||||
ngi->ajoin = scalloc(sizeof(char *), tmp16);
|
||||
for (j = 0; j < tmp16; j++)
|
||||
SAFE(read_string(&ngi->ajoin[j], f));
|
||||
} else {
|
||||
for (j = 0; j < tmp16; j++)
|
||||
SAFE(read_string(&s, f));
|
||||
}
|
||||
SAFE(read_ptr((void *)&tmpptr, f)); /* forbidinfo */
|
||||
if (tmpptr) {
|
||||
SAFE(read_buffer(nickbuf, f)); /* forbidder */
|
||||
SAFE(read_string(&s, f)); /* forbid_message */
|
||||
}
|
||||
SAFE(read_int32(&tmp32, f)); /* authcode */
|
||||
SAFE(read_int16(&tmp16, f)); /* authmode */
|
||||
if (tmp16 & 3) /* NH_AUTHENTIC | NH_OLDAUTH */
|
||||
tmp32 = 0;
|
||||
if (is_root) {
|
||||
ngi->authcode = tmp32;
|
||||
ngi->authset = time(NULL);
|
||||
}
|
||||
SAFE(read_int16(&tmp16, f)); /* ignorecount */
|
||||
if (is_root) {
|
||||
ngi->ignore_count = tmp16;
|
||||
ngi->ignore = scalloc(sizeof(char *), tmp16);
|
||||
for (j = 0; j < ngi->ignore_count; j++) {
|
||||
SAFE(read_int16(&tmp16, f));
|
||||
if (tmp16)
|
||||
SAFE(read_string(&ngi->ignore[j], f));
|
||||
}
|
||||
} else {
|
||||
for (j = tmp16; j > 0; j--) {
|
||||
SAFE(read_int16(&tmp16, f));
|
||||
if (tmp16)
|
||||
SAFE(read_string(&s, f));
|
||||
}
|
||||
}
|
||||
SAFE(read_string(&s, f)); /* infomsg */
|
||||
if (is_root)
|
||||
ngi->info = s;
|
||||
SAFE(read_int32(&tmp32, f)); /* expiredelay */
|
||||
SAFE(read_int16(&tmp16, f)); /* count for memo expire */
|
||||
for (j = 0; j < tmp16; j++)
|
||||
SAFE(read_int32(&tmp32, f)); /* memo.expiration */
|
||||
} /* while (getc_db(f) == 1) */
|
||||
if (c != -1)
|
||||
fprintf(stderr, "Warning: %s may be corrupt.\n", f->filename);
|
||||
close_db(f);
|
||||
}
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
static struct {
|
||||
int32 flag;
|
||||
char mode;
|
||||
} cmodes[] = {
|
||||
{ 0x00000001, 'i' },
|
||||
{ 0x00000002, 'm' },
|
||||
{ 0x00000004, 'n' },
|
||||
{ 0x00000008, 'p' },
|
||||
{ 0x00000010, 's' },
|
||||
{ 0x00000020, 't' },
|
||||
{ 0x00000040, 'k' },
|
||||
{ 0x00000080, 'l' },
|
||||
{ 0x00000100, 'R' },
|
||||
{ 0x00000200, 0 }, /* 'r', never set in mlock */
|
||||
{ 0x00000400, 'c' },
|
||||
{ 0x00000800, 'O' },
|
||||
{ 0x00001000, 'A' },
|
||||
{ 0x00002000, 'z' },
|
||||
{ 0x00004000, 'Q' },
|
||||
{ 0x00008000, 'K' },
|
||||
{ 0x00010000, 'V' },
|
||||
{ 0x00020000, 'H' },
|
||||
{ 0x00040000, 'C' },
|
||||
{ 0x00080000, 'N' },
|
||||
{ 0x00100000, 'S' },
|
||||
{ 0x00200000, 'G' },
|
||||
{ 0x00400000, 'u' },
|
||||
{ 0x00800000, 'f' },
|
||||
{ 0x01000000, 'M' },
|
||||
{ 0, 0 }
|
||||
};
|
||||
|
||||
static void trircd_load_chan(const char *dir)
|
||||
{
|
||||
dbFILE *f;
|
||||
int i, j, c;
|
||||
ChannelInfo *ci;
|
||||
NickInfo *ni;
|
||||
int32 tmp32, mlock_on, mlock_off;
|
||||
MemoInfo tmpmi;
|
||||
void *tmpptr;
|
||||
|
||||
f = open_db_ver(dir, "chan.db", 22, 25, NULL);
|
||||
|
||||
for (i = 0; i < 256; i++) {
|
||||
int16 tmp16;
|
||||
char *s, *on, *off;
|
||||
char namebuf[64], passbuf[32], nickbuf[32];
|
||||
|
||||
while ((c = getc_db(f)) == 1) {
|
||||
SAFE(read_buffer(namebuf, f));
|
||||
ci = makechan(namebuf);
|
||||
SAFE(read_string(&s, f));
|
||||
if (s) {
|
||||
ni = get_nickinfo(s);
|
||||
if (!ni) {
|
||||
fprintf(stderr,
|
||||
"Warning: Founder %s for channel %s not found\n",
|
||||
s, ci->name);
|
||||
} else if (!ni->nickgroup) {
|
||||
fprintf(stderr, "Warning: Founder %s for channel %s is a"
|
||||
" forbidden nick\n", s, ci->name);
|
||||
} else {
|
||||
ci->founder = ni->nickgroup;
|
||||
}
|
||||
}
|
||||
SAFE(read_string(&s, f));
|
||||
if (s) {
|
||||
ni = get_nickinfo(s);
|
||||
if (!ni) {
|
||||
fprintf(stderr, "Warning: Successor %s for channel %s"
|
||||
" not found\n", s, ci->name);
|
||||
} else if (!ni->nickgroup) {
|
||||
fprintf(stderr, "Warning: Successor %s for channel %s"
|
||||
" is a forbidden nick\n", s, ci->name);
|
||||
} else if (ni->nickgroup == ci->founder) {
|
||||
fprintf(stderr, "Warning: Successor %s for channel %s"
|
||||
" is the same as the founder, clearing\n",
|
||||
s, ci->name);
|
||||
} else {
|
||||
ci->successor = ni->nickgroup;
|
||||
}
|
||||
}
|
||||
SAFE(read_buffer(passbuf, f));
|
||||
init_password(&ci->founderpass);
|
||||
memcpy(ci->founderpass.password, passbuf, sizeof(passbuf));
|
||||
SAFE(read_string(&ci->desc, f));
|
||||
if (!ci->desc)
|
||||
ci->desc = (char *)"";
|
||||
SAFE(read_string(&ci->url, f));
|
||||
SAFE(read_string(&ci->email, f));
|
||||
SAFE(read_int32(&tmp32, f));
|
||||
ci->time_registered = tmp32;
|
||||
SAFE(read_int32(&tmp32, f));
|
||||
ci->last_used = tmp32;
|
||||
SAFE(read_string(&ci->last_topic, f));
|
||||
SAFE(read_buffer(nickbuf, f));
|
||||
strbcpy(ci->last_topic_setter, nickbuf);
|
||||
SAFE(read_int32(&tmp32, f));
|
||||
ci->last_topic_time = tmp32;
|
||||
|
||||
SAFE(read_int32(&tmp32, f)); /* flags */
|
||||
if (tmp32 & 0x00000001)
|
||||
ci->flags |= CF_KEEPTOPIC;
|
||||
if (tmp32 & 0x00000002)
|
||||
ci->flags |= CF_SECUREOPS;
|
||||
if (tmp32 & 0x00000004)
|
||||
ci->flags |= CF_PRIVATE;
|
||||
if (tmp32 & 0x00000008)
|
||||
ci->flags |= CF_TOPICLOCK;
|
||||
if (tmp32 & 0x00000010)
|
||||
ci->flags |= CF_RESTRICTED;
|
||||
if (tmp32 & 0x00000020)
|
||||
ci->flags |= CF_LEAVEOPS;
|
||||
if (tmp32 & 0x00000040)
|
||||
ci->flags |= CF_SECURE;
|
||||
if (tmp32 & 0x00000080)
|
||||
ci->flags |= CF_VERBOTEN;
|
||||
if (tmp32 & 0x00000100)
|
||||
ci->founderpass.cipher = sstrdup("md5");
|
||||
if (tmp32 & 0x00000200)
|
||||
ci->flags |= CF_NOEXPIRE;
|
||||
if (tmp32 & 0x01000000)
|
||||
ci->flags |= CF_HIDE_TOPIC;
|
||||
if (tmp32 & 0x04000000)
|
||||
ci->flags |= CF_HIDE_MLOCK;
|
||||
if (tmp32 & 0x80000000)
|
||||
ci->flags |= CF_HIDE_EMAIL;
|
||||
|
||||
SAFE(read_ptr((void **)&tmpptr, f));
|
||||
if (tmpptr) {
|
||||
SAFE(read_buffer(nickbuf, f));
|
||||
strbcpy(ci->suspend_who, nickbuf);
|
||||
SAFE(read_string(&ci->suspend_reason, f));
|
||||
SAFE(read_int32(&tmp32, f));
|
||||
ci->suspend_time = tmp32;
|
||||
SAFE(read_int32(&tmp32, f));
|
||||
ci->suspend_expires = tmp32;
|
||||
ci->flags |= CF_SUSPENDED;
|
||||
}
|
||||
|
||||
SAFE(read_int16(&tmp16, f)); /* n_levels */
|
||||
for (j = tmp16; j > 0; j--)
|
||||
SAFE(read_int16(&tmp16, f)); /* levels */
|
||||
|
||||
SAFE(read_int16(&ci->access_count, f));
|
||||
if (ci->access_count) {
|
||||
ci->access = scalloc(ci->access_count, sizeof(ChanAccess));
|
||||
for (j = 0; j < ci->access_count; j++) {
|
||||
SAFE(read_int16(&tmp16, f)); /* in_use */
|
||||
if (tmp16) {
|
||||
SAFE(read_int16(&ci->access[j].level, f));
|
||||
SAFE(read_string(&s, f));
|
||||
ci->access[j].level =
|
||||
convert_acclev(ci->access[j].level);
|
||||
if (s) {
|
||||
ni = get_nickinfo(s);
|
||||
if (ni)
|
||||
ci->access[j].nickgroup = ni->nickgroup;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SAFE(read_int16(&ci->akick_count, f));
|
||||
if (ci->akick_count) {
|
||||
ci->akick = scalloc(ci->akick_count, sizeof(AutoKick));
|
||||
for (j = 0; j < ci->akick_count; j++) {
|
||||
SAFE(read_int16(&tmp16, f)); /* in_use */
|
||||
if (tmp16) {
|
||||
SAFE(read_int16(&tmp16, f)); /* is_nick */
|
||||
SAFE(read_string(&s, f));
|
||||
if (tmp16 && s) {
|
||||
ci->akick[j].mask = smalloc(strlen(s)+5);
|
||||
sprintf(ci->akick[j].mask, "%s!*@*", s);
|
||||
} else {
|
||||
ci->akick[j].mask = s;
|
||||
}
|
||||
SAFE(read_string(&s, f));
|
||||
SAFE(read_buffer(nickbuf, f));
|
||||
if (ci->akick[j].mask) {
|
||||
ci->akick[j].reason = s;
|
||||
strbcpy(ci->akick[j].who, nickbuf);
|
||||
ci->akick[j].set = time(NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SAFE(read_int32(&mlock_on, f));
|
||||
SAFE(read_int32(&mlock_off, f));
|
||||
ci->mlock.on = on = scalloc(64, 1);
|
||||
ci->mlock.off = off = scalloc(64, 1);
|
||||
for (j = 0; cmodes[j].flag != 0; j++) {
|
||||
if (mlock_on & cmodes[j].flag)
|
||||
*on++ = cmodes[j].mode;
|
||||
if (mlock_off & cmodes[j].flag)
|
||||
*off++ = cmodes[j].mode;
|
||||
}
|
||||
*on = 0;
|
||||
*off = 0;
|
||||
SAFE(read_int32(&ci->mlock.limit, f));
|
||||
SAFE(read_string(&ci->mlock.key, f));
|
||||
|
||||
SAFE(read_int16(&tmpmi.memos_count, f));
|
||||
SAFE(read_int16(&tmp16, f)); /* memomax */
|
||||
if (tmpmi.memos_count) {
|
||||
Memo *memos;
|
||||
memos = scalloc(sizeof(Memo), tmpmi.memos_count);
|
||||
tmpmi.memos = memos;
|
||||
for (j = 0; j < tmpmi.memos_count; j++, memos++) {
|
||||
SAFE(read_uint32(&memos->number, f));
|
||||
SAFE(read_int16(&memos->flags, f));
|
||||
SAFE(read_int32(&tmp32, f));
|
||||
memos->time = tmp32;
|
||||
SAFE(read_buffer(nickbuf, f));
|
||||
strbcpy(memos->sender, nickbuf);
|
||||
SAFE(read_string(&memos->text, f));
|
||||
}
|
||||
}
|
||||
|
||||
SAFE(read_string(&ci->entry_message, f));
|
||||
|
||||
if (!(ci->flags & CF_VERBOTEN) && !ci->founder) {
|
||||
fprintf(stderr, "Ignoring channel %s (missing founder)\n",
|
||||
ci->name);
|
||||
del_channelinfo(ci);
|
||||
}
|
||||
|
||||
} /* while (getc_db(f) == 1) */
|
||||
|
||||
if (c != 0) {
|
||||
fprintf(stderr, "%s is corrupt, aborting.\n", f->filename);
|
||||
exit(1);
|
||||
}
|
||||
} /* for (i) */
|
||||
close_db(f);
|
||||
}
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
static void trircd_load_cforbid(const char *dir)
|
||||
{
|
||||
dbFILE *f;
|
||||
int c;
|
||||
|
||||
f = open_db_ver(dir, "cforbid.db", 25, 25, NULL);
|
||||
while ((c = getc_db(f)) == 1) {
|
||||
char chanbuf[64];
|
||||
void *tmpptr;
|
||||
int8 tmp8;
|
||||
int16 i, tmp16;
|
||||
int32 tmp32;
|
||||
char *s;
|
||||
ChannelInfo *ci;
|
||||
|
||||
SAFE(read_buffer(chanbuf, f));
|
||||
ci = get_channelinfo(chanbuf);
|
||||
if (!ci) {
|
||||
fprintf(stderr, "Warning: cforbid data for nonexistent channel"
|
||||
" %s, ignoring\n", chanbuf);
|
||||
}
|
||||
SAFE(read_ptr(&tmpptr, f)); /* forbidinfo */
|
||||
if (tmpptr) {
|
||||
char nickbuf[32];
|
||||
SAFE(read_buffer(nickbuf, f)); /* forbidder */
|
||||
SAFE(read_string(&s, f)); /* forbid_message */
|
||||
}
|
||||
SAFE(read_int16(&tmp16, f)); /* akickcount */
|
||||
if (ci && tmp16 != ci->akick_count) {
|
||||
fprintf(stderr, "Warning: autokick count mismatch (chan.db: %d,"
|
||||
" cforbid.db: %d); databases may be corrupt\n",
|
||||
ci->akick_count, tmp16);
|
||||
}
|
||||
for (i = 0; i < tmp16; i++) {
|
||||
int16 in_use;
|
||||
SAFE(read_int16(&in_use, f));
|
||||
if (in_use) {
|
||||
if (ci && i < ci->akick_count) {
|
||||
SAFE(read_int32(&tmp32, f));
|
||||
ci->akick[i].set = tmp32;
|
||||
SAFE(read_int32(&tmp32, f));
|
||||
ci->akick[i].lastused = tmp32;
|
||||
} else {
|
||||
SAFE(read_int32(&tmp32, f));
|
||||
SAFE(read_int32(&tmp32, f));
|
||||
}
|
||||
SAFE(read_int32(&tmp32, f)); /* expires */
|
||||
}
|
||||
}
|
||||
SAFE(read_int16(&tmp16, f)); /* accesscount */
|
||||
for (i = tmp16; i > 0; i--) {
|
||||
SAFE(read_int16(&tmp16, f)); /* in_use */
|
||||
if (tmp16)
|
||||
SAFE(read_int32(&tmp32, f)); /* last_used */
|
||||
}
|
||||
SAFE(read_int8(&tmp8, f));
|
||||
if (tmp8 != 0) {
|
||||
fprintf(stderr, "%s is corrupt, aborting.\n", f->filename);
|
||||
exit(1);
|
||||
}
|
||||
} /* while (getc_db(f) == 1) */
|
||||
if (c != -1)
|
||||
fprintf(stderr, "Warning: %s may be corrupt.\n", f->filename);
|
||||
close_db(f);
|
||||
}
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
static void trircd_load_oper(const char *dir)
|
||||
{
|
||||
dbFILE *f;
|
||||
int16 i, n;
|
||||
int32 tmp32;
|
||||
int8 tmp8;
|
||||
char *s;
|
||||
|
||||
f = open_db_ver(dir, "oper.db", 22, 25, NULL);
|
||||
/* servadmin */
|
||||
SAFE(read_int16(&n, f));
|
||||
for (i = 0; i < n; i++) {
|
||||
SAFE(read_string(&s, f));
|
||||
set_os_priv(s, NP_SERVADMIN);
|
||||
}
|
||||
/* servoper */
|
||||
SAFE(read_int16(&n, f));
|
||||
for (i = 0; i < n; i++) {
|
||||
SAFE(read_string(&s, f));
|
||||
set_os_priv(s, NP_SERVOPER);
|
||||
}
|
||||
SAFE(read_int32(&maxusercnt, f));
|
||||
SAFE(read_int32(&tmp32, f));
|
||||
maxusertime = tmp32;
|
||||
SAFE(read_int8(&tmp8, f));
|
||||
no_supass = tmp8;
|
||||
if (!no_supass) {
|
||||
char passbuf[32];
|
||||
SAFE(read_buffer(passbuf, f));
|
||||
memcpy(supass.password, passbuf, sizeof(passbuf));
|
||||
}
|
||||
close_db(f);
|
||||
}
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
static void trircd_load_akill(const char *dir)
|
||||
{
|
||||
dbFILE *f;
|
||||
int16 i, n;
|
||||
MaskData *md;
|
||||
|
||||
f = open_db_ver(dir, "akill.db", 22, 25, NULL);
|
||||
SAFE(read_int16(&n, f));
|
||||
md = scalloc(sizeof(*md), n);
|
||||
for (i = 0; i < n; i++) {
|
||||
char nick[32];
|
||||
int32 tmp32;
|
||||
SAFE(read_string(&md[i].mask, f));
|
||||
SAFE(read_string(&md[i].reason, f));
|
||||
SAFE(read_buffer(nick, f));
|
||||
strbcpy(md[i].who, nick);
|
||||
SAFE(read_int32(&tmp32, f));
|
||||
md[i].time = tmp32;
|
||||
SAFE(read_int32(&tmp32, f));
|
||||
md[i].expires = tmp32;
|
||||
if (md[i].mask)
|
||||
add_maskdata(MD_AKILL, &md[i]);
|
||||
}
|
||||
close_db(f);
|
||||
}
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
static void trircd_load_exclude(const char *dir)
|
||||
{
|
||||
dbFILE *f;
|
||||
int16 i, n;
|
||||
MaskData *md;
|
||||
|
||||
f = open_db_ver(dir, "exclude.db", 22, 25, NULL);
|
||||
SAFE(read_int16(&n, f));
|
||||
md = scalloc(sizeof(*md), n);
|
||||
for (i = 0; i < n; i++) {
|
||||
char nick[32];
|
||||
int32 tmp32;
|
||||
SAFE(read_string(&md[i].mask, f));
|
||||
SAFE(read_string(&md[i].reason, f));
|
||||
SAFE(read_buffer(nick, f));
|
||||
strbcpy(md[i].who, nick);
|
||||
SAFE(read_int32(&tmp32, f));
|
||||
md[i].time = tmp32;
|
||||
SAFE(read_int32(&tmp32, f));
|
||||
md[i].expires = tmp32;
|
||||
if (md[i].mask)
|
||||
add_maskdata(MD_EXCLUDE, &md[i]);
|
||||
}
|
||||
close_db(f);
|
||||
}
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
static void trircd_load_exception(const char *dir)
|
||||
{
|
||||
dbFILE *f;
|
||||
int16 i, n;
|
||||
MaskData *md;
|
||||
|
||||
f = open_db_ver(dir, "exception.db", 22, 25, NULL);
|
||||
SAFE(read_int16(&n, f));
|
||||
md = scalloc(sizeof(*md), n);
|
||||
for (i = 0; i < n; i++) {
|
||||
char nick[32];
|
||||
int32 tmp32;
|
||||
SAFE(read_string(&md[i].mask, f));
|
||||
SAFE(read_int16(&md[i].limit, f));
|
||||
SAFE(read_buffer(nick, f));
|
||||
strbcpy(md[i].who, nick);
|
||||
SAFE(read_string(&md[i].reason, f));
|
||||
SAFE(read_int32(&tmp32, f));
|
||||
md[i].time = tmp32;
|
||||
SAFE(read_int32(&tmp32, f));
|
||||
md[i].expires = tmp32;
|
||||
if (md[i].mask)
|
||||
add_maskdata(MD_AKILL, &md[i]);
|
||||
}
|
||||
close_db(f);
|
||||
}
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
static void trircd_load_news(const char *dir)
|
||||
{
|
||||
dbFILE *f;
|
||||
int16 i, n;
|
||||
NewsItem *news;
|
||||
|
||||
f = open_db_ver(dir, "news.db", 22, 25, NULL);
|
||||
SAFE(read_int16(&n, f));
|
||||
news = scalloc(sizeof(*news), n);
|
||||
for (i = 0; i < n; i++) {
|
||||
char nick[32];
|
||||
int32 tmp32;
|
||||
SAFE(read_int16(&news[i].type, f));
|
||||
SAFE(read_int32(&news[i].num, f));
|
||||
SAFE(read_string(&news[i].text, f));
|
||||
SAFE(read_buffer(nick, f));
|
||||
strbcpy(news[i].who, nick);
|
||||
SAFE(read_int32(&tmp32, f));
|
||||
news[i].time = tmp32;
|
||||
add_news(&news[i]);
|
||||
}
|
||||
close_db(f);
|
||||
}
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
static void trircd_load_sline(const char *dir, const unsigned char type)
|
||||
{
|
||||
char filenamebuf[16];
|
||||
dbFILE *f;
|
||||
int32 ver;
|
||||
int16 i, n;
|
||||
MaskData *md;
|
||||
|
||||
snprintf(filenamebuf, sizeof(filenamebuf), "s%cline.db", type);
|
||||
f = open_db_ver(dir, filenamebuf, 22, 25, &ver);
|
||||
read_int16(&n, f);
|
||||
md = scalloc(sizeof(*md), n);
|
||||
for (i = 0; i < n; i++) {
|
||||
char nickbuf[32];
|
||||
int32 tmp32;
|
||||
SAFE(read_string(&md[i].mask, f));
|
||||
SAFE(read_string(&md[i].reason, f));
|
||||
SAFE(read_buffer(nickbuf, f));
|
||||
strbcpy(md[i].who, nickbuf);
|
||||
if (ver >= 23) {
|
||||
SAFE(read_int32(&tmp32, f));
|
||||
md[i].time = tmp32;
|
||||
SAFE(read_int32(&tmp32, f));
|
||||
md[i].expires = tmp32;
|
||||
} else {
|
||||
md[i].time = time(NULL);
|
||||
}
|
||||
if (md[i].mask)
|
||||
add_maskdata(type, &md[i]);
|
||||
}
|
||||
close_db(f);
|
||||
}
|
||||
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
|
||||
static const char *check_trircd(const char *dir)
|
||||
{
|
||||
char buf[PATH_MAX+1];
|
||||
FILE *f;
|
||||
|
||||
snprintf(buf, sizeof(buf), "%s/cforbid.db", dir);
|
||||
if ((f = fopen(buf, "rb")) != NULL) {
|
||||
int32 ver;
|
||||
ver = fgetc(f)<<24;
|
||||
ver |= fgetc(f)<<16;
|
||||
ver |= fgetc(f)<< 8;
|
||||
ver |= fgetc(f);
|
||||
fclose(f);
|
||||
if (ver == 25)
|
||||
return "trircd-4.26";
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void load_trircd(const char *dir, int verbose, int ac, char **av)
|
||||
{
|
||||
if (ac > 1) {
|
||||
fprintf(stderr, "Unrecognized option %s\n", av[1]);
|
||||
usage(av[0]);
|
||||
}
|
||||
if (verbose)
|
||||
fprintf(stderr, "Loading nick.db...\n");
|
||||
trircd_load_nick(dir);
|
||||
if (verbose)
|
||||
fprintf(stderr, "Loading ajoin.db...\n");
|
||||
trircd_load_ajoin(dir);
|
||||
if (verbose)
|
||||
fprintf(stderr, "Loading chan.db...\n");
|
||||
trircd_load_chan(dir);
|
||||
if (verbose)
|
||||
fprintf(stderr, "Loading cforbid.db...\n");
|
||||
trircd_load_cforbid(dir);
|
||||
if (verbose)
|
||||
fprintf(stderr, "Loading oper.db...\n");
|
||||
trircd_load_oper(dir);
|
||||
if (verbose)
|
||||
fprintf(stderr, "Loading akill.db...\n");
|
||||
trircd_load_akill(dir);
|
||||
if (verbose)
|
||||
fprintf(stderr, "Loading exclude.db...\n");
|
||||
trircd_load_exclude(dir);
|
||||
if (verbose)
|
||||
fprintf(stderr, "Loading exception.db...\n");
|
||||
trircd_load_exception(dir);
|
||||
if (verbose)
|
||||
fprintf(stderr, "Loading news.db...\n");
|
||||
trircd_load_news(dir);
|
||||
if (verbose)
|
||||
fprintf(stderr, "Loading sgline.db...\n");
|
||||
trircd_load_sline(dir, 'g');
|
||||
if (verbose)
|
||||
fprintf(stderr, "Loading sqline.db...\n");
|
||||
trircd_load_sline(dir, 'q');
|
||||
if (verbose)
|
||||
fprintf(stderr, "Loading szline.db...\n");
|
||||
trircd_load_sline(dir, 'z');
|
||||
}
|
||||
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
|
||||
DBTypeInfo dbtype_trircd_4_26 = {
|
||||
"trircd-4.26",
|
||||
check_trircd,
|
||||
load_trircd
|
||||
};
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* c-file-style: "stroustrup"
|
||||
* c-file-offsets: ((case-label . *) (statement-case-intro . *))
|
||||
* indent-tabs-mode: nil
|
||||
* End:
|
||||
*
|
||||
* vim: expandtab shiftwidth=4:
|
||||
*/
|
734
tools/convert-ver8.c
Normal file
734
tools/convert-ver8.c
Normal file
@ -0,0 +1,734 @@
|
||||
/* Conversion routines for datafile version 8 based databases (Daylight and
|
||||
* IRCS 1.2).
|
||||
*
|
||||
* IRC Services is copyright (c) 1996-2009 Andrew Church.
|
||||
* E-mail: <achurch@achurch.org>
|
||||
* Parts written by Andrew Kempe and others.
|
||||
* This program is free but copyrighted software; see the file GPL.txt for
|
||||
* details.
|
||||
*/
|
||||
|
||||
#include "convert-db.h"
|
||||
|
||||
#if NICKMAX < 32
|
||||
# error NICKMAX too small (must be >=32)
|
||||
#elif CHANMAX < 204
|
||||
# error CHANMAX too small (must be >=204)
|
||||
#elif PASSMAX < 32
|
||||
# error PASSMAX too small (must be >=32)
|
||||
#endif
|
||||
|
||||
#define TYPE_DAYLIGHT 0
|
||||
#define TYPE_IRCS 1
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
static void ver8_load_nick(const char *dir, int type)
|
||||
{
|
||||
dbFILE *f;
|
||||
int i, j, c;
|
||||
int16 tmp16;
|
||||
int32 tmp32;
|
||||
NickInfo *ni;
|
||||
NickGroupInfo *ngi;
|
||||
|
||||
f = open_db_ver(dir, "nick.db", 8, 8, NULL);
|
||||
for (i = 0; i < 256; i++) {
|
||||
while ((c = getc_db(f)) == 1) {
|
||||
char nickbuf[32];
|
||||
SAFE(read_buffer(nickbuf, f));
|
||||
ni = makenick(nickbuf, &ngi);
|
||||
init_password(&ngi->pass);
|
||||
if (type == TYPE_IRCS) {
|
||||
char passbuf[16];
|
||||
SAFE(read_buffer(passbuf, f));
|
||||
memcpy(ngi->pass.password, passbuf, sizeof(passbuf));
|
||||
} else {
|
||||
char passbuf[32];
|
||||
SAFE(read_buffer(passbuf, f));
|
||||
memcpy(ngi->pass.password, passbuf, sizeof(passbuf));
|
||||
}
|
||||
SAFE(read_string(&ngi->url, f));
|
||||
SAFE(read_string(&ngi->email, f));
|
||||
SAFE(read_string(&ni->last_usermask, f));
|
||||
if (!ni->last_usermask)
|
||||
ni->last_usermask = (char *)"@";
|
||||
SAFE(read_string(&ni->last_realname, f));
|
||||
if (!ni->last_realname)
|
||||
ni->last_realname = (char *)"";
|
||||
SAFE(read_string(&ni->last_quit, f));
|
||||
SAFE(read_int32(&tmp32, f));
|
||||
ni->time_registered = tmp32;
|
||||
SAFE(read_int32(&tmp32, f));
|
||||
ni->last_seen = tmp32;
|
||||
SAFE(read_int16(&tmp16, f)); /* status */
|
||||
if (tmp16 & 0x0001)
|
||||
ngi->pass.cipher = sstrdup("md5");
|
||||
if (tmp16 & 0x0002) {
|
||||
ni->status |= NS_VERBOTEN;
|
||||
del_nickgroupinfo(ngi);
|
||||
ni->nickgroup = 0;
|
||||
}
|
||||
if (tmp16 & 0x0004)
|
||||
ni->status |= NS_NOEXPIRE;
|
||||
SAFE(read_string(&ni->last_realmask, f)); /* link */
|
||||
SAFE(read_int16(&tmp16, f)); /* linkcount */
|
||||
if (ni->last_realmask) {
|
||||
ni->nickgroup = 0;
|
||||
SAFE(read_int16(&tmp16, f)); /* channelcount */
|
||||
} else {
|
||||
SAFE(read_int32(&tmp32, f)); /* flags */
|
||||
if (tmp32 & 0x00000001)
|
||||
ngi->flags |= NF_KILLPROTECT;
|
||||
if (tmp32 & 0x00000002)
|
||||
ngi->flags |= NF_SECURE;
|
||||
if (tmp32 & 0x00000008)
|
||||
ngi->flags |= NF_MEMO_HARDMAX;
|
||||
if (tmp32 & 0x00000010)
|
||||
ngi->flags |= NF_MEMO_SIGNON;
|
||||
if (tmp32 & 0x00000020)
|
||||
ngi->flags |= NF_MEMO_RECEIVE;
|
||||
if (tmp32 & 0x00000040)
|
||||
ngi->flags |= NF_PRIVATE;
|
||||
if (tmp32 & 0x00000080)
|
||||
ngi->flags |= NF_HIDE_EMAIL;
|
||||
if (tmp32 & 0x00000100)
|
||||
ngi->flags |= NF_HIDE_MASK;
|
||||
if (tmp32 & 0x00000200)
|
||||
ngi->flags |= NF_HIDE_QUIT;
|
||||
if (tmp32 & 0x00000400)
|
||||
ngi->flags |= NF_KILL_QUICK;
|
||||
if (tmp32 & 0x00000800)
|
||||
ngi->flags |= NF_KILL_IMMED;
|
||||
SAFE(read_int16(&ngi->access_count, f));
|
||||
if (ngi->access_count) {
|
||||
char **access;
|
||||
access = scalloc(sizeof(char *), ngi->access_count);
|
||||
ngi->access = access;
|
||||
for (j = 0; j < ngi->access_count; j++, access++)
|
||||
SAFE(read_string(access, f));
|
||||
}
|
||||
SAFE(read_int16(&ngi->memos.memos_count, f));
|
||||
SAFE(read_int16(&ngi->memos.memomax, f));
|
||||
if (ngi->memos.memos_count) {
|
||||
Memo *memos;
|
||||
memos = scalloc(sizeof(Memo), ngi->memos.memos_count);
|
||||
ngi->memos.memos = memos;
|
||||
for (j = 0; j < ngi->memos.memos_count; j++, memos++) {
|
||||
SAFE(read_uint32(&memos->number, f));
|
||||
SAFE(read_int16(&tmp16, f));
|
||||
if (tmp16 & 1)
|
||||
memos->flags |= MF_UNREAD;
|
||||
SAFE(read_int32(&tmp32, f));
|
||||
memos->time = tmp32;
|
||||
SAFE(read_buffer(nickbuf, f));
|
||||
strbcpy(memos->sender, nickbuf);
|
||||
SAFE(read_string(&memos->text, f));
|
||||
}
|
||||
}
|
||||
SAFE(read_int16(&tmp16, f)); /* channelcount */
|
||||
SAFE(read_int16(&tmp16, f)); /* channelmax */
|
||||
SAFE(read_int16(&tmp16, f));
|
||||
switch (tmp16) {
|
||||
case 0: ngi->language = LANG_EN_US; break;
|
||||
case 2: ngi->language = LANG_JA_EUC; break;
|
||||
case 3: ngi->language = LANG_JA_SJIS; break;
|
||||
case 4: ngi->language = LANG_ES; break;
|
||||
case 5: ngi->language = LANG_PT; break;
|
||||
case 6: ngi->language = LANG_FR; break;
|
||||
case 7: ngi->language = LANG_TR; break;
|
||||
case 8: ngi->language = LANG_IT; break;
|
||||
}
|
||||
}
|
||||
} /* while (getc_db(f) == 1) */
|
||||
if (c != 0) {
|
||||
fprintf(stderr, "%s is corrupt, aborting.\n", f->filename);
|
||||
exit(1);
|
||||
}
|
||||
} /* for (i) */
|
||||
close_db(f);
|
||||
|
||||
/* Resolve links */
|
||||
for (ni = first_nickinfo(); ni; ni = next_nickinfo()) {
|
||||
NickInfo *ni2;
|
||||
const char *last_nick;
|
||||
if (ni->last_realmask) {
|
||||
ni2 = ni;
|
||||
/* Find root nick (this will actually stop at the first nick
|
||||
* in the path to the root that isn't marked as linked, but
|
||||
* that's okay because such a nick will already have its
|
||||
* nickgroup ID set correctly) */
|
||||
do {
|
||||
last_nick = ni2->last_realmask;
|
||||
ni2 = get_nickinfo(last_nick);
|
||||
} while (ni2 && ni2 != ni && ni2->last_realmask);
|
||||
ni->last_realmask = NULL;
|
||||
/* Set nickgroup, or delete nick if an error occurred */
|
||||
if (ni2 == ni) {
|
||||
fprintf(stderr,
|
||||
"Warning: dropping nick %s with circular link\n",
|
||||
ni->nick);
|
||||
del_nickinfo(ni);
|
||||
} else if (!ni2) {
|
||||
fprintf(stderr, "Warning: dropping nick %s linked to"
|
||||
" nonexistent nick %s\n", ni->nick, last_nick);
|
||||
del_nickinfo(ni);
|
||||
} else {
|
||||
ngi = get_nickgroupinfo(ni->nickgroup);
|
||||
if (ngi)
|
||||
del_nickgroupinfo(ngi);
|
||||
ni->nickgroup = ni2->nickgroup;
|
||||
ngi = get_nickgroupinfo(ni->nickgroup);
|
||||
if (ngi) {
|
||||
ARRAY_EXTEND(ngi->nicks);
|
||||
strbcpy(ngi->nicks[ngi->nicks_count-1], ni->nick);
|
||||
} else if (ni->nickgroup != 0) {
|
||||
fprintf(stderr, "Warning: Nick group %d for nick %s not"
|
||||
" found -- program bug? Output may be corrupt.",
|
||||
ni->nickgroup, ni->nick);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
static struct {
|
||||
int32 flag;
|
||||
char mode;
|
||||
} cmodes[] = {
|
||||
{ 0x00000001, 'i' },
|
||||
{ 0x00000002, 'm' },
|
||||
{ 0x00000004, 'n' },
|
||||
{ 0x00000008, 'p' },
|
||||
{ 0x00000010, 's' },
|
||||
{ 0x00000020, 't' },
|
||||
{ 0x00000040, 'k' },
|
||||
{ 0x00000080, 'l' },
|
||||
{ 0x00000100, 'R' },
|
||||
{ 0x00000200, 0 }, /* 'r', never set in mlock */
|
||||
{ 0x00000400, 'K' },
|
||||
{ 0x00000800, 'V' },
|
||||
{ 0x00001000, 'Q' },
|
||||
{ 0x00002000, 'c' },
|
||||
{ 0x00004000, 'O' },
|
||||
{ 0x00008000, 'A' },
|
||||
{ 0x00010000, 'S' },
|
||||
{ 0x00020000, 'H' },
|
||||
{ 0x00040000, 'C' },
|
||||
{ 0x00080000, 'u' },
|
||||
{ 0x00100000, 'N' },
|
||||
{ 0x00200000, 'f' },
|
||||
{ 0x00400000, 'z' },
|
||||
{ 0, 0 }
|
||||
};
|
||||
|
||||
static void ver8_load_chan(const char *dir, int type)
|
||||
{
|
||||
dbFILE *f;
|
||||
int i, j, c;
|
||||
ChannelInfo *ci, dummy_ci;
|
||||
NickInfo *ni;
|
||||
int32 tmp32, mlock_on, mlock_off;
|
||||
MemoInfo tmpmi;
|
||||
|
||||
f = open_db_ver(dir, "chan.db", 8, type==TYPE_DAYLIGHT?9:8, NULL);
|
||||
|
||||
for (i = 0; i < 256; i++) {
|
||||
int16 tmp16;
|
||||
char *s, *on, *off;
|
||||
|
||||
while ((c = getc_db(f)) == 1) {
|
||||
char nickbuf[32];
|
||||
if (type == TYPE_IRCS) {
|
||||
char namebuf[204];
|
||||
SAFE(read_buffer(namebuf, f));
|
||||
#if CHANMAX < 204
|
||||
if (CHANMAX-1 < strlen(namebuf)) {
|
||||
fprintf(stderr, "Warning: Channel %s name truncated\n",
|
||||
namebuf);
|
||||
namebuf[CHANMAX-1] = 0;
|
||||
}
|
||||
#endif
|
||||
if (get_channelinfo(namebuf)) {
|
||||
fprintf(stderr, "Channel %s conflicts with existing"
|
||||
" channel, ignoring\n", namebuf);
|
||||
ci = &dummy_ci;
|
||||
} else {
|
||||
ci = makechan(namebuf);
|
||||
}
|
||||
} else {
|
||||
char namebuf[64];
|
||||
SAFE(read_buffer(namebuf, f));
|
||||
if (get_channelinfo(namebuf)) {
|
||||
fprintf(stderr, "Channel %s conflicts with existing"
|
||||
" channel, ignoring\n", namebuf);
|
||||
ci = &dummy_ci;
|
||||
} else {
|
||||
ci = makechan(namebuf);
|
||||
}
|
||||
}
|
||||
SAFE(read_string(&s, f));
|
||||
if (s) {
|
||||
ni = get_nickinfo(s);
|
||||
if (!ni) {
|
||||
fprintf(stderr,
|
||||
"Warning: Founder %s for channel %s not found\n",
|
||||
s, ci->name);
|
||||
} else if (!ni->nickgroup) {
|
||||
fprintf(stderr, "Warning: Founder %s for channel %s is a"
|
||||
" forbidden nick\n", s, ci->name);
|
||||
} else {
|
||||
ci->founder = ni->nickgroup;
|
||||
}
|
||||
}
|
||||
if (type != TYPE_IRCS) {
|
||||
SAFE(read_string(&s, f));
|
||||
if (s) {
|
||||
ni = get_nickinfo(s);
|
||||
if (!ni) {
|
||||
fprintf(stderr, "Warning: Successor %s for channel %s"
|
||||
" not found\n", s, ci->name);
|
||||
} else if (!ni->nickgroup) {
|
||||
fprintf(stderr, "Warning: Successor %s for channel %s"
|
||||
" is a forbidden nick\n", s, ci->name);
|
||||
} else if (ni->nickgroup == ci->founder) {
|
||||
fprintf(stderr, "Warning: Successor %s for channel %s"
|
||||
" is the same as the founder, clearing\n",
|
||||
s, ci->name);
|
||||
} else {
|
||||
ci->successor = ni->nickgroup;
|
||||
}
|
||||
}
|
||||
}
|
||||
init_password(&ci->founderpass);
|
||||
if (type == TYPE_IRCS) {
|
||||
char passbuf[16];
|
||||
SAFE(read_buffer(passbuf, f));
|
||||
memcpy(ci->founderpass.password, passbuf, sizeof(passbuf));
|
||||
} else {
|
||||
char passbuf[32];
|
||||
SAFE(read_buffer(passbuf, f));
|
||||
memcpy(ci->founderpass.password, passbuf, sizeof(passbuf));
|
||||
}
|
||||
SAFE(read_string(&ci->desc, f));
|
||||
if (!ci->desc)
|
||||
ci->desc = (char *)"";
|
||||
SAFE(read_string(&ci->url, f));
|
||||
SAFE(read_string(&ci->email, f));
|
||||
if (type == TYPE_IRCS)
|
||||
SAFE(read_int16(&tmp16, f)); /* autoop */
|
||||
SAFE(read_int32(&tmp32, f));
|
||||
ci->time_registered = tmp32;
|
||||
SAFE(read_int32(&tmp32, f));
|
||||
ci->last_used = tmp32;
|
||||
SAFE(read_string(&ci->last_topic, f));
|
||||
SAFE(read_buffer(nickbuf, f));
|
||||
strbcpy(ci->last_topic_setter, nickbuf);
|
||||
SAFE(read_int32(&tmp32, f));
|
||||
ci->last_topic_time = tmp32;
|
||||
|
||||
SAFE(read_int32(&tmp32, f)); /* flags */
|
||||
if (tmp32 & 0x00000001)
|
||||
ci->flags |= CF_KEEPTOPIC;
|
||||
if (tmp32 & 0x00000002)
|
||||
ci->flags |= CF_SECUREOPS;
|
||||
if (tmp32 & 0x00000004)
|
||||
ci->flags |= CF_PRIVATE;
|
||||
if (tmp32 & 0x00000008)
|
||||
ci->flags |= CF_TOPICLOCK;
|
||||
if (tmp32 & 0x00000010)
|
||||
ci->flags |= CF_RESTRICTED;
|
||||
if (tmp32 & 0x00000020)
|
||||
ci->flags |= CF_LEAVEOPS;
|
||||
if (tmp32 & 0x00000040)
|
||||
ci->flags |= CF_SECURE;
|
||||
if (tmp32 & 0x00000080)
|
||||
ci->flags |= CF_VERBOTEN;
|
||||
if (tmp32 & 0x00000100)
|
||||
ci->founderpass.cipher = sstrdup("md5");
|
||||
if (tmp32 & 0x00000200)
|
||||
ci->flags |= CF_NOEXPIRE;
|
||||
|
||||
/* Levels data is ignored */
|
||||
SAFE(read_int16(&tmp16, f));
|
||||
for (j = tmp16; j > 0; j--)
|
||||
SAFE(read_int16(&tmp16, f));
|
||||
|
||||
SAFE(read_int16(&ci->access_count, f));
|
||||
if (ci->access_count) {
|
||||
ci->access = scalloc(ci->access_count, sizeof(ChanAccess));
|
||||
for (j = 0; j < ci->access_count; j++) {
|
||||
SAFE(read_int16(&tmp16, f)); /* in_use */
|
||||
if (tmp16) {
|
||||
SAFE(read_int16(&ci->access[j].level, f));
|
||||
if (type == TYPE_IRCS) {
|
||||
if (ci->access[j].level >= 10)
|
||||
ci->access[j].level = 15;
|
||||
else if (ci->access[j].level >= 7)
|
||||
ci->access[j].level += 3;
|
||||
ci->access[j].level =
|
||||
convert_acclev(ci->access[j].level);
|
||||
SAFE(read_int16(&tmp16, f)); /* autoop */
|
||||
}
|
||||
SAFE(read_string(&s, f));
|
||||
if (s) {
|
||||
ni = get_nickinfo(s);
|
||||
if (ni)
|
||||
ci->access[j].nickgroup = ni->nickgroup;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SAFE(read_int16(&ci->akick_count, f));
|
||||
if (ci->akick_count) {
|
||||
ci->akick = scalloc(ci->akick_count, sizeof(AutoKick));
|
||||
for (j = 0; j < ci->akick_count; j++) {
|
||||
SAFE(read_int16(&tmp16, f)); /* in_use */
|
||||
if (tmp16) {
|
||||
SAFE(read_int16(&tmp16, f)); /* is_nick */
|
||||
SAFE(read_string(&s, f));
|
||||
if (tmp16 && s) {
|
||||
ci->akick[j].mask = smalloc(strlen(s)+5);
|
||||
sprintf(ci->akick[j].mask, "%s!*@*", s);
|
||||
} else {
|
||||
ci->akick[j].mask = s;
|
||||
}
|
||||
SAFE(read_string(&s, f));
|
||||
if (ci->akick[j].mask) {
|
||||
ci->akick[j].reason = s;
|
||||
strbcpy(ci->akick[j].who, "<unknown>");
|
||||
ci->akick[j].set = time(NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (type == TYPE_DAYLIGHT) {
|
||||
SAFE(read_int32(&mlock_on, f));
|
||||
SAFE(read_int32(&mlock_off, f));
|
||||
} else {
|
||||
SAFE(read_int16(&tmp16, f));
|
||||
mlock_on = tmp16 & 0x00FF;
|
||||
SAFE(read_int16(&tmp16, f));
|
||||
mlock_off = tmp16 & 0x00FF;
|
||||
}
|
||||
ci->mlock.on = on = scalloc(64, 1);
|
||||
ci->mlock.off = off = scalloc(64, 1);
|
||||
for (j = 0; cmodes[j].flag != 0; j++) {
|
||||
if (mlock_on & cmodes[j].flag)
|
||||
*on++ = cmodes[j].mode;
|
||||
if (mlock_off & cmodes[j].flag)
|
||||
*off++ = cmodes[j].mode;
|
||||
}
|
||||
*on = 0;
|
||||
*off = 0;
|
||||
SAFE(read_int32(&ci->mlock.limit, f));
|
||||
SAFE(read_string(&ci->mlock.key, f));
|
||||
|
||||
SAFE(read_int16(&tmpmi.memos_count, f));
|
||||
SAFE(read_int16(&tmp16, f)); /* memomax */
|
||||
if (tmpmi.memos_count) {
|
||||
Memo *memos;
|
||||
memos = scalloc(sizeof(Memo), tmpmi.memos_count);
|
||||
tmpmi.memos = memos;
|
||||
for (j = 0; j < tmpmi.memos_count; j++, memos++) {
|
||||
SAFE(read_uint32(&memos->number, f));
|
||||
SAFE(read_int16(&memos->flags, f));
|
||||
SAFE(read_int32(&tmp32, f));
|
||||
memos->time = tmp32;
|
||||
SAFE(read_buffer(nickbuf, f));
|
||||
strbcpy(memos->sender, nickbuf);
|
||||
SAFE(read_string(&memos->text, f));
|
||||
}
|
||||
}
|
||||
|
||||
SAFE(read_string(&ci->entry_message, f));
|
||||
|
||||
if (!(ci->flags & CF_VERBOTEN) && !ci->founder) {
|
||||
fprintf(stderr, "Ignoring channel %s (missing founder)\n",
|
||||
ci->name);
|
||||
del_channelinfo(ci);
|
||||
}
|
||||
|
||||
} /* while (getc_db(f) == 1) */
|
||||
|
||||
if (c != 0) {
|
||||
fprintf(stderr, "%s is corrupt, aborting.\n", f->filename);
|
||||
exit(1);
|
||||
}
|
||||
} /* for (i) */
|
||||
close_db(f);
|
||||
}
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
static void ver8_load_oper(const char *dir, int type)
|
||||
{
|
||||
dbFILE *f;
|
||||
int16 i, n;
|
||||
int32 tmp32;
|
||||
char *s;
|
||||
|
||||
f = open_db_ver(dir, "oper.db", 8, 8, NULL);
|
||||
/* servadmin */
|
||||
SAFE(read_int16(&n, f));
|
||||
for (i = 0; i < n; i++) {
|
||||
SAFE(read_string(&s, f));
|
||||
set_os_priv(s, NP_SERVADMIN);
|
||||
}
|
||||
if (type == TYPE_IRCS) {
|
||||
/* senior */
|
||||
SAFE(read_int16(&n, f));
|
||||
for (i = 0; i < n; i++) {
|
||||
SAFE(read_string(&s, f));
|
||||
set_os_priv(s, NP_SERVADMIN);
|
||||
}
|
||||
/* junior */
|
||||
SAFE(read_int16(&n, f));
|
||||
for (i = 0; i < n; i++) {
|
||||
SAFE(read_string(&s, f));
|
||||
set_os_priv(s, NP_SERVOPER);
|
||||
}
|
||||
/* helper */
|
||||
SAFE(read_int16(&n, f));
|
||||
for (i = 0; i < n; i++) {
|
||||
SAFE(read_string(&s, f));
|
||||
set_os_priv(s, NP_SERVOPER);
|
||||
}
|
||||
}
|
||||
/* servoper */
|
||||
SAFE(read_int16(&n, f));
|
||||
for (i = 0; i < n; i++) {
|
||||
SAFE(read_string(&s, f));
|
||||
set_os_priv(s, NP_SERVOPER);
|
||||
}
|
||||
SAFE(read_int32(&maxusercnt, f));
|
||||
if (type != TYPE_IRCS) {
|
||||
SAFE(read_int32(&tmp32, f));
|
||||
maxusertime = tmp32;
|
||||
}
|
||||
close_db(f);
|
||||
}
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
static void ver8_load_akill(const char *dir, int type)
|
||||
{
|
||||
dbFILE *f;
|
||||
int16 i, n;
|
||||
MaskData *md;
|
||||
|
||||
f = open_db_ver(dir, "akill.db", 8, 8, NULL);
|
||||
SAFE(read_int16(&n, f));
|
||||
md = scalloc(sizeof(*md), n);
|
||||
for (i = 0; i < n; i++) {
|
||||
char nick[32];
|
||||
int32 tmp32;
|
||||
SAFE(read_string(&md[i].mask, f));
|
||||
SAFE(read_string(&md[i].reason, f));
|
||||
SAFE(read_buffer(nick, f));
|
||||
strbcpy(md[i].who, nick);
|
||||
SAFE(read_int32(&tmp32, f));
|
||||
md[i].time = tmp32;
|
||||
SAFE(read_int32(&tmp32, f));
|
||||
md[i].expires = tmp32;
|
||||
if (md[i].mask)
|
||||
add_maskdata(MD_AKILL, &md[i]);
|
||||
}
|
||||
close_db(f);
|
||||
}
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
static void ver8_load_exception(const char *dir, int type)
|
||||
{
|
||||
dbFILE *f;
|
||||
int16 i, n;
|
||||
MaskData *md;
|
||||
|
||||
f = open_db_ver(dir, "exception.db", 8, 8, NULL);
|
||||
SAFE(read_int16(&n, f));
|
||||
md = scalloc(sizeof(*md), n);
|
||||
for (i = 0; i < n; i++) {
|
||||
char nick[32];
|
||||
int32 tmp32;
|
||||
SAFE(read_string(&md[i].mask, f));
|
||||
SAFE(read_int16(&md[i].limit, f));
|
||||
SAFE(read_buffer(nick, f));
|
||||
strbcpy(md[i].who, nick);
|
||||
SAFE(read_string(&md[i].reason, f));
|
||||
SAFE(read_int32(&tmp32, f));
|
||||
md[i].time = tmp32;
|
||||
SAFE(read_int32(&tmp32, f));
|
||||
md[i].expires = tmp32;
|
||||
if (md[i].mask)
|
||||
add_maskdata(MD_AKILL, &md[i]);
|
||||
}
|
||||
close_db(f);
|
||||
}
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
static void ver8_load_news(const char *dir, int type)
|
||||
{
|
||||
dbFILE *f;
|
||||
int16 i, n;
|
||||
NewsItem *news;
|
||||
|
||||
f = open_db_ver(dir, "news.db", 8, 8, NULL);
|
||||
SAFE(read_int16(&n, f));
|
||||
news = scalloc(sizeof(*news), n);
|
||||
for (i = 0; i < n; i++) {
|
||||
char nick[32];
|
||||
int32 tmp32;
|
||||
SAFE(read_int16(&news[i].type, f));
|
||||
SAFE(read_int32(&news[i].num, f));
|
||||
SAFE(read_string(&news[i].text, f));
|
||||
SAFE(read_buffer(nick, f));
|
||||
strbcpy(news[i].who, nick);
|
||||
SAFE(read_int32(&tmp32, f));
|
||||
news[i].time = tmp32;
|
||||
add_news(&news[i]);
|
||||
}
|
||||
close_db(f);
|
||||
}
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
static void ircs_load_gline(const char *dir)
|
||||
{
|
||||
dbFILE *f;
|
||||
int16 i, n;
|
||||
MaskData *md;
|
||||
|
||||
f = open_db_ver(dir, "gline.db", 8, 8, NULL);
|
||||
read_int16(&n, f);
|
||||
md = scalloc(sizeof(*md), n);
|
||||
for (i = 0; i < n; i++) {
|
||||
char *user, *host;
|
||||
char nick[32];
|
||||
int32 tmp32;
|
||||
SAFE(read_string(&user, f));
|
||||
SAFE(read_string(&host, f));
|
||||
if (user && host) {
|
||||
md[i].mask = smalloc(strlen(user)+strlen(host)+2);
|
||||
sprintf(md[i].mask, "%s@%s", user, host);
|
||||
} else {
|
||||
md[i].mask = NULL;
|
||||
}
|
||||
SAFE(read_string(&md[i].reason, f));
|
||||
SAFE(read_buffer(nick, f));
|
||||
strbcpy(md[i].who, nick);
|
||||
SAFE(read_int32(&tmp32, f));
|
||||
md[i].time = tmp32;
|
||||
SAFE(read_int32(&tmp32, f));
|
||||
md[i].expires = tmp32;
|
||||
if (md[i].mask)
|
||||
add_maskdata(MD_AKILL, &md[i]);
|
||||
}
|
||||
close_db(f);
|
||||
}
|
||||
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
|
||||
static const char *check_daylight(const char *dir)
|
||||
{
|
||||
char buf[PATH_MAX+1];
|
||||
|
||||
snprintf(buf, sizeof(buf), "%s/services.conn", dir);
|
||||
if (access(buf, R_OK) == 0)
|
||||
return "Daylight";
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void load_daylight(const char *dir, int verbose, int ac,
|
||||
char **av)
|
||||
{
|
||||
if (ac > 1) {
|
||||
fprintf(stderr, "Unrecognized option %s\n", av[1]);
|
||||
usage(av[0]);
|
||||
}
|
||||
if (verbose)
|
||||
fprintf(stderr, "Loading nick.db...\n");
|
||||
ver8_load_nick(dir, TYPE_DAYLIGHT);
|
||||
if (verbose)
|
||||
fprintf(stderr, "Loading chan.db...\n");
|
||||
ver8_load_chan(dir, TYPE_DAYLIGHT);
|
||||
if (verbose)
|
||||
fprintf(stderr, "Loading oper.db...\n");
|
||||
ver8_load_oper(dir, TYPE_DAYLIGHT);
|
||||
if (verbose)
|
||||
fprintf(stderr, "Loading akill.db...\n");
|
||||
ver8_load_akill(dir, TYPE_DAYLIGHT);
|
||||
if (verbose)
|
||||
fprintf(stderr, "Loading exception.db...\n");
|
||||
ver8_load_exception(dir, TYPE_DAYLIGHT);
|
||||
if (verbose)
|
||||
fprintf(stderr, "Loading news.db...\n");
|
||||
ver8_load_news(dir, TYPE_DAYLIGHT);
|
||||
}
|
||||
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
|
||||
static const char *check_ircs_1_2(const char *dir)
|
||||
{
|
||||
char buf[PATH_MAX+1];
|
||||
|
||||
snprintf(buf, sizeof(buf), "%s/gline.db", dir);
|
||||
if (access(buf, R_OK) == 0)
|
||||
return "IRCS 1.2";
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void load_ircs_1_2(const char *dir, int verbose, int ac,
|
||||
char **av)
|
||||
{
|
||||
if (ac > 1) {
|
||||
fprintf(stderr, "Unrecognized option %s\n", av[1]);
|
||||
usage(av[0]);
|
||||
}
|
||||
if (verbose)
|
||||
fprintf(stderr, "Loading nick.db...\n");
|
||||
ver8_load_nick(dir, TYPE_IRCS);
|
||||
if (verbose)
|
||||
fprintf(stderr, "Loading chan.db...\n");
|
||||
ver8_load_chan(dir, TYPE_IRCS);
|
||||
if (verbose)
|
||||
fprintf(stderr, "Loading oper.db...\n");
|
||||
ver8_load_oper(dir, TYPE_IRCS);
|
||||
if (verbose)
|
||||
fprintf(stderr, "Loading gline.db...\n");
|
||||
ircs_load_gline(dir);
|
||||
}
|
||||
|
||||
/*************************************************************************/
|
||||
/*************************************************************************/
|
||||
|
||||
DBTypeInfo dbtype_daylight = {
|
||||
"daylight",
|
||||
check_daylight,
|
||||
load_daylight
|
||||
};
|
||||
|
||||
DBTypeInfo dbtype_ircs_1_2 = {
|
||||
"ircs-1.2",
|
||||
check_ircs_1_2,
|
||||
load_ircs_1_2
|
||||
};
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* c-file-style: "stroustrup"
|
||||
* c-file-offsets: ((case-label . *) (statement-case-intro . *))
|
||||
* indent-tabs-mode: nil
|
||||
* End:
|
||||
*
|
||||
* vim: expandtab shiftwidth=4:
|
||||
*/
|
35
tools/ircservices-chk.in
Normal file
35
tools/ircservices-chk.in
Normal file
@ -0,0 +1,35 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# Script to check whether IRC Services is running, and restart it if not.
|
||||
# Usage: ircservices-chk [-q] [ircservices-options]
|
||||
# -q: don't write any output
|
||||
# ircservices-options: options to pass to ircservices executable
|
||||
# If you change PIDFile in ircservices.conf, also change PIDFILE below.
|
||||
#
|
||||
# IRC Services is copyright (c) 1996-2009 Andrew Church.
|
||||
# E-mail: <achurch@achurch.org>
|
||||
# Parts written by Andrew Kempe and others.
|
||||
# This program is free but copyrighted software; see the file GPL.txt for
|
||||
# details.
|
||||
|
||||
PIDFILE=@PROGRAM@.pid
|
||||
|
||||
if [ "X$1" = "X-q" ] ; then
|
||||
exec 1>/dev/null
|
||||
exec 2>/dev/null
|
||||
shift
|
||||
fi
|
||||
|
||||
ok=
|
||||
if [ -f "@DATDEST@/$PIDFILE" ] ; then
|
||||
pid=`cat "@DATDEST@/$PIDFILE"`
|
||||
if echo "0$pid" | grep -q '[^0-9]' ; then
|
||||
rm -f "@DATDEST@/$PIDFILE"
|
||||
elif kill -0 $pid ; then
|
||||
ok=1
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ ! "$ok" ] ; then
|
||||
"@BINDEST@/ircservices" "$@"
|
||||
fi
|
Loading…
x
Reference in New Issue
Block a user