]> jfr.im git - solanum.git/blame - ircd/monitor.c
extensions/helpops: implement DEHELPER command
[solanum.git] / ircd / monitor.c
CommitLineData
5f8fb56d
AW
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 *
32 * $Id: monitor.c 3520 2007-06-30 22:15:35Z jilles $
33 */
34#include "stdinc.h"
35#include "client.h"
36#include "monitor.h"
37#include "hash.h"
38#include "numeric.h"
39#include "send.h"
40
41static rb_dlink_list monitorTable[MONITOR_HASH_SIZE];
42static rb_bh *monitor_heap;
43
44void
45init_monitor(void)
46{
47 monitor_heap = rb_bh_create(sizeof(struct monitor), MONITOR_HEAP_SIZE, "monitor_heap");
48}
49
50static inline unsigned int
51hash_monitor_nick(const char *name)
52{
53 return fnv_hash_upper((const unsigned char *)name, MONITOR_HASH_BITS);
54}
55
56struct monitor *
57find_monitor(const char *name, int add)
58{
59 struct monitor *monptr;
60 rb_dlink_node *ptr;
61
62 unsigned int hashv = hash_monitor_nick(name);
63
64 RB_DLINK_FOREACH(ptr, monitorTable[hashv].head)
65 {
66 monptr = ptr->data;
67 if(!irccmp(monptr->name, name))
68 return monptr;
69 }
70
71 if(add)
72 {
73 monptr = rb_bh_alloc(monitor_heap);
74 rb_strlcpy(monptr->name, name, sizeof(monptr->name));
75 monptr->hashv = hashv;
76
77 rb_dlinkAdd(monptr, &monptr->node, &monitorTable[hashv]);
78 return monptr;
79 }
80
81 return NULL;
82}
83
84void
85free_monitor(struct monitor *monptr)
86{
87 if (rb_dlink_list_length(&monptr->users) > 0)
88 return;
89
90 rb_dlinkDelete(&monptr->node, &monitorTable[monptr->hashv]);
91 rb_bh_free(monitor_heap, monptr);
92}
93
94/* monitor_signon()
95 *
96 * inputs - client who has just connected
97 * outputs -
98 * side effects - notifies any clients monitoring this nickname that it has
99 * connected to the network
100 */
101void
102monitor_signon(struct Client *client_p)
103{
104 char buf[USERHOST_REPLYLEN];
105 struct monitor *monptr = find_monitor(client_p->name, 0);
106
107 /* noones watching this nick */
108 if(monptr == NULL)
109 return;
110
111 rb_snprintf(buf, sizeof(buf), "%s!%s@%s", client_p->name, client_p->username, client_p->host);
112
113 sendto_monitor(monptr, form_str(RPL_MONONLINE), me.name, "*", buf);
114}
115
116/* monitor_signoff()
117 *
118 * inputs - client who is exiting
119 * outputs -
120 * side effects - notifies any clients monitoring this nickname that it has
121 * left the network
122 */
123void
124monitor_signoff(struct Client *client_p)
125{
126 struct monitor *monptr = find_monitor(client_p->name, 0);
127
128 /* noones watching this nick */
129 if(monptr == NULL)
130 return;
131
132 sendto_monitor(monptr, form_str(RPL_MONOFFLINE), me.name, "*",
133 client_p->name);
134}
135
136void
137clear_monitor(struct Client *client_p)
138{
139 struct monitor *monptr;
140 rb_dlink_node *ptr, *next_ptr;
141
142 RB_DLINK_FOREACH_SAFE(ptr, next_ptr, client_p->localClient->monitor_list.head)
143 {
144 monptr = ptr->data;
145
146 rb_dlinkFindDestroy(client_p, &monptr->users);
147 rb_free_rb_dlink_node(ptr);
148
7a40c9a5 149 free_monitor(monptr);
5f8fb56d
AW
150 }
151
152 client_p->localClient->monitor_list.head = client_p->localClient->monitor_list.tail = NULL;
153 client_p->localClient->monitor_list.length = 0;
154}