/* proto-p10.c - IRC protocol output
* Copyright 2000-2004 srvx Development Team
*
- * This file is part of srvx.
+ * This file is part of x3.
*
* srvx is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
}
void
-irc_account(struct userNode *user, const char *stamp)
+irc_account(struct userNode *user, const char *stamp, time_t timestamp)
{
- putsock("%s " P10_ACCOUNT " %s %s", self->numeric, user->numeric, stamp);
+ putsock("%s " P10_ACCOUNT " %s R %s %lu", self->numeric, user->numeric, stamp, timestamp);
}
void
}
irc_numeric(from, RPL_WHOISUSER, "%s %s %s * :%s", who->nick, who->ident, who->hostname, who->info);
if (his_servername && his_servercomment)
- irc_numeric(from, RPL_WHOISSERVER, "%s %s :%s", who->nick, his_servername, his_servercomment);
+ irc_numeric(from, RPL_WHOISSERVER, "%s %s :%s", who->nick, his_servername, his_servercomment);
else
- irc_numeric(from, RPL_WHOISSERVER, "%s %s :%s", who->nick, who->uplink->name, who->uplink->description);
-
- if (IsOper(who)) {
+ irc_numeric(from, RPL_WHOISSERVER, "%s %s :%s", who->nick, who->uplink->name, who->uplink->description);
+ if (IsOper(who))
irc_numeric(from, RPL_WHOISOPERATOR, "%s :is a megalomaniacal power hungry tyrant", who->nick);
- }
irc_numeric(from, RPL_ENDOFWHOIS, "%s :End of /WHOIS list", who->nick);
return 1;
}
if (argc < 8)
return 0;
- if (origin) {
+ if (self->uplink) {
/* another server introduced us */
srv = AddServer(GetServerH(origin), argv[1], atoi(argv[2]), atoi(argv[3]), atoi(argv[4]), argv[6], argv[argc-1]);
if (!srv)
static CMD_FUNC(cmd_account)
{
struct userNode *user;
+ struct server *server;
+ struct handle_info *hi;
- if ((argc < 3) || !origin || !GetServerH(origin))
+ if ((argc < 3) || !origin || !(server = GetServerH(origin)))
return 0; /* Origin must be server. */
+
+ /* This next line appears to tremple origin.. why? */
user = GetUserN(argv[1]);
if (!user)
return 1; /* A QUIT probably passed the ACCOUNT. */
- call_account_func(user, argv[2]);
+
+ if(!strcmp(argv[2],"C"))
+ {
+ if((hi = loc_auth(argv[4], argv[5])))
+ {
+ /* Return a AC A */
+ putsock("%s " P10_ACCOUNT " %s A %s %lu", self->numeric, server->numeric , argv[3], hi->registered);
+
+ }
+ else
+ {
+ /* Return a AC D */
+ putsock("%s " P10_ACCOUNT " %s D %s", self->numeric, server->numeric , argv[3]);
+ }
+ return 1;
+ }
+ else if(!strcmp(argv[2],"R"))
+ call_account_func(user, argv[3]);
+ else
+ call_account_func(user, argv[2]); /* For backward compatability */
return 1;
}
extern int rel_age;
char modes[MAXLEN], *members = "";
static char exemptlist[MAXLEN], banlist[MAXLEN];
- unsigned int next = 3;
- unsigned int res = 1;
+ unsigned int next = 3, res = 1;
int ctype = 0, echeck = 0, bcheck = 0;
struct chanNode *cNode;
struct userNode *un;
case '+': {
const char *pos;
int n_modes;
- for (pos=argv[next], n_modes = 1; *pos; pos++) {
+ for (pos=argv[next], n_modes = 1; *pos; pos++)
if ((*pos == 'k') || (*pos == 'l'))
n_modes++;
- }
unsplit_string(argv+next, n_modes, modes);
next += n_modes;
break;
next++;
break;
}
- default: {
- members = argv[next++];
- break;
- }
+ default: members = argv[next++]; break;
}
}
-
in_timestamp = atoi(argv[2]);
if ((cNode = dict_find(unbursted_channels, argv[1], NULL))) {
cNode->timestamp = in_timestamp;
dict_remove(unbursted_channels, cNode->name);
irc_burst(cNode);
}
-
- /* Burst channel members in now. */
cNode = AddChannel(argv[1], in_timestamp, modes, banlist, exemptlist);
+ /* Burst channel members in now. */
for (user = members, sep = *members, mode = 0; sep; user = end) {
for (end = user + 3; isalnum(*end) || *end == '[' || *end == ']'; end++) ;
sep = *end++; end[-1] = 0;
mode |= MODE_HALFOP;
else if (sep == 'v')
mode |= MODE_VOICE;
- else
+ else if (isdigit(sep)) {
+ mode |= MODE_CHANOP;
+ while (isdigit(*end)) end++;
+ } else
break;
}
if (rel_age < 0)
dict_insert(irc_func_dict, "401", cmd_dummy); /* target left network */
dict_insert(irc_func_dict, "403", cmd_dummy); /* no such channel */
dict_insert(irc_func_dict, "404", cmd_dummy); /* cannot send to channel */
+ dict_insert(irc_func_dict, "439", cmd_dummy); /* target change too fast */
dict_insert(irc_func_dict, "441", cmd_dummy); /* target isn't on that channel */
dict_insert(irc_func_dict, "442", cmd_dummy); /* you aren't on that channel */
dict_insert(irc_func_dict, "443", cmd_dummy); /* is already on channel (after invite?) */
}
struct userNode *
-AddService(const char *nick, const char *desc, const char *hostname)
+AddService(const char *nick, const char *modes, const char *desc, const char *hostname)
{
char numeric[COMBO_NUMERIC_LEN+1];
int local_num = get_local_numeric();
if (!hostname)
hostname = self->name;
make_numeric(self, local_num, numeric);
- return AddUser(self, nick, nick, hostname, "+oik", numeric, desc, now, "AAAAAA");
+ /* TODO: Make these modes part of the conf file */
+ return AddUser(self, nick, nick, hostname, modes ? modes : "+oik", numeric, desc, now, "AAAAAA");
}
struct userNode *
int
is_valid_nick(const char *nick) {
+ unsigned int ii;
/* IRC has some of The Most Fucked-Up ideas about character sets
* in the world.. */
if (!isalpha(*nick) && !strchr("{|}~[\\]^_`", *nick))
return 0;
- for (++nick; *nick; ++nick)
- if (!isalnum(*nick) && !strchr("{|}~[\\]^-_`", *nick))
+ for (ii = 0; nick[ii]; ++ii)
+ if (!isalnum(nick[ii]) && !strchr("{|}~[\\]^-_`", nick[ii]))
return 0;
if (strlen(nick) > nicklen)
return 0;
{
unsigned int n;
+ verify(user);
+
/* mark them as dead, in case anybody cares */
user->dead = 1;
if (!user || !mode_change)
return;
- while (*word != ' ' && *word) word++;\
- while (*word == ' ') word++; \
+ while (*word != ' ' && *word) word++;
+ while (*word == ' ') word++;
while (1) {
#define do_user_mode(FLAG) do { if (add) user->modes |= FLAG; else user->modes &= ~FLAG; } while (0)
switch (*mode_change++) {
case 'Q': do_chan_mode(MODE_NOQUITMSGS); break;
case 'T': do_chan_mode(MODE_NOAMSG); break;
case 'O': do_chan_mode(MODE_OPERSONLY); break;
+ case 'z':
+ if (!(flags & MCP_REGISTERED)) {
+ do_chan_mode(MODE_REGISTERED);
+ } else {
+ mod_chanmode_free(change);
+ return NULL;
+ }
+ break;
// uncomment this when ssl is enabled on the network.
-// case 'z': do_chan_mode(MODE_SSLONLY); break;
+// case 'Z': do_chan_mode(MODE_SSLONLY); break;
#undef do_chan_mode
case 'l':
if (add) {
change->args[ch_arg].mode = MODE_BAN;
if (!add)
change->args[ch_arg].mode |= MODE_REMOVE;
- change->args[ch_arg++].hostmask = modes[in_arg++];
+ change->args[ch_arg++].u.hostmask = modes[in_arg++];
break;
case 'e':
if (!(flags & MCP_ALLOW_OVB))
change->args[ch_arg].mode = MODE_EXEMPT;
if (!add)
change->args[ch_arg].mode |= MODE_REMOVE;
- change->args[ch_arg++].hostmask = modes[in_arg++];
+ change->args[ch_arg++].u.hostmask = modes[in_arg++];
break;
case 'o': case 'h': case 'v':
{
victim = GetUserH(modes[in_arg++]);
if (!victim)
continue;
- if ((change->args[ch_arg].member = GetUserMode(channel, victim)))
+ if ((change->args[ch_arg].u.member = GetUserMode(channel, victim)))
ch_arg++;
break;
}
DO_MODE_CHAR(NOQUITMSGS, 'Q');
DO_MODE_CHAR(NOAMSG, 'T');
DO_MODE_CHAR(OPERSONLY, 'O');
+ DO_MODE_CHAR(REGISTERED, 'z');
// uncomment this for ssl support
- //DO_MODE_CHAR(SSLONLY, 'z');
+ //DO_MODE_CHAR(SSLONLY, 'Z');
#undef DO_MODE_CHAR
if (change->modes_clear & channel->modes & MODE_KEY)
mod_chanmode_append(&chbuf, 'k', channel->key);
chbuf.modes[chbuf.modes_used++] = mode = '-';
switch (change->args[arg].mode & ~MODE_REMOVE) {
case MODE_BAN:
- mod_chanmode_append(&chbuf, 'b', change->args[arg].hostmask);
+ mod_chanmode_append(&chbuf, 'b', change->args[arg].u.hostmask);
break;
case MODE_EXEMPT:
- mod_chanmode_append(&chbuf, 'e', change->args[arg].hostmask);
+ mod_chanmode_append(&chbuf, 'e', change->args[arg].u.hostmask);
break;
default:
if (change->args[arg].mode & MODE_CHANOP)
- mod_chanmode_append(&chbuf, 'o', change->args[arg].member->user->numeric);
+ mod_chanmode_append(&chbuf, 'o', change->args[arg].u.member->user->numeric);
if (change->args[arg].mode & MODE_HALFOP)
- mod_chanmode_append(&chbuf, 'h', change->args[arg].member->user->numeric);
+ mod_chanmode_append(&chbuf, 'h', change->args[arg].u.member->user->numeric);
if (change->args[arg].mode & MODE_VOICE)
- mod_chanmode_append(&chbuf, 'v', change->args[arg].member->user->numeric);
+ mod_chanmode_append(&chbuf, 'v', change->args[arg].u.member->user->numeric);
break;
}
}
DO_MODE_CHAR(NOQUITMSGS, 'Q');
DO_MODE_CHAR(NOAMSG, 'T');
DO_MODE_CHAR(OPERSONLY, 'O');
+ DO_MODE_CHAR(REGISTERED, 'z');
// uncomment this for ssl support
- //DO_MODE_CHAR(SSLONLY, 'z');
+ //DO_MODE_CHAR(SSLONLY, 'Z');
#undef DO_MODE_CHAR
if(change->modes_set & MODE_KEY)
mod_chanmode_append(&chbuf, 'k', change->new_key);
chbuf.modes[chbuf.modes_used++] = mode = '+';
switch (change->args[arg].mode) {
case MODE_BAN:
- mod_chanmode_append(&chbuf, 'b', change->args[arg].hostmask);
+ mod_chanmode_append(&chbuf, 'b', change->args[arg].u.hostmask);
break;
case MODE_EXEMPT:
- mod_chanmode_append(&chbuf, 'e', change->args[arg].hostmask);
+ mod_chanmode_append(&chbuf, 'e', change->args[arg].u.hostmask);
break;
default:
if (change->args[arg].mode & MODE_CHANOP)
- mod_chanmode_append(&chbuf, 'o', change->args[arg].member->user->numeric);
+ mod_chanmode_append(&chbuf, 'o', change->args[arg].u.member->user->numeric);
if (change->args[arg].mode & MODE_HALFOP)
- mod_chanmode_append(&chbuf, 'h', change->args[arg].member->user->numeric);
+ mod_chanmode_append(&chbuf, 'h', change->args[arg].u.member->user->numeric);
if (change->args[arg].mode & MODE_VOICE)
- mod_chanmode_append(&chbuf, 'v', change->args[arg].member->user->numeric);
+ mod_chanmode_append(&chbuf, 'v', change->args[arg].u.member->user->numeric);
break;
}
}
DO_MODE_CHAR(NOQUITMSGS, 'Q');
DO_MODE_CHAR(NOAMSG, 'T');
DO_MODE_CHAR(OPERSONLY, 'O');
+ DO_MODE_CHAR(REGISTERED, 'z');
// uncomment this for ssl support
- //DO_MODE_CHAR(SSLONLY, 'z');
+ //DO_MODE_CHAR(SSLONLY, 'Z');
#undef DO_MODE_CHAR
}
if (change->modes_set) {
DO_MODE_CHAR(NOQUITMSGS, 'Q');
DO_MODE_CHAR(NOAMSG, 'T');
DO_MODE_CHAR(OPERSONLY, 'O');
+ DO_MODE_CHAR(REGISTERED, 'z');
// uncomment this for ssl support
- //DO_MODE_CHAR(SSLONLY, 'z');
+ //DO_MODE_CHAR(SSLONLY, 'Z');
#undef DO_MODE_CHAR
switch (change->modes_set & (MODE_KEY|MODE_LIMIT)) {
case MODE_KEY|MODE_LIMIT:
case 'Q': remove |= MODE_NOQUITMSGS; break;
case 'T': remove |= MODE_NOAMSG; break;
case 'O': remove |= MODE_OPERSONLY; break;
+ case 'z': remove |= MODE_REGISTERED; break;
}
}