]>
jfr.im git - irc/thales.git/blob - src/actions.c
1 /* GNU Thales - IRC to Relational Database Gateway
2 * Copyright (C) 2002 Lucas Nussbaum <lucas@lucas-nussbaum.net>
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
29 extern char *ServerName
;
30 extern char *RemoteServer
;
31 extern time_t start_time
;
33 extern int ServerCacheTime
;
34 extern int UserCacheTime
;
35 extern int HidePasswords
;
37 /*************************************************************************/
39 * Max values calculation
42 unsigned int nbusers
= 0;
43 unsigned int nbusers_max
= 0;
44 unsigned int nbchans
= 0;
45 unsigned int nbchans_max
= 0;
46 unsigned int nbservs
= 0;
47 unsigned int nbservs_max
= 0;
48 /* keep track of logged umodes et cmodes, init to 0 by default */
52 /* check if nbchans > nbchans_max */
53 void do_checknbchansmax()
55 if (nbchans
> nbchans_max
)
57 nbchans_max
= nbchans
;
60 " SET val=\'%d\', time=NOW() WHERE type='channels'",
65 /* check if nbusers > nbusers_max */
66 void do_checknbusersmax()
68 if (nbusers
> nbusers_max
)
70 nbusers_max
= nbusers
;
73 " SET val=\'%d\', time=NOW() WHERE type='users'", nbusers_max
);
77 /* check if nbservs > nbservs_max */
78 void do_checknbservsmax()
80 if (nbservs
> nbservs_max
)
82 nbservs_max
= nbservs
;
85 " SET val=\'%d\', time=NOW() WHERE type='servers'", nbservs_max
);
89 /*************************************************************************/
91 * general purpose functions
94 #if !(defined(IRCD_UNREAL)||defined(IRCD_HYBRID)||defined(IRCD_ULTI28))
95 /* converts an IP numeric to a char * */
96 static char *do_ipdecode(char *ipaddr
)
98 static char buf
[16]; /* enough for an IPv4 address. TODO IPv6 ? */
99 unsigned int ip
= (unsigned int) strtoul(ipaddr
, (char **) NULL
, 10);
100 snprintf(buf
, 16, "%u.%u.%u.%u", (unsigned int) ip
>> 24,
101 (unsigned int) (ip
& 0xff0000) >> 16,
102 (unsigned int) (ip
& 0xff00) >> 8, (unsigned int) ip
& 0xff);
107 /* adds modes to a given chanid */
108 static void do_chanmodes(int chanid
, char **av
, int ac
)
110 /* the ircd parses the mode before forwarding it to thales, so there's no buffer overrun
111 * possibility here. - lucas
114 char db
[1000]; /* should be enough for long queries */
115 char tmp
[14] = "mode_XX=\"X\", ";
120 strcpy(db
, "UPDATE " TBL_CHAN
" SET ");
132 if (!strchr(CHANMODES
, *modes
))
134 if (!log_cmode
[(int) *modes
])
136 mylog("unknown mode : chanmode %c (in %s)", *modes
, inbuf
);
137 log_cmode
[(int) *modes
] = TRUE
;
141 else if (*modes
== 'b' || *modes
== 'e' || *modes
== 'f') /* ignore them */
144 else if (*modes
== 'b' || *modes
== 'e' || *modes
== 'I') /* ignore them */
148 else if (*modes
== 'B' || *modes
== 'X' || *modes
== 'E') /* ignore them too */
152 #if defined(IRCD_BAHAMUT)||defined(IRCD_IRCDRU)
153 else if (*modes
== 'o' || *modes
== 'v')
154 #elif defined(IRCD_HYBRID)||defined(IRCD_ULTI28)
155 else if (*modes
== 'o' || *modes
== 'v' || *modes
== 'h')
156 #elif defined(IRCD_ULTIMATE)
157 else if (*modes
== 'o' || *modes
== 'v'
158 || *modes
== 'a' || *modes
== 'h')
159 #elif defined(IRCD_UNREAL)
160 else if (*modes
== 'o' || *modes
== 'v'
161 || *modes
== 'a' || *modes
== 'h' || *modes
== 'q')
165 user
= db_escape(av
[argptr
++]);
168 " SET mode_l%c=\"%c\" WHERE chanid=\"%d\" AND nickid=\"%d\"",
169 *modes
, tmp
[9], chanid
, db_getnick(user
));
175 tmp
[5] = ((*modes
>= 'a') ? 'l' : 'u');
176 tmp
[6] = tolower(*modes
);
182 char *key
= db_escape(av
[argptr
++]);
185 strcat(db
, "mode_lk_data=\"HIDDEN\", ");
189 strcat(db
, "mode_lk_data=\"");
197 strcat(db
, "mode_lk_data=\"\", ");
198 argptr
++; /* mode -k needs a parameter */
201 else if (*modes
== 'l')
205 strcat(db
, "mode_ll_data=\"");
206 strcat(db
, av
[argptr
++]);
211 strcat(db
, "mode_ll_data=\"\", ");
214 #if defined(IRCD_UNREAL)||defined(IRCD_ULTI28)
215 else if (*modes
== 'L')
219 char *ch
= db_escape(av
[argptr
++]);
220 strcat(db
, "mode_ul_data=\"");
227 strcat(db
, "mode_ul_data=\"\", ");
232 else if (*modes
== 'f')
236 strcat(db
, "mode_lf_data=\"");
237 strcat(db
, av
[argptr
++]);
242 strcat(db
, "mode_lf_data=\"\", ");
254 sprintf(&db
[strlen(db
) - 2], " WHERE chanid=\'%d\'", chanid
);
257 #endif /* !NOMODES */
260 /* add one or more users to a chanid */
261 static void do_addusers(int chanid
, char *users
)
263 int op
, voice
, halfop
, owner
, protect
;
266 while (users
&& (*users
))
268 #if defined(IRCD_UNREAL)
269 /* Unreal uses SJOIN to send bans and exempts. Just ignore them. */
270 if ((*users
== '&') || (*users
== '\"'))
272 nextusers
= strchr(users
, ' ');
286 #if defined(IRCD_ULTIMATE)||defined(IRCD_ULTI28)
287 #if defined(IRCD_ULTIMATE)
288 if ((*users
== '!') || (*users
== '¤'))
315 #if defined(IRCD_UNREAL)||defined(IRCD_HYBRID)
322 #if defined(IRCD_UNREAL)
334 nextusers
= strchr(users
, ' ');
337 users
= db_escape(users
);
338 nickid
= db_checknick(users
);
341 #if defined(IRCD_BAHAMUT)||defined(IRCD_IRCDRU)
342 db_query("INSERT INTO " TBL_ISON
343 " (nickid, chanid, mode_lo, mode_lv) VALUES (\'%d\', \'%d\',\'%s\',\'%s\')",
344 nickid
, chanid
, (op
? "Y" : "N"), (voice
? "Y" : "N"));
345 #elif defined(IRCD_UNREAL)
346 db_query("INSERT IGNORE INTO " TBL_ISON
347 " (nickid, chanid, mode_lo, mode_lv, mode_lq, mode_lh, mode_la) VALUES (\'%d\', \'%d\',\'%s\',\'%s\',\'%s\',\'%s\',\'%s\')",
348 nickid
, chanid
, (op
? "Y" : "N"), (voice
? "Y" : "N"),
349 (owner
? "Y" : "N"), (halfop
? "Y" : "N"),
350 (protect
? "Y" : "N"));
351 #elif defined(IRCD_HYBRID)
352 db_query("INSERT INTO " TBL_ISON
353 " (nickid, chanid, mode_lo, mode_lv, mode_lh) VALUES (\'%d\', \'%d\',\'%s\',\'%s\', \'%s\')",
354 nickid
, chanid
, (op
? "Y" : "N"), (voice
? "Y" : "N"),
355 (halfop
? "Y" : "N"));
356 #elif defined(IRCD_ULTI28)
357 db_query("INSERT INTO " TBL_ISON
358 " (nickid, chanid, mode_lo, mode_lv, mode_lh) VALUES (\'%d\', \'%d\',\'%s\',\'%s\',\'%s\')",
359 nickid
, chanid
, (op
? "Y" : "N"), (voice
? "Y" : "N"),
360 (halfop
? "Y" : "N"));
361 #elif defined(IRCD_ULTIMATE)
362 db_query("INSERT INTO " TBL_ISON
363 " (nickid, chanid, mode_lo, mode_lv, mode_lh, mode_la) VALUES (\'%d\', \'%d\',\'%s\',\'%s\',\'%s\',\'%s\')",
364 nickid
, chanid
, (op
? "Y" : "N"), (voice
? "Y" : "N"),
365 (halfop
? "Y" : "N"), (owner
? "Y" : "N"));
370 mylog("received join of non-existing user %s on channel ID %d",
380 /* add modes to a nickid */
381 static void do_usermodes(int nickid
, char *modes
)
385 char db
[1000]; /*should be enough for long queries */
386 char tmp
[14] = "mode_XX=\"X\", ";
387 strcpy(db
, "UPDATE " TBL_USER
" SET ");
399 if (!strchr(USERMODES
, *modes
))
401 if (!log_umode
[(int) *modes
])
403 mylog("unknown mode : usermode %c (in %s)", *modes
, inbuf
);
404 log_umode
[(int) *modes
] = TRUE
;
410 tmp
[5] = ((*modes
>= 'a') ? 'l' : 'u');
411 #if defined(IRCD_UNREAL)||defined(IRCD_ULTIMATE)
412 if (tmp
[9] == 'N' && *modes
== 'x') /* lame Unreal ... */
415 " SET hiddenhostname='*' WHERE nickid='%d'", nickid
);
417 tmp
[6] = tolower(*modes
);
426 sprintf(&db
[strlen(db
) - 2], " WHERE nickid=\'%d\'", nickid
);
429 #endif /* !NOMODES */
432 /*************************************************************************/
434 * IRC messages handlers
438 void do_server(char *server
, char *comment
, char *linkedto
)
442 server
= db_escape(server
);
443 comment
= db_escape(comment
);
444 linkedto
= db_escape(linkedto
);
445 if (ServerCacheTime
&& ((servid
= db_checkserver(server
)) != -1))
447 db_query("UPDATE " TBL_SERV
448 " SET server=\"%s\", comment=\"%s\", linkedto=\"%d\", connecttime=NOW(), online=\"Y\" WHERE servid=\"%d\"",
449 server
, comment
, db_getserver(linkedto
), servid
);
450 db_addserver(server
, servid
);
456 ("INSERT INTO " TBL_SERV
457 " (server, comment, linkedto, connecttime) VALUES(\'%s\','\%s\',\'%d\', NOW())",
458 server
, comment
, db_getserver(linkedto
));
459 db_addserver(server
, db_insertid());
467 do_checknbservsmax();
471 void do_squit(char *server
)
473 server
= db_escape(server
);
476 db_query("UPDATE " TBL_SERV
477 " SET online=\"N\", lastsplit=NOW(),linkedto=NULL WHERE servid=\"%d\"",
478 db_getserver(server
));
483 db_query("DELETE FROM " TBL_SERV
" WHERE server=\'%s\'", server
);
484 db_delserver(server
);
490 /* NICK (new nick) */
491 void do_nick_new(int ac
, char **av
)
493 char *nick
, *realname
, *hostname
, *username
, *serv
;
497 #if !(defined(IRCD_UNREAL)||defined(IRCD_HYBRID)||defined(IRCD_ULTI28))
500 unsigned int connecttime
;
505 nick
= db_escape(av
[0]);
506 connecttime
= atoi(av
[2]);
507 #if defined(IRCD_BAHAMUT)||defined(IRCD_ULTIMATE)||defined(IRCD_IRCDRU)||defined(IRCD_HYBRID)
508 username
= db_escape(av
[4]);
509 hostname
= db_escape(av
[5]);
510 serv
= db_escape(av
[6]);
511 #if defined(IRCD_HYBRID)
513 realname
= db_escape(av
[7]);
516 ipaddr
= do_ipdecode(av
[8]);
517 realname
= db_escape(av
[9]);
519 #elif defined(IRCD_UNREAL)||defined(IRCD_ULTI28)
520 username
= db_escape(av
[3]);
521 hostname
= db_escape(av
[4]);
522 serv
= db_escape(av
[5]);
524 hiddenhost
= db_escape(av
[8]);
525 realname
= db_escape(av
[9]);
527 realname
= db_escape(av
[7]);
530 servid
= db_getserver(serv
);
532 if (UserCacheTime
&& ((nickid
= db_checknick(nick
)) != -1))
534 #if defined(IRCD_BAHAMUT)||defined(IRCD_IRCDRU) /* with nickip */
537 " SET nick=\'%s\', realname=\'%s\', hostname=\'%s\', ipaddr=\'%s\', username=\'%s\', connecttime=FROM_UNIXTIME(\'%d\'), servid=\'%d\',lastquit=NULL, online=\'Y\', away=\'N\', awaymsg=\'\' WHERE nickid=\'%d\'",
538 nick
, realname
, hostname
, ipaddr
, username
, connecttime
, servid
,
540 #elif defined(IRCD_ULTIMATE) /* with nickip & hiddenhost */
543 " SET nick=\'%s\', realname=\'%s\', hostname=\'%s\', hiddenhostname=\"%s\", ipaddr=\'%s\', username=\'%s\', connecttime=FROM_UNIXTIME(\'%d\'), servid=\'%d\', lastquit=NULL, online=\'Y\', away=\'N\', awaymsg=\'\' WHERE nickid=\'%d\'",
544 nick
, realname
, hostname
, hiddenhost
, ipaddr
, username
,
545 connecttime
, servid
, nickid
);
546 #elif defined(IRCD_UNREAL)||defined(IRCD_HYBRID) /* with hiddenhost */
549 " SET nick=\'%s\', realname=\'%s\', hostname=\'%s\', hiddenhostname=\"%s\", username=\'%s\', connecttime=FROM_UNIXTIME(\'%d\'), servid=\'%d\', lastquit=NULL, online=\'Y\', away=\'N\', awaymsg=\'\' WHERE nickid=\'%d\'",
550 nick
, realname
, hostname
, hiddenhost
, username
, connecttime
,
552 #elif defined(IRCD_ULTI28) /* without nickip */
555 " SET nick=\'%s\', realname=\'%s\', hostname=\'%s\', username=\'%s\', connecttime=FROM_UNIXTIME(\'%d\'), servid=\'%d\',lastquit=NULL, online=\'Y\', away=\'N\', awaymsg=\'\' WHERE nickid=\'%d\'",
556 nick
, realname
, hostname
, username
, connecttime
, servid
, nickid
);
562 #if defined(IRCD_BAHAMUT)||defined(IRCD_IRCDRU) /* with nickip */
564 ("INSERT INTO " TBL_USER
565 " (nick, realname, hostname, ipaddr, username, connecttime, servid) VALUES(\'%s\',\'%s\',\'%s\',\'%s\',\'%s\',FROM_UNIXTIME(\'%d\'),\'%d\')",
566 nick
, realname
, hostname
, ipaddr
, username
, connecttime
, servid
);
567 #elif defined(IRCD_ULTIMATE) /* with nickip & hiddenhost */
569 ("INSERT INTO " TBL_USER
570 " (nick, realname, hostname, hiddenhostname, ipaddr, username, connecttime, servid) VALUES(\'%s\',\'%s\',\'%s\',\'%s\',\'%s\',\'%s\',FROM_UNIXTIME(\'%d\'),\'%d\')",
571 nick
, realname
, hostname
, hiddenhost
, ipaddr
, username
,
572 connecttime
, servid
);
573 #elif defined(IRCD_UNREAL)||defined(IRCD_HYBRID) /* with hiddenhost */
575 ("INSERT INTO " TBL_USER
576 " (nick, realname, hostname, hiddenhostname, username, connecttime, servid) VALUES(\'%s\',\'%s\',\'%s\',\'%s\',\'%s\',FROM_UNIXTIME(\'%d\'),\'%d\')",
577 nick
, realname
, hostname
, hiddenhost
, username
, connecttime
,
579 #elif defined(IRCD_ULTI28) /* without nickip */
581 ("INSERT INTO " TBL_USER
582 " (nick, realname, hostname, username, connecttime, servid) VALUES(\'%s\',\'%s\',\'%s\',\'%s\',FROM_UNIXTIME(\'%d\'),\'%d\')",
583 nick
, realname
, hostname
, username
, connecttime
, servid
);
585 db_addnick(nick
, db_insertid());
593 #if defined(IRCD_UNREAL)
597 #if defined(IRCD_BAHAMUT)||defined(IRCD_ULTIMATE)||defined(IRCD_IRCDRU)||defined(IRCD_HYBRID)
598 do_usermodes(db_insertid(), av
[3]);
599 #elif defined(IRCD_UNREAL)
600 do_usermodes(db_insertid(), av
[7]);
603 do_checknbusersmax();
606 /* NICK (nick change) */
607 void do_nick_chg(char *newnick
, char *oldnick
)
611 newnick
= db_escape(newnick
);
612 oldnick
= db_escape(oldnick
);
613 /* the target nickname might already exist if caching is enabled */
614 if (UserCacheTime
&& (strcasecmp(newnick
, oldnick
))
615 && ((nickid
= db_checknick(newnick
)) != -1))
617 /* In this case, we don't keep a record of the old nick. It would be :
618 * - technically difficult, because we'd have to make a copy of the record
619 * - dangerous, because it would provide an easy way to fill up the DB */
621 db_query("DELETE from " TBL_USER
" WHERE nickid=\'%d\'", nickid
);
623 /* we update the nickname */
624 db_query("UPDATE " TBL_USER
" SET nick=\'%s\' WHERE nick=\'%s\'",
626 db_chgnick(newnick
, oldnick
);
632 void do_part(char *chan
, char *nick
)
634 chan
= db_escape(chan
);
635 nick
= db_escape(nick
);
636 db_query("DELETE FROM " TBL_ISON
637 " WHERE nickid=\'%d\' AND chanid=\'%d\'", db_getnick(nick
),
638 db_getchannel(chan
));
639 db_checkemptychan(db_getchannel(chan
), chan
);
645 void do_partall(char *nick
)
647 nick
= db_escape(nick
);
648 db_removefromchans(db_getnick(nick
));
653 void do_join(char *chan
, char *nick
)
655 chan
= db_escape(chan
);
656 /* we don't escape nick because do_addusers does. */
657 do_addusers(db_getchancreate(chan
), nick
);
662 void do_quit(char *nick
)
664 nick
= db_escape(nick
);
665 db_removenick(nick
); /* sql */
672 db_delnick(nick
); /* hash */
679 void do_sjoin(char *chan
, char *users
, char **modes
, int nbmodes
)
681 chan
= db_escape(chan
);
682 do_addusers(db_getchancreate(chan
), users
);
684 do_chanmodes(db_getchannel(chan
), modes
, nbmodes
);
688 /* [SVS]MODE - user */
689 void do_umode(char *nick
, char *modes
)
691 nick
= db_escape(nick
);
692 do_usermodes(db_getnick(nick
), modes
);
696 /* [SVS]MODE - channel */
697 void do_cmode(char *chan
, char **modes
, int nbmodes
)
699 chan
= db_escape(chan
);
700 do_chanmodes(db_getchannel(chan
), modes
, nbmodes
);
705 /* hybrid7 patches -iwes */
707 void do_topic(char *author
, char *chan
, char *topic
)
709 chan
= db_escape(chan
);
710 author
= db_escape(author
);
711 topic
= db_escape(topic
);
714 " SET topic=\'%s\', topicauthor=\'%s\', topictime=NOW() WHERE chanid=\'%d\'",
715 topic
? topic
: "", author
, db_getchannel(chan
));
721 #else /* regular topic */
722 void do_topic(char *chan
, char *author
, char *time
, char *topic
)
724 chan
= db_escape(chan
);
725 author
= db_escape(author
);
726 topic
= db_escape(topic
);
729 " SET topic=\'%s\', topicauthor=\'%s\', topictime=FROM_UNIXTIME(\'%s\') WHERE chanid=\'%d\'",
730 topic
? topic
: "", author
, time
, db_getchannel(chan
));
736 #endif /* IRCD_HYBRID */
740 void do_tburst(char *chan
, char *time
, char *author
, char *topic
)
742 chan
= db_escape(chan
);
743 author
= db_escape(author
);
744 topic
= db_escape(topic
);
747 " SET topic=\'%s\', topicauthor=\'%s\', topictime=FROM_UNIXTIME(\'%s\') WHERE chanid=\'%d\'",
748 topic
? topic
: "", author
, time
, db_getchannel(chan
));
754 #endif /* IRCD_HYBRID */
758 void do_away_set(char *nick
, char *msg
)
760 nick
= db_escape(nick
);
761 msg
= db_escape(msg
);
762 db_query("UPDATE " TBL_USER
763 " SET away=\'Y\', awaymsg=\'%s\' WHERE nickid=\'%d\'", msg
,
770 void do_away_unset(char *nick
)
772 nick
= db_escape(nick
);
773 db_query("UPDATE " TBL_USER
774 " SET away=\'N\', awaymsg=\'\' WHERE nickid=\'%d\'",
780 void do_lusers(char *nick
)
783 "251 %s :There are %d users and %d invisible on %d servers",
784 nick
, db_getlusers(LUSERS_USERS
),
785 db_getlusers(LUSERS_USERSINV
), db_getlusers(LUSERS_SERV
));
786 send_cmd(ServerName
, "252 %s :%d :IRC Operators online", nick
,
787 db_getlusers(LUSERS_OPERS
));
788 send_cmd(ServerName
, "254 %s :%d :channels formed", nick
, nbchans
,
789 db_getlusers(LUSERS_CHAN
));
790 send_cmd(ServerName
, "255 %s :I have 0 clients and 1 servers", nick
);
791 send_cmd(ServerName
, "265 %s :Current local users: 0 Max: 0", nick
);
792 send_cmd(ServerName
, "266 %s :Current global users: %d Max: %d", nick
,
793 db_getlusers(LUSERS_USERSGLOB
), db_getlusers(LUSERS_USERSMAX
));
796 #if defined(IRCD_UNREAL)||defined(IRCD_ULTIMATE)||defined(IRCD_ULTI28)
798 void do_defhost(char *user
, char *msg
)
800 user
= db_escape(user
);
801 msg
= db_escape(msg
);
804 " SET mode_lx=\'Y\', mode_lt=\'Y\', hiddenhostname=\'%s\' WHERE nickid=\'%d\'",
805 msg
, db_getnick(user
));
812 #if defined(IRCD_UNREAL)||defined(IRCD_ULTI28)
815 void do_defname(char *user
, char *msg
)
817 user
= db_escape(user
);
818 msg
= db_escape(msg
);
820 ("UPDATE " TBL_USER
" SET realname=\'%s\' WHERE nickid=\'%d\'",
821 msg
, db_getnick(user
));
827 void do_defident(char *user
, char *msg
)
829 user
= db_escape(user
);
830 msg
= db_escape(msg
);
832 ("UPDATE " TBL_USER
" SET username=\'%s\' WHERE nickid=\'%d\'",
833 msg
, db_getnick(user
));
842 void do_sdesc(char *user
, char *msg
)
844 user
= db_escape(user
);
845 msg
= db_escape(msg
);
846 db_query("UPDATE " TBL_SERV
" SET comment=\'%s\' WHERE servid=\'%d\'",
847 msg
, db_getservfromnick(user
));
852 void do_swhois(char * user
, char * msg
)
854 user
= db_escape(user
);
855 msg
= db_escape(msg
);
857 ("UPDATE " TBL_USER
" SET swhois=\'%s\' WHERE nickid=\'%d\'",
858 msg
, db_getnick(user
));
867 void do_realhost(char *user
, char *host
)
869 user
= db_escape(user
);
870 host
= db_escape(host
);
871 db_query("UPDATE " TBL_USER
872 " SET hiddenhostname=\'%s\' WHERE nickid=\'%d\'", host
,