summary refs log blame commit diff stats
path: root/src/htm/Main.cs
blob: 67fcf32f314e187de2fae666730ca0f768296307 (plain) (tree)
8ec3e469 generated by cgit-pink 1.4.1 (git 2.36.1) at 2025-02-01 15:23:07 +0000
n> return; case 'h': if (!quiet) EMIT_SIGNAL (XP_TE_CHANDEHOP, sess, nick, arg, NULL, NULL, 0); return; case 'v': if (!quiet) mr->devoice = mode_cat (mr->devoice, arg); return; case 'b': if (!quiet) EMIT_SIGNAL (XP_TE_CHANUNBAN, sess, nick, arg, NULL, NULL, 0); return; case 'e': if (!quiet) EMIT_SIGNAL (XP_TE_CHANRMEXEMPT, sess, nick, arg, NULL, NULL, 0); return; case 'I': if (!quiet) EMIT_SIGNAL (XP_TE_CHANRMINVITE, sess, nick, arg, NULL, NULL, 0); return; case 'q': if (!supportsq) break; /* -q is owner on this server */ if (!quiet) EMIT_SIGNAL (XP_TE_CHANUNQUIET, sess, nick, arg, NULL, NULL, 0); return; } } fe_update_mode_buttons (sess, mode, sign); genmode: /* Received umode +e. If we're waiting to send JOIN then send now! */ if (mode == 'e' && sign == '+' && !serv->p_cmp (chan, serv->nick)) inbound_identified (serv); if (!quiet) { if (*arg) { char *buf = malloc (strlen (chan) + strlen (arg) + 2); sprintf (buf, "%s %s", chan, arg); EMIT_SIGNAL (XP_TE_CHANMODEGEN, sess, nick, outbuf, outbuf + 2, buf, 0); free (buf); } else EMIT_SIGNAL (XP_TE_CHANMODEGEN, sess, nick, outbuf, outbuf + 2, chan, 0); } } /* does this mode have an arg? like +b +l +o */ static int mode_has_arg (server * serv, char sign, char mode) { int type; /* if it's a nickmode, it must have an arg */ if (strchr (serv->nick_modes, mode)) return 1; type = mode_chanmode_type (serv, mode); switch (type) { case 0: /* type A */ case 1: /* type B */ return 1; case 2: /* type C */ if (sign == '+') return 1; case 3: /* type D */ return 0; default: return 0; } } /* what type of chanmode is it? -1 for not in chanmode */ static int mode_chanmode_type (server * serv, char mode) { /* see what numeric 005 CHANMODES=xxx said */ char *cm = serv->chanmodes; int type = 0; int found = 0; while (*cm && !found) { if (*cm == ',') { type++; } else if (*cm == mode) { found = 1; } cm++; } if (found) return type; /* not found? -1 */ else return -1; } static void mode_print_grouped (session *sess, char *nick, mode_run *mr) { /* print all the grouped Op/Deops */ if (mr->op) { EMIT_SIGNAL (XP_TE_CHANOP, sess, nick, mr->op, NULL, NULL, 0); free (mr->op); mr->op = NULL; } if (mr->deop) { EMIT_SIGNAL (XP_TE_CHANDEOP, sess, nick, mr->deop, NULL, NULL, 0); free (mr->deop); mr->deop = NULL; } if (mr->voice) { EMIT_SIGNAL (XP_TE_CHANVOICE, sess, nick, mr->voice, NULL, NULL, 0); free (mr->voice); mr->voice = NULL; } if (mr->devoice) { EMIT_SIGNAL (XP_TE_CHANDEVOICE, sess, nick, mr->devoice, NULL, NULL, 0); free (mr->devoice); mr->devoice = NULL; } } /* handle a MODE or numeric 324 from server */ void handle_mode (server * serv, char *word[], char *word_eol[], char *nick, int numeric_324) { session *sess; char *chan; char *modes; char *argstr; char sign; int len; int arg; int i, num_args; int num_modes; int offset = 3; int all_modes_have_args = FALSE; int using_front_tab = FALSE; mode_run mr; mr.serv = serv; mr.op = mr.deop = mr.voice = mr.devoice = NULL; /* numeric 324 has everything 1 word later (as opposed to MODE) */ if (numeric_324) offset++; chan = word[offset]; modes = word[offset + 1]; if (*modes == ':') modes++; if (*modes == 0) return; /* beyondirc's blank modes */ sess = find_channel (serv, chan); if (!sess) { sess = serv->front_session; using_front_tab = TRUE; } /* remove trailing space */ len = strlen (word_eol[offset]) - 1; if (word_eol[offset][len] == ' ') word_eol[offset][len] = 0; if (prefs.hex_irc_raw_modes && !numeric_324) EMIT_SIGNAL (XP_TE_RAWMODES, sess, nick, word_eol[offset], 0, 0, 0); if (numeric_324 && !using_front_tab) { if (sess->current_modes) free (sess->current_modes); sess->current_modes = strdup (word_eol[offset+1]); } sign = *modes; modes++; arg = 1; /* count the number of arguments (e.g. after the -o+v) */ num_args = 0; i = 1; while ((i + offset + 1) < PDIWORDS) { i++; if (!(*word[i + offset])) break; num_args++; } /* count the number of modes (without the -/+ chars */ num_modes = 0; i = 0; while (i < strlen (modes)) { if (modes[i] != '+' && modes[i] != '-') num_modes++; i++; } if (num_args == num_modes) all_modes_have_args = TRUE; while (*modes) { switch (*modes) { case '-': case '+': /* print all the grouped Op/Deops */ mode_print_grouped (sess, nick, &mr); sign = *modes; break; default: argstr = ""; if ((all_modes_have_args || mode_has_arg (serv, sign, *modes)) && arg < (num_args+1)) { arg++; argstr = word[arg + offset]; } handle_single_mode (&mr, sign, *modes, nick, chan, argstr, numeric_324 || prefs.hex_irc_raw_modes, numeric_324); } modes++; } /* update the title at the end, now that the mode update is internal now */ if (!using_front_tab) fe_set_title (sess); /* print all the grouped Op/Deops */ mode_print_grouped (sess, nick, &mr); } /* handle the 005 numeric */ void inbound_005 (server * serv, char *word[]) { int w; char *pre; w = 4; /* start at the 4th word */ while (w < PDIWORDS && *word[w]) { if (strncmp (word[w], "MODES=", 6) == 0) { serv->modes_per_line = atoi (word[w] + 6); } else if (strncmp (word[w], "CHANTYPES=", 10) == 0) { free (serv->chantypes); serv->chantypes = strdup (word[w] + 10); } else if (strncmp (word[w], "CHANMODES=", 10) == 0) { free (serv->chanmodes); serv->chanmodes = strdup (word[w] + 10); } else if (strncmp (word[w], "PREFIX=", 7) == 0) { pre = strchr (word[w] + 7, ')'); if (pre) { pre[0] = 0; /* NULL out the ')' */ free (serv->nick_prefixes); free (serv->nick_modes); serv->nick_prefixes = strdup (pre + 1); serv->nick_modes = strdup (word[w] + 8); } else { /* bad! some ircds don't give us the modes. */ /* in this case, we use it only to strip /NAMES */ serv->bad_prefix = TRUE; if (serv->bad_nick_prefixes) free (serv->bad_nick_prefixes); serv->bad_nick_prefixes = strdup (word[w] + 7); } } else if (strncmp (word[w], "WATCH=", 6) == 0) { serv->supports_watch = TRUE; } else if (strncmp (word[w], "MONITOR=", 8) == 0) { serv->supports_monitor = TRUE; } else if (strncmp (word[w], "NETWORK=", 8) == 0) { /* if (serv->networkname) free (serv->networkname); serv->networkname = strdup (word[w] + 8);*/ if (serv->server_session->type == SESS_SERVER) { safe_strcpy (serv->server_session->channel, word[w] + 8, CHANLEN); fe_set_channel (serv->server_session); } } else if (strncmp (word[w], "CASEMAPPING=", 12) == 0) { if (strcmp (word[w] + 12, "ascii") == 0) /* bahamut */ serv->p_cmp = (void *)g_ascii_strcasecmp; } else if (strncmp (word[w], "CHARSET=", 8) == 0) { if (g_ascii_strcasecmp (word[w] + 8, "UTF-8") == 0) { server_set_encoding (serv, "UTF-8"); } } else if (strcmp (word[w], "NAMESX") == 0) { /* 12345678901234567 */ tcp_send_len (serv, "PROTOCTL NAMESX\r\n", 17); } else if (strcmp (word[w], "WHOX") == 0) { serv->have_whox = TRUE; } else if (strcmp (word[w], "EXCEPTS") == 0) { #ifndef WIN32 serv->have_except = TRUE; #endif } else if (strcmp (word[w], "INVEX") == 0) { /* supports mode letter +I, default channel invite */ serv->have_invite = TRUE; } else if (strncmp (word[w], "ELIST=", 6) == 0) { /* supports LIST >< min/max user counts? */ if (strchr (word[w] + 6, 'U') || strchr (word[w] + 6, 'u')) serv->use_listargs = TRUE; } w++; } }