]> git.netwichtig.de Git - user/henk/code/inspircd.git/blob - include/users.h
429606344d6fe87d15e203568d0d5ba01598b3be
[user/henk/code/inspircd.git] / include / users.h
1 /*       +------------------------------------+
2  *       | Inspire Internet Relay Chat Daemon |
3  *       +------------------------------------+
4  *
5  *  InspIRCd is copyright (C) 2002-2006 ChatSpike-Dev.
6  *                       E-mail:
7  *                <brain@chatspike.net>
8  *                <Craig@chatspike.net>
9  *     
10  * Written by Craig Edwards, Craig McLure, and others.
11  * This program is free but copyrighted software; see
12  *            the file COPYING for details.
13  *
14  * ---------------------------------------------------
15  */
16
17 #ifndef __USERS_H__ 
18 #define __USERS_H__ 
19
20 #include <string>
21 #include "inspircd_config.h" 
22 #include "socket.h"
23 #include "channels.h"
24 #include "inspstring.h"
25 #include "connection.h"
26 #include "hashcomp.h"
27 #include "dns.h"
28 #include "cull_list.h"
29
30 enum ChanStatus {
31         STATUS_OP     = 4,
32         STATUS_HOP    = 2,
33         STATUS_VOICE  = 1,
34         STATUS_NORMAL = 0
35 };
36
37 enum ClassTypes {
38         CC_ALLOW = 0,
39         CC_DENY  = 1
40 };
41
42 /** RFC1459 channel modes
43  *  */
44 enum UserModes {
45         UM_SERVERNOTICE = 's'-65,
46         UM_WALLOPS = 'w'-65,
47         UM_INVISIBLE = 'i'-65,
48         UM_OPERATOR = 'o'-65,
49         UM_SNOMASK = 'n'-65,
50 };
51
52 enum RegistrationState {
53         REG_NONE = 0,           /* Has sent nothing */
54         REG_USER = 1,           /* Has sent USER */
55         REG_NICK = 2,           /* Has sent NICK */
56         REG_NICKUSER = 3,       /* Bitwise combination of REG_NICK and REG_USER */
57         REG_ALL = 7             /* REG_NICKUSER plus next bit along */
58 };
59
60 /** Holds a channel name to which a user has been invited.
61  */
62 class Invited : public classbase
63 {
64  public:
65          irc::string channel;
66 };
67
68 class InspIRCd;
69
70 /** Derived from Resolver, and performs user forward/reverse lookups.
71  */
72 class UserResolver : public Resolver
73 {
74  private:
75         /** User this class is 'attached' to.
76          */
77         userrec* bound_user;
78         int bound_fd;
79         bool fwd;
80  public:
81         UserResolver(InspIRCd* Instance, userrec* user, std::string to_resolve, QueryType qt);
82
83         void OnLookupComplete(const std::string &result);
84         void OnError(ResolverError e, const std::string &errormessage);
85 };
86
87
88 /** Holds information relevent to &lt;connect allow&gt; and &lt;connect deny&gt; tags in the config file.
89  */
90 class ConnectClass : public classbase
91 {
92  public:
93         /** Type of line, either CC_ALLOW or CC_DENY
94          */
95         char type;
96         /** Max time to register the connection in seconds
97          */
98         int registration_timeout;
99         /** Number of lines in buffer before excess flood is triggered
100          */
101         int flood;
102         /** Host mask for this line
103          */
104         std::string host;
105         /** Number of seconds between pings for this line
106          */
107         int pingtime;
108         /** (Optional) Password for this line
109          */
110         std::string pass;
111
112         /** Threshold value for flood disconnect
113          */
114         int threshold;
115
116         /** Maximum size of sendq for users in this class (bytes)
117          */
118         long sendqmax;
119
120         /** Maximum size of recvq for users in this class (bytes)
121          */
122         long recvqmax;
123
124         /** Local max when connecting by this connection class
125          */
126         long maxlocal;
127
128         /** Global max when connecting by this connection class
129          */
130         long maxglobal;
131         
132         ConnectClass() : registration_timeout(0), flood(0), host(""), pingtime(0), pass(""), threshold(0), sendqmax(0), recvqmax(0)
133         {
134         }
135 };
136
137 /** Holds a complete list of all channels to which a user has been invited and has not yet joined.
138  */
139 typedef std::vector<Invited> InvitedList;
140
141
142
143 /** Holds a complete list of all allow and deny tags from the configuration file (connection classes)
144  */
145 typedef std::vector<ConnectClass> ClassVector;
146
147 /** Typedef for the list of user-channel records for a user
148  */
149 typedef std::map<chanrec*, char> UserChanList;
150 typedef UserChanList::iterator UCListIter;
151
152 /** Holds all information about a user
153  * This class stores all information about a user connected to the irc server. Everything about a
154  * connection is stored here primarily, from the user's socket ID (file descriptor) through to the
155  * user's nickname and hostname. Use the FindNick method of the InspIRCd class to locate a specific user
156  * by nickname, or the FindDescriptor method of the InspIRCd class to find a specific user by their
157  * file descriptor value.
158  */
159 class userrec : public connection
160 {
161  private:
162         /** Pointer to creator.
163          * This is required to make use of core functions
164          * from within the userrec class.
165          */
166         InspIRCd* ServerInstance;
167
168         /** A list of channels the user has a pending invite to.
169          * Upon INVITE channels are added, and upon JOIN, the
170          * channels are removed from this list.
171          */
172         InvitedList invites;
173
174         /** Number of channels this user is currently on
175          */
176         unsigned int ChannelCount;
177  public:
178         /** Resolvers for looking up this users IP address
179          * This will occur if and when res_reverse completes.
180          * When this class completes its lookup, userrec::dns_done
181          * will be set from false to true.
182          */
183         UserResolver* res_forward;
184
185         /** Resolvers for looking up this users hostname
186          * This is instantiated by userrec::StartDNSLookup(),
187          * and on success, instantiates userrec::res_reverse.
188          */
189         UserResolver* res_reverse;
190
191         /** Stored reverse lookup from res_forward
192          */
193         std::string stored_host;
194
195         /** Starts a DNS lookup of the user's IP.
196          * This will cause two UserResolver classes to be instantiated.
197          * When complete, these objects set userrec::dns_done to true.
198          */
199         void StartDNSLookup();
200         
201         /** The users nickname.
202          * An invalid nickname indicates an unregistered connection prior to the NICK command.
203          * Use InspIRCd::IsNick() to validate nicknames.
204          */
205         char nick[NICKMAX];
206         
207         /** The users ident reply.
208          * Two characters are added to the user-defined limit to compensate for the tilde etc.
209          */
210         char ident[IDENTMAX+2];
211
212         /** The host displayed to non-opers (used for cloaking etc).
213          * This usually matches the value of userrec::host.
214          */
215         char dhost[65];
216         
217         /** The users full name (GECOS).
218          */
219         char fullname[MAXGECOS+1];
220         
221         /** The user's mode list.
222          * This is NOT a null terminated string! In the 1.1 version of InspIRCd
223          * this is an array of values in a similar way to channel modes.
224          * A value of 1 in field (modeletter-65) indicates that the mode is
225          * set, for example, to work out if mode +s is set, we  check the field
226          * userrec::modes['s'-65] != 0.
227          * The following RFC characters o, w, s, i have constants defined via an
228          * enum, such as UM_SERVERNOTICE and UM_OPETATOR.
229          */
230         char modes[64];
231
232         /** What snomasks are set on this user.
233          * This functions the same as the above modes.
234          */
235         char snomasks[64];
236
237         /** Channels this user is on, and the permissions they have there
238          */
239         UserChanList chans;
240         
241         /** The server the user is connected to.
242          */
243         const char* server;
244         
245         /** The user's away message.
246          * If this string is empty, the user is not marked as away.
247          */
248         char awaymsg[MAXAWAY+1];
249         
250         /** Number of lines the user can place into the buffer
251          * (up to the global NetBufferSize bytes) before they
252          * are disconnected for excess flood
253          */
254         int flood;
255         
256         /** Number of seconds this user is given to send USER/NICK
257          * If they do not send their details in this time limit they
258          * will be disconnected
259          */
260         unsigned int timeout;
261         
262         /** The oper type they logged in as, if they are an oper.
263          * This is used to check permissions in operclasses, so that
264          * we can say 'yay' or 'nay' to any commands they issue.
265          * The value of this is the value of a valid 'type name=' tag.
266          */
267         char oper[NICKMAX];
268
269         /** True when DNS lookups are completed.
270          * The UserResolver classes res_forward and res_reverse will
271          * set this value once they complete.
272          */
273         bool dns_done;
274
275         /** Number of seconds between PINGs for this user (set from &lt;connect:allow&gt; tag
276          */
277         unsigned int pingmax;
278
279         /** Password specified by the user when they registered.
280          * This is stored even if the <connect> block doesnt need a password, so that
281          * modules may check it.
282          */
283         char password[64];
284
285         /** User's receive queue.
286          * Lines from the IRCd awaiting processing are stored here.
287          * Upgraded april 2005, old system a bit hairy.
288          */
289         std::string recvq;
290
291         /** User's send queue.
292          * Lines waiting to be sent are stored here until their buffer is flushed.
293          */
294         std::string sendq;
295
296         /** Flood counters - lines received
297          */
298         int lines_in;
299
300         /** Flood counters - time lines_in is due to be reset
301          */
302         time_t reset_due;
303
304         /** Flood counters - Highest value lines_in may reach before the user gets disconnected
305          */
306         long threshold;
307
308         /** IPV4 or IPV6 ip address
309          */
310         sockaddr* ip;
311
312         /** Initialize the clients sockaddr
313          * @param protocol_family The protocol family of the IP address, AF_INET or AF_INET6
314          * @param ip A human-readable IP address for this user matching the protcol_family
315          * @param port The port number of this user or zero for a remote user
316          */
317         void SetSockAddr(int protocol_family, const char* ip, int port);
318
319         /** Get port number from sockaddr
320          * @return The port number of this user.
321          */
322         int GetPort();
323
324         /** Get protocol family from sockaddr
325          * @return The protocol family of this user, either AF_INET or AF_INET6
326          */
327         int GetProtocolFamily();
328
329         /** Get IP string from sockaddr, using static internal buffer
330          * @return The IP string
331          */
332         const char* GetIPString();
333
334         /** Get IP string from sockaddr, using caller-specified buffer
335          * @param buf A buffer to use
336          * @return The IP string
337          */
338         const char* GetIPString(char* buf);
339
340         /* Write error string
341          */
342         std::string WriteError;
343
344         /** Maximum size this user's sendq can become
345          */
346         long sendqmax;
347
348         /** Maximum size this user's recvq can become
349          */
350         long recvqmax;
351
352         /** This is true if the user matched an exception when they connected to the ircd.
353          * It isnt valid after this point, and you should not attempt to do anything with it
354          * after this point, because the eline might be removed at a later time, and/or no
355          * longer be applicable to this user. It is only used to save doing the eline lookup
356          * twice (instead we do it once and set this value).
357          */
358         bool exempt;
359
360         /** Default constructor
361          * @throw Nothing at present
362          */
363         userrec(InspIRCd* Instance);
364         
365         /** Returns the full displayed host of the user
366          * This member function returns the hostname of the user as seen by other users
367          * on the server, in nick!ident&at;host form.
368          * @return The full masked host of the user
369          */
370         virtual char* GetFullHost();
371         
372         /** Returns the full real host of the user
373          * This member function returns the hostname of the user as seen by other users
374          * on the server, in nick!ident&at;host form. If any form of hostname cloaking is in operation,
375          * e.g. through a module, then this method will ignore it and return the true hostname.
376          * @return The full real host of the user
377          */
378         virtual char* GetFullRealHost();
379
380         /** Create a displayable mode string for this users snomasks
381          * @return The notice mask character sequence
382          */
383         const char* FormatNoticeMasks();
384
385         /** Process a snomask modifier string, e.g. +abc-de
386          * @param sm A sequence of notice mask characters
387          * @return The cleaned mode sequence which can be output,
388          * e.g. in the above example if masks c and e are not
389          * valid, this function will return +ab-d
390          */
391         std::string ProcessNoticeMasks(const char *sm);
392
393         /** Returns true if a notice mask is set
394          * @param sm A notice mask character to check
395          * @return True if the notice mask is set
396          */
397         bool IsNoticeMaskSet(unsigned char sm);
398
399         /** Changed a specific notice mask value
400          * @param sm The server notice mask to change
401          * @param value An on/off value for this mask
402          */
403         void SetNoticeMask(unsigned char sm, bool value);
404
405         /** Create a displayable mode string for this users umodes
406          * @param The mode string
407          */
408         const char* FormatModes();
409
410         /** Returns true if a specific mode is set
411          * @param m The user mode
412          * @return True if the mode is set
413          */
414         bool IsModeSet(unsigned char m);
415
416         /** Set a specific usermode to on or off
417          * @param m The user mode
418          * @param value On or off setting of the mode
419          */
420         void SetMode(unsigned char m, bool value);
421         
422         /** Returns true if a user is invited to a channel.
423          * @param channel A channel name to look up
424          * @return True if the user is invited to the given channel
425          */
426         virtual bool IsInvited(irc::string &channel);
427         
428         /** Adds a channel to a users invite list (invites them to a channel)
429          * @param channel A channel name to add
430          */
431         virtual void InviteTo(irc::string &channel);
432         
433         /** Removes a channel from a users invite list.
434          * This member function is called on successfully joining an invite only channel
435          * to which the user has previously been invited, to clear the invitation.
436          * @param channel The channel to remove the invite to
437          */
438         virtual void RemoveInvite(irc::string &channel);
439         
440         /** Returns true or false for if a user can execute a privilaged oper command.
441          * This is done by looking up their oper type from userrec::oper, then referencing
442          * this to their oper classes and checking the commands they can execute.
443          * @param command A command (should be all CAPS)
444          * @return True if this user can execute the command
445          */
446         bool HasPermission(const std::string &command);
447
448         /** Calls read() to read some data for this user using their fd.
449          * @param buffer The buffer to read into
450          * @param size The size of data to read
451          * @return The number of bytes read, or -1 if an error occured.
452          */
453         int ReadData(void* buffer, size_t size);
454
455         /** This method adds data to the read buffer of the user.
456          * The buffer can grow to any size within limits of the available memory,
457          * managed by the size of a std::string, however if any individual line in
458          * the buffer grows over 600 bytes in length (which is 88 chars over the
459          * RFC-specified limit per line) then the method will return false and the
460          * text will not be inserted.
461          * @param a The string to add to the users read buffer
462          * @return True if the string was successfully added to the read buffer
463          */
464         bool AddBuffer(std::string a);
465
466         /** This method returns true if the buffer contains at least one carriage return
467          * character (e.g. one complete line may be read)
468          * @return True if there is at least one complete line in the users buffer
469          */
470         bool BufferIsReady();
471
472         /** This function clears the entire buffer by setting it to an empty string.
473          */
474         void ClearBuffer();
475
476         /** This method returns the first available string at the tail end of the buffer
477          * and advances the tail end of the buffer past the string. This means it is
478          * a one way operation in a similar way to strtok(), and multiple calls return
479          * multiple lines if they are available. The results of this function if there
480          * are no lines to be read are unknown, always use BufferIsReady() to check if
481          * it is ok to read the buffer before calling GetBuffer().
482          * @return The string at the tail end of this users buffer
483          */
484         std::string GetBuffer();
485
486         /** Sets the write error for a connection. This is done because the actual disconnect
487          * of a client may occur at an inopportune time such as half way through /LIST output.
488          * The WriteErrors of clients are checked at a more ideal time (in the mainloop) and
489          * errored clients purged.
490          * @param error The error string to set.
491          */
492         void SetWriteError(const std::string &error);
493
494         /** Returns the write error which last occured on this connection or an empty string
495          * if none occured.
496          * @return The error string which has occured for this user
497          */
498         const char* GetWriteError();
499
500         /** Adds to the user's write buffer.
501          * You may add any amount of text up to this users sendq value, if you exceed the
502          * sendq value, SetWriteError() will be called to set the users error string to
503          * "SendQ exceeded", and further buffer adds will be dropped.
504          * @param data The data to add to the write buffer
505          */
506         void AddWriteBuf(const std::string &data);
507
508         /** Flushes as much of the user's buffer to the file descriptor as possible.
509          * This function may not always flush the entire buffer, rather instead as much of it
510          * as it possibly can. If the send() call fails to send the entire buffer, the buffer
511          * position is advanced forwards and the rest of the data sent at the next call to
512          * this method.
513          */
514         void FlushWriteBuf();
515
516         /** Returns the list of channels this user has been invited to but has not yet joined.
517          * @return A list of channels the user is invited to
518          */
519         InvitedList* GetInviteList();
520
521         /** Creates a wildcard host.
522          * Takes a buffer to use and fills the given buffer with the host in the format *!*@hostname
523          * @return The wildcarded hostname in *!*@host form
524          */
525         char* MakeWildHost();
526
527         /** Creates a usermask with real host.
528          * Takes a buffer to use and fills the given buffer with the hostmask in the format user@host
529          * @return the usermask in the format user@host
530          */
531         char* MakeHost();
532
533         /** Creates a usermask with real ip.
534          * Takes a buffer to use and fills the given buffer with the ipmask in the format user@ip
535          * @return the usermask in the format user@ip
536          */
537         char* MakeHostIP();
538
539         /** Shuts down and closes the user's socket
540          * This will not cause the user to be deleted. Use InspIRCd::QuitUser for this,
541          * which will call CloseSocket() for you.
542          */
543         void CloseSocket();
544
545         /** Disconnect a user gracefully
546          * @param user The user to remove
547          * @param r The quit reason
548          * @return Although this function has no return type, on exit the user provided will no longer exist.
549          */
550         static void QuitUser(InspIRCd* Instance, userrec *user, const std::string &r);
551
552         /** Add the user to WHOWAS system
553          */
554         void AddToWhoWas();
555
556         /** Oper up the user using the given opertype.
557          * This will also give the +o usermode.
558          * @param opertype The oper type to oper as
559          */
560         void Oper(const std::string &opertype);
561
562         /** Use this method to fully connect a user.
563          * This will send the message of the day, check G/K/E lines, etc.
564          * @param Goners If the user is disconnected by this method call, the
565          * value of 'this' will be pushed onto this CullList. This is used by
566          * the core to connect many users in rapid succession without invalidating
567          * iterators.
568          * @param Goners a CullList to use for failed connections
569          */
570         void FullConnect(CullList* Goners);
571
572         /** Change this users hash key to a new string.
573          * You should not call this function directly. It is used by the core
574          * to update the users hash entry on a nickchange.
575          * @param New new user_hash key
576          * @return Pointer to userrec in hash (usually 'this')
577          */
578         userrec* UpdateNickHash(const char* New);
579
580         /** Force a nickname change.
581          * If the nickname change fails (for example, because the nick in question
582          * already exists) this function will return false, and you must then either
583          * output an error message, or quit the user for nickname collision.
584          * @param newnick The nickname to change to
585          * @return True if the nickchange was successful.
586          */
587         bool ForceNickChange(const char* newnick);
588
589         /** Add a client to the system.
590          * This will create a new userrec, insert it into the user_hash,
591          * initialize it as not yet registered, and add it to the socket engine.
592          * @param Instance a pointer to the server instance
593          * @param socket The socket id (file descriptor) this user is on
594          * @param port The port number this user connected on
595          * @param iscached This variable is reserved for future use
596          * @param ip The IP address of the user
597          * @return This function has no return value, but a call to AddClient may remove the user.
598          */
599         static void AddClient(InspIRCd* Instance, int socket, int port, bool iscached, insp_inaddr ip);
600
601         /** Oper down.
602          * This will clear the +o usermode and unset the user's oper type
603          */
604         void UnOper();
605
606         /** Return the number of global clones of this user
607          * @return The global clone count of this user
608          */
609         long GlobalCloneCount();
610
611         /** Return the number of local clones of this user
612          * @return The local clone count of this user
613          */
614         long LocalCloneCount();
615
616         /** Write text to this user, appending CR/LF.
617          * @param text A std::string to send to the user
618          */
619         void Write(std::string text);
620
621         /** Write text to this user, appending CR/LF.
622          * @param text The format string for text to send to the user
623          * @param ... POD-type format arguments
624          */
625         void Write(const char *text, ...);
626
627         /** Write text to this user, appending CR/LF and prepending :server.name
628          * @param text A std::string to send to the user
629          */
630         void WriteServ(const std::string& text);
631
632         /** Write text to this user, appending CR/LF and prepending :server.name
633          * @param text The format string for text to send to the user
634          * @param ... POD-type format arguments
635          */
636         void WriteServ(const char* text, ...);
637
638         /** Write text to this user, appending CR/LF and prepending :nick!user@host of the user provided in the first parameter.
639          * @param user The user to prepend the :nick!user@host of
640          * @param text A std::string to send to the user
641          */
642         void WriteFrom(userrec *user, const std::string &text);
643
644         /** Write text to this user, appending CR/LF and prepending :nick!user@host of the user provided in the first parameter.
645          * @param user The user to prepend the :nick!user@host of
646          * @param text The format string for text to send to the user
647          * @param ... POD-type format arguments
648          */
649         void WriteFrom(userrec *user, const char* text, ...);
650
651         /** Write text to the user provided in the first parameter, appending CR/LF, and prepending THIS user's :nick!user@host.
652          * @param dest The user to route the message to
653          * @param text A std::string to send to the user
654          */
655         void WriteTo(userrec *dest, const std::string &data);
656
657         /** Write text to the user provided in the first parameter, appending CR/LF, and prepending THIS user's :nick!user@host.
658          * @param dest The user to route the message to
659          * @param text The format string for text to send to the user
660          * @param ... POD-type format arguments
661          */
662         void WriteTo(userrec *dest, const char *data, ...);
663
664         /** Write to all users that can see this user (including this user in the list), appending CR/LF
665          * @param text A std::string to send to the users
666          */
667         void WriteCommon(const std::string &text);
668
669         /** Write to all users that can see this user (including this user in the list), appending CR/LF
670          * @param text The format string for text to send to the users
671          * @param ... POD-type format arguments
672          */
673         void WriteCommon(const char* text, ...);
674
675         /** Write to all users that can see this user (not including this user in the list), appending CR/LF
676          * @param text The format string for text to send to the users
677          * @param ... POD-type format arguments
678          */
679         void WriteCommonExcept(const char* text, ...);
680
681         /** Write to all users that can see this user (not including this user in the list), appending CR/LF
682          * @param text A std::string to send to the users
683          */
684         void WriteCommonExcept(const std::string &text);
685
686         /** Write a WALLOPS message from this user to all local opers.
687          * If this user is not opered, the function will return without doing anything.
688          * @param text The format string to send in the WALLOPS message
689          * @param ... Format arguments
690          */
691         void WriteWallOps(const char* text, ...);
692
693         /** Write a WALLOPS message from this user to all local opers.
694          * If this user is not opered, the function will return without doing anything.
695          * @param text The text to send in the WALLOPS message
696          */
697         void WriteWallOps(const std::string &text);
698
699         /** Return true if the user shares at least one channel with another user
700          * @param other The other user to compare the channel list against
701          * @return True if the given user shares at least one channel with this user
702          */
703         bool SharesChannelWith(userrec *other);
704
705         /** Change the displayed host of a user.
706          * ALWAYS use this function, rather than writing userrec::dhost directly,
707          * as this triggers module events allowing the change to be syncronized to
708          * remote servers. This will also emulate a QUIT and rejoin (where configured)
709          * before setting their host field.
710          * @param host The new hostname to set
711          * @return True if the change succeeded, false if it didn't
712          */
713         bool ChangeDisplayedHost(const char* host);
714
715         /** Change the ident (username) of a user.
716          * ALWAYS use this function, rather than writing userrec::ident directly,
717          * as this correctly causes the user to seem to quit (where configured)
718          * before setting their ident field.
719          * @param host The new ident to set
720          * @return True if the change succeeded, false if it didn't
721          */
722         bool ChangeIdent(const char* newident);
723
724         /** Change a users realname field.
725          * ALWAYS use this function, rather than writing userrec::fullname directly,
726          * as this triggers module events allowing the change to be syncronized to
727          * remote servers.
728          * @param gecos The user's new realname
729          * @return True if the change succeeded, false if otherwise
730          */
731         bool ChangeName(const char* gecos);
732
733         /** Return the total number of channels this user is on.
734          * @return The number of channels the user is on
735          */
736         int CountChannels();
737
738         /** Modify the number of channels this user is on (used by CountChannels).
739          * Pass a positive number to increment the counter, or a negative number
740          * to decrement it.
741          */
742         void ModChannelCount(int n);
743
744         /** Send a notice to all local users from this user
745          * @param text The text format string to send
746          * @param ... Format arguments
747          */
748         void NoticeAll(char* text, ...);
749
750         /** Compile a channel list for this user, and send it to the user 'source'
751          * Used internally by WHOIS
752          * @param The user to send the channel list to if it is not too long
753          * @return This user's channel list
754          */
755         std::string ChannelList(userrec* source);
756
757         /** Split the channel list in cl which came from dest, and spool it to this user
758          * Used internally by WHOIS
759          * @param dest The user the original channel list came from
760          * @param cl The  channel list as a string obtained from userrec::ChannelList()
761          */
762         void SplitChanList(userrec* dest, const std::string &cl);
763
764         /** Remove this user from all channels they are on, and delete any that are now empty.
765          * This is used by QUIT, and will not send part messages!
766          */
767         void PurgeEmptyChannels();
768
769         /** Get the connect class which matches this user's host or IP address
770          * @return A reference to this user's connect class
771          */
772         ConnectClass& GetClass();
773
774         /** Show the message of the day to this user
775          */
776         void ShowMOTD();
777
778         /** Show the server RULES file to this user
779          */
780         void ShowRULES();
781
782         /** Handle socket event.
783          * From EventHandler class.
784          */
785         void HandleEvent(EventType et, int errornum = 0);
786
787         /** Default destructor
788          */
789         virtual ~userrec();
790 };
791
792
793 namespace irc
794 {
795         /** Holds whowas related functions and classes
796          */
797         namespace whowas
798         {
799
800                 /** Used to hold WHOWAS information
801                  */
802                 class WhoWasGroup : public classbase
803                 {
804                  public:
805                         /** Real host
806                          */
807                         char* host;
808                         /** Displayed host
809                          */
810                         char* dhost;
811                         /** Ident
812                          */
813                         char* ident;
814                         /** Server name
815                          */
816                         const char* server;
817                         /** Fullname (GECOS)
818                          */
819                         char* gecos;
820                         /** Signon time
821                          */
822                         time_t signon;
823         
824                         /** Initialize this WhoQasFroup with a user
825                          */
826                         WhoWasGroup(userrec* user);
827                         /** Destructor
828                          */
829                         ~WhoWasGroup();
830                 };
831
832                 /** A group of users related by nickname
833                  */
834                 typedef std::deque<WhoWasGroup*> whowas_set;
835
836                 /** Sets of users in the whowas system
837                  */
838                 typedef std::map<irc::string,whowas_set*> whowas_users;
839
840                 /** Sets of time and users in whowas list
841                  */
842                 typedef std::map<time_t,irc::string> whowas_users_fifo;
843
844                 /** Called every hour by the core to remove expired entries
845                  */
846                 void MaintainWhoWas(InspIRCd* ServerInstance, time_t TIME);
847
848                 /** Prune for WhoWasGroupSize, WhoWasMaxGroups and
849                  *  WhoWasMaxKeep on rehash
850                  */
851                 void PruneWhoWas(InspIRCd* ServerInstance, time_t TIME);
852         };
853 };
854
855 /* Configuration callbacks */
856 class ServerConfig;
857
858 #endif