]> jfr.im git - irc/ircd-hybrid/ircd-hybrid-8-cvs.git/commitdiff
- Added core/ modules, which cvsignore previously caused not to be imported.
authora1kmm <a1kmm>
Fri, 4 Jan 2002 10:57:21 +0000 (10:57 +0000)
committera1kmm <a1kmm>
Fri, 4 Jan 2002 10:57:21 +0000 (10:57 +0000)
- Added message files. Probably a .cvsignore problem again.
- Added needed .depend files.
- Now using my O(1) alloc O(1) free block-allocator I wrote a while ago for 7
  that missed the freeze.

18 files changed:
include/balloc.h
include/memory.h
loader/.depend
messages/ayb.po [new file with mode: 0644]
messages/custom.po [new file with mode: 0644]
modules/.depend [new file with mode: 0644]
modules/core/m_die.c [new file with mode: 0644]
modules/core/m_kick.c [new file with mode: 0644]
modules/core/m_kill.c [new file with mode: 0644]
modules/core/m_mode.c [new file with mode: 0644]
modules/core/m_nick.c [new file with mode: 0644]
modules/core/m_part.c [new file with mode: 0644]
modules/core/m_quit.c [new file with mode: 0644]
modules/core/m_server.c [new file with mode: 0644]
modules/core/m_sjoin.c [new file with mode: 0644]
modules/core/m_squit.c [new file with mode: 0644]
src/.depend
src/balloc.c

index ff10ab1b807cde7de2cb3f01329f9fa2655ee13b..31e3be557927c386f5252be203d9f810ccfaa6cc 100644 (file)
@@ -1,88 +1,51 @@
-/*
- * balloc.h - Based roughly on Wohali's old block allocator.
+/************************************************************************
+ *  ircd hybrid - Internet Relay Chat Daemon, include/balloc.h
+ *  balloc.h: The block allocator header.
+ *  Copyright(C) 2001 by the past and present ircd-hybrid teams.
  *
- * Mangled by Aaron Sethman <androsyn@ratbox.org>
- * Below is the original header found on this file
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
  *
- * File:   blalloc.h
- * Owner:   Wohali (Joan Touzet)
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
  *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  *
- * $Id: balloc.h,v 1.1 2002/01/04 09:12:47 a1kmm Exp $
+ * $Id: balloc.h,v 1.2 2002/01/04 10:57:21 a1kmm Exp $
  */
-#ifndef INCLUDED_blalloc_h
-#define INCLUDED_blalloc_h
-#ifndef NOBALLOC
-#ifndef INCLUDED_sys_types_h
-#include <sys/types.h>       /* size_t */
-#define INCLUDED_sys_types_h
-#endif
 
-#ifndef INCLUDED_stddef_h
-#include <stddef.h>
-#define INCLUDED_stddef_h
-#endif
-#include <sys/mman.h>
+#ifndef _I_BALLOC_H
+#define _I_BALLOC_H
 #include "tools.h"
-#include "memory.h"
-#include "ircd_defs.h"
-
-
-/* 
- * Block contains status information for an allocated block in our
- * heap.
- */
-
-
-struct Block {
-       int             freeElems;              /* Number of available elems */
-       size_t          alloc_size;
-       struct Block*   next;                   /* Next in our chain of blocks */
-       void*           elems;                  /* Points to allocated memory */
-       dlink_list      free_list;
-       dlink_list      used_list;                                      
-};
-
-typedef struct Block Block;
-
-struct MemBlock {
-       dlink_node self;                
-       Block *block;                           /* Which block we belong to */
-       void *data;                             /* Maybe pointless? :P */
-};
-typedef struct MemBlock MemBlock;
-
-/* 
- * BlockHeap contains the information for the root node of the
- * memory heap.
- */
-struct BlockHeap {
-   size_t  elemSize;                    /* Size of each element to be stored */
-   int     elemsPerBlock;               /* Number of elements per block */
-   int     blocksAllocated;             /* Number of blocks allocated */
-   int     freeElems;                   /* Number of free elements */
-   Block*  base;                        /* Pointer to first block */
-};
 
 typedef struct BlockHeap BlockHeap;
 
+/* Only include the block allocator stuff if we use it... */
+#ifndef NOBALLOC
 
-extern BlockHeap* BlockHeapCreate(size_t elemsize, int elemsperblock);
-extern int        BlockHeapDestroy(BlockHeap *bh);
+struct BlockHeap
+{
+ dlink_list f_elements, blocks;
+ int elsize, elsperblock, blocksize;
+};
 
-#if 0 /* These are in memory.h... */
-extern int        BlockHeapFree(BlockHeap *bh, void *ptr);
-extern void *    BlockHeapAlloc(BlockHeap *bh);
-#endif
+/* The functions we need to provide... */
+void initBlockHeap(void);
+void BlockHeapGarbageCollect(BlockHeap *b);
+BlockHeap *BlockHeapCreate(int elsize, int elperblock);
+void BlockHeapDestroy(BlockHeap *b);
 
-extern int        BlockHeapGarbageCollect(BlockHeap *);
-extern void      initBlockHeap(void);
 #else /* NOBALLOC */
-typedef struct BlockHeap BlockHeap;
 #define initBlockHeap()
 #define BlockHeapGarbageCollect(x)
 /* This is really kludgy, passing ints as pointers is always bad. */
 #define BlockHeapCreate(es, epb) ((BlockHeap*)(es))
 #define BlockHeapDestroy(x)
-#endif /* NOBALLOC */
-#endif /* INCLUDED_blalloc_h */
+#endif
+#endif /* _I_BALLOC_H */
index ee3588401015b32ef0f612571cfb04d8fafe81d8..8bc1c9d37c4f19a1694ecda28a82bddda7d21daf 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: memory.h,v 1.1 2002/01/04 09:12:56 a1kmm Exp $ */
+/* $Id: memory.h,v 1.2 2002/01/04 10:57:22 a1kmm Exp $ */
 
 #ifndef _I_MEMORY_H
 #define _I_MEMORY_H
@@ -31,7 +31,7 @@ extern void*       _MyMalloc(size_t size, char *file, int line);
 extern void*       _MyRealloc(void* p, size_t size, char * file, int line);
 extern void        _MyFree(void* p, char * file, int line);
 extern void        _DupString(char**, const char*, char*, int);
-extern int         _BlockHeapFree(BlockHeap *bh, void *ptr);
+extern void         _BlockHeapFree(BlockHeap *bh, void *ptr);
 extern void *    _BlockHeapAlloc(BlockHeap *bh);
 #define MyMalloc(x) _MyMalloc(x, __FILE__, __LINE__)
 #define MyRealloc(x,y) _MyRealloc(x, y, __FILE__, __LINE__)
@@ -39,7 +39,7 @@ extern void *   _BlockHeapAlloc(BlockHeap *bh);
 #define DupString(x,y) _DupString(&x, y, __FILE__, __LINE__)
 #ifndef NOBALLOC
 #define BlockHeapAlloc(x) memlog(_BlockHeapAlloc(x), \
-                                 x->elemSize-sizeof(MemoryEntry), \
+                                 x->elsize-sizeof(MemoryEntry), \
                                  __FILE__, __LINE__)
 #define BlockHeapFree(x, y) memulog(y); \
                             _BlockHeapFree(x, \
@@ -64,9 +64,9 @@ extern MemoryEntry *first_mem_entry;
 
 extern void * _MyMalloc(size_t size);
 extern void* _MyRealloc(void* x, size_t y);
-extern void _MyFree(void *x);
-extern void _DupString(char **x, const char *y);
-extern int         _BlockHeapFree(BlockHeap *bh, void *ptr);
+extern inline void _MyFree(void *x);
+extern inline void _DupString(char **x, const char *y);
+extern void         _BlockHeapFree(BlockHeap *bh, void *ptr);
 extern void *    _BlockHeapAlloc(BlockHeap *bh);
 
 #define MyMalloc(x) _MyMalloc(x)
@@ -85,4 +85,3 @@ extern void *   _BlockHeapAlloc(BlockHeap *bh);
 #endif
 
 #endif /* _I_MEMORY_H */
-
index aa27a6fb3cdb2fe0350e0c2e6b0eb9b9175648b2..05f2028648a5035f7769ffc4120a903fa015f499 100644 (file)
@@ -1,2 +1,8 @@
-# $Id: .depend,v 1.1 2002/01/04 09:15:07 a1kmm Exp $
-ircd_loader.o: ircd_loader.c ../include/setup.h
+# $Id: .depend,v 1.2 2002/01/04 10:57:24 a1kmm Exp $
+ircd_loader.o: ircd_loader.c ../include/setup.h ../include/tools.h \
+  ../include/channel.h ../include/config.h ../include/defaults.h \
+  ../include/ircd_defs.h ../include/memory.h ../include/balloc.h \
+  ../include/s_conf.h ../include/fileio.h ../include/motd.h \
+  ../include/class.h ../include/client.h ../include/ircd_handler.h \
+  ../include/linebuf.h ../include/res.h ../adns/adns.h ../include/ircd.h \
+  ../include/irc_string.h ../include/sprintf_irc.h ../include/s_stats.h
diff --git a/messages/ayb.po b/messages/ayb.po
new file mode 100644 (file)
index 0000000..0f4c32e
--- /dev/null
@@ -0,0 +1,902 @@
+# ircd-hybrid-7 custom message file
+# Copyright (C) 2000
+# David Taylor <davidt@yadt.co.uk>, 2000.
+# $Id: ayb.po,v 1.1 2002/01/04 10:57:26 a1kmm Exp $
+#
+#, fuzzy
+msgid  ""
+msgstr "Project-Id-Version: ircd-hybrid-7\n"
+       "POT-Creation-Date: 2001-07-01 21:52-0700\n"
+       "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+       "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
+       "Language-Team: LANGUAGE <LL@li.org>\n"
+       "MIME-Version: 1.0\n"
+       "Content-Type: text/plain; charset=CHARSET\n"
+       "Content-Transfer-Encoding: ENCODING\n"
+
+#: ../src/messages.tab:24
+#, c-format
+msgid  ":%s 001 %s :Welcome to the %s Internet Relay Chat Network %s"
+msgstr ":%s 001 %s :ALL YOUR BASE ARE BELONG TO %s, %s!!!"
+
+#: ../src/messages.tab:25
+#, c-format
+msgid  ":%s 002 %s :Your host is %s, running version %s"
+msgstr ""
+
+#: ../src/messages.tab:26
+#, c-format
+msgid  ":%s 003 %s :This server was created %s"
+msgstr ":%s 003 %s :Someone set up us the server %s"
+
+#: ../src/messages.tab:27
+#, c-format
+msgid  ":%s 004 %s %s %s oiwszcerkfydnxbaugl biklmnopstveIha bkloveIh"
+msgstr ""
+
+#: ../src/messages.tab:28
+#, c-format
+msgid  ":%s 005 %s %s :are supported by this server"
+msgstr ":%s 005 %s %s :are moved for great justice"
+
+#: ../src/messages.tab:33
+#, c-format
+msgid  ":%s 010 %s %s %d :Please use this Server/Port instead"
+msgstr ":%s 010 %s %s %d :You have no chance to survive make this "
+       "Server/Port instead. Ha ha ha."
+
+#: ../src/messages.tab:43
+#, c-format
+msgid  ":%s 020 %s %s %s :Your ID and key is"
+msgstr ""
+
+#: ../src/messages.tab:223
+#, c-format
+msgid  ":%s 200 %s Link %s%s %s %s"
+msgstr ""
+
+#: ../src/messages.tab:224
+#, c-format
+msgid  ":%s 201 %s Try. %s %s"
+msgstr ""
+
+#: ../src/messages.tab:225
+#, c-format
+msgid  ":%s 202 %s H.S. %s %s"
+msgstr ""
+
+#: ../src/messages.tab:226
+#, c-format
+msgid  ":%s 203 %s ???? %s %s (%s) %d"
+msgstr ""
+
+#: ../src/messages.tab:227
+#, c-format
+msgid  ":%s 204 %s Oper %s %s (%s) %lu %lu"
+msgstr ""
+
+#: ../src/messages.tab:228
+#, c-format
+msgid  ":%s 205 %s User %s %s (%s) %lu %lu"
+msgstr ""
+
+#: ../src/messages.tab:229
+#, c-format
+msgid  ":%s 206 %s Serv %s %dS %dC %s %s!%s@%s %lu"
+msgstr ""
+
+#: ../src/messages.tab:231
+#, c-format
+msgid  ":%s 208 %s <newtype> 0 %s"
+msgstr ""
+
+#: ../src/messages.tab:232
+#, c-format
+msgid  ":%s 209 %s Class %s %d"
+msgstr ""
+
+#: ../src/messages.tab:235
+#, c-format
+msgid  ":%s 212 %s %s %u %u :%u"
+msgstr ""
+
+#: ../src/messages.tab:236
+#, c-format
+msgid  ":%s 213 %s %c %s %s %s %d %s"
+msgstr ""
+
+#: ../src/messages.tab:237
+#, c-format
+msgid  ":%s 214 %s %c %s * %s %d %s"
+msgstr ""
+
+#: ../src/messages.tab:238
+#, c-format
+msgid  ":%s 215 %s %c %s * %s@%s %d %s"
+msgstr ""
+
+#: ../src/messages.tab:239
+#, c-format
+msgid  ":%s 216 %s %c %s * %s %s"
+msgstr ""
+
+#: ../src/messages.tab:240
+#, c-format
+msgid  ":%s 217 %s %c %s %s"
+msgstr ""
+
+#: ../src/messages.tab:241
+#, c-format
+msgid  ":%s 218 %s %c %s %d %d %d %lu"
+msgstr ""
+
+#: ../src/messages.tab:242
+#, c-format
+msgid  ":%s 219 %s %s :End of /STATS report"
+msgstr ""
+
+#: ../src/messages.tab:243
+#, c-format
+msgid  ":%s 220 %s %c %d %s %d :%s"
+msgstr ""
+
+#: ../src/messages.tab:244
+#, c-format
+msgid  ":%s 221 %s %s"
+msgstr ""
+
+#: ../src/messages.tab:248
+#, c-format
+msgid  ":%s 225 %s %c %s %s"
+msgstr ""
+
+#: ../src/messages.tab:249
+#, c-format
+msgid  ":%s 226 %s %s"
+msgstr ""
+
+#: ../src/messages.tab:264
+#, c-format
+msgid  ":%s 241 %s %c %s * %s %d %s"
+msgstr ""
+
+#: ../src/messages.tab:265
+#, c-format
+msgid  ":%s 242 %s :Server Up %d days, %d:%02d:%02d"
+msgstr ":%s 242 %s :Someone set up us the bomb %d days, %d:%02d:%02d ago"
+
+#: ../src/messages.tab:266
+#, c-format
+msgid  ":%s 243 %s %c %s@%s * %s %s %s %s"
+msgstr ""
+
+#: ../src/messages.tab:267
+#, c-format
+msgid  ":%s 244 %s %c %s * %s %d %s"
+msgstr ""
+
+#: ../src/messages.tab:270
+#, c-format
+msgid  ":%s 247 %s X %s %s * * 0 0"
+msgstr ""
+
+#: ../src/messages.tab:272
+#, c-format
+msgid  ":%s 248 %s U %s %s"
+msgstr ""
+
+#: ../src/messages.tab:275
+#, c-format
+msgid  ":%s 250 %s :Highest connection count: %d (%d clients) (%d "
+       "connections received)"
+msgstr ""
+
+#: ../src/messages.tab:277
+#, c-format
+msgid  ":%s 251 %s :There are %d users and %d invisible on %d servers"
+msgstr ":%s 251 %s :There are %d minor Zigs and %d invisible on %d servers"
+
+#: ../src/messages.tab:278
+#, c-format
+msgid  ":%s 252 %s %d :IRC Operators online"
+msgstr ":%s 252 %s %d :Zigs online"
+
+#: ../src/messages.tab:279
+#, c-format
+msgid  ":%s 253 %s %d :unknown connection(s)"
+msgstr ""
+
+#: ../src/messages.tab:280
+#, c-format
+msgid  ":%s 254 %s %d :channels formed"
+msgstr ""
+
+#: ../src/messages.tab:281
+#, c-format
+msgid  ":%s 255 %s :I have %d clients and %d servers"
+msgstr ":%s 255 %s :%d clients and %d servers are belong to me"
+
+#: ../src/messages.tab:282
+#, c-format
+msgid  ":%s 256 %s :Administrative info about %s"
+msgstr ""
+
+#: ../src/messages.tab:283
+#, c-format
+msgid  ":%s 257 %s :%s"
+msgstr ""
+
+#: ../src/messages.tab:284
+#, c-format
+msgid  ":%s 258 %s :%s"
+msgstr ""
+
+#: ../src/messages.tab:285
+#, c-format
+msgid  ":%s 259 %s :%s"
+msgstr ""
+
+#: ../src/messages.tab:287
+#, c-format
+msgid  ":%s 261 %s File %s %d"
+msgstr ""
+
+#: ../src/messages.tab:288
+#, c-format
+msgid  ":%s 262 %s %s :End of TRACE"
+msgstr ""
+
+#: ../src/messages.tab:290
+#, c-format
+msgid  ":%s 263 %s :Server load is temporarily too heavy. Please wait a "
+       "while and try again."
+msgstr ":%s 263 %s :Hold your horses... the server load is temporarily too "
+       "heavy. Try again later, ok?"
+
+#: ../src/messages.tab:292
+#, c-format
+msgid  ":%s 265 %s :Current local  users: %d  Max: %d"
+msgstr ":%s 265 %s :%d users (max %d) are belong to me"
+
+#: ../src/messages.tab:293
+#, c-format
+msgid  ":%s 266 %s :Current global users: %d  Max: %d"
+msgstr ":%s 266 %s :%d users (max %d) are belong to the network"
+
+#: ../src/messages.tab:303
+#, c-format
+msgid  ":%s 276 %s %s :has %d possible virtual channels available"
+msgstr ":%s 276 %s %s :%d virtual channels are belong to it"
+
+#: ../src/messages.tab:304
+#, c-format
+msgid  ":%s 277 %s %s "
+msgstr ""
+
+#: ../src/messages.tab:305
+#, c-format
+msgid  ":%s 278 %s :Type /%s %s <key> to specify the channel you want"
+msgstr ""
+
+#: ../src/messages.tab:306
+#, c-format
+msgid   ":%s 281 %s %s :"
+msgstr  ""
+
+#: ../src/messages.tab:307
+#, c-format
+msgid   ":%s 282 %s :End of /ACCEPT list."
+msgstr  ""
+
+#: ../src/messages.tab:328
+#, c-format
+msgid  ":%s 301 %s %s :%s"
+msgstr ""
+
+#: ../src/messages.tab:329
+#, c-format
+msgid  ":%s 302 %s :%s"
+msgstr ""
+
+#: ../src/messages.tab:330
+#, c-format
+msgid  ":%s 303 %s :"
+msgstr ""
+
+#: ../src/messages.tab:332
+#, c-format
+msgid  ":%s 305 %s :You are no longer marked as being away"
+msgstr ":%s 305 %s :OK, you're not /away anymore. Did you move Zig for great "
+       "justice?"
+
+#: ../src/messages.tab:333
+#, c-format
+msgid  ":%s 306 %s :You have been marked as being away"
+msgstr ":%s 306 %s :OK, you're /away now. Hurry back!"
+
+#: ../src/messages.tab:335
+#, c-format
+msgid  ":%s 308 %s %s :is a Server Administrator"
+msgstr ":%s 308 %s %s :is a Master Zig (Server Admin)"
+
+#: ../src/messages.tab:338
+#, c-format
+msgid  ":%s 311 %s %s %s %s * :%s"
+msgstr ""
+
+#: ../src/messages.tab:339
+#, c-format
+msgid  ":%s 312 %s %s %s :%s"
+msgstr ""
+
+#: ../src/messages.tab:340
+#, c-format
+msgid  ":%s 313 %s %s :is an IRC Operator"
+msgstr ":%s 313 %s %s :is a Zig for Great Justice"
+
+#: ../src/messages.tab:341
+#, c-format
+msgid  ":%s 314 %s %s %s %s * :%s"
+msgstr ""
+
+#: ../src/messages.tab:342
+#, c-format
+msgid  ":%s 315 %s %s :End of /WHO list."
+msgstr ""
+
+#: ../src/messages.tab:344
+#, c-format
+msgid  ":%s 317 %s %s %d %d :seconds idle, signon time"
+msgstr ""
+
+#: ../src/messages.tab:345
+#, c-format
+msgid  ":%s 318 %s %s :End of /WHOIS list."
+msgstr ""
+
+#: ../src/messages.tab:346
+#, c-format
+msgid  ":%s 319 %s %s :%s"
+msgstr ""
+
+#: ../src/messages.tab:348
+#, c-format
+msgid  ":%s 321 %s Channel :Users  Name"
+msgstr ""
+
+#: ../src/messages.tab:349
+#, c-format
+msgid  ":%s 322 %s %s %d :%s"
+msgstr ""
+
+#: ../src/messages.tab:350
+#, c-format
+msgid  ":%s 323 %s :End of /LIST"
+msgstr ""
+
+#: ../src/messages.tab:351
+#, c-format
+msgid  ":%s 324 %s %s %s %s"
+msgstr ""
+
+#: ../src/messages.tab:356
+#, c-format
+msgid  ":%s 329 %s %s %lu"
+msgstr ""
+
+#: ../src/messages.tab:358
+#, c-format
+msgid  ":%s 331 %s %s :No topic is set."
+msgstr ""
+
+#: ../src/messages.tab:359
+#, c-format
+msgid  ":%s 332 %s %s :%s"
+msgstr ""
+
+#: ../src/messages.tab:360
+#, c-format
+msgid  ":%s 333 %s %s %s %lu"
+msgstr ""
+
+#: ../src/messages.tab:368
+#, c-format
+msgid  ":%s 341 %s %s %s"
+msgstr ""
+
+#: ../src/messages.tab:373
+#, c-format
+msgid  ":%s 346 %s %s %s %s %lu"
+msgstr ""
+
+#: ../src/messages.tab:374
+#, c-format
+msgid  ":%s 347 %s %s :End of Channel Invite List"
+msgstr ""
+
+#: ../src/messages.tab:375
+#, c-format
+msgid  ":%s 348 %s %s %s %s %lu"
+msgstr ""
+
+#: ../src/messages.tab:376
+#, c-format
+msgid  ":%s 349 %s %s :End of Channel Exception List"
+msgstr ""
+
+#: ../src/messages.tab:378
+#, c-format
+msgid  ":%s 351 %s %s(%s).%s %s :%s%s"
+msgstr ""
+
+#: ../src/messages.tab:379
+#, c-format
+msgid  ":%s 352 %s %s %s %s %s %s %s :%d %s"
+msgstr ""
+
+#: ../src/messages.tab:380
+#, c-format
+msgid  ":%s 353 %s %s"
+msgstr ""
+
+#: ../src/messages.tab:389
+#, c-format
+msgid  ":%s 362 %s %s :Closed. Status = %d"
+msgstr ""
+
+#: ../src/messages.tab:390
+#, c-format
+msgid  ":%s 363 %s %d: Connections Closed"
+msgstr ""
+
+#: ../src/messages.tab:391
+#, c-format
+msgid  ":%s 364 %s %s %s :%d %s"
+msgstr ""
+
+#: ../src/messages.tab:392
+#, c-format
+msgid  ":%s 365 %s %s :End of /LINKS list."
+msgstr ""
+
+#: ../src/messages.tab:393
+#, c-format
+msgid  ":%s 366 %s %s :End of /NAMES list."
+msgstr ""
+
+#: ../src/messages.tab:394
+#, c-format
+msgid  ":%s 367 %s %s %s %s %lu"
+msgstr ""
+
+#: ../src/messages.tab:395
+#, c-format
+msgid  ":%s 368 %s %s :End of Channel Ban List"
+msgstr ""
+
+#: ../src/messages.tab:396
+#, c-format
+msgid  ":%s 369 %s %s :End of WHOWAS"
+msgstr ""
+
+#: ../src/messages.tab:398
+#, c-format
+msgid  ":%s 371 %s :%s"
+msgstr ""
+
+#: ../src/messages.tab:399
+#, c-format
+msgid  ":%s 372 %s :- %s"
+msgstr ""
+
+#: ../src/messages.tab:400
+#, c-format
+msgid  ":%s 373 %s :Server INFO"
+msgstr ""
+
+#: ../src/messages.tab:401
+#, c-format
+msgid  ":%s 374 %s :End of /INFO list."
+msgstr ""
+
+#: ../src/messages.tab:402
+#, c-format
+msgid  ":%s 375 %s :- %s Message of the Day - "
+msgstr ""
+
+#: ../src/messages.tab:403
+#, c-format
+msgid  ":%s 376 %s :End of /MOTD command."
+msgstr ""
+
+#: ../src/messages.tab:408
+#, c-format
+msgid  ":%s 381 %s :You have entered... the Twilight Zone!."
+msgstr ":%s 381 %s :SOMEONE SET YOU UP THE /KILL FOR GREAT JUSTICE!"
+
+#: ../src/messages.tab:409
+#, c-format
+msgid  ":%s 382 %s %s :Rehashing"
+msgstr ":%s 382 %s %s :it slices, dices, and even reloads config files! "
+       "Rehashing config file, mang."
+
+#: ../src/messages.tab:411
+#, c-format
+msgid  ":%s 384 %s %d :Port to local server is"
+msgstr ""
+
+#: ../src/messages.tab:413
+#, c-format
+msgid  ":%s 386 %s :%s"
+msgstr ""
+
+#: ../src/messages.tab:418
+#, c-format
+msgid  ":%s 391 %s %s :%s"
+msgstr ""
+
+#: ../src/messages.tab:428
+#, c-format
+msgid  ":%s 401 %s %s :No such nick/channel"
+msgstr ":%s 401 %s %s :No such Zig"
+
+#: ../src/messages.tab:429
+#, c-format
+msgid  ":%s 402 %s %s :No such server"
+msgstr ""
+
+#: ../src/messages.tab:430
+#, c-format
+msgid  ":%s 403 %s %s :No such channel"
+msgstr ""
+
+#: ../src/messages.tab:431
+#, c-format
+msgid  ":%s 404 %s %s :Cannot send to channel"
+msgstr ""
+
+#: ../src/messages.tab:432
+#, c-format
+msgid  ":%s 405 %s %s :You have joined too many channels"
+msgstr ":%s 405 %s %s :Too many channels are belong to you"
+
+#: ../src/messages.tab:433
+#, c-format
+msgid  ":%s 406 %s %s :There was no such nickname"
+msgstr ":%s 406 %s %s :There was no such Zig"
+
+#: ../src/messages.tab:435
+#, c-format
+msgid  ":%s 407 %s %s :Too many recipients. Only %d processed"
+msgstr ":%s 407 %s %s :Too many recipients. Your message is only belong to %d"
+
+#: ../src/messages.tab:437
+#, c-format
+msgid  ":%s 409 %s :No origin specified"
+msgstr ""
+
+#: ../src/messages.tab:439
+#, c-format
+msgid  ":%s 411 %s :No recipient given (%s)"
+msgstr ":%s 411 %s :No Zigs Moved (%s)"
+
+#: ../src/messages.tab:440
+#, c-format
+msgid  ":%s 412 %s :No text to send"
+msgstr ""
+
+#: ../src/messages.tab:441
+#, c-format
+msgid  ":%s 413 %s %s :No toplevel domain specified"
+msgstr ""
+
+#: ../src/messages.tab:442
+#, c-format
+msgid  ":%s 414 %s %s :Wildcard in toplevel Domain"
+msgstr ""
+
+#: ../src/messages.tab:449
+#, c-format
+msgid  ":%s 421 %s %s :Unknown command"
+msgstr ":%s 421 %s %s :THAT COMMAND IS NOT BELONG TO ME!!!"
+
+#: ../src/messages.tab:450
+#, c-format
+msgid  ":%s 422 %s :MOTD File is missing"
+msgstr ":%s 422 %s :MOTD file is not belong to me"
+
+#: ../src/messages.tab:452
+#, c-format
+msgid  ":%s 423 %s %s :No administrative info available"
+msgstr ""
+
+#: ../src/messages.tab:453
+#, c-format
+msgid  ":%s 424 %s :File error doing %s on %s"
+msgstr ""
+
+#: ../src/messages.tab:460
+#, c-format
+msgid  ":%s 431 %s :No nickname given"
+msgstr ""
+
+#: ../src/messages.tab:461
+#, c-format
+msgid  ":%s 432 %s %s :Erroneous Nickname"
+msgstr ""
+
+#: ../src/messages.tab:462
+#, c-format
+msgid  ":%s 433 %s %s :Nickname is already in use."
+msgstr ":%s 433 %s %s :Zig is belong to someone else."
+
+#: ../src/messages.tab:465
+#, c-format
+msgid  ":%s 436 %s %s :Nickname collision KILL"
+msgstr ""
+
+#: ../src/messages.tab:466
+#, c-format
+msgid  ":%s 437 %s %s :Nick/channel is temporarily unavailable"
+msgstr ""
+
+#: ../src/messages.tab:467
+#, fuzzy, c-format
+msgid  ":%s 438 %s %s %s :Nick change too fast. Please wait %d seconds."
+msgstr ":%s 433 %s %s :Zig is belong to someone else."
+
+#: ../src/messages.tab:470
+#, c-format
+msgid  ":%s 441 %s %s %s :They aren't on that channel"
+msgstr ""
+
+#: ../src/messages.tab:471
+#, c-format
+msgid  ":%s 442 %s %s :You're not on that channel"
+msgstr ""
+
+#: ../src/messages.tab:472
+#, c-format
+msgid  ":%s 443 %s %s %s :is already on channel"
+msgstr ""
+
+#: ../src/messages.tab:473
+#, c-format
+msgid  ":%s 444 %s %s :User not logged in"
+msgstr ""
+
+#: ../src/messages.tab:474
+#, c-format
+msgid  ":%s 445 %s :SUMMON has been removed"
+msgstr ""
+
+#: ../src/messages.tab:475
+#, c-format
+msgid  ":%s 446 %s :USERS has been removed"
+msgstr ""
+
+#: ../src/messages.tab:480
+#, c-format
+msgid  ":%s 451 %s :You have not registered"
+msgstr ""
+
+#: ../src/messages.tab:481
+#, c-format
+msgid   ":%s 456 %s :Accept list is full"
+msgstr  ""
+
+#: ../src/messages.tab:482
+#, c-format
+msgid   ":%s 457 %s %s :is already on your accept list"
+msgstr  ""
+
+#: ../src/messages.tab:483
+#, c-format
+msgid   ":%s 458 %s %s :is not on your accept list"
+msgstr  ""
+
+#: ../src/messages.tab:490
+#, c-format
+msgid  ":%s 461 %s %s :Not enough parameters"
+msgstr ""
+
+#: ../src/messages.tab:491
+#, c-format
+msgid  ":%s 462 %s :You may not reregister"
+msgstr ""
+
+#: ../src/messages.tab:492
+#, c-format
+msgid  ":%s 463 %s :Your host isn't among the privileged"
+msgstr ""
+
+#: ../src/messages.tab:493
+#, c-format
+msgid  ":%s 464 %s :Password Incorrect"
+msgstr ":%s 464 %s :BZZT!! Wrong password, homez. Are you sure you know what "
+       "you're doing??"
+
+#: ../src/messages.tab:494
+#, fuzzy, c-format
+msgid  ":%s 465 %s :You are banned from this server- %s"
+msgstr ":%s 005 %s %s :are moved for great justice"
+
+#: ../src/messages.tab:496
+#, c-format
+msgid  ":%s 467 %s %s :Channel key already set"
+msgstr ""
+
+#: ../src/messages.tab:500
+#, c-format
+msgid  ":%s 471 %s %s :Cannot join channel (+l)"
+msgstr ""
+
+#: ../src/messages.tab:501
+#, c-format
+msgid  ":%s 472 %s %c :is unknown mode char to me"
+msgstr ""
+
+#: ../src/messages.tab:502
+#, c-format
+msgid  ":%s 473 %s %s :Cannot join channel (+i)"
+msgstr ""
+
+#: ../src/messages.tab:503
+#, c-format
+msgid  ":%s 474 %s %s :Cannot join channel (+b)"
+msgstr ""
+
+#: ../src/messages.tab:504
+#, c-format
+msgid  ":%s 475 %s %s :Cannot join channel (+k)"
+msgstr ""
+
+#: ../src/messages.tab:505
+#, c-format
+msgid  ":%s 476 %s %s :Bad Channel Mask"
+msgstr ""
+
+#: ../src/messages.tab:506
+#, c-format
+msgid  ":%s 477 %s %s :Channel does not support modes"
+msgstr ""
+
+#: ../src/messages.tab:507
+#, c-format
+msgid  ":%s 478 %s %s %s :Channel ban list is full"
+msgstr ""
+
+#: ../src/messages.tab:508
+#, c-format
+msgid  ":%s 479 %s %s :Illegal channel name"
+msgstr ""
+
+#: ../src/messages.tab:511
+#, fuzzy, c-format
+msgid  ":%s 481 %s :Permission Denied - You're not an IRC operator"
+msgstr ":%s 481 %s :I don't THINK so, homez... you ain't got what it takes. "
+       "(IRC operator)"
+
+#: ../src/messages.tab:512
+#, c-format
+msgid  ":%s 482 %s %s :You're not channel operator"
+msgstr ":%s 482 %s %s :You can't do that thing, when you don't have that "
+       "swing (You're not channel operator)"
+
+#: ../src/messages.tab:513
+#, c-format
+msgid  ":%s 483 %s :You can't kill a server!"
+msgstr ":%s 483 %s :Don't be an idiot - you can't kill a SERVER, fool."
+
+#: ../src/messages.tab:514
+#, c-format
+msgid  ":%s 484 %s :You are restricted"
+msgstr ""
+
+#: ../src/messages.tab:516
+#, c-format
+msgid  ":%s 485 %s :Can't change nick when banned or on a moderated channel "
+       "(%s)"
+msgstr ""
+
+#: ../src/messages.tab:522
+#, c-format
+msgid  ":%s 491 %s :Only few of mere mortals may try to enter the twilight "
+       "zone"
+msgstr ":%s 491 %s :Sorry, you just don't have what it takes to be an IRC "
+       "Operator here."
+
+#: ../src/messages.tab:532
+#, c-format
+msgid  ":%s 501 %s :Unknown MODE flag"
+msgstr ""
+
+#: ../src/messages.tab:533
+#, c-format
+msgid  ":%s 502 %s :Can't change mode for other users"
+msgstr ""
+
+#: ../src/messages.tab:534
+#, c-format
+msgid  ":%s 503 %s :Message could not be delivered to %s"
+msgstr ""
+
+#: ../src/messages.tab:535
+#, c-format
+msgid  ":%s 504 %s %s :User is not on this server"
+msgstr ""
+
+#: ../src/messages.tab:537
+#, c-format
+msgid  ":%s 506 %s :Virtual Channels are disabled"
+msgstr ""
+
+#: ../src/messages.tab:538
+#, c-format
+msgid  ":%s 507 %s %s :You are already on a subchan"
+msgstr ""
+
+#: ../src/messages.tab:555
+#, c-format
+msgid  ":%s 524 %s %s :Help not found"
+msgstr ""
+
+#: ../src/messages.tab:702
+#, c-format
+msgid  ":%s 702 %s %s 0x%x %s"
+msgstr ""
+
+#: ../src/messages.tab:703
+#, c-format
+msgid  ":%s 703 %s :End of /MODLIST."
+msgstr  ""
+
+#: ../src/messages.tab:735
+#, c-format
+msgid  ":%s 704 %s %s :%s"
+msgstr ""
+
+#: ../src/messages.tab:736
+#, c-format
+msgid  ":%s 705 %s %s :%s"
+msgstr ""
+
+#: ../src/messages.tab:737
+#, c-format
+msgid  ":%s 706 %s %s :End of /HELP."
+msgstr ""
+
+#: ../src/messages.tab:741
+#, c-format
+msgid  ":%s 710 %s %s %s!%s@%s :has asked for an invite."
+msgstr ""
+
+#: ../src/messages.tab:742
+#, c-format
+msgid  ":%s 711 %s %s :Your KNOCK has been delivered."
+msgstr ""
+
+#: ../src/messages.tab:743
+#, c-format
+msgid  ":%s 712 %s %s :Too many KNOCKs (%s)."
+msgstr ""
+
+#: ../src/messages.tab:744
+#, c-format
+msgid  ":%s 713 %s %s :Channel is open."
+msgstr ""
+
+#: ../src/messages.tab:745
+#, c-format
+msgid  ":%s 714 %s %s :You are already on that channel."
+msgstr ""
+
+#: ../src/messages.tab:746
+#, c-format
+msgid  ":%s 715 %s :KNOCKs are disabled."
+msgstr ""
+
+#: ../src/messages.tab:536
+#, c-format
+msgid  ":%s 999 %s :Last Error Message"
+msgstr ""
diff --git a/messages/custom.po b/messages/custom.po
new file mode 100644 (file)
index 0000000..891f328
--- /dev/null
@@ -0,0 +1,900 @@
+# ircd-hybrid-7 custom message file
+# Copyright (C) 2000
+# David Taylor <davidt@yadt.co.uk>, 2000.
+# $Id: custom.po,v 1.1 2002/01/04 10:57:26 a1kmm Exp $
+#
+#, fuzzy
+msgid  ""
+msgstr "Project-Id-Version: ircd-hybrid-7\n"
+       "POT-Creation-Date: 2001-07-01 21:52-0700\n"
+       "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+       "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
+       "Language-Team: LANGUAGE <LL@li.org>\n"
+       "MIME-Version: 1.0\n"
+       "Content-Type: text/plain; charset=CHARSET\n"
+       "Content-Transfer-Encoding: ENCODING\n"
+
+#: ../src/messages.tab:24
+#, c-format
+msgid  ":%s 001 %s :Welcome to the %s Internet Relay Chat Network %s"
+msgstr ""
+
+#: ../src/messages.tab:25
+#, c-format
+msgid  ":%s 002 %s :Your host is %s, running version %s"
+msgstr ""
+
+#: ../src/messages.tab:26
+#, c-format
+msgid  ":%s 003 %s :This server was created %s"
+msgstr ""
+
+#: ../src/messages.tab:27
+#, c-format
+msgid  ":%s 004 %s %s %s oiwszcerkfydnxbaugl biklmnopstveIha bkloveIh"
+msgstr ""
+
+#: ../src/messages.tab:28
+#, c-format
+msgid  ":%s 005 %s %s :are supported by this server"
+msgstr ""
+
+#: ../src/messages.tab:33
+#, c-format
+msgid  ":%s 010 %s %s %d :Please use this Server/Port instead"
+msgstr ""
+
+#: ../src/messages.tab:43
+#, c-format
+msgid  ":%s 020 %s %s %s :Your ID and key is"
+msgstr ""
+
+#: ../src/messages.tab:223
+#, c-format
+msgid  ":%s 200 %s Link %s%s %s %s"
+msgstr ""
+
+#: ../src/messages.tab:224
+#, c-format
+msgid  ":%s 201 %s Try. %s %s"
+msgstr ""
+
+#: ../src/messages.tab:225
+#, c-format
+msgid  ":%s 202 %s H.S. %s %s"
+msgstr ""
+
+#: ../src/messages.tab:226
+#, c-format
+msgid  ":%s 203 %s ???? %s %s (%s) %d"
+msgstr ""
+
+#: ../src/messages.tab:227
+#, c-format
+msgid  ":%s 204 %s Oper %s %s (%s) %lu %lu"
+msgstr ""
+
+#: ../src/messages.tab:228
+#, c-format
+msgid  ":%s 205 %s User %s %s (%s) %lu %lu"
+msgstr ""
+
+#: ../src/messages.tab:229
+#, c-format
+msgid  ":%s 206 %s Serv %s %dS %dC %s %s!%s@%s %lu"
+msgstr ""
+
+#: ../src/messages.tab:231
+#, c-format
+msgid  ":%s 208 %s <newtype> 0 %s"
+msgstr ""
+
+#: ../src/messages.tab:232
+#, c-format
+msgid  ":%s 209 %s Class %s %d"
+msgstr ""
+
+#: ../src/messages.tab:235
+#, c-format
+msgid  ":%s 212 %s %s %u %u :%u"
+msgstr ""
+
+#: ../src/messages.tab:236
+#, c-format
+msgid  ":%s 213 %s %c %s %s %s %d %s"
+msgstr ""
+
+#: ../src/messages.tab:237
+#, c-format
+msgid  ":%s 214 %s %c %s * %s %d %s"
+msgstr ""
+
+#: ../src/messages.tab:238
+#, c-format
+msgid  ":%s 215 %s %c %s * %s@%s %d %s"
+msgstr ""
+
+#: ../src/messages.tab:239
+#, c-format
+msgid  ":%s 216 %s %c %s * %s %s"
+msgstr ""
+
+#: ../src/messages.tab:240
+#, c-format
+msgid  ":%s 217 %s %c %s %s"
+msgstr ""
+
+#: ../src/messages.tab:241
+#, c-format
+msgid  ":%s 218 %s %c %s %d %d %d %lu"
+msgstr ""
+
+#: ../src/messages.tab:242
+#, c-format
+msgid  ":%s 219 %s %s :End of /STATS report"
+msgstr ""
+
+#: ../src/messages.tab:243
+#, c-format
+msgid  ":%s 220 %s %c %d %s %d :%s"
+msgstr ""
+
+#: ../src/messages.tab:244
+#, c-format
+msgid  ":%s 221 %s %s"
+msgstr ""
+
+#: ../src/messages.tab:248
+#, c-format
+msgid  ":%s 225 %s %c %s %s"
+msgstr ""
+
+#: ../src/messages.tab:249
+#, c-format
+msgid  ":%s 226 %s %s"
+msgstr ""
+
+#: ../src/messages.tab:264
+#, c-format
+msgid  ":%s 241 %s %c %s * %s %d %s"
+msgstr ""
+
+#: ../src/messages.tab:265
+#, c-format
+msgid  ":%s 242 %s :Server Up %d days, %d:%02d:%02d"
+msgstr ""
+
+#: ../src/messages.tab:266
+#, c-format
+msgid  ":%s 243 %s %c %s@%s * %s %s %s %s"
+msgstr ""
+
+#: ../src/messages.tab:267
+#, c-format
+msgid  ":%s 244 %s %c %s * %s %d %s"
+msgstr ""
+
+#: ../src/messages.tab:270
+#, c-format
+msgid  ":%s 247 %s X %s %s * * 0 0"
+msgstr ""
+
+#: ../src/messages.tab:272
+#, c-format
+msgid  ":%s 248 %s U %s %s"
+msgstr ""
+
+#: ../src/messages.tab:275
+#, c-format
+msgid  ":%s 250 %s :Highest connection count: %d (%d clients) (%d "
+       "connections received)"
+msgstr ""
+
+#: ../src/messages.tab:277
+#, c-format
+msgid  ":%s 251 %s :There are %d users and %d invisible on %d servers"
+msgstr ""
+
+#: ../src/messages.tab:278
+#, c-format
+msgid  ":%s 252 %s %d :IRC Operators online"
+msgstr ":%s 252 %s %d :Smurf Targets (IRC Operators) online"
+
+#: ../src/messages.tab:279
+#, c-format
+msgid  ":%s 253 %s %d :unknown connection(s)"
+msgstr ""
+
+#: ../src/messages.tab:280
+#, c-format
+msgid  ":%s 254 %s %d :channels formed"
+msgstr ""
+
+#: ../src/messages.tab:281
+#, c-format
+msgid  ":%s 255 %s :I have %d clients and %d servers"
+msgstr ""
+
+#: ../src/messages.tab:282
+#, c-format
+msgid  ":%s 256 %s :Administrative info about %s"
+msgstr ""
+
+#: ../src/messages.tab:283
+#, c-format
+msgid  ":%s 257 %s :%s"
+msgstr ""
+
+#: ../src/messages.tab:284
+#, c-format
+msgid  ":%s 258 %s :%s"
+msgstr ""
+
+#: ../src/messages.tab:285
+#, c-format
+msgid  ":%s 259 %s :%s"
+msgstr ""
+
+#: ../src/messages.tab:287
+#, c-format
+msgid  ":%s 261 %s File %s %d"
+msgstr ""
+
+#: ../src/messages.tab:288
+#, c-format
+msgid  ":%s 262 %s %s :End of TRACE"
+msgstr ""
+
+#: ../src/messages.tab:290
+#, c-format
+msgid  ":%s 263 %s :Server load is temporarily too heavy. Please wait a "
+       "while and try again."
+msgstr ":%s 263 %s :Hold your horses... the server load is temporarily too "
+       "heavy. Try again later, ok?"
+
+#: ../src/messages.tab:292
+#, c-format
+msgid  ":%s 265 %s :Current local  users: %d  Max: %d"
+msgstr ""
+
+#: ../src/messages.tab:293
+#, c-format
+msgid  ":%s 266 %s :Current global users: %d  Max: %d"
+msgstr ""
+
+#: ../src/messages.tab:303
+#, c-format
+msgid  ":%s 276 %s %s :has %d possible virtual channels available"
+msgstr ""
+
+#: ../src/messages.tab:304
+#, c-format
+msgid  ":%s 277 %s %s "
+msgstr ""
+
+#: ../src/messages.tab:305
+#, c-format
+msgid  ":%s 278 %s :Type /%s %s <key> to specify the channel you want"
+msgstr ""
+
+#: ../src/messages.tab:306
+#, c-format
+msgid   ":%s 281 %s %s :"
+msgstr  ""
+
+#: ../src/messages.tab:307
+#, c-format
+msgid   ":%s 282 %s :End of /ACCEPT list."
+msgstr  ""
+
+#: ../src/messages.tab:328
+#, c-format
+msgid  ":%s 301 %s %s :%s"
+msgstr ""
+
+#: ../src/messages.tab:329
+#, c-format
+msgid  ":%s 302 %s :%s"
+msgstr ""
+
+#: ../src/messages.tab:330
+#, c-format
+msgid  ":%s 303 %s :"
+msgstr ""
+
+#: ../src/messages.tab:332
+#, c-format
+msgid  ":%s 305 %s :You are no longer marked as being away"
+msgstr ":%s 305 %s :OK, you're not /away anymore. Did you have fun?"
+
+#: ../src/messages.tab:333
+#, c-format
+msgid  ":%s 306 %s :You have been marked as being away"
+msgstr ":%s 306 %s :OK, you're /away now. Hurry back!"
+
+#: ../src/messages.tab:335
+#, c-format
+msgid  ":%s 308 %s %s :is a Server Administrator"
+msgstr ":%s 308 %s %s :is a Goon Gumpa (Server Admin)"
+
+#: ../src/messages.tab:338
+#, c-format
+msgid  ":%s 311 %s %s %s %s * :%s"
+msgstr ""
+
+#: ../src/messages.tab:339
+#, c-format
+msgid  ":%s 312 %s %s %s :%s"
+msgstr ""
+
+#: ../src/messages.tab:340
+#, c-format
+msgid  ":%s 313 %s %s :is an IRC Operator"
+msgstr ":%s 313 %s %s :is a Smurf Target (IRC Operator)"
+
+#: ../src/messages.tab:341
+#, c-format
+msgid  ":%s 314 %s %s %s %s * :%s"
+msgstr ""
+
+#: ../src/messages.tab:342
+#, c-format
+msgid  ":%s 315 %s %s :End of /WHO list."
+msgstr ""
+
+#: ../src/messages.tab:344
+#, c-format
+msgid  ":%s 317 %s %s %d %d :seconds idle, signon time"
+msgstr ""
+
+#: ../src/messages.tab:345
+#, c-format
+msgid  ":%s 318 %s %s :End of /WHOIS list."
+msgstr ""
+
+#: ../src/messages.tab:346
+#, c-format
+msgid  ":%s 319 %s %s :%s"
+msgstr ""
+
+#: ../src/messages.tab:348
+#, c-format
+msgid  ":%s 321 %s Channel :Users  Name"
+msgstr ""
+
+#: ../src/messages.tab:349
+#, c-format
+msgid  ":%s 322 %s %s %d :%s"
+msgstr ""
+
+#: ../src/messages.tab:350
+#, c-format
+msgid  ":%s 323 %s :End of /LIST"
+msgstr ""
+
+#: ../src/messages.tab:351
+#, c-format
+msgid  ":%s 324 %s %s %s %s"
+msgstr ""
+
+#: ../src/messages.tab:356
+#, c-format
+msgid  ":%s 329 %s %s %lu"
+msgstr ""
+
+#: ../src/messages.tab:358
+#, c-format
+msgid  ":%s 331 %s %s :No topic is set."
+msgstr ""
+
+#: ../src/messages.tab:359
+#, c-format
+msgid  ":%s 332 %s %s :%s"
+msgstr ""
+
+#: ../src/messages.tab:360
+#, c-format
+msgid  ":%s 333 %s %s %s %lu"
+msgstr ""
+
+#: ../src/messages.tab:368
+#, c-format
+msgid  ":%s 341 %s %s %s"
+msgstr ""
+
+#: ../src/messages.tab:373
+#, c-format
+msgid  ":%s 346 %s %s %s %s %lu"
+msgstr ""
+
+#: ../src/messages.tab:374
+#, c-format
+msgid  ":%s 347 %s %s :End of Channel Invite List"
+msgstr ""
+
+#: ../src/messages.tab:375
+#, c-format
+msgid  ":%s 348 %s %s %s %s %lu"
+msgstr ""
+
+#: ../src/messages.tab:376
+#, c-format
+msgid  ":%s 349 %s %s :End of Channel Exception List"
+msgstr ""
+
+#: ../src/messages.tab:378
+#, c-format
+msgid  ":%s 351 %s %s(%s).%s %s :%s%s"
+msgstr ""
+
+#: ../src/messages.tab:379
+#, c-format
+msgid  ":%s 352 %s %s %s %s %s %s %s :%d %s"
+msgstr ""
+
+#: ../src/messages.tab:380
+#, c-format
+msgid  ":%s 353 %s %s"
+msgstr ""
+
+#: ../src/messages.tab:389
+#, c-format
+msgid  ":%s 362 %s %s :Closed. Status = %d"
+msgstr ""
+
+#: ../src/messages.tab:390
+#, c-format
+msgid  ":%s 363 %s %d: Connections Closed"
+msgstr ""
+
+#: ../src/messages.tab:391
+#, c-format
+msgid  ":%s 364 %s %s %s :%d %s"
+msgstr ""
+
+#: ../src/messages.tab:392
+#, c-format
+msgid  ":%s 365 %s %s :End of /LINKS list."
+msgstr ""
+
+#: ../src/messages.tab:393
+#, c-format
+msgid  ":%s 366 %s %s :End of /NAMES list."
+msgstr ""
+
+#: ../src/messages.tab:394
+#, c-format
+msgid  ":%s 367 %s %s %s %s %lu"
+msgstr ""
+
+#: ../src/messages.tab:395
+#, c-format
+msgid  ":%s 368 %s %s :End of Channel Ban List"
+msgstr ""
+
+#: ../src/messages.tab:396
+#, c-format
+msgid  ":%s 369 %s %s :End of WHOWAS"
+msgstr ""
+
+#: ../src/messages.tab:398
+#, c-format
+msgid  ":%s 371 %s :%s"
+msgstr ""
+
+#: ../src/messages.tab:399
+#, c-format
+msgid  ":%s 372 %s :- %s"
+msgstr ""
+
+#: ../src/messages.tab:400
+#, c-format
+msgid  ":%s 373 %s :Server INFO"
+msgstr ""
+
+#: ../src/messages.tab:401
+#, c-format
+msgid  ":%s 374 %s :End of /INFO list."
+msgstr ""
+
+#: ../src/messages.tab:402
+#, c-format
+msgid  ":%s 375 %s :- %s Message of the Day - "
+msgstr ""
+
+#: ../src/messages.tab:403
+#, c-format
+msgid  ":%s 376 %s :End of /MOTD command."
+msgstr ""
+
+#: ../src/messages.tab:408
+#, c-format
+msgid  ":%s 381 %s :You have entered... the Twilight Zone!."
+msgstr ":%s 381 %s :You are now one bad motherfucker - Go /kill someone."
+
+#: ../src/messages.tab:409
+#, c-format
+msgid  ":%s 382 %s %s :Rehashing"
+msgstr ":%s 382 %s %s :it slices, dices, and even reloads config files! "
+       "Rehashing config file, mang."
+
+#: ../src/messages.tab:411
+#, c-format
+msgid  ":%s 384 %s %d :Port to local server is"
+msgstr ""
+
+#: ../src/messages.tab:413
+#, c-format
+msgid  ":%s 386 %s :%s"
+msgstr ""
+
+#: ../src/messages.tab:418
+#, c-format
+msgid  ":%s 391 %s %s :%s"
+msgstr ""
+
+#: ../src/messages.tab:428
+#, c-format
+msgid  ":%s 401 %s %s :No such nick/channel"
+msgstr ""
+
+#: ../src/messages.tab:429
+#, c-format
+msgid  ":%s 402 %s %s :No such server"
+msgstr ""
+
+#: ../src/messages.tab:430
+#, c-format
+msgid  ":%s 403 %s %s :No such channel"
+msgstr ""
+
+#: ../src/messages.tab:431
+#, c-format
+msgid  ":%s 404 %s %s :Cannot send to channel"
+msgstr ""
+
+#: ../src/messages.tab:432
+#, c-format
+msgid  ":%s 405 %s %s :You have joined too many channels"
+msgstr ""
+
+#: ../src/messages.tab:433
+#, c-format
+msgid  ":%s 406 %s %s :There was no such nickname"
+msgstr ""
+
+#: ../src/messages.tab:435
+#, c-format
+msgid  ":%s 407 %s %s :Too many recipients. Only %d processed"
+msgstr ""
+
+#: ../src/messages.tab:437
+#, c-format
+msgid  ":%s 409 %s :No origin specified"
+msgstr ""
+
+#: ../src/messages.tab:439
+#, c-format
+msgid  ":%s 411 %s :No recipient given (%s)"
+msgstr ""
+
+#: ../src/messages.tab:440
+#, c-format
+msgid  ":%s 412 %s :No text to send"
+msgstr ""
+
+#: ../src/messages.tab:441
+#, c-format
+msgid  ":%s 413 %s %s :No toplevel domain specified"
+msgstr ""
+
+#: ../src/messages.tab:442
+#, c-format
+msgid  ":%s 414 %s %s :Wildcard in toplevel Domain"
+msgstr ""
+
+#: ../src/messages.tab:449
+#, c-format
+msgid  ":%s 421 %s %s :Unknown command"
+msgstr ""
+
+#: ../src/messages.tab:450
+#, c-format
+msgid  ":%s 422 %s :MOTD File is missing"
+msgstr ""
+
+#: ../src/messages.tab:452
+#, c-format
+msgid  ":%s 423 %s %s :No administrative info available"
+msgstr ""
+
+#: ../src/messages.tab:453
+#, c-format
+msgid  ":%s 424 %s :File error doing %s on %s"
+msgstr ""
+
+#: ../src/messages.tab:460
+#, c-format
+msgid  ":%s 431 %s :No nickname given"
+msgstr ""
+
+#: ../src/messages.tab:461
+#, c-format
+msgid  ":%s 432 %s %s :Erroneous Nickname"
+msgstr ""
+
+#: ../src/messages.tab:462
+#, c-format
+msgid  ":%s 433 %s %s :Nickname is already in use."
+msgstr ""
+
+#: ../src/messages.tab:465
+#, c-format
+msgid  ":%s 436 %s %s :Nickname collision KILL"
+msgstr ""
+
+#: ../src/messages.tab:466
+#, c-format
+msgid  ":%s 437 %s %s :Nick/channel is temporarily unavailable"
+msgstr ""
+
+#: ../src/messages.tab:467
+#, c-format
+msgid  ":%s 438 %s %s %s :Nick change too fast. Please wait %d seconds."
+msgstr ""
+
+#: ../src/messages.tab:470
+#, c-format
+msgid  ":%s 441 %s %s %s :They aren't on that channel"
+msgstr ""
+
+#: ../src/messages.tab:471
+#, c-format
+msgid  ":%s 442 %s %s :You're not on that channel"
+msgstr ""
+
+#: ../src/messages.tab:472
+#, c-format
+msgid  ":%s 443 %s %s %s :is already on channel"
+msgstr ""
+
+#: ../src/messages.tab:473
+#, c-format
+msgid  ":%s 444 %s %s :User not logged in"
+msgstr ""
+
+#: ../src/messages.tab:474
+#, c-format
+msgid  ":%s 445 %s :SUMMON has been removed"
+msgstr ""
+
+#: ../src/messages.tab:475
+#, c-format
+msgid  ":%s 446 %s :USERS has been removed"
+msgstr ""
+
+#: ../src/messages.tab:480
+#, c-format
+msgid  ":%s 451 %s :You have not registered"
+msgstr ""
+
+#: ../src/messages.tab:481
+#, c-format
+msgid   ":%s 456 %s :Accept list is full"
+msgstr  ""
+
+#: ../src/messages.tab:482
+#, c-format
+msgid   ":%s 457 %s %s :is already on your accept list"
+msgstr  ""
+
+#: ../src/messages.tab:483
+#, c-format
+msgid   ":%s 458 %s %s :is not on your accept list"
+msgstr  ""
+
+#: ../src/messages.tab:490
+#, c-format
+msgid  ":%s 461 %s %s :Not enough parameters"
+msgstr ""
+
+#: ../src/messages.tab:491
+#, c-format
+msgid  ":%s 462 %s :You may not reregister"
+msgstr ""
+
+#: ../src/messages.tab:492
+#, c-format
+msgid  ":%s 463 %s :Your host isn't among the privileged"
+msgstr ""
+
+#: ../src/messages.tab:493
+#, c-format
+msgid  ":%s 464 %s :Password Incorrect"
+msgstr ":%s 464 %s :BZZT!! Wrong password, homez. Are you sure you know what "
+       "you're doing??"
+
+#: ../src/messages.tab:494
+#, c-format
+msgid  ":%s 465 %s :You are banned from this server- %s"
+msgstr ""
+
+#: ../src/messages.tab:496
+#, c-format
+msgid  ":%s 467 %s %s :Channel key already set"
+msgstr ""
+
+#: ../src/messages.tab:500
+#, c-format
+msgid  ":%s 471 %s %s :Cannot join channel (+l)"
+msgstr ""
+
+#: ../src/messages.tab:501
+#, c-format
+msgid  ":%s 472 %s %c :is unknown mode char to me"
+msgstr ""
+
+#: ../src/messages.tab:502
+#, c-format
+msgid  ":%s 473 %s %s :Cannot join channel (+i)"
+msgstr ""
+
+#: ../src/messages.tab:503
+#, c-format
+msgid  ":%s 474 %s %s :Cannot join channel (+b)"
+msgstr ""
+
+#: ../src/messages.tab:504
+#, c-format
+msgid  ":%s 475 %s %s :Cannot join channel (+k)"
+msgstr ""
+
+#: ../src/messages.tab:505
+#, c-format
+msgid  ":%s 476 %s %s :Bad Channel Mask"
+msgstr ""
+
+#: ../src/messages.tab:506
+#, c-format
+msgid  ":%s 477 %s %s :Channel does not support modes"
+msgstr ""
+
+#: ../src/messages.tab:507
+#, c-format
+msgid  ":%s 478 %s %s %s :Channel ban list is full"
+msgstr ""
+
+#: ../src/messages.tab:508
+#, c-format
+msgid  ":%s 479 %s %s :Illegal channel name"
+msgstr ""
+
+#: ../src/messages.tab:511
+#, fuzzy, c-format
+msgid  ":%s 481 %s :Permission Denied - You're not an IRC operator"
+msgstr ":%s 481 %s :I don't THINK so, homez... you ain't got what it takes. "
+       "(IRC operator)"
+
+#: ../src/messages.tab:512
+#, c-format
+msgid  ":%s 482 %s %s :You're not channel operator"
+msgstr ":%s 482 %s %s :You can't do that thing, when you don't have that "
+       "swing (You're not channel operator)"
+
+#: ../src/messages.tab:513
+#, c-format
+msgid  ":%s 483 %s :You can't kill a server!"
+msgstr ":%s 483 %s :Don't be an idiot - you can't kill a SERVER, fool."
+
+#: ../src/messages.tab:514
+#, c-format
+msgid  ":%s 484 %s :You are restricted"
+msgstr ""
+
+#: ../src/messages.tab:516
+#, c-format
+msgid  ":%s 485 %s :Can't change nick when banned or on a moderated channel "
+       "(%s)"
+msgstr ""
+
+#: ../src/messages.tab:522
+#, c-format
+msgid  ":%s 491 %s :Only few of mere mortals may try to enter the twilight "
+       "zone"
+msgstr ":%s 491 %s :Sorry, you just don't have what it takes to be an IRC "
+       "Operator here."
+
+#: ../src/messages.tab:532
+#, c-format
+msgid  ":%s 501 %s :Unknown MODE flag"
+msgstr ""
+
+#: ../src/messages.tab:533
+#, c-format
+msgid  ":%s 502 %s :Can't change mode for other users"
+msgstr ""
+
+#: ../src/messages.tab:534
+#, c-format
+msgid  ":%s 503 %s :Message could not be delivered to %s"
+msgstr ""
+
+#: ../src/messages.tab:535
+#, c-format
+msgid  ":%s 504 %s %s :User is not on this server"
+msgstr ""
+
+#: ../src/messages.tab:537
+#, c-format
+msgid   ":%s 506 %s :Virtual Channels are disabled"
+msgstr  ""
+
+#: ../src/messages.tab:538
+#, c-format
+msgid   ":%s 507 %s %s :You are already on a subchan"
+msgstr  ""
+
+#: ../src/messages.tab:555
+#, c-format
+msgid  ":%s 524 %s %s :Help not found"
+msgstr  ""
+
+#: ../src/messages.tab:702
+#, c-format
+msgid   ":%s 702 %s %s 0x%x %s"
+msgstr  ""
+
+#: ../src/messages.tab:703
+#, c-format
+msgid   ":%s 703 %s :End of /MODLIST."
+msgstr  ""
+
+#: ../src/messages.tab:735
+#, c-format
+msgid   ":%s 704 %s %s :%s"
+msgstr  ""
+
+#: ../src/messages.tab:736
+#, c-format
+msgid   ":%s 705 %s %s :%s"
+msgstr  ""
+
+#: ../src/messages.tab:737
+#, c-format
+msgid   ":%s 706 %s %s :End of /HELP."
+msgstr  ""
+
+#: ../src/messages.tab:741
+#, c-format
+msgid   ":%s 710 %s %s %s!%s@%s :has asked for an invite."
+msgstr  ""
+
+#: ../src/messages.tab:742
+#, c-format
+msgid   ":%s 711 %s %s :Your KNOCK has been delivered."
+msgstr ""
+
+#: ../src/messages.tab:743
+#, c-format
+msgid   ":%s 712 %s %s :Too many KNOCKs (%s)."
+msgstr  ""
+
+#: ../src/messages.tab:744
+#, c-format
+msgid   ":%s 713 %s %s :Channel is open."
+msgstr  ""
+
+#: ../src/messages.tab:745
+#, c-format
+msgid   ":%s 714 %s %s :You are already on that channel."
+msgstr  ""
+
+#: ../src/messages.tab:746
+#, c-format
+msgid   ":%s 715 %s :KNOCKs are disabled."
+msgstr  ""
+
+#: ../src/messages.tab:536
+#, c-format
+msgid  ":%s 999 %s :Last Error Message"
+msgstr ""
diff --git a/modules/.depend b/modules/.depend
new file mode 100644 (file)
index 0000000..ade10da
--- /dev/null
@@ -0,0 +1,589 @@
+# $Id: .depend,v 1.1 2002/01/04 10:57:29 a1kmm Exp $
+m_accept.o: m_accept.c ../include/handlers.h ../include/client.h \
+  ../include/config.h ../include/setup.h ../include/defaults.h \
+  ../include/ircd_defs.h ../include/ircd_handler.h ../include/linebuf.h \
+  ../include/tools.h ../include/channel.h ../include/res.h \
+  ../include/fileio.h ../adns/adns.h ../include/ircd.h \
+  ../include/memory.h ../include/balloc.h ../include/irc_string.h \
+  ../include/sprintf_irc.h ../include/hash.h ../include/list.h \
+  ../include/numeric.h ../include/s_conf.h ../include/motd.h \
+  ../include/class.h ../include/s_serv.h ../include/send.h \
+  ../include/msg.h ../include/parse.h ../include/modules.h
+m_admin.o: m_admin.c ../include/handlers.h ../include/client.h \
+  ../include/config.h ../include/setup.h ../include/defaults.h \
+  ../include/ircd_defs.h ../include/ircd_handler.h ../include/linebuf.h \
+  ../include/tools.h ../include/channel.h ../include/res.h \
+  ../include/fileio.h ../adns/adns.h ../include/ircd.h \
+  ../include/memory.h ../include/balloc.h ../include/irc_string.h \
+  ../include/sprintf_irc.h ../include/numeric.h ../include/s_conf.h \
+  ../include/motd.h ../include/class.h ../include/s_serv.h \
+  ../include/send.h ../include/msg.h ../include/parse.h ../include/hook.h \
+  ../include/modules.h
+m_away.o: m_away.c ../include/handlers.h ../include/client.h \
+  ../include/config.h ../include/setup.h ../include/defaults.h \
+  ../include/ircd_defs.h ../include/ircd_handler.h ../include/linebuf.h \
+  ../include/tools.h ../include/channel.h ../include/res.h \
+  ../include/fileio.h ../adns/adns.h ../include/ircd.h \
+  ../include/memory.h ../include/balloc.h ../include/irc_string.h \
+  ../include/sprintf_irc.h ../include/numeric.h ../include/send.h \
+  ../include/msg.h ../include/parse.h ../include/modules.h \
+  ../include/s_conf.h ../include/motd.h ../include/class.h \
+  ../include/s_serv.h
+m_capab.o: m_capab.c ../include/handlers.h ../include/client.h \
+  ../include/config.h ../include/setup.h ../include/defaults.h \
+  ../include/ircd_defs.h ../include/ircd_handler.h ../include/linebuf.h \
+  ../include/tools.h ../include/channel.h ../include/res.h \
+  ../include/fileio.h ../adns/adns.h ../include/ircd.h \
+  ../include/memory.h ../include/balloc.h ../include/irc_string.h \
+  ../include/sprintf_irc.h ../include/s_serv.h ../include/s_conf.h \
+  ../include/motd.h ../include/class.h ../include/msg.h \
+  ../include/parse.h ../include/modules.h
+m_cburst.o: m_cburst.c ../include/tools.h ../include/channel.h \
+  ../include/config.h ../include/setup.h ../include/defaults.h \
+  ../include/ircd_defs.h ../include/client.h ../include/ircd_handler.h \
+  ../include/linebuf.h ../include/res.h ../include/fileio.h \
+  ../adns/adns.h ../include/ircd.h ../include/memory.h \
+  ../include/balloc.h ../include/irc_string.h ../include/sprintf_irc.h \
+  ../include/common.h ../include/hash.h ../include/list.h \
+  ../include/numeric.h ../include/s_serv.h ../include/s_user.h \
+  ../include/send.h ../include/msg.h ../include/handlers.h \
+  ../include/parse.h ../include/modules.h
+m_challenge.o: m_challenge.c ../include/handlers.h ../include/client.h \
+  ../include/config.h ../include/setup.h ../include/defaults.h \
+  ../include/ircd_defs.h ../include/ircd_handler.h ../include/linebuf.h \
+  ../include/tools.h ../include/channel.h ../include/res.h \
+  ../include/fileio.h ../adns/adns.h ../include/ircd.h \
+  ../include/memory.h ../include/balloc.h ../include/irc_string.h \
+  ../include/sprintf_irc.h ../include/modules.h ../include/parse.h \
+  ../include/msg.h ../include/numeric.h ../include/send.h \
+  ../include/s_conf.h ../include/motd.h ../include/class.h \
+  ../include/rsa.h ../include/s_log.h
+m_cjoin.o: m_cjoin.c ../include/tools.h ../include/handlers.h \
+  ../include/channel.h ../include/config.h ../include/setup.h \
+  ../include/defaults.h ../include/ircd_defs.h ../include/channel_mode.h \
+  ../include/vchannel.h ../include/client.h ../include/ircd_handler.h \
+  ../include/linebuf.h ../include/res.h ../include/fileio.h \
+  ../adns/adns.h ../include/ircd.h ../include/memory.h \
+  ../include/balloc.h ../include/irc_string.h ../include/sprintf_irc.h \
+  ../include/common.h ../include/hash.h ../include/list.h \
+  ../include/numeric.h ../include/send.h ../include/s_serv.h \
+  ../include/s_conf.h ../include/motd.h ../include/class.h \
+  ../include/msg.h ../include/parse.h ../include/modules.h
+m_close.o: m_close.c ../include/tools.h ../include/handlers.h \
+  ../include/client.h ../include/config.h ../include/setup.h \
+  ../include/defaults.h ../include/ircd_defs.h ../include/ircd_handler.h \
+  ../include/linebuf.h ../include/channel.h ../include/res.h \
+  ../include/fileio.h ../adns/adns.h ../include/ircd.h \
+  ../include/memory.h ../include/balloc.h ../include/irc_string.h \
+  ../include/sprintf_irc.h ../include/numeric.h ../include/fdlist.h \
+  ../include/s_bsd.h ../include/send.h ../include/msg.h \
+  ../include/parse.h ../include/modules.h
+m_connect.o: m_connect.c ../include/handlers.h ../include/client.h \
+  ../include/config.h ../include/setup.h ../include/defaults.h \
+  ../include/ircd_defs.h ../include/ircd_handler.h ../include/linebuf.h \
+  ../include/tools.h ../include/channel.h ../include/res.h \
+  ../include/fileio.h ../adns/adns.h ../include/ircd.h \
+  ../include/memory.h ../include/balloc.h ../include/irc_string.h \
+  ../include/sprintf_irc.h ../include/numeric.h ../include/fdlist.h \
+  ../include/s_bsd.h ../include/s_conf.h ../include/motd.h \
+  ../include/class.h ../include/s_log.h ../include/s_serv.h \
+  ../include/send.h ../include/msg.h ../include/parse.h ../include/hash.h \
+  ../include/modules.h
+m_cryptlink.o: m_cryptlink.c ../include/handlers.h ../include/client.h \
+  ../include/config.h ../include/setup.h ../include/defaults.h \
+  ../include/ircd_defs.h ../include/ircd_handler.h ../include/linebuf.h \
+  ../include/tools.h ../include/channel.h ../include/res.h \
+  ../include/fileio.h ../adns/adns.h ../include/ircd.h \
+  ../include/memory.h ../include/balloc.h ../include/irc_string.h \
+  ../include/sprintf_irc.h ../include/modules.h ../include/parse.h \
+  ../include/msg.h ../include/numeric.h ../include/send.h \
+  ../include/rsa.h ../include/common.h ../include/event.h \
+  ../include/hash.h ../include/md5.h ../include/list.h \
+  ../include/s_conf.h ../include/motd.h ../include/class.h \
+  ../include/s_log.h ../include/s_serv.h ../include/s_stats.h \
+  ../include/scache.h
+m_dmem.o: m_dmem.c ../include/handlers.h ../include/client.h \
+  ../include/config.h ../include/setup.h ../include/defaults.h \
+  ../include/ircd_defs.h ../include/ircd_handler.h ../include/linebuf.h \
+  ../include/tools.h ../include/channel.h ../include/res.h \
+  ../include/fileio.h ../adns/adns.h ../include/ircd.h \
+  ../include/memory.h ../include/balloc.h ../include/irc_string.h \
+  ../include/sprintf_irc.h ../include/common.h ../include/list.h \
+  ../include/s_gline.h ../include/numeric.h ../include/s_conf.h \
+  ../include/motd.h ../include/class.h ../include/s_log.h \
+  ../include/send.h ../include/msg.h ../include/parse.h \
+  ../include/modules.h
+m_drop.o: m_drop.c ../include/tools.h ../include/channel.h \
+  ../include/config.h ../include/setup.h ../include/defaults.h \
+  ../include/ircd_defs.h ../include/client.h ../include/ircd_handler.h \
+  ../include/linebuf.h ../include/res.h ../include/fileio.h \
+  ../adns/adns.h ../include/ircd.h ../include/memory.h \
+  ../include/balloc.h ../include/irc_string.h ../include/sprintf_irc.h \
+  ../include/common.h ../include/hash.h ../include/list.h \
+  ../include/numeric.h ../include/s_serv.h ../include/s_user.h \
+  ../include/send.h ../include/handlers.h ../include/msg.h \
+  ../include/parse.h ../include/modules.h
+m_eob.o: m_eob.c ../include/handlers.h ../include/client.h \
+  ../include/config.h ../include/setup.h ../include/defaults.h \
+  ../include/ircd_defs.h ../include/ircd_handler.h ../include/linebuf.h \
+  ../include/tools.h ../include/channel.h ../include/res.h \
+  ../include/fileio.h ../adns/adns.h ../include/ircd.h \
+  ../include/memory.h ../include/balloc.h ../include/irc_string.h \
+  ../include/sprintf_irc.h ../include/numeric.h ../include/s_conf.h \
+  ../include/motd.h ../include/class.h ../include/s_serv.h \
+  ../include/send.h ../include/msg.h ../include/parse.h \
+  ../include/modules.h
+m_gline.o: m_gline.c ../include/tools.h ../include/handlers.h \
+  ../include/s_gline.h ../include/config.h ../include/setup.h \
+  ../include/defaults.h ../include/ircd_defs.h ../include/channel.h \
+  ../include/client.h ../include/ircd_handler.h ../include/linebuf.h \
+  ../include/res.h ../include/fileio.h ../adns/adns.h ../include/ircd.h \
+  ../include/memory.h ../include/balloc.h ../include/irc_string.h \
+  ../include/sprintf_irc.h ../include/common.h ../include/m_kline.h \
+  ../include/hostmask.h ../include/numeric.h ../include/fdlist.h \
+  ../include/s_bsd.h ../include/s_conf.h ../include/motd.h \
+  ../include/class.h ../include/s_misc.h ../include/scache.h \
+  ../include/send.h ../include/msg.h ../include/s_serv.h \
+  ../include/hash.h ../include/parse.h ../include/modules.h \
+  ../include/list.h
+m_help.o: m_help.c ../include/handlers.h ../include/client.h \
+  ../include/config.h ../include/setup.h ../include/defaults.h \
+  ../include/ircd_defs.h ../include/ircd_handler.h ../include/linebuf.h \
+  ../include/tools.h ../include/channel.h ../include/res.h \
+  ../include/fileio.h ../adns/adns.h ../include/ircd.h \
+  ../include/memory.h ../include/balloc.h ../include/irc_string.h \
+  ../include/sprintf_irc.h ../include/motd.h ../include/msg.h \
+  ../include/numeric.h ../include/send.h ../include/s_conf.h \
+  ../include/class.h ../include/parse.h ../include/modules.h
+m_info.o: m_info.c ../include/tools.h ../include/m_info.h \
+  ../include/config.h ../include/setup.h ../include/defaults.h \
+  ../include/channel.h ../include/ircd_defs.h ../include/client.h \
+  ../include/ircd_handler.h ../include/linebuf.h ../include/res.h \
+  ../include/fileio.h ../adns/adns.h ../include/ircd.h \
+  ../include/memory.h ../include/balloc.h ../include/irc_string.h \
+  ../include/sprintf_irc.h ../include/common.h ../include/hook.h \
+  ../include/numeric.h ../include/s_serv.h ../include/s_user.h \
+  ../include/send.h ../include/s_conf.h ../include/motd.h \
+  ../include/class.h ../include/handlers.h ../include/msg.h \
+  ../include/parse.h ../include/modules.h
+m_invite.o: m_invite.c ../include/tools.h ../include/handlers.h \
+  ../include/common.h ../include/channel.h ../include/config.h \
+  ../include/setup.h ../include/defaults.h ../include/ircd_defs.h \
+  ../include/channel_mode.h ../include/list.h ../include/memory.h \
+  ../include/balloc.h ../include/vchannel.h ../include/client.h \
+  ../include/ircd_handler.h ../include/linebuf.h ../include/res.h \
+  ../include/fileio.h ../adns/adns.h ../include/ircd.h \
+  ../include/irc_string.h ../include/sprintf_irc.h ../include/hash.h \
+  ../include/numeric.h ../include/send.h ../include/s_conf.h \
+  ../include/motd.h ../include/class.h ../include/s_serv.h \
+  ../include/msg.h ../include/parse.h ../include/modules.h
+m_ison.o: m_ison.c ../include/handlers.h ../include/client.h \
+  ../include/config.h ../include/setup.h ../include/defaults.h \
+  ../include/ircd_defs.h ../include/ircd_handler.h ../include/linebuf.h \
+  ../include/tools.h ../include/channel.h ../include/res.h \
+  ../include/fileio.h ../adns/adns.h ../include/ircd.h \
+  ../include/memory.h ../include/balloc.h ../include/irc_string.h \
+  ../include/sprintf_irc.h ../include/numeric.h ../include/send.h \
+  ../include/msg.h ../include/parse.h ../include/modules.h \
+  ../include/s_conf.h ../include/motd.h ../include/class.h \
+  ../include/s_serv.h
+m_join.o: m_join.c ../include/tools.h ../include/handlers.h \
+  ../include/channel.h ../include/config.h ../include/setup.h \
+  ../include/defaults.h ../include/ircd_defs.h ../include/channel_mode.h \
+  ../include/vchannel.h ../include/client.h ../include/ircd_handler.h \
+  ../include/linebuf.h ../include/res.h ../include/fileio.h \
+  ../adns/adns.h ../include/ircd.h ../include/memory.h \
+  ../include/balloc.h ../include/irc_string.h ../include/sprintf_irc.h \
+  ../include/common.h ../include/resv.h ../include/hash.h \
+  ../include/list.h ../include/numeric.h ../include/send.h \
+  ../include/s_serv.h ../include/s_conf.h ../include/motd.h \
+  ../include/class.h ../include/msg.h ../include/parse.h \
+  ../include/modules.h
+m_kline.o: m_kline.c ../include/tools.h ../include/m_kline.h \
+  ../include/channel.h ../include/config.h ../include/setup.h \
+  ../include/defaults.h ../include/ircd_defs.h ../include/class.h \
+  ../include/client.h ../include/ircd_handler.h ../include/linebuf.h \
+  ../include/res.h ../include/fileio.h ../adns/adns.h ../include/ircd.h \
+  ../include/memory.h ../include/balloc.h ../include/irc_string.h \
+  ../include/sprintf_irc.h ../include/common.h ../include/hostmask.h \
+  ../include/numeric.h ../include/fdlist.h ../include/s_bsd.h \
+  ../include/s_conf.h ../include/motd.h ../include/s_log.h \
+  ../include/s_misc.h ../include/send.h ../include/hash.h \
+  ../include/handlers.h ../include/s_serv.h ../include/msg.h \
+  ../include/parse.h ../include/modules.h
+m_knock.o: m_knock.c ../include/tools.h ../include/handlers.h \
+  ../include/channel.h ../include/config.h ../include/setup.h \
+  ../include/defaults.h ../include/ircd_defs.h ../include/channel_mode.h \
+  ../include/client.h ../include/ircd_handler.h ../include/linebuf.h \
+  ../include/res.h ../include/fileio.h ../adns/adns.h ../include/ircd.h \
+  ../include/memory.h ../include/balloc.h ../include/irc_string.h \
+  ../include/sprintf_irc.h ../include/hash.h ../include/numeric.h \
+  ../include/send.h ../include/s_conf.h ../include/motd.h \
+  ../include/class.h ../include/vchannel.h ../include/msg.h \
+  ../include/parse.h ../include/modules.h ../include/s_serv.h
+m_links.o: m_links.c ../include/handlers.h ../include/client.h \
+  ../include/config.h ../include/setup.h ../include/defaults.h \
+  ../include/ircd_defs.h ../include/ircd_handler.h ../include/linebuf.h \
+  ../include/tools.h ../include/channel.h ../include/res.h \
+  ../include/fileio.h ../adns/adns.h ../include/ircd.h \
+  ../include/memory.h ../include/balloc.h ../include/irc_string.h \
+  ../include/sprintf_irc.h ../include/numeric.h ../include/s_serv.h \
+  ../include/send.h ../include/s_conf.h ../include/motd.h \
+  ../include/class.h ../include/msg.h ../include/parse.h \
+  ../include/modules.h ../include/hook.h
+m_list.o: m_list.c ../include/tools.h ../include/handlers.h \
+  ../include/channel.h ../include/config.h ../include/setup.h \
+  ../include/defaults.h ../include/ircd_defs.h ../include/channel_mode.h \
+  ../include/client.h ../include/ircd_handler.h ../include/linebuf.h \
+  ../include/res.h ../include/fileio.h ../adns/adns.h ../include/ircd.h \
+  ../include/memory.h ../include/balloc.h ../include/irc_string.h \
+  ../include/sprintf_irc.h ../include/hash.h ../include/numeric.h \
+  ../include/s_conf.h ../include/motd.h ../include/class.h \
+  ../include/s_serv.h ../include/send.h ../include/vchannel.h \
+  ../include/list.h ../include/msg.h ../include/parse.h \
+  ../include/modules.h
+m_lljoin.o: m_lljoin.c ../include/tools.h ../include/channel.h \
+  ../include/config.h ../include/setup.h ../include/defaults.h \
+  ../include/ircd_defs.h ../include/channel_mode.h ../include/vchannel.h \
+  ../include/client.h ../include/ircd_handler.h ../include/linebuf.h \
+  ../include/res.h ../include/fileio.h ../adns/adns.h ../include/ircd.h \
+  ../include/memory.h ../include/balloc.h ../include/irc_string.h \
+  ../include/sprintf_irc.h ../include/hash.h ../include/common.h \
+  ../include/list.h ../include/numeric.h ../include/s_serv.h \
+  ../include/s_conf.h ../include/motd.h ../include/class.h \
+  ../include/send.h ../include/handlers.h ../include/msg.h \
+  ../include/parse.h ../include/modules.h
+m_llnick.o: m_llnick.c ../include/tools.h ../include/client.h \
+  ../include/config.h ../include/setup.h ../include/defaults.h \
+  ../include/ircd_defs.h ../include/ircd_handler.h ../include/linebuf.h \
+  ../include/channel.h ../include/res.h ../include/fileio.h \
+  ../adns/adns.h ../include/ircd.h ../include/memory.h \
+  ../include/balloc.h ../include/irc_string.h ../include/sprintf_irc.h \
+  ../include/hash.h ../include/common.h ../include/list.h \
+  ../include/numeric.h ../include/s_serv.h ../include/send.h \
+  ../include/handlers.h ../include/msg.h ../include/parse.h \
+  ../include/modules.h
+m_locops.o: m_locops.c ../include/handlers.h ../include/client.h \
+  ../include/config.h ../include/setup.h ../include/defaults.h \
+  ../include/ircd_defs.h ../include/ircd_handler.h ../include/linebuf.h \
+  ../include/tools.h ../include/channel.h ../include/res.h \
+  ../include/fileio.h ../adns/adns.h ../include/ircd.h \
+  ../include/memory.h ../include/balloc.h ../include/irc_string.h \
+  ../include/sprintf_irc.h ../include/numeric.h ../include/send.h \
+  ../include/s_user.h ../include/s_conf.h ../include/motd.h \
+  ../include/class.h ../include/hash.h ../include/msg.h \
+  ../include/parse.h ../include/modules.h
+m_lusers.o: m_lusers.c ../include/handlers.h ../include/client.h \
+  ../include/config.h ../include/setup.h ../include/defaults.h \
+  ../include/ircd_defs.h ../include/ircd_handler.h ../include/linebuf.h \
+  ../include/tools.h ../include/channel.h ../include/res.h \
+  ../include/fileio.h ../adns/adns.h ../include/ircd.h \
+  ../include/memory.h ../include/balloc.h ../include/irc_string.h \
+  ../include/sprintf_irc.h ../include/numeric.h ../include/s_serv.h \
+  ../include/s_user.h ../include/send.h ../include/s_conf.h \
+  ../include/motd.h ../include/class.h ../include/msg.h \
+  ../include/parse.h ../include/modules.h
+m_message.o: m_message.c ../include/handlers.h ../include/client.h \
+  ../include/config.h ../include/setup.h ../include/defaults.h \
+  ../include/ircd_defs.h ../include/ircd_handler.h ../include/linebuf.h \
+  ../include/tools.h ../include/channel.h ../include/res.h \
+  ../include/fileio.h ../adns/adns.h ../include/ircd.h \
+  ../include/memory.h ../include/balloc.h ../include/irc_string.h \
+  ../include/sprintf_irc.h ../include/numeric.h ../include/common.h \
+  ../include/s_conf.h ../include/motd.h ../include/class.h \
+  ../include/s_serv.h ../include/send.h ../include/msg.h \
+  ../include/parse.h ../include/modules.h ../include/channel_mode.h \
+  ../include/vchannel.h ../include/hash.h ../include/packet.h \
+  ../include/fdlist.h
+m_motd.o: m_motd.c ../include/client.h ../include/config.h \
+  ../include/setup.h ../include/defaults.h ../include/ircd_defs.h \
+  ../include/ircd_handler.h ../include/linebuf.h ../include/tools.h \
+  ../include/channel.h ../include/res.h ../include/fileio.h \
+  ../adns/adns.h ../include/ircd.h ../include/memory.h \
+  ../include/balloc.h ../include/irc_string.h ../include/sprintf_irc.h \
+  ../include/motd.h ../include/send.h ../include/numeric.h \
+  ../include/handlers.h ../include/hook.h ../include/msg.h \
+  ../include/s_serv.h ../include/parse.h ../include/modules.h \
+  ../include/s_conf.h ../include/class.h
+m_names.o: m_names.c ../include/tools.h ../include/handlers.h \
+  ../include/channel.h ../include/config.h ../include/setup.h \
+  ../include/defaults.h ../include/ircd_defs.h ../include/channel_mode.h \
+  ../include/vchannel.h ../include/client.h ../include/ircd_handler.h \
+  ../include/linebuf.h ../include/res.h ../include/fileio.h \
+  ../adns/adns.h ../include/ircd.h ../include/memory.h \
+  ../include/balloc.h ../include/irc_string.h ../include/sprintf_irc.h \
+  ../include/common.h ../include/hash.h ../include/list.h \
+  ../include/numeric.h ../include/send.h ../include/s_serv.h \
+  ../include/s_conf.h ../include/motd.h ../include/class.h \
+  ../include/msg.h ../include/parse.h ../include/modules.h
+m_nburst.o: m_nburst.c ../include/tools.h ../include/channel.h \
+  ../include/config.h ../include/setup.h ../include/defaults.h \
+  ../include/ircd_defs.h ../include/client.h ../include/ircd_handler.h \
+  ../include/linebuf.h ../include/res.h ../include/fileio.h \
+  ../adns/adns.h ../include/ircd.h ../include/memory.h \
+  ../include/balloc.h ../include/irc_string.h ../include/sprintf_irc.h \
+  ../include/common.h ../include/hash.h ../include/list.h \
+  ../include/numeric.h ../include/s_serv.h ../include/s_user.h \
+  ../include/send.h ../include/msg.h ../include/handlers.h \
+  ../include/parse.h ../include/modules.h ../include/s_conf.h \
+  ../include/motd.h ../include/class.h
+m_oper.o: m_oper.c ../include/tools.h ../include/handlers.h \
+  ../include/client.h ../include/config.h ../include/setup.h \
+  ../include/defaults.h ../include/ircd_defs.h ../include/ircd_handler.h \
+  ../include/linebuf.h ../include/channel.h ../include/res.h \
+  ../include/fileio.h ../adns/adns.h ../include/ircd.h \
+  ../include/memory.h ../include/balloc.h ../include/irc_string.h \
+  ../include/sprintf_irc.h ../include/common.h ../include/fdlist.h \
+  ../include/numeric.h ../include/s_bsd.h ../include/s_conf.h \
+  ../include/motd.h ../include/class.h ../include/s_log.h \
+  ../include/s_user.h ../include/send.h ../include/list.h \
+  ../include/msg.h ../include/parse.h ../include/modules.h
+m_operwall.o: m_operwall.c ../include/handlers.h ../include/client.h \
+  ../include/config.h ../include/setup.h ../include/defaults.h \
+  ../include/ircd_defs.h ../include/ircd_handler.h ../include/linebuf.h \
+  ../include/tools.h ../include/channel.h ../include/res.h \
+  ../include/fileio.h ../adns/adns.h ../include/ircd.h \
+  ../include/memory.h ../include/balloc.h ../include/irc_string.h \
+  ../include/sprintf_irc.h ../include/numeric.h ../include/send.h \
+  ../include/s_user.h ../include/msg.h ../include/parse.h \
+  ../include/modules.h
+m_pass.o: m_pass.c ../include/handlers.h ../include/client.h \
+  ../include/config.h ../include/setup.h ../include/defaults.h \
+  ../include/ircd_defs.h ../include/ircd_handler.h ../include/linebuf.h \
+  ../include/tools.h ../include/channel.h ../include/res.h \
+  ../include/fileio.h ../adns/adns.h ../include/ircd.h \
+  ../include/memory.h ../include/balloc.h ../include/irc_string.h \
+  ../include/sprintf_irc.h ../include/send.h ../include/numeric.h \
+  ../include/msg.h ../include/parse.h ../include/modules.h
+m_ping.o: m_ping.c ../include/handlers.h ../include/client.h \
+  ../include/config.h ../include/setup.h ../include/defaults.h \
+  ../include/ircd_defs.h ../include/ircd_handler.h ../include/linebuf.h \
+  ../include/tools.h ../include/channel.h ../include/res.h \
+  ../include/fileio.h ../adns/adns.h ../include/ircd.h \
+  ../include/memory.h ../include/balloc.h ../include/irc_string.h \
+  ../include/sprintf_irc.h ../include/numeric.h ../include/send.h \
+  ../include/msg.h ../include/parse.h ../include/modules.h \
+  ../include/hash.h ../include/s_conf.h ../include/motd.h \
+  ../include/class.h
+m_pong.o: m_pong.c ../include/ircd.h ../include/config.h \
+  ../include/setup.h ../include/defaults.h ../include/tools.h \
+  ../include/memory.h ../include/ircd_defs.h ../include/balloc.h \
+  ../include/handlers.h ../include/s_user.h ../include/client.h \
+  ../include/ircd_handler.h ../include/linebuf.h ../include/channel.h \
+  ../include/res.h ../include/fileio.h ../adns/adns.h \
+  ../include/irc_string.h ../include/sprintf_irc.h ../include/hash.h \
+  ../include/numeric.h ../include/s_conf.h ../include/motd.h \
+  ../include/class.h ../include/send.h ../include/s_debug.h \
+  ../include/msg.h ../include/parse.h ../include/modules.h
+m_post.o: m_post.c ../include/handlers.h ../include/client.h \
+  ../include/config.h ../include/setup.h ../include/defaults.h \
+  ../include/ircd_defs.h ../include/ircd_handler.h ../include/linebuf.h \
+  ../include/tools.h ../include/channel.h ../include/res.h \
+  ../include/fileio.h ../adns/adns.h ../include/ircd.h \
+  ../include/memory.h ../include/balloc.h ../include/irc_string.h \
+  ../include/sprintf_irc.h ../include/numeric.h ../include/s_serv.h \
+  ../include/send.h ../include/msg.h ../include/parse.h \
+  ../include/modules.h ../include/s_conf.h ../include/motd.h \
+  ../include/class.h
+m_rehash.o: m_rehash.c ../include/handlers.h ../include/client.h \
+  ../include/config.h ../include/setup.h ../include/defaults.h \
+  ../include/ircd_defs.h ../include/ircd_handler.h ../include/linebuf.h \
+  ../include/tools.h ../include/channel.h ../include/res.h \
+  ../include/fileio.h ../adns/adns.h ../include/ircd.h \
+  ../include/memory.h ../include/balloc.h ../include/irc_string.h \
+  ../include/sprintf_irc.h ../include/common.h ../include/list.h \
+  ../include/s_gline.h ../include/numeric.h ../include/s_conf.h \
+  ../include/motd.h ../include/class.h ../include/s_log.h \
+  ../include/send.h ../include/msg.h ../include/parse.h \
+  ../include/modules.h
+m_restart.o: m_restart.c ../include/handlers.h ../include/client.h \
+  ../include/config.h ../include/setup.h ../include/defaults.h \
+  ../include/ircd_defs.h ../include/ircd_handler.h ../include/linebuf.h \
+  ../include/tools.h ../include/channel.h ../include/res.h \
+  ../include/fileio.h ../adns/adns.h ../include/ircd.h \
+  ../include/memory.h ../include/balloc.h ../include/irc_string.h \
+  ../include/sprintf_irc.h ../include/common.h ../include/numeric.h \
+  ../include/s_conf.h ../include/motd.h ../include/class.h \
+  ../include/restart.h ../include/s_log.h ../include/send.h \
+  ../include/msg.h ../include/parse.h ../include/modules.h
+m_resv.o: m_resv.c ../include/handlers.h ../include/client.h \
+  ../include/config.h ../include/setup.h ../include/defaults.h \
+  ../include/ircd_defs.h ../include/ircd_handler.h ../include/linebuf.h \
+  ../include/tools.h ../include/channel.h ../include/res.h \
+  ../include/fileio.h ../adns/adns.h ../include/ircd.h \
+  ../include/memory.h ../include/balloc.h ../include/irc_string.h \
+  ../include/sprintf_irc.h ../include/numeric.h ../include/s_serv.h \
+  ../include/send.h ../include/msg.h ../include/parse.h \
+  ../include/modules.h ../include/s_conf.h ../include/motd.h \
+  ../include/class.h ../include/resv.h ../include/hash.h
+m_set.o: m_set.c ../include/handlers.h ../include/client.h \
+  ../include/config.h ../include/setup.h ../include/defaults.h \
+  ../include/ircd_defs.h ../include/ircd_handler.h ../include/linebuf.h \
+  ../include/tools.h ../include/channel.h ../include/res.h \
+  ../include/fileio.h ../adns/adns.h ../include/ircd.h \
+  ../include/memory.h ../include/balloc.h ../include/irc_string.h \
+  ../include/sprintf_irc.h ../include/event.h ../include/numeric.h \
+  ../include/fdlist.h ../include/s_bsd.h ../include/s_serv.h \
+  ../include/send.h ../include/common.h ../include/s_log.h \
+  ../include/s_conf.h ../include/motd.h ../include/class.h \
+  ../include/msg.h ../include/parse.h ../include/modules.h
+m_stats.o: m_stats.c ../include/tools.h ../include/handlers.h \
+  ../include/class.h ../include/client.h ../include/config.h \
+  ../include/setup.h ../include/defaults.h ../include/ircd_defs.h \
+  ../include/ircd_handler.h ../include/linebuf.h ../include/channel.h \
+  ../include/res.h ../include/fileio.h ../adns/adns.h ../include/ircd.h \
+  ../include/memory.h ../include/balloc.h ../include/irc_string.h \
+  ../include/sprintf_irc.h ../include/common.h ../include/listener.h \
+  ../include/s_gline.h ../include/msg.h ../include/hostmask.h \
+  ../include/numeric.h ../include/scache.h ../include/send.h \
+  ../include/fdlist.h ../include/s_bsd.h ../include/s_conf.h \
+  ../include/motd.h ../include/s_debug.h ../include/s_misc.h \
+  ../include/s_serv.h ../include/s_stats.h ../include/s_user.h \
+  ../include/event.h ../include/parse.h ../include/modules.h \
+  ../include/hook.h ../include/resv.h
+m_svinfo.o: m_svinfo.c ../include/handlers.h ../include/client.h \
+  ../include/config.h ../include/setup.h ../include/defaults.h \
+  ../include/ircd_defs.h ../include/ircd_handler.h ../include/linebuf.h \
+  ../include/tools.h ../include/channel.h ../include/res.h \
+  ../include/fileio.h ../adns/adns.h ../include/ircd.h \
+  ../include/memory.h ../include/balloc.h ../include/irc_string.h \
+  ../include/sprintf_irc.h ../include/common.h ../include/numeric.h \
+  ../include/send.h ../include/s_conf.h ../include/motd.h \
+  ../include/class.h ../include/s_log.h ../include/msg.h \
+  ../include/parse.h ../include/modules.h
+m_testline.o: m_testline.c ../include/handlers.h ../include/client.h \
+  ../include/config.h ../include/setup.h ../include/defaults.h \
+  ../include/ircd_defs.h ../include/ircd_handler.h ../include/linebuf.h \
+  ../include/tools.h ../include/channel.h ../include/res.h \
+  ../include/fileio.h ../adns/adns.h ../include/ircd.h \
+  ../include/memory.h ../include/balloc.h ../include/irc_string.h \
+  ../include/sprintf_irc.h ../include/common.h ../include/restart.h \
+  ../include/s_conf.h ../include/motd.h ../include/class.h \
+  ../include/send.h ../include/msg.h ../include/hostmask.h \
+  ../include/numeric.h ../include/parse.h ../include/modules.h
+m_time.o: m_time.c ../include/handlers.h ../include/client.h \
+  ../include/config.h ../include/setup.h ../include/defaults.h \
+  ../include/ircd_defs.h ../include/ircd_handler.h ../include/linebuf.h \
+  ../include/tools.h ../include/channel.h ../include/res.h \
+  ../include/fileio.h ../adns/adns.h ../include/ircd.h \
+  ../include/memory.h ../include/balloc.h ../include/irc_string.h \
+  ../include/sprintf_irc.h ../include/numeric.h ../include/s_misc.h \
+  ../include/s_conf.h ../include/motd.h ../include/class.h \
+  ../include/s_serv.h ../include/send.h ../include/msg.h \
+  ../include/parse.h ../include/modules.h
+m_topic.o: m_topic.c ../include/tools.h ../include/handlers.h \
+  ../include/channel.h ../include/config.h ../include/setup.h \
+  ../include/defaults.h ../include/ircd_defs.h ../include/channel_mode.h \
+  ../include/vchannel.h ../include/client.h ../include/ircd_handler.h \
+  ../include/linebuf.h ../include/res.h ../include/fileio.h \
+  ../adns/adns.h ../include/ircd.h ../include/memory.h \
+  ../include/balloc.h ../include/irc_string.h ../include/sprintf_irc.h \
+  ../include/hash.h ../include/numeric.h ../include/send.h \
+  ../include/s_conf.h ../include/motd.h ../include/class.h \
+  ../include/s_serv.h ../include/msg.h ../include/parse.h \
+  ../include/modules.h
+m_trace.o: m_trace.c ../include/handlers.h ../include/class.h \
+  ../include/hook.h ../include/tools.h ../include/client.h \
+  ../include/config.h ../include/setup.h ../include/defaults.h \
+  ../include/ircd_defs.h ../include/ircd_handler.h ../include/linebuf.h \
+  ../include/channel.h ../include/res.h ../include/fileio.h \
+  ../adns/adns.h ../include/ircd.h ../include/memory.h \
+  ../include/balloc.h ../include/irc_string.h ../include/sprintf_irc.h \
+  ../include/hash.h ../include/common.h ../include/numeric.h \
+  ../include/fdlist.h ../include/s_bsd.h ../include/s_serv.h \
+  ../include/send.h ../include/msg.h ../include/parse.h \
+  ../include/modules.h
+m_unkline.o: m_unkline.c ../include/tools.h ../include/handlers.h \
+  ../include/channel.h ../include/config.h ../include/setup.h \
+  ../include/defaults.h ../include/ircd_defs.h ../include/client.h \
+  ../include/ircd_handler.h ../include/linebuf.h ../include/res.h \
+  ../include/fileio.h ../adns/adns.h ../include/ircd.h \
+  ../include/memory.h ../include/balloc.h ../include/irc_string.h \
+  ../include/sprintf_irc.h ../include/common.h ../include/list.h \
+  ../include/hostmask.h ../include/numeric.h ../include/s_conf.h \
+  ../include/motd.h ../include/class.h ../include/s_log.h \
+  ../include/s_misc.h ../include/send.h ../include/msg.h \
+  ../include/s_gline.h ../include/parse.h ../include/modules.h
+m_user.o: m_user.c ../include/handlers.h ../include/client.h \
+  ../include/config.h ../include/setup.h ../include/defaults.h \
+  ../include/ircd_defs.h ../include/ircd_handler.h ../include/linebuf.h \
+  ../include/tools.h ../include/channel.h ../include/res.h \
+  ../include/fileio.h ../adns/adns.h ../include/ircd.h \
+  ../include/memory.h ../include/balloc.h ../include/irc_string.h \
+  ../include/sprintf_irc.h ../include/numeric.h ../include/s_user.h \
+  ../include/send.h ../include/s_conf.h ../include/motd.h \
+  ../include/class.h ../include/msg.h ../include/parse.h \
+  ../include/modules.h
+m_userhost.o: m_userhost.c ../include/handlers.h ../include/client.h \
+  ../include/config.h ../include/setup.h ../include/defaults.h \
+  ../include/ircd_defs.h ../include/ircd_handler.h ../include/linebuf.h \
+  ../include/tools.h ../include/channel.h ../include/res.h \
+  ../include/fileio.h ../adns/adns.h ../include/ircd.h \
+  ../include/memory.h ../include/balloc.h ../include/irc_string.h \
+  ../include/sprintf_irc.h ../include/numeric.h ../include/s_serv.h \
+  ../include/send.h ../include/msg.h ../include/parse.h \
+  ../include/modules.h ../include/s_conf.h ../include/motd.h \
+  ../include/class.h
+m_users.o: m_users.c ../include/handlers.h ../include/client.h \
+  ../include/config.h ../include/setup.h ../include/defaults.h \
+  ../include/ircd_defs.h ../include/ircd_handler.h ../include/linebuf.h \
+  ../include/tools.h ../include/channel.h ../include/res.h \
+  ../include/fileio.h ../adns/adns.h ../include/ircd.h \
+  ../include/memory.h ../include/balloc.h ../include/irc_string.h \
+  ../include/sprintf_irc.h ../include/numeric.h ../include/s_serv.h \
+  ../include/s_conf.h ../include/motd.h ../include/class.h \
+  ../include/send.h ../include/msg.h ../include/parse.h \
+  ../include/modules.h
+m_version.o: m_version.c ../include/handlers.h ../include/client.h \
+  ../include/config.h ../include/setup.h ../include/defaults.h \
+  ../include/ircd_defs.h ../include/ircd_handler.h ../include/linebuf.h \
+  ../include/tools.h ../include/channel.h ../include/res.h \
+  ../include/fileio.h ../adns/adns.h ../include/ircd.h \
+  ../include/memory.h ../include/balloc.h ../include/irc_string.h \
+  ../include/sprintf_irc.h ../include/numeric.h ../include/s_conf.h \
+  ../include/motd.h ../include/class.h ../include/s_serv.h \
+  ../include/s_user.h ../include/send.h ../include/msg.h \
+  ../include/parse.h ../include/modules.h
+m_wallops.o: m_wallops.c ../include/handlers.h ../include/client.h \
+  ../include/config.h ../include/setup.h ../include/defaults.h \
+  ../include/ircd_defs.h ../include/ircd_handler.h ../include/linebuf.h \
+  ../include/tools.h ../include/channel.h ../include/res.h \
+  ../include/fileio.h ../adns/adns.h ../include/ircd.h \
+  ../include/memory.h ../include/balloc.h ../include/irc_string.h \
+  ../include/sprintf_irc.h ../include/numeric.h ../include/send.h \
+  ../include/s_user.h ../include/s_conf.h ../include/motd.h \
+  ../include/class.h ../include/msg.h ../include/parse.h \
+  ../include/modules.h
+m_who.o: m_who.c ../include/tools.h ../include/common.h \
+  ../include/handlers.h ../include/client.h ../include/config.h \
+  ../include/setup.h ../include/defaults.h ../include/ircd_defs.h \
+  ../include/ircd_handler.h ../include/linebuf.h ../include/channel.h \
+  ../include/res.h ../include/fileio.h ../adns/adns.h ../include/ircd.h \
+  ../include/memory.h ../include/balloc.h ../include/irc_string.h \
+  ../include/sprintf_irc.h ../include/channel_mode.h \
+  ../include/vchannel.h ../include/hash.h ../include/numeric.h \
+  ../include/s_serv.h ../include/send.h ../include/list.h \
+  ../include/s_conf.h ../include/motd.h ../include/class.h \
+  ../include/msg.h ../include/parse.h ../include/modules.h
+m_whois.o: m_whois.c ../include/tools.h ../include/common.h \
+  ../include/handlers.h ../include/client.h ../include/config.h \
+  ../include/setup.h ../include/defaults.h ../include/ircd_defs.h \
+  ../include/ircd_handler.h ../include/linebuf.h ../include/channel.h \
+  ../include/res.h ../include/fileio.h ../adns/adns.h ../include/ircd.h \
+  ../include/memory.h ../include/balloc.h ../include/irc_string.h \
+  ../include/sprintf_irc.h ../include/hash.h ../include/channel_mode.h \
+  ../include/vchannel.h ../include/numeric.h ../include/s_conf.h \
+  ../include/motd.h ../include/class.h ../include/s_serv.h \
+  ../include/send.h ../include/list.h ../include/msg.h ../include/parse.h \
+  ../include/modules.h ../include/hook.h
+m_whowas.o: m_whowas.c ../include/whowas.h ../include/ircd_defs.h \
+  ../include/config.h ../include/setup.h ../include/defaults.h \
+  ../include/client.h ../include/ircd_handler.h ../include/linebuf.h \
+  ../include/tools.h ../include/channel.h ../include/res.h \
+  ../include/fileio.h ../adns/adns.h ../include/ircd.h \
+  ../include/memory.h ../include/balloc.h ../include/irc_string.h \
+  ../include/sprintf_irc.h ../include/handlers.h ../include/common.h \
+  ../include/hash.h ../include/numeric.h ../include/s_serv.h \
+  ../include/s_user.h ../include/send.h ../include/s_conf.h \
+  ../include/motd.h ../include/class.h ../include/msg.h \
+  ../include/parse.h ../include/modules.h
diff --git a/modules/core/m_die.c b/modules/core/m_die.c
new file mode 100644 (file)
index 0000000..6348ac6
--- /dev/null
@@ -0,0 +1,122 @@
+/************************************************************************
+ *   IRC - Internet Relay Chat, modules/m_die.c
+ *   Copyright (C) 1990 Jarkko Oikarinen and
+ *                      University of Oulu, Computing Center
+ *
+ *   See file AUTHORS in IRC package for additional names of
+ *   the programmers. 
+ *
+ *   This program is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 1, or (at your option)
+ *   any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *   $Id: m_die.c,v 1.1 2002/01/04 10:57:31 a1kmm Exp $
+ */
+#include "tools.h"
+#include "handlers.h"
+#include "client.h"
+#include "ircd.h"
+#include "irc_string.h"
+#include "numeric.h"
+#include "fdlist.h"
+#include "s_bsd.h"
+#include "s_log.h"
+#include "s_conf.h"
+#include "send.h"
+#include "msg.h"
+#include "parse.h"
+#include "modules.h"
+
+static void mo_die(struct Client*, struct Client*, int, char**);
+
+struct Message die_msgtab = {
+  "DIE", 0, 0, 1, 0, MFLG_SLOW, 0,
+  {m_unregistered, m_not_oper, m_ignore, mo_die}
+};
+#ifndef STATIC_MODULES
+void
+_modinit(void)
+{
+  mod_add_cmd(&die_msgtab);
+}
+
+void
+_moddeinit(void)
+{
+  mod_del_cmd(&die_msgtab);
+}
+
+char *_version = "$Revision: 1.1 $";
+#endif
+/*
+ * mo_die - DIE command handler
+ */
+static void mo_die(struct Client *client_p, struct Client *source_p,
+                  int parc, char *parv[])
+{
+  struct Client* target_p;
+  dlink_node *ptr;
+
+  if (!IsOperDie(source_p))
+    {
+      sendto_one(source_p,":%s NOTICE %s :You need die = yes;", me.name, parv[0]);
+      return;
+    }
+
+  if (parc < 2)
+    {
+      sendto_one(source_p,":%s NOTICE %s :Need server name /die %s",
+                 me.name,source_p->name,me.name);
+      return;
+    }
+  else
+    {
+      if (irccmp(parv[1], me.name))
+        {
+          sendto_one(source_p,":%s NOTICE %s :Mismatch on /die %s",
+                     me.name,source_p->name,me.name);
+          return;
+        }
+    }
+
+  for(ptr = lclient_list.head; ptr; ptr = ptr->next)
+    {
+      target_p = ptr->data;
+
+      sendto_one(target_p,
+                ":%s NOTICE %s :Server Terminating. %s",
+                me.name, target_p->name,
+                get_client_name(source_p, HIDE_IP));
+    }
+
+  for(ptr = serv_list.head; ptr; ptr = ptr->next)
+    {
+      target_p = ptr->data;
+
+      sendto_one(target_p, ":%s ERROR :Terminated by %s",
+                me.name, get_client_name(source_p, HIDE_IP));
+    }
+
+  /*
+   * XXX we called flush_connections() here. Read server_reboot()
+   * for an explanation as to what we should do.
+   *     -- adrian
+   */
+  ilog(L_NOTICE, "Server terminated by %s", get_oper_name(source_p));
+  /* 
+   * this is a normal exit, tell the os it's ok 
+   */
+  exit(0);
+  /* NOT REACHED */
+}
+
diff --git a/modules/core/m_kick.c b/modules/core/m_kick.c
new file mode 100644 (file)
index 0000000..f9f629a
--- /dev/null
@@ -0,0 +1,247 @@
+/************************************************************************
+ *   IRC - Internet Relay Chat, modules/m_kick.c
+ *   Copyright (C) 1990 Jarkko Oikarinen and
+ *                      University of Oulu, Computing Center
+ *
+ *   See file AUTHORS in IRC package for additional names of
+ *   the programmers. 
+ *
+ *   This program is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 1, or (at your option)
+ *   any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *   $Id: m_kick.c,v 1.1 2002/01/04 10:57:31 a1kmm Exp $
+ */
+#include "tools.h"
+#include "handlers.h"
+#include "channel.h"
+#include "channel_mode.h"
+#include "vchannel.h"
+#include "client.h"
+#include "irc_string.h"
+#include "ircd.h"
+#include "numeric.h"
+#include "send.h"
+#include "msg.h"
+#include "modules.h"
+#include "parse.h"
+#include "hash.h"
+
+#include <string.h>
+
+static void m_kick(struct Client*, struct Client*, int, char**);
+static void ms_kick(struct Client*, struct Client*, int, char**);
+
+struct Message kick_msgtab = {
+  "KICK", 0, 0, 3, 0, MFLG_SLOW, 0,
+  {m_unregistered, m_kick, ms_kick, m_kick}
+};
+#ifndef STATIC_MODULES
+void
+_modinit(void)
+{
+  mod_add_cmd(&kick_msgtab);
+}
+
+void
+_moddeinit(void)
+{
+  mod_del_cmd(&kick_msgtab);
+}
+
+char *_version = "$Revision: 1.1 $";
+#endif
+/*
+** m_kick
+**      parv[0] = sender prefix
+**      parv[1] = channel
+**      parv[2] = client to kick
+**      parv[3] = kick comment
+*/
+static void m_kick(struct Client *client_p,
+                  struct Client *source_p,
+                  int parc,
+                  char *parv[])
+{
+  struct Client *who;
+  struct Channel *chptr;
+  struct Channel *vchan;
+  int   chasing = 0;
+  char  *comment;
+  char  *name;
+  char  *p = (char *)NULL;
+  char  *user;
+  static char     buf[BUFSIZE];
+
+  if (*parv[2] == '\0')
+    {
+      sendto_one(source_p, form_str(ERR_NEEDMOREPARAMS),
+                 me.name, parv[0], "KICK");
+      return;
+    }
+
+  comment = (BadPtr(parv[3])) ? parv[2] : parv[3];
+  if (strlen(comment) > (size_t) TOPICLEN)
+    comment[TOPICLEN] = '\0';
+
+  *buf = '\0';
+  if( (p = strchr(parv[1],',')) )
+    *p = '\0';
+
+  name = parv[1];
+
+  chptr = hash_find_channel(name);
+  if (!chptr)
+    {
+      sendto_one(source_p, form_str(ERR_NOSUCHCHANNEL),
+                 me.name, parv[0], name);
+      return;
+    }
+
+  if (HasVchans(chptr))
+    {
+      vchan = map_vchan(chptr,source_p);
+      if(vchan != 0)
+       {
+         chptr = vchan;
+       }
+    }
+
+  if (!IsServer(source_p) && !is_any_op(chptr, source_p) ) 
+    { 
+      /* was a user, not a server, and user isn't seen as a chanop here */
+      
+      if(MyConnect(source_p))
+        {
+          /* user on _my_ server, with no chanops.. so go away */
+          
+          sendto_one(source_p, form_str(ERR_CHANOPRIVSNEEDED),
+                     me.name, parv[0], name);
+          return;
+        }
+
+      if(chptr->channelts == 0)
+        {
+          /* If its a TS 0 channel, do it the old way */
+          
+          sendto_one(source_p, form_str(ERR_CHANOPRIVSNEEDED),
+                     me.name, parv[0], name);
+          return;
+        }
+
+      /* Its a user doing a kick, but is not showing as chanop locally
+       * its also not a user ON -my- server, and the channel has a TS.
+       * There are two cases we can get to this point then...
+       *
+       *     1) connect burst is happening, and for some reason a legit
+       *        op has sent a KICK, but the SJOIN hasn't happened yet or 
+       *        been seen. (who knows.. due to lag...)
+       *
+       *     2) The channel is desynced. That can STILL happen with TS
+       *        
+       *     Now, the old code roger wrote, would allow the KICK to 
+       *     go through. Thats quite legit, but lets weird things like
+       *     KICKS by users who appear not to be chanopped happen,
+       *     or even neater, they appear not to be on the channel.
+       *     This fits every definition of a desync, doesn't it? ;-)
+       *     So I will allow the KICK, otherwise, things are MUCH worse.
+       *     But I will warn it as a possible desync.
+       *
+       *     -Dianora
+       */
+    }
+
+  if( (p = strchr(parv[2],',')) )
+    *p = '\0';
+
+  user = parv[2]; /* strtoken(&p2, parv[2], ","); */
+
+  if (!(who = find_chasing(source_p, user, &chasing)))
+    {
+      return;
+    }
+
+  if (IsMember(who, chptr))
+    {
+      /* half ops cannot kick full chanops */
+      if (is_half_op(chptr,source_p) && is_any_op(chptr,who))
+       {
+          sendto_one(source_p, form_str(ERR_CHANOPRIVSNEEDED),
+                     me.name, parv[0], name);
+         return;
+       }
+      /* jdc
+       * - In the case of a server kicking a user (i.e. CLEARCHAN),
+       *   the kick should show up as coming from the server which did
+       *   the kick.
+       * - Personally, flame and I believe that server kicks shouldn't
+       *   be sent anyways.  Just waiting for some oper to abuse it...
+       */
+      if (IsServer(source_p))
+      {
+        sendto_channel_local(ALL_MEMBERS, chptr, ":%s KICK %s %s :%s",
+          source_p->name, name, who->name, comment);
+      }
+      else if(chptr->mode.mode & MODE_HIDEOPS)
+       {
+         /* jdc -- Non-chanops get kicked from me.name, not
+          *        who->name (themselves).
+          */
+         sendto_channel_local(NON_CHANOPS, chptr,
+                              ":%s KICK %s %s :%s",
+                              me.name,
+                              name, who->name, comment);
+
+         sendto_channel_local(ONLY_CHANOPS_HALFOPS, chptr,
+                              ":%s!%s@%s KICK %s %s :%s",
+                              source_p->name,
+                              source_p->username,
+                              source_p->host,
+                              name,
+                              who->name, comment);
+       }
+      else
+       {
+         sendto_channel_local(ALL_MEMBERS, chptr,
+                              ":%s!%s@%s KICK %s %s :%s",
+                              source_p->name,
+                              source_p->username,
+                              source_p->host,
+                              name, who->name, comment);
+       }
+
+      sendto_server(client_p, NULL, chptr, NOCAPS, NOCAPS, NOFLAGS,
+                    ":%s KICK %s %s :%s",
+                    parv[0], chptr->chname,
+                    who->name, comment);
+      remove_user_from_channel(chptr, who, 0);
+    }
+  else
+    sendto_one(source_p, form_str(ERR_USERNOTINCHANNEL),
+               me.name, parv[0], user, name);
+}
+
+static void ms_kick(struct Client *client_p,
+                   struct Client *source_p,
+                   int parc,
+                   char *parv[])
+{
+  if (*parv[2] == '\0')
+    {
+      sendto_one(source_p, form_str(ERR_NEEDMOREPARAMS),
+                 me.name, parv[0], "KICK");
+      return;
+    }
+
+  m_kick(client_p, source_p, parc, parv);
+}
diff --git a/modules/core/m_kill.c b/modules/core/m_kill.c
new file mode 100644 (file)
index 0000000..f584242
--- /dev/null
@@ -0,0 +1,380 @@
+/************************************************************************
+ *   IRC - Internet Relay Chat, modules/m_kill.c
+ *   Copyright (C) 1990 Jarkko Oikarinen and
+ *                      University of Oulu, Computing Center
+ *
+ *   See file AUTHORS in IRC package for additional names of
+ *   the programmers. 
+ *
+ *   This program is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 1, or (at your option)
+ *   any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *   $Id: m_kill.c,v 1.1 2002/01/04 10:57:31 a1kmm Exp $
+ */
+#include "handlers.h"
+#include "client.h"
+#include "hash.h"       /* for find_client() */
+#include "ircd.h"
+#include "numeric.h"
+#include "s_log.h"
+#include "s_serv.h"
+#include "s_conf.h"
+#include "send.h"
+#include "whowas.h"
+#include "irc_string.h"
+#include "msg.h"
+#include "parse.h"
+#include "modules.h"
+
+#include <string.h>
+
+static char buf[BUFSIZE];
+
+static void ms_kill(struct Client*, struct Client*, int, char**);
+static void mo_kill(struct Client*, struct Client*, int, char**);
+static void relay_kill(struct Client *, struct Client *, struct Client *,
+                       const char *, const char *);
+
+struct Message kill_msgtab = {
+  "KILL", 0, 0, 2, 0, MFLG_SLOW, 0,
+  {m_unregistered, m_not_oper, ms_kill, mo_kill}
+};
+#ifndef STATIC_MODULES
+
+void
+_modinit(void)
+{
+  mod_add_cmd(&kill_msgtab);
+}
+
+void
+_moddeinit(void)
+{
+  mod_del_cmd(&kill_msgtab);
+}
+
+char *_version = "$Revision: 1.1 $";
+#endif
+/*
+** mo_kill
+**      parv[0] = sender prefix
+**      parv[1] = kill victim
+**      parv[2] = kill path
+*/
+static void mo_kill(struct Client *client_p, struct Client *source_p,
+                    int parc, char *parv[])
+{
+  struct Client*    target_p;
+  const char* inpath = client_p->name;
+  char*       user;
+  char*       reason;
+
+  user = parv[1];
+  reason = parv[2]; /* Either defined or NULL (parc >= 2!!) */
+
+  if (!IsOperGlobalKill(source_p))
+    {
+      sendto_one(source_p,":%s NOTICE %s :You need global_kill = yes;",me.name,parv[0]);
+      return;
+    }
+
+  if (!BadPtr(reason))
+    {
+      if(strlen(reason) > (size_t) KILLLEN)
+       reason[KILLLEN] = '\0';
+    }
+  else
+    reason = "<No reason given>";
+
+  if ((target_p = find_client(user)) == NULL)
+    {
+      /*
+      ** If the user has recently changed nick, automatically
+      ** rewrite the KILL for this new nickname--this keeps
+      ** servers in synch when nick change and kill collide
+      */
+      if ((target_p = get_history(user, (long)KILLCHASETIMELIMIT)) == NULL)
+        {
+          sendto_one(source_p, form_str(ERR_NOSUCHNICK),
+                     me.name, parv[0], user);
+          return;
+        }
+      sendto_one(source_p,":%s NOTICE %s :KILL changed from %s to %s",
+                 me.name, parv[0], user, target_p->name);
+    }
+  if (IsServer(target_p) || IsMe(target_p))
+    {
+      sendto_one(source_p, form_str(ERR_CANTKILLSERVER),
+                 me.name, parv[0]);
+      return;
+    }
+
+  if (!MyConnect(target_p) && (!IsOperGlobalKill(source_p)))
+    {
+      sendto_one(source_p, ":%s NOTICE %s :Nick %s isnt on your server",
+                 me.name, parv[0], target_p->name);
+      return;
+    }
+
+#if 0
+  ircsprintf(buf, "%s!%s (%s)",
+            inpath, client_p->username, reason);
+#endif
+
+  if(MyConnect(target_p))
+    sendto_one(target_p, ":%s KILL %s :%s", parv[0], target_p->name, reason);
+
+  /* Do not change the format of this message.  There's no point in changing messages
+   * that have been around for ever, for no reason.. */
+  sendto_realops_flags(FLAGS_ALL, L_ALL,
+                      "Received KILL message for %s. From %s Path: %s (%s)", 
+                      target_p->name, parv[0], me.name, reason);
+
+  ilog(L_INFO,"KILL From %s For %s Path %s (%s)",
+       parv[0], target_p->name, me.name, reason);
+
+
+  /*
+  ** And pass on the message to other servers. Note, that if KILL
+  ** was changed, the message has to be sent to all links, also
+  ** back.
+  ** Suicide kills are NOT passed on --SRB
+  */
+  if (!MyConnect(target_p))
+    {
+      relay_kill(client_p, source_p, target_p, inpath, reason);
+      /*
+      ** Set FLAGS_KILLED. This prevents exit_one_client from sending
+      ** the unnecessary QUIT for this. (This flag should never be
+      ** set in any other place)
+      */
+      target_p->flags |= FLAGS_KILLED;
+    }
+
+  exit_client(client_p, target_p, source_p, reason);
+}
+
+/*
+** ms_kill
+**      parv[0] = sender prefix
+**      parv[1] = kill victim
+**      parv[2] = kill path
+*/
+static void ms_kill(struct Client *client_p, struct Client *source_p,
+                    int parc, char *parv[])
+{
+  struct Client*    target_p;
+  char*       user;
+  char*       reason;
+  int         chasing = 0;
+  *buf = '\0';
+
+  if (*parv[1] == '\0')
+    {
+      sendto_one(source_p, form_str(ERR_NEEDMOREPARAMS),
+                 me.name, parv[0], "KILL");
+      return;
+    }
+
+  user = parv[1];
+
+/* OK, parv[2] contains the path AND the reason, so we either
+   split it up, or make the path ourselves using the info
+   we know.. (host/user/name).. for now we use the latter --fl */
+
+  if(IsServer(source_p))
+    ircsprintf(buf, "%s", source_p->name);
+  else
+    ircsprintf(buf, "%s!%s!%s!%s", source_p->user->server, source_p->host,
+               source_p->username, source_p->name);
+
+  if ((target_p = find_client(user)) == NULL)
+    {
+      /*
+       * If the user has recently changed nick, but only if its 
+       * not an uid, automatically rewrite the KILL for this new nickname.
+       * --this keeps servers in synch when nick change and kill collide
+       */
+      if( (*user == '.')  ||
+         (!(target_p = get_history(user, (long)KILLCHASETIMELIMIT))))
+        {
+          sendto_one(source_p, form_str(ERR_NOSUCHNICK),
+                     me.name, parv[0], user);
+          return;
+        }
+      sendto_one(source_p,":%s NOTICE %s :KILL changed from %s to %s",
+                 me.name, parv[0], user, target_p->name);
+      chasing = 1;
+    }
+  if (IsServer(target_p) || IsMe(target_p))
+    {
+      sendto_one(source_p, form_str(ERR_CANTKILLSERVER),
+                 me.name, parv[0]);
+      return;
+    }
+
+#if 0
+  /* If we make the path ourselves, there can never BE a bogus path */
+  if (BadPtr(path))
+    path = "*no-path*"; /* Bogus server sending??? */
+#endif
+
+  /*
+  ** Notify all *local* opers about the KILL (this includes the one
+  ** originating the kill, if from this server--the special numeric
+  ** reply message is not generated anymore).
+  **
+  ** Note: "target_p->name" is used instead of "user" because we may
+  **     have changed the target because of the nickname change.
+  */
+  if(BadPtr(parv[2]))
+      reason = "<No reason given>";
+  else
+    {
+      reason = strchr(parv[2], ' ');
+      if(reason)
+        reason++;
+      else
+        reason = parv[2];
+    }
+
+  /* dont send clients kills from a hidden server */
+  if(MyConnect(target_p))
+  {
+    if(ConfigServerHide.hide_servers && IsServer(source_p) && 
+       !IsOper(source_p))
+      sendto_one(target_p, ":%s KILL %s :%s",
+                 me.name, target_p->name, reason);
+    else
+      sendto_one(target_p, ":%s KILL %s :%s", parv[0], target_p->name, reason);
+  }
+
+  /* Be warned, this message must be From %s, or it confuses clients
+   * so dont change it to From: or the case or anything! -- fl -- db */
+  if (IsOper(source_p)) /* send it normally */
+    {
+      sendto_realops_flags(FLAGS_ALL, L_ALL,
+                          "Received KILL message for %s. From %s Path: %s %s",
+                          target_p->name, parv[0], source_p->user->server, reason);
+    }
+  else
+    {
+      sendto_realops_flags(FLAGS_SKILL, L_ALL,
+                          "Received KILL message for %s. From %s %s",
+                          target_p->name, parv[0], reason);
+    }
+
+  ilog(L_INFO,"KILL From %s For %s Path %s %s",
+       parv[0], target_p->name, parv[0], reason);
+
+  /*
+  ** And pass on the message to other servers. Note, that if KILL
+  ** was changed, the message has to be sent to all links, also
+  ** back.
+  ** Suicide kills are NOT passed on --SRB
+  */
+
+  if (!MyConnect(target_p) || !MyConnect(source_p) || !IsOper(source_p))
+    {
+      relay_kill(client_p, source_p, target_p, buf, reason);
+
+      /*
+      ** Set FLAGS_KILLED. This prevents exit_one_client from sending
+      ** the unnecessary QUIT for this. (This flag should never be
+      ** set in any other place)
+      */
+      target_p->flags |= FLAGS_KILLED;
+    }
+
+  exit_client(client_p, target_p, source_p, reason );
+}
+
+static void relay_kill(struct Client *one, struct Client *source_p,
+                       struct Client *target_p,
+                       const char *inpath,
+                      const char *reason)
+{
+  dlink_node *ptr;
+  struct Client *client_p;
+  int introduce_killed_client;
+  char* user; 
+  
+  /* LazyLinks:
+   * Check if each lazylink knows about target_p.
+   *   If it does, send the kill, introducing source_p if required.
+   *   If it doesn't either:
+   *     a) don't send the kill (risk ghosts)
+   *     b) introduce the client (and source_p, if required)
+   *        [rather redundant]
+   *
+   * Use a) if IsServer(source_p), but if an oper kills someone,
+   * ensure we blow away any ghosts.
+   *
+   * -davidt
+   */
+
+  if(IsServer(source_p))
+    introduce_killed_client = 0;
+  else
+    introduce_killed_client = 1;
+
+  for( ptr = serv_list.head; ptr; ptr = ptr->next )
+  {
+    client_p = (struct Client *) ptr->data;
+    
+    if( !client_p || client_p == one )
+      continue;
+
+    if( !introduce_killed_client )
+    {
+      if( ServerInfo.hub && IsCapable(client_p, CAP_LL) )
+      {
+        if(((client_p->localClient->serverMask &
+             target_p->lazyLinkClientExists) == 0))
+        {
+          /* target isn't known to lazy leaf, skip it */
+          continue;
+        }
+      }
+    }
+    /* force introduction of killed client but check that
+     * its not on the server we're bursting too.. */
+    else if(strcmp(target_p->user->server,client_p->name))
+      client_burst_if_needed(client_p, target_p);
+
+    /* introduce source of kill */
+    client_burst_if_needed(client_p, source_p);
+
+    /* check the server supports UID */
+    if (IsCapable(client_p, CAP_UID))
+      user = ID(target_p);
+    else
+      user = target_p->name;
+
+    if(MyClient(source_p))
+      {
+        sendto_one(client_p, ":%s KILL %s :%s!%s!%s!%s (%s)",
+                   source_p->name, user,
+                   me.name, source_p->host, source_p->username,
+                   source_p->name, reason);
+      }
+    else
+      {
+        sendto_one(client_p, ":%s KILL %s :%s %s",
+                   source_p->name, user,
+                   inpath, reason);
+      }
+  }
+}
+
diff --git a/modules/core/m_mode.c b/modules/core/m_mode.c
new file mode 100644 (file)
index 0000000..e01c282
--- /dev/null
@@ -0,0 +1,211 @@
+/************************************************************************
+ *   IRC - Internet Relay Chat, modules/m_mode.c
+ *   Copyright (C) 1990 Jarkko Oikarinen and
+ *                      University of Oulu, Computing Center
+ *
+ *   See file AUTHORS in IRC package for additional names of
+ *   the programmers. 
+ *
+ *   This program is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 1, or (at your option)
+ *   any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *   $Id: m_mode.c,v 1.1 2002/01/04 10:57:32 a1kmm Exp $
+ */
+#include "tools.h"
+#include "handlers.h"
+#include "channel.h"
+#include "channel_mode.h"
+#include "vchannel.h"
+#include "client.h"
+#include "hash.h"
+#include "irc_string.h"
+#include "ircd.h"
+#include "numeric.h"
+#include "s_user.h"
+#include "s_conf.h"
+#include "s_serv.h"
+#include "send.h"
+#include "msg.h"
+#include "parse.h"
+#include "modules.h"
+#include "packet.h"
+
+static void m_mode(struct Client*, struct Client*, int, char**);
+
+struct Message mode_msgtab = {
+  "MODE", 0, 0, 2, 0, MFLG_SLOW, 0,
+  {m_unregistered, m_mode, m_mode, m_mode}
+};
+#ifndef STATIC_MODULES
+
+void
+_modinit(void)
+{
+  mod_add_cmd(&mode_msgtab);
+}
+
+void
+_moddeinit(void)
+{
+  mod_del_cmd(&mode_msgtab);
+}
+
+
+char *_version = "$Revision: 1.1 $";
+#endif
+/*
+ * m_mode - MODE command handler
+ * parv[0] - sender
+ * parv[1] - channel
+ */
+static void m_mode(struct Client *client_p, struct Client *source_p,
+              int parc, char *parv[])
+{
+  struct Channel* chptr=NULL;
+  struct Channel* vchan;
+  struct Channel* root;
+  static char     modebuf[MODEBUFLEN];
+  static char     parabuf[MODEBUFLEN];
+  int n = 2;
+  
+  /* Now, try to find the channel in question */
+  if (!IsChanPrefix(parv[1][0]))
+    {
+      /* if here, it has to be a non-channel name */
+      user_mode(client_p, source_p, parc, parv);
+      return;
+    }
+  /* Finish the flood grace period... */
+  SetFloodDone(source_p);
+  if (!check_channel_name(parv[1]))
+    { 
+      sendto_one(source_p, form_str(ERR_BADCHANNAME),
+                me.name, parv[0], (unsigned char *)parv[1]);
+      return;
+    }
+         
+  chptr = hash_find_channel(parv[1]);
+
+  if (chptr == NULL)
+    {
+      /* if chptr isn't found locally, it =could= exist
+       * on the uplink. So ask.
+       */
+      
+      /* LazyLinks */
+      /* this was segfaulting if we had no servers linked.
+       *  -pro
+       */
+      /* only send a mode upstream if a local client sent this request
+       * -davidt
+       */
+      if (MyClient(source_p) && !ServerInfo.hub && uplink &&
+          IsCapable(uplink, CAP_LL))
+       {
+#if 0
+         /* cache the channel if it exists on uplink
+          * If the channel as seen by the uplink, has vchans,
+          * the uplink will have to SJOIN all of those.
+          */
+         /* Lets not for now -db */
+
+         sendto_one(uplink, ":%s CBURST %s",
+                     me.name, parv[1]);
+         
+#endif
+         sendto_one(uplink, ":%s MODE %s %s",
+                    source_p->name, parv[1], (parv[2] ? parv[2] : ""));
+         return;
+       }
+      else
+       {
+         sendto_one(source_p, form_str(ERR_NOSUCHCHANNEL),
+                    me.name, parv[0], parv[1]);
+         return;
+       }
+    }
+  
+  /* Now known the channel exists */
+
+  root = chptr;
+
+  if ((parc > 2) && parv[2][0] == '!')
+    {
+     struct Client *target_p;
+     if (!(target_p = find_client(++parv[2])))
+       {
+        sendto_one(source_p, form_str(ERR_NOSUCHCHANNEL), me.name,
+                   parv[0], root->chname);
+        return;
+       }
+     if ((chptr = map_vchan(root, target_p)) == NULL)
+       {
+        sendto_one(source_p, form_str(ERR_NOSUCHCHANNEL), me.name,
+                   parv[0], root->chname);
+        return;
+       }
+     n++;
+    }
+
+  else
+    {
+      if (HasVchans(chptr))
+        {
+          if ((vchan = map_vchan(chptr,source_p)) != NULL)
+            chptr = vchan; /* root = chptr, chptr = vchan */
+
+          /* XXX - else? the user isn't on any vchan, so we
+           *       end up giving them the mode of the root
+           *       channel.  MODE #vchan !nick ? (ugh)
+           */
+        }
+      else if (IsVchan(chptr))
+        {
+          vchan = find_bchan(chptr);
+          root = vchan;  /* root = vchan, chptr = chptr */
+
+          /* XXX - else? the user isn't on any vchan,
+           *       but they asked for MODE ##vchan_12345
+           *       we send MODE #vchan
+           */
+        }
+    }
+
+  if (parc < n+1)
+    {
+      channel_modes(chptr, source_p, modebuf, parabuf);
+      sendto_one(source_p, form_str(RPL_CHANNELMODEIS),
+                me.name, parv[0], parv[1],
+                modebuf, parabuf);
+      
+      /* Let opers see the "true" TS everyone else see's
+       * the top root chan TS
+       */
+      if (!IsOper(source_p))
+       sendto_one(source_p, form_str(RPL_CREATIONTIME),
+                  me.name, parv[0],
+                  parv[1], root->channelts);
+      else
+       sendto_one(source_p, form_str(RPL_CREATIONTIME),
+                  me.name, parv[0],
+                  parv[1], chptr->channelts);
+    }
+  else
+    set_channel_mode(client_p, source_p, chptr, parc - n, parv + n, 
+                     root->chname);
+}
+
+
+
+
diff --git a/modules/core/m_nick.c b/modules/core/m_nick.c
new file mode 100644 (file)
index 0000000..e710762
--- /dev/null
@@ -0,0 +1,928 @@
+/*
+ * modules/m_nick.c
+ * Copyright (C) 2001 Hybrid Development Team
+ *
+ * $Id: m_nick.c,v 1.1 2002/01/04 10:57:32 a1kmm Exp $
+ */
+
+#include "handlers.h"
+#include "client.h"
+#include "hash.h"
+#include "fdlist.h"
+#include "irc_string.h"
+#include "ircd.h"
+#include "numeric.h"
+#include "s_conf.h"
+#include "s_stats.h"
+#include "s_user.h"
+#include "hash.h"
+#include "whowas.h"
+#include "s_serv.h"
+#include "send.h"
+#include "list.h"
+#include "channel.h"
+#include "s_log.h"
+#include "resv.h"
+#include "msg.h"
+#include "parse.h"
+#include "modules.h"
+#include "common.h"
+
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+
+static void mr_nick(struct Client *, struct Client *, int, char**);
+static void m_nick(struct Client *, struct Client *, int, char**);
+static void ms_nick(struct Client *, struct Client *, int, char**);
+
+static void ms_client(struct Client *, struct Client *, int, char**);
+
+static int nick_from_server(struct Client *, struct Client *, int, char **,
+                            time_t, char *);
+static int client_from_server(struct Client *, struct Client *, int, char **,
+                              time_t, char *);
+
+static int check_clean_nick(struct Client *, struct Client *, 
+                            char *, char *, char *);
+static int check_clean_user(struct Client *, char *, char *, char *);
+static int check_clean_host(struct Client *, char *, char *, char *);
+
+static int clean_nick_name(char *);
+static int clean_user_name(char *);
+static int clean_host_name(char *);
+
+static int perform_nick_collides(struct Client *, struct Client *,
+                                 struct Client *, int, char **, time_t, char *);
+                            
+
+struct Message nick_msgtab = {
+  "NICK", 0, 0, 1, 0, MFLG_SLOW, 0,
+  {mr_nick, m_nick, ms_nick, m_nick}
+};
+
+struct Message client_msgtab = {
+  "CLIENT", 0, 0, 10, 0, MFLG_SLOW, 0,
+  {m_ignore, m_ignore, ms_client, m_ignore}
+};
+
+#ifndef STATIC_MODULES
+void
+_modinit(void)
+{
+  mod_add_cmd(&nick_msgtab);
+  mod_add_cmd(&client_msgtab);
+}
+
+void
+_moddeinit(void)
+{
+  mod_del_cmd(&nick_msgtab);
+  mod_del_cmd(&client_msgtab);
+}
+
+char *_version = "$Revision: 1.1 $";
+#endif
+
+/*
+ * mr_nick()
+ *
+ *       parv[0] = sender prefix
+ *       parv[1] = nickname
+ */
+static void mr_nick(struct Client *client_p, struct Client *source_p, 
+                    int parc, char *parv[])
+{
+  struct   Client *target_p, *uclient_p;
+  char     nick[NICKLEN + 2];
+  char*    s;
+  dlink_node *ptr;
+   
+  if(parc < 2)
+  {
+    sendto_one(source_p, form_str(ERR_NONICKNAMEGIVEN),
+               me.name, BadPtr(parv[0]) ? "*" : parv[0]);
+    return;
+  }
+
+  /* Terminate the nick at the first ~ */
+  if ((s = strchr(parv[1], '~')))
+    *s = '\0';
+
+  /* copy the nick and terminate it */
+  strncpy_irc(nick, parv[1], NICKLEN);
+  nick[NICKLEN] = '\0';
+
+  /* check the nickname is ok */
+  if(!clean_nick_name(nick))
+  {
+    sendto_one(source_p, form_str(ERR_ERRONEUSNICKNAME),
+               me.name, BadPtr(parv[0]) ? "*" : parv[0], parv[1]);
+    return;
+  }
+
+  /* check if the nick is resv'd */
+  if(find_nick_resv(nick))
+  {
+    sendto_one(source_p, form_str(ERR_UNAVAILRESOURCE),
+               me.name, BadPtr(parv[0]) ? "*" : parv[0], nick);
+    return;
+  }
+
+  if (!(target_p = find_client(nick)))
+  {
+    if(!ServerInfo.hub && uplink && IsCapable(uplink, CAP_LL))
+    {
+      /* We don't know anyone called nick, but our hub might */
+      for(ptr = unknown_list.head; ptr; ptr = ptr->next)
+      {
+        uclient_p = ptr->data;
+
+       if(!strcmp(nick, uclient_p->llname))
+       {
+       
+         /* We're already waiting for a reply about this nick
+          * for someone else. */
+
+         sendto_one(source_p, form_str(ERR_NICKNAMEINUSE), me.name, "*", nick);
+         return;
+       }
+      }
+
+      /* Set their llname so we can find them later */
+      strcpy(source_p->llname, nick);
+
+      /* Ask the hub about their requested name */
+      sendto_one(uplink, ":%s NBURST %s %s !%s", me.name, nick,
+                 nick, nick);
+
+      /* wait for LLNICK */
+      return;
+    }
+    else
+    {
+      set_initial_nick(client_p, source_p, nick);
+      return;
+    }
+  }
+  else /* nickname is in use */
+  {
+    sendto_one(source_p, form_str(ERR_NICKNAMEINUSE), me.name, "*", nick);
+  }
+}
+
+/*
+ * m_nick()
+ *
+ *     parv[0] = sender prefix
+ *     parv[1] = nickname
+ */
+ static void m_nick(struct Client *client_p, struct Client *source_p,
+                   int parc, char *parv[])
+{
+  char     nick[NICKLEN + 2];
+  struct   Client *target_p;
+
+  if(parc < 2)
+  {
+    sendto_one(source_p, form_str(ERR_NONICKNAMEGIVEN),
+               me.name, parv[0]);
+    return;
+  }
+
+  /* terminate nick to NICKLEN */
+  strncpy_irc(nick, parv[1], NICKLEN);
+  nick[NICKLEN] = '\0';
+
+  /* check the nickname is ok */
+  if(!clean_nick_name(nick))
+  {
+    sendto_one(source_p, form_str(ERR_ERRONEUSNICKNAME),
+               me.name, parv[0], nick);
+    return;
+  }
+
+  if(find_nick_resv(nick))
+  {
+    sendto_one(source_p, form_str(ERR_UNAVAILRESOURCE),
+               me.name, parv[0], nick);
+    return;
+  }
+
+  if ((target_p = find_client(nick)))
+  {
+    /* If(target_p == source_p) the client is changing nicks between
+     * equivalent nicknames ie: [nick] -> {nick}
+     */
+
+    if(target_p == source_p)
+    {
+      /* check the nick isnt exactly the same */
+      if(strcmp(target_p->name, nick))
+      {
+        change_local_nick(client_p, source_p, nick);
+       return;
+      }
+      else
+      {
+        /* client is doing :old NICK old
+        * ignore it..
+        */
+        return;
+      }
+    }
+
+    /* if the client that has the nick isnt registered yet (nick but no
+     * user) then drop the unregged client
+     */
+    if(IsUnknown(target_p))
+    {
+      /* the old code had an if(MyConnect(target_p)) here.. but I cant see
+       * how that can happen, m_nick() is local only --fl_
+       */
+      
+      exit_client(NULL, target_p, &me, "Overridden");
+      change_local_nick(client_p, source_p, nick);
+      return;
+    }
+    else
+    {
+      sendto_one(source_p, form_str(ERR_NICKNAMEINUSE), me.name,
+                 parv[0], nick);
+      return;
+    }
+
+  }
+  else
+  {
+    if(!ServerInfo.hub && uplink && IsCapable(uplink, CAP_LL))
+    {
+      /* The uplink might know someone by this name already. */
+      sendto_one(uplink, ":%s NBURST %s %s %s", me.name, nick,
+                 nick, source_p->name);
+      return;
+    }
+    else
+    {
+      change_local_nick(client_p,source_p,nick);
+      return;
+    }
+  }
+}
+
+/*
+ * ms_nick()
+ *      
+ * server -> server nick change
+ *    parv[0] = sender prefix
+ *    parv[1] = nickname
+ *    parv[2] = TS when nick change
+ *
+ * server introducing new nick
+ *    parv[0] = sender prefix
+ *    parv[1] = nickname
+ *    parv[2] = hop count
+ *    parv[3] = TS
+ *    parv[4] = umode
+ *    parv[5] = username
+ *    parv[6] = hostname
+ *    parv[7] = server
+ *    parv[8] = ircname
+ */
+static void ms_nick(struct Client *client_p, struct Client *source_p,
+                    int parc, char *parv[])
+{
+  struct Client* target_p;
+  char     nick[NICKLEN + 2];
+  time_t   newts = 0;
+
+  if(parc < 2)
+  {
+    sendto_one(source_p, form_str(ERR_NONICKNAMEGIVEN), me.name, parv[0]);
+    return;
+  }
+
+  /* parc == 3 on nickchange, parc == 9 on new nick */
+  if((parc != 3) && (parc != 9))
+    return;
+
+  /* fix the length of the nick */
+  strncpy_irc(nick, parv[1], NICKLEN);
+  nick[NICKLEN] = '\0';
+
+  if(check_clean_nick(client_p, source_p, nick, parv[1], parv[7]))
+    return;
+
+  if (parc == 9)
+    {
+      if (check_clean_user(client_p, nick, parv[5], parv[7]) ||
+          check_clean_host(client_p, nick, parv[6], parv[7]))
+        return;
+
+      /* check the length of the clients gecos */
+      if(strlen(parv[8]) > REALLEN)
+        {
+          sendto_realops_flags(FLAGS_ALL, L_ALL, "Long realname from server %s for %s",
+                         parv[7], parv[1]);
+          parv[8][REALLEN] = '\0';
+        }
+
+      if (IsServer(source_p))
+        newts = atol(parv[3]);
+    }
+  else
+    {
+      if (!IsServer(source_p))
+        newts = atol(parv[2]);
+    }
+
+  /* if the nick doesnt exist, allow it and process like normal */
+  if (!(target_p = find_client(nick)))
+  {
+    nick_from_server(client_p,source_p,parc,parv,newts,nick);
+    return;
+  }
+
+  /* we're not living in the past anymore, an unknown client is local only. */
+  if(IsUnknown(target_p))
+  {
+    exit_client(NULL, target_p, &me, "Overridden");
+    nick_from_server(client_p,source_p,parc,parv,newts,nick);
+    return;
+  }
+
+  if(target_p == source_p)
+  {
+    if(strcmp(target_p->name, nick))
+    {
+      /* client changing case of nick */
+      nick_from_server(client_p,source_p,parc,parv,newts,nick);
+      return;
+    }
+    else
+      /* client not changing nicks at all */
+      return;
+  }
+
+  perform_nick_collides(source_p, client_p, target_p,
+                        parc, parv, newts, nick);
+                       
+
+}
+
+/*
+ * ms_client()
+ */
+static void ms_client(struct Client *client_p, struct Client *source_p,
+                      int parc, char *parv[])
+{
+  struct Client* target_p;
+  char     nick[NICKLEN + 2];
+  time_t   newts = 0;
+  char    *id;
+  char    *name;
+
+  id = parv[8];
+  name = parv[9];
+
+  /* parse the nickname */
+  strncpy_irc(nick, parv[1], NICKLEN);
+  nick[NICKLEN] = '\0';
+
+  /* check the nicknames, usernames and hostnames are ok */
+  if(check_clean_nick(client_p, source_p, nick, parv[1], parv[7]) ||
+     check_clean_user(client_p, nick, parv[5], parv[7]) ||
+     check_clean_host(client_p, nick, parv[6], parv[7]))
+    return;
+
+  /* check length of clients gecos */
+  if (strlen(name) > REALLEN)
+  {
+    sendto_realops_flags(FLAGS_ALL, L_ALL, "Long realname from server %s for %s",
+                         parv[0], parv[1]);
+    name[REALLEN] = '\0';                       
+  }
+
+  newts = atol(parv[3]);
+  
+  if (!(target_p = find_client(nick)))
+  {
+    client_from_server(client_p,source_p,parc,parv,newts,nick);
+    return;
+  }
+
+
+  if(IsUnknown(target_p))
+  {
+    exit_client(NULL, target_p, &me, "Overridden");
+    client_from_server(client_p,source_p,parc,parv,newts,nick);
+    return;
+  }
+
+  perform_nick_collides(source_p, client_p, target_p,
+                        parc, parv, newts, nick);
+}                        
+
+
+/* 
+ * check_clean_nick()
+ * 
+ * input       - pointer to source
+ *             - nickname
+ *             - truncated nickname
+ *             - origin of client
+ * output      - none
+ * side effects - if nickname is erroneous, or a different length to
+ *                truncated nickname, return 1
+ */
+static int check_clean_nick(struct Client *client_p, struct Client *source_p, 
+                            char *nick, char *newnick, char *server)
+{
+  /* the old code did some wacky stuff here, if the nick is invalid, kill it
+   * and dont bother messing at all
+   */
+
+  if(!clean_nick_name(nick) || strcmp(nick, newnick))
+  {
+    ServerStats->is_kill++;
+    sendto_realops_flags(FLAGS_DEBUG, L_ALL,
+                         "Bad Nick: %s From: %s(via %s)",
+                         nick, server, client_p->name);
+
+    sendto_one(client_p, ":%s KILL %s :%s (Bad Nickname)",
+               me.name, newnick, me.name);
+
+    /* bad nick change */
+    if(source_p != client_p)
+    {
+      kill_client_ll_serv_butone(client_p, source_p,
+                                 "%s (Bad Nickname)",
+                                me.name);
+      source_p->flags |= FLAGS_KILLED;
+      exit_client(client_p, source_p, &me, "Bad Nickname");
+    }
+
+    return 1;
+  }
+
+  return 0;
+}
+
+/* check_clean_user()
+ * 
+ * input       - pointer to client sending data
+ *              - nickname
+ *              - username to check
+ *             - origin of NICK
+ * output      - none
+ * side effects - if username is erroneous, return 1
+ */
+static int check_clean_user(struct Client *client_p, char *nick, 
+                            char *user, char *server)
+{
+  if(strlen(user) > USERLEN)
+  {
+    ServerStats->is_kill++;
+    sendto_realops_flags(FLAGS_DEBUG, L_ALL,
+                         "Long Username: %s Nickname: %s From: %s(via %s)",
+                        user, nick, server, client_p->name);
+
+    sendto_one(client_p, ":%s KILL %s :%s (Bad Username)",
+               me.name, nick, me.name);
+  
+    return 1;
+  }
+
+  if(!clean_user_name(user))
+    sendto_realops_flags(FLAGS_DEBUG, L_ALL,
+                         "Bad Username: %s Nickname: %s From: %s(via %s)",
+                        user, nick, server, client_p->name);
+                        
+  return 0;
+}
+
+/* check_clean_host()
+ * 
+ * input       - pointer to client sending us data
+ *              - nickname
+ *              - hostname to check
+ *             - source name
+ * output      - none
+ * side effects - if hostname is erroneous, return 1
+ */
+static int check_clean_host(struct Client *client_p, char *nick,
+                           char *host, char *server)
+{
+  if(strlen(host) > HOSTLEN)
+  {
+    ServerStats->is_kill++;
+    sendto_realops_flags(FLAGS_DEBUG, L_ALL,
+                         "Long Hostname: %s Nickname: %s From: %s(via %s)",
+                        host, nick, server, client_p->name);
+
+    sendto_one(client_p, ":%s KILL %s :%s (Bad Hostname)",
+               me.name, nick, me.name);
+
+    return 1;
+  }
+
+  if(!clean_host_name(host))
+    sendto_realops_flags(FLAGS_DEBUG, L_ALL,
+                         "Bad Hostname: %s Nickname: %s From: %s(via %s)",
+                        host, nick, server, client_p->name);
+
+  return 0;
+}
+
+/* clean_nick_name()
+ *
+ * input       - nickname
+ * output      - none
+ * side effects - walks through the nickname, returning 0 if erroneous
+ */
+static int clean_nick_name(char *nick)
+{
+  assert(nick);
+
+  /* nicks cant start with a digit or - */
+  if (*nick == '-' || IsDigit(*nick))
+    return 0;
+
+  for(; *nick; nick++)
+  {
+    if(!IsNickChar(*nick))
+      return 0;
+  }
+
+  return 1;
+}
+
+/* clean_user_name()
+ *
+ * input       - username
+ * output      - none
+ * side effects - walks through the username, returning 0 if erroneous
+ */
+static int clean_user_name(char *user)
+{
+  assert(user);
+
+  for(; *user; user++)
+  {
+    if(!IsUserChar(*user))
+      return 0;
+  }
+
+  return 1;
+}
+
+/* clean_host_name()
+ * input       - hostname
+ * output      - none
+ * side effects - walks through the hostname, returning 0 if erroneous
+ */
+static int clean_host_name(char *host)
+{
+  assert(host);
+
+  for(; *host; host++)
+  {
+    if(!IsHostChar(*host))
+      return 0;
+  }
+
+  return 1;
+}
+
+
+/*
+ * nick_from_server()
+ */
+static int
+nick_from_server(struct Client *client_p, struct Client *source_p, int parc,
+                 char *parv[], time_t newts,char *nick)
+{
+  if(IsServer(source_p))
+  {
+    /* A server introducing a new client, change source */
+    source_p = make_client(client_p);
+    add_client_to_list(source_p);
+
+    /* We don't need to introduce leafs clients back to them! */
+    if (ConfigFileEntry.hub && IsCapable(client_p, CAP_LL))
+      add_lazylinkclient(client_p, source_p);
+
+    if(parc > 2)
+      source_p->hopcount = atoi(parv[2]);
+    if(newts)
+      source_p->tsinfo = newts;
+    else
+    {
+      newts = source_p->tsinfo = CurrentTime;
+      ts_warn("Remote nick %s (%s) introduced without a TS", nick, parv[0]);
+    }
+
+    /* copy the nick in place */
+    (void)strcpy(source_p->name, nick);
+    (void)add_to_client_hash_table(nick, source_p);
+
+    if (parc > 8)
+    {
+       int   flag;
+       char *m;
+
+       /* parse usermodes */
+       m = &parv[4][1];
+       while (*m)
+       {
+         flag = user_modes_from_c_to_bitmask[(unsigned char)*m];
+        if(!(source_p->umodes & FLAGS_INVISIBLE) && (flag & FLAGS_INVISIBLE))
+          Count.invisi++;
+        if(!(source_p->umodes & FLAGS_OPER) && (flag & FLAGS_OPER))
+          Count.oper++;
+
+        source_p->umodes |= flag & SEND_UMODES;
+        m++;
+      }
+
+      return do_remote_user(nick, client_p, source_p, parv[5], parv[6],
+                            parv[7], parv[8], NULL);
+    }
+  }
+  else if(source_p->name[0])
+  {
+    /* client changing their nick */
+    if(irccmp(parv[0], nick))
+      source_p->tsinfo = newts ? newts : CurrentTime;
+
+    sendto_common_channels_local(source_p, ":%s!%s@%s NICK :%s",
+                                 source_p->name,source_p->username,source_p->host,
+                                 nick);
+
+    if (source_p->user)
+    {
+      add_history(source_p,1);
+      sendto_server(client_p, source_p, NULL, NOCAPS, NOCAPS, NOFLAGS,
+                    ":%s NICK %s :%lu",
+                     parv[0], nick, (unsigned long) source_p->tsinfo);
+    }
+  }
+
+  /* set the new nick name */
+  if(source_p->name[0])
+    del_from_client_hash_table(source_p->name, source_p);
+
+  strcpy(source_p->name, nick);
+  add_to_client_hash_table(nick, source_p);
+
+  /* remove all accepts pointing to the client */
+  del_all_accepts(source_p);
+
+  return 0;
+}
+
+
+/*
+ * client_from_server()
+ */
+static int
+client_from_server(struct Client *client_p, struct Client *source_p, int parc,
+                   char *parv[], time_t newts,char *nick)
+{
+  char *name;
+  char *id;
+  int flag;
+  char *m;
+
+  id = parv[8];
+  name = parv[9];
+
+  source_p = make_client(client_p);
+  add_client_to_list(source_p);
+
+  /* We don't need to introduce leafs clients back to them! */
+  if (ConfigFileEntry.hub && IsCapable(client_p, CAP_LL))
+    add_lazylinkclient(client_p, source_p);
+
+  source_p->hopcount = atoi(parv[2]);
+  source_p->tsinfo = newts;
+
+  /* copy the nick in place */
+  (void)strcpy(source_p->name, nick);
+  (void)add_to_client_hash_table(nick, source_p);
+  add_to_id_hash_table(id, source_p);
+
+  /* parse usermodes */
+  m = &parv[4][1];
+  while (*m)
+  {
+    flag = user_modes_from_c_to_bitmask[(unsigned char)*m];
+    if(flag & FLAGS_INVISIBLE)
+      Count.invisi++;
+    if(flag & FLAGS_OPER)
+      Count.oper++;
+
+    source_p->umodes |= flag & SEND_UMODES;
+    m++;
+
+  }
+
+  return do_remote_user(nick, client_p, source_p, parv[5], parv[6],
+                        parv[7], name, id);
+}                      
+  
+static int 
+perform_nick_collides(struct Client *source_p, struct Client *client_p, 
+                      struct Client *target_p, int parc, char *parv[], 
+                     time_t newts, char *nick)
+{
+  int sameuser;
+  
+  /* server introducing new nick */
+  if(IsServer(source_p))
+  {
+    /* if we dont have a ts, or their TS's are the same, kill both */
+    if(!newts || !target_p->tsinfo ||
+       (newts == target_p->tsinfo))
+    {
+      sendto_realops_flags(FLAGS_ALL, L_ALL,
+                           "Nick collision on %s(%s <- %s)(both killed)",
+                          target_p->name, target_p->from->name,
+                          client_p->name);
+      
+      if(ServerInfo.hub && IsCapable(client_p,CAP_LL))
+        add_lazylinkclient(client_p, target_p);
+
+      kill_client_ll_serv_butone(NULL, target_p,
+                                 "%s (Nick collision (new))",
+                                me.name);
+      ServerStats->is_kill++;
+      sendto_one(target_p, form_str(ERR_NICKCOLLISION),
+                 me.name, target_p->name, target_p->name);
+
+      target_p->flags |= FLAGS_KILLED;
+      exit_client(client_p, target_p, &me, "Nick collision (new)");
+      return 0;
+    }
+    /* the timestamps are different */
+    else
+    {
+      sameuser = (target_p->user) && !irccmp(target_p->username, parv[5])
+                 && !irccmp(target_p->host, parv[6]);
+   
+      /* if the users are the same (loaded a client on a different server)
+       * and the new users ts is older, or the users are different and the
+       * new users ts is newer, ignore the new client and let it do the kill
+       */
+      if ((sameuser && newts < target_p->tsinfo) ||
+         (!sameuser && newts > target_p->tsinfo))
+      {
+        client_burst_if_needed(client_p, target_p);
+       return 0;
+      }
+      else
+      {
+        if(sameuser)
+         sendto_realops_flags(FLAGS_ALL, L_ALL,
+                         "Nick collision on %s(%s <- %s)(older killed)",
+                         target_p->name, target_p->from->name,
+                         client_p->name);
+        else
+         sendto_realops_flags(FLAGS_ALL, L_ALL,
+                         "Nick collision on %s(%s <- %s)(newer killed)",
+                         target_p->name, target_p->from->name,
+                         client_p->name);
+
+        ServerStats->is_kill++;
+       sendto_one(target_p, form_str(ERR_NICKCOLLISION),
+                  me.name, target_p->name, target_p->name);
+
+        /* if it came from a LL server, itd have been source_p,
+        * so we dont need to mark target_p as known
+        */
+       kill_client_ll_serv_butone(source_p, target_p,
+                                  "%s (Nick collision (new))",
+                                  me.name);
+
+        target_p->flags |= FLAGS_KILLED;
+       (void)exit_client(client_p, target_p, &me, "Nick collision");
+       
+       if(parc == 9)
+         nick_from_server(client_p,source_p,parc,parv,newts,nick);
+       else if(parc == 10)
+         client_from_server(client_p,source_p,parc,parv,newts,nick);
+         
+       return 0;
+      }
+    }
+  }
+
+  /* its a client changing nick and causing a collide */
+  if(!newts || !target_p->tsinfo || (newts == target_p->tsinfo) ||
+       !source_p->user)
+    {
+      sendto_realops_flags(FLAGS_ALL, L_ALL,
+                 "Nick change collision from %s to %s(%s <- %s)(both killed)",
+                source_p->name, target_p->name, target_p->from->name,
+                client_p->name);
+    
+      ServerStats->is_kill++;
+      sendto_one(target_p, form_str(ERR_NICKCOLLISION),
+                 me.name, target_p->name, target_p->name);
+
+      /* if we got the message from a LL, it knows about source_p */
+      kill_client_ll_serv_butone(NULL, source_p,
+                                  "%s (Nick change collision)",
+                                 me.name);
+
+      ServerStats->is_kill++;
+      /* If we got the message from a LL, ensure it gets the kill */
+      if(ServerInfo.hub && IsCapable(client_p,CAP_LL))
+        add_lazylinkclient(client_p, target_p);
+
+      kill_client_ll_serv_butone(NULL, target_p,
+                                 "%s (Nick change collision)",
+                                me.name);
+
+      target_p->flags |= FLAGS_KILLED;
+      exit_client(NULL, target_p, &me, "Nick collision(new)");
+      source_p->flags |= FLAGS_KILLED;
+      exit_client(client_p, source_p, &me, "Nick collision(old)");
+      return 0;
+    }
+    else
+    {
+      sameuser = !irccmp(target_p->username, source_p->username) &&
+                 !irccmp(target_p->host, source_p->host);
+
+      if ((sameuser && newts < target_p->tsinfo) ||
+          (!sameuser && newts > target_p->tsinfo))
+      {
+        if(sameuser)
+         sendto_realops_flags(FLAGS_ALL, L_ALL,
+              "Nick change collision from %s to %s(%s <- %s)(older killed)",
+              source_p->name, target_p->name, target_p->from->name,
+              client_p->name);
+        else
+         sendto_realops_flags(FLAGS_ALL, L_ALL,
+              "Nick change collision from %s to %s(%s <- %s)(newer killed)",
+              source_p->name, target_p->name, target_p->from->name,
+              client_p->name);
+
+        ServerStats->is_kill++;
+
+       /* this won't go back to the incoming link, so LL doesnt matter */
+        kill_client_ll_serv_butone(client_p, source_p,
+                                  "%s (Nick change collision)",
+                                  me.name);
+
+        source_p->flags |= FLAGS_KILLED;
+       
+       if(sameuser)
+         exit_client(client_p, source_p, &me, "Nick collision(old)");
+       else
+         exit_client(client_p, source_p, &me, "Nick collision(new)");
+       return 0;
+     }
+     else
+     {
+       if(sameuser)
+         sendto_realops_flags(FLAGS_ALL, L_ALL,
+                             "Nick collision on %s(%s <- %s)(older killed)",
+                             target_p->name, target_p->from->name,
+                             client_p->name);
+       else
+         sendto_realops_flags(FLAGS_ALL, L_ALL,
+                             "Nick collision on %s(%s <- %s)(newer killed)",
+                             target_p->name, target_p->from->name,
+                             client_p->name);
+                             
+       kill_client_ll_serv_butone(source_p, target_p,
+                                 "%s (Nick collision)",
+                                me.name);
+
+       ServerStats->is_kill++;
+       sendto_one(target_p, form_str(ERR_NICKCOLLISION),
+                  me.name, target_p->name, target_p->name);
+
+       target_p->flags |= FLAGS_KILLED;
+       (void)exit_client(client_p, target_p, &me, "Nick collision");
+     }
+   }
+
+   /*
+   if(HasID(source_p))
+     client_from_server(client_p,source_p,parc,parv,newts,nick);
+   else
+   */
+   
+   /* we should only ever call nick_from_server() here, as
+    * this is a client changing nick, not a new client
+    */
+   nick_from_server(client_p,source_p,parc,parv,newts,nick);
+
+  return 0;
+}
+
+           
+
diff --git a/modules/core/m_part.c b/modules/core/m_part.c
new file mode 100644 (file)
index 0000000..17070f0
--- /dev/null
@@ -0,0 +1,203 @@
+/************************************************************************
+ *   IRC - Internet Relay Chat, modules/m_part.c
+ *   Copyright (C) 1990 Jarkko Oikarinen and
+ *                      University of Oulu, Computing Center
+ *
+ *   See file AUTHORS in IRC package for additional names of
+ *   the programmers. 
+ *
+ *   This program is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 1, or (at your option)
+ *   any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *   $Id: m_part.c,v 1.1 2002/01/04 10:57:32 a1kmm Exp $
+ */
+#include "tools.h"
+#include "handlers.h"
+#include "channel.h"
+#include "vchannel.h"
+#include "client.h"
+#include "common.h"   /* bleah */
+#include "hash.h"
+#include "irc_string.h"
+#include "ircd.h"
+#include "list.h"
+#include "numeric.h"
+#include "send.h"
+#include "s_serv.h"
+#include "msg.h"
+#include "parse.h"
+#include "modules.h"
+#include "s_conf.h"
+#include "packet.h"
+
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+
+static void m_part(struct Client*, struct Client*, int, char**);
+void check_spambot_warning(struct Client *source_p, const char *name);
+
+struct Message part_msgtab = {
+  "PART", 0, 0, 2, 0, MFLG_SLOW, 0,
+  {m_unregistered, m_part, m_part, m_part}
+};
+
+#ifndef STATIC_MODULES
+void
+_modinit(void)
+{
+  mod_add_cmd(&part_msgtab);
+}
+
+void
+_moddeinit(void)
+{
+  mod_del_cmd(&part_msgtab);
+}
+char *_version = "$Revision: 1.1 $";
+#endif
+
+static void part_one_client(struct Client *client_p,
+                           struct Client *source_p,
+                           char *name, char *reason);
+
+
+/*
+** m_part
+**      parv[0] = sender prefix
+**      parv[1] = channel
+**      parv[2] = reason
+*/
+static void m_part(struct Client *client_p,
+                  struct Client *source_p,
+                  int parc,
+                  char *parv[])
+{
+  char  *p, *name;
+  char reason[TOPICLEN+1];
+
+  if (*parv[1] == '\0')
+    {
+      sendto_one(source_p, form_str(ERR_NEEDMOREPARAMS),
+                 me.name, parv[0], "PART");
+      return;
+    }
+
+  reason[0] = '\0';
+
+  if (parc > 2)
+    strncpy_irc(reason, parv[2], TOPICLEN);
+
+  name = strtoken( &p, parv[1], ",");
+
+  /* Finish the flood grace period... */
+  SetFloodDone(source_p);
+  /* if its my client, and isn't an oper */
+
+  while(name)
+  {
+    part_one_client(client_p, source_p, name, reason);
+    name = strtoken(&p, (char *)NULL, ",");
+  }
+  return;
+}
+
+/*
+ * part_one_client
+ *
+ * inputs      - pointer to server
+ *             - pointer to source client to remove
+ *             - char pointer of name of channel to remove from
+ * output      - none
+ * side effects        - remove ONE client given the channel name 
+ */
+static void part_one_client(struct Client *client_p,
+                           struct Client *source_p,
+                           char *name,
+                            char *reason)
+{
+  struct Channel *chptr;
+  struct Channel *bchan;
+
+  if ((chptr = hash_find_channel(name)) == NULL)
+    {
+      sendto_one(source_p, form_str(ERR_NOSUCHCHANNEL),
+                me.name, source_p->name, name);
+      return;
+    }
+
+  if (IsVchan(chptr) || HasVchans(chptr))
+    {
+      if(HasVchans(chptr))
+        {
+          /* Set chptr to actual channel, bchan to the base channel */
+          bchan = chptr;
+          chptr = map_vchan(bchan,source_p);
+        }
+      else
+        {
+          /* chptr = chptr; */
+          bchan = find_bchan(chptr);
+        }
+    }
+  else
+    bchan = chptr; /* not a vchan */
+
+  if (!chptr || !bchan || !IsMember(source_p, chptr))
+    {
+      sendto_one(source_p, form_str(ERR_NOTONCHANNEL),
+                 me.name, source_p->name, name);
+      return;
+    }
+  if (MyConnect(source_p) && !IsOper(source_p))
+   check_spambot_warning(source_p, NULL);
+
+  /*
+   *  Remove user from the old channel (if any)
+   *  only allow /part reasons in -m chans
+   */
+  if(reason[0] && (is_any_op(chptr, source_p) || !MyConnect(source_p) ||
+     ((can_send(chptr, source_p) > 0 && 
+      (source_p->firsttime + ConfigFileEntry.anti_spam_exit_message_time)
+      < CurrentTime))))
+    {
+      sendto_server(client_p, NULL, chptr, CAP_UID, NOCAPS, NOFLAGS,
+                    ":%s PART %s :%s", ID(source_p), chptr->chname,
+                    reason);
+      sendto_server(client_p, NULL, chptr, NOCAPS, CAP_UID, NOFLAGS,
+                    ":%s PART %s  :%s", source_p->name, chptr->chname,
+                    reason);
+      sendto_channel_local(ALL_MEMBERS,
+                           chptr, ":%s!%s@%s PART %s :%s",
+                           source_p->name,
+                           source_p->username,
+                           source_p->host,
+                           bchan->chname,
+                           reason);
+    }
+  else
+    {
+      sendto_server(client_p, NULL, chptr, CAP_UID, NOCAPS, NOFLAGS,
+                    ":%s PART %s", ID(source_p), chptr->chname);
+      sendto_server(client_p, NULL, chptr, NOCAPS, CAP_UID, NOFLAGS,
+                    ":%s PART %s", source_p->name, chptr->chname);
+      sendto_channel_local(ALL_MEMBERS,
+                           chptr, ":%s!%s@%s PART %s",
+                           source_p->name,
+                           source_p->username,
+                           source_p->host,
+                           bchan->chname);
+    }
+  remove_user_from_channel(chptr, source_p, 0);
+}
diff --git a/modules/core/m_quit.c b/modules/core/m_quit.c
new file mode 100644 (file)
index 0000000..5a6f0ba
--- /dev/null
@@ -0,0 +1,114 @@
+/************************************************************************
+ *   IRC - Internet Relay Chat, modules/m_quit.c
+ *   Copyright (C) 1990 Jarkko Oikarinen and
+ *                      University of Oulu, Computing Center
+ *
+ *   See file AUTHORS in IRC package for additional names of
+ *   the programmers. 
+ *
+ *   This program is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 1, or (at your option)
+ *   any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *   $Id: m_quit.c,v 1.1 2002/01/04 10:57:32 a1kmm Exp $
+ */
+#include "handlers.h"
+#include "client.h"
+#include "ircd.h"
+#include "numeric.h"
+#include "s_serv.h"
+#include "send.h"
+#include "msg.h"
+#include "parse.h"
+#include "modules.h"
+#include "s_conf.h"
+
+static void m_quit(struct Client*, struct Client*, int, char**);
+static void ms_quit(struct Client*, struct Client*, int, char**);
+
+struct Message quit_msgtab = {
+  "QUIT", 0, 0, 0, 0, MFLG_SLOW | MFLG_UNREG, 0,
+  {m_quit, m_quit, ms_quit, m_quit}
+};
+
+#ifndef STATIC_MODULES
+void
+_modinit(void)
+{
+  mod_add_cmd(&quit_msgtab);
+}
+
+void
+_moddeinit(void)
+{
+  mod_del_cmd(&quit_msgtab);
+}
+
+char *_version = "$Revision: 1.1 $";
+#endif
+/*
+** m_quit
+**      parv[0] = sender prefix
+**      parv[1] = comment
+*/
+static void m_quit(struct Client *client_p,
+                  struct Client *source_p,
+                  int parc,
+                  char *parv[])
+{
+  char *comment = (parc > 1 && parv[1]) ? parv[1] : client_p->name;
+  char reason [TOPICLEN + 1];
+
+  source_p->flags |= FLAGS_NORMALEX;
+  if (strlen(comment) > (size_t) TOPICLEN)
+    comment[TOPICLEN] = '\0';
+
+  if (ConfigFileEntry.client_exit && comment[0])
+    {
+#ifndef VMS
+      snprintf(reason, TOPICLEN, "Client Exit: %s", comment);
+#else
+      sprintf(reason, "Client Exit: %s", comment);
+#endif
+      comment = reason;
+    }
+  
+  if(!IsOper(source_p) && 
+     (source_p->firsttime + ConfigFileEntry.anti_spam_exit_message_time)
+     > CurrentTime)
+    {
+      comment = "Client Quit";
+    }
+
+  exit_client(client_p, source_p, source_p, comment);
+}
+
+/*
+** ms_quit
+**      parv[0] = sender prefix
+**      parv[1] = comment
+*/
+static void ms_quit(struct Client *client_p,
+                   struct Client *source_p,
+                   int parc,
+                   char *parv[])
+{
+  char *comment = (parc > 1 && parv[1]) ? parv[1] : client_p->name;
+
+  source_p->flags |= FLAGS_NORMALEX;
+  if (strlen(comment) > (size_t) TOPICLEN)
+    comment[TOPICLEN] = '\0';
+
+  exit_client(client_p, source_p, source_p, comment);
+}
+
diff --git a/modules/core/m_server.c b/modules/core/m_server.c
new file mode 100644 (file)
index 0000000..7112a6c
--- /dev/null
@@ -0,0 +1,644 @@
+/***********************************************************************
+ *   IRC - Internet Relay Chat, modules/m_server.c
+ *   Copyright (C) 1990 Jarkko Oikarinen and
+ *                      University of Oulu, Computing Center
+ *
+ *   See file AUTHORS in IRC package for additional names of
+ *   the programmers. 
+ *
+ *   This program is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 1, or (at your option)
+ *   any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *   $Id: m_server.c,v 1.1 2002/01/04 10:57:32 a1kmm Exp $
+ */
+#include "tools.h"
+#include "handlers.h"  /* m_server prototype */
+#include "client.h"      /* client struct */
+#include "common.h"      /* TRUE bleah */
+#include "event.h"
+#include "hash.h"        /* add_to_client_hash_table */
+#include "irc_string.h"  /* strncpy_irc */
+#include "ircd.h"        /* me */
+#include "list.h"        /* make_server */
+#include "numeric.h"     /* ERR_xxx */
+#include "s_conf.h"      /* struct ConfItem */
+#include "s_log.h"       /* log level defines */
+#include "s_serv.h"      /* server_estab, check_server, my_name_for_link */
+#include "s_stats.h"     /* ServerStats */
+#include "scache.h"      /* find_or_add */
+#include "send.h"        /* sendto_one */
+#include "motd.h"
+#include "msg.h"
+#include "parse.h"
+#include "modules.h"
+
+#include <string.h>
+#include <stdlib.h>
+
+static void mr_server(struct Client*, struct Client*, int, char **);
+static void ms_server(struct Client*, struct Client*, int, char **);
+
+static int set_server_gecos(struct Client *, char *);
+
+struct Message server_msgtab = {
+  "SERVER", 0, 0, 3, 0, MFLG_SLOW | MFLG_UNREG, 0,
+  {mr_server, m_registered, ms_server, m_registered}
+};
+
+#ifndef STATIC_MODULES
+void 
+_modinit(void)
+{
+  mod_add_cmd(&server_msgtab);
+}
+
+void
+_moddeinit(void)
+{
+  mod_del_cmd(&server_msgtab);
+}
+char *_version = "$Revision: 1.1 $";
+#endif
+
+int bogus_host(char *host);
+struct Client *server_exists(char *);
+
+/*
+ * mr_server - SERVER message handler
+ *      parv[0] = sender prefix
+ *      parv[1] = servername
+ *      parv[2] = serverinfo/hopcount
+ *      parv[3] = serverinfo
+ */
+static void mr_server(struct Client *client_p, struct Client *source_p,
+                      int parc, char *parv[])
+{
+  char             info[REALLEN + 1];
+  char             *name;
+  struct Client    *target_p;
+  int hop;
+
+  if (parc < 4)
+    {
+      sendto_one(client_p,"ERROR :No servername");
+      exit_client(client_p, client_p, client_p, "Wrong number of args");
+      return;
+    }
+
+  name = parv[1];
+  hop = atoi(parv[2]);
+  strncpy_irc(info, parv[3], REALLEN);
+  info[REALLEN] = '\0';
+
+  /* 
+   * Reject a direct nonTS server connection if we're TS_ONLY -orabidoo
+   */
+  if (!DoesTS(client_p))
+    {
+      sendto_realops_flags(FLAGS_ALL, L_ADMIN,"Link %s dropped, non-TS server",
+                          get_client_name(client_p, HIDE_IP));
+      sendto_realops_flags(FLAGS_ALL, L_OPER,"Link %s dropped, non-TS server",
+                          get_client_name(client_p, MASK_IP));
+      exit_client(client_p, client_p, client_p, "Non-TS server");
+      return;
+    }
+
+  if (bogus_host(name))
+  {
+    exit_client(client_p, client_p, client_p, "Bogus server name");
+    return;
+  }
+
+  /* Now we just have to call check_server and everything should be
+   * check for us... -A1kmm. */
+  switch (check_server(name, client_p, CHECK_SERVER_NOCRYPTLINK))
+  {
+    case -1:
+      if (ConfigFileEntry.warn_no_nline)
+      {
+        sendto_realops_flags(FLAGS_ALL, L_ADMIN,
+           "Unauthorized server connection attempt from %s: No entry for "
+           "servername %s", get_client_name(client_p, HIDE_IP), name);
+
+        sendto_realops_flags(FLAGS_ALL, L_OPER,
+           "Unauthorized server connection attempt from %s: No entry for "
+           "servername %s", get_client_name(client_p, MASK_IP), name);
+      }
+      
+      exit_client(client_p, client_p, client_p, "Invalid servername.");
+      return;
+      break;
+      
+    case -2:
+      sendto_realops_flags(FLAGS_ALL, L_ADMIN,
+           "Unauthorized server connection attempt from %s: Bad password "
+           "for server %s", get_client_name(client_p, HIDE_IP), name);
+
+      sendto_realops_flags(FLAGS_ALL, L_OPER,
+           "Unauthorized server connection attempt from %s: Bad password "
+           "for server %s", get_client_name(client_p, MASK_IP), name);
+
+      exit_client(client_p, client_p, client_p, "Invalid password.");
+      return;
+      break;
+      
+    case -3:
+      sendto_realops_flags(FLAGS_ALL, L_ADMIN,
+           "Unauthorized server connection attempt from %s: Invalid host "
+           "for server %s", get_client_name(client_p, HIDE_IP), name);
+
+      sendto_realops_flags(FLAGS_ALL, L_OPER,
+           "Unauthorized server connection attempt from %s: Invalid host "
+           "for server %s", get_client_name(client_p, MASK_IP), name);
+
+      exit_client(client_p, client_p, client_p, "Invalid host.");
+      return;
+      break;
+  }
+    
+  if ((target_p = server_exists(name)))
+    {
+      /*
+       * This link is trying feed me a server that I already have
+       * access through another path -- multiple paths not accepted
+       * currently, kill this link immediately!!
+       *
+       * Rather than KILL the link which introduced it, KILL the
+       * youngest of the two links. -avalon
+       *
+       * Definitely don't do that here. This is from an unregistered
+       * connect - A1kmm.
+       */
+      sendto_realops_flags(FLAGS_ALL, L_ADMIN,
+         "Attempt to re-introduce server %s from %s", name,
+         get_client_name(client_p, HIDE_IP));
+
+      sendto_realops_flags(FLAGS_ALL, L_OPER,
+         "Attempt to re-introduce server %s from %s", name,
+         get_client_name(client_p, MASK_IP));
+
+      sendto_one(client_p, "ERROR :Server already exists.");
+      exit_client(client_p, client_p, client_p, "Server Exists");
+      return;
+    }
+
+  if(ServerInfo.hub && IsCapable(client_p, CAP_LL))
+    {
+      if(IsCapable(client_p, CAP_HUB))
+        {
+          ClearCap(client_p,CAP_LL);
+          sendto_realops_flags(FLAGS_ALL, L_ALL,
+               "*** LazyLinks to a hub from a hub, thats a no-no.");
+        }
+      else
+        {
+          client_p->localClient->serverMask = nextFreeMask();
+
+          if(!client_p->localClient->serverMask)
+            {
+              sendto_realops_flags(FLAGS_ALL, L_ALL,
+                                   "serverMask is full!");
+              /* try and negotiate a non LL connect */
+              ClearCap(client_p,CAP_LL);
+            }
+        }
+    }
+  else if (IsCapable(client_p, CAP_LL))
+    {
+      if(!IsCapable(client_p, CAP_HUB))
+        {
+          ClearCap(client_p,CAP_LL);
+          sendto_realops_flags(FLAGS_ALL, L_ALL,
+               "*** LazyLinks to a leaf from a leaf, thats a no-no.");
+        }
+    }
+
+  /*
+   * if we are connecting (Handshake), we already have the name from the
+   * C:line in client_p->name
+   */
+
+  strncpy_irc(client_p->name, name, HOSTLEN);
+  set_server_gecos(client_p, info);
+  client_p->hopcount = hop;
+  server_estab(client_p);
+}
+
+/*
+ * ms_server - SERVER message handler
+ *      parv[0] = sender prefix
+ *      parv[1] = servername
+ *      parv[2] = serverinfo/hopcount
+ *      parv[3] = serverinfo
+ */
+static void ms_server(struct Client *client_p, struct Client *source_p,
+                      int parc, char *parv[])
+{
+  char             info[REALLEN + 1];
+                   /* same size as in s_misc.c */
+  char*            name;
+  struct Client*   target_p;
+  struct Client*   bclient_p;
+  struct ConfItem* aconf;
+  int              hop;
+  int              hlined = 0;
+  int              llined = 0;
+  dlink_node      *ptr;
+
+  /* Just to be sure -A1kmm. */
+  if (!IsServer(source_p))
+   return;
+
+  if (parc < 4)
+    {
+      sendto_one(client_p,"ERROR :No servername");
+      return;
+    }
+
+  name = parv[1];
+  hop = atoi(parv[2]);
+  strncpy_irc(info, parv[3], REALLEN);
+  info[REALLEN] = '\0';
+
+  if ((target_p = server_exists(name)))
+    {
+      /*
+       * This link is trying feed me a server that I already have
+       * access through another path -- multiple paths not accepted
+       * currently, kill this link immediately!!
+       *
+       * Rather than KILL the link which introduced it, KILL the
+       * youngest of the two links. -avalon
+       *
+       * I think that we should exit the link itself, not the introducer,
+       * and we should always exit the most recently received(i.e. the
+       * one we are receiving this SERVER for. -A1kmm
+       *
+       * You *cant* do this, if you link somewhere, it bursts you a server
+       * that already exists, then sends you a client burst, you squit the
+       * server, but you keep getting the burst of clients on a server that
+       * doesnt exist, although ircd can handle it, its not a realistic
+       * solution.. --fl_ 
+       */
+      /* It is behind a host-masked server. Completely ignore the
+       * server message(don't propagate or we will delink from whoever
+       * we propagate to). -A1kmm */
+      if (irccmp(target_p->name, name) && target_p->from==client_p)
+        return;
+      
+      if(client_p->firsttime > target_p->from->firsttime)
+      {
+        sendto_one(client_p, "ERROR :Server %s already exists", name);
+       
+        sendto_realops_flags(FLAGS_ALL, L_ADMIN,
+                         "Link %s cancelled, server %s already exists",
+                         get_client_name(client_p, SHOW_IP), name);
+        sendto_realops_flags(FLAGS_ALL, L_OPER,
+                         "Link %s cancelled, server %s already exists",
+                         client_p->name, name);
+      
+        exit_client(client_p, client_p, &me, "Server Exists");
+       return;
+      }
+      else
+      {
+        sendto_one(target_p->from, "ERROR :Server %s already exists", name);
+        sendto_realops_flags(FLAGS_ALL, L_ADMIN,
+                   "Link %s cancelled, server %s reintroduced by %s",
+                   get_client_name(target_p->from, SHOW_IP),
+                   name, client_p->name);
+        sendto_realops_flags(FLAGS_ALL, L_ADMIN,
+                   "Link %s cancelled, server %s reintroduced by %s",
+                   target_p->from->name, name, client_p->name);
+
+        exit_client(target_p->from, target_p->from, &me, "Server Exists");
+       return;
+      }
+  }
+  
+  /* 
+   * User nicks never have '.' in them and server names
+   * must always have '.' in them.
+   */
+  if (strchr(name,'.') == NULL)
+    {
+      /*
+       * Server trying to use the same name as a person. Would
+       * cause a fair bit of confusion. Enough to make it hellish
+       * for a while and servers to send stuff to the wrong place.
+       */
+      sendto_one(client_p,"ERROR :Nickname %s already exists!", name);
+      sendto_realops_flags(FLAGS_ALL, L_ADMIN,
+                          "Link %s cancelled: Server/nick collision on %s",
+               /* inpath */ get_client_name(client_p, HIDE_IP), name);
+      sendto_realops_flags(FLAGS_ALL, L_OPER,
+          "Link %s cancelled: Server/nick collision on %s",
+         get_client_name(client_p, MASK_IP), name);
+      exit_client(client_p, client_p, client_p, "Nick as Server");
+      return;
+    }
+
+  /*
+   * Server is informing about a new server behind
+   * this link. Create REMOTE server structure,
+   * add it to list and propagate word to my other
+   * server links...
+   */
+  if (parc == 1 || info[0] == '\0')
+    {
+      sendto_one(client_p, "ERROR :No server info specified for %s", name);
+      return;
+    }
+
+  /*
+   * See if the newly found server is behind a guaranteed
+   * leaf. If so, close the link.
+   *
+   */
+
+  for (aconf = ConfigItemList; aconf; aconf=aconf->next)
+    {
+     if ((aconf->status & (CONF_LEAF|CONF_HUB)) == 0)
+       continue;
+
+     if (match(aconf->name, client_p->name))
+       {
+        if (aconf->status == CONF_HUB)
+         {
+           if(match(aconf->host, name))
+             hlined++;
+         }
+        else if (aconf->status == CONF_LEAF)
+         {
+           if(match(aconf->host, name))
+             llined++;
+         }
+       }
+    }
+
+  /* Ok, this way this works is
+   *
+   * A server can have a CONF_HUB allowing it to introduce servers
+   * behind it.
+   *
+   * connect {
+   *            name = "irc.bighub.net";
+   *            hub_mask="*";
+   *            ...
+   * 
+   * That would allow "irc.bighub.net" to introduce anything it wanted..
+   *
+   * However
+   *
+   * connect {
+   *            name = "irc.somehub.fi";
+   *           hub_mask="*";
+   *           leaf_mask="*.edu";
+   *...
+   * Would allow this server in finland to hub anything but
+   * .edu's
+   */
+
+  /* Ok, check client_p can hub the new server, and make sure it's not a LL */
+  if (!hlined || (IsCapable(client_p, CAP_LL) && !IsCapable(client_p, CAP_HUB)))
+    {
+      /* OOOPs nope can't HUB */
+      sendto_realops_flags(FLAGS_ALL, L_ADMIN, "Non-Hub link %s introduced %s.",
+                get_client_name(client_p, HIDE_IP), name);
+
+      sendto_realops_flags(FLAGS_ALL, L_OPER,
+          "Non-Hub link %s introduced %s.",
+         get_client_name(client_p, MASK_IP), name);
+      /* If it is new, we are probably misconfigured, so split the
+       * non-hub server introducing this. Otherwise, split the new
+       * server. -A1kmm. */
+      if ((CurrentTime - source_p->firsttime) < 20)
+        {
+          exit_client(NULL, source_p, &me, "No matching hub_mask.");
+          return;
+        }
+      else
+        {
+          sendto_one(source_p, ":%s SQUIT %s :Sorry, no matching hub_mask.",
+                     me.name, name);
+          return;
+        }
+    }
+
+  /* Check for the new server being leafed behind this HUB */
+  if (llined)
+    {
+      /* OOOPs nope can't HUB this leaf */
+      sendto_realops_flags(FLAGS_ALL, L_ADMIN,
+            "link %s introduced leafed %s.",
+           get_client_name(client_p, HIDE_IP), name);
+      sendto_realops_flags(FLAGS_ALL, L_OPER, 
+            "link %s introduced leafed %s.",
+            get_client_name(client_p, MASK_IP), name);
+      /* If it is new, we are probably misconfigured, so split the
+       * non-hub server introducing this. Otherwise, split the new
+       * server. -A1kmm.
+       */
+      if ((CurrentTime - source_p->firsttime) < 20)
+        {
+          exit_client(NULL, source_p, &me, "Leafed Server.");
+          return;
+        }
+      else
+        {
+          sendto_one(source_p, ":%s SQUIT %s :Sorry, Leafed server.",
+                     me.name, name);
+          return;
+        }
+    }
+
+  target_p = make_client(client_p);
+  make_server(target_p);
+  target_p->hopcount = hop;
+  strncpy_irc(target_p->name, name, HOSTLEN);
+  set_server_gecos(target_p, info);
+
+  target_p->serv->up = find_or_add(parv[0]);
+  target_p->servptr = source_p;
+
+  SetServer(target_p);
+
+  Count.server++;
+
+  add_client_to_list(target_p);
+  add_server_to_list(target_p);
+  add_to_client_hash_table(target_p->name, target_p);
+  add_client_to_llist(&(target_p->servptr->serv->servers), target_p);
+
+
+  /*
+   * Old sendto_serv_but_one() call removed because we now
+   * need to send different names to different servers
+   * (domain name matching)
+   */
+  for (ptr = serv_list.head; ptr; ptr = ptr->next)
+    {
+      bclient_p = ptr->data;
+
+      if (bclient_p == client_p)
+       continue;
+      if (!(aconf = bclient_p->serv->sconf))
+       {
+         sendto_realops_flags(FLAGS_ALL, L_ADMIN, 
+               "Lost N-line for %s on %s. Closing",
+               get_client_name(client_p, HIDE_IP), name);
+         sendto_realops_flags(FLAGS_ALL, L_OPER, 
+               "Lost N-line for %s on %s. Closing",
+               get_client_name(client_p, MASK_IP), name);
+         exit_client(client_p, client_p, client_p, "Lost N line");
+          return;
+       }
+      if (match(my_name_for_link(me.name, aconf), target_p->name))
+       continue;
+
+      sendto_one(bclient_p, ":%s SERVER %s %d :%s%s",
+                parv[0], target_p->name, hop + 1,
+                target_p->hidden_server ? "(H) " : "",
+                target_p->info);
+    }
+      
+  sendto_realops_flags(FLAGS_EXTERNAL, L_ALL,
+                       "Server %s being introduced by %s",
+                      target_p->name, source_p->name);
+
+}
+
+/* set_server_gecos()
+ *
+ * input       - pointer to client
+ * output      - none
+ * side effects - servers gecos field is set
+ */
+int set_server_gecos(struct Client *client_p, char *info)
+{
+  /* check the info for [IP] */
+  if(info[0])
+  {
+    char *p;
+    char *s;
+    char *t;
+    
+    s = info;
+    
+    /* we should only check the first word for an ip */
+    if((p = strchr(s, ' ')))
+      *p = '\0';
+      
+    /* check for a ] which would symbolise an [IP] */
+    if((t = strchr(s, ']')))
+    {
+      /* set s to after the first space */
+      if(p)
+        s = ++p;
+      else
+        s = NULL;
+    }
+    /* no ], put the space back */
+    else if(p)
+      *p = ' ';
+
+    /* p may have been set to a trailing space, so check s exists and that
+     * it isnt \0 */
+    if(s && (*s != '\0'))
+    {
+      /* a space? if not (H) could be the last part of info.. */
+      if((p = strchr(s, ' ')))
+        *p = '\0';
+      
+      /* check for (H) which is a hidden server */
+      if(!strcmp(s, "(H)"))
+      {
+        client_p->hidden_server = 1;
+
+        /* if there was no space.. theres nothing to set info to */
+        if(p)
+         s = ++p;
+       else
+         s = NULL;
+      }
+      else if(p)
+        *p = ' ';
+      
+      /* if there was a trailing space, s could point to \0, so check */
+      if(s && (*s != '\0'))
+        strncpy_irc(client_p->info, s, REALLEN);
+      else
+        strncpy_irc(client_p->info, "(Unknown Location)", REALLEN);
+    }
+    else
+      strncpy_irc(client_p->info, "(Unknown Location)", REALLEN);
+  }
+  else
+    strncpy_irc(client_p->info, "(Unknown Location)", REALLEN);
+
+  return 1;
+}
+
+/*
+ * bogus_host
+ *
+ * inputs      - hostname
+ * output      - 1 if a bogus hostname input, 0 if its valid
+ * side effects        - none
+ */
+int bogus_host(char *host)
+{
+  int bogus_server = 0;
+  char *s;
+  int dots = 0;
+
+  for( s = host; *s; s++ )
+    {
+      if (!IsServChar(*s))
+       {
+         bogus_server = 1;
+         break;
+       }
+      if ('.' == *s)
+       ++dots;
+    }
+
+  if (!dots || bogus_server )
+    return 1;
+
+  return 0;
+}
+
+/*
+ * server_exists()
+ * 
+ * inputs      - servername
+ * output      - 1 if server exists, 0 if doesnt exist
+ */
+struct Client *server_exists(char *servername)
+{
+  struct Client *target_p;
+  dlink_node *ptr;
+
+  for(ptr = global_serv_list.head; ptr; ptr = ptr->next)
+  {
+    target_p = ptr->data;
+
+    if(match(target_p->name, servername) || 
+         match(servername, target_p->name))
+      return target_p;
+  }
+
+  return NULL;
+}
diff --git a/modules/core/m_sjoin.c b/modules/core/m_sjoin.c
new file mode 100644 (file)
index 0000000..101e5eb
--- /dev/null
@@ -0,0 +1,859 @@
+/************************************************************************
+ *   IRC - Internet Relay Chat, modules/m_sjoin.c
+ *   Copyright (C) 1990 Jarkko Oikarinen and
+ *                      University of Oulu, Computing Center
+ *
+ *   See file AUTHORS in IRC package for additional names of
+ *   the programmers. 
+ *
+ *   This program is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 1, or (at your option)
+ *   any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *   $Id: m_sjoin.c,v 1.1 2002/01/04 10:57:32 a1kmm Exp $
+ */
+#include "tools.h"
+#include "handlers.h"
+#include "channel.h"
+#include "channel_mode.h"
+#include "vchannel.h"
+#include "client.h"
+#include "hash.h"
+#include "irc_string.h"
+#include "ircd.h"
+#include "list.h"
+#include "numeric.h"
+#include "send.h"
+#include "common.h"
+#include "msg.h"
+#include "parse.h"
+#include "modules.h"
+#include "s_serv.h"
+#include "s_conf.h"
+
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+
+static void ms_sjoin(struct Client*, struct Client*, int, char**);
+
+struct Message sjoin_msgtab = {
+  "SJOIN", 0, 0, 0, 0, MFLG_SLOW, 0,
+  {m_unregistered, m_ignore, ms_sjoin, m_ignore}
+};
+
+#ifndef STATIC_MODULES
+void
+_modinit(void)
+{
+  mod_add_cmd(&sjoin_msgtab);
+}
+
+void
+_moddeinit(void)
+{
+  mod_del_cmd(&sjoin_msgtab);
+}
+
+char *_version = "$Revision: 1.1 $";
+#endif
+/*
+ * ms_sjoin
+ * parv[0] - sender
+ * parv[1] - TS
+ * parv[2] - channel
+ * parv[3] - modes + n arguments (key and/or limit)
+ * parv[4+n] - flags+nick list (all in one parameter)
+ * 
+ * process a SJOIN, taking the TS's into account to either ignore the
+ * incoming modes or undo the existing ones or merge them, and JOIN
+ * all the specified users while sending JOIN/MODEs to local clients
+ */
+
+static char    modebuf[MODEBUFLEN];
+static char    parabuf[MODEBUFLEN];
+static char    *para[MAXMODEPARAMS];
+static char    *mbuf;
+static int     pargs;
+
+static void set_final_mode(struct Mode *mode,struct Mode *oldmode);
+static void remove_our_modes(int type,
+                     struct Channel *chptr, struct Channel *top_chptr,
+                     struct Client *source_p);
+
+static void remove_a_mode(int hide_or_not,
+                          struct Channel *chptr, struct Channel *top_chptr,
+                          struct Client *source_p, dlink_list *list, char flag);
+
+
+static void ms_sjoin(struct Client *client_p,
+                    struct Client *source_p,
+                    int parc,
+                    char *parv[])
+{
+  struct Channel *chptr;
+  struct Channel *top_chptr=NULL;      /* XXX vchans */
+  struct Client  *target_p, *lclient_p;
+  time_t         newts;
+  time_t         oldts;
+  time_t         tstosend;
+  static         struct Mode mode, *oldmode;
+  int            args = 0;
+  int            keep_our_modes = 1;
+  int            keep_new_modes = 1;
+  int            doesop = 0;
+  int            fl;
+  int            people = 0;
+  int           num_prefix=0;
+  int            vc_ts = 0;
+  int            isnew;
+  int           buflen = 0;
+  register       char *s, *hops, *nhops;
+  static         char buf[2*BUFSIZE]; /* buffer for modes and prefix */
+  static         char sjbuf_hops[BUFSIZE]; /* buffer with halfops as % */
+  static         char sjbuf_nhops[BUFSIZE]; /* buffer with halfops as @ */
+  char           *p; /* pointer used making sjbuf */
+  int hide_or_not;
+  int i;
+  dlink_node *m;
+
+  *buf = '\0';
+  *sjbuf_hops = '\0';
+  *sjbuf_nhops = '\0';
+
+  if (IsClient(source_p) || parc < 5)
+    return;
+  
+  if (!IsChannelName(parv[2]))
+    return;
+  if (!check_channel_name(parv[2]))
+    return;
+
+  /* SJOIN's for local channels can't happen. */
+  if (*parv[2] == '&')
+    return;
+
+  mbuf = modebuf;
+  *mbuf = '\0';
+  pargs = 0;
+  newts = atol(parv[1]);
+
+  mode.mode = 0;
+  mode.limit = 0;
+  mode.key[0] = '\0';;
+  s = parv[3];
+  while (*s)
+    switch(*(s++))
+      {
+      case 'i':
+        mode.mode |= MODE_INVITEONLY;
+        break;
+      case 'n':
+        mode.mode |= MODE_NOPRIVMSGS;
+        break;
+      case 'p':
+        mode.mode |= MODE_PRIVATE;
+        break;
+      case 's':
+        mode.mode |= MODE_SECRET;
+        break;
+      case 'm':
+        mode.mode |= MODE_MODERATED;
+        break;
+      case 't':
+        mode.mode |= MODE_TOPICLIMIT;
+        break;
+      case 'a':
+        mode.mode |= MODE_HIDEOPS;
+        break;
+      case 'k':
+        strncpy_irc(mode.key, parv[4 + args], KEYLEN);
+        args++;
+        if (parc < 5+args)
+          return;
+        break;
+      case 'l':
+        mode.limit = atoi(parv[4+args]);
+        args++;
+        if (parc < 5+args)
+          return;
+        break;
+      }
+
+  *parabuf = '\0';
+
+  if ((chptr = get_or_create_channel(source_p, parv[2], &isnew)) == NULL)
+    return; /* channel name too long? */
+
+  /* XXX vchan cruft */
+  /* vchans are encoded as "##mainchanname_timestamp" */
+
+  if ( (parv[2][1] == '#') && (ConfigChannel.use_vchans) )
+    {
+      char *subp;
+
+      /* possible sub vchan being sent along ? */
+      if ((subp = strrchr(parv[2],'_')))
+       {
+          vc_ts = atol(subp+1);
+         /* 
+           * XXX - Could be a vchan, but we can't be _sure_
+           *
+           * We now test the timestamp matches below,
+           * but that can still be faked.
+           *
+           * If there was some way to pass an extra bit of
+           * information over non-hybrid-7 servers, through SJOIN,
+           * we could tell other servers that it's a vchan.
+           * That's probably not possible, unfortunately :(
+           */
+
+         *subp = '\0'; /* fugly hack for now ... */
+
+         /* + 1 skip the extra '#' in the name */
+         if ((top_chptr = hash_find_channel(parv[2] + 1)) != NULL)
+           {
+             /* If the vchan is already in the vchan_list for this
+              * root, don't re-add it.
+              */
+              /* Compare timestamps too */
+             if (dlinkFind(&top_chptr->vchan_list,chptr) == NULL &&
+                 newts == vc_ts)
+               {
+                 m = make_dlink_node();
+                 dlinkAdd(chptr, m, &top_chptr->vchan_list);
+                 chptr->root_chptr=top_chptr;
+               }
+           }
+          /* check TS before creating a root channel */
+         else if (newts == vc_ts)
+           {
+             top_chptr = get_or_create_channel(source_p, (parv[2] + 1), NULL);
+             m = make_dlink_node();
+             dlinkAdd(chptr, m, &top_chptr->vchan_list);
+             chptr->root_chptr=top_chptr;
+              /* let users access it somehow... */
+              chptr->vchan_id[0] = '!';
+              chptr->vchan_id[1] = '\0';
+           }
+
+         *subp = '_';  /* fugly hack, restore '_' */
+       }
+    }
+
+  oldts = chptr->channelts;
+
+  doesop = (parv[4+args][0] == '@' || parv[4+args][1] == '@');
+
+  oldmode = &chptr->mode;
+
+#ifdef IGNORE_BOGUS_TS
+  if (newts < 800000000)
+    {
+      sendto_realops_flags(FLAGS_DEBUG, L_ALL,
+                       "*** Bogus TS %lu on %s ignored from %s",
+                       (unsigned long) newts,
+                       chptr->chname,
+                       client_p->name);
+
+      newts = (oldts==0) ? oldts : 800000000;
+    }
+#endif
+
+  /*
+   * XXX - this no doubt destroys vchans
+   */
+  if (isnew)
+    chptr->channelts = tstosend = newts;
+  /* Remote is sending users to a permanent channel.. we need to drop our
+   * version and use theirs, to keep compatibility -- fl */
+  else if (chptr->users == 0 && parv[4+args][0])
+    {
+       keep_our_modes = NO;
+       chptr->channelts = tstosend = newts;
+    }
+  /* They're not sending users, lets just ignore it and carry on */
+  else if (chptr->users == 0 && !parv[4+args][0])
+    return;
+
+  /* It isnt a perm channel, do normal timestamp rules */
+  else if (newts == 0 || oldts == 0)
+    chptr->channelts = tstosend = 0;
+  else if (!newts)
+    chptr->channelts = tstosend = oldts;
+  else if (newts == oldts)
+    tstosend = oldts;
+  else if (newts < oldts)
+    {
+      keep_our_modes = NO;
+      chptr->channelts = tstosend = newts;
+    }
+  else
+    {
+      keep_new_modes = NO;
+      tstosend = oldts;
+    }
+
+  if (!keep_new_modes)
+    mode = *oldmode;
+  else if (keep_our_modes)
+    {
+      mode.mode |= oldmode->mode;
+      if (oldmode->limit > mode.limit)
+        mode.limit = oldmode->limit;
+      if (strcmp(mode.key, oldmode->key) < 0)
+        strcpy(mode.key, oldmode->key);
+    }
+
+  if (mode.mode & MODE_HIDEOPS)
+    hide_or_not = ONLY_CHANOPS_HALFOPS;
+  else
+    hide_or_not = ALL_MEMBERS;
+
+  if ((MODE_HIDEOPS & mode.mode) && !(MODE_HIDEOPS & oldmode->mode))
+    sync_channel_oplists(chptr, MODE_DEL);
+
+  /* Don't reveal the ops, only to remove them all */
+  if (keep_our_modes)
+    if (!(MODE_HIDEOPS & mode.mode) && (MODE_HIDEOPS & oldmode->mode))
+      sync_channel_oplists(chptr, MODE_ADD);
+
+  set_final_mode(&mode,oldmode);
+  chptr->mode = mode;
+
+  /* Lost the TS, other side wins, so remove modes on this side */
+  if (!keep_our_modes)
+    {
+      remove_our_modes(hide_or_not, chptr, top_chptr, source_p);
+    }
+  if(!keep_our_modes)
+     chptr->ts_winner = NO;
+  else
+     chptr->ts_winner = YES;
+     
+  if (*modebuf != '\0')
+    {
+      /* This _SHOULD_ be to ALL_MEMBERS
+       * It contains only +aimnstlki, etc */
+      if (top_chptr != NULL)
+       sendto_channel_local(ALL_MEMBERS,
+                            chptr, ":%s MODE %s %s %s",
+                            me.name,
+                            top_chptr->chname, modebuf, parabuf);
+      else
+       sendto_channel_local(ALL_MEMBERS,
+                            chptr, ":%s MODE %s %s %s",
+                            me.name,
+                            chptr->chname, modebuf, parabuf);
+    }
+
+  *modebuf = *parabuf = '\0';
+  if (parv[3][0] != '0' && keep_new_modes)
+    {
+      channel_modes(chptr, source_p, modebuf, parabuf);
+    }
+  else
+    {
+      modebuf[0] = '0';
+      modebuf[1] = '\0';
+    }
+
+  buflen = ircsprintf(buf, ":%s SJOIN %lu %s %s %s :",
+                     parv[0],
+                     (unsigned long) tstosend,
+                     parv[2], modebuf, parabuf);
+
+  /* check we can fit a nick on the end, as well as \r\n\0 and a prefix "
+   * @+".
+   */
+  if (buflen >= (BUFSIZE - 6 - NICKLEN))
+    {
+      sendto_realops_flags(FLAGS_ALL, L_ALL,
+                          "Long SJOIN from server: %s(via %s) (ignored)",
+                          source_p->name, client_p->name);
+      return;
+    }
+
+  mbuf = modebuf;
+  para[0] = para[1] = para[2] = para[3] = "";
+  pargs = 0;
+
+  *mbuf++ = '+';
+
+  hops = sjbuf_hops;
+  nhops = sjbuf_nhops;
+
+  s = parv[args+4];
+
+  /* remove any leading spaces */
+  while(*s == ' ')
+  {
+    s++;
+  }
+   
+  /* if theres a space, theres going to be more than one nick, change the
+   * first space to \0, so s is just the first nick, and point p to the
+   * second nick
+   */
+  if ((p = strchr(s, ' ')) != NULL)
+  {
+    *p++ = '\0';
+  }
+
+  while (s)
+    {
+      fl = 0;
+      num_prefix = 0;
+
+      for (i = 0; i < 2; i++)
+       {
+         if (*s == '@')
+           {
+             fl |= MODE_CHANOP;
+             if (keep_new_modes)
+             {
+               *hops++ = *s;
+               *nhops++ = *s;
+               num_prefix++;
+              }
+             
+             s++;
+           }
+         else if (*s == '+')
+           {
+             fl |= MODE_VOICE;
+             if (keep_new_modes)
+             {
+               *hops++ = *s;
+               *nhops++ = *s;
+               num_prefix++;
+             }
+             
+             s++;
+           }
+         else if (*s == '%')
+           {
+             fl |= MODE_HALFOP;
+             if (keep_new_modes)
+             {
+               *hops++ = *s;
+               *nhops++ = '@';
+               num_prefix++;
+             }
+             
+             s++;
+           }
+       }
+
+      /* if the client doesnt exist, backtrack over the prefix (@%+) that we
+       * just added and skip to the next nick
+       */
+      if (!(target_p = find_client(s)))
+      {
+        sendto_one(source_p, form_str(ERR_NOSUCHNICK), me.name,
+                  source_p->name, s);
+
+        hops -= num_prefix;
+       *hops = '\0';
+
+       nhops -= num_prefix;
+       *nhops = '\0';
+
+        goto nextnick;
+      }
+
+      target_p = NULL;
+      
+      /* copy the nick to the two buffers */
+      hops += ircsprintf(hops, "%s ", s);
+      nhops += ircsprintf(nhops, "%s ", s);
+      assert((hops-sjbuf_hops) < sizeof(sjbuf_hops) &&
+             (nhops-sjbuf_nhops) < sizeof(sjbuf_nhops));
+
+      if (!keep_new_modes)
+       {
+         if (fl & MODE_CHANOP)
+           {
+             fl = MODE_DEOPPED;
+           }
+         else
+           {
+             fl = 0;
+           }
+       }
+
+      if (!(target_p = find_chasing(source_p, s, NULL)))
+        goto nextnick;
+      if (target_p->from != client_p)
+        goto nextnick;
+      if (!IsPerson(target_p))
+        goto nextnick;
+      
+      people++;
+
+      /* LazyLinks - Introduce unknown clients before sending the sjoin */
+      if (ServerInfo.hub)
+       {
+         for (m = serv_list.head; m; m = m->next)
+           {
+             lclient_p = m->data;
+             
+             /* Hopefully, the server knows about it's own clients. */
+             if (client_p == lclient_p)
+               continue;
+
+             /* Ignore non lazylinks */
+             if (!IsCapable(lclient_p,CAP_LL))
+               continue;
+
+             /* Ignore servers we won't tell anyway */
+             if (!(RootChan(chptr)->lazyLinkChannelExists &
+                   lclient_p->localClient->serverMask) )
+               continue;
+
+             /* Ignore servers that already know target_p */
+             if (!(target_p->lazyLinkClientExists &
+                   lclient_p->localClient->serverMask) )
+               {
+                 /* Tell LazyLink Leaf about client_p,
+                  * as the leaf is about to get a SJOIN */
+                 sendnick_TS( lclient_p, target_p );
+                 add_lazylinkclient(lclient_p,target_p);
+               }
+           }
+       }
+      
+      if (!IsMember(target_p, chptr))
+        {
+          add_user_to_channel(chptr, target_p, fl);
+         /* XXX vchan stuff */
+
+         if (top_chptr)
+           {
+             add_vchan_to_client_cache(target_p,top_chptr, chptr);
+             sendto_channel_local(ALL_MEMBERS,chptr, ":%s!%s@%s JOIN :%s",
+                                  target_p->name,
+                                  target_p->username,
+                                  target_p->host,
+                                  top_chptr->chname);
+           }
+         else
+           {
+             sendto_channel_local(ALL_MEMBERS,chptr, ":%s!%s@%s JOIN :%s",
+                                  target_p->name,
+                                  target_p->username,
+                                  target_p->host,
+                                  parv[2]);
+           }
+       }
+
+      if (fl & MODE_CHANOP)
+        {
+          *mbuf++ = 'o';
+         para[pargs++] = s;
+        }
+      else if (fl & MODE_VOICE)
+        {
+          *mbuf++ = 'v';
+         para[pargs++] = s;
+        }
+      else if (fl & MODE_HALFOP)
+        {
+          *mbuf++ = 'h';
+          para[pargs++] = s;
+        }
+
+      if (pargs >= MAXMODEPARAMS)
+        {
+          *mbuf = '\0';
+          sendto_channel_local(hide_or_not, chptr,
+                               ":%s MODE %s %s %s %s %s %s",
+                               me.name,
+                               RootChan(chptr)->chname,
+                               modebuf,
+                               para[0],para[1],para[2],para[3]);
+          mbuf = modebuf;
+          *mbuf++ = '+';
+          para[0] = para[1] = para[2] = para[3] = "";
+          pargs = 0;
+        }
+
+nextnick:
+      /* p points to the next nick */
+      s = p;
+     
+      /* if there was a trailing space and p was pointing to it, then we
+       * need to exit.. this has the side effect of breaking double spaces
+       * in an sjoin.. but that shouldnt happen anyway
+       */
+      if (s && (*s == '\0'))
+        s = p = NULL;
+       
+      /* if p was NULL due to no spaces, s wont exist due to the above, so
+       * we cant check it for spaces.. if there are no spaces, then when
+       * we next get here, s will be NULL
+       */
+      if (s && ((p = strchr(s, ' ')) != NULL))
+      {
+        *p++ = '\0';
+      }
+    }
+  
+  *mbuf = '\0';
+  if (pargs)
+    {
+      sendto_channel_local(hide_or_not, chptr,
+                           ":%s MODE %s %s %s %s %s %s",
+                           me.name,
+                           RootChan(chptr)->chname,
+                           modebuf,
+                           para[0], para[1], para[2], para[3]);
+    }
+
+  if (!people)
+    return;
+
+  /* relay the SJOIN to other servers */
+  for(m = serv_list.head; m; m = m->next)
+    {
+      target_p = m->data;
+
+      if (target_p == client_p->from)
+        continue;
+
+      /* skip lazylinks that don't know about this server */
+      if (ServerInfo.hub && IsCapable(target_p,CAP_LL))
+      {
+        if (!(RootChan(chptr)->lazyLinkChannelExists &
+              target_p->localClient->serverMask) )
+          continue;
+      }
+
+      /* Its a blank sjoin, ugh */
+      if (!parv[4+args][0])
+          return;
+  
+      if (IsCapable(target_p, CAP_HOPS))
+        sendto_one(target_p, "%s %s", buf, sjbuf_hops);
+      else
+        sendto_one(target_p, "%s %s", buf, sjbuf_nhops);
+   }
+}
+
+/*
+ * set_final_mode
+ *
+ * inputs      - pointer to mode to setup
+ *             - pointer to old mode
+ * output      - NONE
+ * side effects        - 
+ */
+
+struct mode_letter {
+  int mode;
+  char letter;
+};
+
+struct mode_letter flags[] = {
+  { MODE_NOPRIVMSGS, 'n' },
+  { MODE_TOPICLIMIT, 't' },
+  { MODE_SECRET,     's' },
+  { MODE_MODERATED,  'm' },
+  { MODE_INVITEONLY, 'i' },
+  { MODE_PRIVATE,    'p' },
+  { MODE_HIDEOPS,    'a' },
+  { 0, 0 }
+};
+
+static void set_final_mode(struct Mode *mode,struct Mode *oldmode)
+{
+  int what = 0;
+  char *pbuf=parabuf;
+  int  len;
+  int  i;
+
+  for (i = 0; flags[i].letter; i++)
+    {
+      if ((flags[i].mode & mode->mode) && !(flags[i].mode & oldmode->mode))
+       {
+         if (what != 1)
+           {
+             *mbuf++ = '+';
+             what = 1;
+           }
+         *mbuf++ = flags[i].letter;
+       }
+    }
+  for (i = 0; flags[i].letter; i++)
+    {
+      if ((flags[i].mode & oldmode->mode) && !(flags[i].mode & mode->mode))
+       {
+         if (what != -1)
+           {
+             *mbuf++ = '-';
+             what = -1;
+           }
+         *mbuf++ = flags[i].letter;
+       }
+    }
+  if (oldmode->limit && !mode->limit)
+    {
+      if (what != -1)
+        {
+          *mbuf++ = '-';
+          what = -1;
+        }
+      *mbuf++ = 'l';
+    }
+  if (oldmode->key[0] && !mode->key[0])
+    {
+      if (what != -1)
+        {
+          *mbuf++ = '-';
+          what = -1;
+        }
+      *mbuf++ = 'k';
+      len = ircsprintf(pbuf,"%s ", oldmode->key);
+      pbuf += len;
+      pargs++;
+    }
+  if (mode->limit && oldmode->limit != mode->limit)
+    {
+      if (what != 1)
+        {
+          *mbuf++ = '+';
+          what = 1;
+        }
+      *mbuf++ = 'l';
+      len = ircsprintf(pbuf, "%d ", mode->limit);
+      pbuf += len;
+      pargs++;
+    }
+  if (mode->key[0] && strcmp(oldmode->key, mode->key))
+    {
+      if (what != 1)
+        {
+          *mbuf++ = '+';
+          what = 1;
+        }
+      *mbuf++ = 'k';
+      len = ircsprintf(pbuf, "%s ", mode->key);
+      pbuf += len;
+      pargs++;
+    }
+  *mbuf = '\0';
+}
+
+/*
+ * remove_our_modes
+ *
+ * inputs      - hide from ops or not int flag
+ *             - pointer to channel to remove modes from
+ *             - if vchan basechannel pointer 
+ *             - client pointer
+ * output      - NONE
+ * side effects        - Go through the local members, remove all their
+ *               chanop modes etc., this side lost the TS.
+ */
+static void remove_our_modes( int hide_or_not,
+                              struct Channel *chptr, struct Channel *top_chptr,
+                              struct Client *source_p)
+{
+  remove_a_mode(hide_or_not, chptr, top_chptr, source_p, &chptr->chanops, 'o');
+  remove_a_mode(hide_or_not, chptr, top_chptr, source_p, &chptr->halfops, 'h');
+  remove_a_mode(hide_or_not, chptr, top_chptr, source_p, &chptr->voiced, 'v');
+  remove_a_mode(hide_or_not, chptr, top_chptr, source_p,
+                &chptr->chanops_voiced, 'o');
+  remove_a_mode(hide_or_not, chptr, top_chptr, source_p,
+                &chptr->chanops_voiced, 'v');    
+
+  /* Move all voice/ops etc. to non opped list */
+  dlinkMoveList(&chptr->chanops, &chptr->peons);
+  dlinkMoveList(&chptr->halfops, &chptr->peons);
+  dlinkMoveList(&chptr->voiced, &chptr->peons);
+  dlinkMoveList(&chptr->chanops_voiced, &chptr->peons);
+
+  dlinkMoveList(&chptr->locchanops, &chptr->locpeons);
+  dlinkMoveList(&chptr->lochalfops, &chptr->locpeons);
+  dlinkMoveList(&chptr->locvoiced, &chptr->locpeons);
+  dlinkMoveList(&chptr->locchanops_voiced, &chptr->peons);
+}
+
+
+/*
+ * remove_a_mode
+ *
+ * inputs      -
+ * output      - NONE
+ * side effects        - remove ONE mode from a channel
+ */
+static void remove_a_mode( int hide_or_not,
+                           struct Channel *chptr, struct Channel *top_chptr,
+                           struct Client *source_p, dlink_list *list, char flag)
+{
+  dlink_node *ptr;
+  struct Client *target_p;
+  char buf[BUFSIZE];
+  char lmodebuf[MODEBUFLEN];
+  char *lpara[MAXMODEPARAMS];
+  char *chname;
+  int count = 0;
+
+  mbuf = lmodebuf;
+  *mbuf++ = '-';
+
+  lpara[0] = lpara[1] = lpara[2] = lpara[3] = "";
+
+  chname = chptr->chname;
+
+  if (IsVchan(chptr) && top_chptr)
+    chname = top_chptr->chname;
+
+  ircsprintf(buf,":%s MODE %s ", me.name, chname);
+
+  for (ptr = list->head; ptr && ptr->data; ptr = ptr->next)
+    {
+      target_p = ptr->data;
+      lpara[count++] = target_p->name;
+
+      *mbuf++ = flag;
+
+      if (count >= MAXMODEPARAMS)
+       {
+         *mbuf   = '\0';
+         sendto_channel_local(hide_or_not, chptr,
+                              ":%s MODE %s %s %s %s %s %s",
+                              me.name,
+                              chname,
+                              lmodebuf,
+                              lpara[0], lpara[1], lpara[2], lpara[3] );
+
+         mbuf = lmodebuf;
+         *mbuf++ = '-';
+         count = 0;
+         lpara[0] = lpara[1] = lpara[2] = lpara[3] = "";
+       }
+    }
+
+  if (count != 0)
+    {
+      *mbuf   = '\0';
+      sendto_channel_local(hide_or_not, chptr,
+                          ":%s MODE %s %s %s %s %s %s",
+                          me.name,
+                          chname,
+                          lmodebuf,
+                          lpara[0], lpara[1], lpara[2], lpara[3] );
+
+    }
+}
diff --git a/modules/core/m_squit.c b/modules/core/m_squit.c
new file mode 100644 (file)
index 0000000..419f17e
--- /dev/null
@@ -0,0 +1,236 @@
+/************************************************************************
+ *   IRC - Internet Relay Chat, modules/m_squit.c
+ *   Copyright (C) 1990 Jarkko Oikarinen and
+ *                      University of Oulu, Computing Center
+ *
+ *   See file AUTHORS in IRC package for additional names of
+ *   the programmers. 
+ *
+ *   This program is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 1, or (at your option)
+ *   any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *   $Id: m_squit.c,v 1.1 2002/01/04 10:57:32 a1kmm Exp $
+ */
+#include "handlers.h"
+#include "client.h"
+#include "common.h"      /* FALSE bleah */
+#include "irc_string.h"
+#include "ircd.h"
+#include "numeric.h"
+#include "s_conf.h"
+#include "s_log.h"
+#include "s_serv.h"
+#include "send.h"
+#include "msg.h"
+#include "parse.h"
+#include "modules.h"
+
+#include <assert.h>
+
+static void ms_squit(struct Client*, struct Client*, int, char**);
+static void mo_squit(struct Client*, struct Client*, int, char**);
+
+struct Message squit_msgtab = {
+  "SQUIT", 0, 0, 1, 0, MFLG_SLOW, 0,
+  {m_unregistered, m_not_oper, ms_squit, mo_squit}
+};
+
+#ifndef STATIC_MODULES
+void
+_modinit(void)
+{
+  mod_add_cmd(&squit_msgtab);
+}
+
+void
+_moddeinit(void)
+{
+  mod_del_cmd(&squit_msgtab);
+}
+char *_version = "$Revision: 1.1 $";
+#endif
+struct squit_parms 
+{
+  char *server_name;
+  struct Client *target_p;
+};
+
+static struct squit_parms *find_squit(struct Client *client_p,
+                                      struct Client *source_p,
+                                      char *server);
+
+
+/*
+ * mo_squit - SQUIT message handler
+ *      parv[0] = sender prefix
+ *      parv[1] = server name
+ *      parv[2] = comment
+ */
+static void mo_squit(struct Client *client_p, struct Client *source_p,
+                    int parc, char *parv[])
+{
+  struct squit_parms *found_squit;
+  char  *comment = (parc > 2 && parv[2]) ? parv[2] : client_p->name;
+
+  if (!IsOperRemote(source_p))
+    {
+      sendto_one(source_p,":%s NOTICE %s :You need remote = yes;",me.name,parv[0]);
+      return;
+    }
+
+  if(parc < 2)
+    {
+      sendto_one(source_p, form_str(ERR_NEEDMOREPARAMS),
+                 me.name, parv[0], "SQUIT");
+      return;
+    }
+
+  if( (found_squit = find_squit(client_p,source_p,parv[1])) )
+    {
+      if(MyConnect(found_squit->target_p))
+       {
+         sendto_realops_flags(FLAGS_ALL, L_ALL,
+                              "Received SQUIT %s from %s (%s)",
+                              found_squit->target_p->name,
+                              get_client_name(source_p, HIDE_IP), comment);
+          ilog(L_NOTICE, "Received SQUIT %s from %s (%s)",
+              found_squit->target_p->name, get_client_name(source_p, HIDE_IP),
+              comment);
+       }
+      exit_client(client_p, found_squit->target_p, source_p, comment);
+      return;
+    }
+  else
+    {
+           sendto_one(source_p, form_str(ERR_NOSUCHSERVER),
+                      me.name, parv[0], parv[1]);
+    }
+}
+
+/*
+ * ms_squit - SQUIT message handler
+ *      parv[0] = sender prefix
+ *      parv[1] = server name
+ *      parv[2] = comment
+ */
+static void ms_squit(struct Client *client_p, struct Client *source_p,
+                    int parc, char *parv[])
+{
+  struct squit_parms *found_squit;
+  char  *comment = (parc > 2 && parv[2]) ? parv[2] : client_p->name;
+
+  if(parc < 2)
+    {
+      exit_client(client_p, client_p, source_p, comment);
+      return;
+    }
+
+  if( (found_squit = find_squit(client_p, source_p, parv[1])) )
+    {
+      /*
+      **  Notify all opers, if my local link is remotely squitted
+      */
+      if (MyConnect(found_squit->target_p))
+       {
+         sendto_wallops_flags(FLAGS_WALLOP, &me,
+                                "Remote SQUIT %s from %s (%s)",
+                                found_squit->server_name,
+                                source_p->name, comment);
+
+          sendto_server(NULL, NULL, NULL, NOCAPS, NOCAPS, NOFLAGS,
+                        ":%s WALLOPS :Remote SQUIT %s from %s (%s)",
+                        me.name, found_squit->server_name,
+                        source_p->name, comment);
+
+         ilog(L_TRACE, "SQUIT From %s : %s (%s)", parv[0],
+              found_squit->server_name, comment);
+
+       }
+      exit_client(client_p, found_squit->target_p, source_p, comment);
+      return;
+    }
+}
+
+
+/*
+ * find_squit
+ * inputs      - local server connection
+ *             -
+ *             -
+ * output      - pointer to struct containing found squit or none if not found
+ * side effects        -
+ */
+static struct squit_parms *find_squit(struct Client *client_p,
+                                      struct Client *source_p,
+                                      char *server)
+{
+  static struct squit_parms found_squit;
+  static struct Client *target_p;
+  struct ConfItem *aconf;
+
+  found_squit.target_p = NULL;
+  found_squit.server_name = NULL;
+
+  /*
+  ** To accomodate host masking, a squit for a masked server
+  ** name is expanded if the incoming mask is the same as
+  ** the server name for that link to the name of link.
+  */
+  if ((*server == '*') && IsServer(client_p))
+    {
+      aconf = client_p->serv->sconf;
+      if (aconf)
+        {
+         if (!irccmp(server, my_name_for_link(me.name, aconf)))
+           {
+              found_squit.server_name = client_p->name;
+              found_squit.target_p = client_p;
+           }
+       }
+    }
+
+  /*
+  ** The following allows wild cards in SQUIT. Only useful
+  ** when the command is issued by an oper.
+  */
+  for (target_p = GlobalClientList; (target_p = next_client(target_p, server));
+       target_p = target_p->next)
+    {
+      if (IsServer(target_p) || IsMe(target_p))
+       break;
+    }
+
+  found_squit.target_p = target_p;
+  found_squit.server_name = server;
+
+  if (target_p && IsMe(target_p))
+    {
+       if (IsClient(client_p))
+         {
+                sendto_one(source_p,":%s NOTICE %s :You are trying to squit me.",me.name,client_p->name);
+                found_squit.target_p = NULL;
+         }
+       else
+         {
+           found_squit.target_p = client_p;
+           found_squit.server_name = client_p->name;
+         }
+       
+    }
+
+  if(found_squit.target_p != NULL)
+    return &found_squit;
+  else
+    return( NULL );
+}
index f903ed5e77e199681b027ad7b15e577c37cfb096..bae0f340581b073624016f252a1320efa6342075 100644 (file)
@@ -1,4 +1,4 @@
-# $Id: .depend,v 1.1 2002/01/04 09:14:59 a1kmm Exp $
+# $Id: .depend,v 1.2 2002/01/04 10:57:36 a1kmm Exp $
 adns.o: adns.c ../include/fileio.h ../include/res.h ../include/config.h \
   ../include/setup.h ../include/defaults.h ../include/ircd_defs.h \
   ../adns/adns.h ../include/ircd.h ../include/tools.h ../include/memory.h \
@@ -8,7 +8,13 @@ adns.o: adns.c ../include/fileio.h ../include/res.h ../include/config.h \
   ../include/linebuf.h ../include/channel.h ../include/s_bsd.h \
   ../include/fdlist.h ../include/s_log.h ../include/event.h \
   ../include/numeric.h ../adns/internal.h ../adns/dlist.h
-balloc.o: balloc.c ../include/setup.h
+balloc.o: balloc.c ../include/setup.h ../include/ircd_defs.h \
+  ../include/config.h ../include/defaults.h ../include/ircd.h \
+  ../include/tools.h ../include/memory.h ../include/balloc.h \
+  ../include/irc_string.h ../include/s_log.h ../include/client.h \
+  ../include/ircd_handler.h ../include/linebuf.h ../include/channel.h \
+  ../include/res.h ../include/fileio.h ../adns/adns.h \
+  ../include/sprintf_irc.h ../include/fdlist.h
 channel.o: channel.c ../include/tools.h ../include/channel.h \
   ../include/config.h ../include/setup.h ../include/defaults.h \
   ../include/ircd_defs.h ../include/channel_mode.h ../include/vchannel.h \
@@ -19,7 +25,7 @@ channel.o: channel.c ../include/tools.h ../include/channel.h \
   ../include/list.h ../include/numeric.h ../include/s_serv.h \
   ../include/s_user.h ../include/send.h ../include/whowas.h \
   ../include/s_conf.h ../include/motd.h ../include/class.h \
-  ../include/event.h ../include/s_log.h
+  ../include/event.h ../include/resv.h ../include/s_log.h
 channel_mode.o: channel_mode.c ../include/tools.h ../include/channel.h \
   ../include/config.h ../include/setup.h ../include/defaults.h \
   ../include/ircd_defs.h ../include/channel_mode.h ../include/vchannel.h \
@@ -101,9 +107,9 @@ hook.o: hook.c ../include/tools.h ../include/list.h ../include/memory.h \
   ../include/defaults.h ../include/balloc.h ../include/hook.h
 hostmask.o: hostmask.c ../include/memory.h ../include/ircd_defs.h \
   ../include/config.h ../include/setup.h ../include/defaults.h \
-  ../include/balloc.h ../include/s_conf.h ../include/fileio.h \
-  ../include/motd.h ../include/class.h ../include/client.h \
-  ../include/ircd_handler.h ../include/linebuf.h ../include/tools.h \
+  ../include/balloc.h ../include/tools.h ../include/s_conf.h \
+  ../include/fileio.h ../include/motd.h ../include/class.h \
+  ../include/client.h ../include/ircd_handler.h ../include/linebuf.h \
   ../include/channel.h ../include/res.h ../adns/adns.h ../include/ircd.h \
   ../include/irc_string.h ../include/sprintf_irc.h ../include/hostmask.h \
   ../include/numeric.h ../include/send.h
@@ -188,8 +194,8 @@ match.o: match.c ../include/irc_string.h ../include/ircd_defs.h \
   ../include/memory.h ../include/balloc.h ../include/sprintf_irc.h
 md5.o: md5.c ../include/memory.h ../include/ircd_defs.h \
   ../include/config.h ../include/setup.h ../include/defaults.h \
-  ../include/balloc.h ../include/s_log.h ../include/client.h \
-  ../include/ircd_handler.h ../include/linebuf.h ../include/tools.h \
+  ../include/balloc.h ../include/tools.h ../include/s_log.h \
+  ../include/client.h ../include/ircd_handler.h ../include/linebuf.h \
   ../include/channel.h ../include/res.h ../include/fileio.h \
   ../adns/adns.h ../include/ircd.h ../include/irc_string.h \
   ../include/sprintf_irc.h ../include/md5.h
@@ -204,8 +210,8 @@ memory.o: memory.c ../include/ircd_defs.h ../include/config.h \
 modules.o: modules.c ../include/config.h ../include/setup.h \
   ../include/defaults.h ../include/modules.h ../include/parse.h \
   ../include/ircd_handler.h ../include/msg.h ../include/memory.h \
-  ../include/ircd_defs.h ../include/balloc.h ../include/s_log.h \
-  ../include/ircd.h ../include/tools.h ../include/client.h \
+  ../include/ircd_defs.h ../include/balloc.h ../include/tools.h \
+  ../include/s_log.h ../include/ircd.h ../include/client.h \
   ../include/linebuf.h ../include/channel.h ../include/res.h \
   ../include/fileio.h ../adns/adns.h ../include/irc_string.h \
   ../include/sprintf_irc.h ../include/send.h ../include/s_conf.h \
@@ -223,7 +229,7 @@ motd.o: motd.c ../include/tools.h ../include/motd.h \
 numeric.o: numeric.c ../include/setup.h ../include/config.h \
   ../include/defaults.h ../include/numeric.h ../include/irc_string.h \
   ../include/ircd_defs.h ../include/common.h ../include/memory.h \
-  ../include/balloc.h messages.tab
+  ../include/balloc.h ../include/tools.h messages.tab
 packet.o: packet.c ../include/tools.h ../include/s_bsd.h \
   ../include/config.h ../include/setup.h ../include/defaults.h \
   ../include/fdlist.h ../include/ircd_defs.h ../include/res.h \
@@ -247,9 +253,9 @@ parse.o: parse.c ../include/parse.h ../include/client.h \
   ../include/class.h ../include/vchannel.h ../include/s_serv.h
 rsa.o: rsa.c ../include/config.h ../include/setup.h ../include/defaults.h \
   ../include/memory.h ../include/ircd_defs.h ../include/balloc.h \
-  ../include/rsa.h ../include/s_conf.h ../include/fileio.h \
-  ../include/motd.h ../include/class.h ../include/client.h \
-  ../include/ircd_handler.h ../include/linebuf.h ../include/tools.h \
+  ../include/tools.h ../include/rsa.h ../include/s_conf.h \
+  ../include/fileio.h ../include/motd.h ../include/class.h \
+  ../include/client.h ../include/ircd_handler.h ../include/linebuf.h \
   ../include/channel.h ../include/res.h ../adns/adns.h ../include/ircd.h \
   ../include/irc_string.h ../include/sprintf_irc.h ../include/s_log.h
 restart.o: restart.c ../include/tools.h ../include/restart.h \
index 074580b4655ec6f33620ac5f1141a645000b9ef2..985eb05939ade94746da763ee673744b6b6dad72 100644 (file)
-/*
- * balloc.c - Based roughly on Wohali's old block allocator.
+/************************************************************************
+ *  ircd hybrid - Internet Relay Chat Daemon, src/balloc.c
+ *  balloc.c: The block allocator.
+ *  Copyright(C) 2001 by the past and present ircd-hybrid teams.
  *
- * Copyright 2001 Aaron Sethman <androsyn@ratbox.org>
- * 
- * Below is the original header found on this file
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
  *
- * File:   blalloc.c
- * Owner:  Wohali (Joan Touzet)
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
  *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  *
- * $Id: balloc.c,v 1.1 2002/01/04 09:13:41 a1kmm Exp $
+ * $Id: balloc.c,v 1.2 2002/01/04 10:57:36 a1kmm Exp $
  */
 
-/* 
- * About the block allocator
- *
- * Basically we have three ways of getting memory off of the operating
- * system. Below are this list of methods and the order of preference.
- *
- * 1. mmap() anonymous pages with the MMAP_ANON flag.
- * 2. mmap() via the /dev/zero trick.
- * 3. malloc() 
- *
- * The advantages of 1 and 2 are this.  We can munmap() the pages which will
- * return the pages back to the operating system, thus reducing the size 
- * of the process as the memory is unused.  malloc() on many systems just keeps
- * a heap of memory to itself, which never gets given back to the OS, except on
- * exit.  This of course is bad, if say we have an event that causes us to allocate
- * say, 200MB of memory, while our normal memory consumption would be 15MB.  In the
- * malloc() case, the amount of memory allocated to our process never goes down, as
- * malloc() has it locked up in its heap.  With the mmap() method, we can munmap()
- * the block and return it back to the OS, thus causing our memory consumption to go
- * down after we no longer need it.
- * 
- * Of course it is up to the caller to make sure BlockHeapGarbageCollect() gets
- * called periodically to do this cleanup, otherwise you'll keep the memory in the
- * process.
- *
- *
+/* A note on the algorithm:
+ *  - Unlike past block allocators, this one uses a single linked list
+ *    for block segments. This makes garbage collection much slower but
+ *    should drastically increase allocation and de-allocation times.
+ *    This is okay, because garbage collection occurs much less
+ *    frequently than allocation and de-allocation.
+ * The following table is a rough guideline only...
+ * n = number of blocks, m = elements per block.
+ *|     Action      |  Estimated rel. freq. | Worst case bit complexity
+ *|   Heap setup    |             1         |       O(1) + block alloc
+ *|Block allocation |            10^3       |       O(n)
+ *|Element allocate |            10^6       |       O(1)
+ *|  Element free   |            10^6       |       O(1)
+ *| Garbage collect |            10^3       |       O(nm)
+ * - A1kmm
  */
 
-#define WE_ARE_MEMORY_C
-#include "setup.h"
-
-#ifndef NOBALLOC
-#include <stdio.h>
-#include <unistd.h>
-#include <assert.h>
-#include <fcntl.h>
-#include "ircd_defs.h"          /* DEBUG_BLOCK_ALLOCATOR */
-#include "ircd.h"
 #include "memory.h"
-#include "balloc.h"
-#include "irc_string.h"
-#include "tools.h"
-#include "s_log.h"
-#include "client.h"
-#include "fdlist.h"
-
-#include <string.h>
-#include <stdlib.h>
-static int newblock(BlockHeap * bh);
-
-#ifdef HAVE_MMAP /* We've got mmap() that is good */
-#include <sys/mman.h>
-
-/*
- * static inline void free_block(void *ptr, size_t size)
- *
- * Inputs: The block and its size
- * Output: None
- * Side Effects: Returns memory for the block back to the OS
- */
-static inline void free_block(void *ptr, size_t size)
-{
-  munmap(ptr, size);
-}
-
-#ifndef MAP_ANON /* But we cannot mmap() anonymous pages */
-                /* So we mmap() /dev/zero, which is just as good */
-static int zero_fd = -1;
-
-/*
- * void initBlockHeap(void)
- * Note: This is the /dev/zero version of getting pages 
- * 
- * Inputs: None
- * Outputs: None
- * Side Effects: Opens /dev/zero and saves the file handle for
- *              future allocations.
- */
-void initBlockHeap(void)
-{
-  zero_fd = open("/dev/zero", O_RDWR);
-
-  if (zero_fd < 0)
-    outofmemory();
-  fd_open(zero_fd, FD_FILE, "Anonymous mmap()");
-}
+#include <assert.h>
 
-/*
- * static inline void *get_block(size_t size)
- * 
- * Note: This is the /dev/zero version
- * Input: Size of block to allocate
- * Output: Pointer to new block
- * Side Effects: None
+#ifndef NOBALLOC
+/* First some structures. I put them here and not in balloc.h because
+ * I didn't want them to be exposed outside this file, and I also don't
+ * really want to add another header... -A1kmm
  */
-static inline void *get_block(size_t size)
-{
-  return (mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_PRIVATE, zero_fd, 0));
-}
-#else /* MAP_ANON */ 
-
-/* 
- * void initBlockHeap(void)
- *
- * Note: This is the anonymous pages version: This is a placeholder
- * Input: None
- * Output: None
- */ 
-void initBlockHeap(void)
-{
-  return;
-}
-
 /*
- * static inline void *get_block(size_t size)
- * 
- * Note: This is the /dev/zero version
- * Input: Size of block to allocate
- * Output: Pointer to new block
- * Side Effects: None
- */
-
-static inline void *get_block(size_t size)
+psuedo-struct BHElement
 {
-  return (mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0));
-}
+ dlink_node elementn;
+ char data[elsize];
+};
+*/
 
-#endif /* MAP_ANON */
-
-#else  /* HAVE_MMAP */
-/* Poor bastards don't even have mmap() */
-
-/* 
- * static inline void *get_block(size_t size)
- *
- * Note: This is the non-mmap() version
- * Input: Size of block
- * Output: Pointer to the memory
- */
-static inline void *get_block(size_t size)
+struct BHBlock
 {
-  return(malloc(size));
-}
-
-/*
- * static inline void free_block(void *ptr, size_t size)
- *
- * Inputs: The block and its size
- * Output: None
- * Side Effects: Returns memory for the block back to the malloc heap
+ dlink_node blockn;
+ int usedcount;
+ /*
+ pseudo-struct BHElement elements[elsperblock];
  */
+};
 
-static inline void free_block(void *ptr, size_t unused)
-{
-  free(ptr);
-}
+void BlockHeapAddBlock(BlockHeap *bh);
 
-/* 
- * void initBlockHeap(void)
- *
- * Note: This is the malloc() version: This is a placeholder
- * Input: None
- * Output: None
- */ 
-
-void initBlockHeap()
+/* Called once to setup the blockheap code... */
+void
+initBlockHeap(void)
 {
-  return;
+ /* The old block-heap did weird stuff with /dev/zero here which I think
+  * we could and probably should avoid, and just use MyMalloc to get
+  * blocks(it shouldn't happen too often anyway). -A1kmm */
 }
-#endif /* HAVE_MMAP */
-
-
 
-/* ************************************************************************ */
-/* FUNCTION DOCUMENTATION:                                                  */
-/*    newblock                                                              */
-/* Description:                                                             */
-/*    Allocates a new block for addition to a blockheap                     */
-/* Parameters:                                                              */
-/*    bh (IN): Pointer to parent blockheap.                                 */
-/* Returns:                                                                 */
-/*    0 if successful, 1 if not                                             */
-/* ************************************************************************ */
-
-static int newblock(BlockHeap * bh)
+/* Add a block to the blockheap... */
+void
+BlockHeapAddBlock(BlockHeap *bh)
 {
-    MemBlock *newblk;
-    Block *b;
-    int i;
-    void *offset;
-
-    /* Setup the initial data structure. */
-    b = (Block *) MyMalloc(sizeof(Block));
-    if (b == NULL)
-        return 1;
-    b->freeElems = bh->elemsPerBlock;
-    b->free_list.head = b->free_list.tail = NULL;
-    b->used_list.head = b->used_list.tail = NULL;
-    b->next = bh->base;
-
-    b->alloc_size = (bh->elemsPerBlock + 1) * (bh->elemSize + sizeof(MemBlock));
-
-    b->elems = get_block(b->alloc_size);
-    if (b->elems == NULL)
-      {
-        return 1;
-      }
-    offset = b->elems;
-    /* Setup our blocks now */
-    for (i = 0; i < bh->elemsPerBlock; i++)
-      {
-        void *data;
-        newblk = (void *)offset;
-        newblk->block = b;
-        data = (void *)((size_t)offset + sizeof(MemBlock));
-        newblk->block = b;
-        newblk->data = data;
-        dlinkAdd(data, &newblk->self, &b->free_list);
-        offset = (unsigned char *)((unsigned char *)offset + bh->elemSize + sizeof(MemBlock));
-      }
-
-    ++bh->blocksAllocated;
-    bh->freeElems += bh->elemsPerBlock;
-    bh->base = b;
-
-    return 0;
+ char *d;
+ int i;
+ struct BHBlock *bhb = MyMalloc(bh->blocksize);
+ dlinkAdd(bhb, &bhb->blockn, &bh->blocks);
+ d = ((char*)bhb) + sizeof(struct BHBlock);
+ bhb->usedcount = 0;
+ /* On the front is the best because of memory caches/swap/paging. */
+ for (i=0; i<bh->elsperblock; i++)
+ {
+  dlinkAdd(bhb,
+           (dlink_node*)d, &bh->f_elements);
+  d += sizeof(dlink_node) + bh->elsize;
+ }
 }
 
-
-/* ************************************************************************ */
-/* FUNCTION DOCUMENTATION:                                                  */
-/*    BlockHeapCreate                                                       */
-/* Description:                                                             */
-/*   Creates a new blockheap from which smaller blocks can be allocated.    */
-/*   Intended to be used instead of multiple calls to malloc() when         */
-/*   performance is an issue.                                               */
-/* Parameters:                                                              */
-/*   elemsize (IN):  Size of the basic element to be stored                 */
-/*   elemsperblock (IN):  Number of elements to be stored in a single block */
-/*         of memory.  When the blockheap runs out of free memory, it will  */
-/*         allocate elemsize * elemsperblock more.                          */
-/* Returns:                                                                 */
-/*   Pointer to new BlockHeap, or NULL if unsuccessful                      */
-/* ************************************************************************ */
-BlockHeap *BlockHeapCreate(size_t elemsize, int elemsperblock)
+/* Create a blockheap... */
+BlockHeap*
+BlockHeapCreate(int elsize, int elsperblock)
 {
-    BlockHeap *bh;
-    assert(elemsize > 0 && elemsperblock > 0);
-
-    /* Catch idiotic requests up front */
-    if ((elemsize <= 0) || (elemsperblock <= 0))
-      {
-        outofmemory();          /* die.. out of memory */
-      }
-
-    /* Allocate our new BlockHeap */
-    bh = (BlockHeap *) MyMalloc(sizeof(BlockHeap));
-    if (bh == NULL)
-      {
-        outofmemory();          /* die.. out of memory */
-      }
-
+ BlockHeap *bh = MyMalloc(sizeof(*bh));
 #ifdef MEMDEBUG
-    elemsize += sizeof(MemoryEntry);
+ /* Squeeze in the memory header too... -A1kmm */
+ elsize += sizeof(MemoryEntry);
 #endif
-
-    bh->elemSize = elemsize;
-    bh->elemsPerBlock = elemsperblock;
-    bh->blocksAllocated = 0;
-    bh->freeElems = 0;
-    bh->base = NULL;
-
-    /* Be sure our malloc was successful */
-    if (newblock(bh))
-      {
-        MyFree(bh);
-        outofmemory();          /* die.. out of memory */
-      }
-
-    if (bh == NULL)
-      {
-        outofmemory();          /* die.. out of memory */
-      }
-
-    return bh;
+ memset(bh, 0, 2*sizeof(dlink_list));
+ bh->elsize = elsize;
+ bh->elsperblock = elsperblock;
+ bh->blocksize = elsperblock * (elsize + sizeof(dlink_node)) +
+                 sizeof(struct BHBlock);
+ return bh;
 }
 
-/* ************************************************************************ */
-/* FUNCTION DOCUMENTATION:                                                  */
-/*    BlockHeapAlloc                                                        */
-/* Description:                                                             */
-/*    Returns a pointer to a struct within our BlockHeap that's free for    */
-/*    the taking.                                                           */
-/* Parameters:                                                              */
-/*    bh (IN):  Pointer to the Blockheap.                                   */
-/* Returns:                                                                 */
-/*    Pointer to a structure (void *), or NULL if unsuccessful.             */
-/* ************************************************************************ */
-
-void *_BlockHeapAlloc(BlockHeap * bh)
+/* Allocate an element from the free pool, making new blocks if needed.
+ */
+void*
+_BlockHeapAlloc(BlockHeap *bh)
 {
-    Block *walker;
-    dlink_node *new_node;
-
-    assert(bh != NULL);
-    if (bh == NULL)
-        return ((void *) NULL);
-
-    if (bh->freeElems == 0)
-      {   /* Allocate new block and assign */
-        /* newblock returns 1 if unsuccessful, 0 if not */
-
-        if (newblock(bh))
-         {
-            return ((void *) NULL);
-         }
-        walker = bh->base;
-        walker->freeElems--;
-        bh->freeElems--;
-        new_node = walker->free_list.head;
-        dlinkDelete(new_node, &walker->free_list);
-        dlinkAdd(new_node->data, new_node, &walker->used_list);
-        assert(new_node->data != NULL);
-        return (new_node->data);
-      }
-
-    for (walker = bh->base; walker != NULL; walker = walker->next)
-      {
-        if (walker->freeElems > 0)
-         {
-            bh->freeElems--;
-            walker->freeElems--;
-            new_node = walker->free_list.head;
-            dlinkDelete(new_node, &walker->free_list);
-            dlinkAdd(new_node->data, new_node, &walker->used_list);
-            assert(new_node->data != NULL);
-            return (new_node->data);
-         }
-      }
-    assert(0 == 1);
-    return ((void *) NULL);     /* If you get here, something bad happened ! */
+ char *d;
+ if (bh->f_elements.head == NULL)
+   BlockHeapAddBlock(bh);
+ d = (char*)(bh->f_elements.head + 1);
+ ((struct BHBlock*)bh->f_elements.head->data)->usedcount++;
+ bh->f_elements.head = bh->f_elements.head->next;
+ if (bh->f_elements.head == NULL)
+  bh->f_elements.tail = NULL;
+ else 
+  bh->f_elements.head->prev = NULL;
+ /* No need to "frob" when debugging here, it is done on initial
+  * MyMalloc and after each free. -A1kmm */
+ return d;
 }
 
-
-/* ************************************************************************ */
-/* FUNCTION DOCUMENTATION:                                                  */
-/*    BlockHeapFree                                                         */
-/* Description:                                                             */
-/*    Returns an element to the free pool, does not free()                  */
-/* Parameters:                                                              */
-/*    bh (IN): Pointer to BlockHeap containing element                      */
-/*    ptr (in):  Pointer to element to be "freed"                           */
-/* Returns:                                                                 */
-/*    0 if successful, 1 if element not contained within BlockHeap.         */
-/* ************************************************************************ */
-int _BlockHeapFree(BlockHeap * bh, void *ptr)
+/* Release an element back into the pool... */
+void
+_BlockHeapFree(BlockHeap *bh, void *el)
 {
-    Block *block;
-    struct MemBlock *memblock;
-    
-    assert(bh != NULL);
-    assert(ptr != NULL);
-
-    if (bh == NULL)
-      {
-
-        ilog(L_NOTICE, "balloc.c:BlockHeapFree() bh == NULL");
-        return 1;
-      }
-
-    if (ptr == NULL)
-      {
-        ilog(L_NOTICE, "balloc.BlockHeapFree() ptr == NULL");
-        return 1;
-      }
-
-    memblock = (void *)((size_t)ptr - sizeof(MemBlock));
-    assert(memblock->block != NULL);
-    /* XXX: Should check that the block is really our block */
-    block = memblock->block;
-    bh->freeElems++;
-    block->freeElems++;
-    dlinkDelete(&memblock->self, &block->used_list);
-    dlinkAdd(memblock->data, &memblock->self, &block->free_list);
-    return 0;
+ dlink_node *dln = (el-sizeof(dlink_node));
+#ifdef MEMDEBUG
+ mem_frob(el, bh->elsize);
+#endif
+ ((struct BHBlock*)dln->data)->usedcount--;
+ /* On the front is the best because of memory caches/swap/paging. 
+  * It also should make garbage collection work better... -A1kmm */
+ dlinkAdd(dln->data, dln, &bh->f_elements);
 }
 
-/* ************************************************************************ */
-/* FUNCTION DOCUMENTATION:                                                  */
-/*    BlockHeapGarbageCollect                                               */
-/* Description:                                                             */
-/*    Performs garbage collection on the block heap.  Any blocks that are   */
-/*    completely unallocated are removed from the heap.  Garbage collection */
-/*    will never remove the root node of the heap.                          */
-/* Parameters:                                                              */
-/*    bh (IN):  Pointer to the BlockHeap to be cleaned up                   */
-/* Returns:                                                                 */
-/*   0 if successful, 1 if bh == NULL                                       */
-/* ************************************************************************ */
-int BlockHeapGarbageCollect(BlockHeap * bh)
+/* Destroy a blockheap... */
+void
+BlockHeapDestroy(BlockHeap *bh)
 {
-    Block *walker, *last;
-
-    if (bh == NULL)
-        return 1;
-
-    if (bh->freeElems < bh->elemsPerBlock || bh->blocksAllocated == 1)
-      {
-        /* There couldn't possibly be an entire free block.  Return. */
-        return 0;
-      }
-
-    last = NULL;
-    walker = bh->base;
-
-    while (walker)
-      {
-        if (walker->freeElems == bh->elemsPerBlock)
-         {
-            free_block(walker->elems, walker->alloc_size);
-            if (last)
-             {
-                last->next = walker->next;
-                MyFree(walker);
-                walker = last->next;
-             }
-           else
-             {
-                bh->base = walker->next;
-                MyFree(walker);
-                walker = bh->base;
-             }
-            bh->blocksAllocated--;
-            bh->freeElems -= bh->elemsPerBlock;
-         }
-       else
-         {
-            last = walker;
-            walker = walker->next;
-         }
-      }
-    return 0;
+ struct BHBlock *bhb;
+ for (bhb = (struct BHBlock*)bh->blocks.head; bhb;
+      bhb = (struct BHBlock*)bhb->blockn.next)
+   MyFree(bhb);
 }
 
-/* ************************************************************************ */
-/* FUNCTION DOCUMENTATION:                                                  */
-/*    BlockHeapDestroy                                                      */
-/* Description:                                                             */
-/*    Completely free()s a BlockHeap.  Use for cleanup.                     */
-/* Parameters:                                                              */
-/*    bh (IN):  Pointer to the BlockHeap to be destroyed.                   */
-/* Returns:                                                                 */
-/*   0 if successful, 1 if bh == NULL                                       */
-/* ************************************************************************ */
-int BlockHeapDestroy(BlockHeap * bh)
+/* Destroy empty blocks. Note that this is slow because we put off all
+ * processing until this late to save speed in the frequently called
+ * routines.
+ * Okay, that is not really the case any more, so now the garbage
+ * collector doesn't take 10s...
+ **/
+void
+BlockHeapGarbageCollect(BlockHeap *bh)
 {
-    Block *walker, *next;
-
-    if (bh == NULL)
-        return 1;
-
-    for (walker = bh->base; walker != NULL; walker = next)
-      {
-        next = walker->next;
-        free_block(walker->elems, walker->alloc_size);
-        MyFree(walker);
-      }
-    MyFree(bh);
-    return 0;
+ struct BHBlock *bhb, *bhbn;
+ char *d;
+ int i;
+ for (bhb=(struct BHBlock*)bh->blocks.head; bhb; bhb=bhbn)
+ {
+   bhbn = (struct BHBlock*)bhb->blockn.next;
+   if (bhb->usedcount != 0)
+     continue;
+   d = (char*)(bhb+1);
+   for (i=0; i<bh->elsperblock; i++)
+   {
+    dlinkDelete((dlink_node*)d, &bh->f_elements);
+    d += sizeof(dlink_node) + bh->elsize;
+   }
+   dlinkDelete(&bhb->blockn, &bh->blocks);
+   MyFree(bhb);
+ }
 }
 #endif