Update all deprecated/discouraged Guile calls
[clinton/bobotpp.git] / source / ScriptCommands.C
1 // ScriptCommands.C -*- C++ -*-
2 // Copyright (c) 1998 Etienne BERNARD
3 // Copyright (C) 2002,2005,2008 Clinton Ebadi
4
5 // This program is free software; you can redistribute it and/or modify
6 // it under the terms of the GNU General Public License as published by
7 // the Free Software Foundation; either version 2 of the License, or
8 // any later version.
9
10 // This program is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 // GNU General Public License for more details.
14
15 // You should have received a copy of the GNU General Public License
16 // along with this program; if not, write to the Free Software
17 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
18 // 02110-1301, USA.
19
20 #ifdef HAVE_CONFIG_H
21 #include "config.h"
22 #endif
23
24 #ifdef USESCRIPTS
25
26 #include "Utils.H"
27 #include "Server.H"
28 #include "ServerList.H"
29 #include "ServerQueue.H"
30 #include "ScriptCommands.H"
31 #include "Interp.H"
32 #include "DCCPerson.H"
33 #include "DCCManager.H"
34 #include "Parser.H"
35 #include "Commands.H"
36 #include "Message.H"
37 #include <libguile.h>
38
39 #define VERIFY_STRING(par) if (!scm_is_string((par))) \
40 return scm_from_int(-17)
41
42 #define VERIFY_NUMBER(par) if (!SCM_NUMBERP((par))) \
43 return scm_from_int(-17)
44
45 SCM
46 ScriptCommands::Action(SCM channel, SCM message)
47 {
48 VERIFY_STRING(channel);
49 VERIFY_STRING(message);
50 Message m = Commands::Action(Interp::bot, Utils::scm2str(channel),
51 Utils::scm2str(message));
52 return scm_from_int(m.getCode());
53 }
54
55 SCM
56 ScriptCommands::AddUser(SCM who, SCM maskChannel, SCM level,
57 SCM prot, SCM aop, SCM expire, SCM password)
58 {
59 // It segfaults when not online, but otherwise appears to work
60 VERIFY_STRING (who);
61 VERIFY_STRING (maskChannel);
62 VERIFY_NUMBER (level);
63
64 String wwho = Utils::scm2str (who);
65 String mask = Utils::scm2str (maskChannel);
66 String passwd;
67 std::time_t eexpire;
68
69 if (SCM_UNBNDP (password))
70 passwd = "";
71 else
72 {
73 VERIFY_STRING (password);
74 passwd = Utils::scm2str (password);
75 }
76 if (SCM_UNBNDP (expire))
77 eexpire = -1;
78 else
79 {
80 VERIFY_STRING (expire);
81 eexpire = Utils::str2time (Utils::scm2str (expire));
82 if (!eexpire) eexpire = -1;
83 }
84
85 int protect = scm_to_int (prot);
86 bool aaop = scm_is_true (aop);
87 int llevel = scm_to_int (level);
88
89 Message m = Commands::AddUser (Interp::bot, wwho, mask, llevel,
90 protect, aaop, eexpire, passwd);
91
92 return scm_from_int(m.getCode ());
93 }
94
95 SCM
96 ScriptCommands::AddServer(SCM servername, SCM port)
97 {
98 int p = 6667;
99 if (SCM_NUMBERP(port))
100 p = scm_to_int (port);
101 Message m = Commands::AddServer(Interp::bot,
102 Utils::scm2str(servername),
103 p);
104 return scm_from_int(m.getCode());
105 }
106
107 SCM
108 ScriptCommands::AddShit(SCM mask, SCM maskChannel, SCM level,
109 SCM expiration, SCM reason)
110 {
111 // This appears to work...not much testing though
112 VERIFY_STRING (mask);
113 VERIFY_STRING (maskChannel);
114 VERIFY_NUMBER (level);
115 String mmask = Utils::scm2str (mask);
116 String mmaskChannel = Utils::scm2str (maskChannel);
117 int llevel = scm_to_int (level);
118 std::time_t expire;
119 String rreason;
120
121 if (SCM_UNBNDP (expiration))
122 expire = -1;
123 else
124 {
125 VERIFY_STRING (expiration);
126 expire = Utils::str2time (Utils::scm2str (expiration));
127 if (!expire) expire = -1;
128 }
129 if (SCM_UNBNDP (reason))
130 rreason = "You're on my shitlist, lamer";
131 else
132 {
133 VERIFY_STRING (reason);
134 rreason = Utils::scm2str (reason);
135 }
136 Message m = Commands::AddShit (Interp::bot, mmask, mmaskChannel,
137 llevel, expire, rreason);
138
139 return scm_from_int(m.getCode ());
140 }
141
142 SCM
143 ScriptCommands::Ban(SCM channel, SCM who)
144 {
145 VERIFY_STRING(channel);
146 VERIFY_STRING(who);
147 Message m = Commands::Ban(Interp::bot, Utils::scm2str(channel),
148 Utils::scm2str(who));
149 return scm_from_int(m.getCode());
150 }
151
152 SCM
153 ScriptCommands::ChangeCommandLevel(SCM command, SCM level)
154 {
155 VERIFY_STRING (command);
156 VERIFY_NUMBER (level);
157
158 std::string ccommand = scm_to_locale_string (command);
159 unsigned int llevel = scm_to_uint (level);
160
161 if (llevel > 4)
162 return SCM_BOOL_F;
163
164 std::map<std::string, class userFunction*,
165 std::less<std::string> >::const_iterator uf_iter
166 = Interp::bot->userFunctions.find (ccommand);
167 userFunction * f = 0;
168
169 if (uf_iter != Interp::bot->userFunctions.end ())
170 f = uf_iter->second;
171 else
172 return SCM_BOOL_F;
173
174 f->minLevel = llevel;
175 return SCM_BOOL_T;
176 }
177
178 SCM
179 ScriptCommands::CTCP(SCM to, SCM command , SCM message)
180 {
181 VERIFY_STRING(to);
182 VERIFY_STRING(command);
183 VERIFY_STRING(message);
184
185 Commands::CTCP (Interp::bot, Utils::scm2str (to),
186 Utils::scm2str (command),
187 Utils::scm2str (message));
188
189 return SCM_UNSPECIFIED;
190 }
191
192 SCM
193 ScriptCommands::CTCPReply (SCM to, SCM command , SCM message)
194 {
195 VERIFY_STRING(to);
196 VERIFY_STRING(command);
197 VERIFY_STRING(message);
198
199 Commands::CTCPReply (Interp::bot, Utils::scm2str (to),
200 Utils::scm2str (command),
201 Utils::scm2str (message));
202
203 return SCM_UNSPECIFIED;
204 }
205
206 SCM
207 ScriptCommands::Cycle(SCM channel)
208 {
209 VERIFY_STRING(channel);
210 Message m = Commands::Cycle(Interp::bot, Utils::scm2str(channel));
211 return scm_from_int(m.getCode());
212 }
213
214 SCM
215 ScriptCommands::Deban(SCM channel, SCM who)
216 {
217 VERIFY_STRING(channel);
218 VERIFY_STRING(who);
219 Message m = Commands::Deban(Interp::bot, Utils::scm2str(channel),
220 Utils::scm2str(who));
221 return scm_from_int(m.getCode());
222 }
223
224 SCM
225 ScriptCommands::DelServer(SCM number)
226 {
227 VERIFY_NUMBER(number);
228 Message m = Commands::DelServer(Interp::bot, scm_to_int (number));
229 return scm_from_int(m.getCode());
230 }
231
232 SCM
233 ScriptCommands::DelUser(SCM who, SCM maskChannel)
234 {
235 VERIFY_STRING(who);
236 VERIFY_STRING(maskChannel);
237 Message m = Commands::DelUser(Interp::bot, Utils::scm2str(who),
238 Utils::scm2str(maskChannel));
239 return scm_from_int(m.getCode());
240 }
241
242 SCM
243 ScriptCommands::DelShit(SCM who, SCM maskChannel)
244 {
245 VERIFY_STRING(who);
246 VERIFY_STRING(maskChannel);
247 Message m = Commands::DelShit(Interp::bot, Utils::scm2str(who),
248 Utils::scm2str(maskChannel));
249 return scm_from_int(m.getCode());
250 }
251
252 SCM
253 ScriptCommands::Deop(SCM channel, SCM who)
254 {
255 VERIFY_STRING(channel);
256 VERIFY_STRING(who);
257 Message m = Commands::Deop(Interp::bot, Utils::scm2str(channel),
258 Utils::scm2str(who));
259 return scm_from_int(m.getCode());
260 }
261
262 SCM
263 ScriptCommands::Die(SCM reason)
264 {
265 String r = "Leaving";
266 if (scm_is_string(reason))
267 r = Utils::scm2str(reason);
268 Message m = Commands::Die(Interp::bot, r);
269 return scm_from_int(m.getCode());
270 }
271
272 SCM
273 ScriptCommands::Do(SCM command)
274 {
275 VERIFY_STRING(command);
276 Message m = Commands::Do(Interp::bot, Utils::scm2str(command));
277 return scm_from_int(m.getCode());
278 }
279
280 SCM
281 ScriptCommands::Invite(SCM channel, SCM who)
282 {
283 VERIFY_STRING(channel);
284 VERIFY_STRING(who);
285 Message m = Commands::Invite(Interp::bot, Utils::scm2str(channel),
286 Utils::scm2str(who));
287 return scm_from_int(m.getCode());
288 }
289
290 SCM
291 ScriptCommands::Join(SCM channel, SCM key)
292 {
293 VERIFY_STRING(channel);
294 String k = "";
295 if (scm_is_string(key))
296 k = Utils::scm2str(key);
297 Message m = Commands::Join(Interp::bot, Utils::scm2str(channel),
298 k);
299 return scm_from_int(m.getCode());
300 }
301
302 SCM
303 ScriptCommands::Keep(SCM channel, SCM modes)
304 {
305 VERIFY_STRING(channel);
306 VERIFY_STRING(modes);
307 Message m = Commands::Keep(Interp::bot, Utils::scm2str(channel),
308 Utils::scm2str(modes));
309 return scm_from_int(m.getCode());
310 }
311
312 SCM
313 ScriptCommands::Kick(SCM channel, SCM who, SCM reason)
314 {
315 VERIFY_STRING(channel);
316 VERIFY_STRING(who);
317
318 String r = "";
319 if (scm_is_string(reason))
320 r = Utils::scm2str(reason);
321
322 Message m = Commands::Kick(Interp::bot, Utils::scm2str(channel),
323 Utils::scm2str(who), r);
324 return scm_from_int(m.getCode());
325 }
326
327 SCM
328 ScriptCommands::KickBan(SCM channel, SCM who, SCM reason)
329 {
330 VERIFY_STRING(channel);
331 VERIFY_STRING(who);
332 String r = "";
333 if (scm_is_string(reason))
334 r = Utils::scm2str(reason);
335 Message m = Commands::KickBan(Interp::bot, Utils::scm2str(channel),
336 Utils::scm2str(who), r);
337 return scm_from_int(m.getCode());
338 }
339
340 SCM
341 ScriptCommands::Lock(SCM channel)
342 {
343 VERIFY_STRING(channel);
344 Message m = Commands::Lock(Interp::bot, Utils::scm2str(channel));
345 return scm_from_int(m.getCode());
346 }
347
348 SCM
349 ScriptCommands::LogPort(void)
350 {
351 return Interp::bot->botInterp->logPort;
352 }
353
354 SCM
355 ScriptCommands::Mode(SCM channel, SCM mode)
356 {
357 VERIFY_STRING(channel);
358 VERIFY_STRING(mode);
359 Message m = Commands::Mode(Interp::bot, Utils::scm2str(channel),
360 Utils::scm2str(mode));
361 return scm_from_int(m.getCode());
362 }
363
364 SCM
365 ScriptCommands::Msg(SCM nick, SCM message)
366 {
367 VERIFY_STRING(nick);
368 VERIFY_STRING(message);
369 Message m = Commands::Msg(Interp::bot, Utils::scm2str(nick),
370 Utils::scm2str(message));
371 return scm_from_int(m.getCode());
372
373 }
374
375 SCM
376 ScriptCommands::NextServer(void)
377 {
378 Message m = Commands::NextServer(Interp::bot);
379 return scm_from_int(m.getCode());
380 }
381
382 SCM
383 ScriptCommands::Nick(SCM nick)
384 {
385 VERIFY_STRING(nick);
386 Message m = Commands::Nick(Interp::bot, Utils::scm2str(nick));
387 return scm_from_int(m.getCode());
388 }
389
390 SCM
391 ScriptCommands::Notice (SCM to, SCM message)
392 {
393 VERIFY_STRING (to);
394 VERIFY_STRING (message);
395
396 return (scm_from_int
397 (Commands::Notice (Interp::bot,
398 Utils::scm2str (to),
399 Utils::scm2str (message)).getCode ()));
400
401 }
402
403 SCM
404 ScriptCommands::Op(SCM channel, SCM who)
405 {
406 VERIFY_STRING(channel);
407 VERIFY_STRING(who);
408 Message m = Commands::Op(Interp::bot, Utils::scm2str(channel),
409 Utils::scm2str(who));
410 return scm_from_int(m.getCode());
411 }
412
413 SCM
414 ScriptCommands::Part(SCM channel)
415 {
416 VERIFY_STRING(channel);
417 Message m = Commands::Part(Interp::bot, Utils::scm2str(channel));
418 return scm_from_int(m.getCode());
419 }
420
421 SCM
422 ScriptCommands::Reconnect(void)
423 {
424 Message m = Commands::Reconnect(Interp::bot);
425 return scm_from_int(m.getCode());
426 }
427
428 SCM
429 ScriptCommands::Say(SCM channel, SCM message)
430 {
431 VERIFY_STRING(channel);
432 VERIFY_STRING(message);
433 Message m = Commands::Say(Interp::bot, Utils::scm2str(channel),
434 Utils::scm2str(message));
435 return scm_from_int(m.getCode());
436 }
437
438 SCM
439 ScriptCommands::Server(SCM number)
440 {
441 VERIFY_NUMBER(number);
442 Message m = Commands::Server(Interp::bot, scm_to_int(number));
443 return scm_from_int(m.getCode());
444 }
445
446 SCM
447 ScriptCommands::SetFloodRate(SCM rate)
448 {
449 VERIFY_NUMBER(rate);
450 Message m = Commands::SetFloodRate(Interp::bot, scm_to_uint (rate));
451 return scm_from_int(m.getCode());
452 }
453
454 SCM
455 ScriptCommands::SetVersion(SCM version)
456 {
457 Message m = Commands::SetVersion(Interp::bot, Utils::scm2str(version));
458 return scm_from_int(m.getCode());
459 }
460
461 SCM
462 ScriptCommands::TBan(SCM channel, SCM who, SCM seconds)
463 {
464 VERIFY_STRING(channel);
465 VERIFY_STRING(who);
466 VERIFY_NUMBER(seconds);
467 Message m = Commands::TBan(Interp::bot, Utils::scm2str(channel),
468 Utils::scm2str(who), scm_to_int(seconds));
469 return scm_from_int(m.getCode());
470 }
471
472 SCM
473 ScriptCommands::TKBan(SCM channel, SCM who, SCM seconds, SCM reason)
474 {
475 VERIFY_STRING(channel);
476 VERIFY_STRING(who);
477 VERIFY_NUMBER(seconds);
478 String r = "";
479 if (scm_is_string(reason))
480 r = Utils::scm2str(reason);
481 Message m = Commands::TKBan(Interp::bot, Utils::scm2str(channel),
482 Utils::scm2str(who),
483 scm_to_int(seconds), r);
484 return scm_from_int(m.getCode());
485 }
486
487 SCM
488 ScriptCommands::Topic(SCM channel, SCM topic)
489 {
490 VERIFY_STRING(channel);
491 VERIFY_STRING(topic);
492 Message m = Commands::Topic(Interp::bot, Utils::scm2str(channel),
493 Utils::scm2str(topic));
494 return scm_from_int(m.getCode());
495 }
496
497 SCM
498 ScriptCommands::Unlock(SCM channel)
499 {
500 VERIFY_STRING(channel);
501 Message m = Commands::Unlock(Interp::bot, Utils::scm2str(channel));
502 return scm_from_int(m.getCode());
503 }
504
505 SCM
506 ScriptCommands::Who (SCM target)
507 {
508 VERIFY_STRING (target);
509
510 Message m = Commands::Who (Interp::bot, Utils::scm2str (target));
511
512 return scm_from_int (m.getCode ());
513 }
514
515 SCM
516 ScriptCommands::Whois (SCM nick)
517 {
518 VERIFY_STRING (nick);
519
520 Message m = Commands::Whois (Interp::bot, Utils::scm2str (nick));
521
522 return scm_from_int (m.getCode ());
523 }
524
525 SCM
526 ScriptCommands::getNickname(void)
527 {
528 return Utils::str2scm(Interp::bot->nickName);
529 }
530
531 SCM
532 ScriptCommands::getServer(void)
533 {
534 ::Server *serv = Interp::bot->serverList->currentServer();
535 int serverNumber = Interp::bot->serverList->currentNumber;
536
537 return scm_list_n(scm_from_int(serverNumber),
538 Utils::str2scm(serv->getHostName()),
539 scm_from_int(serv->getPort()),
540 Utils::str2scm(serv->getPassword()),
541 SCM_UNDEFINED);
542 }
543
544 SCM
545 ScriptCommands::getServerList(void)
546 {
547 SCM res = scm_list_n(SCM_UNDEFINED);
548 ::Server *s;
549 int i = 0;
550 std::vector<class Server *>::iterator it =
551 Interp::bot->serverList->begin();
552
553 for ( ; it != Interp::bot->serverList->end(); ++it) {
554 s = (*it);
555 res =
556 scm_append
557 (scm_list_2 (res,
558 scm_list_n(scm_list_n(scm_from_int(i++),
559 Utils::str2scm(s->getHostName()),
560 scm_from_int(s->getPort()),
561 Utils::str2scm(s->getPassword()),
562 SCM_UNDEFINED), SCM_UNDEFINED)));
563 }
564 return res;
565 }
566
567 SCM
568 ScriptCommands::flushQueue(void)
569 {
570 if (!Interp::bot->serverConnection)
571 return SCM_BOOL_F;
572 Interp::bot->serverConnection->queue->flush();
573 return SCM_BOOL_T;
574 }
575
576 SCM
577 ScriptCommands::flushPort(void)
578 {
579 scm_flush(Interp::bot->botInterp->logPort);
580 return SCM_BOOL_T;
581 }
582
583 SCM
584 ScriptCommands::random(SCM scm_max)
585 {
586 int max = 0;
587 //srand(time(NULL));
588 if (SCM_NUMBERP(scm_max))
589 max = scm_to_int(scm_max);
590 return scm_from_int(max ? rand() % max : 0);
591 }
592
593 SCM
594 ScriptCommands::addCommand(SCM scm_commandName, SCM scm_function,
595 SCM scm_needsChannel, SCM scm_args,
596 SCM scm_minLevel)
597 {
598 // We check that commandName is a string
599 if (!scm_is_string(scm_commandName))
600 return SCM_BOOL_F;
601
602 // We check that the command does not exist
603 String commandName = Utils::to_upper (Utils::scm2str(scm_commandName));
604 if (Interp::bot->userFunctions[commandName])
605 return SCM_BOOL_F;
606
607 // Next we check that needsChannel is a boolean
608 if (!scm_is_bool (scm_needsChannel))
609 return SCM_BOOL_F;
610 bool needsChannel = scm_to_bool(scm_needsChannel);
611
612 // We check that minLevel is an integer and that it's
613 // a valid level
614 if (!SCM_NUMBERP(scm_minLevel))
615 return SCM_BOOL_F;
616
617 int minLevel = scm_to_int(scm_minLevel);
618 if (minLevel < User::NONE || minLevel > User::MASTER)
619 return SCM_BOOL_F;
620
621 // We check that "scm_function" is a Scheme procedure
622 if (!scm_is_true (scm_procedure_p(scm_function)))
623 return SCM_BOOL_F;
624
625 // We check that args is an integer and is between 0 and 20 (arbitrary limit)
626 if (!SCM_NUMBERP(scm_args))
627 return SCM_BOOL_F;
628
629 int args = scm_to_int(scm_args);
630 if (args < 0 || args > 20)
631 return SCM_BOOL_F;
632
633 // We add the command in the commands list
634 Interp::bot->userFunctions[commandName] =
635 new userFunction(0, minLevel, needsChannel, args, scm_function);
636
637 return SCM_BOOL_T;
638 }
639
640 SCM
641 ScriptCommands::delCommand(SCM scm_commandName)
642 {
643 // We check that commandName is a string
644 if (!scm_is_string(scm_commandName))
645 return SCM_BOOL_F;
646
647 // We check that the command does exist
648 String commandName = Utils::to_upper (Utils::scm2str(scm_commandName));
649 if (!Interp::bot->userFunctions[commandName])
650 return SCM_BOOL_F;
651
652 // We delete the command
653 Interp::bot->userFunctions.erase(commandName);
654
655 return SCM_BOOL_T;
656 }
657
658 SCM
659 ScriptCommands::AddHook(SCM type, SCM regex, SCM function, SCM pri, SCM fall,
660 SCM name)
661 {
662 int priority = 0;
663 bool fallt = true; // does this hook fall through?
664 String rname = "DEFAULT";
665
666 if (!SCM_UNBNDP (pri))
667 priority = scm_to_int (pri);
668 if (!SCM_UNBNDP (fall))
669 fallt = scm_is_true (fall);
670 if (!SCM_UNBNDP (name))
671 rname = Utils::scm2str (name);
672 return scm_from_bool (Interp::bot->botInterp->AddHook(scm_to_int(type),
673 regex, function,
674 priority, fallt, rname));
675 }
676
677 SCM
678 ScriptCommands::AddTimer(SCM when, SCM function)
679 {
680 return Interp::bot->botInterp->AddTimer(scm_to_int(when), function);
681 }
682
683 SCM
684 ScriptCommands::DelTimer(SCM timer)
685 {
686 return scm_from_bool (Interp::bot->botInterp->DelTimer(timer));
687 }
688
689 SCM
690 ScriptCommands::sendDCCChatMessage (SCM to, SCM message)
691 {
692
693 return scm_from_bool (Interp::bot->dccConnections->sendMessage
694 (Utils::scm2str (to),
695 Utils::scm2str (message)));
696 }
697
698
699
700
701
702
703 #endif