/*
* notice.c: special stuff for parsing NOTICEs
*
* Written By Michael Sandrof
*
* Copyright (c) 1990 Michael Sandrof.
* Copyright (c) 1991, 1992 Troy Rollo.
* Copyright (c) 1992-2003 Matthew R. Green.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id: notice.c,v 1.35 2006/03/22 17:16:49 f Exp $
*/
#include "irc.h"
#include "whois.h"
#include "ctcp.h"
#include "window.h"
#include "lastlog.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"
/************************* PATCHED by Flier **************************/
#include "status.h"
#include "myvars.h"
extern void HandleFakes _((char *, char *, int));
extern int HandleNotice _((char *, char *, char *, int, char *, int *));
extern int IsIrcNetOperChannel _((char *));
#if defined(OPERVISION) && defined(WANTANSI)
extern void OVformat _((char *, char *));
#endif
extern char *TimeStamp _((int));
extern void ChannelLogSave _((char *, ChannelList *));
#ifdef BLAXTHOS
extern int DecryptString _((char *, char *, char *, int, int));
#endif
/*********************************************************************/
#ifndef LITE
static void parse_note _((char *, char *));
#endif
static void parse_server_notice _((char *, char *, char *));
/*
* parse_note: handles the parsing of irc note messages which are sent as
* NOTICES. The notice() function determines which notices are note messages
* and send that info to parse_note()
*/
#ifndef LITE
static void
parse_note(server, line)
char *server;
char *line;
{
char *date,
*nick,
*flags,
*high,
*name,
*message;
int ign1,
ign2,
level;
time_t the_time;
flags = next_arg(line, &date); /* what to do with these flags */
nick = next_arg(date, &date);
name = next_arg(date, &date);
if ((message = index(date, '*')) != NULL)
*message = (char) 0;
if (((ign1 = is_ignored(nick, IGNORE_NOTES)) == IGNORED) ||
((ign2 = is_ignored(name, IGNORE_NOTES)) == IGNORED))
return;
if ((ign1 == HIGHLIGHTED) || (ign2 == HIGHLIGHTED))
high = &highlight_char;
else
high = empty_string;
the_time = atol(date);
date = ctime(&the_time);
date[24] = (char) 0;
level = set_lastlog_msg_level(LOG_NOTES);
if (do_hook(NOTE_LIST, "%s %s %s %s %s %s", nick, name, flags, date,
server, message + 2))
{
put_it("Note from %s (%s) %s", nick, name, flags);
put_it("It was queued %s from server %s", date, server);
put_it("%s[%s]%s %s", high, nick, high, message + 2);
}
if (beep_on_level & LOG_NOTES)
beep_em(1);
set_lastlog_msg_level(level);
}
#endif
static void
parse_server_notice(from, to, line)
char *from,
*to,
*line;
{
char server[81],
version[21];
int user_cnt,
server_cnt,
lastlog_level;
int flag;
if (!from || !*from)
from = server_list[parsing_server_index].itsname ?
server_list[parsing_server_index].itsname :
server_list[parsing_server_index].name;
if (get_int_var(SUPPRESS_SERVER_MOTD_VAR) &&
get_server_motd(parsing_server_index))
{
if (strncmp("*** Message-of-today", line, 20) == 0)
{
set_server_motd(parsing_server_index, 0);
return;
}
if (strncmp("MOTD ", line, 5) == 0)
{
set_server_motd(parsing_server_index, 1);
return;
}
if (strcmp("* End of /MOTD command.", line) == 0)
{
set_server_motd(parsing_server_index, 0);
return;
}
}
save_message_from();
if (!strncmp(line, "*** Notice --", 13))
{
message_from((char *) 0, LOG_OPNOTE);
lastlog_level = set_lastlog_msg_level(LOG_OPNOTE);
}
else
{
message_from((char *) 0, LOG_SNOTE);
lastlog_level = set_lastlog_msg_level(LOG_SNOTE);
}
if (to)
{
if (do_hook(SERVER_NOTICE_LIST, "%s %s %s", from, to, line))
/*************************** PATCHED by Flier ******************************/
{
#if defined(OPERVISION) && defined(WANTANSI)
if (OperV &&
(get_server_version(from_server)==Server2_9 ||
get_server_version(from_server)==Server2_10 ||
get_server_version(from_server)==Server2_11) &&
IsIrcNetOperChannel(to))
OVformat(line,NULL);
else
#endif
/***************************************************************************/
put_it("%s %s", to, line);
/**************************** PATCHED by Flier ******************************/
}
/****************************************************************************/
}
else
{
if (get_server_version(parsing_server_index) >= Server2_7 &&
*line != '*' && *line != '#' && strncmp(line, "MOTD ", 4))
flag = 1;
else
flag = 0;
if (do_hook(SERVER_NOTICE_LIST, flag ? "%s *** %s"
: "%s %s", from, line))
/*************************** PATCHED by Flier ******************************/
/*put_it(flag ? "*** %s" : "%s", line);*/
if (strncmp(line,"*** Your host is ",17)) {
#if defined(OPERVISION) && defined(WANTANSI)
if (OperV) OVformat(line,NULL);
else
#endif
if (!ServerNotice && strncmp(line, "*** Notice --", 13)) say("%s",line);
else if (ServerNotice) say("%s",line);
else if (ShowFakes && wild_match("*notice*fake*",line))
HandleFakes(line,from,from_server);
}
/***************************************************************************/
}
if ((parsing_server_index == primary_server) &&
((sscanf(line, "*** There are %d users on %d servers",
&user_cnt, &server_cnt) == 2) ||
(sscanf(line, "There are %d users on %d servers",
&user_cnt, &server_cnt) == 2)))
{
if ((server_cnt < get_int_var(MINIMUM_SERVERS_VAR)) ||
(user_cnt < get_int_var(MINIMUM_USERS_VAR)))
{
say("Trying better populated server...");
get_connected(parsing_server_index + 1, 0);
}
}
#ifdef BROKEN_SCANF
else if (!strncmp(line, "*** Your host is ", 17))
#else
else if ((sscanf(line, "*** Your host is %80s running version %20s",
server, version) == 2))
#endif /* BROKEN_SCANF */
{
if (get_server_version(parsing_server_index) < Server2_8)
got_initial_version(line);
}
if (lastlog_level)
{
set_lastlog_msg_level(lastlog_level);
restore_message_from();
}
}
void
parse_notice(from, Args)
char *from;
char **Args;
{
int level,
type;
char *to;
int no_flooding;
int flag;
char *high,
not_from_server = 1;
char *line;
/**************************** Patched by Flier ******************************/
char *stampbuf = TimeStamp(2);
/****************************************************************************/
PasteArgs(Args, 1);
to = Args[0];
line = Args[1];
if (!to || !line)
return;
if (*to)
{
save_message_from();
if (is_channel(to))
{
message_from(to, LOG_NOTICE);
type = PUBLIC_NOTICE_LIST;
}
else
{
message_from(from, LOG_NOTICE);
type = NOTICE_LIST;
}
if (from && *from && strcmp(get_server_itsname(parsing_server_index), from))
{
flag = double_ignore(from, FromUserHost,IGNORE_NOTICES);
if (flag != IGNORED)
{
if (flag == HIGHLIGHTED)
high = &highlight_char;
else
high = empty_string;
if (index(from, '.'))
{
/*
* only dots in servernames, right ?
*
* But a server name doesn't nessicarily have to have
* a 'dot' in it.. - phone, jan 1993.
*/
not_from_server = 0;
#ifndef LITE
if (strncmp(line, "*/", 2) == 0)
{
parse_note(from, line + 1);
goto out;
}
#endif
}
if (not_from_server && (flag != DONT_IGNORE) && !FromUserHost &&
(ignore_usernames & IGNORE_NOTICES))
add_to_whois_queue(from, whois_ignore_notices, "%s", line);
else
{
line = do_notice_ctcp(from, to, line);
if (*line == '\0')
{
goto out;
}
level = set_lastlog_msg_level(LOG_NOTICE);
no_flooding = check_flooding(from, NOTICE_FLOOD, line);
if (sed == 0 || do_hook(ENCRYPTED_NOTICE_LIST, "%s %s %s", from, to, line))
{
/**************************** Patched by Flier ******************************/
int iscrypted = 0;
/****************************************************************************/
if (type == NOTICE_LIST)
{
/**************************** PATCHED by Flier ******************************/
if (HandleNotice(from, line, FromUserHost, 0, to,
&iscrypted))
/****************************************************************************/
if (no_flooding &&
do_hook(type, "%s %s", from, line))
/**************************** PATCHED by Flier ******************************/
/*put_it("%s-%s-%s %s", high, from, high, line);*/
HandleNotice(from, line, FromUserHost, 1, to,
&iscrypted);
/****************************************************************************/
}
else
{
/**************************** PATCHED by Flier ******************************/
if (HandleNotice(from, line, FromUserHost, 0, to,
&iscrypted))
/****************************************************************************/
if (no_flooding &&
do_hook(type, "%s %s %s", from, to, line))
/**************************** Patched by Flier ******************************/
/*put_it("%s-%s:%s-%s %s", high, from, to, high, line);*/
put_it("%s%s%s-%s:%s-%s %s",
iscrypted ? "[!]" : "",
stampbuf, high, from, to, high, line);
if (ChanLog) {
ChannelList *chan;
chan = lookup_channel(to, parsing_server_index, 0);
if (chan && chan->ChanLog) {
char tmpbuf3[mybufsize];
snprintf(tmpbuf3, sizeof(tmpbuf3), "-%s- %s", from, line);
ChannelLogSave(tmpbuf3, chan);
}
}
/****************************************************************************/
}
if (beep_on_level & LOG_NOTICE)
beep_em(1);
set_lastlog_msg_level(level);
if (not_from_server)
notify_mark(from, 1, 0);
}
}
}
}
else
parse_server_notice(from, type == PUBLIC_NOTICE_LIST ? to : 0, line);
}
else
put_it("%s", line + 1);
out:
restore_message_from();
}
/*
* load the initial .ircrc
*/
void
load_ircrc()
{
static int done = 0;
if (done++)
return;
if (access(ircrc_file, R_OK) == 0)
{
char lbuf[BIG_BUFFER_SIZE+1];
strmcpy(lbuf,ircrc_file,BIG_BUFFER_SIZE);
strmcat(lbuf," ",BIG_BUFFER_SIZE);
strmcat(lbuf,args_str,BIG_BUFFER_SIZE);
load(empty_string, lbuf, empty_string);
}
else if (get_int_var(NOVICE_VAR))
say("If you have not already done so, please read the new user information with /HELP NEWUSER");
}
/*
* load the initial .ircquick
*/
void
load_ircquick()
{
static int done = 0;
if (done++)
return;
if (access(ircquick_file, R_OK) == 0)
{
char lbuf[BIG_BUFFER_SIZE+1];
strmcpy(lbuf,ircquick_file,BIG_BUFFER_SIZE);
strmcat(lbuf," ",BIG_BUFFER_SIZE);
strmcat(lbuf,args_str,BIG_BUFFER_SIZE);
load(empty_string, lbuf, empty_string);
}
}
/*
* got_initial_version: this is called when ircii get the NOTICE in
* all version of ircd before 2.8, or the 002 numeric for 2.8 and
* beyond. I guess its handled rather badly at the moment....
* added by phone, late 1992.
*/
void
got_initial_version(line)
char *line;
{
char server[256],
version[256];
char *s, c;
/**************************** Patched by Flier ******************************/
int was_connected;
/****************************************************************************/
/*
* BROKEN_SCANF crap here provided by Aiken <adrum@u.washington.edu>
* sometime 1993...
*/
#ifdef BROKEN_SCANF
if (strncmp(line, "*** Your host is ", 17))
return;
strncpy(server, &line[17], 256);
server[79] = 0;
if (s = index(server, ','))
*s = 0;
if (s = index(server, ' '))
*s = 0;
version[0] = 0;
if (s = my_index(&line[17], ' '))
{
if (!strncmp(c, " running version ", 17))
{
strncpy(version, &s[17], 255);
version[255] = 0;
}
else return;
}
else return;
#else
if ((sscanf(line, "*** Your host is %256s running version %255s",
server, version)) != 2) {
yell("This server has a non-standard connection message!");
strcpy(version, "2.9");
strcpy(server, server_list[parsing_server_index].name);
}
else if ((c = server[strlen(server) - 1]) == ',' || c == '.')
server[strlen(server) - 1] = '\0';
#endif /* BROKEN_SCANF */
attempting_to_connect--;
/**************************** PATCHED by Flier ******************************/
/* attempting_to_connect is broken if we are connecting to multiple
servers simoultaneously -> correct the value apropriately */
if (attempting_to_connect < 0) attempting_to_connect = 0;
was_connected = server_list[parsing_server_index].connected;
/****************************************************************************/
set_server_motd(parsing_server_index, 1);
server_is_connected(parsing_server_index, 1);
if ((s = (char *) index(server, '[')) != NULL)
*s = '\0'; /*
* Handles the case where the server name is
* different to the host name.
*/
if (!strncmp(version, "2.5", 3))
set_server_version(parsing_server_index, Server2_5);
else if (!strncmp(version, "2.6", 3))
set_server_version(parsing_server_index, Server2_6);
else if (!strncmp(version, "2.7", 3))
set_server_version(parsing_server_index, Server2_7);
else if (!strncmp(version, "2.8", 3))
set_server_version(parsing_server_index, Server2_8);
else if (!strncmp(version, "2.9", 3))
set_server_version(parsing_server_index, Server2_9);
else if (!strncmp(version, "2.10", 4))
set_server_version(parsing_server_index, Server2_10);
/**************************** Patched by Flier ******************************/
/* this is here so we can identify Freenode servers */
else if (strstr(version, "hyperion"))
set_server_version(parsing_server_index, Server2_90);
else
set_server_version(parsing_server_index, Server2_11);
/****************************************************************************/
malloc_strcpy(&server_list[parsing_server_index].version_string, version);
set_server_itsname(parsing_server_index, server);
/**************************** Patched by Flier ******************************/
/* reinstate oper mode if password is stored */
#ifdef BLAXTHOS
if (EncryptPassword && OperNick && OperPassword) {
char nickbuf[mybufsize];
char passbuf[mybufsize];
say("Reinstating OPER mode with stored password");
DecryptString(nickbuf, OperNick, EncryptPassword, sizeof(nickbuf) - 1, 1);
DecryptString(passbuf, OperPassword, EncryptPassword, sizeof(passbuf) - 1, 1);
send_to_server("OPER %s %s", nickbuf, passbuf);
bzero(nickbuf, strlen(nickbuf));
bzero(passbuf, strlen(passbuf));
}
#endif
/* read above, we already parsed this so skip it this time since
it will corrupt all server information we stored in previous
pass */
if (was_connected) {
do_hook(CONNECT_LIST, "%s %d", get_server_name(parsing_server_index),
get_server_port(parsing_server_index));
return;
}
/****************************************************************************/
reconnect_all_channels(parsing_server_index);
reinstate_user_modes(/* parsing_server_index */); /* XXX */
maybe_load_ircrc();
if (server_list[parsing_server_index].away)
send_to_server("AWAY :%s",
server_list[parsing_server_index].away);
update_all_status();
do_hook(CONNECT_LIST, "%s %d", get_server_name(parsing_server_index),
get_server_port(parsing_server_index));
}
void
maybe_load_ircrc()
{
if (never_connected)
{
never_connected = 0;
if (!bflag)
{
loading_global = 1;
/**************************** PATCHED by Flier ******************************/
/*load(empty_string, "global", empty_string);*/
load(empty_string, "szglobal", empty_string);
/****************************************************************************/
loading_global = 0;
}
/* read the .ircrc file */
if (!qflag)
load_ircrc();
}
}
syntax highlighted by Code2HTML, v. 0.9.1