/*
* parse.c: handles messages from the server. Believe it or not. I
* certainly wouldn't if I were you.
*
* 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: parse.c,v 1.76 2005/08/08 18:50:47 f Exp $
*/
#include "irc.h"
#include "server.h"
#include "names.h"
#include "vars.h"
#include "ctcp.h"
#include "hook.h"
#include "edit.h"
#include "ignore.h"
#include "whois.h"
#include "lastlog.h"
#include "ircaux.h"
#include "funny.h"
#include "crypt.h"
#include "ircterm.h"
#include "flood.h"
#include "window.h"
#include "screen.h"
#include "output.h"
#include "numbers.h"
#include "parse.h"
#include "notify.h"
/************************* PATCHED by Flier *************************/
#include "list.h"
#include "status.h"
#include "myvars.h"
extern void OnWho _((char *, char *, char *, char *, char *));
extern void PrintMessage _((char *, char *, char *, int, int));
extern void HandleSplit _((char *, char *, char *, int *));
extern NickList *ChannelJoin _((char *, char *, ChannelList *));
extern NickList *CheckJoin _((char *, char *, char *, int, ChannelList *));
extern struct friends *CheckUsers _((char *, char *));
extern int HandleJoin _((NickList *, char *, char *, char *, ChannelList *));
extern void HandleInvite _((char *, char *, char *));
extern void HandleKills _((int, char *, char *, char *));
extern void ReconnectOnKill _((int));
extern void HandleNickChange _((char *, char *, char *, int));
#ifdef EXTRAS
extern void CheckLock _((char *, int, ChannelList *));
extern void CheckTopic _((char *, int, ChannelList *));
#endif
extern void HandleMyKick _((char *, char *, char *, char *, char *));
extern int HandleKick _((char *, char *, char *, char *, char *, int *));
extern void SplitPrint _((char *, char *, char *, int));
extern void ModePrint _((char *, char *, char *, char *, char *, char *));
extern void KickPrint _((char *, char *, char *, char *, char *, int, int));
extern void PrintWho _((char *, char *, char *, char *, char *, char *, char *,
int));
extern void PrintPublic _((char *, char *, char *, char *, int, int));
extern void DoKill _((char *, char *, char *));
extern NickList *CheckJoiners _((char *, char *, int , ChannelList *));
#if defined(OPERVISION) && defined(WANTANSI)
extern void OVformat _((char *, char *));
#endif
extern void AwaySave _((char *, int));
extern char *GetNetsplitServer _((char *, char *));
extern int CheckChannel _((char *, char *));
extern int DecryptMessage _((char *, char *));
extern int IsIrcNetOperChannel _((char *));
extern int CompareAddr _((List *, char *));
extern int AddLast _((List *, List *));
extern char *TimeStamp _((int));
extern void ChannelLogSave _((char *, ChannelList *));
extern void SendToServer _((void));
extern int RateLimitJoin _((int));
extern void e_nick _((char *, char *, char *));
extern void e_channel _((char *, char *, char *));
extern void timercmd _((char *, char *, char *));
#if defined(CELE)
extern struct timeval PingSent;
#else
extern time_t PingSent;
#endif
#ifdef EXTRAS
typedef struct winlist_str Winlist;
struct winlist_str {
Winlist *next;
Window *window;
};
#endif
extern int SentNick;
extern char *OldNick;
static int NumberMessages=0;
static time_t LastMsgTime=0;
static time_t LastNickFlood=0;
/********************************************************************/
#define STRING_CHANNEL '+'
#define MULTI_CHANNEL '#'
#define LOCAL_CHANNEL '&'
#define SAFE_CHANNEL '!'
#define MAXPARA 15 /* Taken from the ircd */
static void BreakArgs _((char *, char **, char **));
static void p_linreply _((char **));
static void p_ping _((char **));
static void p_topic _((char *, char **));
static void p_wall _((char *, char **));
static void p_wallops _((char *, char **));
static void p_privmsg _((char *, char **));
/*static void p_msgcmd _((char *, char **));*/
static void p_quit _((char *, char **));
static void p_pong _((char *, char **));
static void p_error _((char *, char **));
static void p_channel _((char *, char **));
static void p_invite _((char *, char **));
static void p_server_kill _((char *, char **));
static void p_nick _((char *, char **));
static void p_mode _((char *, char **));
static void p_kick _((char *, char **));
static void p_part _((char *, char **));
/*
* joined_nick: the nickname of the last person who joined the current
* channel
*/
u_char *joined_nick = (u_char *) 0;
/* public_nick: nick of the last person to send a message to your channel */
u_char *public_nick = (u_char *) 0;
/* User and host information from server 2.7 */
char *FromUserHost = (char *) 0;
/* doing a PRIVMSG */
int doing_privmsg = 0;
/*
* is_channel: determines if the argument is a channel. If it's a number,
* begins with MULTI_CHANNEL and has no '*', or STRING_CHANNEL, then its a
* channel
*/
int
is_channel(to)
char *to;
{
int version;
if (to == 0)
return (0);
version = get_server_version(from_server);
return ((version < Server2_7 && (isdigit(*to) || (*to == STRING_CHANNEL) || *to == '-'))
|| (version > Server2_5 && *to == MULTI_CHANNEL)
|| (version > Server2_7 && *to == LOCAL_CHANNEL)
|| (version > Server2_8 && *to == STRING_CHANNEL)
|| (version > Server2_9 && *to == SAFE_CHANNEL));
}
char *
PasteArgs(Args, StartPoint)
char **Args;
int StartPoint;
{
int i;
for (; StartPoint; Args++, StartPoint--)
if (!*Args)
return (char *) 0;
for (i = 0; Args[i] && Args[i+1]; i++)
Args[i][strlen(Args[i])] = ' ';
Args[1] = (char *) 0;
return Args[0];
}
/*
* BreakArgs: breaks up the line from the server, in to where its from,
* setting FromUserHost if it should be, and returns all the arguements
* that are there. Re-written by phone, dec 1992.
*/
static void
BreakArgs(Input, Sender, OutPut)
char *Input;
char **Sender;
char **OutPut;
{
char *s = Input,
*t;
int ArgCount = 0;
/*
* Get sender from :sender and user@host if :nick!user@host
*/
FromUserHost = (char *) 0;
if (*Input == ':')
{
char *tmp;
*Input++ = '\0';
if ((s = (char *) index(Input, ' ')) != (char *) 0)
*s++ = '\0';
*Sender = Input;
if ((tmp = (char *) index(*Sender, '!')) != (char *) 0)
{
*tmp++ = '\0';
FromUserHost = tmp;
}
}
else
*Sender = empty_string;
if (!s)
return;
for (;;)
{
while (*s == ' ')
*s++ = '\0';
if (!*s)
break;
if (*s == ':')
{
for (t = s; *t; t++)
*t = *(t + 1);
OutPut[ArgCount++] = s;
break;
}
OutPut[ArgCount++] = s;
if (ArgCount >= MAXPARA)
break;
for (; *s != ' ' && *s; s++)
;
}
OutPut[ArgCount] = (char *) 0;
}
/* beep_em: Not hard to figure this one out */
void
beep_em(beeps)
int beeps;
{
int cnt,
i;
for (cnt = beeps, i = 0; i < cnt; i++)
term_beep();
}
/* in response to a TOPIC message from the server */
static void
p_topic(from, ArgList)
char *from,
**ArgList;
{
int flag;
/**************************** PATCHED by Flier ******************************/
time_t timenow = time(NULL);
ChannelList *chan;
/****************************************************************************/
if (!from)
return;
/**************************** PATCHED by Flier ******************************/
if (ArgList[0] && ArgList[1] && (chan = lookup_channel(ArgList[0], parsing_server_index, 0))) {
char tmpbuf[mybufsize];
chan->topic++;
if (*ArgList[1]) malloc_strcpy(&(chan->topicstr), ArgList[1]);
else new_free(&(chan->topicstr));
malloc_strcpy(&(chan->topicwho), from);
chan->topicwhen = timenow;
#ifdef EXTRAS
CheckTopic(chan->channel, parsing_server_index, chan);
#endif
if (chan->ChanLog) {
snprintf(tmpbuf, sizeof(tmpbuf), "%s has changed the topic on channel %s to %s", from, ArgList[0], ArgList[1]);
ChannelLogSave(tmpbuf, chan);
}
}
if ((double_ignore(ArgList[0], NULL, IGNORE_CRAP)) == IGNORED) return;
if ((double_ignore(FromUserHost, ArgList[0], IGNORE_CRAP)) == IGNORED) return;
/****************************************************************************/
flag = double_ignore(from, FromUserHost, IGNORE_CRAP);
if (flag == IGNORED)
return;
save_message_from();
if (!ArgList[1])
{
message_from((char *) 0, LOG_CRAP);
if (do_hook(TOPIC_LIST, "%s * %s", from, ArgList[0]))
/**************************** PATCHED by Flier ******************************/
/*say("%s has changed the topic to %s", from, ArgList[0]);*/
{
if (*ArgList[0])
say("%s has set the topic to %s", from, ArgList[0]);
else
say("%s has unset the topic", from);
}
/****************************************************************************/
}
else
{
message_from(ArgList[0], LOG_CRAP);
if (do_hook(TOPIC_LIST, "%s %s %s", from, ArgList[0], ArgList[1]))
/**************************** PATCHED by Flier ******************************/
/*say("%s has changed the topic on channel %s to %s",
from, ArgList[0], ArgList[1]);*/
{
if (*ArgList[1])
say("%s has set the topic on channel %s to %s",
from, ArgList[0], ArgList[1]);
else
say("%s has unset the topic on channel %s",
from, ArgList[0]);
}
/****************************************************************************/
}
/**************************** PATCHED by Flier ******************************/
update_all_status();
/****************************************************************************/
restore_message_from();
}
static void
p_linreply(ArgList)
char **ArgList;
{
PasteArgs(ArgList, 0);
say("%s", ArgList[0]);
}
static void
p_wall(from, ArgList)
char *from,
**ArgList;
{
int flag,
level;
char *line;
char *high;
if (!from)
return;
PasteArgs(ArgList, 0);
if (!(line = ArgList[0]))
return;
flag = double_ignore(from, FromUserHost, IGNORE_WALLS);
save_message_from();
message_from(from, LOG_WALL);
if (flag != IGNORED)
{
if (flag == HIGHLIGHTED)
high = &highlight_char;
else
high = empty_string;
if ((flag != DONT_IGNORE) && (ignore_usernames & IGNORE_WALLS)
&& !FromUserHost)
add_to_whois_queue(from, whois_ignore_walls, "%s",line);
else
{
level = set_lastlog_msg_level(LOG_WALL);
if (check_flooding(from, WALL_FLOOD, line) &&
do_hook(WALL_LIST, "%s %s", from, line))
put_it("%s#%s#%s %s", high, from, high, line);
if (beep_on_level & LOG_WALL)
beep_em(1);
set_lastlog_msg_level(level);
}
}
restore_message_from();
}
static void
p_wallops(from, ArgList)
char *from,
**ArgList;
{
int flag, level;
char *line;
if (!from)
return;
if (!(line = PasteArgs(ArgList, 0)))
return;
flag = double_ignore(from, FromUserHost, IGNORE_WALLOPS);
level = set_lastlog_msg_level(LOG_WALLOP);
save_message_from();
message_from(from, LOG_WALLOP);
if (index(from, '.'))
{
char *high;
if (flag != IGNORED)
{
if (flag == HIGHLIGHTED)
high = &highlight_char;
else
high = empty_string;
if (do_hook(WALLOP_LIST, "%s S %s", from, line))
/**************************** PATCHED by Flier ******************************/
/*put_it("%s!%s!%s %s", high, from, high, line);*/
{
char *stampbuf = TimeStamp(2);
#if defined(OPERVISION) && defined(WANTANSI)
if (OperV) OVformat(line, from);
else
#endif
put_it("%s%s!%s!%s %s", stampbuf, high, from, high, line);
}
/****************************************************************************/
if (beep_on_level & LOG_WALLOP)
beep_em(1);
}
}
else
{
if (get_int_var(USER_WALLOPS_VAR))
{
if ((flag != DONT_IGNORE) && (check_flooding(from, WALLOP_FLOOD, line)))
add_to_whois_queue(from, whois_new_wallops, "%s", line);
}
/**************************** PATCHED by Flier ******************************/
/* Why not show user their own wallops ? I will ignore this */
/*else if (strcmp(from, get_server_nickname(get_window_server(0))) != 0)
put_it("!%s! %s", from, line);*/
else if (flag != IGNORED) {
char *stampbuf = TimeStamp(2);
#if defined(OPERVISION) && defined(WANTANSI)
if (OperV) OVformat(line,from);
else
#endif
put_it("%s!%s! %s", stampbuf, from, line);
}
/****************************************************************************/
}
set_lastlog_msg_level(level);
restore_message_from();
}
/*ARGSUSED*/
void
whoreply(from, ArgList)
char **ArgList,
*from;
{
static char format[40];
static int last_width = -1;
int ok = 1;
char *channel,
*user,
*host,
*server,
*nick,
*status,
*name;
int i;
/**************************** PATCHED by Flier ******************************/
int show_server = 0;
/****************************************************************************/
FILE *fip;
char buf_data[BUFSIZ];
if (last_width != get_int_var(CHANNEL_NAME_WIDTH_VAR))
{
if ((last_width = get_int_var(CHANNEL_NAME_WIDTH_VAR)) != 0)
snprintf(format, sizeof format, "%%-%u.%us %%-9s %%-3s %%s@%%s (%%s)",
(unsigned char) last_width,
(unsigned char) last_width);
else
strcpy(format, "%s\t%-9s %-3s %s@%s (%s)");
}
i = 0;
channel = user = host = server = nick = status = name = empty_string;
if (ArgList[i])
channel = ArgList[i++];
if (ArgList[i])
user = ArgList[i++];
if (ArgList[i])
host = ArgList[i++];
if (ArgList[i])
server = ArgList[i++];
if (ArgList[i])
nick = ArgList[i++];
if (ArgList[i])
status = ArgList[i++];
PasteArgs(ArgList, i);
if (*status == 'S') /* this only true for the header WHOREPLY */
{
channel = "Channel";
if (((who_mask & WHO_FILE) == 0) || (fopen (who_file, "r")))
{
if (do_hook(WHO_LIST, "%s %s %s %s %s %s", channel,
nick, status, user, host, ArgList[6]))
put_it(format, channel, nick, status, user,
host, ArgList[6]);
return;
}
}
if (ArgList[i])
name = ArgList[i];
/**************************** PATCHED by Flier ******************************/
if (who_mask & WHO_SHOW_SERVER) {
show_server = 1;
who_mask &= ~WHO_SHOW_SERVER;
}
/****************************************************************************/
if (who_mask)
{
if (who_mask & WHO_HERE)
ok = ok && (*status == 'H');
if (who_mask & WHO_AWAY)
ok = ok && (*status == 'G');
if (who_mask & WHO_OPS)
ok = ok && (*(status + 1) == '*');
if (who_mask & WHO_LUSERS)
ok = ok && (*(status + 1) != '*');
if (who_mask & WHO_CHOPS)
ok = ok && ((*(status + 1) == '@') ||
(*(status + 2) == '@'));
if (who_mask & WHO_HOPS)
ok = ok && (*(status + 1) == '%');
if (who_mask & WHO_NAME)
ok = ok && wild_match(who_name, user);
if (who_mask & WHO_NICK)
ok = ok && wild_match(who_nick, nick);
if (who_mask & WHO_HOST)
ok = ok && wild_match(who_host, host);
if (who_mask & WHO_REAL)
ok = ok && wild_match(who_real, name);
if (who_mask & WHO_SERVER)
ok = ok && wild_match(who_server, server);
if (who_mask & WHO_FILE)
{
ok = 0;
cannot_open = (char *) 0;
if ((fip = fopen (who_file, "r")) != (FILE *) 0)
{
while (fgets (buf_data, BUFSIZ, fip) !=
(char *) 0)
{
buf_data[strlen(buf_data)-1] = '\0';
ok = ok || wild_match(buf_data, nick);
}
fclose (fip);
} else
cannot_open = who_file;
}
}
if (ok)
{
/**************************** PATCHED by Flier ******************************/
if (server_list[from_server].SZWho) {
#ifdef OPER
if (inSZFKill) DoKill(nick, user, host);
else OnWho(nick, user, host, channel, status);
#else
OnWho(nick, user, host, channel, status);
#endif
}
else
/****************************************************************************/
if (do_hook(WHO_LIST, "%s %s %s %s %s %s", channel, nick,
status, user, host, name))
{
if (get_int_var(SHOW_WHO_HOPCOUNT_VAR))
/**************************** PATCHED by Flier ******************************/
/*put_it(format, channel, nick, status, user, host,
name);*/
PrintWho(channel, nick, status, user, host, name,
server, show_server);
/****************************************************************************/
else
{
char *tmp;
if ((tmp = (char *) index(name, ' ')) !=
(char *) 0)
tmp++;
else
tmp = name;
/**************************** PATCHED by Flier ******************************/
/*put_it(format, channel, nick, status, user, host,
tmp);*/
PrintWho(channel, nick, status, user, host, tmp,
server, show_server);
/****************************************************************************/
}
}
}
/**************************** PATCHED by Flier ******************************/
if (show_server) who_mask |= WHO_SHOW_SERVER;
/****************************************************************************/
}
static void
p_privmsg(from, Args)
char *from,
**Args;
{
int level,
flag,
list_type,
flood_type,
log_type;
u_char ignore_type;
char *ptr,
*to;
char *high;
int no_flood;
/**************************** PATCHED by Flier ******************************/
int iscrypted;
char tmpbuf[mybufsize / 8];
time_t timenow = time(NULL);
struct friends *tmpfriend;
/****************************************************************************/
if (!from)
return;
PasteArgs(Args, 1);
to = Args[0];
ptr = Args[1];
if (!to || !ptr)
return;
save_message_from();
if (is_channel(to))
{
message_from(to, LOG_MSG);
malloc_strcpy((char **) &public_nick, from);
if (!is_on_channel(to, parsing_server_index, from))
{
log_type = LOG_PUBLIC;
ignore_type = IGNORE_PUBLIC;
list_type = PUBLIC_MSG_LIST;
flood_type = PUBLIC_FLOOD;
}
else
{
log_type = LOG_PUBLIC;
ignore_type = IGNORE_PUBLIC;
if (is_current_channel(to, parsing_server_index, 0))
list_type = PUBLIC_LIST;
else
list_type = PUBLIC_OTHER_LIST;
flood_type = PUBLIC_FLOOD;
}
}
else
{
message_from(from, LOG_MSG);
flood_type = MSG_FLOOD;
if (my_stricmp(to, get_server_nickname(parsing_server_index)))
{
log_type = LOG_WALL;
ignore_type = IGNORE_WALLS;
list_type = MSG_GROUP_LIST;
}
else
{
log_type = LOG_MSG;
ignore_type = IGNORE_MSGS;
list_type = MSG_LIST;
}
}
flag = double_ignore(from, FromUserHost, ignore_type);
switch (flag)
{
case IGNORED:
if ((list_type == MSG_LIST) && get_int_var(SEND_IGNORE_MSG_VAR))
send_to_server("NOTICE %s :%s is ignoring you", from,
get_server_nickname(parsing_server_index));
goto out;
case HIGHLIGHTED:
high = &highlight_char;
break;
default:
high = empty_string;
break;
}
/**************************** Patched by Flier ******************************/
if (ignore_type == IGNORE_PUBLIC && double_ignore(to, NULL, IGNORE_PUBLIC) == IGNORED)
goto out;
if (ignore_type == IGNORE_PUBLIC && is_channel(to) && double_ignore(from, to, IGNORE_PUBLIC) == IGNORED)
goto out;
if (ignore_type == IGNORE_PUBLIC && is_channel(to) && double_ignore(FromUserHost, to, IGNORE_PUBLIC) == IGNORED)
goto out;
if (FloodProt > 1 && flood_type == MSG_FLOOD) {
snprintf(tmpbuf, sizeof(tmpbuf), "%s!%s", from, FromUserHost);
tmpfriend = CheckUsers(tmpbuf, NULL);
if (!tmpfriend || (tmpfriend && !(tmpfriend->privs) & FLNOFLOOD)) {
if (timenow > LastMsgTime + FloodSeconds) {
LastMsgTime = timenow;
NumberMessages = 1;
}
else NumberMessages++;
if (NumberMessages >= FloodMessages && timenow >= LastNickFlood + 10) {
LastMsgTime = timenow;
LastNickFlood = timenow;
NumberMessages = 0;
snprintf(tmpbuf,sizeof(tmpbuf), "%.7s%c%c", get_server_nickname(from_server),
'a' + (rand() % 25) ,'a' + (rand() % 25));
e_nick(NULL, tmpbuf, NULL);
#ifdef WANTANSI
snprintf(tmpbuf,sizeof(tmpbuf), "%sFlood attack%s detected, changing nick",
CmdsColors[COLWARNING].color1, Colors[COLOFF]);
#else
snprintf(tmpbuf,sizeof(tmpbuf), "%cFlood attack%c detected, changing nick", bold, bold);
#endif
say("%s", tmpbuf);
if (away_set || LogOn) AwaySave(tmpbuf, SAVEFLOOD);
}
}
}
/****************************************************************************/
level = set_lastlog_msg_level(log_type);
ptr = do_ctcp(from, to, ptr);
if (!ptr || !*ptr)
goto out;
if ((flag != DONT_IGNORE) && (ignore_usernames & ignore_type) && !FromUserHost)
add_to_whois_queue(from, whois_ignore_msgs, "%s", ptr);
else
{
no_flood = check_flooding(from, flood_type, ptr);
if (sed == 0 || do_hook(ENCRYPTED_PRIVMSG_LIST,"%s %s %s",from, to, ptr))
{
switch (list_type)
{
case PUBLIC_MSG_LIST:
if (no_flood && do_hook(list_type, "%s %s %s", from, to, ptr))
/**************************** Patched by Flier ******************************/
{
/*put_it("%s(%s/%s)%s %s", high, from, to, high, ptr);*/
char *stampbuf = TimeStamp(2);
put_it("%s%s(%s/%s)%s %s", stampbuf, high, from, to, high, ptr);
}
/****************************************************************************/
break;
case MSG_GROUP_LIST:
/**************************** Patched by Flier ******************************/
if (*to == '@' && is_channel(to + 1)) message_from(to+1, LOG_MSG);
/****************************************************************************/
if (no_flood && do_hook(list_type, "%s %s %s", from, to, ptr))
/**************************** Patched by Flier ******************************/
{
/*put_it("%s-%s:%s-%s %s", high, from, to, high, ptr);*/
char *stampbuf = TimeStamp(2);
put_it("%s-%s:%s- %s", stampbuf, from, to, ptr);
}
/****************************************************************************/
break;
case MSG_LIST:
if (!no_flood)
break;
malloc_strcpy((char **) &recv_nick, from);
if (away_set)
beep_em(get_int_var(BEEP_WHEN_AWAY_VAR));
/**************************** PATCHED by Flier ******************************/
iscrypted = DecryptMessage(ptr, from);
/****************************************************************************/
if (do_hook(list_type, "%s %s", from, ptr))
{
/**************************** PATCHED by Flier ******************************/
/*if (away_set)
{
time_t t;
char *msg = (char *) 0;
size_t len = my_strlen(ptr) + 20;
t = time((time_t *) 0);
msg = (char *) new_malloc(len);
snprintf(msg, len, "%s <%.16s>", ptr, ctime(&t));
put_it("%s*%s*%s %s", high, from, high, msg);
new_free(&msg);
}
else
put_it("%s*%s*%s %s", high, from, high, ptr);*/
PrintMessage(from, FromUserHost, ptr, 1, iscrypted);
/****************************************************************************/
}
/**************************** PATCHED by Flier ******************************/
else PrintMessage(from, FromUserHost, ptr, 0, iscrypted);
/****************************************************************************/
break;
case PUBLIC_LIST:
if (get_int_var(MAKE_NOTICE_MSG_VAR))
doing_privmsg = 1;
/**************************** PATCHED by Flier ******************************/
iscrypted = DecryptMessage(ptr, to);
/****************************************************************************/
if (no_flood && do_hook(list_type, "%s %s %s", from,
to, ptr))
/**************************** PATCHED by Flier ******************************/
/*put_it("%s<%s>%s %s", high, from, high, ptr);*/
PrintPublic(from, NULL, to, ptr, 1, iscrypted);
else PrintPublic(from, NULL, to, ptr, 0, iscrypted);
/****************************************************************************/
doing_privmsg = 0;
break;
case PUBLIC_OTHER_LIST:
if (get_int_var(MAKE_NOTICE_MSG_VAR))
doing_privmsg = 1;
/**************************** PATCHED by Flier ******************************/
iscrypted = DecryptMessage(ptr, to);
/****************************************************************************/
if (no_flood && do_hook(list_type, "%s %s %s", from,
to, ptr))
/**************************** PATCHED by Flier ******************************/
/*put_it("%s<%s:%s>%s %s", high, from, to, high,
ptr);*/
PrintPublic(from, ":", to, ptr, 1, iscrypted);
else PrintPublic(from, ":", to, ptr, 0, iscrypted);
/****************************************************************************/
doing_privmsg = 0;
break;
}
if (beep_on_level & log_type)
beep_em(1);
}
}
set_lastlog_msg_level(level);
out:
restore_message_from();
}
#if 0
static void
p_msgcmd(from, ArgList)
char *from,
**ArgList;
{
char *high,
*channel,
*text;
int log_type,
no_flooding;
int flag;
if (!from)
return;
flag = double_ignore(from, FromUserHost, IGNORE_PUBLIC);
switch (flag)
{
case IGNORED:
return;
case HIGHLIGHTED:
high = &highlight_char;
break;
default:
high = empty_string;
break;
}
if ((channel = real_channel()) == (char *) 0)
return;
text = do_ctcp(from, channel, ArgList[0]);
if (!text || !*text)
return;
malloc_strcpy((char **) &public_nick, from);
log_type = set_lastlog_msg_level(LOG_PUBLIC);
no_flooding = check_flooding(from, PUBLIC_FLOOD, text);
save_message_from();
message_from(channel, LOG_PUBLIC);
if (is_current_channel(channel, parsing_server_index, 0))
{
if (get_int_var(MAKE_NOTICE_MSG_VAR))
doing_privmsg = 1;
if (no_flooding && do_hook(PUBLIC_LIST, "%s %s %s", from, channel, text))
put_it("%s<%s>%s %s", high, from, high, text);
doing_privmsg = 0;
}
else
{
if (get_int_var(MAKE_NOTICE_MSG_VAR))
doing_privmsg = 1;
if (no_flooding && do_hook(PUBLIC_OTHER_LIST, "%s %s %s", from,
channel, text))
put_it("%s<%s:%s>%s %s", high, from, channel, high,
text);
doing_privmsg = 0;
}
restore_message_from();
if (beep_on_level & LOG_PUBLIC)
beep_em(1);
set_lastlog_msg_level(log_type);
}
#endif
/*ARGSUSED*/
static void
p_quit(from, ArgList)
char *from,
**ArgList;
{
int one_prints = 0;
char *chan;
char *Reason;
int flag;
/**************************** PATCHED by Flier ******************************/
int netsplit;
#ifdef WANTANSI
char *colnick;
#endif
NickList *joiner;
#ifdef EXTRAS
Winlist *winlist=NULL,*winelem;
#endif
/****************************************************************************/
if (!from)
return;
flag = double_ignore(from, FromUserHost, IGNORE_CRAP);
save_message_from();
if (flag != IGNORED)
{
PasteArgs(ArgList, 0);
Reason = ArgList[0] ? ArgList[0] : "?";
for (chan = walk_channels(from, 1, parsing_server_index); chan; chan = walk_channels(from, 0, -1))
{
message_from(chan, LOG_CRAP);
/**************************** PATCHED by Flier ******************************/
/*if (do_hook(CHANNEL_SIGNOFF_LIST, "%s %s %s", chan, from, Reason))
one_prints = 1;*/
HandleSplit(Reason,from,chan,&netsplit);
if (do_hook(CHANNEL_SIGNOFF_LIST, "%s %s %s", chan, from,Reason)) {
SplitPrint(Reason,from,chan,netsplit);
one_prints = 1;
}
/****************************************************************************/
}
if (one_prints)
{
message_from(what_channel(from, parsing_server_index), LOG_CRAP);
if (do_hook(SIGNOFF_LIST, "%s %s", from, Reason))
/**************************** PATCHED by Flier *****************************/
/*say("Signoff: %s (%s)", from, Reason);*/
if (!netsplit || !NHDisp) {
#ifdef EXTRAS
int showed=0;
char chanbuf[mybufsize/4+1];
Window *oldto_window;
ChannelList *chan;
*chanbuf='\0';
oldto_window=to_window;
chan=server_list[parsing_server_index].chan_list;
for (;chan;chan=chan->next) {
joiner=CheckJoiners(from,chan->channel,parsing_server_index,chan);
/* only if user was on a channel */
if (ShowSignAllChan && joiner) {
/* major pain in the ass: if we have several channels in
* one window we have to display signoff only once in
* that window so we have to know which windows have
* already displayed signoff - we use window pointer */
if (!list_lookup_ext((List **) &winlist,(char *) chan->window,
!USE_WILDCARDS,!REMOVE_FROM_LIST,CompareAddr)) {
winelem=(Winlist *) malloc(sizeof(Winlist));
winelem->window=chan->window;
winelem->next=NULL;
add_to_list_ext((List **) &winlist,(List *) winelem,
(int (*) _((List *, List *))) AddLast);
}
}
if (ShowSignoffChan && SignoffChannels && *SignoffChannels) {
if (!CheckChannel(SignoffChannels,chan->channel))
continue;
if (strlen(chan->channel)+strlen(chanbuf)>=sizeof(chanbuf)-1)
continue;
if (joiner) {
if (*chanbuf) strmcat(chanbuf,",",sizeof(chanbuf));
else strcpy(chanbuf,"(");
strmcat(chanbuf,chan->channel,sizeof(chanbuf));
chanbuf[sizeof(chanbuf)-1]='\0';
}
}
}
if (ShowSignoffChan && SignoffChannels && *SignoffChannels) {
if (strlen(chanbuf)>=sizeof(chanbuf)-3) {
chanbuf[sizeof(chanbuf)-3]=')';
chanbuf[sizeof(chanbuf)-2]=' ';
chanbuf[sizeof(chanbuf)-1]='\0';
}
else strmcat(chanbuf,") ",sizeof(chanbuf));
}
for (winelem=winlist;;) {
if (winelem) to_window=winelem->window;
else if (showed) break;
showed=1;
#endif /* EXTRAS */
#ifdef WANTANSI
joiner=CheckJoiners(from,NULL,parsing_server_index,NULL);
if (joiner && joiner->shitlist && joiner->shitlist->shit)
colnick=CmdsColors[COLLEAVE].color5;
else if (joiner && joiner->frlist && joiner->frlist->privs)
colnick=CmdsColors[COLLEAVE].color4;
else colnick=CmdsColors[COLLEAVE].color1;
#ifdef EXTRAS
say("Signoff: %s%s%s (%s%s%s%s)",
#else /* EXTRAS */
say("Signoff: %s%s%s (%s%s%s)",
#endif /* EXTRAS */
colnick,from,Colors[COLOFF],
#ifdef EXTRAS
chanbuf,
#endif /* EXTRAS */
CmdsColors[COLLEAVE].color3,Reason,Colors[COLOFF]);
#else /* WANTANSI */
#ifdef EXTRAS
say("Signoff: %s (%s%s)",from,chanbuf,Reason);
#else /* EXTRAS */
say("Signoff: %s (%s)",from,Reason);
#endif /* EXTRAS */
#endif /* WANTANSI */
#ifdef EXTRAS
if (!winelem) break;
else winelem=winelem->next;
}
to_window=oldto_window;
if (ShowSignAllChan && winlist) {
/* free stored info about windows */
while (winlist) {
winelem=winlist;
winlist=winlist->next;
new_free(&winelem);
}
}
#endif /* EXTRAS */
}
/***************************************************************************/
}
}
message_from((char *) 0, LOG_CURRENT);
remove_from_channel((char *) 0, from, parsing_server_index);
notify_mark(from, 0, 0);
restore_message_from();
}
/*ARGSUSED*/
static void
p_pong(from, ArgList)
char *from,
**ArgList;
{
int flag;
/**************************** PATCHED by Flier ******************************/
char tmpbuf[mybufsize/32];
struct timeval timenow;
struct spingstr *spingtmp;
/****************************************************************************/
if (!from)
return;
flag = double_ignore(from, FromUserHost, IGNORE_CRAP);
if (flag == IGNORED)
return;
/**************************** PATCHED by Flier ******************************/
/*if (ArgList[0])
say("%s: PONG received from %s", ArgList[0], from);*/
if (ArgList[0]) {
if (ArgList[1] &&
(index(ArgList[0],'.') || !strcmp(ArgList[0],get_server_itsname(parsing_server_index)))) {
if ((spingtmp=(struct spingstr *) list_lookup((List **) &spinglist,
ArgList[0],!USE_WILDCARDS,
REMOVE_FROM_LIST))) {
gettimeofday(&timenow,NULL);
timenow.tv_sec-=spingtmp->sec;
if (timenow.tv_usec>=spingtmp->usec)
timenow.tv_usec-=spingtmp->usec;
else {
timenow.tv_usec=timenow.tv_usec-spingtmp->usec+1000000;
timenow.tv_sec--;
}
#ifdef WANTANSI
snprintf(tmpbuf,sizeof(tmpbuf),"%06ld",timenow.tv_usec);
tmpbuf[3]='\0';
say("Server pong from %s%s%s received in %s%ld.%s%s seconds",
CmdsColors[COLCSCAN].color1,ArgList[0],Colors[COLOFF],
CmdsColors[COLCSCAN].color2,timenow.tv_sec,tmpbuf,Colors[COLOFF]);
#else /* WANTANSI */
say("Server pong from %s received in %ld.%s seconds",ArgList[0],
timenow.tv_sec,tmpbuf);
#endif /* WANTANSI */
new_free(&(spingtmp->servername));
new_free(&spingtmp);
if (!my_stricmp(server_list[parsing_server_index].itsname,ArgList[0])) {
#if defined(CELE)
LagTimer=timenow;
#else
LagTimer=timenow.tv_sec;
#endif
update_all_status();
}
}
else if (!strcmp(ArgList[1],"szlagmeter") ||
!strcmp(ArgList[0],get_server_itsname(parsing_server_index))) {
#if defined(CELE)
gettimeofday(&LagTimer,NULL);
LagTimer.tv_sec-=PingSent.tv_sec;
if (LagTimer.tv_usec>=PingSent.tv_usec)
LagTimer.tv_usec-=PingSent.tv_usec;
else {
LagTimer.tv_usec=LagTimer.tv_usec-PingSent.tv_usec+1000000;
LagTimer.tv_sec--;
}
update_all_status();
#else
LagTimer=time((time_t *) 0)-PingSent;
#endif
update_all_status();
}
else say("%s: PONG received from %s", ArgList[0], from);
}
else say("%s: PONG received from %s", ArgList[0], from);
}
/****************************************************************************/
}
/*ARGSUSED*/
static void
p_error(from, ArgList)
char *from,
**ArgList;
{
PasteArgs(ArgList, 0);
if (!ArgList[0])
return;
say("%s", ArgList[0]);
}
static void
p_channel(from, ArgList)
char *from;
char **ArgList;
{
int join;
char *channel;
int flag;
char *s, *ov = NULL;
int chan_oper = 0, chan_voice = 0, chan_halfop = 0;
/**************************** PATCHED by Flier ******************************/
int donelj = 0;
char tmpbuf[mybufsize + 1];
NickList *joiner = NULL;
ChannelList *chan = NULL;
/****************************************************************************/
if (!from)
return;
flag = double_ignore(from, FromUserHost, IGNORE_CRAP);
if (strcmp(ArgList[0], irczero))
{
join = 1;
channel = ArgList[0];
/*
* this \007 should be \a but a lot of compilers are
* broken. *sigh* -mrg
*/
if ((ov = s = index(channel, '\007')))
{
*s = '\0';
ov++;
while (*++s)
{
if (*s == 'o')
chan_oper = 1;
if (*s == 'h')
chan_halfop = 1;
if (*s == 'v')
chan_voice = 1;
}
}
malloc_strcpy((char **) &joined_nick, from);
}
else
{
channel = irczero;
join = 0;
}
if (!my_stricmp(from, get_server_nickname(parsing_server_index)))
{
if (join)
{
/***************************** PATCHED by Flier **************************/
/*add_channel(channel, parsing_server_index, CHAN_JOINED, (ChannelList *) 0);
send_to_server("MODE %s", channel);*/
chan = lookup_channel(channel, parsing_server_index, 0);
add_channel(channel, parsing_server_index, CHAN_JOINED, NULL, NULL,
chan ? chan->gotwho : 0);
chan = lookup_channel(channel, parsing_server_index, 0);
if ((get_server_version(parsing_server_index) == Server2_9 ||
get_server_version(parsing_server_index) == Server2_10 ||
get_server_version(parsing_server_index) == Server2_11) &&
IsIrcNetOperChannel(channel)) {
snprintf(tmpbuf,sizeof(tmpbuf), "MODE %s", channel);
}
else {
if (chan && chan->gotwho) *tmpbuf = '\0';
else snprintf(tmpbuf,sizeof(tmpbuf), "WHO %s", channel);
if (*channel != '+') {
snprintf(&tmpbuf[strlen(tmpbuf)], sizeof(tmpbuf),
"\r\nMODE %s\r\nMODE %s e\r\nMODE %s b",
channel, channel, channel);
}
}
send_to_server("%s", tmpbuf);
/*************************************************************************/
if (get_server_version(parsing_server_index) == Server2_5)
send_to_server("NAMES %s", channel);
/***************************** PATCHED by Flier **************************/
add_to_channel(channel, from, parsing_server_index, chan_oper,
chan_halfop, chan_voice, FromUserHost, NULL);
if (*channel == '+') chan->gotbans = 1;
joiner = ChannelJoin(from, channel, chan);
donelj = 1;
gettimeofday(&(chan->time), NULL);
/*************************************************************************/
}
else
remove_channel(channel, parsing_server_index);
}
else
{
/************************* PATCHED by Flier ***************************/
/*if (join)
add_to_channel(channel, from, parsing_server_index, chan_oper, chan_voice);*/
#ifdef WANTANSI
char tmpbuf1[mybufsize];
#endif
char tmpbuf2[mybufsize];
if (join) {
chan = add_to_channel(channel, from, parsing_server_index, chan_oper,
chan_halfop, chan_voice, FromUserHost, NULL);
joiner = CheckJoin(from, FromUserHost, channel, parsing_server_index, chan);
if (chan && (chan->status & CHAN_CHOP) && chan_oper && chan->NHProt) {
if (!(joiner && joiner->frlist && joiner->frlist->privs))
send_to_server("MODE %s -o %s", channel, from);
}
if (chan_oper && NHDisp == 2) {
save_message_from();
message_from(channel, LOG_CRAP);
#ifdef WANTANSI
snprintf(tmpbuf1, sizeof(tmpbuf1), "[%s%s%s] on %s%s%s",
CmdsColors[COLNETSPLIT].color3, GetNetsplitServer(channel, from),
Colors[COLOFF], CmdsColors[COLNETSPLIT].color4, channel, Colors[COLOFF]);
snprintf(tmpbuf2, sizeof(tmpbuf2), "%sNetsplit hack%s %s by : %s%s%s",
CmdsColors[COLNETSPLIT].color1, Colors[COLOFF], tmpbuf1,
CmdsColors[COLNETSPLIT].color5, from, Colors[COLOFF]);
#else
snprintf(tmpbuf2, sizeof(tmpbuf2), "Netsplit hack [%s] on %s by : %s",
GetNetsplitServer(channel, from), channel, from);
#endif
say("%s",tmpbuf2);
if (away_set || LogOn) AwaySave(tmpbuf2, SAVEHACK);
if (chan && chan->ChanLog) ChannelLogSave(tmpbuf2, chan);
restore_message_from();
}
}
/**********************************************************************/
else
remove_from_channel(channel, from, parsing_server_index);
}
if (join)
{
/**************************** PATCHED by Flier ******************************/
if ((double_ignore(channel, NULL, IGNORE_JOIN)) == IGNORED)
return;
if ((double_ignore(channel, from, IGNORE_JOIN)) == IGNORED)
return;
if (is_channel(channel) &&
double_ignore(FromUserHost, channel, IGNORE_JOIN) == IGNORED)
return;
/****************************************************************************/
if (!get_channel_oper(channel, parsing_server_index))
in_on_who = 1;
save_message_from();
message_from(channel, LOG_CRAP);
if (flag != IGNORED && do_hook(JOIN_LIST, "%s %s %s", from,
channel, ov ? ov : ""))
{
/**************************** PATCHED by Flier ******************************/
/*if (FromUserHost)
if (ov && *ov)
say("%s (%s) has joined channel %s +%s", from,
FromUserHost, channel, ov);
else
say("%s (%s) has joined channel %s", from,
FromUserHost, channel);
else
if (ov && *ov)
say("%s has joined channel %s +%s", from,
channel, ov);
else
say("%s has joined channel %s", from, channel);*/
if (FromUserHost) {
if (HandleJoin(joiner, from, FromUserHost, channel, chan) && !donelj) {
strmcpy(tmpbuf, from, sizeof(tmpbuf));
strmcat(tmpbuf, "/", sizeof(tmpbuf));
if (ov && *ov) strmcat(tmpbuf, "+", sizeof(tmpbuf));
strmcat(tmpbuf, channel, sizeof(tmpbuf));
malloc_strcpy(&(server_list[parsing_server_index].LastJoin), tmpbuf);
update_all_status();
}
}
else
if (ov && *ov)
say("%s has joined channel %s +%s", from, channel, ov);
else
say("%s has joined channel %s", from, channel);
/****************************************************************************/
}
/**************************** PATCHED by Flier ******************************/
else if (flag != IGNORED) {
strmcpy(tmpbuf, from, sizeof(tmpbuf));
strmcat(tmpbuf, "/", sizeof(tmpbuf));
if (ov && *ov) strmcat(tmpbuf, "+", sizeof(tmpbuf));
strmcat(tmpbuf, channel, sizeof(tmpbuf));
malloc_strcpy(&(server_list[parsing_server_index].LastJoin), tmpbuf);
update_all_status();
}
/****************************************************************************/
restore_message_from();
in_on_who = 0;
}
}
static void
p_invite(from, ArgList)
char *from,
**ArgList;
{
char *high;
int flag;
if (!from)
return;
flag = double_ignore(from, FromUserHost, IGNORE_INVITES);
switch (flag)
{
case IGNORED:
if (get_int_var(SEND_IGNORE_MSG_VAR))
send_to_server("NOTICE %s :%s is ignoring you",
from, get_server_nickname(parsing_server_index));
return;
case HIGHLIGHTED:
high = &highlight_char;
break;
default:
high = empty_string;
break;
}
if (ArgList[0] && ArgList[1])
{
if ((flag != DONT_IGNORE) && (ignore_usernames & IGNORE_INVITES)
&& !FromUserHost)
add_to_whois_queue(from, whois_ignore_invites,
"%s", ArgList[1]);
else
{
/**************************** PATCHED by Flier ******************************/
if ((double_ignore(ArgList[1], NULL, IGNORE_INVITES)) == IGNORED)
return;
if ((double_ignore(FromUserHost, ArgList[1], IGNORE_INVITES)) == IGNORED)
return;
/****************************************************************************/
save_message_from();
message_from(from, LOG_CRAP);
if (do_hook(INVITE_LIST, "%s %s", from, ArgList[1]))
/************************** PATCHED by Flier **************************/
/*say("%s%s%s invites you to channel %s", high,
from, high, ArgList[1]);*/
HandleInvite(from,FromUserHost,ArgList[1]);
/**********************************************************************/
restore_message_from();
malloc_strcpy(&invite_channel, ArgList[1]);
malloc_strcpy((char **) &recv_nick, from);
}
}
}
static void
p_server_kill(from, ArgList)
char *from,
**ArgList;
{
/*
* this is so bogus checking for a server name having a '.'
* in it - phone, april 1993.
*/
if (index(from, '.'))
say("You have been rejected by server %s", from);
else
{
say("You have been killed by operator %s %s", from,
ArgList[1] ? ArgList[1] : "(No Reason Given)");
/*************************** PATCHED by SHEIK ****************************/
HandleKills(from_server, from, FromUserHost, ArgList[1]);
/****************************************************************************/
}
close_server(parsing_server_index, empty_string);
/*************************** PATCHED by SHEIK ****************************/
ReconnectOnKill(from_server);
/*************************************************************************/
window_check_servers();
if (!connected_to_server)
say("Use /SERVER to reconnect to a server");
}
static void
p_ping(ArgList)
char **ArgList;
{
PasteArgs(ArgList, 0);
send_to_server("PONG :%s", ArgList[0]);
}
static void
p_nick(from, ArgList)
char *from,
**ArgList;
{
int one_prints = 0,
its_me = 0;
char *chan;
char *line;
int flag;
if (!from)
return;
flag = double_ignore(from, FromUserHost, IGNORE_CRAP);
line = ArgList[0];
/**************************** Patched by Flier ******************************/
/*if (my_stricmp(from, get_server_nickname(parsing_server_index)) == 0) {*/
if ((SentNick && !my_stricmp(from, OldNick)) ||
!my_stricmp(from, get_server_nickname(parsing_server_index))) {
/****************************************************************************/
if (parsing_server_index == primary_server)
malloc_strcpy(&nickname, line);
set_server_nickname(parsing_server_index, line);
its_me = 1;
/**************************** Patched by Flier ******************************/
if (OrigNickSent > 0) OrigNickSent--;
/****************************************************************************/
}
save_message_from();
if (flag != IGNORED)
{
for (chan = walk_channels(from, 1, parsing_server_index); chan;
chan = walk_channels(from, 0, -1))
{
message_from(chan, LOG_CRAP);
if (do_hook(CHANNEL_NICK_LIST, "%s %s %s", chan, from, line))
one_prints = 1;
}
if (one_prints)
{
if (its_me)
message_from((char *) 0, LOG_CRAP);
else
message_from(what_channel(from, parsing_server_index), LOG_CRAP);
/**************************** PATCHED by Flier *****************************/
HandleNickChange(from, line, FromUserHost, parsing_server_index);
/***************************************************************************/
if (do_hook(NICKNAME_LIST, "%s %s", from, line))
/**************************** PATCHED by Flier ******************************/
/*say("%s is now known as %s", from, line);*/
{
#ifdef EXTRAS
int showed = 0;
char chanbuf[mybufsize / 4 + 1];
Window *oldto_window;
Winlist *winlist = NULL, *winelem;
NickList *joiner;
ChannelList *chan;
*chanbuf = '\0';
oldto_window = to_window;
chan = server_list[parsing_server_index].chan_list;
for (;chan; chan=chan->next) {
joiner = CheckJoiners(from, chan->channel, parsing_server_index, chan);
/* only if user was on a channel */
if (ShowNickAllChan && joiner) {
/* major pain in the ass: if we have several channels in
* one window we have to display nick change only once in
* that window so we have to know which windows have
* already displayed signoff - we use window pointer */
if (!list_lookup_ext((List **) &winlist,(char *) chan->window,
!USE_WILDCARDS, !REMOVE_FROM_LIST, CompareAddr)) {
winelem = (Winlist *) malloc(sizeof(Winlist));
winelem->window = chan->window;
winelem->next = NULL;
add_to_list_ext((List **) &winlist, (List *) winelem,
(int (*) _((List *, List *))) AddLast);
}
}
}
for (winelem = winlist; ;) {
if (winelem) to_window = winelem->window;
else if (showed) break;
showed = 1;
#endif /* EXTRAS */
#ifdef WANTANSI
say("%s%s%s is now %sknown%s as %s%s%s",
CmdsColors[COLNICK].color1, from, Colors[COLOFF],
CmdsColors[COLNICK].color2, Colors[COLOFF],
CmdsColors[COLNICK].color3, line, Colors[COLOFF]);
#else /* WANTANSI */
say("%s is now known as %s", from, line);
#endif /* WANTANSI */
#ifdef EXTRAS
if (!winelem) break;
else winelem = winelem->next;
}
to_window = oldto_window;
if (ShowNickAllChan && winlist) {
/* free stored info about windows */
while (winlist) {
winelem = winlist;
winlist = winlist->next;
new_free(&winelem);
}
}
#endif /* EXTRAS */
}
/****************************************************************************/
}
}
rename_nick(from, line, parsing_server_index);
if (my_stricmp(from, line))
{
message_from((char *) 0, LOG_CURRENT);
notify_mark(from, 0, 0);
notify_mark(line, 1, 0);
}
restore_message_from();
}
static void
p_mode(from, ArgList)
char *from,
**ArgList;
{
char *channel;
char *line;
int flag;
/**************************** PATCHED by Flier ******************************/
char tmpbuf1[mybufsize/2];
char tmpbuf2[mybufsize/2];
char tmpbuf3[mybufsize/2];
/****************************************************************************/
if (!from)
return;
flag = double_ignore(from, FromUserHost, IGNORE_CRAP);
PasteArgs(ArgList, 1);
channel = ArgList[0];
line = ArgList[1];
save_message_from();
message_from(channel, LOG_CRAP);
if (channel && line)
{
if (is_channel(channel))
{
/************************ PATCHED by Flier *************************/
/*if (flag != IGNORED && do_hook(MODE_LIST, "%s %s %s",
from, channel, line))
say("Mode change \"%s\" on channel %s by %s",
line, channel, from);
update_channel_mode(channel, parsing_server_index, line);*/
strmcpy(tmpbuf3,line,sizeof(tmpbuf3));
update_channel_mode(channel,parsing_server_index,tmpbuf3,sizeof(tmpbuf3),
from,FromUserHost,tmpbuf1,tmpbuf2,NULL);
if (flag!=IGNORED) flag=double_ignore(channel,NULL,IGNORE_CRAP);
if (flag!=IGNORED) flag=double_ignore(FromUserHost,channel,IGNORE_CRAP);
if (*tmpbuf3 && flag!=IGNORED && do_hook(MODE_LIST, "%s %s %s",
from,channel,tmpbuf3))
ModePrint(tmpbuf3,channel,from,FromUserHost,tmpbuf1,tmpbuf2);
#ifdef EXTRAS
if (my_stricmp(from,get_server_nickname(from_server)))
CheckLock(channel,from_server,NULL);
#endif
/*******************************************************************/
}
else
{
if (flag != IGNORED && do_hook(MODE_LIST, "%s %s %s",
from, channel, line))
say("Mode change \"%s\" for user %s by %s",
line, channel, from);
update_user_mode(line);
}
update_all_status();
}
restore_message_from();
}
static void
p_kick(from, ArgList)
char *from,
**ArgList;
{
char *channel,
*who,
*comment;
/**************************** PATCHED by Flier *******************************/
int flag;
int frkick;
/****************************************************************************/
if (!from)
return;
channel = ArgList[0];
who = ArgList[1];
comment = ArgList[2];
if (channel && who)
{
save_message_from();
message_from(channel, LOG_CRAP);
if (my_stricmp(who, get_server_nickname(parsing_server_index)) == 0)
{
/**************************** PATCHED by Flier *******************************/
/*if (comment && *comment)
{
if (do_hook(KICK_LIST, "%s %s %s %s", who,
from, channel, comment))
say("You have been kicked off channel %s by %s (%s)",
channel, from, comment);
}
else
{
if (do_hook(KICK_LIST, "%s %s %s", who, from,
channel))
say("You have been kicked off channel %s by %s",
channel, from);
}*/
int rejoin=0;
char tmpbuf[mybufsize/2];
NickList *joiner;
ChannelList *chan;
chan=lookup_channel(channel,parsing_server_index,0);
if (chan) {
if (chan->AutoRejoin) {
snprintf(tmpbuf,sizeof(tmpbuf),"%s ",chan->channel);
if (chan->key) strmcat(tmpbuf,chan->key, sizeof(tmpbuf));
rejoin=1;
}
chan->kick++;
}
joiner=CheckJoiners(who,channel,from_server,chan);
frkick=(joiner && joiner->frlist)?joiner->frlist->privs:0;
HandleMyKick(who,from,FromUserHost,channel,comment);
flag = double_ignore(channel,NULL,IGNORE_CRAP);
if (flag == 0)
flag = double_ignore(FromUserHost,channel,IGNORE_CRAP);
if (flag != IGNORED) {
if (comment && *comment)
{
if (do_hook(KICK_LIST, "%s %s %s %s", who,
from, channel, comment))
#ifdef CELECOSM
KickPrint("You","were",from,channel,comment,rejoin,frkick);
#else
KickPrint("You","have",from,channel,comment,rejoin,frkick);
#endif /* CELECOSM */
}
else
{
if (do_hook(KICK_LIST, "%s %s %s", who, from,
channel))
#ifdef CELECOSM
KickPrint("You","were",from,channel,NULL,rejoin,frkick);
#else
KickPrint("You","have",from,channel,NULL,rejoin,frkick);
#endif /*CELECOSM*/
}
}
/****************************************************************************/
remove_channel(channel, parsing_server_index);
/**************************** PATCHED by Flier ******************************/
if (rejoin) e_channel("JOIN",tmpbuf,NULL);
/****************************************************************************/
update_all_status();
}
else
{
/**************************** PATCHED by Flier ******************************/
HandleKick(from,who,FromUserHost,channel,comment,&frkick);
/*if (comment && *comment)
{
if (do_hook(KICK_LIST, "%s %s %s %s", who,
from, channel, comment))
say("%s has been kicked off channel %s by %s (%s)",
who, channel, from, comment);
}
else
{
if (do_hook(KICK_LIST, "%s %s %s", who, from,
channel))
say("%s has been kicked off channel %s by %s",
who, channel, from);
}*/
flag = double_ignore(channel,NULL,IGNORE_CRAP);
if (flag == 0)
flag = double_ignore(FromUserHost,channel,IGNORE_CRAP);
if (flag!=IGNORED) {
if (comment && *comment)
{
if (do_hook(KICK_LIST, "%s %s %s %s", who,
from, channel, comment))
#ifdef CELECOSM
KickPrint(who,"was",from,channel,comment,0,frkick);
#else
KickPrint(who,"has",from,channel,comment,0,frkick);
#endif /* CELECOSM */
}
else
{
if (do_hook(KICK_LIST, "%s %s %s", who, from,
channel))
#ifdef CELECOSM
KickPrint(who,"was",from,channel,NULL,0,frkick);
#else
KickPrint(who,"has",from,channel,NULL,0,frkick);
#endif /*CELECOSM*/
}
}
/****************************************************************************/
remove_from_channel(channel, who, parsing_server_index);
}
restore_message_from();
}
}
static void
p_part(from, ArgList)
char *from,
**ArgList;
{
char *channel;
char *comment;
int flag;
/**************************** PATCHED by Flier ******************************/
#ifdef WANTANSI
char *colnick;
NickList *joiner;
#endif
ChannelList *chan;
/****************************************************************************/
if (!from)
return;
flag = double_ignore(from, FromUserHost, IGNORE_CRAP);
/**************************** PATCHED by Flier ******************************/
if (flag!=IGNORED) flag=double_ignore(ArgList[0],NULL,IGNORE_PART);
if (flag!=IGNORED) flag=double_ignore(FromUserHost,ArgList[0],IGNORE_PART);
/****************************************************************************/
channel = ArgList[0];
if (!is_on_channel(channel, parsing_server_index, from))
return;
comment = ArgList[1];
if (!comment)
comment = empty_string;
in_on_who = 1;
if (flag != IGNORED)
{
save_message_from();
message_from(channel, LOG_CRAP);
if (do_hook(LEAVE_LIST, "%s %s %s", from, channel, comment)) {
/**************************** PATCHED by Flier ******************************/
/*if (comment && *comment != '\0')
say("%s has left channel %s (%s)", from, channel, comment);
else
say("%s has left channel %s", from, channel);*/
#ifdef WANTANSI
joiner=CheckJoiners(from,channel,parsing_server_index,NULL);
if (joiner && joiner->shitlist && joiner->shitlist->shit)
colnick=CmdsColors[COLLEAVE].color5;
else if (joiner && joiner->frlist && joiner->frlist->privs)
colnick=CmdsColors[COLLEAVE].color4;
else colnick=CmdsColors[COLLEAVE].color1;
if (comment && *comment!='\0' && strcmp(from,comment))
say("%s%s%s has left channel %s%s%s (%s%s%s)",
colnick,from,Colors[COLOFF],
CmdsColors[COLLEAVE].color2,channel,Colors[COLOFF],
CmdsColors[COLLEAVE].color6,comment,Colors[COLOFF]);
else say("%s%s%s has left channel %s%s%s",colnick,from,Colors[COLOFF],
CmdsColors[COLLEAVE].color2,channel,Colors[COLOFF]);
#else
if (comment && *comment!='\0' && strcmp(from,comment))
say("%s has left channel %s (%s)",from,channel,comment);
else say("%s has left channel %s",from,channel);
#endif
if (ChanLog) {
chan = lookup_channel(channel, parsing_server_index, 0);
if (chan->ChanLog) {
char tmpbuf2[mybufsize];
snprintf(tmpbuf2, sizeof(tmpbuf2), "%s has left channel %s", from, channel);
if (comment && *comment)
snprintf(&tmpbuf2[strlen(tmpbuf2)], sizeof(tmpbuf2), "(%s)", comment);
ChannelLogSave(tmpbuf2, chan);
}
}
/****************************************************************************/
}
restore_message_from();
}
if (my_stricmp(from, get_server_nickname(parsing_server_index)) == 0)
remove_channel(channel, parsing_server_index);
else
remove_from_channel(channel, from, parsing_server_index);
in_on_who = 0;
}
/*
* parse_server: parses messages from the server, doing what should be done
* with them
*/
void
parse_server(line)
char *line;
{
server_list[parsing_server_index].parse_server(line);
}
void
irc2_parse_server(line)
char *line;
{
char *from,
*comm,
*end,
*copy = (char *) 0;
int numeric;
char **ArgList;
char *TrueArgs[MAXPARA + 1];
if ((char *) 0 == line)
return;
end = strlen(line) + line;
if (*--end == '\n')
*end-- = '\0';
if (*end == '\r')
*end-- = '\0';
if (*line == ':')
{
if (!do_hook(RAW_IRC_LIST, "%s", line + 1))
return;
}
else if (!do_hook(RAW_IRC_LIST, "%s %s", "*", line))
return;
malloc_strcpy(©, line);
ArgList = TrueArgs;
BreakArgs(copy, &from, ArgList);
if (!(comm = (*ArgList++)))
return; /* Empty line from server - ByeBye */
/*
* XXX!!!
* this should fail on '1xxx'!!!
*/
if (0 != (numeric = atoi(comm)))
numbered_command(from, numeric, ArgList);
else if (strcmp(comm, "NAMREPLY") == 0)
funny_namreply(from, ArgList);
else if (strcmp(comm, "WHOREPLY") == 0)
whoreply(from, ArgList);
else if (strcmp(comm, "NOTICE") == 0)
parse_notice(from, ArgList);
/* everything else is handled locally */
else if (strcmp(comm, "PRIVMSG") == 0)
p_privmsg(from, ArgList);
else if (strcmp(comm, "JOIN") == 0)
p_channel(from, ArgList);
else if (strcmp(comm, "PART") == 0)
p_part(from, ArgList);
else if (strcmp(comm, "CHANNEL") == 0)
p_channel(from, ArgList);
else if (strcmp(comm, "MSG") == 0)
/*p_msgcmd(from, ArgList)*/;
else if (strcmp(comm, "QUIT") == 0)
p_quit(from, ArgList);
else if (strcmp(comm, "WALL") == 0)
p_wall(from, ArgList);
else if (strcmp(comm, "WALLOPS") == 0)
p_wallops(from, ArgList);
else if (strcmp(comm, "LINREPLY") == 0)
p_linreply(ArgList);
else if (strcmp(comm, "PING") == 0)
p_ping(ArgList);
else if (strcmp(comm, "TOPIC") == 0)
p_topic(from, ArgList);
else if (strcmp(comm, "PONG") == 0)
p_pong(from, ArgList);
else if (strcmp(comm, "INVITE") == 0)
p_invite(from, ArgList);
else if (strcmp(comm, "NICK") == 0)
p_nick(from, ArgList);
else if (strcmp(comm, "KILL") == 0)
p_server_kill(from, ArgList);
else if (strcmp(comm, "MODE") == 0)
p_mode(from, ArgList);
else if (strcmp(comm, "KICK") == 0)
p_kick(from, ArgList);
else if (strcmp(comm, "ERROR") == 0)
p_error(from, ArgList);
else if (strcmp(comm, "ERROR:") == 0) /* Server bug makes this a must */
p_error(from, ArgList);
else
{
PasteArgs(ArgList, 0);
if (from)
say("Odd server stuff: \"%s %s\" (%s)", comm,
ArgList[0], from);
else
say("Odd server stuff: \"%s %s\"", comm, ArgList[0]);
}
new_free(©);
}
syntax highlighted by Code2HTML, v. 0.9.1