2
ctrlproxy: A modular IRC proxy
3
strip: Module that removes replies to commands from other
5
(c) 2002-2003 Jelmer Vernooij <jelmer@nl.linux.org>
7
This program is free software; you can redistribute it and/or modify
8
it under the terms of the GNU General Public License as published by
9
the Free Software Foundation; either version 2 of the License, or
10
(at your option) any later version.
12
This program is distributed in the hope that it will be useful,
13
but WITHOUT ANY WARRANTY; without even the implied warranty of
14
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
GNU General Public License for more details.
17
You should have received a copy of the GNU General Public License
18
along with this program; if not, write to the Free Software
19
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23
#include "ctrlproxy.h"
29
struct network *network;
30
struct client *client;
31
struct query_stack *next;
34
struct query_stack *stack = NULL;
40
/* Should add this query to the stack. return TRUE if this has
41
* been done successfully, FALSE otherwise */
42
int (*handle) (struct line *, struct query *);
45
int handle_default(struct line *, struct query *);
46
int handle_topic(struct line *, struct query *);
48
struct query queries[] = {
49
/* Commands that get a one-client reply:
50
* WHOIS [<server>] <nickmask>[,<nickmask>[,...]] */
52
{ ERR_NOSUCHSERVER, RPL_WHOISUSER, RPL_WHOISCHANNELS, RPL_AWAY,
53
RPL_WHOISIDLE, RPL_ENDOFWHOIS, ERR_NONICKNAMEGIVEN, RPL_WHOISCHANNELS,
54
RPL_WHOISSERVER, RPL_WHOISOPERATOR, ERR_NOSUCHNICK, 0 },
55
{ ERR_NOSUCHSERVER, ERR_NONICKNAMEGIVEN, ERR_NOSUCHNICK,
60
/* WHO [<name> [<o>]] */
62
{ ERR_NOSUCHSERVER, RPL_WHOREPLY, RPL_ENDOFWHO, 0 },
63
{ ERR_NOSUCHSERVER, RPL_ENDOFWHO, 0 },
67
/* NAMES [<channel>{,<channel>}]*/
69
{ RPL_NAMREPLY, RPL_ENDOFNAMES, 0 },
70
{ RPL_ENDOFNAMES, 0 },
74
/* LIST [<channel>{,<channel>} [<server>]*/
76
{ ERR_NOSUCHSERVER, RPL_LIST, RPL_LISTSTART, RPL_LISTEND, 0 },
77
{ ERR_NOSUCHSERVER, RPL_LISTEND, 0 },
81
/* TOPIC <channel> [<topic>]*/
83
{ ERR_NEEDMOREPARAMS, RPL_NOTOPIC, ERR_NOTONCHANNEL, RPL_TOPIC,
84
ERR_CHANOPRIVSNEEDED, 0 },
85
{ ERR_NEEDMOREPARAMS, RPL_NOTOPIC, ERR_NOTONCHANNEL, RPL_TOPIC,
86
ERR_CHANOPRIVSNEEDED, 0 },
90
/* WHOWAS <nickname> [<count> [<server>]]*/
92
{ ERR_NONICKNAMEGIVEN, ERR_WASNOSUCHNICK, RPL_WHOWASUSER,
93
RPL_WHOISSERVER, RPL_ENDOFWHOWAS, 0 },
94
{ ERR_NONICKNAMEGIVEN, ERR_WASNOSUCHNICK, RPL_ENDOFWHOWAS,
99
/* STATS [<query> [<server>]]*/
101
{ ERR_NOSUCHSERVER, RPL_STATSCLINE, RPL_STATSILINE, RPL_STATSQLINE,
102
RPL_STATSLINKINFO, RPL_STATSCOMMANDS, RPL_STATSHLINE, RPL_STATSNLINE,
103
RPL_STATSKLINE, RPL_STATSLLINE, RPL_STATSUPTIME, RPL_STATSOLINE,
105
{ ERR_NOSUCHSERVER, RPL_ENDOFSTATS, 0 },
109
/* VERSION [<server>]*/
111
{ ERR_NOSUCHSERVER, RPL_VERSION, 0 },
112
{ ERR_NOSUCHSERVER, RPL_VERSION, 0 },
116
/* LINKS [[<remote server>] <server mask>]*/
118
{ ERR_NOSUCHSERVER, RPL_LINKS, RPL_ENDOFLINKS, 0 },
119
{ ERR_NOSUCHSERVER, RPL_ENDOFLINKS, 0 },
125
{ ERR_NOSUCHSERVER, RPL_TIME, 0 },
126
{ ERR_NOSUCHSERVER, RPL_TIME, 0 },
130
/* TRACE [<server>]*/
132
/* This one is ifdef'ed out because there is no response that
133
* can be used as a 'end-of-response' indicator. */
135
{ ERR_NOSUCHSERVER, RPL_TRACELINK, RPL_TRACECONNECTING,
136
RPL_TRACEUNKNOWN, RPL_TRACEUSER, RPL_TRACECLASS,
137
RPL_TRACEHANDSHAKE, RPL_TRACEOPERATOR,
138
RPL_TRACESERVER, RPL_TRACENEWTYPE, 0 },
139
{ ERR_NOSUCHSERVER, 0 },
144
/* SUMMON <user> [<server>]*/
146
{ ERR_NORECIPIENT, ERR_FILEERROR, ERR_NOLOGIN, ERR_NOSUCHSERVER,
148
{ ERR_NORECIPIENT, ERR_FILEERROR, ERR_NOLOGIN, ERR_NOSUCHSERVER,
153
/* USERS [<server>]*/
155
{ ERR_NOSUCHSERVER, ERR_FILEERROR, RPL_USERSSTART, RPL_USERS,
156
RPL_NOUSERS, RPL_ENDOFUSERS, ERR_USERSDISABLED, 0 },
157
{ ERR_NOSUCHSERVER, ERR_FILEERROR, ERR_USERSDISABLED, RPL_ENDOFUSERS, 0 },
161
/* USERHOST <nickname>{ <nickname>}{ ...}*/
163
{ RPL_USERHOST, ERR_NEEDMOREPARAMS, 0 },
164
{ RPL_USERHOST, ERR_NEEDMOREPARAMS, 0 },
168
/* ISON <nickname>{ <nickname>}{ ...} */
170
{ RPL_ISON, ERR_NEEDMOREPARAMS, 0 },
171
{ RPL_ISON, ERR_NEEDMOREPARAMS, 0 },
178
int is_reply(int *replies, int r)
181
for(i = 0; i < 20 && replies[i]; i++) {
182
if(replies[i] == r) return 1;
187
int is_numeric(char *s)
190
if(*s < '0' || *s > '9')return 0;
196
struct query *find_query(char *name)
199
for(i = 0; queries[i].name; i++) {
200
if(!strcasecmp(queries[i].name, name)) return &queries[i];
206
static gboolean handle_data(struct line *l) {
209
if(l->direction == TO_SERVER) {
210
q = find_query(l->args[0]);
212
/* Push it up the stack! */
213
if(q->handle(l, q)) {
214
/* Don't send this line to other clients */
215
l->options |= LINE_IS_PRIVATE;
219
struct query_stack *s = stack, *p = NULL;
221
if(!is_numeric(l->args[0])) return TRUE;
223
n = atoi(l->args[0]);
225
/* Loop thru the stack until we find something that's matching */
227
if(is_reply(s->query->replies, n) && s->network == l->network) {
228
/* Send to client that queried, if that client still exists */
229
if(verify_client(s->network, s->client))
230
irc_send_line(s->client->incoming, l);
232
if(is_reply(s->query->end_replies, n)) {
233
/* Remove from stack */
234
if(!p)stack = s->next;
235
else p->next = s->next;
239
l->options |= LINE_DONT_SEND;
249
gboolean fini_plugin(struct plugin *p) {
250
del_filter(handle_data);
254
gboolean init_plugin(struct plugin *p) {
255
add_filter("strip", handle_data);
259
int handle_default(struct line *l, struct query *q)
261
struct query_stack *s = malloc(sizeof(struct query_stack));
262
s->network = l->network;
263
s->client = l->client;
270
int handle_topic(struct line *l, struct query *q)
272
if(l->args[2])return 0;
273
return handle_default(l,q);