log_module(MAIN_LOG, LOG_INFO, "Connecting to %s:%i...", addr, port);
- socket_io_fd = ioset_connect((struct sockaddr*)cManager.uplink->bind_addr, sizeof(struct sockaddr), addr, port, 1, 0, NULL);
+ socket_io_fd = ioset_connect(cManager.uplink->bind_addr, cManager.uplink->bind_addr_len, addr, port, 1, 0, NULL);
if (!socket_io_fd) {
log_module(MAIN_LOG, LOG_ERROR, "Connection to uplink failed: %s (%d)", strerror(errno), errno);
target->state = DISCONNECTED;
mn->idle_since = now;
/* Never send a NOTICE to a channel to one of the services */
- if (!pd->is_notice && cf->func && GetUserMode(cn, cf->service))
+ if (!pd->is_notice && cf->func
+ && ((cn->modes & MODE_REGISTERED) || GetUserMode(cn, cf->service)))
cf->func(pd->user, cn, pd->text+1, cf->service);
/* This catches *all* text sent to the channel that the services server sees */
for (x = 0; x < ALLCHANMSG_FUNCS_MAX; x++) {
cf = (struct chanmsg_func *)&allchanmsg_funcs[x];
if (!cf->func)
- break; /* end of list */
+ break; /* end of list */
else
- cf->func(pd->user, cn, pd->text, cf->service);
+ cf->func(pd->user, cn, pd->text, cf->service);
}
}
* to be more specific than an existing ban.
*/
for (jj=0; jj<channel->banlist.used; ++jj) {
- if (match_ircglobs(change->args[ii].hostmask, channel->banlist.list[jj]->ban)) {
- banList_remove(&channel->banlist, channel->banlist.list[jj]);
- free(channel->banlist.list[jj]);
+ bn = channel->banlist.list[jj];
+ if (match_ircglobs(change->args[ii].u.hostmask, bn->ban)) {
+ banList_remove(&channel->banlist, bn);
+ free(bn);
jj--;
}
}
bn = calloc(1, sizeof(*bn));
- safestrncpy(bn->ban, change->args[ii].hostmask, sizeof(bn->ban));
+ safestrncpy(bn->ban, change->args[ii].u.hostmask, sizeof(bn->ban));
if (who)
safestrncpy(bn->who, who->nick, sizeof(bn->who));
else
break;
case MODE_REMOVE|MODE_BAN:
for (jj=0; jj<channel->banlist.used; ++jj) {
- if (strcmp(channel->banlist.list[jj]->ban, change->args[ii].hostmask))
+ bn = channel->banlist.list[jj];
+ if (strcmp(bn->ban, change->args[ii].u.hostmask))
continue;
- free(channel->banlist.list[jj]);
- banList_remove(&channel->banlist, channel->banlist.list[jj]);
+ free(bn);
+ banList_remove(&channel->banlist, bn);
break;
}
break;
case MODE_REMOVE|MODE_VOICE:
case MODE_REMOVE|MODE_VOICE|MODE_CHANOP:
if (change->args[ii].mode & MODE_REMOVE)
- change->args[ii].member->modes &= ~change->args[ii].mode;
+ change->args[ii].u.member->modes &= ~change->args[ii].mode;
else
- change->args[ii].member->modes |= change->args[ii].mode;
+ change->args[ii].u.member->modes |= change->args[ii].mode;
break;
default:
assert(0 && "Invalid mode argument");
}
int
-irc_make_chanmode(struct chanNode *chan, char *out) {
+irc_make_chanmode(struct chanNode *chan, char *out)
+{
struct mod_chanmode change;
mod_chanmode_init(&change);
change.modes_set = chan->modes;
char *
generate_hostmask(struct userNode *user, int options)
{
- char *nickname, *ident, *hostname;
- char *mask;
+ irc_in_addr_t ip;
+ char *nickname, *ident, *hostname, *mask;
int len, ii;
/* figure out string parts */
} else if (IsHiddenHost(user) && user->handle_info && hidden_host_suffix && !(options & GENMASK_NO_HIDING)) {
hostname = alloca(strlen(user->handle_info->handle) + strlen(hidden_host_suffix) + 2);
sprintf(hostname, "%s.%s", user->handle_info->handle, hidden_host_suffix);
- } else if (options & GENMASK_STRICT_HOST) {
- if (options & GENMASK_BYIP)
- hostname = inet_ntoa(user->ip);
- } else if ((options & GENMASK_BYIP) || !hostname[strspn(hostname, "0123456789.")]) {
- /* Should generate an IP-based hostmask. By popular acclaim, a /16
- * hostmask is used by default. */
- unsigned masked_ip, mask, masklen;
- masklen = 16;
- mask = ~0 << masklen;
- masked_ip = ntohl(user->ip.s_addr) & mask;
- hostname = alloca(32);
- if (options & GENMASK_SRVXMASK) {
- sprintf(hostname, "%d.%d.%d.%d/%d", (masked_ip>>24)&0xFF, (masked_ip>>16)&0xFF, (masked_ip>>8)&0xFF, masked_ip&0xFF, masklen);
+ } else if (options & GENMASK_STRICT_HOST && options & GENMASK_BYIP) {
+ hostname = (char*)irc_ntoa(&user->ip);
+ } else if ((options & GENMASK_BYIP) || irc_pton(&ip, NULL, hostname)) {
+ /* Should generate an IP-based hostmask. */
+ hostname = alloca(IRC_NTOP_MAX_SIZE);
+ hostname[IRC_NTOP_MAX_SIZE-1] = '\0';
+ if (irc_in_addr_is_ipv4(user->ip)) {
+ /* By popular acclaim, a /16 hostmask is used. */
+ sprintf(hostname, "%d.%d.*", user->ip.in6_8[12], user->ip.in6_8[13]);
+ } else if (irc_in_addr_is_ipv6(user->ip)) {
+ /* Who knows what the default mask should be? Use a /48 to start with. */
+ sprintf(hostname, "%x:%x:%x:*", user->ip.in6[0], user->ip.in6[1], user->ip.in6[2]);
} else {
- int ofs = 0;
- for (ii=0; ii<4; ii++) {
- if (masklen) {
- ofs += sprintf(hostname+ofs, "%d.", (masked_ip>>24)&0xFF);
- masklen -= 8;
- masked_ip <<= 8;
- } else {
- ofs += sprintf(hostname+ofs, "*.");
- }
- }
- /* Truncate the last . */
- hostname[ofs-1] = 0;
+ /* Unknown type; just copy IP directly. */
+ irc_ntop(hostname, IRC_NTOP_MAX_SIZE, &user->ip);
}
} else {
int cnt;