]> jfr.im git - irc/evilnet/x3.git/blame - src/mod-webtv.c
Added NICK and WHOIS
[irc/evilnet/x3.git] / src / mod-webtv.c
CommitLineData
2784452e 1/* mod-webtv.c - WebTV Module for X3
2 * Copyright 2007 X3 Development Team
3 *
4 * This file is part of x3.
5 *
6 * x3 is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with srvx; if not, write to the Free Software Foundation,
18 * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
19 */
20
21/*
22 *
23 * /msg opserv bind opserv service *modcmd.joiner
24 * /msg opserv bind opserv service\ add *modcmd.service\ add
25 * /msg opserv bind opserv service\ rename *modcmd.service\ rename
26 * /msg opserv bind opserv service\ trigger *modcmd.service\ trigger
27 * /msg opserv bind opserv service\ remove *modcmd.service\ remove
28 * Add the bot:
29 * /msg opserv service add IRC WebTV Service Bot
30 * /msg opserv bind IRC help *modcmd.help
31 * Restart X3 with the updated conf file (as above, butwith "bot"
32 * "IRC"), and bind the commands to it:
33 * /msg opserv bind IRC * *webtv.*
2784452e 34 */
35
36#include "chanserv.h"
37#include "conf.h"
38#include "modcmd.h"
39#include "nickserv.h"
40#include "opserv.h"
41#include "saxdb.h"
42#include "timeq.h"
43
b15cddea 44#define MAX_CHANNELS_WHOIS 50
45
2784452e 46static const struct message_entry msgtab[] = {
b15cddea 47 { "WBMSG_NOT_MARKED", "You are not a WebTV client." },
48
49 { "WBMSG_NICK_PARAMS", "You need to specify a nickname." },
50 { "WBMSG_NICK_SAME", "You are already $b%s$b." },
51 { "WBMSG_NICK_INVALID", "The nickname $b%s$b is invalid." },
52 { "WBMSG_NICK_IN_USE", "The nickname $b%s$b is in use, please choose another." },
53
54 { "WBMSG_WHOIS_NICKIDENT", "[%s] (%s@%s): %s" },
55 { "WBMSG_WHOIS_CHANNELS", "On %s" },
56 { "WBMSG_WHOIS_SERVER", "[%s] %s : %s" },
57 { "WBMSG_WHOIS_OPER", "[%s] is an IRC Operator" },
58 { "WBMSG_WHOIS_SERVICE", "[%s] is an IRC Service" },
59 { "WBMSG_WHOIS_ACCOUNT", "[%s] is logged in as %s" },
60 { "WBMSG_WHOIS_REALHOST", "[%s] realhost %s@%s %s" },
61 { "WBMSG_WHOIS_SWHOIS", "[%s] %s" },
62 { "WBMSG_WHOIS_DNSBL", "[%s] is DNSBL listed on %s" },
63 { "WBMSG_WHOIS_CONNECTED", "[%s] %s" },
64 { "WBMSG_WHOIS_END", "[%s] End of WHOIS list." },
2784452e 65
66 { NULL, NULL }
67};
68
69struct userNode *webtv;
70
71#define WEBTV_FUNC(NAME) MODCMD_FUNC(NAME)
72#define WEBTV_SYNTAX() svccmd_send_help_brief(user, webtv, cmd)
73#define WEBTV_MIN_PARAMS(N) if(argc < (N)) { \
74 reply("MSG_MISSING_PARAMS", argv[0]); \
75 WEBTV_SYNTAX(); \
76 return 0; }
77
78static struct {
79 struct userNode *bot;
b15cddea 80 int required_mark;
81 struct string_list *valid_marks;
2784452e 82} webtv_conf;
83
84#define OPTION_FUNC(NAME) int NAME(struct svccmd *cmd, struct userNode *user, struct handle_info *hi, UNUSED_ARG(unsigned int override), unsigned int argc, char *argv[])
85typedef OPTION_FUNC(option_func_t);
86
87extern struct string_list *autojoin_channels;
88const char *webtv_module_deps[] = { NULL };
89static struct module *webtv_module;
90static struct log_type *WB_LOG;
b15cddea 91static char *his_servername;
92static char *his_servercomment;
93
94
95int check_mark(struct svccmd *cmd, struct userNode *user, UNUSED_ARG(struct handle_info *hi), UNUSED_ARG(unsigned int override), UNUSED_ARG(unsigned int argc), UNUSED_ARG(char *argv[]))
96{
97 unsigned int y = 0;
2784452e 98
b15cddea 99 if (webtv_conf.required_mark == 0)
100 return 1;
101 else {
102 if (!user->mark) {
103 reply("WBMSG_NOT_MARKED");
104 return 0;
105 }
106 for (y = 0; y < webtv_conf.valid_marks->used; y++) {
107 if (!strcasecmp(webtv_conf.valid_marks->list[y], user->mark))
108 return 1;
109 }
110 reply("WBMSG_NOT_MARKED");
111 return 0;
112 }
113}
2784452e 114
b15cddea 115static MODCMD_FUNC(cmd_nick)
116{
117 struct userNode *nick;
2784452e 118
b15cddea 119 if (!check_mark(cmd, user, NULL, 0, 0, NULL))
120 return 0;
2784452e 121
b15cddea 122 if (argc < 2) {
123 reply("WBMSG_NICK_PARAMS");
124 return 0;
125 }
2784452e 126
b15cddea 127 if (!strcasecmp(argv[1], user->nick)) {
128 reply("WBMSG_NICK_SAME", argv[1]);
129 return 0;
130 }
2784452e 131
b15cddea 132 if (!is_valid_nick(argv[1])) {
133 reply("WBMSG_NICK_INVALID", argv[1]);
134 return 0;
135 }
136
137 nick = GetUserH(argv[1]);
138 if (nick) {
139 reply("WBMSG_NICK_IN_USE", argv[1]);
140 return 0;
141 }
142
143 irc_svsnick(webtv, user, argv[1]);
144 return 1;
145}
146
147void
148webtv_ison(struct userNode *bot, struct userNode *tell, struct userNode *target, const char *message)
149{
150 struct modeNode *mn;
151 unsigned int count, here_len, n, maxlen;
152 char buff[MAXLEN];
153
154 maxlen = tell->handle_info ? tell->handle_info->screen_width : 0;
155 if (!maxlen)
156 maxlen = MAX_LINE_SIZE;
157 for (n=count=0; n<target->channels.used; n++) {
158 mn = target->channels.list[n];
159 if ((mn->channel->modes & (MODE_PRIVATE|MODE_SECRET)))
160 continue;
161
162 here_len = strlen(mn->channel->name);
163 if ((count + here_len + 4) > maxlen) {
164 buff[count] = 0;
165 send_message(tell, bot, message, buff);
166 count = 0;
167 }
168 if (mn->modes & MODE_CHANOP)
169 buff[count++] = '@';
170 if (mn->modes & MODE_HALFOP)
171 buff[count++] = '%';
172 if (mn->modes & MODE_VOICE)
173 buff[count++] = '+';
174 memcpy(buff+count, mn->channel->name, here_len);
175 count += here_len;
176 buff[count++] = ' ';
177 }
178 if (count) {
179 buff[count] = 0;
180 send_message(tell, bot, message, buff);
181 }
182}
183
184static MODCMD_FUNC(cmd_whois)
185{
186 struct userNode *target;
187
188 if (!check_mark(cmd, user, NULL, 0, 0, NULL))
189 return 0;
190
191 if (argc < 2) {
192 reply("WBMSG_NICK_PARAMS");
193 return 0;
194 }
195
196 target = GetUserH(argv[1]);
197 if (target) {
198 reply("WBMSG_WHOIS_NICKIDENT", target->nick, target->ident,
199 IsFakeHost(target) ? target->fakehost : target->hostname, target->info);
200
201 if ((target->channels.used <= MAX_CHANNELS_WHOIS) && !IsService(target))
202 webtv_ison(cmd->parent->bot, user, target, "WBMSG_WHOIS_CHANNELS");
203
204 if (target == user)
205 reply("WBMSG_WHOIS_SERVER", target->nick, target->uplink->name, target->uplink->description);
206 else {
207 reply("WBMSG_WHOIS_SERVER", target->nick, his_servername ? his_servername : target->uplink->name,
208 his_servercomment ? his_servercomment : target->uplink->description);
209 }
210
211 if (IsOper(target))
212 reply("WBMSG_WHOIS_OPER", target->nick);
213
214 if (IsService(target))
215 reply("WBMSG_WHOIS_SERVICE", target->nick);
216
217 if (target->handle_info)
218 reply("WBMSG_WHOIS_ACCOUNT", target->nick, target->handle_info->handle);
219
220 if ((target == user) && (target->fakehost || IsHiddenHost(target)))
221 reply("WBMSG_WHOIS_REALHOST", target->nick, target->ident, target->hostname, irc_ntoa(&target->ip));
222
223 if (target->handle_info) {
224 if (target->handle_info->epithet)
225 reply("WBMSG_WHOIS_SWHOIS", target->nick, target->handle_info->epithet);
226 }
227
228 if (target->mark)
229 reply("WBMSG_WHOIS_DNSBL", target->nick, target->mark);
230
231 reply("WBMSG_WHOIS_END", target->nick);
232 } else {
233 reply("MSG_NICK_UNKNOWN", argv[1]);
234 return 0;
235 }
236
237 return 1;
238}
2784452e 239
240static void
241webtv_conf_read(void)
242{
243 dict_t conf_node;
244 const char *str;
b15cddea 245 struct string_list *strlist;
2784452e 246
247 str = "modules/webtv";
248 if (!(conf_node = conf_get_data(str, RECDB_OBJECT))) {
249 log_module(WB_LOG, LOG_ERROR, "config node `%s' is missing or has wrong type.", str);
250 return;
251 }
b15cddea 252
253 str = database_get_data(conf_node, "required_mark", RECDB_QSTRING);
254 webtv_conf.required_mark = str ? atoi(str) : 0;
255
256 free_string_list(webtv_conf.valid_marks);
257 strlist = database_get_data(conf_node, "valid_marks", RECDB_STRING_LIST);
258 if(strlist)
259 strlist = string_list_copy(strlist);
260 else
261 strlist = alloc_string_list(4);
262 webtv_conf.valid_marks = strlist;
263
264 str = conf_get_data("server/his_servername", RECDB_QSTRING);
265 his_servername = str ? strdup(str) : NULL;
266 str = conf_get_data("server/his_servercomment", RECDB_QSTRING);
267 his_servercomment = str ? strdup(str) : NULL;
2784452e 268}
269
270static void
271webtv_cleanup(void)
272{
273}
274
275int
276webtv_init(void)
277{
278 WB_LOG = log_register_type("WebTV", "file:webtv.log");
279
280 conf_register_reload(webtv_conf_read);
281 reg_exit_func(webtv_cleanup);
282
283 webtv_module = module_register("WebTV", WB_LOG, "mod-webtv.help", NULL);
b15cddea 284 modcmd_register(webtv_module, "nick", cmd_nick, 1, 0, NULL);
285 modcmd_register(webtv_module, "whois", cmd_whois, 1, 0, NULL);
286
2784452e 287 message_register_table(msgtab);
288 return 1;
289}
290
291int
292webtv_finalize(void) {
293 struct chanNode *chan;
294 unsigned int i;
295 dict_t conf_node;
296 const char *str;
297
298 str = "modules/webtv";
299 if (!(conf_node = conf_get_data(str, RECDB_OBJECT))) {
300 log_module(WB_LOG, LOG_ERROR, "config node `%s' is missing or has wrong type.", str);
301 return 0;
302 }
303
304 str = database_get_data(conf_node, "bot", RECDB_QSTRING);
305 if (str) {
306 webtv = webtv_conf.bot;
307 const char *modes = conf_get_data("modules/webtv/modes", RECDB_QSTRING);
308 webtv = AddService(str, modes ? modes : NULL, "WebTV IRC Service", NULL);
309 } else {
310 log_module(WB_LOG, LOG_ERROR, "database_get_data for webtv_conf.bot failed!");
311 exit(1);
312 }
313
314 if (autojoin_channels && webtv) {
315 for (i = 0; i < autojoin_channels->used; i++) {
316 chan = AddChannel(autojoin_channels->list[i], now, "+nt", NULL, NULL);
317 AddChannelUser(webtv, chan)->modes |= MODE_CHANOP;
318 }
319 }
320
321 return 1;
322}