This commit is contained in:
joonicks 2018-03-27 01:48:21 +02:00
parent c44d8598c6
commit d7121a6b1f
18 changed files with 288 additions and 70 deletions

View File

@ -1,27 +1,30 @@
3.0.99p4 -- WORK IN PROGRESS (~March, 2018)
* Added: New toybox command: ASCII, load an ascii file and line
buffer it to target
* Added: Experimental code to suppress certain commands to run on only one bot even
if command is issued in public.
* Added: Some example ascii art: bbw, camel, goatse, mech, phooler
* Added: New command: CQ (Clear sendQueue), removes all previously buffered output.
* Added: New toybox command: ASCII, load an ascii file and line buffer it to target.
* Fixed: Crash bug in BIGSAY
* Added: Signal handlers for SIGILL and SIGABRT ifdef DEBUG
* Added: New command: CRASH, for debugging/development...
* Changed: configure now defaults to optimizing for code size.
* Changed: configure now defaults to optimizing for code size (--optimize=size).
* Added: configuration option --optimize=speed or --optimize=size
* Added: STABLE/BETA/ALPHA status to individual features in configure.
* Fixed: If bot guid is changed or deleted in the config, and the bot
is reset, the connection associated with the removed guid
will be cleaned up and closed instead of lingering.
* Added: Support for read only userfiles. If you prefix the filename
with < the file wil never be written to, only ever read.
* Added: ALPHA/BETA/STABLE status to individual features in configure.
* Fixed: If bot guid is changed or deleted in the config, and the bot is reset, the
connection associated with the removed guid will be cleaned up and closed
instead of lingering.
* Added: Support for read only userfiles. If you prefix the filename with < the file
will never be written to, only ever read.
* Added: Bots now recover Ontime after a reset.
* Added: URL capturing with command to display recent URLs seen
by the bot. Also spy source "URL" for spy channels.
* Added: URL capturing with command to display recent URLs seen by the bot. Also spy
source "URL" for spy channels.
* Fixed: Rewrite of is_safepath() to conform with standard C
* Fixed: Potential crash bug in send_uptime()
* Fixed: Potential crash bug in debug()
* Added: New host information commands: HOSTINFO, MEMINFO, CPUINFO.
* Added: New configuration option: hostinfo
* Fixed: Custom ld script fintuning the core order.
* Fixed: Custom ld script finetuning the code order.
* Changed: Rewrite of ALIAS aliasing routine, adding features.
* Fixed: RawDNS, again...
* Fixed: Save procvars only once in session file.
@ -32,7 +35,7 @@
* Added: CORE & INFO (statistics) can now be output redirected.
* Added: SPY to files saved in sessions.
* Fixed: HELP command should now be working properly again.
* Fixed: Strlen/Strlen2 code cleanup.
* Fixed: StrlenX/Strlen2 code cleanup.
* Fixed: Various compiler warnings.
3.0.99p3 -- July 24th, 2009.

24
ascii/bbw Normal file
View File

@ -0,0 +1,24 @@
_.--._
,' `.
/ __) __` \
( (`-`(-') )
/) \ _ / (
/' )-._.' . \ ___
( ,--' `-)___( )
)( `-.,--' _ \ /`
'/ .' ( )\
/ `/,-' )
| ' )`._.'
\ .-. ( .-. |
". " /\ ~ /
/"---' "._.-'|
/ \
( ."-.
/(` -) / \
( \`-.__ -'_." |
| \`-.__.--"v" |
`.' \ |, |
/ `._/ :
/ | '
/ /| /
: / / /

18
ascii/camel Normal file
View File

@ -0,0 +1,18 @@
,.
. :%%%. .%%%.
__%%%(\ `%%%%% .%%%%%
/a ^ '% %%%% %: ,% %%"`
'__.. ,'% .-%: %-' %
~~""%:. ` % ' . `.
%% % ` %% .%: . \.
%%:. `-' ` .%% . %: :\
%(%,%..." `%, %%' %% ) )
%)%%)%%' )%%%.....- ' "/ (
%a:f%%\ % / \`% "%%% ` / \))
%(%' % /-. \ ' \ |-. '.
`' |% `() \| `()
|| / () /
() 0 | o
\ /\ o /
o ` /-|
,-/ ` ,-/

22
ascii/goatse Normal file
View File

@ -0,0 +1,22 @@
/ \ \ / \
| | \ | |
| `. | | :
` | | \| |
\ | / / \\\ --__ \\ :
\ \/ _--~~ ~--__| \ |
\ \_-~ ~-_\ |
\_ \ _.--------.______\| |
\ \______// _ ___ _ (_(__> \ |
\ . C ___) ______ (_(____> | /
/\ | C ____)/ \ (_____> |_/
/ /\| C_____) | (___> / \
| ( _C_____)\______/ // _/ / \
| \ |__ \\_________// (__/ |
| \ \____) `---- --' |
| \_ ___\ /_ _/ |
| / | | \ |
| | / \ \ |
| / / | | \ |
| / / \__/\___/ | |
| / | | | |
| | | | | |

20
ascii/phooler Normal file
View File

@ -0,0 +1,20 @@
( .-,
/ ) .' ( ___
//(.-"""-/ /\ ) .-" "-.
|.' _`.\// .-' `..--.
..--/-. .'_` `'-' ___ ( C\ \
/ /O\ / O\ | .' ```--`-|_/
/ \_/| \__/ | (
| _\-' _ __ / `.
\ ,--7 `.(_)_.| .' `.
| C._) `.___/' .---._ \ __
\ | `. / `-. \ ,' `.
`--' Y \ | ) `-._.--.__
| \ | _.' .--.___.-'`--.\
| | |\ / / `
_ \ | / `v |
.'`-' `--._) /::___.' \ /
/ .---. / `-. \ |
_.' _.-' `._ `-. / `. /
/.--' `-. `. \ `-.__.'
`.'_/

16
configure vendored
View File

@ -80,6 +80,7 @@ do
session ) ft_session=$yesno ;;
sha ) ft_sha=$yesno ;;
stats ) ft_stats=$yesno ;;
suppress ) ft_suppress=$yesno ;;
tcl ) ft_tcl=$yesno ;;
telnet ) ft_telnet=$yesno ;;
toybox ) ft_toybox=$yesno ;;
@ -116,7 +117,7 @@ do
case "$feature" in
debug | botnet | telnet | alias | seen | session | dyncmd | newbie | wingate | md5 | sha \
| ctcp | dccfile | uptime | redirect | greet | perl | profiling | tcl | dynamode | web | hostinfo \
| note | notify | trivia | toybox | bounce | stats | rawdns | ircd_ext | idwrap | chanban | python | urlcapture )
| note | notify | trivia | toybox | bounce | stats | suppress | rawdns | ircd_ext | idwrap | chanban | python | urlcapture )
case _"$optarg"_ in
_yes_ | _no_ | __ )
;;
@ -190,6 +191,8 @@ do
sha_no ) ft_sha=no ;;
stats_yes | stats_ ) ft_stats=yes ;;
stats_no ) ft_stats=no ;;
suppress_yes | suppress_ ) ft_suppress=yes ;;
suppress_no ) ft_suppress=no ;;
tcl_yes | tcl_ ) ft_tcl=yes ;;
tcl_no ) ft_tcl=no ;;
telnet_yes | telnet_ ) ft_telnet=yes ;;
@ -238,6 +241,7 @@ do
session ) ft_session=no ;;
sha ) ft_sha=yes ;;
stats ) ft_stats=no ;;
suppress ) ft_suppress=no ;;
tcl ) ft_tcl=no ;;
telnet ) ft_telnet=no ;;
toybox ) ft_toybox=no ;;
@ -290,6 +294,7 @@ do
ft_session=yes
ft_sha=yes
ft_stats=yes
ft_suppress=yes
ft_tcl=yes
ft_telnet=yes
ft_toybox=yes
@ -325,6 +330,7 @@ Features and packages:
--with-profiling Profiling (gcc+gprof)
--with-seen SEEN support
--with-session Session support
--with-suppress Command duplication suppression
--with-tcl Tcl support
--with-telnet Telnet support
--with-uptime Include code that sends uptime reports to the IRC bot uptime contest server
@ -1003,6 +1009,13 @@ test "$ft_chanban" && $out "$ft_chanban" && ans=$ft_chanban
test -z "$ft_chanban" && read ans
test -z "$ans" -o "$ans" = y -o "$ans" = Y -o "$ans" = yes -o "$ans" = YES -o "$ans" = Yes && def_chanban='#define CHANBAN'
def_suppress='#undef SUPPRESS'
unset ans
$out $ac_n "[ ALPHA] Command duplication suppression? ............ [Y/n] "$ac_c
test "$ft_suppress" && $out "$ft_suppress" && ans=$ft_suppress
test -z "$ft_suppress" && read ans
test -z "$ans" -o "$ans" = y -o "$ans" = Y -o "$ans" = yes -o "$ans" = YES -o "$ans" = Yes && def_suppress='#define SUPPRESS'
def_redirect='#undef REDIRECT'
unset ans
$out $ac_n "[STABLE] Command output redirect? ................... [Y/n] "$ac_c
@ -1297,6 +1310,7 @@ s|@DEF_REDIRECT@|$def_redirect|;
s|@DEF_SEEN@|$def_seen|;
s|@DEF_SESSION@|$def_session|;
s|@DEF_STATS@|$def_stats|;
s|@DEF_SUPPRESS@|$def_suppress|;
s|@DEF_TCL@|$def_tcl|;
s|@DEF_TELNET@|$def_telnet|;
s|@DEF_TOYBOX@|$def_toybox|;

View File

@ -40,7 +40,7 @@ MV = mv -f
RM = rm -f
CHMOD = chmod
INCS = config.h mcmd.h defines.h global.h h.h structs.h text.h
INCS = config.h defines.h global.h h.h mcmd.h structs.h text.h usercombo.h
TESTFILES = aliastest safepathtest

View File

@ -1,7 +1,7 @@
/*
EnergyMech, IRC bot software
Parts Copyright (c) 1997-2004 proton
Parts Copyright (c) 1997-2018 proton
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -197,6 +197,11 @@
*/
@DEF_URLCAPTURE@
/*
* SUPPRESS: suppress duplication of certain commands
*/
@DEF_SUPPRESS@
/*
* FASTNICK: faster nick regain if the nick is seen when released
* Enables code that is potentially dangerous if an attacker aquires
@ -368,20 +373,20 @@
* Defines for commandlist parsing
*/
#define DCC 0x00100 /* requires DCC */
#define CC 0x00200 /* requires commandchar */
#define PASS 0x00400 /* requires password / authentication */
#define CARGS 0x00800 /* requires args */
#define NOPUB 0x01000 /* ignore in channel (for password commands) */
#define NOCMD 0x02000 /* not allowed to be executed thru CMD */
#define GAXS 0x04000 /* check global access */
#define CAXS 0x08000 /* check channel access */
#define REDIR 0x10000 /* may be redirected */
#define LBUF 0x20000 /* should be linebuffered to server */
#define CBANG 0x40000 /* command may be prefixed with a bang (!) */
#define ACCHAN 0x80000 /* needs an active channel */
#define CLEVEL 0x000ff
#define CLEVEL 0x0000ff
#define DCC 0x000100 /* requires DCC */
#define CC 0x000200 /* requires commandchar */
#define PASS 0x000400 /* requires password / authentication */
#define CARGS 0x000800 /* requires args */
#define NOPUB 0x001000 /* ignore in channel (for password commands) */
#define NOCMD 0x002000 /* not allowed to be executed thru CMD */
#define GAXS 0x004000 /* check global access */
#define CAXS 0x008000 /* check channel access */
#define REDIR 0x010000 /* may be redirected */
#define LBUF 0x020000 /* should be linebuffered to server */
#define CBANG 0x040000 /* command may be prefixed with a bang (!) */
#define ACCHAN 0x080000 /* needs an active channel */
#define SUPRES 0x100000 /* command is not suitable to run on many bots at once, try to suppress it */
/*
* integer only version of RANDOM()

View File

@ -214,13 +214,6 @@ void dupe_strp(Strp *sp, Strp **pp)
make_strp(pp,sp->p);
pp = &((*pp)->next);
sp = sp->next;
/*
set_mallocdoer(dupe_strp);
*pp = (Strp*)Calloc(sizeof(Strp) + strlen(sp->p));
Strcpy((*pp)->p,sp->p);
pp = &((*pp)->next);
sp = sp->next;
*/
}
}

View File

@ -30,18 +30,19 @@ char gsockdata[MAXLEN];
These are defined in config.h
DCC 0x00100 requires DCC
CC 0x00200 requires commandchar
PASS 0x00400 requires password / authentication
CARGS 0x00800 requires args
NOPUB 0x01000 ignore in channel (for password commands)
NOCMD 0x02000 not allowed to be executed thru CMD
GAXS 0x04000 check global access
CAXS 0x08000 check channel access
REDIR 0x10000 may be redirected
LBUF 0x20000 can be linebuffered to server
CBANG 0x40000 command may be prefixed with a bang (!)
ACCHAN 0x80000 needs an active channel
DCC 0x000100 requires DCC
CC 0x000200 requires commandchar
PASS 0x000400 requires password / authentication
CARGS 0x000800 requires args
NOPUB 0x001000 ignore in channel (for password commands)
NOCMD 0x002000 not allowed to be executed thru CMD
GAXS 0x004000 check global access
CAXS 0x008000 check channel access
REDIR 0x010000 may be redirected
LBUF 0x020000 can be linebuffered to server
CBANG 0x040000 command may be prefixed with a bang (!)
ACCHAN 0x080000 needs an active channel
SUPRES 0x100000 command is not suitable to run on many bots at once, try to suppress it
CLEVEL 0x000ff
@ -65,7 +66,7 @@ struct
{ 0, "AUTH", "do_auth", 0 | NOPUB | CBANG }, // double up on AUTH/VERIFY to better
{ 0, "VERIFY", "do_auth", 0 | NOPUB | CBANG }, // catch login attempts
#ifdef TOYBOX
{ 0, "8BALL", "do_8ball", 0 | CBANG },
{ 0, "8BALL", "do_8ball", 0 | CBANG | SUPRES },
#endif /* TOYBOX */
/*
@ -75,11 +76,11 @@ struct
{ 0, "BYE", "do_bye", 10 | CC },
{ 0, "CHAT", "do_chat", 10 | CCPW | NOCMD },
#ifdef RAWDNS
{ 0, "DNS", "do_dns", 10 | CCPW | GAXS | CARGS },
{ 0, "DNS", "do_dns", 10 | CCPW | GAXS | CARGS | SUPRES },
#endif /* RAWDNS */
{ 0, "DOWN", "do_opdeopme", 10 | CC | CAXS },
{ 0, "ECHO", "do_echo", 10 | CCPW | CARGS },
{ 0, "HELP", "do_help", 10 | CCPW | REDIR | LBUF },
{ 0, "HELP", "do_help", 10 | CCPW | REDIR | LBUF | SUPRES },
{ 0, "PASSWD", "do_passwd", 10 | PASS | NOPUB | CARGS },
#ifdef DCC_FILE
{ 0, "SEND", "do_send", 10 | CC | NOCMD | CBANG | CARGS },
@ -125,7 +126,7 @@ struct
{ 0, "SITEBAN", "do_kickban", 40 | CCPW | CAXS | CARGS | ACCHAN , "\\x01siteban\\0sitebann" },
{ 0, "SITEKB", "do_kickban", 40 | CCPW | CAXS | CARGS | ACCHAN , "\\x05sitekickban\\0sitekickbann" },
{ 0, "TIME", "do_time", 40 | CCPW },
{ 0, "TOPIC", "do_topic", 40 | CCPW | CAXS | CARGS | ACCHAN },
{ 0, "TOPIC", "do_topic", 40 | CCPW | CAXS | CARGS | ACCHAN | SUPRES },
{ 0, "UNBAN", "do_unban", 40 | CCPW | CAXS },
{ 0, "UNVOICE", "do_opvoice", 40 | CCPW | CAXS | CARGS , "v-" },
{ 0, "UP", "do_opdeopme", 40 | CCPW | CAXS },
@ -158,7 +159,7 @@ struct
{ 0, "PICKUP", "do_random_msg", 50 | CCPW , RANDPICKUPFILE },
{ 0, "RSAY", "do_random_msg", 50 | CCPW , RANDSAYFILE },
{ 0, "RT", "do_randtopic", 50 | CCPW | CAXS | ACCHAN },
{ 0, "ASCII", "do_ascii", 50 | CCPW | CAXS | CARGS },
{ 0, "ASCII", "do_ascii", 50 | CCPW | CAXS | CARGS | SUPRES },
#endif /* TOYBOX */
#ifdef TRIVIA
{ 0, "TRIVIA", "do_trivia", 50 | CCPW | CAXS | CARGS | CBANG },
@ -195,6 +196,7 @@ struct
#if defined(BOTNET) && defined(REDIRECT)
{ 0, "CMD", "do_cmd", 80 | CCPW | CARGS },
#endif /* BOTNET && REDIRECT */
{ 0, "CQ", "do_clearqueue", 80 | CCPW | GAXS },
{ 0, "LAST", "do_last", 80 | CCPW | DCC },
{ 0, "LOAD", "do_load", 80 | CCPW | GAXS },
{ 0, "MSG", "do_msg", 80 | CCPW | CARGS },
@ -208,7 +210,7 @@ struct
{ 0, "UNALIAS", "do_unalias", 80 | CCPW | GAXS | CARGS },
#endif /* ALIAS */
#ifdef TOYBOX
{ 0, "BIGSAY", "do_bigsay", 80 | CCPW | CAXS | CARGS },
{ 0, "BIGSAY", "do_bigsay", 80 | CCPW | CAXS | CARGS | SUPRES },
#endif /* TOYBOX */
/*
@ -351,8 +353,9 @@ void make_mcmd(void)
v.lbuf = (pre_mcmd[wh].flags & LBUF) ? 1 : 0;
v.cbang = (pre_mcmd[wh].flags & CBANG) ? 1 : 0;
v.acchan = (pre_mcmd[wh].flags & ACCHAN) ? 1 : 0;
v.supres = (pre_mcmd[wh].flags & SUPRES) ? 1 : 0;
sprintf(tmp,"%3i,%2i,%2i,%2i,%2i,%2i,%2i,%2i,%2i,%2i,%2i,%2i,%2i",
sprintf(tmp,"%3i,%2i,%2i,%2i,%2i,%2i,%2i,%2i,%2i,%2i,%2i,%2i,%2i,%2i",
v.defaultaccess,
v.dcc,
v.cc,
@ -365,7 +368,8 @@ void make_mcmd(void)
v.redir,
v.lbuf,
v.cbang,
v.acchan
v.acchan,
v.supres
);
sl = strlen(pre_mcmd[wh].func) + 1;

View File

@ -182,8 +182,8 @@ LS void sig_suicide() __attr(RARE_SEG, __noreturn__); /* rare */
/* net_chan.c */
LS int makecrc(const char *) __page(CORE_SEG);
LS void send_supress(const char *, const char *) __page(CORE_SEG);
LS void netchanSupress(BotNet *, char *) __page(CORE_SEG);
LS void send_suppress(const char *, const char *) __page(CORE_SEG);
LS void netchanSuppress(BotNet *, char *) __page(CORE_SEG);
/* note.c */
/* notify.c */
@ -204,6 +204,7 @@ LS int SockConnect(char *, int, int) __page(CORE_SEG);
LS void SockFlags(int) __page(CORE_SEG);
LS int SockListener(int) __page(CORE_SEG);
LS int SockOpts(void) __page(CORE_SEG);
LS void do_clearqueue(COMMAND_ARGS) __page(CMD1_SEG);
/* spy.c */
/* stats.c */

View File

@ -134,12 +134,80 @@ void do_meminfo(COMMAND_ARGS)
vmsize,vmpeak,vmrss,vmexe,vmdata,vmlib,vmstk);
}
char *cpufrom,cpuline[MSGLEN];
int sentmodel;
int cpus;
int cores;
int parse_proc_cpuinfo(char *line)
{
char *src,*dst;
if (strncmp(line,"model name\t:",12) == 0)
;
}
/*
proton@endemic:~/energymech/src> cat /proc/loadavg
0.00 0.00 0.00 1/178 6759
processor : 0
vendor_id : GenuineIntel
cpu family : 6
model : 23
model name : Intel(R) Core(TM)2 Quad CPU Q8200 @ 2.33GHz
stepping : 7
microcode : 0x705
cpu MHz : 2024.267
cache size : 2048 KB
physical id : 0
siblings : 4
core id : 0
cpu cores : 4
*/
/*---Help:CPUINFO:(no arguments)
See also: hostinfo, meminfo
*/
void do_cpuinfo(COMMAND_ARGS)
{
char *a1,*a2,*a3;
int fd,n;
if ((fd = open("/proc/loadavg",O_RDONLY)) < 0)
#ifdef DEBUG
{
debug("(do_cpuinfo) /proc/loadavg: %s\n",strerror(errno));
return;
}
#else
return;
#endif
n = read(fd,gsockdata,MSGLEN-2);
gsockdata[n] = 0;
close(fd);
rest = gsockdata;
a1 = chop(&rest);
a2 = chop(&rest);
a3 = chop(&rest);
if (!a3 || !*a3)
return;
if ((fd = open("/proc/cpuinfo",O_RDONLY)) < 0)
#ifdef DEBUG
{
debug("(do_cpuinfo) /proc/cpuinfo: %s\n",strerror(errno));
return;
}
#else
return;
#endif
cpufrom = from;
sentmodel = 0;
readline(fd,&parse_proc_cpuinfo);
}
#endif /* HOSTINFO */

View File

@ -78,7 +78,9 @@ LS const LinkCmd basicProto[] =
{ 'B', 'L', basicLink },
{ 'B', 'Q', basicQuit },
{ 'C', 'O', netchanNeedop },
{ 'C', 'S', netchanSupress }, // experimental command supression
#ifdef SUPPRESS
{ 'C', 'S', netchanSuppress }, // experimental command supression
#endif /* SUPPRESS */
{ 'P', 'A', partyAuth },
#ifdef REDIRECT
{ 'P', 'C', partyCommand },

View File

@ -30,6 +30,8 @@
#include "text.h"
#include "mcmd.h"
#ifdef SUPPRESS
int makecrc(const char *args)
{
int crc = 0;
@ -43,7 +45,7 @@ int makecrc(const char *args)
return(crc);
}
void send_supress(const char *command, const char *args)
void send_suppress(const char *command, const char *args)
{
Mech *backup;
int crc;
@ -60,6 +62,8 @@ void send_supress(const char *command, const char *args)
botnet_relay(NULL,"CS%s %i\n",command,crc);
}
#endif /* SUPPRESS */
ChanUser *find_chanbot(Chan *chan, char *nick)
{
ChanUser *cu;
@ -171,7 +175,9 @@ void netchanNeedop(BotNet *source, char *rest)
}
}
void netchanSupress(BotNet *source, char *rest)
#ifdef SUPPRESS
void netchanSuppress(BotNet *source, char *rest)
{
Mech *backup;
const char *cmd;
@ -206,4 +212,6 @@ void netchanSupress(BotNet *source, char *rest)
}
}
#endif /* SUPPRESS */
#endif /* BOTNET */

View File

@ -521,6 +521,7 @@ recheck_alias:
CurrentCmd = &mcmd[i];
#ifdef SUPPRESS
#ifdef BOTNET
// experimental command supression
if (CurrentCmd->name == current->supres_cmd)
@ -540,12 +541,12 @@ recheck_alias:
}
}
//if command should be supressed ...
if (CurrentChan)
if (mcmd[i].supres && CurrentChan)
{
send_supress(CurrentCmd->name,rest);
send_suppress(CurrentCmd->name,rest);
}
#endif
#endif /* SUPPRESS */
/*
* convert the command to uppercase
*/

View File

@ -1,7 +1,7 @@
/*
EnergyMech, IRC bot software
Parts Copyright (c) 1997-2009 proton
Parts Copyright (c) 1997-2018 proton
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -678,4 +678,13 @@ int killsock(int sock)
return(TRUE);
}
void do_clearqueue(COMMAND_ARGS)
{
#ifdef DEBUG
debug("(do_clearqueue) purging sendq...\n");
#endif
purge_strplist(current->sendq);
current->sendq = NULL;
}
#endif /* GENCMD_C */

View File

@ -785,7 +785,8 @@ typedef struct OnMsg
redir:1,
lbuf:1,
cbang:1,
acchan:1; // -- 20 bits
acchan:1,
supres:1; // -- 21 bits
char *cmdarg;
} OnMsg;

View File

@ -356,14 +356,39 @@ void do_ascii(COMMAND_ARGS)
char fname[MSGLEN];
int fd;
Strcat(Strcpy(fname,"ascii/"),rest);
#ifdef DEBUG
if (STRCHR(rest,'/'))
{
debug("(do_ascii) '/' not permitted in filename\n");
ascii_badfile:
to_user_q(from,"%s","Bad filename or file does not exist");
return;
}
Strcat(Strcpy(fname,"ascii/"),rest);
debug("(do_ascii) file = \"%s\"\n",fname);
#endif
if (is_safepath(fname,FILE_MUST_EXIST) != FILE_IS_SAFE)
return;
{
debug("(do_ascii) is_safepath() not safe\n");
goto ascii_badfile;
}
if ((fd = open(fname,O_RDONLY)) < 0)
{
debug("(do_ascii) open(%s): %s\n",fname,strerror(errno));
goto ascii_badfile;
}
#else
if (STRCHR(rest,'/'))
{
ascii_badfile:
to_user_q(from,"%s","Bad filename or file does not exist");
return;
}
Strcat(Strcpy(fname,"ascii/"),rest);
if (is_safepath(fname,FILE_MUST_EXIST) != FILE_IS_SAFE)
goto ascii_badfile;
if ((fd = open(fname,O_RDONLY)) < 0)
goto ascii_badfile;
#endif
ascii_from = from;
readline(fd,&read_ascii); /* readline closes fd */