]> jfr.im git - irc/rqf/shadowircd.git/blame - src/monitor.c
Argh, wrong replace caused by MS VS 2005 interface.
[irc/rqf/shadowircd.git] / src / monitor.c
CommitLineData
212380e3 1/*
2 * ircd-ratbox: an advanced Internet Relay Chat Daemon(ircd).
3 * monitor.c - Code for server-side notify lists
4 *
5 * Copyright (C) 2005 Lee Hardy <lee -at- leeh.co.uk>
6 * Copyright (C) 2005 ircd-ratbox development team
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions are
10 * met:
11 *
12 * 1.Redistributions of source code must retain the above copyright notice,
13 * this list of conditions and the following disclaimer.
14 * 2.Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 * 3.The name of the author may not be used to endorse or promote products
18 * derived from this software without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
21 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
22 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
24 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
25 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
26 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
28 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
29 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30 * POSSIBILITY OF SUCH DAMAGE.
31 *
8aba962d 32 * $Id: monitor.c 3520 2007-06-30 22:15:35Z jilles $
212380e3 33 */
34#include "stdinc.h"
212380e3 35#include "client.h"
212380e3 36#include "monitor.h"
37#include "hash.h"
212380e3 38#include "numeric.h"
39
40static struct monitor *monitorTable[MONITOR_HASH_SIZE];
41BlockHeap *monitor_heap;
42
43static void cleanup_monitor(void *unused);
44
45void
46init_monitor(void)
47{
48 monitor_heap = BlockHeapCreate(sizeof(struct monitor), MONITOR_HEAP_SIZE);
49 eventAddIsh("cleanup_monitor", cleanup_monitor, NULL, 3600);
50}
51
52static inline unsigned int
53hash_monitor_nick(const char *name)
54{
55 return fnv_hash_upper((const unsigned char *) name, MONITOR_HASH_BITS);
56}
57
58struct monitor *
59find_monitor(const char *name, int add)
60{
61 struct monitor *monptr;
62
63 unsigned int hashv = hash_monitor_nick(name);
64
65 for(monptr = monitorTable[hashv]; monptr; monptr = monptr->hnext)
66 {
67 if(!irccmp(monptr->name, name))
68 return monptr;
69 }
70
71 if(add)
72 {
73 monptr = BlockHeapAlloc(monitor_heap);
74 strlcpy(monptr->name, name, sizeof(monptr->name));
75
76 monptr->hnext = monitorTable[hashv];
77 monitorTable[hashv] = monptr;
78
79 return monptr;
80 }
81
82 return NULL;
83}
84
85/* monitor_signon()
86 *
87 * inputs - client who has just connected
88 * outputs -
89 * side effects - notifies any clients monitoring this nickname that it has
90 * connected to the network
91 */
92void
93monitor_signon(struct Client *client_p)
94{
95 char buf[USERHOST_REPLYLEN];
96 struct monitor *monptr = find_monitor(client_p->name, 0);
212380e3 97
98 /* noones watching this nick */
99 if(monptr == NULL)
100 return;
101
38e6acdd 102 rb_snprintf(buf, sizeof(buf), "%s!%s@%s",
212380e3 103 client_p->name, client_p->username, client_p->host);
104
8aba962d 105 sendto_monitor(monptr, form_str(RPL_MONONLINE), me.name, "*", buf);
212380e3 106}
107
108/* monitor_signoff()
109 *
110 * inputs - client who is exiting
111 * outputs -
112 * side effects - notifies any clients monitoring this nickname that it has
113 * left the network
114 */
115void
116monitor_signoff(struct Client *client_p)
117{
118 struct monitor *monptr = find_monitor(client_p->name, 0);
212380e3 119
120 /* noones watching this nick */
121 if(monptr == NULL)
122 return;
123
8aba962d 124 sendto_monitor(monptr, form_str(RPL_MONOFFLINE), me.name, "*",
125 client_p->name);
212380e3 126}
127
128void
129clear_monitor(struct Client *client_p)
130{
131 struct monitor *monptr;
90a3c35b 132 rb_dlink_node *ptr, *next_ptr;
212380e3 133
90a3c35b 134 RB_DLINK_FOREACH_SAFE(ptr, next_ptr, client_p->localClient->monitor_list.head)
212380e3 135 {
136 monptr = ptr->data;
137
138 /* we leave the actual entry around with no users, itll be
139 * cleaned up periodically by cleanup_monitor() --anfl
140 */
af81d5a0
WP
141 rb_dlinkFindDestroy(client_p, &monptr->users);
142 free_rb_dlink_node(ptr);
212380e3 143 }
144
145 client_p->localClient->monitor_list.head = client_p->localClient->monitor_list.tail = NULL;
146 client_p->localClient->monitor_list.length = 0;
147}
148
149static void
150cleanup_monitor(void *unused)
151{
152 struct monitor *last_ptr = NULL;
90a3c35b 153 struct monitor *next_ptr, *ptr;
212380e3 154 int i;
155
156 for(i = 0; i < MONITOR_HASH_SIZE; i++)
157 {
158 last_ptr = NULL;
90a3c35b 159 for(ptr = monitorTable[i]; ptr; ptr = next_ptr)
212380e3 160 {
90a3c35b 161 next_ptr = ptr->hnext;
212380e3 162
af81d5a0 163 if(!rb_dlink_list_length(&ptr->users))
212380e3 164 {
165 if(last_ptr)
90a3c35b 166 last_ptr->hnext = next_ptr;
212380e3 167 else
90a3c35b 168 monitorTable[i] = next_ptr;
212380e3 169
170 BlockHeapFree(monitor_heap, ptr);
171 }
172 else
173 last_ptr = ptr;
174 }
175 }
176}