#define CMD_RESTART "RESTART"
#define CMD_RPING "RPING"
#define CMD_RPONG "RPONG"
+#define CMD_SASL "SASL"
#define CMD_SERVER "SERVER"
#define CMD_SERVLIST "SERVLIST"
#define CMD_SERVSET "SERVSET"
#define TOK_PONG "Z"
#define TOK_POST "POST"
#define TOK_PRIVMSG "P"
-#define TOK_PRIVS "PR"
+#define TOK_PRIVS "PRIVS"
#define TOK_PROTO "PROTO"
#define TOK_QUIT "Q"
#define TOK_REHASH "REHASH"
#define TOK_RESTART "RESTART"
#define TOK_RPING "RI"
#define TOK_RPONG "RO"
+#define TOK_SASL "SASL"
#define TOK_SERVER "S"
#define TOK_SERVLIST "SERVSET"
#define TOK_SERVSET "SERVSET"
#define P10_RESTART TYPE(RESTART)
#define P10_RPING TYPE(RPING)
#define P10_RPONG TYPE(RPONG)
+#define P10_SASL TYPE(SASL)
#define P10_SERVER CMD_SERVER
#define P10_SERVLIST TYPE(SERVLIST)
#define P10_SERVSET TYPE(SERVSET)
void
irc_shun(struct server *srv, struct shun *shun)
{
- putsock("%s " P10_SHUN " %s +%s " FMT_TIME_T " :<%s> %s",
- self->numeric, (srv ? srv->numeric : "*"), shun->target, shun->expires-now, shun->issuer, shun->reason);
+ putsock("%s " P10_SHUN " %s +%s " FMT_TIME_T " " FMT_TIME_T " :<%s> %s",
+ self->numeric, (srv ? srv->numeric : "*"), shun->target, shun->expires-now, now, shun->issuer, shun->reason);
}
void
void
irc_ungline(const char *mask)
{
- putsock("%s " P10_GLINE " * -%s", self->numeric, mask);
+ putsock("%s " P10_GLINE " * -%s " FMT_TIME_T, self->numeric, mask, now);
}
void
irc_unshun(const char *mask)
{
- putsock("%s " P10_SHUN " * -%s", self->numeric, mask);
+ putsock("%s " P10_SHUN " * -%s " FMT_TIME_T, self->numeric, mask, now);
}
void
if ((n+1)<chan->members.used)
burst_line[pos++] = ',';
}
+
+ if (len > 0 && (chan->banlist.used > 0 || chan->exemptlist.used > 0))
+ burst_line[pos++] = ' ';
+
if (chan->banlist.used) {
/* dump the bans */
first_ban = 1;
}
}
}
+
if (chan->exemptlist.used) {
/* dump the exempts */
first_exempt = 1;
for (n=0; n<chan->exemptlist.used; ) {
if (first_exempt && (pos < 500)) {
- burst_line[pos++] = ' ';
+ if (chan->banlist.used < 1) {
+ burst_line[pos++] = ':';
+ burst_line[pos++] = '%';
+ burst_line[pos++] = ' ';
+ }
burst_line[pos++] = '~';
burst_line[pos++] = ' ';
}
irc_topic(struct userNode *service, struct userNode *who, struct chanNode *what, const char *topic)
{
- int type = 4, host_in_topic = 0, hasident = 0;
- const char *hstr, *tstr;
+ int type = 4, host_in_topic = 0, hasident = 0, hhtype = 0;
+ const char *hstr, *tstr, *hhstr, *htstr;
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);
+ hhstr = conf_get_data("server/hidden_host", RECDB_QSTRING);
+ htstr = conf_get_data("server/hidden_host_type", RECDB_QSTRING);
if(tstr)
type = atoi(tstr);
else
type = 4;/* default to 040 style topics */
+ if (htstr)
+ hhtype = atoi(htstr);
if (hstr) {
- if (IsFakeHost(who))
+ if (IsHiddenHost(who) && IsFakeHost(who))
safestrncpy(shost, who->fakehost, sizeof(shost));
- else if (IsSetHost(who)) {
+ else if (IsHiddenHost(who) && IsSetHost(who)) {
hostmask = strdup(who->sethost);
if ((host = (strrchr(hostmask, '@')))) {
hasident = 1;
safestrncpy(sident, who->ident, sizeof(shost));
safestrncpy(shost, host, sizeof(shost));
+ } else if (IsHiddenHost(who) && ((hhtype == 1) || (hhtype == 3)) && who->handle_info && hhstr) {
+ snprintf(shost, sizeof(shost), "%s.%s", who->handle_info->handle, hhstr);
+ } else if (IsHiddenHost(who) && ((hhtype == 2) || (hhtype == 3)) && who->crypthost[0]) {
+ safestrncpy(shost, who->crypthost, sizeof(shost));
} else
safestrncpy(shost, who->hostname, sizeof(shost));
irc_mark(struct userNode *user, char *mark)
{
char *host = user->hostname;
+ int type = 4;
+ const char *tstr = NULL;
+ unsigned int ii = 0;
+ int markfound = 0;
+
+ tstr = conf_get_data("server/type", RECDB_QSTRING);
+ if(tstr)
+ type = atoi(tstr);
+ else
+ type = 4;
+
+ if (user->marks)
+ for (ii=0; ii<user->marks->used; ii++)
+ if (!irccasecmp(user->marks->list[ii], mark))
+ markfound = 1;
+
+ if (!markfound)
+ {
+ if (!user->marks)
+ user->marks = alloc_string_list(1);
+ string_list_append(user->marks, strdup(mark));
+ }
+
+ if (type >= 9)
+ {
+ putsock("%s " CMD_MARK " %s MARK %s", self->numeric, user->nick, mark);
+ return;
+ }
/* TODO: Allow mark overwrite. If they are marked, and their fakehost is oldmark.hostname, update it to newmark.hostname so mark can be called multiple times. Probably requires ircd modification also */
if(user->mark)
putsock("%s " CMD_SNO " %d :%s", self->numeric, mask, buffer);
}
+void
+irc_sasl(struct server* dest, const char *identifier, const char *subcmd, const char *data)
+{
+ putsock("%s " P10_SASL " %s %s %s %s", self->numeric, dest->numeric, identifier, subcmd, data);
+}
+
static void send_burst(void);
static void
return 1;
}
+static CMD_FUNC(cmd_sasl)
+{
+ struct server *serv;
+
+ if (argc < 5)
+ return 0;
+
+ serv = GetServerH(origin);
+ if (!serv)
+ return 0;
+
+ call_sasl_input_func(serv, argv[2], argv[3], argv[4], (argc>5 ? argv[5] : NULL));
+
+ return 1;
+}
+
static CMD_FUNC(cmd_ping)
{
struct server *srv;
break;
}
case '%': {
+ ctype = 1;
for(parm = mysep(&argv[next], " "); /* parm = first param */
parm; /* While param is not null */
parm = mysep(&argv[next], " ") /* parm = next param */
)
{
- switch (parm[0]) {
- case '%': {
- ctype = 1;
- break;
- }
- case '~': {
- ctype = 2;
- break;
- }
- default: {
- break;
- }
- }
+ if (0 == strcmp("~", parm))
+ ctype = 2;
if (ctype == 1) {
if (bcheck == 0) {
/* strip % char off start of very first ban */
*/
static CMD_FUNC(cmd_mark)
{
+ const char *tstr;
+ int type = 4;
struct userNode *target;
/*
* log_module(MAIN_LOG, LOG_ERROR, "DEBUG: mark, user %s, type %s, arg %s", argv[1], argv[2], argv[3]);
*/
+ tstr = conf_get_data("server/type", RECDB_QSTRING);
+ if(tstr)
+ type = atoi(tstr);
+ else
+ type = 4;/* default to 040 style topics */
+
if(argc < 4)
return 0;
if(!strcasecmp(argv[2], "DNSBL")) {
/* DNSBL <modes> */
return 1;
}
- else if(!strcasecmp(argv[2], "DNSBL_DATA")) {
+ else if(!strcasecmp(argv[2], "DNSBL_DATA") || !strcasecmp(argv[2], "MARK")) {
+ int markfound = 0;
+ unsigned int ii = 0;
/* DNSBL_DATA name */
target = GetUserH(argv[1]);
if(!target) {
log_module(MAIN_LOG, LOG_ERROR, "Unable to find user %s whose dnsbl mark is changing.", argv[1]);
return 0;
}
- target->mark = strdup(argv[3]);
+ if (type >= 9) {
+ if (target->marks)
+ for (ii=0; ii<target->marks->used; ii++)
+ if (!irccasecmp(target->marks->list[ii], argv[3]))
+ markfound = 1;
+ if (!markfound)
+ {
+ if (!target->marks)
+ target->marks = alloc_string_list(1);
+ string_list_append(target->marks, strdup(argv[3]));
+ }
+ } else
+ target->mark = strdup(argv[3]);
return 1;
}
* Ghost response to a KILL we sent out earlier. So we only
* whine if the target is local.
*/
- if (!strncmp(argv[1], self->numeric, strlen(self->numeric)))
+ if (!strncmp(argv[1], self->numeric, strlen(self->numeric))) {
log_module(MAIN_LOG, LOG_ERROR, "Unable to find kill victim %s", argv[1]);
- return 0;
+ return 0;
+ }
+ return 1;
}
if (IsLocal(user) && IsService(user)) {
dict_insert(irc_func_dict, CMD_RPONG, cmd_dummy);
dict_insert(irc_func_dict, TOK_RPONG, cmd_dummy);
+ dict_insert(irc_func_dict, CMD_SASL, cmd_sasl);
+ dict_insert(irc_func_dict, TOK_SASL, cmd_sasl);
+
/* In P10, DESTRUCT doesn't do anything except be broadcast to servers.
* Apparently to obliterate channels from any servers that think they
* exist?
if (!hostname)
hostname = self->name;
make_numeric(self, local_num, numeric);
- return AddUser(self, nick, ident, hostname, modes, numeric, desc, now, "AAAAAA");
+ return AddUser(self, nick, ident, hostname, modes, numeric, desc, timestamp, "AAAAAA");
}
struct userNode *
free(user->mark);
user->mark = NULL;
}
+ free_string_list(user->marks);
+ user->marks = NULL;
/* clean up geoip data if any */
if(user->country_code) free(user->country_code);