#define CMD_WHO "WHO"
#define CMD_WHOIS "WHOIS"
#define CMD_WHOWAS "WHOWAS"
+#define CMD_XQUERY "XQUERY"
+#define CMD_XRESPONSE "XRESPONSE"
/* Tokenized commands. */
#define TOK_ACCOUNT "AC"
#define TOK_WHO "H"
#define TOK_WHOIS "W"
#define TOK_WHOWAS "X"
+#define TOK_XQUERY "XQ"
+#define TOK_XRESPONSE "XR"
/* Protocol messages; aliased to full commands or tokens depending
on compile-time configuration. ircu prefers tokens WITH THE
#define P10_WHO TYPE(WHO)
#define P10_WHOIS TYPE(WHOIS)
#define P10_WHOWAS TYPE(WHOWAS)
+#define P10_XQUERY TYPE(XQUERY)
+#define P10_XRESPONSE TYPE(XRESPONSE)
/* Servers claiming to have a boot or link time before PREHISTORY
* trigger errors to the log. We hope no server has been running
putsock(":%s %03d %s %s", self->name, num, user->nick, buffer);
}
+void
+irc_xresponse(struct server *target, const char *routing, const char *response)
+{
+ putsock("%s " P10_XRESPONSE " %s %s :%s", self->numeric, target->numeric, routing, response);
+}
+
static void send_burst(void);
static void
static CMD_FUNC(cmd_topic)
{
struct chanNode *cn;
- unsigned long chan_ts, topic_ts;
+ unsigned long topic_ts;
if (argc < 3)
return 0;
}
if (argc >= 5) {
/* Looks like an Asuka style topic burst. */
- chan_ts = atoi(argv[2]);
topic_ts = atoi(argv[3]);
} else {
- chan_ts = cn->timestamp;
topic_ts = now;
}
SetChannelTopic(cn, GetUserH(origin), argv[argc-1], 0);
return 1;
}
+static CMD_FUNC(cmd_xquery)
+{
+ struct server *source;
+ if ((argc < 4)
+ || !(source = GetServerH(origin)))
+ return 0;
+ call_xquery_funcs(source, argv[2], argv[3]);
+ return 1;
+}
+
void
free_user(struct userNode *user)
{
dict_insert(irc_func_dict, TOK_ADMIN, cmd_admin);
dict_insert(irc_func_dict, CMD_TIME, cmd_time);
dict_insert(irc_func_dict, TOK_TIME, cmd_time);
+ /* We don't handle XR or the (not really defined) XQUERY. */
+ dict_insert(irc_func_dict, TOK_XQUERY, cmd_xquery);
/* In P10, DESTRUCT doesn't do anything except be broadcast to servers.
* Apparently to obliterate channels from any servers that think they
{
char numeric[COMBO_NUMERIC_LEN+1];
int local_num = get_local_numeric();
- unsigned long timestamp = now;
struct userNode *old_user = GetUserH(nick);
if (!modes)
if (old_user) {
if (IsLocal(old_user))
return old_user;
- timestamp = old_user->timestamp - 1;
}
if (local_num == -1) {
log_module(MAIN_LOG, LOG_ERROR, "Unable to allocate numnick for service %s", nick);
case 's': do_chan_mode(MODE_SECRET); break;
case 't': do_chan_mode(MODE_TOPICLIMIT); break;
case 'z':
- if (!(flags & MCP_REGISTERED)) {
+ if (!(flags & MCP_REGISTERED))
do_chan_mode(MODE_REGISTERED);
- } else {
- mod_chanmode_free(change);
- return NULL;
- }
break;
#undef do_chan_mode
case 'l':
mod_chanmode_format(struct mod_chanmode *change, char *outbuff)
{
unsigned int used = 0;
+ unsigned int args_used = 0;
+ char args[MAXLEN];
+
assert(change->argc <= change->alloc_argc);
if (change->modes_clear) {
outbuff[used++] = '-';
DO_MODE_CHAR(NOCOLORS, 'c');
DO_MODE_CHAR(NOCTCPS, 'C');
DO_MODE_CHAR(REGISTERED, 'z');
+ DO_MODE_CHAR(LIMIT, 'l'), args_used += sprintf(args + args_used, " %d", change->new_limit);
+ DO_MODE_CHAR(KEY, 'k'), args_used += sprintf(args + args_used, " %s", change->new_key);
+ DO_MODE_CHAR(UPASS, 'U'), args_used += sprintf(args + args_used, " %s", change->new_upass);
+ DO_MODE_CHAR(APASS, 'A'), args_used += sprintf(args + args_used, " %s", change->new_apass);
#undef DO_MODE_CHAR
- switch (change->modes_set & (MODE_KEY|MODE_LIMIT|MODE_APASS|MODE_UPASS)) {
- /* Doing this implementation has been a pain in the arse, I hope I didn't forget a possible combination */
- case MODE_KEY|MODE_LIMIT|MODE_APASS|MODE_UPASS:
- used += sprintf(outbuff+used, "lkAU %d %s %s %s", change->new_limit, change->new_key, change->new_apass, change->new_upass);
- break;
-
- case MODE_KEY|MODE_LIMIT|MODE_APASS:
- used += sprintf(outbuff+used, "lkA %d %s %s", change->new_limit, change->new_key, change->new_apass);
- break;
- case MODE_KEY|MODE_LIMIT|MODE_UPASS:
- used += sprintf(outbuff+used, "lkU %d %s %s", change->new_limit, change->new_key, change->new_upass);
- break;
- case MODE_KEY|MODE_APASS|MODE_UPASS:
- used += sprintf(outbuff+used, "kAU %s %s %s", change->new_key, change->new_apass, change->new_upass);
- break;
-
- case MODE_KEY|MODE_APASS:
- used += sprintf(outbuff+used, "kA %s %s", change->new_key, change->new_apass);
- break;
- case MODE_KEY|MODE_UPASS:
- used += sprintf(outbuff+used, "kU %s %s", change->new_key, change->new_upass);
- break;
- case MODE_KEY|MODE_LIMIT:
- used += sprintf(outbuff+used, "lk %d %s", change->new_limit, change->new_key);
- break;
- case MODE_LIMIT|MODE_UPASS:
- used += sprintf(outbuff+used, "lU %d %s", change->new_limit, change->new_upass);
- break;
- case MODE_LIMIT|MODE_APASS:
- used += sprintf(outbuff+used, "lA %d %s", change->new_limit, change->new_apass);
- break;
- case MODE_APASS|MODE_UPASS:
- used += sprintf(outbuff+used, "AU %s %s", change->new_apass, change->new_upass);
- break;
-
- case MODE_LIMIT|MODE_APASS|MODE_UPASS:
- used += sprintf(outbuff+used, "lAU %d %s %s", change->new_limit, change->new_apass, change->new_upass);
- break;
-
- case MODE_APASS:
- used += sprintf(outbuff+used, "A %s", change->new_apass);
- break;
- case MODE_UPASS:
- used += sprintf(outbuff+used, "U %s", change->new_upass);
- break;
- case MODE_KEY:
- used += sprintf(outbuff+used, "k %s", change->new_key);
- break;
- case MODE_LIMIT:
- used += sprintf(outbuff+used, "l %d", change->new_limit);
- break;
- }
}
- outbuff[used] = 0;
+ args[args_used] = '\0';
+ strcpy(outbuff + used, args);
return outbuff;
}