X-Git-Url: https://jfr.im/git/irc/evilnet/x3.git/blobdiff_plain/ec311f39148004a0a43ce45371bd02c61f19f886..964abe6bbe1247063a151d0c14a8f2ad02d366fc:/src/proto-p10.c diff --git a/src/proto-p10.c b/src/proto-p10.c index 7acf0c0..e3fa69e 100644 --- a/src/proto-p10.c +++ b/src/proto-p10.c @@ -3,7 +3,7 @@ * * This file is part of x3. * - * srvx is free software; you can redistribute it and/or modify + * x3 is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. @@ -20,7 +20,9 @@ #include "nickserv.h" #include "chanserv.h" +#include "hosthiding.h" #include "proto-common.c" +#include "opserv.h" /* Full commands. */ #define CMD_ACCOUNT "ACCOUNT" @@ -90,6 +92,7 @@ #define CMD_SQUIT "SQUIT" #define CMD_STATS "STATS" #define CMD_SVSNICK "SVSNICK" +#define CMD_SWHOIS "SWHOIS" #define CMD_TIME "TIME" #define CMD_TOPIC "TOPIC" #define CMD_TRACE "TRACE" @@ -177,6 +180,7 @@ #define TOK_SQUIT "SQ" #define TOK_STATS "R" #define TOK_SVSNICK "SN" +#define TOK_SWHOIS "SW" #define TOK_TIME "TI" #define TOK_TOPIC "T" #define TOK_TRACE "TR" @@ -274,6 +278,7 @@ #define P10_SQUIT TYPE(SQUIT) #define P10_STATS TYPE(STATS) #define P10_SVSNICK TYPE(SVSNICK) +#define P10_SWHOIS TYPE(SWHOIS) #define P10_TIME TYPE(TIME) #define P10_TOPIC TYPE(TOPIC) #define P10_TRACE TYPE(TRACE) @@ -376,6 +381,43 @@ privmsg_user_helper(struct userNode *un, void *data) } } +/* equiv to user doing /connect server port target */ +void irc_connect(struct userNode *user, char *server, unsigned int port, struct server *target) +{ + putsock("%s " P10_CONNECT " %s %d %s", user->numeric, server, port, target->numeric); +} + +void +irc_squit_route(struct server *srv, const char *message, ...) +{ + va_list arg_list; + char buffer[MAXLEN]; + va_start(arg_list, message); + vsnprintf(buffer, MAXLEN-2, message, arg_list); + buffer[MAXLEN-1] = 0; + + /* When would we squit ourselves exactly?? -Rubin */ + if(srv == self && cManager.uplink->state == CONNECTED ) { + unsigned int i; + + /* Quit all clients linked to me. */ + for(i = 0; i <= self->num_mask; i++) { + if(!self->users[i]) + continue; + irc_quit(self->users[i], buffer); + } + } + + putsock("%s " P10_SQUIT " %s %d :%s", self->numeric, srv->name, 0, buffer); + + if(srv == self) { + /* Force a reconnect to the currently selected server. */ + cManager.uplink->tries = 0; + log_module(MAIN_LOG, LOG_INFO, "Squitting from uplink: %s", buffer); + close_socket(); + } +} + void irc_server(struct server *srv) { @@ -594,6 +636,17 @@ irc_wallchops(struct userNode *from, const char *to, const char *message) putsock("%s " P10_WALLCHOPS " %s :%s", from->numeric, to, message); } +void +irc_wallops(const char *format, ...) +{ + va_list arg_list; + char buffer[MAXLEN]; + va_start(arg_list, format); + vsnprintf(buffer, MAXLEN-2, format, arg_list); + buffer[MAXLEN-1] = 0; + putsock("%s " P10_WALLOPS " :%s", self->numeric, buffer); +} + void irc_notice(struct userNode *from, const char *to, const char *message) { @@ -722,6 +775,8 @@ irc_burst(struct chanNode *chan) if (len) burst_line[pos++] = ' '; + if(chan->members.used < 1) + return; /* dont burst empty channels (created by discrims) */ /* dump the users */ for (n=0; nmembers.used; n++) { mn = chan->members.list[n]; @@ -857,6 +912,12 @@ irc_invite(struct userNode *from, struct userNode *who, struct chanNode *to) putsock("%s " P10_INVITE " %s %s", from->numeric, who->nick, to->name); } +void +irc_silence(struct userNode *who, const char *mask, int add) +{ + putsock("%s " P10_SILENCE " %s %s%s", self->numeric, who->numeric, add ? "+" : "-", mask); +} + void irc_join(struct userNode *who, struct chanNode *what) { @@ -890,6 +951,14 @@ irc_svsnick(struct userNode *from, struct userNode *target, const char *newnick) putsock("%s " P10_SVSNICK " %s %s "FMT_TIME_T, from->uplink->numeric, target->numeric, newnick, now); } +void +irc_swhois(struct userNode *from, struct userNode *target, const char *message) +{ + putsock("%s " P10_SWHOIS " %s %s%s", from->uplink->numeric, target->numeric, message ? ":" : "", + message ? message : ""); + +} + void irc_part(struct userNode *who, struct chanNode *what, const char *reason) { @@ -903,13 +972,47 @@ irc_part(struct userNode *who, struct chanNode *what, const char *reason) void irc_topic(struct userNode *service, struct userNode *who, struct chanNode *what, const char *topic) { -/* UNCOMMENT FOR NEFARIOUS 0.5.0 TOPIC SUPPORT - * putsock("%s " P10_TOPIC " %s %s " FMT_TIME_T " " FMT_TIME_T " :%s", service->numeric, what->name, who->nick, what->timestamp, now, topic); - * UNCOMMENT FOR NEFARIOUS 0.5.0 TOPIC SUPPORT */ - who = service; /* REMOVE LINE FOR NEFARIOUS 0.5.0 */ - - putsock("%s " P10_TOPIC " %s :%s", who->numeric, what->name, topic); + int type = 4; + int host_in_topic = 0; + const char *hstr, *tstr; + char *host, *hostmask; + char shost[MAXLEN]; + char sident[MAXLEN]; + + tstr = conf_get_data("server/type", RECDB_QSTRING); + hstr = conf_get_data("server/host_in_topic", RECDB_QSTRING); + if(tstr) + type = atoi(tstr); + else + type = 4;/* default to 040 style topics */ + + if (hstr) { + if (IsFakeHost(who)) + safestrncpy(shost, who->fakehost, sizeof(shost)); + else if (IsSetHost(who)) { + hostmask = strdup(who->sethost); + if ((host = (strrchr(hostmask, '@')))) + *host++ = '\0'; + else + host = hostmask; + + safestrncpy(sident, hostmask, sizeof(shost)); + safestrncpy(shost, host, sizeof(shost)); + } else + safestrncpy(shost, who->hostname, sizeof(shost)); + + host_in_topic = atoi(hstr); + } + + if (type == 5) { + putsock("%s " P10_TOPIC " %s %s%s%s%s%s " FMT_TIME_T " " FMT_TIME_T " :%s", service->numeric, what->name, + who->nick, host_in_topic ? "!" : "", host_in_topic ? (IsSetHost(who) ? sident : who->ident) : "", + host_in_topic ? "@" : "", host_in_topic ? shost : "", what->timestamp, now, topic); + } else { + who = service; + putsock("%s " P10_TOPIC " %s :%s", who->numeric, what->name, topic); + } } void @@ -1031,6 +1134,7 @@ static CMD_FUNC(cmd_server) return 1; } + static CMD_FUNC(cmd_eob) { struct server *sender; @@ -1047,11 +1151,21 @@ static CMD_FUNC(cmd_eob) unbursted_channels = NULL; irc_eob(); irc_eob_ack(); + + /* now that we know who our uplink is, + * we can center the routing map and activate auto-routing. + */ + activate_routing(NULL, NULL, NULL); } sender->self_burst = 0; recalc_bursts(sender); for (ii=0; iiuplink != self) + routing_handle_connect(sender->name, sender->uplink->name); return 1; } @@ -1606,6 +1720,49 @@ static CMD_FUNC(cmd_part) return 1; } +static CMD_FUNC(cmd_silence) +{ + struct userNode *user; + char *mask; + char *new_mask; + unsigned int i; + + if (argc < 2) + return 0; + + user = GetUserN(argv[1]); + + /* Sanity, go nuts if this happens */ + if (!user) + return 0; + + /* We can safely ignore this if a user adding a silence is not + * ignored. However this brings up a TODO. If a user logs in and + * they have silences on the IRCd then we need to set them here + * somehow + */ + if (!user->handle_info) + return 1; + + mask = argv[2]; + + if (*mask == '-') { + for (i=0; ihandle_info->ignores->used; i++) { + if (!irccasecmp(mask+1, user->handle_info->ignores->list[i])) + user->handle_info->ignores->list[i] = user->handle_info->ignores->list[--user->handle_info->ignores->used]; + } + } else { + for (i=0; ihandle_info->ignores->used; i++) { + if (!strcmp(mask+1, user->handle_info->ignores->list[i])) + return 1; /* Already on the users NickServ ignore list, safely ignore */ + } + + new_mask = strdup(mask+1); + string_list_append(user->handle_info->ignores, new_mask); + } + return 1; +} + static CMD_FUNC(cmd_kick) { if (argc < 3) @@ -1617,6 +1774,7 @@ static CMD_FUNC(cmd_kick) static CMD_FUNC(cmd_squit) { struct server *server; + char *uplink; if (argc < 4) return 0; @@ -1631,7 +1789,13 @@ static CMD_FUNC(cmd_squit) return 1; } + uplink = strdup(server->uplink->name); DelServer(server, 0, argv[3]); + /* if its a pingout and pingout connecting is enabled + or its a read error and readerror connecting is enabled + or were doing a "N" and i need to connect that server somewhere */ + routing_handle_squit(argv[1], uplink, argv[3]); + free(uplink); return 1; } @@ -1652,14 +1816,46 @@ static CMD_FUNC(cmd_privmsg) static CMD_FUNC(cmd_notice) { struct privmsg_desc pd; + struct server *srv; + int nuser = 0; + if (argc != 3) return 0; + pd.user = GetUserH(origin); - if (!pd.user || (IsGagged(pd.user) && !IsOper(pd.user))) - return 1; - pd.is_notice = 1; - pd.text = argv[2]; - parse_foreach(argv[1], privmsg_chan_helper, NULL, privmsg_user_helper, privmsg_invalid, &pd); + if(!pd.user) + nuser = 1; + if (!pd.user || (IsGagged(pd.user) && !IsOper(pd.user))) { + } + else { + pd.is_notice = 1; + pd.text = argv[2]; + parse_foreach(argv[1], privmsg_chan_helper, NULL, privmsg_user_helper, privmsg_invalid, &pd); + } + + srv = GetServerH(origin); + if(srv) { + char *sargv[MAXNUMPARAMS]; + int sargc; + + sargc = split_line(argv[2], true, MAXNUMPARAMS, sargv); + + if(!strcasecmp(sargv[0], "Connect:")) { + /* :Connect: Host shoe.loxxin.net not listed in ircd.conf */ + if(!strcasecmp(sargv[3], "not") && !strcasecmp(sargv[4], "listed")) { + routing_handle_connect_failure(srv, sargv[2], unsplit_string(sargv+3, sargc-3, NULL)); + } + } + else if(!strcasecmp(sargv[0], "Link")) { + /* :Link with mephisto.etheria.cx cancelled: Server mephisto.etheria.cx[216.46.33.71] + * + * :Link with laptop.afternet.org cancelled: Connection refused + */ + if(!strcasecmp(sargv[3], "cancelled:")) { + routing_handle_connect_failure(srv, sargv[2], unsplit_string(sargv+4, sargc-4, NULL)); + } + } + } return 1; } @@ -1840,8 +2036,8 @@ init_parse(void) dict_insert(irc_func_dict, TOK_TOPIC, cmd_topic); dict_insert(irc_func_dict, CMD_AWAY, cmd_away); dict_insert(irc_func_dict, TOK_AWAY, cmd_away); - dict_insert(irc_func_dict, CMD_SILENCE, cmd_dummy); - dict_insert(irc_func_dict, TOK_SILENCE, cmd_dummy); + dict_insert(irc_func_dict, CMD_SILENCE, cmd_silence); + dict_insert(irc_func_dict, TOK_SILENCE, cmd_silence); dict_insert(irc_func_dict, CMD_KICK, cmd_kick); dict_insert(irc_func_dict, TOK_KICK, cmd_kick); dict_insert(irc_func_dict, CMD_SQUIT, cmd_squit); @@ -1854,6 +2050,8 @@ init_parse(void) dict_insert(irc_func_dict, TOK_STATS, cmd_stats); dict_insert(irc_func_dict, CMD_SVSNICK, cmd_svsnick); dict_insert(irc_func_dict, TOK_SVSNICK, cmd_svsnick); + dict_insert(irc_func_dict, CMD_SWHOIS, cmd_dummy); + dict_insert(irc_func_dict, TOK_SWHOIS, cmd_dummy); dict_insert(irc_func_dict, CMD_WHOIS, cmd_whois); dict_insert(irc_func_dict, TOK_WHOIS, cmd_whois); dict_insert(irc_func_dict, CMD_GLINE, cmd_gline); @@ -1904,6 +2102,11 @@ init_parse(void) /* We have reliable clock! Always! Wraaa! */ dict_insert(irc_func_dict, CMD_SETTIME, cmd_dummy); dict_insert(irc_func_dict, TOK_SETTIME, cmd_dummy); + + /* ignore /trace and /motd commands targetted at us */ + dict_insert(irc_func_dict, TOK_TRACE, cmd_dummy); + dict_insert(irc_func_dict, TOK_MOTD, cmd_dummy); + /* handle topics */ dict_insert(irc_func_dict, "331", cmd_num_topic); dict_insert(irc_func_dict, "332", cmd_num_topic); @@ -2257,6 +2460,14 @@ AddUser(struct server* uplink, const char *nick, const char *ident, const char * safestrncpy(uNode->hostname, hostname, sizeof(uNode->hostname)); safestrncpy(uNode->numeric, numeric, sizeof(uNode->numeric)); irc_p10_pton(&uNode->ip, realip); + + if (irc_in_addr_is_ipv4(uNode->ip)) { + make_virtip((char*)irc_ntoa(&uNode->ip), (char*)irc_ntoa(&uNode->ip), uNode->cryptip); + make_virthost((char*)irc_ntoa(&uNode->ip), uNode->hostname, uNode->crypthost); + } else if (irc_in_addr_is_ipv6(uNode->ip)) { + make_ipv6virthost((char*)irc_ntoa(&uNode->ip), uNode->hostname, uNode->crypthost); + } + uNode->timestamp = timestamp; modeList_init(&uNode->channels); uNode->uplink = uplink;