/* * notice.c: special stuff for parsing NOTICEs * * Written By Michael Sandrof * * Copyright(c) 1991 * * See the COPYRIGHT file, or do a HELP IRCII COPYRIGHT */ #include "irc.h" static char cvsrevision[] = "$Id$"; CVS_REVISION(notice_c) #include "struct.h" #include "commands.h" #include "who.h" #include "ctcp.h" #include "window.h" #include "lastlog.h" #include "log.h" #include "flood.h" #include "vars.h" #include "ircaux.h" #include "hook.h" #include "ignore.h" #include "server.h" #include "funny.h" #include "output.h" #include "names.h" #include "parse.h" #include "notify.h" #include "misc.h" #include "screen.h" #include "status.h" #include "notice.h" #include "hash2.h" #include "cset.h" #include "input.h" #define MAIN_SOURCE #include "modval.h" extern char *FromUserHost; int doing_notice = 0; unsigned long default_swatch = -1; long oper_kills = 0, nick_collisions = 0, serv_fakes = 0, serv_unauth = 0, serv_squits = 0, serv_connects = 0, client_connects = 0, serv_rehash = 0, client_exits = 0, serv_klines = 0, client_floods = 0, client_invalid = 0, stats_req = 0, client_bot = 0, oper_requests = 0; #ifdef WANT_OPERVIEW extern void check_orig_nick(char *); static void handle_oper_vision(const char *from, const char *line) { char arg[4][IRCD_BUFFER_SIZE]; int up_status = 0; const unsigned long flags = get_server_ircop_flags(from_server); if (strbegins(line, "*** Notice --")) line += 14; else if (strbegins(line, "*** \002Notice\002 --")) line += 16; else if (strbegins(line, "*** ")) line += 4; /* [ss]!irc.cs.cmu.edu D-line active for think[think@skateboarders.edu] */ set_display_target(NULL, LOG_SNOTE); /* "Received KILL message for %s. From %s Path: %s (%s)" */ if (sscanf(line, "Received KILL message for %500[^.]. From %500s Path: %500s (%500[^)])", arg[0], arg[1], arg[2], arg[3]) == 4) { enum FSET_TYPES kill_fset; check_orig_nick(arg[0]); if (strchr(arg[1], '.')) { nick_collisions++; if (!(flags & NICK_COLLIDE)) goto done; kill_fset = FORMAT_SERVER_NOTICE_NICK_COLLISION_FSET; } else { oper_kills++; if (!(flags & NICK_KILL)) goto done; if (charcount(arg[2], '!') <= 2) kill_fset = FORMAT_SERVER_NOTICE_KILL_LOCAL_FSET; else kill_fset = FORMAT_SERVER_NOTICE_KILL_FSET; } serversay(from, "%s", convert_output_format(fget_string_var(kill_fset), "%s %s %s %s", update_clock(GET_TIME), arg[1], arg[0], arg[3])); up_status = 1; } /* hybrid: "Nick collision on %s(%s <- %s)(both killed)" * bahamut: "Nick collision on %s" * ircnet: "Nick collision on %s (%s@%s)%s <- (%s@%s)%s" * unreal: "Nick collision on %s (%s %ld <- %s %ld)" */ else if (arg[1][0] = 0, sscanf(line, "Nick collision on %500[^( ] %500[^\n]", arg[0], arg[1]) > 0) { nick_collisions++; if (!(flags & NICK_COLLIDE)) goto done; serversay(from, "%s", convert_output_format(fget_string_var(FORMAT_SERVER_NOTICE_NICK_COLLISION_FSET), "%s %s %s", update_clock(GET_TIME), arg[0], arg[1])); up_status = 1; } else if (sscanf(line, "IP# Mismatch: %500[^\n]", arg[0]) == 1) { if (!(flags & IP_MISMATCH)) goto done; serversay(from, "%s", convert_output_format("IP Mismatch %C$0-", "%s %s", arg[0])); } else if (sscanf(line, "Hacked ops on opless channel: %500s", arg[0]) == 1) { if (!(flags & HACK_OPS)) goto done; serversay(from, "%s", convert_output_format("Hacked ops on $0", "%s", arg[0])); } else if (sscanf(line, "connect failure: %500[^\n]", arg[0]) == 1) { client_connects++; client_exits++; if (!(flags & SERVER_CRAP)) goto done; serversay(from, "%s", convert_output_format("Connect failure %K[%n$0-%K]", "%s", arg[0])); } else if (sscanf(line, "Fake: %500s MODE %500[^\n]", arg[0], arg[1]) == 2) { serv_fakes++; if (!(flags & FAKE_MODE)) goto done; serversay(from, "%s", convert_output_format(fget_string_var(FORMAT_SERVER_NOTICE_FAKE_FSET), "%s %s MODE %s", update_clock(GET_TIME), arg[0], arg[1])); } /* "Unauthorized connection from %s." */ else if (sscanf(line, "Unauthorized connection from %500s", arg[0]) == 1) { serv_unauth++; if (!(flags & UNAUTHS)) goto done; chop(arg[0], 1); serversay(from, "%s", convert_output_format(fget_string_var(FORMAT_SERVER_NOTICE_UNAUTH_FSET), "%s %s", update_clock(GET_TIME), arg[0])); } /* "Too many connections from %s." */ else if (sscanf(line, "Too many connections from %500s", arg[0]) == 1) { serv_unauth++; if (!(flags & TOO_MANY)) goto done; chop(arg[0], 1); serversay(from, "%s", convert_output_format(fget_string_var(FORMAT_SERVER_NOTICE_UNAUTH_FSET), "%s %s", update_clock(GET_TIME), arg[0])); } /* hybrid-7/ratbox/ircnet/unreal: "%s is rehashing server config file" * hybrid-8: "%s is rehashing configuration file(s)" * bahamut: "%s is rehashing Server config file while whistling innocently" * ircu: "%s is rehashing Server config file" */ else if (sscanf(line, "%500s is rehashing Server config %500s", arg[0], arg[1]) == 2 || sscanf(line, "%500s is rehashing server config %500s", arg[0], arg[1]) == 2 || sscanf(line, "%500s is rehashing configuration %500s", arg[0], arg[1]) == 2) { serv_rehash++; if (!(flags & REHASH)) goto done; serversay(from, "%s", convert_output_format(fget_string_var(FORMAT_SERVER_NOTICE_REHASH_FSET), "%s %s", update_clock(GET_TIME), arg[0])); } /* hybrid/ratbox: "%s added K-Line for [%s@%s] [%s]" * bahamut: "%s added "LOCAL_BAN_NAME" for [%s@%s] [%s]" */ else if (sscanf(line, "%500s added %500s for [%500[^]]] [%500[^\n]", arg[0], arg[1], arg[2], arg[3]) == 4) { char oper[IRCD_BUFFER_SIZE]; char serv[IRCD_BUFFER_SIZE]; serv_klines++; if (!(flags & KLINE)) goto done; chop(arg[3], 1); /* hybrid/ratbox: get_oper_name() is "%s!%s@%s{%s}" */ if (sscanf(arg[0], "%100[^!]!%*[^@]@%*[^{]{%100s", oper, serv) == 2 && strchr(serv, '.')) { chop(serv, 1); serversay(from, "%s", convert_output_format(fget_string_var(FORMAT_SERVER_NOTICE_GLINE_FSET), "%s %s %s %s %s %s", update_clock(GET_TIME), oper, arg[2], serv, arg[1], arg[3])); } else serversay(from, "%s", convert_output_format(fget_string_var(FORMAT_SERVER_NOTICE_KLINE_FSET), "%s %s %s %s %s", update_clock(GET_TIME), arg[0], arg[2], arg[1], arg[3])); } /* "User %s (%s@%s) trying to join %s is a possible spambot" * "User %s (%s@%s) is a possible spambot" */ else if (sscanf(line, "User %500s (%500s is a possible spam%500s", arg[0], arg[1], arg[2]) == 3 || sscanf(line, "User %500s (%500s trying to join %*s is a possible spam%500s", arg[0], arg[1], arg[2]) == 3) { client_bot++; if (!(flags & POSSIBLE_BOT)) goto done; chop(arg[1], 1); serversay(from, "%s", convert_output_format(fget_string_var(FORMAT_SERVER_NOTICE_BOT_FSET), "%s %s %s", update_clock(GET_TIME), arg[0], arg[1])); } /* ircnet/ircu/bahamut: "%s (%s@%s) is now operator (%c)" * hybrid-7/ratbox: "%s (%s@%s) is now an operator" * hybrid-8: "%s!%s@%s{%s} is now an operator" */ else if (sscanf(line, "%500s (%500s is now oper%500s", arg[0], arg[1], arg[2]) == 3 || sscanf(line, "%500s (%500s is now an oper%500s", arg[0], arg[1], arg[2]) == 3 || sscanf(line, "%500[^!]!%500s is now an oper%500s", arg[0], arg[1], arg[2]) == 3) { size_t len; oper_requests++; if (!(flags & OPER_MODE)) goto done; len = strlen(arg[1]); if (arg[1][len - 1] == ')') arg[1][len - 1] = 0; serversay(from, "%s", convert_output_format(fget_string_var(FORMAT_OPER_FSET), "%s %s %s", update_clock(GET_TIME), arg[0], arg[1])); } /* "Received SQUIT %s from %s (%s)" */ else if (sscanf(line, "Received SQUIT %500s from %500s (%500[^\n]", arg[0], arg[1], arg[2]) == 3) { serv_squits++; if (!(flags & SQUIT)) goto done; chop(arg[2], 1); serversay(from, "%s", convert_output_format("SQUIT of $1 from $2 %K[%R$3-%K]", "%s %s %s %s", update_clock(GET_TIME), arg[0], arg[1], arg[2])); } /* "Received SERVER %s from %s (%d %s)" */ else if (sscanf(line, "Received SERVER %500s from %500s (%500[^\n]", arg[0], arg[1], arg[2]) == 3) { serv_connects++; if (!(flags & SERVER_CONNECT)) goto done; chop(arg[2], 1); serversay(from, "%s", convert_output_format("Received SERVER %c$1%n from %c$2%n %K[%W$3-%K]", "%s %s %s %s", update_clock(GET_TIME), arg[0], arg[1], arg[2])); } /* "Sending SQUIT %s (%s)" */ else if (sscanf(line, "Sending SQUIT %500s (%500[^\n]", arg[0], arg[1]) == 2) { serv_squits++; if (!(flags & SQUIT)) goto done; chop(arg[1], 1); serversay(from, "%s", convert_output_format("Sending SQUIT %c$1%n %K[%R$2-%K]", "%s %s %s", update_clock(GET_TIME), arg[0], arg[1])); } /* "Remote CONNECT %s %d from %s" */ else if (sscanf(line, "Remote CONNECT %500s %500s from %500s", arg[0], arg[1], arg[2]) == 3) { serv_connects++; if (!(flags & SERVER_CONNECT)) goto done; serversay(from, "%s", convert_output_format("Remote Connect of $1:$2 from $3", "%s %s %s %s", update_clock(GET_TIME), arg[0], arg[1], arg[2])); } /* hybrid-7, ratbox: "Client connecting: %s (%s@%s) [%s] {%s} [%s]" * hybrid-8: "Client connecting: %s (%s@%s) [%s] {%s} [%s] <%s>" * ircu: "Client connecting: %s (%s@%s) [%s] {%s} [%s] <%s%s>" * bahamut: "Client connecting: %s (%s@%s) [%s] {%s}" * unreal: "Client connecting on port %d: %s (%s@%s) [%s] %s%s%s" */ else if (sscanf(line, "Client connecting: %500s (%500[^)]) %500[^\n]", arg[0], arg[1], arg[2]) == 3 || sscanf(line, "Client connecting on port %*[^:]: %500s (%500[^)]) %500[^\n]", arg[0], arg[1], arg[2]) == 3) { client_connects++; if (!(flags & CLIENT_CONNECT)) goto done; serversay(from, "%s", convert_output_format(fget_string_var(FORMAT_SERVER_NOTICE_CLIENT_CONNECT_FSET), "%s %s %s %s", update_clock(GET_TIME), arg[0], arg[1], arg[2])); } /* hybrid, ratbox, bahamut: "Client exiting: %s (%s@%s) [%s] [%s]" * ircu: "Client exiting: %s (%s@%s) [%s] [%s] <%s%s>" * unreal: "Client exiting: %s (%s@%s) [%s]" */ else if (sscanf(line, "Client exiting: %500s (%500[^)]) %500[^\n]", arg[0], arg[1], arg[2]) == 3) { client_exits++; if (!(flags & CLIENT_CONNECT)) goto done; serversay(from, "%s", convert_output_format(fget_string_var(FORMAT_SERVER_NOTICE_CLIENT_EXIT_FSET), "%s %s %s %s", update_clock(GET_TIME), arg[0], arg[1], arg[2])); } /* bahamut: "Flood -- %s!%s@%s (%d) Exceeds %d RecvQ" * unreal: "Flood -- %s!%s@%s (%d) exceeds %d recvQ" */ else if (sscanf(line, "Flood -- %500s %500[^\n]", arg[0], arg[1]) == 2) { client_floods++; if (!(flags & TERM_FLOOD)) goto done; serversay(from, "%s", convert_output_format(fget_string_var(FORMAT_SERVER_NOTICE_CLIENT_TERM_FSET), "%s %s %s", update_clock(GET_TIME), arg[0], arg[1])); } /* !ircnet: "Invalid username: %s (%s@%s)" */ else if (sscanf(line, "Invalid username: %500s (%500[^)])", arg[0], arg[1]) == 2) { client_invalid++; if (!(flags & INVALID_USER)) goto done; serversay(from, "%s", convert_output_format(fget_string_var(FORMAT_SERVER_NOTICE_CLIENT_INVALID_FSET), "%s %s %s", update_clock(GET_TIME), arg[0], arg[1])); } /* ircnet: "Invalid username: %s@%s." */ else if (sscanf(line, "Invalid username: %500s", arg[0]) == 1) { client_invalid++; if (!(flags & INVALID_USER)) goto done; chop(arg[0], 1); serversay(from, "%s", convert_output_format(fget_string_var(FORMAT_SERVER_NOTICE_CLIENT_INVALID_FSET), "%s - %s", update_clock(GET_TIME), arg[0])); } /* "STATS %c requested by %s (%s@%s) [%s]" */ else if (sscanf(line, "STATS %500s requested by %500s (%500[^)]) [%500[^]]]", arg[0], arg[1], arg[2], arg[3]) == 4) { stats_req++; if (!(flags & STATS_REQUEST)) goto done; serversay(from, "%s", convert_output_format(fget_string_var(FORMAT_SERVER_NOTICE_STATS_FSET), "%s %s %s %s %s", update_clock(GET_TIME), arg[0], arg[1], arg[2], arg[3])); } else if (sscanf(line, "Nick flooding detected by: %500[^\n]", arg[0]) == 1) { if (!(flags & NICK_FLOODING)) goto done; serversay(from, "%s", convert_output_format("Nick Flooding %K[%B$1-%K]", "%s %s", update_clock(GET_TIME), arg[0])); } /* ircu: "K-line active for %s%s" * ircnet: "Kill line active for %s" */ else if (sscanf(line, "Kill line active for %500[^\n]", arg[0]) == 1 || sscanf(line, "K-line active for %500[^\n]", arg[0]) == 1) { if (!(flags & KILL_ACTIVE)) goto done; serversay(from, "%s", convert_output_format("Kill line for $1- active", "%s %s", update_clock(GET_TIME), arg[0])); } else { if (!(flags & SERVER_CRAP)) goto done; serversay(from, "%s", convert_output_format(fget_string_var(FORMAT_SERVER_NOTICE_FSET), "%s %s %s", update_clock(GET_TIME), from, stripansicodes(line))); } done: reset_display_target(); if (up_status) update_all_status(current_window, NULL, 0); } #endif static void parse_server_notice(const char *from, char *line) { int flag = 0; const char *f = from; if (!f || !*f) f = get_server_itsname(from_server); if (*line != '*' && *line != '#' && !strbegins(line, "MOTD")) flag = 1; else flag = 0; if (do_hook(SERVER_NOTICE_LIST, flag?"%s *** %s":"%s %s", f, line)) { #ifdef WANT_OPERVIEW handle_oper_vision(f, line); #else if (!flag) next_arg(line, &line); set_display_target(NULL, LOG_SNOTE); serversay(f, "%s", convert_output_format( fget_string_var(FORMAT_SERVER_NOTICE_FSET), "%s %s %s", update_clock(GET_TIME), f, stripansicodes(line))); reset_display_target(); #endif } } static int check_ignore_notice(char *from, char *to, unsigned long type, char *line, char **high) { int flag = check_ignore(from, FromUserHost, to, type, line); switch (flag) { case IGNORED: doing_notice = 0; break; case HIGHLIGHTED: *high = highlight_char; break; default: *high = empty_string; } return flag; } /* Check if a notice is a BitchX /WALL, and if so handle it as such. */ static int check_chanwall_notice(const char *from, const char *line, int type) { ChannelList *chan = NULL; char *line_copy; char *newline; char *channel = NULL, *p; if (!wild_match("[%Wall%/%] *", line)) return 0; line_copy = m_strdup(line); p = next_arg(line_copy, &newline); if ((p = strchr(p, '/'))) { p++; if (*p == BOLD_TOG) p++; channel = p; if ((p = strrchr(channel, ']'))) { *p = 0; if (p > channel && *(p-1) == BOLD_TOG) *(p-1) = 0; } } if (channel && *channel) chan = lookup_channel(channel, from_server, CHAN_NOUNLINK); if (!chan) { new_free(&line_copy); return 0; } set_display_target(channel, LOG_WALL); if (do_hook(type, "%s %s", from, line)) { char *s = convert_output_format(fget_string_var(FORMAT_BWALL_FSET), "%s %s %s %s %s", update_clock(GET_TIME), channel, from, FromUserHost, newline); add_to_log(chan->msglog_fp, now, s, logfile_line_mangler); put_it("%s", s); } add_last_type(&last_wall[0], 1, from, FromUserHost, NULL, line); logmsg(LOG_WALL, from, 0, "%s", line); /* addtabkey(from, "wall", 0);*/ new_free(&line_copy); return 1; } void parse_notice(char *from, char **Args) { int list_type; unsigned long ignore_type = IGNORE_NOTICES; unsigned long log_type = LOG_NOTICE; int flood_type = NOTICE_FLOOD; char *to, *high = empty_string, *target, *line; ChannelList *tmpc = NULL; PasteArgs(Args, 1); to = Args[0]; line = Args[1]; if (!to || !line) return; if (!*to) { put_it("*** obsolete notice received. [%s]", line+1); return; } /* An unprefixed NOTICE or one received before registration is assumed to * be from the local server. */ if (!from || !*from || !is_server_connected(from_server) || !strcmp(get_server_itsname(from_server), from)) { parse_server_notice(from, line); return; } if (is_channel(to)) { target = to; list_type = PUBLIC_NOTICE_LIST; if ((tmpc = lookup_channel(to, from_server, CHAN_NOUNLINK))) { NickList *nick = find_nicklist_in_channellist(from, tmpc, 0); update_stats(NOTICELIST, nick, tmpc, 0); } } else { target = from; if (my_stricmp(to, get_server_nickname(from_server))) { /* A NOTICE to a global destination like $$*.org */ log_type = LOG_WALL; ignore_type = IGNORE_WALLS; list_type = NOTICE_GROUP_LIST; flood_type = WALL_FLOOD; } else { list_type = NOTICE_LIST; } } set_display_target(target, log_type); doing_notice = 1; if ((check_ignore_notice(from, to, ignore_type, line, &high) == IGNORED)) goto notice_cleanup; if (!check_flooding(from, flood_type, line, NULL)) goto notice_cleanup; if (!strchr(from, '.') && list_type != NOTICE_GROUP_LIST) { notify_mark(from, FromUserHost, 1, 0); line = do_notice_ctcp(from, to, line); if (!*line) goto notice_cleanup; } if (!check_chanwall_notice(from, line, list_type)) { char *s; switch (list_type) { case PUBLIC_NOTICE_LIST: s = convert_output_format(fget_string_var(check_auto_reply(line)?FORMAT_PUBLIC_NOTICE_AR_FSET:FORMAT_PUBLIC_NOTICE_FSET), "%s %s %s %s %s", update_clock(GET_TIME), from, FromUserHost, to, line); break; case NOTICE_GROUP_LIST: s = convert_output_format(fget_string_var(FORMAT_NOTICE_GROUP_FSET), "%s %s %s %s", update_clock(GET_TIME), from, to, line); break; default: s = convert_output_format(fget_string_var(FORMAT_NOTICE_FSET), "%s %s %s %s", update_clock(GET_TIME), from, FromUserHost, line); } switch (list_type) { case PUBLIC_NOTICE_LIST: case NOTICE_GROUP_LIST: if (do_hook(list_type, "%s %s %s", from, to, line)) put_it("%s", s); break; default: if (do_hook(list_type, "%s %s", from, line)) put_it("%s", s); } if (tmpc) add_to_log(tmpc->msglog_fp, now, s, logfile_line_mangler); logmsg(log_type, from, 0, "%s", line); add_last_type(&last_notice[0], MAX_LAST_MSG, from, FromUserHost, to, line); } notice_cleanup: if (beep_on_level & log_type) beep_em(1); reset_display_target(); doing_notice = 0; } int loading_savefile = 0; void load_scripts(void) { extern char *new_script; static int done = 0; #if !defined(WINNT) && !defined(__EMX__) char buffer[BIG_BUFFER_SIZE+1]; int old_display = window_display; #endif if (!done++) { never_connected = 0; #if !defined(WINNT) && !defined(__EMX__) window_display = 0; sprintf(buffer, "%s/bxglobal", SCRIPT_PATH); loading_global = 1; load("LOAD", buffer, empty_string, NULL); loading_global = 0; window_display = old_display; #endif if (!quick_startup) { loading_savefile++; reload_save(NULL, NULL, empty_string, NULL); loading_savefile--; /* read the newscript/.bitchxrc/.ircrc file */ if (new_script && !access(new_script, R_OK)) load("LOAD", new_script, empty_string, NULL); else if (!access(bircrc_file, R_OK)) load("LOAD", bircrc_file, empty_string, NULL); else if (!access(ircrc_file, R_OK)) load("LOAD", ircrc_file, empty_string, NULL); } } if (get_server_away(from_server)) set_server_away(from_server, get_server_away(from_server), 1); } #define IGNORE_DONT 1 void setup_ov_mode(int on, int hide, int log) { #ifdef WANT_OPERVIEW char *default_oper = "wsckf"; Window *win = NULL; if (on) { if ((win = get_window_by_name("oper_view"))) { if (win->log) do_log(0, NULL, &win->log_fp); delete_window(win); update_all_windows(); set_input_prompt(current_window, get_string_var(INPUT_PROMPT_VAR), 0); cursor_to_input(); } send_to_server("MODE %s -%s%s", get_server_nickname(from_server), get_string_var(OPER_MODES_VAR)?get_string_var(OPER_MODES_VAR):default_oper, send_umode); } else { Window *tmp = NULL; win = current_window; if ((tmp = new_window(current_window->screen))) { malloc_strcpy(&tmp->name, "oper_view"); tmp->double_status = 0; if (hide) hide_window(tmp); else resize_window(1, tmp, -5); tmp->window_level = LOG_WALLOP|LOG_OPNOTE|LOG_SNOTE; tmp->absolute_size = 1; tmp->skip = 1; set_wset_string_var(tmp->wset, STATUS_FORMAT1_WSET, fget_string_var(FORMAT_OV_FSET)); build_status(tmp, NULL, 0); update_all_windows(); set_input_prompt(current_window, get_string_var(INPUT_PROMPT_VAR), 0); cursor_to_input(); send_to_server("MODE %s +%s", get_server_nickname(from_server), get_string_var(OPER_MODES_VAR)?get_string_var(OPER_MODES_VAR):default_oper); set_screens_current_window(win->screen, win); tmp->mangler = operlog_line_mangler; if (log != -1) { tmp->log = log; if (tmp->log) do_log(log, "~/.BitchX/operview.log", &tmp->log_fp); } } } #endif } #ifdef WANT_OPERVIEW char *opflags[] = {"COLLIDE", "KILLS", "MISMATCH", "HACK", "IDENTD", "FAKES", "UNAUTHS", "CLIENTS", "TRAFFIC", "REHASH", "KLINE", "BOTS", "OPER", "SQUIT", "SERVER", "CONNECT", "FLOOD", "USER", "STATS", "NICK", "ACTIVEK", "CRAP", NULL}; char all[] = "ALL", none[] = "NONE"; unsigned long ircop_str_to_flags(unsigned org_flags, char *str) { unsigned long flag = org_flags; int neg = 0; char *ptr; int i, j; while ((ptr = next_in_comma_list(str, &str))) { if (!ptr || !*ptr) return flag; switch(*ptr) { case '-': neg = IGNORE_DONT; ptr++; break; default: neg = 0; } upper(ptr); if (!strcmp(ptr, all)) { switch(neg) { case IGNORE_DONT: flag &= (~-1); break; default: flag = -1; break; } } if (!strcmp(ptr, none)) return 0; for (i = 0, j = 1; opflags[i]; i++, j <<= 1 ) { if (!strcmp(ptr, opflags[i])) { switch(neg) { case IGNORE_DONT: flag &= (~j); break; default: flag |= j; break; } break; } } } return flag; } char *ircop_flags_to_str(long flag, char *buffer, size_t len) { int i; buffer[0] = 0; for (i = 0; opflags[i]; i++) { if (flag & (1L << i)) { strlcat(buffer, opflags[i], len); strlcat(buffer, ",", len); } } return chop(buffer, 1); } void print_ircop_flags(int server) { char buffer[200]; long flag = get_server_ircop_flags(server); ircop_flags_to_str(flag, buffer, sizeof buffer); put_it("%s", convert_output_format("$G %bOper%BView%n: $0-", "%s", *buffer ? flag == -1 ? "ALL" : buffer : "NONE")); } void convert_swatch(Window *win, char *str, int unused) { unsigned long flag; char buffer[200]; if (from_server != -1) { flag = ircop_str_to_flags(get_server_ircop_flags(from_server), str); set_server_ircop_flags(from_server, flag); } else flag = ircop_str_to_flags(default_swatch, str); default_swatch = flag; ircop_flags_to_str(flag, buffer, sizeof buffer); set_string_var(SWATCH_VAR, buffer); } void set_operview_flags(int server, unsigned long flags, int neg) { unsigned long old_flags = get_server_ircop_flags(server); switch (neg) { case IGNORE_DONT: set_server_ircop_flags(server, old_flags & ~flags); break; default: set_server_ircop_flags(server, old_flags | flags); break; } } BUILT_IN_COMMAND(s_watch) { int gotargs = 0; unsigned long old_flags, flag; if (from_server == -1) { put_it("%s", convert_output_format("$G Try connecting to a server first", NULL, NULL)); return; } if (args && *args) gotargs = 1; old_flags = get_server_ircop_flags(from_server); flag = ircop_str_to_flags(old_flags, args); if (flag != old_flags) set_server_ircop_flags(from_server, flag); else if (gotargs && old_flags != -1) { int i; char buffer[BIG_BUFFER_SIZE]; strcpy(buffer, all); for (i = 0; opflags[i]; i++) { strlcat(buffer, space, sizeof buffer); strlcat(buffer, opflags[i], sizeof buffer); } strlcat(buffer, space, BIG_BUFFER_SIZE); strlcat(buffer, none, BIG_BUFFER_SIZE); bitchsay("You must specify from the following:"); put_it("\t%s", buffer); return; } print_ircop_flags(from_server); } extern int old_ov_mode; BUILT_IN_COMMAND(ov_window) { char *arg; int ov = get_int_var(OV_VAR); static int hide = DEFAULT_OPERVIEW_HIDE; int count = 0; int old_hide = hide; char *number = NULL; int log = 0; while ((arg = next_arg(args, &args))) { if (!my_stricmp(arg, on)) ov = 1; else if (!my_stricmp(arg, off)) ov = 0; else if (!my_stricmp(arg, "+HIDE")) hide = 1; else if (!my_stricmp(arg, "-HIDE")) hide = 0; else if (!my_stricmp(arg, "HIDE")) hide = 1; else if (!my_stricmp(arg, "GROW")) number = next_arg(args, &args); else if (!my_stricmp(arg, "LOG")) log ^= 1; count++; } if (count == 0) put_it("%s", convert_output_format("$G %BOper%bView%n is %K[%W$0%K]", "%s", on_off(get_int_var(OV_VAR)))); else { if ((!ov && get_int_var(OV_VAR)) || (ov && !get_int_var(OV_VAR))) { setup_ov_mode(ov ? 0 : 1, hide, log); old_ov_mode = ov; set_int_var(OV_VAR, ov); put_it("%s", convert_output_format("$G %BOper%bView%n is now toggled %K[%W$0%K]", "%s", on_off(get_int_var(OV_VAR)))); return; } if (get_int_var(OV_VAR) && old_hide != hide) { Window *tmp = get_window_by_name("oper_view"); Window *old_window = current_window; if (tmp) { if (!old_hide && hide) hide_window(tmp); else { show_window(tmp); resize_window(1, tmp, -5); } update_all_windows(); cursor_to_input(); if (old_window) set_screens_current_window(old_window->screen, old_window); } return; } if (hide == 0 && number && is_number(number)) { Window *tmp = get_window_by_name("oper_view"); if (tmp) resize_window(1, tmp, my_atol(number)); update_all_windows(); return; } put_it("%s", convert_output_format("$G %BOper%bView%n is already %K[%W$0%K]", "%s", on_off(get_int_var(OV_VAR)))); hide = old_hide; { char buffer[BIG_BUFFER_SIZE] = "~/.BitchX/operview.log"; Window *tmp = get_window_by_name("oper_view"); if (tmp) { tmp->log = log; do_log(tmp->log, buffer, &tmp->log_fp); if (!tmp->log_fp) tmp->log = 0; tmp->mangler = operlog_line_mangler; } } } } #endif