]>
jfr.im git - irc/thales.git/blob - src/actions.c
1 /* 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 /* keep track of logged umodes et cmodes, init to 0 by default */
50 /* check if nbchans > nbchans_max */
51 void do_checknbchansmax()
53 if (nbchans
> nbchans_max
)
55 nbchans_max
= nbchans
;
58 " SET val=\'%d\', time=NOW() WHERE type='channels'",
63 /* check if nbusers > nbusers_max */
64 void do_checknbusersmax()
66 if (nbusers
> nbusers_max
)
68 nbusers_max
= nbusers
;
71 " SET val=\'%d\', time=NOW() WHERE type='users'", nbusers_max
);
75 /*************************************************************************/
77 * general purpose functions
80 #if !(defined(IRCD_UNREAL)||defined(IRCD_HYBRID)||defined(IRCD_ULTI28))
81 /* converts an IP numeric to a char * */
82 static char *do_ipdecode(char *ipaddr
)
84 static char buf
[16]; /* enough for an IPv4 address. TODO IPv6 ? */
85 unsigned int ip
= (unsigned int) strtoul(ipaddr
, (char **) NULL
, 10);
86 snprintf(buf
, 16, "%u.%u.%u.%u", (unsigned int) ip
>> 24,
87 (unsigned int) (ip
& 0xff0000) >> 16,
88 (unsigned int) (ip
& 0xff00) >> 8, (unsigned int) ip
& 0xff);
93 /* adds modes to a given chanid */
94 static void do_chanmodes(int chanid
, char **av
, int ac
)
96 /* the ircd parses the mode before forwarding it to thales, so there's no buffer overrun
97 * possibility here. - lucas
100 char db
[1000]; /* should be enough for long queries */
101 char tmp
[14] = "mode_XX=\"X\", ";
106 strcpy(db
, "UPDATE " TBL_CHAN
" SET ");
118 if (!strchr(CHANMODES
, *modes
))
120 if (!log_cmode
[(int) *modes
])
122 log("unknown mode : chanmode %c (in %s)", *modes
, inbuf
);
123 log_cmode
[(int) *modes
] = TRUE
;
127 else if (*modes
== 'b' || *modes
== 'e' || *modes
== 'f') /* ignore them */
130 else if (*modes
== 'b' || *modes
== 'e' || *modes
== 'I') /* ignore them */
134 else if (*modes
== 'B' || *modes
== 'X' || *modes
== 'E') /* ignore them too */
138 #if defined(IRCD_SEQUANA)||defined(IRCD_BAHAMUT)||defined(IRCD_IRCDRU)
139 else if (*modes
== 'o' || *modes
== 'v')
140 #elif defined(IRCD_HYBRID)||defined(IRCD_ULTI28)
141 else if (*modes
== 'o' || *modes
== 'v' || *modes
== 'h')
142 #elif defined(IRCD_ULTIMATE)
143 else if (*modes
== 'o' || *modes
== 'v'
144 || *modes
== 'a' || *modes
== 'h')
145 #elif defined(IRCD_UNREAL)
146 else if (*modes
== 'o' || *modes
== 'v'
147 || *modes
== 'a' || *modes
== 'h' || *modes
== 'q')
151 user
= db_escape(av
[argptr
++]);
154 " SET mode_l%c=\"%c\" WHERE chanid=\"%d\" AND nickid=\"%d\"",
155 *modes
, tmp
[9], chanid
, db_getnick(user
));
161 tmp
[5] = ((*modes
>= 'a') ? 'l' : 'u');
162 tmp
[6] = tolower(*modes
);
168 char *key
= db_escape(av
[argptr
++]);
171 strcat(db
, "mode_lk_data=\"HIDDEN\", ");
175 strcat(db
, "mode_lk_data=\"");
183 strcat(db
, "mode_lk_data=\"\", ");
184 argptr
++; /* mode -k needs a parameter */
187 else if (*modes
== 'l')
191 strcat(db
, "mode_ll_data=\"");
192 strcat(db
, av
[argptr
++]);
197 strcat(db
, "mode_ll_data=\"\", ");
200 #if defined(IRCD_UNREAL)||defined(IRCD_ULTI28)
201 else if (*modes
== 'L')
205 char *ch
= db_escape(av
[argptr
++]);
206 strcat(db
, "mode_ul_data=\"");
213 strcat(db
, "mode_ul_data=\"\", ");
218 else if (*modes
== 'f')
222 strcat(db
, "mode_lf_data=\"");
223 strcat(db
, av
[argptr
++]);
228 strcat(db
, "mode_lf_data=\"\", ");
240 sprintf(&db
[strlen(db
) - 2], " WHERE chanid=\'%d\'", chanid
);
243 #endif /* !NOMODES */
246 /* add one or more users to a chanid */
247 static void do_addusers(int chanid
, char *users
)
249 int op
, voice
, halfop
, owner
, protect
;
252 while (users
&& (*users
))
254 #if defined(IRCD_UNREAL)
255 /* Unreal uses SJOIN to send bans and exempts. Just ignore them. */
256 if ((*users
== '&') || (*users
== '\"'))
258 nextusers
= strchr(users
, ' ');
272 #if defined(IRCD_ULTIMATE)||defined(IRCD_ULTI28)
273 #if defined(IRCD_ULTIMATE)
274 if ((*users
== '!') || (*users
== '¤'))
301 #if defined(IRCD_UNREAL)||defined(IRCD_HYBRID)
308 #if defined(IRCD_UNREAL)
320 nextusers
= strchr(users
, ' ');
323 users
= db_escape(users
);
324 nickid
= db_checknick(users
);
327 #if defined(IRCD_BAHAMUT)||defined(IRCD_SEQUANA)||defined(IRCD_IRCDRU)
328 db_query("INSERT INTO " TBL_ISON
329 " (nickid, chanid, mode_lo, mode_lv) VALUES (\'%d\', \'%d\',\'%s\',\'%s\')",
330 nickid
, chanid
, (op
? "Y" : "N"), (voice
? "Y" : "N"));
331 #elif defined(IRCD_UNREAL)
332 db_query("INSERT IGNORE INTO " TBL_ISON
333 " (nickid, chanid, mode_lo, mode_lv, mode_lq, mode_lh, mode_la) VALUES (\'%d\', \'%d\',\'%s\',\'%s\',\'%s\',\'%s\',\'%s\')",
334 nickid
, chanid
, (op
? "Y" : "N"), (voice
? "Y" : "N"),
335 (owner
? "Y" : "N"), (halfop
? "Y" : "N"),
336 (protect
? "Y" : "N"));
337 #elif defined(IRCD_HYBRID)
338 db_query("INSERT INTO " TBL_ISON
339 " (nickid, chanid, mode_lo, mode_lv, mode_lh) VALUES (\'%d\', \'%d\',\'%s\',\'%s\', \'%s\')",
340 nickid
, chanid
, (op
? "Y" : "N"), (voice
? "Y" : "N"),
341 (halfop
? "Y" : "N"));
342 #elif defined(IRCD_ULTI28)
343 db_query("INSERT INTO " TBL_ISON
344 " (nickid, chanid, mode_lo, mode_lv, mode_lh) VALUES (\'%d\', \'%d\',\'%s\',\'%s\',\'%s\')",
345 nickid
, chanid
, (op
? "Y" : "N"), (voice
? "Y" : "N"),
346 (halfop
? "Y" : "N"));
347 #elif defined(IRCD_ULTIMATE)
348 db_query("INSERT INTO " TBL_ISON
349 " (nickid, chanid, mode_lo, mode_lv, mode_lh, mode_la) VALUES (\'%d\', \'%d\',\'%s\',\'%s\',\'%s\',\'%s\')",
350 nickid
, chanid
, (op
? "Y" : "N"), (voice
? "Y" : "N"),
351 (halfop
? "Y" : "N"), (owner
? "Y" : "N"));
356 log("received join of non-existing user %s on channel ID %d",
366 /* add modes to a nickid */
367 static void do_usermodes(int nickid
, char *modes
)
371 char db
[1000]; /*should be enough for long queries */
372 char tmp
[14] = "mode_XX=\"X\", ";
373 strcpy(db
, "UPDATE " TBL_USER
" SET ");
385 if (!strchr(USERMODES
, *modes
))
387 if (!log_umode
[(int) *modes
])
389 log("unknown mode : usermode %c (in %s)", *modes
, inbuf
);
390 log_umode
[(int) *modes
] = TRUE
;
396 tmp
[5] = ((*modes
>= 'a') ? 'l' : 'u');
397 #if defined(IRCD_UNREAL)||defined(IRCD_ULTIMATE)
398 if (tmp
[9] == 'N' && *modes
== 'x') /* lame Unreal ... */
401 " SET hiddenhostname='*' WHERE nickid='%d'", nickid
);
403 tmp
[6] = tolower(*modes
);
412 sprintf(&db
[strlen(db
) - 2], " WHERE nickid=\'%d\'", nickid
);
415 #endif /* !NOMODES */
418 /*************************************************************************/
420 * IRC messages handlers
424 void do_server(char *server
, char *comment
, char *linkedto
)
428 server
= db_escape(server
);
429 comment
= db_escape(comment
);
430 linkedto
= db_escape(linkedto
);
431 if (ServerCacheTime
&& ((servid
= db_checkserver(server
)) != -1))
433 db_query("UPDATE " TBL_SERV
434 " SET server=\"%s\", comment=\"%s\", linkedto=\"%d\", connecttime=NOW(), lastsplit=NULL, online=\"Y\" WHERE servid=\"%d\"",
435 server
, comment
, db_getserver(linkedto
), servid
);
436 db_addserver(server
, servid
);
442 ("INSERT INTO " TBL_SERV
443 " (server, comment, linkedto, connecttime) VALUES(\'%s\','\%s\',\'%d\', NOW())",
444 server
, comment
, db_getserver(linkedto
));
445 db_addserver(server
, db_insertid());
455 void do_squit(char *server
)
457 server
= db_escape(server
);
460 db_query("UPDATE " TBL_SERV
461 " SET online=\"N\", lastsplit=NOW(),linkedto=NULL WHERE servid=\"%d\"",
462 db_getserver(server
));
467 db_query("DELETE FROM " TBL_SERV
" WHERE server=\'%s\'", server
);
468 db_delserver(server
);
473 /* NICK (new nick) */
474 void do_nick_new(int ac
, char **av
)
476 char *nick
, *realname
, *hostname
, *username
, *serv
;
480 #if !(defined(IRCD_UNREAL)||defined(IRCD_HYBRID)||defined(IRCD_ULTI28))
483 unsigned int connecttime
;
488 nick
= db_escape(av
[0]);
489 connecttime
= atoi(av
[2]);
490 #if defined(IRCD_SEQUANA)||defined(IRCD_BAHAMUT)||defined(IRCD_ULTIMATE)||defined(IRCD_IRCDRU)||defined(IRCD_HYBRID)
491 username
= db_escape(av
[4]);
492 hostname
= db_escape(av
[5]);
493 serv
= db_escape(av
[6]);
495 hiddenhost
= db_escape(av
[8]);
496 ipaddr
= do_ipdecode(av
[9]);
497 realname
= db_escape(av
[10]);
498 #elif defined(IRCD_HYBRID)
500 realname
= db_escape(av
[7]);
503 ipaddr
= do_ipdecode(av
[8]);
504 realname
= db_escape(av
[9]);
505 #endif /* IRCD_SEQUANA/BAHAMUT/ULTIMATE/HYBRID */
506 #elif defined(IRCD_UNREAL)||defined(IRCD_ULTI28)
507 username
= db_escape(av
[3]);
508 hostname
= db_escape(av
[4]);
509 serv
= db_escape(av
[5]);
511 hiddenhost
= db_escape(av
[8]);
512 realname
= db_escape(av
[9]);
514 realname
= db_escape(av
[7]);
517 servid
= db_getserver(serv
);
519 if (UserCacheTime
&& ((nickid
= db_checknick(nick
)) != -1))
521 #if defined(IRCD_BAHAMUT)||defined(IRCD_IRCDRU) /* with nickip */
524 " 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\'",
525 nick
, realname
, hostname
, ipaddr
, username
, connecttime
, servid
,
527 #elif defined(IRCD_SEQUANA)||defined(IRCD_ULTIMATE) /* with nickip & hiddenhost */
530 " 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\'",
531 nick
, realname
, hostname
, hiddenhost
, ipaddr
, username
,
532 connecttime
, servid
, nickid
);
533 #elif defined(IRCD_UNREAL)||defined(IRCD_HYBRID) /* with hiddenhost */
536 " 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\'",
537 nick
, realname
, hostname
, hiddenhost
, username
, connecttime
,
539 #elif defined(IRCD_ULTI28) /* without nickip */
542 " 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\'",
543 nick
, realname
, hostname
, username
, connecttime
, servid
, nickid
);
549 #if defined(IRCD_BAHAMUT)||defined(IRCD_IRCDRU) /* with nickip */
551 ("INSERT INTO " TBL_USER
552 " (nick, realname, hostname, ipaddr, username, connecttime, servid) VALUES(\'%s\',\'%s\',\'%s\',\'%s\',\'%s\',FROM_UNIXTIME(\'%d\'),\'%d\')",
553 nick
, realname
, hostname
, ipaddr
, username
, connecttime
, servid
);
554 #elif defined(IRCD_SEQUANA)||defined(IRCD_ULTIMATE) /* with nickip & hiddenhost */
556 ("INSERT INTO " TBL_USER
557 " (nick, realname, hostname, hiddenhostname, ipaddr, username, connecttime, servid) VALUES(\'%s\',\'%s\',\'%s\',\'%s\',\'%s\',\'%s\',FROM_UNIXTIME(\'%d\'),\'%d\')",
558 nick
, realname
, hostname
, hiddenhost
, ipaddr
, username
,
559 connecttime
, servid
);
560 #elif defined(IRCD_UNREAL)||defined(IRCD_HYBRID) /* with hiddenhost */
562 ("INSERT INTO " TBL_USER
563 " (nick, realname, hostname, hiddenhostname, username, connecttime, servid) VALUES(\'%s\',\'%s\',\'%s\',\'%s\',\'%s\',FROM_UNIXTIME(\'%d\'),\'%d\')",
564 nick
, realname
, hostname
, hiddenhost
, username
, connecttime
,
566 #elif defined(IRCD_ULTI28) /* without nickip */
568 ("INSERT INTO " TBL_USER
569 " (nick, realname, hostname, username, connecttime, servid) VALUES(\'%s\',\'%s\',\'%s\',\'%s\',FROM_UNIXTIME(\'%d\'),\'%d\')",
570 nick
, realname
, hostname
, username
, connecttime
, servid
);
572 db_addnick(nick
, db_insertid());
580 #if defined(IRCD_SEQUANA)||defined(IRCD_UNREAL)
584 #if defined(IRCD_SEQUANA)||defined(IRCD_BAHAMUT)||defined(IRCD_ULTIMATE)||defined(IRCD_IRCDRU)||defined(IRCD_HYBRID)
585 do_usermodes(db_insertid(), av
[3]);
586 #elif defined(IRCD_UNREAL)
587 do_usermodes(db_insertid(), av
[7]);
590 do_checknbusersmax();
593 /* NICK (nick change) */
594 void do_nick_chg(char *newnick
, char *oldnick
)
598 newnick
= db_escape(newnick
);
599 oldnick
= db_escape(oldnick
);
600 /* the target nickname might already exist if caching is enabled */
601 if (UserCacheTime
&& (strcasecmp(newnick
, oldnick
))
602 && ((nickid
= db_checknick(newnick
)) != -1))
604 /* In this case, we don't keep a record of the old nick. It would be :
605 * - technically difficult, because we'd have to make a copy of the record
606 * - dangerous, because it would provide an easy way to fill up the DB */
608 db_query("DELETE from " TBL_USER
" WHERE nickid=\'%d\'", nickid
);
610 /* we update the nickname */
611 db_query("UPDATE " TBL_USER
" SET nick=\'%s\' WHERE nick=\'%s\'",
613 db_chgnick(newnick
, oldnick
);
619 void do_part(char *chan
, char *nick
)
621 chan
= db_escape(chan
);
622 nick
= db_escape(nick
);
623 db_query("DELETE FROM " TBL_ISON
624 " WHERE nickid=\'%d\' AND chanid=\'%d\'", db_getnick(nick
),
625 db_getchannel(chan
));
626 db_checkemptychan(db_getchannel(chan
), chan
);
632 void do_partall(char *nick
)
634 nick
= db_escape(nick
);
635 db_removefromchans(db_getnick(nick
));
640 void do_join(char *chan
, char *nick
)
642 chan
= db_escape(chan
);
643 /* we don't escape nick because do_addusers does. */
644 do_addusers(db_getchancreate(chan
), nick
);
649 void do_quit(char *nick
)
651 nick
= db_escape(nick
);
652 db_removenick(nick
); /* sql */
659 db_delnick(nick
); /* hash */
666 void do_sjoin(char *chan
, char *users
, char **modes
, int nbmodes
)
668 chan
= db_escape(chan
);
669 do_addusers(db_getchancreate(chan
), users
);
671 do_chanmodes(db_getchannel(chan
), modes
, nbmodes
);
675 /* [SVS]MODE - user */
676 void do_umode(char *nick
, char *modes
)
678 nick
= db_escape(nick
);
679 do_usermodes(db_getnick(nick
), modes
);
683 /* [SVS]MODE - channel */
684 void do_cmode(char *chan
, char **modes
, int nbmodes
)
686 chan
= db_escape(chan
);
687 do_chanmodes(db_getchannel(chan
), modes
, nbmodes
);
692 /* hybrid7 patches -iwes */
694 void do_topic(char *author
, char *chan
, char *topic
)
696 chan
= db_escape(chan
);
697 author
= db_escape(author
);
698 topic
= db_escape(topic
);
701 " SET topic=\'%s\', topicauthor=\'%s\', topictime=NOW() WHERE chanid=\'%d\'",
702 topic
? topic
: "", author
, db_getchannel(chan
));
708 #else /* regular topic */
709 void do_topic(char *chan
, char *author
, char *time
, char *topic
)
711 chan
= db_escape(chan
);
712 author
= db_escape(author
);
713 topic
= db_escape(topic
);
716 " SET topic=\'%s\', topicauthor=\'%s\', topictime=FROM_UNIXTIME(\'%s\') WHERE chanid=\'%d\'",
717 topic
? topic
: "", author
, time
, db_getchannel(chan
));
723 #endif /* IRCD_HYBRID */
727 void do_tburst(char *chan
, char *time
, char *author
, char *topic
)
729 chan
= db_escape(chan
);
730 author
= db_escape(author
);
731 topic
= db_escape(topic
);
734 " SET topic=\'%s\', topicauthor=\'%s\', topictime=FROM_UNIXTIME(\'%s\') WHERE chanid=\'%d\'",
735 topic
? topic
: "", author
, time
, db_getchannel(chan
));
741 #endif /* IRCD_HYBRID */
745 void do_away_set(char *nick
, char *msg
)
747 nick
= db_escape(nick
);
748 msg
= db_escape(msg
);
749 db_query("UPDATE " TBL_USER
750 " SET away=\'Y\', awaymsg=\'%s\' WHERE nickid=\'%d\'", msg
,
757 void do_away_unset(char *nick
)
759 nick
= db_escape(nick
);
760 db_query("UPDATE " TBL_USER
761 " SET away=\'N\', awaymsg=\'\' WHERE nickid=\'%d\'",
767 void do_lusers(char *nick
)
770 "251 %s :There are %d users and %d invisible on %d servers",
771 nick
, db_getlusers(LUSERS_USERS
),
772 db_getlusers(LUSERS_USERSINV
), db_getlusers(LUSERS_SERV
));
773 send_cmd(ServerName
, "252 %s :%d :IRC Operators online", nick
,
774 db_getlusers(LUSERS_OPERS
));
775 send_cmd(ServerName
, "254 %s :%d :channels formed", nick
, nbchans
,
776 db_getlusers(LUSERS_CHAN
));
777 send_cmd(ServerName
, "255 %s :I have 0 clients and 1 servers", nick
);
778 send_cmd(ServerName
, "265 %s :Current local users: 0 Max: 0", nick
);
779 send_cmd(ServerName
, "266 %s :Current global users: %d Max: %d", nick
,
780 db_getlusers(LUSERS_USERSGLOB
), db_getlusers(LUSERS_USERSMAX
));
783 #if defined(IRCD_UNREAL)||defined(IRCD_ULTIMATE)||defined(IRCD_ULTI28)
785 void do_defhost(char *user
, char *msg
)
787 user
= db_escape(user
);
788 msg
= db_escape(msg
);
791 " SET mode_lx=\'Y\', mode_lt=\'Y\', hiddenhostname=\'%s\' WHERE nickid=\'%d\'",
792 msg
, db_getnick(user
));
799 #if defined(IRCD_UNREAL)||defined(IRCD_ULTI28)
802 void do_defname(char *user
, char *msg
)
804 user
= db_escape(user
);
805 msg
= db_escape(msg
);
807 ("UPDATE " TBL_USER
" SET realname=\'%s\' WHERE nickid=\'%d\'",
808 msg
, db_getnick(user
));
814 void do_defident(char *user
, char *msg
)
816 user
= db_escape(user
);
817 msg
= db_escape(msg
);
819 ("UPDATE " TBL_USER
" SET username=\'%s\' WHERE nickid=\'%d\'",
820 msg
, db_getnick(user
));
829 void do_sdesc(char *user
, char *msg
)
831 user
= db_escape(user
);
832 msg
= db_escape(msg
);
833 db_query("UPDATE " TBL_SERV
" SET comment=\'%s\' WHERE servid=\'%d\'",
834 msg
, db_getservfromnick(user
));
843 void do_realhost(char *user
, char *host
)
845 user
= db_escape(user
);
846 host
= db_escape(host
);
847 db_query("UPDATE " TBL_USER
848 " SET hiddenhostname=\'%s\' WHERE nickid=\'%d\'", host
,