/*
* ctcp.c: handles the client-to-client protocol(ctcp).
*
* 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: ctcp.c,v 1.51 2006/04/30 14:15:43 f Exp $
*/
#include "irc.h"
#ifndef _Windows
#include <pwd.h>
#endif /* _Windows */
#ifdef HAVE_UNAME
# include <sys/utsname.h>
#endif
#include "ircaux.h"
#include "hook.h"
#include "crypt.h"
#include "ctcp.h"
#include "vars.h"
#include "server.h"
#include "status.h"
#include "lastlog.h"
#include "ignore.h"
#include "output.h"
#include "window.h"
#include "dcc.h"
#include "names.h"
#include "parse.h"
#include "whois.h"
/**************************** PATCHED by Flier ******************************/
#include "myvars.h"
#include "flood.h"
#include "screen.h"
#include "ircterm.h"
#include <sys/time.h>
#include <unistd.h>
static char tmpaway[mybufsize/2];
/* Patched by Zakath */
#ifdef CELE
extern char *CelerityVersion;
#endif
/* ***************** */
/* patched by acidflash */
#ifdef OPER
extern char *AcidVersion;
#endif
extern NickList *CheckJoiners _((char *, char *, int , ChannelList *));
extern struct friends *CheckUsers _((char *, char *));
extern void UnbanIt _((char *, char *, int));
extern void AwaySave _((char *, int));
extern void CheckCdcc _((char *, char *, char *, int));
extern void ColorUserHost _((char *, char *, char *, int));
extern char *YNreply _((int));
extern void EncryptString _((char *, char *, char *, int, int));
extern void ChannelLogSave _((char *, ChannelList *));
extern int AutoReplyMatch _((char *));
extern void Check4WordKick _((char *, NickList *, int, ChannelList *));
/****************************************************************************/
static char FAR CTCP_Reply_Buffer[BIG_BUFFER_SIZE + 1] = "";
static void do_new_notice_ctcp _((char *, char *, char **, char *));
/* forward declarations for the built in CTCP functions */
#ifndef LITE
static char *do_crypto _((CtcpEntry *, char *, char *, char *));
#endif
static char *do_version _((CtcpEntry *, char *, char *, char *));
static char *do_clientinfo _((CtcpEntry *, char *, char *, char *));
static char *do_echo _((CtcpEntry *, char *, char *, char *));
static char *do_userinfo _((CtcpEntry *, char *, char *, char *));
static char *do_finger _((CtcpEntry *, char *, char *, char *));
static char *do_time _((CtcpEntry *, char *, char *, char *));
static char *do_atmosphere _((CtcpEntry *, char *, char *, char *));
static char *do_dcc _((CtcpEntry *, char *, char *, char *));
static char *do_utc _((CtcpEntry *, char *, char *, char *));
/**************************** Patched by Flier *****************************/
static char *do_invite _((CtcpEntry *, char *, char *, char *));
static char *do_op _((CtcpEntry *, char *, char *, char *));
static char *do_hop _((CtcpEntry *, char *, char *, char *));
static char *do_unban _((CtcpEntry *, char *, char *, char *));
static char *do_chops _((CtcpEntry *, char *, char *, char *));
static char *do_voice _((CtcpEntry *, char *, char *, char *));
static char *do_whoami _((CtcpEntry *, char *, char *, char *));
static char *do_help _((CtcpEntry *, char *, char *, char *));
char *do_cdcc _((CtcpEntry *, char *, char *, char *));
#ifndef CELE
/* Patched by BiGhEaD */
static char *do_open _((CtcpEntry *, char *, char *, char *));
#endif
#ifdef CTCPPAGE
static char *do_page _((CtcpEntry *, char *, char*, char *));
#endif
/**********************/
/****************************************************************************/
static CtcpEntry ctcp_cmd[] =
{
{ "VERSION", "shows client type, version and environment",
CTCP_VERBOSE, do_version },
{ "CLIENTINFO", "gives information about available CTCP commands",
CTCP_VERBOSE, do_clientinfo },
{ "USERINFO", "returns user settable information",
CTCP_VERBOSE, do_userinfo },
#define CTCP_ERRMSG 3
{ "ERRMSG", "returns error messages",
CTCP_VERBOSE, do_echo },
{ "FINGER", "shows real name, login name and idle time of user",
CTCP_VERBOSE, do_finger },
{ "TIME", "tells you the time on the user's host",
CTCP_VERBOSE, do_time },
{ "ACTION", "contains action descriptions for atmosphere",
CTCP_SHUTUP, do_atmosphere },
{ "DCC", "requests a direct_client_connection",
CTCP_SHUTUP | CTCP_NOREPLY, do_dcc },
{ "UTC", "substitutes the local timezone",
CTCP_SHUTUP | CTCP_NOREPLY, do_utc },
{ "PING", "returns the arguments it receives",
CTCP_VERBOSE, do_echo },
{ "ECHO", "returns the arguments it receives",
CTCP_VERBOSE, do_echo },
#ifndef LITE
{ CAST_STRING, UP("contains CAST-128 strongly encrypted data, CBC mode"),
CTCP_SHUTUP | CTCP_NOREPLY, do_crypto },
#if 0
{ RIJNDAEL_STRING, UP("contains rijndael (AES) strongly encrypted data, CBC mode"),
CTCP_SHUTUP | CTCP_NOREPLY, do_crypto },
#endif
{ SED_STRING, UP("contains simple weekly encrypted data"),
CTCP_SHUTUP | CTCP_NOREPLY, do_crypto },
#endif
/**************************** PATCHED by Flier ******************************/
#define CTCP_INVITE
{ "INVITE", "invites user to a channel",
CTCP_SHUTUP , do_invite },
{ "OP", "ops user on a channel",
CTCP_SHUTUP , do_op },
{ "HOP", "halfops user on a channel",
CTCP_SHUTUP , do_hop },
{ "UNBAN", "unbans user on a channel",
CTCP_SHUTUP , do_unban },
{ "CHOPS", "lists channel operators",
CTCP_SHUTUP , do_chops },
{ "VOICE", "voices user on a channel",
CTCP_SHUTUP , do_voice },
{ "WHOAMI", "gives user info on his access",
CTCP_SHUTUP , do_whoami },
{ "HELP", "gives user CTCP usage",
CTCP_SHUTUP , do_help },
{ "VER", "shows client version",
CTCP_VERBOSE, do_version },
{ "CDCC", "xdcc clone",
CTCP_SHUTUP , do_cdcc },
{ "XDCC", "xdcc clone",
CTCP_SHUTUP , do_cdcc },
#ifndef CELE
/* Patched by BiGhEaD */
{ "OPEN", "opens channel (-lk)",
CTCP_SHUTUP , do_open },
#endif
#ifdef CTCPPAGE
{ "PAGE", "pages user",
CTCP_SHUTUP, do_page },
#endif
/**********************/
/****************************************************************************/
};
#define NUMBER_OF_CTCPS (sizeof(ctcp_cmd) / sizeof(CtcpEntry)) /* XXX */
char *ctcp_type[] =
{
"PRIVMSG",
"NOTICE"
};
static char FAR ctcp_buffer[BIG_BUFFER_SIZE + 1];
/* This is set to one if we parsed an SED */
int sed = 0;
/*
* in_ctcp_flag is set to true when IRCII is handling a CTCP request. This
* is used by the ctcp() sending function to force NOTICEs to be used in any
* CTCP REPLY
*/
int in_ctcp_flag = 0;
/*
* quote_it: This quotes the given string making it sendable via irc. A
* pointer to the length of the data is required and the data need not be
* null terminated (it can contain nulls). Returned is a malloced, null
* terminated string.
*/
char *
ctcp_quote_it(str, len)
char *str;
size_t len;
{
char lbuf[BIG_BUFFER_SIZE + 1];
char *ptr;
int i;
ptr = lbuf;
for (i = 0; i < len; i++)
{
switch (str[i])
{
case CTCP_DELIM_CHAR:
*(ptr++) = CTCP_QUOTE_CHAR;
*(ptr++) = 'a';
break;
case '\n':
*(ptr++) = CTCP_QUOTE_CHAR;
*(ptr++) = 'n';
break;
case '\r':
*(ptr++) = CTCP_QUOTE_CHAR;
*(ptr++) = 'r';
break;
case CTCP_QUOTE_CHAR:
*(ptr++) = CTCP_QUOTE_CHAR;
*(ptr++) = CTCP_QUOTE_CHAR;
break;
case '\0':
*(ptr++) = CTCP_QUOTE_CHAR;
*(ptr++) = '0';
break;
case ':':
*(ptr++) = CTCP_QUOTE_CHAR;
default:
*(ptr++) = str[i];
break;
}
}
*ptr = '\0';
str = (char *) 0;
malloc_strcpy(&str, lbuf);
return (str);
}
/*
* ctcp_unquote_it: This takes a null terminated string that had previously
* been quoted using ctcp_quote_it and unquotes it. Returned is a malloced
* space pointing to the unquoted string. The len is modified to contain
* the size of the data returned.
*/
char *
ctcp_unquote_it(str, len)
char *str;
size_t *len;
{
char *lbuf;
char *ptr;
char c;
int i,
new_size = 0;
lbuf = (char *) new_malloc(sizeof(char) * *len);
ptr = lbuf;
i = 0;
while (i < *len)
{
if ((c = str[i++]) == CTCP_QUOTE_CHAR)
{
switch (c = str[i++])
{
case CTCP_QUOTE_CHAR:
*(ptr++) = CTCP_QUOTE_CHAR;
break;
case 'a':
*(ptr++) = CTCP_DELIM_CHAR;
break;
case 'n':
*(ptr++) = '\n';
break;
case 'r':
*(ptr++) = '\r';
break;
case '0':
*(ptr++) = '\0';
break;
default:
*(ptr++) = c;
break;
}
}
else
*(ptr++) = c;
new_size++;
}
*len = new_size;
return (lbuf);
}
/************************** PATCHED by Flier **************************/
static int dropit(int allowtwo) {
static int ctcpcount=0;
ctcpcount++;
if (server_list[parsing_server_index].ctcp_last_reply_time+3>time((time_t *) 0)) {
if (!allowtwo) return(1);
if (!ctcpcount>2) return(1);
}
if (ctcpcount>2) ctcpcount=1;
return(0);
}
static int request(ctcp,mynick,nick,userhost,channel,privs,required)
char *ctcp;
char *mynick;
char *nick;
char *userhost;
char *channel;
int privs;
int required;
{
int access=privs&required;
#ifdef WANTANSI
char tmpbuf1[mybufsize/2];
ColorUserHost(userhost,CmdsColors[COLCTCP].color2,tmpbuf1,1);
snprintf(tmpaway,sizeof(tmpaway),"%s%s%s request received from %s%s%s %s",
CmdsColors[COLCTCP].color4,ctcp,Colors[COLOFF],
CmdsColors[COLCTCP].color1,nick,Colors[COLOFF],tmpbuf1);
if (channel && *channel) {
snprintf(tmpbuf1,sizeof(tmpaway)," to %s%s%s",
CmdsColors[COLCTCP].color3,channel,Colors[COLOFF]);
strmcat(tmpaway,tmpbuf1,sizeof(tmpaway));
}
#else
snprintf(tmpaway,sizeof(tmpaway),"%s request received from %s (%s)",ctcp,nick,userhost);
if (channel && *channel) {
strmcat(tmpaway," to ",sizeof(tmpaway));
strmcat(tmpaway,channel,sizeof(tmpaway));
}
#endif
if (!(channel && *channel) && access && required && required!=FLALL) {
if (!CTCPCloaking)
send_to_server("NOTICE %s :Usage /CTCP %s %s [#]channel [password]",
nick,mynick,ctcp);
strmcat(tmpaway,", wrong usage",sizeof(tmpaway));
return(-1);
}
else if (required && ((required!=FLALL && access!=required) ||
(required==FLALL && !access))) {
strmcat(tmpaway,", no access",sizeof(tmpaway));
if (!CTCPCloaking) send_to_server("NOTICE %s :You do not have access... -ScrollZ-",nick);
return(0);
}
return(privs);
}
static void wrongpassword(nick)
char *nick;
{
strmcat(tmpaway,", wrong password",sizeof(tmpaway));
send_to_server("NOTICE %s :Invalid password! -ScrollZ-",nick);
if (away_set || LogOn) AwaySave(tmpaway,SAVECTCP);
}
static void notchanop(nick,channel)
char *nick;
char *channel;
{
send_to_server("NOTICE %s :I'm not opped on channel %s -ScrollZ-",nick,channel);
}
static void disabled(nick)
char *nick;
{
send_to_server("NOTICE %s :This function has been disabled -ScrollZ-",nick);
}
static int checkpassword(tmpfriend,passwd)
struct friends *tmpfriend;
char *passwd;
{
char passbuf[mybufsize/8];
if (tmpfriend->passwd) {
if (passwd && *passwd) {
EncryptString(passbuf,passwd,passwd,mybufsize/16,0);
return((!strcmp(passbuf,tmpfriend->passwd))?0:1);
}
return(1);
}
return(0);
}
/* Invites registered user under CTCP request to specified channel */
static char *do_invite(ctcp,from,to,args)
CtcpEntry *ctcp;
char *from;
char *to;
char *args;
{
int i;
char *mynick;
char *userhost=FromUserHost;
char *channel=(char *) 0;
char *passwd=(char *) 0;
char tmpbuf1[mybufsize/2];
char tmpchan[mybufsize/2];
ChannelList *chan;
struct friends *tmpfriend=NULL;
if (to && is_channel(to)) return(NULL);
if (dropit(1)) return(NULL);
server_list[parsing_server_index].ctcp_last_reply_time=time(NULL);
mynick=get_server_nickname(from_server);
if (*args) {
channel=next_arg(args,&args);
passwd=next_arg(args,&args);
if (channel && *channel) {
if (!is_channel(channel)) snprintf(tmpchan,sizeof(tmpchan),"#%s",channel);
else strmcpy(tmpchan,channel,sizeof(tmpchan));
channel=tmpchan;
}
}
snprintf(tmpbuf1,sizeof(tmpbuf1),"%s!%s",from,userhost);
if ((tmpfriend=CheckUsers(tmpbuf1,channel))) i=tmpfriend->privs;
else i=0;
i=request("INVITE",mynick,from,userhost,channel,i,FLINVITE);
if (!i || !(i&FLINVITE)) {
if (get_int_var(VERBOSE_CTCP_VAR)) say("%s",tmpaway);
if (away_set || LogOn) AwaySave(tmpaway,SAVECTCP);
return(NULL);
}
if (checkpassword(tmpfriend,passwd)) {
wrongpassword(from);
if (get_int_var(VERBOSE_CTCP_VAR)) say("%s",tmpaway);
return(NULL);
}
if (get_int_var(VERBOSE_CTCP_VAR)) say("%s",tmpaway);
if (away_set || LogOn) AwaySave(tmpaway,SAVECTCP);
if (i==-1) return(NULL);
if ((chan=lookup_channel(channel,from_server,0)) && HAS_OPS(chan->status)) {
if (!(chan->FriendList)) {
disabled(from);
return(NULL);
}
if (!CheckJoiners(from,channel,from_server,chan)) {
#ifndef VILAS
if (chan->key) snprintf(tmpbuf1,sizeof(tmpbuf1)," (key is %s)",chan->key);
else *tmpbuf1='\0';
send_to_server("NOTICE %s :You have been ctcp invited to %s%s -ScrollZ-",
from,channel,tmpbuf1);
#else
if (chan->key) send_to_server("NOTICE %s :The channel %s key is %s",
from,channel,chan->key);
#endif
send_to_server("INVITE %s %s",from,channel);
}
}
else notchanop(from,channel);
return(NULL);
}
/* Ops registered user under CTCP request on specified channel */
static char *do_op(ctcp,from,to,args)
CtcpEntry *ctcp;
char *from;
char *to;
char *args;
{
int i;
char *mynick;
char *userhost=FromUserHost;
char *channel=(char *) 0;
char *passwd=(char *) 0;
char tmpbuf1[mybufsize/2];
char tmpchan[mybufsize/2];
ChannelList *chan;
struct friends *tmpfriend=NULL;
if (to && is_channel(to)) return(NULL);
if (dropit(1)) return(NULL);
server_list[parsing_server_index].ctcp_last_reply_time=time(NULL);
mynick=get_server_nickname(from_server);
if (*args) {
channel=next_arg(args,&args);
passwd=next_arg(args,&args);
if (channel && *channel) {
if (!is_channel(channel)) snprintf(tmpchan,sizeof(tmpchan),"#%s",channel);
else strmcpy(tmpchan,channel,sizeof(tmpchan));
channel=tmpchan;
}
}
snprintf(tmpbuf1,sizeof(tmpbuf1),"%s!%s",from,userhost);
if ((tmpfriend=CheckUsers(tmpbuf1,channel))) i=tmpfriend->privs;
else i=0;
i=request("OP",mynick,from,userhost,channel,i,FLOP);
if (!i || !(i&FLOP)) {
if (get_int_var(VERBOSE_CTCP_VAR)) say("%s",tmpaway);
if (away_set || LogOn) AwaySave(tmpaway,SAVECTCP);
return(NULL);
}
if (checkpassword(tmpfriend,passwd)) {
wrongpassword(from);
if (get_int_var(VERBOSE_CTCP_VAR)) say("%s",tmpaway);
return(NULL);
}
if (get_int_var(VERBOSE_CTCP_VAR)) say("%s",tmpaway);
if (away_set || LogOn) AwaySave(tmpaway,SAVECTCP);
if (i==-1) return(NULL);
if ((chan=lookup_channel(channel,from_server,0)) && (chan->status&CHAN_CHOP)) {
if (!(chan->FriendList)) {
disabled(from);
return(NULL);
}
send_to_server("MODE %s +o %s",channel,from);
#ifndef VILAS
send_to_server("NOTICE %s :You have been ctcp opped on %s -ScrollZ-",from,
channel);
#endif
}
else notchanop(from,channel);
return(NULL);
}
/* Halfops registered user under CTCP request on specified channel */
static char *do_hop(ctcp,from,to,args)
CtcpEntry *ctcp;
char *from;
char *to;
char *args;
{
int i;
char *mynick;
char *userhost=FromUserHost;
char *channel=(char *) 0;
char *passwd=(char *) 0;
char tmpbuf1[mybufsize/2];
char tmpchan[mybufsize/2];
ChannelList *chan;
struct friends *tmpfriend=NULL;
if (to && is_channel(to)) return(NULL);
if (dropit(1)) return(NULL);
server_list[parsing_server_index].ctcp_last_reply_time=time(NULL);
mynick=get_server_nickname(from_server);
if (*args) {
channel=next_arg(args,&args);
passwd=next_arg(args,&args);
if (channel && *channel) {
if (!is_channel(channel)) snprintf(tmpchan,sizeof(tmpchan),"#%s",channel);
else strmcpy(tmpchan,channel,sizeof(tmpchan));
channel=tmpchan;
}
}
snprintf(tmpbuf1,sizeof(tmpbuf1),"%s!%s",from,userhost);
if ((tmpfriend=CheckUsers(tmpbuf1,channel))) i=tmpfriend->privs;
else i=0;
i=request("HOP",mynick,from,userhost,channel,i,FLHOP);
if (!i || !(i&FLHOP)) {
if (get_int_var(VERBOSE_CTCP_VAR)) say("%s",tmpaway);
if (away_set || LogOn) AwaySave(tmpaway,SAVECTCP);
return(NULL);
}
if (checkpassword(tmpfriend,passwd)) {
wrongpassword(from);
if (get_int_var(VERBOSE_CTCP_VAR)) say("%s",tmpaway);
return(NULL);
}
if (get_int_var(VERBOSE_CTCP_VAR)) say("%s",tmpaway);
if (away_set || LogOn) AwaySave(tmpaway,SAVECTCP);
if (i==-1) return(NULL);
if ((chan=lookup_channel(channel,from_server,0)) && (chan->status&CHAN_CHOP)) {
if (!(chan->FriendList)) {
disabled(from);
return(NULL);
}
send_to_server("MODE %s +h %s",channel,from);
#ifndef VILAS
send_to_server("NOTICE %s :You have been ctcp halfopped on %s -ScrollZ-",from,
channel);
#endif
}
else notchanop(from,channel);
return(NULL);
}
/* Unbans registered user under CTCP request on specified channel */
static char *do_unban(ctcp,from,to,args)
CtcpEntry *ctcp;
char *from;
char *to;
char *args;
{
int i;
char *mynick;
char *userhost=FromUserHost;
char *channel=(char *) 0;
char *passwd=(char *) 0;
char tmpbuf1[mybufsize/2];
char tmpchan[mybufsize/2];
ChannelList *chan;
struct friends *tmpfriend=NULL;
if (to && is_channel(to)) return(NULL);
if (dropit(1)) return(NULL);
server_list[parsing_server_index].ctcp_last_reply_time=time(NULL);
mynick=get_server_nickname(from_server);
if (*args) {
channel=next_arg(args,&args);
passwd=next_arg(args,&args);
if (channel && *channel) {
if (!is_channel(channel)) snprintf(tmpchan,sizeof(tmpchan),"#%s",channel);
else strmcpy(tmpchan,channel,sizeof(tmpchan));
channel=tmpchan;
}
}
snprintf(tmpbuf1,sizeof(tmpbuf1),"%s!%s",from,userhost);
if ((tmpfriend=CheckUsers(tmpbuf1,channel))) i=tmpfriend->privs;
else i=0;
i=request("UNBAN",mynick,from,userhost,channel,i,FLUNBAN);
if (!i || !(i&FLUNBAN)) {
if (get_int_var(VERBOSE_CTCP_VAR)) say("%s",tmpaway);
if (away_set || LogOn) AwaySave(tmpaway,SAVECTCP);
return(NULL);
}
if (checkpassword(tmpfriend,passwd)) {
wrongpassword(from);
if (get_int_var(VERBOSE_CTCP_VAR)) say("%s",tmpaway);
return(NULL);
}
if (get_int_var(VERBOSE_CTCP_VAR)) say("%s",tmpaway);
if (away_set || LogOn) AwaySave(tmpaway,SAVECTCP);
if (i==-1) return(NULL);
if ((chan=lookup_channel(channel,from_server,0)) && HAS_OPS(chan->status)) {
if (!(chan->FriendList)) {
disabled(from);
return(NULL);
}
UnbanIt(tmpbuf1,channel,from_server);
#ifndef VILAS
send_to_server("NOTICE %s :You have been ctcp unbanned on %s -ScrollZ-",
from,channel);
#endif
}
else notchanop(from,channel);
return(NULL);
}
/* Tells registered user who are the ops of specified channel */
static char *do_chops(ctcp,from,to,args)
CtcpEntry *ctcp;
char *from;
char *to;
char *args;
{
int i;
char *mynick;
char *chops=(char *) 0;
char *userhost=FromUserHost;
char *channel=(char *) 0;
char *passwd=(char *) 0;
char tmpbuf1[mybufsize/2];
char tmpchan[mybufsize/2];
NickList *tmp;
ChannelList *chan;
struct friends *tmpfriend=NULL;
if (to && is_channel(to)) return(NULL);
if (dropit(1)) return(NULL);
server_list[parsing_server_index].ctcp_last_reply_time=time(NULL);
mynick=get_server_nickname(from_server);
if (*args) {
channel=next_arg(args,&args);
passwd=next_arg(args,&args);
if (channel && *channel) {
if (!is_channel(channel)) snprintf(tmpchan,sizeof(tmpchan),"#%s",channel);
else strmcpy(tmpchan,channel,sizeof(tmpchan));
channel=tmpchan;
}
}
snprintf(tmpbuf1,sizeof(tmpbuf1),"%s!%s",from,userhost);
if ((tmpfriend=CheckUsers(tmpbuf1,channel))) i=tmpfriend->privs;
else i=0;
i=request("CHOPS",mynick,from,userhost,channel,i,FLCHOPS);
if (!i || !(i&FLCHOPS)) {
if (get_int_var(VERBOSE_CTCP_VAR)) say("%s",tmpaway);
if (away_set || LogOn) AwaySave(tmpaway,SAVECTCP);
return(NULL);
}
if (checkpassword(tmpfriend,passwd)) {
wrongpassword(from);
if (get_int_var(VERBOSE_CTCP_VAR)) say("%s",tmpaway);
return(NULL);
}
if (get_int_var(VERBOSE_CTCP_VAR)) say("%s",tmpaway);
if (away_set || LogOn) AwaySave(tmpaway,SAVECTCP);
if (i==-1) return(NULL);
if ((chan=lookup_channel(channel,from_server,0))) {
if (!(chan->FriendList)) {
disabled(from);
return(NULL);
}
for (tmp=chan->nicks;tmp;tmp=tmp->next) {
if (tmp->chanop) {
if (chops) malloc_strcat(&chops," ");
malloc_strcat(&chops,tmp->nick);
}
}
if (chops) {
send_to_server("NOTICE %s :Ops on %s are : %s -ScrollZ-", from,
channel,chops);
new_free(&chops);
}
else send_to_server("NOTICE %s :There are no ops on %s -ScrollZ-",
from,channel);
}
else send_to_server("NOTICE %s :I'm not on channel %s -ScrollZ-",from,channel);
return(NULL);
}
/* Voices registered user under CTCP request to specified channel */
static char *do_voice(ctcp,from,to,args)
CtcpEntry *ctcp;
char *from;
char *to;
char *args;
{
int i;
char *mynick;
char *userhost=FromUserHost;
char *channel=(char *) 0;
char *passwd=(char *) 0;
char tmpbuf1[mybufsize/2];
char tmpchan[mybufsize/2];
ChannelList *chan;
struct friends *tmpfriend=NULL;
if (to && is_channel(to)) return(NULL);
if (dropit(1)) return(NULL);
server_list[parsing_server_index].ctcp_last_reply_time=time(NULL);
mynick=get_server_nickname(from_server);
if (*args) {
channel=next_arg(args,&args);
passwd=next_arg(args,&args);
if (channel && *channel) {
if (!is_channel(channel)) snprintf(tmpchan,sizeof(tmpchan),"#%s",channel);
else strmcpy(tmpchan,channel,sizeof(tmpchan));
channel=tmpchan;
}
}
snprintf(tmpbuf1,sizeof(tmpbuf1),"%s!%s",from,userhost);
if ((tmpfriend=CheckUsers(tmpbuf1,channel))) i=tmpfriend->privs;
else i=0;
i=request("VOICE",mynick,from,userhost,channel,i,FLVOICE);
if (!i || !(i&FLVOICE)) {
if (get_int_var(VERBOSE_CTCP_VAR)) say("%s",tmpaway);
if (away_set || LogOn) AwaySave(tmpaway,SAVECTCP);
return(NULL);
}
if (checkpassword(tmpfriend,passwd)) {
wrongpassword(from);
if (get_int_var(VERBOSE_CTCP_VAR)) say("%s",tmpaway);
return(NULL);
}
if (get_int_var(VERBOSE_CTCP_VAR)) say("%s",tmpaway);
if (away_set || LogOn) AwaySave(tmpaway,SAVECTCP);
if (i==-1) return(NULL);
if ((chan=lookup_channel(channel,from_server,0)) && HAS_OPS(chan->status)) {
if (!(chan->FriendList)) {
disabled(from);
return(NULL);
}
if (CheckJoiners(from,channel,from_server,chan)) {
send_to_server("MODE %s +v %s",channel,from);
#ifndef VILAS
send_to_server("NOTICE %s :You have been ctcp voiced on %s -ScrollZ-",
from,channel);
#endif
}
}
else notchanop(from,channel);
return(NULL);
}
/* Tells registered users what privileges does he/she have */
static char *do_whoami(ctcp,from,to,args)
CtcpEntry *ctcp;
char *from;
char *to;
char *args;
{
int i;
int found=0;
char *mynick;
char *userhost=FromUserHost;
char tmpbuf1[mybufsize/2];
char tmpbuf2[mybufsize/2];
struct friends *tmpfriend=NULL;
if (to && is_channel(to)) return(NULL);
if (dropit(1)) return(NULL);
server_list[parsing_server_index].ctcp_last_reply_time=time(NULL);
mynick=get_server_nickname(from_server);
snprintf(tmpbuf2,sizeof(tmpbuf2),"%s!%s",from,userhost);
if ((tmpfriend=CheckUsers(tmpbuf2,NULL))) i=tmpfriend->privs;
else i=0;
i=request("WHOAMI",mynick,from,userhost,(char *) 0,i,FLALL);
if (!i) {
if (get_int_var(VERBOSE_CTCP_VAR)) say("%s",tmpaway);
if (away_set || LogOn) AwaySave(tmpaway,SAVECTCP);
return(NULL);
}
if (get_int_var(VERBOSE_CTCP_VAR)) say("%s",tmpaway);
if (away_set || LogOn) AwaySave(tmpaway,SAVECTCP);
if (!FriendList) {
disabled(from);
return(NULL);
}
for (tmpfriend=frlist;tmpfriend;tmpfriend=tmpfriend->next) {
if (wild_match(tmpfriend->userhost,tmpbuf2)) {
if (!found) {
send_to_server("NOTICE %s :-ScrollZ- Found you in my friends list as:",
from);
found=1;
}
send_to_server("NOTICE %s :-ScrollZ- Mask: %s Channel(s): %s",from,
tmpfriend->userhost,tmpfriend->channels);
i=tmpfriend->privs;
strmcpy(tmpbuf1,"CTCP access: ",sizeof(tmpbuf1));
if (i&FLINVITE) strmcat(tmpbuf1,"INVITE ",sizeof(tmpbuf1));
if (i&FLCHOPS) strmcat(tmpbuf1,"CHOPS ",sizeof(tmpbuf1));
if (i&FLOP) strmcat(tmpbuf1,"OP ",sizeof(tmpbuf1));
if (i&FLHOP) strmcat(tmpbuf1,"HOP ",sizeof(tmpbuf1));
if (i&FLUNBAN) strmcat(tmpbuf1,"UNBAN ",sizeof(tmpbuf1));
if (i&FLCDCC) strmcat(tmpbuf1,"CDCC ",sizeof(tmpbuf1));
if (i&FLVOICE) strmcat(tmpbuf1,"VOICE ",sizeof(tmpbuf1));
if ((i&(FLOP|FLINVITE|FLUNBAN))==(FLOP|FLINVITE|FLUNBAN))
strmcat(tmpbuf1,"OPEN",sizeof(tmpbuf1));
snprintf(tmpaway,sizeof(tmpaway),"Auto:%s Prot:%s No flood:%s God:%s",
YNreply((i&FLAUTOOP)|(i&FLINSTANT)),YNreply(i&FLPROT),
YNreply(i&FLNOFLOOD),YNreply(i&FLGOD));
send_to_server("NOTICE %s :-ScrollZ- %s",from,tmpbuf1);
send_to_server("NOTICE %s :-ScrollZ- %s",from,tmpaway);
if (i&FLJOIN) send_to_server("NOTICE %s :-ScrollZ- I will auto-join above channel(s) when invited by you.",from);
}
}
return(NULL);
}
/* Tells registered user usage of the CTCPs */
static char *do_help(ctcp,from,to,args)
CtcpEntry *ctcp;
char *from;
char *to;
char *args;
{
int i;
char *mynick;
char *userhost=FromUserHost;
char tmpbuf1[mybufsize/2];
struct friends *tmpfriend;
if (to && is_channel(to)) return(NULL);
if (dropit(1)) return(NULL);
server_list[parsing_server_index].ctcp_last_reply_time=time(NULL);
mynick=get_server_nickname(from_server);
snprintf(tmpbuf1,sizeof(tmpbuf1),"%s!%s",from,userhost);
if ((tmpfriend=CheckUsers(tmpbuf1,NULL))) i=tmpfriend->privs;
else i=0;
i=request("HELP",mynick,from,userhost,(char *) 0,i,FLALL);
if (!i) {
if (get_int_var(VERBOSE_CTCP_VAR)) say("%s",tmpaway);
if (away_set || LogOn) AwaySave(tmpaway,SAVECTCP);
return(NULL);
}
if (get_int_var(VERBOSE_CTCP_VAR)) say("%s",tmpaway);
if (away_set || LogOn) AwaySave(tmpaway,SAVECTCP);
if (!FriendList) {
disabled(from);
return(NULL);
}
send_to_server("NOTICE %s :Usage /CTCP %s <command> [channel] [password] where command is :",from,mynick);
*tmpbuf1='\0';
if (i&FLINVITE) strmcat(tmpbuf1,"INVITE ",sizeof(tmpbuf1));
if (i&FLCHOPS) strmcat(tmpbuf1,"CHOPS ",sizeof(tmpbuf1));
if (i&FLOP) strmcat(tmpbuf1,"OP ",sizeof(tmpbuf1));
if (i&FLHOP) strmcat(tmpbuf1,"HOP ",sizeof(tmpbuf1));
if (i&FLUNBAN) strmcat(tmpbuf1,"UNBAN ",sizeof(tmpbuf1));
if ((i&FLOP) && (i&FLINVITE) && (i&FLUNBAN)) strmcat(tmpbuf1,"OPEN ",sizeof(tmpbuf1));
if (i&FLCDCC) strmcat(tmpbuf1,"CDCC ",sizeof(tmpbuf1));
if (i&FLVOICE) strmcat(tmpbuf1,"VOICE ",sizeof(tmpbuf1));
strmcat(tmpbuf1,"WHOAMI HELP",sizeof(tmpbuf1));
send_to_server("NOTICE %s : %s",from,tmpbuf1);
return(NULL);
}
#ifndef CELE
/* Patched by BiGhEaD */
/* Open channel (-lk) under CTCP request on specified channel (for OP users) */
static char *do_open(ctcp,from,to,args)
CtcpEntry *ctcp;
char *from;
char *to;
char *args;
{
int i;
char *mynick;
char *userhost=FromUserHost;
char *channel=(char *) 0;
char *passwd=(char *) 0;
char tmpbuf1[mybufsize/2];
char tmpchan[mybufsize/2];
ChannelList *chan;
struct friends *tmpfriend=NULL;
if (to && is_channel(to)) return(NULL);
if (dropit(1)) return(NULL);
server_list[parsing_server_index].ctcp_last_reply_time=time(NULL);
mynick=get_server_nickname(from_server);
if (*args) {
channel=next_arg(args,&args);
passwd=next_arg(args,&args);
if (channel && *channel) {
if (!is_channel(channel)) snprintf(tmpchan,sizeof(tmpchan),"#%s",channel);
else strmcpy(tmpchan,channel,sizeof(tmpchan));
channel=tmpchan;
}
}
snprintf(tmpbuf1,sizeof(tmpbuf1),"%s!%s",from,userhost);
if ((tmpfriend=CheckUsers(tmpbuf1,channel))) i=tmpfriend->privs;
else i=0;
i=request("OPEN",mynick,from,userhost,channel,i,FLOP|FLINVITE|FLUNBAN);
if (!i || !(i&(FLOP|FLINVITE|FLUNBAN))) {
if (get_int_var(VERBOSE_CTCP_VAR)) say("%s",tmpaway);
if (away_set || LogOn) AwaySave(tmpaway,SAVECTCP);
return(NULL);
}
if (checkpassword(tmpfriend,passwd)) {
wrongpassword(from);
if (get_int_var(VERBOSE_CTCP_VAR)) say("%s",tmpaway);
return(NULL);
}
if (get_int_var(VERBOSE_CTCP_VAR)) say("%s",tmpaway);
if (away_set || LogOn) AwaySave(tmpaway,SAVECTCP);
if (i==-1) return(NULL);
if ((chan=lookup_channel(channel,from_server,0)) && HAS_OPS(chan->status)) {
if (!(chan->FriendList)) {
disabled(from);
return(NULL);
}
*tmpbuf1='\0';
if ((chan->mode)&MODE_LIMIT) strmcat(tmpbuf1,"l",sizeof(tmpbuf1));
if ((chan->mode)&MODE_KEY && chan->key) {
strmcat(tmpbuf1,"k ",sizeof(tmpbuf1));
strmcat(tmpbuf1,chan->key,sizeof(tmpbuf1));
}
if (*tmpbuf1) {
send_to_server("MODE %s -%s",channel,tmpbuf1);
#ifdef ACID
send_to_server("INVITE %s %s",from,channel);
#endif
}
#ifndef VILAS
send_to_server("NOTICE %s :Channel %s has been ctcp opened -ScrollZ-",from,channel);
#endif
}
else notchanop(from,channel);
return(NULL);
}
#endif /* CELE */
#ifdef CTCPPAGE
/* PAGE (BEEP) user from a friend */
static char *do_page(ctcp,from,to,args)
CtcpEntry *ctcp;
char *from;
char *to;
char *args;
{
int i;
char *mynick;
char *userhost=FromUserHost;
char tmpbuf1[mybufsize/2];
struct friends *tmpfriend;
if (to && is_channel(to)) return(NULL);
if (dropit(1)) return(NULL);
server_list[parsing_server_index].ctcp_last_reply_time=time(NULL);
mynick=get_server_nickname(from_server);
snprintf(tmpbuf1,sizeof(tmpbuf1),"%s!%s",from,userhost);
if ((tmpfriend=CheckUsers(tmpbuf1,NULL))) i=tmpfriend->privs;
else i=0;
i=request("PAGE",mynick,from,userhost,(char *) 0,i,FLALL);
if (!i) {
if (get_int_var(VERBOSE_CTCP_VAR)) say("%s",tmpaway);
if (away_set || LogOn) AwaySave(tmpaway,SAVECTCP);
return(NULL);
}
if (get_int_var(VERBOSE_CTCP_VAR)) say("%s",tmpaway);
if (away_set || LogOn) AwaySave(tmpaway,SAVECTCP);
if (!FriendList) {
disabled(from);
return(NULL);
}
term_beep();
send_to_server("NOTICE %s :Ok, %s has been paged, wait for a reply. -ScrollZ-",from,mynick);
return(NULL);
}
#endif
/*******************************************/
/* Handles Cdcc requests */
char *do_cdcc(ctcp,from,to,args)
CtcpEntry *ctcp;
char *from;
char *to;
char *args;
{
int i;
int flag;
char *mynick;
char *userhost=FromUserHost;
char tmpbuf1[mybufsize/2];
char tmpbuf2[mybufsize/2];
struct friends *tmpfriend;
if (dropit(0)) return(NULL);
server_list[parsing_server_index].ctcp_last_reply_time=time(NULL);
mynick=get_server_nickname(from_server);
#ifdef WANTANSI
if (args && *args)
snprintf(tmpbuf1,sizeof(tmpbuf1)," %s%s%s",CmdsColors[COLCDCC].color3,args,Colors[COLOFF]);
else *tmpbuf1='\0';
ColorUserHost(userhost,CmdsColors[COLCTCP].color2,tmpbuf2,1);
snprintf(tmpaway,sizeof(tmpaway),"%sCdcc%s%s request received from %s%s%s %s",
CmdsColors[COLCDCC].color4,Colors[COLOFF],tmpbuf1,
CmdsColors[COLCDCC].color1,from,Colors[COLOFF],tmpbuf2);
if (to && is_channel(to)) {
snprintf(tmpbuf1,sizeof(tmpbuf1)," to %s%s%s",CmdsColors[COLCDCC].color6,to,Colors[COLOFF]);
strmcat(tmpaway,tmpbuf1,sizeof(tmpaway));
}
#else
if (args && *args) snprintf(tmpbuf1,sizeof(tmpbuf1)," %s",args);
else *tmpbuf1='\0';
snprintf(tmpaway,sizeof(tmpaway),"Cdcc%s request received from %s (%s)",tmpbuf1,from,userhost);
if (to && is_channel(to)) {
snprintf(tmpbuf1,sizeof(tmpbuf1)," to %s",to);
strmcat(tmpaway,tmpbuf1,sizeof(tmpaway));
}
#endif
snprintf(tmpbuf2,sizeof(tmpbuf2),"%s!%s",from,userhost);
if ((tmpfriend=CheckUsers(tmpbuf2,NULL))) i=tmpfriend->privs;
else i=0;
if (Security)
if (!i || !(i&FLCDCC)) {
strmcat(tmpaway,", no access",sizeof(tmpaway));
if (get_int_var(VERBOSE_CTCP_VAR)) say("%s",tmpaway);
if (!i && !CTCPCloaking)
send_to_server("NOTICE %s :You do not have access... -ScrollZ-",from);
if (away_set || LogOn) AwaySave(tmpaway,SAVECTCP);
return(NULL);
}
if (!(*args)) {
strmcat(tmpaway,", wrong usage",sizeof(tmpaway));
if (get_int_var(VERBOSE_CTCP_VAR)) say("%s",tmpaway);
if (!CTCPCloaking) send_to_server("NOTICE %s :Try /CTCP %s CDCC HELP",from,mynick);
if (away_set || LogOn) AwaySave(tmpaway,SAVECTCP);
return(NULL);
}
strmcpy(tmpbuf1,args,sizeof(tmpbuf1));
flag=in_ctcp_flag;
in_ctcp_flag=0;
CheckCdcc(from,tmpbuf1,to,0);
in_ctcp_flag=flag;
return(NULL);
}
/***********************************************************************/
/*
* do_crypto: performs the ecrypted data trasfer for ctcp. Returns in a
* malloc string the decryped message (if a key is set for that user) or the
* text "[ENCRYPTED MESSAGE]"
*/
#ifndef LITE
static char *
do_crypto(ctcp, from, to, args)
CtcpEntry *ctcp;
char *from,
*to,
*args;
{
crypt_key *key;
char *crypt_who,
*msg;
char *ret = NULL;
if (is_channel(to))
crypt_who = to;
else
crypt_who = from;
if ((key = is_crypted(crypt_who)) && (msg = crypt_msg(args, key, 0)))
{
/* this doesn't work ...
... when it does, set this to 0 ... */
static int the_youth_of_america_on_elle_esse_dee = 1;
malloc_strcpy(&ret, msg);
/*
* since we are decrypting, run it through do_ctcp() again
* to detect embeded CTCP messages, in an encrypted message.
* we avoid recusing here more than once.
*/
if (the_youth_of_america_on_elle_esse_dee++ == 0)
ret = do_ctcp(from, to, ret);
the_youth_of_america_on_elle_esse_dee--;
sed = 1;
}
else
malloc_strcpy(&ret, "[ENCRYPTED MESSAGE]");
return (ret);
}
#endif
/*
* do_clientinfo: performs the CLIENTINFO CTCP. If cmd is empty, returns the
* list of all CTCPs currently recognized by IRCII. If an arg is supplied,
* it returns specific information on that CTCP. If a matching CTCP is not
* found, an ERRMSG ctcp is returned
*/
static char *
do_clientinfo(ctcp, from, to, cmd)
CtcpEntry *ctcp;
char *from,
*to,
*cmd;
{
int i;
char *ucmd = (char *) 0;
u_char buffer[BIG_BUFFER_SIZE+1];
/**************************** PATCHED by Flier ******************************/
if (CTCPCloaking==1) {
/****************************************************************************/
if (cmd && *cmd)
{
malloc_strcpy(&ucmd, cmd);
upper(ucmd);
for (i = 0; i < NUMBER_OF_CTCPS; i++)
{
/**************************** PATCHED by Flier ******************************/
/* stop at invite */
if (!strcmp(ctcp_cmd[i].name,"INVITE")) break;
/****************************************************************************/
if (strcmp(ucmd, ctcp_cmd[i].name) == 0)
{
send_ctcp_reply(from, ctcp->name, "%s %s",
ctcp_cmd[i].name, ctcp_cmd[i].desc);
return NULL;
}
}
send_ctcp_reply(from, ctcp_cmd[CTCP_ERRMSG].name,
"%s: %s is not a valid function",
ctcp->name, cmd);
}
else
{
*buffer = '\0';
for (i = 0; i < NUMBER_OF_CTCPS; i++)
{
/**************************** PATCHED by Flier ******************************/
/* stop at invite */
if (!strcmp(ctcp_cmd[i].name,"INVITE")) break;
/****************************************************************************/
strmcat(buffer, ctcp_cmd[i].name, BIG_BUFFER_SIZE);
strmcat(buffer, " ", BIG_BUFFER_SIZE);
}
send_ctcp_reply(from, ctcp->name,
"%s :Use CLIENTINFO <COMMAND> to get more specific information",
buffer);
}
/**************************** PATCHED by Flier ******************************/
}
else if (!CTCPCloaking) send_ctcp_reply(from, ctcp->name, "No client here! -ScrollZ-");
/****************************************************************************/
return NULL;
}
/* do_version: does the CTCP VERSION command */
static char *
do_version(ctcp, from, to, cmd)
CtcpEntry *ctcp;
char *from,
*to,
*cmd;
{
/**************************** PATCHED by Flier ******************************/
char tmpbuf1[mybufsize/4];
char tmpbuf2[mybufsize/4];
if (CTCPCloaking==1) {
/****************************************************************************/
#if defined(PARANOID)
send_ctcp_reply(from, ctcp->name, "ircII user");
#else
char *tmp;
#if defined(HAVE_UNAME)
struct utsname un;
char *the_unix,
*the_version;
if (uname(&un) < 0)
{
the_version = empty_string;
the_unix = "unknown";
}
else
{
the_version = un.release;
the_unix = un.sysname;
}
send_ctcp_reply(from, ctcp->name, "ircII %s %s %s :%s", irc_version, the_unix, the_version,
#else
#ifdef _Windows
send_ctcp_reply(from, ctcp->name, "ircII %s MS-Windows :%s", irc_version,
#else
send_ctcp_reply(from, ctcp->name, "ircII %s *IX :%s", irc_version,
#endif /* _Windows */
#endif /* HAVE_UNAME */
(tmp = get_string_var(CLIENTINFO_VAR)) ? tmp : IRCII_COMMENT);
#endif /* PARANOID */
/**************************** PATCHED by Flier ******************************/
}
else if (!CTCPCloaking) {
strmcpy(tmpbuf1,ScrollZver,sizeof(tmpbuf1));
#ifdef CELE
if (get_string_var(CLIENTINFO_VAR))
snprintf(tmpbuf2,sizeof(tmpbuf2),"%s+%s - %s",tmpbuf1,CelerityVersion,
get_string_var(CLIENTINFO_VAR));
else snprintf(tmpbuf2,sizeof(tmpbuf2),"%s+%s",tmpbuf1,CelerityVersion);
#else /* CELE */
#ifdef OPER
if (get_string_var(CLIENTINFO_VAR))
snprintf(tmpbuf2,sizeof(tmpbuf2),"%s+%s - %s",tmpbuf1,AcidVersion,
get_string_var(CLIENTINFO_VAR));
else snprintf(tmpbuf2,sizeof(tmpbuf2),"%s+%s",tmpbuf1,AcidVersion);
#else /* OPER */
if (get_string_var(CLIENTINFO_VAR))
snprintf(tmpbuf2,sizeof(tmpbuf2),"%s - %s",tmpbuf1,get_string_var(CLIENTINFO_VAR));
else strmcpy(tmpbuf2,tmpbuf1,sizeof(tmpbuf2));
#endif /* OPER */
#endif /* CELE */
send_ctcp_reply(from, ctcp->name, "%s", tmpbuf2);
}
/****************************************************************************/
return NULL;
}
/* do_time: does the CTCP TIME command --- done by Veggen */
static char *
do_time(ctcp, from, to, cmd)
CtcpEntry *ctcp;
char *from,
*to,
*cmd;
{
time_t tm = time((time_t *) 0);
char *s, *t = ctime(&tm);
if ((char *) 0 != (s = index(t, '\n')))
*s = '\0';
/************************ PATCHED by Flier ***************************/
/*send_ctcp_reply(from, ctcp->name, "%s", t);*/
if (CTCPCloaking!=2) send_ctcp_reply(from, ctcp->name, "%s", t);
/*********************************************************************/
return NULL;
}
/* do_userinfo: does the CTCP USERINFO command */
static char *
do_userinfo(ctcp, from, to, cmd)
CtcpEntry *ctcp;
char *from,
*to,
*cmd;
{
/**************************** PATCHED by Flier ******************************/
/*send_ctcp_reply(from, ctcp->name, "%s", get_string_var(USER_INFO_VAR));*/
if (CTCPCloaking==1)
send_ctcp_reply(from, ctcp->name, "%s", get_string_var(USER_INFO_VAR));
else if (!CTCPCloaking) send_ctcp_reply(from,ctcp->name,"%s",DefaultUserinfo);
/****************************************************************************/
return NULL;
}
/*
* do_echo: does the CTCP ECHO, CTCP ERRMSG and CTCP PING commands. Does
* not send an error for ERRMSG and if the CTCP was sent to a channel.
*/
static char *
do_echo(ctcp, from, to, cmd)
CtcpEntry *ctcp;
char *from,
*to,
*cmd;
{
/**************************** PATCHED by Flier ******************************/
if (CTCPCloaking!=2)
/****************************************************************************/
if (!is_channel(to) || strncmp(cmd, "ERRMSG", 6))
send_ctcp_reply(from, ctcp->name, "%s", cmd);
return NULL;
}
static char *
do_finger(ctcp, from, to, cmd)
CtcpEntry *ctcp;
char *from,
*to,
*cmd;
{
/**************************** PATCHED by Flier ******************************/
if (CTCPCloaking==1) {
/****************************************************************************/
#if defined(PARANOID)
send_ctcp_reply(from, ctcp->name, "ircII user");
#else
struct passwd *pwd;
time_t diff;
unsigned uid;
char c;
/*
* sojge complained that ircII says 'idle 1 seconds'
* well, now he won't ever get the chance to see that message again
* *grin* ;-) -lynx
*
* Made this better by saying 'idle 1 second' -phone
*/
diff = time(0) - idle_time;
c = (diff == 1) ? ' ' : 's';
/* XXX - fix me */
# ifdef _Windows
send_ctcp_reply(from, ctcp->name,
"IRCII For MS-Windows User Idle %d second%c",
(int)diff, c);
# else
uid = getuid();
# ifdef DAEMON_UID
if (uid != DAEMON_UID)
{
# endif /* DAEMON_UID */
if ((pwd = getpwuid(uid)) != NULL)
{
char *tmp;
# ifndef GECOS_DELIMITER
# define GECOS_DELIMITER ','
# endif /* GECOS_DELIMITER */
if ((tmp = index(pwd->pw_gecos, GECOS_DELIMITER)) != NULL)
*tmp = '\0';
send_ctcp_reply(from, ctcp->name,
"%s (%s@%s) Idle %d second%c", pwd->pw_gecos,
pwd->pw_name, hostname, (int)diff, c);
}
# ifdef DAEMON_UID
}
else
send_ctcp_reply(from, ctcp->name,
"IRCII Telnet User (%s) Idle %d second%c",
realname, (int)diff, c);
# endif /* DAEMON_UID */
# endif /* _Windows */
#endif /* PARANOID */
/**************************** PATCHED by Flier ******************************/
}
else if (!CTCPCloaking) send_ctcp_reply(from, ctcp->name,"%s",DefaultFinger);
/****************************************************************************/
return NULL;
}
/*
* do_atmosphere: does the CTCP ACTION command --- done by lynX
* Changed this to make the default look less offensive to people
* who don't like it and added a /on ACTION. This is more in keeping
* with the design philosophy behind IRCII
*/
static char *
do_atmosphere(ctcp, from, to, cmd)
CtcpEntry *ctcp;
char *from,
*to,
*cmd;
{
/**************************** PATCHED by Flier ******************************/
int foundar = 0;
int isshit;
int isfriend;
char *thing;
#ifdef WANTANSI
char *color = CmdsColors[COLME].color3;
#else
char *color = "";
#endif
char tmpbuf1[mybufsize / 2];
void (*func)();
ChannelList *chan;
NickList *joiner;
Window *oldwin;
#ifdef HAVE_ICONV_H
if (get_int_var(HIGH_ASCII_VAR)) thing = "\342\210\236";
#else
if (get_int_var(HIGH_ASCII_VAR)) thing = "ì";
#endif /* HAVE_ICONV_H */
else thing = "*";
if (Stamp == 2) func = (void(*)()) say;
else func = (void(*)()) put_it;
/****************************************************************************/
if (cmd && *cmd)
{
int old;
/**************************** Patched by Flier ******************************/
if (AutoReplyBuffer) {
char tmpbuf[2 * mybufsize];
strmcpy(tmpbuf, cmd, sizeof(tmpbuf));
foundar = AutoReplyMatch(tmpbuf);
#ifdef WANTANSI
if (foundar) color = CmdsColors[COLME].color6;
#else
if (foundar) color = "";
#endif
}
/****************************************************************************/
save_message_from();
old = set_lastlog_msg_level(LOG_ACTION);
if (is_channel(to))
{
message_from(to, LOG_ACTION);
if (do_hook(ACTION_LIST, "%s %s %s", from, to, cmd))
{
/**************************** PATCHED by Flier ******************************/
/*if (is_current_channel(to, parsing_server_index, 0))
put_it("* %s %s", from, cmd);
else
put_it("* %s:%s %s", from, to, cmd);*/
if (is_current_channel(to, parsing_server_index, 0))
#ifdef WANTANSI
func("%s%s%s %s%s%s %s%s%s",
CmdsColors[COLME].color1, thing, Colors[COLOFF],
color, from, Colors[COLOFF],
CmdsColors[COLME].color5, cmd, Colors[COLOFF]);
#else
func("%s %s%s%s %s", thing, color, from, color, cmd);
#endif
else {
#ifdef WANTANSI
snprintf(tmpbuf1,sizeof(tmpbuf1),"<%s%s%s> %s%s%s %s%s%s",
CmdsColors[COLME].color4, to, Colors[COLOFF],
CmdsColors[COLME].color1, thing, Colors[COLOFF],
color, from, Colors[COLOFF]);
func("%s %s%s%s",tmpbuf1,
CmdsColors[COLME].color5,cmd, Colors[COLOFF]);
#else
func("<%s> %s %s%s%s %s", to, thing, color, from, color, cmd);
#endif
}
/****************************************************************************/
}
/**************************** Patched by Flier ******************************/
/* by braneded */
chan = lookup_channel(to, parsing_server_index, 0);
if (chan) {
joiner = CheckJoiners(from, to,
parsing_server_index, chan);
if (joiner) {
isshit = joiner->shitlist ?
joiner->shitlist->shit : 0;
isfriend = (!isshit && joiner->frlist) ?
joiner->frlist->privs : 0;
Check4WordKick(cmd, joiner, isfriend, chan);
if (ChanLog) {
char tmpbuf2[mybufsize];
if (chan->ChanLog) {
snprintf(tmpbuf2, sizeof(tmpbuf2),
"* %s %s", from, cmd);
ChannelLogSave(tmpbuf2, chan);
}
}
}
}
if (foundar &&
(ARinWindow == 3 ||
(ARinWindow && chan->window != curr_scr_win))) {
#ifdef WANTANSI
snprintf(tmpbuf1, sizeof(tmpbuf1),
"<%s%s%s> %s%s%s %s%s%s",
CmdsColors[COLME].color4, to, Colors[COLOFF],
CmdsColors[COLME].color1, thing,
Colors[COLOFF],
color, from, Colors[COLOFF]);
#else
sprintf(tmpbuf1, "<%s> %s %s%s%s %s",
to, thing, color, from, color, cmd);
#endif
oldwin = to_window;
if (ARinWindow == 1) /* ON */
to_window = curr_scr_win;
else { /* USER/BOTH */
to_window = get_window_by_level(LOG_USER4);
if (to_window == NULL)
to_window = curr_scr_win;
}
#ifdef WANTANSI
func("%s %s%s%s", tmpbuf1,
CmdsColors[COLME].color5, cmd, Colors[COLOFF]);
#else
func("%s", tmpbuf1);
#endif
to_window = oldwin;
}
/****************************************************************************/
}
else
{
if ('=' == *from)
{
set_lastlog_msg_level(LOG_DCC);
message_from(from+1, LOG_DCC);
}
else
message_from(from, LOG_ACTION);
if (do_hook(ACTION_LIST, "%s %s %s", from, to, cmd))
/**************************** PATCHED by Flier ******************************/
/*put_it("*> %s %s", from, cmd);*/
#ifdef WANTANSI
func("%s%s%s> %s%s%s %s%s%s",
CmdsColors[COLME].color1, thing, Colors[COLOFF],
color, from, Colors[COLOFF],
CmdsColors[COLME].color5, cmd, Colors[COLOFF]);
#else
func("%s> %s%s%s %s", thing, color, from, color, cmd);
#endif
/****************************************************************************/
}
set_lastlog_msg_level(old);
restore_message_from();
}
return NULL;
}
/*
* do_dcc: Records data on an incoming DCC offer. Makes sure it's a
* user->user CTCP, as channel DCCs don't make any sense whatsoever
*/
static char *
do_dcc(ctcp, from, to, args)
CtcpEntry *ctcp;
char *from,
*to,
*args;
{
char *type;
char *description;
char *inetaddr;
char *port;
char *size;
if (my_stricmp(to, get_server_nickname(parsing_server_index)))
return NULL;
if (!(type = next_arg(args, &args)) ||
/**************************** PATCHED by Flier ******************************/
/*!(description = next_arg(args, &args)) ||*/
/* support filenames enclosed in quotes */
!(description = new_next_arg(args, &args)) ||
/****************************************************************************/
!(inetaddr = next_arg(args, &args)) ||
!(port = next_arg(args, &args)))
return NULL;
size = next_arg(args, &args);
register_dcc_offer(from, type, description, inetaddr, port, size);
return NULL;
}
static char *
do_utc(ctcp, from, to, args)
CtcpEntry *ctcp;
char *from,
*to,
*args;
{
time_t tm;
char *date = NULL;
if (!args || !*args)
return NULL;
tm = atol(args);
malloc_strcpy(&date, ctime(&tm));
date[strlen(date)-1] = '\0';
return date;
}
/*
* do_ctcp: handles the client to client protocol embedded in PRIVMSGs. Any
* such messages are removed from the original str, so after do_ctcp()
* returns, str will be changed
*/
char *
do_ctcp(from, to, str)
char *from,
*to,
*str;
{
int i = 0,
ctcp_flag = 1;
char *end,
*cmd,
*args,
*ptr;
char *arg_copy = NULL;
int flag;
int messages = 0;
time_t curtime = time(NULL);
/************************ PATCHED by Flier ***************************/
char *mynick=get_server_nickname(from_server);
#if defined(WANTANSI)
char tmpbuf1[mybufsize/2];
#endif
/*********************************************************************/
flag = double_ignore(from, FromUserHost, IGNORE_CTCPS);
if (!in_ctcp_flag)
in_ctcp_flag = 1;
*ctcp_buffer = '\0';
while ((cmd = index(str, CTCP_DELIM_CHAR)) != NULL)
{
if (messages > 3)
break;
*(cmd++) = '\0';
/**************************** Patched by Flier ******************************/
/*strcat(ctcp_buffer, str);*/
strmcat(ctcp_buffer, str, sizeof(ctcp_buffer));
/****************************************************************************/
if ((end = index(cmd, CTCP_DELIM_CHAR)) != NULL)
{
messages++;
if (flag == IGNORED)
continue;
*(end++) = '\0';
if ((args = index(cmd, ' ')) != NULL)
*(args++) = '\0';
else
args = empty_string;
/* Skip leading : for arguments */
if (*args == ':')
++args;
malloc_strcpy(&arg_copy, args);
/**************************** PATCHED by Flier ******************************/
/* if it came via DCC CHAT only allow ACTION to be processed */
if (*from!='=' || (*from=='=' && !strcmp(cmd,"ACTION")))
/****************************************************************************/
for (i = 0; i < NUMBER_OF_CTCPS; i++)
{
if (strcmp(cmd, ctcp_cmd[i].name) == 0)
{
/* protect against global (oper) messages */
if (*to != '$' && !(*to == '#' && !lookup_channel(to, parsing_server_index, CHAN_NOUNLINK)))
{
ptr = ctcp_cmd[i].func(&ctcp_cmd[i], from, to, arg_copy);
if (ptr)
{
/**************************** Patched by Flier ******************************/
/*strcat(ctcp_buffer, ptr);*/
strmcat(ctcp_buffer, ptr, sizeof(ctcp_buffer));
/****************************************************************************/
new_free(&ptr);
}
}
ctcp_flag = ctcp_cmd[i].flag;
cmd = ctcp_cmd[i].name;
break;
}
}
new_free(&arg_copy);
/**************************** PATCHED by Flier ******************************/
if (!check_flooding(from,CTCP_FLOOD,args)) continue;
/* if it came via DCC CHAT only allow ACTION to be processed */
if (*from=='=' && strcmp(cmd,"ACTION")) continue;
/****************************************************************************/
if (in_ctcp_flag == 1 &&
do_hook(CTCP_LIST, "%s %s %s %s", from, to, cmd,
args) && get_int_var(VERBOSE_CTCP_VAR))
{
int lastlog_level;
save_message_from();
lastlog_level = set_lastlog_msg_level(LOG_CTCP);
message_from((char *) 0, LOG_CTCP);
/**************************** PATCHED by Flier ******************************/
/*if (i == NUMBER_OF_CTCPS)
{
if (beep_on_level & LOG_CTCP)
beep_em(1);
say("Unknown CTCP %s from %s to %s: %s%s",
cmd, from, to, *args ? ": " :
empty_string, args);
}
else if (ctcp_flag & CTCP_VERBOSE)
{
if (my_stricmp(to,
get_server_nickname(parsing_server_index)))
say("CTCP %s from %s to %s: %s",
cmd, from, to, args);
else
say("CTCP %s from %s%s%s", cmd,
from, *args ? ": " :
empty_string, args);
}*/
#ifdef WANTANSI
ColorUserHost(FromUserHost,CmdsColors[COLCTCP].color2,
tmpaway,1);
#endif
if (i == NUMBER_OF_CTCPS && get_int_var(VERBOSE_CTCP_VAR)) {
if (beep_on_level & LOG_CTCP) beep_em(1);
#ifdef WANTANSI
snprintf(tmpbuf1,sizeof(tmpbuf1),"%sUnknown CTCP %s%s from %s%s%s",
CmdsColors[COLCTCP].color4,cmd,Colors[COLOFF],
CmdsColors[COLCTCP].color1,from,Colors[COLOFF]);
if (to && my_stricmp(to,mynick))
say("%s %s to %s%s%s",tmpbuf1,tmpaway,
CmdsColors[COLCTCP].color3,to,Colors[COLOFF]);
else say("%s %s",tmpbuf1,tmpaway);
#else
say("Unknown CTCP %s from %s (%s)%s%s",
cmd,from,FromUserHost,
(to && my_stricmp(to,mynick))?" to ":"",
(to && my_stricmp(to,mynick))?to:"");
#endif
}
else if (ctcp_flag & CTCP_VERBOSE && get_int_var(VERBOSE_CTCP_VAR)) {
if (beep_on_level & LOG_CTCP) beep_em(1);
#ifdef WANTANSI
snprintf(tmpbuf1,sizeof(tmpbuf1),"%sCTCP %s%s from %s%s%s",
CmdsColors[COLCTCP].color4,cmd,Colors[COLOFF],
CmdsColors[COLCTCP].color1,from,Colors[COLOFF]);
if (to && my_stricmp(to,mynick))
say("%s %s to %s%s%s",tmpbuf1,tmpaway,
CmdsColors[COLCTCP].color3,to,Colors[COLOFF]);
else say("%s %s",tmpbuf1,tmpaway);
#else
say("CTCP %s from %s (%s)%s%s",
cmd,from,FromUserHost,
(to && my_stricmp(to,mynick))?" to ":"",
(to && my_stricmp(to,mynick))?to:"");
#endif
}
/****************************************************************************/
set_lastlog_msg_level(lastlog_level);
restore_message_from();
}
str = end;
}
else
{
/**************************** Patched by Flier ******************************/
/*strcat(ctcp_buffer, CTCP_DELIM_STR);*/
strmcat(ctcp_buffer, CTCP_DELIM_STR, sizeof(ctcp_buffer));
/****************************************************************************/
str = cmd;
}
}
if (in_ctcp_flag == 1)
in_ctcp_flag = 0;
if (CTCP_Reply_Buffer && *CTCP_Reply_Buffer)
{
#ifdef PARANOID
/*
* paranoid users don't want to send ctcp replies to
* requests send to channels, probably...
*/
if (is_channel(to))
goto clear_ctcp_reply_buffer;
#endif
/*
* Newave ctcp flood protection : each time you are requested to send
* more than CTCP_REPLY_FLOOD_SIZE bytes in CTCP_REPLY_BACKLOG_SECONDS
* no ctcp replies will be done for CTCP_REPLY_IGNORE_SECONDS.
* Current default is 256 bytes/ 5s/ 10s
* This is a sliding window, i.e. you can't get caught sending too much
* because of a 5s boundary, and the checking is still active even if
* you don't reply anymore.
*/
if (*from == '=')
send_ctcp(ctcp_type[CTCP_NOTICE], from, NULL, "%s", CTCP_Reply_Buffer);
else
{
Server *cur_serv = &server_list[parsing_server_index];
int no_reply,
no_flood = get_int_var(NO_CTCP_FLOOD_VAR),
delta = cur_serv->ctcp_last_reply_time ? curtime-cur_serv->ctcp_last_reply_time : 0,
size = 0,
was_ignoring = cur_serv->ctcp_flood_time != 0,
crbs = get_int_var(CTCP_REPLY_BACKLOG_SECONDS_VAR),
crfs = get_int_var(CTCP_REPLY_FLOOD_SIZE_VAR),
cris = get_int_var(CTCP_REPLY_IGNORE_SECONDS_VAR);
cur_serv->ctcp_last_reply_time = curtime;
if (delta)
{
for (i = crbs - 1; i >= delta; i--)
cur_serv->ctcp_send_size[i] = cur_serv->ctcp_send_size[i - delta];
for (i = 0; i < delta && i < crbs; i++)
cur_serv->ctcp_send_size[i] = 0;
}
cur_serv->ctcp_send_size[0] += strlen(CTCP_Reply_Buffer);
for (i = 0; i < crbs; i++)
size += cur_serv->ctcp_send_size[i];
if (size >= crfs)
cur_serv->ctcp_flood_time = curtime;
no_reply = cur_serv->ctcp_flood_time && (curtime <= cur_serv->ctcp_flood_time+cris);
if (no_flood && get_int_var(VERBOSE_CTCP_VAR))
{
save_message_from();
message_from((char *) 0, LOG_CTCP);
if (no_reply && was_ignoring == 0)
say("CTCP flood detected - suspending replies");
else if (no_reply == 0 && was_ignoring)
say("CTCP reply suspending time elapsed - replying normally");
restore_message_from();
}
if (no_flood == 0 || no_reply == 0)
{
cur_serv->ctcp_flood_time = 0;
send_ctcp(ctcp_type[CTCP_NOTICE], from, NULL, "%s", CTCP_Reply_Buffer);
}
}
#ifdef PARANOID
clear_ctcp_reply_buffer:
#endif
*CTCP_Reply_Buffer = '\0';
}
if (*str)
/**************************** Patched by Flier ******************************/
/*strcat(ctcp_buffer, str);*/
strmcat(ctcp_buffer, str, sizeof(ctcp_buffer));
/****************************************************************************/
return (ctcp_buffer);
}
char *
do_notice_ctcp(from, to, str)
char *from,
*to,
*str;
{
char *cmd;
in_ctcp_flag = -1;
*ctcp_buffer = '\0';
/*
* The following used to say "While". It now says "if" because people
* Started using CTCP ERRMSG replies to CTCP bomb. The effect of this
* is that IRCII users can only send one CTCP/message if they expect a
* reply. This shouldn't be a problem as that is the way IRCII operates
*
* Changed this behavouir to follow NO_CTCP_FLOOD
*/
if (get_int_var(NO_CTCP_FLOOD_VAR))
{
if ((cmd = index(str, CTCP_DELIM_CHAR)) != NULL)
do_new_notice_ctcp(from, to, &str, cmd);
}
else
while ((cmd = index(str, CTCP_DELIM_CHAR)) != NULL)
do_new_notice_ctcp(from, to, &str, cmd);
in_ctcp_flag = 0;
/**************************** Patched by Flier ******************************/
/*strcat(ctcp_buffer, str);*/
strmcat(ctcp_buffer, str, sizeof(ctcp_buffer));
/****************************************************************************/
return (ctcp_buffer);
}
static void
do_new_notice_ctcp(from, to, str, cmd)
char *from,
*to,
**str,
*cmd;
{
char *end,
*args,
*ptr,
*arg_copy = NULL;
int flags,
i,
lastlog_level;
/**************************** PATCHED by Flier *****************************/
int isitme;
char tmpbuf1[mybufsize/32];
#if defined(CELE)
struct timeval timenow;
#endif
/***************************************************************************/
flags = 0;
*(cmd++) = '\0';
/**************************** Patched by Flier ******************************/
/*strcat(ctcp_buffer, *str);*/
strmcat(ctcp_buffer, *str, sizeof(ctcp_buffer));
/****************************************************************************/
if ((end = index(cmd, CTCP_DELIM_CHAR)) != NULL)
{
*(end++) = '\0';
if ((args = index(cmd, ' ')) != NULL)
*(args++) = '\0';
malloc_strcpy(&arg_copy, args);
for (i = 0; i < NUMBER_OF_CTCPS; i++)
{
if ((strcmp(cmd, ctcp_cmd[i].name) == 0) && ctcp_cmd[i].flag & CTCP_NOREPLY)
{
if ((ptr = ctcp_cmd[i].func(&(ctcp_cmd[i]), from, to, arg_copy)) != NULL)
{
/**************************** Patched by Flier ******************************/
/*strcat(ctcp_buffer, ptr);*/
strmcat(ctcp_buffer, ptr, sizeof(ctcp_buffer));
/****************************************************************************/
new_free(&ptr);
flags = ctcp_cmd[i].flag;
}
break;
}
}
new_free(&arg_copy);
if (!args)
args = empty_string;
if (do_hook(CTCP_REPLY_LIST, "%s %s %s", from, cmd,
args) && !(flags & CTCP_NOREPLY))
{
if (!strcmp(cmd, "PING"))
{
/**************************** PATCHED by Flier ******************************/
/*char buf[20];
time_t timediff,
currenttime;
currenttime = time(NULL);
if (args && *args)
timediff = currenttime -
(time_t) atol(args);
else
timediff = (time_t) 0;
snprintf(buf, sizeof buf, "%ld second%s",
(long) timediff, (timediff == 1) ? "" : "s");
args = buf;*/
char *tmpstr=(char *) 0;
char buf[mybufsize/16];
struct timeval timeofday;
gettimeofday(&timeofday,NULL);
if ((tmpstr=next_arg(args,&args))) {
timeofday.tv_sec-=atol(tmpstr);
if ((tmpstr=next_arg(args,&args))) {
if (timeofday.tv_usec>=atol(tmpstr))
timeofday.tv_usec-=atol(tmpstr);
else {
timeofday.tv_usec=timeofday.tv_usec-
atol(tmpstr)+1000000;
timeofday.tv_sec--;
}
snprintf(tmpbuf1,sizeof(tmpbuf1),"%06ld",timeofday.tv_usec);
tmpbuf1[3]='\0';
snprintf(buf,sizeof(buf),"%ld.%s",timeofday.tv_sec,tmpbuf1);
strmcat(buf," seconds",sizeof(buf));
#ifdef CELE
timenow=timeofday;
#endif
}
else snprintf(buf,sizeof(buf),"%ld second%s",timeofday.tv_sec,
(timeofday.tv_sec==1)?"":"s");
}
else strcpy(buf, "0 seconds");
args=buf;
/****************************************************************************/
}
save_message_from();
lastlog_level = set_lastlog_msg_level(LOG_CTCP);
message_from((char *) 0, LOG_CTCP);
/**************************** PATCHED by Flier ******************************/
/*say("CTCP %s reply from %s: %s", cmd, from,
args);*/
if (my_stricmp(cmd,"PING")) {
#ifdef WANTANSI
say("%sCTCP %s%s reply from %s%s%s: %s",
CmdsColors[COLCTCP].color4,cmd,Colors[COLOFF],
CmdsColors[COLCTCP].color1,from,Colors[COLOFF],args);
#else
say("CTCP %s reply from %s: %s",cmd,from,args);
#endif
}
else {
isitme=!my_stricmp(from,get_server_nickname(from_server));
#ifdef WANTANSI
say("%sCTCP %s%s reply from %s%s%s: %s",
CmdsColors[COLCTCP].color4,cmd,Colors[COLOFF],
CmdsColors[COLCTCP].color1,from,Colors[COLOFF],args);
#else
say("CTCP %s reply from %s: %s",cmd,from,args);
#endif
if (isitme) {
#if defined(CELE)
/* CTCP Ping is client->server->client->client->server->client
== double lag */
if (timenow.tv_sec>0) {
if (timenow.tv_sec%2==0) {
timenow.tv_sec=timenow.tv_sec/2;
timenow.tv_usec=timenow.tv_usec/2;
}
else {
timenow.tv_sec=(timenow.tv_sec-1)/2;
timenow.tv_usec=(timenow.tv_usec/2)+500000;
}
}
else timenow.tv_usec=timenow.tv_usec/2;
LagTimer=timenow;
#else
LagTimer=atoi(args)>>1;
#endif /*CELE*/
update_all_status();
}
}
/****************************************************************************/
set_lastlog_msg_level(lastlog_level);
restore_message_from();
}
*str = end;
}
else
{
/**************************** Patched by Flier ******************************/
/*strcat(ctcp_buffer, CTCP_DELIM_STR);*/
strmcat(ctcp_buffer, CTCP_DELIM_STR, sizeof(ctcp_buffer));
/****************************************************************************/
*str = cmd;
}
}
/* in_ctcp: simply returns the value of the ctcp flag */
int
in_ctcp()
{
return (in_ctcp_flag);
}
/* These moved here because they belong here - phone */
/*
* send_ctcp: A simply way to send CTCP queries. if the datatag
* is NULL, we must have already formatted the ctcp reply (it has the
* ctcp delimiters), so don't add them again, etc.
*/
void
#ifdef HAVE_STDARG_H
send_ctcp(char *type, char *to, char *datatag, char *format, ...)
{
va_list vl;
#else
send_ctcp(type, to, datatag, format, arg0, arg1, arg2, arg3, arg4,
arg5, arg6, arg7, arg8, arg9)
char *type,
*to,
*datatag,
*format;
char *arg0,
*arg1,
*arg2,
*arg3,
*arg4,
*arg5,
*arg6,
*arg7,
*arg8,
*arg9;
{
#endif
char putbuf[BIG_BUFFER_SIZE + 1], sendbuf[BIG_BUFFER_SIZE + 1];
char *sendp;
if (in_on_who)
return; /* Silently drop it on the floor */
if (format)
{
#ifdef HAVE_STDARG_H
va_start(vl, format);
vsnprintf(putbuf, sizeof putbuf, format, vl);
va_end(vl);
#else
snprintf(putbuf, sizeof putbuf, format, arg0, arg1, arg2, arg3, arg4, arg5,
arg6, arg7, arg8, arg9);
#endif /* HAVE_STDARG_H */
if (datatag)
{
snprintf(sendbuf, sizeof sendbuf, "%c%s %s%c",
CTCP_DELIM_CHAR, datatag, putbuf, CTCP_DELIM_CHAR);
sendp = sendbuf;
}
else
sendp = putbuf;
}
else
{
snprintf(sendbuf, sizeof sendbuf, "%c%s%c",
CTCP_DELIM_CHAR, datatag, CTCP_DELIM_CHAR);
sendp = sendbuf;
}
/*
* ugh, special case dcc because we don't want to go through
* send_text in it's current state. XXX - fix send_text to
* deal with ctcp's as well.
*/
if (*to == '=')
dcc_message_transmit(to + 1, sendp, DCC_CHAT, 0);
else
/**************************** PATCHED by Flier ******************************/
{
/****************************************************************************/
send_to_server("%s %s :%s", type, to, sendp);
/**************************** PATCHED by Flier ******************************/
#ifndef CELEHOOK
if (datatag && strcmp(datatag,"ACTION"))
do_hook(SEND_CTCP_LIST, "%s %s %s %s",type,to,datatag,sendp);
#endif
}
/****************************************************************************/
}
/*
* send_ctcp_notice: A simply way to send CTCP replies. I put this here
* rather than in ctcp.c to keep my compiler quiet
*/
void
#ifdef HAVE_STDARG_H
send_ctcp_reply(char *to, char *datatag, char *format, ...)
{
va_list vl;
#else
send_ctcp_reply(to, datatag, format, arg0, arg1, arg2, arg3, arg4,
arg5, arg6, arg7, arg8, arg9)
char *to,
*datatag,
*format;
char *arg0,
*arg1,
*arg2,
*arg3,
*arg4,
*arg5,
*arg6,
*arg7,
*arg8,
*arg9;
{
#endif /* HAVE_STDARG_H */
char putbuf[BIG_BUFFER_SIZE + 1];
if (in_on_who)
return; /* Silently drop it on the floor */
if (to && (*to == '='))
return; /* don't allow dcc replies */
strmcat(CTCP_Reply_Buffer, "\001", BIG_BUFFER_SIZE);
strmcat(CTCP_Reply_Buffer, datatag, BIG_BUFFER_SIZE);
strmcat(CTCP_Reply_Buffer, " ", BIG_BUFFER_SIZE);
if (format)
{
#ifdef HAVE_STDARG_H
va_start(vl, format);
vsnprintf(putbuf, sizeof putbuf, format, vl);
va_end(vl);
#else
snprintf(putbuf, sizeof putbuf, format, arg0, arg1, arg2, arg3, arg4, arg5,
arg6, arg7, arg8, arg9);
#endif /* HAVE_STDARG_H */
strmcat(CTCP_Reply_Buffer, putbuf, BIG_BUFFER_SIZE);
}
else
strmcat(CTCP_Reply_Buffer, putbuf, BIG_BUFFER_SIZE);
strmcat(CTCP_Reply_Buffer, "\001", BIG_BUFFER_SIZE);
}
syntax highlighted by Code2HTML, v. 0.9.1