2
2
* ircd-hybrid: an advanced, lightweight Internet Relay Chat Daemon (ircd)
4
4
* Copyright (c) 1997 Jukka Santala (Donwulff)
5
* Copyright (c) 2005-2014 ircd-hybrid development team
5
* Copyright (c) 2005-2015 ircd-hybrid development team
7
7
* This program is free software; you can redistribute it and/or modify
8
8
* it under the terms of the GNU General Public License as published by
79
79
* \param reply Numeric to send. Either RPL_LOGON or RPL_LOGOFF
82
watch_check_hash(struct Client *client_p, const enum irc_numerics reply)
82
watch_check_hash(const struct Client *client_p, const enum irc_numerics reply)
84
struct Watch *anptr = NULL;
85
dlink_node *ptr = NULL;
84
struct Watch *watch = NULL;
85
dlink_node *node = NULL;
87
87
assert(IsClient(client_p));
89
if ((anptr = watch_find_hash(client_p->name)) == NULL)
89
if ((watch = watch_find_hash(client_p->name)) == NULL)
90
90
return; /* This nick isn't on watch */
92
92
/* Update the time of last change to item */
93
anptr->lasttime = CurrentTime;
93
watch->lasttime = CurrentTime;
95
95
/* Send notifies out to everybody on the list in header */
96
DLINK_FOREACH(ptr, anptr->watched_by.head)
97
sendto_one_numeric(ptr->data, &me, reply, client_p->name,
96
DLINK_FOREACH(node, watch->watched_by.head)
97
sendto_one_numeric(node->data, &me, reply, client_p->name,
98
98
client_p->username, client_p->host,
99
anptr->lasttime, client_p->info);
99
watch->lasttime, client_p->info);
102
102
/*! \brief Looks up the watch table for a given nick
106
106
watch_find_hash(const char *name)
108
dlink_node *ptr = NULL;
108
dlink_node *node = NULL;
110
DLINK_FOREACH(ptr, watchTable[strhash(name)].head)
110
DLINK_FOREACH(node, watchTable[strhash(name)].head)
112
struct Watch *anptr = ptr->data;
112
struct Watch *watch = node->data;
114
if (!irccmp(anptr->nick, name))
114
if (!irccmp(watch->nick, name))
126
126
watch_add_to_hash_table(const char *nick, struct Client *client_p)
128
struct Watch *anptr = NULL;
129
dlink_node *ptr = NULL;
128
struct Watch *watch = NULL;
129
dlink_node *node = NULL;
131
131
/* If found NULL (no header for this nick), make one... */
132
if ((anptr = watch_find_hash(nick)) == NULL)
132
if ((watch = watch_find_hash(nick)) == NULL)
134
anptr = mp_pool_get(watch_pool);
136
anptr->lasttime = CurrentTime;
137
strlcpy(anptr->nick, nick, sizeof(anptr->nick));
139
dlinkAdd(anptr, &anptr->node, &watchTable[strhash(anptr->nick)]);
134
watch = mp_pool_get(watch_pool);
136
watch->lasttime = CurrentTime;
137
strlcpy(watch->nick, nick, sizeof(watch->nick));
139
dlinkAdd(watch, &watch->node, &watchTable[strhash(watch->nick)]);
143
143
/* Is this client already on the watch-list? */
144
ptr = dlinkFind(&anptr->watched_by, client_p);
144
node = dlinkFind(&watch->watched_by, client_p);
149
/* No it isn't, so add it in the bucket and client addint it */
150
dlinkAdd(client_p, make_dlink_node(), &anptr->watched_by);
151
dlinkAdd(anptr, make_dlink_node(), &client_p->localClient->watches);
149
/* No it isn't, so add it in the bucket and client adding it */
150
dlinkAdd(client_p, make_dlink_node(), &watch->watched_by);
151
dlinkAdd(watch, make_dlink_node(), &client_p->connection->watches);
160
160
watch_del_from_hash_table(const char *nick, struct Client *client_p)
162
struct Watch *anptr = NULL;
163
dlink_node *ptr = NULL;
162
struct Watch *watch = NULL;
163
dlink_node *node = NULL;
165
if ((anptr = watch_find_hash(nick)) == NULL)
165
if ((watch = watch_find_hash(nick)) == NULL)
166
166
return; /* No header found for that nick. i.e. it's not being watched */
168
if ((ptr = dlinkFind(&anptr->watched_by, client_p)) == NULL)
168
if ((node = dlinkFind(&watch->watched_by, client_p)) == NULL)
169
169
return; /* This nick isn't being watched by client_p */
171
dlinkDelete(ptr, &anptr->watched_by);
172
free_dlink_node(ptr);
171
dlinkDelete(node, &watch->watched_by);
172
free_dlink_node(node);
174
if ((ptr = dlinkFindDelete(&client_p->localClient->watches, anptr)))
175
free_dlink_node(ptr);
174
if ((node = dlinkFindDelete(&client_p->connection->watches, watch)))
175
free_dlink_node(node);
177
177
/* In case this header is now empty of notices, remove it */
178
if (anptr->watched_by.head == NULL)
178
if (watch->watched_by.head == NULL)
180
assert(dlinkFind(&watchTable[strhash(anptr->nick)], anptr));
181
dlinkDelete(&anptr->node, &watchTable[strhash(anptr->nick)]);
182
mp_pool_release(anptr);
180
assert(dlinkFind(&watchTable[strhash(watch->nick)], watch));
181
dlinkDelete(&watch->node, &watchTable[strhash(watch->nick)]);
182
mp_pool_release(watch);
191
191
watch_del_watch_list(struct Client *client_p)
193
dlink_node *ptr = NULL, *ptr_next = NULL;
194
dlink_node *tmp = NULL;
193
dlink_node *node = NULL, *node_next = NULL;
194
dlink_node *temp = NULL;
196
DLINK_FOREACH_SAFE(ptr, ptr_next, client_p->localClient->watches.head)
196
DLINK_FOREACH_SAFE(node, node_next, client_p->connection->watches.head)
198
struct Watch *anptr = ptr->data;
200
assert(dlinkFind(&anptr->watched_by, client_p));
202
if ((tmp = dlinkFindDelete(&anptr->watched_by, client_p)))
203
free_dlink_node(tmp);
198
struct Watch *watch = node->data;
200
assert(dlinkFind(&watch->watched_by, client_p));
202
if ((temp = dlinkFindDelete(&watch->watched_by, client_p)))
203
free_dlink_node(temp);
205
205
/* If this leaves a header without notifies, remove it. */
206
if (anptr->watched_by.head == NULL)
206
if (watch->watched_by.head == NULL)
208
assert(dlinkFind(&watchTable[strhash(anptr->nick)], anptr));
209
dlinkDelete(&anptr->node, &watchTable[strhash(anptr->nick)]);
208
assert(dlinkFind(&watchTable[strhash(watch->nick)], watch));
209
dlinkDelete(&watch->node, &watchTable[strhash(watch->nick)]);
211
mp_pool_release(anptr);
211
mp_pool_release(watch);
214
dlinkDelete(ptr, &client_p->localClient->watches);
215
free_dlink_node(ptr);
214
dlinkDelete(node, &client_p->connection->watches);
215
free_dlink_node(node);
218
assert(client_p->localClient->watches.head == NULL);
219
assert(client_p->localClient->watches.tail == NULL);
218
assert(client_p->connection->watches.head == NULL);
219
assert(client_p->connection->watches.tail == NULL);