#include "nickserv.h"
#include "chanserv.h"
+#include "helpfile.h"
#include "hosthiding.h"
#include "proto-common.c"
+#include "opserv.h"
/* Full commands. */
#define CMD_ACCOUNT "ACCOUNT"
*/
#define PREHISTORY 780000000
+#define MODELEN 40 + KEYLEN
+
static struct server *servers_num[64*64];
static privmsg_func_t *privmsg_funcs;
static unsigned int num_privmsg_funcs;
static struct userNode *AddUser(struct server* uplink, const char *nick, const char *ident, const char *hostname, const char *modes, const char *numeric, const char *userinfo, time_t timestamp, const char *realip);
extern int off_channel;
+extern int DefConLevel;
+extern int DefConTimeOut;
+extern char *DefConChanModes;
static int parse_oplevel(char *str);
}
}
+/* 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)
{
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)
{
irc_eob_ack(void)
{
putsock("%s " P10_EOB_ACK, self->numeric);
+
+ char *nick;
+ const char *str;
+ str = conf_get_data("services/opserv/nick", RECDB_QSTRING);
+ nick = strdup(str);
+
+ if (nick && (DefConLevel < 5)) {
+ DefConProcess(GetUserH(nick));
+
+ if (DefConTimeOut > 0)
+ timeq_add(now + DefConTimeOut, defcon_timeout, NULL);
+ }
}
void
if (len)
burst_line[pos++] = ' ';
+ if(chan->members.used < 1)
+ return; /* dont burst empty channels (created by discrims) */
/* dump the users */
for (n=0; n<chan->members.used; n++) {
mn = chan->members.list[n];
{
int type = 4;
- const char *str;
- str = conf_get_data("server/type", RECDB_QSTRING);
- if(str)
- type = atoi(str);
+ 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 " FMT_TIME_T " " FMT_TIME_T " :%s", service->numeric, what->name, who->nick, what->timestamp, now, topic);
+ 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);
return 1;
}
+
static CMD_FUNC(cmd_eob)
{
struct server *sender;
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; ii<slf_used; ii++)
slf_list[ii](sender);
+ /* let auto-routing figure out if we were
+ * wating on this server to link a child to it */
+ /* DONT call this if uplink is _US_ */
+ if(sender->uplink != self)
+ routing_handle_connect(sender->name, sender->uplink->name);
return 1;
}
NickChange(user, argv[1], 1);
} else {
struct server *serv;
+ struct userNode *nuser;
char modes[MAXLEN];
/* new nick */
if (argc < 9)
unsplit_string(argv+6, argc-9, modes);
else
strcpy(modes, "+");
- AddUser(serv, argv[1], argv[4], argv[5], modes, argv[argc-2], argv[argc-1], atoi(argv[3]), argv[argc-3]);
+ nuser = AddUser(serv, argv[1], argv[4], argv[5], modes, argv[argc-2], argv[argc-1], atoi(argv[3]), argv[argc-3]);
}
return 1;
}
cn->timestamp = atoi(argv[argc-1]);
}
+ if (checkDefCon(DEFCON_NO_MODE_CHANGE) && !IsOper(un)) {
+ const char *str;
+ str = conf_get_data("services/opserv/nick", RECDB_QSTRING);
+ if (str) {
+ char modes[MODELEN];
+ struct userNode *opserv = GetUserH(str);
+
+ send_message_type(4, un, opserv, "Channel modes cannot be changed due to DefCon level %d in effect, please try again soon", DefConLevel);
+ irc_make_chanmode(cn, modes);
+ irc_mode(opserv, cn, modes);
+ irc_mode(opserv, cn, DefConChanModes);
+ }
+ return 1;
+ }
+
+
return mod_chanmode(un, cn, argv+2, argc-2, MCP_ALLOW_OVB|MCP_FROM_SERVER|(un ? MC_NOTIFY : 0));
}
{
struct userNode *user;
char *mask;
+ char *new_mask;
unsigned int i;
if (argc < 2)
if (!user->handle_info)
return 1;
- mask = strdup(argv[2]);
+ mask = argv[2];
if (*mask == '-') {
for (i=0; i<user->handle_info->ignores->used; i++) {
return 1; /* Already on the users NickServ ignore list, safely ignore */
}
- string_list_append(user->handle_info->ignores, mask+1);
+ new_mask = strdup(mask+1);
+ string_list_append(user->handle_info->ignores, new_mask);
}
-
return 1;
}
static CMD_FUNC(cmd_squit)
{
struct server *server;
+ char *uplink;
if (argc < 4)
return 0;
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;
}
pd.user = GetUserH(origin);
if (!pd.user || (IsGagged(pd.user) && !IsOper(pd.user)))
return 1;
+
+ if (checkDefCon(DEFCON_OPER_ONLY) && !IsOper(pd.user)) {
+ const char *str;
+ str = conf_get_data("services/opserv/nick", RECDB_QSTRING);
+ if (str)
+ send_message_type(4, pd.user, GetUserH(str), "Services are currently not available, please try again soon");
+ return 1;
+ }
+
+ if (checkDefCon(DEFCON_SILENT_OPER_ONLY) && !IsOper(pd.user))
+ return 1; /* Silently Ignore */
+
pd.is_notice = 0;
pd.text = argv[2];
parse_foreach(argv[1], privmsg_chan_helper, NULL, privmsg_user_helper, privmsg_invalid, &pd);
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;
}