inttobase64(extranum, srv->num_mask, (srv->numeric[1] || (srv->num_mask >= 64*64)) ? 3 : 2);
if (srv == self) {
/* The +s, ignored by Run's ircu, means "service" to Undernet's ircu */
- putsock(P10_SERVER " %s %d %li %li J10 %s%s +s :%s",
+ putsock(P10_SERVER " %s %d %li %li J10 %s%s +s6 :%s",
srv->name, srv->hops+1, srv->boot, srv->link, srv->numeric, extranum, srv->description);
} else {
- putsock("%s " P10_SERVER " %s %d %li %li %c10 %s%s +s :%s",
+ putsock("%s " P10_SERVER " %s %d %li %li %c10 %s%s +s6 :%s",
self->numeric, srv->name, srv->hops+1, srv->boot, srv->link, (srv->self_burst ? 'J' : 'P'), srv->numeric, extranum, srv->description);
}
}
unsigned int value;
memset(ip, 0, 6 * sizeof(ip->in6[0]));
value = base64toint(input, 6);
+ if (value)
+ ip->in6[5] = htons(65535);
ip->in6[6] = htons(value >> 16);
ip->in6[7] = htons(value & 65535);
} else {
static void
irc_p10_ntop(char *output, const irc_in_addr_t *ip)
{
- if (irc_in_addr_is_ipv4(*ip)) {
+ if (!irc_in_addr_is_valid(*ip)) {
+ strcpy(output, "AAAAAA");
+ } else if (irc_in_addr_is_ipv4(*ip)) {
unsigned int in4;
in4 = (ntohs(ip->in6[6]) << 16) | ntohs(ip->in6[7]);
inttobase64(output, in4, 6);
putsock("%s " P10_PONG " %s :%s", self->numeric, who, data);
}
+void
+irc_pong_asll(const char *who, const char *orig_ts)
+{
+ char *delim;
+ struct timeval orig;
+ struct timeval now;
+ int diff;
+
+ orig.tv_sec = strtoul(orig_ts, &delim, 10);
+ orig.tv_usec = (*delim == '.') ? strtoul(delim + 1, NULL, 10) : 0;
+ gettimeofday(&now, NULL);
+ diff = (now.tv_sec - orig.tv_sec) * 1000 + (now.tv_usec - orig.tv_usec) / 1000;
+ putsock("%s " P10_PONG " %s %s %d " FMT_TIME_T ".%06u", self->numeric, who, orig_ts, diff, now.tv_sec, (unsigned)now.tv_usec);
+}
+
void
irc_pass(const char *passwd)
{
struct server *srv;
struct userNode *un;
- if(argc > 3)
- irc_pong(argv[2], argv[1]);
+ if (argc > 3)
+ irc_pong_asll(argv[2], argv[3]);
else if ((srv = GetServerH(origin)))
irc_pong(self->name, srv->numeric);
else if ((un = GetUserH(origin)))
struct create_desc {
struct userNode *user;
- int oplevel;
time_t when;
};
join_helper(struct chanNode *chan, void *data)
{
struct create_desc *cd = data;
- struct modeNode *mNode;
-
- mNode = AddChannelUser(cd->user, chan);
- mNode->oplevel = cd->oplevel;
- if (mNode->oplevel >= 0)
- mNode->modes |= MODE_CHANOP;
+ AddChannelUser(cd->user, chan);
}
static void
parse_foreach(char *target_list, foreach_chanfunc cf, foreach_nonchan nc, foreach_userfunc uf, foreach_nonuser nu, void *data)
{
char *j, old;
- char *cPos, *hPos;
- int oplevel;
do {
j = target_list;
old = *j;
*j = 0;
- hPos = strchr(target_list,'#');
- cPos = strchr(target_list,':');
-
- /*
- * Check if both a '#' and a ':' is in the target's name
- * and if cPos < hPos.
- * If that's the case, voila, we've found a join with an oplevel
- */
- if (hPos && cPos && (cPos < hPos))
- {
- oplevel = parse_oplevel(target_list);
- target_list = hPos + 1;
- }
- else
- oplevel = -1;
-
if (IsChannelName(target_list)
|| (target_list[0] == '0' && target_list[1] == '\0')) {
struct chanNode *chan = GetChannel(target_list);
- struct create_desc *cd = (struct create_desc*) data;
- cd->oplevel = oplevel;
if (chan) {
if (cf)
cf(chan, data);
}
struct mod_chanmode *
-mod_chanmode_parse(struct chanNode *channel, char **modes, unsigned int argc, unsigned int flags)
+mod_chanmode_parse(struct chanNode *channel, char **modes, unsigned int argc, unsigned int flags, short base_oplevel)
{
struct mod_chanmode *change;
unsigned int ii, in_arg, ch_arg, add;
int oplevel;
oplevel_str = strchr(modes[in_arg], ':');
-
- /* XXYYY M #channel +o XXYYY:<oplevel> */
if (oplevel_str)
{
- oplevel = parse_oplevel(oplevel_str+1);
- *oplevel_str = 0;
+ /* XXYYY M #channel +o XXYYY:<oplevel> */
+ *oplevel_str++ = '\0';
+ oplevel = parse_oplevel(oplevel_str);
+ if (oplevel <= base_oplevel && !(flags & MCP_FROM_SERVER))
+ oplevel = base_oplevel + 1;
}
else if (channel->modes & MODE_UPASS)
- {
- /* TODO: need to set oplevel based on issuer's oplevel */
- oplevel = -1;
- }
+ oplevel = base_oplevel + 1;
else
oplevel = -1;
+ /* Check that oplevel is within bounds. */
+ if (oplevel > MAXOPLEVEL)
+ oplevel = MAXOPLEVEL;
+
if (!(flags & MCP_ALLOW_OVB))
goto error;
if (in_arg >= argc)