irc_user(struct userNode *user)
{
char b64ip[25];
- if (!user || IsDummy(user))
+ if (!user)
return;
irc_p10_ntop(b64ip, &user->ip);
if (user->modes) {
modes[modelen++] = 'd';
if (IsGlobal(user))
modes[modelen++] = 'g';
+ // sethost - reed/apples
+ // if (IsHelperIrcu(user))
if (IsSetHost(user))
modes[modelen++] = 'h';
if (IsFakeHost(user))
modes[modelen++] = 'f';
if (IsHiddenHost(user))
modes[modelen++] = 'x';
- if (IsNoChan(user))
- modes[modelen++] = 'n';
- if (IsNoIdle(user))
- modes[modelen++] = 'I';
modes[modelen] = 0;
/* we don't need to put the + in modes because it's in the format string. */
putsock("%s " P10_WALLOPS " :%s", self->numeric, buffer);
}
-static int
-deliver_to_dummy(struct userNode *source, struct userNode *dest, const char *message, int type)
-{
- unsigned int num;
-
- if (!dest || !IsDummy(dest) || !IsLocal(dest))
- return 0;
- num = dest->num_local;
- switch (type) {
- default:
- if ((num < num_notice_funcs) && notice_funcs[num])
- notice_funcs[num](source, dest, message, 0);
- break;
- case 1:
- if ((num < num_privmsg_funcs) && privmsg_funcs[num])
- privmsg_funcs[num](source, dest, message, 0);
- break;
- }
- return 1;
-}
void
irc_notice(struct userNode *from, const char *to, const char *message)
{
- if (to[0] == '#' || to[0] == '$'
- || !deliver_to_dummy(from, GetUserN(to), message, 0))
putsock("%s " P10_NOTICE " %s :%s", from->numeric, to, message);
}
void
irc_notice_user(struct userNode *from, struct userNode *to, const char *message)
{
- if (!deliver_to_dummy(from, to, message, 0))
putsock("%s " P10_NOTICE " %s :%s", from->numeric, to->numeric, message);
}
void
irc_privmsg(struct userNode *from, const char *to, const char *message)
{
- if (to[0] == '#' || to[0] == '$'
- || !deliver_to_dummy(from, GetUserN(to), message, 1))
putsock("%s " P10_PRIVMSG " %s :%s", from->numeric, to, message);
}
void
irc_gline(struct server *srv, struct gline *gline, int silent)
{
- if (gline->lastmod)
- putsock("%s " P10_GLINE " %s +%s %ld %ld :%s",
- self->numeric, (srv ? srv->numeric : "*"), gline->target, gline->expires-now, gline->lastmod, gline->reason);
- else
putsock("%s " P10_GLINE " %s +%s %ld :%s<%s> %s",
self->numeric, (srv ? srv->numeric : "*"), gline->target, gline->expires-now, silent ? "AUTO " : "", gline->issuer, gline->reason);
}
void
irc_shun(struct server *srv, struct shun *shun)
{
- if (shun->lastmod)
- putsock("%s " P10_SHUN " %s +%s %ld %ld :%s",
- self->numeric, (srv ? srv->numeric : "*"), shun->target, shun->expires-now, shun->lastmod, shun->reason);
- else
putsock("%s " P10_SHUN " %s +%s %ld :<%s> %s",
self->numeric, (srv ? srv->numeric : "*"), shun->target, shun->expires-now, shun->issuer, shun->reason);
}
{
struct userNode *from;
struct userNode *who;
- char buf[MAXLEN];
- unsigned int i, mlen, len;
if (argc < 3)
return 0;
irc_numeric(from, ERR_NOSUCHNICK, "%s@%s :No such nick", argv[2], self->name);
return 1;
}
-
- if (IsFakeHost(who) && IsHiddenHost(who))
- irc_numeric(from, RPL_WHOISUSER, "%s %s %s * :%s", who->nick, who->ident, who->fakehost, who->info);
- else if (IsHiddenHost(who) && who->handle_info && hidden_host_suffix)
- irc_numeric(from, RPL_WHOISUSER, "%s %s %s.%s * :%s", who->nick, who->ident, who->handle_info->handle, hidden_host_suffix, who->info);
- else
- irc_numeric(from, RPL_WHOISUSER, "%s %s %s * :%s", who->nick, who->ident, who->hostname, who->info);
-
- if ((!IsService(who) && !IsNoChan(who)) || (from == who)) {
- struct modeNode *mn;
- mlen = strlen(self->name) + strlen(from->nick) + 12 + strlen(who->nick);
- len = 0;
- *buf = '\0';
- for (i = who->channels.used; i > 0; )
- {
- mn = who->channels.list[--i];
-
- if (!IsOper(from) && (mn->channel->modes & (MODE_PRIVATE | MODE_SECRET)) && !GetUserMode(mn->channel, from))
- continue;
-
- if (len + strlen(mn->channel->name) + mlen > MAXLEN - 5)
- {
- irc_numeric(from, RPL_WHOISCHANNELS, "%s :%s", who->nick, buf);
- *buf = '\0';
- len = 0;
- }
-
- if (IsDeaf(who))
- *(buf + len++) = '-';
- if ((mn->channel->modes & (MODE_PRIVATE | MODE_SECRET)) && !GetUserMode(mn->channel, from))
- *(buf + len++) = '*';
- if (mn->modes & MODE_CHANOP)
- *(buf + len++) = '@';
- else if (mn->modes & MODE_VOICE)
- *(buf + len++) = '+';
-
- if (len)
- *(buf + len) = '\0';
- strcpy(buf + len, mn->channel->name);
- len += strlen(mn->channel->name);
- strcat(buf + len, " ");
- len++;
- }
- if (buf[0] != '\0')
- irc_numeric(from, RPL_WHOISCHANNELS, "%s :%s", who->nick, buf);
+ if (IsHiddenHost(who) && !IsOper(from)) {
+ /* Just stay quiet. */
+ return 1;
}
-
- if (his_servername && his_servercomment && !IsOper(from) && from != who)
+ 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);
else
irc_numeric(from, RPL_WHOISSERVER, "%s %s :%s", who->nick, who->uplink->name, who->uplink->description);
-
- if (IsAway(who))
- irc_numeric(from, RPL_AWAY, "%s :Away", who->nick);
-
if (IsOper(who))
- irc_numeric(from, RPL_WHOISOPERATOR, "%s :%s", who->nick, IsLocal(who) ? "is a megalomaniacal power hungry tyrant" : "is an IRC Operator");
- if (who->handle_info)
- irc_numeric(from, RPL_WHOISACCOUNT, "%s %s :is logged in as", who->nick, who->handle_info->handle);
- if (IsHiddenHost(who) && who->handle_info && (IsOper(from) || from == who))
- irc_numeric(from, RPL_WHOISACTUALLY, "%s %s@%s %s :Actual user@host, Actual IP", who->nick, who->ident, who->hostname, irc_ntoa(&who->ip));
- if (IsLocal(who) && !IsService(who) && (!IsNoIdle(who) || IsOper(from) || from == who))
- irc_numeric(from, RPL_WHOISIDLE, "%s %ld %ld :seconds idle, signon time", who->nick, now - who->idle_since, who->timestamp);
-
+ 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;
}
static char exemptlist[MAXLEN], banlist[MAXLEN];
unsigned int next = 3, res = 1;
int ctype = 0, echeck = 0, bcheck = 0;
+ struct chanData *cData;
struct chanNode *cNode;
struct userNode *un;
struct modeNode *mNode;
if ((*pos == 'k') || (*pos == 'l') || (*pos == 'A')
|| (*pos == 'U'))
n_modes++;
- if (next + n_modes > argc)
- n_modes = argc - next;
unsplit_string(argv+next, n_modes, modes);
next += n_modes;
break;
irc_burst(cNode);
}
cNode = AddChannel(argv[1], in_timestamp, modes, banlist, exemptlist);
+ cData = cNode->channel_info;
+
+ if (!cData) {
+ if (cNode->modes & MODE_REGISTERED) {
+ irc_join(opserv, cNode);
+ irc_mode(opserv, cNode, "-z");
+ irc_part(opserv, cNode, "");
+ }
+ }
/* Burst channel members in now. */
for (user = members, sep = *members, mode = 0; sep; user = end) {
/* DNSBL_DATA name */
target = GetUserH(argv[1]);
if(!target) {
- log_module(MAIN_LOG, LOG_ERROR, "Unable to find user %s whose mark is changing.", argv[1]);
+ 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]);
return 1;
}
+ else if(!strcasecmp(argv[2], "CVERSION")) {
+ /* DNSBL_DATA name */
+ target = GetUserH(argv[1]);
+ if(!target) {
+ log_module(MAIN_LOG, LOG_ERROR, "Unable to find user %s whose version mark is changing.", argv[1]);
+ return 0;
+ }
+
+ char *version = unsplit_string(argv + 3, argc - 3, NULL);
+ if(!version)
+ version = "";
+
+ target->version_reply = strdup(version);
+
+ if(match_ircglob(version, "WebTV;*"))
+ target->no_notice = true; /* webbies cant see notices */
+
+ return 1;
+ }
/* unknown type of mark */
return 1;
}
static CMD_FUNC(cmd_num_gline)
{
- time_t lastmod;
if (argc < 6)
return 0;
- lastmod = (argc > 5) ? strtoul(argv[5], NULL, 0) : 0;
- gline_add(origin, argv[3], atoi(argv[4])-now, argv[argc - 1], now, lastmod, 0, 0);
+ gline_add(origin, argv[3], atoi(argv[4])-now, argv[5], now, 0, 0);
return 1;
}
static CMD_FUNC(cmd_num_shun)
{
- time_t lastmod;
if (argc < 6)
return 0;
- lastmod = (argc > 5) ? strtoul(argv[5], NULL, 0) : 0;
- shun_add(origin, argv[3], atoi(argv[4])-now, argv[argc - 1], now, lastmod, 0);
+ shun_add(origin, argv[3], atoi(argv[4])-now, argv[5], now, 0);
return 1;
}
return 1;
}
+static CMD_FUNC(cmd_part)
+{
+ struct userNode *user;
+
+ if (argc < 2)
+ return 0;
+ user = GetUserH(origin);
+ if (!user)
+ return 0;
+ parse_foreach(argv[1], part_helper, NULL, NULL, NULL, user);
+ return 1;
+}
+
static CMD_FUNC(cmd_svspart)
{
struct userNode *user;
static CMD_FUNC(cmd_privmsg)
{
struct privmsg_desc pd;
- if (argc < 3)
+ if (argc != 3)
return 0;
pd.user = GetUserH(origin);
if (!pd.user || (IsGagged(pd.user) && !IsOper(pd.user)))
return 1; /* Silently Ignore */
pd.is_notice = 0;
- pd.text = argv[argc - 1];
+ pd.text = argv[2];
parse_foreach(argv[1], privmsg_chan_helper, NULL, privmsg_user_helper, privmsg_invalid, &pd);
return 1;
struct server *srv;
int nuser = 0;
- if (argc < 3)
+ if (argc != 3)
return 0;
pd.user = GetUserH(origin);
}
else {
pd.is_notice = 1;
- pd.text = argv[argc - 1];
+ pd.text = argv[2];
parse_foreach(argv[1], privmsg_chan_helper, NULL, privmsg_user_helper, privmsg_invalid, &pd);
}
static CMD_FUNC(cmd_gline)
{
- time_t lastmod;
-
if (argc < 3)
return 0;
if (argv[2][0] == '+') {
if (argc < 5)
return 0;
- lastmod = (argc > 5) ? strtoul(argv[5], NULL, 0) : 0;
- gline_add(origin, argv[2]+1, strtoul(argv[3], NULL, 0), argv[argc-1], now, lastmod, 0, 0);
+ gline_add(origin, argv[2]+1, strtoul(argv[3], NULL, 0), argv[argc-1], now, 0, 0);
return 1;
} else if (argv[2][0] == '-') {
gline_remove(argv[2]+1, 0);
static CMD_FUNC(cmd_shun)
{
- time_t lastmod;
if (argc < 3)
return 0;
if (argv[2][0] == '+') {
if (argc < 5)
return 0;
- lastmod = (argc > 5) ? strtoul(argv[5], NULL, 0) : 0;
- shun_add(origin, argv[2]+1, strtoul(argv[3], NULL, 0), argv[argc-1], now, lastmod, 0);
+ shun_add(origin, argv[2]+1, strtoul(argv[3], NULL, 0), argv[argc-1], now, 0);
return 1;
} else if (argv[2][0] == '-') {
shun_remove(argv[2]+1, 0);
unsigned int nn;
free(of_list);
free(privmsg_funcs);
- num_privmsg_funcs = 0;
free(notice_funcs);
- num_notice_funcs = 0;
free(mcf_list);
dict_delete(irc_func_dict);
for (nn=0; nn<dead_users.used; nn++)
free_user(dead_users.list[nn]);
userList_clean(&dead_users);
- free(his_servername);
- free(his_servercomment);
}
static void
}
struct userNode *
-AddLocalUser(const char *nick, const char *ident, const char *hostname, const char *desc, const char *modes)
+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();
time_t timestamp = now;
struct userNode *old_user = GetUserH(nick);
- if (!modes)
- modes = "+oik";
if (old_user) {
if (IsLocal(old_user))
return old_user;
if (!hostname)
hostname = self->name;
make_numeric(self, local_num, numeric);
- return AddUser(self, nick, ident, hostname, modes, 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 *
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)
{
struct userNode *oldUser, *uNode;
- unsigned int n, ignore_user, dummy;
+ unsigned int n, ignore_user;
+ char *tstr;
+ int type;
if ((strlen(numeric) < 3) || (strlen(numeric) > 5)) {
log_module(MAIN_LOG, LOG_WARNING, "AddUser(%p, %s, ...): numeric %s wrong length!", uplink, nick, numeric);
return NULL;
}
- dummy = modes && modes[0] == '*';
- if (dummy) {
- ++modes;
- } else if (!is_valid_nick(nick)) {
+ if (!is_valid_nick(nick)) {
log_module(MAIN_LOG, LOG_WARNING, "AddUser(%p, %s, ...): invalid nickname detected.", uplink, nick);
return NULL;
}
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);
+ tstr = conf_get_data("server/type", RECDB_QSTRING);
+ type = atoi(tstr);
+ if (type > 6) {
+ 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);
+ }
}
if (!uNode->crypthost && uNode->cryptip)
snprintf(uNode->crypthost, sizeof(uNode->crypthost), "%s", strdup(uNode->cryptip));
uNode->timestamp = timestamp;
- uNode->idle_since = timestamp;
modeList_init(&uNode->channels);
uNode->uplink = uplink;
if (++uNode->uplink->clients > uNode->uplink->max_clients) {
uNode->num_local = base64toint(numeric+strlen(uNode->uplink->numeric), 3) & uNode->uplink->num_mask;
uNode->uplink->users[uNode->num_local] = uNode;
mod_usermode(uNode, modes);
- if (dummy)
- uNode->modes |= FLAGS_DUMMY;
set_geoip_info(uNode);
/* remove user from all channels */
while (user->channels.used > 0)
- DelChannelUser(user, user->channels.list[user->channels.used-1]->channel, NULL, false);
+ DelChannelUser(user, user->channels.list[user->channels.used-1]->channel, false, 0);
/* Call these in reverse order so ChanServ can update presence
information before NickServ nukes the handle_info. */
if(user->region) free(user->region);
if(user->postal_code) free(user->postal_code);
- if (IsLocal(user)) {
- unsigned int num = user->num_local;
- if (num < num_privmsg_funcs)
- privmsg_funcs[num] = NULL;
- if (num < num_notice_funcs)
- notice_funcs[num] = NULL;
- }
-
/* We don't free them, in case we try to privmsg them or something
* (like when a stupid oper kills themself). We just put them onto
* a list of clients that get freed after processing each line.
case 'd': do_user_mode(FLAGS_DEAF); break;
case 'k': do_user_mode(FLAGS_SERVICE); break;
case 'g': do_user_mode(FLAGS_GLOBAL); break;
+ // sethost - reed/apples
+ // case 'h': do_user_mode(FLAGS_HELPER); break;
+ // I check if there's an 'h' in the first part, and if there,
+ // then everything after the space becomes their new host.
+ case 'C': do_user_mode(FLAGS_CLOAKHOST);
+ if (*word) {
+ char cloakhost[MAXLEN];
+ unsigned int ii;
+ for (ii=0; (*word != ' ') && (*word != '\0'); )
+ cloakhost[ii++] = *word++;
+ cloakhost[ii] = 0;
+ while (*word == ' ')
+ word++;
+ safestrncpy(user->crypthost, cloakhost, sizeof(user->crypthost));
+ }
+ break;
+ case 'c': do_user_mode(FLAGS_CLOAKIP);
+ if (*word) {
+ char cloakip[MAXLEN];
+ unsigned int ii;
+ for (ii=0; (*word != ' ') && (*word != '\0'); )
+ cloakip[ii++] = *word++;
+ cloakip[ii] = 0;
+ while (*word == ' ')
+ word++;
+ safestrncpy(user->cryptip, cloakip, sizeof(user->cryptip));
+ }
+ break;
case 'h': do_user_mode(FLAGS_SETHOST);
if (*word) {
char sethost[MAXLEN];
safestrncpy(user->sethost, sethost, sizeof(user->sethost));
}
break;
- case 'n': do_user_mode(FLAGS_NOCHAN); break;
- case 'I': do_user_mode(FLAGS_NOIDLE); break;
case 'x': do_user_mode(FLAGS_HIDDEN_HOST); break;
case 'r':
if (*word) {
mod_chanmode_append(&chbuf, 'k', channel->key);
if (change->modes_clear & channel->modes & MODE_UPASS)
mod_chanmode_append(&chbuf, 'U', channel->upass);
- if (change->modes_clear & channel->modes & MODE_APASS)
+ if (change->modes_clear * channel->modes & MODE_APASS)
mod_chanmode_append(&chbuf, 'A', channel->apass);
}
for (arg = 0; arg < change->argc; ++arg) {
{
unsigned int numeric = user->num_local;
if (numeric >= num_privmsg_funcs) {
- int newnum = numeric + 8, ii;
+ int newnum = numeric + 8;
privmsg_funcs = realloc(privmsg_funcs, newnum*sizeof(privmsg_func_t));
- for (ii = num_privmsg_funcs; ii < newnum; ++ii)
- privmsg_funcs[ii] = NULL;
+ memset(privmsg_funcs+num_privmsg_funcs, 0, (newnum-num_privmsg_funcs)*sizeof(privmsg_func_t));
num_privmsg_funcs = newnum;
}
if (privmsg_funcs[numeric])
}
void
-unreg_privmsg_func(struct userNode *user)
+unreg_privmsg_func(struct userNode *user, privmsg_func_t handler)
{
- if (!IsLocal(user) || user->num_local >= num_privmsg_funcs)
+ unsigned int x;
+
+ if (!user || handler)
return; /* this really only works with users */
- privmsg_funcs[user->num_local] = NULL;
+ memset(privmsg_funcs+user->num_local, 0, sizeof(privmsg_func_t));
+
+ for (x = user->num_local+1; x < num_privmsg_funcs; x++)
+ memmove(privmsg_funcs+x-1, privmsg_funcs+x, sizeof(privmsg_func_t));
+
+ privmsg_funcs = realloc(privmsg_funcs, num_privmsg_funcs*sizeof(privmsg_func_t));
+ num_privmsg_funcs--;
}
{
unsigned int numeric = user->num_local;
if (numeric >= num_notice_funcs) {
- int newnum = numeric + 8, ii;
+ int newnum = numeric + 8;
notice_funcs = realloc(notice_funcs, newnum*sizeof(privmsg_func_t));
- for (ii = num_privmsg_funcs; ii < newnum; ++ii)
- privmsg_funcs[ii] = NULL;
+ memset(notice_funcs+num_notice_funcs, 0, (newnum-num_notice_funcs)*sizeof(privmsg_func_t));
num_notice_funcs = newnum;
}
if (notice_funcs[numeric])
}
void
-unreg_notice_func(struct userNode *user)
+unreg_notice_func(struct userNode *user, privmsg_func_t handler)
{
- if (!IsLocal(user) || user->num_local >= num_privmsg_funcs)
+ unsigned int x;
+
+ if (!user || handler)
return; /* this really only works with users */
- notice_funcs[user->num_local] = NULL;
+ memset(notice_funcs+user->num_local, 0, sizeof(privmsg_func_t));
+
+ for (x = user->num_local+1; x < num_notice_funcs; x++)
+ memmove(notice_funcs+x-1, notice_funcs+x, sizeof(privmsg_func_t));
+
+ memset(notice_funcs+user->num_local, 0, sizeof(privmsg_func_t));
+ notice_funcs = realloc(notice_funcs, num_notice_funcs*sizeof(privmsg_func_t));
+ num_notice_funcs--;
}
void