Merge pull request #1 from MadCamel/master

update
This commit is contained in:
joonicks 2018-03-16 02:51:47 +01:00 committed by GitHub
commit 74e88ed675
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
63 changed files with 2799 additions and 1029 deletions

11
.gitignore vendored
View File

@ -9,12 +9,21 @@ src/energymech
src/gencmd
src/mcmd.h
src/usercombo.h
src/aliastest
src/safepathtest
*~
*.bak
*.passwd
mech.passwd
mech.conf
mech.users
mech.pid
mech.session
root.zone*
trick.conf
conf
debug*
*.log
*.stats
github

339
COPYING
View File

@ -1,339 +0,0 @@
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
675 Mass Ave, Cambridge, MA 02139, USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Library General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
Appendix: How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) 19yy <name of author>
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.
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) 19yy name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
<signature of Ty Coon>, 1 April 1989
Ty Coon, President of Vice
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Library General
Public License instead of this License.

67
FEATURES Normal file
View File

@ -0,0 +1,67 @@
--- Alias support
Command substitution
--- Async DNS support
Normally energymech uses blocking calls to lookup hostnames.
On bad networks this could cause problems because the whole mech
process will lock up until it gets its answer from the domain name
server. Async DNS support, or RawDNS for short, uses low level code
to do hostname lookups asynchronously.
--- Botnet support
Standard botnet functionality. Connect to other bots and share userlists
and other informaton. Partyline extends over the whole botnet.
--- Channel ban support
Sometimes ypu want to keep people from certain other channels out of your
own channel. With channel ban enabled, the bot will periodically do WHOIS on
users in your channel and if they are in your rivals channel as well, they can
be kicked or banned, etc.
--- Command output redirect
Certain commands like HELP normally require you to DCC chat or telnet to the
bot in order to execute. With command output redirect enabled, you can run
commands and force the output to be sent to a different target, like a nick,
channel or even file.
--- CTCP
Standard CTCP replies, VERSION, PING and FINGER. CTCP is not necessary for
DCC chat and DCC file support to operate.
--- DCC file support
--- Debug support
If you have a problem running a mech, debug output could explain whats going on.
Very necessary to include if you are a developer...
--- Dynamic channel limit (+l)
--- Dynamic command levels support
--- Greet support
--- HTTP server support
--- Host info support
--- IRC proxy support
--- IRCD extensions support
--- Newbie support
--- Note support
--- Notify support
--- Password hashing with MD5
--- Password hashing with SHA
--- Scripting with Python
--- Scripting with Tcl
--- Seen support
--- Session support
--- Statistics support
--- Telnet support
--- Trivia support
--- Toybox fun and games
--- Uptime support
--- URL capture support
--- WinGate support

View File

@ -1,6 +1,6 @@
#
# EnergyMech, IRC Bot software
# Copyright (c) 1997-2009 proton
# Copyright (c) 1997-2018 proton
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@ -17,14 +17,14 @@
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#
MISCFILES = COPYING CREDITS README README.TCL TODO VERSIONS VERSIONS-1 Makefile configure \
checkmech sample.conf sample.py sample.tcl sample.userfile default.bigchars
MISCFILES = CREDITS LICENSE README README.TCL TODO VERSIONS VERSIONS-1 Makefile configure \
checkmech sample.conf sample.py sample.tcl sample.userfile default.bigchars public/README
HELPFILES = help/8BALL help/ACCESS help/ALIAS help/AWAY help/BAN help/BANLIST help/BYE \
help/CCHAN help/CHACCESS help/CHANBAN help/CHANNELS help/CHAT help/CLEARSHIT \
help/CMD help/CORE help/CSERV help/CTCP help/CYCLE help/DEOP help/DIE \
help/DNS help/DNSSERVER help/DO help/DOWN help/ECHO help/ESAY help/FORGET \
help/GREET help/HELP help/IDLE help/INSULT help/INVITE help/JOIN help/KB \
help/DNS help/DNSSERVER help/DO help/DOWN help/ECHO help/ESAY help/FEATURES \
help/FORGET help/GREET help/HELP help/IDLE help/INSULT help/INVITE help/JOIN help/KB \
help/KICK help/KS help/LAST help/LEVELS help/LINK help/LOAD help/LUSERS help/ME \
help/MODE help/MSG help/NAMES help/NEXTSERVER help/NICK help/NOTIFY help/ONTIME \
help/OP help/PART help/PASSWD help/PROTECTION help/PYTHON help/PYTHONSCRIPT \
@ -45,23 +45,24 @@ RANDFILES = messages/8ball.txt messages/away.txt messages/insult.txt \
messages/kick.txt messages/nick.txt messages/pickup.txt \
messages/say.txt messages/signoff.txt messages/version.txt
STUBFILES = src/Makefile.in src/config.h.in src/ld/mech.ldscript
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/inet_addr.c config/ldtest.c \
TESTFILES = config/cc.c config/endian.c config/inet_addr.c config/ldtest.c \
config/ptr_size.c config/socket.c config/tcl.c config/which \
config/md5.h config/md5_internal.c config/pw.c \
config/sha_internal.c config/sha1.h \
config/inet_aton.c config/unaligned.c config/python.c
TRIVFILES = trivia/mkindex.c
SRCFILES = src/alias.c src/auth.c src/bounce.c src/chanban.c src/channel.c \
src/core.c src/ctcp.c src/debug.c src/dns.c src/dynamode.c \
src/function.c src/gencmd.c src/greet.c src/help.c src/irc.c \
src/function.c src/gencmd.c src/greet.c src/help.c src/hostinfo.c src/irc.c \
src/kicksay.c src/main.c src/mega.c src/net.c src/net_chan.c \
src/note.c src/notify.c src/ons.c src/parse.c src/perl.c \
src/prot.c src/python.c src/redirect.c src/reset.c src/seen.c \
src/shit.c src/socket.c src/spy.c src/stats.c src/tcl.c \
src/telnet.c src/toybox.c src/trivia.c src/uptime.c src/user.c \
src/telnet.c src/toybox.c src/trivia.c src/uptime.c src/urlcap.c src/user.c \
src/vars.c src/web.c src/md5/md5.c src/md5/md5.h
HDRFILES = src/defines.h src/global.h src/h.h src/settings.h src/structs.h src/text.h src/usage.h
@ -87,6 +88,19 @@ clean: FORCE
install: FORCE
$(MAKE) -C src install
mega: FORCE
$(MAKE) -C src mega
mega-install: FORCE
$(MAKE) -C src mega-install
#
# code validation tests
#
test: FORCE
$(MAKE) -C src test
#
# packing things up for distribution
#
@ -97,7 +111,7 @@ dist: FORCE
dist2: FORCE
rm -rf /tmp/$(DISTDIR)
mkdir /tmp/$(DISTDIR)
tar cf - $(DISTFILES) | ( cd /tmp/$(DISTDIR) ; tar --preserve -xf - )
tar cf - $(DISTFILES) | ( cd /tmp/$(DISTDIR) ; tar --preserve-permissions -xf - )
cd /tmp ; tar cf - $(DISTDIR) | gzip -9 > $(DISTDIR).tar.gz
rm -rf /tmp/$(DISTDIR)
chmod 644 /tmp/$(DISTDIR).tar.gz

17
README
View File

@ -48,15 +48,15 @@ Setup?
Read the sample.conf file to get an idea of the config file
commands and then try to make your own. A basic setup doesnt need
much more than NICK, ALTNICK, SET USERFILE, JOIN and SERVER
entries, the rest is just tweaks of default values.
much more than NICK, SET ALTNICK, SET USERFILE, JOIN and SERVER
entries, the rest is mostly just tweaks of default values.
Quick steps:
1) cp sample.conf mech.conf
2) pico mech.conf
-- replace ''pico'' with your favourite text editor, look through
2) edit mech.conf
-- replace ''edit'' with your favourite text editor, look through
the file for sections to change, you will have to remove lines
in order to get the bot to work. Check the file completely!
@ -72,7 +72,7 @@ Quick steps:
then 'run' this file with './energymech -f trick.conf'. this
will create a userfile with the name you chose ('mech.passwd'
is a good descriptive name which I usually use myself).
is a good descriptive name which I often use myself).
re-use the filename you selected in your proper configuration
file. and remember to 'rm -f mech.session' if you compiled your
@ -95,6 +95,10 @@ Updated Files?
~~~~~~~~~~~~~~
The main distro-site for the EnergyMech is:
https://github.com/MadCamel/energymech
Files, documentation and tips can be found at:
http://www.energymech.net
---*---
@ -131,5 +135,4 @@ IT COMES TO CONFIGURING AND USING IT.
---*---
proton, July 24th, 2009.
<mailto:proton@energymech.net>
proton, March 13th, 2018.

10
TODO
View File

@ -1,13 +1,17 @@
/*
* EnergyMech TODO (May 17th, 2009)
* EnergyMech TODO (March 9th, 2018)
*/
- URL grabber/log
- SSL support for irc server/botnet
- IPv6 support
- Script timer
- Genuine telnet protocol support for telnet sessions (?)
- SOCKS4/5 support (?)
- Undernet CService support (IMHO, should be channel settings (set=password, tog=enable/disable) /proton)
- DalNet Nickserv/Chanserv support (needed? they dont tolerate much bots on that network /proton)

View File

@ -1,3 +1,33 @@
3.0.99p4 -- WORK IN PROGRESS (~March, 2018)
* Added: STABLE/BETA/ALPHA status to individual features in configure.
* Fixed: If bot guid is changed or deleted in the config, and the bot
is reset, the connection associated with the removed guid
will be cleaned up and closed instead of lingering.
* Added: Support for read only userfiles. If you prefix the filename
with < the file wil never be written to, only ever read.
* Added: Bots now recover Ontime after a reset.
* Added: URL capturing with command to display recent URLs seen
by the bot. Also spy source "URL" for spy channels.
* Fixed: Rewrite of is_safepath() to conform with standard C
* Fixed: Potential crash bug in send_uptime()
* Fixed: Potential crash bug in debug()
* Added: New host information commands: HOSTINFO, MEMINFO, CPUINFO.
* Added: New configuration option: hostinfo
* Fixed: Custom ld script fintuning the core order.
* Changed: Rewrite of ALIAS aliasing routine, adding features.
* Fixed: RawDNS, again...
* Fixed: Save procvars only once in session file.
* Added: Support for SHA password hashes.
* Added: ESAY $cap will display compile time capabilities.
* Fixed: Potential memory corruption bug in do_user().
* Fixed: Aliases saves to session file.
* Added: CORE & INFO (statistics) can now be output redirected.
* Added: SPY to files saved in sessions.
* Fixed: HELP command should now be working properly again.
* Fixed: Strlen/Strlen2 code cleanup.
* Fixed: Various compiler warnings.
3.0.99p3 -- July 24th, 2009.
* Added: Python scripting support (supplied by S.Marquis)

12
config/endian.c Normal file
View File

@ -0,0 +1,12 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
int main(int argc, char **argv)
{
char x[4];
*((int*)&x) = 1;
printf("%i\n",x[0]);
return(0);
}

View File

@ -9,13 +9,22 @@
#define S(x) x,sizeof(x)
__page(".text.e")
#if 0
*(.text.e) /* RARE */
*(.text.d) /* INIT */ main
*(.text.b) /* CFG1 */ func2
*(.text.c) /* CMD1 */ func1
*(.text.a) /* CORE */
*(.text.f) /* DBUG */
#endif
__page(".text.c")
int function1(int a)
{
return a + 1;
}
__page(".text.c")
__page(".text.b")
int function2(int a)
{
return a + 2;
@ -24,7 +33,7 @@ int function2(int a)
__page(".text.d")
int main(int argc, char **argv)
{
if (((void*)main < (void*)function1) && ((void*)function1 < (void*)function2))
if (((void*)main < (void*)function2) && ((void*)function2 < (void*)function1))
write(1,S("yes\n"));
else
write(1,S("no\n"));

View File

@ -1,27 +1,48 @@
#include <stdio.h>
#include <string.h>
#include <unistd.h>
/*
The glibc2 version of this function supports additional encryption algorithms.
If salt is a character string starting with the characters "$id$" followed by a string terminated by "$":
$id$salt$encrypted
then instead of using the DES machine, id identifies the encryption method used and this then determines how the rest of the password string is inter-
preted. The following values of id are supported:
ID | Method
---------------------------------------------------------
1 | MD5
2a | Blowfish (not in mainline glibc; added in some
| Linux distributions)
5 | SHA-256 (since glibc 2.7)
6 | SHA-512 (since glibc 2.7)
*/
char * CRYPT_FUNC (const char *, const char *);
int main(void)
{
char *enc;
int md5,des;
int md5,sha;
md5 = sha = 0;
enc = CRYPT_FUNC ("abc","$6$");
if (enc && !strcmp(enc,"$6$$K7EQl9xnonG1x970hnNPqFQKlunsvbFHwzYLnbANzfHjxbphBMjLilW7SKO5EQOidBzcHseqkDOBCSPD8a3CR0"))
sha = 1;
des = md5 = 0;
enc = CRYPT_FUNC ("password","$1$XX");
if (enc && !strcmp(enc,"$1$XX$HxaXRcnpWZWDaXxMy1Rfn0"))
md5 = 1;
enc = CRYPT_FUNC ("password","XX");
if (enc && !strcmp(enc,"XXq2wKiyI43A2"))
des = 1;
if (md5 && des)
write(1,"DESaMD5\n",8);
else
if (des)
write(1,"DES\n",4);
else
if (sha)
write(1,"SHA",3);
if (md5)
write(1,"MD5\n",4);
write(1,"MD5",3);
write(1,"\n",1);
return(0);
}

1
config/sha1.h Symbolic link
View File

@ -0,0 +1 @@
../src/sha/sha1.h

1
config/sha_internal.c Symbolic link
View File

@ -0,0 +1 @@
../src/sha/sha1.c

402
configure vendored
View File

@ -1,7 +1,7 @@
#!/bin/sh
#
# EnergyMech, IRC Bot software
# Copyright (c) 1997-2009 proton
# Copyright (c) 1997-2018 proton
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@ -22,6 +22,9 @@ umask 077
# perl still unsupported
has_perl=no
compile=no
install=no
silentopt=no
for opt
do
@ -59,6 +62,7 @@ do
dynamode ) ft_dynamode=$yesno ;;
dyncmd ) ft_dyncmd=$yesno ;;
greet ) ft_greet=$yesno ;;
hostinfo ) ft_hostinfo=$yesno ;;
idwrap ) ft_idwrap=$yesno ;;
ircd_ext ) ft_ircd_ext=$yesno ;;
md5 ) ft_md5=$yesno ;;
@ -71,12 +75,14 @@ do
redirect ) ft_redirect=$yesno ;;
seen ) ft_seen=$yesno ;;
session ) ft_session=$yesno ;;
sha ) ft_sha=$yesno ;;
stats ) ft_stats=$yesno ;;
tcl ) ft_tcl=$yesno ;;
telnet ) ft_telnet=$yesno ;;
toybox ) ft_toybox=$yesno ;;
trivia ) ft_trivia=$yesno ;;
uptime ) ft_uptime=$yesno ;;
urlcapture ) ft_urlcapture=$yesno ;;
web ) ft_web=$yesno ;;
wingate ) ft_wingate=$yesno ;;
esac
@ -105,9 +111,9 @@ do
esac
case "$feature" in
debug | botnet | telnet | alias | seen | session | dyncmd | newbie | wingate | md5 \
| ctcp | dccfile | uptime | redirect | greet | perl | profiling | tcl | dynamode | web \
| note | notify | trivia | toybox | bounce | stats | rawdns | ircd_ext | idwrap | chanban | python )
debug | botnet | telnet | alias | seen | session | dyncmd | newbie | wingate | md5 | sha \
| ctcp | dccfile | uptime | redirect | greet | perl | profiling | tcl | dynamode | web | hostinfo \
| note | notify | trivia | toybox | bounce | stats | rawdns | ircd_ext | idwrap | chanban | python | urlcapture )
case _"$optarg"_ in
_yes_ | _no_ | __ )
;;
@ -151,6 +157,8 @@ do
dyncmd_no ) ft_dyncmd=no ;;
greet_yes | greet_ ) ft_greet=yes ;;
greet_no ) ft_greet=no ;;
hostinfo_yes | hostinfo_ ) ft_hostinfo=yes ;;
hostinfo_no ) ft_hostinfo=no ;;
idwrap_yes | idwrap_ ) ft_idwrap=yes ;;
idwrap_no ) ft_idwrap=no ;;
ircd_ext_yes | ircd_ext_ ) ft_ircd_ext=yes ;;
@ -175,6 +183,8 @@ do
seen_no ) ft_seen=no ;;
session_yes | session_ ) ft_session=yes ;;
session_no ) ft_session=no ;;
sha_yes | sha_ ) ft_seen=yes ;;
sha_no ) ft_sha=no ;;
stats_yes | stats_ ) ft_stats=yes ;;
stats_no ) ft_stats=no ;;
tcl_yes | tcl_ ) ft_tcl=yes ;;
@ -187,6 +197,8 @@ do
trivia_no ) ft_trivia=no ;;
uptime_yes | uptime_ ) ft_uptime=yes ;;
uptime_no ) ft_uptime=no ;;
urlcapture_yes | urlcapture_ ) ft_urlcapture=yes ;;
urlcapture_no ) ft_urlcapture=no ;;
web_yes | web_ ) ft_web=yes ;;
web_no ) ft_web=no ;;
wingate_yes | wingate_ ) ft_wingate=yes ;;
@ -207,6 +219,7 @@ do
dynamode ) ft_dynamode=no ;;
dyncmd ) ft_dyncmd=no ;;
greet ) ft_greet=no ;;
hostinfo ) ft_hostinfo=no ;;
idwrap ) ft_idwrap=no ;;
ircd_ext ) ft_ircd_ext=no ;;
md5 ) ft_md5=no ;;
@ -220,17 +233,23 @@ do
redirect ) ft_redirect=no ;;
seen ) ft_seen=no ;;
session ) ft_session=no ;;
sha ) ft_sha=yes ;;
stats ) ft_stats=no ;;
tcl ) ft_tcl=no ;;
telnet ) ft_telnet=no ;;
toybox ) ft_toybox=no ;;
trivia ) ft_trivia=no ;;
uptime ) ft_uptime=no ;;
urlcapture ) ft_urlcapture=no ;;
web ) ft_web=no ;;
wingate ) ft_wingate=no ;;
esac
;;
--compile) compile=yes ;;
--install) install=yes ;;
--silence=options) silentopt=yes ;;
--md5=internal) ft_md5=internal ;;
--sha=internal) ft_sha=internal ;;
--use-cpuflags) cc_arch_opt=yes ;;
--no-cpuflags) cc_arch_opt=no ;;
--use-optimize) cc_optimize_opt=yes ;;
@ -253,6 +272,7 @@ do
ft_dynamode=yes
ft_dyncmd=yes
ft_greet=yes
ft_hostinfo=yes
ft_ircd_ext=yes
ft_md5=yes
ft_newbie=yes
@ -263,12 +283,14 @@ do
ft_redirect=yes
ft_seen=yes
ft_session=yes
ft_sha=yes
ft_stats=yes
ft_tcl=yes
ft_telnet=yes
ft_toybox=yes
ft_trivia=yes
ft_uptime=yes
ft_urlcapture=yes
ft_web=yes
ft_wingate=yes
;;
@ -283,18 +305,25 @@ Features and packages:
--with-FEATURE[=ARG] use FEATURE [ARG=yes]
--without-FEATURE do not use FEATURE (same as --with-FEATURE=no)
--md5=internal Use internal routines for MD5 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
--no-ofp Do not use compiler flag -fomit-frame-pointer
#md5 | ctcp | dccfile | uptime | redirect | greet | perl | dynamode | web \
#note | notify | trivia | toybox | bounce | stats | rawdns | ircd_ext | idwrap | chanban | python )
--with-alias ALIAS support
--with-botnet Botnet support
--with-debug Debug support
--with-dyncmd Dynamic command levels support
--with-hostinfo Support for code that reveals/displays/shares information about the host
that the bot is running on
--with-newbie Newbie support
--with-profiling Profiling (gcc+gprof)
--with-seen SEEN support
--with-session Session support
--with-tcl Tcl support
--with-telnet Telnet support
--with-uptime Include code that sends uptime reports to the IRC bot uptime contest server
--with-urlcapture URL capture support
--with-wingate Wingate support
__EOT__
exit 0
@ -330,7 +359,7 @@ fi
echo $ac_n "checking system type ... "$ac_c
cf_ERR=yes
UNAME=`config/which uname`
UNAME=`config/which uname`
test -x $UNAME && cf_ERR=
if test -z "$cf_ERR" && cf_ERR=yes && $UNAME -s 1> /dev/null 2> /dev/null; then
@ -359,7 +388,7 @@ if [ "$cf_SYS" = AIX ]; then
else
cf_SYSMACH="$cf_SYS"'-'"$cf_MACH"
fi
echo $ac_t "$cf_SYSMACH"
#
@ -578,7 +607,41 @@ esac
rm -f $TESTP
#
# big/little endian
#
TESTC=config/endian.c
if [ -z "$endian" ]; then
endian=unknown
echo $ac_n "checking endianness ... "$ac_c
$CC -o $TESTP $TESTC 1> /dev/null 2> /dev/null
if [ -x $TESTP ]; then
endian=`$TESTP`
if [ "$endian" == "1" ]; then
endian="little"
else
endian="big"
fi
fi
echo $ac_t "$endian endian"
fi
case "$endian" in
little )
LIT_END="#define LITTLE_ENDIAN"
BIG_END="#undef BIG_ENDIAN"
;;
* )
LIT_END="#undef LITTLE_ENDIAN"
BIG_END="#define BIG_ENDIAN"
;;
esac
rm -f $TESTP
#
# Some processors like Sparc, will cause a bus error (SIGBUS) if you try to access unaligned memory
#
has_unaligned=no
@ -619,7 +682,7 @@ echo $ac_t "$has_inet_addr"
rm -f $TESTP
#
# where is inet_addr() ?
# where is inet_aton() ?
#
has_inet_aton=no
@ -663,13 +726,59 @@ echo $ac_t "$has_socket"
rm -f $TESTP
#
# check for MD5 capabilities
# check for SHA capabilities in libc/glibc/libcrypt
#
has_sha=no
has_md5=no
has_des=no
if [ ! "$ft_md5" = no ]; then
if [ ! "$ft_sha" = no ]; then
TESTC=config/pw.c
echo $ac_n "checking for crypt() ... "$ac_c
echo $ac_n "checking for SHA in crypt() ... "$ac_c
sha_internal=
crypt_func='-DCRYPT_FUNC=crypt'
CRYPT_FUNCTION='#define CRYPT_FUNC crypt'
if [ "$ft_sha" = internal ]; then
sha_internal=config/sha_internal.c
crypt_func='-DCRYPT_FUNC=sha_crypt'
CRYPT_FUNCTION='#define CRYPT_FUNC sha_crypt'
fi
$CC -o $TESTP $TESTC $sha_internal $crypt_func 1> /dev/null 2> /dev/null
if [ ! -x $TESTP ]; then
libcrypt=-lcrypt
has_sha=yes
$CC -o $TESTP $TESTC $crypt_func $libcrypt 1> /dev/null 2> /dev/null
fi
if [ ! -x $TESTP ]; then
libcrypt=/usr/lib/libcrypt.so
has_sha=yes
$CC -o $TESTP $TESTC $crypt_func $libcrypt 1> /dev/null 2> /dev/null
fi
if [ ! -x $TESTP ]; then
has_sha=no
libcrypt=
fi
if [ -x $TESTP ]; then
pwhash=`$TESTP`
case "$pwhash" in
MD5 ) has_md5=yes ;;
SHAMD5 )
has_md5=yes
has_sha=yes
;;
esac
fi
echo $ac_t "$has_sha"
[ "$has_sha" = yes -a "$sha_internal" ] && has_sha=internal
rm -f $TESTP
fi
#
# check for MD5 capabilities in libc/glibc/libcrypt
#
if [ "$has_md5" = yes ]; then
echo "checking for MD5 in crypt() ... (cached) yes"
elif [ ! "$ft_md5" = no ]; then
TESTC=config/pw.c
echo $ac_n "checking for MD5 in crypt() ... "$ac_c
md5_internal=
crypt_func='-DCRYPT_FUNC=crypt'
CRYPT_FUNCTION='#define CRYPT_FUNC crypt'
@ -697,11 +806,6 @@ if [ ! "$ft_md5" = no ]; then
pwhash=`$TESTP`
case "$pwhash" in
MD5 ) has_md5=yes ;;
DES ) has_des=yes ;;
DESaMD5 )
has_md5=yes
has_des=yes
;;
esac
fi
echo $ac_t "$has_md5"
@ -794,10 +898,10 @@ TESTC=config/ldtest.c
echo $ac_n "checking for friendly ld ... "$ac_c
$CC -o $TESTP $TESTC -Wl,-T,src/ld/mech.ldscript 1> /dev/null 2> /dev/null
$CC -o $TESTP $TESTC -Wl,-T,src/ld/elf64-x86-64 1> /dev/null 2> /dev/null
if [ -x $TESTP ]; then
if [ `$TESTP` = "yes" ]; then
ldscript='-Wl,-T,ld/mech.ldscript'
ldscript='-Wl,-T,ld/elf64-x86-64'
has_ldscript=yes
fi
fi
@ -847,140 +951,168 @@ if [ "$ft_md5" = internal ]; then
MD5_O=md5/md5.o
fi
SHA_O=
if [ "$ft_sha" = internal ]; then
SHA_O=sha/sha.o
fi
out=echo
if [ "$silentopt" == yes ]; then
out=/bin/true
fi
echo
echo "Do you want ..."
echo
$out "Do you want ..."
$out
def_alias='#undef ALIAS'
unset ans
echo $ac_n "Alias support? ............................. [Y/n] "$ac_c
test "$ft_alias" && echo "$ft_alias" && ans=$ft_alias
$out $ac_n "[STABLE] Alias support? ............................. [Y/n] "$ac_c
test "$ft_alias" && $out "$ft_alias" && ans=$ft_alias
test -z "$ft_alias" && read ans
test -z "$ans" -o "$ans" = y -o "$ans" = Y -o "$ans" = yes -o "$ans" = YES -o "$ans" = Yes && def_alias='#define ALIAS'
def_toybox='#undef TOYBOX'
unset ans
echo $ac_n "Amusing misc commands (toybox)? ............ [Y/n] "$ac_c
test "$ft_toybox" && echo "$ft_toybox" && ans=$ft_toybox
test -z "$ft_toybox" && read ans
test -z "$ans" -o "$ans" = y -o "$ans" = Y -o "$ans" = yes -o "$ans" = YES -o "$ans" = Yes && def_toybox='#define TOYBOX'
def_rawdns='#undef RAWDNS'
unset ans
echo $ac_n "Async DNS support? ......................... [y/N] "$ac_c
test "$ft_rawdns" && echo "$ft_rawdns" && ans=$ft_rawdns
$out $ac_n "[ BETA ] Async DNS support? ......................... [y/N] "$ac_c
test "$ft_rawdns" && $out "$ft_rawdns" && ans=$ft_rawdns
test -z "$ft_rawdns" && read ans
test "$ans" = y -o "$ans" = Y -o "$ans" = yes -o "$ans" = YES -o "$ans" = Yes && def_rawdns='#define RAWDNS'
def_botnet='#undef BOTNET'
unset ans
echo $ac_n "Botnet support? ............................ [Y/n] "$ac_c
test "$ft_botnet" && echo "$ft_botnet" && ans=$ft_botnet
$out $ac_n "[STABLE] Botnet support? ............................ [Y/n] "$ac_c
test "$ft_botnet" && $out "$ft_botnet" && ans=$ft_botnet
test -z "$ft_botnet" && read ans
test -z "$ans" -o "$ans" = y -o "$ans" = Y -o "$ans" = yes -o "$ans" = YES -o "$ans" = Yes && def_botnet='#define BOTNET'
def_chanban='#undef CHANBAN'
unset ans
echo $ac_n "Channel ban support? ....................... [Y/n] "$ac_c
test "$ft_chanban" && echo "$ft_chanban" && ans=$ft_chanban
$out $ac_n "[STABLE] Channel ban support? ....................... [Y/n] "$ac_c
test "$ft_chanban" && $out "$ft_chanban" && ans=$ft_chanban
test -z "$ft_chanban" && read ans
test -z "$ans" -o "$ans" = y -o "$ans" = Y -o "$ans" = yes -o "$ans" = YES -o "$ans" = Yes && def_chanban='#define CHANBAN'
def_redirect='#undef REDIRECT'
unset ans
$out $ac_n "[STABLE] Command output redirect? ................... [Y/n] "$ac_c
test "$ft_redirect" && $out "$ft_redirect" && ans=$ft_redirect
test -z "$ft_redirect" && read ans
test -z "$ans" -o "$ans" = y -o "$ans" = Y -o "$ans" = yes -o "$ans" = YES -o "$ans" = Yes && def_redirect='#define REDIRECT'
def_ctcp='#undef CTCP'
unset ans
echo $ac_n "CTCP? ...................................... [Y/n] "$ac_c
test "$ft_ctcp" && echo "$ft_ctcp" && ans=$ft_ctcp
$out $ac_n "[STABLE] CTCP? ...................................... [Y/n] "$ac_c
test "$ft_ctcp" && $out "$ft_ctcp" && ans=$ft_ctcp
test -z "$ft_ctcp" && read ans
test -z "$ans" -o "$ans" = y -o "$ans" = Y -o "$ans" = yes -o "$ans" = YES -o "$ans" = Yes && def_ctcp='#define CTCP'
def_dccfile='#undef DCC_FILE'
unset ans
echo $ac_n "DCC file support? .......................... [Y/n] "$ac_c
test "$ft_dccfile" && echo "$ft_dccfile" && ans=$ft_dccfile
$out $ac_n "[STABLE] DCC file support? .......................... [Y/n] "$ac_c
test "$ft_dccfile" && $out "$ft_dccfile" && ans=$ft_dccfile
test -z "$ft_dccfile" && read ans
test -z "$ans" -o "$ans" = y -o "$ans" = Y -o "$ans" = yes -o "$ans" = YES -o "$ans" = Yes && def_dccfile='#define DCC_FILE'
def_debug='#undef DEBUG'
unset ans
echo $ac_n "Debug support? ............................. [y/N] "$ac_c
test "$ft_debug" && echo "$ft_debug" && ans=$ft_debug
$out $ac_n "[STABLE] Debug support? ............................. [y/N] "$ac_c
test "$ft_debug" && $out "$ft_debug" && ans=$ft_debug
test -z "$ft_debug" && read ans
test "$ans" = y -o "$ans" = Y -o "$ans" = yes -o "$ans" = YES -o "$ans" = Yes && def_debug='#define DEBUG'
def_dynamode='#undef DYNAMODE'
unset ans
echo $ac_n "Dynamic channel limit (+l)? ................ [Y/n] "$ac_c
test "$ft_dynamode" && echo "$ft_dynamode" && ans=$ft_dynamode
$out $ac_n "[STABLE] Dynamic channel limit (+l)? ................ [Y/n] "$ac_c
test "$ft_dynamode" && $out "$ft_dynamode" && ans=$ft_dynamode
test -z "$ft_dynamode" && read ans
test -z "$ans" -o "$ans" = y -o "$ans" = Y -o "$ans" = yes -o "$ans" = YES -o "$ans" = Yes && def_dynamode='#define DYNAMODE'
def_dyncmd='#undef DYNCMD'
unset ans
echo $ac_n "Dynamic command levels support? ............ [Y/n] "$ac_c
test "$ft_dyncmd" && echo "$ft_dyncmd" && ans=$ft_dyncmd
$out $ac_n "[STABLE] Dynamic command levels support? ............ [Y/n] "$ac_c
test "$ft_dyncmd" && $out "$ft_dyncmd" && ans=$ft_dyncmd
test -z "$ft_dyncmd" && read ans
test -z "$ans" -o "$ans" = y -o "$ans" = Y -o "$ans" = yes -o "$ans" = YES -o "$ans" = Yes && def_dyncmd='#define DYNCMD'
def_bounce='#undef BOUNCE'
unset ans
echo $ac_n "IRC proxy support? ......................... [Y/n] "$ac_c
test "$ft_bounce" && echo "$ft_bounce" && ans=$ft_bounce
test -z "$ft_bounce" && read ans
test -z "$ans" -o "$ans" = y -o "$ans" = Y -o "$ans" = yes -o "$ans" = YES -o "$ans" = Yes && def_bounce='#define BOUNCE'
def_ircd_ext='#undef IRCD_EXTENSIONS'
unset ans
echo $ac_n "IRCD extensions support? ................... [Y/n] "$ac_c
test "$ft_ircd_ext" && echo "$ft_ircd_ext" && ans=$ft_ircd_ext
test -z "$ft_ircd_ext" && read ans
test -z "$ans" -o "$ans" = y -o "$ans" = Y -o "$ans" = yes -o "$ans" = YES -o "$ans" = Yes && def_ircd_ext='#define IRCD_EXTENSIONS'
def_greet='#undef GREET'
unset ans
echo $ac_n "Greet support? ............................. [Y/n] "$ac_c
test "$ft_greet" && echo "$ft_greet" && ans=$ft_greet
$out $ac_n "[STABLE] Greet support? ............................. [Y/n] "$ac_c
test "$ft_greet" && $out "$ft_greet" && ans=$ft_greet
test -z "$ft_greet" && read ans
test -z "$ans" -o "$ans" = y -o "$ans" = Y -o "$ans" = yes -o "$ans" = YES -o "$ans" = Yes && def_greet='#define GREET'
def_web='#undef WEB'
unset ans
echo $ac_n "HTTP server support? ....................... [y/N] "$ac_c
test "$ft_web" && echo "$ft_web" && ans=$ft_web
$out $ac_n "[ ALPHA] HTTP server support? ....................... [y/N] "$ac_c
test "$ft_web" && $out "$ft_web" && ans=$ft_web
test -z "$ft_web" && read ans
test "$ans" = y -o "$ans" = Y -o "$ans" = yes -o "$ans" = YES -o "$ans" = Yes && def_web='#define WEB'
def_md5='#undef MD5CRYPT'
def_hostinfo='#undef HOSTINFO'
unset ans
echo $ac_n "MD5 password support? ...................... [Y/n] "$ac_c
if [ "$has_md5" = no ]; then
echo 'no (unsupported)'
else
test "$ft_md5" && echo "$ft_md5" && ans=$ft_md5
test -z "$ft_md5" && read ans
test -z "$ans" -o "$ans" = y -o "$ans" = Y -o "$ans" = yes -o "$ans" = YES -o "$ans" = Yes -o "$ans" = internal && def_md5='#define MD5CRYPT'
fi
$out $ac_n "[ BETA ] Host info support? ......................... [Y/n] "$ac_c
test "$ft_hostinfo" && $out "$ft_hostinfo" && ans=$ft_hostinfo
test -z "$ft_hostinfo" && read ans
test -z "$ans" -o "$ans" = y -o "$ans" = Y -o "$ans" = yes -o "$ans" = YES -o "$ans" = Yes && def_hostinfo='#define HOSTINFO'
def_bounce='#undef BOUNCE'
unset ans
$out $ac_n "[STABLE] IRC proxy support? ......................... [Y/n] "$ac_c
test "$ft_bounce" && $out "$ft_bounce" && ans=$ft_bounce
test -z "$ft_bounce" && read ans
test -z "$ans" -o "$ans" = y -o "$ans" = Y -o "$ans" = yes -o "$ans" = YES -o "$ans" = Yes && def_bounce='#define BOUNCE'
def_ircd_ext='#undef IRCD_EXTENSIONS'
unset ans
$out $ac_n "[ BETA ] IRCD extensions support? ................... [Y/n] "$ac_c
test "$ft_ircd_ext" && $out "$ft_ircd_ext" && ans=$ft_ircd_ext
test -z "$ft_ircd_ext" && read ans
test -z "$ans" -o "$ans" = y -o "$ans" = Y -o "$ans" = yes -o "$ans" = YES -o "$ans" = Yes && def_ircd_ext='#define IRCD_EXTENSIONS'
def_newbie='#undef NEWBIE'
unset ans
echo $ac_n "Newbie support? ............................ [Y/n] "$ac_c
test "$ft_newbie" && echo "$ft_newbie" && ans=$ft_newbie
$out $ac_n "[STABLE] Newbie support? ............................ [Y/n] "$ac_c
test "$ft_newbie" && $out "$ft_newbie" && ans=$ft_newbie
test -z "$ft_newbie" && read ans
test -z "$ans" -o "$ans" = y -o "$ans" = Y -o "$ans" = yes -o "$ans" = YES -o "$ans" = Yes && def_newbie='#define NEWBIE'
def_note='#undef NOTE'
unset ans
echo $ac_n "Note support? .............................. [Y/n] "$ac_c
test "$ft_note" && echo "$ft_note" && ans=$ft_note
$out $ac_n "[STABLE] Note support? .............................. [Y/n] "$ac_c
test "$ft_note" && $out "$ft_note" && ans=$ft_note
test -z "$ft_note" && read ans
test -z "$ans" -o "$ans" = y -o "$ans" = Y -o "$ans" = yes -o "$ans" = YES -o "$ans" = Yes && def_note='#define NOTE'
def_notify='#undef NOTIFY'
unset ans
echo $ac_n "Notify support? ............................ [Y/n] "$ac_c
test "$ft_notify" && echo "$ft_notify" && ans=$ft_notify
$out $ac_n "[STABLE] Notify support? ............................ [Y/n] "$ac_c
test "$ft_notify" && $out "$ft_notify" && ans=$ft_notify
test -z "$ft_notify" && read ans
test -z "$ans" -o "$ans" = y -o "$ans" = Y -o "$ans" = yes -o "$ans" = YES -o "$ans" = Yes && def_notify='#define NOTIFY'
def_md5='#undef MD5CRYPT'
unset ans
$out $ac_n "[STABLE] Password hashing with MD5? (less secure) ... [Y/n] "$ac_c
if [ "$has_md5" = no ]; then
$out 'no (unsupported)'
else
test "$ft_md5" && $out "$ft_md5" && ans=$ft_md5
test -z "$ft_md5" && read ans
test -z "$ans" -o "$ans" = y -o "$ans" = Y -o "$ans" = yes -o "$ans" = YES -o "$ans" = Yes -o "$ans" = internal && def_md5='#define MD5CRYPT'
fi
def_sha='#undef SHACRYPT'
unset ans
$out $ac_n "[ BETA ] Password hashing with SHA? (best) .......... [Y/n] "$ac_c
if [ "$has_sha" = no ]; then
$out 'no (unsupported)'
else
test "$ft_sha" && $out "$ft_sha" && ans=$ft_sha
test -z "$ft_sha" && read ans
test -z "$ans" -o "$ans" = y -o "$ans" = Y -o "$ans" = yes -o "$ans" = YES -o "$ans" = Yes -o "$ans" = internal && def_sha='#define SHACRYPT'
fi
#
# perl support not yet functional (2009-05-11)
#
@ -997,11 +1129,11 @@ def_perl='#undef PERL'
def_python='#undef PYTHON'
unset ans
echo $ac_n "Python scripting support? .................. [y/N] "$ac_c
$out $ac_n "[ BETA ] Scripting with Python? ..................... [y/N] "$ac_c
if [ "$has_python" = no ]; then
echo 'no (unsupported)'
$out 'no (unsupported)'
else
test "$ft_python" && echo "$ft_python" && ans=$ft_python
test "$ft_python" && $out "$ft_python" && ans=$ft_python
test -z "$ft_python" && read ans
test "$ans" = y -o "$ans" = Y -o "$ans" = yes -o "$ans" = YES -o "$ans" = Yes && def_python='#define PYTHON'
fi
@ -1010,41 +1142,13 @@ if [ "$def_python" = '#undef PYTHON' ]; then
incpython=
fi
def_redirect='#undef REDIRECT'
unset ans
echo $ac_n "Command output redirect? ................... [Y/n] "$ac_c
test "$ft_redirect" && echo "$ft_redirect" && ans=$ft_redirect
test -z "$ft_redirect" && read ans
test -z "$ans" -o "$ans" = y -o "$ans" = Y -o "$ans" = yes -o "$ans" = YES -o "$ans" = Yes && def_redirect='#define REDIRECT'
def_seen='#undef SEEN'
unset ans
echo $ac_n "Seen support? .............................. [y/N] "$ac_c
test "$ft_seen" && echo "$ft_seen" && ans=$ft_seen
test -z "$ft_seen" && read ans
test "$ans" = y -o "$ans" = Y -o "$ans" = yes -o "$ans" = YES -o "$ans" = Yes && def_seen='#define SEEN'
def_session='#undef SESSION'
unset ans
echo $ac_n "Session support? ........................... [Y/n] "$ac_c
test "$ft_session" && echo "$ft_session" && ans=$ft_session
test -z "$ft_session" && read ans
test -z "$ans" -o "$ans" = y -o "$ans" = Y -o "$ans" = yes -o "$ans" = YES -o "$ans" = Yes && def_session='#define SESSION'
def_stats='#undef STATS'
unset ans
echo $ac_n "Statistics support? ........................ [Y/n] "$ac_c
test "$ft_stats" && echo "$ft_stats" && ans=$ft_stats
test -z "$ft_stats" && read ans
test -z "$ans" -o "$ans" = y -o "$ans" = Y -o "$ans" = yes -o "$ans" = YES -o "$ans" = Yes && def_stats='#define STATS'
def_tcl='#undef TCL'
unset ans
echo $ac_n "Tcl scripting support? ..................... [y/N] "$ac_c
$out $ac_n "[ BETA ] Scripting with Tcl? ........................ [y/N] "$ac_c
if [ "$has_tcl" = no ]; then
echo 'no (unsupported)'
$out 'no (unsupported)'
else
test "$ft_tcl" && echo "$ft_tcl" && ans=$ft_tcl
test "$ft_tcl" && $out "$ft_tcl" && ans=$ft_tcl
test -z "$ft_tcl" && read ans
test "$ans" = y -o "$ans" = Y -o "$ans" = yes -o "$ans" = YES -o "$ans" = Yes && def_tcl='#define TCL'
fi
@ -1053,35 +1157,70 @@ if [ "$def_tcl" = '#undef TCL' ]; then
inctcl=
fi
def_seen='#undef SEEN'
unset ans
$out $ac_n "[STABLE] Seen support? .............................. [y/N] "$ac_c
test "$ft_seen" && $out "$ft_seen" && ans=$ft_seen
test -z "$ft_seen" && read ans
test "$ans" = y -o "$ans" = Y -o "$ans" = yes -o "$ans" = YES -o "$ans" = Yes && def_seen='#define SEEN'
def_session='#undef SESSION'
unset ans
$out $ac_n "[STABLE] Session support? ........................... [Y/n] "$ac_c
test "$ft_session" && $out "$ft_session" && ans=$ft_session
test -z "$ft_session" && read ans
test -z "$ans" -o "$ans" = y -o "$ans" = Y -o "$ans" = yes -o "$ans" = YES -o "$ans" = Yes && def_session='#define SESSION'
def_stats='#undef STATS'
unset ans
$out $ac_n "[STABLE] Statistics support? ........................ [Y/n] "$ac_c
test "$ft_stats" && $out "$ft_stats" && ans=$ft_stats
test -z "$ft_stats" && read ans
test -z "$ans" -o "$ans" = y -o "$ans" = Y -o "$ans" = yes -o "$ans" = YES -o "$ans" = Yes && def_stats='#define STATS'
def_telnet='#undef TELNET'
unset ans
echo $ac_n "Telnet support? ............................ [Y/n] "$ac_c
test "$ft_telnet" && echo "$ft_telnet" && ans=$ft_telnet
$out $ac_n "[STABLE] Telnet support? ............................ [Y/n] "$ac_c
test "$ft_telnet" && $out "$ft_telnet" && ans=$ft_telnet
test -z "$ft_telnet" && read ans
test -z "$ans" -o "$ans" = y -o "$ans" = Y -o "$ans" = yes -o "$ans" = YES -o "$ans" = Yes && def_telnet='#define TELNET'
def_trivia='#undef TRIVIA'
unset ans
echo $ac_n "Trivia support? ............................ [y/N] "$ac_c
test "$ft_trivia" && echo "$ft_trivia" && ans=$ft_trivia
$out $ac_n "[STABLE] Trivia support? ............................ [y/N] "$ac_c
test "$ft_trivia" && $out "$ft_trivia" && ans=$ft_trivia
test -z "$ft_trivia" && read ans
test "$ans" = y -o "$ans" = Y -o "$ans" = yes -o "$ans" = YES -o "$ans" = Yes && def_trivia='#define TRIVIA'
def_toybox='#undef TOYBOX'
unset ans
$out $ac_n "[STABLE] Toybox fun and games? ...................... [Y/n] "$ac_c
test "$ft_toybox" && $out "$ft_toybox" && ans=$ft_toybox
test -z "$ft_toybox" && read ans
test -z "$ans" -o "$ans" = y -o "$ans" = Y -o "$ans" = yes -o "$ans" = YES -o "$ans" = Yes && def_toybox='#define TOYBOX'
def_uptime='#undef UPTIME'
unset ans
echo $ac_n "Uptime support? ............................ [Y/n] "$ac_c
test "$ft_uptime" && echo "$ft_uptime" && ans=$ft_uptime
$out $ac_n "[STABLE] Uptime support? ............................ [Y/n] "$ac_c
test "$ft_uptime" && $out "$ft_uptime" && ans=$ft_uptime
test -z "$ft_uptime" && read ans
test -z "$ans" -o "$ans" = y -o "$ans" = Y -o "$ans" = yes -o "$ans" = YES -o "$ans" = Yes && def_uptime='#define UPTIME'
def_urlcapture='#undef URLCAPTURE'
unset ans
$out $ac_n "[ BETA ] URL capture support? ....................... [Y/n] "$ac_c
test "$ft_urlcapture" && $out "$ft_urlcapture" && ans=$ft_urlcapture
test -z "$ft_urlcapture" && read ans
test -z "$ans" -o "$ans" = y -o "$ans" = Y -o "$ans" = yes -o "$ans" = YES -o "$ans" = Yes && def_urlcapture='#define URLCAPTURE'
def_wingate='#undef WINGATE'
unset ans
echo $ac_n "WinGate support? ........................... [Y/n] "$ac_c
test "$ft_wingate" && echo "$ft_wingate" && ans=$ft_wingate
$out $ac_n "[STABLE] WinGate support? ........................... [Y/n] "$ac_c
test "$ft_wingate" && $out "$ft_wingate" && ans=$ft_wingate
test -z "$ft_wingate" && read ans
test -z "$ans" -o "$ans" = y -o "$ans" = Y -o "$ans" = yes -o "$ans" = YES -o "$ans" = Yes && def_wingate='#define WINGATE'
echo ''
$out ''
echo "Creating src/Makefile"
O_FLAGS="$cc_optimize_flag $cc_arch_flag $cc_march_flag $cc_ofp_flag"
@ -1106,6 +1245,7 @@ s%@gdbflag@%$cc_g_flag%;
/@PYINCLUDE@/ { s,@PYINCLUDE@,$incpython,; };
/@TCLINCLUDE@/ { s,@TCLINCLUDE@,$inctcl,; };
s|@MD5_O@|$MD5_O|;
s|@SHA_O@|$SHA_O|;
s%@oc@%$objcomment%;
s%@sz@%$sizecomment%;
s/[ ]*\$//g;
@ -1113,8 +1253,10 @@ s/[ ]*\$//g;
echo "Creating src/config.h"
CRYPT_HAS_SHA='#undef CRYPT_HAS_SHA'
CRYPT_HAS_MD5='#undef CRYPT_HAS_MD5'
CRYPT_HAS_DES='#undef CRYPT_HAS_DES'
[ "$has_sha" = yes ] && CRYPT_HAS_SHA='#define CRYPT_HAS_SHA'
[ "$has_md5" = yes ] && CRYPT_HAS_MD5='#define CRYPT_HAS_MD5'
[ "$has_des" = yes ] && CRYPT_HAS_DES='#define CRYPT_HAS_DES'
@ -1130,9 +1272,11 @@ sed "
s|@DEF_DYNCMD@|$def_dyncmd|;
s|@DEF_DYNAMODE@|$def_dynamode|;
s|@DEF_GREET@|$def_greet|;
s|@DEF_HOSTINFO@|$def_hostinfo|;
s|@DEF_IDWRAP@|$def_idwrap|;
s|@DEF_IRCD_EXT@|$def_ircd_ext|;
s|@DEF_MD5@|$def_md5|;
s|@DEF_SHA@|$def_sha|;
s|@DEF_NEWBIE@|$def_newbie|;
s|@DEF_NOTE@|$def_note|;
s|@DEF_NOTIFY@|$def_notify|;
@ -1148,10 +1292,14 @@ s|@DEF_REDIRECT@|$def_redirect|;
s|@DEF_TOYBOX@|$def_toybox|;
s|@DEF_TRIVIA@|$def_trivia|;
s|@DEF_UPTIME@|$def_uptime|;
s|@DEF_URLCAPTURE@|$def_urlcapture|;
s|@DEF_WEB@|$def_web|;
s|@DEF_WINGATE@|$def_wingate|;
s|@LIT_END@|$LIT_END|;
s|@BIG_END@|$BIG_END|;
s|@DEF_CRYPT_FUNCTION@|$CRYPT_FUNCTION|;
s|@CRYPT_HAS_SHA@|$CRYPT_HAS_SHA|;
s|@CRYPT_HAS_MD5@|$CRYPT_HAS_MD5|;
s|@CRYPT_HAS_DES@|$CRYPT_HAS_DES|;
s|@IDWRAP_PATH@|$IDWRAP_PATH|;
@ -1160,10 +1308,20 @@ s|@PTSIZE_DEFINE64@|$PTSIZE_DEFINE64|;
s|@UNALIGNED_MEM@|$UNALIGNED_MEM|;
" < src/config.h.in >> src/config.h
if [ "$install" == "yes" ]; then
make -C src energymech
exit
fi
if [ "$compile" == "yes" ]; then
make -C src energymech
exit
fi
echo ''
echo 'All done. You can now "make clean install"'
echo ''
echo 'Send your bugreports to <proton@energymech.net>'
echo 'Submit your bugreports at https://github.com/MadCamel/energymech/issues'
echo ''
echo 'You have read the README file I hope?'
echo ''

View File

@ -1,4 +1,18 @@
Shows core information about the bot.
See also: ver, uptime, ontime
Current nick Nick of the bot you are connected to and its Guid.
Users in userlist Total number of userlist entries, as well as users with
userlevel access (0-100) and bot level access (200).
Active channels Channels that the bot is active on, as well as channels
that the bot is trying to rejoin.
Current server Which server the bot is connected to.
Server ontime How long the bot has been connected to the current server.
Mode User modes of the bot, like +i for invisible, etc.
Current time Time as reported by the machine that the bot is running on.
Started Time when the bot was first started.
Uptime How long (in days, hours, minutes and seconds) the bot has been running.
Version Source code version of the bot.
Features List of which features were compiled into the bot.
See also: ver, uptime, ontime, features

9
help/FEATURES Normal file
View File

@ -0,0 +1,9 @@
The Energymech contains a list of which features were included
when the source was compiled.
You can view this list at the command prompt in your shell with
./(name of executable) -v
Or, once the bot is started, with the command CORE or ESAY $cap
See also: core, esay

View File

@ -4,3 +4,6 @@ Number of MODE operations that can be sent to the IRC server
in a single line. This value can be auto-detected on server
connect if the bot is compiled with support for 005 replies
and the server sends them (most big networks today).
To support auto-detect of server capabilities, the energymech
needs to be compiled with the ircd-extensions feature enabled.

View File

@ -21,6 +21,11 @@ Add/remove a host mask:
Only one channel or one mask can be modified with each USER command.
Prefix flags with a "-" to disable them or a "+" to enable them.
Bots can be added to the userlist to be recognized by other bots.
Use the special access level 200. No password is set for bots and is
not needed because level 200 users can not execute any commands.
They can not access bots by telnet either.
User flags:
AO auto-op on/off

1
public/README Normal file
View File

@ -0,0 +1 @@
Store files here that you want to access with the SEND command.

View File

@ -1,4 +1,5 @@
user example
mask *!*@*.example.com
chan *
opt u100
opt p0u100
pass ___absolutely_do_not_use_this_file___

View File

@ -1,6 +1,6 @@
#
# EnergyMech, IRC bot software
# Copyright (c) 1997-2009 proton
# Copyright (c) 1997-2018 proton
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@ -42,23 +42,30 @@ CHMOD = chmod
INCS = config.h mcmd.h defines.h global.h h.h structs.h text.h
TESTFILES = aliastest safepathtest
OFILES = alias.o auth.o bounce.o chanban.o channel.o core.o \
ctcp.o debug.o dns.o dynamode.o function.o greet.o help.o irc.o \
ctcp.o debug.o dns.o dynamode.o function.o greet.o help.o hostinfo.o irc.o \
kicksay.o main.o net.o net_chan.o note.o notify.o ons.o parse.o \
perl.o prot.o python.o redirect.o reset.o seen.o shit.o socket.o \
spy.o stats.o tcl.o telnet.o toybox.o trivia.o uptime.o \
user.o vars.o web.o @MD5_O@
spy.o stats.o tcl.o telnet.o toybox.o trivia.o uptime.o urlcap.o \
user.o vars.o web.o @MD5_O@ @SHA_O@
SRCFILES = alias.c auth.c bounce.c chanban.c channel.c core.c \
ctcp.c debug.c dns.c dynamode.c function.c greet.c help.c irc.c \
ctcp.c debug.c dns.c dynamode.c function.c greet.c help.c hostinfo.c irc.c \
kicksay.c main.c net.c net_chan.c note.c notify.c ons.c parse.c \
perl.c prot.c python.c redirect.c reset.c seen.c shit.c socket.c \
spy.c stats.c tcl.c telnet.c toybox.c trivia.c uptime.c \
spy.c stats.c tcl.c telnet.c toybox.c trivia.c uptime.c urlcap.c \
user.c vars.c web.c
all: $(INSTALLNAME)
mcmd.h: gencmd.c config.h structs.h ;
#
# mcmd.h is generated at compile time to wrap up all command attributes more efficiently,
# instead of doing extra parsing and handling while the bot is running.
#
mcmd.h: gencmd.c config.h structs.h
$(CC) $(LFLAGS) -o gencmd gencmd.c
./gencmd > mcmd.h
@ -67,24 +74,31 @@ install: $(INSTALLNAME)
$(MV) $(INSTALLNAME) $(INSTALLDIR)
clean: FORCE
$(RM) $(INSTALLNAME) gencmd mcmd.h core $(OFILES)
$(RM) $(INSTALLNAME) gencmd mcmd.h core $(TESTFILES) $(OFILES)
$(INSTALLNAME): $(OFILES)
$(CROSS_COMPILE)$(CC) $(LFLAGS) -o $(INSTALLNAME) $(OFILES) $(LPROF) $(LIBS) $(LDSCRIPT)
@oc@ $(CROSS_COMPILE)objcopy -R .note -R .comment $(INSTALLNAME)
@sz@ size $(INSTALLNAME)
mega: $(SRCFILES) $(INCS) usage.h
$(CROSS_COMPILE)$(CC) $(CFLAGS) -o $(INSTALLNAME) mega.c $(LPROF) $(LIBS) $(LDSCRIPT) $(PYINCLUDE) $(TCLINCLUDE)
$(INSTALLNAME)-static: $(OFILES)
$(CROSS_COMPILE)$(CC) $(LFLAGS) -o $(INSTALLNAME) $(OFILES) $(LPROF) $(LIBS) $(LDSCRIPT) -static
@oc@ $(CROSS_COMPILE)objcopy -R .note -R .comment $(INSTALLNAME)
@sz@ size $(INSTALLNAME)
#
# static targets
# 'mega' versions
# compiling the C files all at once (having all the code "visible" during the whole process) enables GCC to make more optimizations,
# resulting in a smaller, more efficient, binary. this process uses lots more memory at compile time.
#
$(INSTALLNAME)-static: $(OFILES)
$(CROSS_COMPILE)$(CC) $(LFLAGS) -o $(INSTALLNAME) $(OFILES) $(LPROF) $(LIBS) $(LDSCRIPT) -static
mega-install: mega $(SRCFILES) $(INCS) usage.h
$(CHMOD) $(INSTALLMODE) $(INSTALLNAME)
$(MV) $(INSTALLNAME) $(INSTALLDIR)
mega: $(SRCFILES) $(INCS) usage.h
$(CROSS_COMPILE)$(CC) $(CFLAGS) -o $(INSTALLNAME) mega.c $(LPROF) $(LIBS) $(LDSCRIPT) $(PYINCLUDE) $(TCLINCLUDE)
@oc@ $(CROSS_COMPILE)objcopy -R .note -R .comment $(INSTALLNAME)
@sz@ size $(INSTALLNAME)
@ -93,6 +107,23 @@ mega-static: $(SRCFILES) $(INCS) usage.h
@oc@ $(CROSS_COMPILE)objcopy -R .note -R .comment $(INSTALLNAME)
@sz@ size $(INSTALLNAME)
#
# testing stuff
#
test: $(TESTFILES)
./aliastest
./safepathtest
aliastest: alias.c
$(CROSS_COMPILE)$(CC) $(CFLAGS) -o aliastest $< $(LPROF) $(LIBS) $(LDSCRIPT) -DTEST
safepathtest: function.c
$(CROSS_COMPILE)$(CC) $(CFLAGS) -o safepathtest $< $(LPROF) $(LIBS) $(LDSCRIPT) -DTEST
commands:
grep -E '(void do_.*\(COMMAND_ARGS\)|/*---Help:)' *c
#
#
#
@ -136,6 +167,9 @@ greet.o: greet.c $(INCS)
help.o: help.c $(INCS) usage.h
$(CROSS_COMPILE)$(CC) $(CFLAGS) -c $< $(CPROF)
hostinfo.o: hostinfo.c $(INCS)
$(CROSS_COMPILE)$(CC) $(CFLAGS) -c $< $(CPROF)
irc.o: irc.c $(INCS)
$(CROSS_COMPILE)$(CC) $(CFLAGS) -c $< $(CPROF)
@ -208,6 +242,9 @@ trivia.o: trivia.c $(INCS)
uptime.o: uptime.c $(INCS)
$(CROSS_COMPILE)$(CC) $(CFLAGS) -c $< $(CPROF)
urlcap.o: urlcap.c $(INCS)
$(CROSS_COMPILE)$(CC) $(CFLAGS) -c $< $(CPROF)
user.o: user.c $(INCS)
$(CROSS_COMPILE)$(CC) $(CFLAGS) -c $< $(CPROF)
@ -220,4 +257,7 @@ web.o: web.c $(INCS)
md5/md5.o: md5/md5.c $(INCS)
$(CROSS_COMPILE)$(CC) $(CFLAGS) -c $< -o $@ -Imd5 $(CPROF)
sha/sha1.o: sha/sha1.c $(INCS)
$(CROSS_COMPILE)$(CC) $(CFLAGS) -c $< -o $@ -Isha1 $(CPROF)
FORCE:

View File

@ -1,7 +1,7 @@
/*
EnergyMech, IRC bot software
Copyright (c) 1997-2004 proton
Copyright (c) 1997-2018 proton
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -20,104 +20,195 @@
*/
#define ALIAS_C
#include "config.h"
#ifdef ALIAS
#include "defines.h"
#include "structs.h"
#ifdef TEST
#define MAIN_C
#endif
#include "global.h"
#include "h.h"
#include "text.h"
#include "mcmd.h"
#ifdef TEST
#include "debug.c"
char result[MSGLEN];
char *input = "alias one two three four five six seven eight nine ten";
void testcase(const char *test, const char *expect)
{
afmt(result,test,input);
if (strcmp(result,expect) == 0) debug("testcase SUCCESS: test \"%s\" -> got \"%s\"\n",test,expect);
else debug("testcase FAIL: test \"%s\", expected \"%s\", got \"%s\"\n",test,expect,result);
}
int main(int argc, char **argv)
{
char *format = argv[1];
dodebug = 1;
strcpy(CurrentNick,"noob");
if (format == NULL)
{
// testcases
testcase("cmd","cmd");
testcase("cmd cmd","cmd cmd");
testcase("cmd $$","cmd $");
testcase("cmd $$0","cmd $0");
testcase("cmd $$$0","cmd $alias");
testcase("cmd $$$0$$","cmd $alias$");
testcase("cmd $1","cmd one");
testcase("cmd $0","cmd alias");
testcase("cmd $1-2","cmd one two");
testcase("cmd $1 $2","cmd one two");
testcase("cmd $2 $1","cmd two one");
testcase("cmd $8-","cmd eight nine ten");
testcase("cmd $4-5","cmd four five");
testcase("cmd $5-6","cmd five six");
testcase("cmd $~","cmd noob");
testcase("cmd $one $two","cmd $one $two");
exit(0);
}
debug("input = %s\n",input);
debug("format = %s\n",format);
afmt(result,format,input);
debug("result = %s\n",result);
exit(0);
}
#endif /* TEST */
/*
* copy_to = buffer to put resulting new command into
* src = Alias format string
* input = input from user
*/
void afmt(char *copy_to, const char *src, const char *input)
{
#define BUFTAIL (tmp+MSGLEN-1) /* avoid buffer overflows */
char tmp[MSGLEN];
const char *np;
#define BUFTAIL (copy_to+MSGLEN-1) /* avoid buffer overflows */
const char *argstart,*argend;
char *dest;
int n,t,tu,spc;
int startnum,endnum,spc;
dest = tmp;
dest = copy_to;
while(*src)
{
check_fmt:
if (*src == '$')
if (src[0] == '$' && src[1] == '$')
src++;
else
if (*src == '$' && src[1] == '~')
{
src += 2;
argstart = CurrentNick;
while(*argstart && dest <= BUFTAIL)
*(dest++) = *(argstart++);
}
else
if (*src == '$' && (attrtab[(uchar)src[1]] & NUM) == NUM)
{
src++;
if (*src == '$')
goto copychar;
tu = t = n = 0;
startnum = endnum = 0;
while(attrtab[(uchar)*src] & NUM)
startnum = (startnum * 10) + (*(src++) - '0');
if (*src == ' ' || *src == 0)
endnum = startnum;
else
if (*src == '-')
{
n = (n * 10) + (*(src++) - '0');
src++;
if ((attrtab[(uchar)*src] & NUM) != NUM)
endnum = 9999;
else
while(attrtab[(uchar)*src] & NUM)
endnum = (endnum * 10) + (*src++ - '0');
}
if (n)
argstart = input;
if (startnum)
for(spc=0;*argstart;argstart++)
{
if (*src == '-')
if (*argstart == ' ')
{
tu = n;
src++;
while(attrtab[(uchar)*src] & NUM)
{
t = (t * 10) + (*(src++) - '0');
}
}
n--;
spc = 0;
for(np=input;*np;)
{
if (*np == ' ')
{
if (!spc)
n--;
spc = 1;
}
else
{
spc = 0;
if (!n)
break;
}
np++;
}
spc = 0;
while(*np)
{
if (*np == ' ')
{
if (!tu || (t && tu >= t))
goto check_fmt;
if (!spc)
tu++;
spc = 1;
}
else
{
spc = 0;
}
if (dest == BUFTAIL)
goto afmt_escape;
*(dest++) = *(np++);
while(*argstart == ' ') // skip multiple spaces
argstart++;
if (++spc >= startnum)
break;
}
}
goto check_fmt;
for(argend=argstart,spc=startnum;*argend;argend++)
{
if (*argend == ' ')
{
if (++spc > endnum)
break;
while(*argend == ' ') // skip multiple spaces
argend++;
}
}
#ifdef DEBUG
#ifndef TEST
debug("(afmt) args #%i-#%i, characters %i-%i\n",startnum,endnum,argstart-input,argend-input);
#endif /* ifndef TEST */
#endif /* DEBUG */
while(*argstart && argstart < argend && dest <= BUFTAIL)
*(dest++) = *(argstart++);
continue;
}
copychar:
if (dest == BUFTAIL)
goto afmt_escape;
if (dest >= BUFTAIL)
break;
*(dest++) = *(src++);
}
afmt_escape:
*dest = 0;
Strcpy(copy_to,tmp);
#ifdef DEBUG
#ifndef TEST
debug("(afmt) start %i end %i spc %i\n",startnum,endnum,spc);
#endif /* ifndef TEST */
#endif /* DEBUG */
}
#ifndef TEST
/*
*
* associated commands
*
*/
/*---Help:ALIAS
Create a command alias. Arguments in the form $#, $#- and $#-# will
be replaced with the corresponding argument from input.
$0 The zeroeth argument (the aliased command).
$1 The first argument.
$1- All arguments starting with the first.
$3- All arguments starting with the third.
$1-2 The first and second argument.
$3-5 The third, fourth and fifth argument.
$$ A literal $ character.
$~ Nickname of the user doing the command.
Example:
ALIAS MEEP SAY $2 $1 $3-
Doing ``MEEP one two three four''
Would become ``SAY two one three four''
Example 2:
ALIAS MEEP SAY #home $~ did $0
Doing ``MEEP one two three four''
Would become ``SAY #home nickname did MEEP''
Aliases may call other aliases and aliases can be used
to replace built in commands. Aliases can recurse a
maximum of 20 times (to prevent infinite loops).
See also: unalias
---Helpend---*/
void do_alias(COMMAND_ARGS)
{
/*
@ -158,6 +249,9 @@ void do_alias(COMMAND_ARGS)
set_mallocdoer(do_alias);
alias->format = Strdup(rest);
to_user(from,"Replaced alias: %s --> %s",cmd,rest);
#ifdef DEBUG
debug("(do_alias) Replaced alias: %s --> %s\n",cmd,rest);
#endif
return;
}
}
@ -169,6 +263,9 @@ void do_alias(COMMAND_ARGS)
alias->next = aliaslist;
aliaslist = alias;
to_user(from,"Added alias: %s --> %s",cmd,rest);
#ifdef DEBUG
debug("(do_alias) Added alias: %s --> %s\n",cmd,rest);
#endif
}
void do_unalias(COMMAND_ARGS)
@ -193,4 +290,6 @@ void do_unalias(COMMAND_ARGS)
to_user(from,"Couldnt find matching alias");
}
#endif /* not TEST */
#endif /* ALIAS */

View File

@ -1,7 +1,7 @@
/*
EnergyMech, IRC bot software
Copyright (c) 2001-2004 proton
Copyright (c) 2001-2018 proton
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -29,6 +29,7 @@
#include "mcmd.h"
#ifndef MD5CRYPT
#ifndef SHACRYPT
/*
* simple password encryption
@ -68,7 +69,7 @@ char *cipher(char *arg)
if (!arg || !*arg)
return(NULL);
B1a = B2a = B3a = B4a = 0;
B1b = B2b = B3b = B4b = 0;
ptr = arg;
@ -114,7 +115,39 @@ int passmatch(char *plain, char *encoded)
return(!Strcmp(cipher(plain),encoded));
}
#else /* MD5CRYPT */
#endif /* not SHACRYPT */
#endif /* not MD5CRYPT */
#ifdef SHACRYPT
/*
* use SHA512 to hash passwords
*/
char *CRYPT_FUNC(const char *, const char *);
char *makepass(char *plain)
{
char salt[8];
sprintf(salt,"$6$%04x",(rand() >> 16));
return(CRYPT_FUNC(plain,salt));
}
int passmatch(char *plain, char *encoded)
{
char *enc;
if (matches("$6$????$*",encoded))
return(FALSE);
enc = CRYPT_FUNC(plain,encoded);
return(!Strcmp(enc,encoded));
}
#endif /* SHACRYPT */
#ifndef SHACRYPT
#ifdef MD5CRYPT
/*
* use MD5 to hash passwords
@ -141,7 +174,7 @@ int passmatch(char *plain, char *encoded)
}
#endif /* MD5CRYPT */
#endif /* not SHACRYPT */
/*
*
*/
@ -384,8 +417,9 @@ int make_auth(const char *userhost, const User *user)
*
*/
/*
* Usage: VERIFY <password>
/*---Help:AUTH:<password>
*/
/*---Help:VERIFY:<password>
*/
void do_auth(COMMAND_ARGS)
{

View File

@ -1,7 +1,7 @@
/*
EnergyMech, IRC bot software
Parts Copyright (c) 1997-2009 proton
Parts Copyright (c) 1997-2018 proton
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -58,8 +58,8 @@ void check_idlekick(void)
}
}
__attr (CORE_SEG, regparm(2))
Chan *find_channel(char *name, int anychannel)
__attr(CORE_SEG, __regparm(2))
Chan *find_channel(const char *name, int anychannel)
{
Chan *chan;
uchar ni;
@ -79,13 +79,13 @@ Chan *find_channel(char *name, int anychannel)
}
__attr(CORE_SEG, __regparm (1))
Chan *find_channel_ac(char *name)
Chan *find_channel_ac(const char *name)
{
return(find_channel(name,CHAN_ACTIVE));
}
__attr(CORE_SEG, __regparm (1))
Chan *find_channel_ny(char *name)
Chan *find_channel_ny(const char *name)
{
return(find_channel(name,CHAN_ANY));
}
@ -295,8 +295,7 @@ Ban *make_ban(Ban **banlist, char *from, char *banmask, time_t when)
return(NULL);
}
sz = sizeof(Ban) + Strlen2(from,banmask);
//sz = sizeof(Ban) + strlen(from) + strlen(banmask);
sz = sizeof(Ban) + Strlen2(from,banmask); // banmask is never NULL
set_mallocdoer(make_ban);
new = (Ban*)Calloc(sz);
@ -478,7 +477,7 @@ void channel_massmode(Chan *chan, char *pattern, int filtmode, char mode, char t
if (i)
{
if ((Strlen2(deopstring,burst)) >= MSGLEN-2)
if ((Strlen2(deopstring,burst)) >= MSGLEN-2) // burst is never NULL
{
write(current->sock,burst,strlen(burst));
#ifdef DEBUG
@ -626,7 +625,7 @@ void remove_chanuser(Chan *chan, char *nick)
/*
* Requires CurrentChan to be set properly
*/
__attr(CORE_SEG, __regparm (2) )
__attr(CORE_SEG, __regparm(2))
void make_chanuser(char *nick, char *userhost)
{
ChanUser *new;

View File

@ -70,6 +70,11 @@
*/
@DEF_WINGATE@
/*
* SHACRYPT: support use of SHA to hash passwords
*/
@DEF_SHA@
/*
* MD5CRYPT: support use of MD5 to hash passwords
*/
@ -182,6 +187,16 @@
#undef CHANBAN
#endif /* IRCD_EXTENSIONS */
/*
* HOSTINFO: share information about the host that the bot is running on
*/
@DEF_HOSTINFO@
/*
* URLCAPTURE: capture url's mentioned
*/
@DEF_URLCAPTURE@
/*
* FASTNICK: faster nick regain if the nick is seen when released
* Enables code that is potentially dangerous if an attacker aquires
@ -218,6 +233,7 @@
*
*/
@DEF_CRYPT_FUNCTION@
@CRYPT_HAS_SHA@
@CRYPT_HAS_MD5@
@CRYPT_HAS_DES@
@ -372,6 +388,15 @@
*/
#define RANDOM(min,max) (min + (rand() / (RAND_MAX / (max - min + 1))))
/* endianness */
#ifndef LITTLE_ENDIAN
@LIT_END@
#endif /* LITTLE_ENDIAN */
#ifndef BIG_ENDIAN
@BIG_END@
#endif /* BIG_ENDIAN */
/* unaligned memory access */
@UNALIGNED_MEM@
@ -446,6 +471,13 @@ const char __mx_opts[] = ""
#undef OPT_COREONLY
#endif /* DYNCMD */
#ifdef SHACRYPT
OPT_COMMA "sha"
#undef OPT_COMMA
#define OPT_COMMA ", "
#undef OPT_COREONLY
#endif /* SHACRYPT */
#ifdef MD5CRYPT
OPT_COMMA "md5"
#undef OPT_COMMA

View File

@ -138,7 +138,11 @@ int write_session(void)
#ifdef RAWDNS
Strp *p;
#endif /* RAWDNS */
#ifdef ALIAS
Alias *alias;
#endif /* ALIAS */
Server *sp;
Spy *spy;
Chan *chan;
Mech *bot;
UniVar *varval;
@ -155,67 +159,6 @@ int write_session(void)
to_file(sf,"dnsserver %s\n",inet_ntoa(ia_ns[j]));
#endif /* RAWDNS */
for(bot=botlist;bot;bot=bot->next)
{
to_file(sf,"nick %i %s\n",bot->guid,bot->wantnick);
/*
* current->setting contains channel defaults and global vars
*/
for(j=0;VarName[j].name;j++)
{
varval = &bot->setting[j];
if (IsProc(j))
varval = varval->proc_var;
if (IsChar(j))
{
if ((int)VarName[j].setto != varval->char_var)
to_file(sf,"set %s %c\n",VarName[j].name,varval->char_var);
}
else
if (IsNum(j))
{
if ((int)VarName[j].setto != varval->int_var)
to_file(sf,"set %s %i\n",VarName[j].name,varval->int_var);
}
else
if (IsStr(j))
{
/*
* There are no default string settings
*/
if (varval->str_var)
to_file(sf,"set %s %s\n",VarName[j].name,varval->str_var);
}
}
for(chan=bot->chanlist;chan;chan=chan->next)
{
if (!chan->active && !chan->rejoin)
continue;
to_file(sf,"join %s %s\n",chan->name,(chan->key) ? chan->key : "");
/*
* using CHANSET_SIZE: only the first settings contain stuff
*/
for(j=0;j<CHANSET_SIZE;j++)
{
varval = &chan->setting[j];
if (IsNum(j))
{
if ((int)VarName[j].setto != varval->int_var)
to_file(sf,"set %s %i\n",VarName[j].name,varval->int_var);
}
else
if (IsStr(j))
{
/*
* There are no default string settings
*/
if (varval->str_var)
to_file(sf,"set %s %s\n",VarName[j].name,varval->str_var);
}
}
}
}
to_file(sf,"set ctimeout %i\n",ctimeout);
for(sp=serverlist;sp;sp=sp->next)
{
@ -223,27 +166,6 @@ int write_session(void)
(sp->pass[0]) ? sp->pass : "");
}
#ifdef TRIVIA
if (triv_qfile)
to_file(sf,"set qfile %s\n",triv_qfile);
to_file(sf,"set qdelay %i\n",triv_qdelay);
to_file(sf,"set qchar %c\n",triv_qchar);
#endif /* TRIVIA */
#ifdef UPTIME
if (uptimehost && Strcasecmp(uptimehost,defaultuptimehost))
to_file(sf,"set uphost %s\n",uptimehost);
if (uptimeport)
to_file(sf,"set upport %i\n",uptimeport);
if (uptimenick)
to_file(sf,"set upnick %s\n",uptimenick);
#endif /* UPTIME */
#ifdef SEEN
if (seenfile)
to_file(sf,"set seenfile %s\n",seenfile);
#endif /* SEEN */
#ifdef BOTNET
if (linkpass)
to_file(sf,"set linkpass %s\n",linkpass);
@ -270,6 +192,27 @@ int write_session(void)
to_file(sf,"set webport %i\n",webport);
#endif /* WEB */
#ifdef UPTIME
if (uptimehost && Strcasecmp(uptimehost,defaultuptimehost))
to_file(sf,"set uphost %s\n",uptimehost);
if (uptimeport)
to_file(sf,"set upport %i\n",uptimeport);
if (uptimenick)
to_file(sf,"set upnick %s\n",uptimenick);
#endif /* UPTIME */
#ifdef TRIVIA
if (triv_qfile)
to_file(sf,"set qfile %s\n",triv_qfile);
to_file(sf,"set qdelay %i\n",triv_qdelay);
to_file(sf,"set qchar %c\n",triv_qchar);
#endif /* TRIVIA */
#ifdef SEEN
if (seenfile)
to_file(sf,"set seenfile %s\n",seenfile);
#endif /* SEEN */
#ifdef DYNCMD
/*
* because of "chaccess XXX disable" its best to save chaccess last
@ -286,6 +229,87 @@ int write_session(void)
}
#endif /* DYNCMD */
#ifdef ALIAS
for(alias=aliaslist;alias;alias=alias->next)
{
to_file(sf,"alias %s %s\n",alias->alias,alias->format);
}
#endif /* ALIAS */
for(bot=botlist;bot;bot=bot->next)
{
to_file(sf,"nick %i %s\n",bot->guid,bot->wantnick);
/*
* current->setting contains channel defaults and global vars
*/
for(j=0;VarName[j].name;j++)
{
if (IsProc(j))
continue;
varval = &bot->setting[j];
if (IsChar(j))
{
if (VarName[j].v.num != varval->char_var)
to_file(sf,"set %s %c\n",VarName[j].name,varval->char_var);
}
else
if (IsNum(j))
{
if (VarName[j].v.num != varval->int_var)
to_file(sf,"set %s %i\n",VarName[j].name,varval->int_var);
}
else
if (IsStr(j))
{
/*
* There are no default string settings
*/
if (varval->str_var)
to_file(sf,"set %s %s\n",VarName[j].name,varval->str_var);
}
}
for(chan=bot->chanlist;chan;chan=chan->next)
{
if (!chan->active && !chan->rejoin)
continue;
to_file(sf,"join %s %s\n",chan->name,(chan->key) ? chan->key : "");
/*
* using CHANSET_SIZE: only the first settings contain stuff
*/
for(j=0;j<CHANSET_SIZE;j++)
{
varval = &chan->setting[j];
if (IsNum(j))
{
if (VarName[j].v.num != varval->int_var)
to_file(sf,"set %s %i\n",VarName[j].name,varval->int_var);
}
else
if (IsStr(j))
{
/*
* There are no default string settings
*/
if (varval->str_var)
to_file(sf,"set %s %s\n",VarName[j].name,varval->str_var);
}
}
}
// SPY files
for(spy=bot->spylist;spy;spy=spy->next)
{
if (spy->t_dest == SPY_FILE)
{
if (spy->src && spy->dest)
to_file(sf,"spy %s > %s\n",spy->src,spy->dest);
#ifdef DEBUG
else
debug("spy to session fail\n");
#endif /* DEBUG */
}
}
}
close(sf);
return(TRUE);
}
@ -840,7 +864,44 @@ typedef struct
} HookTimer;
//using that struct, calculate when the next time will be
//start by determining what the time is now
thistime = now;
//which second is it
thissecond = thistime % 60;
if (ht->second1 == 0x3FFFFFFF && ht->second2 == 0x3FFFFFFF)
{
// dont add waiting period to get to the proper second
}
//which minute is it
thistime = (thistime - thissecond) / 60;
thisminute = thistime % 60;
if (ht->minute1 == 0x3FFFFFFF && ht->minute2 == 0x3FFFFFFF)
{
// dont add waiting period to get to the proper minute
}
//which hour is it
thistime = (thistime - thisminute) / 60;
thishour = thistime % 24;
if (ht->hour == 0xFFFFFF)
{
// dont add waiting period to get to the proper hour
}
//which weekday is it
thistime = (thistime - thishour) / 60; //thistime is now = day since epoch
if (ht->weekday == 0x7F) // every day
{
// dont add waiting period to get to the correct day
}
#endif /* 0 */
/*
* return -1 on failure
*/
@ -1184,8 +1245,10 @@ void do_core(COMMAND_ARGS)
}
i = Strcmp(current->nick,current->wantnick);
table_buffer((i) ? TEXT_CURRNICKWANT : TEXT_CURRNICKHAS,current->nick,current->wantnick);
table_buffer(TEXT_CURRGUID,current->guid);
if (i)
table_buffer(TEXT_CURRNICKWANT,current->nick,current->wantnick,current->guid);
else
table_buffer(TEXT_CURRNICKHAS,current->nick,current->guid);
table_buffer(TEXT_USERLISTSTATS,u,su,EXTRA_CHAR(su),bu,EXTRA_CHAR(bu));
pt = tmp;
@ -1358,12 +1421,12 @@ void do_server(COMMAND_ARGS)
ServerGroup *sg;
Server *sp,*dp,**spp;
char *server,*aport,*pass;
char addc,*last,*quitmsg = "Trying new server, brb...";
char addc,*last,*quitmsg = TEXT_TRYNEWSERVER;
int n,iport,sgi;
if (CurrentCmd->name == C_NEXTSERVER)
{
quitmsg = "Switching servers...";
quitmsg = TEXT_SWITCHSERVER;
to_user(from,FMT_PLAIN,quitmsg);
goto do_server_jump;
}
@ -1591,7 +1654,7 @@ void do_nick(COMMAND_ARGS)
return;
}
guid = a2i(nick);
backup = current;
backup = current;
if (!errno)
{
nick = chop(&rest);

View File

@ -156,7 +156,7 @@ int dcc_sendfile(char *target, char *filename)
struct sockaddr_in sai;
Client *client;
int s,f,sz;
char tempfile[Strlen2(filename,DCC_PUBLICFILES)+2];
char tempfile[strlen(filename)+strlen(DCC_PUBLICFILES)+2]; // strlen(DCC_PUBLICFILES) evaluates at compile time to a constant.
Strcpy(tempfile,DCC_PUBLICFILES);
Strcat(tempfile,filename);
@ -177,7 +177,7 @@ int dcc_sendfile(char *target, char *filename)
}
set_mallocdoer(dcc_sendfile);
client = (Client*)Calloc(sizeof(Client) + Strlen2(filename,target));
client = (Client*)Calloc(sizeof(Client) + Strlen2(filename,target)); // target is never NULL
client->fileno = f;
client->sock = s;
@ -551,7 +551,7 @@ void ctcp_dcc(char *from, char *to, char *rest)
debug("(ctcp_dcc) rest: `%s'\n",nullstr(rest));
#endif /* DEBUG */
filename = chop(&rest);
if (!is_safepath(filename))
if (is_safepath(filename,FILE_MUST_EXIST) != FILE_IS_SAFE)
{
#ifdef DEBUG
debug("(ctcp_dcc) filename `%s' is not safe\n",filename);
@ -608,7 +608,7 @@ void ctcp_dcc(char *from, char *to, char *rest)
if (1)
{
char tempname[Strlen2(filename,DCC_PUBLICINCOMING)+1];
char tempname[strlen(filename)+strlen(DCC_PUBLICINCOMING)+1]; // strlen(DCC_PUBLICINCOMING) evaluates to a constant during compile.
Strcpy(Strcpy(tempname,DCC_PUBLICINCOMING),filename);
@ -620,7 +620,7 @@ void ctcp_dcc(char *from, char *to, char *rest)
return;
}
set_mallocdoer(ctcp_dcc);
client = (Client*)Calloc(sizeof(Client) + Strlen2(filename,from));
client = (Client*)Calloc(sizeof(Client) + Strlen2(filename,from)); // from is never NULL
client->fileno = f;
client->fileend = filesz;
client->sock = s;

View File

@ -1,7 +1,7 @@
/*
EnergyMech, IRC bot software
Copyright (c) 1997-2009 proton
Copyright (c) 1997-2018 proton
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -29,6 +29,8 @@
#include "h.h"
#include "settings.h"
#ifndef TEST
#define boolstr(x) (x) ? "TRUE" : "FALSE"
LS const char tabs[20] = "\t\t\t\t\t\t\t\t\t\t";
@ -40,19 +42,49 @@ LS const struct
} StructList[] =
{
{ "aME\t", sizeof(aME) }, // for memory allocation debugging
{ "aMEA", sizeof(aMEA) },
#ifdef ALIAS
{ "Alias", sizeof(Alias) },
#endif /* ALIAS */
{ "Auth", sizeof(Auth) },
{ "Ban\t", sizeof(Ban) },
#ifdef BOTNET
{ "BotInfo", sizeof(BotInfo) },
{ "BotNet", sizeof(BotNet) },
#endif
{ "Chan", sizeof(Chan) },
{ "ChanStats", sizeof(ChanStats) },
{ "ChanUser", sizeof(ChanUser) },
{ "Client", sizeof(Client) },
{ "ShortClient", sizeof(ShortClient) },
#ifdef RAWDNS
{ "dnsAuthority", sizeof(dnsAuthority) },
{ "dnsList", sizeof(dnsList) },
{ "dnsQuery", sizeof(dnsQuery) },
#endif
#ifdef SCRIPTING
{ "Hook", sizeof(Hook) },
{ "HookTimer", sizeof(HookTimer) },
#endif
{ "ircLink", sizeof(ircLink) },
{ "IReq", sizeof(IReq) },
{ "KickSay", sizeof(KickSay) },
{ "KillSock", sizeof(KillSock) },
{ "Mech", sizeof(Mech) },
#ifdef BOTNET
{ "NetCfg", sizeof(NetCfg) },
#endif
#ifdef NOTE
{ "Note", sizeof(Note) },
#endif /* NOTE */
#ifdef NOTIFY
{ "nfLog", sizeof(nfLog) },
{ "Notify", sizeof(Notify) },
#endif /* NOTIFY */
{ "OnMsg", sizeof(OnMsg) },
{ "qKick", sizeof(qKick) },
{ "qMode", sizeof(qMode) },
#ifdef SEEN
{ "Seen", sizeof(Seen) },
#endif /* SEEN */
@ -60,15 +92,20 @@ LS const struct
{ "ServerGroup", sizeof(ServerGroup) },
{ "Setting", sizeof(Setting) },
{ "Shit", sizeof(Shit) },
{ "Spy\t", sizeof(Spy) },
{ "Strp", sizeof(Strp) },
#ifdef TRIVIA
{ "TrivScore", sizeof(TrivScore) },
#endif /* TRIVIA */
{ "UniVar", sizeof(UniVar) },
{ "User", sizeof(User) },
{ "OnMsg", sizeof(OnMsg) },
{ "Spy\t", sizeof(Spy) },
#ifdef WEB
{ "WebDoc", sizeof(WebDoc) },
{ "WebSock", sizeof(WebSock) },
#endif
{ NULL, }};
LS struct
{
void *func;
@ -154,7 +191,7 @@ LS struct
#ifdef PYTHON
{ python_hook, "python_hook" },
{ python_unhook, "python_unhook" },
#endif /* PYTHON */
#endif /* PYTHON */
#ifdef RAWDNS
{ rawdns, "rawdns" },
{ parse_query, "parse_query" },
@ -184,6 +221,9 @@ LS struct
{ init_uptime, "init_uptime" },
{ send_uptime, "send_uptime" },
#endif /* UPTIME */
#ifdef URLCAPTURE
{ urlcapture, "urlcapture" },
#endif /* URLCAPTURE */
{ 0, "(unknown)" },
{ NULL, }};
@ -196,12 +236,12 @@ LS const DEFstruct SCRIPTdefs[] =
{ HOOK_BOTNET, "HOOK_BOTNET" },
{ HOOK_DCC_COMPLETE, "HOOK_DCC_COMPLETE" },
#ifdef TCL
{ (int)tcl_timer_jump, "tcl_timer_jump" },
{ (int)tcl_parse_jump, "tcl_parse_jump" },
{ .v.func=tcl_timer_jump, "tcl_timer_jump" },
{ .v.func=tcl_parse_jump, "tcl_parse_jump" },
#endif /* TCL */
#ifdef PYTHON
{ (int)python_timer_jump, "python_timer_jump" },
{ (int)python_parse_jump, "python_parse_jump" },
{ .v.func=python_timer_jump, "python_timer_jump" },
{ .v.func=python_parse_jump, "python_parse_jump" },
#endif /* PYTHON */
{ 0, }};
#endif /* SCRIPTING */
@ -301,9 +341,9 @@ void strflags(char *dst, const DEFstruct *flagsstruct, int flags)
int i;
*dst = 0;
for(i=0;(flagsstruct[i].id);i++)
for(i=0;(flagsstruct[i].v.id);i++)
{
if (flagsstruct[i].id & flags)
if (flagsstruct[i].v.id & flags)
{
if (*dst)
Strcat(dst,"|");
@ -318,7 +358,19 @@ const char *strdef(const DEFstruct *dtab, int num)
for(i=0;(dtab[i].idstr);i++)
{
if (dtab[i].id == num)
if (dtab[i].v.id == num)
return(dtab[i].idstr);
}
return("UNKNOWN");
}
const char *funcdef(const DEFstruct *dtab, void *func)
{
int i;
for(i=0;(dtab[i].idstr);i++)
{
if (dtab[i].v.func == func)
return(dtab[i].idstr);
}
return("UNKNOWN");
@ -468,7 +520,7 @@ void debug_settings(UniVar *setting, int type)
}
tpad = STREND(tabs);
n = 24 - (Strlen2(pad,VarName[i].name) + 2);
n = 24 - (Strlen2(pad,VarName[i].name) + 2); // VarName[i].name is never NULL
while(n >= 8)
{
n = n - 8;
@ -1161,7 +1213,7 @@ void debug_rawdns(void)
#endif /* RAWDNS */
#if defined(TCL) || defined(PYTHON)
#if defined(TCL) || defined(PYTHON)
#if 0
typedef struct
@ -1174,7 +1226,7 @@ typedef struct
ulong minute2; //:30;
ulong hour; //:24;
ulong weekday; //:7;
} HookTimer;
#endif /* 0 */
@ -1213,7 +1265,7 @@ void debug_scripthook(void)
for(h=hooklist;h;h=h->next)
{
memtouch(h);
debug(" ; func\t\t"mx_pfmt" %s\n",(mx_ptr)h->func,strdef(SCRIPTdefs,(int)h->func));
debug(" ; func\t\t"mx_pfmt" %s\n",(mx_ptr)h->func,funcdef(SCRIPTdefs,h->func));
debug(" ; guid\t\t%i\n",h->guid);
debug(" ; flags\t\t%s (%i)\n",strdef(SCRIPTdefs,h->flags),h->flags);
if (h->flags == HOOK_TIMER)
@ -1288,7 +1340,7 @@ int wrap_debug(void)
close(fd);
debug_fd = backup_fd;
dodebug = backup_dodebug;
dodebug = backup_dodebug;
debug("(wrap_debug) all done.\n");
return(1);
@ -1302,6 +1354,8 @@ void do_debug(COMMAND_ARGS)
to_user(from,"Unable to write debug information to file");
}
#endif /* ifndef TEST */
void debug(char *format, ...)
{
va_list msg;
@ -1327,7 +1381,7 @@ void debug(char *format, ...)
}
va_start(msg,format);
vsprintf(debugbuf,format,msg);
vsnprintf(debugbuf,sizeof(debugbuf),format,msg);
va_end(msg);
if ((write(debug_fd,debugbuf,strlen(debugbuf))) < 0)

View File

@ -1,7 +1,7 @@
/*
EnergyMech, IRC bot software
Parts Copyright (c) 1997-2009 proton
Parts Copyright (c) 1997-2018 proton
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -161,6 +161,14 @@
#define IsChar(x) ((VarName[x].type & CHR_VAR) == CHR_VAR)
#define IsProc(x) (VarName[x].type & PROC_VAR)
/*
* is_safepath
*/
#define FILE_IS_SAFE 1
#define FILE_MUST_EXIST 1
#define FILE_MAY_EXIST 2
#define FILE_MUST_NOTEXIST 3
/*
* see settings.h for the actual setting struct
*/
@ -264,6 +272,9 @@ enum {
STR_UPNICK,
INT_UPPORT,
#endif /* UPTIME */
#ifdef URLCAPTURE
INT_URLHISTMAX,
#endif /* URLCAPTURE */
STR_USERFILE,
STR_VIRTUAL,
#ifdef WEB
@ -303,6 +314,7 @@ enum {
#define BNAUTH_PLAINTEXT 0
#define BNAUTH_DES 1
#define BNAUTH_MD5 2
#define BNAUTH_SHA 3
#endif /* BOTNET */
@ -355,6 +367,14 @@ enum {
/* 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
@ -380,6 +400,9 @@ enum {
#define SPY_MESSAGE 5
#define SPY_RAWIRC 6
#define SPY_BOTNET 7
#ifdef URLCAPTURE
#define SPY_URL 8
#endif /* URLCAPTURE */
#define SPYF_ANY 1
#define SPYF_CHANNEL (1 << SPY_CHANNEL)
@ -387,6 +410,7 @@ enum {
#define SPYF_MESSAGE (1 << SPY_MESSAGE)
#define SPYF_RAWIRC (1 << SPY_RAWIRC)
#define SPYF_BOTNET (1 << SPY_BOTNET)
#define SPYF_URL (1 << SPY_URL)
/*
* notify defines

View File

@ -1,7 +1,7 @@
/*
EnergyMech, IRC bot software
Copyright (c) 1997-2009 proton
Copyright (c) 1997-2018 proton
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -64,25 +64,7 @@ LS int dnsserver = 0;
#ifdef DEBUG
char *type_textlist[] =
{
NULL,
"A",
"NS",
"MD",
"MF",
"CNAME",
"SOA",
"MB",
"MG",
"MR",
"NULL",
"WKS",
"PTR",
"HINFO",
"MINFO",
"MX",
"TXT",
};
{ NULL, "A", "NS", "MD", "MF", "CNAME", "SOA", "MB", "MG", "MR", "NULL", "WKS", "PTR", "HINFO", "MINFO", "MX", "TXT", };
#endif /* DEBUG */
void init_rawdns(void)
@ -164,17 +146,17 @@ const char *get_dns_token(const char *src, const char *packet, char *dst, int sz
int make_query(char *packet, const char *hostname)
{
dnsQuery *h;
char *size,*dst;
/*
* make a packet
*/
packet[0] = rand() >> 24;
packet[1] = rand() >> 24;
packet[2] = 1; // RD, recursion desired flag
packet[3] = 0;
((ulong*)packet)[1] = htonl(0x10000);
((ulong*)packet)[2] = 0;
memset(packet,0,12);
h = (dnsQuery*)packet;
h->qid = rand() & 0xffff;
h->flags = htons(0x0100);; // Query = 0, Recursion Desired = 1
h->questions = htons(1);
size = packet + 12;
dst = size + 1;
while(*hostname)
@ -932,7 +914,10 @@ flipstep:
return;
}
make_ireq(PA_DNS,from,host);
if (to && *to == '#')
make_ireq(PA_DNS,to,host);
else
make_ireq(PA_DNS,from,host);
rawdns(host);
}

View File

@ -1,7 +1,7 @@
/*
EnergyMech, IRC bot software
Parts Copyright (c) 1997-2009 proton
Parts Copyright (c) 1997-2018 proton
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -23,25 +23,19 @@
#include "defines.h"
#include "structs.h"
#ifdef TEST
#define MAIN_C
#endif
#include "global.h"
#include "h.h"
#include "text.h"
#ifndef TEST
LS char timebuf[24]; /* max format lentgh == 20+1, round up to nearest longword -> 24 */
LS char idlestr[36]; /* max format lentgh == 24+1, round up to nearest longword -> 28 */
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"
};
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" };
/*
* memory allocation routines
@ -176,7 +170,7 @@ void Free(char **mem)
#endif /* DEBUG */
int Strlen(const char *first, ...)
const int Strlen(const char *first, ...)
{
const char *s,*o;
int n;
@ -200,7 +194,7 @@ int Strlen(const char *first, ...)
}
__attr(CORE_SEG,__regparm(2))
int Strlen2(const char *one, const char *two)
const int Strlen2(const char *one, const char *two)
{
const char *s1,*s2;
@ -493,7 +487,7 @@ char *cluster(char *hostname)
}
else
{
/*
/*
* its not a numeric mask
*/
p = mask;
@ -841,7 +835,8 @@ char *Strchr(const char *t, int c)
return((*t == ch) ? (char*)t : NULL);
}
char *Strdup(char *src)
__attr(CORE_SEG,__regparm(1))
char *Strdup(const char *src)
{
char *dest;
@ -1064,6 +1059,8 @@ void table_send(const char *from, const int space)
e_table = NULL;
}
#ifdef OLDCODE
int is_safepath(const char *path)
{
struct stat st;
@ -1097,3 +1094,125 @@ int is_safepath(const char *path)
}
return(path_token_check() == 1 ? TRUE : FALSE);
}
#endif
#endif /* ifndef TEST at the beginning of file */
#define FILE_MUST_EXIST 1
#define FILE_MAY_EXIST 2
#define FILE_MUST_NOTEXIST 3
__attr(CORE_SEG,__regparm(2))
int is_safepath(const char *path, int filemustexist)
{
struct stat st;
ino_t ino;
char tmp[PATH_MAX];
const char *src;
char *dst;
int r,mo,dir_r,orr,oerrno;
#ifdef TEST
memset(&st,0,sizeof(st));
#endif
if (*(src = path) == '/') // dont allow starting at root, only allow relative paths
return(-1);//(FALSE);
if (strlen(path) >= PATH_MAX)
return(-6);
orr = lstat(path,&st);
oerrno = errno;
if (filemustexist == FILE_MUST_EXIST && orr == -1 && errno == ENOENT)
return(-2);
if (filemustexist == FILE_MUST_NOTEXIST && orr == 0)
return(-3);
mo = st.st_mode; // save mode for later
dir_r = -1;
for(dst=tmp;*src;)
{
if (*src == '/')
{
*dst = 0;
if ((dir_r = lstat(tmp,&st)) == -1 && errno == ENOENT)
return(-7);
if (!(S_ISREG(st.st_mode) || S_ISDIR(st.st_mode))) // disallow all except regular files and directories
return(-4);
if (st.st_ino == parent_inode) // disallow traversing below bots homedir
return(-5);
}
if (dst == tmp + PATH_MAX-1)
return(-6);
*dst++ = *src++;
}
if (filemustexist != FILE_MUST_EXIST && orr == -1 && oerrno == ENOENT)
return(TRUE);
return (S_ISREG(mo)) ? TRUE : FALSE;
}
#ifdef TEST
#include "debug.c"
#define P0 "verylongexcessivelengthfilenamegibberish"
#define P1 P0 "/" P0 "/" P0 "/" P0 "/" P0 "/" P0 "/" P0 "/" P0 "/" P0 "/" P0 "/"
#define P2 P1 P1 P1 P1 P1 P1 P1 P1 P1 P1 P1 P1 P1 P1 P1 P1 P1 P1 P1 P1 P1 P1 P0
char *tostr[] = { "ZERO", "FILE_MUST_EXIST", "FILE_MAY_EXIST", "FILE_MUST_NOTEXIST" };
void testcase(const char *str, int expected, int filemustexist)
{
int r;
r = is_safepath(str,filemustexist);
if (r == expected)
{
debug("testcase SUCCESS: testpath %s %s -> result %i\n",
(strlen(str)>50) ? "(very long string)" : str,tostr[filemustexist],r);
}
else
{
debug("testcase FAIL: testpath %s(%i) %s -> result %i, expected %i\n",
(strlen(str)>50) ? "(very long string)" : str,
strlen(str),tostr[filemustexist],r,expected);//(r) ? "TRUE" : "FALSE",(expected) ? "TRUE" : "FALSE");
}
}
int main(int argc, char **argv)
{
struct stat st;
int r;
dodebug = 1;
stat("../..",&st);
parent_inode = st.st_ino; // used for is_safepath()
debug("PATH_MAX = %i\n",PATH_MAX);
if (argv[1] == NULL)
{
testcase("/etc/passwd",-1,FILE_MAY_EXIST);
testcase("../../../../../../../../../../../etc/passwd",-5,FILE_MAY_EXIST);
testcase("../anyparentfile",1,FILE_MAY_EXIST);
testcase("../../anyparentparentfile",-5,FILE_MAY_EXIST);
testcase("function.c",TRUE,FILE_MUST_EXIST);
testcase("./function.c",TRUE,FILE_MUST_EXIST);
testcase("function.c",-3,FILE_MUST_NOTEXIST);
testcase("./function.c",-3,FILE_MUST_NOTEXIST);
testcase("nosuchfile",1,FILE_MAY_EXIST);
testcase("nosuchfile",1,FILE_MUST_NOTEXIST);
testcase("./nosuchfile",1,FILE_MUST_NOTEXIST);
testcase("../../nosuchfile",-5,FILE_MUST_NOTEXIST);
testcase(P2,-6,FILE_MAY_EXIST);
exit(0);
}
r = is_safepath(argv[1],FILE_MAY_EXIST);
debug("testpath %s -> result %s\n",argv[1],(r) ? "TRUE" : "FALSE");
}
#endif /* TEST */

View File

@ -1,7 +1,7 @@
/*
EnergyMech, IRC bot software
Copyright (c) 1997-2009 proton
Copyright (c) 1997-2018 proton
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -58,7 +58,8 @@ struct
/*
* public access commands
*/
{ 0, "VERIFY", "do_auth", 0 | NOPUB },
{ 0, "AUTH", "do_auth", 0 | NOPUB | CBANG }, // double up on AUTH/VERIFY to better
{ 0, "VERIFY", "do_auth", 0 | NOPUB | CBANG }, // catch login attempts
#ifdef TOYBOX
{ 0, "8BALL", "do_8ball", 0 | CBANG },
#endif /* TOYBOX */
@ -91,6 +92,9 @@ struct
#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
@ -132,7 +136,7 @@ struct
{ 0, "READ", "do_read", 40 | CCPW },
#endif /* NOTE */
#ifdef STATS
{ 0, "INFO", "do_info", 40 | CCPW | CAXS | DCC },
{ 0, "INFO", "do_info", 40 | CCPW | REDIR | CAXS | DCC },
#endif /* STATS */
/*
@ -223,11 +227,16 @@ struct
/*
* Level 100
*/
#ifdef HOSTINFO
{ 0, "HOSTINFO", "do_hostinfo", 100 | CCPW | GAXS },
{ 0, "MEMINFO", "do_meminfo", 100 | CCPW | GAXS },
{ 0, "CPUINFO", "do_cpuinfo", 100 | CCPW | GAXS },
#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 | DCC },
{ 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 },
@ -235,7 +244,7 @@ struct
{ 0, "DEBUG", "do_debug", 100 | CCPW | GAXS },
#endif /* DEBUG */
#ifdef PYTHON
#ifdef PLEASE_HACK_MY_SHELL
#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 },
@ -271,7 +280,7 @@ int main(int argc, char **argv)
ct = 0;
printf("/""* This file is automatically generated from gencmd.c *""/\n");
printf("#ifndef MCMD_H\n#define MCMD_H 1\n\n");
printf("#ifndef TEST\n#ifndef MCMD_H\n#define MCMD_H 1\n\n");
while(pass)
{
@ -396,6 +405,7 @@ int main(int argc, char **argv)
printf("extern OnMsg_access acmd[];\n\n");
printf("#endif /""* MAIN_C *""/\n\n");
printf("#endif /""* MCMD_H *""/\n\n");
printf("#endif /""* TEST *""/\n\n");
unlink("usercombo.h");
of = fopen("usercombo.h","w");

View File

@ -1,7 +1,7 @@
/*
EnergyMech, IRC bot software
Copyright (c) 1997-2009 proton
Copyright (c) 1997-2018 proton
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -40,8 +40,8 @@
#define DEFAULTCMDCHAR '-'
#define MECHUSERLOGIN "v3.energymech.net"
BEG const char VERSION[] MDEF("3.0.99p3");
BEG const char SRCDATE[] MDEF("July 24th, 2009");
BEG const char VERSION[] MDEF("3.0.99p4");
BEG const char SRCDATE[] MDEF("March 13th, 2018");
#ifdef __CYGWIN__
BEG const char BOTCLASS[] MDEF("WinMech");
#else /* ! CYGWIN */
@ -63,10 +63,15 @@ BEG const char __SPYSTR_RAWIRC[] MDEF("rawirc");
BEG const char __SPYSTR_MESSAGE[] MDEF("message");
BEG const char __SPYSTR_STATUS[] MDEF("status");
BEG const char __SPYSTR_BOTNET[] MDEF("botnet");
#define SPYSTR_RAWIRC (char*)__SPYSTR_RAWIRC
#define SPYSTR_MESSAGE (char*)__SPYSTR_MESSAGE
#define SPYSTR_STATUS (char*)__SPYSTR_STATUS
#define SPYSTR_BOTNET (char*)__SPYSTR_BOTNET
#define SPYSTR_RAWIRC __SPYSTR_RAWIRC
#define SPYSTR_MESSAGE __SPYSTR_MESSAGE
#define SPYSTR_STATUS __SPYSTR_STATUS
#define SPYSTR_BOTNET __SPYSTR_BOTNET
#ifdef URLCAPTURE
BEG const char __SPYSTR_URL[] MDEF("url");
#define SPYSTR_URL __SPYSTR_URL
#endif /* URLCAPTURE */
BEG const char STR_MECHRESET[] MDEF("MECHRESET=");
@ -110,7 +115,6 @@ BEG User __internal_users[2];
* (functions that do not call any other non-trivial functions)
*/
BEG char gsockdata[MAXLEN];
BEG char nick_buf[MAXHOSTLEN];
BEG char nuh_buf[NUHLEN];
@ -139,10 +143,6 @@ BEG Alias *aliaslist MDEF(NULL);
#endif /* ALIAS */
#ifdef UPTIME
BEG char *defaultuptimehost MDEF("uptime.energymech.net");
#endif /* UPTIME */
#ifdef BOTNET
BEG const char UNKNOWNATUNKNOWN[] MDEF("unknown@unknown");
@ -191,11 +191,17 @@ BEG Note *notelist MDEF(NULL);
#endif /* NOTE */
#ifdef SCRIPTING
#ifdef RAWDNS
BEG Hook *hooklist MDEF(NULL);
BEG dnsList *dnslist MDEF(NULL);
BEG dnsAuthority *dnsroot MDEF(NULL);
BEG struct in_addr ia_ns[MAX_NAMESERVERS];
BEG struct in_addr ia_default;
#endif /* SCRIPTING */
#ifdef SESSION
BEG Strp *dnsrootfiles MDEF(NULL);
#endif /* SESSION */
#endif /* RAWDNS */
#ifdef REDIRECT
@ -211,6 +217,12 @@ LS struct
#endif /* REDIRECT */
#ifdef SCRIPTING
BEG Hook *hooklist MDEF(NULL);
#endif /* SCRIPTING */
#ifdef SEEN
BEG char *seenfile MDEF(NULL); /* proc var */
@ -237,9 +249,17 @@ BEG ulong uptimeip MDEF((ulong)-1);
BEG ulong uptimecookie;
BEG ulong uptimeregnr MDEF(0);
BEG time_t uptimelast MDEF(0);
BEG const char *defaultuptimehost MDEF("uptime.energymech.net");
#endif /* UPTIME */
#ifdef URLCAPTURE
BEG int urlhistmax MDEF(20); /* proc var */
BEG Strp *urlhistory MDEF(NULL);
#endif /* URLCAPTURE */
#ifdef WEB
BEG int websock MDEF(-1);
@ -247,17 +267,6 @@ BEG int webport MDEF(0);
#endif /* WEB */
#ifdef RAWDNS
BEG dnsList *dnslist MDEF(NULL);
BEG dnsAuthority *dnsroot MDEF(NULL);
BEG struct in_addr ia_ns[MAX_NAMESERVERS];
BEG struct in_addr ia_default;
#ifdef SESSION
BEG Strp *dnsrootfiles MDEF(NULL);
#endif /* SESSION */
#endif /* RAWDNS */
#ifndef I_HAVE_A_LEGITIMATE_NEED_FOR_MORE_THAN_4_BOTS
@ -395,7 +404,7 @@ LS const uchar attrtab[256] =
/*
* user struct for the core client
*/
LS const Strp CMA =
LS const Strp CMA =
{
NULL,
"*"

View File

@ -130,7 +130,7 @@ void do_greet(COMMAND_ARGS)
{
if (isfile)
{
if (!is_safepath(rest))
if (is_safepath(rest,FILE_MUST_EXIST) != FILE_IS_SAFE)
goto usage;
}

44
src/h.h
View File

@ -1,7 +1,7 @@
/*
EnergyMech, IRC bot software
Copyright (c) 1997-2009 proton
Copyright (c) 1997-2018 proton
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -23,7 +23,7 @@
#define ischannel(x) (*x == '#')
#define nullstr(x) (x) ? x : NULLSTR
#define nullstr(x) ((x)) ? (x) : NULLSTR
#define nullbuf(x) (x && *x) ? x : NULLSTR
#define chkhigh(x) if (x > hisock) { hisock = x; }
@ -106,9 +106,13 @@
}
#endif /* DEBUG */
LS int makecrc(const char *);
LS void send_supress(const char *, const char *);
LS void netchanSupress(BotNet *, char *);
LS Chan *find_channel_ac(char *) __attr(CORE_SEG, __regparm (1) );
LS Chan *find_channel_ny(char *) __attr(CORE_SEG, __regparm (1) );
LS Chan *find_channel(const char *, int) __attr(CORE_SEG, __regparm (2) );
LS Chan *find_channel_ac(const char *) __attr(CORE_SEG, __regparm (1) );
LS Chan *find_channel_ny(const char *) __attr(CORE_SEG, __regparm (1) );
LS ChanUser *find_chanuser(Chan *, const char *) __attr(CORE_SEG, __regparm (2) );
LS Client *find_client(const char *) __page(CORE_SEG);
LS Mech *add_bot(int, char *) __page(CORE_SEG);
@ -120,13 +124,13 @@ LS Shit *add_shit(char *, char *, char *, char *, int, int) __page(CMD1_SEG);
LS Shit *find_shit(const char *, const char *) __page(CORE_SEG);
LS Shit *get_shituser(char *, char *) __page(CORE_SEG);
LS User *add_user(char *, char *, int) __page(CFG1_SEG);
LS User *find_handle(char *) __page(CORE_SEG);
LS User *find_handle(const char *) __page(CORE_SEG);
LS User *get_authuser(char *, char *) __page(CORE_SEG);
LS User *get_user(const char *, const char *) __page(CORE_SEG);
LS int get_authaccess(char *, char *) __page(CORE_SEG);
LS int get_protaction(Chan *, char *) __page(CORE_SEG);
LS int get_shitaction(const char *, const char *) __page(CORE_SEG);
LS int get_useraccess(char *, char *) __page(CORE_SEG);
LS int get_useraccess(const char *, const char *) __page(CORE_SEG);
LS int get_maxaccess(const char *) __page(CORE_SEG);
LS int Strcasecmp(const char *, const char *) __att2(CORE_SEG, const, __regparm (2) );
@ -134,7 +138,7 @@ LS int Strcmp(const char *, const char *) __att2(CORE_SEG, const, __regparm (2
LS char *Strcat(char *, const char *) __attr(CORE_SEG, __regparm (2) );
LS char *Strchr(const char *, int) __att2(CORE_SEG, const, __regparm (2) );
LS char *Strcpy(char *, const char *) __attr(CORE_SEG, __regparm (2) );
LS char *Strdup(char *) __page(CORE_SEG);
LS char *Strdup(const char *) __attr(CORE_SEG, __regparm (1) );
LS void Strncpy(char *, const char *, int) __attr(CORE_SEG, __regparm (3) );
LS char *chop(char **) __attr(CORE_SEG, __regparm (1) );
LS int get_number(const char *) __page(CORE_SEG);
@ -208,12 +212,12 @@ LS ulong stringhash(char *) __page(CORE_SEG);
*/
LS void *Calloc(int) __attr(CORE_SEG, __regparm (1) );
LS void Free(char **) __attr(CORE_SEG, __regparm (1) );
LS int Strlen(const char *, ...) __page(CORE_SEG);
LS int Strlen2(const char *, const char *) __attr(CORE_SEG, __regparm (2) );
LS const int Strlen(const char *, ...) __page(CORE_SEG);
LS const int Strlen2(const char *, const char *) __attr(CORE_SEG, __regparm (2) );
LS int matches(const char *, const char *) __att2(CORE_SEG, const, __regparm (2) );
LS int num_matches(const char *, const char *) __att2(CORE_SEG, const, __regparm (2) );
LS int a2i(char *) __attr(CORE_SEG, __regparm (1) );
LS int is_safepath(const char *) __page(CORE_SEG);
LS int is_safepath(const char *, int) __attr(CORE_SEG, __regparm (2) );
LS void afmt(char *, const char *, const char *) __page(CMD1_SEG);
LS void aucheck(User *) __attr(CORE_SEG, __regparm (1) );
@ -256,7 +260,7 @@ LS void cfg_shit(char *) __page(CFG1_SEG);
LS void cfg_user(char *) __page(CFG1_SEG);
void mirror_user(User *) __page(CORE_SEG);
void mirror_userlist(void) __page(CORE_SEG);
LS void addtouser(Strp **, const char *) __attr(CORE_SEG, __regparm (2) );
LS void addtouser(Strp **, const char *, int) __attr(CORE_SEG, __regparm (3) );
LS int remfromuser(Strp **, const char *) __attr(CORE_SEG, __regparm (2) );
/*
@ -397,6 +401,9 @@ LS void parse_mode(char *, char *) __page(CORE_SEG);
LS void parse_notice(char *, char *) __page(CORE_SEG);
LS void parse_part(char *, char *) __page(CORE_SEG);
LS void parse_ping(char *, char *) __page(CORE_SEG);
#ifdef URLCAPTURE
LS void urlcapture(const char *) __page(CORE_SEG);
#endif /* URLCAPTURE */
LS void parse_privmsg(char *, char *) __page(CORE_SEG);
LS void parse_quit(char *, char *) __page(CORE_SEG);
LS void parse_topic(char *, char *) __page(CMD1_SEG);
@ -527,6 +534,7 @@ LS void select_bounce(void) __page(CORE_SEG);
LS void do_chanban(COMMAND_ARGS) __page(CMD1_SEG);
LS void process_chanbans(void) __page(CORE_SEG);
LS void chanban_action(char *, char *, Shit *) __page(CORE_SEG);
#endif /* CHANBAN */
@ -579,6 +587,13 @@ LS void check_dynamode(Chan *) __page(CORE_SEG);
#endif /* DYNAMODE */
#ifdef HOSTINFO
LS void do_hostinfo(COMMAND_ARGS) __page(CMD1_SEG);
LS void do_meminfo(COMMAND_ARGS) __page(CMD1_SEG);
LS void do_cpuinfo(COMMAND_ARGS) __page(CMD1_SEG);
#endif /* HOSTINFO */
/*
*
*/
@ -763,6 +778,13 @@ LS void uptime_death(int) __page(RARE_SEG); /* rare */
#endif /* UPTIME */
#ifdef URLCAPTURE
LS void urlcapture(const char *) __page(CORE_SEG);
LS void do_urlhist(COMMAND_ARGS) __page(CMD1_SEG);
#endif /* ifdef URLCAPTURE */
/*
* WEB prototypes
*/

View File

@ -168,12 +168,6 @@ help_loop:
return;
}
/*
* We dont want to show help for "../../../../../../etc/passwd"
*/
if (!is_safepath(rest))
return;
pt = Strcpy(line,HELPDIR);
for(i=0;(rest[i]);i++)
{
@ -184,6 +178,20 @@ help_loop:
pt++;
}
*pt = 0;
/*
* We dont want to show help for "../../../../../../etc/passwd"
*/
if (is_safepath(line,FILE_MUST_EXIST) != FILE_IS_SAFE)
#ifdef DEBUG
{
debug("(do_help) unsafe help filename (%s), exiting\n",line);
return;
}
#else
return;
#endif /* DEBUG */
#ifdef DEBUG
debug("(do_help) help file check: %s\n",line);
#endif /* DEBUG */

145
src/hostinfo.c Normal file
View File

@ -0,0 +1,145 @@
/*
EnergyMech, IRC bot software
Copyright (c) 2001-2018 proton
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
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.
*/
#define HOSTINFO_C
#include "config.h"
#ifdef HOSTINFO
#include "defines.h"
#include "structs.h"
#include "global.h"
#include "h.h"
#include "text.h"
#include "mcmd.h"
#include <sys/utsname.h>
/*---Help:HOSTINFO:(no arguments)
Equivalent to ``uname -orm''
See also: meminfo, cpuinfo
*/
void do_hostinfo(COMMAND_ARGS)
{
struct utsname un;
if (uname(&un) == 0)
to_user_q(from,"%s %s %s",un.sysname,un.release,un.machine);
}
char vmpeak[32];
char vmsize[32];
char vmrss[32];
char vmdata[32];
char vmstk[32];
char vmexe[32];
char vmlib[32];
struct // statusvalues
{
const char *key;
const int klen;
char *valbuf;
} sv[] =
{
{ "VmPeak:", 7, vmpeak },
{ "VmSize:", 7, vmsize },
{ "VmRSS:", 6, vmrss },
{ "VmData:", 7, vmdata },
{ "VmStk:", 6, vmstk },
{ "VmExe:", 6, vmexe },
{ "VmLib:", 6, vmlib },
{ NULL, 0, NULL }
};
int parse_proc_status(char *line)
{
const char *key;
char *dest,*limit;
int i;
key = chop(&line);
#ifdef DEBUG
debug("pps key = %s (%s)\n",key,line);
#endif
if (key == NULL)
return(FALSE);
for(i=0;sv[i].key;i++)
{
if (strncmp(key,sv[i].key,sv[i].klen) == 0)
{
#ifdef DEBUG
debug("(parse_proc_status) key %s -> %s\n",key,line);
#endif /* DEBUG */
dest = sv[i].valbuf;
limit = sv[i].valbuf + 31;
while(*line == ' ')
line++;
while(*line && dest <= limit)
*(dest++) = *(line++);
*dest = 0;
}
}
return(FALSE);
}
/*---Help:MEMINFO:(no arguments)
Will display memory usage of the energymech process.
VM Virtual size, size if everything was loaded into memory)
RSS Resident set size, physical memory actually in use right now.
Code Memory allocated for code
Data Memory allocated for data
Libs Memory used by shared libraries
Stack Memory allocated for stack
See also: hostinfo, cpuinfo
*/
void do_meminfo(COMMAND_ARGS)
{
char fn[64];
pid_t p;
int i,fd;
p = getpid();
snprintf(fn,sizeof(fn),"/proc/%i/status",p);
for(i=0;sv[i].key;i++)
*(sv[i].valbuf) = 0;
if ((fd = open(fn,O_RDONLY)) < 0)
return;
readline(fd,&parse_proc_status); // readline closes fd
to_user_q(from,"VM %s (Max %s), RSS %s [ Code %s, Data %s, Libs %s, Stack %s ]",
vmsize,vmpeak,vmrss,vmexe,vmdata,vmlib,vmstk);
}
/*---Help:CPUINFO:(no arguments)
See also: hostinfo, meminfo
*/
void do_cpuinfo(COMMAND_ARGS)
{
}
#endif /* HOSTINFO */

View File

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

5
src/ld/README Normal file
View File

@ -0,0 +1,5 @@
get the default script with:
gcc -o energymech mega.c -lcrypt -Wl,-verbose > default
edit out non-script output and modify with the custom .text.[abcde] entries

236
src/ld/elf64-x86-64 Normal file
View File

@ -0,0 +1,236 @@
/* Script for -z combreloc: combine and sort reloc sections */
/* Copyright (C) 2014-2015 Free Software Foundation, Inc.
Copying and distribution of this script, with or without modification,
are permitted in any medium without royalty provided the copyright
notice and this notice are preserved. */
OUTPUT_FORMAT("elf64-x86-64", "elf64-x86-64",
"elf64-x86-64")
OUTPUT_ARCH(i386:x86-64)
ENTRY(_start)
SEARCH_DIR("/usr/x86_64-slackware-linux/lib64"); SEARCH_DIR("/usr/lib64"); SEARCH_DIR("/usr/local/lib64"); SEARCH_DIR("/lib64"); SEARCH_DIR("/usr/x86_64-slackware-linux/lib"); SEARCH_DIR("/usr/local/lib"); SEARCH_DIR("/lib"); SEARCH_DIR("/usr/lib");
SECTIONS
{
/* Read-only sections, merged into text segment: */
PROVIDE (__executable_start = SEGMENT_START("text-segment", 0x400000)); . = SEGMENT_START("text-segment", 0x400000) + SIZEOF_HEADERS;
.interp : { *(.interp) }
.note.gnu.build-id : { *(.note.gnu.build-id) }
.hash : { *(.hash) }
.gnu.hash : { *(.gnu.hash) }
.dynsym : { *(.dynsym) }
.dynstr : { *(.dynstr) }
.gnu.version : { *(.gnu.version) }
.gnu.version_d : { *(.gnu.version_d) }
.gnu.version_r : { *(.gnu.version_r) }
.rela.dyn :
{
*(.rela.init)
*(.rela.text .rela.text.* .rela.gnu.linkonce.t.*)
*(.rela.fini)
*(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*)
*(.rela.data .rela.data.* .rela.gnu.linkonce.d.*)
*(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*)
*(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*)
*(.rela.ctors)
*(.rela.dtors)
*(.rela.got)
*(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*)
*(.rela.ldata .rela.ldata.* .rela.gnu.linkonce.l.*)
*(.rela.lbss .rela.lbss.* .rela.gnu.linkonce.lb.*)
*(.rela.lrodata .rela.lrodata.* .rela.gnu.linkonce.lr.*)
*(.rela.ifunc)
}
.rela.plt :
{
*(.rela.plt)
PROVIDE_HIDDEN (__rela_iplt_start = .);
*(.rela.iplt)
PROVIDE_HIDDEN (__rela_iplt_end = .);
}
.init :
{
KEEP (*(SORT_NONE(.init)))
}
.plt : { *(.plt) *(.iplt) }
.plt.got : { *(.plt.got) }
.plt.bnd : { *(.plt.bnd) }
.text :
{
*(.text.unlikely .text.*_unlikely .text.unlikely.*)
*(.text.exit .text.exit.*)
*(.text.startup .text.startup.*)
*(.text.hot .text.hot.*)
*(.text.e) /* RARE */
*(.text.d) /* INIT */
*(.text.b) /* CFG1 */
*(.text.c) /* CMD1 */
*(.text.a) /* CORE */
*(.text.f) /* DBUG */
*(.text .stub .text.* .gnu.linkonce.t.*)
/* .gnu.warning sections are handled specially by elf32.em. */
*(.gnu.warning)
}
.fini :
{
KEEP (*(SORT_NONE(.fini)))
}
PROVIDE (__etext = .);
PROVIDE (_etext = .);
PROVIDE (etext = .);
.rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) }
.rodata1 : { *(.rodata1) }
.eh_frame_hdr : { *(.eh_frame_hdr) *(.eh_frame_entry .eh_frame_entry.*) }
.eh_frame : ONLY_IF_RO { KEEP (*(.eh_frame)) *(.eh_frame.*) }
.gcc_except_table : ONLY_IF_RO { *(.gcc_except_table
.gcc_except_table.*) }
.gnu_extab : ONLY_IF_RO { *(.gnu_extab*) }
/* These sections are generated by the Sun/Oracle C++ compiler. */
.exception_ranges : ONLY_IF_RO { *(.exception_ranges
.exception_ranges*) }
/* Adjust the address for the data segment. We want to adjust up to
the same address within the page on the next page up. */
. = DATA_SEGMENT_ALIGN (CONSTANT (MAXPAGESIZE), CONSTANT (COMMONPAGESIZE));
/* Exception handling */
.eh_frame : ONLY_IF_RW { KEEP (*(.eh_frame)) *(.eh_frame.*) }
.gnu_extab : ONLY_IF_RW { *(.gnu_extab) }
.gcc_except_table : ONLY_IF_RW { *(.gcc_except_table .gcc_except_table.*) }
.exception_ranges : ONLY_IF_RW { *(.exception_ranges .exception_ranges*) }
/* Thread Local Storage sections */
.tdata : { *(.tdata .tdata.* .gnu.linkonce.td.*) }
.tbss : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) }
.preinit_array :
{
PROVIDE_HIDDEN (__preinit_array_start = .);
KEEP (*(.preinit_array))
PROVIDE_HIDDEN (__preinit_array_end = .);
}
.init_array :
{
PROVIDE_HIDDEN (__init_array_start = .);
KEEP (*(SORT(.init_array.*)))
KEEP (*(.init_array ))
PROVIDE_HIDDEN (__init_array_end = .);
}
.fini_array :
{
PROVIDE_HIDDEN (__fini_array_start = .);
KEEP (*(SORT(.fini_array.*)))
KEEP (*(.fini_array ))
PROVIDE_HIDDEN (__fini_array_end = .);
}
.ctors :
{
/* gcc uses crtbegin.o to find the start of
the constructors, so we make sure it is
first. Because this is a wildcard, it
doesn't matter if the user does not
actually link against crtbegin.o; the
linker won't look for a file to match a
wildcard. The wildcard also means that it
doesn't matter which directory crtbegin.o
is in. */
KEEP (*crtbegin.o(.ctors))
KEEP (*crtbegin?.o(.ctors))
/* We don't want to include the .ctor section from
the crtend.o file until after the sorted ctors.
The .ctor section from the crtend file contains the
end of ctors marker and it must be last */
KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors))
KEEP (*(SORT(.ctors.*)))
KEEP (*(.ctors))
}
.dtors :
{
KEEP (*crtbegin.o(.dtors))
KEEP (*crtbegin?.o(.dtors))
KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors))
KEEP (*(SORT(.dtors.*)))
KEEP (*(.dtors))
}
.jcr : { KEEP (*(.jcr)) }
.data.rel.ro : { *(.data.rel.ro.local* .gnu.linkonce.d.rel.ro.local.*) *(.data.rel.ro .data.rel.ro.* .gnu.linkonce.d.rel.ro.*) }
.dynamic : { *(.dynamic) }
.got : { *(.got) *(.igot) }
. = DATA_SEGMENT_RELRO_END (SIZEOF (.got.plt) >= 24 ? 24 : 0, .);
.got.plt : { *(.got.plt) *(.igot.plt) }
.data :
{
*(.data .data.* .gnu.linkonce.d.*)
SORT(CONSTRUCTORS)
}
.data1 : { *(.data1) }
_edata = .; PROVIDE (edata = .);
. = .;
__bss_start = .;
.bss :
{
*(.dynbss)
*(.bss .bss.* .gnu.linkonce.b.*)
*(COMMON)
/* Align here to ensure that the .bss section occupies space up to
_end. Align after .bss to ensure correct alignment even if the
.bss section disappears because there are no input sections.
FIXME: Why do we need it? When there is no .bss section, we don't
pad the .data section. */
. = ALIGN(. != 0 ? 64 / 8 : 1);
}
.lbss :
{
*(.dynlbss)
*(.lbss .lbss.* .gnu.linkonce.lb.*)
*(LARGE_COMMON)
}
. = ALIGN(64 / 8);
. = SEGMENT_START("ldata-segment", .);
.lrodata ALIGN(CONSTANT (MAXPAGESIZE)) + (. & (CONSTANT (MAXPAGESIZE) - 1)) :
{
*(.lrodata .lrodata.* .gnu.linkonce.lr.*)
}
.ldata ALIGN(CONSTANT (MAXPAGESIZE)) + (. & (CONSTANT (MAXPAGESIZE) - 1)) :
{
*(.ldata .ldata.* .gnu.linkonce.l.*)
. = ALIGN(. != 0 ? 64 / 8 : 1);
}
. = ALIGN(64 / 8);
_end = .; PROVIDE (end = .);
. = DATA_SEGMENT_END (.);
/* Stabs debugging sections. */
.stab 0 : { *(.stab) }
.stabstr 0 : { *(.stabstr) }
.stab.excl 0 : { *(.stab.excl) }
.stab.exclstr 0 : { *(.stab.exclstr) }
.stab.index 0 : { *(.stab.index) }
.stab.indexstr 0 : { *(.stab.indexstr) }
.comment 0 : { *(.comment) }
/* DWARF debug sections.
Symbols in the DWARF debugging sections are relative to the beginning
of the section so we begin them at 0. */
/* DWARF 1 */
.debug 0 : { *(.debug) }
.line 0 : { *(.line) }
/* GNU DWARF 1 extensions */
.debug_srcinfo 0 : { *(.debug_srcinfo) }
.debug_sfnames 0 : { *(.debug_sfnames) }
/* DWARF 1.1 and DWARF 2 */
.debug_aranges 0 : { *(.debug_aranges) }
.debug_pubnames 0 : { *(.debug_pubnames) }
/* DWARF 2 */
.debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) }
.debug_abbrev 0 : { *(.debug_abbrev) }
.debug_line 0 : { *(.debug_line .debug_line.* .debug_line_end ) }
.debug_frame 0 : { *(.debug_frame) }
.debug_str 0 : { *(.debug_str) }
.debug_loc 0 : { *(.debug_loc) }
.debug_macinfo 0 : { *(.debug_macinfo) }
/* SGI/MIPS DWARF 2 extensions */
.debug_weaknames 0 : { *(.debug_weaknames) }
.debug_funcnames 0 : { *(.debug_funcnames) }
.debug_typenames 0 : { *(.debug_typenames) }
.debug_varnames 0 : { *(.debug_varnames) }
/* DWARF 3 */
.debug_pubtypes 0 : { *(.debug_pubtypes) }
.debug_ranges 0 : { *(.debug_ranges) }
/* DWARF Extension. */
.debug_macro 0 : { *(.debug_macro) }
.gnu.attributes 0 : { KEEP (*(.gnu.attributes)) }
/DISCARD/ : { *(.note.GNU-stack) *(.gnu_debuglink) *(.gnu.lto_*) *(.gnu_object_only) }
}

View File

@ -1,7 +1,7 @@
/*
EnergyMech, IRC bot software
Parts Copyright (c) 1997-2009 proton
Parts Copyright (c) 1997-2018 proton
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -770,10 +770,11 @@ restart_die:
LS char *bad_exe = "init: Error: Improper executable name\n";
#ifdef __GNUC__
int main(int argc, char **argv, char **envp) __attribute__ ((__noreturn__, __sect(INIT_SEG)));
int main(int argc, char **argv, char **envp) __attribute__ ((__sect(INIT_SEG)));
#endif
int main(int argc, char **argv, char **envp)
{
struct stat st;
char *opt;
int do_fork = TRUE;
int versiononly = FALSE;
@ -786,15 +787,18 @@ int main(int argc, char **argv, char **envp)
_exit(1);
}
{
struct stat st; // allocate temporary
stat("..",&st);
parent_inode = st.st_ino; // used for is_safepath()
}
stat("..",&st);
parent_inode = st.st_ino; // used for is_safepath()
srand(now+getpid());
/*
* Code to detect and recover after a RESET
*/
/*
execve( ./energymech, argv = { ./energymech <NULL> <NULL> <NULL> <NULL> }, envp = { MECHRESET=d3 f1881:2:X12 } )
(recover_debug) debug fd recovered
*/
while(*envp)
{
char *p1;
@ -812,6 +816,9 @@ int main(int argc, char **argv, char **envp)
if (*p2 == 0)
{
mechresetenv = p1;
do_fork = FALSE;
if (*p1 == 'd')
mechresetenv = recover_debug(p1+1);
break;
}
envp++;
@ -850,16 +857,27 @@ int main(int argc, char **argv, char **envp)
versiononly = TRUE;
break;
case 'h':
/*
#define TEXT_PSWITCH1 " -p <string> encrypt <string> using the password hashing algorithm,\n"
#define TEXT_PSWITCH2 " output the result and then quit.\n"
#define TEXT_DSWITCH " -d start mech in debug mode\n"
#define TEXT_OSWITCH " -o <file> write debug output to <file>\n"
#define TEXT_XSWITCH " -X write a debug file before exit\n"
*/
to_file(1,TEXT_USAGE,executable);
to_file(1,TEXT_FSWITCH);
to_file(1,TEXT_CSWITCH);
to_file(1,TEXT_FSWITCH
TEXT_CSWITCH
TEXT_PSWITCH1
TEXT_PSWITCH2
#ifdef DEBUG
to_file(1," -d start mech in debug mode\n");
to_file(1," -o <file> write debug output to <file>\n");
to_file(1," -X write a debug file before exit\n");
TEXT_DSWITCH
TEXT_OSWITCH
TEXT_XSWITCH
#endif /* DEBUG */
to_file(1,TEXT_HSWITCH);
to_file(1,TEXT_VSWITCH);
TEXT_HSWITCH
TEXT_VSWITCH);
_exit(0);
case 'c':
makecore = TRUE;
@ -887,6 +905,13 @@ int main(int argc, char **argv, char **envp)
}
do_fork = TRUE;
break;
case 'p':
++argv;
if (*argv)
to_file(1,"%s\n",makepass(*argv));
else
to_file(1,"error: Missing argument for -p <string>\n");
_exit(0);
case 'X':
debug_on_exit = TRUE;
break;
@ -959,6 +984,10 @@ int main(int argc, char **argv, char **envp)
LocalBot.x.x.aop = 1;
LocalBot.chan = CoreUser.chan = (Strp*)&CMA;
#ifdef UPTIME
init_uptime();
#endif /* UPTIME */
readcfgfile();
#ifndef I_HAVE_A_LEGITIMATE_NEED_FOR_MORE_THAN_4_BOTS
@ -985,7 +1014,7 @@ int main(int argc, char **argv, char **envp)
if (!mechresetenv)
to_file(1,INFO_RUNNING);
if (!mechresetenv && do_fork)
if (do_fork)
{
close(0);
close(1);
@ -1018,10 +1047,6 @@ int main(int argc, char **argv, char **envp)
memset(&ctcp_slot,0,sizeof(ctcp_slot));
#endif /* CTCP */
#ifdef UPTIME
init_uptime();
#endif /* UPTIME */
#ifdef BOTNET
last_autolink = now + 30 + (rand() >> 27); /* + 0-31 seconds */
#endif /* BOTNET */

View File

@ -24,6 +24,7 @@
#include "function.c"
#include "greet.c"
#include "help.c"
#include "hostinfo.c"
#include "irc.c"
#include "kicksay.c"
#include "main.c"
@ -48,6 +49,7 @@
#include "toybox.c"
#include "trivia.c"
#include "uptime.c"
#include "urlcap.c"
#include "user.c"
#include "vars.c"
#include "web.c"

View File

@ -1,7 +1,7 @@
/*
EnergyMech, IRC bot software
Copyright (c) 1997-2009 proton
Copyright (c) 1997-2018 proton
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -30,12 +30,18 @@
#include "text.h"
#include "mcmd.h"
#ifdef MD5CRYPT
#define md5banneropt " MD5"
#if defined(SHACRYPT) || defined(MD5CRYPT)
char *CRYPT_FUNC(const char *, const char *);
#else
#define md5banneropt
#endif
const char banneropt[] = "BB%i %i PTA"
#ifdef SHACRYPT
" SHA"
#endif /* SHACRYPT */
#ifdef MD5CRYPT
" MD5"
#endif /* MD5CRYPT */
"\n";
#ifdef TELNET
char *telnetprompt = TEXT_ENTERNICKNAME;
@ -72,6 +78,7 @@ LS const LinkCmd basicProto[] =
{ 'B', 'L', basicLink },
{ 'B', 'Q', basicQuit },
{ 'C', 'O', netchanNeedop },
{ 'C', 'S', netchanSupress }, // experimental command supression
{ 'P', 'A', partyAuth },
#ifdef REDIRECT
{ 'P', 'C', partyCommand },
@ -91,7 +98,7 @@ LS int deadlinks = FALSE;
*
*/
Mech *get_netbot(void)
Mech *get_netbot(void) //get local bot with the lowes guid to act as local master
{
Mech *netbot,*bot;
int uid;
@ -307,6 +314,10 @@ void basicAuth(BotNet *bn, char *rest)
{
if (!Strcmp(pass,"PTA"))
authtype = BNAUTH_PLAINTEXT;
#ifdef SHACRYPT
if (!Strcmp(pass,"SHA"))
authtype = BNAUTH_SHA;
#endif /* SHACRYPT */
#ifdef MD5CRYPT
if (!Strcmp(pass,"MD5"))
authtype = BNAUTH_MD5;
@ -334,11 +345,31 @@ void basicAuth(BotNet *bn, char *rest)
if (Strcmp(pass,rest))
goto badpass;
break;
#ifdef SHACRYPT
case BNAUTH_SHA:
if (linkpass && *linkpass)
{
char *enc,temppass[24 + Strlen2(pass,linkpass)]; // linkpass is never NULL
/* "mypass theirpass REMOTEsid LOCALsid" */
sprintf(temppass,"%s %s %i %i",linkpass,pass,bn->rsid,bn->lsid);
#ifdef DEBUG
debug(">> sha pass exchange: \"%s\"\n",temppass);
#endif /* DEBUG */
enc = CRYPT_FUNC(temppass,rest);
#ifdef DEBUG
debug("(basicAuth) their = %s, mypass = %s :: sha = %s\n",
pass,linkpass,enc);
#endif /* DEBUG */
if (!Strcmp(enc,rest))
break;
}
#endif /* SHACRYPT */
#ifdef MD5CRYPT
case BNAUTH_MD5:
if (linkpass && *linkpass)
{
char *enc,temppass[24 + Strlen2(pass,linkpass)];
char *enc,temppass[24 + Strlen2(pass,linkpass)]; // linkpass is never NULL
/* "mypass theirpass REMOTEsid LOCALsid" */
sprintf(temppass,"%s %s %i %i",linkpass,pass,bn->rsid,bn->lsid);
@ -492,6 +523,10 @@ void basicBanner(BotNet *bn, char *rest)
{
if (!Strcmp(p,"PTA"))
bn->opt.pta = TRUE;
#ifdef SHACRYPT
if (!Strcmp(p,"SHA"))
bn->opt.sha = TRUE;
#endif /* SHACRYPT */
#ifdef MD5CRYPT
if (!Strcmp(p,"MD5"))
bn->opt.md5 = TRUE;
@ -510,7 +545,7 @@ void basicBanner(BotNet *bn, char *rest)
if (bn->status == BN_UNKNOWN)
{
bn->controller = netbot = get_netbot();
to_file(bn->sock,"BB%i %i PTA" md5banneropt "\n",netbot->guid,bn->lsid);
to_file(bn->sock,banneropt,netbot->guid,bn->lsid);
bn->status = BN_WAITAUTH;
return;
}
@ -533,12 +568,37 @@ void basicBanner(BotNet *bn, char *rest)
if (bn->opt.md5 && (BNAUTH_MD5 > authtype))
authtype = BNAUTH_MD5;
#endif /* MD5CRYPT */
#ifdef SHACRYPT
if (bn->opt.sha && (BNAUTH_SHA > authtype))
authtype = BNAUTH_SHA;
#endif /* SHACRYPT */
switch(authtype)
{
case BNAUTH_PLAINTEXT:
to_file(bn->sock,"BAPTA %s\n",linkpass);
break;
#ifdef SHACRYPT
case BNAUTH_SHA:
if ((cfg = find_netcfg(guid)))
{
if (cfg->pass && *cfg->pass)
{
char *enc,salt[8];
char temppass[24 + Strlen2(cfg->pass,linkpass)]; // linkpass(procvar) is not NULL
/* "theirpass mypass LOCALsid REMOTEsid" */
sprintf(temppass,"%s %s %i %i",cfg->pass,linkpass,bn->lsid,bn->rsid);
#ifdef DEBUG
debug(">> sha pass exchange: \"%s\"\n",temppass);
#endif /* DEBUG */
sprintf(salt,"$6$%04x",(rand() >> 16));
enc = CRYPT_FUNC(temppass,salt);
to_file(bn->sock,"BASHA %s\n",enc);
break;
}
}
#endif /* SHACRYPT */
#ifdef MD5CRYPT
case BNAUTH_MD5:
if ((cfg = find_netcfg(guid)))
@ -546,7 +606,7 @@ void basicBanner(BotNet *bn, char *rest)
if (cfg->pass && *cfg->pass)
{
char *enc,salt[8];
char temppass[24 + Strlen2(cfg->pass,linkpass)];
char temppass[24 + Strlen2(cfg->pass,linkpass)]; // linkpass(procvar) is not NULL
/* "theirpass mypass LOCALsid REMOTEsid" */
sprintf(temppass,"%s %s %i %i",cfg->pass,linkpass,bn->lsid,bn->rsid);
@ -1016,7 +1076,7 @@ void ushareUser(BotNet *bn, char *rest)
#ifdef DEBUG
debug("(ushareUser) user %s ++ mask/chan %s\n",user->name,rest);
#endif /* DEBUG */
addtouser((c == '*') ? &user->mask : &user->chan,rest);
addtouser((c == '*') ? &user->mask : &user->chan,rest,TRUE);
}
}
}
@ -1320,7 +1380,7 @@ void process_botnet(void)
{
bn->lsid = rand();
bn->controller = netbot = get_netbot();
if (to_file(bn->sock,"BB%i %i PTA" md5banneropt "\n",netbot->guid,bn->lsid) < 0)
if (to_file(bn->sock,banneropt,netbot->guid,bn->lsid) < 0)
{
botnet_deaduplink(bn);
}
@ -1498,7 +1558,7 @@ usage:
goto usage;
set_mallocdoer(do_link);
cfg = (NetCfg*)Calloc(sizeof(NetCfg) + Strlen2(pass,host));
cfg = (NetCfg*)Calloc(sizeof(NetCfg) + Strlen(pass,host,NULL)); // host might be NULL, Strlen() handles NULLs, Strlen2() does not.
cfg->guid = iguid;
cfg->port = iport;

View File

@ -1,7 +1,7 @@
/*
EnergyMech, IRC bot software
Copyright (c) 1997-2004 proton
Copyright (c) 1997-2018 proton
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -30,6 +30,36 @@
#include "text.h"
#include "mcmd.h"
int makecrc(const char *args)
{
int crc = 0;
while(*args)
{
crc += ((12345 * *args) % 321) + 4567;
args++;
}
return(crc);
}
void send_supress(const char *command, const char *args)
{
Mech *backup;
int crc;
crc = makecrc(args);
for(backup=botlist;backup;backup=backup->next)
{
if (backup != current)
{
backup->supres_cmd = command;
backup->supres_crc = crc;
}
}
botnet_relay(NULL,"CS%s %i\n",command,crc);
}
ChanUser *find_chanbot(Chan *chan, char *nick)
{
ChanUser *cu;
@ -141,4 +171,39 @@ void netchanNeedop(BotNet *source, char *rest)
}
}
void netchanSupress(BotNet *source, char *rest)
{
Mech *backup;
const char *cmd;
int crc,i,j;
botnet_relay(source,"CS%s\n",rest);
cmd = chop(&rest);
// convert command to const command
for(i=0;mcmd[i].name;i++)
{
j = Strcasecmp(mcmd[i].name,cmd);
if (j < 0)
continue;
if (j > 0)
return;
cmd = mcmd[i].name;
break;
}
if (mcmd[i].name == NULL)
return;
crc = a2i(rest);
// to all local bots
for(backup=botlist;backup;backup=backup->next)
{
backup->supres_cmd = cmd;
backup->supres_crc = crc;
}
}
#endif /* BOTNET */

View File

@ -244,7 +244,7 @@ void catch_whois(char *nick, char *userhost, char *realname)
* put in a new log entry
*/
set_mallocdoer(catch_whois);
nlog = (nfLog*)Calloc(sizeof(nfLog) + Strlen2(userhost,realname));
nlog = (nfLog*)Calloc(sizeof(nfLog) + Strlen2(userhost,realname)); // realname is never NULL
nlog->signon = now;
nlog->next = nf->log;
nf->log = nlog;
@ -306,7 +306,7 @@ int notifylog_callback(char *rest)
pp = &(*pp)->next;
}
set_mallocdoer(notifylog_callback);
nlog = (nfLog*)Calloc(sizeof(nfLog) + Strlen2(userhost,rest));
nlog = (nfLog*)Calloc(sizeof(nfLog) + Strlen2(userhost,rest)); // rest is never NULL
nlog->signon = on;
nlog->signoff = off;
nlog->next = *pp;

View File

@ -325,15 +325,15 @@ void on_nick(char *from, char *newnick)
if ((maxcount = chan->setting[INT_NCL].int_var) < 2)
continue;
if ((now - cu->nicktime) > NICKFLOODTIME)
if ((now - cu->action_time[INDEX_NICK]) > NICKFLOODTIME)
{
cu->nicktime = now + (NICKFLOODTIME / (maxcount - 1));
cu->nicknum = 1;
cu->action_time[INDEX_NICK] = now + (NICKFLOODTIME / (maxcount - 1));
cu->action_num[INDEX_NICK] = 1;
}
else
{
cu->nicktime += (NICKFLOODTIME / (maxcount - 1));
if (++cu->nicknum >= maxcount)
cu->action_time[INDEX_NICK] += (NICKFLOODTIME / (maxcount - 1));
if (++cu->action_num[INDEX_NICK] >= maxcount)
{
deop_ban(chan,cu,NULL);
send_kick(chan,newnick,KICK_NICKFLOOD);
@ -342,7 +342,7 @@ void on_nick(char *from, char *newnick)
}
}
void on_msg(char *from, char *to, char *msg)
void on_msg(char *from, char *to, char *rest)
{
#ifdef SCRIPTING
Hook *hook;
@ -368,7 +368,7 @@ void on_msg(char *from, char *to, char *msg)
*/
#ifdef NOTE
if (notelist && catch_note(from,to,msg))
if (notelist && catch_note(from,to,rest))
return;
#endif /* NOTE */
@ -378,7 +378,7 @@ void on_msg(char *from, char *to, char *msg)
*/
if (CurrentChan && !CurrentChan->setting[TOG_PUB].int_var)
{
common_public(CurrentChan,from,"<%s> %s",msg);
common_public(CurrentChan,from,"<%s> %s",rest);
return;
}
@ -398,7 +398,7 @@ void on_msg(char *from, char *to, char *msg)
/*
* remember where the string started
*/
origstart = msg;
origstart = rest;
if (from == CoreUser.name)
{
@ -412,7 +412,7 @@ void on_msg(char *from, char *to, char *msg)
/*
* check for command bots nick replacing command char
*/
if ((p2 = (uchar*)(command = chop(&msg))) == NULL)
if ((p2 = (uchar*)(command = chop(&rest))) == NULL)
return;
p1 = (uchar*)current->nick;
@ -421,7 +421,7 @@ void on_msg(char *from, char *to, char *msg)
if (!i || ((p2 > (uchar*)command) && (*p2 == ':' || *p2 == ';' || *p2 == ',') && p2[1] == 0))
{
if ((command = chop(&msg)) == NULL)
if ((command = chop(&rest)) == NULL)
return;
has_cc = TRUE;
}
@ -449,12 +449,13 @@ recheck_alias:
{
if (!Strcasecmp(alias->alias,command))
{
afmt(amem,alias->format,msg);
unchop(command,rest);
afmt(amem,alias->format,command);
#ifdef DEBUG
debug("(on_msg) [ALIAS] %s %s --> %s\n",command,msg,amem);
debug("(on_msg) [ALIAS] %s --> %s\n",command,amem);
#endif /* DEBUG */
msg = amem;
pt = chop(&msg);
rest = amem;
pt = chop(&rest);
i = Strcasecmp(pt,command);
command = pt;
arec++;
@ -482,7 +483,7 @@ recheck_alias:
*/
if (hook->flags == HOOK_COMMAND && !Strcasecmp(command,hook->type.command))
{
if (hook->func(from,msg,hook))
if (hook->func(from,rest,hook))
/* if the hook returns non-zero, the input should not be parsed internally */
i = 1;
}
@ -517,8 +518,34 @@ recheck_alias:
#endif /* DEBUG */
return;
}
CurrentCmd = &mcmd[i];
#ifdef BOTNET
// experimental command supression
if (CurrentCmd->name == current->supres_cmd)
{
int crc;
crc = makecrc(rest);
if (current->supres_crc == crc)
{
// another bot has already executed this command and is trying to supress its execution on other bots
current->supres_cmd = NULL;
current->supres_crc = 0;
#ifdef DEBUG
debug("(on_msg) command \"%s\" from %s was supressed\n",CurrentCmd->name,CurrentNick);
#endif
return;
}
}
//if command should be supressed ...
if (CurrentChan)
{
send_supress(CurrentCmd->name,rest);
}
#endif
/*
* convert the command to uppercase
*/
@ -565,7 +592,7 @@ recheck_alias:
if (mcmd[i].caxs)
{
/* get channel name; 1: msg, 2: to, 3: active channel */
to = get_channel(to,&msg);
to = get_channel(to,&rest);
if (!ischannel(to))
return;
uaccess = get_authaccess(from,to);
@ -592,7 +619,7 @@ recheck_alias:
/*
* CARGS check: at least one argument is required
*/
if (mcmd[i].args && !*msg)
if (mcmd[i].args && !*rest)
{
if (uaccess) usage_command(from,command);
return;
@ -610,7 +637,7 @@ recheck_alias:
redirect.method = R_PRIVMSG;
}
else
if (begin_redirect(from,msg) < 0)
if (begin_redirect(from,rest) < 0)
return;
}
#endif /* REDIRECT */
@ -618,7 +645,7 @@ recheck_alias:
if (mcmd[i].dcc && dcc_only_command(from))
return;
mcmd[i].func(from,to,msg,acmd[i]);
mcmd[i].func(from,to,rest,acmd[i]);
#ifdef DEBUG
CurrentCmd = NULL;
@ -636,7 +663,7 @@ recheck_alias:
/*
* un-chop() the message string
*/
unchop(origstart,msg);
unchop(origstart,rest);
if (CurrentChan)
{

View File

@ -1,7 +1,7 @@
/*
EnergyMech, IRC bot software
Parts Copyright (c) 1997-2009 proton
Parts Copyright (c) 1997-2018 proton
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -350,10 +350,35 @@ void parse_ping(char *from, char *rest)
to_server("PONG :%s\n",rest);
}
void parse_pong(char *from, char *rest)
{
time_t ot;
char *src;
#ifdef DEBUG
debug("(parse_pong) rest == %s\n",rest);
#endif
if (rest[0] == ':' && rest[1] == 'O' && rest[2] == 'T')
{
ot = 0;
src = &rest[3];
while(attrtab[(uchar)*src] & NUM)
ot = (ot * 10) + (*src++ - '0');
current->ontime = ot;
#ifdef DEBUG
debug("(parse_pong) recovering ontime = %lu (%s)\n",ot,idle2str(now - ot,TRUE));
#endif
}
}
void parse_privmsg(char *from, char *rest)
{
ChanUser *cu;
char *to,*channel;
#ifdef URLCAPTURE
const char *src;
#endif /* URLCAPTURE */
to = chop(&rest);
if (*rest == ':')
@ -404,6 +429,24 @@ void parse_privmsg(char *from, char *rest)
if (CurrentChan && CurrentChan->stats)
CurrentChan->stats->privmsg++;
#endif /* STATS */
#ifdef URLCAPTURE
src = rest;
while(*src)
{
if (tolowertab[*src] == 'h')
{
if (tolowertab[src[1]] == 't' && tolowertab[src[2]] == 't' && tolowertab[src[3]] == 'p')
{
if ((src[4] == ':') || // "http:"
(tolowertab[src[4]] == 's' && src[5] == ':')) // "https:"
{
urlcapture(src);
}
}
}
src++;
}
#endif /* URLCAPTURE */
on_msg(from,to,rest);
}
@ -1345,6 +1388,7 @@ LS const struct
{ 0x4E49434B, NEEDFROM, on_nick }, /* NICK */
{ 0x4B49434B, NEEDFROM, on_kick }, /* KICK */
{ 0x50494E47, 0, parse_ping }, /* PING */
{ 0x504F4E47, DROPONE, parse_pong }, /* PONG */
{ 0x544F5049, NEEDFROM, parse_topic }, /* TOPIC */
{ 0x4E4F5449, NEEDFROM, parse_notice }, /* NOTICE */
{ 0x51554954, NEEDFROM, parse_quit }, /* QUIT */
@ -1476,12 +1520,13 @@ void parseline(char *rest)
cmdhash = 0;
}
}
if (!cmdhash)
if (cmdhash == 0)
return;
#endif /* SCRIPTING */
cmdhash = stringhash(command);
//debug("cmdhash = %08X\n",cmdhash);
for(i=0;pFuncs[i].hash;i++)
{
if (cmdhash == pFuncs[i].hash)
@ -1489,9 +1534,26 @@ void parseline(char *rest)
if ((pFuncs[i].flags & NEEDFROM) && !from)
return;
if (pFuncs[i].flags & DROPONE)
chop(&rest); /* discard bot nick */
chop(&rest); /* discard one argument (usually bot nick) */
pFuncs[i].func(from,rest);
return;
}
}
//debug("unmatched cmdhash %08X\n",cmdhash);
}
/*
(in) {2} :weber.freenode.net PONG weber.freenode.net :OT1521044136
cmdhash = 504F4E47
unmatched cmdhash 504F4E47
(in) {2} :weber.freenode.net 347 jooboy #amdx :End of Channel Invite List
cmdhash = 00333437
unmatched cmdhash 00333437
(in) {2} :weber.freenode.net 349 jooboy #amdx :End of Channel Exception List
cmdhash = 00333439
unmatched cmdhash 00333439
*/

View File

@ -61,7 +61,6 @@ int perl_parse_jump(char *from, char *rest, Hook *hook)
SPAGAIN; /* Rehash stack, it's probably been clobbered */
return(POPi); /* Pop an int */
}
/*
@ -83,7 +82,7 @@ XS(XS_perl_parse_hook)
/*
* translate *name and *sub from perl variables to C strings
* SvPV(ST(0)) returns a string(char) pointer to the first arg.
* SvPV(ST(0)) returns a string(char) pointer to the first arg.
* but I don't know if it's safe to point directly in to perl
* space like that.
*/
@ -100,7 +99,7 @@ XS(XS_perl_parse_hook)
* make a Hook struct and link it into the parse hook list
*/
set_mallocdoer(perl_parse_hook);
hook = (Hook*)Calloc(sizeof(Hook) + Strlen2(name,sub));
hook = (Hook*)Calloc(sizeof(Hook) + Strlen2(name,sub)); // sub is never NULL
hook->func = perl_parse_jump;
hook->next = hooklist;
hooklist = hook;

View File

@ -51,7 +51,7 @@ void send_kick(Chan *chan, const char *nick, const char *format, ...)
pp = &(*pp)->next;
set_mallocdoer(send_kick);
*pp = new = (qKick*)Calloc(sizeof(qKick) + Strlen2(nick,gsockdata));
*pp = new = (qKick*)Calloc(sizeof(qKick) + Strlen2(nick,gsockdata)); // gsockdata is never NULL
/* Calloc sets to zero new->next = NULL; */
new->reason = Strcpy(new->nick,nick) + 1;
@ -277,11 +277,11 @@ void update_modes(Chan *chan)
*/
int check_mass(Chan *chan, ChanUser *doer, int type)
{
time_t *when;
int *num,limit;
time_t when;
int num,limit;
/*
* must handle servers ...
* must handle servers ... (netsplits, chanserv, nickserv, ...)
*/
if (!doer)
return(FALSE);
@ -300,38 +300,37 @@ int check_mass(Chan *chan, ChanUser *doer, int type)
*/
//case CHK_CAPS:
case INT_CKL:
num = &doer->capsnum;
num = INDEX_CAPS;
break;
//case CHK_PUB:
case INT_FL:
num = &doer->floodnum;
num = INDEX_FLOOD;
break;
/*
* three things we dont want channel ops to do
*/
//case CHK_DEOP:
case INT_MDL:
num = &doer->deopnum;
num = INDEX_DEOP;
break;
//case CHK_BAN:
case INT_MBL:
num = &doer->bannum;
num = INDEX_BAN;
break;
default:
/* case CHK_KICK: */
/* case INT_MKL: */
num = &doer->kicknum;
num = INDEX_KICK;
break;
}
when = (time_t*)&num[1];
if ((now - *when) > 10)
if ((now - doer->action_time[num]) > 10)
{
*when = now;
*num = 0;
doer->action_time[num] = now;
doer->action_num[num] = 0;
}
++(*num);
if (*num >= limit && limit)
++(doer->action_num[num]);
if (doer->action_num[num] >= limit && limit)
return(TRUE);
return(FALSE);
}

View File

@ -1,7 +1,7 @@
/*
EnergyMech, IRC bot software
Copyright (c) 1997-2004 proton
Copyright (c) 1997-2018 proton
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -78,7 +78,7 @@ int begin_redirect(char *from, char *args)
to_user(from,"Missing name for redirect.");
return(-1);
}
if (!is_safepath(nick))
if (is_safepath(nick,FILE_MAY_EXIST) != FILE_IS_SAFE) // redirect output is appended
{
to_user(from,"Bad filename.");
return(-1);

View File

@ -1,7 +1,7 @@
/*
EnergyMech, IRC bot software
Copyright (c) 1997-2008 proton
Copyright (c) 1997-2018 proton
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -105,6 +105,7 @@ char *recover_client(char *env)
}
}
close(fd);
killsock(fd);
return(p);
found_user:
@ -183,6 +184,8 @@ char *recover_debug(char *env)
#endif /* DEBUG */
//execve( ./energymech, argv = { ./energymech <NULL> <NULL> <NULL> <NULL> }, envp = { MECHRESET=d3 f1881:2:X12 f99:4:X12 } )
char *recover_server(char *env)
{
struct sockaddr_in sai;
@ -268,9 +271,17 @@ char *recover_server(char *env)
debug("(recover_server) {%i} server socket recovered\n",fd);
#endif /* DEBUG */
to_file(fd,"LUSERS\n");
fd = -1;
break;
}
}
// if we recover a guid:socket without a matching bot in config, it got removed or changed guid
// if the guid changed, we cant guess which old<-->new is the matching one so
if (fd != -1)
{
to_file(fd,"QUIT :I'm no longer wanted *cry*\n");
killsock(fd);
}
return(p);
}
@ -376,22 +387,24 @@ void do_reset(COMMAND_ARGS)
/*
* Save server connections
*/
for(backup=botlist;backup;backup=backup->next)
backup = current;
for(current=botlist;current;current=current->next)
{
if ((backup->connect == CN_ONLINE) && ((MSGLEN - (p - env)) > 25))
if ((current->connect == CN_ONLINE) && ((MSGLEN - (p - env)) > 25))
{
unset_closeonexec(backup->sock);
unset_closeonexec(current->sock);
if (n)
*(p++) = ' ';
#ifdef IRCD_EXTENSIONS
sprintf(p,"f%i:%i:X%i",backup->guid,backup->sock,backup->ircx_flags);
sprintf(p,"f%i:%i:X%i",current->guid,current->sock,current->ircx_flags);
#else /* IRCD_EXTENSIONS */
sprintf(p,"f%i:%i",backup->guid,backup->sock);
sprintf(p,"f%i:%i",current->guid,current->sock);
#endif /* IRCD_EXTENSIONS */
p = STREND(p);
n++;
to_server("PING :OT%lu\n",current->ontime);
}
for(client=backup->clientlist;client;client=client->next)
for(client=current->clientlist;client;client=client->next)
{
#ifdef TELNET
if ((client->flags & (DCC_ACTIVE|DCC_TELNET)) == 0)
@ -408,15 +421,16 @@ void do_reset(COMMAND_ARGS)
*(p++) = ' ';
#ifdef TELNET
sprintf(p,(client->flags & DCC_TELNET) ? "t%i:%i:%s" : "c%i:%i:%s",
backup->guid,client->sock,client->user->name);
current->guid,current->sock,client->user->name);
#else
sprintf(p,"c%i:%i:%s",backup->guid,client->sock,client->user->name);
sprintf(p,"c%i:%i:%s",current->guid,current->sock,client->user->name);
#endif /* TELNET */
p = STREND(p);
n++;
}
}
}
current = backup;
#ifdef DEBUG
debug("(do_reset) %s [%i]\n",env,(int)(p - env));

View File

@ -1,7 +1,7 @@
/*
EnergyMech, IRC bot software
Copyright (c) 2001-2009 proton
Copyright (c) 2001-2018 proton
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -25,8 +25,13 @@
#define DEFAULTCMDCHAR '-'
#define ZERO 0
#define INTCAST(x) (void*)((int)x)
#define CHARCAST (void*)((int)DEFAULTCMDCHAR)
#define INTCAST(x) .v.num=x
#define CMDCHAR .v.chr=DEFAULTCMDCHAR
#define VNULL .v.str=NULL
#define TOGPROC(x) .v.numptr=&x
#define CHRPROC(x) .v.str=&x
#define INTPROC(x) .v.numptr=&x
#define STRPROC(x) .v.strptr=&x
LS const Setting VarName[SIZE_VARS] =
{
@ -44,10 +49,10 @@ LS const Setting VarName[SIZE_VARS] =
{ INT_VAR, 40, 0, ZERO, "CKL", 20 },
{ TOG_VAR, 40, 0, ZERO, "CTL", 1 },
#ifdef DYNAMODE
{ STR_VAR, 40, 0, NULL, "DYNLIMIT", 1 }, /* settings for dynamode: `delay:window:minwin' */
{ STR_VAR, 40, 0, VNULL, "DYNLIMIT", 1 }, /* settings for dynamode: `delay:window:minwin' */
#endif /* DYNAMODE */
{ TOG_VAR, 40, 0, ZERO, "ENFM", 1 },
{ STR_VAR, 40, 0, NULL, "ENFMODES" }, /* modes to enforce, +ENFM to enable */
{ STR_VAR, 40, 0, VNULL, "ENFMODES" }, /* modes to enforce, +ENFM to enable */
{ INT_VAR, 40, 0, INTCAST(6), "FL", 20 }, /* number of lines that counts as a text flood */
{ INT_VAR, 40, 0, ZERO, "FPL", 2 },
{ INT_VAR, 40, 0, INTCAST(0), "IKT", 40320 }, /* idle-kick: minutes of idle-time (max 4 weeks) */
@ -65,79 +70,82 @@ LS const Setting VarName[SIZE_VARS] =
{ TOG_VAR, 40, 0, INTCAST(1), "SHIT", 1 }, /* shitlist enable */
{ TOG_VAR, 40, 0, ZERO, "SO", 1 }, /* safe-op enable */
#ifdef STATS
{ STR_VAR, 80, 0, NULL, "STATS" }, /* statistics log file */
{ STR_VAR, 80, 0, VNULL, "STATS" }, /* statistics log file */
#endif /* STATS */
{ TOG_VAR, 40, 0, ZERO, "TOP", 1 },
/*
* all global variables
*/
/* TYPE UACCES MIN DEFAULT NAME MAX */
{ INT_GLOBAL, 40, 0, ZERO, "AAWAY", 1440 }, /* set auto-away after ___ minutes */
{ STR_GLOBAL, 90, 0, NULL, "ALTNICK" }, /* alternative nick */
/* TYPE UACCES MIN DEFAULT NAME MAX */
{ INT_GLOBAL, 40, 0, ZERO, "AAWAY", 1440 }, /* set auto-away after ___ minutes */
{ STR_GLOBAL, 90, 0, VNULL, "ALTNICK" }, /* alternative nick */
#ifdef BOTNET
{ TOG_PROC, 90, 0, (&autolink), "AUTOLINK", 1 }, /* establish links automagically */
{ TOG_PROC, 90, 0, TOGPROC(autolink), "AUTOLINK", 1 }, /* establish links automagically */
#endif /* BOTNET */
#ifdef BOUNCE
{ INT_PROC, 100, 0, (&bounce_port), "BNCPORT", 65535, (&new_port_bounce) }, /* irc proxy port to listen on */
{ INT_PROC, 100, 0, INTPROC(bounce_port), "BNCPORT", 65535, (&new_port_bounce) }, /* irc proxy port to listen on */
#endif /* BOUNCE */
{ TOG_GLOBAL, 90, 0, INTCAST(1), "CC", 1 }, /* require command char */
{ CHR_GLOBAL, 90, 1, CHARCAST, "CMDCHAR", 255 }, /* command char */
{ TOG_GLOBAL, 90, 0, INTCAST(1), "CC", 1 }, /* require command char */
{ CHR_GLOBAL, 90, 1, CMDCHAR, "CMDCHAR", 255 }, /* command char */
#ifdef CTCP
{ TOG_GLOBAL, 90, 0, INTCAST(1), "CTCP", 1 }, /* ctcp replies enable */
{ TOG_GLOBAL, 90, 0, INTCAST(1), "CTCP", 1 }, /* ctcp replies enable */
#endif /* CTCP */
{ INT_PROC, 100, 10, (&ctimeout), "CTIMEOUT", 3600 }, /* how long to wait between connect attempts */
{ INT_PROC, 100, 10, INTPROC(ctimeout), "CTIMEOUT", 3600 }, /* how long to wait between connect attempts */
#ifdef DCC_FILE
{ INT_GLOBAL, 80, 0, ZERO, "DCCANON", 100 }, /* anonymous (non user) DCC slots */
{ STR_GLOBAL, 80, 0, NULL, "DCCFILES" }, /* string with space separated masks for auto-accepted filenames */
{ INT_GLOBAL, 80, 0, INTCAST(4), "DCCUSER", 100 }, /* user DCC slots */
{ INT_GLOBAL, 80, 0, ZERO, "DCCANON", 100 }, /* anonymous (non user) DCC slots */
{ STR_GLOBAL, 80, 0, VNULL, "DCCFILES" }, /* string with space separated masks for auto-accepted filenames */
{ INT_GLOBAL, 80, 0, INTCAST(4), "DCCUSER", 100 }, /* user DCC slots */
#endif /* DCC_FILE */
{ TOG_GLOBAL, 80, 0, ZERO, "ENFPASS", 1 }, /* disallow users with no passwords */
{ STR_GLOBAL, 90, 0, NULL, "IDENT" }, /* register with this in the `user' field */
{ STR_GLOBAL, 90, 0, NULL, "IRCNAME" }, /* register with this in the `real name' field */
{ TOG_GLOBAL, 80, 0, ZERO, "ENFPASS", 1 }, /* disallow users with no passwords */
{ STR_GLOBAL, 90, 0, VNULL, "IDENT" }, /* register with this in the `user' field */
{ STR_GLOBAL, 90, 0, VNULL, "IRCNAME" }, /* register with this in the `real name' field */
#ifdef NOTIFY
{ INT_GLOBAL, 80, 10, INTCAST(30), "ISONDELAY", 600 }, /* seconds between each ISON */
{ INT_GLOBAL, 80, 10, INTCAST(30), "ISONDELAY", 600 }, /* seconds between each ISON */
#endif /* NOTIFY */
#ifdef BOTNET
{ STR_PROC, 90, 0, (&linkpass), "LINKPASS" }, /* local process linkpass */
{ INT_PROC, 100, 0, (&linkport), "LINKPORT", 65535 }, /* listen on <linkport> for botnet connections */
{ STR_PROC, 90, 0, STRPROC(linkpass), "LINKPASS" }, /* local process linkpass */
{ INT_PROC, 100, 0, INTPROC(linkport), "LINKPORT", 65535 }, /* listen on <linkport> for botnet connections */
#endif /* BOTNET */
{ INT_GLOBAL, 80, 1, INTCAST(3), "MODES", 20 }, /* max number of channel modes to send */
{ INT_GLOBAL, 80, 1, INTCAST(3), "MODES", 20 }, /* max number of channel modes to send */
#ifdef BOTNET
{ TOG_GLOBAL, 90, 0, INTCAST(1), "NETUSERS", 1 }, /* this bot accepts shared users (on by default) */
{ TOG_GLOBAL, 90, 0, INTCAST(1), "NETUSERS", 1 }, /* this bot accepts shared users (on by default) */
#endif /* BOTNET */
{ TOG_GLOBAL, 80, 0, ZERO, "NOIDLE", 1 }, /* dont idle */
{ TOG_GLOBAL, 80, 0, ZERO, "NOIDLE", 1 }, /* dont idle */
#ifdef NOTIFY
{ STR_GLOBAL, 80, 0, NULL, "NOTIFYFILE" }, /* read notify settings from <notifyfile> */
{ STR_GLOBAL, 80, 0, VNULL, "NOTIFYFILE" }, /* read notify settings from <notifyfile> */
#endif /* NOTIFY */
{ TOG_GLOBAL, 90, 0, ZERO, "ONOTICE", 1 }, /* ircd has /notice @#channel */
{ TOG_GLOBAL, 90, 0, ZERO, "ONOTICE", 1 }, /* ircd has /notice @#channel */
#ifdef TRIVIA
{ CHR_PROC, 80, 0, (&triv_qchar), "QCHAR" }, /* use <qchar> as mask char when displaying answer */
{ INT_PROC, 80, 1, (&triv_qdelay), "QDELAY", 3600 }, /* seconds between each question */
{ STR_PROC, 80, 0, (&triv_qfile), "QFILE" }, /* load questions from <qfile> */
{ CHR_PROC, 80, 0, CHRPROC(triv_qchar), "QCHAR" }, /* use <qchar> as mask char when displaying answer */
{ INT_PROC, 80, 1, INTPROC(triv_qdelay), "QDELAY", 3600 }, /* seconds between each question */
{ STR_PROC, 80, 0, STRPROC(triv_qfile), "QFILE" }, /* load questions from <qfile> */
#endif /* TRIVIA */
#ifdef CTCP
{ TOG_GLOBAL, 80, 0, ZERO, "RF", 1 }, /* random ctcp finger reply */
{ TOG_GLOBAL, 80, 0, ZERO, "RV", 1 }, /* random ctcp version reply */
{ TOG_GLOBAL, 80, 0, ZERO, "RF", 1 }, /* random ctcp finger reply */
{ TOG_GLOBAL, 80, 0, ZERO, "RV", 1 }, /* random ctcp version reply */
#endif /* CTCP */
#ifdef SEEN
{ STR_PROC, 90, 0, (&seenfile), "SEENFILE" }, /* load/save seen database from <seenfile> */
{ STR_PROC, 90, 0, STRPROC(seenfile), "SEENFILE" }, /* load/save seen database from <seenfile> */
#endif /* SEEN */
{ STR_GLOBAL, 80, 0, NULL, "SERVERGROUP" }, /* connect bot to a certain group of servers */
{ TOG_GLOBAL, 90, 0, ZERO, "SPY", 1 }, /* send info about executed commands to status channel */
{ STR_GLOBAL, 90, 0, NULL, "UMODES" }, /* send these modes on connect */
{ STR_GLOBAL, 80, 0, VNULL, "SERVERGROUP" }, /* connect bot to a certain group of servers */
{ TOG_GLOBAL, 90, 0, ZERO, "SPY", 1 }, /* send info about executed commands to status channel */
{ STR_GLOBAL, 90, 0, VNULL, "UMODES" }, /* send these modes on connect */
#ifdef UPTIME
{ STR_PROC, 100, 0, (&uptimehost), "UPHOST" }, /* send uptime packets to <uphost> */
{ STR_PROC, 100, 0, (&uptimenick), "UPNICK" }, /* send <upnick> as identifier instead of bots nick */
{ INT_PROC, 100, 0, (&uptimeport), "UPPORT", 65535 }, /* send packets to port <upport> */
{ STR_PROC, 100, 0, STRPROC(uptimehost), "UPHOST" }, /* send uptime packets to <uphost> */
{ STR_PROC, 100, 0, STRPROC(uptimenick), "UPNICK" }, /* send <upnick> as identifier instead of bots nick */
{ INT_PROC, 100, 0, INTPROC(uptimeport), "UPPORT", 65535 }, /* send packets to port <upport> */
#ifdef URLCAPTURE
{ INT_PROC, 100, 0, INTPROC(urlhistmax), "URLHIST", 100 }, /* max # of url's to keep in history */
#endif /* URLCAPTURE */
#endif /* UPTIME */
{ STR_GLOBAL, 90, 0, NULL, "USERFILE" }, /* what file to load/save userlist from/to */
{ STR_GLOBAL, 90, 0, NULL, "VIRTUAL", 0, (&var_resolve_host) }, /* visual host */
{ STR_GLOBAL, 90, 0, VNULL, "USERFILE" }, /* what file to load/save userlist from/to */
{ STR_GLOBAL, 90, 0, VNULL, "VIRTUAL", 0, (&var_resolve_host) }, /* visual host */
#ifdef WEB
{ INT_PROC, 100, 0, (&webport), "WEBPORT", 65535 }, /* httpd should listen on... */
{ INT_PROC, 100, 0, INTPROC(webport), "WEBPORT", 65535 }, /* httpd should listen on... */
#endif /* WEB */
#ifdef WINGATE
{ STR_GLOBAL, 90, 0, NULL, "WINGATE", 0, (&var_resolve_host) }, /* wingate hostname */
{ INT_GLOBAL, 90, 0, ZERO, "WINGPORT", 65535 }, /* wingate port */
{ STR_GLOBAL, 90, 0, VNULL, "WINGATE", 0, (&var_resolve_host) }, /* wingate hostname */
{ INT_GLOBAL, 90, 0, ZERO, "WINGPORT", 65535 }, /* wingate port */
#endif /* WINGATE */
{ 0, }};

27
src/sha/sha.c Normal file
View File

@ -0,0 +1,27 @@
#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include "sha1.h"
int main(int argc, char **argv)
{
SHA1_CTX sha;
uint8_t results[20];
char *buf;
int n;
buf = "abc";
n = strlen(buf);
SHA1Init(&sha);
SHA1Update(&sha, (uint8_t *)buf, n);
SHA1Final(results, &sha);
/* Print the digest as one long hex value */
printf("a9993e364706816aba3e25717850c26c9cd0d89d <-- expected result\n");
for (n = 0; n < 20; n++)
printf("%02x", results[n]);
putchar('\n');
return(0);
}

296
src/sha/sha1.c Normal file
View File

@ -0,0 +1,296 @@
/*
SHA-1 in C
By Steve Reid <steve@edmweb.com>
100% Public Domain
Test Vectors (from FIPS PUB 180-1)
"abc"
A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D
"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"
84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1
A million repetitions of "a"
34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F
*/
/* #define LITTLE_ENDIAN * This should be #define'd already, if true. */
/* #define SHA1HANDSOFF * Copies data before messing with it. */
#define SHA1HANDSOFF
#include <stdio.h>
#include <string.h>
/* for uint32_t */
#include <stdint.h>
#include "sha1.h"
#define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits))))
/* blk0() and blk() perform the initial expand. */
/* I got the idea of expanding during the round function from SSLeay */
#if BYTE_ORDER == LITTLE_ENDIAN
#define blk0(i) (block->l[i] = (rol(block->l[i],24)&0xFF00FF00) \
|(rol(block->l[i],8)&0x00FF00FF))
#elif BYTE_ORDER == BIG_ENDIAN
#define blk0(i) block->l[i]
#else
#error "Endianness not defined!"
#endif
#define blk(i) (block->l[i&15] = rol(block->l[(i+13)&15]^block->l[(i+8)&15] \
^block->l[(i+2)&15]^block->l[i&15],1))
/* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */
#define R0(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk0(i)+0x5A827999+rol(v,5);w=rol(w,30);
#define R1(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk(i)+0x5A827999+rol(v,5);w=rol(w,30);
#define R2(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0x6ED9EBA1+rol(v,5);w=rol(w,30);
#define R3(v,w,x,y,z,i) z+=(((w|x)&y)|(w&x))+blk(i)+0x8F1BBCDC+rol(v,5);w=rol(w,30);
#define R4(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0xCA62C1D6+rol(v,5);w=rol(w,30);
/* Hash a single 512-bit block. This is the core of the algorithm. */
void SHA1Transform(
uint32_t state[5],
const unsigned char buffer[64]
)
{
uint32_t a, b, c, d, e;
typedef union
{
unsigned char c[64];
uint32_t l[16];
} CHAR64LONG16;
#ifdef SHA1HANDSOFF
CHAR64LONG16 block[1]; /* use array to appear as a pointer */
memcpy(block, buffer, 64);
#else
/* The following had better never be used because it causes the
* pointer-to-const buffer to be cast into a pointer to non-const.
* And the result is written through. I threw a "const" in, hoping
* this will cause a diagnostic.
*/
CHAR64LONG16 *block = (const CHAR64LONG16 *) buffer;
#endif
/* Copy context->state[] to working vars */
a = state[0];
b = state[1];
c = state[2];
d = state[3];
e = state[4];
/* 4 rounds of 20 operations each. Loop unrolled. */
R0(a, b, c, d, e, 0);
R0(e, a, b, c, d, 1);
R0(d, e, a, b, c, 2);
R0(c, d, e, a, b, 3);
R0(b, c, d, e, a, 4);
R0(a, b, c, d, e, 5);
R0(e, a, b, c, d, 6);
R0(d, e, a, b, c, 7);
R0(c, d, e, a, b, 8);
R0(b, c, d, e, a, 9);
R0(a, b, c, d, e, 10);
R0(e, a, b, c, d, 11);
R0(d, e, a, b, c, 12);
R0(c, d, e, a, b, 13);
R0(b, c, d, e, a, 14);
R0(a, b, c, d, e, 15);
R1(e, a, b, c, d, 16);
R1(d, e, a, b, c, 17);
R1(c, d, e, a, b, 18);
R1(b, c, d, e, a, 19);
R2(a, b, c, d, e, 20);
R2(e, a, b, c, d, 21);
R2(d, e, a, b, c, 22);
R2(c, d, e, a, b, 23);
R2(b, c, d, e, a, 24);
R2(a, b, c, d, e, 25);
R2(e, a, b, c, d, 26);
R2(d, e, a, b, c, 27);
R2(c, d, e, a, b, 28);
R2(b, c, d, e, a, 29);
R2(a, b, c, d, e, 30);
R2(e, a, b, c, d, 31);
R2(d, e, a, b, c, 32);
R2(c, d, e, a, b, 33);
R2(b, c, d, e, a, 34);
R2(a, b, c, d, e, 35);
R2(e, a, b, c, d, 36);
R2(d, e, a, b, c, 37);
R2(c, d, e, a, b, 38);
R2(b, c, d, e, a, 39);
R3(a, b, c, d, e, 40);
R3(e, a, b, c, d, 41);
R3(d, e, a, b, c, 42);
R3(c, d, e, a, b, 43);
R3(b, c, d, e, a, 44);
R3(a, b, c, d, e, 45);
R3(e, a, b, c, d, 46);
R3(d, e, a, b, c, 47);
R3(c, d, e, a, b, 48);
R3(b, c, d, e, a, 49);
R3(a, b, c, d, e, 50);
R3(e, a, b, c, d, 51);
R3(d, e, a, b, c, 52);
R3(c, d, e, a, b, 53);
R3(b, c, d, e, a, 54);
R3(a, b, c, d, e, 55);
R3(e, a, b, c, d, 56);
R3(d, e, a, b, c, 57);
R3(c, d, e, a, b, 58);
R3(b, c, d, e, a, 59);
R4(a, b, c, d, e, 60);
R4(e, a, b, c, d, 61);
R4(d, e, a, b, c, 62);
R4(c, d, e, a, b, 63);
R4(b, c, d, e, a, 64);
R4(a, b, c, d, e, 65);
R4(e, a, b, c, d, 66);
R4(d, e, a, b, c, 67);
R4(c, d, e, a, b, 68);
R4(b, c, d, e, a, 69);
R4(a, b, c, d, e, 70);
R4(e, a, b, c, d, 71);
R4(d, e, a, b, c, 72);
R4(c, d, e, a, b, 73);
R4(b, c, d, e, a, 74);
R4(a, b, c, d, e, 75);
R4(e, a, b, c, d, 76);
R4(d, e, a, b, c, 77);
R4(c, d, e, a, b, 78);
R4(b, c, d, e, a, 79);
/* Add the working vars back into context.state[] */
state[0] += a;
state[1] += b;
state[2] += c;
state[3] += d;
state[4] += e;
/* Wipe variables */
a = b = c = d = e = 0;
#ifdef SHA1HANDSOFF
memset(block, '\0', sizeof(block));
#endif
}
/* SHA1Init - Initialize new context */
void SHA1Init(
SHA1_CTX * context
)
{
/* SHA1 initialization constants */
context->state[0] = 0x67452301;
context->state[1] = 0xEFCDAB89;
context->state[2] = 0x98BADCFE;
context->state[3] = 0x10325476;
context->state[4] = 0xC3D2E1F0;
context->count[0] = context->count[1] = 0;
}
/* Run your data through this. */
void SHA1Update(
SHA1_CTX * context,
const unsigned char *data,
uint32_t len
)
{
uint32_t i;
uint32_t j;
j = context->count[0];
if ((context->count[0] += len << 3) < j)
context->count[1]++;
context->count[1] += (len >> 29);
j = (j >> 3) & 63;
if ((j + len) > 63)
{
memcpy(&context->buffer[j], data, (i = 64 - j));
SHA1Transform(context->state, context->buffer);
for (; i + 63 < len; i += 64)
{
SHA1Transform(context->state, &data[i]);
}
j = 0;
}
else
i = 0;
memcpy(&context->buffer[j], &data[i], len - i);
}
/* Add padding and return the message digest. */
void SHA1Final(
unsigned char digest[20],
SHA1_CTX * context
)
{
unsigned i;
unsigned char finalcount[8];
unsigned char c;
#if 0 /* untested "improvement" by DHR */
/* Convert context->count to a sequence of bytes
* in finalcount. Second element first, but
* big-endian order within element.
* But we do it all backwards.
*/
unsigned char *fcp = &finalcount[8];
for (i = 0; i < 2; i++)
{
uint32_t t = context->count[i];
int j;
for (j = 0; j < 4; t >>= 8, j++)
*--fcp = (unsigned char) t}
#else
for (i = 0; i < 8; i++)
{
finalcount[i] = (unsigned char) ((context->count[(i >= 4 ? 0 : 1)] >> ((3 - (i & 3)) * 8)) & 255); /* Endian independent */
}
#endif
c = 0200;
SHA1Update(context, &c, 1);
while ((context->count[0] & 504) != 448)
{
c = 0000;
SHA1Update(context, &c, 1);
}
SHA1Update(context, finalcount, 8); /* Should cause a SHA1Transform() */
for (i = 0; i < 20; i++)
{
digest[i] = (unsigned char)
((context->state[i >> 2] >> ((3 - (i & 3)) * 8)) & 255);
}
/* Wipe variables */
memset(context, '\0', sizeof(*context));
memset(&finalcount, '\0', sizeof(finalcount));
}
void SHA1(
char *hash_out,
const char *str,
int len)
{
SHA1_CTX ctx;
unsigned int ii;
SHA1Init(&ctx);
for (ii=0; ii<len; ii+=1)
SHA1Update(&ctx, (const unsigned char*)str + ii, 1);
SHA1Final((unsigned char *)hash_out, &ctx);
hash_out[20] = '\0';
}

44
src/sha/sha1.h Normal file
View File

@ -0,0 +1,44 @@
#ifndef SHA1_H
#define SHA1_H
/*
SHA-1 in C
By Steve Reid <steve@edmweb.com>
100% Public Domain
*/
#include "stdint.h"
typedef struct
{
uint32_t state[5];
uint32_t count[2];
unsigned char buffer[64];
} SHA1_CTX;
void SHA1Transform(
uint32_t state[5],
const unsigned char buffer[64]
);
void SHA1Init(
SHA1_CTX * context
);
void SHA1Update(
SHA1_CTX * context,
const unsigned char *data,
uint32_t len
);
void SHA1Final(
unsigned char digest[20],
SHA1_CTX * context
);
void SHA1(
char *hash_out,
const char *str,
int len);
#endif /* SHA1_H */

View File

@ -1,7 +1,7 @@
/*
EnergyMech, IRC bot software
Parts Copyright (c) 1997-2004 proton
Parts Copyright (c) 1997-2018 proton
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -30,7 +30,7 @@
#ifdef DEBUG
LS const char SPY_DEFS[7][12] =
LS const char SPY_DEFS[][12] =
{
"SPY_FILE",
"SPY_CHANNEL",
@ -38,7 +38,10 @@ LS const char SPY_DEFS[7][12] =
"SPY_STATUS",
"SPY_MESSAGE",
"SPY_RAWIRC",
"SPY_BOTNET"
"SPY_BOTNET",
#ifdef URLCAPTURE
"SPY_URL",
#endif /* URLCAPTURE */
};
#endif /* DEBUG */
@ -161,22 +164,29 @@ void spy_typecount(Mech *bot)
struct
{
char *idstring;
const char *idstring;
int typenum;
} spy_source_list[] =
} spy_source_list[] =
{
{ SPYSTR_STATUS, SPY_STATUS },
{ SPYSTR_MESSAGE, SPY_MESSAGE },
{ SPYSTR_RAWIRC, SPY_RAWIRC },
{ SPYSTR_BOTNET, SPY_BOTNET },
#ifdef URLCAPTURE
{ SPYSTR_URL, SPY_URL },
#endif /* URLCAPTURE */
{ NULL, 0 },
};
int spy_source(char *from, int *t_src, char **src)
int spy_source(char *from, int *t_src, const char **src)
{
int i;
#ifdef DEBUG
debug("(spy_source) t_src %i, src %s\n",*t_src,*src);
#endif /* ifdef DEBUG */
for(i=0;spy_source_list[i].idstring;i++)
{
if (!Strcasecmp(*src,spy_source_list[i].idstring))
@ -198,6 +208,31 @@ int spy_source(char *from, int *t_src, char **src)
*
*/
/*---Help:SPY:[STATUS|MESSAGE|RAWIRC|URL|[guid:|botnick:] [channel|> filename]
Spy on a certain source of messages. When you join DCC chat,
the STATUS source is added by default as a spy source for you.
If no arguments are given, the current list of active spy
channels is shown. Output is not line buffered and can cause
excess flood if not careful.
(sources)
STATUS Status messages.
MESSAGE Pivate messages that the bot receives.
RAWIRC Lines received from irc server before processing.
URL URLs seen by the bot.
guid: Messages from a bot specified by guid.
botnick: Messages from a bot specified by nick.
channel Activities on the specified channel.
(destinations)
(none) Send output to you (default).
channel Send output to the specified channel.
>file Send output to file. Lines are appended to the end of the file.
This file needs to exist before logging to it.
See also: rspy
*/
void do_spy(COMMAND_ARGS)
{
/*
@ -205,10 +240,10 @@ void do_spy(COMMAND_ARGS)
*/
Spy *spy;
Mech *backup,*destbot;
char *src,*dest;
const char *src;
char *dest;
int t_src,t_dest;
int sz;
int guid;
int sz,r,guid;
if (!*rest)
{
@ -291,9 +326,9 @@ guid_ok:
else
{
sz = spy_source(from,&t_src,&src);
if (sz < 0)
if (sz < 0) // user has insufficient access to source
goto spy_usage;
if (sz < cmdaccess)
if (sz < cmdaccess) // user has less access relative to source than the command level of SPY
return;
}
@ -304,6 +339,7 @@ guid_ok:
*/
if (*dest == '>')
{
// accept both ">file" and "> file"
dest++;
if (!*dest)
{
@ -314,8 +350,16 @@ guid_ok:
/*
* Dont just open anything.
*/
if (!is_safepath(dest))
r = is_safepath(dest,FILE_MAY_EXIST);
if (r != FILE_IS_SAFE)
#ifdef DEBUG
{
debug("(do_spy) Filename \"%s\" was deemed unsafe (%i)\n",dest,r);
goto spy_usage;
}
#else
goto spy_usage;
#endif /* DEBUG */
t_dest = SPY_FILE;
goto spy_dest_ok;
}
@ -384,7 +428,7 @@ spy_dest_ok:
if (t_src == SPY_CHANNEL)
{
Strcpy(spy->src,src);
Strcpy((char*)spy->src,src);
}
else
{
@ -434,7 +478,8 @@ void do_rspy(COMMAND_ARGS)
* on_msg checks: CARGS
*/
Spy *spy,**pspy;
char *src,*dest,*tmp;
const char *src;
char *dest,*tmp;
int t_src,t_dest;
int n;
@ -468,10 +513,11 @@ rspy_usage:
goto rspy_usage;
}
/*
* Dont just open anything.
* this is about removing an existing spy channel
* filename does not need to be checked because
* - if its a bogus filename, it wont match any open spy channels
* - if its a matching filename, its going to be removed right now
*/
if (!is_safepath(dest))
goto rspy_usage;
t_dest = SPY_FILE;
goto rspy_dest_ok;
}

View File

@ -1,7 +1,7 @@
/*
EnergyMech, IRC bot software
Parts Copyright (c) 1997-2009 proton
Parts Copyright (c) 1997-2018 proton
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -82,7 +82,12 @@ typedef struct
typedef struct DEFstruct
{
int id;
union
{
int id;
void *func;
} v;
char *idstr;
} DEFstruct;
@ -168,7 +173,16 @@ typedef struct Setting
uchar type;
uchar uaccess; /* user access to touch/view this setting */
short min;
void *setto; /* type-casted to whatever */
union
{
int num;
int *numptr;
char chr;
char *str;
char **strptr;
} v;
//void *setto; /* type-casted to whatever */
char *name;
int max;
void (*func)(const struct Setting *);
@ -306,20 +320,8 @@ typedef struct ChanUser
int flags;
/* distance between &_num -> &_time is used in check_mass */
int floodnum;
time_t floodtime;
int bannum;
time_t bantime;
int deopnum;
time_t deoptime;
int kicknum;
time_t kicktime;
int nicknum;
time_t nicktime;
int capsnum;
time_t capstime;
uint8_t action_num[INDEX_MAX];
time_t action_time[INDEX_MAX];
time_t idletime;
#ifdef CHANBAN
@ -455,7 +457,7 @@ typedef struct Spy
Client *dcc;
int destbot;
char *src;
const char *src;
char *dest;
char p[2];
@ -500,6 +502,11 @@ typedef struct Mech
int server; /* ident of my current server */
int nextserver;
#ifdef BOTNET
const char *supres_cmd;
int supres_crc;
#endif
/*
* Line buffer for non-essential stuff
*/
@ -535,7 +542,6 @@ typedef struct Mech
#endif /* NOTIFY */
Spy *spylist;
int spy;
#ifdef NOTIFY
@ -565,7 +571,7 @@ typedef struct Mech
#ifdef IDWRAP
char *identfile;
#endif /* IDWRAP */
#endif /* IDWRAP */
/* big buffers at the end */
UniVar setting[SIZE_VARS]; /* global vars + channel defaults */
@ -645,7 +651,7 @@ typedef struct BotNet
/*
* do not touch the above vars!
* they are copied partially in net.c
* they are copied partially in that order in net.c
*/
int guid; /* remote bot guid */
@ -654,8 +660,9 @@ typedef struct BotNet
struct
{
ulong pta:1; /* plain text auth */
ulong md5:1; /* md5 */
ulong pta:1, /* plain text auth */
sha:1, /* SHA */
md5:1; /* MD5 */
} opt;
@ -778,7 +785,7 @@ typedef struct OnMsg
redir:1,
lbuf:1,
cbang:1,
acchan:1;
acchan:1; // -- 20 bits
char *cmdarg;
} OnMsg;
@ -795,7 +802,7 @@ typedef struct dnsAuthority
} dnsAuthority;
typedef struct dnsList
{
{
struct dnsList *next;
time_t when;
struct in_addr ip;

View File

@ -173,8 +173,7 @@ int tcl_parse_jump(char *from, char *rest, Hook *hook)
Tcl_GetIntFromObj(energymech_tcl,tcl_result,&i);
}
#ifdef DEBUG
if (energymech_tcl->result && *energymech_tcl->result)
debug("(tcl_parse_jump) result = %s\n",nullstr(energymech_tcl->result));
debug("(tcl_parse_jump) result = %i\n",i);
#endif /* DEBUG */
return(i);
}
@ -199,8 +198,7 @@ void tcl_dcc_complete(Client *client, int cps)
Tcl_ObjSetVar2(energymech_tcl,vname,NULL,obj,TCL_GLOBAL_ONLY);
Tcl_VarEval(energymech_tcl,hook->self," $_filetarget $_filename $_cps",NULL);
#ifdef DEBUG
if (energymech_tcl->result && *energymech_tcl->result)
debug("(tcl_dcc_complete) result = %s\n",nullstr(energymech_tcl->result));
debug("(tcl_dcc_complete) filetarget %s, filename %s\n",client->whom,client->filename);
#endif /* DEBUG */
}
}
@ -335,7 +333,7 @@ int tcl_debug(void *foo, Tcl_Interp *I, int objc, Tcl_Obj *CONST objv[])
return(TCL_ERROR);
debug("(tcl_debug) %s\n",text);
return(TCL_OK);
}
@ -476,8 +474,7 @@ int tcl_dns_jump(char *host, char *resolved, Hook *hook)
Tcl_GetIntFromObj(energymech_tcl,tcl_result,&i);
}
#ifdef DEBUG
if (energymech_tcl->result && *energymech_tcl->result)
debug("(tcl_dns_jump) result = %s\n",nullstr(energymech_tcl->result));
debug("(tcl_dns_jump) result = %i\n",i);
#endif /* DEBUG */
return(i);
}

View File

@ -1,7 +1,7 @@
/*
EnergyMech, IRC bot software
Copyright (c) 2000-2009 proton
Copyright (c) 2000-2018 proton
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -74,9 +74,8 @@
#define TEXT_SERVERDELETED "Server has been deleted: %s:%i"
#define TEXT_MANYSERVMATCH "Several entries for %s exists, please specify port also"
/* do_core() */
#define TEXT_CURRNICKWANT "Current nick\t%s (Wanted: %s)"
#define TEXT_CURRNICKHAS "Current nick\t%s"
#define TEXT_CURRGUID "Guid\t%i"
#define TEXT_CURRNICKWANT "Current nick\t%s (Wanted: %s) [#%i]"
#define TEXT_CURRNICKHAS "Current nick\t%s [#%i]"
#define TEXT_USERLISTSTATS "Users in userlist\t%i (%i Superuser%s, %i Bot%s)"
#define TEXT_ACTIVECHANS "Active channels\t%s"
#define TEXT_MOREACTIVECHANS "\t%s"
@ -87,6 +86,8 @@
#define TEXT_CURRSERVER "Current Server\t%s:%i"
#define TEXT_CURRSERVERNOT "Current Server\t" TEXT_NOTINSERVLIST
#define TEXT_TRYNEWSERVER "Trying new server, brb..."
#define TEXT_SWITCHSERVER "Switching servers..."
#define TEXT_SERVERONTIME "Server Ontime\t%s"
#define TEXT_BOTMODES "Mode\t+%s"
@ -129,10 +130,16 @@
#define TEXT_SIGUSR1 "QUIT :Switching servers... (SIGUSR1)\n"
#define TEXT_USAGE "Usage: %s [switches [args]]\n"
#define TEXT_FSWITCH " -f <file> read configuration from <file>\n"
#define TEXT_CSWITCH " -c make core file instead of coredebug/reset\n"
#define TEXT_HSWITCH " -h show this help\n"
#define TEXT_VSWITCH " -v show EnergyMech version\n"
#define TEXT_FSWITCH " -f <file> read configuration from <file>\n"
#define TEXT_CSWITCH " -c make core file instead of coredebug/reset\n"
#define TEXT_HSWITCH " -h show this help\n"
#define TEXT_VSWITCH " -v show EnergyMech version\n"
#define TEXT_PSWITCH1 " -p <string> encrypt <string> using the password hashing algorithm,\n"
#define TEXT_PSWITCH2 " output the result and then quit.\n"
#define TEXT_DSWITCH " -d start mech in debug mode\n"
#define TEXT_OSWITCH " -o <file> write debug output to <file>\n"
#define TEXT_XSWITCH " -X write a debug file before exit\n"
#define TEXT_HDR_VERS "EnergyMech %s, %s\n"
#define TEXT_HDR_DATE "Compiled on " __DATE__ " " __TIME__ "\n"

View File

@ -1,7 +1,7 @@
/*
EnergyMech, IRC bot software
Copyright (c) 1997-2004 proton
Copyright (c) 1997-2018 proton
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -101,7 +101,7 @@ void send_uptime(int type)
const char *server,*nick;
int sz;
if (uptimeport == 0)
if (uptimehost == NULL || uptimeport == 0)
return;
#ifdef RAWDNS

120
src/urlcap.c Normal file
View File

@ -0,0 +1,120 @@
/*
EnergyMech, IRC bot software
Copyright (c) 2018 proton
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
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.
*/
#define URLCAP_C
#include "config.h"
#ifdef URLCAPTURE
#include "defines.h"
#include "structs.h"
#include "global.h"
#include "h.h"
#include "text.h"
__page(CORE_SEG)
void urlcapture(const char *rest)
{
Strp *sp,*nx;
char *dest,url[MSGLEN];
int n;
dest = url;
while(*rest && *rest != ' ' && dest < url+MSGLEN-1)
*(dest++) = *(rest++);
*dest = 0;
#ifdef DEBUG
debug("(urlcapture) URL = \"%s\"\n",url);
#endif /* ifdef DEBUG */
send_spy(SPYSTR_URL,"%s",url);
if ((n = urlhistmax))
{
set_mallocdoer(urlcapture);
sp = (Strp*)Calloc(sizeof(Strp) + strlen(url));
Strcpy(sp->p,url);
sp->next = urlhistory;
urlhistory = sp;
for(sp=urlhistory;sp;sp=sp->next)
{
if (n <= 0)
{
do
{
nx = sp->next;
Free((char**)&sp);
sp = nx;
}
while(sp);
}
n--;
}
}
}
/*
*
* Commands associated with URLCAPTURE
*
*/
/*---Help:URLHIST:[max]
Display a list of URLs seen by the bot in order most recent to oldest.
[max] Maximum number of URLs to display.
*/
__page(CMD1_SEG)
void do_urlhist(COMMAND_ARGS)
{
Strp *sp;
char *thenum;
int n,maxnum;
if (urlhistory == NULL)
{
to_user(from,"No URLs recorded.");
return;
}
if (!rest || !*rest)
maxnum = urlhistmax;
else
{
thenum = chop(&rest);
maxnum = a2i(thenum);
}
if ((maxnum < 1) || (maxnum > urlhistmax))
usage(from); /* usage for CurrentCmd->name */
n = 1;
for(sp=urlhistory;sp;sp=sp->next)
{
if (n > maxnum)
break;
to_user(from,"[%i] %s",n,sp->p);
n++;
}
}
#endif /* ifdef URLCAPTURE */

View File

@ -1,7 +1,7 @@
/*
EnergyMech, IRC bot software
Parts Copyright (c) 1997-2009 proton
Parts Copyright (c) 1997-2018 proton
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -69,12 +69,12 @@ void cfg_pass(char *rest)
void cfg_mask(char *rest)
{
addtouser(&cfgUser->mask,rest);
addtouser(&cfgUser->mask,rest,TRUE);
}
void cfg_chan(char *rest)
{
addtouser(&cfgUser->chan,rest);
addtouser(&cfgUser->chan,rest,TRUE);
}
LS struct
@ -294,9 +294,24 @@ int read_userlist(char *filename)
User *olduserlist;
User *newuserlist;
int in;
#ifdef DEBUG
int r;
#endif
if (!filename)
return(FALSE);
if (*filename == '<') // read only userfile
filename++;
#ifdef DEBUG
if ((r = is_safepath(filename,FILE_MUST_EXIST)) != FILE_IS_SAFE)
{
debug("(write_userlist) %s: unsafe filename (%i)...\n",filename,r);
return(FALSE);
}
#else
if (is_safepath(filename,FILE_MUST_EXIST) != FILE_IS_SAFE)
return(FALSE);
#endif
if ((in = open(filename,O_RDONLY)) < 0)
return(FALSE);
@ -345,7 +360,7 @@ int write_userlist(char *filename)
char *p,flags[7];
int i,f;
#ifdef DEBUG
int dodeb;
int dodeb,r;
#endif /* DEBUG */
if (!filename)
@ -354,6 +369,27 @@ int write_userlist(char *filename)
if (!current->ul_save)
return(TRUE);
if (*filename == '<') // we dont write to read only userfiles
#ifdef DEBUG
{
debug("(write_userlist) %s: writing to read only userfile is prohibited...\n",filename);
return(FALSE);
}
#else
return(FALSE);
#endif
#ifdef DEBUG
if ((r = is_safepath(filename,FILE_MAY_EXIST)) != FILE_IS_SAFE)
{
debug("(write_userlist) %s: unsafe filename (%i)...\n",filename,r);
return(FALSE);
}
#else
if (is_safepath(filename,FILE_MAY_EXIST) != FILE_IS_SAFE)
return(FALSE);
#endif
if ((f = open(filename,O_WRONLY|O_CREAT|O_TRUNC,NEWFILEMODE)) < 0)
return(FALSE);
@ -447,8 +483,8 @@ void rehash_chanusers(void)
}
}
__attr(CORE_SEG, __regparm (2))
void addtouser(Strp **pp, const char *string)
__attr(CORE_SEG, __regparm (3))
void addtouser(Strp **pp, const char *string, int rehash)
{
Strp *um;
@ -463,7 +499,8 @@ void addtouser(Strp **pp, const char *string)
set_mallocdoer(addtouser);
*pp = um = (Strp*)Calloc(sizeof(Strp) + strlen(string));
Strcpy(um->p,string);
rehash_chanusers();
if (rehash)
rehash_chanusers();
}
__attr(CORE_SEG, __regparm (2))
@ -716,7 +753,7 @@ User *add_user(char *handle, char *pass, int axs)
#endif /* DEBUG */
set_mallocdoer(add_user);
user = (User*)Calloc(sizeof(User) + Strlen2(handle,pass));
user = (User*)Calloc(sizeof(User) + Strlen(handle,pass,NULL)); // Strlen() tolerates pass being NULL, Strlen2() does not.
user->x.x.access = axs;
user->next = current->userlist;
current->userlist = user;
@ -737,7 +774,7 @@ User *add_user(char *handle, char *pass, int axs)
/*
* find the user record for a named handle
*/
User *find_handle(char *handle)
User *find_handle(const char *handle)
{
User *user;
@ -802,7 +839,7 @@ User *get_user(const char *userhost, const char *channel)
/*
* highest channel on a given channel
*/
int get_useraccess(char *userhost, char *channel)
int get_useraccess(const char *userhost, const char *channel)
{
User *user;
@ -1133,6 +1170,7 @@ void do_user(COMMAND_ARGS)
Strp *ump;
char *handle,*pt,*mask,*nick,*chan,*anum,*pass,*encpass;
char mode;
char tmpmask[NUHLEN];
int change;
int newaccess,uaccess;
union usercombo combo;
@ -1209,27 +1247,31 @@ void do_user(COMMAND_ARGS)
/*
* convert and check nick/mask
*/
if ((mask = nick2uh(from,nick)) == NULL)
if ((mask = nick2uh(from,nick)) == NULL) // nick2uh uses nuh_buf
return;
Strcpy(tmpmask,mask);
#ifdef DEBUG
debug("(do_user) nick2uh(from \"%s\", nick \"%s\") = mask \"%s\"\n",from,nick,tmpmask);
#endif /* DEBUG */
#ifdef NEWBIE
if (!matches(mask,"!@"))
if (!matches(tmpmask,"!@"))
{
to_user(from,"Problem adding %s (global mask)",mask);
to_user(from,"Problem adding %s (global mask)",tmpmask);
return;
}
if (matches("*@?*.?*",mask))
if (matches("*@?*.?*",tmpmask))
{
to_user(from,"Problem adding %s (invalid mask)",mask);
to_user(from,"Problem adding %s (invalid mask)",tmpmask);
return;
}
#endif /* NEWBIE */
format_uh(mask,FUH_USERHOST);
format_uh(tmpmask,FUH_USERHOST); // format_uh uses local temporary buffer but copies result back into tmpmask
/*
* dont duplicate users
*/
if (get_useraccess(mask,chan))
if (get_useraccess(tmpmask,chan))
{
to_user(from,"%s (%s) on %s is already a user",nick,mask,chan);
to_user(from,"%s (%s) on %s is already a user",nick,tmpmask,chan);
return;
}
/*
@ -1246,9 +1288,12 @@ void do_user(COMMAND_ARGS)
* add_user() touches current->ul_save for us
*/
user = add_user(handle,encpass,newaccess);
addtouser(&user->mask,mask);
addtouser(&user->chan,chan);
to_user(from,"%s has been added as %s on %s",handle,mask,chan);
addtouser(&user->mask,tmpmask,FALSE); // does not run rehash_chanusers(), does not clobber nuh_buf
addtouser(&user->chan,chan,TRUE); // clobbers nuh_buf
#ifdef DEBUG
debug("(do_user) from %s, handle %s,\n\tmask %s, chan %s\n",from,handle,tmpmask,chan);
#endif /* DEBUG */
to_user(from,"%s has been added as %s on %s",handle,tmpmask,chan);
to_user(from,"Access level: %i%s%s",newaccess,(pass) ? " Password: " : "",(pass) ? pass : "");
#ifdef NEWUSER_SPAM
if ((newaccess != BOTLEVEL) && find_nuh(nick))
@ -1418,7 +1463,7 @@ usage:
return;
}
#endif /* NEWBIE */
addtouser(&user->chan,mask);
addtouser(&user->chan,mask,TRUE);
change++;
}
else
@ -1452,7 +1497,7 @@ usage:
return;
}
#endif /* NEWBIE */
addtouser(&user->mask,mask);
addtouser(&user->mask,mask,TRUE);
change++;
}
@ -1516,7 +1561,14 @@ void do_echo(COMMAND_ARGS)
void change_pass(User *user, char *pass)
{
User *new,**uptr;
char *enc;
enc = makepass(pass);
if (strlen(user->pass) <= strlen(enc))
{
Strcpy(user->pass,enc);
user->modcount++;
}
/*
* password is stuck in a solid malloc in a linked list
* add_user() touches current->ul_save for us

View File

@ -79,7 +79,7 @@ void copy_vars(UniVar *dst, UniVar *src)
{
dst[i].int_var = src[i].int_var;
}
}
}
}
void set_binarydefault(UniVar *dst)
@ -87,7 +87,7 @@ void set_binarydefault(UniVar *dst)
int i;
for(i=0;VarName[i].name;i++)
dst[i].str_var = VarName[i].setto;
dst[i].str_var = VarName[i].v.str;
}
void delete_vars(UniVar *vars, int which)
@ -133,6 +133,11 @@ void ec_access(char *from, char *to)
nobo_strcpy(num);
}
void ec_capabilities(char *from, char *to)
{
nobo_strcpy(__mx_opts);
}
void ec_cc(char *from, char *to)
{
nobo_strcpy((current->activechan) ? current->activechan->name : TEXT_NONE);
@ -272,16 +277,17 @@ LS const struct
} ecmd[] =
{
{ ec_access, "$access", 7 },
{ ec_cc, "$cc", 3 },
{ ec_channels, "$channels", 9 },
{ ec_time, "$time", 5 },
{ ec_set, "$var(", 5 },
{ ec_on, "$on", 3 },
{ ec_server, "$server", 7 },
{ ec_up, "$up", 3 },
{ ec_ver, "$ver", 4 },
{ NULL, "", 0 },
{ ec_access, "$access", 7 },
{ ec_capabilities, "$cap", 4 },
{ ec_cc, "$cc", 3 },
{ ec_channels, "$channels", 9 },
{ ec_time, "$time", 5 },
{ ec_set, "$var(", 5 },
{ ec_on, "$on", 3 },
{ ec_server, "$server", 7 },
{ ec_up, "$up", 3 },
{ ec_ver, "$ver", 4 },
{ NULL, "", 0 },
};
/*
@ -388,7 +394,7 @@ second_pass:
varval = (IsProc(i)) ? current->setting[i].proc_var : &univar[i];
sz = Strlen2(tmp,VarName[i].name);
sz = Strlen2(tmp,VarName[i].name); // VarName[i].name is never NULL
if (IsStr(i))
{