Merge pull request #33 from joonicks/dev

Christmas update dev -> main
This commit is contained in:
joonicks 2025-12-14 13:30:45 +01:00 committed by GitHub
commit 3210a84d37
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
81 changed files with 4102 additions and 3240 deletions

10
.gitignore vendored
View File

@ -8,6 +8,7 @@ src/config.h
src/mcmd.h
src/usercombo.h
src/githash.h
src/hashdata.cache
trivia/*.index
# compiled files
@ -32,14 +33,21 @@ trivia/megatrivia.txt
*.stats
# developer files
dev/*
.use_size
.use_warn
conf
debug*
src/musl.c
src/benchmark*
src/nostdlib
src/x
src/y
src/z
x
y
z
randdata
test.conf
postfix.sh
gmon.out

View File

@ -42,26 +42,60 @@ DCC chat and DCC file support to operate.
Very necessary to include if you are a developer...
--- Dynamic channel limit (+l)
Make the bot update the channel user limit (+l) to a value that only allows
a limited number of users to join within a certain time period.
--- Dynamic command levels support
Permit altering at runtime the access level needed to use commands. Including
the possibility to disable commands.
--- Greet support
--- HTTP server support
Warning: ALPHA grade code. Not recommended for casual use. Make energymech
respond to HTTP requests on a user configurable port.
--- Host info support
Include features to monitor the server that the energymech runs on.
--- IRC proxy support
--- IRCD extensions support
BETA code. Support for non-standard IRC server features.
--- Newbie support
Extra safeguards and messages for beginners.
--- Note support
--- Notify support
--- Password hashing with MD5
Encrypt user passwords with md5.
--- Password hashing with SHA
Encrypt user passwords with sha1 or sha512.
--- Scripting with Python
--- Scripting with Tcl
--- Seen support
--- Session support
--- Statistics support
--- Telnet support
Support for connecting to the energymech partyline with telnet/netcat.
--- Trivia support
--- Toybox fun and games
--- Uptime support
Send bot uptime packets to the bot uptime tracker (https://www.eggheads.org/uptime)
--- URL capture support
--- WinGate support
Ancient tech. Support for wingate proxy.

View File

@ -17,52 +17,55 @@
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#
MISCFILES = CREDITS FEATURES LICENSE README README.TCL TODO VERSIONS VERSIONS-2.x Makefile configure \
checkmech sample.conf sample.py sample.tcl sample.userfile default.bigchars public/README trivia/README
MISCFILES = CREDITS FEATURES LICENSE README README.TCL TODO VERSIONS VERSIONS-2.x Makefile \
configure checkmech sample.conf sample.py sample.tcl sample.userfile \
common/default.bigchars public/README trivia/README
ASCIIFILES = ascii/README ascii/bbw ascii/camel ascii/goatse ascii/mech ascii/phooler
HELPFILES = help/8BALL help/ACCESS help/ALIAS help/AWAY help/BAN help/BANLIST help/BYE \
help/CCHAN help/CHACCESS help/CHANBAN help/CHANNELS help/CHAT help/CLEARSHIT \
help/CMD help/CORE help/CSERV help/CTCP help/CYCLE help/DEOP help/DIE \
help/DNS help/DNSSERVER help/DO help/DOWN help/ECHO help/ESAY help/FEATURES \
help/FORGET help/GREET help/HELP help/IDLE help/INSULT help/INVITE help/JOIN help/KB \
help/KICK help/KS help/LAST help/LEVELS help/LINK help/LOAD help/LUSERS help/ME \
help/MODE help/MSG help/NAMES help/NEXTSERVER help/NICK help/NOTIFY help/ONTIME \
help/OP help/PART help/PASSWD help/PROTECTION help/PYTHON help/PYTHONSCRIPT \
help/QSHIT help/RESET help/RKS help/RSHIT help/RSPY help/RT help/SAVE help/SAY \
help/SCREW help/SEEN help/SERVER help/SERVERGROUP help/SET help/SETAAWAY \
help/SETAOP help/SETAUB help/SETAVOICE help/SETCC help/SETCHANBAN help/SETCKL \
help/SETDCC help/SETENFM help/SETENFMODES help/SETENFPASS help/SETFL help/SETFPL \
help/SETIKT help/SETKS help/SETMAL help/SETMBL help/SETMDL help/SETMKL \
help/SETMODES help/SETMPL help/SETNCL help/SETPASS help/SETPROT help/SETPUB \
help/SETRK help/SETSD help/SETSERVERGROUP help/SETSHIT help/SETSO help/SETSTATS \
help/SETTOP help/SHIT help/SHITLIST help/SHOWIDLE help/SHUTDOWN help/SITEBAN \
help/SITEKB help/SPY help/STATS help/TCL help/TCLSCRIPT help/TIME help/TOPIC \
help/UNALIAS help/UNBAN help/UNVOICE help/UP help/UPTIME help/USAGE help/USER \
help/USERHOST help/USERLIST help/VER help/VERIFY help/VOICE help/WALL help/WHO \
help/WHOIS help/WHOM
HELPFILES = help/8BALL help/ACCESS help/ALIAS help/AWAY help/BAN help/BANLIST help/BOOT \
help/BYE help/CCHAN help/CHACCESS help/CHANBAN help/CHANNELS help/CHAT \
help/CLEARSHIT help/CMD help/CORE help/CSERV help/CTCP help/CYCLE help/DEBUG \
help/DEOP help/DIE help/DNS help/DNSSERVER help/DO help/DOWN help/ECHO \
help/ESAY help/FEATURES help/FORGET help/GREET help/HELP help/IDLE help/INSULT \
help/INVITE help/JOIN help/KB help/KICK help/KS help/LAST help/LEVELS help/LINK \
help/LOAD help/LUSERS help/ME help/MODE help/MSG help/NAMES help/NEXTSERVER \
help/NICK help/NOTE help/NOTIFY help/ONTIME help/OP help/PART help/PASSWD \
help/PROTECTION help/PYTHON help/PYTHONSCRIPT help/QSHIT help/RAND help/READ \
help/RESET help/RKS help/RSHIT help/RSPY help/RT help/SAVE help/SAY help/SCREW \
help/SEEN help/SERVER help/SERVERGROUP help/SET help/SETAAWAY help/SETAOP \
help/SETAUB help/SETAVOICE help/SETCC help/SETCHANBAN help/SETCKL help/SETDCC \
help/SETENFM help/SETENFMODES help/SETENFPASS help/SETFL help/SETFPL help/SETIKT \
help/SETKS help/SETMAL help/SETMBL help/SETMDL help/SETMKL help/SETMODES \
help/SETMPL help/SETNCL help/SETPASS help/SETPROT help/SETPUB help/SETRK \
help/SETSD help/SETSERVERGROUP help/SETSHIT help/SETSO help/SETSTATS help/SETTOP \
help/SHIT help/SHITLIST help/SHOWIDLE help/SHUTDOWN help/SITEBAN help/SITEKB \
help/SPY help/STATS help/TCL help/TCLSCRIPT help/TIME help/TOPIC help/UNALIAS \
help/UNBAN help/UNVOICE help/UP help/UPTIME help/USAGE help/USER help/USERHOST \
help/USERLIST help/VER help/VERIFY help/VOICE help/WALL help/WHO help/WHOIS help/WHOM
RANDFILES = messages/8ball.txt messages/away.txt messages/insult.txt \
messages/kick.txt messages/nick.txt messages/pickup.txt \
messages/say.txt messages/signoff.txt messages/version.txt
RANDFILES = common/8ball.txt common/away.txt common/insult.txt \
common/kick.txt common/nick.txt common/pickup.txt \
common/say.txt common/signoff.txt common/version.txt
STUBFILES = src/Makefile.in src/config.h.in src/ld/README src/ld/elf32-i386 src/ld/elf64-x86-64
TESTFILES = config/cc.c config/endian.c config/inet_addr.c config/inet_aton.c config/ldtest.c config/md5.h config/md5_internal.c \
config/perl.c config/ptr_size.c config/python.c config/pw.c config/sha1.h config/sha_internal.c config/socket.c config/tcl.c \
TESTFILES = config/cc.c config/endian.c config/inet_addr.c config/inet_aton.c config/ldtest.c \
config/md5.h config/md5.c config/perl.c config/ptr_size.c config/python.c config/pw.c \
config/sha1.h config/sha1.c config/sha512.c config/socket.c config/tcl.c \
config/unaligned.c config/which
TRIVFILES = trivia/mkindex.c
SRCFILES = src/alias.c src/auth.c src/bounce.c src/channel.c src/core.c src/ctcp.c src/debug.c src/dns.c \
src/function.c src/gencmd.c src/greet.c src/help.c src/hostinfo.c src/irc.c src/main.c \
src/net.c src/note.c src/ons.c src/parse.c src/partyline.c src/perl.c src/prot.c \
src/python.c src/reset.c src/seen.c src/shit.c src/io.c src/spy.c src/tcl.c \
src/toybox.c src/uptime.c src/user.c src/vars.c src/web.c \
src/lib/md5.c src/lib/md5.h src/lib/string.c
SRCFILES = src/alias.c src/auth.c src/bounce.c src/calc.c src/channel.c src/core.c src/ctcp.c \
src/debug.c src/dns.c src/function.c src/gencmd.c src/greet.c src/help.c src/hostinfo.c \
src/irc.c src/main.c src/net.c src/note.c src/ons.c src/parse.c src/partyline.c \
src/perl.c src/prot.c src/python.c src/reset.c src/seen.c src/shit.c src/io.c \
src/spy.c src/tcl.c src/toybox.c src/uptime.c src/user.c src/vars.c src/web.c \
src/lib/md5.c src/lib/md5.h src/string.c
HDRFILES = src/defines.h src/global.h src/h.h src/settings.h src/structs.h src/text.h src/usage.h
HDRFILES = src/commands.h src/defines.h src/global.h src/h.h src/onhash.h src/settings.h \
src/structs.h src/text.h src/usage.h
CONFFILES = src/Makefile src/config.h
@ -86,14 +89,18 @@ clean:
install:
$(MAKE) -C src install
test -x postfix.sh && ./postfix.sh
@if [ -x test ]; then \
./postfix.sh; \
fi
mega:
$(MAKE) -C src mega
mega-install:
mega-install mi:
$(MAKE) -C src mega-install
test -x postfix.sh && ./postfix.sh
@if [ -x test ]; then \
./postfix.sh; \
fi
#
# code validation tests

4
README
View File

@ -120,7 +120,7 @@ Extra files for users of EnergyMech can be found at:
Files, documentation and tips can be found at:
http://www.energymech.net
(no official website currently)
---*---
@ -129,4 +129,4 @@ IT COMES TO CONFIGURING AND USING IT.
---*---
proton, April 17th, 2018.
proton, November 5th, 2025.

5
TODO
View File

@ -1,7 +1,9 @@
/*
* EnergyMech TODO (March 16th, 2018)
* EnergyMech TODO (November 6th, 2025)
*/
- copy a master read_fds for select instead of building a new one each loop
- Toybox hangman game
- Support for MD5 and SHA enabled at the same time for compatibility/fallback
@ -19,6 +21,7 @@
- DalNet Nickserv/Chanserv support (needed? they dont tolerate much bots on that network /proton)
- Update/complete the help files.
- Parse help files out of source code comments.
- Mode +/-o commands to check for SO and if SO is set, check userlevel and make sure user has access before sending MODEs.

View File

@ -1,4 +1,53 @@
3.1 -- WORK IN PROGRESS (~May, 2018)
3.5(.dev) --
* Fixed: Channel stats would be desynched after bot being kicked and rejoining.
* Added: New debug command: INJECT <rest>. Inject data as if it came from the server itself.
* Fixed: prot_action enforced protection levels above SET PROT.
* Fixed: Apparently Eggheads changed the uptime protocol without telling anyone.
* Changed: Branchless more compact base64 conversion for RANDSRC in send_spy().
* Changed: New botnet connection announced on spy status instead of spy botnet.
* Changed: Adjusted output of INFO command.
* Changed: Rewrote how SERVERGROUP works. Config files might need changes.
* Removed: SERVERGROUP command.
* Changed: Nicks/Wantnick/Userhost dynamically allocated only for 'too long' strings.
* Removed: IDWRAP code. It was my personal thing.
* Changed: on_msg now matches commands using a hash function instead
of iterating through the list of commands using strcasecmp.
* Added: More help files; BOOT, DEBUG, NOTE, READ
* Changed: Updated several helpfiles.
* Changed: Table of builtin commands taken out of gencmd.c and put into
commands.h for easier editing.
* Added: ESAY $load to show system CPU loadavg (HOSTINFO feature).
* Changed: Bumped version because of undocumented changes.
3.2 -- October 21, 2025.
* Added: Server maxontime is actually used.
* Fixed: Crash in SETPASS
* Fixed: FORGET command Issue #20
* Added: Support for a posfix.sh command at the end of the compilation
process for developers.
* Added: Host info added to CORE (with HOSTINFO support).
* Plenty of unlisted changes...
* Changed: Do not log commands until all the checks are done.
* Added: Debug info on code layout in debug files.
* Changed: HOSTINFO changed to SYSINFO.
* Fixed: Compiler warnings.
* Changed: More code layout adjustments.
* Added: Superuser doing AUTH with no arguments will list active auths.
* Changed: Default uptime host set to uptime.eggheads.org.
* Fixed: CHAT crash bug.
* Changed: Reorder HELP command list to alphabetical order.
* Added: Binary as source for CV command.
* Added: Newbie warning about using -f with sessions support.
* Added: CALC command (still alpha code).
* Added: Spy RANDSRC: generate randomness from IRC activity.
* Fixed: away.txt grammar (m4t).
* Fixed: 8ball.txt language fixes.
* Changed: ESAY overflow adjustment.
* Changed: January 15, 2025: Proton no longer single. Sorry to all the ladies.
3.1 -- May 25, 2020.
* Fixed: If the network interface goes down, the mech will mark all servers as unconnectable,
permanently, so even when the network comes back up... Fixed!

12
config/fdset.c Normal file
View File

@ -0,0 +1,12 @@
#include <stdio.h>
#include <sys/select.h>
int main(int argc, char **argv, char **envp)
{
fd_set readfds;
int sz;
sz = sizeof(readfds);
printf("%i\n",sz);
return(0);
}

View File

@ -1,9 +1,20 @@
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <string.h>
int main(int argc, char **argv)
{
struct in_addr ia;
ia.s_addr = inet_addr("0.0.0.0");
if (argc == 2)
{
if (strcmp("safamily",argv[1]) == 0)
printf("%i\n",(int)sizeof(sa_family_t));
if (strcmp("sockaddr",argv[1]) == 0)
printf("%i\n",(int)sizeof(struct sockaddr_in));
if (strcmp("sockaddrv6",argv[1]) == 0)
printf("%i\n",(int)sizeof(struct sockaddr_in6));
}
return(0);
}

1
config/sha512.c Symbolic link
View File

@ -0,0 +1 @@
../src/lib/sha512.c

153
configure vendored
View File

@ -24,6 +24,8 @@ compile=no
install=no
silentopt=no
try_libmusl=no
no_flto=no
use_fnostrictalias=no
# default optimization goal, speed = -O2, size = -Os
optitype=size
@ -103,7 +105,6 @@ do
dyncmd ) ft_dyncmd=$yesno ;;
greet ) ft_greet=$yesno ;;
hostinfo ) ft_hostinfo=$yesno ;;
idwrap ) ft_idwrap=$yesno ;;
ircd_ext ) ft_ircd_ext=$yesno ;;
libmusl ) try_libmusl=$yesno ;;
md5 ) ft_md5=$yesno ;;
@ -154,7 +155,7 @@ do
esac
case "$feature" in
alias | botnet | bounce | chanban | ctcp | dccfile | debug | dynamode | dyncmd | greet | hostinfo | idwrap | ircd_ext | libmusl | md5 \
alias | botnet | bounce | chanban | ctcp | dccfile | debug | dynamode | dyncmd | greet | hostinfo | ircd_ext | libmusl | md5 \
| netcfg | newbie | note | notify | perl | profiling | python | rawdns | redirect | seen | session | sha | stats | suppress | tcl \
| telnet | toybox | trivia | uptime | urlcapture | web | wingate )
case _"$optarg"_ in
@ -206,8 +207,6 @@ do
greet_no ) ft_greet=no ;;
hostinfo_yes | hostinfo_ ) ft_hostinfo=yes ;;
hostinfo_no ) ft_hostinfo=no ;;
idwrap_yes | idwrap_ ) ft_idwrap=yes ;;
idwrap_no ) ft_idwrap=no ;;
ircd_ext_yes | ircd_ext_ ) ft_ircd_ext=yes ;;
ircd_ext_no ) ft_ircd_ext=no ;;
libmusl_yes | libmusl_ ) try_libmusl=/usr/local/musl/bin/musl-gcc ;;
@ -273,11 +272,10 @@ do
dyncmd ) ft_dyncmd=no ;;
greet ) ft_greet=no ;;
hostinfo ) ft_hostinfo=no ;;
idwrap ) ft_idwrap=no ;;
ircd_ext ) ft_ircd_ext=no ;;
libmusl ) try_libmusl=no ;;
libmusl ) try_libmusl=no ;;
md5 ) ft_md5=no ;;
netcfg ) ft_netcfg=no ;;
netcfg ) ft_netcfg=no ;;
newbie ) ft_newbie=no ;;
note ) ft_note=no ;;
notify ) ft_notify=no ;;
@ -306,12 +304,15 @@ do
--silence=options) silentopt=yes ;;
--md5=internal) ft_md5=internal ;;
--sha=internal) ft_sha=internal ;;
--sha=internal512) ft_sha=internal512 ;;
--use-cpuflags) cc_arch_opt=yes ;;
--no-cpuflags) cc_arch_opt=no ;;
--use-optimize) cc_optimize_opt=yes ;;
--no-optimize) cc_optimize_opt=no ;;
--optimize=speed) optitype=speed ;;
--optimize=size) optitype=size ;;
--use-nostrictalias) use_fnostrictalias=yes ;;
--no-nostrictalias) use_fnostrictalias=no ;;
--use-gnudebug) cc_g_opt=yes ;;
--no-gnudebug) cc_g_opt=no ;;
--use-warnflag) cc_wall_opt=yes ;;
@ -320,6 +321,8 @@ do
--no-pipeflag) cc_pipe_opt=no ;;
--use-ofp) cc_ofp_opt=yes ;;
--no-ofp) cc_ofp_opt=no ;;
--use-flto) no_flto=no ;;
--no-flto) no_flto=yes ;;
--default-yes) ft_default=yes set_feature_defaults ;;
--default-no) ft_default=no set_feature_defaults ;;
--help | -h)
@ -338,6 +341,8 @@ Features and packages:
--sha=internal Use internal routines for SHA password hashes instead of system libraries
--use-ofp Try to use compiler flag -fomit-frame-pointer
--no-ofp Do not use compiler flag -fomit-frame-pointer
--use-flto Try to compile with Link-Time Optimizatons
--no-flto Dont use Link-Time Optimizations
--with-alias ALIAS support
--with-botnet Botnet support
--with-bounce
@ -557,7 +562,7 @@ cf_cflags=
if [ -n "$CFLAGS" ]; then
if $CC $CFLAGS -c -o $TESTO $TESTC 1> /dev/null 2> /dev/null && test -r $TESTO; then
cf_cflags="$CFLAGS"
echo $ac_n "$CFLAGS "$ac_c
echo $ac_n "$CFLAGS (from environment CFLAGS) "$ac_c
fi
fi
@ -589,7 +594,7 @@ if [ -z "$cf_cflags" -a -n "$cf_GNUCC" ]; then
fi
fi
fi
if [ "$cc_wall_flag" = -Wall -a "$cf_GNUCC" = 33 ]; then
if [ "$use_fnostrictalias" = yes -a "$cc_wall_opt" = -Wall ]; then
cc_fnostrictalias="-fno-strict-aliasing"
echo $ac_n "-fno-strict-aliasing "$ac_c
fi
@ -627,6 +632,9 @@ if [ -z "$cf_cflags" -a -n "$cf_GNUCC" ]; then
fi
fi
#
# test for -pipe flag
#
if [ -z "$cf_cflags" -a -z "$cc_pipe_opt" ]; then
if $CC -pipe -c -o $TESTO $TESTC 1> /dev/null 2> /dev/null && test -r $TESTO; then
cc_pipe_flag="-pipe"
@ -634,6 +642,20 @@ if [ -z "$cf_cflags" -a -z "$cc_pipe_opt" ]; then
fi
fi
#
# test -flto (link-time optimizations)
#
if [ -z "$no_flto" -o "$no_flto" = no ]; then
if [ -z "$cf_cflags" ]; then
if $CC -flto -c -o $TESTO $TESTC 1> /dev/null 2> /dev/null && test -r $TESTO; then
cc_flto_flag="-flto"
echo $ac_n "-flto "$ac_c
fi
fi
else
cc_flto_flag=
fi
oflag="-O2"
if [ "$optitype" = size ]; then
oflag="-Os"
@ -652,6 +674,14 @@ if [ -z "$cf_cflags" -a -z "$cc_optimize_opt" ]; then
fi
fi
cc_omitprotect_flag=""
if [ "$optitype" = size ]; then
if $CC $oflag -fcf-protection=none -o $TESTO $TESTC 1> /dev/null 2> /dev/null; then
cc_omitprotect_flag="-fcf-protection=none "
echo $ac_n "$cc_omitprotect_flag "$ac_c
fi
fi
echo $ac_t ""
if [ "$ft_prof" = yes ]; then
@ -677,6 +707,20 @@ fi
rm -f $TESTO $TESTP
#
# size of select fd_set
#
TESTC=config/fdset.c
size_fdset=128
echo $ac_n "checking size of select fd_set ... "$ac_c
$CC -o $TESTP $TESTC 1> /dev/null 2> /dev/null
if [ -x $TESTP ]; then
size_fdset=`$TESTP`
fi
echo $ac_t "$size_fdset bytes"
rm -f $TESTP
#
# 32bit? 64bit?
#
@ -690,7 +734,11 @@ if [ -z "$ptr_size" ]; then
if [ -x $TESTP ]; then
ptr_size=`$TESTP`
fi
echo $ac_t "$ptr_size"
if [ "$ptr_size" = 8 ]; then
echo $ac_t "64 bit"
else
echo $ac_t "$ptr_size"
fi
fi
case _"$ptr_size"_ in
@ -798,6 +846,17 @@ else
fi
fi
echo $ac_t "$has_inet_addr"
if [ "$has_inet_addr" = no ]; then
echo "error: missing inet_addr(), cant proceed without it."
exit
fi
echo $ac_n "checking sizeof(sa_family_t) ... "$ac_c
safamily=unknown
if [ -x $TESTP ]; then
safamily=`$TESTP`
fi
echo $ac_t "$safamily"
rm -f $TESTP
#
@ -853,20 +912,37 @@ if [ ! "$ft_sha" = no ]; then
TESTC=config/pw.c
echo $ac_n "checking for SHA in crypt() ... "$ac_c
sha_internal=
sha_object=
crypt_func='-DCRYPT_FUNC=crypt'
CRYPT_FUNCTION='#define CRYPT_FUNC crypt'
if [ "$ft_sha" = internal512 ]; then
sha_internal=config/sha512.c
sha_object=config/sha512.o
crypt_func='-DCRYPT_FUNC=crypt_sha512'
CRYPT_FUNCTION='#define CRYPT_FUNC crypt_sha512'
$CC -o $TESTP $sha_internal -DTEST 1> /dev/null 2> /dev/null
fi
if [ "$ft_sha" = internal ]; then
sha_internal=config/sha_internal.c
sha_internal=config/sha1.c
sha_object=config/sha1.o
crypt_func='-DCRYPT_FUNC=sha_crypt'
CRYPT_FUNCTION='#define CRYPT_FUNC sha_crypt'
fi
$CC -o $TESTP $TESTC $sha_internal $crypt_func 1> /dev/null 2> /dev/null
#
if [ ! -x $TESTP ]; then
$CC -o $TESTP $TESTC $sha_object $crypt_func 1> /dev/null 2> /dev/null
fi
#
if [ ! -x $TESTP ]; then
crypt_func='-DCRYPT_FUNC=crypt'
CRYPT_FUNCTION='#define CRYPT_FUNC crypt'
libcrypt=-lcrypt
has_sha=yes
$CC -o $TESTP $TESTC $crypt_func $libcrypt 1> /dev/null 2> /dev/null
fi
if [ ! -x $TESTP ]; then
crypt_func='-DCRYPT_FUNC=crypt'
CRYPT_FUNCTION='#define CRYPT_FUNC crypt'
libcrypt=/usr/lib/libcrypt.so
has_sha=yes
$CC -o $TESTP $TESTC $crypt_func $libcrypt 1> /dev/null 2> /dev/null
@ -878,7 +954,9 @@ if [ ! "$ft_sha" = no ]; then
if [ -x $TESTP ]; then
pwhash=`$TESTP`
case "$pwhash" in
SHA512 ) has_sha=internal512 ;;
MD5 ) has_md5=yes ;;
SHA ) has_sha=yes ;;
SHAMD5 )
has_md5=yes
has_sha=yes
@ -887,9 +965,8 @@ if [ ! "$ft_sha" = no ]; then
fi
echo $ac_t "$has_sha"
[ "$has_sha" = yes -a "$sha_internal" ] && has_sha=internal
rm -f $TESTP
rm -f $TESTP $sha_object
fi
#
# check for MD5 capabilities in libc/glibc/libcrypt
#
@ -898,13 +975,13 @@ if [ "$has_md5" = yes ]; then
elif [ "$ft_md5" = no ]; then
has_md5=notest
elif [ ! "$ft_md5" = no ]; then
TESTC=config/pw.c
echo $ac_n "checking for MD5 in crypt() ... "$ac_c
TESTC=config/pw.c
md5_internal=
crypt_func='-DCRYPT_FUNC=crypt'
CRYPT_FUNCTION='#define CRYPT_FUNC crypt'
if [ "$ft_md5" = internal ]; then
md5_internal=config/md5_internal.c
md5_internal=config/md5.c
crypt_func='-DCRYPT_FUNC=md5_crypt'
CRYPT_FUNCTION='#define CRYPT_FUNC md5_crypt'
fi
@ -1058,26 +1135,6 @@ fi
echo $ac_t "$has_ldscript"
rm -f $TESTP
#
# idwrap
#
has_idwrap=no
def_idwrap='#undef IDWRAP'
IDWRAP_PATH='/* nothing */'
if [ -r .use_idwrap -o "$ft_idwrap" = yes ]; then
echo $ac_n "checking for idwrap path ... "$ac_c
if test -z "$idwrappath"; then
idwrappath="/tmp/.ident/"
fi
if test -d $idwrappath; then
IDWRAP_PATH='"'"$idwrappath"'"'
has_idwrap="$IDWRAP_PATH"
def_idwrap='#define IDWRAP'
fi
echo $ac_t "$has_idwrap"
fi
#
#
#
@ -1107,7 +1164,11 @@ SHA_C=
SHA_O=
if [ "$ft_sha" = internal ]; then
SHA_C=lib/sha1.c
SHA_O=lib/sha.o
SHA_O=lib/sha1.o
fi
if [ "$ft_sha" = internal512 ]; then
SHA_C=lib/sha512.c
SHA_O=lib/sha512.o
fi
out=echo
@ -1306,7 +1367,7 @@ if [ "$has_sha" = no ]; then
else
test "$ft_sha" && $out "$ft_sha" && ans=$ft_sha
test -z "$ft_sha" && read ans
test -z "$ans" -o "$ans" = y -o "$ans" = Y -o "$ans" = yes -o "$ans" = YES -o "$ans" = Yes -o "$ans" = internal && def_sha='#define SHACRYPT'
test -z "$ans" -o "$ans" = y -o "$ans" = Y -o "$ans" = yes -o "$ans" = YES -o "$ans" = Yes -o "$ans" = internal -o "$ans" = internal512 && def_sha='#define SHACRYPT'
fi
def_perl='#undef PERL'
@ -1405,12 +1466,12 @@ test "$ft_uptime" && $out "$ft_uptime" && ans=$ft_uptime
test -z "$ft_uptime" && read ans
test -z "$ans" -o "$ans" = y -o "$ans" = Y -o "$ans" = yes -o "$ans" = YES -o "$ans" = Yes && def_uptime='#define UPTIME'
def_urlcapture='#undef URLCAPTURE'
def_urlcap='#undef URLCAPTURE'
unset ans
$out $ac_n "[ BETA ] URL capture support? ....................... [Y/n] "$ac_c
test "$ft_urlcapture" && $out "$ft_urlcapture" && ans=$ft_urlcapture
test -z "$ft_urlcapture" && read ans
test -z "$ans" -o "$ans" = y -o "$ans" = Y -o "$ans" = yes -o "$ans" = YES -o "$ans" = Yes && def_urlcapture='#define URLCAPTURE'
test -z "$ans" -o "$ans" = y -o "$ans" = Y -o "$ans" = yes -o "$ans" = YES -o "$ans" = Yes && def_urlcap='#define URLCAPTURE'
def_wingate='#undef WINGATE'
unset ans
@ -1422,7 +1483,7 @@ test -z "$ans" -o "$ans" = y -o "$ans" = Y -o "$ans" = yes -o "$ans" = YES -o "$
$out ''
echo "Creating src/Makefile"
O_FLAGS="$cc_optimize_flag $cc_arch_flag $cc_march_flag $cc_ofp_flag"
O_FLAGS="$cc_optimize_flag $cc_arch_flag $cc_march_flag $cc_ofp_flag $cc_omitprotect_flag"
W_FLAGS="$cc_wall_flag $cc_wshadow_flag $cc_fnostrictalias"
libflags="$libcrypt $libtcl $libnsl $libsocket $libresolv $libpython $libperl"
lflags="$cc_g_flag -o"
@ -1430,7 +1491,7 @@ cprof="$cc_pg_flag $cc_pg_define"
lprof="$cc_pg_flag $cc_pg_define $libpgdl"
if [ -z "$cf_cflags" ]; then
cf_cflags='$(PIPEFLAG) $(GDBFLAG) $(WARNFLAG) $(OPTIMIZE)'
cf_cflags='$(PIPEFLAG) $(GDBFLAG) $(FLTO_FLAG) $(WARNFLAG) $(OPTIMIZE)'
fi
echo '# This file is generated from Makefile.in' > src/Makefile
@ -1439,6 +1500,7 @@ s%@CC@%$CCshort%;
s%@ldscript@%$ldscript%;
s%@pipeflag@%$cc_pipe_flag%;
s%@gdbflag@%$cc_g_flag%;
s%@flto_flag@%$cc_flto_flag%;
/@cprof@/ { s,@cprof@,$cprof,; };
/@lprof@/ { s,@lprof@,$lprof,; };
/@lflags@/ { s,@lflags@,$lflags,; };
@ -1482,7 +1544,6 @@ sed "
s|@DEF_DYNAMODE@|$def_dynamode|;
s|@DEF_GREET@|$def_greet|;
s|@DEF_HOSTINFO@|$def_hostinfo|;
s|@DEF_IDWRAP@|$def_idwrap|;
s|@DEF_IRCD_EXT@|$def_ircd_ext|;
s|@DEF_MD5@|$def_md5|;
s|@DEF_SHA@|$def_sha|;
@ -1503,7 +1564,7 @@ s|@DEF_SUPPRESS@|$def_suppress|;
s|@DEF_TOYBOX@|$def_toybox|;
s|@DEF_TRIVIA@|$def_trivia|;
s|@DEF_UPTIME@|$def_uptime|;
s|@DEF_URLCAPTURE@|$def_urlcapture|;
s|@DEF_URLCAP@|$def_urlcap|;
s|@DEF_WEB@|$def_web|;
s|@DEF_WINGATE@|$def_wingate|;
@ -1514,14 +1575,13 @@ s|@DEF_CRYPT_FUNCTION@|$CRYPT_FUNCTION|;
s|@CRYPT_HAS_SHA@|$CRYPT_HAS_SHA|;
s|@CRYPT_HAS_MD5@|$CRYPT_HAS_MD5|;
s|@CRYPT_HAS_DES@|$CRYPT_HAS_DES|;
s|@IDWRAP_PATH@|$IDWRAP_PATH|;
s|@PTSIZE_DEFINE32@|$PTSIZE_DEFINE32|;
s|@PTSIZE_DEFINE64@|$PTSIZE_DEFINE64|;
s|@UNALIGNED_MEM@|$UNALIGNED_MEM|;
" < src/config.h.in >> src/config.h
save_myconfig() {
names="alias botnet bounce chanban ctcp dccfile debug dynamode dyncmd greet hostinfo idwrap ircd_ext libmusl md5
names="alias botnet bounce chanban ctcp dccfile debug dynamode dyncmd greet hostinfo ircd_ext libmusl md5
netcfg newbie note notify perl profiling python rawdns redirect seen session sha stats suppress tcl
telnet toybox trivia uptime urlcapture web wingate"
echo "./configure \\" > ./myconfig
@ -1539,6 +1599,7 @@ save_myconfig() {
test "$silentopt" = yes && echo "--silence=options \\" >> ./myconfig
test "$ft_md5" = internal && echo "--md5=internal \\" >> ./myconfig
test "$ft_sha" = internal && echo "--sha=internal \\" >> ./myconfig
test "$ft_sha" = internal512 && echo "--sha=internal512 \\" >> ./myconfig
test "$optitype" = speed && echo "--optimize=speed \\" >> ./myconfig
test "$optitype" = size && echo "--optimize=size \\" >> ./myconfig
test "$cc_ofp_opt" = yes && echo "--use-ofp \\" >> ./myconfig

View File

@ -18,4 +18,6 @@ Aliases may call other aliases and aliases can be used
to replace built in commands. Aliases can recurse a
maximum of 20 times (prevents infinite loops).
If no argument is given, all current aliases will be listed.
See also: unalias

4
help/BOOT Normal file
View File

@ -0,0 +1,4 @@
Boot a user from the partyline.
See also: core, whom

10
help/DEBUG Normal file
View File

@ -0,0 +1,10 @@
On <debugfile> - Turn On debug and write output to <debugfile>
Off - Turn Off debug
If no arguments are given, debug data will be written
to a file named "debug.<timestamp>".
Only available if compiled with debug support.
See also: crash

View File

@ -4,4 +4,4 @@ SHUTDOWN command instead to preserve the configurations
for all bots. If DIE is used, the killed bot(s) will
not be saved to the session file.
See also: reset, shutdown
See also: nick, reset, shutdown

View File

@ -1,4 +1,12 @@
Usage: NICK <nick>
Changes the nick of the bot. If the nick given is already
in use, the bot will not change its nickname until the
occupied nick is available.
Changes the nick of the bot. If the nick given is already
in use, the bot will not change its nickname until the
occupied nick is available.
If a guid is given, the nick of the bot with the given guid
will be changed.
If no bot with the given guid exists, a new bot will be
created with the given guid.
See also: die

4
help/NOTE Normal file
View File

@ -0,0 +1,4 @@
Record a note for another user.
See also: read

View File

@ -1,3 +1,4 @@
Usage: ONTIME
Shows time connected to current server.
See also: UPTIME
Shows time connected to current server.
See also: time, uptime

4
help/READ Normal file
View File

@ -0,0 +1,4 @@
Read a note left by another user.
See also: note

View File

@ -1,3 +1,4 @@
Usage: RSHIT <channel> <nick|userhost>
Removes someone from the shitlist
See also: SHIT, SHITLIST
Removes someone from the shitlist
See also: shit, qshit, shitlist, clearshit

View File

@ -1,3 +1,4 @@
Usage: TOG [channel] SO [0|1|on|off]
Toggles strict opping. If on, if people not in the userlist
are opped, they will be deopped.
Toggles strict opping. If on, if people not in the userlist
are opped, they will be deopped.

View File

@ -1,12 +1,16 @@
Shitlists someone on all channels (*) or a certain channel
Level - can be 1 through 3
Level - can be 1 through 4
1 - doesn't let the person be opped or voiced
2 - will kb the person
3 - rebans the person when unbanned by anyone
4 - add a channel ban (see CHANBAN), requires chanban support
Expire - the number of days the entry will be good for (default is 30)
Reason - reason for the shitlist...displays it on kickban
Note: The bot checks for shitlisted users on join, nick switch, and
when the bot is opped
See also: rshit, qshit, shitlist
See also: rshit, qshit, shitlist, clearshit

View File

@ -1,3 +1,4 @@
Usage: SHITLIST
Shows the bots shitlist.
See also: SHIT, RSHIT, QSHIT, SHITLVL
Shows the bots shitlist.
See also: shit, rshit, qshit, shitlvl

View File

@ -2,13 +2,15 @@
Spy on a certain source of messages. When you join DCC chat,
the STATUS source is added by default as a spy source for you.
If no arguments are given, the current list of active spy
channels is shown. Output is not line buffered and can cause
excess flood if not careful.
channels is shown.
(sources)
STATUS Status messages.
MESSAGE Pivate messages that the bot receives.
RAWIRC Lines received from irc server before processing.
RANDSRC Collect randomness from IRC activity, best saved to a file.
SYSMON Hostinfo events.
URL Captured URLs.
guid: Messages from a bot specified by guid.
botnick: Messages from a bot specified by nick.
channel Activities on the specified channel.

View File

@ -1,3 +1,4 @@
Usage: TIME
Show current time (where the bot is)
See also: UPTIME, ONTIME
Show current time (where the bot is)
See also: ontime, uptime

View File

@ -1,3 +1,4 @@
Usage: UPTIME
Shows how long the bot has been running.
See also: ONTIME
Shows how long the bot has been running.
See also: core, ontime, time

View File

@ -1,2 +1,4 @@
Usage: VER
Returns the version of EnergyMech that is running
Returns the version of EnergyMech that is running
See also: core, features

View File

@ -1,7 +1,8 @@
Usage: WHO <channel> [-ops|-nonops] [pattern]
Lists people in a channel that the bot is in now,
or was in. The optional parameters can be used to
list only ops or only non ops respectively.
If a pattern is given, only users matching the pattern
will be listed.
See also: NAMES
Lists people in a channel that the bot is in now,
or was in. The optional parameters can be used to
list only ops or only non ops respectively.
If a pattern is given, only users matching the pattern
will be listed.
See also: names

View File

@ -1,2 +1,4 @@
Usage: WHOM
Show who are connected to the partyline.
Show who are connected to the partyline.
See also: core, boot

View File

@ -9,35 +9,40 @@ set ctimeout 60
; We don't currently support SSL or ipv6 but there's an easy workaround
; see socat.sh
servergroup undernet
server amsterdam.nl.eu.undernet.org 6663
server amsterdam2.nl.eu.undernet.org 6663
server bucharest.ro.eu.undernet.org 6663
server carouge.ch.eu.undernet.org 6663
server ede.nl.eu.undernet.org 6669
server elsene.be.eu.undernet.org 6669
server fulda.de.eu.undernet.org 6663
server geneva.ch.eu.undernet.org 6663
server graz.at.eu.undernet.org 6663
server graz2.at.eu.undernet.org 6663
server helsinki.fi.eu.undernet.org 6669
server lelystad.nl.eu.undernet.org 6668
server london.uk.eu.undernet.org 6666
server london2.uk.eu.undernet.org 6663
server milan.it.eu.undernet.org 6663
server oslo1.no.eu.undernet.org 6663
server oslo2.no.eu.undernet.org 6663
server stockholm.se.eu.undernet.org 6669
server surrey.uk.eu.undernet.org 6669
server zagreb.hr.eu.undernet.org 6666
server panamacity.pa.undernet.org 6663
server ashburn.va.us.undernet.org 6663
server fairfax.va.us.undernet.org 6666
server mesa.az.us.undernet.org 6666
server miami.fl.us.undernet.org 6669
server princeton.nj.us.undernet.org 6663
server sanjose.ca.us.undernet.org 6663
server sterling.va.us.undernet.org 6669
; Use only undernet servers
set servergroup undernet
; Our list of servers
; server <host> [port] [@group] ["password"]
;
server amsterdam.nl.eu.undernet.org 6663 @undernet
server amsterdam2.nl.eu.undernet.org 6663 @undernet
server bucharest.ro.eu.undernet.org 6663 @undernet
server carouge.ch.eu.undernet.org 6663 @undernet
server ede.nl.eu.undernet.org 6669 @undernet
server elsene.be.eu.undernet.org 6669 @undernet
server fulda.de.eu.undernet.org 6663 @undernet
server geneva.ch.eu.undernet.org 6663 @undernet
server graz.at.eu.undernet.org 6663 @undernet
server graz2.at.eu.undernet.org 6663 @undernet
server helsinki.fi.eu.undernet.org 6669 @undernet
server lelystad.nl.eu.undernet.org 6668 @undernet
server london.uk.eu.undernet.org 6666 @undernet
server london2.uk.eu.undernet.org 6663 @undernet
server milan.it.eu.undernet.org 6663 @undernet
server oslo1.no.eu.undernet.org 6663 @undernet
server oslo2.no.eu.undernet.org 6663 @undernet
server stockholm.se.eu.undernet.org 6669 @undernet
server surrey.uk.eu.undernet.org 6669 @undernet
server zagreb.hr.eu.undernet.org 6666 @undernet
server panamacity.pa.undernet.org 6663 @undernet
server ashburn.va.us.undernet.org 6663 @undernet
server fairfax.va.us.undernet.org 6666 @undernet
server mesa.az.us.undernet.org 6666 @undernet
server miami.fl.us.undernet.org 6669 @undernet
server princeton.nj.us.undernet.org 6663 @undernet
server sanjose.ca.us.undernet.org 6663 @undernet
server sterling.va.us.undernet.org 6669 @undernet
;
; this is sorta how a botnet configuration would look like...

View File

@ -1,5 +1,5 @@
#!/bin/bash
# Simple wrapper that alows energymech to connect to SSL and/or ipv6 servers
# Simple wrapper that allows energymech to connect to SSL and/or ipv6 servers
# Run it before running energymech
# Listen port. In the energymech config put 'server localhost 6003'

View File

@ -1,6 +1,6 @@
#
# EnergyMech, IRC bot software
# Copyright (c) 1997-2021 proton
# Copyright (c) 1997-2025 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
@ -27,6 +27,7 @@ LPROF = @lprof@
LIBS = @libflags@
PIPEFLAG = @pipeflag@
GDBFLAG = @gdbflag@
FLTO_FLAG = @flto_flag@
WARNFLAG = @W_FLAGS@
OPTIMIZE = @O_FLAGS@
PYINCLUDE = @PYINCLUDE@
@ -35,7 +36,7 @@ I_PERL = @I_PERL@
L_PERL = @L_PERL@
CFLAGS = @CFLAGS@
LFLAGS = $(PIPEFLAG) $(GDBFLAG)
LFLAGS = $(PIPEFLAG) $(GDBFLAG) $(FLTO_FLAG)
CC = @CC@
MV = mv -f
@ -49,13 +50,13 @@ TESTFILES = aliastest calctest safepathtest
OFILES = alias.o auth.o bounce.o calc.o channel.o core.o ctcp.o debug.o dns.o function.o greet.o \
help.o hostinfo.o io.o irc.o main.o net.o note.o ons.o parse.o partyline.o \
perl.o prot.o python.o reset.o seen.o shit.o spy.o tcl.o toybox.o \
uptime.o user.o vars.o web.o lib/string.o @MD5_O@ @SHA_O@
perl.o prot.o python.o reset.o seen.o shit.o spy.o string.o tcl.o toybox.o \
uptime.o user.o vars.o web.o @MD5_O@ @SHA_O@
SRCFILES = alias.c auth.c bounce.c calc.c channel.c core.c ctcp.c debug.c dns.c function.c greet.c \
help.c hostinfo.c io.c irc.c main.c net.c note.c ons.c parse.c partyline.c \
perl.c prot.c python.c reset.c seen.c shit.c spy.c tcl.c toybox.c \
uptime.c user.c vars.c web.c lib/string.c @MD5_C@ @SHA_C@
perl.c prot.c python.c reset.c seen.c shit.c spy.c string.c tcl.c toybox.c \
uptime.c user.c vars.c web.c @MD5_C@ @SHA_C@
.PHONY: all clean mega-install mega mega-static test commands
@ -66,7 +67,7 @@ all: $(INSTALLNAME)
# instead of doing extra parsing and handling while the bot is running.
#
gencmd: gencmd.c io.c config.h structs.h
gencmd: gencmd.c io.c config.h structs.h onhash.h commands.h
$(CC) $(LFLAGS) -o gencmd gencmd.c
mcmd.h: gencmd
@ -104,12 +105,12 @@ $(INSTALLNAME)-static: $(OFILES)
# resulting in a smaller, more efficient, binary. this process uses lots more memory at compile time.
#
mega-install: mega $(SRCFILES) $(INCS) usage.h
mega-install mi:mega $(SRCFILES) $(INCS) usage.h
$(CHMOD) $(INSTALLMODE) $(INSTALLNAME)
$(MV) $(INSTALLNAME) $(INSTALLDIR)
mega: $(SRCFILES) $(INCS) usage.h
$(CROSS_COMPILE)$(CC) $(CFLAGS) -o $(INSTALLNAME) main.c -DMEGA_C -DGENDATE="`./gencmd date`" -I. $(LPROF) $(LIBS) $(LDSCRIPT) $(PYINCLUDE) $(TCLINCLUDE) $(I_PERL) $(L_PERL)
mega: $(SRCFILES) $(INCS) usage.h @SHA_O@
$(CROSS_COMPILE)$(CC) $(CFLAGS) -o $(INSTALLNAME) main.c -DMEGA_C -DGENDATE="`./gencmd date`" -I. @SHA_O@ $(LPROF) $(LIBS) $(LDSCRIPT) $(PYINCLUDE) $(TCLINCLUDE) $(I_PERL) $(L_PERL)
#@oc@ $(CROSS_COMPILE)objcopy -R .note -R .comment $(INSTALLNAME)
@sz@ size $(INSTALLNAME)
@ -127,14 +128,14 @@ test: $(TESTFILES)
./calctest
./safepathtest
aliastest: alias.c githash.h lib/string.o
$(CROSS_COMPILE)$(CC) $(CFLAGS) -o aliastest $< lib/string.o $(LPROF) $(LIBS) -DTEST
aliastest: alias.c githash.h mcmd.h string.o function.o
$(CROSS_COMPILE)$(CC) $(CFLAGS) -o aliastest $< string.o function.o $(LPROF) $(LIBS) -DTEST
calctest: calc.c githash.h mcmd.h lib/string.o
$(CROSS_COMPILE)$(CC) $(CFLAGS) -o calctest $< lib/string.o $(LPROF) $(LIBS) -DTEST
calctest: calc.c githash.h mcmd.h string.o
$(CROSS_COMPILE)$(CC) $(CFLAGS) -o calctest $< string.o $(LPROF) $(LIBS) -DTEST
safepathtest: function.c githash.h lib/string.o
$(CROSS_COMPILE)$(CC) $(CFLAGS) -o safepathtest $< lib/string.o $(LPROF) $(LIBS) -DTEST
safepathtest: function.c githash.h string.o
$(CROSS_COMPILE)$(CC) $(CFLAGS) -o safepathtest $< string.o $(LPROF) $(LIBS) -DTEST
commands:
grep -E '(void do_.*\(COMMAND_ARGS\)|/*---Help:)' *c
@ -149,8 +150,8 @@ lib/md5.o: lib/md5.c $(INCS)
lib/sha1.o: lib/sha1.c $(INCS)
$(CROSS_COMPILE)$(CC) $(CFLAGS) -c $< -o $@ -Ilib $(CPROF)
lib/string.o: lib/string.c $(BASEINCLUDES)
$(CROSS_COMPILE)$(CC) $(CFLAGS) -c $< -o $@ -I. $(CPROF)
lib/sha512.o: lib/sha512.c $(INCS)
$(CROSS_COMPILE)$(CC) $(CFLAGS) -c $< -o $@ -Ilib $(CPROF)
alias.o: alias.c $(INCS)
$(CROSS_COMPILE)$(CC) $(CFLAGS) -c $< $(CPROF)
@ -206,7 +207,7 @@ net.o: net.c $(INCS)
note.o: note.c $(INCS)
$(CROSS_COMPILE)$(CC) $(CFLAGS) -c $< $(CPROF)
ons.o: ons.c $(INCS)
ons.o: ons.c $(INCS) onhash.h
$(CROSS_COMPILE)$(CC) $(CFLAGS) -c $< $(CPROF)
parse.o: parse.c $(INCS)
@ -236,6 +237,9 @@ shit.o: shit.c $(INCS)
spy.o: spy.c $(INCS)
$(CROSS_COMPILE)$(CC) $(CFLAGS) -c $< $(CPROF)
string.o: string.c $(BASEINCLUDES)
$(CROSS_COMPILE)$(CC) $(CFLAGS) -c $< $(CPROF)
tcl.o: tcl.c $(INCS)
$(CROSS_COMPILE)$(CC) $(CFLAGS) -c $< $(CPROF) $(TCLINCLUDE)

View File

@ -1,7 +1,7 @@
/*
EnergyMech, IRC bot software
Copyright (c) 1997-2020 proton
Copyright (c) 1997-2025 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
@ -32,22 +32,20 @@
#include "mcmd.h"
#ifdef TEST
#include "debug.c"
char result[MSGLEN];
char *input = "alias one two three four five six seven eight nine ten";
char result[MSGLEN];
char *alias_test_input = "alias one two three four five -6- seven eight nine ten";
void *Calloc(int size)
{
return(calloc(1,size));
}
void run_debug(void) {}
void testcase(const char *test, const char *expect)
{
afmt(result,test,input);
if (strcmp(result,expect) == 0) debug("testcase SUCCESS: test \"%s\" -> got \"%s\"\n",test,expect);
else debug("testcase FAIL: test \"%s\", expected \"%s\", got \"%s\"\n",test,expect,result);
afmt(result,test,alias_test_input);
if (strcmp(result,expect) == 0)
debug("testcase SUCCESS: test \"%s\" -> got \"%s\"\n",test,expect);
else
debug("testcase FAIL: test \"%s\", expected \"%s\", got \"%s\"\n",test,expect,result);
}
int main(int argc, char **argv, char **envp)
@ -72,14 +70,16 @@ int main(int argc, char **argv, char **envp)
testcase("cmd $2 $1","cmd two one");
testcase("cmd $8-","cmd eight nine ten");
testcase("cmd $4-5","cmd four five");
testcase("cmd $5-6","cmd five six");
testcase("cmd $5-6","cmd five -6-");
testcase("cmd $5-7","cmd five -6- seven");
testcase("cmd $~","cmd noob");
testcase("cmd $~1234567890","cmd noob1234567890");
testcase("cmd $one $two","cmd $one $two");
exit(0);
}
debug("input = %s\n",input);
debug("input = %s\n",alias_test_input);
debug("format = %s\n",format);
afmt(result,format,input);
afmt(result,format,alias_test_input);
debug("result = %s\n",result);
exit(0);
}
@ -90,46 +90,37 @@ int main(int argc, char **argv, char **envp)
* copy_to = buffer to put resulting new command into
* src = Alias format string
* input = input from user
* size: 0x159
* size: 0x163
*/
void afmt(char *copy_to, const char *src, const char *input)
{
#define BUFTAIL (copy_to+MSGLEN-1) /* avoid buffer overflows */
const char *argstart,*argend;
char *dest;
int startnum,endnum,spc;
#define OUTPUTEND (output+MSGLEN-1) /* avoid buffer overflows */
#define startnum n[0]
#define endnum n[1]
void afmt(char *output, const char *src, const char *input)
{
const char *argstart,*argend;
int spc,n[3];
dest = copy_to;
while(*src)
{
if (src[0] == '$' && src[1] == '$')
if (*src == '$' && src[1] == '$')
src++;
else
if (*src == '$' && src[1] == '~')
{
src += 2;
argstart = CurrentNick;
while(*argstart && dest <= BUFTAIL)
*(dest++) = *(argstart++);
while(*argstart && output <= OUTPUTEND)
*(output++) = *(argstart++);
}
else
if (*src == '$' && (attrtab[(uchar)src[1]] & NUM) == NUM)
if (*src == '$' && (src[1] >= '0' && src[1] <= '9'))
{
src++;
startnum = endnum = 0;
while(attrtab[(uchar)*src] & NUM)
startnum = (startnum * 10) + (*(src++) - '0');
if (*src == ' ' || *src == 0)
endnum = startnum;
else
if (*src == '-')
{
src++;
if ((attrtab[(uchar)*src] & NUM) != NUM)
endnum = 9999;
else
while(attrtab[(uchar)*src] & NUM)
endnum = (endnum * 10) + (*src++ - '0');
}
parse_range((char**)&src,n);
if (n[2] && n[1] == -1)
endnum = 9999;
argstart = input;
if (startnum)
@ -154,25 +145,15 @@ void afmt(char *copy_to, const char *src, const char *input)
argend++;
}
}
#ifdef DEBUG
#ifndef TEST
debug("(afmt) args #%i-#%i, characters %i-%i\n",startnum,endnum,argstart-input,argend-input);
#endif /* ifndef TEST */
#endif /* DEBUG */
while(*argstart && argstart < argend && dest <= BUFTAIL)
*(dest++) = *(argstart++);
while(*argstart && argstart < argend && output <= OUTPUTEND)
*(output++) = *(argstart++);
continue;
}
if (dest >= BUFTAIL)
if (output >= OUTPUTEND)
break;
*(dest++) = *(src++);
*(output++) = *(src++);
}
*dest = 0;
#ifdef DEBUG
#ifndef TEST
debug("(afmt) start %i end %i spc %i\n",startnum,endnum,spc);
#endif /* ifndef TEST */
#endif /* DEBUG */
*output = 0;
}
#ifndef TEST
@ -270,13 +251,14 @@ void do_alias(COMMAND_ARGS)
set_mallocdoer(do_alias);
alias = (Alias*)Calloc(sizeof(Alias)+strlen(cmd));
stringcpy(alias->alias,cmd);
alias->hash = mkhash(cmd);
set_mallocdoer(do_alias);
alias->format = stringdup(rest);
alias->next = aliaslist;
aliaslist = alias;
to_user(from,"Added alias: %s --> %s",cmd,rest);
#ifdef DEBUG
debug("(do_alias) Added alias: %s --> %s\n",cmd,rest);
debug("(do_alias) Added alias: %s [#%i] --> %s\n",cmd,alias->hash,rest);
#endif
}

View File

@ -63,7 +63,7 @@ char *cipher(char *arg)
static char res[40];
uint32_t B1a,B2a,B3a,B4a;
uint32_t B1b,B2b,B3b,B4b;
uchar *ptr;
unsigned char *ptr;
uint32_t R1;
int i;
@ -72,7 +72,7 @@ char *cipher(char *arg)
B1a = B2a = B3a = B4a = 0;
B1b = B2b = B3b = B4b = 0;
ptr = arg;
ptr = (unsigned char *)arg;
while(*ptr)
{
@ -259,7 +259,7 @@ void change_authnick(char *nuh, char *newnuh)
set_mallocdoer(change_authnick);
auth = (Auth*)Calloc(sizeof(Auth) + strlen(newnuh));
auth->user = oldauth->user;
auth->active = now;
auth->active = cx.now;
auth->next = current->authlist;
current->authlist = auth;
stringcpy(auth->nuh,newnuh);
@ -271,10 +271,10 @@ void change_authnick(char *nuh, char *newnuh)
}
}
LS User *au_user;
LS const char *au_userhost;
LS const char *au_channel;
LS int au_access;
User *au_user;
const char *au_userhost;
const char *au_channel;
int au_access;
void aucheck(User *user)
{
@ -282,6 +282,7 @@ void aucheck(User *user)
if (au_channel)
{
/* does the user record have channel access? */
for(ump=user->chan;ump;ump=ump->next)
{
if (*ump->p == '*' || !stringcasecmp(au_channel,ump->p))
@ -348,7 +349,7 @@ int get_authaccess(const char *userhost, const char *channel)
User *user;
Strp *ump;
if (userhost == CoreUser.name)
if (userhost == cx.CoreUser.name)
return(100);
if (CurrentDCC && CurrentDCC->user->name == userhost)
{
@ -390,7 +391,7 @@ int make_auth(const char *userhost, const User *user)
set_mallocdoer(make_auth);
auth = (Auth*)Calloc(sizeof(Auth) + strlen(userhost));
auth->user = (User*)user;
auth->active = now;
auth->active = cx.now;
stringcpy(auth->nuh,userhost);
auth->next = current->authlist;
@ -418,6 +419,25 @@ int make_auth(const char *userhost, const User *user)
*
*/
void do_auth_noargs(const char *from)
{
Auth *au;
if (get_authaccess(from,MATCH_ALL) < 100)
return;
/* no args + owner: List active auths */
table_buffer("\037Active Auths\037");
if (current->authlist == NULL)
table_buffer("(none)");
for(au=current->authlist;au;au=au->next)
{
table_buffer("%s\t%i\t%s\t%s",au->user->name,au->user->x.x.access,au->nuh,
idle2str(au->active,TRUE));
}
table_send(from,3);
}
/*
help:AUTH
help:VERIFY
@ -434,7 +454,6 @@ See also: passwd, setpass
*/
void do_auth(COMMAND_ARGS)
{
Auth *au;
#ifdef BOTNET
char *checksum;
#endif /* BOTNET */
@ -443,22 +462,7 @@ void do_auth(COMMAND_ARGS)
char *pass;
int hostmatch;
if ((pass = chop(&rest)) == NULL)
{
if (get_authaccess(from,MATCH_ALL) == 100)
{
/* empty pass + owner: List active auths */
table_buffer("\037Active Auths\037");
if (current->authlist == NULL)
table_buffer("(none)");
for(au=current->authlist;au;au=au->next)
{
table_buffer("%s\t%i\t%s\t%s",au->user->name,au->user->x.x.access,au->nuh,idle2str(now - au->active,TRUE));
}
table_send(from,3);
}
return;
}
pass = chop(&rest);
/*
* chop chop

View File

@ -45,16 +45,8 @@
#define BNC_ACTIVE 5
#define BNC_DEAD 6
#ifdef IDWRAP
#define USE_VHOST 2
#else /* not IDWRAP */
#define USE_VHOST TRUE
#endif /* IDWRAP */
void bounce_parse(ircLink *irc, char *message)
{
Mech fakebot;
@ -90,7 +82,7 @@ void bounce_parse(ircLink *irc, char *message)
if (irc->userLine && irc->nickLine)
{
to_file(irc->usersock,TEXT_ASK_HANDLE,irc->nick);
irc->active = now;
irc->active = cx.now;
++irc->status;
}
return;
@ -143,7 +135,7 @@ void bounce_parse(ircLink *irc, char *message)
{
to_file(irc->usersock,TEXT_ASK_SERVER,irc->nick);
irc->status = BNC_ASK_SERVER;
irc->active = now;
irc->active = cx.now;
return;
}
}
@ -175,10 +167,6 @@ void bounce_parse(ircLink *irc, char *message)
#ifdef WINGATE
current->setting[STR_WINGATE].str_var = NULL;
#endif /* WINGATE */
#ifdef IDWRAP
current->identfile = NULL;
current->setting[STR_IDENT].str_var = irc->handle;
#endif /* IDWRAP */
if (virtual)
{
@ -188,30 +176,15 @@ void bounce_parse(ircLink *irc, char *message)
if ((irc->servsock = SockConnect(server,iport,USE_VHOST)) >= 0)
{
irc->status = BNC_CONNECTING;
irc->active = now + 60; /* 120 second timeout */
#ifdef IDWRAP
irc->idfile = current->identfile;
#endif /* IDWRAP */
irc->active = cx.now + 60; /* 120 second timeout */
}
}
}
#ifdef IDWRAP
void bounce_cleanup(void)
{
ircLink *irc;
for(irc=bnclist;irc;irc=irc->next)
{
if (irc->idfile)
unlink(irc->idfile);
}
}
#endif /* IDWRAP */
void new_port_bounce(const struct Setting *no_op)
/*
* any time setting is changed
*/
void new_port_bounce(const struct Setting *dontcare)
{
if (bounce_sock != -1)
close(bounce_sock);
@ -276,7 +249,7 @@ void process_bounce(void)
irc = (ircLink*)Calloc(sizeof(ircLink)); /* sets all to zero */
irc->next = bnclist;
bnclist = irc;
irc->active = now;
irc->active = cx.now;
irc->usersock = s;
--irc->servsock; /* == -1 */
}
@ -324,7 +297,7 @@ void process_bounce(void)
debug("(process_bounce) {%i} servsock connected\n",irc->servsock);
#endif /* DEBUG */
irc->status = BNC_ACTIVE;
irc->active = now;
irc->active = cx.now;
to_file(irc->servsock,"USER %s\n",irc->userLine);
if (to_file(irc->servsock,"NICK %s\n",irc->nickLine) < 0)
{
@ -341,7 +314,7 @@ void process_bounce(void)
*/
if (FD_ISSET(irc->servsock,&read_fds))
{
irc->active = now;
irc->active = cx.now;
while((p = sockread(irc->servsock,irc->servmem,message)))
{
if (to_file(irc->usersock,FMT_PLAINLINE,message) < 0)
@ -365,7 +338,7 @@ void process_bounce(void)
pp = &bnclist;
while((irc = *pp))
{
if (irc->status == BNC_DEAD || ((irc->status != BNC_ACTIVE) && ((now - irc->active) > 60)))
if (irc->status == BNC_DEAD || ((irc->status != BNC_ACTIVE) && ((cx.now - irc->active) > 60)))
{
#ifdef DEBUG
debug("(process_bounce) {%i} {%i} BNC_DEAD or timeout, removing...\n",irc->usersock,irc->servsock);
@ -379,13 +352,6 @@ void process_bounce(void)
Free((char**)&irc->nickLine);
Free((char**)&irc->nick);
Free((char**)&irc->handle);
#ifdef IDWRAP
if (irc->idfile)
{
unlink(irc->idfile);
Free((char**)&irc->idfile);
}
#endif /* IDWRAP */
Free((char**)&irc);
continue;
}

View File

@ -128,7 +128,6 @@ new_blank:
op = 0;
para = 0;
op_or_num:
if (*input == '+')
{
op = OPER_ADD;
@ -204,9 +203,11 @@ iterate:
para = -1;
for(i=0;i<=cop_count;i++)
{
#ifdef TEST
if (cop[i].paralevel >= 0)
printf("number %lu, operation %i, decimals %i, paralevel %i\n",
cop[i].number,cop[i].operation,cop[i].decimals,cop[i].paralevel);
#endif /* TEST */
if (cop[i].paralevel >= para)
para = cop[i].paralevel;
}
@ -281,7 +282,7 @@ int bas2int(const char *src, int base)
char ch;
errno = EINVAL;
n = 0;
v = n = 0;
while(*src)
{
@ -291,22 +292,20 @@ int bas2int(const char *src, int base)
switch(base)
{
case 16:
ch = tolowertab[(uchar)*src];
if (*src <= '9')
v = *src - '0';
else
if (ch >= 'a' && ch <= 'f')
v = ch - 'a' + 10;
else
return(-1);
{
ch = tolowertab[(uchar)*src];
if (ch >= 'a' && ch <= 'f')
v = ch - 'a' + 10;
else
return(-1);
}
break;
case 8:
if (*src >= '8')
return(-1);
v = *src - '0';
break;
case 2:
if (*src >= '2')
if(*src >= ('0'+base))
return(-1);
v = *src - '0';
}
@ -329,7 +328,6 @@ void do_calc(COMMAND_ARGS)
{
char prep[MSGLEN];
CalcOp cop[MAX_COP];
int cp = 0;
memset(&cop,0,sizeof(cop));
@ -345,22 +343,22 @@ void do_calc(COMMAND_ARGS)
void do_convert(COMMAND_ARGS)
{
char output[200];
char *ops, *srcnum, *dst;
char *srcnum, *dst;
char inval, outval;
int num, todec, tochr, tooct, tohex, tobin;
ops = chop(&rest);
srcnum = chop(&rest);
if (ops == NULL || srcnum == NULL)
if (cx.rest_end < rest+2)
return;
todec = tochr = tooct = tohex = tobin = 0;
inval = rest[0];
outval = rest[1];
rest += 2;
srcnum = chop(&rest);
switch(ops[1])
todec = tochr = tooct = tohex = tobin = (outval == ' ' || outval == 0) ? 0 : 1;
switch(outval)
{
case 0:
todec = tochr = tooct = tohex = tobin = 1;
break;
case 'b':
tobin = 1;
break;
@ -375,19 +373,12 @@ void do_convert(COMMAND_ARGS)
break;
}
num = 0;
errno = EINVAL;
switch(*ops)
switch(inval)
{
case 'b':
errno = 0;
for(num=0;*srcnum;)
{
num = num << 1;
if (*srcnum != '0' && *srcnum != '1')
return;
num += *srcnum - '0';
srcnum++;
}
num = bas2int(srcnum,2);
break;
case 'c':
num = srcnum[0];
@ -396,8 +387,7 @@ void do_convert(COMMAND_ARGS)
errno = tochr = 0;
break;
case 'd':
num = asc2int(srcnum);
/*todec = 0;*/
num = asc2int(srcnum); /* sets errno */
break;
case 'h':
if (*srcnum == '$')
@ -405,11 +395,9 @@ void do_convert(COMMAND_ARGS)
if (*srcnum == '0' && srcnum[1] == 'x')
srcnum += 2;
num = bas2int(srcnum,16);
/*tohex = 1;*/
break;
case 'o':
num = bas2int(srcnum,8);
/* tooct = 0;*/
break;
}
if (errno)

View File

@ -40,13 +40,15 @@ void check_idlekick(void)
for(chan=current->chanlist;chan;chan=chan->next)
{
if (!chan->bot_is_op)
continue;
limit = chan->setting[INT_IKT].int_var;
timeout = (now - (60 * limit));
if (limit == 0)
continue;
timeout = (cx.now - (60 * limit));
for(cu=chan->users;cu;cu=cu->next)
{
cu->flags &= ~CU_KSWARN; /* remove KS warnings */
if (!chan->bot_is_op || limit == 0)
continue;
if (cu->flags & CU_CHANOP)
continue;
if (timeout < cu->idletime)
@ -207,9 +209,9 @@ int reverse_mode(char *from, Chan *chan, int m, int s)
mode = (char)m;
sign = (char)s;
if (STRCHR(ptr,mode) && (sign == '+'))
if (stringchr(ptr,mode) && (sign == '+'))
return(FALSE);
if (!STRCHR(ptr,mode) && (sign == '-'))
if (!stringchr(ptr,mode) && (sign == '-'))
return(FALSE);
if (get_useraccess(from,chan->name) >= ASSTLEVEL)
{
@ -268,6 +270,12 @@ void chan_modestr(Chan *chan, char *dest)
}
}
char *get_nuh(const ChanUser *user)
{
sprintf(nuh_buf,"%s!%s",user->nick,user->userhost);
return(nuh_buf);
}
char *find_nuh(char *nick)
{
Chan *chan;
@ -281,6 +289,36 @@ char *find_nuh(char *nick)
return(NULL);
}
/*
* NOTE! beware of conflicts in the use of nuh_buf, its also used by find_nuh()
*/
char *nick2uh(char *from, char *userhost)
{
if (stringchr(userhost,'!') && stringchr(userhost,'@'))
{
stringcpy(nuh_buf,userhost);
}
else
if (!stringchr(userhost,'!') && !stringchr(userhost,'@'))
{
/* find_nuh() stores nickuserhost in nuh_buf */
if (find_nuh(userhost) == NULL)
{
if (from)
to_user(from,"No information found for %s",userhost);
return(NULL);
}
}
else
{
stringcpy(nuh_buf,"*!");
if (!stringchr(userhost,'@'))
stringcat(nuh_buf,"*@");
stringcat(nuh_buf,userhost);
}
return(nuh_buf);
}
Ban *make_ban(Ban **banlist, char *from, char *banmask, time_t when)
{
Ban *new;
@ -359,7 +397,7 @@ void channel_massmode(const Chan *chan, char *pattern, int filtmode, char mode,
if ((pat = chop(&pattern)) == NULL)
return;
ispat = (STRCHR(pat,'*')) ? TRUE : FALSE;
ispat = (stringchr(pat,'*')) ? TRUE : FALSE;
maxmode = current->setting[INT_MODES].int_var;
mal = chan->setting[INT_MAL].int_var;
*burst = 0;
@ -376,7 +414,7 @@ void channel_massmode(const Chan *chan, char *pattern, int filtmode, char mode,
s = deopstring;
while(*s) s++;
debug("(...) deopstring "mx_pfmt" uh "mx_pfmt" ("mx_pfmt")\n",(mx_ptr)deopstring,(mx_ptr)uh,(mx_ptr)s);
s = STRCHR(deopstring,0);
s = stringchr(deopstring,0);
debug("(...) deopstring "mx_pfmt" uh "mx_pfmt" ("mx_pfmt")\n",(mx_ptr)deopstring,(mx_ptr)uh,(mx_ptr)s);
}
#endif /* DEBUG */
@ -427,7 +465,7 @@ void channel_massmode(const Chan *chan, char *pattern, int filtmode, char mode,
/*
* never deop yourself, stupid bot
*/
if (nickcmp(pat,current->nick))
if (nickcmp(pat,getbotnick(current)))
willdo = TRUE;
}
else
@ -453,7 +491,7 @@ void channel_massmode(const Chan *chan, char *pattern, int filtmode, char mode,
cu = cu->next;
if (!cu && (pat = chop(&pattern)))
{
ispat = (STRCHR(pat,'*')) ? TRUE : FALSE;
ispat = (stringchr(pat,'*')) ? TRUE : FALSE;
cu = chan->users;
}
}
@ -499,7 +537,7 @@ void channel_massunban(Chan *chan, char *pattern, time_t seconds)
{
if (!matches(pattern,ban->banstring) || !matches(ban->banstring,pattern))
{
if (!seconds || ((now - ban->time) > seconds))
if (!seconds || ((cx.now - ban->time) > seconds))
{
if (chan->setting[TOG_SHIT].int_var)
{
@ -643,7 +681,7 @@ void make_chanuser(char *nick, char *userhost)
new = (ChanUser*)Calloc(sizeof(ChanUser) + strlen(userhost));
/* Calloc sets it all to zero */
new->idletime = now;
new->idletime = cx.now;
new->next = CurrentChan->users;
CurrentChan->users = new;
stringcpy(new->userhost,userhost);
@ -661,12 +699,6 @@ void purge_chanusers(Chan *chan)
remove_chanuser(chan,chan->users->nick);
}
char *get_nuh(const ChanUser *user)
{
sprintf(nuh_buf,"%s!%s",user->nick,user->userhost);
return(nuh_buf);
}
/*
*
* commands associated with channels
@ -890,9 +922,10 @@ void do_mode(COMMAND_ARGS)
}
else
{
/* todo: is it really necessary to chop? */
target = chop(&rest);
if (!nickcmp(current->nick,target))
if (!nickcmp(target,getbotnick(current)))
{
to_server("MODE %s %s\n",target,rest);
}
@ -972,7 +1005,7 @@ void do_cchan(COMMAND_ARGS)
to_user(from,ERR_CHAN,channel);
return;
}
to_user(from,"Current channel: %s",
to_user_q(from,"Current channel: %s",
(current->activechan) ? current->activechan->name : TEXT_NONE);
}
@ -1185,9 +1218,9 @@ void do_showidle(COMMAND_ARGS)
table_buffer(str_underline("Users on %s that are idle more than %i seconds"),chan->name,n);
for(cu=chan->users;cu;cu=cu->next)
{
if (n >= (now - cu->idletime))
if (n >= (cx.now - cu->idletime))
continue;
table_buffer("%s\r %s\t%s",idle2str((now - cu->idletime),TRUE),cu->nick,cu->userhost);
table_buffer("%s\r %s\t%s",idle2str(cu->idletime,TRUE),cu->nick,cu->userhost);
}
table_send(from,1);
}
@ -1218,5 +1251,5 @@ void do_idle(COMMAND_ARGS)
to_user(from,TEXT_UNKNOWNUSER,rest);
return;
}
to_user(from,"%s has been idle for %s",rest,idle2str(now - cu2->idletime,TRUE));
to_user(from,"%s has been idle for %s",rest,idle2str(cu2->idletime,TRUE));
}

277
src/commands.h Normal file
View File

@ -0,0 +1,277 @@
/*
EnergyMech, IRC bot software
Copyright (c) 1997-2025 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
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/*
These are defined in config.h
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
NOARGF 0x200000 run a special function if no arguments are supplied
CLEVEL 0x000ff
*/
#define CCPW CC|PASS
struct CommandList
{
int pass; /* multiple passes to sort & such */
const char *name;
const char *func;
uint32_t flags;
char *cmdarg;
} pre_mcmd[] =
{
/*
* Level 0: public access commands, no CCPW
*/
{ 0, "AUTH", "do_auth", 0 | NOPUB | CBANG | NOARGF }, // double up on AUTH/VERIFY to better
{ 0, "VERIFY", "do_auth", 0 | NOPUB | CBANG | NOARGF }, // catch login attempts
#ifdef TOYBOX
{ 0, "8BALL", "do_8ball", 0 | CBANG | SUPRES },
{ 0, "RAND", "do_rand", 0 | CBANG | SUPRES },
#endif /* TOYBOX */
{ 0, "CV", "do_convert", 0 | CBANG | SUPRES },
{ 0, "CALC", "do_calc", 0 | CBANG | SUPRES },
/*
* Level 5: Semi-public commands, No PW required. CC included by default.
*/
{ 0, "BYE", "do_bye", 5 },
{ 0, "DOWN", "do_opdeopme", 5 | CAXS },
#ifdef DCC_FILE
{ 0, "SEND", "do_send", 5 | NOCMD | CBANG | CARGS | LBUF },
#endif /* DCC_FILE */
/*
* Level 10: All commands level 10+ PW by default (plus CC from Level 5+).
*/
{ 0, "ACCESS", "do_access", 10 },
{ 0, "CHAT", "do_chat", 10 | NOCMD },
#ifdef RAWDNS
{ 0, "DNS", "do_dns", 10 | GAXS | CARGS | SUPRES },
#endif /* RAWDNS */
{ 0, "ECHO", "do_echo", 10 | CARGS },
{ 0, "HELP", "do_help", 10 | REDIR | LBUF | SUPRES },
{ 0, "PASSWD", "do_passwd", 10 | NOPUB | CARGS },
{ 0, "USAGE", "do_usage", 10 | REDIR | CARGS },
/*
* Level 20
*/
{ 0, "ONTIME", "do_upontime", 20 , "Ontime: %s" },
{ 0, "UPTIME", "do_upontime", 20 , "Uptime: %s" },
{ 0, "VER", "do_version", 20 },
{ 0, "WHOM", "do_whom", 20 | REDIR | LBUF },
#ifdef SEEN
{ 0, "SEEN", "do_seen", 20 | CBANG },
#endif /* SEEN */
#ifdef URLCAPTURE
{ 0, "URLHIST", "do_urlhist", 20 | REDIR | LBUF },
#endif /* ifdef URLCAPTURE */
/*
* Level 40
*/
{ 0, "BAN", "do_kickban", 40 | CCPW | CAXS | CARGS | ACCHAN , "\\x00ban\\0bann" },
{ 0, "BANLIST", "do_banlist", 40 | CAXS | DCC | REDIR | LBUF | ACCHAN },
{ 0, "CCHAN", "do_cchan", 40 | CCPW }, /* global_access ? */
{ 0, "CSERV", "do_cserv", 40 | CCPW },
{ 0, "CHANNELS", "do_channels", 40 | CCPW | DCC },
{ 0, "DEOP", "do_opvoice", 40 | CAXS | CARGS , "o-" },
{ 0, "ESAY", "do_esay", 40 | CAXS | CARGS },
{ 0, "IDLE", "do_idle", 40 | CCPW | CARGS },
{ 0, "INVITE", "do_invite", 40 | CAXS | ACCHAN },
{ 0, "KB", "do_kickban", 40 | CAXS | CARGS | ACCHAN , "\\x04kickban\\0kickbann" },
{ 0, "KICK", "do_kickban", 40 | CAXS | CARGS | ACCHAN , "\\x07kick\\0kick" },
{ 0, "LUSERS", "do_irclusers", 40 | CCPW | DCC | REDIR | LBUF },
{ 0, "ME", "do_sayme", 40 | CCPW | CARGS },
{ 0, "MODE", "do_mode", 40 | CCPW | CARGS },
{ 0, "NAMES", "do_names", 40 | CCPW },
{ 0, "OP", "do_opvoice", 40 | CAXS , "o+" },
{ 0, "SAY", "do_sayme", 40 | CCPW | CARGS },
{ 0, "SCREW", "do_kickban", 40 | CAXS | CARGS | ACCHAN , "\\x02screwban\\0screwbann" },
{ 0, "SET", "do_set", 40 | CCPW },
{ 0, "SITEBAN", "do_kickban", 40 | CAXS | CARGS | ACCHAN , "\\x01siteban\\0sitebann" },
{ 0, "SITEKB", "do_kickban", 40 | CAXS | CARGS | ACCHAN , "\\x05sitekickban\\0sitekickbann" },
{ 0, "TIME", "do_time", 40 | CCPW },
{ 0, "TOPIC", "do_topic", 40 | CAXS | CARGS | ACCHAN | SUPRES },
{ 0, "UNBAN", "do_unban", 40 | CAXS },
{ 0, "UNVOICE", "do_opvoice", 40 | CAXS | CARGS , "v-" },
{ 0, "UP", "do_opdeopme", 40 | CAXS },
{ 0, "USER", "do_user", 40 | CCPW | CARGS },
{ 0, "USERHOST", "do_ircwhois", 40 | CCPW | CARGS },
{ 0, "VOICE", "do_opvoice", 40 | CAXS , "v+" },
{ 0, "WALL", "do_wall", 40 | CCPW | CAXS | CARGS | ACCHAN },
{ 0, "WHO", "do_who", 40 | CCPW | CAXS | DCC },
{ 0, "WHOIS", "do_ircwhois", 40 | CCPW | CARGS | DCC | REDIR | LBUF },
#ifdef NOTE
{ 0, "NOTE", "do_note", 40 | CCPW | CARGS },
{ 0, "READ", "do_read", 40 | CCPW },
#endif /* NOTE */
#ifdef STATS
{ 0, "INFO", "do_info", 40 | CCPW | REDIR | CAXS | DCC },
#endif /* STATS */
/*
* Level 50
*/
{ 0, "QSHIT", "do_shit", 50 | CCPW | CARGS },
{ 0, "RSHIT", "do_rshit", 50 | CCPW | CARGS },
{ 0, "SHIT", "do_shit", 50 | CCPW | CARGS },
{ 0, "SHITLIST", "do_shitlist", 50 | CCPW | DCC | REDIR | LBUF },
#ifdef GREET
{ 0, "GREET", "do_greet", 50 | CCPW | CARGS },
#endif /* GREET */
#ifdef TOYBOX
{ 0, "INSULT", "do_randmsg", 50 | CCPW , RANDINSULTFILE },
{ 0, "PICKUP", "do_randmsg", 50 | CCPW , RANDPICKUPFILE },
{ 0, "RSAY", "do_randmsg", 50 | CCPW , RANDSAYFILE },
{ 0, "RT", "do_randtopic", 50 | CCPW | CAXS | ACCHAN },
{ 0, "ASCII", "do_ascii", 50 | CCPW | CAXS | CARGS | SUPRES },
#endif /* TOYBOX */
#ifdef TRIVIA
{ 0, "TRIVIA", "do_trivia", 50 | CCPW | CAXS | CARGS | CBANG },
#endif /* TRIVIA */
/*
* Level 60
*/
{ 0, "SHOWIDLE", "do_showidle", 60 | CAXS | DCC | ACCHAN },
{ 0, "USERLIST", "do_userlist", 60 | DCC },
#ifdef CTCP
{ 0, "CTCP", "do_ping_ctcp", 60 | CARGS },
{ 0, "PING", "do_ping_ctcp", 60 | CARGS },
#endif /* CTCP */
/*
* Level 70 == JOINLEVEL
*/
{ 0, "CYCLE", "do_cycle", 70 | CAXS | ACCHAN },
{ 0, "FORGET", "do_forget", 70 | CAXS },
{ 0, "JOIN", "do_join", 70 | CARGS },
{ 0, "KS", "do_kicksay", 70 | REDIR | LBUF },
{ 0, "PART", "do_part", 70 | CAXS | ACCHAN },
{ 0, "RKS", "do_rkicksay", 70 | CARGS },
{ 0, "SETPASS", "do_setpass", 70 | NOPUB | CARGS },
#ifdef NOTIFY
{ 0, "NOTIFY", "do_notify", 70 | DCC | GAXS | REDIR | LBUF },
#endif /* NOTIFY */
/*
* Level 80 == ASSTLEVEL
*/
{ 0, "AWAY", "do_away", 80 | GAXS },
{ 0, "BOOT", "do_boot", 80 | GAXS | CARGS },
#if defined(BOTNET) && defined(REDIRECT)
{ 0, "CMD", "do_cmd", 80 | CARGS },
#endif /* BOTNET && REDIRECT */
{ 0, "CQ", "do_clearqueue", 80 | GAXS },
{ 0, "LAST", "do_last", 80 | DCC },
{ 0, "LOAD", "do_load", 80 | GAXS },
{ 0, "MSG", "do_msg", 80 | CARGS },
{ 0, "NEXTSERVER", "do_server", 80 | CCPW | GAXS },
{ 0, "SAVE", "do_save", 80 | CCPW | GAXS },
{ 0, "SERVER", "do_server", 80 | CCPW | GAXS | REDIR | NOPUB | NOARGF },
{ 0, "STATS", "do_ircstats", 80 | CCPW | DCC | CARGS },
#ifdef ALIAS
{ 0, "ALIAS", "do_alias", 80 | CCPW | GAXS },
{ 0, "UNALIAS", "do_unalias", 80 | CCPW | GAXS | CARGS },
#endif /* ALIAS */
#ifdef TOYBOX
{ 0, "BIGSAY", "do_bigsay", 80 | CCPW | CAXS | CARGS | SUPRES },
#endif /* TOYBOX */
/*
* Level 90
*/
{ 0, "CLEARSHIT", "do_clearshit", 90 | CCPW | GAXS },
{ 0, "DO", "do_do", 90 | CCPW | GAXS | CARGS },
{ 0, "NICK", "do_nick", 90 | CCPW | GAXS | CARGS },
{ 0, "RSPY", "do_rspy", 90 | CCPW | CARGS },
{ 0, "SPY", "do_spy", 90 | CCPW },
#ifdef BOTNET
{ 0, "LINK", "do_link", 90 | CCPW | GAXS | NOPUB | NOARGF },
#endif /* BOTNET */
#ifdef DYNCMD
{ 0, "CHACCESS", "do_chaccess", 90 | CCPW | GAXS | CARGS },
#endif /* DYNCMD */
#ifdef UPTIME
{ 0, "UPSEND", "do_upsend", 90 | CCPW | GAXS },
#endif /* UPTIME */
/*
* Level 100
*/
#ifdef HOSTINFO
{ 0, "SYSINFO", "do_sysinfo", 100 | CCPW | GAXS },
{ 0, "MEMINFO", "do_meminfo", 100 | CCPW | GAXS },
{ 0, "CPUINFO", "do_cpuinfo", 100 | CCPW | GAXS },
{ 0, "FILEMON", "do_filemon", 100 | CCPW | GAXS | CARGS },
#endif /* HOSTINFO */
#ifdef RAWDNS
{ 0, "DNSSERVER", "do_dnsserver", 100 | CCPW | GAXS },
{ 0, "DNSROOT", "do_dnsroot", 100 | CCPW | GAXS | CARGS },
#endif /* RAWDNS */
{ 0, "CORE", "do_core", 100 | CCPW | REDIR | DCC },
{ 0, "DIE", "do_die", 100 | CCPW | GAXS },
{ 0, "RESET", "do_reset", 100 | CCPW | GAXS | NOCMD },
{ 0, "SHUTDOWN", "do_shutdown", 100 | CCPW | GAXS | NOPUB | NOCMD },
#ifdef DEBUG
{ 0, "DEBUG", "do_debug", 100 | CCPW | GAXS },
{ 0, "CRASH", "do_crash", 100 | CCPW | GAXS },
{ 0, "INJECT", "do_inject", 100 | CCPW | CARGS | GAXS },
#endif /* DEBUG */
#ifdef PERL
#ifdef PLEASE_HACK_MY_SHELL
{ 0, "PERL", "do_perl", 100 | CCPW | GAXS | CARGS },
#endif /* PLEASE_HACK_MY_SHELL */
{ 0, "PERLSCRIPT", "do_perlscript", 100 | CCPW | GAXS | CARGS },
#endif /* PERL */
#ifdef PYTHON
#ifdef PLEASE_HACK_MY_SHELL
{ 0, "PYTHON", "do_python", 100 | CCPW | GAXS | CARGS },
#endif /* PLEASE_HACK_MY_SHELL */
{ 0, "PYTHONSCRIPT", "do_pythonscript", 100 | CCPW | GAXS | CARGS },
#endif /* PYTHON */
#ifdef TCL
#ifdef PLEASE_HACK_MY_SHELL
{ 0, "TCL", "do_tcl", 100 | CCPW | GAXS | CARGS },
#endif /* PLEASE_HACK_MY_SHELL */
{ 0, "TCLSCRIPT", "do_tcl", 100 | CCPW | GAXS | CARGS },
#endif /* TCL */
/*---*/
{ 0, NULL, NULL, 0 },
};

View File

@ -71,12 +71,6 @@
*/
@DEF_HOSTINFO@
/*
* IDWRAP: support for idwrap ident spoofing
*/
@DEF_IDWRAP@
#define IDWRAP_PATH @IDWRAP_PATH@
/*
* IRCD_EXTENSIONS: support some special features of new ircds
*/
@ -103,7 +97,7 @@
@DEF_DCCFILE@
#define DCC_PUBLICFILES "public/"
#define DCC_PUBLICINCOMING DCC_PUBLICFILES "incoming/"
#define DCC_FILETIMEOUT 90
#define DCCFILE_TIMEOUT 90
/*
* REDIRECT: send command output from certain commands to a different target
@ -195,7 +189,7 @@
/*
* URLCAPTURE: capture url's mentioned
*/
@DEF_URLCAPTURE@
@DEF_URLCAP@
/*
* WEB: serving documents via HTTP
@ -322,8 +316,8 @@
#define AWAYFORM "AWAY :%s (since %s)\n"
#define KILLSOCKTIMEOUT 30
#define WAITTIMEOUT 30
#define KILLSOCK_TIMEOUT 30
#define WAIT_TIMEOUT 30
#define NICKFLOODTIME 120 /* 240 second window for floods ( 240 / 2 = 120 ) */
@ -361,6 +355,9 @@
#define NAMELEN 79
#define NAMEBUF NAMELEN+1
#define SERVERGROUPBUF 16
#define SERVERGROUPLEN SERVERGROUPBUF-1
#define MINPASSCHARS 4
#define MAXPASSCHARS 50
@ -400,6 +397,7 @@
#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 */
#define NOARGF 0x200000 /* run a special function if no arguments are supplied */
/*
* integer only version of RANDOM()
@ -604,6 +602,13 @@ const char __mx_opts[] = ""
#undef OPT_COREONLY
#endif /* TRIVIA */
#ifdef UPTIME
OPT_COMMA "uptime"
#undef OPT_COMMA
#define OPT_COMMA ", "
#undef OPT_COREONLY
#endif /* UPTIME */
#ifdef WINGATES
OPT_COMMA "wingate"
#undef OPT_COMMA

File diff suppressed because it is too large Load Diff

View File

@ -82,7 +82,7 @@ void delete_client(Client *client)
pspy = &(*pspy)->next;
}
send_global(SPYSTR_STATUS,"[%s] %s[%i] has disconnected",
current->nick,client->user->name,client->user->x.x.access);
getbotnick(current),client->user->name,client->user->x.x.access);
}
#ifdef DCC_FILE
if (client->fileno >= 0)
@ -99,7 +99,8 @@ int dcc_sendfile(char *target, char *filename)
{
struct sockaddr_in sai;
Client *client;
int s,f,sz;
int s,f;
unsigned int sz;
char tempfile[strlen(filename)+strlen(DCC_PUBLICFILES)+2]; // strlen(DCC_PUBLICFILES) evaluates at compile time to a constant.
stringcpy(tempfile,DCC_PUBLICFILES);
@ -127,7 +128,7 @@ int dcc_sendfile(char *target, char *filename)
client->sock = s;
client->user = NULL;
client->flags = DCC_WAIT|DCC_ASYNC|DCC_SEND;
client->lasttime = now;
client->lasttime = cx.now;
client->whom = stringcpy(client->filename,filename) + 1;
stringcpy(client->whom,target);
@ -215,7 +216,7 @@ void parse_dcc(Client *client)
else
{
client->flags = DCC_SEND;
client->start = now;
client->start = cx.now;
dcc_pushfile(client,0);
}
#endif /* DCC_FILE */
@ -249,7 +250,7 @@ void parse_dcc(Client *client)
if (write(client->sock,&where,4) == -1)
return;
client->lasttime = now;
client->lasttime = cx.now;
if (oc == client->fileend)
{
@ -265,7 +266,7 @@ void parse_dcc(Client *client)
{
uint32_t where;
client->lasttime = now;
client->lasttime = cx.now;
s = client->inputcount;
oc = read(client->sock,(client->sockdata+s),(4-s));
if ((oc < 1) && (errno != EINTR) && (errno != EAGAIN))
@ -318,7 +319,7 @@ void parse_dcc(Client *client)
/*
* DCC input flood protection
*/
s = now - client->lasttime;
s = cx.now - client->lasttime;
if (s > 10)
{
client->inputcount = strlen(ptr);
@ -337,7 +338,7 @@ void parse_dcc(Client *client)
*/
CurrentShit = NULL;
CurrentChan = NULL;
client->lasttime = now;
client->lasttime = cx.now;
CurrentDCC = client;
CurrentUser = client->user;
stringcpy(CurrentNick,CurrentUser->name);
@ -347,11 +348,11 @@ void parse_dcc(Client *client)
bp = ptr;
chop(&bp);
ptr = get_token(&bp,"\001");
on_action(CurrentUser->name,current->nick,ptr);
on_action(CurrentUser->name,getbotnick(current),ptr);
}
else
{
on_msg(CurrentUser->name,current->nick,ptr);
on_msg(CurrentUser->name,getbotnick(current),ptr);
}
CurrentDCC = NULL;
/*
@ -389,7 +390,7 @@ void process_dcc(void)
partyline_banner(client);
}
else
if ((client->flags & DCC_WAIT) && ((now - client->lasttime) >= WAITTIMEOUT))
if ((client->flags & DCC_WAIT) && ((cx.now - client->lasttime) >= WAIT_TIMEOUT))
{
#ifdef DEBUG
debug("(process_dcc) connection timed out (%s)\n",
@ -399,7 +400,7 @@ void process_dcc(void)
}
#ifdef DCC_FILE
else
if ((client->flags & DCC_SEND) && ((now - client->lasttime) >= DCC_FILETIMEOUT))
if ((client->flags & DCC_SEND) && ((cx.now - client->lasttime) >= DCCFILE_TIMEOUT))
{
#ifdef DEBUG
debug("(process_dcc) {%i} DCC %s stalled (%s), closing connection\n",
@ -411,7 +412,7 @@ void process_dcc(void)
#endif /* DCC_FILE */
#ifdef TELNET
else
if ((client->flags & DCC_TELNETPASS) && ((now - client->lasttime) >= TELNET_TIMEOUT))
if ((client->flags & DCC_TELNETPASS) && ((cx.now - client->lasttime) >= TELNET_TIMEOUT))
{
client->flags = DCC_DELETE;
}
@ -528,7 +529,7 @@ void ctcp_dcc(char *from, char *to, char *rest)
client->fileend = filesz;
client->sock = s;
client->flags = DCC_WAIT|DCC_SEND|DCC_RECV;
client->lasttime = client->start = now;
client->lasttime = client->start = cx.now;
client->whom = stringcpy(client->filename,filename) + 1;
stringcpy(client->whom,from);
@ -587,7 +588,7 @@ void ctcp_dcc(char *from, char *to, char *rest)
client->sock = x;
client->user = user;
client->flags = DCC_WAIT|DCC_ASYNC;
client->lasttime = now;
client->lasttime = cx.now;
client->next = current->clientlist;
current->clientlist = client;
}
@ -671,7 +672,7 @@ void ctcp_version(char *from, char *to, char *rest)
#endif /* CTCP */
LS const struct
const struct
{
char *name;
void (*func)(char *, char *, char *);
@ -731,9 +732,9 @@ void on_ctcp(char *from, char *to, char *rest)
{
for(mul=0;mul<CTCP_SLOTS;mul++)
{
if (ctcp_slot[mul] < now)
if (ctcp_slot[mul] < cx.now)
{
ctcp_slot[mul] = now + CTCP_TIMEOUT;
ctcp_slot[mul] = cx.now + CTCP_TIMEOUT;
break;
}
}
@ -777,7 +778,7 @@ void do_ping_ctcp(COMMAND_ARGS)
{
if (CurrentCmd->name == C_PING || !stringcasecmp(rest,"PING"))
{
to_server("PRIVMSG %s :\001PING %lu\001\n",target,now);
to_server("PRIVMSG %s :\001PING %lu\001\n",target,cx.now);
return;
}
if (*rest)

View File

@ -36,9 +36,11 @@
#define boolstr(x) (x) ? "TRUE" : "FALSE"
LS const char tabs[20] = "\t\t\t\t\t\t\t\t\t\t";
#define UNKNOWNSTR "(unknown)"
LS const struct
const char tabs[20] = "\t\t\t\t\t\t\t\t\t\t";
const struct
{
char *name;
int size;
@ -92,7 +94,6 @@ LS const struct
{ "Seen", sizeof(Seen) },
#endif /* SEEN */
{ "Server", sizeof(Server) },
{ "ServerGroup", sizeof(ServerGroup) },
{ "Setting", sizeof(Setting) },
{ "Shit", sizeof(Shit) },
{ "Spy\t", sizeof(Spy) },
@ -115,7 +116,7 @@ LS const struct
#define RARE_SE ,"RARE"
#define DBUG_SE ,"DBUG"
LS struct
struct
{
void *func;
char *name;
@ -142,7 +143,6 @@ LS struct
{ do_die, "do_die" RARE_SE },
{ do_nick, "do_nick" CMD1_SE },
{ do_kicksay, "do_kicksay" CMD1_SE },
{ do_servergroup, "do_servergroup" CMD1_SE },
{ do_set, "do_set" CMD1_SE },
{ do_spy, "do_spy" CMD1_SE },
{ join_channel, "join_channel" CFG1_SE },
@ -168,7 +168,8 @@ LS struct
{ send_kick, "send_kick" },
{ send_mode, "send_mode" },
{ set_str_varc, "set_str_varc" CFG1_SE },
{ setbotnick, "setbotnick" },
{ set_mix16, "set_mix16" CORE_SE },
{ set_mix64, "set_mix64" CORE_SE },
{ sig_hup, "sig_hup" RARE_SE },
{ table_buffer, "table_buffer" },
#ifdef ALIAS
@ -206,6 +207,8 @@ LS struct
#ifdef PYTHON
{ python_hook, "python_hook" },
{ python_unhook, "python_unhook" },
{ python_timer_jump, "python_timer_jump" },
{ python_parse_jump, "python_parse_jump" },
#endif /* PYTHON */
#ifdef RAWDNS
{ rawdns, "rawdns" },
@ -223,6 +226,8 @@ LS struct
#endif /* STATS */
#ifdef TCL
{ tcl_hook, "tcl_hook" },
{ tcl_timer_jump, "tcl_timer_jump" },
{ tcl_parse_jump, "tcl_parse_jump" },
#endif /* TCL */
#ifdef TELNET
{ check_telnet, "check_telnet" },
@ -242,11 +247,34 @@ LS struct
#ifdef URLCAPTURE
{ urlcapture, "urlcapture" CORE_SE },
#endif /* URLCAPTURE */
{ 0, "(unknown)" },
{ 0, UNKNOWNSTR },
{ NULL, }};
#ifdef HOSTINFO
#include <sys/inotify.h>
const DEFstruct inomasks[] =
{
{ IN_ACCESS, "IN_ACCESS" }, /* File was accessed (read) */
{ IN_ATTRIB, "IN_ATTRIB" }, /* Metadata changed, e.g., permissions, timestamps, extended attributes, link count, UID, GID, etc. */
{ IN_CLOSE_WRITE, "IN_CLOSE_WRITE" }, /* File opened for writing was closed */
{ IN_CLOSE_NOWRITE, "IN_CLOSE_NOWRITE" }, /* File not opened for writing was closed */
{ IN_CREATE, "IN_CREATE" }, /* File/directory created in watched directory */
{ IN_DELETE, "IN_DELETE" }, /* File/directory deleted from watched directory */
{ IN_DELETE_SELF, "IN_DELETE_SELF" }, /* Watched file/directory was itself deleted */
{ IN_MODIFY, "IN_MODIFY" }, /* File was modified */
{ IN_MOVE_SELF, "IN_MOVE_SELF" }, /* Watched file/directory was itself moved */
{ IN_MOVED_FROM, "IN_MOVED_FROM" }, /* Generated for the directory containing the old filename when a file is renamed */
{ IN_MOVED_TO, "IN_MOVED_TO" }, /* Generated for the directory containing the new filename when a file is renamed */
{ IN_OPEN, "IN_OPEN" }, /* File was opened */
{ 0, }};
#endif /* HOSTINFO */
#ifdef SCRIPTING
LS const DEFstruct SCRIPTdefs[] =
const DEFstruct SCRIPTdefs[] =
{
{ MEV_PARSE, "MEV_PARSE" },
{ MEV_TIMER, "MEV_TIMER" },
@ -254,18 +282,11 @@ LS const DEFstruct SCRIPTdefs[] =
{ MEV_BOTNET, "MEV_BOTNET" },
{ MEV_DCC_COMPLETE, "MEV_DCC_COMPLETE" },
{ MEV_DNSRESULT, "MEV_DNSRESULT" },
#ifdef TCL
{ .v.func=tcl_timer_jump, "tcl_timer_jump" },
{ .v.func=tcl_parse_jump, "tcl_parse_jump" },
#endif /* TCL */
#ifdef PYTHON
{ .v.func=python_timer_jump, "python_timer_jump" },
{ .v.func=python_parse_jump, "python_parse_jump" },
#endif /* PYTHON */
{ 0, }};
#endif /* SCRIPTING */
LS const DEFstruct CNdefs[] =
const DEFstruct CNdefs[] =
{
{ CN_NOSOCK, "CN_NOSOCK" },
{ CN_DNSLOOKUP, "CN_DNSLOOKUP" },
@ -279,7 +300,7 @@ LS const DEFstruct CNdefs[] =
{ CN_SPINNING, "CN_SPINNING" },
{ 0, }};
LS const DEFstruct SPdefs[] =
const DEFstruct SPdefs[] =
{
{ SP_NULL, "SP_NULL" },
{ SP_NOAUTH, "SP_NOAUTH" },
@ -291,17 +312,20 @@ LS const DEFstruct SPdefs[] =
{ 0, }};
#ifdef NOTIFY
LS const DEFstruct NFdefs[] =
const DEFstruct NFdefs[] =
{
{ NF_OFFLINE, "NF_OFFLINE" },
{ NF_WHOIS, "NF_WHOIS" },
{ NF_MASKONLINE, "NF_MASKONLINE" },
{ NF_NOMATCH, "NF_NOMATCH" },
{ 0, }};
#endif /* NOTIFY */
#ifdef SEEN
LS const DEFstruct SEdefs[] =
const DEFstruct SEdefs[] =
{
{ SEEN_PARTED, "SEEN_PARTED" },
{ SEEN_QUIT, "SEEN_QUIT" },
@ -311,7 +335,8 @@ LS const DEFstruct SEdefs[] =
#endif /* SEEN */
#ifdef BOTNET
LS const DEFstruct BNdefs[] =
const DEFstruct BNdefs[] =
{
{ BN_UNKNOWN, "BN_UNKNOWN" },
{ BN_DEAD, "BN_DEAD" },
@ -322,9 +347,10 @@ LS const DEFstruct BNdefs[] =
{ BN_WAITLINK, "BN_WAITLINK" },
{ BN_LINKED, "BN_LINKED" },
{ 0, }};
#endif /* BOTNET */
LS const DEFstruct dcc_flags[] =
const DEFstruct dcc_flags[] =
{
{ DCC_SEND, "DCC_SEND" },
{ DCC_RECV, "DCC_RECV" },
@ -336,7 +362,7 @@ LS const DEFstruct dcc_flags[] =
{ DCC_DELETE, "DCC_DELETE" },
{ 0, }};
LS const DEFstruct ircx_flags[] =
const DEFstruct ircx_flags[] =
{
{ IRCX_WALLCHOPS, "IRCX_WALLCHOPS" },
{ IRCX_WALLVOICES, "IRCX_WALLVOICES" },
@ -344,7 +370,7 @@ LS const DEFstruct ircx_flags[] =
{ IRCX_EMODE, "IRCX_EMODE" },
{ 0, }};
LS const DEFstruct chanuser_flags[] =
const DEFstruct chanuser_flags[] =
{
{ CU_VOICE, "CU_VOICE" },
{ CU_CHANOP, "CU_CHANOP" },
@ -362,9 +388,9 @@ void strflags(char *dst, const DEFstruct *flagsstruct, int flags)
int i;
*dst = 0;
for(i=0;(flagsstruct[i].v.id);i++)
for(i=0;(flagsstruct[i].id);i++)
{
if (flagsstruct[i].v.id & flags)
if (flagsstruct[i].id & flags)
{
if (*dst)
stringcat(dst,"|");
@ -379,22 +405,10 @@ const char *strdef(const DEFstruct *dtab, int num)
for(i=0;(dtab[i].idstr);i++)
{
if (dtab[i].v.id == num)
if (dtab[i].id == num)
return(dtab[i].idstr);
}
return("UNKNOWN");
}
const char *funcdef(const DEFstruct *dtab, void *func)
{
int i;
for(i=0;(dtab[i].idstr);i++)
{
if (dtab[i].v.func == func)
return(dtab[i].idstr);
}
return("UNKNOWN");
return(UNKNOWNSTR);
}
void memreset(void)
@ -409,8 +423,8 @@ void memreset(void)
}
}
LS const void *mem_lowptr;
LS const void *mem_hiptr;
const void *mem_lowptr;
const void *mem_hiptr;
void memtouch(const void *addr)
{
@ -437,6 +451,18 @@ void memtouch(const void *addr)
}
}
const char *proc_getname(void *addr)
{
int i;
for(i=0;ProcList[i].name;i++)
{
if (ProcList[i].func == addr)
return(ProcList[i].name);
}
return(UNKNOWNSTR);
}
const char *proc_lookup(void *addr, int size)
{
int i;
@ -495,14 +521,13 @@ char *atime(time_t when)
char *pt,*zp;
pt = ctime(&when);
zp = STRCHR(pt,'\n');
zp = stringchr(pt,'\n');
*zp = 0;
return(pt);
}
void debug_server(Server *sp, char *pad)
{
ServerGroup *sg;
char *pl;
if (!sp)
@ -516,17 +541,9 @@ void debug_server(Server *sp, char *pad)
debug("%s; ident\t\t%i\n",pad,sp->ident);
debug("%s; name\t\t\"%s\"\n",pad,nullbuf(sp->name));
debug("%s; pass\t\t\"%s\"\n",pad,nullbuf(sp->pass));
debug("%s; group\t\t\"%s\"\n",pad,nullbuf(sp->group));
debug("%s; realname\t\t\"%s\"\n",pad,nullbuf(sp->realname));
debug("%s; usenum\t\t%i\n",pad,sp->usenum);
sg = getservergroupid(sp->servergroup);
if (sg)
{
debug("%s; servergroup\t%s%i \"%s\"\n",pad,pl,sp->servergroup,sg->name);
}
else
{
debug("%s; servergroup\t%s%i (unknown)\n",pad,pl,sp->servergroup);
}
debug("%s; port\t\t%i\n",pad,sp->port);
debug("%s; err\t\t%s%s (%i)\n",pad,pl,strdef(SPdefs,sp->err),sp->err);
debug("%s; lastconnect\t%s%s (%lu)\n",pad,pl,atime(sp->lastconnect),sp->lastconnect);
@ -561,7 +578,7 @@ void debug_settings(UniVar *setting, int type)
}
debug("%s> setting\n",pad+2);
for(;VarName[i].name;i++)
for(;i<SIZE_VARS;i++)
{
if ((type == DSET_CHAN) && (i >= CHANSET_SIZE))
break;
@ -644,7 +661,7 @@ void debug_memory(void)
#endif /* URLCAPTURE */
for(bot=botlist;bot;bot=bot->next)
{
for(i=CHANSET_SIZE;VarName[i].name;i++)
for(i=CHANSET_SIZE;i<SIZE_VARS;i++)
{
if (IsStr(i))
memtouch(bot->setting[i].str_var);
@ -661,7 +678,6 @@ void debug_memory(void)
{
memtouch(bot->lastcmds[i]);
}
memtouch(bot->userhost);
}
debug("> Memory allocations\n");
for(mea=mrrec;(mea);mea=mea->next)
@ -741,7 +757,7 @@ void debug_botnet(void)
struct sockaddr_in sai;
BotNet *bn;
NetCfg *cfg;
int sz;
unsigned int sz;
debug("; linkpass\t\t\"%s\"\n",nullstr(linkpass));
memtouch(linkpass);
@ -826,7 +842,6 @@ void debug_core(void)
Seen *seen;
#endif /* SEEN */
Server *sp;
ServerGroup *sg;
Spy *spy;
Strp *st;
Shit *shit;
@ -851,31 +866,13 @@ void debug_core(void)
}
debug(" ; ---\n");
if (current)
debug("; current\t\t"mx_pfmt" \"%s\"\n",(mx_ptr)current,nullstr(current->nick));
debug("; current\t\t"mx_pfmt" \"%s\"\n",(mx_ptr)current,nullstr(getbotnick(current)));
else
debug("; current\t\t"mx_pfmt"\n",(mx_ptr)current);
debug("; executable\t\t\"%s\"\n",executable);
debug("; configfile\t\t\"%s\"\n",configfile);
debug("; uptime\t\t%s (%lu)\n",atime(uptime),uptime);
debug("; short_tv\t\t%s (%is wait)\n",boolstr(short_tv),(short_tv) ? 1 : 30);
debug("> currentservergroup\t"mx_pfmt"\n",(mx_ptr)currentservergroup);
if (currentservergroup)
{
sg = currentservergroup;
debug(" ; next\t\t"mx_pfmt"\n",(mx_ptr)sg->next);
debug(" ; servergroup\t\t%i\n",sg->servergroup);
debug(" ; name\t\t\"%s\"\n",nullbuf(sg->name));
debug(" ; ---\n");
}
debug("> servergrouplist\t"mx_pfmt"\n",(mx_ptr)servergrouplist);
for(sg=servergrouplist;sg;sg=sg->next)
{
memtouch(sg);
debug(" ; next\t\t"mx_pfmt"\n",(mx_ptr)sg->next);
debug(" ; servergroup\t\t%i\n",sg->servergroup);
debug(" ; name\t\t\"%s\"\n",nullbuf(sg->name));
debug(" ; ---\n");
}
debug("; short_tv\t\t%s (%is wait)\n",boolstr(cx.short_tv),(cx.short_tv) ? 1 : 30);
debug("> serverlist\t\t"mx_pfmt"\n",(mx_ptr)serverlist);
for(sp=serverlist;sp;sp=sp->next)
{
@ -887,8 +884,6 @@ void debug_core(void)
for(bot=botlist;bot;bot=bot->next)
{
memtouch(bot);
memtouch(bot->nick);
memtouch(bot->wantnick);
debug(" ; Mech*\t\t"mx_pfmt"\n",(mx_ptr)bot);
debug(" ; next\t\t"mx_pfmt"\n",(mx_ptr)bot->next);
debug(" ; connect\t\t%s (%i)\n",strdef(CNdefs,bot->connect),bot->connect);
@ -906,8 +901,8 @@ void debug_core(void)
{
debug_server(sp," ");
}
debug(" ; nick\t\t\"%s\"\n",nullstr(bot->nick));
debug(" ; wantnick\t\t\"%s\"\n",nullstr(bot->wantnick));
debug(" ; nick\t\t\"%s\"\n",nullstr(getbotnick(bot)));
debug(" ; wantnick\t\t\"%s\"\n",nullstr(getbotwantnick(bot)));
debug_settings(bot->setting,DSET_GLOBAL);
@ -1361,7 +1356,7 @@ void debug_scripthook(void)
for(h=hooklist;h;h=h->next)
{
memtouch(h);
debug(" ; func\t\t"mx_pfmt" %s\n",(mx_ptr)h->func,funcdef(SCRIPTdefs,h->func));
debug(" ; func\t\t"mx_pfmt" %s\n",(mx_ptr)h->func,proc_getname(h->func));
debug(" ; guid\t\t%i\n",h->guid);
debug(" ; flags\t\t%s (%i)\n",strdef(SCRIPTdefs,h->flags),h->flags);
if (h->flags == MEV_TIMER)
@ -1429,13 +1424,14 @@ int wrap_debug(void)
backup_dodebug = dodebug;
backup_fd = debug_fd;
sprintf(fname,"debug.%lu",now);
sprintf(fname,"debug.%lu",cx.now);
if ((fd = open(fname,O_WRONLY|O_CREAT|O_TRUNC,NEWFILEMODE)) < 0)
return(0);
debug_fd = fd;
dodebug = TRUE;
run_debug();
parse_server_input(NULL);
close(fd);
debug_fd = backup_fd;
@ -1445,8 +1441,49 @@ int wrap_debug(void)
return(1);
}
void do_inject(COMMAND_ARGS)
{
set_mallocdoer(do_inject);
current->inject = stringdup(rest);
}
void do_debug(COMMAND_ARGS)
{
const char *arg;
int m;
arg = chop(&rest);
if (arg && strcasecmp(arg,"off") == 0)
{
if (debugfile && debugfilemalloc == TRUE)
Free(&debugfile);
debugfilemalloc = FALSE;
debugfile = NULL;
dodebug = FALSE;
to_user(from,"Debug output turned off");
return;
}
if (arg && strcasecmp(arg,"on") == 0)
{
m = is_safepath(rest,FILE_MAY_EXIST);
debug("(do_debug) turn on, rest = '%s', %i\n",rest,m);
if (*rest && m == FILE_IS_SAFE)
{
if (debugfile && debugfilemalloc == TRUE)
Free(&debugfile);
debugfilemalloc = TRUE;
set_mallocdoer(do_debug);
debugfile = stringdup(rest);
dodebug = TRUE;
to_user(from,"Debug output turned on, Output = %s",rest);
}
else
{
to_user(from,"debug: Unsafe filename");
}
return;
}
if (wrap_debug())
to_user(from,"Debug information has been written to file");
else
@ -1466,6 +1503,7 @@ void do_crash(COMMAND_ARGS)
void debug(char *format, ...)
{
va_list msg;
int sz;
if (!dodebug)
return;
@ -1488,10 +1526,10 @@ void debug(char *format, ...)
}
va_start(msg,format);
vsnprintf(debugbuf,sizeof(debugbuf),format,msg);
sz = vsnprintf(debugbuf,sizeof(debugbuf),format,msg);
va_end(msg);
if ((write(debug_fd,debugbuf,strlen(debugbuf))) < 0)
if ((write(debug_fd,debugbuf,sz)) < 0)
dodebug = FALSE;
}

View File

@ -1,7 +1,7 @@
/*
EnergyMech, IRC bot software
Parts Copyright (c) 1997-2018 proton
Parts Copyright (c) 1997-2025 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
@ -21,15 +21,6 @@
#ifndef DEFINES_H
#define DEFINES_H 1
/*
* dont export too many symbols...
*/
#ifdef LIBRARY
#define LS static
#else /* not LIBRARY */
#define LS /* nothing */
#endif /* LIBRARY */
/*
* startup ==
*/
@ -104,16 +95,9 @@
#define QM_PRI_LOW 100
/*
* Bitfield for short_tv being set to 1 or 30 seconds
* stats.c
*/
#define TV_TELNET_NICK 0x0002
#define TV_UCACHE 0x0004
#define TV_SERVCONNECT 0x0008
#define TV_LINEBUF 0x0010
#define TV_BOTNET 0x0020
#define TV_REJOIN 0x0040
#define TV_TRIVIA 0x0080
#define CSTAT_PARTIAL 1
/* Misc Crap: */
@ -148,6 +132,227 @@
#define FUH_USERHOST 1
#define FUH_HOST 2
/*
* why would channel structs contain global vars?
* they shouldnt! and now they dont! :)
*/
#define CHANSET_SIZE INT_AAWAY
/*
* For botlinks
*/
/* BotNet->status */
#define BN_UNKNOWN 0
#define BN_DEAD 1
#define BN_LINKSOCK 2
#define BN_CONNECT 3
#define BN_BANNERSENT 4
#define BN_WAITAUTH 5
#define BN_WAITLINK 6
#define BN_LINKED 7
#define BNAUTH_PLAINTEXT 0
#define BNAUTH_DES 1
#define BNAUTH_MD5 2
#define BNAUTH_SHA 3
/* for server connect status */
#define CN_NOSOCK 0
#define CN_DNSLOOKUP 1
#define CN_TRYING 2
#define CN_CONNECTED 3
#define CN_ONLINE 4
#define CN_DISCONNECT 5
#define CN_BOTDIE 6
#define CN_NEXTSERV 7
#define CN_WINGATEWAIT 8
#define CN_SPINNING 9 /* after exhausting serverlist */
#define SERVERSILENCETIMEOUT 360 /* server connection idle timeout */
/* DCC Kill flags (BYE command) */
#define DCC_NULL 0
#define DCC_COMMAND 1
#define DCC_KILL 2
/*
* is_safepath
*/
#define FILE_IS_SAFE 1
#define FILE_MUST_EXIST 1
#define FILE_MAY_EXIST 2
#define FILE_MUST_NOTEXIST 3
/* check_mass() */
#define CHK_CAPS 0
#define CHK_PUB 1
#define CHK_PUBLIC CHK_PUB
#define CHK_DEOP 2
#define CHK_BAN 3
#define CHK_KICK 4
#define INDEX_FLOOD 0
#define INDEX_BAN 1
#define INDEX_DEOP 2
#define INDEX_KICK 3
#define INDEX_NICK 4
#define INDEX_CAPS 5
#define INDEX_MAX 6
/*
*
*/
#define IRCX_WALLCHOPS 1
#define IRCX_WALLVOICES 2
#define IRCX_IMODE 4
#define IRCX_EMODE 8
/*
* dns.c
*/
#define MAX_NAMESERVERS 4
/*
* scripting events
*/
#define MEV_PARSE 0
#define MEV_TIMER 1
#define MEV_COMMAND 2
#define MEV_BOTNET 3
#define MEV_DCC_COMPLETE 4
#define MEV_DNSRESULT 5
/*
* notify defines
*/
#define NF_OFFLINE 0
#define NF_WHOIS 1
#define NF_MASKONLINE 2 /* anything above NF_MASKONLINE is "online" */
#define NF_NOMATCH 3
/*
* redirect.c
*/
#define R_NOTICE 0
#define R_PRIVMSG 1
#define R_FILE 2
#define R_BOTNET 3
/*
* seen selector types
*/
#define SEEN_PARTED 0
#define SEEN_QUIT 1
#define SEEN_NEWNICK 2
#define SEEN_KICKED 3
/* server error types */
#define SP_NULL 0
#define SP_NOAUTH 1
#define SP_KLINED 2
#define SP_FULLCLASS 3
#define SP_TIMEOUT 4
#define SP_ERRCONN 5
#define SP_DIFFPORT 6
#define SP_NO_DNS 7
#define SP_THROTTLED 8
/*
* spying types, source and target types are mixed
*/
#define SPY_FILE 1
#define SPY_DCC 2
#define SPY_CHANNEL 3
#define SPY_STATUS 4
#define SPY_MESSAGE 5
#define SPY_RAWIRC 6
#define SPY_BOTNET 7
#ifdef URLCAPTURE
#define SPY_URL 8
#endif /* URLCAPTURE */
#ifdef HOSTINFO
#define SPY_SYSMON 9
#endif /* HOSTINFO */
#define SPY_RANDSRC 10
#define SPYF_ANY 1
#define SPYF_CHANNEL (1 << SPY_CHANNEL)
#define SPYF_STATUS (1 << SPY_STATUS)
#define SPYF_MESSAGE (1 << SPY_MESSAGE)
#define SPYF_RAWIRC (1 << SPY_RAWIRC)
#define SPYF_BOTNET (1 << SPY_BOTNET)
#define SPYF_URL (1 << SPY_URL)
#define SPYF_RANDSRC (1 << SPY_RANDSRC)
/*
* function.c :: maketimestr()
*/
#define TFMT_LOG 0x20506
#define TFMT_FULL 0x60402
#define TFMT_AWAY 0x40307
#define TFMT_CLOCK 0x1
#define TFMT_DATE 0x4
/*
* Bitfield for short_tv being set to 1 or 30 seconds
*/
#define TV_TELNET_NICK 0x0002
#define TV_UCACHE 0x0004
#define TV_SERVCONNECT 0x0008
#define TV_LINEBUF 0x0010
#define TV_BOTNET 0x0020
#define TV_REJOIN 0x0040
#define TV_TRIVIA 0x0080
/*
* uptime defines
*/
#define UPTIME_ENERGYMECH 1 /* http://www.energymech.net */
#define UPTIME_EGGDROP 2 /* http://www.eggheads.org */
#define UPTIME_MINIMECH 3 /* http://www.energymech.net */
#define UPTIME_WINMECH 4 /* http://www.energymech.net */
#define UPTIME_RACBOT 5 /* http://www.racbot.org */
#define UPTIME_MIRC 6 /* http://www.mirc.com */
#define UPTIME_HAL9000 7 /* http://www.2010.org */
#define UPTIME_ANABOT 8 /* http://www.sirklabs.hu/ana-liza/ */
#define UPTIME_ANGELBOT 9 /* unknown */
#define UPTIME_FIRECLAW 10 /* http://www.fireclaw.org */
#define UPTIME_GARNAX 11 /* http://garnax.mircx.com */
#define UPTIME_WINEGGDROP 12 /* http://www.eggheads.org */
#define UPTIME_SUPYBOT 14 /* http://supybot.sourceforge.net */
#define UPTIME_GENERICDEATH 5000 /* generic death */
#define UPTIME_SIGSEGV 5001
#define UPTIME_SIGBUS 5002
#define UPTIME_SIGTERM 5003
#define UPTIME_SIGINT 5004
#define UPTIMEHOST "uptime.eggheads.org"
#ifdef __CYGWIN__
#define UPTIME_BOTTYPE UPTIME_WINMECH
#else
#define UPTIME_BOTTYPE UPTIME_ENERGYMECH
#endif /* __CYGWIN__ */
/* VHOST types */
#define VH_ZERO 0
#define VH_IPALIAS (1 << 1)
#define VH_IPALIAS_FAIL (1 << 2)
#define VH_IPALIAS_BOTH (VH_IPALIAS|VH_IPALIAS_FAIL)
#define VH_WINGATE (1 << 3)
#define VH_WINGATE_FAIL (1 << 4)
#define VH_WINGATE_BOTH (VH_WINGATE|VH_WINGATE_FAIL)
/* Type of Variable: */
#define INT_VAR 0x01
@ -174,14 +379,6 @@
#define IsChar(x) ((VarName[x].type & CHR_VAR) == CHR_VAR)
#define IsProc(x) (VarName[x].type & PROC_VAR)
/*
* is_safepath
*/
#define FILE_IS_SAFE 1
#define FILE_MUST_EXIST 1
#define FILE_MAY_EXIST 2
#define FILE_MUST_NOTEXIST 3
/*
* see settings.h for the actual setting struct
*/
@ -301,205 +498,5 @@ enum {
SIZE_VARS
};
/*
* why would channel structs contain global vars?
* they shouldnt! and now they dont! :)
*/
#define CHANSET_SIZE INT_AAWAY
/*
* For botlinks
*/
#ifdef BOTNET
/* BotNet->status */
#define BN_UNKNOWN 0
#define BN_DEAD 1
#define BN_LINKSOCK 2
#define BN_CONNECT 3
#define BN_BANNERSENT 4
#define BN_WAITAUTH 5
#define BN_WAITLINK 6
#define BN_LINKED 7
#define BNAUTH_PLAINTEXT 0
#define BNAUTH_DES 1
#define BNAUTH_MD5 2
#define BNAUTH_SHA 3
#endif /* BOTNET */
/* for connect status */
#define CN_NOSOCK 0
#define CN_DNSLOOKUP 1
#define CN_TRYING 2
#define CN_CONNECTED 3
#define CN_ONLINE 4
#define CN_DISCONNECT 5
#define CN_BOTDIE 6
#define CN_NEXTSERV 7
#define CN_WINGATEWAIT 8
#define CN_SPINNING 9 /* after exhausting serverlist */
#define SERVERSILENCETIMEOUT 360 /* server connection idle timeout */
/* DCC Kill flags (BYE command) */
#define DCC_NULL 0
#define DCC_COMMAND 1
#define DCC_KILL 2
/* VHOST types */
#define VH_ZERO 0
#define VH_IPALIAS (1 << 1)
#define VH_IPALIAS_FAIL (1 << 2)
#define VH_IPALIAS_BOTH (VH_IPALIAS|VH_IPALIAS_FAIL)
#define VH_WINGATE (1 << 3)
#define VH_WINGATE_FAIL (1 << 4)
#define VH_WINGATE_BOTH (VH_WINGATE|VH_WINGATE_FAIL)
/* server error types */
#define SP_NULL 0
#define SP_NOAUTH 1
#define SP_KLINED 2
#define SP_FULLCLASS 3
#define SP_TIMEOUT 4
#define SP_ERRCONN 5
#define SP_DIFFPORT 6
#define SP_NO_DNS 7
#define SP_THROTTLED 8
/* check_mass() */
#define INDEX_FLOOD 0
#define INDEX_BAN 1
#define INDEX_DEOP 2
#define INDEX_KICK 3
#define INDEX_NICK 4
#define INDEX_CAPS 5
#define INDEX_MAX 6
#define CHK_CAPS 0
#define CHK_PUB 1
#define CHK_PUBLIC CHK_PUB
#define CHK_DEOP 2
#define CHK_BAN 3
#define CHK_KICK 4
/*
* seen selector types
*/
#define SEEN_PARTED 0
#define SEEN_QUIT 1
#define SEEN_NEWNICK 2
#define SEEN_KICKED 3
/*
* spying types, source and target types are mixed
*/
#define SPY_FILE 1
#define SPY_DCC 2
#define SPY_CHANNEL 3
#define SPY_STATUS 4
#define SPY_MESSAGE 5
#define SPY_RAWIRC 6
#define SPY_BOTNET 7
#ifdef URLCAPTURE
#define SPY_URL 8
#endif /* URLCAPTURE */
#ifdef HOSTINFO
#define SPY_SYSMON 9
#endif /* HOSTINFO */
#define SPY_RANDSRC 10
#define SPYF_ANY 1
#define SPYF_CHANNEL (1 << SPY_CHANNEL)
#define SPYF_STATUS (1 << SPY_STATUS)
#define SPYF_MESSAGE (1 << SPY_MESSAGE)
#define SPYF_RAWIRC (1 << SPY_RAWIRC)
#define SPYF_BOTNET (1 << SPY_BOTNET)
#define SPYF_URL (1 << SPY_URL)
#define SPYF_RANDSRC (1 << SPY_RANDSRC)
/*
* notify defines
*/
#define NF_OFFLINE 0
#define NF_WHOIS 1
#define NF_MASKONLINE 2 /* anything above NF_MASKONLINE is "online" */
#define NF_NOMATCH 3
/*
* uptime defines
*/
#define UPTIME_ENERGYMECH 1 /* http://www.energymech.net */
#define UPTIME_EGGDROP 2 /* http://www.eggheads.org */
#define UPTIME_MINIMECH 3 /* http://www.energymech.net */
#define UPTIME_WINMECH 4 /* http://www.energymech.net */
#define UPTIME_RACBOT 5 /* http://www.racbot.org */
#define UPTIME_MIRC 6 /* http://www.mirc.com */
#define UPTIME_HAL9000 7 /* http://www.2010.org */
#define UPTIME_ANABOT 8 /* http://www.sirklabs.hu/ana-liza/ */
#define UPTIME_ANGELBOT 9 /* unknown */
#define UPTIME_FIRECLAW 10 /* http://www.fireclaw.org */
#define UPTIME_GARNAX 11 /* http://garnax.mircx.com */
#define UPTIME_WINEGGDROP 12 /* http://www.eggheads.org */
#define UPTIME_SUPYBOT 14 /* http://supybot.sourceforge.net */
#define UPTIME_GENERICDEATH 5000 /* generic death */
#define UPTIME_SIGSEGV 5001
#define UPTIME_SIGBUS 5002
#define UPTIME_SIGTERM 5003
#define UPTIME_SIGINT 5004
#define UPTIMEHOST "uptime.eggheads.org"
#ifdef __CYGWIN__
#define UPTIME_BOTTYPE UPTIME_WINMECH
#else
#define UPTIME_BOTTYPE UPTIME_ENERGYMECH
#endif /* __CYGWIN__ */
/*
* scripting events
*/
#define MEV_PARSE 0
#define MEV_TIMER 1
#define MEV_COMMAND 2
#define MEV_BOTNET 3
#define MEV_DCC_COMPLETE 4
#define MEV_DNSRESULT 5
/*
*
*/
#define IRCX_WALLCHOPS 1
#define IRCX_WALLVOICES 2
#define IRCX_IMODE 4
#define IRCX_EMODE 8
/*
* stats.c
*/
#define CSTAT_PARTIAL 1
/*
* dns.c
*/
#define MAX_NAMESERVERS 4
/*
* redirect.c
*/
#define R_NOTICE 0
#define R_PRIVMSG 1
#define R_FILE 2
#define R_BOTNET 3
#endif /* DEFINES_H */

View File

@ -59,9 +59,6 @@ typedef struct dnsRType
#define MAX_QUESTIONS 16
LS int dnssock = -1;
LS int dnsserver = 0;
#ifdef DEBUG
char *type_textlist[] =
{ NULL, "A", "NS", "MD", "MF", "CNAME", "SOA", "MB", "MG", "MR", "NULL", "WKS", "PTR", "HINFO", "MINFO", "MX", "TXT", };
@ -233,7 +230,7 @@ void parse_query(int psz, dnsQuery *query)
dnsList *dns;
const char *src,*rtyp;
char token[64],token2[64];
int sz,n;
int n,pick;
src = (const char*)query;
@ -243,7 +240,7 @@ void parse_query(int psz, dnsQuery *query)
token[16] = 0;
n = ntohs(query->flags);
debug("(parse_query) %i: flags = %i { %s %i %s%s%s%s%s }\n",
sz,n,token,
psz,n,token,
(n&15), /* result code */
(n&32768) ? "QR 1 (Answer) ":"QR 0 (Question) ",
(n&1024) ? "AA ":"",
@ -292,7 +289,7 @@ void parse_query(int psz, dnsQuery *query)
#endif /* DEBUG */
if (dns->cname)
Free((char**)&dns->cname);
dns->when = now + 30;
dns->when = cx.now + 30;
set_mallocdoer(parse_query);
dns->cname = stringdup(token2);
}
@ -305,7 +302,7 @@ void parse_query(int psz, dnsQuery *query)
if (dns->auth && !stringcasecmp(dns->auth->hostname,token))
{
dns->auth->ip.s_addr = ip->s_addr;
dns->when = now + 60;
dns->when = cx.now + 60;
#ifdef DEBUG
debug("(parse_query) a auth: %s = %s\n",token,inet_ntoa(*ip));
#endif /* DEBUG */
@ -314,7 +311,7 @@ void parse_query(int psz, dnsQuery *query)
if (!stringcasecmp(dns->host,token) || (dns->cname && !stringcasecmp(dns->cname,token)))
{
dns->ip.s_addr = ip->s_addr;
dns->when = now + 3600;
dns->when = cx.now + 3600;
#ifdef DEBUG
debug("(parse_query) a: %s = %s\n",token,inet_ntoa(*ip));
#endif /* DEBUG */
@ -336,10 +333,10 @@ void parse_query(int psz, dnsQuery *query)
}
n = ntohs(query->authorities);
sz = (n > 1) ? RANDOM(1,n) : 1;
pick = (n > 1) ? RANDOM(1,n) : 1;
#ifdef DEBUG
if (n)
debug("(parse_query) auth: select %i count %i\n",sz,n);
debug("(parse_query) auth: select %i count %i\n",pick,n);
#endif /* DEBUG */
while(n)
{
@ -352,7 +349,7 @@ void parse_query(int psz, dnsQuery *query)
dnsAuthority *da;
get_dns_token(src,(const char *)query,token2,psz);
if (sz == n)
if (pick == n)
{
if (dns->auth == NULL)
{
@ -377,7 +374,7 @@ void parse_query(int psz, dnsQuery *query)
}
}
#ifdef DEBUG
debug("(parse_query) authorities: %s = %s%s\n",token,token2,(sz==n) ? MATCH_ALL : "");
debug("(parse_query) authorities: %s = %s%s\n",token,token2,(pick==n) ? MATCH_ALL : "");
#endif /* DEBUG */
}
#ifdef DEBUG
@ -511,12 +508,14 @@ void parse_query(int psz, dnsQuery *query)
}
if (src)
{
int sz;
dns->id = rand();
#ifdef DEBUG
debug("(parse_query) %i: asking %s who is `%s'\n",dns->id,inet_ntoa(sai.sin_addr),src);
#endif /* DEBUG */
sz = make_query(packet,src);
dns->when = now + 60;
dns->when = cx.now + 60;
sai.sin_family = AF_INET;
sai.sin_port = htons(53);
((dnsQuery*)packet)->qid = htons(dns->id);
@ -532,13 +531,15 @@ void parse_query(int psz, dnsQuery *query)
Free((char**)&dns->auth2);
if (src == NULL && dns->ip.s_addr == 0 && dns->cname && dns->host && dns->auth == NULL && dns->auth2 == NULL)
{
int sz;
dns->id = rand();
sai.sin_addr.s_addr = (ia_ns[dnsserver].s_addr == 0) ? ia_default.s_addr : ia_ns[dnsserver].s_addr;
#ifdef DEBUG
debug("(parse_query) %i: asking %s who is `%s' (CNAME question)\n",dns->id,inet_ntoa(sai.sin_addr),dns->cname);
#endif /* DEBUG */
sz = make_query(packet,dns->cname);
dns->when = now + 60;
dns->when = cx.now + 60;
sai.sin_family = AF_INET;
sai.sin_port = htons(53);
((dnsQuery*)packet)->qid = htons(dns->id);
@ -571,7 +572,7 @@ void rawdns(const char *hostname)
item = (dnsList*)Calloc(sizeof(dnsList) + strlen(hostname));
stringcpy(item->host,hostname);
item->id = ntohs(query->qid);
item->when = now + 30;
item->when = cx.now + 30;
item->next = dnslist;
dnslist = item;
@ -610,7 +611,7 @@ restart:
pdns = &dnslist;
while(*pdns)
{
if ((*pdns)->when < now)
if ((*pdns)->when < cx.now)
{
dns = *pdns;
if (dns->cname)
@ -640,22 +641,18 @@ restart:
void process_rawdns(void)
{
struct sockaddr_in sai;
unsigned int sz;
char packet[512];
int sz,n;
int n;
if (dnssock == -1)
sz = sizeof(sai);
n = recvfrom(dnssock,packet,512,0,(struct sockaddr*)&sai,&sz);
if (n < sizeof(dnsQuery))
return;
if (FD_ISSET(dnssock,&read_fds))
{
sz = sizeof(sai);
n = recvfrom(dnssock,packet,512,0,(struct sockaddr*)&sai,&sz);
if (n < sizeof(dnsQuery))
return;
#ifdef DEBUG
debug("(process_rawdns) packet from: %s (%i bytes)\n",inet_ntoa(sai.sin_addr),n);
debug("(process_rawdns) packet from: %s (%i bytes)\n",inet_ntoa(sai.sin_addr),n);
#endif /* DEBUG */
parse_query(n,(dnsQuery*)packet);
}
parse_query(n,(dnsQuery*)packet);
}
char *poll_rawdns(char *hostname)
@ -675,7 +672,7 @@ char *poll_rawdns(char *hostname)
return(NULL);
}
LS int backup_debug;
int backup_debug;
int read_dnsroot(char *line)
{
@ -855,7 +852,7 @@ void do_dns(COMMAND_ARGS)
uint32_t ip;
/* to date, all hostnames contain atleast one dot */
if ((STRCHR(rest,'.')))
if ((stringchr(rest,'.')))
{
host = rest;
}

View File

@ -1,7 +1,7 @@
/*
EnergyMech, IRC bot software
Parts Copyright (c) 1997-2020 proton
Parts Copyright (c) 1997-2025 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
@ -30,12 +30,13 @@
#include "h.h"
#include "text.h"
#ifndef TEST
char timebuf[64]; /* max format lentgh == 20+1 */
char idlestr[64]; /* max format lentgh == 24+1 */
LS char timebuf[32]; /* max format lentgh == 20+1, round up to 32 */
LS char idlestr[36]; /* max format lentgh == 24+1, round up to 36 */
LS const char monlist[12][4] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
LS const char daylist[7][4] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" };
const char monlist[12][4] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
const char daylist[7][4] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" };
#ifndef TEST
/*
* memory allocation routines
@ -91,7 +92,7 @@ void *Calloc(int size)
exit(1);
}
mmep->size = size;
mmep->when = now;
mmep->when = cx.now;
mmep->doer = mallocdoer;
mallocdoer = NULL;
return((void*)mmep->area+4);
@ -126,7 +127,8 @@ void Free(char **mem)
{
debug("(Free) PANIC: Free(0x"mx_pfmt"); Unregistered memory block\n",(mx_ptr)src);
run_debug();
/*exit(1); /* overreacting. just ignore it and accept the leak. */
/*exit(1);*/
/* overreacting. just ignore it and accept the leak. */
return;
}
mp = mp->next;
@ -167,6 +169,50 @@ void Free(char **mem)
#endif /* DEBUG */
void set_mix16(Mix16 *mix, const char *str)
{
int sz;
if (mix->opt >= 16)
{
Free(&mix->x.ptr);
}
sz = strlen(str);
if (sz < 16)
{
stringcpy(mix->x.string,str);
}
else
{
set_mallocdoer(set_mix16);
mix->x.ptr = stringdup(str);
}
mix->opt = sz;
}
void set_mix64(Mix64 *mix, const char *str)
{
int sz;
if (mix->opt >= 64)
{
Free(&mix->x.ptr);
}
sz = strlen(str);
if (sz < 64)
{
stringcpy(mix->x.string,str);
}
else
{
set_mallocdoer(set_mix64);
mix->x.ptr = stringdup(str);
}
mix->opt = sz;
}
Strp *make_strp(Strp **pp, const char *string)
{
set_mallocdoer(make_strp);
@ -223,96 +269,6 @@ void dupe_strp(Strp *sp, Strp **pp)
}
}
Strp *e_table = NULL;
void table_buffer(const char *format, ...)
{
Strp **sp;
va_list msg;
int sz;
va_start(msg,format);
sz = sizeof(Strp) + vsprintf(globaldata,format,msg);
va_end(msg);
for(sp=&e_table;*sp;sp=&(*sp)->next)
;
set_mallocdoer(table_buffer);
*sp = (Strp*)Calloc(sz);
/* Calloc sets to zero (*sp)->next = NULL; */
stringcpy((*sp)->p,globaldata);
}
void table_send(const char *from, const int space)
{
char message[MAXLEN];
Strp *sp,*next;
char *src,*o,*end;
int i,u,g,x,z[6];
z[0] = z[1] = z[2] = z[3] = z[4] = z[5] = 0;
for(sp=e_table;sp;sp=sp->next)
{
u = i = 0;
src = o = sp->p;
while(*src)
{
if (*src == '\037' || *src == '\002')
u++;
if (*src == '\t' || *src == '\r')
{
x = (src - o) - u;
if (x > z[i])
z[i] = x;
i++;
o = src+1;
u = 0;
}
src++;
}
}
for(sp=e_table;sp;sp=next)
{
next = sp->next;
o = message;
src = sp->p;
g = x = i = 0;
while(*src)
{
if (g)
{
end = src;
while(*end && *end != '\t' && *end != '\r')
end++;
g -= (end - src);
while(g-- > 0)
*(o++) = ' ';
}
if (*src == '\037' || *src == '\002')
x++;
if (*src == '\t' || *src == '\r')
{
if (*src == '\r')
g = z[i+1];
src++;
x += (z[i++] + space);
while(o < (message + x))
*(o++) = ' ';
}
else
*(o++) = *(src++);
}
*o = 0;
to_user(from,FMT_PLAIN,message);
Free((char**)&sp);
}
e_table = NULL;
}
char *getuh(char *nuh)
{
char *s;
@ -322,12 +278,11 @@ char *getuh(char *nuh)
{
if (*s == '!')
{
nuh = s + 1;
/*
* We have to grab everything from the first '!' since some
* braindamaged ircds allow '!' in the "user" part of the nuh
*/
break;
return(s + 1);
}
s++;
}
@ -385,80 +340,63 @@ a: ++(*src);
return(token);
}
#endif /* ifndef TEST */
/*
* time to string routines
*/
char *logtime(time_t when)
char *maketimestr(time_t when, int format)
{
struct tm *btime;
char *dest,*f,ampm;
int option;
btime = localtime(&when);
sprintf(timebuf,"%s %i %i %02i:%02i:%02i", /* max format length: 20+1 */
monlist[btime->tm_mon],btime->tm_mday,btime->tm_year+1900,
btime->tm_hour,btime->tm_min,btime->tm_sec);
return(timebuf);
}
dest = timebuf;
char *time2str(time_t when)
{
struct tm *btime;
if (!when)
return(NULL);
btime = localtime(&when);
sprintf(timebuf,"%02i:%02i:%02i %s %02i %i", /* max format length: 20+1 */
btime->tm_hour,btime->tm_min,btime->tm_sec,monlist[btime->tm_mon],
btime->tm_mday,btime->tm_year+1900);
return(timebuf);
}
char *time2away(time_t when)
{
struct tm *btime;
char ampm;
if (!when)
return(NULL);
btime = localtime(&when);
if (btime->tm_hour < 12)
do
{
if (btime->tm_hour == 0)
btime->tm_hour = 12;
ampm = 'a';
option = format & 0x7;
format = format >> 4;
f = "%02i:%02i:%02i";
switch(option)
{
case 0:
*(dest++) = ' ';
break;
case 1:/* HH:mm */
f += 5;
case 2:/* HH:mm:ss */
dest += sprintf(dest,f,btime->tm_hour,btime->tm_min,btime->tm_sec);
break;
case 3:/* WeekDay */
/* stringcpy return a pointer to the last char, not how many chars was copied */
dest = stringcpy(dest,daylist[btime->tm_wday]);
break;
case 4:/* ascii-Month Day */
dest += sprintf(dest,"%s %i",monlist[btime->tm_mon],btime->tm_mday);
break;
case 5:/* num-Month Day */
dest += sprintf(dest,"%02i %02i",btime->tm_mon+1,btime->tm_mday);
break;
case 6:/* Year */
dest += sprintf(dest,"%i",btime->tm_year+1900);
break;
case 7:/* am/pm */
unsigned char a,b;
a = ((unsigned char)btime->tm_hour - 1);
a >>= 7;
b = ((unsigned char)btime->tm_hour - 12);
b >>= 7;
btime->tm_hour += (a * 12) - 12 * (b^1);
ampm = 'p' - (b * ('p' - 'a'));
dest += sprintf(dest,"%i:%02i%cm",btime->tm_hour,btime->tm_min,ampm);
break;
}
}
else
{
if (btime->tm_hour != 12)
btime->tm_hour -= 12;
ampm = 'p';
}
sprintf(timebuf,"%i:%02i%cm %s %s %i", /* max format length: 18+1 */
btime->tm_hour,btime->tm_min,ampm,daylist[btime->tm_wday],
monlist[btime->tm_mon],btime->tm_mday);
return(timebuf);
}
char *time2medium(time_t when)
{
struct tm *btime;
btime = localtime(&when);
sprintf(timebuf,"%02i:%02i", /* max format length: 5+1 */
btime->tm_hour,btime->tm_min);
return(timebuf);
}
char *time2small(time_t when)
{
struct tm *btime;
btime = localtime(&when);
sprintf(timebuf,"%s %02i", /* max format length: 6+1 */
monlist[btime->tm_mon],btime->tm_mday);
while(format);
return(timebuf);
}
@ -467,18 +405,31 @@ char *idle2str(time_t when, int small)
char *dst;
int n,z[4];
when = cx.now - when;
z[0] = when / 86400;
z[1] = (when -= z[0] * 86400) / 3600;
z[2] = (when -= z[1] * 3600) / 60;
z[3] = when % 60;
#ifdef DEBUG
{
struct tm *btime;
btime = localtime(&when);
debug("(idle2str) days %i, hours %i, minutes %i, seconds %i\n"
"(idle2str) d %i, h %i, m %i, s %i\n",
z[0],z[1],z[2],z[3],
btime->tm_yday,btime->tm_hour,btime->tm_min,btime->tm_sec);
}
#endif /* DEBUG*/
/* 32 : "9999 days, 24 hours, 59 minutes" */
/* xx : "24 hours, 59 minutes" */
/* xx : "59 minutes, 59 seconds" */
/* xx : "59 seconds" */
if (small)
{
char *f[] = {"day","hour","minute","second"};
const char *f[] = {"day","hour","minute","second"};
*idlestr = 0;
for(n=0;n<4;n++)
@ -496,6 +447,8 @@ char *idle2str(time_t when, int small)
return(idlestr);
}
#ifndef TEST
const char *get_channel(const char *to, char **rest)
{
const char *channel;
@ -608,7 +561,7 @@ char *format_uh(char *userhost, int type)
char tmpmask[NUHLEN];
char *u,*h;
if (STRCHR(userhost,'*'))
if (stringchr(userhost,'*'))
return(userhost);
stringcpy(tmpmask,userhost);
@ -632,87 +585,6 @@ char *format_uh(char *userhost, int type)
return(userhost);
}
/*
* NOTE! beware of conflicts in the use of nuh_buf, its also used by find_nuh()
*/
char *nick2uh(char *from, char *userhost)
{
if (STRCHR(userhost,'!') && STRCHR(userhost,'@'))
{
stringcpy(nuh_buf,userhost);
}
else
if (!STRCHR(userhost,'!') && !STRCHR(userhost,'@'))
{
/* find_nuh() stores nickuserhost in nuh_buf */
if (find_nuh(userhost) == NULL)
{
if (from)
to_user(from,"No information found for %s",userhost);
return(NULL);
}
}
else
{
stringcpy(nuh_buf,"*!");
if (!STRCHR(userhost,'@'))
stringcat(nuh_buf,"*@");
stringcat(nuh_buf,userhost);
}
return(nuh_buf);
}
void deop_ban(Chan *chan, ChanUser *victim, char *mask)
{
if (!mask)
mask = format_uh(get_nuh(victim),FUH_USERHOST);
send_mode(chan,85,QM_CHANUSER,'-','o',victim);
send_mode(chan,90,QM_RAWMODE,'+','b',mask);
}
void deop_siteban(Chan *chan, ChanUser *victim)
{
char *mask;
mask = format_uh(get_nuh(victim),FUH_HOST);
deop_ban(chan,victim,mask);
}
void screwban_format(char *userhost)
{
int sz,n,pos;
#ifdef DEBUG
debug("(screwban_format) %s\n",userhost);
#endif /* DEBUG */
if ((sz = strlen(userhost)) < 8)
return;
n = RANDOM(4,sz);
while(--n)
{
pos = RANDOM(0,(sz - 1));
if (!STRCHR("?!@*",userhost[pos]))
{
userhost[pos] = (RANDOM(0,3) == 0) ? '*' : '?';
}
}
}
void deop_screwban(Chan *chan, ChanUser *victim)
{
char *mask;
int i;
for(i=2;--i;)
{
mask = format_uh(get_nuh(victim),FUH_USERHOST);
screwban_format(mask);
deop_ban(chan,victim,mask);
}
}
int is_nick(const char *nick)
{
uchar *p;
@ -729,6 +601,8 @@ int is_nick(const char *nick)
return(TRUE);
}
#endif /* ifndef TEST */
/* asc2int requires the whole string *anum to be a valid numeric */
int asc2int(const char *anum)
{
@ -770,6 +644,46 @@ int get_number(const char *rest)
return(n);
}
#define checkifdigit(xcx) (xcx >= '0' && xcx <= '9')
void parse_range(char **s, int *a)
{
int v;
a[0] = -1;
a[1] = -1;
a[2] = 0;
if (0 == checkifdigit(**s))
return;
v = 0;
while(checkifdigit(**s))
{
v = (v * 10) + **s - '0';
(*s)++;
}
a[0] = v;
/* optional second number */
if (**s == '-')
{
a[2] = 1;
(*s)++;
}
if (0 == checkifdigit(**s))
return;
v = 0;
while(checkifdigit(**s))
{
v = (v * 10) + **s - '0';
(*s)++;
}
a[1] = v;
}
void fix_config_line(char *text)
{
char *s,*space;
@ -788,8 +702,6 @@ void fix_config_line(char *text)
*space = 0;
}
#endif /* ifndef TEST */
/*
* mask matching
* returns 0 for match
@ -996,7 +908,9 @@ void teststring(void)
int main(int argc, char **argv, char **envp)
{
char mybuffer[64];
struct stat st;
time_t when;
int r;
dodebug = 1;
@ -1020,11 +934,25 @@ int main(int argc, char **argv, char **envp)
testcase("../../nosuchfile",-5,FILE_MUST_NOTEXIST);
testcase(P2,-6,FILE_MAY_EXIST);
teststring();
exit(0);
}
r = is_safepath(argv[1],FILE_MAY_EXIST);
debug("testpath %s -> result %s\n",argv[1],(r) ? "TRUE" : "FALSE");
if (argv[1])
{
r = is_safepath(argv[1],FILE_MAY_EXIST);
debug("testpath %s -> result %s\n",argv[1],(r) ? "TRUE" : "FALSE");
}
time(&cx.now);
for(r=0;r<10;r++)
{
when = cx.now - (int[]){100000,888,534569,999999,99,9000,84600,7777777,56565656+3600,78987654}[r];
debug("\nmaketimestr %s\n",maketimestr(when,TFMT_LOG));
debug("maketimestr %s\n",maketimestr(when,TFMT_FULL));
debug("maketimestr %s\n",maketimestr(when,TFMT_AWAY));
debug("maketimestr %s\n",maketimestr(when,TFMT_CLOCK));
debug("maketimestr %s\n",maketimestr(when,TFMT_DATE));
}
}
#endif /* TEST */

View File

@ -26,347 +26,236 @@ char globaldata[MAXLEN];
#include "io.c"
#define HASHDATASZ 256
#define HASHDATAMASK 255
uint8_t hash[512];
uint8_t hashmap[512];
uint8_t hashdata[HASHDATASZ];
#define HEATMAP 1
#ifdef HEATMAP
uint8_t heatmap[HASHDATASZ];
#endif
int mx,collis,mincoll,randfd,heatmapon;
/*
These are defined in config.h
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
*/
#define CCPW CC|PASS
struct
* tolowertab blatantly ripped from ircu2.9.32
*/
const uchar tolowertab[256] =
{
int pass;
const char *name;
const char *func;
uint32_t flags;
char *cmdarg;
} pre_mcmd[] =
{
/*
* public access commands
*/
{ 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 | SUPRES },
{ 0, "RAND", "do_rand", 0 | CBANG | SUPRES },
#endif /* TOYBOX */
{ 0, "CV", "do_convert", 0 | CBANG | SUPRES },
{ 0, "CALC", "do_calc", 0 | CBANG | SUPRES },
/*
* Level 10
*/
{ 0, "ACCESS", "do_access", 10 | CCPW },
{ 0, "BYE", "do_bye", 10 | CC },
{ 0, "CHAT", "do_chat", 10 | CCPW | NOCMD },
#ifdef RAWDNS
{ 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 | SUPRES },
{ 0, "PASSWD", "do_passwd", 10 | PASS | NOPUB | CARGS },
#ifdef DCC_FILE
{ 0, "SEND", "do_send", 10 | CC | NOCMD | CBANG | CARGS },
#endif /* DCC_FILE */
{ 0, "USAGE", "do_usage", 10 | CCPW | REDIR | CARGS },
/*
* Level 20
*/
{ 0, "ONTIME", "do_upontime", 20 | CCPW , "Ontime: %s" },
{ 0, "UPTIME", "do_upontime", 20 | CCPW , "Uptime: %s" },
{ 0, "VER", "do_version", 20 | CCPW },
{ 0, "WHOM", "do_whom", 20 | CCPW | REDIR | LBUF },
#ifdef SEEN
{ 0, "SEEN", "do_seen", 20 | CCPW | CBANG },
#endif /* SEEN */
#ifdef URLCAPTURE
{ 0, "URLHIST", "do_urlhist", 20 | CCPW | REDIR | LBUF },
#endif /* ifdef URLCAPTURE */
/*
* Level 40
*/
{ 0, "BAN", "do_kickban", 40 | CCPW | CAXS | CARGS | ACCHAN , "\\x00ban\\0bann" },
{ 0, "BANLIST", "do_banlist", 40 | CCPW | CAXS | DCC | REDIR | LBUF | ACCHAN },
{ 0, "CCHAN", "do_cchan", 40 | CCPW }, /* global_access ? */
{ 0, "CSERV", "do_cserv", 40 | CCPW },
{ 0, "CHANNELS", "do_channels", 40 | CCPW | DCC },
{ 0, "DEOP", "do_opvoice", 40 | CCPW | CAXS | CARGS , "o-" },
{ 0, "ESAY", "do_esay", 40 | CCPW | CAXS | CARGS },
{ 0, "IDLE", "do_idle", 40 | CCPW | CARGS },
{ 0, "INVITE", "do_invite", 40 | CCPW | CAXS | ACCHAN },
{ 0, "KB", "do_kickban", 40 | CCPW | CAXS | CARGS | ACCHAN , "\\x04kickban\\0kickbann" },
{ 0, "KICK", "do_kickban", 40 | CCPW | CAXS | CARGS | ACCHAN , "\\x07kick\\0kick" },
{ 0, "LUSERS", "do_irclusers", 40 | CCPW | DCC | REDIR | LBUF },
{ 0, "ME", "do_sayme", 40 | CCPW | CARGS },
{ 0, "MODE", "do_mode", 40 | CCPW | CARGS },
{ 0, "NAMES", "do_names", 40 | CCPW },
{ 0, "OP", "do_opvoice", 40 | CCPW | CAXS , "o+" },
{ 0, "SAY", "do_sayme", 40 | CCPW | CARGS },
{ 0, "SCREW", "do_kickban", 40 | CCPW | CAXS | CARGS | ACCHAN , "\\x02screwban\\0screwbann" },
{ 0, "SET", "do_set", 40 | CCPW },
{ 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 | SUPRES },
{ 0, "UNBAN", "do_unban", 40 | CCPW | CAXS },
{ 0, "UNVOICE", "do_opvoice", 40 | CCPW | CAXS | CARGS , "v-" },
{ 0, "UP", "do_opdeopme", 40 | CCPW | CAXS },
{ 0, "USER", "do_user", 40 | CCPW | CARGS },
{ 0, "USERHOST", "do_ircwhois", 40 | CCPW | CARGS },
{ 0, "VOICE", "do_opvoice", 40 | CCPW | CAXS , "v+" },
{ 0, "WALL", "do_wall", 40 | CCPW | CAXS | CARGS | ACCHAN },
{ 0, "WHO", "do_who", 40 | CCPW | CAXS | DCC },
{ 0, "WHOIS", "do_ircwhois", 40 | CCPW | CARGS | DCC | REDIR | LBUF },
#ifdef NOTE
{ 0, "NOTE", "do_note", 40 | CCPW | CARGS },
{ 0, "READ", "do_read", 40 | CCPW },
#endif /* NOTE */
#ifdef STATS
{ 0, "INFO", "do_info", 40 | CCPW | REDIR | CAXS | DCC },
#endif /* STATS */
/*
* Level 50
*/
{ 0, "QSHIT", "do_shit", 50 | CCPW | CARGS },
{ 0, "RSHIT", "do_rshit", 50 | CCPW | CARGS },
{ 0, "SHIT", "do_shit", 50 | CCPW | CARGS },
{ 0, "SHITLIST", "do_shitlist", 50 | CCPW | DCC | REDIR | LBUF },
#ifdef GREET
{ 0, "GREET", "do_greet", 50 | CCPW | CARGS },
#endif /* GREET */
#ifdef TOYBOX
{ 0, "INSULT", "do_random_msg", 50 | CCPW , RANDINSULTFILE },
{ 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 | SUPRES },
#endif /* TOYBOX */
#ifdef TRIVIA
{ 0, "TRIVIA", "do_trivia", 50 | CCPW | CAXS | CARGS | CBANG },
#endif /* TRIVIA */
/*
* Level 60
*/
{ 0, "SHOWIDLE", "do_showidle", 60 | CCPW | CAXS | DCC | ACCHAN },
{ 0, "USERLIST", "do_userlist", 60 | CCPW | DCC },
#ifdef CTCP
{ 0, "CTCP", "do_ping_ctcp", 60 | CCPW | CARGS },
{ 0, "PING", "do_ping_ctcp", 60 | CCPW | CARGS },
#endif /* CTCP */
/*
* Level 70 == JOINLEVEL
*/
{ 0, "CYCLE", "do_cycle", 70 | CCPW | CAXS | ACCHAN },
{ 0, "FORGET", "do_forget", 70 | CCPW | CAXS },
{ 0, "JOIN", "do_join", 70 | CCPW | CARGS },
{ 0, "KS", "do_kicksay", 70 | CCPW | REDIR | LBUF },
{ 0, "PART", "do_part", 70 | CCPW | CAXS | ACCHAN },
{ 0, "RKS", "do_rkicksay", 70 | CCPW | CARGS },
{ 0, "SETPASS", "do_setpass", 70 | CCPW | NOPUB | CARGS },
#ifdef NOTIFY
{ 0, "NOTIFY", "do_notify", 70 | CCPW | DCC | GAXS | REDIR | LBUF },
#endif /* NOTIFY */
/*
* Level 80 == ASSTLEVEL
*/
{ 0, "AWAY", "do_away", 80 | CCPW | GAXS },
{ 0, "BOOT", "do_boot", 80 | CCPW | GAXS | CARGS },
#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 },
{ 0, "NEXTSERVER", "do_server", 80 | CCPW | GAXS },
{ 0, "SAVE", "do_save", 80 | CCPW | GAXS },
{ 0, "SERVER", "do_server", 80 | CCPW | GAXS | REDIR | LBUF },
{ 0, "SERVERGROUP", "do_servergroup", 80 | CCPW | GAXS | REDIR | LBUF },
{ 0, "STATS", "do_ircstats", 80 | CCPW | DCC | CARGS },
#ifdef ALIAS
{ 0, "ALIAS", "do_alias", 80 | CCPW | GAXS },
{ 0, "UNALIAS", "do_unalias", 80 | CCPW | GAXS | CARGS },
#endif /* ALIAS */
#ifdef TOYBOX
{ 0, "BIGSAY", "do_bigsay", 80 | CCPW | CAXS | CARGS | SUPRES },
#endif /* TOYBOX */
/*
* Level 90
*/
{ 0, "CLEARSHIT", "do_clearshit", 90 | CCPW | GAXS },
{ 0, "DO", "do_do", 90 | CCPW | GAXS | CARGS },
{ 0, "NICK", "do_nick", 90 | CCPW | GAXS | CARGS },
{ 0, "RSPY", "do_rspy", 90 | CCPW | CARGS },
{ 0, "SPY", "do_spy", 90 | CCPW },
#ifdef BOTNET
{ 0, "LINK", "do_link", 90 | CCPW | GAXS },
#endif /* BOTNET */
#ifdef DYNCMD
{ 0, "CHACCESS", "do_chaccess", 90 | CCPW | GAXS | CARGS },
#endif /* DYNCMD */
#ifdef UPTIME
{ 0, "UPSEND", "do_upsend", 90 | CCPW | GAXS },
#endif /* UPTIME */
/*
* Level 100
*/
#ifdef HOSTINFO
{ 0, "SYSINFO", "do_sysinfo", 100 | CCPW | GAXS },
{ 0, "MEMINFO", "do_meminfo", 100 | CCPW | GAXS },
{ 0, "CPUINFO", "do_cpuinfo", 100 | CCPW | GAXS },
{ 0, "FILEMON", "do_filemon", 100 | CCPW | GAXS | CARGS },
#endif /* HOSTINFO */
#ifdef RAWDNS
{ 0, "DNSSERVER", "do_dnsserver", 100 | CCPW | GAXS },
{ 0, "DNSROOT", "do_dnsroot", 100 | CCPW | GAXS | CARGS },
#endif /* RAWDNS */
{ 0, "CORE", "do_core", 100 | CCPW | REDIR | DCC },
{ 0, "DIE", "do_die", 100 | CCPW | GAXS },
{ 0, "RESET", "do_reset", 100 | CCPW | GAXS | NOCMD },
{ 0, "SHUTDOWN", "do_shutdown", 100 | CCPW | GAXS | NOPUB | NOCMD },
#ifdef DEBUG
{ 0, "DEBUG", "do_debug", 100 | CCPW | GAXS },
{ 0, "CRASH", "do_crash", 100 | CCPW | GAXS },
#endif /* DEBUG */
#ifdef PERL
#ifdef PLEASE_HACK_MY_SHELL
{ 0, "PERL", "do_perl", 100 | CCPW | GAXS | CARGS },
#endif /* PLEASE_HACK_MY_SHELL */
{ 0, "PERLSCRIPT", "do_perlscript", 100 | CCPW | GAXS | CARGS },
#endif /* PERL */
#ifdef PYTHON
#ifdef PLEASE_HACK_MY_SHELL
{ 0, "PYTHON", "do_python", 100 | CCPW | GAXS | CARGS },
#endif /* PLEASE_HACK_MY_SHELL */
{ 0, "PYTHONSCRIPT", "do_pythonscript", 100 | CCPW | GAXS | CARGS },
#endif /* PYTHON */
#ifdef TCL
#ifdef PLEASE_HACK_MY_SHELL
{ 0, "TCL", "do_tcl", 100 | CCPW | GAXS | CARGS },
#endif /* PLEASE_HACK_MY_SHELL */
{ 0, "TCLSCRIPT", "do_tcl", 100 | CCPW | GAXS | CARGS },
#endif /* TCL */
/*---*/
{ 0, NULL, NULL, 0 },
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
' ', '!', '"', '#', '$', '%', '&', 0x27,
'(', ')', '*', '+', ',', '-', '.', '/',
'0', '1', '2', '3', '4', '5', '6', '7',
'8', '9', ':', ';', '<', '=', '>', '?',
'@', 'a', 'b', 'c', 'd', 'e', 'f', 'g',
'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',
'p', 'q', 'r', 's', 't', 'u', 'v', 'w',
'x', 'y', 'z', '{', '|', '}', '~', '_',
'`', 'a', 'b', 'c', 'd', 'e', 'f', 'g',
'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',
'p', 'q', 'r', 's', 't', 'u', 'v', 'w',
'x', 'y', 'z', '{', '|', '}', '~', 0x7f,
0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7,
0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff
};
#define __define_strng 4
#define __define_print 3
#define __struct_acces 2
#define __struct_print 1
#include "onhash.h"
void make_mcmd(void)
#include "commands.h"
#define __command_hash_9 9
#define __print_hashta_7 7
#define __define_strng_5 5
#define __define_print_3 3
#define __struct_acces_2 2
#define __struct_print_1 1
static const char *getsortedcommand(int pass, int *idxout)
{
const char *pt;
char tmp[100],*tabs;
int i,j,wh,pass,ct,sl,fd;
const char *chosen;
int j,index;
chosen = NULL;
index = -1;
for(j=0;pre_mcmd[j].name;j++)
{
if (pre_mcmd[j].pass == pass)
continue;
if (chosen == NULL)
{
chosen = pre_mcmd[j].name;
index = j;
continue;
}
if (strcmp(chosen,pre_mcmd[j].name) > 0)
{
chosen = pre_mcmd[j].name;
index = j;
}
}
*idxout = index;
return(chosen);
}
void make_mcmd(int mode)
{
const char *cmdstr;
char tmp[257];
int i,j,cmdidx,pass,fd,h;
int cmdcount;
OnMsg v;
unlink("mcmd.h");
fd = open("mcmd.h",O_WRONLY|O_CREAT|O_TRUNC,0644);
if (mode == 0)
{
unlink("mcmd.h");
fd = open("mcmd.h",O_WRONLY|O_CREAT|O_TRUNC,0644);
}
if (mode == 1)
{
fd = 1;
}
pass = __define_strng;
ct = 0;
collis = 0;
pass = __command_hash_9;
cmdcount = 0;
to_file(fd,"/""* This file is automatically generated from gencmd.c *""/\n");
to_file(fd,"#ifndef TEST\n#ifndef MCMD_H\n#define MCMD_H 1\n\n");
while(pass)
{
if (pass == __struct_print)
if (pass == __command_hash_9)
{
to_file(fd,"LS const OnMsg mcmd[] =\n{\n");
memset(hash,0,sizeof(hash));
memset(hashmap,255,sizeof(hashmap));
j = 0;
if (randfd < 0)
{
randfd = open("hashdata.cache",O_RDONLY);
if (randfd > 0)
{
j = read(randfd,hashdata,sizeof(hashdata));
close(randfd);
if (j == sizeof(hashdata))
to_file(2,"gencmd: hashdata recovered from hashdata.cache\n");
}
randfd = open("/dev/urandom",O_RDONLY);
if (randfd < 0)
{
to_file(2,"gencmd: Fatal error: unable to create random hashdata from /dev/urandom!\n");
exit(50);
}
}
if (j < sizeof(hashdata))
{
j = read(randfd,hashdata,sizeof(hashdata));
}
}
if (pass == __struct_acces)
if (pass == __print_hashta_7)
{
to_file(fd,"LS OnMsg_access acmd[] =\n{\n");
}
if (pass == __struct_acces_2)
{
to_file(fd,"OnMsg_access acmd[] =\n{\n");
}
if (pass == __struct_print_1)
{
to_file(fd,"const OnMsg mcmd[] =\n{\n");
}
#ifdef HEATMAP
memset(heatmap,0,sizeof(heatmap));
#endif
for(i=0;pre_mcmd[i].name;i++)
{
pt = 0;
wh = 0;
for(j=0;pre_mcmd[j].name;j++)
const char *tabs,*tabx;
int adj;
if (pass == __command_hash_9)
{
if (pre_mcmd[j].pass != pass)
h = mkhash(pre_mcmd[i].name);
#ifdef HEATMAP
if (heatmapon > 0)
{
pt = pre_mcmd[j].name;
wh = j;
for(j=0;j<sizeof(heatmap);j++)
{
to_file(2,"%s%c",((j%32)==0) ? "\n" : "",(heatmap[j] > 0) ? (-1 + 'A' + heatmap[j]) : '.');
}
to_file(2,"\nend of heatmap for %s\n",pre_mcmd[i].name);
}
#endif
if (collis > mincoll)
break;
}
continue;
}
for(j=0;pre_mcmd[j].name;j++)
cmdstr = getsortedcommand(pass,&cmdidx);
if (pass == __define_strng_5)
{
if ((pre_mcmd[j].pass != pass) && (strcmp(pt,pre_mcmd[j].name) > 0))
}
if (pass == __define_print_3)
{
if (cmdstr)
{
pt = pre_mcmd[j].name;
wh = j;
adj = strlen(cmdstr);
tabs = ((adj) < 7) ? "\t\t" : "\t";
to_file(fd,"BEG const char C_%s[]%s\tMDEF(\"%s\");%s/""* %3i *""/\n",
cmdstr,((adj + 3) < 8) ? "\t" : "",cmdstr,tabs,cmdcount);
cmdcount++;
}
}
if (pass == __define_strng)
if (pass == __struct_acces_2)
{
//to_file(fd,"#define S_%s%s\t\"%s\"\n",pt,((strlen(pt) + 2) < 8) ? "\t" : "",pt);
to_file(fd,"\t%i,\t/""* %s *""/\n",pre_mcmd[cmdidx].flags & CLEVEL,cmdstr);
}
if (pass == __define_print)
{
//to_file(fd,"#define C_%s%s\tmcmd[%i].name\n",pt,((strlen(pt) + 2) < 8) ? "\t" : "",ct);
to_file(fd,"BEG const char C_%s[]%s\tMDEF(\"%s\");\n",pt,((strlen(pt) + 3) < 8) ? "\t" : "",pt);
ct++;
}
if (pass == __struct_acces)
{
to_file(fd,"\t%i,\t/""* %s *""/\n",
pre_mcmd[wh].flags & CLEVEL,
pt);
}
if (pass == __struct_print)
if (pass == __struct_print_1)
{
char noargfunc[64];
h = mkhash(cmdstr);
hashmap[h] = i;
memset(&v,0,sizeof(v));
v.defaultaccess = pre_mcmd[wh].flags & CLEVEL;
v.defaultaccess = pre_mcmd[cmdidx].flags & CLEVEL;
/* + defaultaccess */
v.dcc = (pre_mcmd[wh].flags & DCC) ? 1 : 0;
v.cc = (pre_mcmd[wh].flags & CC) ? 1 : 0;
v.pass = (pre_mcmd[wh].flags & PASS) ? 1 : 0;
v.args = (pre_mcmd[wh].flags & CARGS) ? 1 : 0;
v.nopub = (pre_mcmd[wh].flags & NOPUB) ? 1 : 0;
v.nocmd = (pre_mcmd[wh].flags & NOCMD) ? 1 : 0;
v.gaxs = (pre_mcmd[wh].flags & GAXS) ? 1 : 0;
v.caxs = (pre_mcmd[wh].flags & CAXS) ? 1 : 0;
v.redir = (pre_mcmd[wh].flags & REDIR) ? 1 : 0;
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;
if (v.defaultaccess >= 5) /* semi-public commands */
v.cc = 1;
if (v.defaultaccess >= 10) /* normal commands */
v.pass = 1;
sprintf(tmp,"%3i,%2i,%2i,%2i,%2i,%2i,%2i,%2i,%2i,%2i,%2i,%2i,%2i,%2i",
v.dcc = (pre_mcmd[cmdidx].flags & DCC) ? 1 : 0;
v.args = (pre_mcmd[cmdidx].flags & CARGS) ? 1 : 0;
v.nopub = (pre_mcmd[cmdidx].flags & NOPUB) ? 1 : 0;
v.nocmd = (pre_mcmd[cmdidx].flags & NOCMD) ? 1 : 0;
v.gaxs = (pre_mcmd[cmdidx].flags & GAXS) ? 1 : 0;
v.caxs = (pre_mcmd[cmdidx].flags & CAXS) ? 1 : 0;
v.redir = (pre_mcmd[cmdidx].flags & REDIR) ? 1 : 0;
v.lbuf = (pre_mcmd[cmdidx].flags & LBUF) ? 1 : 0;
v.cbang = (pre_mcmd[cmdidx].flags & CBANG) ? 1 : 0;
v.acchan = (pre_mcmd[cmdidx].flags & ACCHAN) ? 1 : 0;
v.supres = (pre_mcmd[cmdidx].flags & SUPRES) ? 1 : 0;
v.noargf = (pre_mcmd[cmdidx].flags & NOARGF) ? 1 : 0;
sprintf(tmp,"%3i,%2i,%2i,%2i,%2i,%2i,%2i,%2i,%2i,%2i,%2i,%2i,%2i,%2i,%2i",
v.defaultaccess,
v.dcc,
v.cc,
@ -380,42 +269,87 @@ void make_mcmd(void)
v.lbuf,
v.cbang,
v.acchan,
v.supres
v.supres,
v.noargf
);
sl = strlen(pre_mcmd[wh].func) + 1;
tabs = "\t\t\t";
sl = (sl & ~7) / 8;
tabs += sl;
adj = strlen(cmdstr);
if (adj < 3)
tabx = tabs + 1;
else
if (adj < 11)
tabx = tabs + 2;
else
tabx = tabs + 3;
to_file(fd,(pre_mcmd[wh].cmdarg) ? "{ C_%s,%s\t%s,%s%s\t, \"%s\"\t},\n" : "{ C_%s,%s\t%s,%s%s\t},\n",
pt,
((strlen(pt) + 5) < 8) ? "\t" : "",
pre_mcmd[wh].func,
if (v.noargf)
sprintf(noargfunc,"\n\t\t\t%s_noargs",pre_mcmd[cmdidx].func);
else
strcpy(noargfunc," 0");
adj = strlen(pre_mcmd[cmdidx].func);
tabs += 1 + ((adj > 6));
//to_file(fd,"/""* %3i=%3i *""/",h,i);
to_file(fd,(pre_mcmd[cmdidx].cmdarg) ?
"{ C_%s,%s\t%s,%s,%s%s\t, \"%s\"\t},\n" :
"{ C_%s,%s\t%s,%s,%s%s\t},\n",
cmdstr,
tabx,
pre_mcmd[cmdidx].func,
noargfunc,
tabs,
tmp,
pre_mcmd[wh].cmdarg
pre_mcmd[cmdidx].cmdarg
);
}
pre_mcmd[wh].pass = pass;
pre_mcmd[cmdidx].pass = pass;
}
if (pass == __define_strng)
if (pass == __define_strng_5)
{
/* nothing */
/* nothing */;
}
if (pass == __define_print)
if (pass == __define_print_3)
{
to_file(fd,"\n#ifdef MAIN_C\n\n");
to_file(fd,"\n/""* number of builtin commands: %i *""/\n\n",cmdcount);
if (cmdcount >= 255)
{
to_file(2,"gencmd: Hashmap overflow error\n");
exit(66);
}
to_file(fd,"#ifdef MAIN_C\n\n");
}
if (pass == __struct_print)
if (pass == __struct_print_1)
{
to_file(fd,"{ NULL, }};\n\n");
}
if (pass == __struct_acces)
if (pass == __struct_acces_2)
{
to_file(fd,"};\n\n");
}
if (pass == __command_hash_9)
{
if (collis > 0)
pass = __command_hash_9 + 1;
if (collis < mincoll)
{
mincoll = collis;
to_file(fd,"\n");
}
if (collis == 0)
{
int cachefd;
cachefd = open("hashdata.cache",O_WRONLY|O_CREAT|O_TRUNC,0644);
write(cachefd,hashdata,sizeof(hashdata));
close(cachefd);
}
to_file(2,"gencmd: Hash options tried: %8i, Collisions %4i, Best hash option so far %4i collisions%c",
mx,collis,mincoll,(collis == 0) ? '\n' : '\r');
mx++;
collis = 0;
}
pass--;
}
to_file(fd,"#define LOCALHOST_ULONG %lu\n",inet_addr("127.1"));
@ -423,8 +357,26 @@ void make_mcmd(void)
to_file(fd,"extern OnMsg mcmd[];\n");
to_file(fd,"extern OnMsg_access acmd[];\n\n");
to_file(fd,"#endif /""* MAIN_C *""/\n\n");
to_file(fd,"#endif /""* MCMD_H *""/\n\n");
to_file(fd,"#endif /""* TEST *""/\n\n");
to_file(fd,"#if defined(COM_ONS_C) || defined(MEGA_C)\n\n");
to_file(fd,"#define HASHDATAMASK\t\t%i\n",HASHDATAMASK);
to_file(fd,"#define HASHDATASZ\t\t%i\n\nconst uint8_t hashdata[HASHDATASZ] =\n{",HASHDATASZ);
for(i=0;i<HASHDATASZ;i++)
{
to_file(fd,"%s0x%02X%s",((i%16)==0) ? "\n\t" : "",hashdata[i],(i==HASHDATASZ-1) ? "" : ",");
}
to_file(fd,"\n};\n\n");
to_file(fd,"const uint8_t hashmap[%i] =\n{",sizeof(hashmap));
for(i=0;i<sizeof(hashmap);i++)
{
to_file(fd,"%s0x%02X%s",((i%16)==0) ? "\n\t" : "",hashmap[i],(i==511) ? "" : ",");
}
to_file(fd,"\n};\n\n");
to_file(fd,"#endif /""* defined(COM_ONS_C) || defined(MEGA_C) *""/\n\n");
to_file(fd,"#endif /""* not MCMD_H *""/\n\n");
to_file(fd,"#endif /""* not TEST *""/\n\n");
close(fd);
exit(0);
}
@ -439,24 +391,20 @@ void make_usercombo(void)
to_file(fd,"/""* This file is automatically generated from gencmd.c *""/\n");
#ifdef BOTNET
/* dont gatekeep these flags with ifdefs,
make userfiles compatible between different compiles */
combo.comboflags = 0; combo.x.noshare = 1;
to_file(fd,"#define COMBO_NOSHARE\t0x%x\n",combo.comboflags);
combo.comboflags = 0; combo.x.readonly = 1;
to_file(fd,"#define COMBO_READONLY\t0x%x\n",combo.comboflags);
#endif /* BOTNET */
#ifdef GREET
combo.comboflags = 0; combo.x.greetfile = 1;
to_file(fd,"#define COMBO_GREETFILE\t0x%x\n",combo.comboflags);
combo.comboflags = 0; combo.x.randline = 1;
to_file(fd,"#define COMBO_RANDLINE\t0x%x\n",combo.comboflags);
#endif /* GREET */
#ifdef BOUNCE
combo.comboflags = 0; combo.x.bounce = 1;
to_file(fd,"#define COMBO_BOUNCE\t0x%x\n",combo.comboflags);
#endif /* BOUNCE */
combo.comboflags = 0; combo.x.echo = 1;
to_file(fd,"#define COMBO_ECHO\t0x%x\n",combo.comboflags);
@ -515,7 +463,7 @@ void datestamp(void)
#ifndef HAVE_GIT
const char *srcfile[] = { "../configure", "../Makefile", "Makefile.in", "alias.c", "auth.c", "bounce.c", //"calc.c",
const char *srcfile[] = { "../configure", "../Makefile", "Makefile.in", "alias.c", "auth.c", "bounce.c", "calc.c",
"channel.c", "config.h", "config.h.in", "core.c", "ctcp.c", "debug.c", "defines.h", "dns.c", "function.c",
"gencmd.c", "global.h", "greet.c", "h.h", "help.c", "hostinfo.c", "io.c", "irc.c", "lib/string.c", "main.c",
"net.c", "note.c", "ons.c", "parse.c", "partyline.c", "perl.c", "prot.c", "python.c", "reset.c", "seen.c",
@ -562,13 +510,18 @@ void githash(void)
int main(int argc, char **argv)
{
randfd = -1;
mx = 0;
mincoll = 666666;
heatmapon = 0;
if (argv[1])
{
if (strcmp(argv[1],"usercombo.h") == 0)
make_usercombo();
if (strcmp(argv[1],"mcmd.h") == 0)
make_mcmd();
make_mcmd(0);
if (strcmp(argv[1],"testhelp") == 0)
test_help();
@ -578,6 +531,16 @@ int main(int argc, char **argv)
if (strcmp(argv[1],"githash.h") == 0)
githash();
if (strcmp(argv[1],"heatmap") == 0)
{
heatmapon = 1;
make_mcmd(1);
}
}
else
{
make_mcmd(1);
}
return(0);
}

View File

@ -1,7 +1,7 @@
/*
EnergyMech, IRC bot software
Copyright (c) 1997-2024 proton
Copyright (c) 1997-2025 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
@ -21,10 +21,10 @@
#ifndef GLOBAL_H
#define GLOBAL_H 1
#ifdef MAIN_C
#if defined(MAIN_C) || defined(TEST)
#define MDEF(x) = x
#define BEG LS
#define BEG
#else /* MAIN_C */
@ -39,11 +39,34 @@
*
*/
struct CoreData /* Collect core data all in one place */
{
time_t now;
time_t system_uptime;
Mech *current;
char *from;
char *to;
char *rest;
char *rest_end;
char *chop_end;
sai_v4 myip4; /* where to reach me by ipv4 */
sai_v6 myip6; /* where to reach me by ipv4 */
int socksmodified;
int hisock;
int short_tv;
User CoreUser;
User LocalBot;
};
BEG struct CoreData cx;
#define current cx.current
#define DEFAULTCMDCHAR '-'
#define MECHUSERLOGIN "v3.energymech.net"
BEG const char VERSION[] MDEF("3.2p" GITHASH);
BEG const char SRCDATE[] MDEF("May 13th, 2024");
BEG const char VERSION[] MDEF("3.5.dev" GITHASH);
BEG const char SRCDATE[] MDEF("November 20th, 2025");
#ifdef __CYGWIN__
BEG const char BOTCLASS[] MDEF("WinMech");
#else /* ! CYGWIN */
@ -52,10 +75,15 @@ BEG const char BOTCLASS[] MDEF("EnergyMech");
BEG const char BOTLOGIN[] MDEF("emech");
BEG const char NULLSTR[] MDEF("<NULL>");
#define EMPTYSTR (&NULLSTR[6])
BEG const char DEFAULTSTR[] MDEF("default");
BEG const char UNKNOWNATUNKNOWN[] MDEF("unknown@unknown");
#define UNKNOWN (&UNKNOWNATUNKNOWN[8])
BEG const char FMT_PLAIN[] MDEF("%s");
BEG const char FMT_PLAINLINE[] MDEF("%s\n");
BEG const char ERR_CHAN[] MDEF("I'm not on %s");
BEG const char ERR_FILEOPEN[] MDEF("Couldn't open the file %s");
BEG const char ERR_INIT[] MDEF("init: Warning:");
BEG const char ERR_NICK[] MDEF("Invalid nickname: %s");
BEG const char ERR_NOCHANNELS[] MDEF("I'm not active on any channels");
BEG const char ERR_NOTOPPED[] MDEF("I'm not opped on %s");
@ -78,10 +106,8 @@ BEG const char STR_MECHRESET[] MDEF("MECHRESET=");
BEG const char FMT_6XSTRTAB[] MDEF("%s\t%s\t%s\t%s\t%s\t%s");
#define FMT_4XSTRTAB &FMT_6XSTRTAB[6]
#define FMT_3XSTRTAB &FMT_6XSTRTAB[9]
#define FMT_PLAIN &FMT_6XSTRTAB[15]
BEG Mech *botlist MDEF(NULL);
BEG Mech *current;
BEG char *executable;
BEG char *configfile MDEF(CFGFILE);
@ -99,9 +125,6 @@ BEG ino_t parent_inode;
BEG KillSock *killsocks MDEF(NULL);
BEG Server *serverlist MDEF(NULL);
BEG ServerGroup *servergrouplist MDEF(NULL);
BEG ServerGroup *currentservergroup MDEF(NULL);
BEG int servergroupid MDEF(0);
BEG int serverident MDEF(1);
BEG char CurrentNick[NUHLEN];
@ -113,9 +136,6 @@ BEG const OnMsg *CurrentCmd MDEF(NULL);
BEG User *cfgUser MDEF(NULL);
BEG const char *global_from MDEF(NULL);
BEG User __internal_users[2];
#define CoreUser (__internal_users[0])
#define LocalBot (__internal_users[1])
/*
* generic output buffer, can be used as buffer in any `leaf' function
@ -131,14 +151,6 @@ BEG char nuh_buf[NUHLEN];
BEG fd_set read_fds;
BEG fd_set write_fds;
BEG int hisock;
BEG int short_tv;
/*
* current UNIX timestamp
*/
BEG time_t now;
/*
* defined features
@ -152,9 +164,6 @@ BEG Alias *aliaslist MDEF(NULL);
#ifdef BOTNET
BEG const char UNKNOWNATUNKNOWN[] MDEF("unknown@unknown");
#define UNKNOWN (&UNKNOWNATUNKNOWN[8])
BEG BotNet *botnetlist MDEF(NULL);
BEG NetCfg *netcfglist MDEF(NULL);
BEG char *linkpass MDEF(NULL); /* proc var */
@ -184,6 +193,7 @@ BEG time_t ctcp_slot[CTCP_SLOTS];
BEG char debugbuf[MAXLEN];
BEG char *debugfile MDEF(NULL);
BEG int debugfilemalloc MDEF(FALSE);
BEG int dodebug MDEF(FALSE);
BEG int debug_fd MDEF(-1);
BEG int debug_on_exit MDEF(FALSE);
@ -204,6 +214,8 @@ BEG Note *notelist MDEF(NULL);
#ifdef RAWDNS
BEG int dnssock MDEF(-1);
BEG int dnsserver MDEF(0);
BEG dnsList *dnslist MDEF(NULL);
BEG dnsAuthority *dnsroot MDEF(NULL);
BEG struct in_addr ia_ns[MAX_NAMESERVERS];
@ -241,12 +253,12 @@ BEG Seen *seenlist MDEF(NULL);
#endif /* SEEN */
BEG char *fontname MDEF(NULL);
BEG BigC *fontlist MDEF(NULL);
BEG int charlines;
BEG int charheight;
BEG int spacewidth;
BEG int kerning;
BEG char *fontname MDEF(NULL);
BEG BigC *fontlist MDEF(NULL);
BEG int charlines;
BEG int charheight;
BEG int spacewidth;
BEG int kerning;
#ifdef TRIVIA
@ -254,6 +266,7 @@ BEG int triv_qdelay MDEF(30); /* proc var */
BEG char *triv_qfile MDEF(NULL); /* proc var */
BEG char triv_qchar MDEF('*'); /* proc var */
BEG TrivScore *scorelist MDEF(NULL);
BEG time_t triv_next_time MDEF(0);
#endif /* TRIVIA */
@ -264,7 +277,7 @@ BEG char *uptimehost MDEF(NULL); /* proc var */
BEG char *uptimenick MDEF(NULL); /* proc var */
BEG int uptimesock;
BEG uint32_t uptimeip MDEF((uint32_t)-1);
BEG uint32_t uptimecookie;
BEG uint32_t uptimepackets MDEF(0);
BEG uint32_t uptimeregnr MDEF(0);
BEG time_t uptimelast MDEF(0);
BEG const char *defaultuptimehost MDEF("uptime.eggheads.org");
@ -300,14 +313,14 @@ BEG int spawning_lamer MDEF(0);
#define CRLF 0x08
#define FNICK (NICK|FIRST)
#define NNICK (NICK|NUM)
#define NUMNI (NICK|NUM)
#if defined(MAIN_C) || defined(MAKETABLES)
/*
* tolowertab blatantly ripped from ircu2.9.32
*/
LS const uchar tolowertab[256] =
const uchar tolowertab[256] =
{
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
@ -346,7 +359,7 @@ LS const uchar tolowertab[256] =
/*
* be wary, this is not a normal upper-to-lower table...
*/
LS const uchar nickcmptab[256] =
const uchar nickcmptab[256] =
{
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
@ -382,7 +395,16 @@ LS const uchar nickcmptab[256] =
0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff
};
LS const uchar attrtab[256] =
/*
#define NUM 0x01
#define NICK 0x02
#define FIRST 0x04
#define CRLF 0x08
#define FNICK (NICK|FIRST)
#define NUMNI (NICK|NUM)
*/
const uchar attrtab[256] =
{
0, 0, 0, 0, 0, 0, 0, 0, /* 0x00 - 0x07 */
0, 0, CRLF, 0, 0, CRLF, 0, 0, /* 0x08 - 0x0F */
@ -390,8 +412,10 @@ LS const uchar attrtab[256] =
0, 0, 0, 0, 0, 0, 0, 0, /* 0x18 - 0x1F */
0, 0, 0, 0, 0, 0, 0, 0, /* 0x20 - 0x27 */
0, 0, 0, 0, 0, NICK, 0, 0, /* 0x28 - 0x2F */
NNICK, NNICK, NNICK, NNICK, NNICK, NNICK, NNICK, NNICK, /* 0x30 - 0x37 */
NNICK, NNICK, 0, 0, 0, 0, 0, 0, /* 0x38 - 0x3F */
NUMNI, NUMNI, NUMNI, NUMNI, NUMNI, NUMNI, NUMNI, NUMNI, /* 0x30 - 0x37 */
NUMNI, NUMNI, 0, 0, 0, 0, 0, 0, /* 0x38 - 0x3F */
0, FNICK, FNICK, FNICK, FNICK, FNICK, FNICK, FNICK, /* 0x40 - 0x47 */
FNICK, FNICK, FNICK, FNICK, FNICK, FNICK, FNICK, FNICK, /* 0x48 - 0x4F */
FNICK, FNICK, FNICK, FNICK, FNICK, FNICK, FNICK, FNICK, /* 0x50 - 0x57 */
@ -425,7 +449,7 @@ LS const uchar attrtab[256] =
/*
* user struct for the core client
*/
LS const Strp CMA =
const Strp CMA =
{
NULL,
"*"
@ -434,37 +458,23 @@ LS const Strp CMA =
/*
* client struct for the core client
*/
LS ShortClient CoreClient =
ShortClient CoreClient =
{
NULL, /* next */
(User*)&CoreUser, /* user */
(User*)&cx.CoreUser, /* user */
-1, /* socket */
0, /* flags */
0, /* inputcount */
0 /* lasttime */
};
LS ShortChan CoreChan =
ShortChan CoreChan =
{
NULL,
NULL
};
typedef struct coreServerGroup
{
ServerGroup *next;
int servergroup;
char name[8];
} coreServerGroup;
LS coreServerGroup defaultServerGroup =
{
NULL, /* next */
0, /* servergroup */
"default" /* name */
};
LS struct
struct
{
const char *string;
const int id;
@ -482,11 +492,8 @@ LS struct
extern const uchar tolowertab[];
extern const uchar nickcmptab[];
extern const uchar attrtab[];
extern const User xxCoreUser;
extern const User xxLocalBot;
extern ShortClient CoreClient;
extern ShortChan CoreChan;
extern ServerGroup defaultServerGroup;
#endif /* MAIN_C */

605
src/h.h
View File

@ -1,7 +1,7 @@
/*
EnergyMech, IRC bot software
Copyright (c) 1997-2024 proton
Copyright (c) 1997-2025 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
@ -21,17 +21,28 @@
#ifndef H_H
#define H_H 1
#if !defined(__STRICT_ANSI__)
#define __INLINE__ inline
#else
#define __INLINE__
#endif
#if defined(__GNUC__)
#define __notused__ __attribute__((unused))
#else
#define __notused__
#endif
#define ischannel(x) (*x == '#')
#define nullstr(x) ((x)) ? (x) : NULLSTR
#define nullstr(x) ((x) ? x : NULLSTR)
#define nullbuf(x) (x && *x) ? x : NULLSTR
#define chkhigh(x) if (x > hisock) { hisock = x; }
#define chkhigh(x) if (x > cx.hisock) { cx.hisock = x; }
#define COMMAND_ARGS char *from, const char *to, char *rest, const int cmdaccess
#define STRCHR stringchr
#define STREND(x) STRCHR(x,0)
#define STREND(x) stringchr(x,0)
/*
* some default code for socket flags
@ -67,14 +78,6 @@
#define __att2(x,y,z) /* nothing */
#endif
/* __x86_64__ automatically compiles for regparm optimization */
#if !defined(__profiling__) && defined(__i386__)
# define __regparm(x) regparm(x)
#else
# define __regparm(x)
#endif
#define CORE_SEG ".text.a"
#define CFG1_SEG ".text.b"
#define CMD1_SEG ".text.c"
@ -110,23 +113,24 @@
/* alias.c */
LS void afmt(char *, const char *, const char *) __page(CORE_SEG);
LS void do_alias(COMMAND_ARGS) __page(CMD1_SEG);
LS void do_unalias(COMMAND_ARGS) __page(CMD1_SEG);
void afmt(char *, const char *, const char *) __page(CORE_SEG);
void do_alias(COMMAND_ARGS) __page(CMD1_SEG);
void do_unalias(COMMAND_ARGS) __page(CMD1_SEG);
/* auth.c */
LS char *cipher(char *) __page(CMD1_SEG);
LS char *makepass(char *) __page(CMD1_SEG);
LS int passmatch(char *, char *) __page(CMD1_SEG);
LS void delete_auth(char *) __page(CMD1_SEG);
LS void remove_auth(Auth *) __page(CMD1_SEG);
LS void change_authnick(char *, char *) __page(CORE_SEG);
LS void aucheck(User *) __page(CORE_SEG);
LS User *get_authuser(const char *, const char *) __page(CORE_SEG);
LS int get_authaccess(const char *, const char *) __page(CORE_SEG);
LS int make_auth(const char *, const User *) __page(CMD1_SEG);
LS void do_auth(COMMAND_ARGS) __page(CMD1_SEG);
char *cipher(char *) __page(CMD1_SEG);
char *makepass(char *) __page(CMD1_SEG);
int passmatch(char *, char *) __page(CMD1_SEG);
void delete_auth(char *) __page(CMD1_SEG);
void remove_auth(Auth *) __page(CMD1_SEG);
void change_authnick(char *, char *) __page(CORE_SEG);
void aucheck(User *) __page(CORE_SEG);
User *get_authuser(const char *, const char *) __page(CORE_SEG);
int get_authaccess(const char *, const char *) __page(CORE_SEG);
int make_auth(const char *, const User *) __page(CMD1_SEG);
void do_auth_noargs(const char *) __page(CMD1_SEG);
void do_auth(COMMAND_ARGS) __page(CMD1_SEG);
/* bounce.c */
@ -138,62 +142,71 @@ void process_bounce(void) __page(CORE_SEG);
/* calc.c */
LS void do_convert(COMMAND_ARGS) __page(CMD1_SEG);
LS void do_calc(COMMAND_ARGS) __page(CMD1_SEG);
void do_calc(COMMAND_ARGS) __page(CMD1_SEG);
void do_convert(COMMAND_ARGS) __page(CMD1_SEG);
/* channel.c */
void check_idlekick(void);
LS Chan *find_channel(const char *, int) __attr(CORE_SEG, __regparm(2));
LS Chan *find_channel_ac(const char *) __attr(CORE_SEG, __regparm(1));
LS Chan *find_channel_ny(const char *) __attr(CORE_SEG, __regparm(1));
Chan *find_channel(const char *, int) __page(CORE_SEG);
Chan *find_channel_ac(const char *) __page(CORE_SEG);
Chan *find_channel_ny(const char *) __page(CORE_SEG);
void remove_chan(Chan *) __page(CMD1_SEG);
void join_channel(char *, char *) __page(CFG1_SEG);
void reverse_topic(Chan *, char *, char *) __page(CORE_SEG);
void cycle_channel(Chan *) __page(CMD1_SEG);
int reverse_mode(char *, Chan *, int, int) __page(CORE_SEG);
void chan_modestr(Chan *, char *) __page(CORE_SEG);
char *get_nuh(const ChanUser *) __page(CORE_SEG);
char *find_nuh(char *) __page(CORE_SEG);
char *nick2uh(char *, char *) __page(CORE_SEG);
Ban *make_ban(Ban **, char *, char *, time_t);
void delete_ban(Chan *, char *);
void delete_modemask(Chan *, char *, int);
void channel_massmode(const Chan *, char *, int, char, char);
void channel_massunban(Chan *, char *, time_t);
LS ChanUser *find_chanuser(Chan *, const char *) __page(CORE_SEG);
LS ChanUser *find_chanbot(Chan *, const char *) __page(CORE_SEG);
LS void remove_chanuser(Chan *, const char *) __page(CORE_SEG);
LS void make_chanuser(char *, char *) __page(CORE_SEG);
LS void purge_chanusers(Chan *) __page(CMD1_SEG);
LS char *get_nuh(const ChanUser *) __page(CORE_SEG);
LS void do_join(COMMAND_ARGS) __page(CMD1_SEG);
LS void do_part(COMMAND_ARGS) __page(CMD1_SEG);
LS void do_cycle(COMMAND_ARGS) __page(CMD1_SEG);
LS void do_forget(COMMAND_ARGS) __page(CMD1_SEG);
LS void do_channels(COMMAND_ARGS) __page(CMD1_SEG);
LS void do_wall(COMMAND_ARGS) __page(CMD1_SEG);
LS void do_mode(COMMAND_ARGS) __page(CMD1_SEG);
LS void do_names(COMMAND_ARGS) __page(CMD1_SEG);
LS void do_cchan(COMMAND_ARGS) __page(CMD1_SEG);
LS void do_invite(COMMAND_ARGS) __page(CMD1_SEG);
LS void do_sayme(COMMAND_ARGS) __page(CMD1_SEG);
LS void do_who(COMMAND_ARGS) __page(CMD1_SEG);
LS void do_topic(COMMAND_ARGS) __page(CMD1_SEG);
LS void do_showidle(COMMAND_ARGS) __page(CMD1_SEG);
LS void do_idle(COMMAND_ARGS) __page(CMD1_SEG);
ChanUser *find_chanuser(Chan *, const char *) __page(CORE_SEG);
ChanUser *find_chanbot(Chan *, const char *) __page(CORE_SEG);
void remove_chanuser(Chan *, const char *) __page(CORE_SEG);
void make_chanuser(char *, char *) __page(CORE_SEG);
void purge_chanusers(Chan *) __page(CMD1_SEG);
void do_join(COMMAND_ARGS) __page(CMD1_SEG);
void do_part(COMMAND_ARGS) __page(CMD1_SEG);
void do_cycle(COMMAND_ARGS) __page(CMD1_SEG);
void do_forget(COMMAND_ARGS) __page(CMD1_SEG);
void do_channels(COMMAND_ARGS) __page(CMD1_SEG);
void do_wall(COMMAND_ARGS) __page(CMD1_SEG);
void do_mode(COMMAND_ARGS) __page(CMD1_SEG);
void do_names(COMMAND_ARGS) __page(CMD1_SEG);
void do_cchan(COMMAND_ARGS) __page(CMD1_SEG);
void do_invite(COMMAND_ARGS) __page(CMD1_SEG);
void do_sayme(COMMAND_ARGS) __page(CMD1_SEG);
void do_who(COMMAND_ARGS) __page(CMD1_SEG);
void do_topic(COMMAND_ARGS) __page(CMD1_SEG);
void do_showidle(COMMAND_ARGS) __page(CMD1_SEG);
void do_idle(COMMAND_ARGS) __page(CMD1_SEG);
/* core.c */
void unlink_identfile(void);
#define getbotnicklen(z) (z->nick.opt)
#define getbotnick(z) ((z->nick.opt < 16) ? z->nick.x.string : z->nick.x.ptr)
#define getbotwantnick(z) ((z->wantnick.opt < 16) ? z->wantnick.x.string : z->wantnick.x.ptr)
#define getbotuserhost(z) ((z->userhost.opt == 0) ? UNKNOWNATUNKNOWN : ((z->userhost.opt < 64) ? z->userhost.x.string : z->userhost.x.ptr))
#define setbotnick(z,y) set_mix16(&z->nick,y)
#define setbotwantnick(z,y) set_mix16(&z->wantnick,y)
#define setbotuserhost(z,y) set_mix64(&z->userhost,y)
void set_mix16(Mix16 *, const char *) __page(CORE_SEG);
void set_mix64(Mix64 *, const char *) __page(CORE_SEG);
int conf_callback(char *line) __page(CFG1_SEG);
void readcfgfile(void) __page(CFG1_SEG);
void readcfgfile(void) __page(INIT_SEG);
int write_session(void) __page(CORE_SEG);
void setbotnick(Mech *bot, char *nick) __page(CFG1_SEG);
Mech *add_bot(int guid, char *nick) __page(CFG1_SEG);
void signoff(char *from, char *reason) __page(RARE_SEG);
void kill_all_bots(char *reason) __attr(RARE_SEG, __noreturn__);;
Server *add_server(char *host, int port, char *pass) __page(CFG1_SEG);
ServerGroup *getservergroup(const char *name);
ServerGroup *getservergroupid(int id);
Server *add_server(const char *host, const int port, const char *pass, const char *group) __page(CFG1_SEG);
Server *find_server(int id) __page(CORE_SEG);
int try_server(Server *sp, char *hostname) __page(CORE_SEG);
void connect_to_server(void) __page(CORE_SEG);
@ -206,7 +219,7 @@ void do_version(COMMAND_ARGS) __page(CMD1_SEG);
void do_core(COMMAND_ARGS) __page(CMD1_SEG);
void do_die(COMMAND_ARGS) __page(RARE_SEG);
void do_shutdown(COMMAND_ARGS) __page(RARE_SEG);
void do_servergroup(COMMAND_ARGS) __page(CMD1_SEG);
void do_server_noargs(const char *from) __page(CMD1_SEG);
void do_server(COMMAND_ARGS) __page(CMD1_SEG);
void do_cserv(COMMAND_ARGS) __page(CMD1_SEG);
void do_away(COMMAND_ARGS) __page(CMD1_SEG);
@ -253,8 +266,9 @@ char *uint32tobin(int limit, uint32_t x);
void debug_scripthook(void);
void run_debug(void);
int wrap_debug(void);
void do_debug(COMMAND_ARGS) __page(CMD1_SEG);
void do_crash(COMMAND_ARGS) __page(RARE_SEG);
void do_debug(COMMAND_ARGS) __page(CMD1_SEG);
void do_inject(COMMAND_ARGS) __page(CMD1_SEG);
void debug(char *format, ...) __page(CORE_SEG);
/* dns.c */
@ -277,43 +291,34 @@ void do_dnsserver(COMMAND_ARGS) __page(CMD1_SEG);
void do_dns(COMMAND_ARGS) __page(CMD1_SEG);
/* dynamode.c */
/* function.c */
LS void *Calloc(int) __attr(CORE_SEG, __regparm(1));
LS void Free(char **) __attr(CORE_SEG, __regparm(1));
LS Strp *make_strp(Strp **, const char *) __attr(CORE_SEG, __regparm(2));
LS Strp *append_strp(Strp **, const char *) __attr(CORE_SEG, __regparm(2));
LS Strp *prepend_strp(Strp **, const char *) __attr(CORE_SEG, __regparm(2));
LS void purge_linklist(void **) __attr(CORE_SEG, __regparm(1));
LS void dupe_strp(Strp *, Strp **) __attr(CORE_SEG, __regparm(2));
LS const int StrlenX(const char *, ...) __attr(CORE_SEG, __regparm(1));
LS const int Strlen2(const char *, const char *) __attr(CORE_SEG, __regparm(2));
LS char *getuh(char *) __page(CORE_SEG);
LS char *get_token(char **, const char *) __page(CORE_SEG);
LS char *logtime(time_t) __page(CORE_SEG);
LS char *time2str(time_t) __page(CORE_SEG);
LS char *time2away(time_t) __page(CORE_SEG);
LS char *time2medium(time_t) __page(CORE_SEG);
LS char *time2small(time_t) __page(CORE_SEG);
LS char *idle2str(time_t, int) __page(CORE_SEG);
LS const char *get_channel(const char *, char **) __page(CORE_SEG);
LS const char *get_channel2(const char *, char **) __page(CORE_SEG);
LS char *cluster(char *) __page(CORE_SEG);
LS char *format_uh(char *, int) __page(CORE_SEG);
LS char *nick2uh(char *, char *) __page(CORE_SEG);
LS void deop_ban(Chan *, ChanUser *, char *) __page(CORE_SEG);
LS void deop_siteban(Chan *, ChanUser *) __page(CORE_SEG);
LS void screwban_format(char *) __page(CORE_SEG);
LS void deop_screwban(Chan *, ChanUser *) __page(CORE_SEG);
LS int is_nick(const char *) __attr(CORE_SEG, __regparm(1));
LS int asc2int(const char *) __attr(CORE_SEG, __regparm(1));
LS int get_number(const char *) __attr(CORE_SEG, __regparm(1));
LS void fix_config_line(char *) __page(CFG1_SEG);
LS int matches(const char *, const char *) __attr(CORE_SEG, __regparm(2));
LS int num_matches(const char *, const char *) __attr(CORE_SEG, __regparm(2));
LS void table_buffer(const char *, ...) __page(CMD1_SEG);
LS void table_send(const char *, const int) __page(CMD1_SEG);
LS int is_safepath(const char *, int) __attr(CORE_SEG, __regparm(2));
void *Calloc(int) __page(CORE_SEG);
void Free(char **) __page(CORE_SEG);
Strp *make_strp(Strp **, const char *) __page(CORE_SEG);
Strp *append_strp(Strp **, const char *) __page(CORE_SEG);
Strp *prepend_strp(Strp **, const char *) __page(CORE_SEG);
void purge_linklist(void **) __page(CORE_SEG);
void dupe_strp(Strp *, Strp **) __page(CORE_SEG);
const int StrlenX(const char *, ...) __page(CORE_SEG);
const int Strlen2(const char *, const char *) __page(CORE_SEG);
char *getuh(char *) __page(CORE_SEG);
char *get_token(char **, const char *) __page(CORE_SEG);
char *maketimestr(time_t, int) __page(CORE_SEG);
char *idle2str(time_t, int) __page(CORE_SEG);
const char *get_channel(const char *, char **) __page(CORE_SEG);
const char *get_channel2(const char *, char **) __page(CORE_SEG);
char *cluster(char *) __page(CORE_SEG);
char *format_uh(char *, int) __page(CORE_SEG);
int is_nick(const char *) __page(CORE_SEG);
int asc2int(const char *) __page(CORE_SEG);
int get_number(const char *) __page(CORE_SEG);
void parse_range(char **, int *) __page(CORE_SEG);
void fix_config_line(char *) __page(CFG1_SEG);
int matches(const char *, const char *) __page(CORE_SEG);
int num_matches(const char *, const char *) __page(CORE_SEG);
int is_safepath(const char *, int) __page(CORE_SEG);
/* greet.c */
@ -343,25 +348,27 @@ void do_filemon(COMMAND_ARGS) __page(CMD1_SEG);
/* io.c */
LS uint32_t get_ip(const char *) __page(CORE_SEG);
LS void SockFlags(int) __page(CORE_SEG);
LS int SockOpts(void) __page(CORE_SEG);
LS int SockListener(int) __page(CORE_SEG);
LS int SockConnect(char *, int, int) __page(CORE_SEG);
LS int SockAccept(int) __page(CORE_SEG);
uint32_t get_ip(const char *) __page(CORE_SEG);
void SockFlags(int) __page(CORE_SEG);
int SockOpts(void) __page(CORE_SEG);
int SockListener(int) __page(CORE_SEG);
int SockConnect(char *, int, int) __page(CORE_SEG);
int SockAccept(int) __page(CORE_SEG);
int to_file(const int sock, const char *format, ...) __page(CORE_SEG);
void to_server(char *format, ...) __page(CORE_SEG);
void to_server(const char *format, ...) __page(CORE_SEG);
void to_user_q(const char *, const char *, ...) __page(CMD1_SEG);
void to_user(const char *, const char *, ...) __page(CORE_SEG);
void table_buffer(const char *, ...) __page(CMD1_SEG);
void table_send(const char *, const int) __page(CMD1_SEG);
char *sockread(int, char *, char *) __page(CORE_SEG);
void readline(int, int (*)(char *)) __page(CMD1_SEG);
void remove_ks(KillSock *);
int killsock(int);
LS void do_clearqueue(COMMAND_ARGS) __page(CMD1_SEG);
void do_clearqueue(COMMAND_ARGS) __page(CMD1_SEG);
/* irc.c */
LS void make_ireq(int, const char *, const char *) __page(CMD1_SEG);
void make_ireq(int, const char *, const char *) __page(CMD1_SEG);
void send_pa(int type, const char *nick, const char *format, ...);
void do_irclusers(COMMAND_ARGS) __page(CMD1_SEG);
void do_ircstats(COMMAND_ARGS) __page(CMD1_SEG);
@ -376,50 +383,51 @@ void purge_kicklist(void);
void do_kicksay(COMMAND_ARGS) __page(CMD1_SEG);
void do_rkicksay(COMMAND_ARGS) __page(CMD1_SEG);
/* lib/string.c */
/* string.c */
LS char *chop(char **) __attr(CORE_SEG, __regparm(1));
LS void unchop(char *, const char *) __attr(CORE_SEG, __regparm(2));
LS int stringcasecmp(const char *, const char *) __attr(CORE_SEG, __regparm(2));
LS int stringcmp(const char *, const char *) __attr(CORE_SEG, __regparm(2));
LS int nickcmp(const char *, const char *) __attr(CORE_SEG, __regparm(2));
LS char *nickcpy(char *, const char *) __attr(CORE_SEG, __regparm(2));
LS void stringcpy_n(char *, const char *, int) __attr(CORE_SEG, __regparm(3));
LS char *stringcpy(char *, const char *) __attr(CORE_SEG, __regparm(2));
LS char *stringchr(const char *, int) __attr(CORE_SEG, __regparm(2));
LS char *stringdup(const char *) __attr(CORE_SEG, __regparm(1));
LS char *stringcat(char *, const char *) __attr(CORE_SEG, __regparm(2));
LS char *tolowercat(char *, const char *) __attr(CORE_SEG, __regparm(2));
char *chop(char **) __page(CORE_SEG);
void unchop(char *, const char *) __page(CORE_SEG);
int stringcasecmp(const char *, const char *) __page(CORE_SEG);
int stringcmp(const char *, const char *) __page(CORE_SEG);
int nickcmp(const char *, const char *) __page(CORE_SEG);
char *nickcpy(char *, const char *) __page(CORE_SEG);
void stringcpy_n(char *, const char *, int) __page(CORE_SEG);
char *stringcpy(char *, const char *) __page(CORE_SEG);
char *stringchr(const char *, int) __page(CORE_SEG);
char *stringdup(const char *) __page(CORE_SEG);
char *stringcat(char *, const char *) __page(CORE_SEG);
char *tolowercat(char *, const char *) __page(CORE_SEG);
/* main.c */
void mech_exec(void) __page(RARE_SEG);
int randstring_count(char *line) __page(CMD1_SEG);
int randstring_getline(char *line) __page(CMD1_SEG);
LS char *randstring(const char *) __page(CORE_SEG);
LS int sig_hup_callback(char *) __page(RARE_SEG); /* rare */
LS void do_sighup(void) __page(CMD1_SEG);
LS void sig_hup(int) __page(RARE_SEG); /* rare */
LS void sig_child(int) __page(RARE_SEG); /* rare */
LS void sig_alrm(int) __page(RARE_SEG); /* rare */
LS void sig_pipe(int) __page(CORE_SEG);
LS void do_sigusr1(void) __page(CMD1_SEG);
LS void sig_usr1(int) __page(CMD1_SEG);
LS void sig_usr2(int) __page(DBUG_SEG); /* DEBUG */
LS void sig_suicide() __attr(RARE_SEG, __noreturn__); /* rare */
LS void do_sigint(void) __page(RARE_SEG); /* rare */
LS void sig_int(int) __page(RARE_SEG); /* rare */
LS void sig_ill(int) __page(RARE_SEG);
LS void sig_abrt(int) __page(RARE_SEG);
LS void sig_bus(int) __page(CMD1_SEG);
char *randstring(const char *) __page(CORE_SEG);
int sig_hup_callback(char *) __page(RARE_SEG); /* rare */
void do_sighup(void) __page(CMD1_SEG);
void sig_hup(int) __page(RARE_SEG); /* rare */
void sig_child(int) __page(RARE_SEG); /* rare */
void sig_alrm(int) __page(RARE_SEG); /* rare */
void sig_pipe(int) __page(CORE_SEG);
void do_sigusr1(void) __page(CMD1_SEG);
void sig_usr1(int) __page(CMD1_SEG);
void sig_usr2(int) __page(DBUG_SEG); /* DEBUG */
void sig_suicide() __attr(RARE_SEG, __noreturn__); /* rare */
void do_sigint(void) __attr(RARE_SEG, __noreturn__); /* rare */
void sig_int(int) __page(RARE_SEG); /* rare */
void sig_ill(int) __page(RARE_SEG);
void sig_abrt(int) __page(RARE_SEG);
void sig_bus(int) __attr(RARE_SEG, __noreturn__);
#if defined(__linux__) && defined(__x86_64__) && defined(DEBUG) && !defined(__STRICT_ANSI__)
LS void sig_segv(int, siginfo_t *, void *) __attr(RARE_SEG, __noreturn__);
void sig_segv(int, siginfo_t *, void *) __attr(RARE_SEG, __noreturn__);
#else
LS void sig_segv(int) __attr(RARE_SEG, __noreturn__);
void sig_segv(int) __attr(RARE_SEG, __noreturn__);
#endif
LS void sig_term(int) __attr(RARE_SEG, __noreturn__); /* rare */
LS void doit(void) __page(CORE_SEG);
LS int main(int argc, char **argv, char **envp) __page(INIT_SEG);
void sig_term(int) __attr(RARE_SEG, __noreturn__); /* rare */
int main(int argc, char **argv, char **envp) __page(INIT_SEG);
void parse_commandline(int argc, char **argv, char **envp) __page(INIT_SEG);
void mainloop(void) __attr(CORE_SEG, __noreturn__);
/* net.c */
@ -434,15 +442,15 @@ void botnet_binfo_relay(BotNet *source, BotInfo *binfo);
void botnet_binfo_tofile(int sock, BotInfo *binfo);
void botnet_dumplinklist(BotNet *bn);
int connect_to_bot(NetCfg *cfg);
LS void check_botjoin(Chan *chan, ChanUser *cu);
LS void check_botinfo(BotInfo *binfo, const char *channel);
void check_botjoin(Chan *chan, ChanUser *cu);
void check_botinfo(BotInfo *binfo, const char *channel);
void basicAuth(BotNet *bn, char *rest);
void basicAuthOK(BotNet *bn, char *rest);
void basicBanner(BotNet *bn, char *rest);
void basicLink(BotNet *bn, char *version);
void basicQuit(BotNet *bn, char *rest);
LS void netchanNeedop(BotNet *source, char *rest);
LS void netchanSuppress(BotNet *, char *) __page(CORE_SEG);
void netchanNeedop(BotNet *source, char *rest);
void netchanSuppress(BotNet *, char *) __page(CORE_SEG);
void partyAuth(BotNet *bn, char *rest);
int commandlocal(int dg, int sg, char *from, char *command);
void partyCommand(BotNet *bn, char *rest);
@ -454,12 +462,13 @@ void parse_botnet(BotNet *bn, char *rest);
void botnet_newsock(void);
void select_botnet(void) __page(CORE_SEG);
void process_botnet(void) __page(CORE_SEG);
void do_link_noargs(const char *) __page(CMD1_SEG);
void do_link(COMMAND_ARGS) __page(CMD1_SEG);
void do_cmd(COMMAND_ARGS) __page(CMD1_SEG);
/* note.c */
int catch_note(char *from, char *to, char *rest);
int catch_note(char *from, char *to, char *rest) __page(CMD1_SEG);
void do_note(COMMAND_ARGS) __page(CMD1_SEG);
void do_read(COMMAND_ARGS) __page(CMD1_SEG);
@ -482,104 +491,108 @@ void do_notify(COMMAND_ARGS) __page(CMD1_SEG);
/* ons.c */
LS uint32_t makecrc(const char *) __page(CORE_SEG);
LS void send_suppress(const char *, const char *) __page(CORE_SEG);
LS void on_kick(char *from, char *rest) __page(CORE_SEG);
LS void on_join(Chan *chan, char *from) __page(CORE_SEG);
LS void on_nick(char *from, char *newnick) __page(CORE_SEG);
LS void on_msg(char *from, char *to, char *rest) __page(CORE_SEG);
LS void on_mode(char *from, char *channel, char *rest) __page(CORE_SEG);
LS void common_public(Chan *chan, char *from, char *spyformat, char *rest) __page(CORE_SEG);
LS void on_action(char *from, char *to, char *rest) __page(CORE_SEG);
LS int access_needed(char *name) __page(CORE_SEG);
LS void do_chaccess(COMMAND_ARGS) __page(CMD1_SEG);
LS void do_last(COMMAND_ARGS) __page(CMD1_SEG);
uint32_t makecrc(const char *) __page(CORE_SEG);
void send_suppress(const char *, const char *) __page(CORE_SEG);
void on_kick(char *from, char *rest) __page(CORE_SEG);
void on_join(Chan *chan, char *from) __page(CORE_SEG);
void on_nick(char *from, char *newnick) __page(CORE_SEG);
int mkhash(const char *) __page(CORE_SEG);
void on_msg(char *from, char *to, char *rest) __page(CORE_SEG);
void on_mode(char *from, char *channel, char *rest) __page(CORE_SEG);
void common_public(Chan *chan, char *from, char *spyformat, char *rest) __page(CORE_SEG);
void on_action(char *from, char *to, char *rest) __page(CORE_SEG);
int access_needed(char *name) __page(CORE_SEG);
void do_chaccess(COMMAND_ARGS) __page(CMD1_SEG);
void do_last(COMMAND_ARGS) __page(CMD1_SEG);
/* parse.c */
LS void parse_error(char *from, char *rest) __page(CORE_SEG);
LS void parse_invite(char *from, char *rest) __page(CMD1_SEG);
LS void parse_join(char *from, char *rest) __page(CORE_SEG);
LS void parse_mode(char *from, char *rest) __page(CORE_SEG);
LS void parse_notice(char *from, char *rest) __page(CORE_SEG);
LS void parse_part(char *from, char *rest) __page(CORE_SEG);
LS void parse_ping(char *from, char *rest) __page(CORE_SEG);
LS void parse_pong(char *from, char *rest) __page(CORE_SEG);
LS void parse_privmsg(char *from, char *rest) __page(CORE_SEG);
LS void parse_quit(char *from, char *rest) __page(CORE_SEG);
LS void parse_topic(char *from, char *rest) __page(CORE_SEG);
LS void parse_wallops(char *from, char *rest) __page(CORE_SEG);
LS void parse_213(char *from, char *rest);
LS void parse_219(char *from, char *rest);
LS void parse_251(char *from, char *rest);
LS void parse_252(char *from, char *rest);
LS void parse_253(char *from, char *rest);
LS void parse_254(char *from, char *rest);
LS void parse_255(char *from, char *rest);
LS void parse_301(char *from, char *rest);
LS void parse_303(char *from, char *rest);
LS void parse_311(char *from, char *rest);
LS void parse_312(char *from, char *rest);
LS void parse_313(char *from, char *rest);
LS void parse_315(char *from, char *rest);
LS void parse_317(char *from, char *rest);
LS void parse_318(char *from, char *rest);
LS void parse_319(char *from, char *rest);
LS void parse_324(char *from, char *rest);
LS void parse_352(char *from, char *rest);
LS void parse_367(char *from, char *rest);
LS void parse_376(char *from, char *rest);
LS void parse_401(char *from, char *rest);
LS void parse_433(char *from, char *rest);
LS void parse_451(char *from, char *rest);
LS void parse_471(char *from, char *rest);
LS void parse_473(char *from, char *rest);
LS void parse_346(char *from, char *rest);
LS void parse_348(char *from, char *rest);
LS void parse_368(char *from, char *rest);
LS void parse_005(char *from, char *rest);
LS uint32_t stringhash(char *s) __page(CORE_SEG);
LS void parse_server_input(char *rest) __page(CORE_SEG);
void parse_error(char *from, char *rest) __page(CORE_SEG);
void parse_invite(char *from, char *rest) __page(CMD1_SEG);
void parse_join(char *from, char *rest) __page(CORE_SEG);
void parse_mode(char *from, char *rest) __page(CORE_SEG);
void parse_notice(char *from, char *rest) __page(CORE_SEG);
void parse_part(char *from, char *rest) __page(CORE_SEG);
void parse_ping(char *from, char *rest) __page(CORE_SEG);
void parse_pong(char *from, char *rest) __page(CORE_SEG);
void parse_privmsg(char *from, char *rest) __page(CORE_SEG);
void parse_quit(char *from, char *rest) __page(CORE_SEG);
void parse_topic(char *from, char *rest) __page(CORE_SEG);
void parse_wallops(char *from, char *rest) __page(CORE_SEG);
void parse_213(char *from, char *rest) __page(CORE_SEG);
void parse_219(char *from, char *rest) __page(CORE_SEG);
void parse_251(char *from, char *rest) __page(CORE_SEG);
void parse_252(char *from, char *rest) __page(CORE_SEG);
void parse_253(char *from, char *rest) __page(CORE_SEG);
void parse_254(char *from, char *rest) __page(CORE_SEG);
void parse_255(char *from, char *rest) __page(CORE_SEG);
void parse_301(char *from, char *rest) __page(CORE_SEG);
void parse_303(char *from, char *rest) __page(CORE_SEG);
void parse_311(char *from, char *rest) __page(CORE_SEG);
void parse_312(char *from, char *rest) __page(CORE_SEG);
void parse_313(char *from, char *rest) __page(CORE_SEG);
void parse_315(char *from, char *rest) __page(CORE_SEG);
void parse_317(char *from, char *rest) __page(CORE_SEG);
void parse_318(char *from, char *rest) __page(CORE_SEG);
void parse_319(char *from, char *rest) __page(CORE_SEG);
void parse_324(char *from, char *rest) __page(CORE_SEG);
void parse_352(char *from, char *rest) __page(CORE_SEG);
void parse_367(char *from, char *rest) __page(CORE_SEG);
void parse_376(char *from, char *rest) __page(CORE_SEG);
void parse_401(char *from, char *rest) __page(CORE_SEG);
void parse_433(char *from, char *rest) __page(CORE_SEG);
void parse_451(char *from, char *rest) __page(CORE_SEG);
void parse_471(char *from, char *rest) __page(CORE_SEG);
void parse_473(char *from, char *rest) __page(CORE_SEG);
void parse_346(char *from, char *rest) __page(CORE_SEG);
void parse_348(char *from, char *rest) __page(CORE_SEG);
void parse_368(char *from, char *rest) __page(CORE_SEG);
void parse_005(char *from, char *rest) __page(CORE_SEG);
void parse_server_input(char *) __page(CORE_SEG);
/* partyline.c */
LS int check_telnet(int, char *) __page(CMD1_SEG);
LS void check_telnet_pass(Client *, char *) __page(CMD1_SEG);
LS int partyline_only_command(const char *) __page(CMD1_SEG);
LS void partyline_broadcast(const Client *, const char *, const char *) __page(CMD1_SEG);
LS void partyline_banner(Client *) __page(CMD1_SEG);
LS void dcc_chat(char *) __page(CMD1_SEG);
LS void whom_printbot(char *, BotInfo *, char *) __page(CMD1_SEG);
LS void do_whom(COMMAND_ARGS) __page(CMD1_SEG);
LS void do_chat(COMMAND_ARGS) __page(CMD1_SEG);
LS void do_bye(COMMAND_ARGS) __page(CMD1_SEG);
LS void do_boot(COMMAND_ARGS) __page(CMD1_SEG);
int check_telnet(int, char *) __page(CMD1_SEG);
void check_telnet_pass(Client *, char *) __page(CMD1_SEG);
int partyline_only_command(const char *) __page(CMD1_SEG);
void partyline_broadcast(const Client *, const char *, const char *) __page(CMD1_SEG);
void partyline_banner(Client *) __page(CMD1_SEG);
void dcc_chat(char *) __page(CMD1_SEG);
void whom_printbot(char *, BotInfo *, char *) __page(CMD1_SEG);
void do_whom(COMMAND_ARGS) __page(CMD1_SEG);
void do_chat(COMMAND_ARGS) __page(CMD1_SEG);
void do_bye(COMMAND_ARGS) __page(CMD1_SEG);
void do_boot(COMMAND_ARGS) __page(CMD1_SEG);
/* perl.c */
LS void do_perl(COMMAND_ARGS) __page(CMD1_SEG);
LS void do_perlscript(COMMAND_ARGS) __page(CMD1_SEG);
void do_perl(COMMAND_ARGS) __page(CMD1_SEG);
void do_perlscript(COMMAND_ARGS) __page(CMD1_SEG);
/* prot.c */
LS void send_kick(Chan *chan, const char *nick, const char *format, ...);
LS void push_kicks(Chan *chan);
LS void unmode_chanuser(Chan *chan, ChanUser *cu);
LS void send_mode(Chan *chan, int pri, int type, char plusminus, char modeflag, void *data);
LS int mode_effect(Chan *chan, qMode *mode);
LS void push_modes(Chan *chan, int lowpri);
LS void update_modes(Chan *chan);
LS int check_mass(Chan *chan, ChanUser *doer, int type);
LS void mass_action(Chan *chan, ChanUser *doer);
LS void prot_action(Chan *chan, char *from, ChanUser *doer, char *target, ChanUser *victim);
LS void process_chanbans(void);
LS void chanban_action(char *, char *, Shit *);
LS void check_dynamode(Chan *) __page(CORE_SEG);
LS void do_opdeopme(COMMAND_ARGS) __page(CMD1_SEG);
LS void do_opvoice(COMMAND_ARGS) __page(CMD1_SEG);
LS void do_kickban(COMMAND_ARGS) __page(CMD1_SEG);
LS void do_unban(COMMAND_ARGS) __page(CMD1_SEG);
LS void do_banlist(COMMAND_ARGS) __page(CMD1_SEG);
void screwban_format(char *) __page(CORE_SEG);
void deop_ban(Chan *, ChanUser *, char *) __page(CORE_SEG);
void deop_siteban(Chan *, ChanUser *) __page(CORE_SEG);
void deop_screwban(Chan *, ChanUser *) __page(CORE_SEG);
void send_kick(Chan *chan, const char *nick, const char *format, ...);
void push_kicks(Chan *chan);
void unmode_chanuser(Chan *chan, ChanUser *cu);
void send_mode(Chan *chan, int pri, int type, char plusminus, char modeflag, void *data);
int mode_effect(Chan *chan, qMode *mode);
void push_modes(Chan *chan, int lowpri);
void update_modes(Chan *chan);
int check_mass(Chan *chan, ChanUser *doer, int type);
void mass_action(Chan *chan, ChanUser *doer);
void prot_action(Chan *chan, char *from, ChanUser *doer, char *target, ChanUser *victim);
void process_chanbans(void);
void chanban_action(char *, char *, Shit *);
void check_dynamode(Chan *) __page(CORE_SEG);
void do_opdeopme(COMMAND_ARGS) __page(CMD1_SEG);
void do_opvoice(COMMAND_ARGS) __page(CMD1_SEG);
void do_kickban(COMMAND_ARGS) __page(CMD1_SEG);
void do_unban(COMMAND_ARGS) __page(CMD1_SEG);
void do_banlist(COMMAND_ARGS) __page(CMD1_SEG);
/* python.c */
@ -646,8 +659,8 @@ void send_spy(const char *src, const char *format, ...) __page(CORE_SEG);
void send_global(const char *src, const char *format, ...) __page(CORE_SEG);
void spy_typecount(Mech *bot) __page(CORE_SEG);
int spy_source(char *from, int *t_src, const char **src) __page(CORE_SEG);
char *urlhost(const char *) __page(CORE_SEG);
LS void urlcapture(const char *) __page(CORE_SEG);
void urlhost(const char *) __page(CORE_SEG);
void urlcapture(const char *) __page(CORE_SEG);
int begin_redirect(char *, char *) __page(CORE_SEG);
void send_redirect(char *) __page(CORE_SEG);
void end_redirect(void) __page(CORE_SEG);
@ -656,61 +669,61 @@ void stats_plusminususer(Chan *chan, int plusminus) __page(CORE_SEG);
void do_spy(COMMAND_ARGS) __page(CMD1_SEG);
void do_rspy(COMMAND_ARGS) __page(CMD1_SEG);
void do_info(COMMAND_ARGS) __page(CMD1_SEG);
LS void do_urlhist(COMMAND_ARGS) __page(CMD1_SEG);
void do_urlhist(COMMAND_ARGS) __page(CMD1_SEG);
/* tcl.c */
#ifdef TCL
/*
LS char *tcl_var_read(Tcl_TVInfo *vinfo, Tcl_Interp *I, char *n1, char *n2, int flags);
LS char *tcl_var_write(Tcl_TVInfo *vinfo, Tcl_Interp *I, char *n1, char *n2, int flags);
char *tcl_var_read(Tcl_TVInfo *vinfo, Tcl_Interp *I, char *n1, char *n2, int flags);
char *tcl_var_write(Tcl_TVInfo *vinfo, Tcl_Interp *I, char *n1, char *n2, int flags);
*/
LS int tcl_timer_jump(Hook *hook);
LS int tcl_parse_jump(char *from, char *rest, Hook *hook);
LS void tcl_dcc_complete(Client *client, int cps);
int tcl_timer_jump(Hook *hook);
int tcl_parse_jump(char *from, char *rest, Hook *hook);
void tcl_dcc_complete(Client *client, int cps);
#if defined(DEBUG_C) || defined(MEGA_C)
LS int tcl_hook(void *foo, Tcl_Interp *I, int objc, Tcl_Obj *CONST objv[]);
int tcl_hook(void *foo, Tcl_Interp *I, int objc, Tcl_Obj *CONST objv[]);
#endif
/*
LS int tcl_unhook(void *foo, Tcl_Interp *I, int objc, Tcl_Obj *CONST objv[]);
LS int tcl_userlevel(void *foo, Tcl_Interp *I, int objc, Tcl_Obj *CONST objv[]);
LS int tcl_debug(void *foo, Tcl_Interp *I, int objc, Tcl_Obj *CONST objv[]);
LS int tcl_to_server(void *foo, Tcl_Interp *I, int objc, Tcl_Obj *CONST objv[]);
LS int tcl_to_file(void *foo, Tcl_Interp *I, int objc, Tcl_Obj *CONST objv[]);
LS int tcl_dcc_sendfile(void *foo, Tcl_Interp *I, int objc, Tcl_Obj *CONST objv[]);
LS int tcl_dns_jump(char *host, char *resolved, Hook *hook);
LS int tcl_dns(void *foo, Tcl_Interp *I, int objc, Tcl_Obj *CONST objv[]);
int tcl_unhook(void *foo, Tcl_Interp *I, int objc, Tcl_Obj *CONST objv[]);
int tcl_userlevel(void *foo, Tcl_Interp *I, int objc, Tcl_Obj *CONST objv[]);
int tcl_debug(void *foo, Tcl_Interp *I, int objc, Tcl_Obj *CONST objv[]);
int tcl_to_server(void *foo, Tcl_Interp *I, int objc, Tcl_Obj *CONST objv[]);
int tcl_to_file(void *foo, Tcl_Interp *I, int objc, Tcl_Obj *CONST objv[]);
int tcl_dcc_sendfile(void *foo, Tcl_Interp *I, int objc, Tcl_Obj *CONST objv[]);
int tcl_dns_jump(char *host, char *resolved, Hook *hook);
int tcl_dns(void *foo, Tcl_Interp *I, int objc, Tcl_Obj *CONST objv[]);
*/
LS void init_tcl(void);
LS void do_tcl(COMMAND_ARGS) __page(CMD1_SEG);
void init_tcl(void);
void do_tcl(COMMAND_ARGS) __page(CMD1_SEG);
#endif /* TCL */
/* toybox.c */
LS int read_charset_callback(char *) __page(CMD1_SEG);
LS int read_bigcharset(char *) __page(CMD1_SEG);
LS int read_ascii(char *) __page(CMD1_SEG);
LS void trivia_week_toppers(void) __page(CMD1_SEG);
LS void hint_one(void) __page(CMD1_SEG);
LS void hint_two(void) __page(CMD1_SEG);
LS void hint_three(void) __page(CMD1_SEG);
LS void trivia_cleanup(void) __page(CMD1_SEG);
LS void trivia_check(Chan *, char *) __page(CMD1_SEG);
LS void trivia_no_answer(void) __page(CMD1_SEG);
LS char *random_question(char *) __page(CMD1_SEG);
LS void trivia_question(void) __page(CMD1_SEG);
LS void trivia_tick(void) __page(CMD1_SEG);
LS void write_triviascore(void) __page(CMD1_SEG);
LS int trivia_score_callback(char *) __page(CMD1_SEG);
LS void read_triviascore(void) __page(CMD1_SEG);
LS void do_bigsay(COMMAND_ARGS) __page(CMD1_SEG);
LS void do_random_msg(COMMAND_ARGS) __page(CMD1_SEG);
LS void do_randtopic(COMMAND_ARGS) __page(CMD1_SEG);
LS void do_8ball(COMMAND_ARGS) __page(CMD1_SEG);
LS void do_ascii(COMMAND_ARGS) __page(CMD1_SEG);
LS void do_rand(COMMAND_ARGS) __page(CMD1_SEG);
LS void do_trivia(COMMAND_ARGS) __page(CMD1_SEG);
int read_charset_callback(char *) __page(CMD1_SEG);
int read_bigcharset(char *) __page(CMD1_SEG);
int read_ascii(char *) __page(CMD1_SEG);
void trivia_week_toppers(void) __page(CMD1_SEG);
void hint_one(void) __page(CMD1_SEG);
void hint_two(void) __page(CMD1_SEG);
void hint_three(void) __page(CMD1_SEG);
void trivia_cleanup(void) __page(CMD1_SEG);
void trivia_check(Chan *, char *) __page(CMD1_SEG);
void trivia_no_answer(void) __page(CMD1_SEG);
char *random_question(char *) __page(CMD1_SEG);
void trivia_question(void) __page(CMD1_SEG);
void trivia_tick(void) __page(CMD1_SEG);
void write_triviascore(void) __page(CMD1_SEG);
int trivia_score_callback(char *) __page(CMD1_SEG);
void read_triviascore(void) __page(CMD1_SEG);
void do_bigsay(COMMAND_ARGS) __page(CMD1_SEG);
void do_randmsg(COMMAND_ARGS) __page(CMD1_SEG);
void do_randtopic(COMMAND_ARGS) __page(CMD1_SEG);
void do_8ball(COMMAND_ARGS) __page(CMD1_SEG);
void do_ascii(COMMAND_ARGS) __page(CMD1_SEG);
void do_rand(COMMAND_ARGS) __page(CMD1_SEG);
void do_trivia(COMMAND_ARGS) __page(CMD1_SEG);
/* uptime.c */
@ -723,36 +736,36 @@ void do_upsend(COMMAND_ARGS) __page(CMD1_SEG);
/* user.c */
LS void cfg_user(char *) __page(CFG1_SEG);
void cfg_modcount(char *);
LS void cfg_pass(char *) __page(CFG1_SEG);
LS void cfg_mask(char *) __page(CFG1_SEG);
LS void cfg_chan(char *) __page(CFG1_SEG);
LS void cfg_opt(char *) __page(CFG1_SEG);
LS void cfg_shit(char *) __page(CFG1_SEG);
void cfg_kicksay(char *);
LS void cfg_greet(char *) __page(CFG1_SEG);
LS void cfg_note(char *) __page(CFG1_SEG);
void user_sync(void);
int read_userlist_callback(char *);
int read_userlist(char *);
int write_userlist(char *);
void rehash_chanusers(void);
LS void addtouser(Strp **, const char *, int) __attr(CORE_SEG, __regparm(3));
LS int remfromuser(Strp **, const char *) __attr(CORE_SEG, __regparm(2));
void cfg_user(char *) __page(CFG1_SEG);
void cfg_modcount(char *) __page(CFG1_SEG);
void cfg_pass(char *) __page(CFG1_SEG);
void cfg_mask(char *) __page(CFG1_SEG);
void cfg_chan(char *) __page(CFG1_SEG);
void cfg_opt(char *) __page(CFG1_SEG);
void cfg_shit(char *) __page(CFG1_SEG);
void cfg_kicksay(char *) __page(CFG1_SEG);
void cfg_greet(char *) __page(CFG1_SEG);
void cfg_note(char *) __page(CFG1_SEG);
void user_sync(void) __page(CFG1_SEG);
int read_userlist_callback(char *) __page(CFG1_SEG);
int read_userlist(char *) __page(CFG1_SEG);
int write_userlist(char *) __page(CMD1_SEG);
void rehash_chanusers(void) __page(CORE_SEG);
void addtouser(Strp **, const char *, int) __page(CORE_SEG);
int remfromuser(Strp **, const char *) __page(CORE_SEG);
void mirror_user(User *) __page(CORE_SEG);
void mirror_userlist(void) __page(CORE_SEG);
void reset_userlink(User *, User *);
void remove_user(User *);
User *add_user(char *, char *, int);
User *find_handle(const char *);
int userhaschannel(const User *, const char *);
void reset_userlink(User *, User *) __page(CORE_SEG);
void remove_user(User *) __page(CFG1_SEG);
User *add_user(char *, char *, int) __page(CFG1_SEG);
User *find_handle(const char *) __page(CORE_SEG);
int userhaschannel(const User *, const char *) __page(CORE_SEG);
User *get_user(const char *, const char *) __page(CORE_SEG);
int get_useraccess(const char *, const char *) __page(CORE_SEG);
int get_maxaccess(const char *) __page(CORE_SEG);
int is_bot(const char *) __page(CORE_SEG);
int get_protaction(Chan *, char *) __page(CORE_SEG);
int usercanmodify(const char *, const User *);
int usercanmodify(const char *, const User *) __page(CMD1_SEG);
void change_pass(User *, char *) __page(CMD1_SEG);
void do_access(COMMAND_ARGS) __page(CMD1_SEG);
void do_userlist(COMMAND_ARGS) __page(CMD1_SEG);
@ -770,7 +783,7 @@ int find_setting(const char *) __page(CORE_SEG);
void copy_vars(UniVar *, UniVar *) __page(CFG1_SEG);
void set_binarydefault(UniVar *) __page(CFG1_SEG);
void delete_vars(UniVar *, int) __page(CMD1_SEG);
void var_resolve_host(const struct Setting *);
void var_resolve_host(const struct Setting *) __page(CMD1_SEG);
void nobo_strcpy(const char *) __page(CMD1_SEG);
void ec_access(char *, const char *) __page(CMD1_SEG);
void ec_capabilities(char *, const char *) __page(CMD1_SEG);

View File

@ -145,7 +145,7 @@ help_loop:
return;
}
if (STRCHR(rest,'*'))
if (stringchr(rest,'*'))
{
line[0] = 0;
ci = 0;
@ -229,6 +229,8 @@ void usage_command(char *to, const char *arg)
char *pt;
int i;
if (to == cx.CoreUser.name) /* dont send usage notices to config file */
return;
for(i=0;ulist[i].command;i++)
{
if (!stringcasecmp(arg,ulist[i].command))

View File

@ -53,7 +53,7 @@ struct /* statusvalues */
const int klen;
char *valbuf;
} sv[] =
} statusvalues[] =
{
{ "VmPeak:", 7, vmpeak },
{ "VmSize:", 7, vmsize },
@ -65,55 +65,9 @@ struct /* statusvalues */
{ NULL, 0, NULL }
};
#ifdef DEBUG
struct
{
int value;
char *str;
} in2str[] =
{
{ IN_ACCESS, "IN_ACCESS" }, /* File was accessed (read) */
{ IN_ATTRIB, "IN_ATTRIB" }, /* Metadata changed, e.g., permissions, timestamps, extended attributes, link count, UID, GID, etc. */
{ IN_CLOSE_WRITE, "IN_CLOSE_WRITE" }, /* File opened for writing was closed */
{ IN_CLOSE_NOWRITE, "IN_CLOSE_NOWRITE" }, /* File not opened for writing was closed */
{ IN_CREATE, "IN_CREATE" }, /* File/directory created in watched directory */
{ IN_DELETE, "IN_DELETE" }, /* File/directory deleted from watched directory */
{ IN_DELETE_SELF, "IN_DELETE_SELF" }, /* Watched file/directory was itself deleted */
{ IN_MODIFY, "IN_MODIFY" }, /* File was modified */
{ IN_MOVE_SELF, "IN_MOVE_SELF" }, /* Watched file/directory was itself moved */
{ IN_MOVED_FROM, "IN_MOVED_FROM" }, /* Generated for the directory containing the old filename when a file is renamed */
{ IN_MOVED_TO, "IN_MOVED_TO" }, /* Generated for the directory containing the new filename when a file is renamed */
{ IN_OPEN, "IN_OPEN" }, /* File was opened */
{ 0, NULL }
};
char *inomask2str(uint32_t mask, char *dst)
{
const char *src;
int i,n = 0;
for(i=0;in2str[i].str;i++)
{
if ((mask & in2str[i].value) == in2str[i].value)
{
if (n)
dst[n++] = '|';
src = in2str[i].str;
for(;src[n];n++)
dst[n] = src[n];
}
}
dst[n] = 0;
return(dst);
}
#endif /* DEBUG */
int monitor_fs(const char *file)
{
FileMon *fmon,*fnew;
FileMon *fnew;
int ino;
if ((ino = inotify_init()) < 0)
@ -125,7 +79,7 @@ int monitor_fs(const char *file)
set_mallocdoer(monitor_fs);
fnew = Calloc(sizeof(FileMon) + strlen(file));
fnew->fd = ino;
fnew->nospam = now;
fnew->nospam = cx.now;
stringcpy(fnew->filename,file);
fnew->next = filemonlist;
@ -145,15 +99,15 @@ int parse_proc_status(char *line)
#endif
if (key == NULL)
return(FALSE);
for(i=0;sv[i].key;i++)
for(i=0;statusvalues[i].key;i++)
{
if (strncmp(key,sv[i].key,sv[i].klen) == 0)
if (strncmp(key,statusvalues[i].key,statusvalues[i].klen) == 0)
{
#ifdef DEBUG
debug("(parse_proc_status) key %s -> %s\n",key,line);
#endif /* DEBUG */
dest = sv[i].valbuf;
limit = sv[i].valbuf + 31;
dest = statusvalues[i].valbuf;
limit = statusvalues[i].valbuf + 31;
while(*line == ' ')
line++;
while(*line && dest <= limit)
@ -250,52 +204,60 @@ int parse_proc_cpuinfo(char *line)
return(FALSE); /* return false to continue reading lines */
}
void select_monitor()
void select_monitor(void)
{
FileMon *fmon;
for(fmon=filemonlist;fmon;fmon=fmon->next)
{
if (fmon->fd >= 0)
{
FD_SET(fmon->fd,&read_fds);
chkhigh(fmon->fd);
}
}
}
void process_monitor()
#ifdef DEBUG
extern const DEFstruct inomasks[];
#endif /* DEBUG */
void process_monitor(void)
{
FileMon *fmon;
struct inotify_event *ivent;
#ifdef DEBUG
char tmp[256];
int n,m;
int n;
#else
int n __notused__;
#endif /* DEBUG */
int m __notused__;
for(fmon=filemonlist;fmon;fmon=fmon->next)
{
if (fmon->fd >= 0 && FD_ISSET(fmon->fd,&read_fds))
{
ivent = (struct inotify_event *)&globaldata;
if (fmon->fd < 0 || 0 == FD_ISSET(fmon->fd,&read_fds))
continue;
n = read(fmon->fd,globaldata,sizeof(struct inotify_event));
if (ivent->len > 0)
m = read(fmon->fd,ivent->name,ivent->len);
else
*ivent->name = 0;
ivent = (struct inotify_event *)&globaldata;
n = read(fmon->fd,globaldata,sizeof(struct inotify_event));
if (ivent->len > 0)
m = read(fmon->fd,ivent->name,ivent->len);
else
*ivent->name = 0;
#ifdef DEBUG
debug("(process_monitor) ino %i, n %i, sz %i\n",fmon->fd,n,sizeof(in2str));
debug("(process_monitor) wd %i, mask %lu, cookie %lu, len %lu, name %s\n",
ivent->wd,ivent->mask,ivent->cookie,ivent->len,ivent->name);
debug("(process_monitor) %s\n",inomask2str(ivent->mask,tmp));
debug("(process_monitor) ino %i bytes read, int wd = %i, uint32_t mask = %s (%lu), "
"uint32_t cookie = %lu, uint32_t len = %lu, char name = %s\n",
n,ivent->wd,inomask2str(ivent->mask,tmp),ivent->mask,ivent->cookie,ivent->len,ivent->name);
#endif
if ((ivent->mask & IN_CLOSE_WRITE) == IN_CLOSE_WRITE)
return;
if (fmon->nospam > now-30)
return;
fmon->nospam = now;
send_global(SPYSTR_SYSMON,"Alert: file ``%s'' was touched",fmon->filename);
}
strflags(tmp,inomasks,ivent->mask);
debug("(process_monitor) ino {%i} %i bytes, wd = %i, mask = %s (%lu), cookie = %lu, len = %lu, name = %s\n",
fmon->fd,n,ivent->wd,tmp,ivent->mask,ivent->cookie,ivent->len,ivent->name);
#endif /* DEBUG */
if ((ivent->mask & IN_CLOSE_WRITE) == IN_CLOSE_WRITE)
return;
if (fmon->nospam > (cx.now - 30))
return;
fmon->nospam = cx.now;
send_global(SPYSTR_SYSMON,"Alert: file ``%s'' was touched",fmon->filename);
}
}
@ -346,8 +308,8 @@ void do_meminfo(COMMAND_ARGS)
p = getpid();
snprintf(fn,sizeof(fn),"/proc/%i/status",p);
for(i=0;sv[i].key;i++)
*(sv[i].valbuf) = 0;
for(i=0;statusvalues[i].key;i++)
*(statusvalues[i].valbuf) = 0;
if ((fd = open(fn,O_RDONLY)) < 0)
return;
readline(fd,&parse_proc_status); /* readline closes fd */
@ -364,18 +326,9 @@ See also: hostinfo, meminfo
void do_cpuinfo(COMMAND_ARGS)
{
char bogostr[256],cpustr[64];
char *a1,*a2,*a3,*dst;
int fd,n;
int fd;
double loads[3];
#ifdef DEVELOPING
a1 = chop(&rest);
if (a1)
sprintf(bogostr,"/home/git/cpuinfo/%s",a1);
else
stringcpy(bogostr,"/proc/cpuinfo");
if ((fd = open(bogostr,O_RDONLY)) < 0)
#endif
if ((fd = open("/proc/cpuinfo",O_RDONLY)) < 0)
#ifdef DEBUG
{

175
src/io.c
View File

@ -115,10 +115,6 @@ int SockConnect(char *host, int port, int use_vhost)
{
struct sockaddr_in sai;
int s;
#ifdef IDWRAP
char *id,identfile[64];
int t = FALSE;
#endif /* IDWRAP */
#ifdef DEBUG
debug("(SockConnect) %s %i%s\n",nullstr(host),port,(use_vhost) ? " [VHOST]" : "");
@ -130,16 +126,7 @@ int SockConnect(char *host, int port, int use_vhost)
memset((char*)&sai,0,sizeof(sai));
sai.sin_family = AF_INET;
/*
* special case, BOUNCE feature may call SockConnect()
* to create the IDWRAP symlink, using special use_vhost value == 2
*/
#if defined(BOUNCE) && defined(IDWRAP)
if ((use_vhost == TRUE)
#else /* not ... */
if (use_vhost
#endif /* ... */
&& ((current->vhost_type & VH_IPALIAS_FAIL) == 0)
if (use_vhost && ((current->vhost_type & VH_IPALIAS_FAIL) == 0)
&& current->setting[STR_VIRTUAL].str_var)
{
current->vhost_type |= VH_IPALIAS_BOTH;
@ -151,25 +138,12 @@ int SockConnect(char *host, int port, int use_vhost)
#ifdef WINGATE
use_vhost++;
#endif /* WINGATE */
#ifdef IDWRAP
t = TRUE;
#endif /* IDWRAP */
#ifdef DEBUG
debug("(SockConnect) IP Alias virtual host bound OK\n");
#endif /* DEBUG */
}
}
}
#ifdef IDWRAP
/*
* do a blank bind to get a port number
*/
if (!t)
{
sai.sin_addr.s_addr = INADDR_ANY;
bind(s,(struct sockaddr *)&sai,sizeof(sai));
}
#endif /* IDWRAP */
memset((char*)&sai,0,sizeof(sai));
sai.sin_family = AF_INET;
@ -204,29 +178,6 @@ int SockConnect(char *host, int port, int use_vhost)
/*
* Normal connect, no bounces...
*/
#ifdef IDWRAP
if (use_vhost)
{
t = sizeof(sai);
if (getsockname(s,(struct sockaddr*)&sai,&t) == 0)
{
if (current->identfile)
Free((char**)&current->identfile);
sprintf(identfile,IDWRAP_PATH "%i.%i",ntohs(sai.sin_port),port);
id = current->setting[STR_IDENT].str_var;
if (symlink((id) ? id : BOTLOGIN,identfile) == 0)
{
set_mallocdoer(SockConnect);
current->identfile = Strdup(identfile);
#ifdef DEBUG
debug("(SockConnect) symlink: %s -> %s\n",identfile,(id) ? id : BOTLOGIN);
#endif /* DEBUG */
}
}
memset((char*)&sai,0,sizeof(sai));
sai.sin_family = AF_INET;
}
#endif /* IDWRAP */
sai.sin_port = htons(port);
if ((sai.sin_addr.s_addr = get_ip(host)) == -1)
{
@ -253,7 +204,8 @@ int SockConnect(char *host, int port, int use_vhost)
int SockAccept(int sock)
{
struct sockaddr_in sai;
int s,sz;
unsigned int sz;
int s;
sz = sizeof(sai);
s = accept(sock,(struct sockaddr*)&sai,&sz);
@ -303,18 +255,19 @@ int to_file(const int sock, const char *format, ...)
* Format a message and send it to the current bots server
* to_server needs a newline (\n) it wont manufacture it itself.
*/
void to_server(char *format, ...)
void to_server(const char *format, ...)
{
va_list msg;
#ifdef DEBUG
char *line,*rest;
#endif /* DEBUG */
int sz;
if (current->sock == -1)
return;
va_start(msg,format);
vsprintf(globaldata,format,msg);
sz = vsprintf(globaldata,format,msg);
va_end(msg);
/*
@ -323,7 +276,7 @@ void to_server(char *format, ...)
*/
current->sendq_time += 2;
if (write(current->sock,globaldata,strlen(globaldata)) < 0)
if (write(current->sock,globaldata,sz) < 0)
{
#ifdef DEBUG
debug("[StS] {%i} errno = %i\n",current->sock,errno);
@ -357,7 +310,7 @@ void to_user_q(const char *target, const char *format, ...)
if (STARTUP_ECHOTOCONSOLE)
{
int n;
int n __notused__;
n = write(1,message,strlen(message));
return;
}
@ -497,6 +450,91 @@ void to_user(const char *target, const char *format, ...)
#endif /* DEBUG */
}
Strp *output_table = NULL;
void table_buffer(const char *format, ...)
{
va_list msg;
va_start(msg,format);
vsprintf(globaldata,format,msg);
va_end(msg);
set_mallocdoer(table_buffer);
append_strp(&output_table,globaldata);
}
void table_send(const char *from, const int space)
{
char message[MAXLEN];
Strp *sp,*next;
char *src,*o,*end;
int i,u,g,x,columns[16];
memset(columns,0,sizeof(columns));
for(sp=output_table;sp;sp=sp->next)
{
u = i = 0;
src = o = sp->p;
while(*src)
{
/* Dont count control codes */
if (*src == '\037' || *src == '\002')
u++;
if (*src == '\t' || *src == '\r')
{
x = (src - o) - u;
if (x > columns[i])
columns[i] = x;
i++;
o = src+1;
u = 0;
}
src++;
}
}
for(sp=output_table;sp;sp=next)
{
next = sp->next;
o = message;
src = sp->p;
g = x = i = 0;
while(*src)
{
if (g)
{
end = src;
while(*end && *end != '\t' && *end != '\r')
end++;
g -= (end - src);
while(g-- > 0)
*(o++) = ' ';
}
if (*src == '\037' || *src == '\002')
x++;
if (*src == '\t' || *src == '\r')
{
if (*src == '\r')
g = columns[i+1];
src++;
x += (columns[i++] + space);
while(o < (message + x))
*(o++) = ' ';
}
else
*(o++) = *(src++);
}
*o = 0;
to_user(from,FMT_PLAIN,message);
Free((char**)&sp);
}
output_table = NULL;
}
#endif /* ifndef GENCMD_C */
/*
@ -507,7 +545,7 @@ void to_user(const char *target, const char *format, ...)
* 2: If <rest> data is insufficient, try to read in more
* 3: Try again to make a whole line
*/
char *sockread(int s, char *rest, char *line)
char *sockread(int socket, char *rest, char *output)
{
char *src,*dst,*rdst;
int n;
@ -515,7 +553,7 @@ char *sockread(int s, char *rest, char *line)
errno = EAGAIN;
src = rest;
dst = line;
dst = output;
while(*src)
{
@ -525,20 +563,26 @@ char *sockread(int s, char *rest, char *line)
while(*src == '\n' || *src == '\r')
src++;
*dst = 0;
#if !defined(GENCMD_C)
cx.rest_end = dst;
#endif /* !defined(GENCMD_C) */
/* move remainder of rest to the beginning of the buffer */
/* src can be end of rest or globaldata */
dst = rest;
while(*src)
*(dst++) = *(src++);
*dst = 0;
#if defined(DEBUG) && !defined(GENCMD_C)
debug("(in) {%i} %s\n",s,line);
debug("(in) {%i} %s\n",socket,output);
#endif /* DEBUG */
return((*line) ? line : NULL);
return((*output) ? output : NULL);
}
*(dst++) = *(src++);
}
rdst = src;
n = read(s,globaldata,MSGLEN-2);
n = read(socket,globaldata,MSGLEN-2);
switch(n)
{
case 0:
@ -547,14 +591,15 @@ char *sockread(int s, char *rest, char *line)
return(NULL);
}
rdst = src;
globaldata[n] = 0;
src = globaldata;
while(*src)
{
if (*src == '\r' || *src == '\n')
goto gotline;
if ((dst - line) >= (MSGLEN-2))
goto gotline; /* gotline will move the rest of globaldata to rest */
if ((dst - output) >= (MSGLEN-2))
{
/*
* line is longer than buffer, let the wheel spin
@ -634,7 +679,7 @@ int killsock(int sock)
{
set_mallocdoer(killsock);
ks = (KillSock*)Calloc(sizeof(KillSock));
ks->time = now;
ks->time = cx.now;
ks->sock = sock;
ks->next = killsocks;
killsocks = ks;
@ -686,7 +731,7 @@ int killsock(int sock)
if ((n == 0) || ((n == -1) && (errno != EAGAIN)))
remove_ks(ks);
}
if ((now - ks->time) > KILLSOCKTIMEOUT)
if ((cx.now - ks->time) > KILLSOCK_TIMEOUT)
remove_ks(ks);
ks = ksnext;
}

View File

@ -40,7 +40,7 @@ void make_ireq(int t, const char *from, const char *nick)
ir = (IReq*)Calloc(sizeof(IReq) + StrlenX(from,nick,NULL)); /* can not use Strlen2() if 2nd arg might be NULL, StrlenX() handles NULLs. */
ir->t = t;
ir->when = now;
ir->when = cx.now;
pt = stringcat(ir->from,from) + 1;
if (nick)

View File

@ -294,4 +294,4 @@ int main(int argc, char **argv)
return(0);
}
#endif TEST
#endif /* TEST */

370
src/lib/sha512.c Normal file
View File

@ -0,0 +1,370 @@
/*
* public domain sha512 crypt implementation
*
* original sha crypt design: http://people.redhat.com/drepper/SHA-crypt.txt
* in this implementation at least 32bit int is assumed,
* key length is limited, the $6$ prefix is mandatory, '\n' and ':' is rejected
* in the salt and rounds= setting must contain a valid iteration count,
* on error "*" is returned.
*/
#include <ctype.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <stdint.h>
/* public domain sha512 implementation based on fips180-3 */
/* >=2^64 bits messages are not supported (about 2000 peta bytes) */
struct sha512
{
uint64_t len; /* processed message length */
uint64_t h[8]; /* hash state */
uint8_t buf[128]; /* message block buffer */
};
static uint64_t ror(uint64_t n, int k) { return (n >> k) | (n << (64-k)); }
#define Ch(x,y,z) (z ^ (x & (y ^ z)))
#define Maj(x,y,z) ((x & y) | (z & (x | y)))
#define S0(x) (ror(x,28) ^ ror(x,34) ^ ror(x,39))
#define S1(x) (ror(x,14) ^ ror(x,18) ^ ror(x,41))
#define R0(x) (ror(x,1) ^ ror(x,8) ^ (x>>7))
#define R1(x) (ror(x,19) ^ ror(x,61) ^ (x>>6))
static const uint64_t K[80] =
{
0x428a2f98d728ae22ULL, 0x7137449123ef65cdULL, 0xb5c0fbcfec4d3b2fULL, 0xe9b5dba58189dbbcULL,
0x3956c25bf348b538ULL, 0x59f111f1b605d019ULL, 0x923f82a4af194f9bULL, 0xab1c5ed5da6d8118ULL,
0xd807aa98a3030242ULL, 0x12835b0145706fbeULL, 0x243185be4ee4b28cULL, 0x550c7dc3d5ffb4e2ULL,
0x72be5d74f27b896fULL, 0x80deb1fe3b1696b1ULL, 0x9bdc06a725c71235ULL, 0xc19bf174cf692694ULL,
0xe49b69c19ef14ad2ULL, 0xefbe4786384f25e3ULL, 0x0fc19dc68b8cd5b5ULL, 0x240ca1cc77ac9c65ULL,
0x2de92c6f592b0275ULL, 0x4a7484aa6ea6e483ULL, 0x5cb0a9dcbd41fbd4ULL, 0x76f988da831153b5ULL,
0x983e5152ee66dfabULL, 0xa831c66d2db43210ULL, 0xb00327c898fb213fULL, 0xbf597fc7beef0ee4ULL,
0xc6e00bf33da88fc2ULL, 0xd5a79147930aa725ULL, 0x06ca6351e003826fULL, 0x142929670a0e6e70ULL,
0x27b70a8546d22ffcULL, 0x2e1b21385c26c926ULL, 0x4d2c6dfc5ac42aedULL, 0x53380d139d95b3dfULL,
0x650a73548baf63deULL, 0x766a0abb3c77b2a8ULL, 0x81c2c92e47edaee6ULL, 0x92722c851482353bULL,
0xa2bfe8a14cf10364ULL, 0xa81a664bbc423001ULL, 0xc24b8b70d0f89791ULL, 0xc76c51a30654be30ULL,
0xd192e819d6ef5218ULL, 0xd69906245565a910ULL, 0xf40e35855771202aULL, 0x106aa07032bbd1b8ULL,
0x19a4c116b8d2d0c8ULL, 0x1e376c085141ab53ULL, 0x2748774cdf8eeb99ULL, 0x34b0bcb5e19b48a8ULL,
0x391c0cb3c5c95a63ULL, 0x4ed8aa4ae3418acbULL, 0x5b9cca4f7763e373ULL, 0x682e6ff3d6b2b8a3ULL,
0x748f82ee5defb2fcULL, 0x78a5636f43172f60ULL, 0x84c87814a1f0ab72ULL, 0x8cc702081a6439ecULL,
0x90befffa23631e28ULL, 0xa4506cebde82bde9ULL, 0xbef9a3f7b2c67915ULL, 0xc67178f2e372532bULL,
0xca273eceea26619cULL, 0xd186b8c721c0c207ULL, 0xeada7dd6cde0eb1eULL, 0xf57d4f7fee6ed178ULL,
0x06f067aa72176fbaULL, 0x0a637dc5a2c898a6ULL, 0x113f9804bef90daeULL, 0x1b710b35131c471bULL,
0x28db77f523047d84ULL, 0x32caab7b40c72493ULL, 0x3c9ebe0a15c9bebcULL, 0x431d67c49c100d4cULL,
0x4cc5d4becb3e42b6ULL, 0x597f299cfc657e2aULL, 0x5fcb6fab3ad6faecULL, 0x6c44198c4a475817ULL
};
static void processblock(struct sha512 *s, const uint8_t *buf)
{
uint64_t W[80], t1, t2, a, b, c, d, e, f, g, h;
int i;
for (i = 0; i < 16; i++)
{
W[i] = (uint64_t)buf[8*i]<<56;
W[i] |= (uint64_t)buf[8*i+1]<<48;
W[i] |= (uint64_t)buf[8*i+2]<<40;
W[i] |= (uint64_t)buf[8*i+3]<<32;
W[i] |= (uint64_t)buf[8*i+4]<<24;
W[i] |= (uint64_t)buf[8*i+5]<<16;
W[i] |= (uint64_t)buf[8*i+6]<<8;
W[i] |= buf[8*i+7];
}
for (; i < 80; i++)
W[i] = R1(W[i-2]) + W[i-7] + R0(W[i-15]) + W[i-16];
a = s->h[0];
b = s->h[1];
c = s->h[2];
d = s->h[3];
e = s->h[4];
f = s->h[5];
g = s->h[6];
h = s->h[7];
for (i = 0; i < 80; i++)
{
t1 = h + S1(e) + Ch(e,f,g) + K[i] + W[i];
t2 = S0(a) + Maj(a,b,c);
h = g;
g = f;
f = e;
e = d + t1;
d = c;
c = b;
b = a;
a = t1 + t2;
}
s->h[0] += a;
s->h[1] += b;
s->h[2] += c;
s->h[3] += d;
s->h[4] += e;
s->h[5] += f;
s->h[6] += g;
s->h[7] += h;
}
static void pad(struct sha512 *s)
{
unsigned r = s->len % 128;
s->buf[r++] = 0x80;
if (r > 112)
{
memset(s->buf + r, 0, 128 - r);
r = 0;
processblock(s, s->buf);
}
memset(s->buf + r, 0, 120 - r);
s->len *= 8;
s->buf[120] = s->len >> 56;
s->buf[121] = s->len >> 48;
s->buf[122] = s->len >> 40;
s->buf[123] = s->len >> 32;
s->buf[124] = s->len >> 24;
s->buf[125] = s->len >> 16;
s->buf[126] = s->len >> 8;
s->buf[127] = s->len;
processblock(s, s->buf);
}
static void sha512_init(struct sha512 *s)
{
s->len = 0;
s->h[0] = 0x6a09e667f3bcc908ULL;
s->h[1] = 0xbb67ae8584caa73bULL;
s->h[2] = 0x3c6ef372fe94f82bULL;
s->h[3] = 0xa54ff53a5f1d36f1ULL;
s->h[4] = 0x510e527fade682d1ULL;
s->h[5] = 0x9b05688c2b3e6c1fULL;
s->h[6] = 0x1f83d9abfb41bd6bULL;
s->h[7] = 0x5be0cd19137e2179ULL;
}
static void sha512_sum(struct sha512 *s, uint8_t *md)
{
int i;
pad(s);
for (i = 0; i < 8; i++)
{
md[8*i] = s->h[i] >> 56;
md[8*i+1] = s->h[i] >> 48;
md[8*i+2] = s->h[i] >> 40;
md[8*i+3] = s->h[i] >> 32;
md[8*i+4] = s->h[i] >> 24;
md[8*i+5] = s->h[i] >> 16;
md[8*i+6] = s->h[i] >> 8;
md[8*i+7] = s->h[i];
}
}
static void sha512_update(struct sha512 *s, const void *m, unsigned long len)
{
const uint8_t *p = m;
unsigned r = s->len % 128;
s->len += len;
if (r)
{
if (len < 128 - r)
{
memcpy(s->buf + r, p, len);
return;
}
memcpy(s->buf + r, p, 128 - r);
len -= 128 - r;
p += 128 - r;
processblock(s, s->buf);
}
for (; len >= 128; len -= 128, p += 128)
processblock(s, p);
memcpy(s->buf, p, len);
}
static const unsigned char b64[] =
"./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
static char *to64(char *s, unsigned int u, int n)
{
while (--n >= 0)
{
*s++ = b64[u % 64];
u /= 64;
}
return s;
}
/* key limit is not part of the original design, added for DoS protection.
* rounds limit has been lowered (versus the reference/spec), also for DoS
* protection. runtime is O(klen^2 + klen*rounds) */
#define KEY_MAX 256
#define SALT_MAX 16
#define ROUNDS_DEFAULT 5000
#define ROUNDS_MIN 1000
#define ROUNDS_MAX 9999999
/* hash n bytes of the repeated md message digest */
static void hashmd(struct sha512 *s, unsigned int n, const void *md)
{
unsigned int i;
for (i = n; i > 64; i -= 64)
sha512_update(s, md, 64);
sha512_update(s, md, i);
}
static char *sha512crypt(const char *key, const char *setting, char *output)
{
struct sha512 ctx;
unsigned char md[64], kmd[64], smd[64];
unsigned int i, r, klen, slen;
const char *salt;
char *p;
/* reject large keys */
for (i = 0; i <= KEY_MAX && key[i]; i++);
if (i > KEY_MAX)
return 0;
klen = i;
/* setting: $6$rounds=n$salt$ (rounds=n$ and closing $ are optional) */
if (strncmp(setting, "$6$", 3) != 0)
return 0;
salt = setting + 3;
r = ROUNDS_DEFAULT;
for (i = 0; i < SALT_MAX && salt[i] && salt[i] != '$'; i++)
/* reject characters that interfere with /etc/shadow parsing */
if (salt[i] == '\n' || salt[i] == ':')
return 0;
slen = i;
/* B = sha(key salt key) */
sha512_init(&ctx);
sha512_update(&ctx, key, klen);
sha512_update(&ctx, salt, slen);
sha512_update(&ctx, key, klen);
sha512_sum(&ctx, md);
/* A = sha(key salt repeat-B alternate-B-key) */
sha512_init(&ctx);
sha512_update(&ctx, key, klen);
sha512_update(&ctx, salt, slen);
hashmd(&ctx, klen, md);
for (i = klen; i > 0; i >>= 1)
if (i & 1)
sha512_update(&ctx, md, sizeof md);
else
sha512_update(&ctx, key, klen);
sha512_sum(&ctx, md);
/* DP = sha(repeat-key), this step takes O(klen^2) time */
sha512_init(&ctx);
for (i = 0; i < klen; i++)
sha512_update(&ctx, key, klen);
sha512_sum(&ctx, kmd);
/* DS = sha(repeat-salt) */
sha512_init(&ctx);
for (i = 0; i < 16 + md[0]; i++)
sha512_update(&ctx, salt, slen);
sha512_sum(&ctx, smd);
/* iterate A = f(A,DP,DS), this step takes O(rounds*klen) time */
for (i = 0; i < r; i++)
{
sha512_init(&ctx);
if (i % 2)
hashmd(&ctx, klen, kmd);
else
sha512_update(&ctx, md, sizeof md);
if (i % 3)
sha512_update(&ctx, smd, slen);
if (i % 7)
hashmd(&ctx, klen, kmd);
if (i % 2)
sha512_update(&ctx, md, sizeof md);
else
hashmd(&ctx, klen, kmd);
sha512_sum(&ctx, md);
}
/* output is $6$salt$hash */
p = output;
p += sprintf(p, "$6$%.*s$", slen, salt);
#if 0
static const unsigned char perm[][3] = {
0,21,42,22,43,1,44,2,23,3,24,45,25,46,4,
47,5,26,6,27,48,28,49,7,50,8,29,9,30,51,
31,52,10,53,11,32,12,33,54,34,55,13,56,14,35,
15,36,57,37,58,16,59,17,38,18,39,60,40,61,19,
62,20,41 };
for (i=0; i<21; i++) p = to64(p,
(md[perm[i][0]]<<16)|(md[perm[i][1]]<<8)|md[perm[i][2]], 4);
#else
p = to64(p, (md[0]<<16)|(md[21]<<8)|md[42], 4);
p = to64(p, (md[22]<<16)|(md[43]<<8)|md[1], 4);
p = to64(p, (md[44]<<16)|(md[2]<<8)|md[23], 4);
p = to64(p, (md[3]<<16)|(md[24]<<8)|md[45], 4);
p = to64(p, (md[25]<<16)|(md[46]<<8)|md[4], 4);
p = to64(p, (md[47]<<16)|(md[5]<<8)|md[26], 4);
p = to64(p, (md[6]<<16)|(md[27]<<8)|md[48], 4);
p = to64(p, (md[28]<<16)|(md[49]<<8)|md[7], 4);
p = to64(p, (md[50]<<16)|(md[8]<<8)|md[29], 4);
p = to64(p, (md[9]<<16)|(md[30]<<8)|md[51], 4);
p = to64(p, (md[31]<<16)|(md[52]<<8)|md[10], 4);
p = to64(p, (md[53]<<16)|(md[11]<<8)|md[32], 4);
p = to64(p, (md[12]<<16)|(md[33]<<8)|md[54], 4);
p = to64(p, (md[34]<<16)|(md[55]<<8)|md[13], 4);
p = to64(p, (md[56]<<16)|(md[14]<<8)|md[35], 4);
p = to64(p, (md[15]<<16)|(md[36]<<8)|md[57], 4);
p = to64(p, (md[37]<<16)|(md[58]<<8)|md[16], 4);
p = to64(p, (md[59]<<16)|(md[17]<<8)|md[38], 4);
p = to64(p, (md[18]<<16)|(md[39]<<8)|md[60], 4);
p = to64(p, (md[40]<<16)|(md[61]<<8)|md[19], 4);
p = to64(p, (md[62]<<16)|(md[20]<<8)|md[41], 4);
#endif
p = to64(p, md[63], 2);
*p = 0;
return output;
}
char sha512_buffer[128];
char *crypt_sha512(const char *key, const char *salt)
{
return(sha512crypt(key,salt,sha512_buffer));
}
#ifdef TEST
const char thash1[] = "$6$5c05$WlQbKv/GYeXzSPNsn9bzpfqlDjOCbt8JlhSa2uALujoq6tWn3utZ3jE428lxBAfcJYHfecF59s6Dxg0fLIX7a/";
int main(int argc, char **argv, char **envp)
{
const char mytest[] = "mytestpassword";
const char mysalt[] = "$6$5c05$";
char *s;
int r;
s = crypt_sha512(mytest,mysalt);
r = strcmp(thash1,s);
if (r == 0)
{
printf("SHA512\n");
}
else
{
printf("FAIL\n");
printf("%i\n%s\%s\n",r,thash1,s);
}
}
#endif /* TEST */

View File

@ -1,7 +1,7 @@
/*
EnergyMech, IRC bot software
Parts Copyright (c) 1997-2018 proton
Parts Copyright (c) 1997-2025 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
@ -51,7 +51,6 @@
#include "hostinfo.c"
#include "io.c"
#include "irc.c"
#include "lib/string.c"
#include "net.c"
#include "note.c"
#include "ons.c"
@ -67,6 +66,7 @@
#include "seen.c"
#include "shit.c"
#include "spy.c"
#include "string.c"
#include "tcl.c"
#include "toybox.c"
#include "uptime.c"
@ -144,8 +144,8 @@ void mech_exec(void)
exit(1);
}
LS int r_ct;
LS char r_str[MSGLEN];
int r_ct;
char r_str[MSGLEN];
int randstring_count(char *line)
{
@ -199,7 +199,7 @@ char *randstring(const char *file)
* SIGUSR2 Call run_debug() (dump `everything' to a debug file)
*/
LS struct
struct
{
uint32_t sighup:1,
sigint:1,
@ -209,7 +209,7 @@ LS struct
int sig_hup_callback(char *line)
{
on_msg((char*)CoreUser.name,current->nick,line);
on_msg((char*)cx.CoreUser.name,getbotnick(current),line);
return(FALSE);
}
@ -221,7 +221,7 @@ void do_sighup(void)
CurrentShit = NULL;
CurrentChan = NULL;
CurrentUser = (User*)&CoreUser;
CurrentUser = (User*)&cx.CoreUser;
CurrentDCC = (Client*)&CoreClient;
*CurrentNick = 0;
@ -295,9 +295,6 @@ void do_sigusr1(void)
{
if (current->sock != -1)
{
#ifdef IDWRAP
unlink_identfile();
#endif /* IDWRAP */
close(current->sock);
}
current->sock = -1;
@ -324,7 +321,7 @@ void sig_usr1(int crap)
*/
void sig_usr2(int crap)
{
time(&now);
time(&cx.now);
debug("(sigusr2)\n");
signal(SIGUSR2,sig_usr2);
@ -402,20 +399,20 @@ void sig_int(int signum)
* SIGILL, Illegal instruction
*/
#ifdef DEBUG
void sig_ill(int crap)
{
debug("(sigill)\n");
}
#endif /* DEBUG */
/*
* SIGABRT, abort(3)
*/
#ifdef DEBUG
void sig_abrt(int crap)
{
debug("(sigabrt)\n");
}
#endif /* DEBUG */
/*
@ -423,7 +420,7 @@ void sig_abrt(int crap)
*/
void sig_bus(int crap)
{
time(&now);
time(&cx.now);
respawn++;
if (respawn > 10)
@ -441,27 +438,42 @@ void sig_bus(int crap)
/*
* SIGSEGV shows no mercy, cant schedule it.
*/
#if defined(__linux__) && defined(__x86_64__) && defined(DEBUG) && !defined(__STRICT_ANSI__)
#if defined(__linux__) && defined(DEBUG) && !defined(__STRICT_ANSI__)
#include <sys/ucontext.h>
void sig_segv(int crap, siginfo_t *si, void *uap)
void sig_segv(int sig, siginfo_t *si, void *context)
{
mcontext_t *mctx;
greg_t *rsp,*rip; /* general registers */
ucontext_t *crashcontext = (ucontext_t*)context;
char *sp,*ip; /* general registers */
time(&now);
startup = STARTUP_SIGSEGV;
debug("(sigsegv) trying to access "mx_pfmt"\n",(mx_ptr)si->si_addr);
mctx = &((ucontext_t *)uap)->uc_mcontext;
rsp = &mctx->gregs[15]; /* RSP, 64-bit stack pointer */
rip = &mctx->gregs[16]; /* RIP, 64-bit instruction pointer */
#if defined(__x86_64__)
ip = (char*)crashcontext->uc_mcontext.gregs[16];
sp = (char*)crashcontext->uc_mcontext.gregs[15];
#elif defined(__i386__)
void *ip = (void*)crashcontext->uc_mcontext.gregs[REG_EIP];
void *sp = (void*)crashcontext->uc_mcontext.gregs[REG_ESP];
#elif defined(__aarch64__)
void *ip = (void*)uc->uc_mcontext.pc;
void *sp = (void*)uc->uc_mcontext.sp;
#elif defined(__arm__)
void *pc = (void*)uc->uc_mcontext.arm_pc;
void *sp = (void*)uc->uc_mcontext.arm_sp;
#elif defined(__mips__)
void *pc = (void*)uc->uc_mcontext.pc;
void *sp = (void*)uc->uc_mcontext.gregs[29];
#else
#error "sig_segv(): Unsupported architecture"
#endif
debug("(sigsegv) Stack pointer: "mx_pfmt", Instruction pointer: "mx_pfmt"\n",(mx_ptr)*rsp,(mx_ptr)*rip);
debug("(sigsegv) trying to access "mx_pfmt"\n",(mx_ptr)si->si_addr);
debug("(sigsegv) Stack pointer: "mx_pfmt", Instruction pointer: "mx_pfmt"\n",(mx_ptr)sp,(mx_ptr)ip);
debug("(sigsegv) sig_segv() = "mx_pfmt"\n",(mx_ptr)sig_segv);
debug("(sigsegv) do_crash() = "mx_pfmt"\n",(mx_ptr)do_crash);
if (debug_on_exit)
{
time(&cx.now);
run_debug();
debug_on_exit = FALSE;
}
@ -475,11 +487,11 @@ void sig_segv(int crap, siginfo_t *si, void *uap)
/* NOT REACHED */
}
#else /* defined(__linux__) && defined(__x86_64__) && defined(DEBUG) && !defined(__STRICT_ANSI__) */
#else /* defined(__linux__) && defined(DEBUG) && !defined(__STRICT_ANSI__) */
void sig_segv(int signum)
{
time(&now);
startup = STARTUP_SIGSEGV;
#ifdef DEBUG
if (debug_on_exit)
@ -498,7 +510,7 @@ void sig_segv(int signum)
/* NOT REACHED */
}
#endif /* else defined(__linux__) && defined(__x86_64__) && defined(DEBUG) && !defined(__STRICT_ANSI__) */
#endif /* else defined(__linux__) && defined(DEBUG) && !defined(__STRICT_ANSI__) */
/*
* SIGTERM
@ -509,8 +521,6 @@ void sig_term(int signum)
exit(0);
#endif /* __profiling__ */
time(&now);
#ifdef DEBUG
debug("(sigterm)\n");
#endif /* DEBUG */
@ -525,25 +535,23 @@ void sig_term(int signum)
*
*/
#ifdef __GNUC__
LS void doit(void) __attribute__ ((__noreturn__, __sect(CORE_SEG)));
#endif
void doit(void)
void mainloop(void)
{
struct timeval tv;
SequenceTime this;
Chan *chan;
Client *client;
SequenceTime this;
Strp *qm;
struct timeval tv;
time_t last_update;
last_update = now;
last_update = cx.now;
/*
* init update times so that they dont all run right away
*/
this.tenminute = now / 600;
this.hour = now / 3600;
this.tenminute = cx.now / 600;
this.hour = cx.now / 3600;
/*
* The Main Loop
@ -569,15 +577,15 @@ mainloop:
/*
* check for regular updates
*/
if (last_update != now)
if (last_update != cx.now)
{
last_update = now;
last_update = cx.now;
update(&this);
}
FD_ZERO(&read_fds);
FD_ZERO(&write_fds);
hisock = -1;
cx.hisock = -1;
#ifdef BOTNET
select_botnet();
@ -602,7 +610,7 @@ mainloop:
/*
* unset here, reset if needed in bot loop
*/
short_tv &= ~(TV_SERVCONNECT|TV_LINEBUF);
cx.short_tv &= ~(TV_SERVCONNECT|TV_LINEBUF);
for(current=botlist;current;current=current->next)
{
if (current->sock == -1)
@ -615,7 +623,7 @@ mainloop:
if ((sp = find_server(current->server)))
{
if ((now - current->conntry) > ctimeout)
if ((cx.now - current->conntry) > ctimeout)
{
#ifdef DEBUG
debug("(doit) RAWDNS timed out (%s)\n",sp->name);
@ -641,27 +649,27 @@ mainloop:
{
if (current->connect == CN_SPINNING)
{
if ((now - current->conntry) >= 60)
if ((cx.now - current->conntry) >= 60)
connect_to_server();
}
else
{
doit_jumptonext:
short_tv |= TV_SERVCONNECT;
if ((now - current->conntry) >= 2)
cx.short_tv |= TV_SERVCONNECT;
if ((cx.now - current->conntry) >= 2)
connect_to_server();
}
}
#else /* ! RAWDNS */
if (current->connect == CN_SPINNING)
{
if ((now - current->conntry) >= 60)
if ((cx.now - current->conntry) >= 60)
connect_to_server();
}
else
{
short_tv |= TV_SERVCONNECT;
if ((now - current->conntry) >= 2)
cx.short_tv |= TV_SERVCONNECT;
if ((cx.now - current->conntry) >= 2)
connect_to_server();
}
#endif /* RAWDNS */
@ -672,7 +680,7 @@ doit_jumptonext:
if (current->ip.s_addr == 0)
{
struct sockaddr_in sai;
int sz;
unsigned int sz;
sz = sizeof(sai);
if (getsockname(current->sock,(struct sockaddr *)&sai,&sz) == 0)
@ -680,15 +688,12 @@ doit_jumptonext:
}
if ((current->connect == CN_TRYING) || (current->connect == CN_CONNECTED))
{
short_tv |= TV_SERVCONNECT;
if ((now - current->conntry) > ctimeout)
cx.short_tv |= TV_SERVCONNECT;
if ((cx.now - current->conntry) > ctimeout)
{
#ifdef DEBUG
debug("(doit) {%i} Connection timed out\n",current->sock);
#endif /* DEBUG */
#ifdef IDWRAP
unlink_identfile();
#endif /* IDWRAP */
close(current->sock);
current->sock = -1;
goto restart_dcc;
@ -698,7 +703,7 @@ doit_jumptonext:
}
if (current->sendq)
{
short_tv |= TV_LINEBUF;
cx.short_tv |= TV_LINEBUF;
}
else
{
@ -706,7 +711,7 @@ doit_jumptonext:
{
if (chan->kicklist || chan->modelist)
{
short_tv |= TV_LINEBUF;
cx.short_tv |= TV_LINEBUF;
break;
}
}
@ -752,19 +757,19 @@ restart_dcc:
* Longer delay saves CPU but some features require shorter delays
*/
#ifdef NOTIFY
tv.tv_sec = (short_tv) ? 1 : 5;
tv.tv_sec = (cx.short_tv) ? 1 : 5;
#else /* NOTIFY */
tv.tv_sec = (short_tv) ? 1 : 30;
tv.tv_sec = (cx.short_tv) ? 1 : 30;
#endif /* NOTIFY */
tv.tv_usec = 0;
if ((select(hisock+1,&read_fds,&write_fds,0,&tv) == -1) && (errno == EINTR))
if ((select(cx.hisock+1,&read_fds,&write_fds,0,&tv) == -1) && (errno == EINTR))
goto mainloop;
/*
* Update current time
*/
time(&now);
time(&cx.now);
for(current=botlist;current;current=current->next)
{
@ -773,8 +778,8 @@ restart_dcc:
* it is important that the check is done before anything
* else that could potentially send output to the server!
*/
if (current->sendq_time < now)
current->sendq_time = now;
if (current->sendq_time < cx.now)
current->sendq_time = cx.now;
}
for(current=botlist;current;current=current->next)
@ -785,6 +790,18 @@ restart_dcc:
if (current->sock != -1)
process_server_input();
#ifdef DEBUG
if (current->inject)
{
char injection[MSGLEN];
stringcpy(injection,current->inject);
Free((char**)&current->inject);
debug("(*inject) %s\n");
parse_server_input(injection);
}
#endif /* DEBUG */
if (current->connect == CN_ONLINE)
{
/*
@ -792,10 +809,10 @@ restart_dcc:
*/
if (current->setting[TOG_NOIDLE].int_var)
{
if ((now - current->lastantiidle) > PINGSENDINTERVAL)
if ((cx.now - current->lastantiidle) > PINGSENDINTERVAL)
{
to_server("PRIVMSG * :0\n");
current->lastantiidle = now;
current->lastantiidle = cx.now;
}
}
/*
@ -825,7 +842,7 @@ restart_dcc:
/*
* the un-important sendq only sends when sendq_time <= now
*/
if ((current->sendq) && (current->sendq_time <= now))
if ((current->sendq) && (current->sendq_time <= cx.now))
{
qm = current->sendq;
to_server(FMT_PLAINLINE,qm->p);
@ -857,7 +874,8 @@ restart_die:
#endif /* BOTNET */
#ifdef BOUNCE
process_bounce();
if (bounce_sock != -1 || bnclist)
process_bounce();
#endif /* BOUNCE */
#ifdef CHANBAN
@ -865,7 +883,11 @@ restart_die:
#endif /* CHANBAN */
#ifdef RAWDNS
process_rawdns();
/*
* Only a single socket to check.
*/
if (dnssock != -1 && FD_ISSET(dnssock,&read_fds))
process_rawdns();
#endif /* RAWDNS */
#ifdef UPTIME
@ -881,7 +903,8 @@ restart_die:
#endif
#ifdef TRIVIA
trivia_tick();
if (triv_next_time && (cx.now >= triv_next_time))
trivia_tick();
#endif /* TRIVIA */
/*
@ -894,15 +917,12 @@ restart_die:
}
/*
* main(), we love it and cant live without it
* parse commandline
*/
LS char *bad_exe = "init: Error: Improper executable name\n";
const char *bad_exe = "init: Error: Improper executable name\n";
#ifdef __GNUC__
int main(int argc, char **argv, char **envp) __attribute__ ((__sect(INIT_SEG)));
#endif
int main(int argc, char **argv, char **envp)
void parse_commandline(int argc, char **argv, char **envp)
{
struct stat st;
char *opt;
@ -911,8 +931,9 @@ int main(int argc, char **argv, char **envp)
#ifdef NEWBIE
int n = 0;
#endif
memset(&cx,0,sizeof(cx));
uptime = time(&now);
uptime = time(&cx.now);
startup = STARTUP_NORMALSTART;
if ((getuid() == 0) || (geteuid() == 0))
@ -924,7 +945,12 @@ int main(int argc, char **argv, char **envp)
stat("..",&st);
parent_inode = st.st_ino; /* used for is_safepath() */
srand(now+getpid());
if (stat("/proc",&st) >= 0)
{
cx.system_uptime = st.st_ctime;
}
srand(cx.now + getpid());
/*
* Code to detect and recover after a RESET
@ -961,6 +987,7 @@ int main(int argc, char **argv, char **envp)
}
#ifdef DEBUG
/* memory tracking */
mrrec = calloc(sizeof(aMEA),1);
#endif /* DEBUG */
@ -969,7 +996,7 @@ int main(int argc, char **argv, char **envp)
to_file(1,bad_exe);
_exit(1);
}
if ((opt = STRCHR(*argv,' ')) != NULL)
if ((opt = stringchr(*argv,' ')) != NULL)
{
*(opt++) = 0;
respawn = asc2int(opt);
@ -989,66 +1016,26 @@ int main(int argc, char **argv, char **envp)
opt = *argv;
switch(opt[1])
{
case 'v':
versiononly = TRUE;
break;
case 'h':
to_file(1,TEXT_USAGE,executable);
to_file(1,
TEXT_CSWITCH
#ifdef DEBUG
TEXT_DSWITCH
#endif /* DEBUG */
TEXT_ESWITCH
TEXT_FSWITCH
TEXT_HSWITCH
#ifdef DEBUG
TEXT_OSWITCH
TEXT_PSWITCH1
TEXT_PSWITCH2
#endif /* DEBUG */
TEXT_TSWITCH
TEXT_VSWITCH
#ifdef DEBUG
TEXT_XSWITCH
#endif /* DEBUG */
);
_exit(0);
case 'c':
makecore = TRUE;
break;
#ifdef DEBUG
case 'd':
dodebug = TRUE;
do_fork = FALSE;
break;
case 'o':
if (opt[2] != 0)
do_fork = TRUE;
if (opt[2] != 0) /* -d[file] */
{
debugfile = &opt[2];
}
else
if (argv[1] && argv[1][0] != '-') /* -d [file] */
{
++argv;
if (!*argv)
{
to_file(1,"init: No debugfile specified\n");
_exit(0);
}
debugfile = *argv;
argc--;
}
do_fork = TRUE;
break;
case 'p':
++argv;
if (*argv)
to_file(1,"%s\n",makepass(*argv));
else
to_file(1,"error: Missing argument for -p <string>\n");
_exit(0);
case 'X':
debug_on_exit = TRUE;
do_fork = FALSE;
break;
#endif /* DEBUG */
case 'e': /* run a single command before exiting */
@ -1062,9 +1049,6 @@ int main(int argc, char **argv, char **envp)
else
to_file(1,"error: Missing argument for -e <command string>\n");
_exit(0);
case 't':
startup = STARTUP_TESTRUN;
break;
case 'f':
if (opt[2] != 0)
{
@ -1083,15 +1067,49 @@ int main(int argc, char **argv, char **envp)
}
to_file(1,INFO_USINGCONF,configfile);
break;
case 'h':
to_file(1,TEXT_USAGE,executable);
to_file(1,
TEXT_CSWITCH
#ifdef DEBUG
TEXT_DSWITCH
#endif /* DEBUG */
TEXT_ESWITCH
TEXT_FSWITCH
TEXT_HSWITCH
TEXT_PSWITCH1
TEXT_PSWITCH2
TEXT_TSWITCH
TEXT_VSWITCH
#ifdef DEBUG
TEXT_XSWITCH
#endif /* DEBUG */
);
_exit(0);
case 'p':
++argv;
if (*argv)
to_file(1,"%s\n",makepass(*argv));
else
to_file(1,"error: Missing argument for -p <string>\n");
_exit(0);
case 't':
startup = STARTUP_TESTRUN;
break;
case 'v':
versiononly = TRUE;
break;
#ifdef DEBUG
case 'x':
debug_on_exit = TRUE;
break;
#endif /* DEBUG */
default:
to_file(1,ERR_UNKNOWNOPT,opt);
_exit(1);
}
}
servergrouplist = (ServerGroup*)&defaultServerGroup;
currentservergroup = (ServerGroup*)&defaultServerGroup;
if (!mechresetenv)
{
to_file(1,TEXT_HDR_VERS,VERSION,SRCDATE);
@ -1106,7 +1124,7 @@ int main(int argc, char **argv, char **envp)
to_file(1,"warning: current configuration file overrides session file\n");
}
#endif /* SESSION */
if (stat(configfile,&st));
if (stat(configfile,&st))
{
if ((st.st_mode & (S_IWGRP|S_IWOTH)) != 0)
{
@ -1116,7 +1134,7 @@ int main(int argc, char **argv, char **envp)
if ((st.st_mode & (S_IRGRP|S_IROTH)) != 0)
to_file(1,"warning: configfile is readable by others\n");
}
if (stat(".",&st));
if (stat(".",&st))
{
if ((st.st_mode & (S_IWGRP|S_IWOTH)) != 0)
{
@ -1154,11 +1172,10 @@ int main(int argc, char **argv, char **envp)
ia_default.s_addr = LOCALHOST_ULONG;
#endif /* RAWDNS */
memset(&__internal_users,0,sizeof(User)*2);
CoreUser.x.x.access = 100;
LocalBot.x.x.access = 200;
LocalBot.x.x.aop = 1;
LocalBot.chan = CoreUser.chan = (Strp*)&CMA;
cx.CoreUser.x.x.access = 100;
cx.LocalBot.x.x.access = 200;
cx.LocalBot.x.x.aop = 1;
cx.LocalBot.chan = cx.CoreUser.chan = (Strp*)&CMA;
readcfgfile();
@ -1182,7 +1199,7 @@ int main(int argc, char **argv, char **envp)
}
#else
{
if (stat(opt,&st));
if (stat(opt,&st))
{
if ((st.st_mode & (S_IWGRP|S_IWOTH)) != 0)
{
@ -1196,7 +1213,10 @@ int main(int argc, char **argv, char **envp)
}
if (current->userlist == NULL)
{
to_file(1,"init: No userlist loaded for %s\n",nullstr(current->nick));
char *nick;
nick = getbotnick(current);
to_file(1,"init: No userlist loaded for %s\n",nullstr(nick));
n++;
}
}
@ -1252,7 +1272,7 @@ int main(int argc, char **argv, char **envp)
#endif /* CTCP */
#ifdef BOTNET
last_autolink = now + 30 + (rand() >> 27); /* + 0-31 seconds */
last_autolink = cx.now + 30 + (rand() >> 27); /* + 0-31 seconds */
#endif /* BOTNET */
if (mechresetenv)
@ -1296,7 +1316,16 @@ int main(int argc, char **argv, char **envp)
}
startup = STARTUP_RUNNING;
#ifdef DEBUG
debug("(main) entering doit()...\n");
debug("(main) entering main loop...\n");
#endif
doit();
}
/*
* Make main short and sweet, reduce stack data
* Main(), we love it and cant live without it
*/
int main(int argc, char **argv, char **envp)
{
parse_commandline(argc, argv, envp);
mainloop();
}

178
src/net.c
View File

@ -46,10 +46,11 @@ const char banneropt[] = "BB%i %i PTA"
#ifdef TELNET
char *telnetprompt = TEXT_ENTERNICKNAME;
#endif /* TELNET */
/*
* this is a partial copy of the BotNet struct
*/
LS struct
struct
{
struct BotNet *next;
@ -73,7 +74,7 @@ typedef struct LinkCmd
#define RELAY_YES 1
#define RELAY_NO 0
LS const LinkCmd basicProto[] =
const LinkCmd basicProto[] =
{
{ "BA", basicAuth, RELAY_NO },
{ "BB", basicBanner, RELAY_NO },
@ -95,7 +96,7 @@ LS const LinkCmd basicProto[] =
{ "\0\0", NULL, RELAY_NO },
};
LS int deadlinks = FALSE;
int deadlinks = FALSE;
/*
*
@ -159,21 +160,24 @@ NetCfg *find_netcfg(int guid)
BotInfo *make_botinfo(int guid, int hops, char *nuh, char *server, char *version)
{
BotInfo *new;
BotInfo *newbinfo;
set_mallocdoer(make_botinfo);
new = (BotInfo*)Calloc(sizeof(BotInfo) + StrlenX(nuh,server,version,NULL));
newbinfo = (BotInfo*)Calloc(sizeof(BotInfo) + StrlenX(nuh,server,version,NULL));
new->guid = guid;
new->hops = hops;
newbinfo->guid = guid;
newbinfo->hops = hops;
new->server = stringcat(new->nuh,nuh) + 1;
new->version = stringcat(new->server,server) + 1;
stringcpy(new->version,version);
newbinfo->server = stringcat(newbinfo->nuh,nuh) + 1;
newbinfo->version = stringcat(newbinfo->server,server) + 1;
stringcpy(newbinfo->version,version);
return(new);
return(newbinfo);
}
/*
* broadcast data to all except the source
*/
void botnet_relay(BotNet *source, char *format, ...)
{
BotNet *bn;
@ -188,9 +192,8 @@ void botnet_relay(BotNet *source, char *format, ...)
if (!sz)
{
va_start(msg,format);
vsprintf(globaldata,format,msg);
sz = vsprintf(globaldata,format,msg);
va_end(msg);
sz = strlen(globaldata);
}
if (write(bn->sock,globaldata,sz) < 0)
@ -201,23 +204,10 @@ void botnet_relay(BotNet *source, char *format, ...)
}
}
void botnet_refreshbotinfo(void)
{
Server *sv;
sv = find_server(current->server);
botnet_relay(NULL,"BL%i 0 %s!%s %s:%i %s %s\n", current->guid,current->nick,
(current->userhost) ? current->userhost : UNKNOWNATUNKNOWN,
(sv) ? ((*sv->realname) ? sv->realname : sv->name) : UNKNOWN,
(sv) ? sv->port : 0,BOTCLASS,VERSION);
#ifdef DEBUG
debug("(botnet_refreshbotinfo) sent refreshed information to botnet\n");
#endif /* DEBUG */
}
void botnet_binfo_relay(BotNet *source, BotInfo *binfo)
{
botnet_relay(source,"BL%i %i %s %s %s\n",binfo->guid,(binfo->hops + 1),
botnet_relay(source,
"BL%i %i %s %s %s\n",binfo->guid,(binfo->hops + 1),
(binfo->nuh) ? binfo->nuh : UNKNOWNATUNKNOWN,
(binfo->server) ? binfo->server : UNKNOWN,
(binfo->version) ? binfo->version : "-");
@ -225,12 +215,27 @@ void botnet_binfo_relay(BotNet *source, BotInfo *binfo)
void botnet_binfo_tofile(int sock, BotInfo *binfo)
{
to_file(sock,"BL%i %i %s %s %s\n",binfo->guid,(binfo->hops + 1),
to_file(sock,
"BL%i %i %s %s %s\n",binfo->guid,(binfo->hops + 1),
(binfo->nuh) ? binfo->nuh : UNKNOWNATUNKNOWN,
(binfo->server) ? binfo->server : UNKNOWN,
(binfo->version) ? binfo->version : "-");
}
void botnet_refreshbotinfo(void)
{
Server *sv;
sv = find_server(current->server);
botnet_relay(NULL,"BL%i 0 %s!%s %s:%i %s %s\n", current->guid,getbotnick(current),
getbotuserhost(current),
(sv) ? ((*sv->realname) ? sv->realname : sv->name) : UNKNOWN,
(sv) ? sv->port : 0,BOTCLASS,VERSION);
#ifdef DEBUG
debug("(botnet_refreshbotinfo) sent refreshed information to botnet\n");
#endif /* DEBUG */
}
void botnet_dumplinklist(BotNet *bn)
{
BotInfo *binfo;
@ -248,14 +253,14 @@ void botnet_dumplinklist(BotNet *bn)
*/
sv = find_server(bot->server);
to_file(bn->sock,"BL%i %c %s!%s %s:%i %s %s\n",bot->guid,
(bot == bn->controller) ? '0' : '1',bot->nick,
(bot->userhost) ? bot->userhost : UNKNOWNATUNKNOWN,
(bot == bn->controller) ? '0' : '1',getbotnick(bot),
getbotuserhost(bot),
(sv) ? ((*sv->realname) ? sv->realname : sv->name) : UNKNOWN,
(sv) ? sv->port : 0,BOTCLASS,VERSION);
}
for(bn2=botnetlist;bn2;bn2=bn2->next)
{
if ((bn2 == bn) || (bn2->status != BN_LINKED) || !(bn2->list_complete))
if ((bn2 == bn) || (bn2->status != BN_LINKED) || (bn2->opt.links_complete == 0))
continue;
for(binfo=bn2->botinfo;binfo;binfo=binfo->next)
botnet_binfo_tofile(bn->sock,binfo);
@ -289,7 +294,7 @@ int connect_to_bot(NetCfg *cfg)
bn->sock = s;
bn->status = BN_CONNECT;
bn->when = now;
bn->when = cx.now;
bn->guid = cfg->guid;
bn->next = botnetlist;
@ -409,7 +414,7 @@ void basicAuth(BotNet *bn, char *rest)
{
case BNAUTH_PLAINTEXT:
/*
>> plain text given: "DomoOmiGato" stored "kooplook0988"
>> plain text given: "DomoOmiGato" stored "........."
(reset_linkable) guid 1337 reset to linkable
(basicAuth) bad password [ guid = 1337 ]
*/
@ -420,6 +425,12 @@ void basicAuth(BotNet *bn, char *rest)
goto badpass;
break;
#ifdef SHACRYPT
/*
(in) {6} BB1881 634704033 PTA SHA
(out) {6} BB9344 1233037145 PTA SHA
>> sha pass exchange: "........ ......... 634704033 1233037145"
(out) {2} BASHA $6$5525$mZLr762......
*/
case BNAUTH_SHA:
{
char *enc,temppass[24 + Strlen2(pass,linkpass)]; /* linkpass is never NULL */
@ -476,7 +487,7 @@ void basicAuth(BotNet *bn, char *rest)
debug("(basicAuth) bn->tick = 0\n");
#endif /* DEBUG */
bn->tick = 0;
bn->tick_last = now - 580; /* 10 minutes (10*60) - 20 seconds */
bn->tick_last = cx.now - 580; /* 10 minutes (10*60) - 20 seconds */
}
void basicAuthOK(BotNet *bn, char *rest)
@ -490,7 +501,7 @@ void basicAuthOK(BotNet *bn, char *rest)
debug("(basicAuthOK) bn->tick = 0\n");
#endif /* DEBUG */
bn->tick = 0;
bn->tick_last = now - 580; /* 10 minutes (10*60) - 20 seconds */
bn->tick_last = cx.now - 580; /* 10 minutes (10*60) - 20 seconds */
}
void basicBanner(BotNet *bn, char *rest)
@ -608,7 +619,7 @@ void basicBanner(BotNet *bn, char *rest)
/*
* update timestamp
*/
bn->when = now;
bn->when = cx.now;
/*
* if the remote bot initiated the connection we need a valid pass from them
@ -701,7 +712,7 @@ void basicBanner(BotNet *bn, char *rest)
void basicLink(BotNet *bn, char *version)
{
BotInfo *binfo,*delete,**pp;
BotInfo *binfo,**pp;
NetCfg *cfg;
char *nuh,*server;
int guid,hops;
@ -748,7 +759,7 @@ void basicLink(BotNet *bn, char *version)
continue;
cfg->linked = TRUE;
}
bn->list_complete = TRUE;
bn->opt.links_complete = TRUE;
return;
}
@ -774,23 +785,25 @@ void basicLink(BotNet *bn, char *version)
binfo = make_botinfo(guid,hops,nuh,server,version);
if (bn->botinfo == NULL)
send_global(SPYSTR_BOTNET,"connecting to %s [guid %i]",nickcpy(NULL,nuh),bn->guid);
send_global(SPYSTR_STATUS,"Connected to %s [guid %i]",nickcpy(NULL,nuh),bn->guid);
pp = &bn->botinfo;
while(*pp)
{
delete = *pp;
if (guid == delete->guid)
BotInfo *trash;
if (guid == (*pp)->guid)
{
*pp = delete->next;
Free((char**)&delete);
trash = *pp;
*pp = trash->next;
Free((char**)&trash);
break;
}
pp = &delete->next;
pp = &(*pp)->next;
}
binfo->next = *pp;
*pp = binfo;
if (bn->list_complete)
if (bn->opt.links_complete)
{
if ((cfg = find_netcfg(guid)))
cfg->linked = TRUE;
@ -904,10 +917,10 @@ void partyAuth(BotNet *bn, char *rest)
{
User *user;
Strp *ump;
char *name,*userhost,*checksum;
char *userhost,*checksum;
int m;
name = chop(&rest);
chop(&rest);
userhost = chop(&rest);
if ((checksum = chop(&rest)) == NULL)
checksum = "";
@ -987,7 +1000,7 @@ int commandlocal(int dg, int sg, char *from, char *command)
*p2 = current->setting[CHR_CMDCHAR].char_var;
stringcpy((*p2 == *command) ? p2 : p2+1,command);
on_msg(p1,current->nick,p2);
on_msg(p1,getbotnick(current),p2);
CurrentDCC = NULL;
}
if (dg == -1)
@ -1198,7 +1211,7 @@ void ushareUser(BotNet *bn, char *rest)
bn->addsession = 0;
bn->tick++;
to_file(bn->sock,"UT%i\n",bn->tick);
bn->tick_last = now;
bn->tick_last = cx.now;
break;
case '*':
case '#':
@ -1319,10 +1332,8 @@ void ushareTick(BotNet *bn, char *rest)
void ushareDelete(BotNet *bn, char *rest)
{
User *user;
char *orig;
int modcount;
orig = rest;
modcount = asc2int(chop(&rest));
if (errno)
return;
@ -1417,7 +1428,7 @@ void botnet_newsock(void)
bn->sock = s;
bn->status = BN_UNKNOWN;
bn->lsid = rand();
bn->when = now;
bn->when = cx.now;
bn->next = botnetlist;
botnetlist = bn;
@ -1425,7 +1436,7 @@ void botnet_newsock(void)
/*
* crude... but, should work
*/
last_autolink = now + AUTOLINK_DELAY;
last_autolink = cx.now + AUTOLINK_DELAY;
}
/*
@ -1455,9 +1466,9 @@ void select_botnet(void)
/*
* autolink
*/
if (autolink && (now > last_autolink))
if (autolink && (cx.now > last_autolink))
{
last_autolink = now + AUTOLINK_DELAY;
last_autolink = cx.now + AUTOLINK_DELAY;
if (autolink_cfg)
autolink_cfg = autolink_cfg->next;
@ -1474,14 +1485,14 @@ void select_botnet(void)
}
}
short_tv &= ~TV_BOTNET;
cx.short_tv &= ~TV_BOTNET;
for(bn=botnetlist;bn;bn=bn->next)
{
chkhigh(bn->sock);
if (bn->status == BN_CONNECT)
{
FD_SET(bn->sock,&write_fds);
short_tv |= TV_BOTNET;
cx.short_tv |= TV_BOTNET;
}
else
{
@ -1502,12 +1513,12 @@ void process_botnet(void)
/*
* usersharing tick, 10 minute period
*/
if (bn->status == BN_LINKED && (bn->tick_last + 600) < now)
if (bn->status == BN_LINKED && (bn->tick_last + 600) < cx.now)
{
#ifdef DEBUG
debug("(process_botnet) {%i} periodic ushare tick\n",bn->sock);
#endif /* DEBUG */
bn->tick_last = now;
bn->tick_last = cx.now;
to_file(bn->sock,"UT%i\n",bn->tick);
}
@ -1531,7 +1542,7 @@ void process_botnet(void)
else
{
bn->status = BN_BANNERSENT;
bn->when = now;
bn->when = cx.now;
}
/* write_fds is only set for sockets where reading is not needed */
continue;
@ -1577,7 +1588,7 @@ void process_botnet(void)
}
}
if ((bn->status == BN_CONNECT) && ((now - bn->when) > LINKTIME))
if ((bn->status == BN_CONNECT) && ((cx.now - bn->when) > LINKTIME))
{
#ifdef DEBUG
debug("(process_botnet) {%i} Life is good; but not for this guy (guid == %i). Timeout!\n",
@ -1611,7 +1622,7 @@ clean:
debug("(process_botnet) botnet quit: guid %i child of %i on socket %i\n",
binfo->guid,bn->guid,bn->sock);
#endif /* DEBUG */
if (bn->list_complete)
if (bn->opt.links_complete)
{
send_global(SPYSTR_BOTNET,"quit: guid %i (child of %i)",
binfo->guid,bn->guid);
@ -1620,7 +1631,7 @@ clean:
}
Free((char**)&binfo);
}
if (bn->list_complete)
if (bn->opt.links_complete)
{
botnet_relay(bn,"BQ%i\n",bn->guid);
}
@ -1639,6 +1650,22 @@ clean:
*
*/
void do_link_noargs(const char *from)
{
NetCfg *cfg;
/*
* list all the known links
*/
table_buffer("guid\tpass\thost\tport");
for(cfg=netcfglist;cfg;cfg=cfg->next)
{
table_buffer("%i\t%s\t%s\t%i",cfg->guid,(cfg->pass) ? cfg->pass : EMPTYSTR,
(cfg->host) ? cfg->host : EMPTYSTR,cfg->port);
}
table_send(from,2);
}
void do_link(COMMAND_ARGS)
{
/*
@ -1649,21 +1676,6 @@ void do_link(COMMAND_ARGS)
int iguid,iport;
int mode;
/*
* list all the known links
*/
if (!*rest)
{
table_buffer("guid\tpass\thost\tport");
for(cfg=netcfglist;cfg;cfg=cfg->next)
{
table_buffer("%i\t%s\t%s\t%i",cfg->guid,(cfg->pass) ? cfg->pass : "",
(cfg->host) ? cfg->host : "",cfg->port);
}
table_send(from,2);
return;
}
guid = chop(&rest);
if (*guid == '+' || *guid == '-')
mode = *guid++;
@ -1686,7 +1698,7 @@ usage:
pp = &cfg->next;
}
if (CurrentUser == &CoreUser || mode == '+')
if (CurrentUser == &cx.CoreUser || mode == '+')
{
if (cfg)
{
@ -1726,6 +1738,7 @@ usage:
if (mode == '-')
{
to_user(from,"removing link guid: %i",iguid);
*pp = cfg->next;
Free((char**)&cfg);
return;
@ -1759,10 +1772,9 @@ void do_cmd(COMMAND_ARGS)
Mech *backup;
char tempdata[MAXLEN];
char *target,*orig = rest;
int guid;
target = chop(&rest);
guid = asc2int(target);
asc2int(target);
if (errno)
{
unchop(orig,rest);
@ -1776,7 +1788,7 @@ void do_cmd(COMMAND_ARGS)
return;
}
if (STRCHR(from,'!'))
if (stringchr(from,'!'))
sprintf(tempdata,"%s %i %s %s",target,current->guid,from,rest);
else
sprintf(tempdata,"%s %i %s!%s %s",target,current->guid,from,CurrentUser->mask->p,rest);

View File

@ -34,7 +34,6 @@ int catch_note(char *from, char *to, char *rest)
{
User *u;
Note *n,**pp;
Strp *sp,**np;
#ifdef DEBUG
debug("(catch_note) from = %s, to = %s, rest = %s\n",from,to,rest);
@ -64,7 +63,7 @@ int catch_note(char *from, char *to, char *rest)
append_strp(&u->note,rest);
return(TRUE);
}
if ((now - n->start) > 120)
if ((cx.now - n->start) > 120)
{
*pp = n->next;
Free((char**)&n);
@ -85,7 +84,6 @@ void do_note(COMMAND_ARGS)
{
User *u;
Note *n;
Strp *sp,**np;
char header[MSGLEN];
/*
@ -101,7 +99,7 @@ void do_note(COMMAND_ARGS)
set_mallocdoer(do_note);
n = Calloc(sizeof(Note) + StrlenX(from,to,u->name,NULL));
n->start = now;
n->start = cx.now;
n->next = notelist;
notelist = n;
@ -112,7 +110,7 @@ void do_note(COMMAND_ARGS)
/*
* add a note header
*/
sprintf(header,"\001%s %s",from,time2str(now));
sprintf(header,"\001%s %s",from,maketimestr(cx.now,TFMT_FULL));
append_strp(&u->note,header);
}

40
src/onhash.h Normal file
View File

@ -0,0 +1,40 @@
/*
*
* This file is included in ons.c right before on_msg
* It is also used in gencmd.c where its used with different
* random hashdata in order to find a hashmap with no
* collisions. Unfortunatly there is no way of handling
* hasmaps with collisions currently so if it gets stuck
* trying hashdata forever you are out of luck.
*
*/
int mkhash(const char *cmd)
{
const char *s;
int h,t,ki,kk;
uint8_t a,b;
s = cmd;
ki = 15 * strlen(cmd);
kk = hashdata[ki & HASHDATAMASK];
while(*s)
{
a = tolowertab[(uchar)s[0]];
b = tolowertab[(uchar)s[1]];
h = (a - b) & HASHDATAMASK;
ki += a + hashdata[h];
#ifdef HEATMAP
/* used when refining the algorithm */
heatmap[ki & HASHDATAMASK] += 1;
#endif
kk ^= hashdata[ki & HASHDATAMASK] ^ (hashdata[(h + ki) & HASHDATAMASK] << 8);
s++;
}
t = kk & 511;
#ifndef COM_ONS_C
if (hash[t] > 0)
collis += 1;
hash[t] += 1;
#endif
return(t);
}

504
src/ons.c
View File

@ -1,7 +1,7 @@
/*
EnergyMech, IRC bot software
Parts Copyright (c) 1997-2024 proton
Parts Copyright (c) 1997-2025 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
@ -82,7 +82,7 @@ void on_kick(char *from, char *rest)
if (current->spy & SPYF_CHANNEL)
send_spy(chan->name,"*** %s was kicked by %s (%s)",nick,CurrentNick,rest);
if (!nickcmp(current->nick,nick))
if (!nickcmp(getbotnick(current),nick))
{
#ifdef DEBUG
debug("(on_kick) I was kicked from %s\n",chan->name);
@ -168,7 +168,7 @@ void on_kick(char *from, char *rest)
if (victim)
{
#ifdef SEEN
make_seen(nick,victim->userhost,from,rest,now,SEEN_KICKED);
make_seen(nick,victim->userhost,from,rest,cx.now,SEEN_KICKED);
#endif /* SEEN */
/*
@ -231,7 +231,7 @@ void on_join(Chan *chan, char *from)
*/
if (chan->setting[TOG_CTL].int_var)
{
if (STRCHR(from,'\031') || STRCHR(from,'\002') || STRCHR(from,'\022') || STRCHR(from,'\026'))
if (stringchr(from,'\031') || stringchr(from,'\002') || stringchr(from,'\022') || stringchr(from,'\026'))
{
deop_siteban(chan,cu);
send_kick(chan,CurrentNick,KICK_BAD_IDENT);
@ -290,8 +290,8 @@ void on_nick(char *from, char *newnick)
* grab the nick *RIGHT NOW*
* this is a setting because this is risky, you might get collided as a result
*/
if (!nickcmp(CurrentNick,current->wantnick))
to_server("NICK %s\n",current->wantnick);
if (!nickcmp(CurrentNick,getbotwantnick(current)))
to_server("NICK %s\n",getbotwantnick(current));
#endif /* FASTNICK */
/*
@ -300,7 +300,7 @@ void on_nick(char *from, char *newnick)
sprintf(newnuh,"%s!%s",newnick,getuh(from));
#ifdef SEEN
make_seen(CurrentNick,from,newnick,NULL,now,SEEN_NEWNICK);
make_seen(CurrentNick,from,newnick,NULL,cx.now,SEEN_NEWNICK);
#endif /* SEEN */
/*
@ -311,9 +311,12 @@ void on_nick(char *from, char *newnick)
change_authnick(from,newnuh);
if ((isbot = !nickcmp(current->nick,CurrentNick)))
if ((isbot = !nickcmp(getbotnick(current),CurrentNick)))
{
setbotnick(current,newnick);
#ifdef BOTNET
botnet_refreshbotinfo();
#endif /* BOTNET */
}
for(chan=current->chanlist;chan;chan=chan->next)
@ -355,9 +358,9 @@ void on_nick(char *from, char *newnick)
if ((maxcount = chan->setting[INT_NCL].int_var) < 2)
continue;
if ((now - cu->action_time[INDEX_NICK]) > NICKFLOODTIME)
if ((cx.now - cu->action_time[INDEX_NICK]) > NICKFLOODTIME)
{
cu->action_time[INDEX_NICK] = now + (NICKFLOODTIME / (maxcount - 1));
cu->action_time[INDEX_NICK] = cx.now + (NICKFLOODTIME / (maxcount - 1));
cu->action_num[INDEX_NICK] = 1;
}
else
@ -372,6 +375,8 @@ void on_nick(char *from, char *newnick)
}
}
#include "onhash.h"
void on_msg(char *from, char *to, char *rest)
{
#ifdef SCRIPTING
@ -389,7 +394,7 @@ void on_msg(char *from, char *to, char *rest)
uchar *p1,*p2;
int has_cc,has_bang;
int uaccess;
int i,j;
int i,j,command_hash;
/*
* No line sent to this routine should be longer than MSGLEN
@ -397,6 +402,14 @@ void on_msg(char *from, char *to, char *rest)
* non-NULL and non-zerolength
*/
/*
* remember where the string started
*/
origstart = rest;
/*
* Are we recording a note?
*/
#ifdef NOTE
if (notelist && catch_note(from,to,rest))
return;
@ -407,10 +420,7 @@ void on_msg(char *from, char *to, char *rest)
* public commands, we can go directly to common_public()
*/
if (CurrentChan && !CurrentChan->setting[TOG_PUB].int_var)
{
common_public(CurrentChan,from,"<%s> %s",rest);
return;
}
goto public_msg_unchopped;
if (CurrentDCC)
{
@ -425,12 +435,8 @@ void on_msg(char *from, char *to, char *rest)
return;
}
/*
* remember where the string started
*/
origstart = rest;
if (from == CoreUser.name)
if (from == cx.CoreUser.name)
{
has_cc = TRUE;
}
@ -445,7 +451,7 @@ void on_msg(char *from, char *to, char *rest)
if ((p2 = (uchar*)(command = chop(&rest))) == NULL)
return;
p1 = (uchar*)current->nick;
p1 = (uchar*)getbotnick(current);
while(!(i = tolowertab[*(p1++)] - tolowertab[*p2]) && *(p2++))
;
@ -469,15 +475,15 @@ void on_msg(char *from, char *to, char *rest)
command++;
}
command_hash = mkhash(command);
#ifdef ALIAS
arec = 0;
recheck_alias:
#endif /* ALIAS */
#ifdef ALIAS
for(alias=aliaslist;alias;alias=alias->next)
{
if (!stringcasecmp(alias->alias,command))
if (command_hash == alias->hash && stringcasecmp(alias->alias,command) == 0)
{
unchop(command,rest);
afmt(amem,alias->format,command);
@ -521,177 +527,186 @@ recheck_alias:
if (i) return;
#endif /* SCRIPTING */
command_hash = mkhash(command);
i = hashmap[command_hash];
#ifdef DEBUG
debug("(on_msg) %s = hash %i, mapped to %i %s\n",command,command_hash,i,(i==255)?"(no match)":mcmd[i].name);
#endif /* DEBUG */
if (i == 255)
goto public_msg;
if (!has_cc && mcmd[i].cc && !(has_bang && mcmd[i].cbang))
goto public_msg;
if (uaccess < acmd[i])
goto public_msg;
/*
* match "command" against internal command list
* The string hash matches a command, but is it a false positive?
*/
for(;mcmd[i].name;i++)
{
if (!has_cc && mcmd[i].cc && !(has_bang && mcmd[i].cbang))
continue;
if (uaccess < acmd[i])
continue;
j = stringcasecmp(mcmd[i].name,command);
if (j < 0)
continue;
if (j > 0)
break;
if (stringcasecmp(mcmd[i].name,command) != 0)
goto public_msg;
#if defined(BOTNET) && defined(REDIRECT)
if (mcmd[i].nocmd && redirect.to)
return;
if (mcmd[i].nocmd && redirect.to)
return;
#endif /* BOTNET && REDIRECT */
if (mcmd[i].nopub && CurrentChan)
{
if (mcmd[i].nopub && CurrentChan)
{
#ifdef DEBUG
debug("(on_msg) Public command (%s) ignored\n",command);
debug("(on_msg) Public command (%s) ignored\n",command);
#endif /* DEBUG */
return;
}
CurrentCmd = &mcmd[i];
#ifdef SUPPRESS
#ifdef BOTNET
/* experimental command supression */
if (CurrentCmd->name == current->supres_cmd)
{
int crc;
crc = makecrc(rest);
if (current->supres_crc == crc)
{
/* another bot has already executed this command and is trying to supress its execution on other bots */
current->supres_cmd = NULL;
current->supres_crc = 0;
#ifdef DEBUG
debug("(on_msg) command \"%s\" from %s was supressed\n",CurrentCmd->name,CurrentNick);
#endif
return;
}
}
/*if command should be supressed ... */
if (mcmd[i].supres && CurrentChan)
{
send_suppress(CurrentCmd->name,rest);
}
#endif
#endif /* SUPPRESS */
/*
* convert the command to uppercase
*/
stringcpy(command,mcmd[i].name);
/*
* send statmsg with info on the command executed
*/
if (current->setting[TOG_SPY].int_var)
{
send_spy(SPYSTR_STATUS,":%s[%i]: Executing %s[%i]",
CurrentNick,uaccess,command,(int)acmd[i]);
}
/*
* CAXS check: first argument might be a channel
* check user access on target channel
*/
if (mcmd[i].caxs)
{
/* get channel name; 1: msg, 2: to, 3: active channel */
to = (char*)get_channel(to,&rest);
if (!ischannel(to))
return;
uaccess = get_authaccess(from,to);
if (uaccess < acmd[i])
return;
CurrentChan = find_channel_ny(to);
if (mcmd[i].acchan && (CurrentChan == NULL || CurrentChan->active == 0))
{
to_user(from,ERR_CHAN,to);
return;
}
}
else
/*
* GAXS check: user needs global access
*/
if (mcmd[i].gaxs)
{
uaccess = get_authaccess(from,MATCH_ALL);
if (uaccess < acmd[i])
return;
}
/*
* list of last LASTCMDSIZE commands
*/
if (from != CoreUser.name)
{
Free(&current->lastcmds[LASTCMDSIZE-1]);
for(j=LASTCMDSIZE-2;j>=0;j--)
current->lastcmds[j+1] = current->lastcmds[j];
if ((pt = STRCHR(from,'@')) == NULL)
pt = from;
set_mallocdoer(on_msg);
current->lastcmds[0] = (char*)Calloc(strlen(pt) + 45);
if (CurrentUser)
{
sprintf(current->lastcmds[0],"[%s] %s\r%s[%-3i]\t(*%s)",
time2medium(now),command,CurrentUser->name,
(CurrentUser->x.x.access),pt);
}
else
{
sprintf(current->lastcmds[0],"[%s] %s\r%s[---]\t(*%s)",
time2medium(now),command,CurrentNick,pt);
}
}
/*
* CARGS check: at least one argument is required
*/
if (mcmd[i].args && !*rest)
{
if (uaccess) usage_command(from,command);
return;
}
#ifdef REDIRECT
/*
* can this command be redirected?
*/
if (!redirect.to && mcmd[i].redir)
{
if (mcmd[i].lbuf && ischannel(orig_to))
{
set_mallocdoer(on_msg);
redirect.to = stringdup(to);
redirect.method = R_PRIVMSG;
}
else
if (begin_redirect(from,rest) < 0)
return;
}
#endif /* REDIRECT */
if (mcmd[i].dcc && partyline_only_command(from))
return;
mcmd[i].func(from,to,rest,acmd[i]);
#ifdef DEBUG
CurrentCmd = NULL;
#endif /* DEBUG */
#ifdef REDIRECT
end_redirect();
#endif /* REDIRECT */
/*
* be quick to exit afterwards, there are "dangerous" commands like DIE and DEL (user)
*/
return;
}
CurrentCmd = &mcmd[i];
#ifdef SUPPRESS
#ifdef BOTNET
/* experimental command supression */
if (CurrentCmd->name == current->supres_cmd)
{
int crc;
crc = makecrc(rest);
if (current->supres_crc == crc)
{
/* another bot has already executed this command and is trying to supress its execution on other bots */
current->supres_cmd = NULL;
current->supres_crc = 0;
#ifdef DEBUG
debug("(on_msg) command \"%s\" from %s was supressed\n",CurrentCmd->name,CurrentNick);
#endif
return;
}
}
/*if command should be supressed ... */
if (mcmd[i].supres && CurrentChan)
{
send_suppress(CurrentCmd->name,rest);
}
#endif
#endif /* SUPPRESS */
/*
* convert the command to uppercase
*/
stringcpy(command,mcmd[i].name);
/*
* send statmsg with info on the command executed
*/
if (current->setting[TOG_SPY].int_var)
{
send_spy(SPYSTR_STATUS,":%s[%i]: Executing %s[%i]",
CurrentNick,uaccess,command,(int)acmd[i]);
}
/*
* CAXS check: first argument might be a channel
* check user access on target channel
*/
if (mcmd[i].caxs)
{
/* get channel name; 1: msg, 2: to, 3: active channel */
to = (char*)get_channel(to,&rest);
if (!ischannel(to))
return;
uaccess = get_authaccess(from,to);
if (uaccess < acmd[i])
return;
CurrentChan = find_channel_ny(to);
if (mcmd[i].acchan && (CurrentChan == NULL || CurrentChan->active == 0))
{
to_user(from,ERR_CHAN,to);
return;
}
}
else
/*
* GAXS check: user needs global access
*/
if (mcmd[i].gaxs)
{
uaccess = get_authaccess(from,MATCH_ALL);
if (uaccess < acmd[i])
return;
}
/*
* list of last LASTCMDSIZE commands
*/
if (from != cx.CoreUser.name)
{
Free(&current->lastcmds[LASTCMDSIZE-1]);
for(j=LASTCMDSIZE-2;j>=0;j--)
current->lastcmds[j+1] = current->lastcmds[j];
if ((pt = stringchr(from,'@')) == NULL)
pt = from;
set_mallocdoer(on_msg);
current->lastcmds[0] = (char*)Calloc(strlen(pt) + 45);
if (CurrentUser)
{
sprintf(current->lastcmds[0],"[%s] %s\r%s[%-3i]\t(*%s)",
maketimestr(cx.now,TFMT_CLOCK),command,CurrentUser->name,
(CurrentUser->x.x.access),pt);
}
else
{
sprintf(current->lastcmds[0],"[%s] %s\r%s[---]\t(*%s)",
maketimestr(cx.now,TFMT_CLOCK),command,CurrentNick,pt);
}
}
/*
* CARGS check: at least one argument is required
*/
if (mcmd[i].args && !*rest)
{
if (uaccess) usage_command(from,command);
return;
}
#ifdef REDIRECT
/*
* can this command be redirected?
*/
if (!redirect.to && mcmd[i].redir)
{
if (mcmd[i].lbuf && ischannel(orig_to))
{
set_mallocdoer(on_msg);
redirect.to = stringdup(to);
redirect.method = R_PRIVMSG;
}
else
if (begin_redirect(from,rest) < 0)
return;
}
#endif /* REDIRECT */
if (mcmd[i].dcc && partyline_only_command(from))
return;
/*
* Run command function
*/
if (mcmd[i].noargfunc && *rest == 0)
mcmd[i].noargfunc(from);
else
mcmd[i].func(from,to,rest,acmd[i]);
#ifdef REDIRECT
end_redirect();
#endif /* REDIRECT */
/*
* be quick to exit afterwards, there are "dangerous" commands like DIE and USER -...
*/
return;
/*
* If the input isnt a command or the sender lacks access
*/
public_msg:
/*
* un-chop() the message string
*/
@ -699,6 +714,7 @@ recheck_alias:
if (CurrentChan)
{
public_msg_unchopped:
common_public(CurrentChan,from,"<%s> %s",origstart);
}
else
@ -711,7 +727,7 @@ recheck_alias:
{
partyline_broadcast(CurrentDCC,"<%s> %s\n",origstart);
#ifdef BOTNET
botnet_relay(NULL,"PM* * %s@%s %s\n",CurrentNick,current->nick,origstart);
botnet_relay(NULL,"PM* * %s@%s %s\n",CurrentNick,getbotnick(current),origstart);
#endif /* BOTNET */
}
else
@ -729,8 +745,11 @@ void on_mode(char *from, char *channel, char *rest)
char templimit[20];
char *nick;
char *parm,*nickuh,*mode;
int i,sign,enfm,maxprot;
int i,sign,rev,enfm,flag,maxprot,isself;
#ifdef DEBUG
debug("(on_mode) %s --> %s: %s\n",from,channel,rest);
#endif /* DEBUG */
if ((chan = find_channel_ac(channel)) == NULL)
return;
channel = chan->name;
@ -749,16 +768,6 @@ void on_mode(char *from, char *channel, char *rest)
doer = find_chanuser(chan,from);
modeloop:
if (*mode == 'o' || *mode == 'v')
{
nick = chop(&rest);
if ((victim = find_chanuser(chan,nick)) == NULL)
{
mode++;
goto modeloop;
}
}
switch(*mode)
{
case '+':
@ -767,25 +776,50 @@ modeloop:
break;
/*
*
* MODE <channel> +/-v <nick>
* MODE <channel> +/-o <nick>
*
*/
case 'v':
case 'o':
nick = chop(&rest);
victim = find_chanuser(chan,nick);
if (victim == NULL) /* Cant take action against an unknown entity */
{
mode++;
goto modeloop;
}
rev = 0;
i = (victim->user) ? victim->user->x.x.access : 0;
/*
* Can only be 'o' or 'v'
* Sign can only be '+' or '-'
* #define CU_VOICE 0x0001
* #define CU_CHANOP 0x0002
*/
flag = CU_VOICE + (*mode == 'o');
victim->flags &= ~flag;
victim->flags |= (flag & (-(sign == '+')));
if (*mode == 'v')
break;
victim->flags &= ~CU_DEOPPED;
isself = (0 == nickcmp(getbotnick(current),nick)) ? TRUE : FALSE;
/* +o */ if (sign == '+')
{
victim->flags |= CU_CHANOP;
victim->flags &= ~CU_DEOPPED;
if (!i)
if (0 == i)
{
if (victim->shit || (chan->setting[TOG_SD].int_var && !doer) ||
chan->setting[TOG_SO].int_var)
if (victim->shit || (chan->setting[TOG_SO].int_var) || (chan->setting[TOG_SD].int_var && !doer))
{
send_mode(chan,60,QM_CHANUSER,'-','o',victim);
rev = '-';
}
}
else
if (!nickcmp(current->nick,nick))
if (isself)
{
/*
* wooohoooo! they gave me ops!!!
@ -799,35 +833,30 @@ modeloop:
}
check_shit();
update_modes(chan);
if (current->spy & SPYF_STATUS && doer)
send_spy(SPYSTR_STATUS,"Given op on %s, set by %s",chan->name,doer->nick);
}
#ifdef DEBUG
debug("(on_mode) %s!%s --> %i\n",victim->nick,victim->userhost,i);
#endif /* DEBUG */
}
/* -o */ else
{
victim->flags &= ~(CU_CHANOP|CU_DEOPPED);
if (i == BOTLEVEL)
if (isself)
{
if (!nickcmp(current->nick,nick))
{
/*
* they dont love me!!! :~(
*/
chan->bot_is_op = FALSE;
}
/*
* they dont love me!!! :~(
*/
chan->bot_is_op = FALSE;
if (current->spy & SPYF_STATUS)
send_spy(SPYSTR_STATUS,"Lost op on %s, removed by %s",chan->name,nick);
}
/*
* idiots deopping themselves
*/
if (!nickcmp(from,nick))
#ifdef DEBUG
debug("(on_mode) doer == victim: %s\n",(doer == victim) ? "TRUE" : "FALSE");
#endif /* DEBUG */
if (doer == victim)
break;
/*
* 1. Use enfm var to temporarily store users access
* 2. get_userlevel also checks is_localbot()...
*/
enfm = (doer && doer->user) ? doer->user->x.x.access : 0;
if (enfm == BOTLEVEL)
if (doer && doer->user && doer->user->x.x.access >= OWNERLEVEL)
break;
if (check_mass(chan,doer,INT_MDL))
mass_action(chan,doer);
@ -839,29 +868,14 @@ modeloop:
nickuh = get_nuh(victim);
if (get_authaccess(nickuh,channel))
{
send_mode(chan,60,QM_CHANUSER,'+','o',victim);
rev = '+';
prot_action(chan,from,doer,NULL,victim);
}
}
}
if (rev)
send_mode(chan,60,QM_CHANUSER,rev,'o',victim);
break;
/*
*
* MODE <channel> +/-v <nick>
*
*/
case 'v':
if (sign == '+')
victim->flags |= CU_VOICE;
else
victim->flags &= ~CU_VOICE;
break;
#ifdef IRCD_EXTENSIONS
/*
:joonicks!*@* MODE #emech +I *king*!*@*
:joonicks!*@* MODE #emech +e *kong*!*@*
*/
#endif /* IRCD_EXTENSIONS */
/*
*
* MODE <channel> +/-b <parm>
@ -870,6 +884,8 @@ modeloop:
#ifdef IRCD_EXTENSIONS
/*
* ircnet braindamage modes
* :joonicks!*@* MODE #emech +I *king*!*@*
* :joonicks!*@* MODE #emech +e *kong*!*@*
*/
case 'I':
case 'e':
@ -881,7 +897,7 @@ modeloop:
#ifdef IRCD_EXTENSIONS
Ban *newban;
newban = make_ban(&chan->banlist,from,parm,now);
newban = make_ban(&chan->banlist,from,parm,cx.now);
if (*mode == 'I') newban->imode = TRUE;
if (*mode == 'e') newban->emode = TRUE;
/*
@ -889,7 +905,7 @@ modeloop:
*/
break;
#else /* IRCD_EXTENSIONS */
make_ban(&chan->banlist,from,parm,now);
make_ban(&chan->banlist,from,parm,cx.now);
#endif /* IRCD_EXTENSIONS */
/*
* skip protection checks if the doer is myself or another known bot
@ -1090,7 +1106,7 @@ void on_action(char *from, char *to, char *rest)
{
partyline_broadcast(CurrentDCC,"* %s %s\n",rest);
#ifdef BOTNET
botnet_relay(NULL,"PM* * %s@%s \001%s\n",CurrentNick,current->nick,rest);
botnet_relay(NULL,"PM* * %s@%s \001%s\n",CurrentNick,getbotnick(current),rest);
#endif /* BOTNET */
return;
}

View File

@ -1,7 +1,7 @@
/*
EnergyMech, IRC bot software
Parts Copyright (c) 1997-2021 proton
Parts Copyright (c) 1997-2025 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
@ -67,7 +67,7 @@ void parse_invite(char *from, char *rest)
if ((i >= JOINLEVEL) && (i < BOTLEVEL))
{
join_channel(chan,NULL);
current->lastrejoin = now;
current->lastrejoin = cx.now;
}
}
@ -84,7 +84,7 @@ void parse_join(char *from, char *rest)
if ((CurrentChan = chan = find_channel_ny(rest)) == NULL)
return;
if (!nickcmp(current->nick,from))
if (!nickcmp(getbotnick(current),from))
{
#ifdef DEBUG
debug("(parse_join) Im joining %s\n",chan->name);
@ -122,7 +122,7 @@ void parse_join(char *from, char *rest)
stats = chan->stats;
stats->userseconds = 0;
stats->users = 0;
stats->lastuser = now;
stats->lastuser = cx.now;
stats->flags |= CSTAT_PARTIAL;
}
#endif /* STATS */
@ -151,7 +151,7 @@ void parse_join(char *from, char *rest)
*/
if (is_bot(from))
{
CurrentUser = (User*)&LocalBot;
CurrentUser = (User*)&cx.LocalBot;
CurrentShit = NULL;
}
else
@ -202,7 +202,7 @@ void parse_mode(char *from, char *rest)
on_mode(from,to,rest);
}
else
if (!stringcasecmp(current->nick,to))
if (!stringcasecmp(getbotnick(current),to)) /* todo: nickcmp? */
{
char *dst;
char sign;
@ -259,7 +259,7 @@ void parse_notice(char *from, char *rest)
if (!stringcasecmp(ctcp,"PING") && ((pingtime = get_number(rest)) != -1))
{
send_spy(SPYSTR_STATUS,"[CTCP PING Reply From %s] %i second(s)",
CurrentNick,(int)(now - pingtime));
CurrentNick,(int)(cx.now - pingtime));
}
else
{
@ -311,7 +311,7 @@ void parse_part(char *from, char *rest)
if (current->spy & SPYF_CHANNEL)
send_spy(channel,"*** Parts: %s (%s)",nick,from);
if (!nickcmp(current->nick,nick))
if (!nickcmp(getbotnick(current),nick))
{
#ifdef DEBUG
debug("(parse_part) Im parting %s\n",chan->name);
@ -333,7 +333,7 @@ void parse_part(char *from, char *rest)
#endif /* STATS */
#ifdef SEEN
make_seen(nick,from,channel,NULL,now,SEEN_PARTED);
make_seen(nick,from,channel,NULL,cx.now,SEEN_PARTED);
#endif /* SEEN */
remove_chanuser(chan,nick);
@ -367,7 +367,7 @@ void parse_pong(char *from, char *rest)
ot = (ot * 10) + (*src++ - '0');
current->ontime = ot;
#ifdef DEBUG
debug("(parse_pong) recovering ontime = %lu (%s)\n",ot,idle2str(now - ot,TRUE));
debug("(parse_pong) recovering ontime = %lu (%s)\n",ot,idle2str(ot,TRUE));
#endif
}
}
@ -377,7 +377,7 @@ void parse_privmsg(char *from, char *rest)
ChanUser *cu;
char *to,*channel;
#ifdef URLCAPTURE
const char *src;
unsigned char *src;
#endif /* URLCAPTURE */
to = chop(&rest);
@ -391,7 +391,7 @@ void parse_privmsg(char *from, char *rest)
{
if ((cu = find_chanuser(CurrentChan,from)))
{
cu->idletime = now;
cu->idletime = cx.now;
if (cu->shit)
return;
CurrentUser = cu->user;
@ -430,7 +430,7 @@ void parse_privmsg(char *from, char *rest)
CurrentChan->stats->privmsg++;
#endif /* STATS */
#ifdef URLCAPTURE
src = rest;
src = (unsigned char *)rest;
while(*src)
{
if (tolowertab[*src] == 'h')
@ -440,7 +440,7 @@ void parse_privmsg(char *from, char *rest)
if ((src[4] == ':') || /* "http:" */
(tolowertab[src[4]] == 's' && src[5] == ':')) /* "https:" */
{
urlcapture(src);
urlcapture((const char *)src);
}
}
}
@ -457,7 +457,7 @@ void parse_quit(char *from, char *rest)
nickcpy(CurrentNick,from);
#ifdef SEEN
make_seen(CurrentNick,from,rest,NULL,now,SEEN_QUIT);
make_seen(CurrentNick,from,rest,NULL,cx.now,SEEN_QUIT);
#endif /* SEEN */
#ifdef FASTNICK
@ -505,6 +505,9 @@ void parse_topic(char *from, char *rest)
reverse_topic(chan,from,rest);
}
/*
(in) {5} :She!haveident@libera/staff/she/her WALLOPS :Services stuff done. PSA for channel founders: Single-# channels that do NOT belong
*/
void parse_wallops(char *from, char *rest)
{
nickcpy(CurrentNick,from);
@ -547,12 +550,15 @@ void parse_251(char *from, char *rest)
{
nick = chop(&rest);
setbotnick(current,nick);
#ifdef BOTNET
botnet_refreshbotinfo();
#endif /* BOTNET */
for(sp=serverlist;sp;sp=sp->next)
{
if (!stringcasecmp(sp->name,from) || !stringcasecmp(sp->realname,from))
{
sp->lastconnect = now;
current->ontime = now;
sp->lastconnect = cx.now;
current->ontime = cx.now;
current->server = sp->ident;
}
}
@ -702,11 +708,9 @@ void parse_311(char *from, char *rest)
if (host)
host[-1] = '@';
if (!nickcmp(nick,current->nick))
if (!nickcmp(getbotnick(current),nick))
{
Free((char**)&current->userhost);
set_mallocdoer(parse_311);
current->userhost = stringdup(user);
setbotuserhost(current,user);
#ifdef BOTNET
botnet_refreshbotinfo();
#endif /* BOTNET */
@ -812,7 +816,7 @@ void parse_317(char *from, char *rest)
}
if (when != -1)
send_pa(PA_WHOIS,nick,"Signed On: %s",time2away(when));
send_pa(PA_WHOIS,nick,"Signed On: %s",maketimestr(when,TFMT_AWAY));
send_pa(PA_WHOIS,nick,
(sec) ? "Idle: %i minute%s, %i second%s" : "Idle: %i minute%s",
@ -855,7 +859,7 @@ void parse_319(char *from, char *rest)
send_pa(PA_WHOIS,nick,"Channels: %s",rest);
/* if nick is myself (the bot), check for reset recovery */
if (!nickcmp(nick,current->nick))
if (!nickcmp(getbotnick(current),nick))
{
if (current->reset)
{
@ -871,7 +875,7 @@ loop:
*/
while(*channel && *channel != '#') /* this is a recipe for disaster with other valid channels than '#' */
channel++;
sprintf(nuh,"%s!%s",current->nick,current->userhost);
sprintf(nuh,"%s!%s",getbotnick(current),getbotuserhost(current));
#ifdef DEBUG
debug("(parse_319) :%s JOIN :%s\n",nuh,channel);
#endif /* DEBUG */
@ -961,6 +965,10 @@ void parse_352(char *from, char *rest)
if (chan->wholist == TRUE)
return;
#ifdef STATS
if (chan->stats)
chan->stats->users++;
#endif /* STATS */
userhost = chop(&rest);
rest[-1] = '@'; /* glue: "user\0host" --> "user@host" */
@ -977,7 +985,7 @@ void parse_352(char *from, char *rest)
#ifdef DEBUG
debug("(parse_352) setting as local bot: %s (%s)\n",nuh,channel);
#endif /* DEBUG */
chan->users->user = (User*)&LocalBot;
chan->users->user = (User*)&cx.LocalBot;
chan->users->shit = NULL;
}
else
@ -996,7 +1004,7 @@ void parse_352(char *from, char *rest)
if (*rest == '@')
{
chan->users->flags = CU_CHANOP;
if (!nickcmp(current->nick,nick))
if (!nickcmp(getbotnick(current),nick))
{
#ifdef DEBUG
debug("(parse_352) According to wholist I have ops\n");
@ -1040,7 +1048,7 @@ void parse_367(char *from, char *rest)
banfrom = "?";
if ((bantime = get_number(rest)) == -1)
bantime = now;
bantime = cx.now;
make_ban(&chan->banlist,banfrom,banmask,bantime);
}
@ -1060,19 +1068,16 @@ void parse_376(char *from, char *rest)
{
if (*sp->realname == 0)
stringcpy_n(sp->realname,from,NAMELEN);
sp->lastconnect = now;
sp->lastconnect = cx.now;
}
if (current->connect != CN_ONLINE)
{
current->connect = CN_ONLINE;
current->ontime = now;
to_server("WHOIS %s\n",current->nick);
current->ontime = cx.now;
to_server("WHOIS %s\n",getbotnick(current));
if ((mode = current->setting[STR_UMODES].str_var))
to_server("MODE %s %s\n",current->nick,mode);
to_server("MODE %s %s\n",getbotnick(current),mode);
}
#ifdef IDWRAP
unlink_identfile();
#endif /* IDWRAP */
}
/*
@ -1113,7 +1118,7 @@ void parse_433(char *from, char *rest)
do
{
s2 = chop(&s);
if (current->connect == CN_ONLINE && !stringcasecmp(current->nick,s2))
if (current->connect == CN_ONLINE && !stringcasecmp(getbotnick(current),s2)) /* todo: nickcmp? */
{
/* nicks listed first are more worth, dont try nicks after */
break;
@ -1134,14 +1139,12 @@ void parse_433(char *from, char *rest)
if (nick)
{
#ifdef DEBUG
debug("(parse_433) Nick: %s, Altnick: %s\n",current->nick,nick);
debug("(parse_433) Nick: %s, Altnick: %s\n",getbotnick(current),nick);
#endif /* DEBUG */
to_server("NICK %s\n",nick);
if (current->connect != CN_ONLINE)
{
Free((char**)&current->nick);
set_mallocdoer(parse_433);
current->nick = stringdup(nick);
setbotnick(current,nick);
}
return;
}
@ -1225,7 +1228,7 @@ void parse_346(char *from, char *rest)
banfrom = "?";
if ((bantime = get_number(rest)) == -1)
bantime = now;
bantime = cx.now;
new = make_ban(&chan->banlist,banfrom,banmask,bantime);
new->imode = TRUE;
@ -1255,7 +1258,7 @@ void parse_348(char *from, char *rest)
banfrom = "?";
if ((bantime = get_number(rest)) == -1)
bantime = now;
bantime = cx.now;
new = make_ban(&chan->banlist,banfrom,banmask,bantime);
new->emode = TRUE;
@ -1373,21 +1376,24 @@ void parse_005(char *from, char *rest)
#define NEEDFROM 1
#define DROPONE 2
LS const struct
struct ParseFunctions
{
uint32_t hash;
short flags;
void (*func)(char *, char *);
const uint32_t hash;
const short flags;
void (*func)(char *, char *);
int hits;
} pFuncs[] =
{
{ 0x50494E47, 0, parse_ping }, /* PING */
{ 0x50524956, NEEDFROM, parse_privmsg }, /* PRIVMSG */
{ 0x00333532, NEEDFROM|DROPONE, parse_352 }, /* 352 RPL_WHOREPLY */
{ 0x00333637, NEEDFROM|DROPONE, parse_367 }, /* 367 RPL_BANLIST */
{ 0x4A4F494E, NEEDFROM, parse_join }, /* JOIN */
{ 0x50415254, NEEDFROM, parse_part }, /* PART */
{ 0x4D4F4445, NEEDFROM, parse_mode }, /* MODE */
{ 0x4E49434B, NEEDFROM, on_nick }, /* NICK */
{ 0x4B49434B, NEEDFROM, on_kick }, /* KICK */
{ 0x50494E47, 0, parse_ping }, /* PING */
{ 0x504F4E47, DROPONE, parse_pong }, /* PONG */
{ 0x544F5049, NEEDFROM, parse_topic }, /* TOPIC */
{ 0x4E4F5449, NEEDFROM, parse_notice }, /* NOTICE */
@ -1395,7 +1401,6 @@ LS const struct
{ 0x494E5649, NEEDFROM|DROPONE, parse_invite }, /* INVITE */
{ 0x57414C4C, NEEDFROM, parse_wallops }, /* WALLOPS */
{ 0x4552524F, 0, parse_error }, /* ERROR */
{ 0x00333532, NEEDFROM|DROPONE, parse_352 }, /* 352 RPL_WHOREPLY */
{ 0x00333135, NEEDFROM|DROPONE, parse_315 }, /* 315 RPL_ENDOFWHO */
{ 0x00323231, NEEDFROM, parse_mode }, /* 221 RPL_UMODEIS */
{ 0x00333131, NEEDFROM|DROPONE, parse_311 }, /* 311 RPL_WHOISUSER */
@ -1429,7 +1434,6 @@ LS const struct
{ 0x00333137, NEEDFROM|DROPONE, parse_317 }, /* 317 RPL_WHOISIDLE */
{ 0x00333139, NEEDFROM|DROPONE, parse_319 }, /* 319 RPL_WHOISCHANNELS */
{ 0x00333234, NEEDFROM|DROPONE, parse_324 }, /* 324 RPL_CHANNELMODEIS */
{ 0x00333637, NEEDFROM|DROPONE, parse_367 }, /* 367 RPL_BANLIST */
{ 0x00343531, 0, parse_451 }, /* 451 ERR_NOTREGISTERED */
{ 0x00343035, NEEDFROM|DROPONE, parse_471 }, /* 405 ERR_TOOMANYCHANNELS */
{ 0x00343731, NEEDFROM|DROPONE, parse_471 }, /* 471 ERR_CHANNELISFULL */
@ -1448,7 +1452,7 @@ LS const struct
{ 0, 0, NULL }
};
uint32_t stringhash(char *s)
static __INLINE__ uint32_t stringhash(char *s)
{
uint32_t hash;
int i;
@ -1463,16 +1467,28 @@ void parse_server_input(char *rest)
{
#ifdef SCRIPTING
Hook *hook;
int skip;
#endif /* SCRIPTING */
char *from,*command;
uint32_t cmdhash;
int i;
#ifdef DEBUG
if (rest == NULL)
{
for(i=0;pFuncs[i].hash;i++)
{
debug("[PsI] (%i) hash %X: hits %i\n",i,pFuncs[i].hash,pFuncs[i].hits);
}
return;
}
#endif /* DEBUG */
if (current->spy & (SPYF_RAWIRC|SPYF_RANDSRC))
send_spy(SPYSTR_RAWIRC,rest);
/*new undernet amusements */
/*(in) {5} NOTICE AUTH :*** You have identd disabled (or broken), to continue to connect you must type /QUOTE PASS 17071 */
/* New undernet amusements */
/* NOTICE AUTH :*** You have identd disabled (or broken), to continue to connect you must type /QUOTE PASS 17071 */
if (current->connect == CN_CONNECTED && *rest == 'N' && !matches("NOTICE AUTH * /QUOTE PASS *",rest))
{
from = STREND(rest);
@ -1502,7 +1518,7 @@ void parse_server_input(char *rest)
rest++;
#ifdef SCRIPTING
cmdhash = 1;
skip = 0;
for(hook=hooklist;hook;hook=hook->next)
{
/*
@ -1515,18 +1531,16 @@ void parse_server_input(char *rest)
*/
if (hook->flags == MEV_PARSE && !stringcasecmp(command,hook->type.command))
{
if (hook->func(from,rest,hook))
/* if the hook returns non-zero, the input should not be parsed internally */
cmdhash = 0;
/* if the hook returns non-zero, the input should not be parsed internally */
skip += hook->func(from,rest,hook);
}
}
if (cmdhash == 0)
if (skip)
return;
#endif /* SCRIPTING */
cmdhash = stringhash(command);
/*debug("cmdhash = %08X\n",cmdhash); */
for(i=0;pFuncs[i].hash;i++)
{
if (cmdhash == pFuncs[i].hash)
@ -1535,9 +1549,9 @@ void parse_server_input(char *rest)
return;
if (pFuncs[i].flags & DROPONE)
chop(&rest); /* discard one argument (usually bot nick) */
pFuncs[i].hits++;
pFuncs[i].func(from,rest);
return;
}
}
/*debug("unmatched cmdhash %08X\n",cmdhash); */
}

View File

@ -55,7 +55,7 @@ check_telnet_malloc:
client->fileno = -1;
#endif /* DCC_FILE */
client->flags = DCC_TELNETPASS;
client->lasttime = now;
client->lasttime = cx.now;
client->next = current->clientlist;
current->clientlist = client;
#ifdef DEBUG
@ -119,12 +119,12 @@ void partyline_banner(Client *client)
char tmp[MSGLEN];
client->flags = DCC_ACTIVE;
client->lasttime = now;
client->lasttime = cx.now;
sprintf(tmp,"[%s] %s[%i] has connected",
current->nick,client->user->name,(int)client->user->x.x.access);
getbotnick(current),client->user->name,(int)client->user->x.x.access);
if ((to_file(client->sock,"[%s] %s\n",time2medium(now),tmp)) < 0)
if ((to_file(client->sock,"[%s] %s\n",maketimestr(cx.now,TFMT_CLOCK),tmp)) < 0)
{
client->flags = DCC_DELETE;
return;
@ -134,7 +134,7 @@ void partyline_banner(Client *client)
{
CurrentDCC = client;
stringcpy(tmp,SPYSTR_STATUS);
do_spy(client->user->name,current->nick,tmp,0);
do_spy(client->user->name,getbotnick(current),tmp,0);
CurrentDCC = NULL;
}
}
@ -142,9 +142,10 @@ void partyline_banner(Client *client)
void dcc_chat(char *from)
{
struct sockaddr_in sai;
unsigned int sz;
Client *client;
User *user;
int sock,sz;
int sock;
if ((user = get_authuser(from,NULL)) == NULL)
return;
@ -169,7 +170,7 @@ void dcc_chat(char *from)
client->user = user;
client->sock = sock;
client->flags = DCC_WAIT;
client->lasttime = now;
client->lasttime = cx.now;
client->next = current->clientlist;
current->clientlist = client;
@ -240,11 +241,11 @@ void do_whom(COMMAND_ARGS)
{
stringcpy(stt,TEXT_NOTCONNECTED);
}
table_buffer(TEXT_WHOMSELFLINE,bot->nick,(bot == current) ? "(me)" : "b200",stt);
table_buffer(TEXT_WHOMSELFLINE,getbotnick(bot),(bot == current) ? "(me)" : "b200",stt);
for(client=bot->clientlist;client;client=client->next)
{
m = (now - client->lasttime) / 60;
s = (now - client->lasttime) % 60;
m = (cx.now - client->lasttime) / 60;
s = (cx.now - client->lasttime) % 60;
table_buffer(TEXT_WHOMUSERLINE,
#ifdef TELNET
client->user->name,client->user->x.x.access,(client->flags & DCC_TELNET) ? "telnet" : "DCC",m,s);

View File

@ -28,6 +28,60 @@
#include "text.h"
#include "mcmd.h"
/*
* deal with undesired lusers
*/
void screwban_format(char *userhost)
{
int sz,n,pos;
#ifdef DEBUG
debug("(screwban_format) %s\n",userhost);
#endif /* DEBUG */
if ((sz = strlen(userhost)) < 8)
return;
n = RANDOM(4,sz);
while(--n)
{
pos = RANDOM(0,(sz - 1));
if (!stringchr("?!@*",userhost[pos]))
{
userhost[pos] = (RANDOM(0,3) == 0) ? '*' : '?';
}
}
}
void deop_ban(Chan *chan, ChanUser *victim, char *mask)
{
if (!mask)
mask = format_uh(get_nuh(victim),FUH_USERHOST);
send_mode(chan,85,QM_CHANUSER,'-','o',victim);
send_mode(chan,90,QM_RAWMODE,'+','b',mask);
}
void deop_siteban(Chan *chan, ChanUser *victim)
{
char *mask;
mask = format_uh(get_nuh(victim),FUH_HOST);
deop_ban(chan,victim,mask);
}
void deop_screwban(Chan *chan, ChanUser *victim)
{
char *mask;
int i;
for(i=2;--i;)
{
mask = format_uh(get_nuh(victim),FUH_USERHOST);
screwban_format(mask);
deop_ban(chan,victim,mask);
}
}
/*
*
* kicking and screaming
@ -63,7 +117,7 @@ void push_kicks(Chan *chan)
qKick *kick;
int n;
n = (current->sendq_time - now);
n = (current->sendq_time - cx.now);
while(n < 6)
{
if ((kick = chan->kicklist) == NULL)
@ -189,7 +243,7 @@ void push_modes(Chan *chan, int lowpri)
char *dstflag,*dstparm,lastmode;
int n,maxmodes;
n = (current->sendq_time - now);
n = (current->sendq_time - cx.now);
loop:
maxmodes = current->setting[INT_MODES].int_var;
@ -278,7 +332,6 @@ void update_modes(Chan *chan)
*/
int check_mass(Chan *chan, ChanUser *doer, int type)
{
time_t when;
int num,limit;
/*
@ -325,9 +378,9 @@ int check_mass(Chan *chan, ChanUser *doer, int type)
break;
}
if ((now - doer->action_time[num]) > 10)
if ((cx.now - doer->action_time[num]) > 10)
{
doer->action_time[num] = now;
doer->action_time[num] = cx.now;
doer->action_num[num] = 0;
}
++(doer->action_num[num]);
@ -388,6 +441,9 @@ void prot_action(Chan *chan, char *from, ChanUser *doer, char *target, ChanUser
uprot = get_protaction(chan,target);
}
/* dont enforce protection levels higher than channel is set to */
if (maxprot < uprot) uprot = maxprot;
if ((uprot >= 4) && (!(doer->flags & CU_BANNED)))
{
doer->flags |= CU_BANNED|CU_DEOPPED;
@ -442,12 +498,12 @@ void check_dynamode(Chan *chan)
}
}
v[0] = (v[0] < 20) ? 20 : (v[0] > 600) ? 600 : v[0];
if ((now - chan->lastlimit) < v[0])
if ((cx.now - chan->lastlimit) < v[0])
return;
v[1] = (v[1] < 5) ? 5 : (v[1] > 50) ? 50 : v[1];
v[2] = (v[2] < 1) ? 1 : (v[2] > 50) ? 50 : v[2];
chan->lastlimit = now;
chan->lastlimit = cx.now;
n = 0;
for(cu=chan->users;cu;cu=cu->next)
@ -494,18 +550,18 @@ void process_chanbans(void)
for (current=botlist;current;current=current->next)
{
if (current->lastchanban > (now - 10))
if (current->lastchanban > (cx.now - 10))
{
#ifdef DEBUG
debug("(process_chanbans) skipping %s (%i), (lastchanban (%lu) > now - 10 (%lu)\n",
current->nick,current->guid,current->lastchanban,(now - 10));
getbotnick(current),current->guid,current->lastchanban,(cx.now - 10));
#endif /* DEBUG */
continue;
}
if (current->sendq) /* only do chanbans on empty queue */
{
#ifdef DEBUG
debug("(process_chanbans) skipping %s (%i), sendq not empty\n",current->nick,current->guid);
debug("(process_chanbans) skipping %s (%i), sendq not empty\n",getbotnick(current),current->guid);
#endif /* DEBUG */
continue;
}
@ -530,11 +586,11 @@ void process_chanbans(void)
}
}
if (selcu && selcu->lastwhois < (now-30))
if (selcu && selcu->lastwhois < (cx.now-30))
{
selcu->flags &= ~CU_CHANBAN;
selcu->lastwhois = now;
current->lastchanban = now;
selcu->lastwhois = cx.now;
current->lastchanban = cx.now;
pp = &current->sendq;
while(*pp)
@ -659,7 +715,7 @@ void check_kicksay(Chan *chan, ChanUser *doer, char *text)
mask = format_uh(get_nuh(doer),FUH_USERHOST);
if (action > 2)
{
add_shit("Auto KS",chan->name,mask,save->reason,2,now+3600);
add_shit("Auto KS",chan->name,mask,save->reason,2,cx.now+3600);
}
if (!(doer->flags & CU_BANNED))
{
@ -819,7 +875,7 @@ void do_unban(COMMAND_ARGS)
if (((chan = find_channel_ac(to)) == NULL) || !chan->bot_is_op)
return;
if (nick && STRCHR(nick,'*'))
if (nick && stringchr(nick,'*'))
{
channel_massunban(chan,nick,0);
return;

View File

@ -88,11 +88,11 @@ static PyObject *python_getvar(PyObject *self, PyObject *args)
case PYVAR_currentnick:
return Py_BuildValue("s", CurrentNick);
case PYVAR_botnick:
return Py_BuildValue("s", current && current->nick ? current->nick : "");
return Py_BuildValue("s", current && getbotnick(current));
case PYVAR_wantnick:
return Py_BuildValue("s", current && current->wantnick ? current->wantnick : "");
return Py_BuildValue("s", current && getbotwantnick(current));
case PYVAR_userhost:
return Py_BuildValue("s", current && current->userhost ? current->userhost : "");
return Py_BuildValue("s", current && getbotuserhost(current));
case PYVAR_server:
return Py_BuildValue("i", current && current->server ? current->server : -1);
case PYVAR_nextserver:

View File

@ -1,7 +1,7 @@
/*
EnergyMech, IRC bot software
Copyright (c) 1997-2018 proton
Copyright (c) 1997-2025 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
@ -27,11 +27,13 @@
#include "h.h"
#ifdef TELNET
LS int client_type = DCC_ACTIVE;
int client_type = DCC_ACTIVE;
#endif /* TELNET */
#define mkaxx(x) (0x40404040 + (0x0f0f & x) + ((0xf0f0 & x) << 12))
#define getaxx(x) (((x & 0x0f0f0000) >> 12) | (x & 0x00000f0f))
#define simpleencode(x) (0x41414141 + (0x0f0f & x) + ((0xf0f0 & x) << 12))
#define simpledecode(x) ((((x - 0x41410000) & 0x0f0f0000) >> 12) | ((x - 0x4141) & 0x0f0f))
char *recover_client(char *env)
{
@ -40,17 +42,18 @@ char *recover_client(char *env)
char asc[8];
} axx;
struct sockaddr_in sai;
unsigned int sz;
Client *client;
User *user;
char *p,*handle;
int guid = 0,fd = 0,sz;
int guid = 0,fd = 0;
if (env[8] != ':')
return(env);
memcpy(axx.asc,env,8); /* compiler is not stupid and will optimize the shit out of this */
guid = getaxx(axx.num[0]);
fd = getaxx(axx.num[1]);
guid = simpledecode(axx.num[0]);
fd = simpledecode(axx.num[1]);
handle = p = (env = env + 9);
while(*p)
@ -97,7 +100,7 @@ char *recover_client(char *env)
found_user:
if (to_file(fd,"[%s] [%s] %s[%i] has connected (reset recover)\n",
time2medium(now),current->wantnick,handle,user->x.x.access) < 0)
maketimestr(cx.now,TFMT_CLOCK),getbotwantnick(current),handle,user->x.x.access) < 0)
{
close(fd);
return(p);
@ -112,7 +115,7 @@ found_user:
#else
client->flags = DCC_ACTIVE;
#endif /* TELNET */
client->lasttime = now;
client->lasttime = cx.now;
client->next = current->clientlist;
current->clientlist = client;
@ -121,7 +124,7 @@ found_user:
{
CurrentDCC = client;
stringcpy(client->sockdata,"status");
do_spy(user->name,current->wantnick,client->sockdata,0);
do_spy(user->name,getbotwantnick(current),client->sockdata,0);
*client->sockdata = 0;
CurrentDCC = NULL;
}
@ -142,16 +145,16 @@ char *recover_debug(char *env)
char asc[4];
} axx;
struct stat s;
char *d;
debug_fd = 0;
d = stringchr(env,'&');
if (env[4] != ' ' && env[4] != 0)
return(env);
/*
* get the fd number
*/
memcpy(axx.asc,env,4); /* compiler is not stupid and will optimize the shit out of this */
debug_fd = getaxx(axx.num);
debug_fd = simpledecode(axx.num);
if (fstat(debug_fd,&s) < 0)
{
@ -164,17 +167,19 @@ char *recover_debug(char *env)
dodebug = TRUE;
debug("(recover_debug) {%i} debug fd recovered\n",debug_fd);
CoreClient.sock = debug_fd;
if (d && is_safepath(d+1,FILE_MAY_EXIST) == TRUE)
{
debugfile = d+1;
debug("(recover_debug) output file = %s\n",debugfile);
}
}
return(env+4);
d = chop(&env);
return(env);
}
#endif /* DEBUG */
/*
(do_reset) mkaxx(3) = C@@@
(do_reset) ircx mkaxx(12) = L@@@
(do_reset) sock mkaxx(2) = B@@@
(do_reset) guid mkaxx(1881) = IGE@
[StS] {2} PING :OT1523818405
(do_reset) MECHRESET=dC@@@ fXIGE@B@@@L@@@ tIGE@F@@@:joo [44]
execve( ./energymech, argv = { ./energymech <NULL> <NULL> <NULL> <NULL> }, envp = { MECHRESET=dC@@@ fXIGE@B@@@L@@@ tIGE@F@@@:joo } )
@ -187,8 +192,8 @@ char *recover_server(char *env)
char asc[16];
} axx;
struct sockaddr_in sai;
char *p;
int guid = 0,fd = 0,sz;
unsigned int sz;
int guid = 0,fd = 0;
#ifdef IRCD_EXTENSIONS
int ircx = 0;
#endif /* IRCD_EXTENSIONS */
@ -209,10 +214,10 @@ char *recover_server(char *env)
memcpy(axx.asc,env,sz); /* compiler is not stupid and will optimize the shit out of this */
env += sz;
guid = getaxx(axx.num[0]);
fd = getaxx(axx.num[1]);
guid = simpledecode(axx.num[0]);
fd = simpledecode(axx.num[1]);
#ifdef IRCD_EXTENSIONS
ircx = getaxx(axx.num[2]);
ircx = simpledecode(axx.num[2]);
#ifdef DEBUG
debug("(recover_server) guid = %i; fd = %i, ircx = %i\n",guid,fd,ircx);
#endif /* DEBUG */
@ -235,7 +240,7 @@ char *recover_server(char *env)
current->reset = 1;
current->sock = fd;
current->connect = CN_ONLINE;
current->ontime = now;
current->ontime = cx.now;
#ifdef IRCD_EXTENSIONS
current->ircx_flags = ircx;
#endif /* IRCD_EXTENSIONS */
@ -251,7 +256,7 @@ char *recover_server(char *env)
/* if the guid changed, we cant guess which old<-->new is the matching one so */
if (fd != -1)
{
to_file(fd,"QUIT :I'm no longer wanted *cry*\n");
to_file(fd,"QUIT :Am I a figment of my own imagination?\n");
killsock(fd);
}
return(env);
@ -314,9 +319,8 @@ void do_reset(COMMAND_ARGS)
} axx;
Client *client;
Mech *backup;
char env[MSGLEN];
char *p;
int n,sz;
char *p,env[MSGLEN];
int sz;
if (current->userlist && current->ul_save)
{
@ -350,10 +354,12 @@ void do_reset(COMMAND_ARGS)
*/
if (dodebug && (debug_fd >= 0))
{
axx.num[0] = mkaxx(debug_fd);
axx.num[0] = simpleencode(debug_fd);
axx.num[1] = 0;
sprintf(p,"d%s",axx.asc);
p = STREND(p);
if (debugfile)
p += sprintf(p,"d%s&%s",axx.asc,debugfile);
else
p += sprintf(p,"d%s",axx.asc);
}
#endif /* DEBUG */
/*
@ -365,17 +371,14 @@ void do_reset(COMMAND_ARGS)
if ((current->connect == CN_ONLINE) && ((MSGLEN - (p - env)) > 25))
{
unset_closeonexec(current->sock);
axx.num[0] = mkaxx(current->guid);
axx.num[1] = mkaxx(current->sock);
#ifdef IRCD_EXTENSIONS
axx.num[2] = mkaxx(current->ircx_flags);
axx.num[3] = 0;
sprintf(p," fX%s",axx.asc);
#else /* IRCD_EXTENSIONS */
axx.num[0] = simpleencode(current->guid);
axx.num[1] = simpleencode(current->sock);
axx.num[2] = 0;
sprintf(p," fx%s",axx.asc);
axx.num[3] = 0;
#ifdef IRCD_EXTENSIONS
axx.num[2] = simpleencode(current->ircx_flags);
#endif /* IRCD_EXTENSIONS */
p = STREND(p);
p += sprintf(p," fX%s",axx.asc);
to_server("PING :OT%lu\n",current->ontime);
}
for(client=current->clientlist;client;client=client->next)
@ -391,16 +394,15 @@ void do_reset(COMMAND_ARGS)
if ((MSGLEN - (p - env)) > sz)
{
unset_closeonexec(client->sock);
axx.num[0] = mkaxx(current->guid);
axx.num[1] = mkaxx(client->sock);
axx.num[0] = simpleencode(current->guid);
axx.num[1] = simpleencode(client->sock);
axx.num[2] = 0;
#ifdef TELNET
sprintf(p,(client->flags & DCC_TELNET) ? " t%s:%s" : " c%s:%s",
p += sprintf(p,(client->flags & DCC_TELNET) ? " t%s:%s" : " c%s:%s",
axx.asc,client->user->name);
#else
sprintf(p," c%s:%s",axx.asc,client->user->name);
p += sprintf(p," c%s:%s",axx.asc,client->user->name);
#endif /* TELNET */
p = STREND(p);
}
}
}

View File

@ -44,7 +44,7 @@
#define NF_OPTIONS 7
LS const char notify_opt[NF_OPTIONS][10] =
const char notify_opt[NF_OPTIONS][10] =
{
"-ALL",
"-NOMATCH",
@ -53,9 +53,9 @@ LS const char notify_opt[NF_OPTIONS][10] =
"-SEEN",
};
LS Notify **endoflist;
LS int lock_ison = FALSE;
LS int nf_header;
Notify **endoflist;
int lock_ison = FALSE;
int nf_header;
void purge_notify(void)
{
@ -142,11 +142,11 @@ void send_ison(void)
* dont send nicks to ISON too often
*/
period = current->setting[INT_ISONDELAY].int_var;
x = now - current->lastnotify;
x = cx.now - current->lastnotify;
if ((x < period) || (lock_ison && (x < 600)))
return;
current->lastnotify = now;
current->lastnotify = cx.now;
/*
* the nature of the code makes it so that the first NULL is
@ -206,7 +206,7 @@ void catch_ison(char *rest)
{
if (!nickcmp(nf->nick,nick))
{
nf->checked = now;
nf->checked = cx.now;
/*
* /whois user to get user@host + realname
*/
@ -228,14 +228,14 @@ void catch_ison(char *rest)
{
if (nf->checked == 1)
{
nf->checked = now;
nf->checked = cx.now;
if (nf->status >= NF_WHOIS)
{
/*
* close the log entry for this online period
*/
if (nf->log && nf->log->signon && !nf->log->signoff)
nf->log->signoff = now;
nf->log->signoff = cx.now;
/*
* announce that the user is offline if its a mask match
*/
@ -264,7 +264,7 @@ void catch_whois(char *nick, char *userhost, char *realname)
*/
set_mallocdoer(catch_whois);
nlog = (nfLog*)Calloc(sizeof(nfLog) + Strlen2(userhost,realname)); // realname is never NULL
nlog->signon = now;
nlog->signon = cx.now;
nlog->next = nf->log;
nf->log = nlog;
nlog->realname = stringcat(nlog->userhost,userhost) + 1;
@ -390,7 +390,7 @@ void write_notifylog(void)
for(nlog=nf->log;nlog;nlog=nlog->next)
{
to_file(fd,"%s %lu %lu %s :%s\n",nf->nick,nlog->signon,
(nlog->signoff) ? nlog->signoff : now,
(nlog->signoff) ? nlog->signoff : cx.now,
nlog->userhost,nlog->realname);
}
}
@ -466,7 +466,7 @@ int notify_callback(char *rest)
{
nf->mask = dst + 1;
dst = stringcat(nf->mask,rest);
if (STRCHR(nf->mask,' '))
if (stringchr(nf->mask,' '))
nf->endofmask = dst;
}
if (src)
@ -530,7 +530,7 @@ void nfshow_brief(Notify *nf)
if (nf->log && nf->log->signoff)
{
s = mem;
when = now - nf->log->signoff;
when = cx.now - nf->log->signoff;
d = when / 86400;
h = (when -= d * 86400) / 3600;
m = (when -= h * 3600) / 60;
@ -565,7 +565,7 @@ void nfshow_full(Notify *nf)
for(nlog=nf->log;nlog;nlog=nlog->next)
{
opt = mem;
s = time2away(nlog->signon);
s = maketimestr(nlog->signon,TFMT_AWAY);
if (s[1] == ':')
*(opt++) = ' ';
*opt = 0;
@ -576,7 +576,7 @@ void nfshow_full(Notify *nf)
opt = stringcat(opt," -- ");
if (nlog->signoff)
{
s = time2away(nlog->signoff);
s = maketimestr(nlog->signoff,TFMT_AWAY);
if (s[1] == ':')
*(opt++) = ' ';
*opt = 0;
@ -654,7 +654,7 @@ int write_seenlist(void)
for(seen=seenlist;seen;seen=seen->next)
{
if ((seen->when - now) > (86400 * SEEN_TIME))
if ((seen->when - cx.now) > (86400 * SEEN_TIME))
continue;
else
{
@ -696,7 +696,7 @@ int read_seenlist_callback(char *rest)
pa = chop(&rest);
pb = rest;
if ((now - when) < (SEEN_TIME * 86400))
if ((cx.now - when) < (SEEN_TIME * 86400))
{
/* if (pa && !*pa)
pa = NULL; chop() doesnt return empty strings */
@ -826,12 +826,10 @@ void do_seen(COMMAND_ARGS)
{
Seen *seen;
char ago[35]; /* enought for "36500 days, 23 hours and 59 minutes" (100 years) */
const char *chan;
char *fmt,*n,*u,*c1,*c2,*c3;
time_t when;
int d,h,m,mul;
chan = get_channel(to,&rest);
mul = get_maxaccess(from);
if (!*rest)
@ -847,7 +845,7 @@ void do_seen(COMMAND_ARGS)
return;
}
if (!nickcmp(n,current->nick))
if (!nickcmp(n,getbotnick(current)))
{
fmt = "%s is me you dweeb!";
}
@ -870,7 +868,7 @@ void do_seen(COMMAND_ARGS)
}
else
{
when = now - seen->when;
when = cx.now - seen->when;
d = when / 86400;
h = (when -= d * 86400) / 3600;
m = (when -= h * 3600) / 60;
@ -985,7 +983,7 @@ void do_notify(COMMAND_ARGS)
#ifdef DEBUG
debug("(do_notify) dumping errnames\n");
#endif /* DEBUG */
to_user(from,"User%s not found: %s",(STRCHR(message,',')) ? "s" : "",message);
to_user(from,"User%s not found: %s",(stringchr(message,',')) ? "s" : "",message);
}
if (nf_header)

View File

@ -24,7 +24,7 @@
#define DEFAULTCMDCHAR '-'
#define ZERO 0
#define ZERO .v.num=0
#define INTCAST(x) .v.num=x
#define CMDCHAR .v.chr=DEFAULTCMDCHAR
#define VNULL .v.str=NULL
@ -33,7 +33,7 @@
#define INTPROC(x) .v.numptr=&x
#define STRPROC(x) .v.strptr=&x
LS const Setting VarName[SIZE_VARS] =
const Setting VarName[SIZE_VARS] =
{
/*
* all channel settings in the beginning

View File

@ -58,7 +58,7 @@ void shit_action(Chan *chan, ChanUser *cu)
send_mode(chan,90,QM_RAWMODE,'+','b',shit->mask);
fromnick = nickcpy(NULL,shit->from);
send_kick(chan,nick,"%s %s: %s",time2small(shit->time),fromnick,
send_kick(chan,nick,"%s %s: %s",maketimestr(shit->time,TFMT_DATE),fromnick,
(shit->reason) ? shit->reason : "GET THE HELL OUT!!!");
return;
}
@ -140,7 +140,7 @@ Shit *add_shit(char *from, char *chan, char *mask, char *reason, int axs, int ex
shit = (Shit*)Calloc(sizeof(Shit) + StrlenX(from,chan,mask,reason,NULL));
shit->action = axs;
shit->time = now;
shit->time = cx.now;
shit->expire = expire;
shit->next = current->shitlist;
@ -177,7 +177,7 @@ Shit *find_shit(const char *userhost, const char *channel)
}
}
}
if (save && save->expire < now)
if (save && save->expire < cx.now)
{
remove_shit(save);
save = NULL;
@ -201,7 +201,7 @@ Shit *get_shituser(char *userhost, char *channel)
*/
if (!current->shitlist)
return(NULL);
if (!nickcmp(current->nick,userhost))
if (!nickcmp(getbotnick(current),userhost))
return(NULL);
for(chan=current->chanlist;chan;chan=chan->next)
{
@ -332,10 +332,10 @@ void do_shit(COMMAND_ARGS)
#ifdef DEBUG
debug("(do_shit) adding %s to %s (Level %i)\n",nuh,channel,shitlevel);
#endif /* DEBUG */
add_shit(from,channel,nuh,rest,shitlevel,now + days);
add_shit(from,channel,nuh,rest,shitlevel,cx.now + days);
to_user(from,TEXT_HASSHITTED,nuh,channel);
to_user(from,TEXT_SHITEXPIRES,time2str(now + days));
to_user(from,TEXT_SHITEXPIRES,maketimestr(cx.now + days,TFMT_FULL));
check_shit();
}
@ -390,7 +390,7 @@ void do_shitlist(COMMAND_ARGS)
for(shit=current->shitlist;shit;shit=shit->next)
{
table_buffer(FMT_6XSTRTAB,shit->chan,shit->mask,shit_actions[shit->action],
nickcpy(NULL,shit->from),shit->reason,time2away(shit->expire));
nickcpy(NULL,shit->from),shit->reason,maketimestr(shit->expire,TFMT_AWAY));
}
table_send(from,2);
}

233
src/spy.c
View File

@ -1,7 +1,7 @@
/*
EnergyMech, IRC bot software
Parts Copyright (c) 1997-2024 proton
Parts Copyright (c) 1997-2025 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
@ -34,7 +34,7 @@
#ifdef DEBUG
LS const char SPY_DEFS[][12] =
const char SPY_DEFS[][12] =
{
"SPY_FILE",
"SPY_CHANNEL",
@ -50,27 +50,10 @@ LS const char SPY_DEFS[][12] =
#endif /* DEBUG */
static int basepos(char c)
{
/*
-lcrypt converts to [a-zA-Z0-9./]
included sha1 converts to hex
included md5 converts to [./0-9A-Za-z]
*/
if (c >= 'a' && c <= 'z')
return(c - 'a');
if (c >= 'A' && c <= 'Z')
return(c - 'A' + 26);
if (c >= '0' && c <= '9')
return(c - '0' + 52);
if (c == '.')
return(62);
if (c == '/')
return(63);
return(0);
}
#if defined(SHACRYPT) || defined(MD5CRYPT)
char *CRYPT_FUNC(const char *, const char *);
#endif
void send_spy(const char *src, const char *format, ...)
@ -79,83 +62,95 @@ void send_spy(const char *src, const char *format, ...)
Mech *backup;
Spy *spy;
va_list msg;
const char *tempsrc;
const char *spysrc;
const char *printmsg;
char tempdata[MAXLEN],*rnd,*dst,*end;
int fd,a,b,c,d;
int printed = FALSE;
char tempdata[MAXLEN];
int fd;
if (src == SPYSTR_RAWIRC)
{
tempsrc = printmsg = format;
printed = TRUE;
format = FMT_PLAIN;
}
else
if (src == SPYSTR_STATUS)
{
tempsrc = time2medium(now);
}
else
{
tempsrc = src;
}
printmsg = (src == SPYSTR_RAWIRC) ? format : NULL;
#ifdef DEBUG
if (src != SPYSTR_RAWIRC) /* too much debug spam */
debug("(send_spy) src <%s> format = '%s', current = '%s' (%i)\n",src,format,
(current == NULL) ? "<NULL>" : nullstr(current->nick),(current == NULL) ? -1 : current->guid);
(current == NULL) ? "<NULL>" : getbotnick(current),(current == NULL) ? -1 : current->guid);
#endif /* DEBUG */
for(spy=current->spylist;spy;spy=spy->next)
{
/*
* Dont support RANDSRC unless there is a good hashing function to
* create high quality randomness.
*/
#if defined(SHACRYPT) || defined(MD5CRYPT)
if (spy->t_src == SPY_RANDSRC)
{
char mysalt[16],mydata[128];
char *rnd,*dst,*end;
if (src != SPYSTR_RAWIRC)
continue;
if (spy->data.delay > cx.now)
continue;
/* dont use four-char server messages such as "PING :..." */
if (tempsrc[5] == ':')
#ifdef DEBUG
{
debug("(send_spy) RANDSRC: skipping four-char server message\n");
#endif /* DEBUG */
if (format[5] == ':')
continue;
#ifdef DEBUG
}
#endif /* DEBUG */
/* create delay until next */
spy->data.delay = cx.now + 20 + RANDOM(0,29); /* make it unpredictable which messages will be sourced */
if (spy->data.delay > now)
continue;
spy->data.delay = now + 10 + RANDOM(0,9); /* make it unpredictable which messages will be sourced */
/*
$6$ for sha512, $1$ for MD5
MD5 | 22 characters
SHA-512 | 86 characters
*/
sprintf(mysalt,
#ifdef SHACRYPT
sprintf(tempdata,"$6$%04x",(uint32_t)(now & 0xFFFF));
rnd = CRYPT_FUNC(tempsrc,tempdata);
"$6$%04x",
#else
"$1$%04x",
#endif /* SHACRYPT */
(uint32_t)(cx.now & 0xFFFF));
#if !defined(SHACRYPT) && defined(MD5CRYPT)
sprintf(tempdata,"$1$%04x",(uint32_t)(now & 0xFFFF));
rnd = CRYPT_FUNC(tempsrc,tempdata);
#endif /* !SHACRYPT && MD5CRYPT */
/* SHA512 internal returns NULL if strlen(format) > 256 */
stringcpy_n(mydata,format,120);
rnd = CRYPT_FUNC(mydata,mysalt);
dst = tempdata;
end = STREND(rnd);
#if defined(SHACRYPT) || defined(MD5CRYPT)
rnd += 8; /* skip salt */
#endif
while(rnd < (end - 3))
while(rnd < (end - 4))
{
union WordtoBytes
{
uint32_t m;
uint8_t b[4];
} m32;
uint32_t n, o, p;
int a,b,c,d;
m32.m = *((uint32_t*)rnd);
/*
* branchless bit operations to do 4 bytes at a time
* if input is not base64, the output is undefined
*/
n = (((m32.m - 0x3a3a3a3a) & 0x80808080) >> 7) * 7;
o = (((m32.m - 0x5b5b5b5b) & 0x80808080) >> 7) * 6;
p = (((m32.m - 0x7b7b7b7b) & 0x80808080) >> 7) * 6;
m32.m = m32.m - 0x41414141 + n + o + p;
a = m32.b[0];
b = m32.b[1];
c = m32.b[2];
d = m32.b[3];
/*
|..aaaaaa|..bbbbbb|..cccccc|..dddddd|
| |aaaaaa..|bbbbbb..|cccccc..|
| | ddddDD|
| ddDD|dd
DD|dddd |
*/
/* base64 to bin, 4 chars to 3 */
a = basepos(rnd[0]);
b = basepos(rnd[1]);
dst[0] = (a << 2) | (b >> 4); /* aaaaaabb */
c = basepos(rnd[2]);
dst[1] = (b << 4) | (c >> 2); /* bbbbcccc */
d = basepos(rnd[3]);
dst[2] = (c << 6) | (d); /* ccdddddd */
dst += 3;
rnd += 4;
@ -167,14 +162,14 @@ void send_spy(const char *src, const char *format, ...)
#endif /* DEBUG */
if ((fd = open(spy->dest,O_WRONLY|O_CREAT|O_APPEND,NEWFILEMODE)) >= 0)
{
int n;
int n __notused__;
n = write(fd,tempdata,dst - tempdata);
close(fd);
}
}
continue;
}
#endif /* defined(SHACRYPT) || defined(MD5CRYPT) */
if ((*src == '#' || *src == '*') && spy->t_src == SPY_CHANNEL)
{
@ -184,7 +179,6 @@ void send_spy(const char *src, const char *format, ...)
continue;
if (find_chanuser(chan,CurrentNick) == NULL)
continue;
tempsrc = spy->src;
}
else
/*
@ -193,18 +187,25 @@ void send_spy(const char *src, const char *format, ...)
if (spy->src != src)
continue;
if (!printed)
if (spy->t_src == SPY_STATUS)
{
spysrc = maketimestr(cx.now,TFMT_CLOCK);
}
else
spysrc = spy->src;
if (printmsg == NULL)
{
printed = TRUE;
va_start(msg,format);
vsprintf(tempdata,format,msg);
va_end(msg);
printmsg = tempdata;
}
switch(spy->t_dest)
{
case SPY_DCC:
to_file(spy->data.dcc->sock,"[%s] %s\n",tempsrc,printmsg);
to_file(spy->data.dcc->sock,"[%s] %s\n",spysrc,printmsg);
break;
case SPY_CHANNEL:
if (spy->data.destbot >= 0)
@ -214,7 +215,7 @@ void send_spy(const char *src, const char *format, ...)
{
if (current->guid == spy->data.destbot)
{
to_server("PRIVMSG %s :[%s] %s\n",spy->dest,tempsrc,printmsg);
to_server("PRIVMSG %s :[%s] %s\n",spy->dest,spysrc,printmsg);
break;
}
}
@ -222,13 +223,13 @@ void send_spy(const char *src, const char *format, ...)
}
else
{
to_user(spy->dest,"[%s] %s",tempsrc,printmsg);
to_user(spy->dest,"[%s] %s",spysrc,printmsg);
}
break;
case SPY_FILE:
if ((fd = open(spy->dest,O_WRONLY|O_CREAT|O_APPEND,NEWFILEMODE)) >= 0)
{
to_file(fd,"[%s] %s\n",logtime(now),printmsg);
to_file(fd,"[%s] %s\n",maketimestr(cx.now,TFMT_LOG),printmsg);
close(fd);
}
}
@ -325,7 +326,7 @@ int begin_redirect(char *from, char *args)
if (!args)
return(0);
pt = STRCHR(args,'>');
pt = stringchr(args,'>');
if (pt)
{
*pt = 0;
@ -427,7 +428,7 @@ void send_redirect(char *message)
Mech *backup;
/* PM<targetguid> <targetuserhost> <source> <message> */
sprintf(tempdata,"%i %s %s %s",redirect.guid,redirect.to,current->nick,message);
sprintf(tempdata,"%i %s %s %s",redirect.guid,redirect.to,getbotnick(current),message);
backup = current;
partyMessage(NULL,tempdata);
current = backup;
@ -462,10 +463,10 @@ void end_redirect(void)
#ifdef URLCAPTURE
char *urlhost(const char *url)
void urlhost(const char *url)
{
char copy[strlen(url)];
const char *end,*beg,*dst;
const char *end,*beg;
int n = 0;
beg = end = url;
@ -493,7 +494,7 @@ char *urlhost(const char *url)
void urlcapture(const char *rest)
{
Strp *sp,*nx;
Strp *sp;
char *dest,url[MSGLEN];
int n;
@ -538,7 +539,7 @@ void stats_loghour(Chan *chan, char *filename, int hour)
if (!(stats = chan->stats))
return;
when = (now - (now % 3600));
when = (cx.now - (cx.now % 3600));
if ((fd = open(filename,O_WRONLY|O_APPEND|O_CREAT,NEWFILEMODE)) >= 0)
{
@ -567,16 +568,16 @@ void stats_plusminususer(Chan *chan, int plusminus)
stats->users++;
stats->userpeak = stats->users;
stats->userlow = stats->users;
stats->lastuser = now;
stats->lastuser = cx.now;
stats->flags = CSTAT_PARTIAL;
}
/*
* add (number of users until now * seconds since last user entered/left)
*/
stats->userseconds += stats->users * (now - stats->lastuser);
stats->userseconds += stats->users * (cx.now - stats->lastuser);
stats->lastuser = now;
stats->lastuser = cx.now;
stats->users += plusminus; /* can be both negative (-1), zero (0) and positive (+1) */
if (stats->userpeak < stats->users)
@ -769,7 +770,7 @@ spy_dest_ok:
debug("(do_spy) src = `%s'; t_src = %i (%s); dest = `%s'; t_dest = %i (%s), CurrentDCC "mx_pfmt"\n",
src,t_src,SPY_DEFS[t_src-1],nullstr(dest),t_dest,SPY_DEFS[t_dest-1],CurrentDCC);
if (guid >= 0)
debug("(do_spy) spying from remote bot guid %i (%s), channel %s\n",guid,(destbot) ? destbot->nick : "unknown",src);
debug("(do_spy) spying from remote bot guid %i (%s), channel %s\n",guid,(destbot) ? getbotnick(destbot) : "unknown",src);
#endif /* DEBUG */
if (t_dest == SPY_DCC)
@ -1028,8 +1029,7 @@ void do_info(COMMAND_ARGS)
{
ChanStats *stats;
Chan *chan;
char *p;
char text[MSGLEN];
char modes[128];
uint32_t avg;
if (current->chanlist == NULL)
@ -1037,39 +1037,34 @@ void do_info(COMMAND_ARGS)
to_user(from,ERR_NOCHANNELS);
return;
}
to_user(from,"\037channel\037 "
"\037average\037 \037peak\037 \037low\037");
table_buffer(str_underline("Channel") "\t" str_underline("Statistics") "\t");
for(chan=current->chanlist;chan;chan=chan->next)
{
*(p = text) = 0;
p = stringcat(p,chan->name);
if (chan == current->activechan)
p = stringcat(p," (current)");
if ((stats = chan->stats))
stats = chan->stats;
if (stats == NULL)
{
if (stats && stats->flags == CSTAT_PARTIAL)
p = stringcat(p," (partial)");
while(p < text+35)
*(p++) = ' ';
if (stats->LHuserseconds > 0)
{
avg = stats->LHuserseconds / (60*60);
}
else
{
avg = (stats->userpeak + stats->userlow) / 2;
}
sprintf(p,"%-7u %-4i %i",avg,stats->userpeak,stats->userlow);
to_user(from,FMT_PLAIN,text);
sprintf(text,"Messages: %i Notices: %i Joins: %i Parts: %i Kicks: %i Quits: %i",
stats->privmsg,stats->notice,stats->joins,stats->parts,stats->kicks,stats->quits);
table_buffer("%s (no current data)",chan->name);
continue;
}
if (stats->LHuserseconds > 0)
avg = stats->LHuserseconds / (60*60);
else
{
stringcpy(p," (no current data)");
}
to_user(from,FMT_PLAIN,text);
avg = (stats->userpeak + stats->userlow) / 2;
chan_modestr(chan,modes);
table_buffer("%s%s%s\tUsers:\tAvg\t%u\tPeak\t%i\tLow\t%i",
chan->name,(chan == current->activechan) ? " (current)" : EMPTYSTR,
(stats->flags == CSTAT_PARTIAL) ? " (partial)" : EMPTYSTR,
avg,stats->userpeak,stats->userlow);
table_buffer("Modes: %s\tMessages:\t\t%i\tNotices:\t%i\tJoins:\t%i",modes,
stats->privmsg,stats->notice,stats->joins);
table_buffer("\tParts:\t\t%i\tKicks:\t%i\tQuits:\t%i",
stats->parts,stats->kicks,stats->quits);
}
table_send(from,2);
}
#endif /* STATS */

View File

@ -34,24 +34,25 @@ char *chop(char **src)
{
char *tok,*cut = *src;
while(*cut && *cut == ' ')
/* skip leading spaces */
while(*cut == ' ')
cut++;
if (*cut)
{
tok = cut;
while(*cut && *cut != ' ')
cut++;
*src = cut;
while(*cut && *cut == ' ')
cut++;
**src = 0;
*src = cut;
}
else
{
tok = NULL;
}
if (*cut == 0)
return(NULL);
tok = cut;
while(*cut && *cut != ' ')
cut++;
*src = cut;
/* skip more spaces */
while(*cut == ' ')
cut++;
**src = 0;
cx.chop_end = *src = cut;
return(tok);
}
@ -132,17 +133,6 @@ void stringcpy_n(char *dst, const char *src, int sz)
n++;
}
dst[n] = 0;
/*
char *stop = dst + sz - 1;
while(*src)
{
*(dst++) = *(src++);
if (dst == stop)
break;
}
*dst = 0;
*/
}
char *stringcpy(char *dst, const char *src)

View File

@ -1,7 +1,7 @@
/*
EnergyMech, IRC bot software
Parts Copyright (c) 1997-2020 proton
Parts Copyright (c) 1997-2025 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
@ -21,35 +21,40 @@
#ifndef STRUCTS_H
#define STRUCTS_H 1
typedef union usercombo
typedef struct Strp
{
struct
{
uint32_t access:8, /* access level (0-200) [0-255] */
prot:3, /* protlevel (0-4) [0-7] */
#ifdef BOTNET
noshare:1, /* dont share this user over botnet */
readonly:1, /* botnet cannot alter this user */
#endif /* BOTNET */
#ifdef GREET
greetfile:1, /* greeting is filename */
randline:1, /* grab random line from filename */
#endif /* GREET */
#ifdef BOUNCE
bounce:1, /* user has access to bouncer */
#endif /* BOUNCE */
echo:1, /* partyline echo of own messages */
aop:1, /* auto-opping */
avoice:1; /* auto-voicing */
} x;
uint32_t comboflags;
struct Strp *next;
char p[1];
} usercombo;
} Strp;
typedef struct Mix16
{
union
{
char string[16];
char *ptr;
} x;
int8_t opt;
} Mix16;
typedef struct Mix64
{
union
{
char string[64];
char *ptr;
} x;
int8_t opt;
} Mix64;
typedef struct OnMsg
{
const char *name;
void (*func)(char *, const char *, char *, const int);
void (*noargfunc)(const char *);
uint32_t defaultaccess:8, /* defaultaccess */
dcc:1,
cc:1,
@ -63,15 +68,14 @@ typedef struct OnMsg
lbuf:1,
cbang:1,
acchan:1,
supres:1; /* -- 21 bits */
supres:1, /* -- 21 bits */
noargf:1; /* -- 22 bits */
const char *cmdarg;
} OnMsg;
typedef unsigned char OnMsg_access;
#ifndef GENCMD_C
typedef struct ircLink
{
struct ircLink *next;
@ -88,10 +92,6 @@ typedef struct ircLink
char *nick; /* which nick to speak to */
char *handle;
#ifdef IDWRAP
char *idfile;
#endif /* IDWRAP */
char servmem[MSGLEN];
char usermem[MSGLEN];
@ -106,12 +106,7 @@ typedef struct
typedef struct DEFstruct
{
union
{
int id;
void *func;
} v;
int id;
char *idstr;
} DEFstruct;
@ -120,6 +115,7 @@ typedef struct Alias
{
struct Alias *next;
int hash;
char *format;
char alias[1];
@ -206,19 +202,12 @@ typedef struct Setting
char **strptr;
} v;
char *name;
char name[16];
int max;
void (*func)(const struct Setting *);
void (*onchangefunc)(const struct Setting *);
} Setting;
typedef struct Strp
{
struct Strp *next;
char p[1];
} Strp;
typedef struct KickSay
{
struct KickSay *next;
@ -252,6 +241,28 @@ typedef struct Shit
} Shit;
typedef union usercombo
{
struct
{
/* dont gatekeep these flags with ifdefs,
make userfiles compatible between different compiles */
uint32_t access:8, /* access level (0-200) [0-255] */
prot:3, /* protlevel (0-4) [0-7] */
noshare:1, /* dont share this user over botnet */
readonly:1, /* botnet cannot alter this user */
greetfile:1, /* greeting is filename */
randline:1, /* grab random line from filename */
bounce:1, /* user has access to bouncer */
echo:1, /* partyline echo of own messages */
aop:1, /* auto-opping */
avoice:1; /* auto-voicing */
} x;
uint32_t comboflags;
} usercombo;
#ifndef GENCMD_C
/*
* this struct is put to use in global.h
@ -491,34 +502,33 @@ typedef struct Spy
} Spy;
typedef struct sockaddr_in sai_v4;
typedef struct sockaddr_in6 sai_v6;
typedef struct Server
{
struct Server *next;
int ident;
int usenum;
int servergroup;
int port;
int err;
time_t lastconnect;
time_t lastattempt;
time_t maxontime;
char ipv;
union {
sai_v4 ipv4;
sai_v6 ipv6;
} resolved;
char realname[NAMEBUF];
char name[NAMEBUF];
char pass[PASSLEN];
char pass[PASSBUF];
char group[SERVERGROUPBUF];
} Server;
typedef struct ServerGroup
{
struct ServerGroup *next;
int servergroup;
char name[1];
} ServerGroup;
typedef struct FileMon
{
struct FileMon *next;
@ -535,6 +545,7 @@ typedef struct Mech
uint16_t guid; /* globally uniqe ID */
int connect;
int sock;
char ipv; /* ip version */
struct in_addr ip; /* for DCC */
int server; /* ident of my current server */
int nextserver;
@ -553,9 +564,10 @@ typedef struct Mech
/*
* Basic bot information
*/
char *nick; /* current nickname */
char *wantnick; /* wanted nickname */
char *userhost;
Mix16 nick;
Mix16 wantnick;
Mix64 userhost;
int vhost_type;
uint32_t reset:1,
@ -582,33 +594,31 @@ typedef struct Mech
#endif /* NOTIFY */
time_t lastreset; /* last time bot was reset */
time_t ontime; /* how long the bot has been connected */
time_t lastantiidle; /* avoid showing large idle times */
time_t activity; /* Away timer (AAWAY) */
time_t lastrejoin; /* last time channels were reset */
#ifdef CHANBAN
time_t lastchanban; /* last time a chanban check was run */
#endif /* CHANBAN */
time_t conntry; /* when connect try started */
/* re-used for server activity once connected */
int heartbeat; /* handle server timeout stuff */
time_t activity; /* Away timer (AAWAY) */
time_t ontime; /* how long the bot has been connected */
#ifdef IRCD_EXTENSIONS
int ircx_flags;
#endif /* IRCD_EXTENSIONS */
#ifdef DEBUG
char *inject;
#endif /* DEBUG */
/*
* Buffers for do_die() command.
*/
char *signoff;
char *from;
#ifdef IDWRAP
char *identfile;
#endif /* IDWRAP */
/* big buffers at the end */
UniVar setting[SIZE_VARS]; /* global vars + channel defaults */
char modes[32];
@ -698,8 +708,8 @@ typedef struct BotNet
{
uint32_t pta:1, /* plain text auth */
sha:1, /* SHA */
md5:1; /* MD5 */
md5:1, /* MD5 */
links_complete; /* All links shared to this bot */
} opt;
Mech *controller;
@ -711,7 +721,6 @@ typedef struct BotNet
time_t when;
struct BotInfo *botinfo;
int list_complete;
char sockdata[MSGLEN];

View File

@ -32,7 +32,7 @@
#include <tcl.h>
LS Tcl_Interp *energymech_tcl = NULL;
Tcl_Interp *energymech_tcl = NULL;
#define tclv_READ TCL_TRACE_READS
#define tclv_WRITE TCL_TRACE_WRITES
@ -62,7 +62,7 @@ typedef struct Tcl_TVInfo
} Tcl_TVInfo;
LS Tcl_TVInfo vinfolist[] =
Tcl_TVInfo vinfolist[] =
{
{ TVINFO_pointer | TVINFO_CHAR, tclv_READ, "mech_currentnick", CurrentNick },
{ TVINFO_guid | TVINFO_INT, tclv_READ, "mech_guid" },
@ -99,7 +99,7 @@ char *tcl_var_read(Tcl_TVInfo *vinfo, Tcl_Interp *I, char *n1, char *n2, int fla
rdata.i = (current) ? current->guid : -1;
break;
case TVINFO_nick:
rdata.c = (current) ? current->nick : "(undefined variable)";
rdata.c = (current) ? getbotnick(current) : "(undefined variable)";
break;
case TVINFO_wantnick:
rdata.c = (current) ? current->wantnick : "(undefined variable)";
@ -518,7 +518,7 @@ int tcl_dns(void *foo, Tcl_Interp *I, int objc, Tcl_Obj *CONST objv[])
*
*/
LS struct
struct
{
char *cmdname;
void *func;

View File

@ -25,14 +25,6 @@
* These are more or less globally used..
*/
/*
#define FMT_PLAIN "%s"
#define FMT_6XSTRTAB "%s\t%s\t%s\t%s\t%s\t%s"
#define FMT_4XSTRTAB "%s\t%s\t%s\t%s"
#define FMT_3XSTRTAB "%s\t%s\t%s"
*/
#define FMT_PLAINLINE "%s\n"
#define MATCH_ALL "*"
#define TEXT_NOTINSERVLIST "(not in serverlist)"
@ -80,8 +72,8 @@
#define TEXT_SERVERDELETED "Server has been deleted: %s:%i"
#define TEXT_MANYSERVMATCH "Several entries for %s exists, please specify port also"
/* do_core() */
#define TEXT_CURRNICKWANT "Current nick\t%s (Wanted: %s) [guid #%i]"
#define TEXT_CURRNICKHAS "Current nick\t%s [guid #%i]"
#define TEXT_CURRNICKWANT "Current nick\t%s%s (Wanted: %s) [guid #%i]"
#define TEXT_CURRNICKHAS "Current nick\t%s%s [guid #%i]"
#define TEXT_USERLISTSTATS "Users in userlist\t%i (%i Superuser%s, %i Bot%s)"
#define TEXT_ACTIVECHANS "Active channels\t%s"
#define TEXT_MOREACTIVECHANS "\t%s"
@ -91,11 +83,11 @@
#define TEXT_VHINACTIVE " - Inactive"
#define TEXT_CURRSERVER "Current Server\t%s:%i"
#define TEXT_CURRSERVGRP "Current Server\t%s:%i @%s"
#define TEXT_CURRSERVERNOT "Current Server\t" TEXT_NOTINSERVLIST
#define TEXT_TRYNEWSERVER "Trying new server, brb..."
#define TEXT_SWITCHSERVER "Switching servers..."
#define TEXT_SERVERONTIME "Server Ontime\t%s"
#define TEXT_BOTMODES "Mode\t+%s"
#define TEXT_CURRENTTIME "Current Time\t%s"
#define TEXT_BOTSTARTED "Started\t%s"
@ -141,11 +133,11 @@
#define TEXT_CSWITCH " -c make core file instead of coredebug/reset\n"
#define TEXT_HSWITCH " -h show this help\n"
#define TEXT_VSWITCH " -v show EnergyMech version\n"
#define TEXT_ESWITCH " -e <command> run a single command, then exit\n"
#define TEXT_TSWITCH " -t run normal startup, but exit right before going into main loop\n"
#define TEXT_ESWITCH " -e <command> run a single command, then exit\n"
#define TEXT_TSWITCH " -t run normal startup, but exit right before going into main loop\n"
#ifdef SHACRYPT
#define TEXT_PSWITCH1 " -p <string> encrypt <string> using the password hashing algorithm (SHA-512),\n"
#define TEXT_PSWITCH1 " -p <string> encrypt <string> using the password hashing algorithm (SHA),\n"
#elif MD5CRYPT
#define TEXT_PSWITCH1 " -p <string> encrypt <string> using the password hashing algorithm (MD5),\n"
#else
@ -153,9 +145,8 @@
#endif
#define TEXT_PSWITCH2 " output the result and then quit.\n"
#define TEXT_DSWITCH " -d start mech in debug mode\n"
#define TEXT_OSWITCH " -o <file> write debug output to <file>\n"
#define TEXT_XSWITCH " -X write a debug file before exit\n"
#define TEXT_DSWITCH " -d [file] start mech in debug mode, with an optional output file\n"
#define TEXT_XSWITCH " -x write a debug file before any exit\n"
#define TEXT_HDR_VERS "EnergyMech %s, %s\n"
#define TEXT_HDR_FEAT "Features: %s\n"

View File

@ -46,20 +46,19 @@
#define DAY_IN_SECONDS (24*60*60)
#define WEEK_IN_SECONDS (7*24*60*60)
LS TrivScore *lastwinner;
LS Chan *triv_chan = NULL;
LS Strp *triv_answers = NULL;
LS time_t triv_ask_time;
LS time_t triv_next_time = 0;
LS time_t triv_weektop10;
LS int triv_mode;
LS int triv_score;
LS int triv_streak;
LS int triv_halt_flag;
TrivScore *lastwinner;
Chan *triv_chan = NULL;
Strp *triv_answers = NULL;
time_t triv_ask_time;
time_t triv_weektop10;
int triv_mode;
int triv_score;
int triv_streak;
int triv_halt_flag;
#endif /* TRIVIA */
#define BIGSAY_DEFAULTFONT "default"
#define BIGSAY_DEFAULTFONT DEFAULTSTR
#define FONT_EXTENSION ".bigchars"
BigC *newchar;
@ -196,6 +195,7 @@ int read_bigcharset(char *fname)
int read_ascii(char *rest)
{
to_user_q(global_from,FMT_PLAIN,rest);
return(0);
}
#ifdef TRIVIA
@ -216,7 +216,7 @@ void trivia_week_toppers(void)
int i,x;
chosen[0] = NULL;
week = (now + (3 * DAY_IN_SECONDS)) / WEEK_IN_SECONDS;
week = (cx.now + (3 * DAY_IN_SECONDS)) / WEEK_IN_SECONDS;
for(su=scorelist;su;su=su->next)
{
@ -269,7 +269,7 @@ void hint_one(void)
src = triv_answers->p;
while(*src)
{
if (STRCHR(TRIV_METACHARS,*src))
if (stringchr(TRIV_METACHARS,*src))
*(dst++) = *src;
else
*(dst++) = triv_qchar;
@ -306,7 +306,7 @@ void hint_two(void)
while(*src)
{
if (STRCHR(TRIV_METACHARS,*src))
if (stringchr(TRIV_METACHARS,*src))
*(dst++) = *src;
else
*(dst++) = triv_qchar;
@ -343,7 +343,7 @@ void hint_three(void)
while(*src)
{
if (STRCHR(TRIV_METACHARS "aeiouyAEIOUY",*src))
if (stringchr(TRIV_METACHARS "aeiouyAEIOUY",*src))
*(dst++) = *src;
else
*(dst++) = triv_qchar;
@ -364,7 +364,7 @@ void trivia_cleanup(void)
Strp *ans;
triv_mode = TRIV_WAIT_QUESTION;
triv_next_time = now + triv_qdelay;
triv_next_time = cx.now + triv_qdelay;
while((ans = triv_answers))
{
triv_answers = ans->next;
@ -389,7 +389,7 @@ void trivia_check(Chan *chan, char *rest)
return;
have_answer:
week = (now + (3 * DAY_IN_SECONDS)) / WEEK_IN_SECONDS;
week = (cx.now + (3 * DAY_IN_SECONDS)) / WEEK_IN_SECONDS;
for(su=scorelist;su;su=su->next)
{
@ -425,7 +425,7 @@ have_answer:
to_server("PRIVMSG %s :Yes, %s! got the answer -> %s <- in %i seconds, and gets %i points!\n",
triv_chan->name,CurrentNick,triv_answers->p,
(int)(now - triv_ask_time),triv_score);
(int)(cx.now - triv_ask_time),triv_score);
if (su == lastwinner)
{
@ -481,7 +481,7 @@ char *random_question(char *triv_rand)
} entry;
if (STRCHR(triv_qfile,'/') || strlen(triv_qfile) > 100) /* really bad filenames... */
if (stringchr(triv_qfile,'/') || strlen(triv_qfile) > 100) /* really bad filenames... */
return(NULL);
stringcat(stringcpy(tmpname,"trivia/"),triv_qfile);
@ -497,7 +497,7 @@ char *random_question(char *triv_rand)
#endif /* DEBUG */
stringcpy(triv_rand,tmpname);
if ((p = STRCHR(triv_rand,'.')) == NULL)
if ((p = stringchr(triv_rand,'.')) == NULL)
p = STREND(triv_rand);
stringcpy(p,".index");
@ -545,7 +545,7 @@ stop_trivia:
triv_chan = NULL;
triv_next_time = 0;
triv_halt_flag = FALSE;
short_tv &= ~TV_TRIVIA;
cx.short_tv &= ~TV_TRIVIA;
return;
}
@ -558,12 +558,12 @@ stop_trivia:
goto bad_question;
triv_score = (RANDOM(2,9) + RANDOM(2,10) + RANDOM(2,10)) / 3;
triv_ask_time = now;
triv_ask_time = cx.now;
if (now > (triv_weektop10 + 1200))
if (cx.now > (triv_weektop10 + 1200))
{
trivia_week_toppers();
triv_weektop10 = now;
triv_weektop10 = cx.now;
}
to_server("PRIVMSG %s :%s\n",triv_chan->name,question);
@ -575,37 +575,34 @@ void trivia_tick(void)
Chan *chan;
Mech *bot;
if (triv_next_time && (now >= triv_next_time))
for(bot=botlist;bot;bot=bot->next)
{
for(bot=botlist;bot;bot=bot->next)
for(chan=bot->chanlist;chan;chan=chan->next)
{
for(chan=bot->chanlist;chan;chan=chan->next)
if (triv_chan == chan)
{
if (triv_chan == chan)
current = bot;
triv_next_time = cx.now + TRIV_HINT_DELAY;
switch(triv_mode)
{
current = bot;
triv_next_time = now + TRIV_HINT_DELAY;
switch(triv_mode)
{
case TRIV_WAIT_QUESTION:
trivia_question();
break;
case TRIV_HINT_TWO:
hint_two();
break;
case TRIV_HINT_THREE:
hint_three();
break;
case TRIV_NO_ANSWER:
trivia_no_answer();
return; /* dont increment with triv_mode */
}
triv_mode++;
#ifdef DEBUG
current = NULL;
#endif /* DEBUG */
return;
case TRIV_WAIT_QUESTION:
trivia_question();
break;
case TRIV_HINT_TWO:
hint_two();
break;
case TRIV_HINT_THREE:
hint_three();
break;
case TRIV_NO_ANSWER:
trivia_no_answer();
return; /* dont increment with triv_mode */
}
triv_mode++;
#ifdef DEBUG
current = NULL;
#endif /* DEBUG */
return;
}
}
}
@ -737,7 +734,7 @@ void do_bigsay(COMMAND_ARGS)
if (temp[1] == '-')
; /* allow .bigsay -- -dash- */
else
if (STRCHR(temp,'/') == NULL) /* no filesystem perversions... */
if (stringchr(temp,'/') == NULL) /* no filesystem perversions... */
{
stringcat(stringcat(stringcpy(output,COMMONDIR),temp+1),".bigchars"); /* temp+1 = skip initial '-' */
}
@ -770,7 +767,7 @@ reuse_font:
}
for(bigc=fontlist;bigc;bigc=bigc->next)
{
if (STRCHR(bigc->chars,*pt))
if (stringchr(bigc->chars,*pt))
{
sp = bigc->data;
for(x=0;x<i;x++)
@ -816,7 +813,7 @@ reuse_font:
}
}
void do_random_msg(COMMAND_ARGS)
void do_randmsg(COMMAND_ARGS)
{
const char *filename;
const char *message;
@ -899,7 +896,7 @@ void do_ascii(COMMAND_ARGS)
int fd;
#ifdef DEBUG
if (STRCHR(rest,'/'))
if (stringchr(rest,'/'))
{
debug("(do_ascii) '/' not permitted in filename\n");
ascii_badfile:
@ -919,7 +916,7 @@ ascii_badfile:
goto ascii_badfile;
}
#else
if (STRCHR(rest,'/'))
if (stringchr(rest,'/'))
{
ascii_badfile:
to_user_q(from,"%s","Bad filename or file does not exist");
@ -958,7 +955,11 @@ user (after eliminating all known bots) and says the nick in the channel.
If the command ``RAND luser'' is issued in a channel, the bot picks a random channel
user that has no access in the bots userlist and says the nick in the channel.
0299
*/
#define __characterisnumeric (attrtab[(uchar)*rest] & NUM)
#define characterisnumeric (*rest >= '0' && *rest <= '9')
void do_rand(COMMAND_ARGS)
{
const char *opt;
@ -968,18 +969,18 @@ void do_rand(COMMAND_ARGS)
if (!rest || *rest == 0)
goto pick_randnum;
if (attrtab[(uchar)*rest] & NUM)
if (characterisnumeric)
{
max = 0;
while(attrtab[(uchar)*rest] & NUM)
while(characterisnumeric)
max = 10 * max + (*(rest++) - '0');
if (*rest == '-' || *rest == ' ')
rest++;
if ((attrtab[(uchar)*rest] & NUM) == 0)
if (characterisnumeric == 0)
goto pick_randnum;
min = max;
max = 0;
while(attrtab[(uchar)*rest] & NUM)
while(characterisnumeric)
max = 10 * max + (*(rest++) - '0');
goto pick_randnum;
}
@ -1069,10 +1070,10 @@ void do_trivia(COMMAND_ARGS)
to_server("PRIVMSG %s :Trivia starting! Get ready...\n",chan->name);
triv_chan = chan;
triv_mode = TRIV_WAIT_QUESTION;
triv_next_time = now + triv_qdelay;
triv_weektop10 = now;
triv_next_time = cx.now + triv_qdelay;
triv_weektop10 = cx.now;
lastwinner = NULL;
short_tv |= TV_TRIVIA;
cx.short_tv |= TV_TRIVIA;
if (!scorelist)
{
read_triviascore();
@ -1096,7 +1097,7 @@ void do_trivia(COMMAND_ARGS)
if (triv_chan)
{
uaccess = get_authaccess(from,triv_chan->name);
if (now > (triv_weektop10 + 300))
if (cx.now > (triv_weektop10 + 300))
n = 1;
else
n = uaccess;
@ -1104,7 +1105,7 @@ void do_trivia(COMMAND_ARGS)
if (n)
{
trivia_week_toppers();
if (!uaccess) triv_weektop10 = now;
if (!uaccess) triv_weektop10 = cx.now;
}
}
}

View File

@ -38,10 +38,10 @@ typedef struct
int regnr;
int pid;
int type;
uint32_t cookie;
uint32_t packets_sent;
uint32_t uptime;
uint32_t ontime;
uint32_t now;
uint32_t mytime;
uint32_t sysup;
} PackStub;
@ -51,10 +51,10 @@ typedef struct
int regnr;
int pid;
int type;
uint32_t cookie;
uint32_t packets_sent;
uint32_t uptime;
uint32_t ontime;
uint32_t now;
uint32_t mytime;
uint32_t sysup;
char string[512];
@ -64,7 +64,7 @@ void init_uptime(void)
{
struct sockaddr_in sai;
uptimecookie = rand();
uptimepackets = 0;
if (!uptimehost)
{
@ -94,9 +94,8 @@ void init_uptime(void)
void send_uptime(int type)
{
PackUp upPack;
PackUp *upPack;
struct sockaddr_in sai;
struct stat st;
Server *sp;
const char *server,*nick;
int sz;
@ -109,7 +108,7 @@ void send_uptime(int type)
{
char *host;
uptimelast = now + 10;
uptimelast = cx.now + 10;
if ((host = poll_rawdns(uptimehost)))
{
if ((uptimeip = inet_addr(host)) != -1)
@ -128,37 +127,28 @@ void send_uptime(int type)
}
#endif /* RAWDNS */
upPack = (PackUp*)&globaldata;
/*
* update the time when we last sent packet
*/
sz = (uptimelast + 1) & 7;
uptimelast = (now & ~7) + 21600 + sz; /* 21600 seconds = 6 hours */
uptimelast = (cx.now & ~7) + 21600 + sz; /* 21600 seconds = 6 hours */
uptimecookie = (uptimecookie + 1) * 18457;
upPack.cookie = htonl(uptimecookie);
uptimepackets = uptimepackets + 1;
upPack->packets_sent = htonl(uptimepackets);
upPack.now = htonl(now);
upPack.regnr = uptimeregnr;
upPack.type = htonl(type);
upPack.uptime = htonl(uptime);
upPack.ontime = 0; /* set a few lines down */
upPack->mytime = htonl(cx.now);
upPack->regnr = uptimeregnr;
upPack->type = htonl(type);
upPack->uptime = htonl(uptime);
upPack->ontime = 0; /* set a few lines down */
/*
* callouts to other functions should be done last (think compiler optimizations)
*/
upPack.pid = htonl(getpid());
/*
* this trick for most systems gets the system uptime
*/
if (stat("/proc",&st) < 0)
{
upPack.sysup = 0;
}
else
{
upPack.sysup = htonl(st.st_ctime);
}
upPack->pid = htonl(getpid());
upPack->sysup = htonl(cx.system_uptime);
server = UNKNOWN;
nick = BOTLOGIN;
@ -168,8 +158,8 @@ void send_uptime(int type)
*/
if (botlist)
{
nick = botlist->nick;
upPack.ontime = htonl(botlist->ontime);
nick = getbotnick(botlist);
upPack->ontime = htonl(botlist->ontime);
if ((sp = find_server(botlist->server)))
{
server = (*sp->realname) ? sp->realname : sp->name;
@ -190,12 +180,11 @@ void send_uptime(int type)
}
#endif /* ! RAWDNS */
sz = sizeof(PackStub) + 3 + StrlenX(nick,server,VERSION,NULL);
if (sz > sizeof(PackUp))
return;
sprintf(upPack.string,"%s %s %s",nick,server,VERSION);
sz = sizeof(PackStub) + snprintf(upPack->string,256,"%s %s %s",nick,server,VERSION);
#ifdef DEBUG
debug("(send_uptime) packets sent %i, my pid %i, my ident = \"%s\"\n",uptimepackets,ntohl(upPack->pid),upPack->string);
#endif /* DEBUG */
/*
* udp sending...
*/
@ -204,7 +193,7 @@ void send_uptime(int type)
sai.sin_addr.s_addr = uptimeip;
sai.sin_port = htons(uptimeport);
sendto(uptimesock,(void*)&upPack,sz,0,(struct sockaddr*)&sai,sizeof(sai));
sendto(uptimesock,(void*)upPack,sz,0,(struct sockaddr*)&sai,sizeof(sai));
}
void uptime_death(int type)
@ -212,7 +201,7 @@ void uptime_death(int type)
#ifdef DEBUG
debug("(uptime_death) sending death message\n");
#endif /* DEBUG */
time(&now);
time(&cx.now);
uptimelast = 0; /* avoid resolving the hostname */
send_uptime(type);
uptimeport = 0; /* avoid sending more packets */
@ -221,7 +210,8 @@ void uptime_death(int type)
void process_uptime(void)
{
struct sockaddr_in sai;
int res,sz;
unsigned int sz;
int res;
struct
{
int regnr;
@ -238,7 +228,7 @@ void process_uptime(void)
res = recvfrom(uptimesock,(void*)&regPack,sizeof(regPack),0,(struct sockaddr*)&sai,&sz);
if (res == sizeof(regPack))
{
if (uptimecookie == ntohl(regPack.cookie))
if (uptimepackets == ntohl(regPack.cookie))
{
if (uptimeregnr == 0)
uptimeregnr = ntohl(regPack.regnr);
@ -246,7 +236,7 @@ void process_uptime(void)
}
}
if (uptimelast < now)
if (uptimelast < cx.now)
{
send_uptime(UPTIME_BOTTYPE);
}

View File

@ -1,7 +1,7 @@
/*
EnergyMech, IRC bot software
Copyright (c) 2000-2009 proton
Copyright (c) 2000-2025 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
@ -26,7 +26,7 @@ typedef struct
} UsageList;
LS const UsageList ulist[] =
const UsageList ulist[] =
{
#ifdef TOYBOX
{ C_8BALL, "[text]" },
@ -59,7 +59,7 @@ LS const UsageList ulist[] =
#endif /* CTCP */
{ C_CYCLE, "[channel]" },
#ifdef DEBUG
{ C_DEBUG, NULL },
{ C_DEBUG, "[On <debugfile>|Off]" },
#endif /* DEBUG */
{ C_DEOP, "[channel] <nick|pattern [...]>" },
{ C_DIE, "[reason]" },
@ -115,6 +115,9 @@ LS const UsageList ulist[] =
#endif /* CTCP */
{ C_QSHIT, "<nick> [reason]" },
#ifdef NOTE
#ifdef TOYBOX
{ C_RAND, "[#|#-#|# #|\"nick\"|\"luser\"]" },
#endif /* TOYBOX */
{ C_READ, "[-]<number>" },
#endif /* NOTE */
{ C_RESET, NULL },
@ -137,7 +140,6 @@ LS const UsageList ulist[] =
{ C_SEND, "[to] <filename>" },
#endif /* DCC_FILE */
{ C_SERVER, "[[+|-]servername] [port] [pass]" },
{ C_SERVERGROUP,"[identifier]" },
{ C_SET, "[channel|*] [setting [value]]" },
{ C_SETPASS, "<handle> <password>" },
{ C_SHIT, "<channel|*> <nick|mask> <action> [expire] <reason>" },
@ -146,7 +148,7 @@ LS const UsageList ulist[] =
{ C_SHUTDOWN, NULL },
{ C_SITEBAN, "[channel] <nick|userhost>" },
{ C_SITEKB, "[channel] <nick> [reason]" },
{ C_SPY, "[STATUS|MESSAGE|RAWIRC|[guid\":\"|botnick\":\"] [channel|\">\" filename]" },
{ C_SPY, "[<source>|[guid\":\"|botnick\":\"] [channel|\">\" filename]]" },
{ C_STATS, "<type> [servername]" },
#ifdef TCL
#ifdef PLEASE_HACK_MY_SHELL

View File

@ -77,26 +77,22 @@ void cfg_chan(char *rest)
addtouser(&cfgUser->chan,rest,TRUE);
}
LS struct
struct
{
char modechar;
int modeflag;
} cfg_opt_flags[] =
/* dont gatekeep these flags with ifdefs,
make userfiles compatible between different compiles */
{
{ 'a', COMBO_AOP },
#ifdef BOUNCE
{ 'b', COMBO_BOUNCE },
#endif /* BOUNCE */
{ 'e', COMBO_ECHO },
#ifdef BOTNET
{ 'L', COMBO_NOSHARE },
{ 'R', COMBO_READONLY },
#endif /* BOTNET */
#ifdef GREET
{ 'g', COMBO_GREETFILE },
{ 'r', COMBO_RANDLINE },
#endif /* GREET */
{ 'v', COMBO_AVOICE },
{ 0, 0, }};
@ -148,7 +144,7 @@ void cfg_shit(char *rest)
* convert the expiry time
*/
expire = asc2int(chop(&rest)); /* asc2int() can handle NULLs */
if (errno || expire < now)
if (errno || expire < cx.now)
return;
/*
@ -161,10 +157,10 @@ void cfg_shit(char *rest)
/*
* finally, add the sucker
*/
backup_now = now;
now = when;
backup_now = cx.now;
cx.now = when;
add_shit(from,channel,mask,rest,shitlevel,expire);
now = backup_now;
cx.now = backup_now;
}
void cfg_kicksay(char *rest)
@ -173,7 +169,7 @@ void cfg_kicksay(char *rest)
backup = CurrentDCC;
CurrentDCC = (Client*)&CoreClient;
do_kicksay((char*)CoreUser.name,NULL,rest,0);
do_kicksay((char*)cx.CoreUser.name,NULL,rest,0);
CurrentDCC = backup;
}
@ -232,7 +228,7 @@ typedef struct CommandStruct
} ConfCommand;
LS const ConfCommand userlist_cmds[] =
const ConfCommand userlist_cmds[] =
{
/*
* users
@ -564,7 +560,9 @@ void mirror_user(User *user)
{
Mech *backup,*anybot;
User *newuser,*olduser;
#ifdef NOTE
Strp *notes;
#endif /* NOTE */
#ifdef BOTNET
/* dont mirror noshare users */
@ -593,7 +591,7 @@ void mirror_user(User *user)
}
#ifdef DEBUG
debug("(mirror_user) mirroring user %s[%i] to local bot %s(%i)\n",
user->name,user->x.x.access,nullstr(anybot->nick),anybot->guid);
user->name,user->x.x.access,getbotnick(anybot),anybot->guid);
#endif /* DEBUG */
current = anybot;
@ -646,7 +644,7 @@ void mirror_userlist(void)
User *user;
#ifdef DEBUG
debug("(mirror_userlist) mirroring userlist of %s(%i)\n",nullstr(current->nick),current->guid);
debug("(mirror_userlist) mirroring userlist of %s(%i)\n",getbotnick(current),current->guid);
#endif /* DEBUG */
for(user=current->userlist;user;user=user->next)
@ -903,7 +901,7 @@ int is_bot(const char *userhost)
for(bot=botlist;bot;bot=bot->next)
{
if (!nickcmp(userhost,bot->nick))
if (!nickcmp(userhost,getbotnick(bot)))
return(TRUE);
}
return(FALSE);
@ -1077,7 +1075,7 @@ void do_userlist(COMMAND_ARGS)
channel = rest;
}
else
if (STRCHR(rest,'*') != NULL)
if (stringchr(rest,'*') != NULL)
{
mask = rest;
}
@ -1184,7 +1182,6 @@ void do_user(COMMAND_ARGS)
/*
* on_msg checks: CARGS
*/
Mech *anybot;
User *user;
Strp *ump;
char *handle,*pt,*mask,*nick,*chan,*anum,*pass,*encpass;

View File

@ -1,7 +1,7 @@
/*
EnergyMech, IRC bot software
Parts Copyright (c) 1997-2009 proton
Parts Copyright (c) 1997-2025 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
@ -53,10 +53,12 @@ int find_setting(const char *name)
{
int i;
for(i=0;VarName[i].name;i++)
for(i=0;i<SIZE_VARS;i++)
{
if (!stringcasecmp(name,VarName[i].name))
return(i);
/* 223 = binary 11011111 -> convert lower case to upper */
if ((*name & 223) == *VarName[i].name)
if (stringcasecmp(name,VarName[i].name) == 0)
return(i);
}
return(-1);
}
@ -86,8 +88,10 @@ void set_binarydefault(UniVar *dst)
{
int i;
for(i=0;VarName[i].name;i++)
for(i=0;i<SIZE_VARS;i++)
{
dst[i].str_var = VarName[i].v.str;
}
}
void delete_vars(UniVar *vars, int which)
@ -166,9 +170,24 @@ void ec_channels(char *from, const char *to)
}
}
#ifdef HOSTINFO
static void ec_loadavg(char *from, const char *to)
{
double avg;
char avgstr[8];
getloadavg(&avg,1);
snprintf(avgstr,8,"%.0f%%",100*avg);
avgstr[4] = 0;
nobo_strcpy(avgstr);
}
#endif /* HOSTINFO */
void ec_time(char *from, const char *to)
{
nobo_strcpy(time2away(now));
nobo_strcpy(maketimestr(cx.now,TFMT_AWAY));
}
void ec_set(char *from, const char *to)
@ -242,7 +261,7 @@ void ec_set(char *from, const char *to)
void ec_on(char *from, const char *to)
{
nobo_strcpy(idle2str(now - current->ontime,FALSE));
nobo_strcpy(idle2str(current->ontime,FALSE));
}
void ec_server(char *from, const char *to)
@ -259,7 +278,7 @@ void ec_server(char *from, const char *to)
void ec_up(char *from, const char *to)
{
nobo_strcpy(idle2str(now - uptime,FALSE));
nobo_strcpy(idle2str(uptime,FALSE));
}
void ec_ver(char *from, const char *to)
@ -277,7 +296,7 @@ void ec_guid(char *from, const char *to)
nobo_strcpy(tmp);
}
LS const struct
static const struct
{
void (*func)(char *, const char *);
char name[12];
@ -285,17 +304,23 @@ LS const struct
} ecmd[] =
{
/*
* Sorted by the second parameter alphabetical
*/
{ ec_access, "$access", 7 },
{ ec_capabilities, "$cap", 4 },
{ ec_cc, "$cc", 3 },
{ ec_channels, "$channels", 9 },
{ ec_time, "$time", 5 },
{ ec_set, "$var(", 5 },
{ ec_guid, "$guid", 5 },
#ifdef HOSTINFO
{ ec_loadavg, "$load", 5 },
#endif /* HOSTINFO */
{ ec_on, "$on", 3 },
{ ec_server, "$server", 7 },
{ ec_time, "$time", 5 },
{ ec_up, "$up", 3 },
{ ec_set, "$var(", 5 },
{ ec_ver, "$ver", 4 },
{ ec_guid, "$guid", 5 },
{ NULL, "", 0 },
};
@ -382,6 +407,7 @@ void do_set(COMMAND_ARGS)
/*
* empty args, its "set" or "set #channel"
* list setting and values
*/
if (!name)
{
@ -463,6 +489,10 @@ second_pass:
if ((which = find_setting(name)) == -1)
{
set_usage:
#ifdef DEBUG
if (from == cx.CoreUser.name)
debug("init: set error: %s\n",nullstr(name));
#endif
usage(from); /* usage for CurrentCmd->name */
return;
}
@ -573,6 +603,9 @@ num_data_ok:
}
to_user(from,"Var: %s On: %s Set to: %s",VarName[which].name,
(which >= CHANSET_SIZE) ? "(global)" : channel,(*rest) ? rest : NULLSTR);
if (VarName[which].func)
VarName[which].func(&VarName[which]);
/*
* if there is an onchange function
*/
if (VarName[which].onchangefunc)
VarName[which].onchangefunc(&VarName[which]);
}

View File

@ -35,9 +35,9 @@
#define WEBROOT "web/"
LS WebSock *weblist;
WebSock *weblist;
LS WebDoc docraw = { NULL, NULL, &web_raw };
WebDoc docraw = { NULL, NULL, &web_raw };
#if 0
{
@ -45,7 +45,7 @@ LS WebDoc docraw = { NULL, NULL, &web_raw };
};
#endif
LS WebDoc doclist[] =
WebDoc doclist[] =
{
{ NULL, "/internalstatus.html", &web_botstatus },
#ifdef DEBUG
@ -125,7 +125,7 @@ char *webread(int s, char *rest, char *line)
return(NULL);
}
#define NOBO if (dest == &mem[MSGLEN-2]) { int n; n = write(s,mem,dest-mem); dest = mem; }
#define NOBO if (dest == &mem[MSGLEN-2]) { int _n_ __notused__; _n_ = write(s,mem,dest-mem); dest = mem; }
void eml_fmt(WebSock *client, char *format)
{
@ -133,7 +133,7 @@ void eml_fmt(WebSock *client, char *format)
char *src,*dest,*org;
int out;
int s = client->sock;
int n;
int n __notused__;
org = NULL;
out = TRUE;
@ -165,7 +165,7 @@ restart:
client->echan = (client->ebot) ? client->ebot->chanlist : NULL;
break;
case 'b':
src = (client->ebot) ? client->ebot->nick : (char*)NULLSTR;
src = (client->ebot) ? getbotnick(client->ebot) : (char*)NULLSTR;
while(*src)
{
NOBO;
@ -241,7 +241,7 @@ void web_raw(WebSock *client, char *url)
char path[MSGLEN];
char *src,*dest;
ino_t ino;
int fd,eml,n;
int fd,eml,n __notused__;
size_t sz;
eml = (matches("*.html",url)) ? TRUE : FALSE;
@ -328,7 +328,7 @@ void web_botstatus(WebSock *client, char *url)
"<h1>EnergyMech Status</h1>\r\n"
"Uptime: %s<br><br>\r\n"
"<u>Current bots</u>:<br>\r\n",
idle2str(now - uptime,FALSE));
idle2str(uptime,FALSE));
for(;bot;bot=bot->next)
{
@ -474,7 +474,7 @@ void process_web(void)
new = (WebSock*)Calloc(sizeof(WebSock));
new->sock = s;
new->status = WEB_WAITURL;
new->when = now;
new->when = cx.now;
new->next = weblist;
weblist = new;
}