Restore stats_spy hook that was removed in commit 401f2454671ca233e35b0e6e4f3fa4c43cd...
[seven-1.x.git] / src / monitor.c
blob83c73bab53d914c9907a8d9b42350ae70223f4d6
1 /*
2 * ircd-ratbox: an advanced Internet Relay Chat Daemon(ircd).
3 * monitor.c - Code for server-side notify lists
5 * Copyright (C) 2005 Lee Hardy <lee -at- leeh.co.uk>
6 * Copyright (C) 2005 ircd-ratbox development team
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions are
10 * met:
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.
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.
32 #include "stdinc.h"
33 #include "tools.h"
34 #include "client.h"
35 #include "memory.h"
36 #include "balloc.h"
37 #include "monitor.h"
38 #include "hash.h"
39 #include "event.h"
40 #include "numeric.h"
42 static struct monitor *monitorTable[MONITOR_HASH_SIZE];
43 BlockHeap *monitor_heap;
45 static void cleanup_monitor(void *unused);
47 void
48 init_monitor(void)
50 monitor_heap = BlockHeapCreate(sizeof(struct monitor), MONITOR_HEAP_SIZE);
51 eventAddIsh("cleanup_monitor", cleanup_monitor, NULL, 3600);
54 static inline unsigned int
55 hash_monitor_nick(const char *name)
57 return fnv_hash_upper((const unsigned char *) name, MONITOR_HASH_BITS);
60 struct monitor *
61 find_monitor(const char *name, int add)
63 struct monitor *monptr;
65 unsigned int hashv = hash_monitor_nick(name);
67 for(monptr = monitorTable[hashv]; monptr; monptr = monptr->hnext)
69 if(!irccmp(monptr->name, name))
70 return monptr;
73 if(add)
75 monptr = BlockHeapAlloc(monitor_heap);
76 strlcpy(monptr->name, name, sizeof(monptr->name));
78 monptr->hnext = monitorTable[hashv];
79 monitorTable[hashv] = monptr;
81 return monptr;
84 return NULL;
87 /* monitor_signon()
89 * inputs - client who has just connected
90 * outputs -
91 * side effects - notifies any clients monitoring this nickname that it has
92 * connected to the network
94 void
95 monitor_signon(struct Client *client_p)
97 char buf[USERHOST_REPLYLEN];
98 struct monitor *monptr = find_monitor(client_p->name, 0);
99 struct Client *target_p;
100 dlink_node *ptr;
102 /* noones watching this nick */
103 if(monptr == NULL)
104 return;
106 ircsnprintf(buf, sizeof(buf), "%s!%s@%s",
107 client_p->name, client_p->username, client_p->host);
109 DLINK_FOREACH(ptr, monptr->users.head)
111 target_p = ptr->data;
113 sendto_one(target_p, form_str(RPL_MONONLINE),
114 me.name, target_p->name, buf);
118 /* monitor_signoff()
120 * inputs - client who is exiting
121 * outputs -
122 * side effects - notifies any clients monitoring this nickname that it has
123 * left the network
125 void
126 monitor_signoff(struct Client *client_p)
128 struct monitor *monptr = find_monitor(client_p->name, 0);
129 dlink_node *ptr;
131 /* noones watching this nick */
132 if(monptr == NULL)
133 return;
135 DLINK_FOREACH(ptr, monptr->users.head)
137 sendto_one(ptr->data, form_str(RPL_MONOFFLINE),
138 me.name, ((struct Client *) ptr->data)->name, client_p->name);
142 void
143 clear_monitor(struct Client *client_p)
145 struct monitor *monptr;
146 dlink_node *ptr, *next_ptr;
148 DLINK_FOREACH_SAFE(ptr, next_ptr, client_p->localClient->monitor_list.head)
150 monptr = ptr->data;
152 /* we leave the actual entry around with no users, itll be
153 * cleaned up periodically by cleanup_monitor() --anfl
155 dlinkFindDestroy(client_p, &monptr->users);
156 free_dlink_node(ptr);
159 client_p->localClient->monitor_list.head = client_p->localClient->monitor_list.tail = NULL;
160 client_p->localClient->monitor_list.length = 0;
163 static void
164 cleanup_monitor(void *unused)
166 struct monitor *last_ptr = NULL;
167 struct monitor *next_ptr, *ptr;
168 int i;
170 for(i = 0; i < MONITOR_HASH_SIZE; i++)
172 last_ptr = NULL;
173 for(ptr = monitorTable[i]; ptr; ptr = next_ptr)
175 next_ptr = ptr->hnext;
177 if(!dlink_list_length(&ptr->users))
179 if(last_ptr)
180 last_ptr->hnext = next_ptr;
181 else
182 monitorTable[i] = next_ptr;
184 BlockHeapFree(monitor_heap, ptr);
186 else
187 last_ptr = ptr;