diff options
author | trystan trystan@31f1291d-b8d6-0310-a050-a5561fc1590b <trystan trystan@31f1291d-b8d6-0310-a050-a5561fc1590b@5417fbe8-f217-4b02-8779-1006273d7864> | 2005-02-06 19:18:15 +0000 |
---|---|---|
committer | trystan trystan@31f1291d-b8d6-0310-a050-a5561fc1590b <trystan trystan@31f1291d-b8d6-0310-a050-a5561fc1590b@5417fbe8-f217-4b02-8779-1006273d7864> | 2005-02-06 19:18:15 +0000 |
commit | 9b3a357193a020c53624b29f84e0bca4795722f0 (patch) | |
tree | be1a500c8a469dad8164a72d1266780ac8c28510 /src | |
parent | f8ac398b86ea6a26dba62064d9810796466e4118 (diff) |
BUILD : 1.7.8 (565) BUGS : 293 NOTES : Merge of Win32 branch into the main, support for Unreal +I, German language updated, fixed bug vidents not updating, Setting and Removal of sqlines on forbid or drop
git-svn-id: svn://svn.anope.org/anope/trunk@567 31f1291d-b8d6-0310-a050-a5561fc1590b
git-svn-id: http://anope.svn.sourceforge.net/svnroot/anope/trunk@417 5417fbe8-f217-4b02-8779-1006273d7864
Diffstat (limited to 'src')
37 files changed, 965 insertions, 157 deletions
diff --git a/src/anope-icon.ico b/src/anope-icon.ico Binary files differnew file mode 100644 index 000000000..b60a7994c --- /dev/null +++ b/src/anope-icon.ico diff --git a/src/bahamut.c b/src/bahamut.c index 5e40a7266..36bd28f6d 100644 --- a/src/bahamut.c +++ b/src/bahamut.c @@ -102,6 +102,7 @@ IRCDVar ircd[] = { 1, /* +I support */ 0, /* SJOIN ban char */ 0, /* SJOIN except char */ + 0, /* SJOIN invite char */ 0, /* Can remove User Channel Modes with SVSMODE */ 0, /* Sglines are not enforced until user reconnects */ NULL, /* vhost char */ @@ -856,6 +857,9 @@ void anope_cmd_pong(char *servname, char *who) void anope_cmd_connect(int servernum) { + me_server = + new_server(NULL, ServerName, ServerDesc, SERVER_ISME, NULL); + if (servernum == 1) { anope_cmd_pass(RemotePassword); } else if (servernum == 2) { diff --git a/src/base64.c b/src/base64.c index 68fa80b96..0056822bc 100644 --- a/src/base64.c +++ b/src/base64.c @@ -1,6 +1,6 @@ /* base64 routines. * - * (C) 2003-1005 Anope Team + * (C) 2003-2005 Anope Team * Contact us at info@anope.org * * Please read COPYING and README for further details. diff --git a/src/channels.c b/src/channels.c index 78bdbb045..b9ab710ac 100644 --- a/src/channels.c +++ b/src/channels.c @@ -777,14 +777,14 @@ void do_sjoin(const char *source, int ac, char **av) } } - /* Unreal plans to add +I - for now add the hook to allow - 1.7.6 to work with it and not cause problems - TSL */ - if (*s == '\'') { - add_invite(c, myStrGetToken(s, '\'', 1)); - if (!end) - break; - s = end + 1; - continue; + if (ircd->sjoininvchar) { + if (*s == ircd->sjoininvchar) { + add_invite(c, myStrGetToken(s, ircd->sjoininvchar, 1)); + if (!end) + break; + s = end + 1; + continue; + } } while (csmodes[(int) *s] != 0) diff --git a/src/chanserv.c b/src/chanserv.c index affa29519..ce8863133 100644 --- a/src/chanserv.c +++ b/src/chanserv.c @@ -2925,6 +2925,10 @@ static int do_drop(User * u) } } + if (ircd->chansqline && (ci->flags & CI_VERBOTEN)) { + anope_cmd_unsqline(ci->name); + } + alog("%s: Channel %s dropped by %s!%s@%s (founder: %s)", s_ChanServ, ci->name, u->nick, u->username, common_get_vhost(u), @@ -6360,6 +6364,10 @@ static int do_forbid(User * u) "\2%s\2 used FORBID on channel \2%s\2", u->nick, ci->name); + if (ircd->chansqline) { + anope_cmd_sqline(ci->name, ((reason) ? reason : "Forbidden")); + } + alog("%s: %s set FORBID for channel %s", s_ChanServ, u->nick, ci->name); notice_lang(s_ChanServ, u, CHAN_FORBID_SUCCEEDED, chan); diff --git a/src/compat.c b/src/compat.c index 9db98fc0f..b9931ced9 100644 --- a/src/compat.c +++ b/src/compat.c @@ -136,19 +136,27 @@ char *strerror(int errnum) /*************************************************************************/ #if !HAVE_STRSIGNAL +/* Windows only supports 6 signals: + * SIGINT, SIGILL, SIGABRT, SIGFPE, SIGSEGV, SIGTERM + * -- codemastr + */ char *strsignal(int signum) { static char buf[32]; switch (signum) { +#ifndef _WIN32 case SIGHUP: strscpy(buf, "Hangup", sizeof(buf)); break; +#endif case SIGINT: strscpy(buf, "Interrupt", sizeof(buf)); break; +#ifndef _WIN32 case SIGQUIT: strscpy(buf, "Quit", sizeof(buf)); break; +#endif #ifdef SIGILL case SIGILL: strscpy(buf, "Illegal instruction", sizeof(buf)); @@ -172,15 +180,18 @@ char *strsignal(int signum) case SIGFPE: strscpy(buf, "Floating point exception", sizeof(buf)); break; +#ifndef _WIN32 case SIGKILL: strscpy(buf, "Killed", sizeof(buf)); break; case SIGUSR1: strscpy(buf, "User signal 1", sizeof(buf)); break; +#endif case SIGSEGV: strscpy(buf, "Segmentation fault", sizeof(buf)); break; +#ifndef _WIN32 case SIGUSR2: strscpy(buf, "User signal 2", sizeof(buf)); break; @@ -190,9 +201,11 @@ char *strsignal(int signum) case SIGALRM: strscpy(buf, "Alarm clock", sizeof(buf)); break; +#endif case SIGTERM: strscpy(buf, "Terminated", sizeof(buf)); break; +#ifndef _WIN32 case SIGSTOP: strscpy(buf, "Suspended (signal)", sizeof(buf)); break; @@ -202,6 +215,7 @@ char *strsignal(int signum) case SIGIO: strscpy(buf, "I/O error", sizeof(buf)); break; +#endif default: snprintf(buf, sizeof(buf), "Signal %d\n", signum); break; @@ -210,4 +224,25 @@ char *strsignal(int signum) } #endif +#ifdef _WIN32 + +#ifdef USE_THREADS +/* Simulate pthread conditional variable waiting */ +int ano_cond_wait(ano_cond_t cond, ano_mutex_t mutex) +{ + ReleaseMutex(mutex); + if (WaitForSingleObject(cond, INFINITE) == WAIT_FAILED) + return 1; + if (WaitForSingleObject(mutex, INFINITE) == WAIT_FAILED) + return 1; + return 0; +} + +/* Used for the cleanup functions */ +ano_thread_start __declspec(thread) cleanup_func = NULL; + +#endif + +#endif + /*************************************************************************/ diff --git a/src/datafiles.c b/src/datafiles.c index 48f460f8c..72c795952 100644 --- a/src/datafiles.c +++ b/src/datafiles.c @@ -101,7 +101,8 @@ static dbFILE *open_db_read(const char *service, const char *filename) int errno_save = errno; #ifndef NOT_MAIN if (errno != ENOENT) - log_perror("Can't read %s database %s", service, f->filename); + log_perror("Can not read %s database %s", service, + f->filename); #endif free(f); errno = errno_save; @@ -126,16 +127,33 @@ static dbFILE *open_db_write(const char *service, const char *filename, { dbFILE *f; int fd; +#ifdef _WIN32 + char buffer[_MAX_PATH]; + char win32filename[MAXPATHLEN]; + + /* Get the current working directory: */ + if (_getcwd(buffer, _MAX_PATH) == NULL) { + alog("debug: Unable to set Current working directory"); + } +#endif f = scalloc(sizeof(*f), 1); if (!f) { #ifndef NOT_MAIN - log_perror("Can't read %s database %s", service, filename); + log_perror("Can not read %s database %s", service, filename); +#else + alog("Can not read %s database %s", service, filename); #endif return NULL; } strscpy(f->filename, filename, sizeof(f->filename)); +#ifndef _WIN32 filename = f->filename; +#else + snprintf(win32filename, sizeof(win32filename), "%s\\%s", buffer, + f->filename); + filename = win32filename; +#endif f->mode = 'w'; *f->backupname = 0; @@ -150,19 +168,30 @@ static dbFILE *open_db_write(const char *service, const char *filename, errno = errno_save; return NULL; } - unlink(f->backupname); +#ifndef _WIN32 + unlink(filename); +#else + DeleteFile(filename); +#endif f->backupfp = fopen(filename, "rb"); +#ifdef _WIN32 + if (!MoveFileExA(filename, f->backupname, MOVEFILE_COPY_ALLOWED) + && GetLastError() != ENOENT) { + int errno_save = GetLastError(); +#else if (rename(filename, f->backupname) < 0 && errno != ENOENT) { int errno_save = errno; +#endif #ifndef NOT_MAIN static int walloped = 0; if (!walloped) { walloped++; - anope_cmd_global(NULL, "Can't back up %s database %s", service, - filename); + anope_cmd_global(NULL, "Can not back up %s database %s", + service, filename); } + alog("errno %d %d %d", errno, ENOENT, EACCES); errno = errno_save; - log_perror("Can't back up %s database %s", service, filename); + log_perror("Can not back up %s database %s", service, filename); if (!NoBackupOkay) { #endif if (f->backupfp) @@ -175,9 +204,17 @@ static dbFILE *open_db_write(const char *service, const char *filename, #endif *f->backupname = 0; } +#ifndef _WIN32 unlink(filename); +#else + DeleteFile(filename); +#endif /* Use open() to avoid people sneaking a new file in under us */ +#ifndef _WIN32 fd = open(filename, O_WRONLY | O_CREAT | O_EXCL, 0666); +#else + fd = open(filename, O_WRONLY | O_CREAT | O_EXCL | _O_BINARY, 0666); +#endif f->fp = fdopen(fd, "wb"); /* will fail and return NULL if fd < 0 */ if (!f->fp || !write_file_version(f, version)) { int errno_save = errno; @@ -193,7 +230,11 @@ static dbFILE *open_db_write(const char *service, const char *filename, #endif if (f->fp) { fclose(f->fp); +#ifndef _WIN32 unlink(filename); +#else + DeleteFile(filename); +#endif } if (*f->backupname && rename(f->backupname, filename) < 0) #ifndef NOT_MAIN @@ -283,7 +324,11 @@ void restore_db(dbFILE * f) if (f->backupfp) fclose(f->backupfp); if (*f->backupname) +#ifndef _WIN32 unlink(f->backupname); +#else + DeleteFile(f->backupname); +#endif } fclose(f->fp); if (!errno_save) @@ -306,7 +351,11 @@ void close_db(dbFILE * f) && strcmp(f->backupname, f->filename) != 0) { if (f->backupfp) fclose(f->backupfp); +#ifndef _WIN32 unlink(f->backupname); +#else + DeleteFile(f->backupname); +#endif } fclose(f->fp); free(f); @@ -539,19 +588,47 @@ static void remove_backups(void) strftime(ext, sizeof(ext), "%Y%m%d", &tm); snprintf(path, sizeof(path), "backups/%s.%s", NickDBName, ext); +#ifndef _WIN32 unlink(path); +#else + DeleteFile(path); +#endif snprintf(path, sizeof(path), "backups/%s.%s", BotDBName, ext); +#ifndef _WIN32 unlink(path); +#else + DeleteFile(path); +#endif snprintf(path, sizeof(path), "backups/%s.%s", ChanDBName, ext); +#ifndef _WIN32 unlink(path); +#else + DeleteFile(path); +#endif snprintf(path, sizeof(path), "backups/%s.%s", OperDBName, ext); +#ifndef _WIN32 unlink(path); +#else + DeleteFile(path); +#endif snprintf(path, sizeof(path), "backups/%s.%s", NewsDBName, ext); +#ifndef _WIN32 unlink(path); +#else + DeleteFile(path); +#endif snprintf(path, sizeof(path), "backups/%s.%s", ExceptionDBName, ext); +#ifndef _WIN32 unlink(path); +#else + DeleteFile(path); +#endif snprintf(path, sizeof(path), "backups/%s.%s", HostDBName, ext); +#ifndef _WIN32 unlink(path); +#else + DeleteFile(path); +#endif } /*************************************************************************/ diff --git a/src/dreamforge.c b/src/dreamforge.c index 4193b9df9..8d90704ec 100644 --- a/src/dreamforge.c +++ b/src/dreamforge.c @@ -100,6 +100,7 @@ IRCDVar ircd[] = { 0, /* +I support */ 0, /* SJOIN ban char */ 0, /* SJOIN except char */ + 0, /* SJOIN invite char */ 0, /* Can remove User Channel Modes with SVSMODE */ 0, /* Sglines are not enforced until user reconnects */ NULL, /* vhost char */ @@ -619,6 +620,9 @@ void anope_pong(char *servname) void anope_cmd_connect(int servernum) { + me_server = + new_server(NULL, ServerName, ServerDesc, SERVER_ISME, NULL); + anope_cmd_capab(); if (servernum == 1) anope_cmd_pass(RemotePassword); diff --git a/src/hybrid.c b/src/hybrid.c index e8ddbe477..8ab40ce4a 100644 --- a/src/hybrid.c +++ b/src/hybrid.c @@ -100,6 +100,7 @@ IRCDVar ircd[] = { 0, /* +I support */ 0, /* SJOIN ban char */ 0, /* SJOIN except char */ + 0, /* SJOIN invite char */ 0, /* Can remove User Channel Modes with SVSMODE */ 0, /* Sglines are not enforced until user reconnects */ NULL, /* vhost char */ @@ -778,6 +779,9 @@ void anope_cmd_svsmode(User * u, int ac, char **av) void anope_cmd_connect(int servernum) { + me_server = + new_server(NULL, ServerName, ServerDesc, SERVER_ISME, NULL); + if (servernum == 1) anope_cmd_pass(RemotePassword); else if (servernum == 2) diff --git a/src/init.c b/src/init.c index 2b77668eb..e26378dfb 100644 --- a/src/init.c +++ b/src/init.c @@ -440,8 +440,9 @@ int init(int ac, char **av) } /* Read configuration file; exit if there are problems. */ - if (!read_config(0)) + if (!read_config(0)) { return -1; + } /* Add IRCD Message handlers */ moduleAddIRCDMsgs(); @@ -452,7 +453,7 @@ int init(int ac, char **av) /* Parse all remaining command-line options. */ parse_options(ac, av); - /* Detach ourselves if requested. */ +#ifndef _WIN32 if (!nofork) { if ((i = fork()) < 0) { perror("fork()"); @@ -470,6 +471,21 @@ int init(int ac, char **av) return -1; } } +#else + /* Initialize winsocks -- codemastr */ + { + WSADATA wsa; + if (WSAStartup(MAKEWORD(1, 1), &wsa)) { + alog("Failed to initialized WinSock library"); + return -1; + } + } + if (!nofork) { + alog("Launching Anope into the background"); + FreeConsole(); + } +#endif + /* Write our PID to the PID file. */ write_pidfile(); @@ -515,21 +531,27 @@ int init(int ac, char **av) } #endif signal(SIGTERM, sighandler); +#ifndef _WIN32 signal(SIGQUIT, sighandler); +#endif if (!DumpCore) { signal(SIGSEGV, sighandler); +#ifndef _WIN32 signal(SIGBUS, sighandler); - signal(SIGILL, sighandler); signal(SIGTRAP, sighandler); +#endif } else { signal(SIGSEGV, SIG_DFL); - signal(SIGBUS, SIG_DFL); - signal(SIGILL, SIG_DFL); - signal(SIGTRAP, SIG_DFL); +#ifndef _WIN32 + signal(SIGBUS, sighandler); + signal(SIGTRAP, sighandler); +#endif } +#ifndef _WIN32 signal(SIGQUIT, sighandler); signal(SIGHUP, sighandler); signal(SIGUSR2, sighandler); +#endif #ifdef SIGIOT signal(SIGIOT, sighandler); @@ -537,8 +559,10 @@ int init(int ac, char **av) signal(SIGFPE, sighandler); #if !defined(USE_THREADS) || !defined(LINUX20) +#ifndef _WIN32 signal(SIGUSR1, sighandler); /* This is our "out-of-memory" panic switch */ #endif +#endif /* Initialize multi-language support */ lang_init(); @@ -659,15 +683,6 @@ int init(int ac, char **av) alog("Info: Not reflecting database records."); } #endif - /* Make myself known to myself in the serverlist */ - if (UseTS6 && ircd->ts6) { - me_server = - new_server(NULL, ServerName, ServerDesc, SERVER_ISME, TS6SID); - } else { - me_server = - new_server(NULL, ServerName, ServerDesc, SERVER_ISME, NULL); - } - /* Connect to the remote server */ servsock = conn(RemoteServer, RemotePort, LocalHost, LocalPort); if (servsock < 0 && RemoteServer2) { diff --git a/src/language.c b/src/language.c index a43e03d65..849d7a4a6 100644 --- a/src/language.c +++ b/src/language.c @@ -73,7 +73,11 @@ static void load_lang(int index, const char *filename) index, filename); } snprintf(buf, sizeof(buf), "languages/%s", filename); +#ifndef _WIN32 if (!(f = fopen(buf, "r"))) { +#else + if (!(f = fopen(buf, "rb"))) { +#endif log_perror("Failed to load language %d (%s)", index, filename); return; } else if (read_int32(&num, f) < 0) { @@ -58,7 +58,11 @@ static void remove_log(void) if (!get_logname(name, sizeof(name), &tm)) return; +#ifndef _WIN32 unlink(name); +#else + DeleteFile(name); +#endif } /*************************************************************************/ @@ -314,3 +318,48 @@ void fatal_perror(const char *fmt, ...) } /*************************************************************************/ + +/* Same thing, but do it like perror(). + * This is for socket errors. On *nix, it works just like fatal_perror, + * on Win32, it uses the socket error code and formatting functions. + */ + +void fatal_sockerror(const char *fmt, ...) +{ + va_list args; + time_t t; + struct tm tm; + char buf[256], buf2[4096]; + int errno_save = ano_sockgeterr(); + + checkday(); + + va_start(args, fmt); + time(&t); + tm = *localtime(&t); +#if HAVE_GETTIMEOFDAY + if (debug) { + char *s; + struct timeval tv; + gettimeofday(&tv, NULL); + strftime(buf, sizeof(buf) - 1, "[%b %d %H:%M:%S", &tm); + s = buf + strlen(buf); + s += snprintf(s, sizeof(buf) - (s - buf), ".%06d", tv.tv_usec); + strftime(s, sizeof(buf) - (s - buf) - 1, " %Y] ", &tm); + } else { +#endif + strftime(buf, sizeof(buf) - 1, "[%b %d %H:%M:%S %Y] ", &tm); +#if HAVE_GETTIMEOFDAY + } +#endif + vsnprintf(buf2, sizeof(buf2), fmt, args); + if (logfile) + fprintf(logfile, "%sFATAL: %s: %s\n", buf, buf2, + ano_sockstrerror(errno_save)); + if (stderr) + fprintf(stderr, "%sFATAL: %s: %s\n", buf, buf2, + ano_sockstrerror(errno_save)); + if (servsock >= 0) + wallops(NULL, "FATAL ERROR! %s: %s", buf2, strerror(errno_save)); + exit(1); +} diff --git a/src/main.c b/src/main.c index 6ff76b67f..d75a88f00 100644 --- a/src/main.c +++ b/src/main.c @@ -282,6 +282,7 @@ static void services_shutdown(void) void sighandler(int signum) { if (started) { +#ifndef _WIN32 if (signum == SIGHUP) { /* SIGHUP = save databases and restart */ signal(SIGHUP, SIG_IGN); signal(SIGUSR2, SIG_IGN); @@ -300,7 +301,8 @@ void sighandler(int signum) quitmsg = "Restart attempt failed--SERVICES_BIN not defined (rerun configure)"; #endif - + } else if (signum == SIGQUIT) { + /* had to move it to here to make win32 happy */ } else if (signum == SIGUSR2) { alog("Received SIGUSR2: Saving Databases & Rehash Configuration"); @@ -315,9 +317,13 @@ void sighandler(int signum) } return; - } else if (signum == SIGTERM) { + } else +#endif + if (signum == SIGTERM) { signal(SIGTERM, SIG_IGN); +#ifndef _WIN32 signal(SIGHUP, SIG_IGN); +#endif alog("Received SIGTERM, exiting."); @@ -326,7 +332,6 @@ void sighandler(int signum) quitmsg = "Shutting down on SIGTERM"; services_shutdown(); exit(0); - } else if (signum == SIGINT) { if (nofork) { signal(SIGINT, SIG_IGN); @@ -337,8 +342,6 @@ void sighandler(int signum) services_shutdown(); exit(0); } - } else if (signum == SIGQUIT) { - /* nothing -- terminate below */ } else if (!waiting) { alog("PANIC! buffer = %s", inbuf); /* Cut off if this would make IRC command >510 characters. */ @@ -347,7 +350,7 @@ void sighandler(int signum) inbuf[447] = '>'; inbuf[448] = 0; } - anope_cmd_global(NULL, "PANIC! buffer = %s\r\n", inbuf); + wallops(NULL, "PANIC! buffer = %s\r\n", inbuf); } else if (waiting < 0) { /* This is static on the off-chance we run low on stack */ static char buf[BUFSIZE]; @@ -403,14 +406,13 @@ void sighandler(int signum) default: snprintf(buf, sizeof(buf), "waiting=%d", waiting); } - anope_cmd_global(NULL, "PANIC! %s (%s)", buf, - strsignal(signum)); + wallops(NULL, "PANIC! %s (%s)", buf, strsignal(signum)); alog("PANIC! %s (%s)", buf, strsignal(signum)); } } if ( -#if !defined(USE_THREADS) || !defined(LINUX20) +#if (!defined(USE_THREADS) || !defined(LINUX20)) && !defined(_WIN32) signum == SIGUSR1 || #endif !(quitmsg = calloc(BUFSIZE, 1))) { @@ -599,6 +601,7 @@ int main(int ac, char **av, char **envp) void do_backtrace(int show_segheader) { +#ifndef _WIN32 #ifdef HAVE_BACKTRACE void *array[50]; size_t size; @@ -619,9 +622,9 @@ void do_backtrace(int show_segheader) free(strings); alog("Backtrace: complete"); #else - if (show_segheader) { - alog("Backtrace: Segmentation fault detected"); - } - alog("Backtrace: not available on this system"); + alog("Backtrace: not available on this platform"); +#endif +#else + alog("Backtrace: not available on this windows"); #endif } diff --git a/src/makefile.win32 b/src/makefile.win32 new file mode 100644 index 000000000..e7434cdba --- /dev/null +++ b/src/makefile.win32 @@ -0,0 +1,107 @@ +# Make file for Win32 +# +# (C) 2003-2005 Anope Team +# Contact us at info@anope.org +# +# Please read COPYING and README for further details. +# +# Based on the original code of Epona by Lara. +# Based on the original code of Services by Andy Church. +# +# $Id:$ +# + +# Source Makefile + +include ../Makefile.inc.win32 + +########################################################################### + +OBJS = actions.obj base64.obj botserv.obj channels.obj chanserv.obj commands.obj compat.obj \ + converter.obj config.obj datafiles.obj encrypt.obj helpserv.obj hostserv.obj \ + init.obj language.obj list.obj log.obj mail.obj main.obj memory.obj memoserv.obj \ + messages.obj misc.obj modules.obj news.obj nickserv.obj operserv.obj \ + process.obj proxy.obj send.obj servers.obj sessions.obj slist.obj sockutil.obj \ + timeout.obj users.obj $(RDB_O) $(MYSQL_O) $(CAPAB_O) + +SRCS = actions.c base64.c botserv.c channels.c chanserv.c commands.c compat.c converter.c \ + config.c datafiles.c encrypt.c helpserv.c hostserv.c init.c language.c list.c log.c mail.c main.c \ + memory.c memoserv.c messages.c misc.c modules.c news.c nickserv.c operserv.c \ + process.c proxy.c send.c servers.obj sessions.c slist.c sockutil.c \ + timeout.c users.c $(RDB_C) $(MYSQL_C) $(CAPAB_C) + +########################################################################### + +.c.obj: + $(CC) $(CFLAGS) $(IRCTYPE) -c $< + +all: $(PROGRAM) + +$(PROGRAM): $(OBJS) win32.res + $(CC) $(OBJS) win32.res /link /out:$(PROGRAM) /implib:anope.lib $(LIBS) $(LFLAGS) $(MLIBS) $(ELIBS) + +spotless: + -@erase *.obj *.exe *.exp *.lib tools\*.exe *.res + +install: + -@copy anope.exe ..\anope.exe + -@copy tools\anopesmtp.exe ..\anopesmtp.exe + -@mkdir ..\$(DATDEST)\bin + -@copy bin\* ..\$(DATDEST)\bin + +win32.res: win32.rc + $(RC) /l 0x409 /fowin32.res win32.rc + + +########################################################################### + +# Catch any changes in compilation options at the top of this file +$(OBJS): + +actions.obj: actions.c ..\include\services.h +base64.obj: base64.c ..\include\services.h +botserv.obj: botserv.c ..\include\services.h ..\include\pseudo.h ..\include\language.h +channels.obj: channels.c ..\include\services.h +chanserv.obj: chanserv.c ..\include\services.h ..\include\pseudo.h +commands.obj: commands.c ..\include\services.h ..\include\commands.h ..\include\language.h +compat.obj: compat.c ..\include\services.h +config.obj: config.c ..\include\services.h +converter.obj: converter.c ..\include\services.h ..\include\datafiles.h +datafiles.obj: datafiles.c ..\include\services.h ..\include\datafiles.h +encrypt.obj: encrypt.c ..\include\encrypt.h ..\include\sysconf.h +init.obj: init.c ..\include\services.h +hostserv.obj: hostserv.c ..\include\services.h ..\include\pseudo.h +language.obj: language.c ..\include\services.h ..\include\language.h +list.obj: list.c ..\include\services.h +log.obj: log.c ..\include\services.h ..\include\pseudo.h +mail.obj: mail.c ..\include\services.h ..\include\language.h +main.obj: main.c ..\include\services.h ..\include\timeout.h ..\include\version.h +memory.obj: memory.c ..\include\services.h +memoserv.obj: memoserv.c ..\include\services.h ..\include\pseudo.h +messages.obj: messages.c ..\include\services.h ..\include\messages.h ..\include\language.h +misc.obj: misc.c ..\include\services.h ..\include\language.h +news.obj: news.c ..\include\services.h ..\include\pseudo.h +nickserv.obj: nickserv.c ..\include\services.h ..\include\pseudo.h +operserv.obj: operserv.c ..\include\services.h ..\include\pseudo.h +process.obj: process.c ..\include\services.h ..\include\messages.h +proxy.obj: proxy.c ..\include\services.h ..\include\pseudo.h +send.obj: send.c ..\include\services.h +servers.obj: servers.c ..\include\services.h +sessions.obj: sessions.c ..\include\services.h ..\include\pseudo.h +slist.obj: slist.c ..\include\services.h ..\include\slist.h +sockutil.obj: sockutil.c ..\include\services.h +timeout.obj: timeout.c ..\include\services.h ..\include\timeout.h +users.obj: users.c ..\include\services.h +vsnprintf.obj: vsnprintf.c + +########################################################################### + +..\include\services.h: ..\include\sysconf.h ..\include\config.h ..\include\extern.h + +..\include\extern.h: ..\include\slist.h + +..\include\pseudo.h: ..\include\commands.h ..\include\language.h ..\include\timeout.h ..\include\encrypt.h ..\include\datafiles.h ..\include\slist.h + +########################################################################### + +FRC: diff --git a/src/memory.c b/src/memory.c index 415853416..6c1d8dda7 100644 --- a/src/memory.c +++ b/src/memory.c @@ -38,10 +38,14 @@ void *smalloc(long size) buf = malloc(size); if (!buf) #if !defined(USE_THREADS) || !defined(LINUX20) +#ifndef _WIN32 raise(SIGUSR1); #else abort(); #endif +#else + abort(); +#endif return buf; } @@ -63,10 +67,14 @@ void *scalloc(long elsize, long els) buf = calloc(elsize, els); if (!buf) #if !defined(USE_THREADS) || !defined(LINUX20) +#ifndef _WIN32 raise(SIGUSR1); #else abort(); #endif +#else + abort(); +#endif return buf; } @@ -88,10 +96,14 @@ void *srealloc(void *oldptr, long newsize) buf = realloc(oldptr, newsize); if (!buf) #if !defined(USE_THREADS) || !defined(LINUX20) +#ifndef _WIN32 raise(SIGUSR1); #else abort(); #endif +#else + abort(); +#endif return buf; } @@ -116,10 +128,14 @@ char *sstrdup(const char *src) #endif if (!ret) #if !defined(USE_THREADS) || !defined(LINUX20) +#ifndef _WIN32 raise(SIGUSR1); #else abort(); #endif +#else + abort(); +#endif } else { alog("sstrdup() called with NULL-arg"); if (debug) diff --git a/src/modules.c b/src/modules.c index 32791dfd5..01d1571f3 100644 --- a/src/modules.c +++ b/src/modules.c @@ -16,7 +16,7 @@ #include "language.h" #include "version.h" -#ifdef USE_MODULES +#if defined(USE_MODULES) && !defined(_WIN32) #include <dlfcn.h> /* Define these for systems without them */ #ifndef RTLD_NOW @@ -33,6 +33,10 @@ #endif #endif +#ifdef _WIN32 +const char *ano_moderr(void); +#endif + /** * Declare all the list's we want to use here **/ @@ -283,8 +287,8 @@ int moduleCopyFile(char *name) strncat(output, name, 4095 - len); strncat(input, name, 4095 - len); len += strlen(output); - strncat(output, ".so", 4095 - len); - strncat(input, ".so", 4095 - len); + strncat(output, MODULE_EXT, 4095 - len); + strncat(input, MODULE_EXT, 4095 - len); if ((source = fopen(input, "r")) == NULL) { return MOD_ERR_NOEXIST; @@ -344,22 +348,19 @@ int loadModule(Module * m, User * u) buf[4095] = '\0'; m->filename = sstrdup(buf); -#ifdef HAS_RTLD_LOCAL - m->handle = dlopen(m->filename, RTLD_LAZY | RTLD_LOCAL); -#else - m->handle = dlopen(m->filename, RTLD_LAZY); -#endif - if ((err = dlerror()) != NULL) { + ano_modclearerr(); + m->handle = ano_modopen(m->filename); + if ((err = ano_moderr()) != NULL) { alog(err); if (u) { notice_lang(s_OperServ, u, OPER_MODULE_LOAD_FAIL, m->name); } return MOD_ERR_NOLOAD; } - - func = dlsym(m->handle, DL_PREFIX "AnopeInit"); - if ((err = dlerror()) != NULL) { - dlclose(m->handle); /* If no AnopeInit - it isnt an Anope Module, close it */ + ano_modclearerr(); + func = ano_modsym(m->handle, "AnopeInit"); + if ((err = ano_moderr()) != NULL) { + ano_modclose(m->handle); /* If no AnopeInit - it isnt an Anope Module, close it */ return MOD_ERR_NOLOAD; } if (func) { @@ -421,13 +422,13 @@ int unloadModule(Module * m, User * u) return MOD_ERR_UNKNOWN; } - func = dlsym(m->handle, DL_PREFIX "AnopeFini"); + func = ano_modsym(m->handle, "AnopeFini"); if (func) { func(); /* exec AnopeFini */ } - if ((dlclose(m->handle)) != 0) { - alog(dlerror()); + if ((ano_modclose(m->handle)) != 0) { + alog(ano_moderr()); if (u) { notice_lang(s_OperServ, u, OPER_MODULE_REMOVE_FAIL, m->name); } @@ -2094,4 +2095,18 @@ boolean moduleMinVersion(int major, int minor, int patch, int build) return ret; } +#ifdef _WIN32 +const char *ano_moderr(void) +{ + static char errbuf[513]; + DWORD err = GetLastError(); + if (err == 0) + return NULL; + FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_IGNORE_INSERTS, NULL, err, 0, errbuf, 512, + NULL); + return errbuf; +} +#endif + /* EOF */ diff --git a/src/modules/makefile.inc.win32 b/src/modules/makefile.inc.win32 new file mode 100644 index 000000000..95c0c84b1 --- /dev/null +++ b/src/modules/makefile.inc.win32 @@ -0,0 +1,2 @@ +SRCS=hs_moo.c ircd_catserv.c + diff --git a/src/modules/makefile.win32 b/src/modules/makefile.win32 new file mode 100644 index 000000000..a2cca02e8 --- /dev/null +++ b/src/modules/makefile.win32 @@ -0,0 +1,24 @@ +include ../../Makefile.inc.win32 +include ./Makefile.inc.win32 + +OBJECTS= $(SRCS:.c=.dll) +CFLAGS=/LD /MD /D MODULE_COMPILE $(CFLAGS) /I"../../include" +LFLAGS=/link ../anope.lib wsock32.lib libmysql.lib $(LFLAGS) $(MYSQL_LIB_PATH) /export:AnopeInit + +all: $(OBJECTS) + +distclean: clean spotless + +.c.dll: + $(CC) $(CFLAGS) $(IRCTYPE) $< $(LFLAGS) + +clean: + -@del *.obj + +spotless: clean + -@del *.dll *.lib *.exp + +install: + -@mkdir ..\..\$(DATDEST)\modules + -@mkdir ..\..\$(DATDEST)\modules\runtime + -@copy *.dll ..\..\$(DATDEST)\modules diff --git a/src/mypasql.c b/src/mypasql.c new file mode 100644 index 000000000..a66850c84 --- /dev/null +++ b/src/mypasql.c @@ -0,0 +1,122 @@ +#include <winsock.h> +#include <stdio.h> +#include <mysql.h> + +MYSQL *mysql; +MYSQL_RES *result = NULL; +MYSQL_ROW row; + +int __stdcall mysql_Connect(char *server, char *user, char *pass) +{ + mysql = mysql_init(NULL); + return (int) mysql_real_connect(mysql, server, user, pass, NULL, 0, + NULL, 0); +} + +int __stdcall mysql_SelectDb(char *db) +{ + return (int) mysql_select_db(mysql, db); +} + +const char *__stdcall mysql_Error() +{ + return mysql_error(mysql); +} + +int __stdcall mysql_Query(char *query) +{ + if (result) { + mysql_free_result(result); + result = NULL; + } + return (int) mysql_real_query(mysql, query, strlen(query)); +} + +int __stdcall mysql_NumRows() +{ + if (!result) + result = mysql_store_result(mysql); + return mysql_num_rows(result); +} + +char *strip(char *str) +{ + char *c; + if ((c = strrchr(str, '\n'))) + *c = 0; + if ((c = strrchr(str, '\r'))) + *c = 0; + return str; +} + +void add_line(char **buf, char *line) +{ + int oldlen; + char *tmp; + + if (*buf != NULL) { + oldlen = strlen(*buf); + tmp = malloc(oldlen + 1); + strcpy(tmp, *buf); + *buf = realloc(*buf, oldlen + strlen(line) + 1); + strcpy(*buf, tmp); + strcat(*buf, line); + free(tmp); + } else + *buf = strdup(line); +} + +int __stdcall mysql_LoadFromFile(char *file) +{ + FILE *fd = fopen(file, "r"); + char line[1024]; + char *query = NULL; + + + if (!fd) + return 0; + while (fgets(line, 1024, fd)) { + int len; + strip(line); + len = strlen(line); + if (!*line || (*line == '-' && *(line + 1) == '-')) + continue; + else if (line[len - 1] == ';') { /* End of a query */ + line[len - 1] = 0; + add_line(&query, line); + if (mysql_real_query(mysql, query, strlen(query))) { + free(query); + return 0; + } + free(query); + query = NULL; + } + + else + add_line(&query, line); + } + return 1; +} + +int __stdcall mysql_NumFields() +{ + if (!result) + result = mysql_store_result(mysql); + return mysql_num_fields(result); +} + +int __stdcall mysql_FetchRow() +{ + if (!result) + result = mysql_store_result(mysql); + row = mysql_fetch_row(result); + return (int) row; +} + +char *__stdcall mysql_FetchField(int i) +{ + if (i >= mysql_num_fields(result)) + return NULL; + else + return row[i]; +} diff --git a/src/mypasql.def b/src/mypasql.def new file mode 100644 index 000000000..f04df9556 --- /dev/null +++ b/src/mypasql.def @@ -0,0 +1,10 @@ +EXPORTS
+mysql_Connect
+mysql_Error
+mysql_SelectDb
+mysql_Query
+mysql_NumRows
+mysql_NumFields
+mysql_LoadFromFile
+mysql_FetchRow
+mysql_FetchField
diff --git a/src/nickserv.c b/src/nickserv.c index ae97855e4..bf8d5cd99 100644 --- a/src/nickserv.c +++ b/src/nickserv.c @@ -2794,6 +2794,10 @@ static int do_drop(User * u) if (readonly) notice_lang(s_NickServ, u, READ_ONLY_MODE); + if (ircd->sqline && (na->status & NS_VERBOTEN)) { + anope_cmd_unsqline(na->nick); + } + alog("%s: %s!%s@%s dropped nickname %s (group %s) (e-mail: %s)", s_NickServ, u->nick, u->username, common_get_vhost(u), na->nick, na->nc->display, @@ -4267,6 +4271,11 @@ static int do_forbid(User * u) collide(na, 0); } + + if (ircd->sqline) { + anope_cmd_sqline(na->nick, ((reason) ? reason : "Forbidden")); + } + if (WallForbid) anope_cmd_global(s_NickServ, "\2%s\2 used FORBID on \2%s\2", u->nick, nick); diff --git a/src/plexus.c b/src/plexus.c index 8408c9018..21e89b502 100644 --- a/src/plexus.c +++ b/src/plexus.c @@ -100,6 +100,7 @@ IRCDVar ircd[] = { 1, /* +I support */ 0, /* SJOIN ban char */ 0, /* SJOIN except char */ + 0, /* SJOIN invite char */ 0, /* Can remove User Channel Modes with SVSMODE */ 0, /* Sglines are not enforced until user reconnects */ "h", /* vhost char */ @@ -839,6 +840,9 @@ void anope_cmd_svsmode(User * u, int ac, char **av) void anope_cmd_connect(int servernum) { + me_server = + new_server(NULL, ServerName, ServerDesc, SERVER_ISME, NULL); + if (servernum == 1) anope_cmd_pass(RemotePassword); else if (servernum == 2) diff --git a/src/proxy.c b/src/proxy.c index d1c90ff35..f2e7ae96e 100644 --- a/src/proxy.c +++ b/src/proxy.c @@ -45,11 +45,16 @@ void ntoa(struct in_addr addr, char *ipaddr, int len) /* Proxy queue; access controlled by queuemut */ SList pxqueue; -pthread_mutex_t queuemut = PTHREAD_MUTEX_INITIALIZER; -pthread_cond_t queuecond = PTHREAD_COND_INITIALIZER; +#ifndef _WIN32 +ano_mutex_t queuemut = PTHREAD_MUTEX_INITIALIZER; +ano_cond_t queuecond = PTHREAD_COND_INITIALIZER; #if !defined(HAVE_GETHOSTBYNAME_R6) && !defined(HAVE_GETHOSTBYNAME_R5) && !defined(HAVE_GETHOSTBYNAME_R3) -pthread_mutex_t resmut = PTHREAD_MUTEX_INITIALIZER; +ano_mutex_t resmut = PTHREAD_MUTEX_INITIALIZER; +#endif +#else +ano_mutex_t queuemut; +ano_cond_t queuecond; #endif static uint32 aton(char *ipaddr); @@ -259,7 +264,7 @@ int proxy_check(char *nick, char *host, uint32 ip) static int proxy_connect(unsigned long ip, unsigned short port) { struct sockaddr_in sin; - int s; + ano_socket_t s; fd_set fds; struct timeval tv; @@ -269,8 +274,8 @@ static int proxy_connect(unsigned long ip, unsigned short port) if ((s = socket(PF_INET, SOCK_STREAM, 0)) == -1) return -1; - if (fcntl(s, F_SETFL, O_NONBLOCK) == -1) { - close(s); + if (ano_socksetnonb(s) == -1) { + ano_sockclose(s); return -1; } @@ -281,8 +286,8 @@ static int proxy_connect(unsigned long ip, unsigned short port) sin.sin_port = htons(port); if (connect(s, (struct sockaddr *) &sin, sizeof(struct sockaddr_in)) == - -1 && errno != EINPROGRESS) { - close(s); + -1 && ano_sockerrnonb(ano_sockgeterr())) { + ano_sockclose(s); return -1; } @@ -293,14 +298,18 @@ static int proxy_connect(unsigned long ip, unsigned short port) tv.tv_usec = 0; if (select(s + 1, NULL, &fds, NULL, &tv) <= 0) { - close(s); + ano_sockclose(s); return -1; } errlen = sizeof(int); +#ifndef _WIN32 if (getsockopt(s, SOL_SOCKET, SO_ERROR, &error, &errlen) == -1 +#else + if (getsockopt(s, SOL_SOCKET, SO_ERROR, (char *) &error, &errlen) == -1 +#endif || error != 0) { - close(s); + ano_sockclose(s); return -1; } @@ -347,14 +356,19 @@ void proxy_expire() int proxy_init(void) { int i; - pthread_t th; + ano_thread_t th; slist_init(&pxqueue); +#ifdef _WIN32 + queuemut = CreateMutex(NULL, FALSE, NULL); + queuecond = CreateEvent(NULL, FALSE, FALSE, NULL); +#endif + for (i = 1; i <= ProxyThreads; i++) { - if (pthread_create(&th, NULL, proxy_thread_main, NULL)) + if (ano_thread_create(th, proxy_thread_main, NULL)) return 0; - if (pthread_detach(th)) + if (ano_thread_detach(th)) return 0; if (debug) alog("debug: Creating proxy thread %ld (%d of %d)", (long) th, @@ -379,8 +393,8 @@ static void proxy_queue_lock(void) { if (debug) alog("debug: Thread %ld: Locking proxy queue mutex", - (long) pthread_self()); - pthread_mutex_lock(&queuemut); + (long) ano_thread_self()); + ano_mutex_lock(queuemut); } /*************************************************************************/ @@ -389,8 +403,8 @@ static void proxy_queue_signal(void) { if (debug) alog("debug: Thread %ld: Signaling proxy queue condition", - (long) pthread_self()); - pthread_cond_signal(&queuecond); + (long) ano_thread_self()); + ano_cond_signal(queuecond); } /*************************************************************************/ @@ -399,8 +413,8 @@ static void proxy_queue_unlock(void) { if (debug) alog("debug: Thread %ld: Unlocking proxy queue mutex", - (long) pthread_self()); - pthread_mutex_unlock(&queuemut); + (long) ano_thread_self()); + ano_mutex_unlock(queuemut); } /*************************************************************************/ @@ -409,8 +423,8 @@ static void proxy_queue_wait(void) { if (debug) alog("debug: Thread %ld: waiting proxy queue condition", - (long) pthread_self()); - pthread_cond_wait(&queuecond, &queuemut); + (long) ano_thread_self()); + ano_cond_wait(queuecond, queuemut); } /*************************************************************************/ @@ -458,9 +472,12 @@ static uint32 proxy_resolve(char *host) struct hostent hent; struct hostent_data data; hentp = gethostbyname_r(host, &hent, &data); +#elif defined(_WIN32) + /* MSVC's gethostbyname is thread safe -- codemastr */ + hentp = gethostbyname(host); #else /* Make it safe that way */ - pthread_mutex_lock(&resmut); + ano_mutex_lock(resmut); hentp = gethostbyname(host); #endif @@ -472,11 +489,11 @@ static uint32 proxy_resolve(char *host) addr.s_addr = ip; ntoa(addr, ipbuf, sizeof(ipbuf)); alog("debug: Thread %ld: resolved %s to %s", - (long) pthread_self(), host, ipbuf); + (long) ano_thread_self(), host, ipbuf); } } -#if !defined(HAVE_GETHOSTBYNAME_R6) && !defined(HAVE_GETHOSTBYNAME_R5) && !defined(HAVE_GETHOSTBYNAME_R3) - pthread_mutex_unlock(&resmut); +#if !defined(HAVE_GETHOSTBYNAME_R6) && !defined(HAVE_GETHOSTBYNAME_R5) && !defined(HAVE_GETHOSTBYNAME_R3) && !defined(_WIN32) + ano_mutex_unlock(resmut); #endif return ip; @@ -520,17 +537,17 @@ static int proxy_scan(uint32 ip) buf[8] = 0; if (send(s, buf, 9, 0) != 9) { - close(s); + ano_sockclose(s); return HC_NORMAL; } if (proxy_read(s, buf, 2) != 2) { - close(s); + ano_sockclose(s); continue; } if (buf[1] == 90) { - close(s); + ano_sockclose(s); return HC_SOCKS4; } @@ -541,19 +558,19 @@ static int proxy_scan(uint32 ip) uint32 sip; if (send(s, "\5\1\0", 3, 0) != 3) { - close(s); + ano_sockclose(s); continue; } memset(buf, 0, sizeof(buf)); if (proxy_read(s, buf, 2) != 2) { - close(s); + ano_sockclose(s); continue; } if (buf[0] != 5 || buf[1] != 0) { - close(s); + ano_sockclose(s); continue; } @@ -572,14 +589,14 @@ static int proxy_scan(uint32 ip) buf[9] = ((unsigned short) ProxyTestPort) & 0xFF; if (send(s, buf, 10, 0) != 10) { - close(s); + ano_sockclose(s); continue; } memset(buf, 0, sizeof(buf)); if (proxy_read(s, buf, 2) != 2) { - close(s); + ano_sockclose(s); continue; } @@ -589,7 +606,7 @@ static int proxy_scan(uint32 ip) } } - close(s); + ano_sockclose(s); } /* Scan for HTTP proxy */ @@ -613,12 +630,12 @@ static int proxy_scan(uint32 ip) if (!strnicmp(buf, "HTTP/1.0 200", 12) || !stricmp(buf, "HTTP/1.1 200 Co")) { /* Apache may return 200 OK even if it's not processing the CONNECT request. :/ */ - close(s); + ano_sockclose(s); return HC_HTTP; } } } - close(s); + ano_sockclose(s); } } @@ -629,11 +646,11 @@ static int proxy_scan(uint32 ip) if (proxy_read(s, buf, 8) == 8) { buf[8] = '\0'; if (!stricmp(buf, "Wingate>") || !stricmp(buf, "Too many")) { - close(s); + ano_sockclose(s); return HC_WINGATE; } } - close(s); + ano_sockclose(s); } return HC_NORMAL; @@ -646,24 +663,24 @@ static int proxy_scan(uint32 ip) static void *proxy_thread_main(void *arg) { while (1) { - pthread_cleanup_push(&proxy_queue_cleanup_unlock, NULL); + ano_cleanup_push(proxy_queue_cleanup_unlock, NULL); proxy_queue_lock(); proxy_queue_wait(); - pthread_cleanup_pop(1); + ano_cleanup_pop(1); /* We loop until there is no more host to check in the list */ while (1) { HostCache *hc = NULL; int status; - pthread_cleanup_push(&proxy_queue_cleanup_unlock, NULL); + ano_cleanup_push(proxy_queue_cleanup_unlock, NULL); proxy_queue_lock(); if (pxqueue.count > 0) { hc = pxqueue.list[0]; hc->status = HC_PROGRESS; slist_delete(&pxqueue, 0); } - pthread_cleanup_pop(1); + ano_cleanup_pop(1); if (!hc) break; diff --git a/src/ptlink.c b/src/ptlink.c index 1cc053d11..56704ffd7 100644 --- a/src/ptlink.c +++ b/src/ptlink.c @@ -100,6 +100,7 @@ IRCDVar ircd[] = { 0, /* +I support */ 0, /* SJOIN ban char */ 0, /* SJOIN except char */ + 0, /* SJOIN invite char */ 0, /* Can remove User Channel Modes with SVSMODE */ 0, /* Sglines are not enforced until user reconnects */ NULL, /* vhost char */ @@ -733,6 +734,9 @@ void anope_cmd_pong(char *servname, char *who) void anope_cmd_connect(int servernum) { + me_server = + new_server(NULL, ServerName, ServerDesc, SERVER_ISME, NULL); + if (servernum == 1) anope_cmd_pass(RemotePassword); else if (servernum == 2) diff --git a/src/rageircd.c b/src/rageircd.c index 8fa7de622..6521e5934 100644 --- a/src/rageircd.c +++ b/src/rageircd.c @@ -101,6 +101,7 @@ IRCDVar ircd[] = { 1, /* +I support */ 0, /* SJOIN ban char */ 0, /* SJOIN except char */ + 0, /* SJOIN invite char */ 0, /* Can remove User Channel Modes with SVSMODE */ 0, /* Sglines are not enforced until user reconnects */ "x", /* vhost char */ @@ -744,6 +745,18 @@ void anope_cmd_pong(char *servname, char *who) void anope_cmd_connect(int servernum) { + char buf[16]; + *buf = '\0'; + + if (Numeric) { + snprintf(buf, sizeof(buf), "%d", Numeric); + me_server = + new_server(NULL, ServerName, ServerDesc, SERVER_ISME, buf); + } else { + me_server = + new_server(NULL, ServerName, ServerDesc, SERVER_ISME, NULL); + } + if (servernum == 1) anope_cmd_pass(RemotePassword); else if (servernum == 2) diff --git a/src/ratbox.c b/src/ratbox.c index 3339088d0..45046d654 100644 --- a/src/ratbox.c +++ b/src/ratbox.c @@ -102,6 +102,7 @@ IRCDVar ircd[] = { 1, /* +I support */ 0, /* SJOIN ban char */ 0, /* SJOIN except char */ + 0, /* SJOIN invite char */ 0, /* Can remove User Channel Modes with SVSMODE */ 0, /* Sglines are not enforced until user reconnects */ NULL, /* vhost char */ @@ -912,6 +913,14 @@ void anope_cmd_svsmode(User * u, int ac, char **av) void anope_cmd_connect(int servernum) { + /* Make myself known to myself in the serverlist */ + if (UseTS6) { + me_server = + new_server(NULL, ServerName, ServerDesc, SERVER_ISME, TS6SID); + } else { + me_server = + new_server(NULL, ServerName, ServerDesc, SERVER_ISME, NULL); + } if (servernum == 1) anope_cmd_pass(RemotePassword); else if (servernum == 2) diff --git a/src/sockutil.c b/src/sockutil.c index f6b3df156..d5f390fbf 100644 --- a/src/sockutil.c +++ b/src/sockutil.c @@ -53,15 +53,15 @@ int32 read_buffer_len() * @param int Length of buffer * @return int */ -static int buffered_read(int fd, char *buf, int len) +static int buffered_read(ano_socket_t fd, char *buf, int len) { int nread, left = len; fd_set fds; struct timeval tv = { 0, 0 }; - int errno_save = errno; + int errno_save = ano_sockgeterr(); if (fd < 0) { - errno = EBADF; + ano_sockseterr(SOCKERR_EBADF); return -1; } while (left > 0) { @@ -80,8 +80,8 @@ static int buffered_read(int fd, char *buf, int len) maxread = read_buftop - read_bufend - 1; else maxread = read_buftop - read_bufend; - nread = read(fd, read_bufend, maxread); - errno_save = errno; + nread = ano_sockread(fd, read_bufend, maxread); + errno_save = ano_sockgeterr(); if (debug >= 3) alog("debug: buffered_read wanted %d, got %d", maxread, nread); @@ -118,7 +118,7 @@ static int buffered_read(int fd, char *buf, int len) alog("debug: buffered_read(%d,%p,%d) returning %d", fd, buf, len, len - left); } - errno = errno_save; + ano_sockseterr(errno_save); return len - left; } @@ -130,17 +130,17 @@ static int buffered_read(int fd, char *buf, int len) * @param fd File Pointer * @return int */ -static int buffered_read_one(int fd) +static int buffered_read_one(ano_socket_t fd) { int nread; fd_set fds; struct timeval tv = { 0, 0 }; char c; struct timeval *tvptr = (read_bufend == read_curpos ? NULL : &tv); - int errno_save = errno; + int errno_save = ano_sockgeterr(); if (fd < 0) { - errno = EBADF; + ano_sockseterr(SOCKERR_EBADF); return -1; } FD_ZERO(&fds); @@ -157,8 +157,8 @@ static int buffered_read_one(int fd) maxread = read_buftop - read_bufend - 1; else maxread = read_buftop - read_bufend; - nread = read(fd, read_bufend, maxread); - errno_save = errno; + nread = ano_sockread(fd, read_bufend, maxread); + errno_save = ano_sockgeterr(); if (debug >= 3) alog("debug: buffered_read_one wanted %d, got %d", maxread, nread); @@ -171,7 +171,7 @@ static int buffered_read_one(int fd) if (read_curpos == read_bufend) { /* No more data on socket */ if (debug >= 4) alog("debug: buffered_read_one(%d) returning %d", fd, EOF); - errno = errno_save; + ano_sockseterr(errno_save); return EOF; } c = *read_curpos++; @@ -210,7 +210,7 @@ static int flush_write_buffer(int wait) { fd_set fds; struct timeval tv = { 0, 0 }; - int errno_save = errno; + int errno_save = ano_sockgeterr(); if (write_bufend == write_curpos || write_fd == -1) return 0; @@ -224,8 +224,8 @@ static int flush_write_buffer(int wait) maxwrite = write_buftop - write_curpos - 1; else maxwrite = write_bufend - write_curpos; - nwritten = write(write_fd, write_curpos, maxwrite); - errno_save = errno; + nwritten = ano_sockwrite(write_fd, write_curpos, maxwrite); + errno_save = ano_sockgeterr(); if (debug >= 3) alog("debug: flush_write_buffer wanted %d, got %d", maxwrite, nwritten); @@ -237,7 +237,7 @@ static int flush_write_buffer(int wait) return nwritten; } } - errno = errno_save; + ano_sockseterr(errno_save); return 0; } @@ -250,10 +250,10 @@ static int flush_write_buffer(int wait) * @param len Length to write * @return int */ -static int buffered_write(int fd, char *buf, int len) +static int buffered_write(ano_socket_t fd, char *buf, int len) { int nwritten, left = len; - int errno_save = errno; + int errno_save = ano_sockgeterr(); if (fd < 0) { errno = EBADF; @@ -310,7 +310,7 @@ static int buffered_write(int fd, char *buf, int len) alog("debug: buffered_write(%d,%p,%d) returning %d", fd, buf, len, len - left); } - errno = errno_save; + ano_sockseterr(errno_save); return len - left; } @@ -326,12 +326,12 @@ static int buffered_write(int fd, char *buf, int len) * @return int */ #if 0 -static int buffered_write_one(int c, int fd) +static int buffered_write_one(int c, ano_socket_t fd) { struct timeval tv = { 0, 0 }; if (fd < 0) { - errno = EBADF; + ano_sockseterr(SOCKERR_EBADF); return -1; } write_fd = fd; @@ -373,7 +373,7 @@ static int buffered_write_one(int c, int fd) * @param int to read * @return int */ -int sgetc(int s) +int sgetc(ano_socket_t s) { int c; @@ -408,7 +408,7 @@ int sungetc(int c, int s) * @param s Socket * @return buffer */ -char *sgets(char *buf, int len, int s) +char *sgets(char *buf, int len, ano_socket_t s) { int c = 0; struct timeval tv; @@ -422,7 +422,7 @@ char *sgets(char *buf, int len, int s) tv.tv_usec = 0; while (read_buffer_len() == 0 && (c = select(s + 1, &fds, NULL, NULL, &tv)) < 0) { - if (errno != EINTR) + if (ano_sockgeterr() != EINTR) break; } if (read_buffer_len() == 0 && c == 0) @@ -445,7 +445,7 @@ char *sgets(char *buf, int len, int s) * @param s Socket * @return buffer */ -char *sgets2(char *buf, int len, int s) +char *sgets2(char *buf, int len, ano_socket_t s) { char *str = sgets(buf, len, s); @@ -469,7 +469,7 @@ char *sgets2(char *buf, int len, int s) * @param len Length * @return int */ -int sread(int s, char *buf, int len) +int sread(ano_socket_t s, char *buf, int len) { return buffered_read(s, buf, len); } @@ -482,7 +482,7 @@ int sread(int s, char *buf, int len) * @param str Buffer to write * @return int */ -int sputs(char *str, int s) +int sputs(char *str, ano_socket_t s) { return buffered_write(s, str, strlen(str)); } @@ -496,7 +496,7 @@ int sputs(char *str, int s) * @param ... various args * @return int */ -int sockprintf(int s, char *fmt, ...) +int sockprintf(ano_socket_t s, char *fmt, ...) { va_list args; char buf[16384]; /* Really huge, to try and avoid truncation */ @@ -555,7 +555,7 @@ int conn(const char *host, int port, const char *lhost, int lport) char *addr; #endif struct sockaddr_in sa, lsa; - int sock; + ano_socket_t sock; memset(&lsa, 0, sizeof(lsa)); if (lhost) { @@ -584,7 +584,7 @@ int conn(const char *host, int port, const char *lhost, int lport) #else if (!(addr = pack_ip(host))) { alog("conn(): `%s' is not a valid IP address", host); - errno = EINVAL; + ano_sockseterr(SOCKERR_EINVAL); return -1; } memcpy((char *) &sa.sin_addr, addr, 4); @@ -597,16 +597,16 @@ int conn(const char *host, int port, const char *lhost, int lport) if ((lhost || lport) && bind(sock, (struct sockaddr *) &lsa, sizeof(lsa)) < 0) { - int errno_save = errno; - close(sock); - errno = errno_save; + int errno_save = ano_sockgeterr(); + ano_sockclose(sock); + ano_sockseterr(errno_save); return -1; } if (connect(sock, (struct sockaddr *) &sa, sizeof(sa)) < 0) { - int errno_save = errno; - close(sock); - errno = errno_save; + int errno_save = ano_sockgeterr(); + ano_sockclose(sock); + ano_sockseterr(errno_save); return -1; } @@ -620,8 +620,109 @@ int conn(const char *host, int port, const char *lhost, int lport) * @param s Socket * @return void */ -void disconn(int s) +void disconn(ano_socket_t s) { shutdown(s, 2); - close(s); + ano_sockclose(s); } + +/*************************************************************************/ +/* Windows support functions */ + +#ifdef _WIN32 +/* Microsoft makes things nice and fun for us! */ +struct u_WSA_errors { + int error_code; + char *error_string; +}; + +/* Must be sorted ascending by error code */ +struct u_WSA_errors WSAErrors[] = { + {WSAEINTR, "Interrupted system call"}, + {WSAEBADF, "Bad file number"}, + {WSAEACCES, "Permission denied"}, + {WSAEFAULT, "Bad address"}, + {WSAEINVAL, "Invalid argument"}, + {WSAEMFILE, "Too many open sockets"}, + {WSAEWOULDBLOCK, "Operation would block"}, + {WSAEINPROGRESS, "Operation now in progress"}, + {WSAEALREADY, "Operation already in progress"}, + {WSAENOTSOCK, "Socket operation on non-socket"}, + {WSAEDESTADDRREQ, "Destination address required"}, + {WSAEMSGSIZE, "Message too long"}, + {WSAEPROTOTYPE, "Protocol wrong type for socket"}, + {WSAENOPROTOOPT, "Bad protocol option"}, + {WSAEPROTONOSUPPORT, "Protocol not supported"}, + {WSAESOCKTNOSUPPORT, "Socket type not supported"}, + {WSAEOPNOTSUPP, "Operation not supported on socket"}, + {WSAEPFNOSUPPORT, "Protocol family not supported"}, + {WSAEAFNOSUPPORT, "Address family not supported"}, + {WSAEADDRINUSE, "Address already in use"}, + {WSAEADDRNOTAVAIL, "Can't assign requested address"}, + {WSAENETDOWN, "Network is down"}, + {WSAENETUNREACH, "Network is unreachable"}, + {WSAENETRESET, "Net connection reset"}, + {WSAECONNABORTED, "Software caused connection abort"}, + {WSAECONNRESET, "Connection reset by peer"}, + {WSAENOBUFS, "No buffer space available"}, + {WSAEISCONN, "Socket is already connected"}, + {WSAENOTCONN, "Socket is not connected"}, + {WSAESHUTDOWN, "Can't send after socket shutdown"}, + {WSAETOOMANYREFS, "Too many references, can't splice"}, + {WSAETIMEDOUT, "Connection timed out"}, + {WSAECONNREFUSED, "Connection refused"}, + {WSAELOOP, "Too many levels of symbolic links"}, + {WSAENAMETOOLONG, "File name too long"}, + {WSAEHOSTDOWN, "Host is down"}, + {WSAEHOSTUNREACH, "No route to host"}, + {WSAENOTEMPTY, "Directory not empty"}, + {WSAEPROCLIM, "Too many processes"}, + {WSAEUSERS, "Too many users"}, + {WSAEDQUOT, "Disc quota exceeded"}, + {WSAESTALE, "Stale NFS file handle"}, + {WSAEREMOTE, "Too many levels of remote in path"}, + {WSASYSNOTREADY, "Network subsystem is unavailable"}, + {WSAVERNOTSUPPORTED, "Winsock version not supported"}, + {WSANOTINITIALISED, "Winsock not yet initialized"}, + {WSAHOST_NOT_FOUND, "Host not found"}, + {WSATRY_AGAIN, "Non-authoritative host not found"}, + {WSANO_RECOVERY, "Non-recoverable errors"}, + {WSANO_DATA, "Valid name, no data record of requested type"}, + {WSAEDISCON, "Graceful disconnect in progress"}, +#ifdef WSASYSCALLFAILURE + {WSASYSCALLFAILURE, "System call failure"}, +#endif + {0, NULL} +}; + +char *ano_sockstrerror(int error) +{ + static char unkerr[64]; + int start = 0; + int stop = sizeof(WSAErrors) / sizeof(WSAErrors[0]) - 1; + int mid; + + /* Microsoft decided not to use sequential numbers for the error codes, + * so we can't just use the array index for the code. But, at least + * use a binary search to make it as fast as possible. + */ + while (start <= stop) { + mid = (start + stop) / 2; + if (WSAErrors[mid].error_code > error) + stop = mid - 1; + + else if (WSAErrors[mid].error_code < error) + start = mid + 1; + else + return WSAErrors[mid].error_string; + } + sprintf(unkerr, "Unknown Error: %d", error); + return unkerr; +} + +int ano_socksetnonb(ano_socket_t fd) +{ + int i = 1; + return (!ioctlsocket(fd, FIONBIO, &i) ? -1 : 1); +} +#endif diff --git a/src/solidircd.c b/src/solidircd.c index 80bf21310..ea577a0fa 100644 --- a/src/solidircd.c +++ b/src/solidircd.c @@ -102,6 +102,7 @@ IRCDVar ircd[] = { 1, /* +I support */ 0, /* SJOIN ban char */ 0, /* SJOIN except char */ + 0, /* SJOIN invite char */ 0, /* Can remove User Channel Modes with SVSMODE */ 0, /* Sglines are not enforced until user reconnects */ "v", /* vhost char */ @@ -899,6 +900,9 @@ void anope_cmd_pong(char *servname, char *who) void anope_cmd_connect(int servernum) { + me_server = + new_server(NULL, ServerName, ServerDesc, SERVER_ISME, NULL); + if (servernum == 1) { anope_cmd_pass(RemotePassword); } else if (servernum == 2) { diff --git a/src/tools/anopesmtp.c b/src/tools/anopesmtp.c index 12949c9f9..910caa3bc 100644 --- a/src/tools/anopesmtp.c +++ b/src/tools/anopesmtp.c @@ -20,6 +20,23 @@ static int curday = 0; /*************************************************************************/ +#ifdef _WIN32 +int strcasecmp(const char *s1, const char *s2) +{ + register int c; + + while ((c = tolower(*s1)) == tolower(*s2)) { + if (c == 0) + return 0; + s1++; + s2++; + } + if (c < tolower(*s2)) + return -1; + return 1; +} +#endif + static int get_logname(char *name, int count, struct tm *tm) { diff --git a/src/tools/smtp.h b/src/tools/smtp.h index bce460684..7ffda89e8 100644 --- a/src/tools/smtp.h +++ b/src/tools/smtp.h @@ -24,21 +24,39 @@ #include <stdio.h> #include <stdlib.h> #include <string.h> + +/* Windows does not have: + * unistd.h, grp.h, + * netdb.h, netinet/in.h, + * sys/socket.h, sys/time.h + * Windows requires: + * winsock.h + * -- codemastr + */ + +#ifndef _WIN32 #include <unistd.h> +#endif + #include <signal.h> #include <time.h> #include <errno.h> -#include <grp.h> #include <limits.h> + +#ifndef _WIN32 #include <netdb.h> #include <netinet/in.h> -#include <arpa/inet.h> #include <sys/socket.h> -#include <sys/stat.h> +#else +#include <winsock.h> +#include <windows.h> +#endif + #include <sys/types.h> + +#ifndef _WIN32 #include <sys/time.h> -#include <fcntl.h> -#include <ctype.h> +#endif #ifdef _AIX extern int strcasecmp(const char *, const char *); @@ -49,6 +67,11 @@ extern int connect(int, struct sockaddr *, int); # endif #endif /* _AIX */ +#ifdef _WIN32 +#define PATH_MAX MAX_PATH +#define snprintf _snprintf +#endif + /*************************************************************************/ diff --git a/src/ultimate2.c b/src/ultimate2.c index 7acc22f05..d52ead4ef 100644 --- a/src/ultimate2.c +++ b/src/ultimate2.c @@ -100,6 +100,7 @@ IRCDVar ircd[] = { 0, /* +I support */ 0, /* SJOIN ban char */ 0, /* SJOIN except char */ + 0, /* SJOIN invite char */ 0, /* Can remove User Channel Modes with SVSMODE */ 0, /* Sglines are not enforced until user reconnects */ "x", /* vhost char */ @@ -845,6 +846,9 @@ void anope_cmd_svsmode(User * u, int ac, char **av) void anope_cmd_connect(int servernum) { + me_server = + new_server(NULL, ServerName, ServerDesc, SERVER_ISME, NULL); + anope_cmd_capab(); if (servernum == 1) anope_cmd_pass(RemotePassword); diff --git a/src/ultimate3.c b/src/ultimate3.c index 37fecc9b8..34d9861c2 100644 --- a/src/ultimate3.c +++ b/src/ultimate3.c @@ -102,6 +102,7 @@ IRCDVar ircd[] = { 0, /* +I support */ 0, /* SJOIN ban char */ 0, /* SJOIN except char */ + 0, /* SJOIN invite char */ 0, /* Can remove User Channel Modes with SVSMODE */ 1, /* Sglines are enforced */ "x", /* vhost char */ @@ -1573,9 +1574,8 @@ void anope_cmd_svsnick(char *source, char *guest, time_t when) void anope_cmd_connect(int servernum) { - if (!servernum) { - servernum = 1; - } + me_server = + new_server(NULL, ServerName, ServerDesc, SERVER_ISME, NULL); if (servernum == 1) { anope_cmd_pass(RemotePassword); diff --git a/src/unreal31.c b/src/unreal31.c index 014122cfc..4be075fd2 100644 --- a/src/unreal31.c +++ b/src/unreal31.c @@ -103,6 +103,7 @@ IRCDVar ircd[] = { 0, /* +I support */ 0, /* SJOIN ban char */ 0, /* SJOIN except char */ + 0, /* SJOIN invite char */ 0, /* Can remove User Channel Modes with SVSMODE */ 0, /* Sglines are not enforced until user reconnects */ "x", /* vhost char */ @@ -1127,9 +1128,8 @@ void anope_cmd_vhost_on(char *nick, char *vIdent, char *vhost) void anope_cmd_connect(int servernum) { - if (!servernum) { - servernum = 1; - } + me_server = + new_server(NULL, ServerName, ServerDesc, SERVER_ISME, NULL); anope_cmd_protoctl(); if (servernum == 1) { diff --git a/src/unreal32.c b/src/unreal32.c index ddb553422..2e8123f9a 100644 --- a/src/unreal32.c +++ b/src/unreal32.c @@ -99,9 +99,10 @@ IRCDVar ircd[] = { 1, /* We support Unreal TOKENS */ 0, /* TOKENS are CASE Sensitive */ 1, /* TIME STAMPS are BASE64 */ - 0, /* +I support */ + 1, /* +I support */ '&', /* SJOIN ban char */ '\"', /* SJOIN except char */ + '\'', /* SJOIN invite char */ 1, /* Can remove User Channel Modes with SVSMODE */ 0, /* Sglines are not enforced until user reconnects */ "x", /* vhost char */ @@ -1465,8 +1466,16 @@ void anope_cmd_vhost_on(char *nick, char *vIdent, char *vhost) void anope_cmd_connect(int servernum) { - if (!servernum) { - servernum = 1; + char buf[16]; + *buf = '\0'; + + if (Numeric) { + snprintf(buf, sizeof(buf), "%d", Numeric); + me_server = + new_server(NULL, ServerName, ServerDesc, SERVER_ISME, buf); + } else { + me_server = + new_server(NULL, ServerName, ServerDesc, SERVER_ISME, NULL); } anope_cmd_capab(); diff --git a/src/users.c b/src/users.c index ca7c31b60..1979f0283 100644 --- a/src/users.c +++ b/src/users.c @@ -170,9 +170,9 @@ void change_user_realname(User * user, const char *realname) void change_user_username(User * user, const char *username) { - if (user->username) - free(user->username); - user->username = sstrdup(username); + if (user->vident) + free(user->vident); + user->vident = sstrdup(username); if (user->na && (nick_identified(user) || (!(user->na->nc->flags & NI_SECURE) && nick_recognized(user)))) { diff --git a/src/viagra.c b/src/viagra.c index 1599657ba..1cb883789 100644 --- a/src/viagra.c +++ b/src/viagra.c @@ -101,6 +101,7 @@ IRCDVar ircd[] = { 0, /* +I support */ 0, /* SJOIN ban char */ 0, /* SJOIN except char */ + 0, /* SJOIN invite char */ 0, /* Can remove User Channel Modes with SVSMODE */ 0, /* Sglines are not enforced until user reconnects */ "x", /* vhost char */ @@ -797,7 +798,7 @@ void anope_cmd_topic(char *whosets, char *chan, char *whosetit, void anope_cmd_vhost_off(User * u) { send_cmd(NULL, "SVSMODE %s -x", u->nick); - notice_lang(s_HostServ, u, HOST_OFF_UNREAL, u->nick, ircd->vhostcar); + notice_lang(s_HostServ, u, HOST_OFF_UNREAL, u->nick, ircd->vhostchar); } void anope_cmd_vhost_on(char *nick, char *vIdent, char *vhost) @@ -951,6 +952,9 @@ void anope_cmd_pong(char *servname, char *who) void anope_cmd_connect(int servernum) { + me_server = + new_server(NULL, ServerName, ServerDesc, SERVER_ISME, NULL); + if (servernum == 1) { anope_cmd_pass(RemotePassword); } else if (servernum == 2) { diff --git a/src/win32.rc b/src/win32.rc new file mode 100644 index 000000000..9a6c716a3 --- /dev/null +++ b/src/win32.rc @@ -0,0 +1,91 @@ +///Microsoft Developer Studio generated resource script.
+//
+#include "../include/resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#define APSTUDIO_HIDDEN_SYMBOLS
+#include "windows.h"
+#undef APSTUDIO_HIDDEN_SYMBOLS
+#include "../include/resource.h"
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// English (U.S.) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+#ifdef _WIN32
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+#pragma code_page(1252)
+#endif //_WIN32
+
+#ifndef _MAC
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Version
+//
+
+VER_ANOPE VERSIONINFO
+ FILEVERSION 1,7,8,0
+ PRODUCTVERSION 1,7,8,0
+ FILEFLAGSMASK 0x17L
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS 0x4L
+ FILETYPE 0x1L
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0"
+ BEGIN
+ VALUE "CompanyName", "Anope Dev"
+ VALUE "FileDescription", "Anope IRC Services"
+ VALUE "FileVersion", "1.7.8"
+ VALUE "InternalName", "Anope"
+ VALUE "LegalCopyright", "Copyright (C) 2005"
+ VALUE "OriginalFilename", "anoservices.exe"
+ VALUE "ProductName", "Anope"
+ VALUE "ProductVersion", "1.7.8"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END
+
+#endif // !_MAC
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Icon
+//
+
+// Icon with lowest ID value placed first to ensure application icon
+// remains consistent on all systems.
+ICON_APP ICON "anope-icon.ico"
+#endif // English (U.S.) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+
+
+/////////////////////////////////////////////////////////////////////////////
+#endif // not APSTUDIO_INVOKED
+
|