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/mcmd.h
src/usercombo.h src/usercombo.h
src/githash.h src/githash.h
src/hashdata.cache
trivia/*.index trivia/*.index
# compiled files # compiled files
@ -32,14 +33,21 @@ trivia/megatrivia.txt
*.stats *.stats
# developer files # developer files
dev/*
.use_size .use_size
.use_warn
conf conf
debug* debug*
src/musl.c src/benchmark*
src/nostdlib src/nostdlib
src/x src/x
src/y src/y
src/z src/z
x
y
z
randdata randdata
test.conf test.conf
postfix.sh 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... Very necessary to include if you are a developer...
--- Dynamic channel limit (+l) --- 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 --- Dynamic command levels support
Permit altering at runtime the access level needed to use commands. Including
the possibility to disable commands.
--- Greet support --- Greet support
--- HTTP server 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 --- Host info support
Include features to monitor the server that the energymech runs on.
--- IRC proxy support --- IRC proxy support
--- IRCD extensions support --- IRCD extensions support
BETA code. Support for non-standard IRC server features.
--- Newbie support --- Newbie support
Extra safeguards and messages for beginners.
--- Note support --- Note support
--- Notify support --- Notify support
--- Password hashing with MD5 --- Password hashing with MD5
Encrypt user passwords with md5.
--- Password hashing with SHA --- Password hashing with SHA
Encrypt user passwords with sha1 or sha512.
--- Scripting with Python --- Scripting with Python
--- Scripting with Tcl --- Scripting with Tcl
--- Seen support --- Seen support
--- Session support --- Session support
--- Statistics support --- Statistics support
--- Telnet support --- Telnet support
Support for connecting to the energymech partyline with telnet/netcat.
--- Trivia support --- Trivia support
--- Toybox fun and games --- Toybox fun and games
--- Uptime support --- Uptime support
Send bot uptime packets to the bot uptime tracker (https://www.eggheads.org/uptime)
--- URL capture support --- URL capture support
--- WinGate support --- WinGate support
Ancient tech. Support for wingate proxy.

View File

@ -17,52 +17,55 @@
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
# #
MISCFILES = CREDITS FEATURES LICENSE README README.TCL TODO VERSIONS VERSIONS-2.x Makefile configure \ MISCFILES = CREDITS FEATURES LICENSE README README.TCL TODO VERSIONS VERSIONS-2.x Makefile \
checkmech sample.conf sample.py sample.tcl sample.userfile default.bigchars public/README trivia/README 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 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 \ HELPFILES = help/8BALL help/ACCESS help/ALIAS help/AWAY help/BAN help/BANLIST help/BOOT \
help/CCHAN help/CHACCESS help/CHANBAN help/CHANNELS help/CHAT help/CLEARSHIT \ help/BYE help/CCHAN help/CHACCESS help/CHANBAN help/CHANNELS help/CHAT \
help/CMD help/CORE help/CSERV help/CTCP help/CYCLE help/DEOP help/DIE \ help/CLEARSHIT help/CMD help/CORE help/CSERV help/CTCP help/CYCLE help/DEBUG \
help/DNS help/DNSSERVER help/DO help/DOWN help/ECHO help/ESAY help/FEATURES \ help/DEOP help/DIE help/DNS help/DNSSERVER help/DO help/DOWN help/ECHO \
help/FORGET help/GREET help/HELP help/IDLE help/INSULT help/INVITE help/JOIN help/KB \ help/ESAY help/FEATURES help/FORGET help/GREET help/HELP help/IDLE help/INSULT \
help/KICK help/KS help/LAST help/LEVELS help/LINK help/LOAD help/LUSERS help/ME \ help/INVITE help/JOIN help/KB help/KICK help/KS help/LAST help/LEVELS help/LINK \
help/MODE help/MSG help/NAMES help/NEXTSERVER help/NICK help/NOTIFY help/ONTIME \ help/LOAD help/LUSERS help/ME help/MODE help/MSG help/NAMES help/NEXTSERVER \
help/OP help/PART help/PASSWD help/PROTECTION help/PYTHON help/PYTHONSCRIPT \ help/NICK help/NOTE help/NOTIFY help/ONTIME help/OP help/PART help/PASSWD \
help/QSHIT help/RESET help/RKS help/RSHIT help/RSPY help/RT help/SAVE help/SAY \ help/PROTECTION help/PYTHON help/PYTHONSCRIPT help/QSHIT help/RAND help/READ \
help/SCREW help/SEEN help/SERVER help/SERVERGROUP help/SET help/SETAAWAY \ help/RESET help/RKS help/RSHIT help/RSPY help/RT help/SAVE help/SAY help/SCREW \
help/SETAOP help/SETAUB help/SETAVOICE help/SETCC help/SETCHANBAN help/SETCKL \ help/SEEN help/SERVER help/SERVERGROUP help/SET help/SETAAWAY help/SETAOP \
help/SETDCC help/SETENFM help/SETENFMODES help/SETENFPASS help/SETFL help/SETFPL \ help/SETAUB help/SETAVOICE help/SETCC help/SETCHANBAN help/SETCKL help/SETDCC \
help/SETIKT help/SETKS help/SETMAL help/SETMBL help/SETMDL help/SETMKL \ help/SETENFM help/SETENFMODES help/SETENFPASS help/SETFL help/SETFPL help/SETIKT \
help/SETMODES help/SETMPL help/SETNCL help/SETPASS help/SETPROT help/SETPUB \ help/SETKS help/SETMAL help/SETMBL help/SETMDL help/SETMKL help/SETMODES \
help/SETRK help/SETSD help/SETSERVERGROUP help/SETSHIT help/SETSO help/SETSTATS \ help/SETMPL help/SETNCL help/SETPASS help/SETPROT help/SETPUB help/SETRK \
help/SETTOP help/SHIT help/SHITLIST help/SHOWIDLE help/SHUTDOWN help/SITEBAN \ help/SETSD help/SETSERVERGROUP help/SETSHIT help/SETSO help/SETSTATS help/SETTOP \
help/SITEKB help/SPY help/STATS help/TCL help/TCLSCRIPT help/TIME help/TOPIC \ help/SHIT help/SHITLIST help/SHOWIDLE help/SHUTDOWN help/SITEBAN help/SITEKB \
help/UNALIAS help/UNBAN help/UNVOICE help/UP help/UPTIME help/USAGE help/USER \ help/SPY help/STATS help/TCL help/TCLSCRIPT help/TIME help/TOPIC help/UNALIAS \
help/USERHOST help/USERLIST help/VER help/VERIFY help/VOICE help/WALL help/WHO \ help/UNBAN help/UNVOICE help/UP help/UPTIME help/USAGE help/USER help/USERHOST \
help/WHOIS help/WHOM 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 \ RANDFILES = common/8ball.txt common/away.txt common/insult.txt \
messages/kick.txt messages/nick.txt messages/pickup.txt \ common/kick.txt common/nick.txt common/pickup.txt \
messages/say.txt messages/signoff.txt messages/version.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 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 \ TESTFILES = config/cc.c config/endian.c config/inet_addr.c config/inet_aton.c config/ldtest.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 \ 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 config/unaligned.c config/which
TRIVFILES = trivia/mkindex.c 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 \ SRCFILES = src/alias.c src/auth.c src/bounce.c src/calc.c src/channel.c src/core.c src/ctcp.c \
src/function.c src/gencmd.c src/greet.c src/help.c src/hostinfo.c src/irc.c src/main.c \ src/debug.c src/dns.c src/function.c src/gencmd.c src/greet.c src/help.c src/hostinfo.c \
src/net.c src/note.c src/ons.c src/parse.c src/partyline.c src/perl.c src/prot.c \ src/irc.c src/main.c src/net.c src/note.c src/ons.c src/parse.c src/partyline.c \
src/python.c src/reset.c src/seen.c src/shit.c src/io.c src/spy.c src/tcl.c \ src/perl.c src/prot.c src/python.c src/reset.c src/seen.c src/shit.c src/io.c \
src/toybox.c src/uptime.c src/user.c src/vars.c src/web.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 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 CONFFILES = src/Makefile src/config.h
@ -86,14 +89,18 @@ clean:
install: install:
$(MAKE) -C src install $(MAKE) -C src install
test -x postfix.sh && ./postfix.sh @if [ -x test ]; then \
./postfix.sh; \
fi
mega: mega:
$(MAKE) -C src mega $(MAKE) -C src mega
mega-install: mega-install mi:
$(MAKE) -C src mega-install $(MAKE) -C src mega-install
test -x postfix.sh && ./postfix.sh @if [ -x test ]; then \
./postfix.sh; \
fi
# #
# code validation tests # 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: 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 - Toybox hangman game
- Support for MD5 and SHA enabled at the same time for compatibility/fallback - 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) - DalNet Nickserv/Chanserv support (needed? they dont tolerate much bots on that network /proton)
- Update/complete the help files. - 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. - 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, * 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! 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 <netinet/in.h>
#include <arpa/inet.h> #include <arpa/inet.h>
#include <stdio.h>
#include <string.h>
int main(int argc, char **argv) int main(int argc, char **argv)
{ {
struct in_addr ia; struct in_addr ia;
ia.s_addr = inet_addr("0.0.0.0"); 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); return(0);
} }

1
config/sha512.c Symbolic link
View File

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

147
configure vendored
View File

@ -24,6 +24,8 @@ compile=no
install=no install=no
silentopt=no silentopt=no
try_libmusl=no try_libmusl=no
no_flto=no
use_fnostrictalias=no
# default optimization goal, speed = -O2, size = -Os # default optimization goal, speed = -O2, size = -Os
optitype=size optitype=size
@ -103,7 +105,6 @@ do
dyncmd ) ft_dyncmd=$yesno ;; dyncmd ) ft_dyncmd=$yesno ;;
greet ) ft_greet=$yesno ;; greet ) ft_greet=$yesno ;;
hostinfo ) ft_hostinfo=$yesno ;; hostinfo ) ft_hostinfo=$yesno ;;
idwrap ) ft_idwrap=$yesno ;;
ircd_ext ) ft_ircd_ext=$yesno ;; ircd_ext ) ft_ircd_ext=$yesno ;;
libmusl ) try_libmusl=$yesno ;; libmusl ) try_libmusl=$yesno ;;
md5 ) ft_md5=$yesno ;; md5 ) ft_md5=$yesno ;;
@ -154,7 +155,7 @@ do
esac esac
case "$feature" in 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 \ | netcfg | newbie | note | notify | perl | profiling | python | rawdns | redirect | seen | session | sha | stats | suppress | tcl \
| telnet | toybox | trivia | uptime | urlcapture | web | wingate ) | telnet | toybox | trivia | uptime | urlcapture | web | wingate )
case _"$optarg"_ in case _"$optarg"_ in
@ -206,8 +207,6 @@ do
greet_no ) ft_greet=no ;; greet_no ) ft_greet=no ;;
hostinfo_yes | hostinfo_ ) ft_hostinfo=yes ;; hostinfo_yes | hostinfo_ ) ft_hostinfo=yes ;;
hostinfo_no ) ft_hostinfo=no ;; 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_yes | ircd_ext_ ) ft_ircd_ext=yes ;;
ircd_ext_no ) ft_ircd_ext=no ;; ircd_ext_no ) ft_ircd_ext=no ;;
libmusl_yes | libmusl_ ) try_libmusl=/usr/local/musl/bin/musl-gcc ;; libmusl_yes | libmusl_ ) try_libmusl=/usr/local/musl/bin/musl-gcc ;;
@ -273,7 +272,6 @@ do
dyncmd ) ft_dyncmd=no ;; dyncmd ) ft_dyncmd=no ;;
greet ) ft_greet=no ;; greet ) ft_greet=no ;;
hostinfo ) ft_hostinfo=no ;; hostinfo ) ft_hostinfo=no ;;
idwrap ) ft_idwrap=no ;;
ircd_ext ) ft_ircd_ext=no ;; ircd_ext ) ft_ircd_ext=no ;;
libmusl ) try_libmusl=no ;; libmusl ) try_libmusl=no ;;
md5 ) ft_md5=no ;; md5 ) ft_md5=no ;;
@ -306,12 +304,15 @@ do
--silence=options) silentopt=yes ;; --silence=options) silentopt=yes ;;
--md5=internal) ft_md5=internal ;; --md5=internal) ft_md5=internal ;;
--sha=internal) ft_sha=internal ;; --sha=internal) ft_sha=internal ;;
--sha=internal512) ft_sha=internal512 ;;
--use-cpuflags) cc_arch_opt=yes ;; --use-cpuflags) cc_arch_opt=yes ;;
--no-cpuflags) cc_arch_opt=no ;; --no-cpuflags) cc_arch_opt=no ;;
--use-optimize) cc_optimize_opt=yes ;; --use-optimize) cc_optimize_opt=yes ;;
--no-optimize) cc_optimize_opt=no ;; --no-optimize) cc_optimize_opt=no ;;
--optimize=speed) optitype=speed ;; --optimize=speed) optitype=speed ;;
--optimize=size) optitype=size ;; --optimize=size) optitype=size ;;
--use-nostrictalias) use_fnostrictalias=yes ;;
--no-nostrictalias) use_fnostrictalias=no ;;
--use-gnudebug) cc_g_opt=yes ;; --use-gnudebug) cc_g_opt=yes ;;
--no-gnudebug) cc_g_opt=no ;; --no-gnudebug) cc_g_opt=no ;;
--use-warnflag) cc_wall_opt=yes ;; --use-warnflag) cc_wall_opt=yes ;;
@ -320,6 +321,8 @@ do
--no-pipeflag) cc_pipe_opt=no ;; --no-pipeflag) cc_pipe_opt=no ;;
--use-ofp) cc_ofp_opt=yes ;; --use-ofp) cc_ofp_opt=yes ;;
--no-ofp) cc_ofp_opt=no ;; --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-yes) ft_default=yes set_feature_defaults ;;
--default-no) ft_default=no set_feature_defaults ;; --default-no) ft_default=no set_feature_defaults ;;
--help | -h) --help | -h)
@ -338,6 +341,8 @@ Features and packages:
--sha=internal Use internal routines for SHA password hashes instead of system libraries --sha=internal Use internal routines for SHA password hashes instead of system libraries
--use-ofp Try to use compiler flag -fomit-frame-pointer --use-ofp Try to use compiler flag -fomit-frame-pointer
--no-ofp Do not 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-alias ALIAS support
--with-botnet Botnet support --with-botnet Botnet support
--with-bounce --with-bounce
@ -557,7 +562,7 @@ cf_cflags=
if [ -n "$CFLAGS" ]; then if [ -n "$CFLAGS" ]; then
if $CC $CFLAGS -c -o $TESTO $TESTC 1> /dev/null 2> /dev/null && test -r $TESTO; then if $CC $CFLAGS -c -o $TESTO $TESTC 1> /dev/null 2> /dev/null && test -r $TESTO; then
cf_cflags="$CFLAGS" cf_cflags="$CFLAGS"
echo $ac_n "$CFLAGS "$ac_c echo $ac_n "$CFLAGS (from environment CFLAGS) "$ac_c
fi fi
fi fi
@ -589,7 +594,7 @@ if [ -z "$cf_cflags" -a -n "$cf_GNUCC" ]; then
fi fi
fi 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" cc_fnostrictalias="-fno-strict-aliasing"
echo $ac_n "-fno-strict-aliasing "$ac_c echo $ac_n "-fno-strict-aliasing "$ac_c
fi fi
@ -627,6 +632,9 @@ if [ -z "$cf_cflags" -a -n "$cf_GNUCC" ]; then
fi fi
fi fi
#
# test for -pipe flag
#
if [ -z "$cf_cflags" -a -z "$cc_pipe_opt" ]; then 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 if $CC -pipe -c -o $TESTO $TESTC 1> /dev/null 2> /dev/null && test -r $TESTO; then
cc_pipe_flag="-pipe" cc_pipe_flag="-pipe"
@ -634,6 +642,20 @@ if [ -z "$cf_cflags" -a -z "$cc_pipe_opt" ]; then
fi fi
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" oflag="-O2"
if [ "$optitype" = size ]; then if [ "$optitype" = size ]; then
oflag="-Os" oflag="-Os"
@ -652,6 +674,14 @@ if [ -z "$cf_cflags" -a -z "$cc_optimize_opt" ]; then
fi fi
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 "" echo $ac_t ""
if [ "$ft_prof" = yes ]; then if [ "$ft_prof" = yes ]; then
@ -677,6 +707,20 @@ fi
rm -f $TESTO $TESTP 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? # 32bit? 64bit?
# #
@ -690,8 +734,12 @@ if [ -z "$ptr_size" ]; then
if [ -x $TESTP ]; then if [ -x $TESTP ]; then
ptr_size=`$TESTP` ptr_size=`$TESTP`
fi fi
if [ "$ptr_size" = 8 ]; then
echo $ac_t "64 bit"
else
echo $ac_t "$ptr_size" echo $ac_t "$ptr_size"
fi fi
fi
case _"$ptr_size"_ in case _"$ptr_size"_ in
_8_ ) _8_ )
@ -798,6 +846,17 @@ else
fi fi
fi fi
echo $ac_t "$has_inet_addr" 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 rm -f $TESTP
# #
@ -853,20 +912,37 @@ if [ ! "$ft_sha" = no ]; then
TESTC=config/pw.c TESTC=config/pw.c
echo $ac_n "checking for SHA in crypt() ... "$ac_c echo $ac_n "checking for SHA in crypt() ... "$ac_c
sha_internal= sha_internal=
sha_object=
crypt_func='-DCRYPT_FUNC=crypt' crypt_func='-DCRYPT_FUNC=crypt'
CRYPT_FUNCTION='#define CRYPT_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 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_func='-DCRYPT_FUNC=sha_crypt'
CRYPT_FUNCTION='#define CRYPT_FUNC sha_crypt' CRYPT_FUNCTION='#define CRYPT_FUNC sha_crypt'
fi fi
$CC -o $TESTP $TESTC $sha_internal $crypt_func 1> /dev/null 2> /dev/null #
if [ ! -x $TESTP ]; then 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 libcrypt=-lcrypt
has_sha=yes has_sha=yes
$CC -o $TESTP $TESTC $crypt_func $libcrypt 1> /dev/null 2> /dev/null $CC -o $TESTP $TESTC $crypt_func $libcrypt 1> /dev/null 2> /dev/null
fi fi
if [ ! -x $TESTP ]; then if [ ! -x $TESTP ]; then
crypt_func='-DCRYPT_FUNC=crypt'
CRYPT_FUNCTION='#define CRYPT_FUNC crypt'
libcrypt=/usr/lib/libcrypt.so libcrypt=/usr/lib/libcrypt.so
has_sha=yes has_sha=yes
$CC -o $TESTP $TESTC $crypt_func $libcrypt 1> /dev/null 2> /dev/null $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 if [ -x $TESTP ]; then
pwhash=`$TESTP` pwhash=`$TESTP`
case "$pwhash" in case "$pwhash" in
SHA512 ) has_sha=internal512 ;;
MD5 ) has_md5=yes ;; MD5 ) has_md5=yes ;;
SHA ) has_sha=yes ;;
SHAMD5 ) SHAMD5 )
has_md5=yes has_md5=yes
has_sha=yes has_sha=yes
@ -887,9 +965,8 @@ if [ ! "$ft_sha" = no ]; then
fi fi
echo $ac_t "$has_sha" echo $ac_t "$has_sha"
[ "$has_sha" = yes -a "$sha_internal" ] && has_sha=internal [ "$has_sha" = yes -a "$sha_internal" ] && has_sha=internal
rm -f $TESTP rm -f $TESTP $sha_object
fi fi
# #
# check for MD5 capabilities in libc/glibc/libcrypt # check for MD5 capabilities in libc/glibc/libcrypt
# #
@ -898,13 +975,13 @@ if [ "$has_md5" = yes ]; then
elif [ "$ft_md5" = no ]; then elif [ "$ft_md5" = no ]; then
has_md5=notest has_md5=notest
elif [ ! "$ft_md5" = no ]; then elif [ ! "$ft_md5" = no ]; then
TESTC=config/pw.c
echo $ac_n "checking for MD5 in crypt() ... "$ac_c echo $ac_n "checking for MD5 in crypt() ... "$ac_c
TESTC=config/pw.c
md5_internal= md5_internal=
crypt_func='-DCRYPT_FUNC=crypt' crypt_func='-DCRYPT_FUNC=crypt'
CRYPT_FUNCTION='#define CRYPT_FUNC crypt' CRYPT_FUNCTION='#define CRYPT_FUNC crypt'
if [ "$ft_md5" = internal ]; then if [ "$ft_md5" = internal ]; then
md5_internal=config/md5_internal.c md5_internal=config/md5.c
crypt_func='-DCRYPT_FUNC=md5_crypt' crypt_func='-DCRYPT_FUNC=md5_crypt'
CRYPT_FUNCTION='#define CRYPT_FUNC md5_crypt' CRYPT_FUNCTION='#define CRYPT_FUNC md5_crypt'
fi fi
@ -1058,26 +1135,6 @@ fi
echo $ac_t "$has_ldscript" echo $ac_t "$has_ldscript"
rm -f $TESTP 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= SHA_O=
if [ "$ft_sha" = internal ]; then if [ "$ft_sha" = internal ]; then
SHA_C=lib/sha1.c 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 fi
out=echo out=echo
@ -1306,7 +1367,7 @@ if [ "$has_sha" = no ]; then
else else
test "$ft_sha" && $out "$ft_sha" && ans=$ft_sha test "$ft_sha" && $out "$ft_sha" && ans=$ft_sha
test -z "$ft_sha" && read ans 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 fi
def_perl='#undef PERL' 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 "$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' 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 unset ans
$out $ac_n "[ BETA ] URL capture support? ....................... [Y/n] "$ac_c $out $ac_n "[ BETA ] URL capture support? ....................... [Y/n] "$ac_c
test "$ft_urlcapture" && $out "$ft_urlcapture" && ans=$ft_urlcapture test "$ft_urlcapture" && $out "$ft_urlcapture" && ans=$ft_urlcapture
test -z "$ft_urlcapture" && read ans 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' def_wingate='#undef WINGATE'
unset ans unset ans
@ -1422,7 +1483,7 @@ test -z "$ans" -o "$ans" = y -o "$ans" = Y -o "$ans" = yes -o "$ans" = YES -o "$
$out '' $out ''
echo "Creating src/Makefile" 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" W_FLAGS="$cc_wall_flag $cc_wshadow_flag $cc_fnostrictalias"
libflags="$libcrypt $libtcl $libnsl $libsocket $libresolv $libpython $libperl" libflags="$libcrypt $libtcl $libnsl $libsocket $libresolv $libpython $libperl"
lflags="$cc_g_flag -o" lflags="$cc_g_flag -o"
@ -1430,7 +1491,7 @@ cprof="$cc_pg_flag $cc_pg_define"
lprof="$cc_pg_flag $cc_pg_define $libpgdl" lprof="$cc_pg_flag $cc_pg_define $libpgdl"
if [ -z "$cf_cflags" ]; then if [ -z "$cf_cflags" ]; then
cf_cflags='$(PIPEFLAG) $(GDBFLAG) $(WARNFLAG) $(OPTIMIZE)' cf_cflags='$(PIPEFLAG) $(GDBFLAG) $(FLTO_FLAG) $(WARNFLAG) $(OPTIMIZE)'
fi fi
echo '# This file is generated from Makefile.in' > src/Makefile echo '# This file is generated from Makefile.in' > src/Makefile
@ -1439,6 +1500,7 @@ s%@CC@%$CCshort%;
s%@ldscript@%$ldscript%; s%@ldscript@%$ldscript%;
s%@pipeflag@%$cc_pipe_flag%; s%@pipeflag@%$cc_pipe_flag%;
s%@gdbflag@%$cc_g_flag%; s%@gdbflag@%$cc_g_flag%;
s%@flto_flag@%$cc_flto_flag%;
/@cprof@/ { s,@cprof@,$cprof,; }; /@cprof@/ { s,@cprof@,$cprof,; };
/@lprof@/ { s,@lprof@,$lprof,; }; /@lprof@/ { s,@lprof@,$lprof,; };
/@lflags@/ { s,@lflags@,$lflags,; }; /@lflags@/ { s,@lflags@,$lflags,; };
@ -1482,7 +1544,6 @@ sed "
s|@DEF_DYNAMODE@|$def_dynamode|; s|@DEF_DYNAMODE@|$def_dynamode|;
s|@DEF_GREET@|$def_greet|; s|@DEF_GREET@|$def_greet|;
s|@DEF_HOSTINFO@|$def_hostinfo|; s|@DEF_HOSTINFO@|$def_hostinfo|;
s|@DEF_IDWRAP@|$def_idwrap|;
s|@DEF_IRCD_EXT@|$def_ircd_ext|; s|@DEF_IRCD_EXT@|$def_ircd_ext|;
s|@DEF_MD5@|$def_md5|; s|@DEF_MD5@|$def_md5|;
s|@DEF_SHA@|$def_sha|; s|@DEF_SHA@|$def_sha|;
@ -1503,7 +1564,7 @@ s|@DEF_SUPPRESS@|$def_suppress|;
s|@DEF_TOYBOX@|$def_toybox|; s|@DEF_TOYBOX@|$def_toybox|;
s|@DEF_TRIVIA@|$def_trivia|; s|@DEF_TRIVIA@|$def_trivia|;
s|@DEF_UPTIME@|$def_uptime|; s|@DEF_UPTIME@|$def_uptime|;
s|@DEF_URLCAPTURE@|$def_urlcapture|; s|@DEF_URLCAP@|$def_urlcap|;
s|@DEF_WEB@|$def_web|; s|@DEF_WEB@|$def_web|;
s|@DEF_WINGATE@|$def_wingate|; 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_SHA@|$CRYPT_HAS_SHA|;
s|@CRYPT_HAS_MD5@|$CRYPT_HAS_MD5|; s|@CRYPT_HAS_MD5@|$CRYPT_HAS_MD5|;
s|@CRYPT_HAS_DES@|$CRYPT_HAS_DES|; s|@CRYPT_HAS_DES@|$CRYPT_HAS_DES|;
s|@IDWRAP_PATH@|$IDWRAP_PATH|;
s|@PTSIZE_DEFINE32@|$PTSIZE_DEFINE32|; s|@PTSIZE_DEFINE32@|$PTSIZE_DEFINE32|;
s|@PTSIZE_DEFINE64@|$PTSIZE_DEFINE64|; s|@PTSIZE_DEFINE64@|$PTSIZE_DEFINE64|;
s|@UNALIGNED_MEM@|$UNALIGNED_MEM|; s|@UNALIGNED_MEM@|$UNALIGNED_MEM|;
" < src/config.h.in >> src/config.h " < src/config.h.in >> src/config.h
save_myconfig() { 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 netcfg newbie note notify perl profiling python rawdns redirect seen session sha stats suppress tcl
telnet toybox trivia uptime urlcapture web wingate" telnet toybox trivia uptime urlcapture web wingate"
echo "./configure \\" > ./myconfig echo "./configure \\" > ./myconfig
@ -1539,6 +1599,7 @@ save_myconfig() {
test "$silentopt" = yes && echo "--silence=options \\" >> ./myconfig test "$silentopt" = yes && echo "--silence=options \\" >> ./myconfig
test "$ft_md5" = internal && echo "--md5=internal \\" >> ./myconfig test "$ft_md5" = internal && echo "--md5=internal \\" >> ./myconfig
test "$ft_sha" = internal && echo "--sha=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" = speed && echo "--optimize=speed \\" >> ./myconfig
test "$optitype" = size && echo "--optimize=size \\" >> ./myconfig test "$optitype" = size && echo "--optimize=size \\" >> ./myconfig
test "$cc_ofp_opt" = yes && echo "--use-ofp \\" >> ./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 to replace built in commands. Aliases can recurse a
maximum of 20 times (prevents infinite loops). maximum of 20 times (prevents infinite loops).
If no argument is given, all current aliases will be listed.
See also: unalias 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 for all bots. If DIE is used, the killed bot(s) will
not be saved to the session file. 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 Changes the nick of the bot. If the nick given is already
in use, the bot will not change its nickname until the in use, the bot will not change its nickname until the
occupied nick is available. 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. Shows time connected to current server.
See also: UPTIME
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 Removes someone from the shitlist
See also: SHIT, SHITLIST
See also: shit, qshit, shitlist, clearshit

View File

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

View File

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

View File

@ -2,13 +2,15 @@
Spy on a certain source of messages. When you join DCC chat, 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. the STATUS source is added by default as a spy source for you.
If no arguments are given, the current list of active spy If no arguments are given, the current list of active spy
channels is shown. Output is not line buffered and can cause channels is shown.
excess flood if not careful.
(sources) (sources)
STATUS Status messages. STATUS Status messages.
MESSAGE Pivate messages that the bot receives. MESSAGE Pivate messages that the bot receives.
RAWIRC Lines received from irc server before processing. 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. guid: Messages from a bot specified by guid.
botnick: Messages from a bot specified by nick. botnick: Messages from a bot specified by nick.
channel Activities on the specified channel. channel Activities on the specified channel.

View File

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

View File

@ -1,3 +1,4 @@
Usage: UPTIME
Shows how long the bot has been running. Shows how long the bot has been running.
See also: ONTIME
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, Lists people in a channel that the bot is in now,
or was in. The optional parameters can be used to or was in. The optional parameters can be used to
list only ops or only non ops respectively. list only ops or only non ops respectively.
If a pattern is given, only users matching the pattern If a pattern is given, only users matching the pattern
will be listed. will be listed.
See also: NAMES
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 ; We don't currently support SSL or ipv6 but there's an easy workaround
; see socat.sh ; see socat.sh
servergroup undernet ; Use only undernet servers
server amsterdam.nl.eu.undernet.org 6663 set servergroup undernet
server amsterdam2.nl.eu.undernet.org 6663
server bucharest.ro.eu.undernet.org 6663 ; Our list of servers
server carouge.ch.eu.undernet.org 6663 ; server <host> [port] [@group] ["password"]
server ede.nl.eu.undernet.org 6669 ;
server elsene.be.eu.undernet.org 6669 server amsterdam.nl.eu.undernet.org 6663 @undernet
server fulda.de.eu.undernet.org 6663 server amsterdam2.nl.eu.undernet.org 6663 @undernet
server geneva.ch.eu.undernet.org 6663 server bucharest.ro.eu.undernet.org 6663 @undernet
server graz.at.eu.undernet.org 6663 server carouge.ch.eu.undernet.org 6663 @undernet
server graz2.at.eu.undernet.org 6663 server ede.nl.eu.undernet.org 6669 @undernet
server helsinki.fi.eu.undernet.org 6669 server elsene.be.eu.undernet.org 6669 @undernet
server lelystad.nl.eu.undernet.org 6668 server fulda.de.eu.undernet.org 6663 @undernet
server london.uk.eu.undernet.org 6666 server geneva.ch.eu.undernet.org 6663 @undernet
server london2.uk.eu.undernet.org 6663 server graz.at.eu.undernet.org 6663 @undernet
server milan.it.eu.undernet.org 6663 server graz2.at.eu.undernet.org 6663 @undernet
server oslo1.no.eu.undernet.org 6663 server helsinki.fi.eu.undernet.org 6669 @undernet
server oslo2.no.eu.undernet.org 6663 server lelystad.nl.eu.undernet.org 6668 @undernet
server stockholm.se.eu.undernet.org 6669 server london.uk.eu.undernet.org 6666 @undernet
server surrey.uk.eu.undernet.org 6669 server london2.uk.eu.undernet.org 6663 @undernet
server zagreb.hr.eu.undernet.org 6666 server milan.it.eu.undernet.org 6663 @undernet
server panamacity.pa.undernet.org 6663 server oslo1.no.eu.undernet.org 6663 @undernet
server ashburn.va.us.undernet.org 6663 server oslo2.no.eu.undernet.org 6663 @undernet
server fairfax.va.us.undernet.org 6666 server stockholm.se.eu.undernet.org 6669 @undernet
server mesa.az.us.undernet.org 6666 server surrey.uk.eu.undernet.org 6669 @undernet
server miami.fl.us.undernet.org 6669 server zagreb.hr.eu.undernet.org 6666 @undernet
server princeton.nj.us.undernet.org 6663 server panamacity.pa.undernet.org 6663 @undernet
server sanjose.ca.us.undernet.org 6663 server ashburn.va.us.undernet.org 6663 @undernet
server sterling.va.us.undernet.org 6669 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... ; this is sorta how a botnet configuration would look like...

View File

@ -1,5 +1,5 @@
#!/bin/bash #!/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 # Run it before running energymech
# Listen port. In the energymech config put 'server localhost 6003' # Listen port. In the energymech config put 'server localhost 6003'

View File

@ -1,6 +1,6 @@
# #
# EnergyMech, IRC bot software # 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 # 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 # it under the terms of the GNU General Public License as published by
@ -27,6 +27,7 @@ LPROF = @lprof@
LIBS = @libflags@ LIBS = @libflags@
PIPEFLAG = @pipeflag@ PIPEFLAG = @pipeflag@
GDBFLAG = @gdbflag@ GDBFLAG = @gdbflag@
FLTO_FLAG = @flto_flag@
WARNFLAG = @W_FLAGS@ WARNFLAG = @W_FLAGS@
OPTIMIZE = @O_FLAGS@ OPTIMIZE = @O_FLAGS@
PYINCLUDE = @PYINCLUDE@ PYINCLUDE = @PYINCLUDE@
@ -35,7 +36,7 @@ I_PERL = @I_PERL@
L_PERL = @L_PERL@ L_PERL = @L_PERL@
CFLAGS = @CFLAGS@ CFLAGS = @CFLAGS@
LFLAGS = $(PIPEFLAG) $(GDBFLAG) LFLAGS = $(PIPEFLAG) $(GDBFLAG) $(FLTO_FLAG)
CC = @CC@ CC = @CC@
MV = mv -f 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 \ 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 \ 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 \ 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 lib/string.o @MD5_O@ @SHA_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 \ 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 \ 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 \ 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 lib/string.c @MD5_C@ @SHA_C@ uptime.c user.c vars.c web.c @MD5_C@ @SHA_C@
.PHONY: all clean mega-install mega mega-static test commands .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. # 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 $(CC) $(LFLAGS) -o gencmd gencmd.c
mcmd.h: gencmd 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. # 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) $(CHMOD) $(INSTALLMODE) $(INSTALLNAME)
$(MV) $(INSTALLNAME) $(INSTALLDIR) $(MV) $(INSTALLNAME) $(INSTALLDIR)
mega: $(SRCFILES) $(INCS) usage.h mega: $(SRCFILES) $(INCS) usage.h @SHA_O@
$(CROSS_COMPILE)$(CC) $(CFLAGS) -o $(INSTALLNAME) main.c -DMEGA_C -DGENDATE="`./gencmd date`" -I. $(LPROF) $(LIBS) $(LDSCRIPT) $(PYINCLUDE) $(TCLINCLUDE) $(I_PERL) $(L_PERL) $(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) #@oc@ $(CROSS_COMPILE)objcopy -R .note -R .comment $(INSTALLNAME)
@sz@ size $(INSTALLNAME) @sz@ size $(INSTALLNAME)
@ -127,14 +128,14 @@ test: $(TESTFILES)
./calctest ./calctest
./safepathtest ./safepathtest
aliastest: alias.c githash.h lib/string.o aliastest: alias.c githash.h mcmd.h string.o function.o
$(CROSS_COMPILE)$(CC) $(CFLAGS) -o aliastest $< lib/string.o $(LPROF) $(LIBS) -DTEST $(CROSS_COMPILE)$(CC) $(CFLAGS) -o aliastest $< string.o function.o $(LPROF) $(LIBS) -DTEST
calctest: calc.c githash.h mcmd.h lib/string.o calctest: calc.c githash.h mcmd.h string.o
$(CROSS_COMPILE)$(CC) $(CFLAGS) -o calctest $< lib/string.o $(LPROF) $(LIBS) -DTEST $(CROSS_COMPILE)$(CC) $(CFLAGS) -o calctest $< string.o $(LPROF) $(LIBS) -DTEST
safepathtest: function.c githash.h lib/string.o safepathtest: function.c githash.h string.o
$(CROSS_COMPILE)$(CC) $(CFLAGS) -o safepathtest $< lib/string.o $(LPROF) $(LIBS) -DTEST $(CROSS_COMPILE)$(CC) $(CFLAGS) -o safepathtest $< string.o $(LPROF) $(LIBS) -DTEST
commands: commands:
grep -E '(void do_.*\(COMMAND_ARGS\)|/*---Help:)' *c 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) lib/sha1.o: lib/sha1.c $(INCS)
$(CROSS_COMPILE)$(CC) $(CFLAGS) -c $< -o $@ -Ilib $(CPROF) $(CROSS_COMPILE)$(CC) $(CFLAGS) -c $< -o $@ -Ilib $(CPROF)
lib/string.o: lib/string.c $(BASEINCLUDES) lib/sha512.o: lib/sha512.c $(INCS)
$(CROSS_COMPILE)$(CC) $(CFLAGS) -c $< -o $@ -I. $(CPROF) $(CROSS_COMPILE)$(CC) $(CFLAGS) -c $< -o $@ -Ilib $(CPROF)
alias.o: alias.c $(INCS) alias.o: alias.c $(INCS)
$(CROSS_COMPILE)$(CC) $(CFLAGS) -c $< $(CPROF) $(CROSS_COMPILE)$(CC) $(CFLAGS) -c $< $(CPROF)
@ -206,7 +207,7 @@ net.o: net.c $(INCS)
note.o: note.c $(INCS) note.o: note.c $(INCS)
$(CROSS_COMPILE)$(CC) $(CFLAGS) -c $< $(CPROF) $(CROSS_COMPILE)$(CC) $(CFLAGS) -c $< $(CPROF)
ons.o: ons.c $(INCS) ons.o: ons.c $(INCS) onhash.h
$(CROSS_COMPILE)$(CC) $(CFLAGS) -c $< $(CPROF) $(CROSS_COMPILE)$(CC) $(CFLAGS) -c $< $(CPROF)
parse.o: parse.c $(INCS) parse.o: parse.c $(INCS)
@ -236,6 +237,9 @@ shit.o: shit.c $(INCS)
spy.o: spy.c $(INCS) spy.o: spy.c $(INCS)
$(CROSS_COMPILE)$(CC) $(CFLAGS) -c $< $(CPROF) $(CROSS_COMPILE)$(CC) $(CFLAGS) -c $< $(CPROF)
string.o: string.c $(BASEINCLUDES)
$(CROSS_COMPILE)$(CC) $(CFLAGS) -c $< $(CPROF)
tcl.o: tcl.c $(INCS) tcl.o: tcl.c $(INCS)
$(CROSS_COMPILE)$(CC) $(CFLAGS) -c $< $(CPROF) $(TCLINCLUDE) $(CROSS_COMPILE)$(CC) $(CFLAGS) -c $< $(CPROF) $(TCLINCLUDE)

View File

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

View File

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

View File

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

View File

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

View File

@ -40,13 +40,15 @@ void check_idlekick(void)
for(chan=current->chanlist;chan;chan=chan->next) for(chan=current->chanlist;chan;chan=chan->next)
{ {
if (!chan->bot_is_op)
continue;
limit = chan->setting[INT_IKT].int_var; 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) for(cu=chan->users;cu;cu=cu->next)
{ {
cu->flags &= ~CU_KSWARN; /* remove KS warnings */ cu->flags &= ~CU_KSWARN; /* remove KS warnings */
if (!chan->bot_is_op || limit == 0)
continue;
if (cu->flags & CU_CHANOP) if (cu->flags & CU_CHANOP)
continue; continue;
if (timeout < cu->idletime) if (timeout < cu->idletime)
@ -207,9 +209,9 @@ int reverse_mode(char *from, Chan *chan, int m, int s)
mode = (char)m; mode = (char)m;
sign = (char)s; sign = (char)s;
if (STRCHR(ptr,mode) && (sign == '+')) if (stringchr(ptr,mode) && (sign == '+'))
return(FALSE); return(FALSE);
if (!STRCHR(ptr,mode) && (sign == '-')) if (!stringchr(ptr,mode) && (sign == '-'))
return(FALSE); return(FALSE);
if (get_useraccess(from,chan->name) >= ASSTLEVEL) 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) char *find_nuh(char *nick)
{ {
Chan *chan; Chan *chan;
@ -281,6 +289,36 @@ char *find_nuh(char *nick)
return(NULL); 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 *make_ban(Ban **banlist, char *from, char *banmask, time_t when)
{ {
Ban *new; Ban *new;
@ -359,7 +397,7 @@ void channel_massmode(const Chan *chan, char *pattern, int filtmode, char mode,
if ((pat = chop(&pattern)) == NULL) if ((pat = chop(&pattern)) == NULL)
return; return;
ispat = (STRCHR(pat,'*')) ? TRUE : FALSE; ispat = (stringchr(pat,'*')) ? TRUE : FALSE;
maxmode = current->setting[INT_MODES].int_var; maxmode = current->setting[INT_MODES].int_var;
mal = chan->setting[INT_MAL].int_var; mal = chan->setting[INT_MAL].int_var;
*burst = 0; *burst = 0;
@ -376,7 +414,7 @@ void channel_massmode(const Chan *chan, char *pattern, int filtmode, char mode,
s = deopstring; s = deopstring;
while(*s) s++; while(*s) s++;
debug("(...) deopstring "mx_pfmt" uh "mx_pfmt" ("mx_pfmt")\n",(mx_ptr)deopstring,(mx_ptr)uh,(mx_ptr)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); debug("(...) deopstring "mx_pfmt" uh "mx_pfmt" ("mx_pfmt")\n",(mx_ptr)deopstring,(mx_ptr)uh,(mx_ptr)s);
} }
#endif /* DEBUG */ #endif /* DEBUG */
@ -427,7 +465,7 @@ void channel_massmode(const Chan *chan, char *pattern, int filtmode, char mode,
/* /*
* never deop yourself, stupid bot * never deop yourself, stupid bot
*/ */
if (nickcmp(pat,current->nick)) if (nickcmp(pat,getbotnick(current)))
willdo = TRUE; willdo = TRUE;
} }
else else
@ -453,7 +491,7 @@ void channel_massmode(const Chan *chan, char *pattern, int filtmode, char mode,
cu = cu->next; cu = cu->next;
if (!cu && (pat = chop(&pattern))) if (!cu && (pat = chop(&pattern)))
{ {
ispat = (STRCHR(pat,'*')) ? TRUE : FALSE; ispat = (stringchr(pat,'*')) ? TRUE : FALSE;
cu = chan->users; 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 (!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) 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)); new = (ChanUser*)Calloc(sizeof(ChanUser) + strlen(userhost));
/* Calloc sets it all to zero */ /* Calloc sets it all to zero */
new->idletime = now; new->idletime = cx.now;
new->next = CurrentChan->users; new->next = CurrentChan->users;
CurrentChan->users = new; CurrentChan->users = new;
stringcpy(new->userhost,userhost); stringcpy(new->userhost,userhost);
@ -661,12 +699,6 @@ void purge_chanusers(Chan *chan)
remove_chanuser(chan,chan->users->nick); 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 * commands associated with channels
@ -890,9 +922,10 @@ void do_mode(COMMAND_ARGS)
} }
else else
{ {
/* todo: is it really necessary to chop? */
target = chop(&rest); target = chop(&rest);
if (!nickcmp(current->nick,target)) if (!nickcmp(target,getbotnick(current)))
{ {
to_server("MODE %s %s\n",target,rest); to_server("MODE %s %s\n",target,rest);
} }
@ -972,7 +1005,7 @@ void do_cchan(COMMAND_ARGS)
to_user(from,ERR_CHAN,channel); to_user(from,ERR_CHAN,channel);
return; return;
} }
to_user(from,"Current channel: %s", to_user_q(from,"Current channel: %s",
(current->activechan) ? current->activechan->name : TEXT_NONE); (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); 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) for(cu=chan->users;cu;cu=cu->next)
{ {
if (n >= (now - cu->idletime)) if (n >= (cx.now - cu->idletime))
continue; 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); table_send(from,1);
} }
@ -1218,5 +1251,5 @@ void do_idle(COMMAND_ARGS)
to_user(from,TEXT_UNKNOWNUSER,rest); to_user(from,TEXT_UNKNOWNUSER,rest);
return; 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@ @DEF_HOSTINFO@
/*
* IDWRAP: support for idwrap ident spoofing
*/
@DEF_IDWRAP@
#define IDWRAP_PATH @IDWRAP_PATH@
/* /*
* IRCD_EXTENSIONS: support some special features of new ircds * IRCD_EXTENSIONS: support some special features of new ircds
*/ */
@ -103,7 +97,7 @@
@DEF_DCCFILE@ @DEF_DCCFILE@
#define DCC_PUBLICFILES "public/" #define DCC_PUBLICFILES "public/"
#define DCC_PUBLICINCOMING DCC_PUBLICFILES "incoming/" #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 * REDIRECT: send command output from certain commands to a different target
@ -195,7 +189,7 @@
/* /*
* URLCAPTURE: capture url's mentioned * URLCAPTURE: capture url's mentioned
*/ */
@DEF_URLCAPTURE@ @DEF_URLCAP@
/* /*
* WEB: serving documents via HTTP * WEB: serving documents via HTTP
@ -322,8 +316,8 @@
#define AWAYFORM "AWAY :%s (since %s)\n" #define AWAYFORM "AWAY :%s (since %s)\n"
#define KILLSOCKTIMEOUT 30 #define KILLSOCK_TIMEOUT 30
#define WAITTIMEOUT 30 #define WAIT_TIMEOUT 30
#define NICKFLOODTIME 120 /* 240 second window for floods ( 240 / 2 = 120 ) */ #define NICKFLOODTIME 120 /* 240 second window for floods ( 240 / 2 = 120 ) */
@ -361,6 +355,9 @@
#define NAMELEN 79 #define NAMELEN 79
#define NAMEBUF NAMELEN+1 #define NAMEBUF NAMELEN+1
#define SERVERGROUPBUF 16
#define SERVERGROUPLEN SERVERGROUPBUF-1
#define MINPASSCHARS 4 #define MINPASSCHARS 4
#define MAXPASSCHARS 50 #define MAXPASSCHARS 50
@ -400,6 +397,7 @@
#define CBANG 0x040000 /* command may be prefixed with a bang (!) */ #define CBANG 0x040000 /* command may be prefixed with a bang (!) */
#define ACCHAN 0x080000 /* needs an active channel */ #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 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() * integer only version of RANDOM()
@ -604,6 +602,13 @@ const char __mx_opts[] = ""
#undef OPT_COREONLY #undef OPT_COREONLY
#endif /* TRIVIA */ #endif /* TRIVIA */
#ifdef UPTIME
OPT_COMMA "uptime"
#undef OPT_COMMA
#define OPT_COMMA ", "
#undef OPT_COREONLY
#endif /* UPTIME */
#ifdef WINGATES #ifdef WINGATES
OPT_COMMA "wingate" OPT_COMMA "wingate"
#undef OPT_COMMA #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; pspy = &(*pspy)->next;
} }
send_global(SPYSTR_STATUS,"[%s] %s[%i] has disconnected", 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 #ifdef DCC_FILE
if (client->fileno >= 0) if (client->fileno >= 0)
@ -99,7 +99,8 @@ int dcc_sendfile(char *target, char *filename)
{ {
struct sockaddr_in sai; struct sockaddr_in sai;
Client *client; 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. char tempfile[strlen(filename)+strlen(DCC_PUBLICFILES)+2]; // strlen(DCC_PUBLICFILES) evaluates at compile time to a constant.
stringcpy(tempfile,DCC_PUBLICFILES); stringcpy(tempfile,DCC_PUBLICFILES);
@ -127,7 +128,7 @@ int dcc_sendfile(char *target, char *filename)
client->sock = s; client->sock = s;
client->user = NULL; client->user = NULL;
client->flags = DCC_WAIT|DCC_ASYNC|DCC_SEND; client->flags = DCC_WAIT|DCC_ASYNC|DCC_SEND;
client->lasttime = now; client->lasttime = cx.now;
client->whom = stringcpy(client->filename,filename) + 1; client->whom = stringcpy(client->filename,filename) + 1;
stringcpy(client->whom,target); stringcpy(client->whom,target);
@ -215,7 +216,7 @@ void parse_dcc(Client *client)
else else
{ {
client->flags = DCC_SEND; client->flags = DCC_SEND;
client->start = now; client->start = cx.now;
dcc_pushfile(client,0); dcc_pushfile(client,0);
} }
#endif /* DCC_FILE */ #endif /* DCC_FILE */
@ -249,7 +250,7 @@ void parse_dcc(Client *client)
if (write(client->sock,&where,4) == -1) if (write(client->sock,&where,4) == -1)
return; return;
client->lasttime = now; client->lasttime = cx.now;
if (oc == client->fileend) if (oc == client->fileend)
{ {
@ -265,7 +266,7 @@ void parse_dcc(Client *client)
{ {
uint32_t where; uint32_t where;
client->lasttime = now; client->lasttime = cx.now;
s = client->inputcount; s = client->inputcount;
oc = read(client->sock,(client->sockdata+s),(4-s)); oc = read(client->sock,(client->sockdata+s),(4-s));
if ((oc < 1) && (errno != EINTR) && (errno != EAGAIN)) if ((oc < 1) && (errno != EINTR) && (errno != EAGAIN))
@ -318,7 +319,7 @@ void parse_dcc(Client *client)
/* /*
* DCC input flood protection * DCC input flood protection
*/ */
s = now - client->lasttime; s = cx.now - client->lasttime;
if (s > 10) if (s > 10)
{ {
client->inputcount = strlen(ptr); client->inputcount = strlen(ptr);
@ -337,7 +338,7 @@ void parse_dcc(Client *client)
*/ */
CurrentShit = NULL; CurrentShit = NULL;
CurrentChan = NULL; CurrentChan = NULL;
client->lasttime = now; client->lasttime = cx.now;
CurrentDCC = client; CurrentDCC = client;
CurrentUser = client->user; CurrentUser = client->user;
stringcpy(CurrentNick,CurrentUser->name); stringcpy(CurrentNick,CurrentUser->name);
@ -347,11 +348,11 @@ void parse_dcc(Client *client)
bp = ptr; bp = ptr;
chop(&bp); chop(&bp);
ptr = get_token(&bp,"\001"); ptr = get_token(&bp,"\001");
on_action(CurrentUser->name,current->nick,ptr); on_action(CurrentUser->name,getbotnick(current),ptr);
} }
else else
{ {
on_msg(CurrentUser->name,current->nick,ptr); on_msg(CurrentUser->name,getbotnick(current),ptr);
} }
CurrentDCC = NULL; CurrentDCC = NULL;
/* /*
@ -389,7 +390,7 @@ void process_dcc(void)
partyline_banner(client); partyline_banner(client);
} }
else else
if ((client->flags & DCC_WAIT) && ((now - client->lasttime) >= WAITTIMEOUT)) if ((client->flags & DCC_WAIT) && ((cx.now - client->lasttime) >= WAIT_TIMEOUT))
{ {
#ifdef DEBUG #ifdef DEBUG
debug("(process_dcc) connection timed out (%s)\n", debug("(process_dcc) connection timed out (%s)\n",
@ -399,7 +400,7 @@ void process_dcc(void)
} }
#ifdef DCC_FILE #ifdef DCC_FILE
else else
if ((client->flags & DCC_SEND) && ((now - client->lasttime) >= DCC_FILETIMEOUT)) if ((client->flags & DCC_SEND) && ((cx.now - client->lasttime) >= DCCFILE_TIMEOUT))
{ {
#ifdef DEBUG #ifdef DEBUG
debug("(process_dcc) {%i} DCC %s stalled (%s), closing connection\n", debug("(process_dcc) {%i} DCC %s stalled (%s), closing connection\n",
@ -411,7 +412,7 @@ void process_dcc(void)
#endif /* DCC_FILE */ #endif /* DCC_FILE */
#ifdef TELNET #ifdef TELNET
else 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; client->flags = DCC_DELETE;
} }
@ -528,7 +529,7 @@ void ctcp_dcc(char *from, char *to, char *rest)
client->fileend = filesz; client->fileend = filesz;
client->sock = s; client->sock = s;
client->flags = DCC_WAIT|DCC_SEND|DCC_RECV; 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; client->whom = stringcpy(client->filename,filename) + 1;
stringcpy(client->whom,from); stringcpy(client->whom,from);
@ -587,7 +588,7 @@ void ctcp_dcc(char *from, char *to, char *rest)
client->sock = x; client->sock = x;
client->user = user; client->user = user;
client->flags = DCC_WAIT|DCC_ASYNC; client->flags = DCC_WAIT|DCC_ASYNC;
client->lasttime = now; client->lasttime = cx.now;
client->next = current->clientlist; client->next = current->clientlist;
current->clientlist = client; current->clientlist = client;
} }
@ -671,7 +672,7 @@ void ctcp_version(char *from, char *to, char *rest)
#endif /* CTCP */ #endif /* CTCP */
LS const struct const struct
{ {
char *name; char *name;
void (*func)(char *, char *, char *); 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++) 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; break;
} }
} }
@ -777,7 +778,7 @@ void do_ping_ctcp(COMMAND_ARGS)
{ {
if (CurrentCmd->name == C_PING || !stringcasecmp(rest,"PING")) 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; return;
} }
if (*rest) if (*rest)

View File

@ -36,9 +36,11 @@
#define boolstr(x) (x) ? "TRUE" : "FALSE" #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; char *name;
int size; int size;
@ -92,7 +94,6 @@ LS const struct
{ "Seen", sizeof(Seen) }, { "Seen", sizeof(Seen) },
#endif /* SEEN */ #endif /* SEEN */
{ "Server", sizeof(Server) }, { "Server", sizeof(Server) },
{ "ServerGroup", sizeof(ServerGroup) },
{ "Setting", sizeof(Setting) }, { "Setting", sizeof(Setting) },
{ "Shit", sizeof(Shit) }, { "Shit", sizeof(Shit) },
{ "Spy\t", sizeof(Spy) }, { "Spy\t", sizeof(Spy) },
@ -115,7 +116,7 @@ LS const struct
#define RARE_SE ,"RARE" #define RARE_SE ,"RARE"
#define DBUG_SE ,"DBUG" #define DBUG_SE ,"DBUG"
LS struct struct
{ {
void *func; void *func;
char *name; char *name;
@ -142,7 +143,6 @@ LS struct
{ do_die, "do_die" RARE_SE }, { do_die, "do_die" RARE_SE },
{ do_nick, "do_nick" CMD1_SE }, { do_nick, "do_nick" CMD1_SE },
{ do_kicksay, "do_kicksay" CMD1_SE }, { do_kicksay, "do_kicksay" CMD1_SE },
{ do_servergroup, "do_servergroup" CMD1_SE },
{ do_set, "do_set" CMD1_SE }, { do_set, "do_set" CMD1_SE },
{ do_spy, "do_spy" CMD1_SE }, { do_spy, "do_spy" CMD1_SE },
{ join_channel, "join_channel" CFG1_SE }, { join_channel, "join_channel" CFG1_SE },
@ -168,7 +168,8 @@ LS struct
{ send_kick, "send_kick" }, { send_kick, "send_kick" },
{ send_mode, "send_mode" }, { send_mode, "send_mode" },
{ set_str_varc, "set_str_varc" CFG1_SE }, { 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 }, { sig_hup, "sig_hup" RARE_SE },
{ table_buffer, "table_buffer" }, { table_buffer, "table_buffer" },
#ifdef ALIAS #ifdef ALIAS
@ -206,6 +207,8 @@ LS struct
#ifdef PYTHON #ifdef PYTHON
{ python_hook, "python_hook" }, { python_hook, "python_hook" },
{ python_unhook, "python_unhook" }, { python_unhook, "python_unhook" },
{ python_timer_jump, "python_timer_jump" },
{ python_parse_jump, "python_parse_jump" },
#endif /* PYTHON */ #endif /* PYTHON */
#ifdef RAWDNS #ifdef RAWDNS
{ rawdns, "rawdns" }, { rawdns, "rawdns" },
@ -223,6 +226,8 @@ LS struct
#endif /* STATS */ #endif /* STATS */
#ifdef TCL #ifdef TCL
{ tcl_hook, "tcl_hook" }, { tcl_hook, "tcl_hook" },
{ tcl_timer_jump, "tcl_timer_jump" },
{ tcl_parse_jump, "tcl_parse_jump" },
#endif /* TCL */ #endif /* TCL */
#ifdef TELNET #ifdef TELNET
{ check_telnet, "check_telnet" }, { check_telnet, "check_telnet" },
@ -242,11 +247,34 @@ LS struct
#ifdef URLCAPTURE #ifdef URLCAPTURE
{ urlcapture, "urlcapture" CORE_SE }, { urlcapture, "urlcapture" CORE_SE },
#endif /* URLCAPTURE */ #endif /* URLCAPTURE */
{ 0, "(unknown)" }, { 0, UNKNOWNSTR },
{ NULL, }}; { 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 #ifdef SCRIPTING
LS const DEFstruct SCRIPTdefs[] =
const DEFstruct SCRIPTdefs[] =
{ {
{ MEV_PARSE, "MEV_PARSE" }, { MEV_PARSE, "MEV_PARSE" },
{ MEV_TIMER, "MEV_TIMER" }, { MEV_TIMER, "MEV_TIMER" },
@ -254,18 +282,11 @@ LS const DEFstruct SCRIPTdefs[] =
{ MEV_BOTNET, "MEV_BOTNET" }, { MEV_BOTNET, "MEV_BOTNET" },
{ MEV_DCC_COMPLETE, "MEV_DCC_COMPLETE" }, { MEV_DCC_COMPLETE, "MEV_DCC_COMPLETE" },
{ MEV_DNSRESULT, "MEV_DNSRESULT" }, { 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, }}; { 0, }};
#endif /* SCRIPTING */ #endif /* SCRIPTING */
LS const DEFstruct CNdefs[] = const DEFstruct CNdefs[] =
{ {
{ CN_NOSOCK, "CN_NOSOCK" }, { CN_NOSOCK, "CN_NOSOCK" },
{ CN_DNSLOOKUP, "CN_DNSLOOKUP" }, { CN_DNSLOOKUP, "CN_DNSLOOKUP" },
@ -279,7 +300,7 @@ LS const DEFstruct CNdefs[] =
{ CN_SPINNING, "CN_SPINNING" }, { CN_SPINNING, "CN_SPINNING" },
{ 0, }}; { 0, }};
LS const DEFstruct SPdefs[] = const DEFstruct SPdefs[] =
{ {
{ SP_NULL, "SP_NULL" }, { SP_NULL, "SP_NULL" },
{ SP_NOAUTH, "SP_NOAUTH" }, { SP_NOAUTH, "SP_NOAUTH" },
@ -291,17 +312,20 @@ LS const DEFstruct SPdefs[] =
{ 0, }}; { 0, }};
#ifdef NOTIFY #ifdef NOTIFY
LS const DEFstruct NFdefs[] =
const DEFstruct NFdefs[] =
{ {
{ NF_OFFLINE, "NF_OFFLINE" }, { NF_OFFLINE, "NF_OFFLINE" },
{ NF_WHOIS, "NF_WHOIS" }, { NF_WHOIS, "NF_WHOIS" },
{ NF_MASKONLINE, "NF_MASKONLINE" }, { NF_MASKONLINE, "NF_MASKONLINE" },
{ NF_NOMATCH, "NF_NOMATCH" }, { NF_NOMATCH, "NF_NOMATCH" },
{ 0, }}; { 0, }};
#endif /* NOTIFY */ #endif /* NOTIFY */
#ifdef SEEN #ifdef SEEN
LS const DEFstruct SEdefs[] =
const DEFstruct SEdefs[] =
{ {
{ SEEN_PARTED, "SEEN_PARTED" }, { SEEN_PARTED, "SEEN_PARTED" },
{ SEEN_QUIT, "SEEN_QUIT" }, { SEEN_QUIT, "SEEN_QUIT" },
@ -311,7 +335,8 @@ LS const DEFstruct SEdefs[] =
#endif /* SEEN */ #endif /* SEEN */
#ifdef BOTNET #ifdef BOTNET
LS const DEFstruct BNdefs[] =
const DEFstruct BNdefs[] =
{ {
{ BN_UNKNOWN, "BN_UNKNOWN" }, { BN_UNKNOWN, "BN_UNKNOWN" },
{ BN_DEAD, "BN_DEAD" }, { BN_DEAD, "BN_DEAD" },
@ -322,9 +347,10 @@ LS const DEFstruct BNdefs[] =
{ BN_WAITLINK, "BN_WAITLINK" }, { BN_WAITLINK, "BN_WAITLINK" },
{ BN_LINKED, "BN_LINKED" }, { BN_LINKED, "BN_LINKED" },
{ 0, }}; { 0, }};
#endif /* BOTNET */ #endif /* BOTNET */
LS const DEFstruct dcc_flags[] = const DEFstruct dcc_flags[] =
{ {
{ DCC_SEND, "DCC_SEND" }, { DCC_SEND, "DCC_SEND" },
{ DCC_RECV, "DCC_RECV" }, { DCC_RECV, "DCC_RECV" },
@ -336,7 +362,7 @@ LS const DEFstruct dcc_flags[] =
{ DCC_DELETE, "DCC_DELETE" }, { DCC_DELETE, "DCC_DELETE" },
{ 0, }}; { 0, }};
LS const DEFstruct ircx_flags[] = const DEFstruct ircx_flags[] =
{ {
{ IRCX_WALLCHOPS, "IRCX_WALLCHOPS" }, { IRCX_WALLCHOPS, "IRCX_WALLCHOPS" },
{ IRCX_WALLVOICES, "IRCX_WALLVOICES" }, { IRCX_WALLVOICES, "IRCX_WALLVOICES" },
@ -344,7 +370,7 @@ LS const DEFstruct ircx_flags[] =
{ IRCX_EMODE, "IRCX_EMODE" }, { IRCX_EMODE, "IRCX_EMODE" },
{ 0, }}; { 0, }};
LS const DEFstruct chanuser_flags[] = const DEFstruct chanuser_flags[] =
{ {
{ CU_VOICE, "CU_VOICE" }, { CU_VOICE, "CU_VOICE" },
{ CU_CHANOP, "CU_CHANOP" }, { CU_CHANOP, "CU_CHANOP" },
@ -362,9 +388,9 @@ void strflags(char *dst, const DEFstruct *flagsstruct, int flags)
int i; int i;
*dst = 0; *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) if (*dst)
stringcat(dst,"|"); stringcat(dst,"|");
@ -379,22 +405,10 @@ const char *strdef(const DEFstruct *dtab, int num)
for(i=0;(dtab[i].idstr);i++) for(i=0;(dtab[i].idstr);i++)
{ {
if (dtab[i].v.id == num) if (dtab[i].id == num)
return(dtab[i].idstr); return(dtab[i].idstr);
} }
return("UNKNOWN"); return(UNKNOWNSTR);
}
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");
} }
void memreset(void) void memreset(void)
@ -409,8 +423,8 @@ void memreset(void)
} }
} }
LS const void *mem_lowptr; const void *mem_lowptr;
LS const void *mem_hiptr; const void *mem_hiptr;
void memtouch(const void *addr) 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) const char *proc_lookup(void *addr, int size)
{ {
int i; int i;
@ -495,14 +521,13 @@ char *atime(time_t when)
char *pt,*zp; char *pt,*zp;
pt = ctime(&when); pt = ctime(&when);
zp = STRCHR(pt,'\n'); zp = stringchr(pt,'\n');
*zp = 0; *zp = 0;
return(pt); return(pt);
} }
void debug_server(Server *sp, char *pad) void debug_server(Server *sp, char *pad)
{ {
ServerGroup *sg;
char *pl; char *pl;
if (!sp) 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; ident\t\t%i\n",pad,sp->ident);
debug("%s; name\t\t\"%s\"\n",pad,nullbuf(sp->name)); debug("%s; name\t\t\"%s\"\n",pad,nullbuf(sp->name));
debug("%s; pass\t\t\"%s\"\n",pad,nullbuf(sp->pass)); 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; realname\t\t\"%s\"\n",pad,nullbuf(sp->realname));
debug("%s; usenum\t\t%i\n",pad,sp->usenum); 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; 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; 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); 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); debug("%s> setting\n",pad+2);
for(;VarName[i].name;i++) for(;i<SIZE_VARS;i++)
{ {
if ((type == DSET_CHAN) && (i >= CHANSET_SIZE)) if ((type == DSET_CHAN) && (i >= CHANSET_SIZE))
break; break;
@ -644,7 +661,7 @@ void debug_memory(void)
#endif /* URLCAPTURE */ #endif /* URLCAPTURE */
for(bot=botlist;bot;bot=bot->next) 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)) if (IsStr(i))
memtouch(bot->setting[i].str_var); memtouch(bot->setting[i].str_var);
@ -661,7 +678,6 @@ void debug_memory(void)
{ {
memtouch(bot->lastcmds[i]); memtouch(bot->lastcmds[i]);
} }
memtouch(bot->userhost);
} }
debug("> Memory allocations\n"); debug("> Memory allocations\n");
for(mea=mrrec;(mea);mea=mea->next) for(mea=mrrec;(mea);mea=mea->next)
@ -741,7 +757,7 @@ void debug_botnet(void)
struct sockaddr_in sai; struct sockaddr_in sai;
BotNet *bn; BotNet *bn;
NetCfg *cfg; NetCfg *cfg;
int sz; unsigned int sz;
debug("; linkpass\t\t\"%s\"\n",nullstr(linkpass)); debug("; linkpass\t\t\"%s\"\n",nullstr(linkpass));
memtouch(linkpass); memtouch(linkpass);
@ -826,7 +842,6 @@ void debug_core(void)
Seen *seen; Seen *seen;
#endif /* SEEN */ #endif /* SEEN */
Server *sp; Server *sp;
ServerGroup *sg;
Spy *spy; Spy *spy;
Strp *st; Strp *st;
Shit *shit; Shit *shit;
@ -851,31 +866,13 @@ void debug_core(void)
} }
debug(" ; ---\n"); debug(" ; ---\n");
if (current) 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 else
debug("; current\t\t"mx_pfmt"\n",(mx_ptr)current); debug("; current\t\t"mx_pfmt"\n",(mx_ptr)current);
debug("; executable\t\t\"%s\"\n",executable); debug("; executable\t\t\"%s\"\n",executable);
debug("; configfile\t\t\"%s\"\n",configfile); debug("; configfile\t\t\"%s\"\n",configfile);
debug("; uptime\t\t%s (%lu)\n",atime(uptime),uptime); 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("; short_tv\t\t%s (%is wait)\n",boolstr(cx.short_tv),(cx.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("> serverlist\t\t"mx_pfmt"\n",(mx_ptr)serverlist); debug("> serverlist\t\t"mx_pfmt"\n",(mx_ptr)serverlist);
for(sp=serverlist;sp;sp=sp->next) for(sp=serverlist;sp;sp=sp->next)
{ {
@ -887,8 +884,6 @@ void debug_core(void)
for(bot=botlist;bot;bot=bot->next) for(bot=botlist;bot;bot=bot->next)
{ {
memtouch(bot); memtouch(bot);
memtouch(bot->nick);
memtouch(bot->wantnick);
debug(" ; Mech*\t\t"mx_pfmt"\n",(mx_ptr)bot); debug(" ; Mech*\t\t"mx_pfmt"\n",(mx_ptr)bot);
debug(" ; next\t\t"mx_pfmt"\n",(mx_ptr)bot->next); debug(" ; next\t\t"mx_pfmt"\n",(mx_ptr)bot->next);
debug(" ; connect\t\t%s (%i)\n",strdef(CNdefs,bot->connect),bot->connect); 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_server(sp," ");
} }
debug(" ; nick\t\t\"%s\"\n",nullstr(bot->nick)); debug(" ; nick\t\t\"%s\"\n",nullstr(getbotnick(bot)));
debug(" ; wantnick\t\t\"%s\"\n",nullstr(bot->wantnick)); debug(" ; wantnick\t\t\"%s\"\n",nullstr(getbotwantnick(bot)));
debug_settings(bot->setting,DSET_GLOBAL); debug_settings(bot->setting,DSET_GLOBAL);
@ -1361,7 +1356,7 @@ void debug_scripthook(void)
for(h=hooklist;h;h=h->next) for(h=hooklist;h;h=h->next)
{ {
memtouch(h); 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(" ; guid\t\t%i\n",h->guid);
debug(" ; flags\t\t%s (%i)\n",strdef(SCRIPTdefs,h->flags),h->flags); debug(" ; flags\t\t%s (%i)\n",strdef(SCRIPTdefs,h->flags),h->flags);
if (h->flags == MEV_TIMER) if (h->flags == MEV_TIMER)
@ -1429,13 +1424,14 @@ int wrap_debug(void)
backup_dodebug = dodebug; backup_dodebug = dodebug;
backup_fd = debug_fd; 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) if ((fd = open(fname,O_WRONLY|O_CREAT|O_TRUNC,NEWFILEMODE)) < 0)
return(0); return(0);
debug_fd = fd; debug_fd = fd;
dodebug = TRUE; dodebug = TRUE;
run_debug(); run_debug();
parse_server_input(NULL);
close(fd); close(fd);
debug_fd = backup_fd; debug_fd = backup_fd;
@ -1445,8 +1441,49 @@ int wrap_debug(void)
return(1); return(1);
} }
void do_inject(COMMAND_ARGS)
{
set_mallocdoer(do_inject);
current->inject = stringdup(rest);
}
void do_debug(COMMAND_ARGS) 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()) if (wrap_debug())
to_user(from,"Debug information has been written to file"); to_user(from,"Debug information has been written to file");
else else
@ -1466,6 +1503,7 @@ void do_crash(COMMAND_ARGS)
void debug(char *format, ...) void debug(char *format, ...)
{ {
va_list msg; va_list msg;
int sz;
if (!dodebug) if (!dodebug)
return; return;
@ -1488,10 +1526,10 @@ void debug(char *format, ...)
} }
va_start(msg,format); va_start(msg,format);
vsnprintf(debugbuf,sizeof(debugbuf),format,msg); sz = vsnprintf(debugbuf,sizeof(debugbuf),format,msg);
va_end(msg); va_end(msg);
if ((write(debug_fd,debugbuf,strlen(debugbuf))) < 0) if ((write(debug_fd,debugbuf,sz)) < 0)
dodebug = FALSE; dodebug = FALSE;
} }

View File

@ -1,7 +1,7 @@
/* /*
EnergyMech, IRC bot software 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 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 it under the terms of the GNU General Public License as published by
@ -21,15 +21,6 @@
#ifndef DEFINES_H #ifndef DEFINES_H
#define DEFINES_H 1 #define DEFINES_H 1
/*
* dont export too many symbols...
*/
#ifdef LIBRARY
#define LS static
#else /* not LIBRARY */
#define LS /* nothing */
#endif /* LIBRARY */
/* /*
* startup == * startup ==
*/ */
@ -104,16 +95,9 @@
#define QM_PRI_LOW 100 #define QM_PRI_LOW 100
/* /*
* Bitfield for short_tv being set to 1 or 30 seconds * stats.c
*/ */
#define CSTAT_PARTIAL 1
#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
/* Misc Crap: */ /* Misc Crap: */
@ -148,6 +132,227 @@
#define FUH_USERHOST 1 #define FUH_USERHOST 1
#define FUH_HOST 2 #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: */ /* Type of Variable: */
#define INT_VAR 0x01 #define INT_VAR 0x01
@ -174,14 +379,6 @@
#define IsChar(x) ((VarName[x].type & CHR_VAR) == CHR_VAR) #define IsChar(x) ((VarName[x].type & CHR_VAR) == CHR_VAR)
#define IsProc(x) (VarName[x].type & PROC_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 * see settings.h for the actual setting struct
*/ */
@ -301,205 +498,5 @@ enum {
SIZE_VARS 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 */ #endif /* DEFINES_H */

View File

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

View File

@ -1,7 +1,7 @@
/* /*
EnergyMech, IRC bot software 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 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 it under the terms of the GNU General Public License as published by
@ -30,12 +30,13 @@
#include "h.h" #include "h.h"
#include "text.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 */ const char monlist[12][4] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
LS char idlestr[36]; /* max format lentgh == 24+1, round up to 36 */ const char daylist[7][4] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" };
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" }; #ifndef TEST
/* /*
* memory allocation routines * memory allocation routines
@ -91,7 +92,7 @@ void *Calloc(int size)
exit(1); exit(1);
} }
mmep->size = size; mmep->size = size;
mmep->when = now; mmep->when = cx.now;
mmep->doer = mallocdoer; mmep->doer = mallocdoer;
mallocdoer = NULL; mallocdoer = NULL;
return((void*)mmep->area+4); 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); debug("(Free) PANIC: Free(0x"mx_pfmt"); Unregistered memory block\n",(mx_ptr)src);
run_debug(); run_debug();
/*exit(1); /* overreacting. just ignore it and accept the leak. */ /*exit(1);*/
/* overreacting. just ignore it and accept the leak. */
return; return;
} }
mp = mp->next; mp = mp->next;
@ -167,6 +169,50 @@ void Free(char **mem)
#endif /* DEBUG */ #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) Strp *make_strp(Strp **pp, const char *string)
{ {
set_mallocdoer(make_strp); 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 *getuh(char *nuh)
{ {
char *s; char *s;
@ -322,12 +278,11 @@ char *getuh(char *nuh)
{ {
if (*s == '!') if (*s == '!')
{ {
nuh = s + 1;
/* /*
* We have to grab everything from the first '!' since some * We have to grab everything from the first '!' since some
* braindamaged ircds allow '!' in the "user" part of the nuh * braindamaged ircds allow '!' in the "user" part of the nuh
*/ */
break; return(s + 1);
} }
s++; s++;
} }
@ -385,80 +340,63 @@ a: ++(*src);
return(token); return(token);
} }
#endif /* ifndef TEST */
/* /*
* time to string routines * time to string routines
*/ */
char *logtime(time_t when) char *maketimestr(time_t when, int format)
{ {
struct tm *btime; struct tm *btime;
char *dest,*f,ampm;
int option;
btime = localtime(&when); btime = localtime(&when);
sprintf(timebuf,"%s %i %i %02i:%02i:%02i", /* max format length: 20+1 */ dest = timebuf;
monlist[btime->tm_mon],btime->tm_mday,btime->tm_year+1900,
btime->tm_hour,btime->tm_min,btime->tm_sec);
return(timebuf);
}
char *time2str(time_t when) do
{ {
struct tm *btime; option = format & 0x7;
format = format >> 4;
if (!when) f = "%02i:%02i:%02i";
return(NULL); switch(option)
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; case 0:
char ampm; *(dest++) = ' ';
break;
if (!when) case 1:/* HH:mm */
return(NULL); f += 5;
case 2:/* HH:mm:ss */
btime = localtime(&when); dest += sprintf(dest,f,btime->tm_hour,btime->tm_min,btime->tm_sec);
if (btime->tm_hour < 12) break;
{ case 3:/* WeekDay */
if (btime->tm_hour == 0) /* stringcpy return a pointer to the last char, not how many chars was copied */
btime->tm_hour = 12; dest = stringcpy(dest,daylist[btime->tm_wday]);
ampm = 'a'; 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';
} }
while(format);
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);
return(timebuf); return(timebuf);
} }
@ -467,18 +405,31 @@ char *idle2str(time_t when, int small)
char *dst; char *dst;
int n,z[4]; int n,z[4];
when = cx.now - when;
z[0] = when / 86400; z[0] = when / 86400;
z[1] = (when -= z[0] * 86400) / 3600; z[1] = (when -= z[0] * 86400) / 3600;
z[2] = (when -= z[1] * 3600) / 60; z[2] = (when -= z[1] * 3600) / 60;
z[3] = when % 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" */ /* 32 : "9999 days, 24 hours, 59 minutes" */
/* xx : "24 hours, 59 minutes" */ /* xx : "24 hours, 59 minutes" */
/* xx : "59 minutes, 59 seconds" */ /* xx : "59 minutes, 59 seconds" */
/* xx : "59 seconds" */ /* xx : "59 seconds" */
if (small) if (small)
{ {
char *f[] = {"day","hour","minute","second"}; const char *f[] = {"day","hour","minute","second"};
*idlestr = 0; *idlestr = 0;
for(n=0;n<4;n++) for(n=0;n<4;n++)
@ -496,6 +447,8 @@ char *idle2str(time_t when, int small)
return(idlestr); return(idlestr);
} }
#ifndef TEST
const char *get_channel(const char *to, char **rest) const char *get_channel(const char *to, char **rest)
{ {
const char *channel; const char *channel;
@ -608,7 +561,7 @@ char *format_uh(char *userhost, int type)
char tmpmask[NUHLEN]; char tmpmask[NUHLEN];
char *u,*h; char *u,*h;
if (STRCHR(userhost,'*')) if (stringchr(userhost,'*'))
return(userhost); return(userhost);
stringcpy(tmpmask,userhost); stringcpy(tmpmask,userhost);
@ -632,87 +585,6 @@ char *format_uh(char *userhost, int type)
return(userhost); 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) int is_nick(const char *nick)
{ {
uchar *p; uchar *p;
@ -729,6 +601,8 @@ int is_nick(const char *nick)
return(TRUE); return(TRUE);
} }
#endif /* ifndef TEST */
/* asc2int requires the whole string *anum to be a valid numeric */ /* asc2int requires the whole string *anum to be a valid numeric */
int asc2int(const char *anum) int asc2int(const char *anum)
{ {
@ -770,6 +644,46 @@ int get_number(const char *rest)
return(n); 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) void fix_config_line(char *text)
{ {
char *s,*space; char *s,*space;
@ -788,8 +702,6 @@ void fix_config_line(char *text)
*space = 0; *space = 0;
} }
#endif /* ifndef TEST */
/* /*
* mask matching * mask matching
* returns 0 for match * returns 0 for match
@ -996,7 +908,9 @@ void teststring(void)
int main(int argc, char **argv, char **envp) int main(int argc, char **argv, char **envp)
{ {
char mybuffer[64];
struct stat st; struct stat st;
time_t when;
int r; int r;
dodebug = 1; dodebug = 1;
@ -1020,12 +934,26 @@ int main(int argc, char **argv, char **envp)
testcase("../../nosuchfile",-5,FILE_MUST_NOTEXIST); testcase("../../nosuchfile",-5,FILE_MUST_NOTEXIST);
testcase(P2,-6,FILE_MAY_EXIST); testcase(P2,-6,FILE_MAY_EXIST);
teststring(); teststring();
exit(0);
} }
if (argv[1])
{
r = is_safepath(argv[1],FILE_MAY_EXIST); r = is_safepath(argv[1],FILE_MAY_EXIST);
debug("testpath %s -> result %s\n",argv[1],(r) ? "TRUE" : "FALSE"); 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 */ #endif /* TEST */

View File

@ -26,347 +26,236 @@ char globaldata[MAXLEN];
#include "io.c" #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;
/* /*
* tolowertab blatantly ripped from ircu2.9.32
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
*/ */
const uchar tolowertab[256] =
#define CCPW CC|PASS
struct
{ {
int pass; 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
const char *name; 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
const char *func; 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
uint32_t flags; 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
char *cmdarg; ' ', '!', '"', '#', '$', '%', '&', 0x27,
'(', ')', '*', '+', ',', '-', '.', '/',
} pre_mcmd[] = '0', '1', '2', '3', '4', '5', '6', '7',
{ '8', '9', ':', ';', '<', '=', '>', '?',
/* '@', 'a', 'b', 'c', 'd', 'e', 'f', 'g',
* public access commands 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',
*/ 'p', 'q', 'r', 's', 't', 'u', 'v', 'w',
{ 0, "AUTH", "do_auth", 0 | NOPUB | CBANG }, // double up on AUTH/VERIFY to better 'x', 'y', 'z', '{', '|', '}', '~', '_',
{ 0, "VERIFY", "do_auth", 0 | NOPUB | CBANG }, // catch login attempts '`', 'a', 'b', 'c', 'd', 'e', 'f', 'g',
#ifdef TOYBOX 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',
{ 0, "8BALL", "do_8ball", 0 | CBANG | SUPRES }, 'p', 'q', 'r', 's', 't', 'u', 'v', 'w',
{ 0, "RAND", "do_rand", 0 | CBANG | SUPRES }, 'x', 'y', 'z', '{', '|', '}', '~', 0x7f,
#endif /* TOYBOX */ 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
{ 0, "CV", "do_convert", 0 | CBANG | SUPRES }, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
{ 0, "CALC", "do_calc", 0 | CBANG | SUPRES }, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
/* 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
* Level 10 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
*/ 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
{ 0, "ACCESS", "do_access", 10 | CCPW }, 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
{ 0, "BYE", "do_bye", 10 | CC }, 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
{ 0, "CHAT", "do_chat", 10 | CCPW | NOCMD }, 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
#ifdef RAWDNS 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7,
{ 0, "DNS", "do_dns", 10 | CCPW | GAXS | CARGS | SUPRES }, 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
#endif /* RAWDNS */ 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
{ 0, "DOWN", "do_opdeopme", 10 | CC | CAXS }, 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
{ 0, "ECHO", "do_echo", 10 | CCPW | CARGS }, 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
{ 0, "HELP", "do_help", 10 | CCPW | REDIR | LBUF | SUPRES }, 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff
{ 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 },
}; };
#define __define_strng 4 #include "onhash.h"
#define __define_print 3
#define __struct_acces 2
#define __struct_print 1
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; const char *chosen;
char tmp[100],*tabs; int j,index;
int i,j,wh,pass,ct,sl,fd;
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; OnMsg v;
if (mode == 0)
{
unlink("mcmd.h"); unlink("mcmd.h");
fd = open("mcmd.h",O_WRONLY|O_CREAT|O_TRUNC,0644); fd = open("mcmd.h",O_WRONLY|O_CREAT|O_TRUNC,0644);
}
if (mode == 1)
{
fd = 1;
}
pass = __define_strng; collis = 0;
ct = 0; pass = __command_hash_9;
cmdcount = 0;
to_file(fd,"/""* This file is automatically generated from gencmd.c *""/\n"); 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"); to_file(fd,"#ifndef TEST\n#ifndef MCMD_H\n#define MCMD_H 1\n\n");
while(pass) 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));
if (pass == __struct_acces) j = 0;
if (randfd < 0)
{ {
to_file(fd,"LS OnMsg_access acmd[] =\n{\n"); 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 == __print_hashta_7)
{
}
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++) for(i=0;pre_mcmd[i].name;i++)
{ {
pt = 0; const char *tabs,*tabx;
wh = 0; int adj;
for(j=0;pre_mcmd[j].name;j++)
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; for(j=0;j<sizeof(heatmap);j++)
wh = 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; break;
continue;
} }
} cmdstr = getsortedcommand(pass,&cmdidx);
for(j=0;pre_mcmd[j].name;j++) if (pass == __define_strng_5)
{ {
if ((pre_mcmd[j].pass != pass) && (strcmp(pt,pre_mcmd[j].name) > 0)) }
if (pass == __define_print_3)
{ {
pt = pre_mcmd[j].name; if (cmdstr)
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) if (pass == __struct_print_1)
{
//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)
{ {
char noargfunc[64];
h = mkhash(cmdstr);
hashmap[h] = i;
memset(&v,0,sizeof(v)); memset(&v,0,sizeof(v));
v.defaultaccess = pre_mcmd[wh].flags & CLEVEL; v.defaultaccess = pre_mcmd[cmdidx].flags & CLEVEL;
/* + defaultaccess */ /* + defaultaccess */
v.dcc = (pre_mcmd[wh].flags & DCC) ? 1 : 0; if (v.defaultaccess >= 5) /* semi-public commands */
v.cc = (pre_mcmd[wh].flags & CC) ? 1 : 0; v.cc = 1;
v.pass = (pre_mcmd[wh].flags & PASS) ? 1 : 0; if (v.defaultaccess >= 10) /* normal commands */
v.args = (pre_mcmd[wh].flags & CARGS) ? 1 : 0; v.pass = 1;
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;
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.defaultaccess,
v.dcc, v.dcc,
v.cc, v.cc,
@ -380,42 +269,87 @@ void make_mcmd(void)
v.lbuf, v.lbuf,
v.cbang, v.cbang,
v.acchan, v.acchan,
v.supres v.supres,
v.noargf
); );
sl = strlen(pre_mcmd[wh].func) + 1;
tabs = "\t\t\t"; tabs = "\t\t\t";
sl = (sl & ~7) / 8; adj = strlen(cmdstr);
tabs += sl; 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", if (v.noargf)
pt, sprintf(noargfunc,"\n\t\t\t%s_noargs",pre_mcmd[cmdidx].func);
((strlen(pt) + 5) < 8) ? "\t" : "", else
pre_mcmd[wh].func, 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, tabs,
tmp, 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);
} }
if (pass == __struct_print) to_file(fd,"#ifdef MAIN_C\n\n");
}
if (pass == __struct_print_1)
{ {
to_file(fd,"{ NULL, }};\n\n"); to_file(fd,"{ NULL, }};\n\n");
} }
if (pass == __struct_acces) if (pass == __struct_acces_2)
{ {
to_file(fd,"};\n\n"); 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--; pass--;
} }
to_file(fd,"#define LOCALHOST_ULONG %lu\n",inet_addr("127.1")); 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 mcmd[];\n");
to_file(fd,"extern OnMsg_access acmd[];\n\n"); to_file(fd,"extern OnMsg_access acmd[];\n\n");
to_file(fd,"#endif /""* MAIN_C *""/\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); close(fd);
exit(0); exit(0);
} }
@ -439,24 +391,20 @@ void make_usercombo(void)
to_file(fd,"/""* This file is automatically generated from gencmd.c *""/\n"); 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; combo.comboflags = 0; combo.x.noshare = 1;
to_file(fd,"#define COMBO_NOSHARE\t0x%x\n",combo.comboflags); to_file(fd,"#define COMBO_NOSHARE\t0x%x\n",combo.comboflags);
combo.comboflags = 0; combo.x.readonly = 1; combo.comboflags = 0; combo.x.readonly = 1;
to_file(fd,"#define COMBO_READONLY\t0x%x\n",combo.comboflags); to_file(fd,"#define COMBO_READONLY\t0x%x\n",combo.comboflags);
#endif /* BOTNET */
#ifdef GREET
combo.comboflags = 0; combo.x.greetfile = 1; combo.comboflags = 0; combo.x.greetfile = 1;
to_file(fd,"#define COMBO_GREETFILE\t0x%x\n",combo.comboflags); to_file(fd,"#define COMBO_GREETFILE\t0x%x\n",combo.comboflags);
combo.comboflags = 0; combo.x.randline = 1; combo.comboflags = 0; combo.x.randline = 1;
to_file(fd,"#define COMBO_RANDLINE\t0x%x\n",combo.comboflags); to_file(fd,"#define COMBO_RANDLINE\t0x%x\n",combo.comboflags);
#endif /* GREET */
#ifdef BOUNCE
combo.comboflags = 0; combo.x.bounce = 1; combo.comboflags = 0; combo.x.bounce = 1;
to_file(fd,"#define COMBO_BOUNCE\t0x%x\n",combo.comboflags); to_file(fd,"#define COMBO_BOUNCE\t0x%x\n",combo.comboflags);
#endif /* BOUNCE */
combo.comboflags = 0; combo.x.echo = 1; combo.comboflags = 0; combo.x.echo = 1;
to_file(fd,"#define COMBO_ECHO\t0x%x\n",combo.comboflags); to_file(fd,"#define COMBO_ECHO\t0x%x\n",combo.comboflags);
@ -515,7 +463,7 @@ void datestamp(void)
#ifndef HAVE_GIT #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", "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", "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", "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) int main(int argc, char **argv)
{ {
randfd = -1;
mx = 0;
mincoll = 666666;
heatmapon = 0;
if (argv[1]) if (argv[1])
{ {
if (strcmp(argv[1],"usercombo.h") == 0) if (strcmp(argv[1],"usercombo.h") == 0)
make_usercombo(); make_usercombo();
if (strcmp(argv[1],"mcmd.h") == 0) if (strcmp(argv[1],"mcmd.h") == 0)
make_mcmd(); make_mcmd(0);
if (strcmp(argv[1],"testhelp") == 0) if (strcmp(argv[1],"testhelp") == 0)
test_help(); test_help();
@ -578,6 +531,16 @@ int main(int argc, char **argv)
if (strcmp(argv[1],"githash.h") == 0) if (strcmp(argv[1],"githash.h") == 0)
githash(); githash();
if (strcmp(argv[1],"heatmap") == 0)
{
heatmapon = 1;
make_mcmd(1);
}
}
else
{
make_mcmd(1);
} }
return(0); return(0);
} }

View File

@ -1,7 +1,7 @@
/* /*
EnergyMech, IRC bot software 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 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 it under the terms of the GNU General Public License as published by
@ -21,10 +21,10 @@
#ifndef GLOBAL_H #ifndef GLOBAL_H
#define GLOBAL_H 1 #define GLOBAL_H 1
#ifdef MAIN_C #if defined(MAIN_C) || defined(TEST)
#define MDEF(x) = x #define MDEF(x) = x
#define BEG LS #define BEG
#else /* MAIN_C */ #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 DEFAULTCMDCHAR '-'
#define MECHUSERLOGIN "v3.energymech.net" #define MECHUSERLOGIN "v3.energymech.net"
BEG const char VERSION[] MDEF("3.2p" GITHASH); BEG const char VERSION[] MDEF("3.5.dev" GITHASH);
BEG const char SRCDATE[] MDEF("May 13th, 2024"); BEG const char SRCDATE[] MDEF("November 20th, 2025");
#ifdef __CYGWIN__ #ifdef __CYGWIN__
BEG const char BOTCLASS[] MDEF("WinMech"); BEG const char BOTCLASS[] MDEF("WinMech");
#else /* ! CYGWIN */ #else /* ! CYGWIN */
@ -52,10 +75,15 @@ BEG const char BOTCLASS[] MDEF("EnergyMech");
BEG const char BOTLOGIN[] MDEF("emech"); BEG const char BOTLOGIN[] MDEF("emech");
BEG const char NULLSTR[] MDEF("<NULL>"); 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_CHAN[] MDEF("I'm not on %s");
BEG const char ERR_FILEOPEN[] MDEF("Couldn't open the file %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_NICK[] MDEF("Invalid nickname: %s");
BEG const char ERR_NOCHANNELS[] MDEF("I'm not active on any channels"); 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"); 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"); 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_4XSTRTAB &FMT_6XSTRTAB[6]
#define FMT_3XSTRTAB &FMT_6XSTRTAB[9] #define FMT_3XSTRTAB &FMT_6XSTRTAB[9]
#define FMT_PLAIN &FMT_6XSTRTAB[15]
BEG Mech *botlist MDEF(NULL); BEG Mech *botlist MDEF(NULL);
BEG Mech *current;
BEG char *executable; BEG char *executable;
BEG char *configfile MDEF(CFGFILE); BEG char *configfile MDEF(CFGFILE);
@ -99,9 +125,6 @@ BEG ino_t parent_inode;
BEG KillSock *killsocks MDEF(NULL); BEG KillSock *killsocks MDEF(NULL);
BEG Server *serverlist 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 int serverident MDEF(1);
BEG char CurrentNick[NUHLEN]; BEG char CurrentNick[NUHLEN];
@ -113,9 +136,6 @@ BEG const OnMsg *CurrentCmd MDEF(NULL);
BEG User *cfgUser MDEF(NULL); BEG User *cfgUser MDEF(NULL);
BEG const char *global_from 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 * 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 read_fds;
BEG fd_set write_fds; BEG fd_set write_fds;
BEG int hisock;
BEG int short_tv;
/*
* current UNIX timestamp
*/
BEG time_t now;
/* /*
* defined features * defined features
@ -152,9 +164,6 @@ BEG Alias *aliaslist MDEF(NULL);
#ifdef BOTNET #ifdef BOTNET
BEG const char UNKNOWNATUNKNOWN[] MDEF("unknown@unknown");
#define UNKNOWN (&UNKNOWNATUNKNOWN[8])
BEG BotNet *botnetlist MDEF(NULL); BEG BotNet *botnetlist MDEF(NULL);
BEG NetCfg *netcfglist MDEF(NULL); BEG NetCfg *netcfglist MDEF(NULL);
BEG char *linkpass MDEF(NULL); /* proc var */ BEG char *linkpass MDEF(NULL); /* proc var */
@ -184,6 +193,7 @@ BEG time_t ctcp_slot[CTCP_SLOTS];
BEG char debugbuf[MAXLEN]; BEG char debugbuf[MAXLEN];
BEG char *debugfile MDEF(NULL); BEG char *debugfile MDEF(NULL);
BEG int debugfilemalloc MDEF(FALSE);
BEG int dodebug MDEF(FALSE); BEG int dodebug MDEF(FALSE);
BEG int debug_fd MDEF(-1); BEG int debug_fd MDEF(-1);
BEG int debug_on_exit MDEF(FALSE); BEG int debug_on_exit MDEF(FALSE);
@ -204,6 +214,8 @@ BEG Note *notelist MDEF(NULL);
#ifdef RAWDNS #ifdef RAWDNS
BEG int dnssock MDEF(-1);
BEG int dnsserver MDEF(0);
BEG dnsList *dnslist MDEF(NULL); BEG dnsList *dnslist MDEF(NULL);
BEG dnsAuthority *dnsroot MDEF(NULL); BEG dnsAuthority *dnsroot MDEF(NULL);
BEG struct in_addr ia_ns[MAX_NAMESERVERS]; BEG struct in_addr ia_ns[MAX_NAMESERVERS];
@ -254,6 +266,7 @@ BEG int triv_qdelay MDEF(30); /* proc var */
BEG char *triv_qfile MDEF(NULL); /* proc var */ BEG char *triv_qfile MDEF(NULL); /* proc var */
BEG char triv_qchar MDEF('*'); /* proc var */ BEG char triv_qchar MDEF('*'); /* proc var */
BEG TrivScore *scorelist MDEF(NULL); BEG TrivScore *scorelist MDEF(NULL);
BEG time_t triv_next_time MDEF(0);
#endif /* TRIVIA */ #endif /* TRIVIA */
@ -264,7 +277,7 @@ BEG char *uptimehost MDEF(NULL); /* proc var */
BEG char *uptimenick MDEF(NULL); /* proc var */ BEG char *uptimenick MDEF(NULL); /* proc var */
BEG int uptimesock; BEG int uptimesock;
BEG uint32_t uptimeip MDEF((uint32_t)-1); 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 uint32_t uptimeregnr MDEF(0);
BEG time_t uptimelast MDEF(0); BEG time_t uptimelast MDEF(0);
BEG const char *defaultuptimehost MDEF("uptime.eggheads.org"); BEG const char *defaultuptimehost MDEF("uptime.eggheads.org");
@ -300,14 +313,14 @@ BEG int spawning_lamer MDEF(0);
#define CRLF 0x08 #define CRLF 0x08
#define FNICK (NICK|FIRST) #define FNICK (NICK|FIRST)
#define NNICK (NICK|NUM) #define NUMNI (NICK|NUM)
#if defined(MAIN_C) || defined(MAKETABLES) #if defined(MAIN_C) || defined(MAKETABLES)
/* /*
* tolowertab blatantly ripped from ircu2.9.32 * tolowertab blatantly ripped from ircu2.9.32
*/ */
LS const uchar tolowertab[256] = const uchar tolowertab[256] =
{ {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 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... * 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, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 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 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, 0, 0, 0, 0, 0, 0, /* 0x00 - 0x07 */
0, 0, CRLF, 0, 0, CRLF, 0, 0, /* 0x08 - 0x0F */ 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, /* 0x18 - 0x1F */
0, 0, 0, 0, 0, 0, 0, 0, /* 0x20 - 0x27 */ 0, 0, 0, 0, 0, 0, 0, 0, /* 0x20 - 0x27 */
0, 0, 0, 0, 0, NICK, 0, 0, /* 0x28 - 0x2F */ 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 */ 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, /* 0x48 - 0x4F */
FNICK, FNICK, FNICK, FNICK, FNICK, FNICK, FNICK, FNICK, /* 0x50 - 0x57 */ 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 * user struct for the core client
*/ */
LS const Strp CMA = const Strp CMA =
{ {
NULL, NULL,
"*" "*"
@ -434,37 +458,23 @@ LS const Strp CMA =
/* /*
* client struct for the core client * client struct for the core client
*/ */
LS ShortClient CoreClient = ShortClient CoreClient =
{ {
NULL, /* next */ NULL, /* next */
(User*)&CoreUser, /* user */ (User*)&cx.CoreUser, /* user */
-1, /* socket */ -1, /* socket */
0, /* flags */ 0, /* flags */
0, /* inputcount */ 0, /* inputcount */
0 /* lasttime */ 0 /* lasttime */
}; };
LS ShortChan CoreChan = ShortChan CoreChan =
{ {
NULL, NULL,
NULL NULL
}; };
typedef struct coreServerGroup struct
{
ServerGroup *next;
int servergroup;
char name[8];
} coreServerGroup;
LS coreServerGroup defaultServerGroup =
{
NULL, /* next */
0, /* servergroup */
"default" /* name */
};
LS struct
{ {
const char *string; const char *string;
const int id; const int id;
@ -482,11 +492,8 @@ LS struct
extern const uchar tolowertab[]; extern const uchar tolowertab[];
extern const uchar nickcmptab[]; extern const uchar nickcmptab[];
extern const uchar attrtab[]; extern const uchar attrtab[];
extern const User xxCoreUser;
extern const User xxLocalBot;
extern ShortClient CoreClient; extern ShortClient CoreClient;
extern ShortChan CoreChan; extern ShortChan CoreChan;
extern ServerGroup defaultServerGroup;
#endif /* MAIN_C */ #endif /* MAIN_C */

605
src/h.h
View File

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

View File

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

View File

@ -53,7 +53,7 @@ struct /* statusvalues */
const int klen; const int klen;
char *valbuf; char *valbuf;
} sv[] = } statusvalues[] =
{ {
{ "VmPeak:", 7, vmpeak }, { "VmPeak:", 7, vmpeak },
{ "VmSize:", 7, vmsize }, { "VmSize:", 7, vmsize },
@ -65,55 +65,9 @@ struct /* statusvalues */
{ NULL, 0, NULL } { 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) int monitor_fs(const char *file)
{ {
FileMon *fmon,*fnew; FileMon *fnew;
int ino; int ino;
if ((ino = inotify_init()) < 0) if ((ino = inotify_init()) < 0)
@ -125,7 +79,7 @@ int monitor_fs(const char *file)
set_mallocdoer(monitor_fs); set_mallocdoer(monitor_fs);
fnew = Calloc(sizeof(FileMon) + strlen(file)); fnew = Calloc(sizeof(FileMon) + strlen(file));
fnew->fd = ino; fnew->fd = ino;
fnew->nospam = now; fnew->nospam = cx.now;
stringcpy(fnew->filename,file); stringcpy(fnew->filename,file);
fnew->next = filemonlist; fnew->next = filemonlist;
@ -145,15 +99,15 @@ int parse_proc_status(char *line)
#endif #endif
if (key == NULL) if (key == NULL)
return(FALSE); 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 #ifdef DEBUG
debug("(parse_proc_status) key %s -> %s\n",key,line); debug("(parse_proc_status) key %s -> %s\n",key,line);
#endif /* DEBUG */ #endif /* DEBUG */
dest = sv[i].valbuf; dest = statusvalues[i].valbuf;
limit = sv[i].valbuf + 31; limit = statusvalues[i].valbuf + 31;
while(*line == ' ') while(*line == ' ')
line++; line++;
while(*line && dest <= limit) while(*line && dest <= limit)
@ -250,29 +204,41 @@ int parse_proc_cpuinfo(char *line)
return(FALSE); /* return false to continue reading lines */ return(FALSE); /* return false to continue reading lines */
} }
void select_monitor() void select_monitor(void)
{ {
FileMon *fmon; FileMon *fmon;
for(fmon=filemonlist;fmon;fmon=fmon->next) for(fmon=filemonlist;fmon;fmon=fmon->next)
{
if (fmon->fd >= 0) if (fmon->fd >= 0)
{ {
FD_SET(fmon->fd,&read_fds); FD_SET(fmon->fd,&read_fds);
chkhigh(fmon->fd); chkhigh(fmon->fd);
} }
} }
}
void process_monitor() #ifdef DEBUG
extern const DEFstruct inomasks[];
#endif /* DEBUG */
void process_monitor(void)
{ {
FileMon *fmon; FileMon *fmon;
struct inotify_event *ivent; struct inotify_event *ivent;
#ifdef DEBUG
char tmp[256]; char tmp[256];
int n,m; int n;
#else
int n __notused__;
#endif /* DEBUG */
int m __notused__;
for(fmon=filemonlist;fmon;fmon=fmon->next) for(fmon=filemonlist;fmon;fmon=fmon->next)
{ {
if (fmon->fd >= 0 && FD_ISSET(fmon->fd,&read_fds)) if (fmon->fd < 0 || 0 == FD_ISSET(fmon->fd,&read_fds))
{ continue;
ivent = (struct inotify_event *)&globaldata; ivent = (struct inotify_event *)&globaldata;
n = read(fmon->fd,globaldata,sizeof(struct inotify_event)); n = read(fmon->fd,globaldata,sizeof(struct inotify_event));
@ -281,23 +247,19 @@ void process_monitor()
else else
*ivent->name = 0; *ivent->name = 0;
#ifdef DEBUG #ifdef DEBUG
debug("(process_monitor) ino %i, n %i, sz %i\n",fmon->fd,n,sizeof(in2str)); strflags(tmp,inomasks,ivent->mask);
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) ino {%i} %i bytes, wd = %i, mask = %s (%lu), cookie = %lu, len = %lu, name = %s\n",
debug("(process_monitor) %s\n",inomask2str(ivent->mask,tmp)); fmon->fd,n,ivent->wd,tmp,ivent->mask,ivent->cookie,ivent->len,ivent->name);
debug("(process_monitor) ino %i bytes read, int wd = %i, uint32_t mask = %s (%lu), " #endif /* DEBUG */
"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) if ((ivent->mask & IN_CLOSE_WRITE) == IN_CLOSE_WRITE)
return; return;
if (fmon->nospam > now-30) if (fmon->nospam > (cx.now - 30))
return; return;
fmon->nospam = now; fmon->nospam = cx.now;
send_global(SPYSTR_SYSMON,"Alert: file ``%s'' was touched",fmon->filename); send_global(SPYSTR_SYSMON,"Alert: file ``%s'' was touched",fmon->filename);
} }
} }
}
/*---------------------------------------------------------------------------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------------------------------------------------------------------------*/
@ -346,8 +308,8 @@ void do_meminfo(COMMAND_ARGS)
p = getpid(); p = getpid();
snprintf(fn,sizeof(fn),"/proc/%i/status",p); snprintf(fn,sizeof(fn),"/proc/%i/status",p);
for(i=0;sv[i].key;i++) for(i=0;statusvalues[i].key;i++)
*(sv[i].valbuf) = 0; *(statusvalues[i].valbuf) = 0;
if ((fd = open(fn,O_RDONLY)) < 0) if ((fd = open(fn,O_RDONLY)) < 0)
return; return;
readline(fd,&parse_proc_status); /* readline closes fd */ readline(fd,&parse_proc_status); /* readline closes fd */
@ -364,18 +326,9 @@ See also: hostinfo, meminfo
void do_cpuinfo(COMMAND_ARGS) void do_cpuinfo(COMMAND_ARGS)
{ {
char bogostr[256],cpustr[64]; char bogostr[256],cpustr[64];
char *a1,*a2,*a3,*dst; int fd;
int fd,n;
double loads[3]; 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) if ((fd = open("/proc/cpuinfo",O_RDONLY)) < 0)
#ifdef DEBUG #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; struct sockaddr_in sai;
int s; int s;
#ifdef IDWRAP
char *id,identfile[64];
int t = FALSE;
#endif /* IDWRAP */
#ifdef DEBUG #ifdef DEBUG
debug("(SockConnect) %s %i%s\n",nullstr(host),port,(use_vhost) ? " [VHOST]" : ""); 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)); memset((char*)&sai,0,sizeof(sai));
sai.sin_family = AF_INET; sai.sin_family = AF_INET;
/* if (use_vhost && ((current->vhost_type & VH_IPALIAS_FAIL) == 0)
* 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)
&& current->setting[STR_VIRTUAL].str_var) && current->setting[STR_VIRTUAL].str_var)
{ {
current->vhost_type |= VH_IPALIAS_BOTH; current->vhost_type |= VH_IPALIAS_BOTH;
@ -151,25 +138,12 @@ int SockConnect(char *host, int port, int use_vhost)
#ifdef WINGATE #ifdef WINGATE
use_vhost++; use_vhost++;
#endif /* WINGATE */ #endif /* WINGATE */
#ifdef IDWRAP
t = TRUE;
#endif /* IDWRAP */
#ifdef DEBUG #ifdef DEBUG
debug("(SockConnect) IP Alias virtual host bound OK\n"); debug("(SockConnect) IP Alias virtual host bound OK\n");
#endif /* DEBUG */ #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)); memset((char*)&sai,0,sizeof(sai));
sai.sin_family = AF_INET; sai.sin_family = AF_INET;
@ -204,29 +178,6 @@ int SockConnect(char *host, int port, int use_vhost)
/* /*
* Normal connect, no bounces... * 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); sai.sin_port = htons(port);
if ((sai.sin_addr.s_addr = get_ip(host)) == -1) 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) int SockAccept(int sock)
{ {
struct sockaddr_in sai; struct sockaddr_in sai;
int s,sz; unsigned int sz;
int s;
sz = sizeof(sai); sz = sizeof(sai);
s = accept(sock,(struct sockaddr*)&sai,&sz); 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 * Format a message and send it to the current bots server
* to_server needs a newline (\n) it wont manufacture it itself. * 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; va_list msg;
#ifdef DEBUG #ifdef DEBUG
char *line,*rest; char *line,*rest;
#endif /* DEBUG */ #endif /* DEBUG */
int sz;
if (current->sock == -1) if (current->sock == -1)
return; return;
va_start(msg,format); va_start(msg,format);
vsprintf(globaldata,format,msg); sz = vsprintf(globaldata,format,msg);
va_end(msg); va_end(msg);
/* /*
@ -323,7 +276,7 @@ void to_server(char *format, ...)
*/ */
current->sendq_time += 2; current->sendq_time += 2;
if (write(current->sock,globaldata,strlen(globaldata)) < 0) if (write(current->sock,globaldata,sz) < 0)
{ {
#ifdef DEBUG #ifdef DEBUG
debug("[StS] {%i} errno = %i\n",current->sock,errno); 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) if (STARTUP_ECHOTOCONSOLE)
{ {
int n; int n __notused__;
n = write(1,message,strlen(message)); n = write(1,message,strlen(message));
return; return;
} }
@ -497,6 +450,91 @@ void to_user(const char *target, const char *format, ...)
#endif /* DEBUG */ #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 */ #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 * 2: If <rest> data is insufficient, try to read in more
* 3: Try again to make a whole line * 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; char *src,*dst,*rdst;
int n; int n;
@ -515,7 +553,7 @@ char *sockread(int s, char *rest, char *line)
errno = EAGAIN; errno = EAGAIN;
src = rest; src = rest;
dst = line; dst = output;
while(*src) while(*src)
{ {
@ -525,20 +563,26 @@ char *sockread(int s, char *rest, char *line)
while(*src == '\n' || *src == '\r') while(*src == '\n' || *src == '\r')
src++; src++;
*dst = 0; *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; dst = rest;
while(*src) while(*src)
*(dst++) = *(src++); *(dst++) = *(src++);
*dst = 0; *dst = 0;
#if defined(DEBUG) && !defined(GENCMD_C) #if defined(DEBUG) && !defined(GENCMD_C)
debug("(in) {%i} %s\n",s,line); debug("(in) {%i} %s\n",socket,output);
#endif /* DEBUG */ #endif /* DEBUG */
return((*line) ? line : NULL); return((*output) ? output : NULL);
} }
*(dst++) = *(src++); *(dst++) = *(src++);
} }
rdst = src;
n = read(s,globaldata,MSGLEN-2); n = read(socket,globaldata,MSGLEN-2);
switch(n) switch(n)
{ {
case 0: case 0:
@ -547,14 +591,15 @@ char *sockread(int s, char *rest, char *line)
return(NULL); return(NULL);
} }
rdst = src;
globaldata[n] = 0; globaldata[n] = 0;
src = globaldata; src = globaldata;
while(*src) while(*src)
{ {
if (*src == '\r' || *src == '\n') if (*src == '\r' || *src == '\n')
goto gotline; goto gotline; /* gotline will move the rest of globaldata to rest */
if ((dst - line) >= (MSGLEN-2)) if ((dst - output) >= (MSGLEN-2))
{ {
/* /*
* line is longer than buffer, let the wheel spin * line is longer than buffer, let the wheel spin
@ -634,7 +679,7 @@ int killsock(int sock)
{ {
set_mallocdoer(killsock); set_mallocdoer(killsock);
ks = (KillSock*)Calloc(sizeof(KillSock)); ks = (KillSock*)Calloc(sizeof(KillSock));
ks->time = now; ks->time = cx.now;
ks->sock = sock; ks->sock = sock;
ks->next = killsocks; ks->next = killsocks;
killsocks = ks; killsocks = ks;
@ -686,7 +731,7 @@ int killsock(int sock)
if ((n == 0) || ((n == -1) && (errno != EAGAIN))) if ((n == 0) || ((n == -1) && (errno != EAGAIN)))
remove_ks(ks); remove_ks(ks);
} }
if ((now - ks->time) > KILLSOCKTIMEOUT) if ((cx.now - ks->time) > KILLSOCK_TIMEOUT)
remove_ks(ks); remove_ks(ks);
ks = ksnext; 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 = (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->t = t;
ir->when = now; ir->when = cx.now;
pt = stringcat(ir->from,from) + 1; pt = stringcat(ir->from,from) + 1;
if (nick) if (nick)

View File

@ -294,4 +294,4 @@ int main(int argc, char **argv)
return(0); 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 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 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 it under the terms of the GNU General Public License as published by
@ -51,7 +51,6 @@
#include "hostinfo.c" #include "hostinfo.c"
#include "io.c" #include "io.c"
#include "irc.c" #include "irc.c"
#include "lib/string.c"
#include "net.c" #include "net.c"
#include "note.c" #include "note.c"
#include "ons.c" #include "ons.c"
@ -67,6 +66,7 @@
#include "seen.c" #include "seen.c"
#include "shit.c" #include "shit.c"
#include "spy.c" #include "spy.c"
#include "string.c"
#include "tcl.c" #include "tcl.c"
#include "toybox.c" #include "toybox.c"
#include "uptime.c" #include "uptime.c"
@ -144,8 +144,8 @@ void mech_exec(void)
exit(1); exit(1);
} }
LS int r_ct; int r_ct;
LS char r_str[MSGLEN]; char r_str[MSGLEN];
int randstring_count(char *line) int randstring_count(char *line)
{ {
@ -199,7 +199,7 @@ char *randstring(const char *file)
* SIGUSR2 Call run_debug() (dump `everything' to a debug file) * SIGUSR2 Call run_debug() (dump `everything' to a debug file)
*/ */
LS struct struct
{ {
uint32_t sighup:1, uint32_t sighup:1,
sigint:1, sigint:1,
@ -209,7 +209,7 @@ LS struct
int sig_hup_callback(char *line) 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); return(FALSE);
} }
@ -221,7 +221,7 @@ void do_sighup(void)
CurrentShit = NULL; CurrentShit = NULL;
CurrentChan = NULL; CurrentChan = NULL;
CurrentUser = (User*)&CoreUser; CurrentUser = (User*)&cx.CoreUser;
CurrentDCC = (Client*)&CoreClient; CurrentDCC = (Client*)&CoreClient;
*CurrentNick = 0; *CurrentNick = 0;
@ -295,9 +295,6 @@ void do_sigusr1(void)
{ {
if (current->sock != -1) if (current->sock != -1)
{ {
#ifdef IDWRAP
unlink_identfile();
#endif /* IDWRAP */
close(current->sock); close(current->sock);
} }
current->sock = -1; current->sock = -1;
@ -324,7 +321,7 @@ void sig_usr1(int crap)
*/ */
void sig_usr2(int crap) void sig_usr2(int crap)
{ {
time(&now); time(&cx.now);
debug("(sigusr2)\n"); debug("(sigusr2)\n");
signal(SIGUSR2,sig_usr2); signal(SIGUSR2,sig_usr2);
@ -402,20 +399,20 @@ void sig_int(int signum)
* SIGILL, Illegal instruction * SIGILL, Illegal instruction
*/ */
#ifdef DEBUG #ifdef DEBUG
void sig_ill(int crap) void sig_ill(int crap)
{ {
debug("(sigill)\n"); debug("(sigill)\n");
} }
#endif /* DEBUG */
/* /*
* SIGABRT, abort(3) * SIGABRT, abort(3)
*/ */
#ifdef DEBUG
void sig_abrt(int crap) void sig_abrt(int crap)
{ {
debug("(sigabrt)\n"); debug("(sigabrt)\n");
} }
#endif /* DEBUG */ #endif /* DEBUG */
/* /*
@ -423,7 +420,7 @@ void sig_abrt(int crap)
*/ */
void sig_bus(int crap) void sig_bus(int crap)
{ {
time(&now); time(&cx.now);
respawn++; respawn++;
if (respawn > 10) if (respawn > 10)
@ -441,27 +438,42 @@ void sig_bus(int crap)
/* /*
* SIGSEGV shows no mercy, cant schedule it. * 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> #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; ucontext_t *crashcontext = (ucontext_t*)context;
greg_t *rsp,*rip; /* general registers */ char *sp,*ip; /* general registers */
time(&now);
startup = STARTUP_SIGSEGV; startup = STARTUP_SIGSEGV;
debug("(sigsegv) trying to access "mx_pfmt"\n",(mx_ptr)si->si_addr); #if defined(__x86_64__)
mctx = &((ucontext_t *)uap)->uc_mcontext; ip = (char*)crashcontext->uc_mcontext.gregs[16];
rsp = &mctx->gregs[15]; /* RSP, 64-bit stack pointer */ sp = (char*)crashcontext->uc_mcontext.gregs[15];
rip = &mctx->gregs[16]; /* RIP, 64-bit instruction pointer */ #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) sig_segv() = "mx_pfmt"\n",(mx_ptr)sig_segv);
debug("(sigsegv) do_crash() = "mx_pfmt"\n",(mx_ptr)do_crash); debug("(sigsegv) do_crash() = "mx_pfmt"\n",(mx_ptr)do_crash);
if (debug_on_exit) if (debug_on_exit)
{ {
time(&cx.now);
run_debug(); run_debug();
debug_on_exit = FALSE; debug_on_exit = FALSE;
} }
@ -475,11 +487,11 @@ void sig_segv(int crap, siginfo_t *si, void *uap)
/* NOT REACHED */ /* 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) void sig_segv(int signum)
{ {
time(&now); startup = STARTUP_SIGSEGV;
#ifdef DEBUG #ifdef DEBUG
if (debug_on_exit) if (debug_on_exit)
@ -498,7 +510,7 @@ void sig_segv(int signum)
/* NOT REACHED */ /* NOT REACHED */
} }
#endif /* else defined(__linux__) && defined(__x86_64__) && defined(DEBUG) && !defined(__STRICT_ANSI__) */ #endif /* else defined(__linux__) && defined(DEBUG) && !defined(__STRICT_ANSI__) */
/* /*
* SIGTERM * SIGTERM
@ -509,8 +521,6 @@ void sig_term(int signum)
exit(0); exit(0);
#endif /* __profiling__ */ #endif /* __profiling__ */
time(&now);
#ifdef DEBUG #ifdef DEBUG
debug("(sigterm)\n"); debug("(sigterm)\n");
#endif /* DEBUG */ #endif /* DEBUG */
@ -525,25 +535,23 @@ void sig_term(int signum)
* *
*/ */
#ifdef __GNUC__ void mainloop(void)
LS void doit(void) __attribute__ ((__noreturn__, __sect(CORE_SEG)));
#endif
void doit(void)
{ {
struct timeval tv; SequenceTime this;
Chan *chan; Chan *chan;
Client *client; Client *client;
SequenceTime this;
Strp *qm; Strp *qm;
struct timeval tv;
time_t last_update; time_t last_update;
last_update = now;
last_update = cx.now;
/* /*
* init update times so that they dont all run right away * init update times so that they dont all run right away
*/ */
this.tenminute = now / 600; this.tenminute = cx.now / 600;
this.hour = now / 3600; this.hour = cx.now / 3600;
/* /*
* The Main Loop * The Main Loop
@ -569,15 +577,15 @@ mainloop:
/* /*
* check for regular updates * check for regular updates
*/ */
if (last_update != now) if (last_update != cx.now)
{ {
last_update = now; last_update = cx.now;
update(&this); update(&this);
} }
FD_ZERO(&read_fds); FD_ZERO(&read_fds);
FD_ZERO(&write_fds); FD_ZERO(&write_fds);
hisock = -1; cx.hisock = -1;
#ifdef BOTNET #ifdef BOTNET
select_botnet(); select_botnet();
@ -602,7 +610,7 @@ mainloop:
/* /*
* unset here, reset if needed in bot loop * 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) for(current=botlist;current;current=current->next)
{ {
if (current->sock == -1) if (current->sock == -1)
@ -615,7 +623,7 @@ mainloop:
if ((sp = find_server(current->server))) if ((sp = find_server(current->server)))
{ {
if ((now - current->conntry) > ctimeout) if ((cx.now - current->conntry) > ctimeout)
{ {
#ifdef DEBUG #ifdef DEBUG
debug("(doit) RAWDNS timed out (%s)\n",sp->name); debug("(doit) RAWDNS timed out (%s)\n",sp->name);
@ -641,27 +649,27 @@ mainloop:
{ {
if (current->connect == CN_SPINNING) if (current->connect == CN_SPINNING)
{ {
if ((now - current->conntry) >= 60) if ((cx.now - current->conntry) >= 60)
connect_to_server(); connect_to_server();
} }
else else
{ {
doit_jumptonext: doit_jumptonext:
short_tv |= TV_SERVCONNECT; cx.short_tv |= TV_SERVCONNECT;
if ((now - current->conntry) >= 2) if ((cx.now - current->conntry) >= 2)
connect_to_server(); connect_to_server();
} }
} }
#else /* ! RAWDNS */ #else /* ! RAWDNS */
if (current->connect == CN_SPINNING) if (current->connect == CN_SPINNING)
{ {
if ((now - current->conntry) >= 60) if ((cx.now - current->conntry) >= 60)
connect_to_server(); connect_to_server();
} }
else else
{ {
short_tv |= TV_SERVCONNECT; cx.short_tv |= TV_SERVCONNECT;
if ((now - current->conntry) >= 2) if ((cx.now - current->conntry) >= 2)
connect_to_server(); connect_to_server();
} }
#endif /* RAWDNS */ #endif /* RAWDNS */
@ -672,7 +680,7 @@ doit_jumptonext:
if (current->ip.s_addr == 0) if (current->ip.s_addr == 0)
{ {
struct sockaddr_in sai; struct sockaddr_in sai;
int sz; unsigned int sz;
sz = sizeof(sai); sz = sizeof(sai);
if (getsockname(current->sock,(struct sockaddr *)&sai,&sz) == 0) if (getsockname(current->sock,(struct sockaddr *)&sai,&sz) == 0)
@ -680,15 +688,12 @@ doit_jumptonext:
} }
if ((current->connect == CN_TRYING) || (current->connect == CN_CONNECTED)) if ((current->connect == CN_TRYING) || (current->connect == CN_CONNECTED))
{ {
short_tv |= TV_SERVCONNECT; cx.short_tv |= TV_SERVCONNECT;
if ((now - current->conntry) > ctimeout) if ((cx.now - current->conntry) > ctimeout)
{ {
#ifdef DEBUG #ifdef DEBUG
debug("(doit) {%i} Connection timed out\n",current->sock); debug("(doit) {%i} Connection timed out\n",current->sock);
#endif /* DEBUG */ #endif /* DEBUG */
#ifdef IDWRAP
unlink_identfile();
#endif /* IDWRAP */
close(current->sock); close(current->sock);
current->sock = -1; current->sock = -1;
goto restart_dcc; goto restart_dcc;
@ -698,7 +703,7 @@ doit_jumptonext:
} }
if (current->sendq) if (current->sendq)
{ {
short_tv |= TV_LINEBUF; cx.short_tv |= TV_LINEBUF;
} }
else else
{ {
@ -706,7 +711,7 @@ doit_jumptonext:
{ {
if (chan->kicklist || chan->modelist) if (chan->kicklist || chan->modelist)
{ {
short_tv |= TV_LINEBUF; cx.short_tv |= TV_LINEBUF;
break; break;
} }
} }
@ -752,19 +757,19 @@ restart_dcc:
* Longer delay saves CPU but some features require shorter delays * Longer delay saves CPU but some features require shorter delays
*/ */
#ifdef NOTIFY #ifdef NOTIFY
tv.tv_sec = (short_tv) ? 1 : 5; tv.tv_sec = (cx.short_tv) ? 1 : 5;
#else /* NOTIFY */ #else /* NOTIFY */
tv.tv_sec = (short_tv) ? 1 : 30; tv.tv_sec = (cx.short_tv) ? 1 : 30;
#endif /* NOTIFY */ #endif /* NOTIFY */
tv.tv_usec = 0; 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; goto mainloop;
/* /*
* Update current time * Update current time
*/ */
time(&now); time(&cx.now);
for(current=botlist;current;current=current->next) for(current=botlist;current;current=current->next)
{ {
@ -773,8 +778,8 @@ restart_dcc:
* it is important that the check is done before anything * it is important that the check is done before anything
* else that could potentially send output to the server! * else that could potentially send output to the server!
*/ */
if (current->sendq_time < now) if (current->sendq_time < cx.now)
current->sendq_time = now; current->sendq_time = cx.now;
} }
for(current=botlist;current;current=current->next) for(current=botlist;current;current=current->next)
@ -785,6 +790,18 @@ restart_dcc:
if (current->sock != -1) if (current->sock != -1)
process_server_input(); 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) if (current->connect == CN_ONLINE)
{ {
/* /*
@ -792,10 +809,10 @@ restart_dcc:
*/ */
if (current->setting[TOG_NOIDLE].int_var) if (current->setting[TOG_NOIDLE].int_var)
{ {
if ((now - current->lastantiidle) > PINGSENDINTERVAL) if ((cx.now - current->lastantiidle) > PINGSENDINTERVAL)
{ {
to_server("PRIVMSG * :0\n"); 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 * 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; qm = current->sendq;
to_server(FMT_PLAINLINE,qm->p); to_server(FMT_PLAINLINE,qm->p);
@ -857,6 +874,7 @@ restart_die:
#endif /* BOTNET */ #endif /* BOTNET */
#ifdef BOUNCE #ifdef BOUNCE
if (bounce_sock != -1 || bnclist)
process_bounce(); process_bounce();
#endif /* BOUNCE */ #endif /* BOUNCE */
@ -865,6 +883,10 @@ restart_die:
#endif /* CHANBAN */ #endif /* CHANBAN */
#ifdef RAWDNS #ifdef RAWDNS
/*
* Only a single socket to check.
*/
if (dnssock != -1 && FD_ISSET(dnssock,&read_fds))
process_rawdns(); process_rawdns();
#endif /* RAWDNS */ #endif /* RAWDNS */
@ -881,6 +903,7 @@ restart_die:
#endif #endif
#ifdef TRIVIA #ifdef TRIVIA
if (triv_next_time && (cx.now >= triv_next_time))
trivia_tick(); trivia_tick();
#endif /* TRIVIA */ #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__ void parse_commandline(int argc, char **argv, char **envp)
int main(int argc, char **argv, char **envp) __attribute__ ((__sect(INIT_SEG)));
#endif
int main(int argc, char **argv, char **envp)
{ {
struct stat st; struct stat st;
char *opt; char *opt;
@ -911,8 +931,9 @@ int main(int argc, char **argv, char **envp)
#ifdef NEWBIE #ifdef NEWBIE
int n = 0; int n = 0;
#endif #endif
memset(&cx,0,sizeof(cx));
uptime = time(&now); uptime = time(&cx.now);
startup = STARTUP_NORMALSTART; startup = STARTUP_NORMALSTART;
if ((getuid() == 0) || (geteuid() == 0)) if ((getuid() == 0) || (geteuid() == 0))
@ -924,7 +945,12 @@ int main(int argc, char **argv, char **envp)
stat("..",&st); stat("..",&st);
parent_inode = st.st_ino; /* used for is_safepath() */ 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 * Code to detect and recover after a RESET
@ -961,6 +987,7 @@ int main(int argc, char **argv, char **envp)
} }
#ifdef DEBUG #ifdef DEBUG
/* memory tracking */
mrrec = calloc(sizeof(aMEA),1); mrrec = calloc(sizeof(aMEA),1);
#endif /* DEBUG */ #endif /* DEBUG */
@ -969,7 +996,7 @@ int main(int argc, char **argv, char **envp)
to_file(1,bad_exe); to_file(1,bad_exe);
_exit(1); _exit(1);
} }
if ((opt = STRCHR(*argv,' ')) != NULL) if ((opt = stringchr(*argv,' ')) != NULL)
{ {
*(opt++) = 0; *(opt++) = 0;
respawn = asc2int(opt); respawn = asc2int(opt);
@ -989,66 +1016,26 @@ int main(int argc, char **argv, char **envp)
opt = *argv; opt = *argv;
switch(opt[1]) 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': case 'c':
makecore = TRUE; makecore = TRUE;
break; break;
#ifdef DEBUG #ifdef DEBUG
case 'd': case 'd':
dodebug = TRUE; dodebug = TRUE;
do_fork = FALSE; do_fork = TRUE;
break; if (opt[2] != 0) /* -d[file] */
case 'o':
if (opt[2] != 0)
{ {
debugfile = &opt[2]; debugfile = &opt[2];
} }
else else
if (argv[1] && argv[1][0] != '-') /* -d [file] */
{ {
++argv; ++argv;
if (!*argv)
{
to_file(1,"init: No debugfile specified\n");
_exit(0);
}
debugfile = *argv; debugfile = *argv;
argc--; argc--;
} }
do_fork = TRUE;
break;
case 'p':
++argv;
if (*argv)
to_file(1,"%s\n",makepass(*argv));
else else
to_file(1,"error: Missing argument for -p <string>\n"); do_fork = FALSE;
_exit(0);
case 'X':
debug_on_exit = TRUE;
break; break;
#endif /* DEBUG */ #endif /* DEBUG */
case 'e': /* run a single command before exiting */ case 'e': /* run a single command before exiting */
@ -1062,9 +1049,6 @@ int main(int argc, char **argv, char **envp)
else else
to_file(1,"error: Missing argument for -e <command string>\n"); to_file(1,"error: Missing argument for -e <command string>\n");
_exit(0); _exit(0);
case 't':
startup = STARTUP_TESTRUN;
break;
case 'f': case 'f':
if (opt[2] != 0) if (opt[2] != 0)
{ {
@ -1083,15 +1067,49 @@ int main(int argc, char **argv, char **envp)
} }
to_file(1,INFO_USINGCONF,configfile); to_file(1,INFO_USINGCONF,configfile);
break; 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: default:
to_file(1,ERR_UNKNOWNOPT,opt); to_file(1,ERR_UNKNOWNOPT,opt);
_exit(1); _exit(1);
} }
} }
servergrouplist = (ServerGroup*)&defaultServerGroup;
currentservergroup = (ServerGroup*)&defaultServerGroup;
if (!mechresetenv) if (!mechresetenv)
{ {
to_file(1,TEXT_HDR_VERS,VERSION,SRCDATE); 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"); to_file(1,"warning: current configuration file overrides session file\n");
} }
#endif /* SESSION */ #endif /* SESSION */
if (stat(configfile,&st)); if (stat(configfile,&st))
{ {
if ((st.st_mode & (S_IWGRP|S_IWOTH)) != 0) 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) if ((st.st_mode & (S_IRGRP|S_IROTH)) != 0)
to_file(1,"warning: configfile is readable by others\n"); 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) 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; ia_default.s_addr = LOCALHOST_ULONG;
#endif /* RAWDNS */ #endif /* RAWDNS */
memset(&__internal_users,0,sizeof(User)*2); cx.CoreUser.x.x.access = 100;
CoreUser.x.x.access = 100; cx.LocalBot.x.x.access = 200;
LocalBot.x.x.access = 200; cx.LocalBot.x.x.aop = 1;
LocalBot.x.x.aop = 1; cx.LocalBot.chan = cx.CoreUser.chan = (Strp*)&CMA;
LocalBot.chan = CoreUser.chan = (Strp*)&CMA;
readcfgfile(); readcfgfile();
@ -1182,7 +1199,7 @@ int main(int argc, char **argv, char **envp)
} }
#else #else
{ {
if (stat(opt,&st)); if (stat(opt,&st))
{ {
if ((st.st_mode & (S_IWGRP|S_IWOTH)) != 0) 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) 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++; n++;
} }
} }
@ -1252,7 +1272,7 @@ int main(int argc, char **argv, char **envp)
#endif /* CTCP */ #endif /* CTCP */
#ifdef BOTNET #ifdef BOTNET
last_autolink = now + 30 + (rand() >> 27); /* + 0-31 seconds */ last_autolink = cx.now + 30 + (rand() >> 27); /* + 0-31 seconds */
#endif /* BOTNET */ #endif /* BOTNET */
if (mechresetenv) if (mechresetenv)
@ -1296,7 +1316,16 @@ int main(int argc, char **argv, char **envp)
} }
startup = STARTUP_RUNNING; startup = STARTUP_RUNNING;
#ifdef DEBUG #ifdef DEBUG
debug("(main) entering doit()...\n"); debug("(main) entering main loop...\n");
#endif #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 #ifdef TELNET
char *telnetprompt = TEXT_ENTERNICKNAME; char *telnetprompt = TEXT_ENTERNICKNAME;
#endif /* TELNET */ #endif /* TELNET */
/* /*
* this is a partial copy of the BotNet struct * this is a partial copy of the BotNet struct
*/ */
LS struct struct
{ {
struct BotNet *next; struct BotNet *next;
@ -73,7 +74,7 @@ typedef struct LinkCmd
#define RELAY_YES 1 #define RELAY_YES 1
#define RELAY_NO 0 #define RELAY_NO 0
LS const LinkCmd basicProto[] = const LinkCmd basicProto[] =
{ {
{ "BA", basicAuth, RELAY_NO }, { "BA", basicAuth, RELAY_NO },
{ "BB", basicBanner, RELAY_NO }, { "BB", basicBanner, RELAY_NO },
@ -95,7 +96,7 @@ LS const LinkCmd basicProto[] =
{ "\0\0", NULL, RELAY_NO }, { "\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 *make_botinfo(int guid, int hops, char *nuh, char *server, char *version)
{ {
BotInfo *new; BotInfo *newbinfo;
set_mallocdoer(make_botinfo); 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; newbinfo->guid = guid;
new->hops = hops; newbinfo->hops = hops;
new->server = stringcat(new->nuh,nuh) + 1; newbinfo->server = stringcat(newbinfo->nuh,nuh) + 1;
new->version = stringcat(new->server,server) + 1; newbinfo->version = stringcat(newbinfo->server,server) + 1;
stringcpy(new->version,version); stringcpy(newbinfo->version,version);
return(new); return(newbinfo);
} }
/*
* broadcast data to all except the source
*/
void botnet_relay(BotNet *source, char *format, ...) void botnet_relay(BotNet *source, char *format, ...)
{ {
BotNet *bn; BotNet *bn;
@ -188,9 +192,8 @@ void botnet_relay(BotNet *source, char *format, ...)
if (!sz) if (!sz)
{ {
va_start(msg,format); va_start(msg,format);
vsprintf(globaldata,format,msg); sz = vsprintf(globaldata,format,msg);
va_end(msg); va_end(msg);
sz = strlen(globaldata);
} }
if (write(bn->sock,globaldata,sz) < 0) 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) 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->nuh) ? binfo->nuh : UNKNOWNATUNKNOWN,
(binfo->server) ? binfo->server : UNKNOWN, (binfo->server) ? binfo->server : UNKNOWN,
(binfo->version) ? binfo->version : "-"); (binfo->version) ? binfo->version : "-");
@ -225,12 +215,27 @@ void botnet_binfo_relay(BotNet *source, BotInfo *binfo)
void botnet_binfo_tofile(int sock, 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->nuh) ? binfo->nuh : UNKNOWNATUNKNOWN,
(binfo->server) ? binfo->server : UNKNOWN, (binfo->server) ? binfo->server : UNKNOWN,
(binfo->version) ? binfo->version : "-"); (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) void botnet_dumplinklist(BotNet *bn)
{ {
BotInfo *binfo; BotInfo *binfo;
@ -248,14 +253,14 @@ void botnet_dumplinklist(BotNet *bn)
*/ */
sv = find_server(bot->server); sv = find_server(bot->server);
to_file(bn->sock,"BL%i %c %s!%s %s:%i %s %s\n",bot->guid, to_file(bn->sock,"BL%i %c %s!%s %s:%i %s %s\n",bot->guid,
(bot == bn->controller) ? '0' : '1',bot->nick, (bot == bn->controller) ? '0' : '1',getbotnick(bot),
(bot->userhost) ? bot->userhost : UNKNOWNATUNKNOWN, getbotuserhost(bot),
(sv) ? ((*sv->realname) ? sv->realname : sv->name) : UNKNOWN, (sv) ? ((*sv->realname) ? sv->realname : sv->name) : UNKNOWN,
(sv) ? sv->port : 0,BOTCLASS,VERSION); (sv) ? sv->port : 0,BOTCLASS,VERSION);
} }
for(bn2=botnetlist;bn2;bn2=bn2->next) 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; continue;
for(binfo=bn2->botinfo;binfo;binfo=binfo->next) for(binfo=bn2->botinfo;binfo;binfo=binfo->next)
botnet_binfo_tofile(bn->sock,binfo); botnet_binfo_tofile(bn->sock,binfo);
@ -289,7 +294,7 @@ int connect_to_bot(NetCfg *cfg)
bn->sock = s; bn->sock = s;
bn->status = BN_CONNECT; bn->status = BN_CONNECT;
bn->when = now; bn->when = cx.now;
bn->guid = cfg->guid; bn->guid = cfg->guid;
bn->next = botnetlist; bn->next = botnetlist;
@ -409,7 +414,7 @@ void basicAuth(BotNet *bn, char *rest)
{ {
case BNAUTH_PLAINTEXT: case BNAUTH_PLAINTEXT:
/* /*
>> plain text given: "DomoOmiGato" stored "kooplook0988" >> plain text given: "DomoOmiGato" stored "........."
(reset_linkable) guid 1337 reset to linkable (reset_linkable) guid 1337 reset to linkable
(basicAuth) bad password [ guid = 1337 ] (basicAuth) bad password [ guid = 1337 ]
*/ */
@ -420,6 +425,12 @@ void basicAuth(BotNet *bn, char *rest)
goto badpass; goto badpass;
break; break;
#ifdef SHACRYPT #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: case BNAUTH_SHA:
{ {
char *enc,temppass[24 + Strlen2(pass,linkpass)]; /* linkpass is never NULL */ 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"); debug("(basicAuth) bn->tick = 0\n");
#endif /* DEBUG */ #endif /* DEBUG */
bn->tick = 0; 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) void basicAuthOK(BotNet *bn, char *rest)
@ -490,7 +501,7 @@ void basicAuthOK(BotNet *bn, char *rest)
debug("(basicAuthOK) bn->tick = 0\n"); debug("(basicAuthOK) bn->tick = 0\n");
#endif /* DEBUG */ #endif /* DEBUG */
bn->tick = 0; 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) void basicBanner(BotNet *bn, char *rest)
@ -608,7 +619,7 @@ void basicBanner(BotNet *bn, char *rest)
/* /*
* update timestamp * update timestamp
*/ */
bn->when = now; bn->when = cx.now;
/* /*
* if the remote bot initiated the connection we need a valid pass from them * 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) void basicLink(BotNet *bn, char *version)
{ {
BotInfo *binfo,*delete,**pp; BotInfo *binfo,**pp;
NetCfg *cfg; NetCfg *cfg;
char *nuh,*server; char *nuh,*server;
int guid,hops; int guid,hops;
@ -748,7 +759,7 @@ void basicLink(BotNet *bn, char *version)
continue; continue;
cfg->linked = TRUE; cfg->linked = TRUE;
} }
bn->list_complete = TRUE; bn->opt.links_complete = TRUE;
return; return;
} }
@ -774,23 +785,25 @@ void basicLink(BotNet *bn, char *version)
binfo = make_botinfo(guid,hops,nuh,server,version); binfo = make_botinfo(guid,hops,nuh,server,version);
if (bn->botinfo == NULL) 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; pp = &bn->botinfo;
while(*pp) while(*pp)
{ {
delete = *pp; BotInfo *trash;
if (guid == delete->guid) if (guid == (*pp)->guid)
{ {
*pp = delete->next; trash = *pp;
Free((char**)&delete); *pp = trash->next;
Free((char**)&trash);
break; break;
} }
pp = &delete->next; pp = &(*pp)->next;
} }
binfo->next = *pp; binfo->next = *pp;
*pp = binfo; *pp = binfo;
if (bn->list_complete) if (bn->opt.links_complete)
{ {
if ((cfg = find_netcfg(guid))) if ((cfg = find_netcfg(guid)))
cfg->linked = TRUE; cfg->linked = TRUE;
@ -904,10 +917,10 @@ void partyAuth(BotNet *bn, char *rest)
{ {
User *user; User *user;
Strp *ump; Strp *ump;
char *name,*userhost,*checksum; char *userhost,*checksum;
int m; int m;
name = chop(&rest); chop(&rest);
userhost = chop(&rest); userhost = chop(&rest);
if ((checksum = chop(&rest)) == NULL) if ((checksum = chop(&rest)) == NULL)
checksum = ""; checksum = "";
@ -987,7 +1000,7 @@ int commandlocal(int dg, int sg, char *from, char *command)
*p2 = current->setting[CHR_CMDCHAR].char_var; *p2 = current->setting[CHR_CMDCHAR].char_var;
stringcpy((*p2 == *command) ? p2 : p2+1,command); stringcpy((*p2 == *command) ? p2 : p2+1,command);
on_msg(p1,current->nick,p2); on_msg(p1,getbotnick(current),p2);
CurrentDCC = NULL; CurrentDCC = NULL;
} }
if (dg == -1) if (dg == -1)
@ -1198,7 +1211,7 @@ void ushareUser(BotNet *bn, char *rest)
bn->addsession = 0; bn->addsession = 0;
bn->tick++; bn->tick++;
to_file(bn->sock,"UT%i\n",bn->tick); to_file(bn->sock,"UT%i\n",bn->tick);
bn->tick_last = now; bn->tick_last = cx.now;
break; break;
case '*': case '*':
case '#': case '#':
@ -1319,10 +1332,8 @@ void ushareTick(BotNet *bn, char *rest)
void ushareDelete(BotNet *bn, char *rest) void ushareDelete(BotNet *bn, char *rest)
{ {
User *user; User *user;
char *orig;
int modcount; int modcount;
orig = rest;
modcount = asc2int(chop(&rest)); modcount = asc2int(chop(&rest));
if (errno) if (errno)
return; return;
@ -1417,7 +1428,7 @@ void botnet_newsock(void)
bn->sock = s; bn->sock = s;
bn->status = BN_UNKNOWN; bn->status = BN_UNKNOWN;
bn->lsid = rand(); bn->lsid = rand();
bn->when = now; bn->when = cx.now;
bn->next = botnetlist; bn->next = botnetlist;
botnetlist = bn; botnetlist = bn;
@ -1425,7 +1436,7 @@ void botnet_newsock(void)
/* /*
* crude... but, should work * crude... but, should work
*/ */
last_autolink = now + AUTOLINK_DELAY; last_autolink = cx.now + AUTOLINK_DELAY;
} }
/* /*
@ -1455,9 +1466,9 @@ void select_botnet(void)
/* /*
* autolink * 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) if (autolink_cfg)
autolink_cfg = autolink_cfg->next; 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) for(bn=botnetlist;bn;bn=bn->next)
{ {
chkhigh(bn->sock); chkhigh(bn->sock);
if (bn->status == BN_CONNECT) if (bn->status == BN_CONNECT)
{ {
FD_SET(bn->sock,&write_fds); FD_SET(bn->sock,&write_fds);
short_tv |= TV_BOTNET; cx.short_tv |= TV_BOTNET;
} }
else else
{ {
@ -1502,12 +1513,12 @@ void process_botnet(void)
/* /*
* usersharing tick, 10 minute period * 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 #ifdef DEBUG
debug("(process_botnet) {%i} periodic ushare tick\n",bn->sock); debug("(process_botnet) {%i} periodic ushare tick\n",bn->sock);
#endif /* DEBUG */ #endif /* DEBUG */
bn->tick_last = now; bn->tick_last = cx.now;
to_file(bn->sock,"UT%i\n",bn->tick); to_file(bn->sock,"UT%i\n",bn->tick);
} }
@ -1531,7 +1542,7 @@ void process_botnet(void)
else else
{ {
bn->status = BN_BANNERSENT; bn->status = BN_BANNERSENT;
bn->when = now; bn->when = cx.now;
} }
/* write_fds is only set for sockets where reading is not needed */ /* write_fds is only set for sockets where reading is not needed */
continue; 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 #ifdef DEBUG
debug("(process_botnet) {%i} Life is good; but not for this guy (guid == %i). Timeout!\n", 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", debug("(process_botnet) botnet quit: guid %i child of %i on socket %i\n",
binfo->guid,bn->guid,bn->sock); binfo->guid,bn->guid,bn->sock);
#endif /* DEBUG */ #endif /* DEBUG */
if (bn->list_complete) if (bn->opt.links_complete)
{ {
send_global(SPYSTR_BOTNET,"quit: guid %i (child of %i)", send_global(SPYSTR_BOTNET,"quit: guid %i (child of %i)",
binfo->guid,bn->guid); binfo->guid,bn->guid);
@ -1620,7 +1631,7 @@ clean:
} }
Free((char**)&binfo); Free((char**)&binfo);
} }
if (bn->list_complete) if (bn->opt.links_complete)
{ {
botnet_relay(bn,"BQ%i\n",bn->guid); 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) void do_link(COMMAND_ARGS)
{ {
/* /*
@ -1649,21 +1676,6 @@ void do_link(COMMAND_ARGS)
int iguid,iport; int iguid,iport;
int mode; 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); guid = chop(&rest);
if (*guid == '+' || *guid == '-') if (*guid == '+' || *guid == '-')
mode = *guid++; mode = *guid++;
@ -1686,7 +1698,7 @@ usage:
pp = &cfg->next; pp = &cfg->next;
} }
if (CurrentUser == &CoreUser || mode == '+') if (CurrentUser == &cx.CoreUser || mode == '+')
{ {
if (cfg) if (cfg)
{ {
@ -1726,6 +1738,7 @@ usage:
if (mode == '-') if (mode == '-')
{ {
to_user(from,"removing link guid: %i",iguid);
*pp = cfg->next; *pp = cfg->next;
Free((char**)&cfg); Free((char**)&cfg);
return; return;
@ -1759,10 +1772,9 @@ void do_cmd(COMMAND_ARGS)
Mech *backup; Mech *backup;
char tempdata[MAXLEN]; char tempdata[MAXLEN];
char *target,*orig = rest; char *target,*orig = rest;
int guid;
target = chop(&rest); target = chop(&rest);
guid = asc2int(target); asc2int(target);
if (errno) if (errno)
{ {
unchop(orig,rest); unchop(orig,rest);
@ -1776,7 +1788,7 @@ void do_cmd(COMMAND_ARGS)
return; return;
} }
if (STRCHR(from,'!')) if (stringchr(from,'!'))
sprintf(tempdata,"%s %i %s %s",target,current->guid,from,rest); sprintf(tempdata,"%s %i %s %s",target,current->guid,from,rest);
else else
sprintf(tempdata,"%s %i %s!%s %s",target,current->guid,from,CurrentUser->mask->p,rest); 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; User *u;
Note *n,**pp; Note *n,**pp;
Strp *sp,**np;
#ifdef DEBUG #ifdef DEBUG
debug("(catch_note) from = %s, to = %s, rest = %s\n",from,to,rest); 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); append_strp(&u->note,rest);
return(TRUE); return(TRUE);
} }
if ((now - n->start) > 120) if ((cx.now - n->start) > 120)
{ {
*pp = n->next; *pp = n->next;
Free((char**)&n); Free((char**)&n);
@ -85,7 +84,6 @@ void do_note(COMMAND_ARGS)
{ {
User *u; User *u;
Note *n; Note *n;
Strp *sp,**np;
char header[MSGLEN]; char header[MSGLEN];
/* /*
@ -101,7 +99,7 @@ void do_note(COMMAND_ARGS)
set_mallocdoer(do_note); set_mallocdoer(do_note);
n = Calloc(sizeof(Note) + StrlenX(from,to,u->name,NULL)); n = Calloc(sizeof(Note) + StrlenX(from,to,u->name,NULL));
n->start = now; n->start = cx.now;
n->next = notelist; n->next = notelist;
notelist = n; notelist = n;
@ -112,7 +110,7 @@ void do_note(COMMAND_ARGS)
/* /*
* add a note header * 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); 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);
}

218
src/ons.c
View File

@ -1,7 +1,7 @@
/* /*
EnergyMech, IRC bot software 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 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 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) if (current->spy & SPYF_CHANNEL)
send_spy(chan->name,"*** %s was kicked by %s (%s)",nick,CurrentNick,rest); 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 #ifdef DEBUG
debug("(on_kick) I was kicked from %s\n",chan->name); debug("(on_kick) I was kicked from %s\n",chan->name);
@ -168,7 +168,7 @@ void on_kick(char *from, char *rest)
if (victim) if (victim)
{ {
#ifdef SEEN #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 */ #endif /* SEEN */
/* /*
@ -231,7 +231,7 @@ void on_join(Chan *chan, char *from)
*/ */
if (chan->setting[TOG_CTL].int_var) 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); deop_siteban(chan,cu);
send_kick(chan,CurrentNick,KICK_BAD_IDENT); send_kick(chan,CurrentNick,KICK_BAD_IDENT);
@ -290,8 +290,8 @@ void on_nick(char *from, char *newnick)
* grab the nick *RIGHT NOW* * grab the nick *RIGHT NOW*
* this is a setting because this is risky, you might get collided as a result * this is a setting because this is risky, you might get collided as a result
*/ */
if (!nickcmp(CurrentNick,current->wantnick)) if (!nickcmp(CurrentNick,getbotwantnick(current)))
to_server("NICK %s\n",current->wantnick); to_server("NICK %s\n",getbotwantnick(current));
#endif /* FASTNICK */ #endif /* FASTNICK */
/* /*
@ -300,7 +300,7 @@ void on_nick(char *from, char *newnick)
sprintf(newnuh,"%s!%s",newnick,getuh(from)); sprintf(newnuh,"%s!%s",newnick,getuh(from));
#ifdef SEEN #ifdef SEEN
make_seen(CurrentNick,from,newnick,NULL,now,SEEN_NEWNICK); make_seen(CurrentNick,from,newnick,NULL,cx.now,SEEN_NEWNICK);
#endif /* SEEN */ #endif /* SEEN */
/* /*
@ -311,9 +311,12 @@ void on_nick(char *from, char *newnick)
change_authnick(from,newnuh); change_authnick(from,newnuh);
if ((isbot = !nickcmp(current->nick,CurrentNick))) if ((isbot = !nickcmp(getbotnick(current),CurrentNick)))
{ {
setbotnick(current,newnick); setbotnick(current,newnick);
#ifdef BOTNET
botnet_refreshbotinfo();
#endif /* BOTNET */
} }
for(chan=current->chanlist;chan;chan=chan->next) 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) if ((maxcount = chan->setting[INT_NCL].int_var) < 2)
continue; 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; cu->action_num[INDEX_NICK] = 1;
} }
else else
@ -372,6 +375,8 @@ void on_nick(char *from, char *newnick)
} }
} }
#include "onhash.h"
void on_msg(char *from, char *to, char *rest) void on_msg(char *from, char *to, char *rest)
{ {
#ifdef SCRIPTING #ifdef SCRIPTING
@ -389,7 +394,7 @@ void on_msg(char *from, char *to, char *rest)
uchar *p1,*p2; uchar *p1,*p2;
int has_cc,has_bang; int has_cc,has_bang;
int uaccess; int uaccess;
int i,j; int i,j,command_hash;
/* /*
* No line sent to this routine should be longer than MSGLEN * 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 * non-NULL and non-zerolength
*/ */
/*
* remember where the string started
*/
origstart = rest;
/*
* Are we recording a note?
*/
#ifdef NOTE #ifdef NOTE
if (notelist && catch_note(from,to,rest)) if (notelist && catch_note(from,to,rest))
return; return;
@ -407,10 +420,7 @@ void on_msg(char *from, char *to, char *rest)
* public commands, we can go directly to common_public() * public commands, we can go directly to common_public()
*/ */
if (CurrentChan && !CurrentChan->setting[TOG_PUB].int_var) if (CurrentChan && !CurrentChan->setting[TOG_PUB].int_var)
{ goto public_msg_unchopped;
common_public(CurrentChan,from,"<%s> %s",rest);
return;
}
if (CurrentDCC) if (CurrentDCC)
{ {
@ -425,12 +435,8 @@ void on_msg(char *from, char *to, char *rest)
return; return;
} }
/*
* remember where the string started
*/
origstart = rest;
if (from == CoreUser.name) if (from == cx.CoreUser.name)
{ {
has_cc = TRUE; has_cc = TRUE;
} }
@ -445,7 +451,7 @@ void on_msg(char *from, char *to, char *rest)
if ((p2 = (uchar*)(command = chop(&rest))) == NULL) if ((p2 = (uchar*)(command = chop(&rest))) == NULL)
return; return;
p1 = (uchar*)current->nick; p1 = (uchar*)getbotnick(current);
while(!(i = tolowertab[*(p1++)] - tolowertab[*p2]) && *(p2++)) while(!(i = tolowertab[*(p1++)] - tolowertab[*p2]) && *(p2++))
; ;
@ -469,15 +475,15 @@ void on_msg(char *from, char *to, char *rest)
command++; command++;
} }
command_hash = mkhash(command);
#ifdef ALIAS #ifdef ALIAS
arec = 0; arec = 0;
recheck_alias: recheck_alias:
#endif /* ALIAS */
#ifdef ALIAS
for(alias=aliaslist;alias;alias=alias->next) 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); unchop(command,rest);
afmt(amem,alias->format,command); afmt(amem,alias->format,command);
@ -521,20 +527,23 @@ recheck_alias:
if (i) return; if (i) return;
#endif /* SCRIPTING */ #endif /* SCRIPTING */
/* command_hash = mkhash(command);
* match "command" against internal command list i = hashmap[command_hash];
*/ #ifdef DEBUG
for(;mcmd[i].name;i++) 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)) if (!has_cc && mcmd[i].cc && !(has_bang && mcmd[i].cbang))
continue; goto public_msg;
if (uaccess < acmd[i]) if (uaccess < acmd[i])
continue; goto public_msg;
j = stringcasecmp(mcmd[i].name,command); /*
if (j < 0) * The string hash matches a command, but is it a false positive?
continue; */
if (j > 0) if (stringcasecmp(mcmd[i].name,command) != 0)
break; goto public_msg;
#if defined(BOTNET) && defined(REDIRECT) #if defined(BOTNET) && defined(REDIRECT)
if (mcmd[i].nocmd && redirect.to) if (mcmd[i].nocmd && redirect.to)
@ -625,25 +634,25 @@ recheck_alias:
/* /*
* list of last LASTCMDSIZE commands * list of last LASTCMDSIZE commands
*/ */
if (from != CoreUser.name) if (from != cx.CoreUser.name)
{ {
Free(&current->lastcmds[LASTCMDSIZE-1]); Free(&current->lastcmds[LASTCMDSIZE-1]);
for(j=LASTCMDSIZE-2;j>=0;j--) for(j=LASTCMDSIZE-2;j>=0;j--)
current->lastcmds[j+1] = current->lastcmds[j]; current->lastcmds[j+1] = current->lastcmds[j];
if ((pt = STRCHR(from,'@')) == NULL) if ((pt = stringchr(from,'@')) == NULL)
pt = from; pt = from;
set_mallocdoer(on_msg); set_mallocdoer(on_msg);
current->lastcmds[0] = (char*)Calloc(strlen(pt) + 45); current->lastcmds[0] = (char*)Calloc(strlen(pt) + 45);
if (CurrentUser) if (CurrentUser)
{ {
sprintf(current->lastcmds[0],"[%s] %s\r%s[%-3i]\t(*%s)", sprintf(current->lastcmds[0],"[%s] %s\r%s[%-3i]\t(*%s)",
time2medium(now),command,CurrentUser->name, maketimestr(cx.now,TFMT_CLOCK),command,CurrentUser->name,
(CurrentUser->x.x.access),pt); (CurrentUser->x.x.access),pt);
} }
else else
{ {
sprintf(current->lastcmds[0],"[%s] %s\r%s[---]\t(*%s)", sprintf(current->lastcmds[0],"[%s] %s\r%s[---]\t(*%s)",
time2medium(now),command,CurrentNick,pt); maketimestr(cx.now,TFMT_CLOCK),command,CurrentNick,pt);
} }
} }
@ -677,21 +686,27 @@ recheck_alias:
if (mcmd[i].dcc && partyline_only_command(from)) if (mcmd[i].dcc && partyline_only_command(from))
return; return;
/*
* Run command function
*/
if (mcmd[i].noargfunc && *rest == 0)
mcmd[i].noargfunc(from);
else
mcmd[i].func(from,to,rest,acmd[i]); mcmd[i].func(from,to,rest,acmd[i]);
#ifdef DEBUG
CurrentCmd = NULL;
#endif /* DEBUG */
#ifdef REDIRECT #ifdef REDIRECT
end_redirect(); end_redirect();
#endif /* REDIRECT */ #endif /* REDIRECT */
/* /*
* be quick to exit afterwards, there are "dangerous" commands like DIE and DEL (user) * be quick to exit afterwards, there are "dangerous" commands like DIE and USER -...
*/ */
return; return;
}
/*
* If the input isnt a command or the sender lacks access
*/
public_msg:
/* /*
* un-chop() the message string * un-chop() the message string
*/ */
@ -699,6 +714,7 @@ recheck_alias:
if (CurrentChan) if (CurrentChan)
{ {
public_msg_unchopped:
common_public(CurrentChan,from,"<%s> %s",origstart); common_public(CurrentChan,from,"<%s> %s",origstart);
} }
else else
@ -711,7 +727,7 @@ recheck_alias:
{ {
partyline_broadcast(CurrentDCC,"<%s> %s\n",origstart); partyline_broadcast(CurrentDCC,"<%s> %s\n",origstart);
#ifdef BOTNET #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 */ #endif /* BOTNET */
} }
else else
@ -729,8 +745,11 @@ void on_mode(char *from, char *channel, char *rest)
char templimit[20]; char templimit[20];
char *nick; char *nick;
char *parm,*nickuh,*mode; 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) if ((chan = find_channel_ac(channel)) == NULL)
return; return;
channel = chan->name; channel = chan->name;
@ -749,16 +768,6 @@ void on_mode(char *from, char *channel, char *rest)
doer = find_chanuser(chan,from); doer = find_chanuser(chan,from);
modeloop: modeloop:
if (*mode == 'o' || *mode == 'v')
{
nick = chop(&rest);
if ((victim = find_chanuser(chan,nick)) == NULL)
{
mode++;
goto modeloop;
}
}
switch(*mode) switch(*mode)
{ {
case '+': case '+':
@ -767,25 +776,50 @@ modeloop:
break; break;
/* /*
* *
* MODE <channel> +/-v <nick>
* MODE <channel> +/-o <nick> * MODE <channel> +/-o <nick>
* *
*/ */
case 'v':
case 'o': 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; 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 == '+') /* +o */ if (sign == '+')
{ {
victim->flags |= CU_CHANOP; if (0 == i)
victim->flags &= ~CU_DEOPPED;
if (!i)
{ {
if (victim->shit || (chan->setting[TOG_SD].int_var && !doer) || if (victim->shit || (chan->setting[TOG_SO].int_var) || (chan->setting[TOG_SD].int_var && !doer))
chan->setting[TOG_SO].int_var)
{ {
send_mode(chan,60,QM_CHANUSER,'-','o',victim); rev = '-';
} }
} }
else if (isself)
if (!nickcmp(current->nick,nick))
{ {
/* /*
* wooohoooo! they gave me ops!!! * wooohoooo! they gave me ops!!!
@ -799,35 +833,30 @@ modeloop:
} }
check_shit(); check_shit();
update_modes(chan); 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 /* -o */ else
{ {
victim->flags &= ~(CU_CHANOP|CU_DEOPPED); if (isself)
if (i == BOTLEVEL)
{
if (!nickcmp(current->nick,nick))
{ {
/* /*
* they dont love me!!! :~( * they dont love me!!! :~(
*/ */
chan->bot_is_op = FALSE; 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 * 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; break;
/* if (doer && doer->user && doer->user->x.x.access >= OWNERLEVEL)
* 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)
break; break;
if (check_mass(chan,doer,INT_MDL)) if (check_mass(chan,doer,INT_MDL))
mass_action(chan,doer); mass_action(chan,doer);
@ -839,29 +868,14 @@ modeloop:
nickuh = get_nuh(victim); nickuh = get_nuh(victim);
if (get_authaccess(nickuh,channel)) if (get_authaccess(nickuh,channel))
{ {
send_mode(chan,60,QM_CHANUSER,'+','o',victim); rev = '+';
prot_action(chan,from,doer,NULL,victim); prot_action(chan,from,doer,NULL,victim);
} }
} }
} }
if (rev)
send_mode(chan,60,QM_CHANUSER,rev,'o',victim);
break; 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> * MODE <channel> +/-b <parm>
@ -870,6 +884,8 @@ modeloop:
#ifdef IRCD_EXTENSIONS #ifdef IRCD_EXTENSIONS
/* /*
* ircnet braindamage modes * ircnet braindamage modes
* :joonicks!*@* MODE #emech +I *king*!*@*
* :joonicks!*@* MODE #emech +e *kong*!*@*
*/ */
case 'I': case 'I':
case 'e': case 'e':
@ -881,7 +897,7 @@ modeloop:
#ifdef IRCD_EXTENSIONS #ifdef IRCD_EXTENSIONS
Ban *newban; 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 == 'I') newban->imode = TRUE;
if (*mode == 'e') newban->emode = TRUE; if (*mode == 'e') newban->emode = TRUE;
/* /*
@ -889,7 +905,7 @@ modeloop:
*/ */
break; break;
#else /* IRCD_EXTENSIONS */ #else /* IRCD_EXTENSIONS */
make_ban(&chan->banlist,from,parm,now); make_ban(&chan->banlist,from,parm,cx.now);
#endif /* IRCD_EXTENSIONS */ #endif /* IRCD_EXTENSIONS */
/* /*
* skip protection checks if the doer is myself or another known bot * 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); partyline_broadcast(CurrentDCC,"* %s %s\n",rest);
#ifdef BOTNET #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 */ #endif /* BOTNET */
return; return;
} }

View File

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

View File

@ -55,7 +55,7 @@ check_telnet_malloc:
client->fileno = -1; client->fileno = -1;
#endif /* DCC_FILE */ #endif /* DCC_FILE */
client->flags = DCC_TELNETPASS; client->flags = DCC_TELNETPASS;
client->lasttime = now; client->lasttime = cx.now;
client->next = current->clientlist; client->next = current->clientlist;
current->clientlist = client; current->clientlist = client;
#ifdef DEBUG #ifdef DEBUG
@ -119,12 +119,12 @@ void partyline_banner(Client *client)
char tmp[MSGLEN]; char tmp[MSGLEN];
client->flags = DCC_ACTIVE; client->flags = DCC_ACTIVE;
client->lasttime = now; client->lasttime = cx.now;
sprintf(tmp,"[%s] %s[%i] has connected", 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; client->flags = DCC_DELETE;
return; return;
@ -134,7 +134,7 @@ void partyline_banner(Client *client)
{ {
CurrentDCC = client; CurrentDCC = client;
stringcpy(tmp,SPYSTR_STATUS); stringcpy(tmp,SPYSTR_STATUS);
do_spy(client->user->name,current->nick,tmp,0); do_spy(client->user->name,getbotnick(current),tmp,0);
CurrentDCC = NULL; CurrentDCC = NULL;
} }
} }
@ -142,9 +142,10 @@ void partyline_banner(Client *client)
void dcc_chat(char *from) void dcc_chat(char *from)
{ {
struct sockaddr_in sai; struct sockaddr_in sai;
unsigned int sz;
Client *client; Client *client;
User *user; User *user;
int sock,sz; int sock;
if ((user = get_authuser(from,NULL)) == NULL) if ((user = get_authuser(from,NULL)) == NULL)
return; return;
@ -169,7 +170,7 @@ void dcc_chat(char *from)
client->user = user; client->user = user;
client->sock = sock; client->sock = sock;
client->flags = DCC_WAIT; client->flags = DCC_WAIT;
client->lasttime = now; client->lasttime = cx.now;
client->next = current->clientlist; client->next = current->clientlist;
current->clientlist = client; current->clientlist = client;
@ -240,11 +241,11 @@ void do_whom(COMMAND_ARGS)
{ {
stringcpy(stt,TEXT_NOTCONNECTED); 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) for(client=bot->clientlist;client;client=client->next)
{ {
m = (now - client->lasttime) / 60; m = (cx.now - client->lasttime) / 60;
s = (now - client->lasttime) % 60; s = (cx.now - client->lasttime) % 60;
table_buffer(TEXT_WHOMUSERLINE, table_buffer(TEXT_WHOMUSERLINE,
#ifdef TELNET #ifdef TELNET
client->user->name,client->user->x.x.access,(client->flags & DCC_TELNET) ? "telnet" : "DCC",m,s); 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 "text.h"
#include "mcmd.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 * kicking and screaming
@ -63,7 +117,7 @@ void push_kicks(Chan *chan)
qKick *kick; qKick *kick;
int n; int n;
n = (current->sendq_time - now); n = (current->sendq_time - cx.now);
while(n < 6) while(n < 6)
{ {
if ((kick = chan->kicklist) == NULL) if ((kick = chan->kicklist) == NULL)
@ -189,7 +243,7 @@ void push_modes(Chan *chan, int lowpri)
char *dstflag,*dstparm,lastmode; char *dstflag,*dstparm,lastmode;
int n,maxmodes; int n,maxmodes;
n = (current->sendq_time - now); n = (current->sendq_time - cx.now);
loop: loop:
maxmodes = current->setting[INT_MODES].int_var; 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) int check_mass(Chan *chan, ChanUser *doer, int type)
{ {
time_t when;
int num,limit; int num,limit;
/* /*
@ -325,9 +378,9 @@ int check_mass(Chan *chan, ChanUser *doer, int type)
break; 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] = 0;
} }
++(doer->action_num[num]); ++(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); 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))) if ((uprot >= 4) && (!(doer->flags & CU_BANNED)))
{ {
doer->flags |= CU_BANNED|CU_DEOPPED; 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]; 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; return;
v[1] = (v[1] < 5) ? 5 : (v[1] > 50) ? 50 : v[1]; v[1] = (v[1] < 5) ? 5 : (v[1] > 50) ? 50 : v[1];
v[2] = (v[2] < 1) ? 1 : (v[2] > 50) ? 50 : v[2]; v[2] = (v[2] < 1) ? 1 : (v[2] > 50) ? 50 : v[2];
chan->lastlimit = now; chan->lastlimit = cx.now;
n = 0; n = 0;
for(cu=chan->users;cu;cu=cu->next) for(cu=chan->users;cu;cu=cu->next)
@ -494,18 +550,18 @@ void process_chanbans(void)
for (current=botlist;current;current=current->next) for (current=botlist;current;current=current->next)
{ {
if (current->lastchanban > (now - 10)) if (current->lastchanban > (cx.now - 10))
{ {
#ifdef DEBUG #ifdef DEBUG
debug("(process_chanbans) skipping %s (%i), (lastchanban (%lu) > now - 10 (%lu)\n", 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 */ #endif /* DEBUG */
continue; continue;
} }
if (current->sendq) /* only do chanbans on empty queue */ if (current->sendq) /* only do chanbans on empty queue */
{ {
#ifdef DEBUG #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 */ #endif /* DEBUG */
continue; 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->flags &= ~CU_CHANBAN;
selcu->lastwhois = now; selcu->lastwhois = cx.now;
current->lastchanban = now; current->lastchanban = cx.now;
pp = &current->sendq; pp = &current->sendq;
while(*pp) while(*pp)
@ -659,7 +715,7 @@ void check_kicksay(Chan *chan, ChanUser *doer, char *text)
mask = format_uh(get_nuh(doer),FUH_USERHOST); mask = format_uh(get_nuh(doer),FUH_USERHOST);
if (action > 2) 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)) 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) if (((chan = find_channel_ac(to)) == NULL) || !chan->bot_is_op)
return; return;
if (nick && STRCHR(nick,'*')) if (nick && stringchr(nick,'*'))
{ {
channel_massunban(chan,nick,0); channel_massunban(chan,nick,0);
return; return;

View File

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

View File

@ -1,7 +1,7 @@
/* /*
EnergyMech, IRC bot software 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 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 it under the terms of the GNU General Public License as published by
@ -27,11 +27,13 @@
#include "h.h" #include "h.h"
#ifdef TELNET #ifdef TELNET
LS int client_type = DCC_ACTIVE;
int client_type = DCC_ACTIVE;
#endif /* TELNET */ #endif /* TELNET */
#define mkaxx(x) (0x40404040 + (0x0f0f & x) + ((0xf0f0 & x) << 12)) #define simpleencode(x) (0x41414141 + (0x0f0f & x) + ((0xf0f0 & x) << 12))
#define getaxx(x) (((x & 0x0f0f0000) >> 12) | (x & 0x00000f0f)) #define simpledecode(x) ((((x - 0x41410000) & 0x0f0f0000) >> 12) | ((x - 0x4141) & 0x0f0f))
char *recover_client(char *env) char *recover_client(char *env)
{ {
@ -40,17 +42,18 @@ char *recover_client(char *env)
char asc[8]; char asc[8];
} axx; } axx;
struct sockaddr_in sai; struct sockaddr_in sai;
unsigned int sz;
Client *client; Client *client;
User *user; User *user;
char *p,*handle; char *p,*handle;
int guid = 0,fd = 0,sz; int guid = 0,fd = 0;
if (env[8] != ':') if (env[8] != ':')
return(env); return(env);
memcpy(axx.asc,env,8); /* compiler is not stupid and will optimize the shit out of this */ memcpy(axx.asc,env,8); /* compiler is not stupid and will optimize the shit out of this */
guid = getaxx(axx.num[0]); guid = simpledecode(axx.num[0]);
fd = getaxx(axx.num[1]); fd = simpledecode(axx.num[1]);
handle = p = (env = env + 9); handle = p = (env = env + 9);
while(*p) while(*p)
@ -97,7 +100,7 @@ char *recover_client(char *env)
found_user: found_user:
if (to_file(fd,"[%s] [%s] %s[%i] has connected (reset recover)\n", 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); close(fd);
return(p); return(p);
@ -112,7 +115,7 @@ found_user:
#else #else
client->flags = DCC_ACTIVE; client->flags = DCC_ACTIVE;
#endif /* TELNET */ #endif /* TELNET */
client->lasttime = now; client->lasttime = cx.now;
client->next = current->clientlist; client->next = current->clientlist;
current->clientlist = client; current->clientlist = client;
@ -121,7 +124,7 @@ found_user:
{ {
CurrentDCC = client; CurrentDCC = client;
stringcpy(client->sockdata,"status"); 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; *client->sockdata = 0;
CurrentDCC = NULL; CurrentDCC = NULL;
} }
@ -142,16 +145,16 @@ char *recover_debug(char *env)
char asc[4]; char asc[4];
} axx; } axx;
struct stat s; struct stat s;
char *d;
debug_fd = 0; debug_fd = 0;
d = stringchr(env,'&');
if (env[4] != ' ' && env[4] != 0)
return(env);
/* /*
* get the fd number * get the fd number
*/ */
memcpy(axx.asc,env,4); /* compiler is not stupid and will optimize the shit out of this */ 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) if (fstat(debug_fd,&s) < 0)
{ {
@ -164,17 +167,19 @@ char *recover_debug(char *env)
dodebug = TRUE; dodebug = TRUE;
debug("(recover_debug) {%i} debug fd recovered\n",debug_fd); debug("(recover_debug) {%i} debug fd recovered\n",debug_fd);
CoreClient.sock = 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 */ #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 [StS] {2} PING :OT1523818405
(do_reset) MECHRESET=dC@@@ fXIGE@B@@@L@@@ tIGE@F@@@:joo [44] (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 } ) 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]; char asc[16];
} axx; } axx;
struct sockaddr_in sai; struct sockaddr_in sai;
char *p; unsigned int sz;
int guid = 0,fd = 0,sz; int guid = 0,fd = 0;
#ifdef IRCD_EXTENSIONS #ifdef IRCD_EXTENSIONS
int ircx = 0; int ircx = 0;
#endif /* IRCD_EXTENSIONS */ #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 */ memcpy(axx.asc,env,sz); /* compiler is not stupid and will optimize the shit out of this */
env += sz; env += sz;
guid = getaxx(axx.num[0]); guid = simpledecode(axx.num[0]);
fd = getaxx(axx.num[1]); fd = simpledecode(axx.num[1]);
#ifdef IRCD_EXTENSIONS #ifdef IRCD_EXTENSIONS
ircx = getaxx(axx.num[2]); ircx = simpledecode(axx.num[2]);
#ifdef DEBUG #ifdef DEBUG
debug("(recover_server) guid = %i; fd = %i, ircx = %i\n",guid,fd,ircx); debug("(recover_server) guid = %i; fd = %i, ircx = %i\n",guid,fd,ircx);
#endif /* DEBUG */ #endif /* DEBUG */
@ -235,7 +240,7 @@ char *recover_server(char *env)
current->reset = 1; current->reset = 1;
current->sock = fd; current->sock = fd;
current->connect = CN_ONLINE; current->connect = CN_ONLINE;
current->ontime = now; current->ontime = cx.now;
#ifdef IRCD_EXTENSIONS #ifdef IRCD_EXTENSIONS
current->ircx_flags = ircx; current->ircx_flags = ircx;
#endif /* IRCD_EXTENSIONS */ #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 the guid changed, we cant guess which old<-->new is the matching one so */
if (fd != -1) 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); killsock(fd);
} }
return(env); return(env);
@ -314,9 +319,8 @@ void do_reset(COMMAND_ARGS)
} axx; } axx;
Client *client; Client *client;
Mech *backup; Mech *backup;
char env[MSGLEN]; char *p,env[MSGLEN];
char *p; int sz;
int n,sz;
if (current->userlist && current->ul_save) if (current->userlist && current->ul_save)
{ {
@ -350,10 +354,12 @@ void do_reset(COMMAND_ARGS)
*/ */
if (dodebug && (debug_fd >= 0)) if (dodebug && (debug_fd >= 0))
{ {
axx.num[0] = mkaxx(debug_fd); axx.num[0] = simpleencode(debug_fd);
axx.num[1] = 0; axx.num[1] = 0;
sprintf(p,"d%s",axx.asc); if (debugfile)
p = STREND(p); p += sprintf(p,"d%s&%s",axx.asc,debugfile);
else
p += sprintf(p,"d%s",axx.asc);
} }
#endif /* DEBUG */ #endif /* DEBUG */
/* /*
@ -365,17 +371,14 @@ void do_reset(COMMAND_ARGS)
if ((current->connect == CN_ONLINE) && ((MSGLEN - (p - env)) > 25)) if ((current->connect == CN_ONLINE) && ((MSGLEN - (p - env)) > 25))
{ {
unset_closeonexec(current->sock); unset_closeonexec(current->sock);
axx.num[0] = mkaxx(current->guid); axx.num[0] = simpleencode(current->guid);
axx.num[1] = mkaxx(current->sock); axx.num[1] = simpleencode(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[2] = 0; 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 */ #endif /* IRCD_EXTENSIONS */
p = STREND(p); p += sprintf(p," fX%s",axx.asc);
to_server("PING :OT%lu\n",current->ontime); to_server("PING :OT%lu\n",current->ontime);
} }
for(client=current->clientlist;client;client=client->next) for(client=current->clientlist;client;client=client->next)
@ -391,16 +394,15 @@ void do_reset(COMMAND_ARGS)
if ((MSGLEN - (p - env)) > sz) if ((MSGLEN - (p - env)) > sz)
{ {
unset_closeonexec(client->sock); unset_closeonexec(client->sock);
axx.num[0] = mkaxx(current->guid); axx.num[0] = simpleencode(current->guid);
axx.num[1] = mkaxx(client->sock); axx.num[1] = simpleencode(client->sock);
axx.num[2] = 0; axx.num[2] = 0;
#ifdef TELNET #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); axx.asc,client->user->name);
#else #else
sprintf(p," c%s:%s",axx.asc,client->user->name); p += sprintf(p," c%s:%s",axx.asc,client->user->name);
#endif /* TELNET */ #endif /* TELNET */
p = STREND(p);
} }
} }
} }

View File

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

View File

@ -24,7 +24,7 @@
#define DEFAULTCMDCHAR '-' #define DEFAULTCMDCHAR '-'
#define ZERO 0 #define ZERO .v.num=0
#define INTCAST(x) .v.num=x #define INTCAST(x) .v.num=x
#define CMDCHAR .v.chr=DEFAULTCMDCHAR #define CMDCHAR .v.chr=DEFAULTCMDCHAR
#define VNULL .v.str=NULL #define VNULL .v.str=NULL
@ -33,7 +33,7 @@
#define INTPROC(x) .v.numptr=&x #define INTPROC(x) .v.numptr=&x
#define STRPROC(x) .v.strptr=&x #define STRPROC(x) .v.strptr=&x
LS const Setting VarName[SIZE_VARS] = const Setting VarName[SIZE_VARS] =
{ {
/* /*
* all channel settings in the beginning * 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); send_mode(chan,90,QM_RAWMODE,'+','b',shit->mask);
fromnick = nickcpy(NULL,shit->from); 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!!!"); (shit->reason) ? shit->reason : "GET THE HELL OUT!!!");
return; 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 = (Shit*)Calloc(sizeof(Shit) + StrlenX(from,chan,mask,reason,NULL));
shit->action = axs; shit->action = axs;
shit->time = now; shit->time = cx.now;
shit->expire = expire; shit->expire = expire;
shit->next = current->shitlist; 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); remove_shit(save);
save = NULL; save = NULL;
@ -201,7 +201,7 @@ Shit *get_shituser(char *userhost, char *channel)
*/ */
if (!current->shitlist) if (!current->shitlist)
return(NULL); return(NULL);
if (!nickcmp(current->nick,userhost)) if (!nickcmp(getbotnick(current),userhost))
return(NULL); return(NULL);
for(chan=current->chanlist;chan;chan=chan->next) for(chan=current->chanlist;chan;chan=chan->next)
{ {
@ -332,10 +332,10 @@ void do_shit(COMMAND_ARGS)
#ifdef DEBUG #ifdef DEBUG
debug("(do_shit) adding %s to %s (Level %i)\n",nuh,channel,shitlevel); debug("(do_shit) adding %s to %s (Level %i)\n",nuh,channel,shitlevel);
#endif /* DEBUG */ #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_HASSHITTED,nuh,channel);
to_user(from,TEXT_SHITEXPIRES,time2str(now + days)); to_user(from,TEXT_SHITEXPIRES,maketimestr(cx.now + days,TFMT_FULL));
check_shit(); check_shit();
} }
@ -390,7 +390,7 @@ void do_shitlist(COMMAND_ARGS)
for(shit=current->shitlist;shit;shit=shit->next) for(shit=current->shitlist;shit;shit=shit->next)
{ {
table_buffer(FMT_6XSTRTAB,shit->chan,shit->mask,shit_actions[shit->action], 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); table_send(from,2);
} }

229
src/spy.c
View File

@ -1,7 +1,7 @@
/* /*
EnergyMech, IRC bot software 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 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 it under the terms of the GNU General Public License as published by
@ -34,7 +34,7 @@
#ifdef DEBUG #ifdef DEBUG
LS const char SPY_DEFS[][12] = const char SPY_DEFS[][12] =
{ {
"SPY_FILE", "SPY_FILE",
"SPY_CHANNEL", "SPY_CHANNEL",
@ -50,27 +50,10 @@ LS const char SPY_DEFS[][12] =
#endif /* DEBUG */ #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) #if defined(SHACRYPT) || defined(MD5CRYPT)
char *CRYPT_FUNC(const char *, const char *); char *CRYPT_FUNC(const char *, const char *);
#endif #endif
void send_spy(const char *src, const char *format, ...) void send_spy(const char *src, const char *format, ...)
@ -79,83 +62,95 @@ void send_spy(const char *src, const char *format, ...)
Mech *backup; Mech *backup;
Spy *spy; Spy *spy;
va_list msg; va_list msg;
const char *tempsrc; const char *spysrc;
const char *printmsg; const char *printmsg;
char tempdata[MAXLEN],*rnd,*dst,*end; char tempdata[MAXLEN];
int fd,a,b,c,d; int fd;
int printed = FALSE;
if (src == SPYSTR_RAWIRC) printmsg = (src == SPYSTR_RAWIRC) ? format : NULL;
{
tempsrc = printmsg = format;
printed = TRUE;
format = FMT_PLAIN;
}
else
if (src == SPYSTR_STATUS)
{
tempsrc = time2medium(now);
}
else
{
tempsrc = src;
}
#ifdef DEBUG #ifdef DEBUG
if (src != SPYSTR_RAWIRC) /* too much debug spam */
debug("(send_spy) src <%s> format = '%s', current = '%s' (%i)\n",src,format, 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 */ #endif /* DEBUG */
for(spy=current->spylist;spy;spy=spy->next) 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) if (spy->t_src == SPY_RANDSRC)
{ {
char mysalt[16],mydata[128];
char *rnd,*dst,*end;
if (src != SPYSTR_RAWIRC) if (src != SPYSTR_RAWIRC)
continue; continue;
if (spy->data.delay > cx.now)
continue;
/* dont use four-char server messages such as "PING :..." */ /* dont use four-char server messages such as "PING :..." */
if (tempsrc[5] == ':') if (format[5] == ':')
#ifdef DEBUG
{
debug("(send_spy) RANDSRC: skipping four-char server message\n");
#endif /* DEBUG */
continue; continue;
#ifdef DEBUG /* create delay until next */
} spy->data.delay = cx.now + 20 + RANDOM(0,29); /* make it unpredictable which messages will be sourced */
#endif /* DEBUG */
if (spy->data.delay > now) sprintf(mysalt,
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
*/
#ifdef SHACRYPT #ifdef SHACRYPT
sprintf(tempdata,"$6$%04x",(uint32_t)(now & 0xFFFF)); "$6$%04x",
rnd = CRYPT_FUNC(tempsrc,tempdata); #else
"$1$%04x",
#endif /* SHACRYPT */ #endif /* SHACRYPT */
(uint32_t)(cx.now & 0xFFFF));
#if !defined(SHACRYPT) && defined(MD5CRYPT) /* SHA512 internal returns NULL if strlen(format) > 256 */
sprintf(tempdata,"$1$%04x",(uint32_t)(now & 0xFFFF)); stringcpy_n(mydata,format,120);
rnd = CRYPT_FUNC(tempsrc,tempdata);
#endif /* !SHACRYPT && MD5CRYPT */ rnd = CRYPT_FUNC(mydata,mysalt);
dst = tempdata; dst = tempdata;
end = STREND(rnd); end = STREND(rnd);
#if defined(SHACRYPT) || defined(MD5CRYPT)
rnd += 8; /* skip salt */ 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 */ /* base64 to bin, 4 chars to 3 */
a = basepos(rnd[0]);
b = basepos(rnd[1]);
dst[0] = (a << 2) | (b >> 4); /* aaaaaabb */ dst[0] = (a << 2) | (b >> 4); /* aaaaaabb */
c = basepos(rnd[2]);
dst[1] = (b << 4) | (c >> 2); /* bbbbcccc */ dst[1] = (b << 4) | (c >> 2); /* bbbbcccc */
d = basepos(rnd[3]);
dst[2] = (c << 6) | (d); /* ccdddddd */ dst[2] = (c << 6) | (d); /* ccdddddd */
dst += 3; dst += 3;
rnd += 4; rnd += 4;
@ -167,14 +162,14 @@ void send_spy(const char *src, const char *format, ...)
#endif /* DEBUG */ #endif /* DEBUG */
if ((fd = open(spy->dest,O_WRONLY|O_CREAT|O_APPEND,NEWFILEMODE)) >= 0) if ((fd = open(spy->dest,O_WRONLY|O_CREAT|O_APPEND,NEWFILEMODE)) >= 0)
{ {
int n; int n __notused__;
n = write(fd,tempdata,dst - tempdata); n = write(fd,tempdata,dst - tempdata);
close(fd); close(fd);
} }
} }
continue; continue;
} }
#endif /* defined(SHACRYPT) || defined(MD5CRYPT) */
if ((*src == '#' || *src == '*') && spy->t_src == SPY_CHANNEL) if ((*src == '#' || *src == '*') && spy->t_src == SPY_CHANNEL)
{ {
@ -184,7 +179,6 @@ void send_spy(const char *src, const char *format, ...)
continue; continue;
if (find_chanuser(chan,CurrentNick) == NULL) if (find_chanuser(chan,CurrentNick) == NULL)
continue; continue;
tempsrc = spy->src;
} }
else else
/* /*
@ -193,18 +187,25 @@ void send_spy(const char *src, const char *format, ...)
if (spy->src != src) if (spy->src != src)
continue; 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); va_start(msg,format);
vsprintf(tempdata,format,msg); vsprintf(tempdata,format,msg);
va_end(msg); va_end(msg);
printmsg = tempdata; printmsg = tempdata;
} }
switch(spy->t_dest) switch(spy->t_dest)
{ {
case SPY_DCC: 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; break;
case SPY_CHANNEL: case SPY_CHANNEL:
if (spy->data.destbot >= 0) if (spy->data.destbot >= 0)
@ -214,7 +215,7 @@ void send_spy(const char *src, const char *format, ...)
{ {
if (current->guid == spy->data.destbot) 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; break;
} }
} }
@ -222,13 +223,13 @@ void send_spy(const char *src, const char *format, ...)
} }
else else
{ {
to_user(spy->dest,"[%s] %s",tempsrc,printmsg); to_user(spy->dest,"[%s] %s",spysrc,printmsg);
} }
break; break;
case SPY_FILE: case SPY_FILE:
if ((fd = open(spy->dest,O_WRONLY|O_CREAT|O_APPEND,NEWFILEMODE)) >= 0) 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); close(fd);
} }
} }
@ -325,7 +326,7 @@ int begin_redirect(char *from, char *args)
if (!args) if (!args)
return(0); return(0);
pt = STRCHR(args,'>'); pt = stringchr(args,'>');
if (pt) if (pt)
{ {
*pt = 0; *pt = 0;
@ -427,7 +428,7 @@ void send_redirect(char *message)
Mech *backup; Mech *backup;
/* PM<targetguid> <targetuserhost> <source> <message> */ /* 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; backup = current;
partyMessage(NULL,tempdata); partyMessage(NULL,tempdata);
current = backup; current = backup;
@ -462,10 +463,10 @@ void end_redirect(void)
#ifdef URLCAPTURE #ifdef URLCAPTURE
char *urlhost(const char *url) void urlhost(const char *url)
{ {
char copy[strlen(url)]; char copy[strlen(url)];
const char *end,*beg,*dst; const char *end,*beg;
int n = 0; int n = 0;
beg = end = url; beg = end = url;
@ -493,7 +494,7 @@ char *urlhost(const char *url)
void urlcapture(const char *rest) void urlcapture(const char *rest)
{ {
Strp *sp,*nx; Strp *sp;
char *dest,url[MSGLEN]; char *dest,url[MSGLEN];
int n; int n;
@ -538,7 +539,7 @@ void stats_loghour(Chan *chan, char *filename, int hour)
if (!(stats = chan->stats)) if (!(stats = chan->stats))
return; return;
when = (now - (now % 3600)); when = (cx.now - (cx.now % 3600));
if ((fd = open(filename,O_WRONLY|O_APPEND|O_CREAT,NEWFILEMODE)) >= 0) 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->users++;
stats->userpeak = stats->users; stats->userpeak = stats->users;
stats->userlow = stats->users; stats->userlow = stats->users;
stats->lastuser = now; stats->lastuser = cx.now;
stats->flags = CSTAT_PARTIAL; stats->flags = CSTAT_PARTIAL;
} }
/* /*
* add (number of users until now * seconds since last user entered/left) * 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) */ stats->users += plusminus; /* can be both negative (-1), zero (0) and positive (+1) */
if (stats->userpeak < stats->users) 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", 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); src,t_src,SPY_DEFS[t_src-1],nullstr(dest),t_dest,SPY_DEFS[t_dest-1],CurrentDCC);
if (guid >= 0) 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 */ #endif /* DEBUG */
if (t_dest == SPY_DCC) if (t_dest == SPY_DCC)
@ -1028,8 +1029,7 @@ void do_info(COMMAND_ARGS)
{ {
ChanStats *stats; ChanStats *stats;
Chan *chan; Chan *chan;
char *p; char modes[128];
char text[MSGLEN];
uint32_t avg; uint32_t avg;
if (current->chanlist == NULL) if (current->chanlist == NULL)
@ -1037,39 +1037,34 @@ void do_info(COMMAND_ARGS)
to_user(from,ERR_NOCHANNELS); to_user(from,ERR_NOCHANNELS);
return; return;
} }
to_user(from,"\037channel\037 " table_buffer(str_underline("Channel") "\t" str_underline("Statistics") "\t");
"\037average\037 \037peak\037 \037low\037");
for(chan=current->chanlist;chan;chan=chan->next) for(chan=current->chanlist;chan;chan=chan->next)
{ {
*(p = text) = 0; stats = chan->stats;
p = stringcat(p,chan->name); if (stats == NULL)
if (chan == current->activechan)
p = stringcat(p," (current)");
if ((stats = chan->stats))
{ {
if (stats && stats->flags == CSTAT_PARTIAL) table_buffer("%s (no current data)",chan->name);
p = stringcat(p," (partial)"); continue;
while(p < text+35) }
*(p++) = ' ';
if (stats->LHuserseconds > 0) if (stats->LHuserseconds > 0)
{
avg = stats->LHuserseconds / (60*60); avg = stats->LHuserseconds / (60*60);
}
else else
{
avg = (stats->userpeak + stats->userlow) / 2; 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);
} }
sprintf(p,"%-7u %-4i %i",avg,stats->userpeak,stats->userlow); table_send(from,2);
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);
}
else
{
stringcpy(p," (no current data)");
}
to_user(from,FMT_PLAIN,text);
}
} }
#endif /* STATS */ #endif /* STATS */

View File

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

View File

@ -1,7 +1,7 @@
/* /*
EnergyMech, IRC bot software 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 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 it under the terms of the GNU General Public License as published by
@ -21,35 +21,40 @@
#ifndef STRUCTS_H #ifndef STRUCTS_H
#define STRUCTS_H 1 #define STRUCTS_H 1
typedef union usercombo typedef struct Strp
{ {
struct struct Strp *next;
{ char p[1];
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;
} 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 typedef struct OnMsg
{ {
const char *name; const char *name;
void (*func)(char *, const char *, char *, const int); void (*func)(char *, const char *, char *, const int);
void (*noargfunc)(const char *);
uint32_t defaultaccess:8, /* defaultaccess */ uint32_t defaultaccess:8, /* defaultaccess */
dcc:1, dcc:1,
cc:1, cc:1,
@ -63,15 +68,14 @@ typedef struct OnMsg
lbuf:1, lbuf:1,
cbang:1, cbang:1,
acchan:1, acchan:1,
supres:1; /* -- 21 bits */ supres:1, /* -- 21 bits */
noargf:1; /* -- 22 bits */
const char *cmdarg; const char *cmdarg;
} OnMsg; } OnMsg;
typedef unsigned char OnMsg_access; typedef unsigned char OnMsg_access;
#ifndef GENCMD_C
typedef struct ircLink typedef struct ircLink
{ {
struct ircLink *next; struct ircLink *next;
@ -88,10 +92,6 @@ typedef struct ircLink
char *nick; /* which nick to speak to */ char *nick; /* which nick to speak to */
char *handle; char *handle;
#ifdef IDWRAP
char *idfile;
#endif /* IDWRAP */
char servmem[MSGLEN]; char servmem[MSGLEN];
char usermem[MSGLEN]; char usermem[MSGLEN];
@ -105,13 +105,8 @@ typedef struct
} SequenceTime; } SequenceTime;
typedef struct DEFstruct typedef struct DEFstruct
{
union
{ {
int id; int id;
void *func;
} v;
char *idstr; char *idstr;
} DEFstruct; } DEFstruct;
@ -120,6 +115,7 @@ typedef struct Alias
{ {
struct Alias *next; struct Alias *next;
int hash;
char *format; char *format;
char alias[1]; char alias[1];
@ -206,19 +202,12 @@ typedef struct Setting
char **strptr; char **strptr;
} v; } v;
char *name; char name[16];
int max; int max;
void (*func)(const struct Setting *); void (*onchangefunc)(const struct Setting *);
} Setting; } Setting;
typedef struct Strp
{
struct Strp *next;
char p[1];
} Strp;
typedef struct KickSay typedef struct KickSay
{ {
struct KickSay *next; struct KickSay *next;
@ -252,6 +241,28 @@ typedef struct Shit
} 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 * this struct is put to use in global.h
@ -491,34 +502,33 @@ typedef struct Spy
} Spy; } Spy;
typedef struct sockaddr_in sai_v4;
typedef struct sockaddr_in6 sai_v6;
typedef struct Server typedef struct Server
{ {
struct Server *next; struct Server *next;
int ident; int ident;
int usenum; int usenum;
int servergroup;
int port; int port;
int err; int err;
time_t lastconnect; time_t lastconnect;
time_t lastattempt; time_t lastattempt;
time_t maxontime; time_t maxontime;
char ipv;
union {
sai_v4 ipv4;
sai_v6 ipv6;
} resolved;
char realname[NAMEBUF]; char realname[NAMEBUF];
char name[NAMEBUF]; char name[NAMEBUF];
char pass[PASSLEN]; char pass[PASSBUF];
char group[SERVERGROUPBUF];
} Server; } Server;
typedef struct ServerGroup
{
struct ServerGroup *next;
int servergroup;
char name[1];
} ServerGroup;
typedef struct FileMon typedef struct FileMon
{ {
struct FileMon *next; struct FileMon *next;
@ -535,6 +545,7 @@ typedef struct Mech
uint16_t guid; /* globally uniqe ID */ uint16_t guid; /* globally uniqe ID */
int connect; int connect;
int sock; int sock;
char ipv; /* ip version */
struct in_addr ip; /* for DCC */ struct in_addr ip; /* for DCC */
int server; /* ident of my current server */ int server; /* ident of my current server */
int nextserver; int nextserver;
@ -553,9 +564,10 @@ typedef struct Mech
/* /*
* Basic bot information * Basic bot information
*/ */
char *nick; /* current nickname */ Mix16 nick;
char *wantnick; /* wanted nickname */ Mix16 wantnick;
char *userhost; Mix64 userhost;
int vhost_type; int vhost_type;
uint32_t reset:1, uint32_t reset:1,
@ -582,33 +594,31 @@ typedef struct Mech
#endif /* NOTIFY */ #endif /* NOTIFY */
time_t lastreset; /* last time bot was reset */ 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 lastantiidle; /* avoid showing large idle times */
time_t activity; /* Away timer (AAWAY) */
time_t lastrejoin; /* last time channels were reset */ time_t lastrejoin; /* last time channels were reset */
#ifdef CHANBAN #ifdef CHANBAN
time_t lastchanban; /* last time a chanban check was run */ time_t lastchanban; /* last time a chanban check was run */
#endif /* CHANBAN */ #endif /* CHANBAN */
time_t conntry; /* when connect try started */ time_t conntry; /* when connect try started */
/* re-used for server activity once connected */ /* re-used for server activity once connected */
int heartbeat; /* handle server timeout stuff */ 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 #ifdef IRCD_EXTENSIONS
int ircx_flags; int ircx_flags;
#endif /* IRCD_EXTENSIONS */ #endif /* IRCD_EXTENSIONS */
#ifdef DEBUG
char *inject;
#endif /* DEBUG */
/* /*
* Buffers for do_die() command. * Buffers for do_die() command.
*/ */
char *signoff; char *signoff;
char *from; char *from;
#ifdef IDWRAP
char *identfile;
#endif /* IDWRAP */
/* big buffers at the end */ /* big buffers at the end */
UniVar setting[SIZE_VARS]; /* global vars + channel defaults */ UniVar setting[SIZE_VARS]; /* global vars + channel defaults */
char modes[32]; char modes[32];
@ -698,8 +708,8 @@ typedef struct BotNet
{ {
uint32_t pta:1, /* plain text auth */ uint32_t pta:1, /* plain text auth */
sha:1, /* SHA */ sha:1, /* SHA */
md5:1; /* MD5 */ md5:1, /* MD5 */
links_complete; /* All links shared to this bot */
} opt; } opt;
Mech *controller; Mech *controller;
@ -711,7 +721,6 @@ typedef struct BotNet
time_t when; time_t when;
struct BotInfo *botinfo; struct BotInfo *botinfo;
int list_complete;
char sockdata[MSGLEN]; char sockdata[MSGLEN];

View File

@ -32,7 +32,7 @@
#include <tcl.h> #include <tcl.h>
LS Tcl_Interp *energymech_tcl = NULL; Tcl_Interp *energymech_tcl = NULL;
#define tclv_READ TCL_TRACE_READS #define tclv_READ TCL_TRACE_READS
#define tclv_WRITE TCL_TRACE_WRITES #define tclv_WRITE TCL_TRACE_WRITES
@ -62,7 +62,7 @@ typedef struct Tcl_TVInfo
} Tcl_TVInfo; } Tcl_TVInfo;
LS Tcl_TVInfo vinfolist[] = Tcl_TVInfo vinfolist[] =
{ {
{ TVINFO_pointer | TVINFO_CHAR, tclv_READ, "mech_currentnick", CurrentNick }, { TVINFO_pointer | TVINFO_CHAR, tclv_READ, "mech_currentnick", CurrentNick },
{ TVINFO_guid | TVINFO_INT, tclv_READ, "mech_guid" }, { 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; rdata.i = (current) ? current->guid : -1;
break; break;
case TVINFO_nick: case TVINFO_nick:
rdata.c = (current) ? current->nick : "(undefined variable)"; rdata.c = (current) ? getbotnick(current) : "(undefined variable)";
break; break;
case TVINFO_wantnick: case TVINFO_wantnick:
rdata.c = (current) ? current->wantnick : "(undefined variable)"; 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; char *cmdname;
void *func; void *func;

View File

@ -25,14 +25,6 @@
* These are more or less globally used.. * 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 MATCH_ALL "*"
#define TEXT_NOTINSERVLIST "(not in serverlist)" #define TEXT_NOTINSERVLIST "(not in serverlist)"
@ -80,8 +72,8 @@
#define TEXT_SERVERDELETED "Server has been deleted: %s:%i" #define TEXT_SERVERDELETED "Server has been deleted: %s:%i"
#define TEXT_MANYSERVMATCH "Several entries for %s exists, please specify port also" #define TEXT_MANYSERVMATCH "Several entries for %s exists, please specify port also"
/* do_core() */ /* do_core() */
#define TEXT_CURRNICKWANT "Current nick\t%s (Wanted: %s) [guid #%i]" #define TEXT_CURRNICKWANT "Current nick\t%s%s (Wanted: %s) [guid #%i]"
#define TEXT_CURRNICKHAS "Current nick\t%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_USERLISTSTATS "Users in userlist\t%i (%i Superuser%s, %i Bot%s)"
#define TEXT_ACTIVECHANS "Active channels\t%s" #define TEXT_ACTIVECHANS "Active channels\t%s"
#define TEXT_MOREACTIVECHANS "\t%s" #define TEXT_MOREACTIVECHANS "\t%s"
@ -91,11 +83,11 @@
#define TEXT_VHINACTIVE " - Inactive" #define TEXT_VHINACTIVE " - Inactive"
#define TEXT_CURRSERVER "Current Server\t%s:%i" #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_CURRSERVERNOT "Current Server\t" TEXT_NOTINSERVLIST
#define TEXT_TRYNEWSERVER "Trying new server, brb..." #define TEXT_TRYNEWSERVER "Trying new server, brb..."
#define TEXT_SWITCHSERVER "Switching servers..." #define TEXT_SWITCHSERVER "Switching servers..."
#define TEXT_SERVERONTIME "Server Ontime\t%s" #define TEXT_SERVERONTIME "Server Ontime\t%s"
#define TEXT_BOTMODES "Mode\t+%s"
#define TEXT_CURRENTTIME "Current Time\t%s" #define TEXT_CURRENTTIME "Current Time\t%s"
#define TEXT_BOTSTARTED "Started\t%s" #define TEXT_BOTSTARTED "Started\t%s"
@ -145,7 +137,7 @@
#define TEXT_TSWITCH " -t run normal startup, but exit right before going into main loop\n" #define TEXT_TSWITCH " -t run normal startup, but exit right before going into main loop\n"
#ifdef SHACRYPT #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 #elif MD5CRYPT
#define TEXT_PSWITCH1 " -p <string> encrypt <string> using the password hashing algorithm (MD5),\n" #define TEXT_PSWITCH1 " -p <string> encrypt <string> using the password hashing algorithm (MD5),\n"
#else #else
@ -153,9 +145,8 @@
#endif #endif
#define TEXT_PSWITCH2 " output the result and then quit.\n" #define TEXT_PSWITCH2 " output the result and then quit.\n"
#define TEXT_DSWITCH " -d start mech in debug mode\n" #define TEXT_DSWITCH " -d [file] start mech in debug mode, with an optional output file\n"
#define TEXT_OSWITCH " -o <file> write debug output to <file>\n" #define TEXT_XSWITCH " -x write a debug file before any exit\n"
#define TEXT_XSWITCH " -X write a debug file before exit\n"
#define TEXT_HDR_VERS "EnergyMech %s, %s\n" #define TEXT_HDR_VERS "EnergyMech %s, %s\n"
#define TEXT_HDR_FEAT "Features: %s\n" #define TEXT_HDR_FEAT "Features: %s\n"

View File

@ -46,20 +46,19 @@
#define DAY_IN_SECONDS (24*60*60) #define DAY_IN_SECONDS (24*60*60)
#define WEEK_IN_SECONDS (7*24*60*60) #define WEEK_IN_SECONDS (7*24*60*60)
LS TrivScore *lastwinner; TrivScore *lastwinner;
LS Chan *triv_chan = NULL; Chan *triv_chan = NULL;
LS Strp *triv_answers = NULL; Strp *triv_answers = NULL;
LS time_t triv_ask_time; time_t triv_ask_time;
LS time_t triv_next_time = 0; time_t triv_weektop10;
LS time_t triv_weektop10; int triv_mode;
LS int triv_mode; int triv_score;
LS int triv_score; int triv_streak;
LS int triv_streak; int triv_halt_flag;
LS int triv_halt_flag;
#endif /* TRIVIA */ #endif /* TRIVIA */
#define BIGSAY_DEFAULTFONT "default" #define BIGSAY_DEFAULTFONT DEFAULTSTR
#define FONT_EXTENSION ".bigchars" #define FONT_EXTENSION ".bigchars"
BigC *newchar; BigC *newchar;
@ -196,6 +195,7 @@ int read_bigcharset(char *fname)
int read_ascii(char *rest) int read_ascii(char *rest)
{ {
to_user_q(global_from,FMT_PLAIN,rest); to_user_q(global_from,FMT_PLAIN,rest);
return(0);
} }
#ifdef TRIVIA #ifdef TRIVIA
@ -216,7 +216,7 @@ void trivia_week_toppers(void)
int i,x; int i,x;
chosen[0] = NULL; 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) for(su=scorelist;su;su=su->next)
{ {
@ -269,7 +269,7 @@ void hint_one(void)
src = triv_answers->p; src = triv_answers->p;
while(*src) while(*src)
{ {
if (STRCHR(TRIV_METACHARS,*src)) if (stringchr(TRIV_METACHARS,*src))
*(dst++) = *src; *(dst++) = *src;
else else
*(dst++) = triv_qchar; *(dst++) = triv_qchar;
@ -306,7 +306,7 @@ void hint_two(void)
while(*src) while(*src)
{ {
if (STRCHR(TRIV_METACHARS,*src)) if (stringchr(TRIV_METACHARS,*src))
*(dst++) = *src; *(dst++) = *src;
else else
*(dst++) = triv_qchar; *(dst++) = triv_qchar;
@ -343,7 +343,7 @@ void hint_three(void)
while(*src) while(*src)
{ {
if (STRCHR(TRIV_METACHARS "aeiouyAEIOUY",*src)) if (stringchr(TRIV_METACHARS "aeiouyAEIOUY",*src))
*(dst++) = *src; *(dst++) = *src;
else else
*(dst++) = triv_qchar; *(dst++) = triv_qchar;
@ -364,7 +364,7 @@ void trivia_cleanup(void)
Strp *ans; Strp *ans;
triv_mode = TRIV_WAIT_QUESTION; triv_mode = TRIV_WAIT_QUESTION;
triv_next_time = now + triv_qdelay; triv_next_time = cx.now + triv_qdelay;
while((ans = triv_answers)) while((ans = triv_answers))
{ {
triv_answers = ans->next; triv_answers = ans->next;
@ -389,7 +389,7 @@ void trivia_check(Chan *chan, char *rest)
return; return;
have_answer: 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) 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", 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, 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) if (su == lastwinner)
{ {
@ -481,7 +481,7 @@ char *random_question(char *triv_rand)
} entry; } 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); return(NULL);
stringcat(stringcpy(tmpname,"trivia/"),triv_qfile); stringcat(stringcpy(tmpname,"trivia/"),triv_qfile);
@ -497,7 +497,7 @@ char *random_question(char *triv_rand)
#endif /* DEBUG */ #endif /* DEBUG */
stringcpy(triv_rand,tmpname); stringcpy(triv_rand,tmpname);
if ((p = STRCHR(triv_rand,'.')) == NULL) if ((p = stringchr(triv_rand,'.')) == NULL)
p = STREND(triv_rand); p = STREND(triv_rand);
stringcpy(p,".index"); stringcpy(p,".index");
@ -545,7 +545,7 @@ stop_trivia:
triv_chan = NULL; triv_chan = NULL;
triv_next_time = 0; triv_next_time = 0;
triv_halt_flag = FALSE; triv_halt_flag = FALSE;
short_tv &= ~TV_TRIVIA; cx.short_tv &= ~TV_TRIVIA;
return; return;
} }
@ -558,12 +558,12 @@ stop_trivia:
goto bad_question; goto bad_question;
triv_score = (RANDOM(2,9) + RANDOM(2,10) + RANDOM(2,10)) / 3; 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(); trivia_week_toppers();
triv_weektop10 = now; triv_weektop10 = cx.now;
} }
to_server("PRIVMSG %s :%s\n",triv_chan->name,question); to_server("PRIVMSG %s :%s\n",triv_chan->name,question);
@ -575,8 +575,6 @@ void trivia_tick(void)
Chan *chan; Chan *chan;
Mech *bot; 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)
@ -584,7 +582,7 @@ void trivia_tick(void)
if (triv_chan == chan) if (triv_chan == chan)
{ {
current = bot; current = bot;
triv_next_time = now + TRIV_HINT_DELAY; triv_next_time = cx.now + TRIV_HINT_DELAY;
switch(triv_mode) switch(triv_mode)
{ {
case TRIV_WAIT_QUESTION: case TRIV_WAIT_QUESTION:
@ -609,7 +607,6 @@ void trivia_tick(void)
} }
} }
} }
}
/* /*
* *
@ -737,7 +734,7 @@ void do_bigsay(COMMAND_ARGS)
if (temp[1] == '-') if (temp[1] == '-')
; /* allow .bigsay -- -dash- */ ; /* allow .bigsay -- -dash- */
else 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 '-' */ 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) for(bigc=fontlist;bigc;bigc=bigc->next)
{ {
if (STRCHR(bigc->chars,*pt)) if (stringchr(bigc->chars,*pt))
{ {
sp = bigc->data; sp = bigc->data;
for(x=0;x<i;x++) 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 *filename;
const char *message; const char *message;
@ -899,7 +896,7 @@ void do_ascii(COMMAND_ARGS)
int fd; int fd;
#ifdef DEBUG #ifdef DEBUG
if (STRCHR(rest,'/')) if (stringchr(rest,'/'))
{ {
debug("(do_ascii) '/' not permitted in filename\n"); debug("(do_ascii) '/' not permitted in filename\n");
ascii_badfile: ascii_badfile:
@ -919,7 +916,7 @@ ascii_badfile:
goto ascii_badfile; goto ascii_badfile;
} }
#else #else
if (STRCHR(rest,'/')) if (stringchr(rest,'/'))
{ {
ascii_badfile: ascii_badfile:
to_user_q(from,"%s","Bad filename or file does not exist"); 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 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. 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) void do_rand(COMMAND_ARGS)
{ {
const char *opt; const char *opt;
@ -968,18 +969,18 @@ void do_rand(COMMAND_ARGS)
if (!rest || *rest == 0) if (!rest || *rest == 0)
goto pick_randnum; goto pick_randnum;
if (attrtab[(uchar)*rest] & NUM) if (characterisnumeric)
{ {
max = 0; max = 0;
while(attrtab[(uchar)*rest] & NUM) while(characterisnumeric)
max = 10 * max + (*(rest++) - '0'); max = 10 * max + (*(rest++) - '0');
if (*rest == '-' || *rest == ' ') if (*rest == '-' || *rest == ' ')
rest++; rest++;
if ((attrtab[(uchar)*rest] & NUM) == 0) if (characterisnumeric == 0)
goto pick_randnum; goto pick_randnum;
min = max; min = max;
max = 0; max = 0;
while(attrtab[(uchar)*rest] & NUM) while(characterisnumeric)
max = 10 * max + (*(rest++) - '0'); max = 10 * max + (*(rest++) - '0');
goto pick_randnum; goto pick_randnum;
} }
@ -1069,10 +1070,10 @@ void do_trivia(COMMAND_ARGS)
to_server("PRIVMSG %s :Trivia starting! Get ready...\n",chan->name); to_server("PRIVMSG %s :Trivia starting! Get ready...\n",chan->name);
triv_chan = chan; triv_chan = chan;
triv_mode = TRIV_WAIT_QUESTION; triv_mode = TRIV_WAIT_QUESTION;
triv_next_time = now + triv_qdelay; triv_next_time = cx.now + triv_qdelay;
triv_weektop10 = now; triv_weektop10 = cx.now;
lastwinner = NULL; lastwinner = NULL;
short_tv |= TV_TRIVIA; cx.short_tv |= TV_TRIVIA;
if (!scorelist) if (!scorelist)
{ {
read_triviascore(); read_triviascore();
@ -1096,7 +1097,7 @@ void do_trivia(COMMAND_ARGS)
if (triv_chan) if (triv_chan)
{ {
uaccess = get_authaccess(from,triv_chan->name); uaccess = get_authaccess(from,triv_chan->name);
if (now > (triv_weektop10 + 300)) if (cx.now > (triv_weektop10 + 300))
n = 1; n = 1;
else else
n = uaccess; n = uaccess;
@ -1104,7 +1105,7 @@ void do_trivia(COMMAND_ARGS)
if (n) if (n)
{ {
trivia_week_toppers(); 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 regnr;
int pid; int pid;
int type; int type;
uint32_t cookie; uint32_t packets_sent;
uint32_t uptime; uint32_t uptime;
uint32_t ontime; uint32_t ontime;
uint32_t now; uint32_t mytime;
uint32_t sysup; uint32_t sysup;
} PackStub; } PackStub;
@ -51,10 +51,10 @@ typedef struct
int regnr; int regnr;
int pid; int pid;
int type; int type;
uint32_t cookie; uint32_t packets_sent;
uint32_t uptime; uint32_t uptime;
uint32_t ontime; uint32_t ontime;
uint32_t now; uint32_t mytime;
uint32_t sysup; uint32_t sysup;
char string[512]; char string[512];
@ -64,7 +64,7 @@ void init_uptime(void)
{ {
struct sockaddr_in sai; struct sockaddr_in sai;
uptimecookie = rand(); uptimepackets = 0;
if (!uptimehost) if (!uptimehost)
{ {
@ -94,9 +94,8 @@ void init_uptime(void)
void send_uptime(int type) void send_uptime(int type)
{ {
PackUp upPack; PackUp *upPack;
struct sockaddr_in sai; struct sockaddr_in sai;
struct stat st;
Server *sp; Server *sp;
const char *server,*nick; const char *server,*nick;
int sz; int sz;
@ -109,7 +108,7 @@ void send_uptime(int type)
{ {
char *host; char *host;
uptimelast = now + 10; uptimelast = cx.now + 10;
if ((host = poll_rawdns(uptimehost))) if ((host = poll_rawdns(uptimehost)))
{ {
if ((uptimeip = inet_addr(host)) != -1) if ((uptimeip = inet_addr(host)) != -1)
@ -128,37 +127,28 @@ void send_uptime(int type)
} }
#endif /* RAWDNS */ #endif /* RAWDNS */
upPack = (PackUp*)&globaldata;
/* /*
* update the time when we last sent packet * update the time when we last sent packet
*/ */
sz = (uptimelast + 1) & 7; 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; uptimepackets = uptimepackets + 1;
upPack.cookie = htonl(uptimecookie); upPack->packets_sent = htonl(uptimepackets);
upPack.now = htonl(now); upPack->mytime = htonl(cx.now);
upPack.regnr = uptimeregnr; upPack->regnr = uptimeregnr;
upPack.type = htonl(type); upPack->type = htonl(type);
upPack.uptime = htonl(uptime); upPack->uptime = htonl(uptime);
upPack.ontime = 0; /* set a few lines down */ upPack->ontime = 0; /* set a few lines down */
/* /*
* callouts to other functions should be done last (think compiler optimizations) * callouts to other functions should be done last (think compiler optimizations)
*/ */
upPack.pid = htonl(getpid()); upPack->pid = htonl(getpid());
upPack->sysup = htonl(cx.system_uptime);
/*
* this trick for most systems gets the system uptime
*/
if (stat("/proc",&st) < 0)
{
upPack.sysup = 0;
}
else
{
upPack.sysup = htonl(st.st_ctime);
}
server = UNKNOWN; server = UNKNOWN;
nick = BOTLOGIN; nick = BOTLOGIN;
@ -168,8 +158,8 @@ void send_uptime(int type)
*/ */
if (botlist) if (botlist)
{ {
nick = botlist->nick; nick = getbotnick(botlist);
upPack.ontime = htonl(botlist->ontime); upPack->ontime = htonl(botlist->ontime);
if ((sp = find_server(botlist->server))) if ((sp = find_server(botlist->server)))
{ {
server = (*sp->realname) ? sp->realname : sp->name; server = (*sp->realname) ? sp->realname : sp->name;
@ -190,12 +180,11 @@ void send_uptime(int type)
} }
#endif /* ! RAWDNS */ #endif /* ! RAWDNS */
sz = sizeof(PackStub) + 3 + StrlenX(nick,server,VERSION,NULL); sz = sizeof(PackStub) + snprintf(upPack->string,256,"%s %s %s",nick,server,VERSION);
if (sz > sizeof(PackUp))
return;
sprintf(upPack.string,"%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... * udp sending...
*/ */
@ -204,7 +193,7 @@ void send_uptime(int type)
sai.sin_addr.s_addr = uptimeip; sai.sin_addr.s_addr = uptimeip;
sai.sin_port = htons(uptimeport); 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) void uptime_death(int type)
@ -212,7 +201,7 @@ void uptime_death(int type)
#ifdef DEBUG #ifdef DEBUG
debug("(uptime_death) sending death message\n"); debug("(uptime_death) sending death message\n");
#endif /* DEBUG */ #endif /* DEBUG */
time(&now); time(&cx.now);
uptimelast = 0; /* avoid resolving the hostname */ uptimelast = 0; /* avoid resolving the hostname */
send_uptime(type); send_uptime(type);
uptimeport = 0; /* avoid sending more packets */ uptimeport = 0; /* avoid sending more packets */
@ -221,7 +210,8 @@ void uptime_death(int type)
void process_uptime(void) void process_uptime(void)
{ {
struct sockaddr_in sai; struct sockaddr_in sai;
int res,sz; unsigned int sz;
int res;
struct struct
{ {
int regnr; int regnr;
@ -238,7 +228,7 @@ void process_uptime(void)
res = recvfrom(uptimesock,(void*)&regPack,sizeof(regPack),0,(struct sockaddr*)&sai,&sz); res = recvfrom(uptimesock,(void*)&regPack,sizeof(regPack),0,(struct sockaddr*)&sai,&sz);
if (res == sizeof(regPack)) if (res == sizeof(regPack))
{ {
if (uptimecookie == ntohl(regPack.cookie)) if (uptimepackets == ntohl(regPack.cookie))
{ {
if (uptimeregnr == 0) if (uptimeregnr == 0)
uptimeregnr = ntohl(regPack.regnr); uptimeregnr = ntohl(regPack.regnr);
@ -246,7 +236,7 @@ void process_uptime(void)
} }
} }
if (uptimelast < now) if (uptimelast < cx.now)
{ {
send_uptime(UPTIME_BOTTYPE); send_uptime(UPTIME_BOTTYPE);
} }

View File

@ -1,7 +1,7 @@
/* /*
EnergyMech, IRC bot software 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 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 it under the terms of the GNU General Public License as published by
@ -26,7 +26,7 @@ typedef struct
} UsageList; } UsageList;
LS const UsageList ulist[] = const UsageList ulist[] =
{ {
#ifdef TOYBOX #ifdef TOYBOX
{ C_8BALL, "[text]" }, { C_8BALL, "[text]" },
@ -59,7 +59,7 @@ LS const UsageList ulist[] =
#endif /* CTCP */ #endif /* CTCP */
{ C_CYCLE, "[channel]" }, { C_CYCLE, "[channel]" },
#ifdef DEBUG #ifdef DEBUG
{ C_DEBUG, NULL }, { C_DEBUG, "[On <debugfile>|Off]" },
#endif /* DEBUG */ #endif /* DEBUG */
{ C_DEOP, "[channel] <nick|pattern [...]>" }, { C_DEOP, "[channel] <nick|pattern [...]>" },
{ C_DIE, "[reason]" }, { C_DIE, "[reason]" },
@ -115,6 +115,9 @@ LS const UsageList ulist[] =
#endif /* CTCP */ #endif /* CTCP */
{ C_QSHIT, "<nick> [reason]" }, { C_QSHIT, "<nick> [reason]" },
#ifdef NOTE #ifdef NOTE
#ifdef TOYBOX
{ C_RAND, "[#|#-#|# #|\"nick\"|\"luser\"]" },
#endif /* TOYBOX */
{ C_READ, "[-]<number>" }, { C_READ, "[-]<number>" },
#endif /* NOTE */ #endif /* NOTE */
{ C_RESET, NULL }, { C_RESET, NULL },
@ -137,7 +140,6 @@ LS const UsageList ulist[] =
{ C_SEND, "[to] <filename>" }, { C_SEND, "[to] <filename>" },
#endif /* DCC_FILE */ #endif /* DCC_FILE */
{ C_SERVER, "[[+|-]servername] [port] [pass]" }, { C_SERVER, "[[+|-]servername] [port] [pass]" },
{ C_SERVERGROUP,"[identifier]" },
{ C_SET, "[channel|*] [setting [value]]" }, { C_SET, "[channel|*] [setting [value]]" },
{ C_SETPASS, "<handle> <password>" }, { C_SETPASS, "<handle> <password>" },
{ C_SHIT, "<channel|*> <nick|mask> <action> [expire] <reason>" }, { C_SHIT, "<channel|*> <nick|mask> <action> [expire] <reason>" },
@ -146,7 +148,7 @@ LS const UsageList ulist[] =
{ C_SHUTDOWN, NULL }, { C_SHUTDOWN, NULL },
{ C_SITEBAN, "[channel] <nick|userhost>" }, { C_SITEBAN, "[channel] <nick|userhost>" },
{ C_SITEKB, "[channel] <nick> [reason]" }, { 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]" }, { C_STATS, "<type> [servername]" },
#ifdef TCL #ifdef TCL
#ifdef PLEASE_HACK_MY_SHELL #ifdef PLEASE_HACK_MY_SHELL

View File

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

View File

@ -1,7 +1,7 @@
/* /*
EnergyMech, IRC bot software 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 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 it under the terms of the GNU General Public License as published by
@ -53,9 +53,11 @@ int find_setting(const char *name)
{ {
int i; int i;
for(i=0;VarName[i].name;i++) for(i=0;i<SIZE_VARS;i++)
{ {
if (!stringcasecmp(name,VarName[i].name)) /* 223 = binary 11011111 -> convert lower case to upper */
if ((*name & 223) == *VarName[i].name)
if (stringcasecmp(name,VarName[i].name) == 0)
return(i); return(i);
} }
return(-1); return(-1);
@ -86,9 +88,11 @@ void set_binarydefault(UniVar *dst)
{ {
int i; int i;
for(i=0;VarName[i].name;i++) for(i=0;i<SIZE_VARS;i++)
{
dst[i].str_var = VarName[i].v.str; dst[i].str_var = VarName[i].v.str;
} }
}
void delete_vars(UniVar *vars, int which) 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) 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) 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) 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) 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) 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) void ec_ver(char *from, const char *to)
@ -277,7 +296,7 @@ void ec_guid(char *from, const char *to)
nobo_strcpy(tmp); nobo_strcpy(tmp);
} }
LS const struct static const struct
{ {
void (*func)(char *, const char *); void (*func)(char *, const char *);
char name[12]; char name[12];
@ -285,17 +304,23 @@ LS const struct
} ecmd[] = } ecmd[] =
{ {
/*
* Sorted by the second parameter alphabetical
*/
{ ec_access, "$access", 7 }, { ec_access, "$access", 7 },
{ ec_capabilities, "$cap", 4 }, { ec_capabilities, "$cap", 4 },
{ ec_cc, "$cc", 3 }, { ec_cc, "$cc", 3 },
{ ec_channels, "$channels", 9 }, { ec_channels, "$channels", 9 },
{ ec_time, "$time", 5 }, { ec_guid, "$guid", 5 },
{ ec_set, "$var(", 5 }, #ifdef HOSTINFO
{ ec_loadavg, "$load", 5 },
#endif /* HOSTINFO */
{ ec_on, "$on", 3 }, { ec_on, "$on", 3 },
{ ec_server, "$server", 7 }, { ec_server, "$server", 7 },
{ ec_time, "$time", 5 },
{ ec_up, "$up", 3 }, { ec_up, "$up", 3 },
{ ec_set, "$var(", 5 },
{ ec_ver, "$ver", 4 }, { ec_ver, "$ver", 4 },
{ ec_guid, "$guid", 5 },
{ NULL, "", 0 }, { NULL, "", 0 },
}; };
@ -382,6 +407,7 @@ void do_set(COMMAND_ARGS)
/* /*
* empty args, its "set" or "set #channel" * empty args, its "set" or "set #channel"
* list setting and values
*/ */
if (!name) if (!name)
{ {
@ -463,6 +489,10 @@ second_pass:
if ((which = find_setting(name)) == -1) if ((which = find_setting(name)) == -1)
{ {
set_usage: set_usage:
#ifdef DEBUG
if (from == cx.CoreUser.name)
debug("init: set error: %s\n",nullstr(name));
#endif
usage(from); /* usage for CurrentCmd->name */ usage(from); /* usage for CurrentCmd->name */
return; return;
} }
@ -573,6 +603,9 @@ num_data_ok:
} }
to_user(from,"Var: %s On: %s Set to: %s",VarName[which].name, to_user(from,"Var: %s On: %s Set to: %s",VarName[which].name,
(which >= CHANSET_SIZE) ? "(global)" : channel,(*rest) ? rest : NULLSTR); (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/" #define WEBROOT "web/"
LS WebSock *weblist; WebSock *weblist;
LS WebDoc docraw = { NULL, NULL, &web_raw }; WebDoc docraw = { NULL, NULL, &web_raw };
#if 0 #if 0
{ {
@ -45,7 +45,7 @@ LS WebDoc docraw = { NULL, NULL, &web_raw };
}; };
#endif #endif
LS WebDoc doclist[] = WebDoc doclist[] =
{ {
{ NULL, "/internalstatus.html", &web_botstatus }, { NULL, "/internalstatus.html", &web_botstatus },
#ifdef DEBUG #ifdef DEBUG
@ -125,7 +125,7 @@ char *webread(int s, char *rest, char *line)
return(NULL); 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) void eml_fmt(WebSock *client, char *format)
{ {
@ -133,7 +133,7 @@ void eml_fmt(WebSock *client, char *format)
char *src,*dest,*org; char *src,*dest,*org;
int out; int out;
int s = client->sock; int s = client->sock;
int n; int n __notused__;
org = NULL; org = NULL;
out = TRUE; out = TRUE;
@ -165,7 +165,7 @@ restart:
client->echan = (client->ebot) ? client->ebot->chanlist : NULL; client->echan = (client->ebot) ? client->ebot->chanlist : NULL;
break; break;
case 'b': case 'b':
src = (client->ebot) ? client->ebot->nick : (char*)NULLSTR; src = (client->ebot) ? getbotnick(client->ebot) : (char*)NULLSTR;
while(*src) while(*src)
{ {
NOBO; NOBO;
@ -241,7 +241,7 @@ void web_raw(WebSock *client, char *url)
char path[MSGLEN]; char path[MSGLEN];
char *src,*dest; char *src,*dest;
ino_t ino; ino_t ino;
int fd,eml,n; int fd,eml,n __notused__;
size_t sz; size_t sz;
eml = (matches("*.html",url)) ? TRUE : FALSE; eml = (matches("*.html",url)) ? TRUE : FALSE;
@ -328,7 +328,7 @@ void web_botstatus(WebSock *client, char *url)
"<h1>EnergyMech Status</h1>\r\n" "<h1>EnergyMech Status</h1>\r\n"
"Uptime: %s<br><br>\r\n" "Uptime: %s<br><br>\r\n"
"<u>Current bots</u>:<br>\r\n", "<u>Current bots</u>:<br>\r\n",
idle2str(now - uptime,FALSE)); idle2str(uptime,FALSE));
for(;bot;bot=bot->next) for(;bot;bot=bot->next)
{ {
@ -474,7 +474,7 @@ void process_web(void)
new = (WebSock*)Calloc(sizeof(WebSock)); new = (WebSock*)Calloc(sizeof(WebSock));
new->sock = s; new->sock = s;
new->status = WEB_WAITURL; new->status = WEB_WAITURL;
new->when = now; new->when = cx.now;
new->next = weblist; new->next = weblist;
weblist = new; weblist = new;
} }