This commit is contained in:
2023-12-26 16:40:53 -05:00
commit ab64084f63
93 changed files with 40857 additions and 0 deletions

79
ADD-TO-IRCRC Normal file
View File

@@ -0,0 +1,79 @@
on ^367 * if ([$4] != []) {echo *** $1 \($3 - $stime($4)) $2} {echo *** $1-}
on ^333 * echo *** Topic for $1 set by $2 on $stime($3)
on ^317 * if (index(012345679 $3) != -1) {echo *** $1 has been idle for $2 seconds. Signon at $stime($3)} {echo *** $1 has been idle for $2 seconds.}
On ^329 "*" echo *** $1 : created $stime($2)
alias silence quote silence
alias sile quote silence
on ^raw_irc "% SILENCE %" echo *** $*
@ hideit = 0
on ^server_notice "% % NOTICE -- CLIENT*" if (hideit != 1) {echo *** $2-}
alias show @ hideit = 0;echo *** You can now see clients connecting/exiting
alias hide @ hideit = 1;echo *** You will no longer see clients connecting/exiting
# ctime and sendq written by bry
# modified by Mmmm
alias ctime {
^on 211 -
if ( [$0] )
{ ^assign SS $0- }
{ ^assign SS $S }
^on ^211 * {
eval ^assign hrs2 ${ ([$7]/60)/60}
eval ^assign min2 ${[$7]/60}
eval ^assign dys ${[$HRS2]/24}
eval ^assign hrs ${[$HRS2]-([$DYS]*24)}
eval ^assign min ${[$MIN2] - ( ([$HRS]+([$DYS]*24) )*60)}
eval ^assign sec ${[$7]-([$MIN2]*60)}
@ a = index(\[ $1) - 1
@ b = left($a $1)
if (index(. $b) == -1)
{eval echo *** $1 $[2]DYS days, $[2]HRS hrs, $[2]MIN min, $[2]SEC s}
{eval echo *** $1 $[2]DYS days, $[2]HRS hrs, $[2]MIN min, $[2]SEC s}
}
^stats l $SS
}
alias sendq {
eval ^on ^211 "$SRV *" {
@ a = index(\[ $1) - 1
@ b = left($a $1)
if (index(. $b) == -1)
{eval echo *** $[11]2 sendq $1}
{eval echo *** $[11]2 sendq $1}
}
if ( [$0] )
{ ^assign SRV $0- }
{ ^assign SRV $S }
stats l $SRV
wait -cmd eval ^on ^211 -"$SRV *"
}
# If you use Daveman's toolbox or any auto rejoin line, remove the old
# on raw_irc for KICK, and use the foll. one instead: (Run)
#
#ON ^RAW_IRC "% KICK % % *" {
# IF ([$3]==[$N])
# {
# //QUOTE JOIN $2
# ECHO $MID(11 5 $STIME($TIME())) * You have been kicked off channel $2 by $LEFT($INDEX(! $0) $0) \($MID(1 256 $4-)\)
# }
# {
# ECHO $MID(11 5 $STIME($TIME())) * $3 has been kicked off channel $2 by $LEFT($INDEX(! $0) $0) \($MID(1 256 $4-)\)
# }
# }
# Since 2.9.x :
alias UPING QUOTE UPING
alias RPING QUOTE RPING $0 : $time()
On ^RAW_IRC "% RPONG *" {
echo *** Pingtime $0 - $3 : $4 ms \(total delay: ${[$6]-[$time()]} s\)
}
alias MAP QUOTE MAP
On ^SERVER_NOTICE "% ??? NOTICE -- *" echo *N* $4-
On ^007 "*"

694
Config Executable file
View File

@@ -0,0 +1,694 @@
#!/bin/sh
#
# (C) 1993, 1994 By Darren Reed, avalon@coombs.anu.edu.au
# You may distribute this file without changes freely providing this notice
# remains intact. This file may not be redistributed or made available for
# distribution without the author's prior consent.
#
trap "" 13 14 15
MV=/bin/mv
RM=/bin/rm
SETUP=include/setup.h
#
STDLIBH=undef
STDDEFH=undef
SYSSYSLOGH=undef
MALLOCH=undef
PARAMH=undef
UNISTDH=undef
STRINGH=undef
STRINGSH=undef
NOINDEX=undef
NSTRERROR=undef
NSTRTOKEN=undef
NSTRTOK=undef
NINETADDR=undef
NINETNTOA=undef
NINETNETOF=undef
GETTIMEOFDAY=undef
LRAND48=undef
CCPATH=''
SIGNAL=''
BLOCKING=''
TMP=/tmp/.Configtmp$$.c
EXEC=/tmp/.Configtmp$$
PLATE=/tmp/.ConPlate$$
c=''
n=''
#
2>/dev/null
if [ "`eval echo -n 'a'`" = "-n a" ] ; then
c='\c'
else
n='-n'
fi
#if [ ! -f Makefile.bak ] ; then
# mv Makefile Makefile.bak
# cp Makefile.bak Makefile
# chmod ugo-xw Makefile Makefile.bak
# chmod u+w Makefile
#fi
echo " "
echo " Welcome to autoconfigure for the IRC server."
echo "Before running this script and expecting it to work, please fix the"
echo "Makefile in this directory (I can only do so much without your help!)"
echo "and I'll look into it for help and to checkup on your compiler"
echo "preferences, etc"
echo " "
echo "Enter \"none\" at any prompt to effect a null entry."
echo " "
FOO=`egrep "^CC=" Makefile 2>/dev/null | sed -e 's/^[^=]*[ ]*=\(.*\)/\1/'`
while [ -z "$CCPATH" ] ; do
MYP=`echo "$PATH" | sed -e 's/:/ /g'`
echo "Which compiler do you use, gcc or cc or...?"
echo $n "[$FOO] -> $c"
read cc
if [ -z "$cc" ] ; then
cc=$FOO
CCPATH=$FOO
elif [ -f $cc ] ; then
CCPATH=$cc
else
for i in $MYP; do
if [ -f $i/$cc -a -z "$CCPATH" ] ; then
CCPATH=$i/$cc
fi
done
fi
done
if [ "$FOO" != "$cc" ] ; then
MYP=`echo "$CCPATH" | sed -e 's@/@ @g'`
set $MYP
if [ $2 ] ; then
while [ $2 ] ; do
shift
done
fi
if [ $1 = "gcc" ] ; then
CCPATH="$CCPATH -traditional"
fi
fi
echo "Compiler selected: $CCPATH"
echo " "
# Check it out
cat > $TMP <<_EOF_
main() {}
_EOF_
$CCPATH $TMP -o $EXEC >/dev/null 2>&1
if [ ! -f $EXEC ] ; then
echo "You don't have $CCPATH or it's broken!"
exit 1
fi
# Fix Makefile
#
#$RM -f $TMP
#sed -e "s@^CC=\(.*\)@CC=$CCPATH@" Makefile > $TMP
#cp $TMP Makefile
#$RM -f $TMP
#
echo "Enter additional flags to give to $CCPATH"
FOO=`egrep "^CFLAGS=" Makefile 2>/dev/null | sed -e 's/^[^=]*=[ ]*\(.*\)/\1/'`
INC=`egrep "^INCLUDEDIR=" Makefile 2>/dev/null | sed -e 's/^[^=]*=\(.*\)/\1/'`
FOO=`echo "$FOO" | sed -e "s@\\$(INCLUDEDIR)@$INC@"`
echo $n "[$FOO] -> $c"
read cc
if [ "$cc" = "none" ] ; then
cc=''
elif [ -z "$cc" ] ; then
cc=$FOO
fi
CFLAGS=$cc
# Fix Makefile
#
#$RM -f $TMP
#sed -e "s@^CFLAGS=\(.*\)@CFLAGS=$CFLAGS@" Makefile > $TMP
#cp $TMP Makefile
#$RM -f $TMP
#
echo " "
echo "If you need to use any extra libraries when compiling the server,"
echo "please tell me now (might need to look at the Makefiles) and please"
echo "include all the -l and -L flags (I'm lame)."
LIBS=`egrep "^IRCDLIBS=" Makefile 2>/dev/null | sed -e 's/^[^=]*=\(.*\)/\1/' | tr -d "\012"`
echo $n "[$LIBS] -> $c"
read cc;
if [ "$cc" = "none" ] ; then
cc=''
elif [ -z "$cc" ] ; then
cc=$LIBS
fi
LIBS=$cc
# Fix Makefile
#
#$RM -f $TMP
#sed -e "s@^IRCDLIBS=\(.*\)@IRCDLIBS=$LIBS@" Makefile > $TMP
#cp $TMP Makefile
#$RM -f $TMP
#
COMP="$CCPATH $CFLAGS $TMP -o $EXEC $LIBS"
#
#
echo 'Checking out /usr/include'
echo $n "...Looking for /usr/include/stdlib.h...$c"
if [ -r /usr/include/stdlib.h ] ; then
STDLIBH=define
echo 'found!'
else
echo 'not found :('
fi
# gcc has its own stddef.h
FOO=''
if [ ! -z "`echo $CCPATH | grep gcc`" ] ; then
FOO=`$CCPATH -v 2>&1 | head -1 | \
sed -e 's/Reading specs from //' -e 's/specs$/include/'`
fi
echo $n "...Looking for stddef.h...$c"
if [ -r $FOO/stddef.h ] ; then
STDDEFH=define
echo "found in $FOO!"
elif [ -r /usr/include/stddef.h ] ; then
STDDEFH=define
echo 'found!'
else
echo 'not found :('
fi
echo $n "...Looking for /usr/include/sys/syslog.h...$c"
if [ -r /usr/include/sys/syslog.h ] ; then
SYSSYSLOGH=define
echo 'found!'
else
echo 'not found :('
fi
echo $n "...Looking for malloc.h...$c"
if [ -r /usr/include/malloc.h ] ; then
MALLOCH=malloc.h
echo 'found!'
elif [ -r /usr/include/sys/malloc.h ] ; then
MALLOCH=sys/malloc.h
echo 'found!'
else
echo 'not found :('
MALLOCH=undef
fi
echo $n "...Looking for /usr/include/sys/param.h...$c"
if [ -r /usr/include/sys/param.h ] ; then
PARAMH=define
echo 'found!'
else
echo 'not found :('
fi
echo $n "...Looking for /usr/include/unistd.h...$c"
if [ -r /usr/include/unistd.h ] ; then
UNISTDH=define
echo 'found!'
else
echo 'not found :('
fi
echo $n "...Looking for /usr/include/string.h...$c"
if [ -r /usr/include/string.h ] ; then
STRINGH=define
echo 'found!'
else
echo 'not found :('
fi
echo $n "...Looking for /usr/include/strings.h...$c"
if [ -r /usr/include/strings.h ] ; then
STRINGSH=define
echo 'found!'
else
echo 'not found :('
fi
#
# to b or not to b
#
echo " "
echo $n "To be or not to be...$c"
cat > $TMP <<_EOF_
main()
{
char a[3], b[3];
bzero(b,3);
bcopy(a,b,3);
(void)bcmp(a,b,3);
exit(0);
}
_EOF_
$COMP >/dev/null 2>&1
if [ $? -eq 0 ] ; then
echo "and so it shall be! bcopy/bzero/bcmp are about!"
BZERO=bzero
else
echo "and it wasn't. No bcopy/bzero/bcmp...hmpf"
BZERO=memset
fi
echo " "
echo $n "Which one, gettimeofday, or lrand48..$c"
cat > $TMP <<_EOF_
#include <stdio.h>
#include <sys/time.h>
main()
{
struct timeval tv;
(void) gettimeofday(&tv, NULL);
}
_EOF_
$COMP >/dev/null 2>&1
if [ $? -eq 0 ] ; then
echo "We have a winner! gettimeofday found."
GETTIMEOFDAY=define
else
echo "No gettimeofday. Lets try lrand48."
cat > $TMP <<_EOF_
main()
{
int a;
a=lrand48();
}
_EOF_
$COMP >/dev/null 2>&1
if [ $? -eq 0 ] ; then
echo "Bingo! lrand48!"
LRAND48=define
fi
fi
#
# check for non-blocking fd style available..
#
echo " "
echo 'Checking for POSIX/BSD/SYSV non-blocking stuff'
if [ -f $TMP -o -d $TMP ] ; then
$RM -f $TMP
fi
cat > $PLATE <<_EOF_
#include <sys/types.h>
#include <sys/socket.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <sys/file.h>
#include <signal.h>
alarmed()
{
exit(1);
}
main()
{
char b[12], x[32];
int f, l = sizeof(x);
f = socket(AF_INET, SOCK_DGRAM, 0);
if (f >= 0 && !(fcntl(f, F_SETFL, BLOCKING))) {
signal(SIGALRM, alarmed);
alarm(3);
recvfrom(f, b, 12, 0, x, &l);
alarm(0);
exit(0);
}
exit(1);
}
_EOF_
sed -e 's/BLOCKING/O_NONBLOCK/' $PLATE > $TMP
$COMP >/dev/null 2>&1
if [ 0 -eq $? ] ; then
$EXEC
fi
if [ 0 -eq $? ] ; then
BLOCK=O_NONBLOCK
else
echo 'O_NONBLOCK not present/working in fcntl.h or sys/ioctl.h'
if [ -f $TMP -o -d $TMP ] ; then
$RM -f $TMP $EXEC;
fi
sed -e 's/BLOCKING/O_NDELAY/' $PLATE > $TMP
$COMP >/dev/null 2>&1
if [ 0 -eq $? ] ; then
$EXEC
fi
if [ 0 -eq $? ] ; then
BLOCK=O_NDELAY
else
echo 'O_NDELAY not present/working in fcntl.h or sys/ioctl.h'
if [ -f $TMP -o -d $TMP ] ; then
$RM -f $TMP $EXEC;
fi
sed -e 's/BLOCKING/FIONBIO/' $PLATE > $TMP
$COMP >/dev/null 2>&1
if [ 0 -eq $? ] ; then
echo 'FIONBIO not found! No option found!'
BLOCK=none
else
BLOCK=FIONBIO
fi
fi
fi
$RM -f $TMP $PLATE $EXEC
echo "Blocking selected: $BLOCK";
#
# reliable signals ?
#
echo 'Looking for reliable signals...'
echo "Hmmm...wonder if you have 'action from POSIX..."
cat > $TMP <<_EOF_
#include <signal.h>
main()
{ /* poor replacement for NULL but who cares here ? */
sigaction(SIGTERM, (struct sigaction *)0L, (struct sigaction *)0L);
}
_EOF_
$COMP >/dev/null 2>&1
if [ $? -eq 0 ] ; then
echo "Ooooh, you are a lucky one! 'action from POSIX!"
SIGNAL=posix
else
$RM -f $EXEC $TMP
cat > $TMP <<_EOF_
#include <signal.h>
int calls = 0;
void handler()
{
if (calls)
return;
calls++;
kill(getpid(), SIGTERM);
sleep(1);
}
main()
{
signal(SIGTERM, handler);
kill(getpid(), SIGTERM);
exit (0);
}
_EOF_
echo $n "Nope, but you have...$c"
$COMP >/dev/null 2>&1
$EXEC
if [ $? -eq 0 ] ; then
echo 'reliable signals! Cheers BSD!'
SIGNAL=bsd
else
echo "yucky, unreliable SYSV!"
SIGNAL=sysv
fi
fi
$RM -f $EXEC $TMP
#
echo 'Now those strings libraries...hmm...which one is it...'
cat > $TMP <<_EOF_
#$STRINGH STRINGH
#$STRINGSH STRINGSH
#ifdef STRINGH
#include <string.h>
#endif
#ifdef STRINGSH
#include <strings.h>
#endif
main()
{
char *s = index("foo", 'o');
exit(0);
}
_EOF_
$COMP >/dev/null 2>&1
if [ $? -eq 0 ] ; then
echo "Cool...you have index()!"
else
NOINDEX=define
echo "Grmpf...I guess there is a strchr() out there somewhere..."
fi
$RM -f $EXEC $TMP
#
# getrusage or times ?
#
echo $n "One for debugging, mainly, getrusage(2) or times(2)...$c"
cat > $TMP <<_EOF_
#include <sys/types.h>
#include <sys/time.h>
#include <sys/resource.h>
main()
{
struct rusage rus;
(void)getrusage(RUSAGE_SELF, &rus);
}
_EOF_
$COMP >/dev/null 2>&1
if [ $? -eq 0 ] ; then
TIMES=getrusage
echo "getrusage()"
else
$RM -f $EXEC $TMP
cat > $TMP <<_EOF_
#include <sys/types.h>
#include <sys/time.h>
#include <sys/times.h>
main()
{
struct tms tmsbuf;
(void)times(&tmsbuf);
}
_EOF_
$COMP >/dev/null 2>&1
if [ $? -eq 0 ] ; then
TIMES=times
echo "times()"
else
echo "couldn't get either ?!"
TIMES=none
fi
fi
#
# what do we need that isn't here already ?
#
echo "What else do I need that you don't have..."
echo $n "Lets see...$c"
cat > $TMP <<_EOF_
main()
{
char *s = strerror(0);
exit(0);
}
_EOF_
$COMP >/dev/null 2>&1
if [ $? -ne 0 ] ; then
echo $n " strerror$c"
NSTRERROR=define
fi
$RM -f $EXEC $TMP
cat > $TMP <<_EOF_
#$STRINGH STRINGH
#$STRINGSH STRINGSH
#ifdef STRINGH
#include <string.h>
#endif
#ifdef STRINGSH
#include <strings.h>
#endif
main()
{
char *t = "a", **p = NULL, *s = strtoken(&p, t, ",");
if (!strcmp(t, s))
exit(0);
exit(1);
}
_EOF_
$COMP >/dev/null 2>&1
if [ $? -ne 0 ] ; then
echo $n " strtoken$c"
NSTRTOKEN=define
else
$EXEC
if [ $? -ne 0 ] ; then
echo $n " strtoken$c"
NSTRTOKEN=define
fi
fi
$RM -f $EXEC $TMP
cat > $TMP <<_EOF_
#$STRINGH STRINGH
#$STRINGSH STRINGSH
#ifdef STRINGH
#include <string.h>
#endif
#ifdef STRINGSH
#include <strings.h>
#endif
main()
{
char *t = "a", *s = strtok(t, ",");
if (!strcmp(t, s))
exit(0);
exit(1);
}
_EOF_
$COMP >/dev/null 2>&1
if [ $? -ne 0 ] ; then
echo $n " strtok$c"
NSTRTOK=define
else
$EXEC
if [ $? -ne 0 ] ; then
echo $n " strtok$c"
NSTRTOK=define
fi
fi
$RM -f $EXEC $TMP
cat > $TMP << _EOF_
#include <sys/types.h>
#include <netinet/in.h>
main()
{
struct in_addr in;
(void)inet_addr("1.2.3.4");
}
_EOF_
$COMP >/dev/null 2>&1
if [ $? -ne 0 ] ; then
echo $n " inet_addr$c"
NINETADDR=define
fi
$RM -f $EXEC $TMP
cat > $TMP << _EOF_
#include <sys/types.h>
#include <netinet/in.h>
main()
{
struct in_addr in;
in.s_addr = 0x12345678;
(void)inet_ntoa(in);
}
_EOF_
$COMP >/dev/null 2>&1
if [ $? -ne 0 ] ; then
echo $n " inet_ntoa$c"
fi
$RM -f $EXEC $TMP
cat > $TMP << _EOF_
#include <sys/types.h>
#include <netinet/in.h>
main()
{
struct in_addr in;
in.s_addr = 0x87654321;
(void)inet_netof(in);
}
_EOF_
$COMP >/dev/null 2>&1
if [ $? -ne 0 ] ; then
echo $n " inet_netof$c"
NINETNETOF=define
fi
$RM -f $EXEC $TMP
echo " "
#
#
#
echo " "
echo "Ok, here's your chance...I think you should use $BLOCK, you want"
echo "which of these ? O_NONBLOCK (POSIX) O_NDELAY (BSD) FIONBIO (SYSV)"
echo $n "[$BLOCK] -> $c"
read cc
if [ "$cc" = "none" ] ; then
cc=''
elif [ -z "$cc" ] ; then
cc=$BLOCK
fi
BLOCK=$cc
echo "I found $SIGNAL signals."
if [ "$cc" = "none" ] ; then
cc=''
elif [ "$SIGNAL" = "posix" ] ; then
echo "Hmmm...I'm not sure if signal() is reliable or not either..."
fi
echo "You can choose between posix, bsd and sysv. What'll it be ?"
echo $n "[$SIGNAL] -> $c"
read cc
if [ "$cc" = "none" ] ; then
cc=''
elif [ -z "$cc" ] ; then
cc=$SIGNAL
fi
SIGNAL=$cc
if [ "$TIMES" = "none" ] ; then
echo "I didn't find either getrusage or times earlier...If you do have"
echo "either of these, please tell me now."
else
echo "I found $TIMES, out of getrusage and times. getrusage is"
echo "more informative. If you wish to swap your choice, please"
echo "do so now."
fi
echo $n "[$TIMES] -> $c"
read cc
if [ "$cc" = "none" ] ; then
cc=''
elif [ -z "$cc" ] ; then
cc=$TIMES
fi
TIMES=$cc
$RM -f $EXEC $TMP $PLATE
$MV -f $SETUP $SETUP.bak 2>/dev/null
cat > $SETUP <<_EOF_
#ifndef __setup_include__
#define __setup_include__
#$PARAMH PARAMH
#$UNISTDH UNISTDH
#$STRINGH STRINGH
#$STRINGSH STRINGSH
#$STDLIBH STDLIBH
#$STDDEFH STDDEFH
#$SYSSYSLOGH SYSSYSLOGH
#$NOINDEX NOINDEX
#$NSTRERROR NEED_STRERROR
#$NSTRTOKEN NEED_STRTOKEN
#$NSTRTOK NEED_STRTOK
#$NINETADDR NEED_INET_ADDR
#$NINETNTOA NEED_INET_NTOA
#$NINETNETOF NEED_INET_NETOF
#$GETTIMEOFDAY GETTIMEOFDAY
#$LRAND48 LRAND48
_EOF_
if [ "$MALLOCH" = "undef" ] ; then
echo "#undef MALLOCH" >> $SETUP
else
echo "#define MALLOCH <$MALLOCH>" >> $SETUP
fi
if [ "$BZERO" = "memset" ] ; then
cat >> $SETUP <<_EOF_
#define bzero(a,b) memset(a,0,b)
#define bcopy(a,b,c) memcpy(b,a,c)
#define bcmp memcmp
_EOF_
fi
if [ "$BLOCK" = "O_NONBLOCK" ] ; then
echo "#define NBLOCK_POSIX" >> $SETUP
elif [ "$BLOCK" = "O_NDELAY" ] ; then
echo "#define NBLOCK_BSD" >> $SETUP
else
echo "#define NBLOCK_SYSV" >> $SETUP
fi
if [ "$SIGNAL" = "posix" ] ; then
echo "#define POSIX_SIGNALS" >> $SETUP
elif [ "$SIGNAL" = "bsd" ] ; then
echo "#define BSD_RELIABLE_SIGNALS" >> $SETUP
else
echo "#define SYSV_UNRELIABLE_SIGNALS" >> $SETUP
fi
if [ "$TIMES" = "times" ] ; then
echo "#define TIMES_2" >> $SETUP
echo "#undef GETRUSAGE_2" >> $SETUP
elif [ "$TIMES" = "getrusage" ] ; then
echo "#undef TIMES_2" >> $SETUP
echo "#define GETRUSAGE_2" >> $SETUP
else
echo "#undef TIMES_2" >> $SETUP
echo "#undef GETRUSAGE_2" >> $SETUP
fi
echo "#endif" >> $SETUP
touch include/config.h
echo " "
echo "If you would like to issue any shell commands before proceeding, do so"
echo "now. My findings are in include/setup.h if you wish to change them."
echo $n "--> $c"
read cc
if [ ! -z "$cc" ] ; then
$cc
fi
exit 0

249
LICENCE Normal file
View File

@@ -0,0 +1,249 @@
GNU GENERAL PUBLIC LICENSE
Version 1, February 1989
Copyright (C) 1989 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 license agreements of most software companies try to keep users
at the mercy of those companies. By contrast, our 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. The
General Public License applies to the Free Software Foundation's
software and to any other program whose authors commit to using it.
You can use it for your programs, too.
When we speak of free software, we are referring to freedom, not
price. Specifically, the General Public License is designed to make
sure that you have the freedom to give away or sell copies of free
software, 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 a 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 tell them 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.
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 Agreement 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 work containing the
Program or a portion of it, either verbatim or with modifications. Each
licensee is addressed as "you".
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
General Public License and to the absence of any warranty; and give any
other recipients of the Program a copy of this General Public License
along with the Program. You may charge a fee for the physical act of
transferring a copy.
2. You may modify your copy or copies of the Program or any portion of
it, and copy and distribute such modifications under the terms of Paragraph
1 above, provided that you also do the following:
a) cause the modified files to carry prominent notices stating that
you changed the files and the date of any change; and
b) cause the whole of any work that you distribute or publish, that
in whole or in part contains the Program or any part thereof, either
with or without modifications, to be licensed at no charge to all
third parties under the terms of this General Public License (except
that you may choose to grant warranty protection to some or all
third parties, at your option).
c) If the modified program normally reads commands interactively when
run, you must cause it, when started running for such interactive use
in the simplest and most usual 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 General
Public License.
d) 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.
Mere aggregation of another independent work with the Program (or its
derivative) on a volume of a storage or distribution medium does not bring
the other work under the scope of these terms.
3. You may copy and distribute the Program (or a portion or derivative of
it, under Paragraph 2) in object code or executable form under the terms of
Paragraphs 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
Paragraphs 1 and 2 above; or,
b) accompany it with a written offer, valid for at least three
years, to give any third party free (except for a nominal charge
for the cost of distribution) a complete machine-readable copy of the
corresponding source code, to be distributed under the terms of
Paragraphs 1 and 2 above; or,
c) accompany it with the information you received as to where the
corresponding source code may be obtained. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form alone.)
Source code for a work means the preferred form of the work for making
modifications to it. For an executable file, complete source code means
all the source code for all modules it contains; but, as a special
exception, it need not include source code for modules which are standard
libraries that accompany the operating system on which the executable
file runs, or for standard header files or definitions files that
accompany that operating system.
4. You may not copy, modify, sublicense, distribute or transfer the
Program except as expressly provided under this General Public License.
Any attempt otherwise to copy, modify, sublicense, distribute or transfer
the Program is void, and will automatically terminate your rights to use
the Program under this License. However, parties who have received
copies, or rights to use copies, from you under this General Public
License will not have their licenses terminated so long as such parties
remain in full compliance.
5. By copying, distributing or modifying 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.
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.
7. 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 the 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
the license, you may choose any version ever published by the Free Software
Foundation.
8. 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
9. 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.
10. 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 humanity, 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 1, 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) 19xx 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 a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the
program `Gnomovision' (a program to direct compilers to make passes
at assemblers) written by James Hacker.
<signature of Ty Coon>, 1 April 1989
Ty Coon, President of Vice
That's all there is to it!

139
Makefile Normal file
View File

@@ -0,0 +1,139 @@
#************************************************************************
#* IRC - Internet Relay Chat, Makefile
#* Copyright (C) 1990, Jarkko Oikarinen
#*
#* 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 1, 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.
#*/
CC=cc
RM=/bin/rm
INCLUDEDIR=../include
# Default flags:
CFLAGS= -g -I$(INCLUDEDIR) -O
#IRCDLIBS=
#
# use the following on MIPS:
#CFLAGS= -systype bsd43 -DSYSTYPE_BSD43 -I$(INCLUDEDIR)
# For Irix 4.x (SGI), use the following:
#CFLAGS= -g -cckr -I$(INCLUDEDIR)
#
# on NEXT use:
#CFLAGS=-bsd -I$(INCLUDEDIR)
#on NeXT other than 2.0:
#IRCDLIBS=-lsys_s
#
# AIX 370 flags
#CFLAGS=-D_BSD -Hxa -I$(INCLUDEDIR)
#IRCDLIBS=-lbsd
#
# Dynix/ptx V2.0.x
#CFLAGS= -I$(INCLUDEDIR) -O -Xo
#IRCDLIBS= -lsocket -linet -lnsl -lseq
#
# Dynix/ptx V1.x.x
#IRCDLIBS= -lsocket -linet -lnsl -lseq
#
#use the following on SUN OS without nameserver libraries inside libc
#IRCDLIBS=-lresolv
#
# Solaris 2
#IRCDLIBS=-lsocket -lnsl
#
# ESIX
#CFLAGS=-O -I$(INCLUDEDIR) -I/usr/ucbinclude
#IRCDLIBS=-L/usr/ucblib -L/usr/lib -lsocket -lucb -lns -lnsl
#
# LDFLAGS - flags to send the loader (ld). SunOS users may want to add
# -Bstatic here.
#
#LDFLAGS=-Bstatic
#
#Dell SVR4
#CC=gcc
#CFLAGS= -I$(INCLUDEDIR) -O2
#IRCDLIBS=-lsocket -lnsl -lucb
# IRCDMODE is the mode you want the binary to be.
# The 4 at the front is important (allows for setuidness)
#
# WARNING: if you are making ircd SUID or SGID, check config.h to make sure
# you are not defining CMDLINE_CONFIG
IRCDMODE = 4711
# IRCDDIR must be the same as DPATH in include/config.h
#
IRCDDIR=/usr/local/lib/ircd
SHELL=/bin/sh
SUBDIRS=common ircd
BINDIR=$(IRCDDIR)
MANDIR=/usr/local/man
INSTALL=/usr/bin/install
MAKE=make 'CFLAGS=${CFLAGS}' 'CC=${CC}' 'IRCDLIBS=${IRCDLIBS}' \
'LDFLAGS=${LDFLAGS}' 'IRCDMODE=${IRCDMODE}' 'BINDIR=${BINDIR}' \
'INSTALL=${INSTALL}' 'INCLUDEDIR=${INCLUDEDIR}' \
'IRCDDIR=${IRCDDIR}' 'MANDIR=${MANDIR}'
all: build
server:
@echo 'Making server'; cd ircd; ${MAKE} build; cd ..;
build:
-@if [ ! -f include/setup.h ] ; then \
echo "Hmm...doesn't look like you've run Config..."; \
echo "Doing so now."; \
sh Config; \
fi
@for i in $(SUBDIRS); do \
echo "Building $$i";\
cd $$i;\
${MAKE} build; cd ..;\
done
clean:
$(RM) -f *~ \#* core *.orig include/*.orig
@for i in $(SUBDIRS); do \
echo "Cleaning $$i";\
cd $$i;\
${MAKE} clean; cd ..;\
done
-@if [ -f include/setup.h ] ; then \
echo "To really restart installation, remove include/setup.h" ; \
fi
depend:
@for i in $(SUBDIRS); do \
echo "Making dependencies in $$i";\
cd $$i;\
${MAKE} depend; cd ..;\
done
install: all
chmod +x ./bsdinstall
@for i in ircd doc; do \
echo "Installing $$i";\
cd $$i;\
${MAKE} install; cd ..;\
done
rcs:
cii -H -R Makefile common include ircd

139
Makefile.dist Normal file
View File

@@ -0,0 +1,139 @@
#************************************************************************
#* IRC - Internet Relay Chat, Makefile
#* Copyright (C) 1990, Jarkko Oikarinen
#*
#* 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 1, 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.
#*/
CC=cc
RM=/bin/rm
INCLUDEDIR=../include
# Default flags:
CFLAGS= -g -I$(INCLUDEDIR) -O
#IRCDLIBS=
#
# use the following on MIPS:
#CFLAGS= -systype bsd43 -DSYSTYPE_BSD43 -I$(INCLUDEDIR)
# For Irix 4.x (SGI), use the following:
#CFLAGS= -g -cckr -I$(INCLUDEDIR)
#
# on NEXT use:
#CFLAGS=-bsd -I$(INCLUDEDIR)
#on NeXT other than 2.0:
#IRCDLIBS=-lsys_s
#
# AIX 370 flags
#CFLAGS=-D_BSD -Hxa -I$(INCLUDEDIR)
#IRCDLIBS=-lbsd
#
# Dynix/ptx V2.0.x
#CFLAGS= -I$(INCLUDEDIR) -O -Xo
#IRCDLIBS= -lsocket -linet -lnsl -lseq
#
# Dynix/ptx V1.x.x
#IRCDLIBS= -lsocket -linet -lnsl -lseq
#
#use the following on SUN OS without nameserver libraries inside libc
#IRCDLIBS=-lresolv
#
# Solaris 2
#IRCDLIBS=-lsocket -lnsl
#
# ESIX
#CFLAGS=-O -I$(INCLUDEDIR) -I/usr/ucbinclude
#IRCDLIBS=-L/usr/ucblib -L/usr/lib -lsocket -lucb -lns -lnsl
#
# LDFLAGS - flags to send the loader (ld). SunOS users may want to add
# -Bstatic here.
#
#LDFLAGS=-Bstatic
#
#Dell SVR4
#CC=gcc
#CFLAGS= -I$(INCLUDEDIR) -O2
#IRCDLIBS=-lsocket -lnsl -lucb
# IRCDMODE is the mode you want the binary to be.
# The 4 at the front is important (allows for setuidness)
#
# WARNING: if you are making ircd SUID or SGID, check config.h to make sure
# you are not defining CMDLINE_CONFIG
IRCDMODE = 4711
# IRCDDIR must be the same as DPATH in include/config.h
#
IRCDDIR=/usr/local/lib/ircd
SHELL=/bin/sh
SUBDIRS=common ircd
BINDIR=$(IRCDDIR)
MANDIR=/usr/local/man
INSTALL=/usr/bin/install
MAKE=make 'CFLAGS=${CFLAGS}' 'CC=${CC}' 'IRCDLIBS=${IRCDLIBS}' \
'LDFLAGS=${LDFLAGS}' 'IRCDMODE=${IRCDMODE}' 'BINDIR=${BINDIR}' \
'INSTALL=${INSTALL}' 'INCLUDEDIR=${INCLUDEDIR}' \
'IRCDDIR=${IRCDDIR}' 'MANDIR=${MANDIR}'
all: build
server:
@echo 'Making server'; cd ircd; ${MAKE} build; cd ..;
build:
-@if [ ! -f include/setup.h ] ; then \
echo "Hmm...doesn't look like you've run Config..."; \
echo "Doing so now."; \
sh Config; \
fi
@for i in $(SUBDIRS); do \
echo "Building $$i";\
cd $$i;\
${MAKE} build; cd ..;\
done
clean:
$(RM) -f *~ \#* core *.orig include/*.orig
@for i in $(SUBDIRS); do \
echo "Cleaning $$i";\
cd $$i;\
${MAKE} clean; cd ..;\
done
-@if [ -f include/setup.h ] ; then \
echo "To really restart installation, remove include/setup.h" ; \
fi
depend:
@for i in $(SUBDIRS); do \
echo "Making dependencies in $$i";\
cd $$i;\
${MAKE} depend; cd ..;\
done
install: all
chmod +x ./bsdinstall
@for i in ircd doc; do \
echo "Installing $$i";\
cd $$i;\
${MAKE} install; cd ..;\
done
rcs:
cii -H -R Makefile common include ircd

4
NOTICE Normal file
View File

@@ -0,0 +1,4 @@
This software package includes source code supplied by the University of
California of Berkeley.

14
READTHIS.NOW Normal file
View File

@@ -0,0 +1,14 @@
Hiya!
Please remember:
* Do *not* run this version on the Efnet or any other net other than the
Undernet - it is *incompatible*. Please HEED this warning!
* All the information you need on the patches is in the file README.patches
* Remember to add the lines suggested in your .ircrc to obtain the full benefit
of your server patches. Distribute the lines to your users too! Check the
file ADD-TO-IRCRC for the new additions.
Mmmm

83
bsdinstall Executable file
View File

@@ -0,0 +1,83 @@
#! /bin/sh
#
# @(#)install.sh 4.5 (Berkeley) 10/12/83
#
cmd=/bin/mv
strip=""
chmod="/bin/chmod 755"
chown="chown -f root"
chgrp="/bin/chgrp -f bin"
while true ; do
case $1 in
-s ) strip="strip"
shift
;;
-c ) cmd="/bin/cp"
shift
;;
-m ) chmod="/bin/chmod $2"
shift
shift
;;
-o ) chown="/etc/chown -f $2"
shift
shift
;;
-g ) chgrp="/bin/chgrp -f $2"
shift
shift
;;
-d ) cmd="/bin/mkdir"
shift
;;
* ) break
;;
esac
done
if [ ! ${2-""} ]
then echo "install: no destination specified"
exit 1
fi
if [ ${3-""} ]
then echo "install: too many files specified -> $*"
exit 1
fi
if [ $1 = $2 -o $2 = . ]
then echo "install: can't move $1 onto itself"
exit 1
fi
case $cmd in
/bin/mkdir )
file=$2/$1
;;
* )
if [ '!' -f $1 ]
then echo "install: can't open $1"
exit 1
fi
if [ -d $2 ]
then file=$2/$1
else file=$2
fi
/bin/rm -f $file
;;
esac
case $cmd in
/bin/mkdir )
if [ ! -d "$file" ]
then $cmd $file
fi
;;
* )
$cmd $1 $file
if [ $strip ]
then $strip $file
fi
;;
esac
$chown $file
$chgrp $file
$chmod $file

63
common/Makefile Normal file
View File

@@ -0,0 +1,63 @@
#************************************************************************
#* IRC - Internet Relay Chat, common/Makefile
#* Copyright (C) 1990 Jarkko Oikarinen
#*
#* 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 1, 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.
#*/
CC=cc
RM=/bin/rm
INCLUDE=../include
# For MIPS, use:
# CFLAGS=-O -systype bsd43 -I${INCLUDE}
# and otherwise:
CFLAGS=-O -I${INCLUDE}
OBJS=bsd.o dbuf.o packet.o send.o match.o parse.o support.o
SRC=bsd.c dbuf.c packet.c parse.c send.c match.c support.c
tm: tm.o match.o tab.o
$(CC) -g tab.o tm.o match.o -o tm
all: build
build: $(OBJS)
install:
clean:
$(RM) -f *.o *~ core \#* *.bak *.orig
depend:
makedepend -I${INCLUDE} ${SRC}
# DO NOT DELETE THIS LINE -- make depend depends on it.
bsd.o: bsd.c ../include/common.h ../include/sys.h ../include/config.h
dbuf.o: ../include/config.h ../include/common.h ../include/dbuf.h
dbuf.o: ../include/sys.h dbuf.c
packet.o: ../include/struct.h ../include/config.h ../include/class.h
packet.o: ../include/dbuf.h ../include/common.h ../include/msg.h packet.c
parse.o: ../include/struct.h ../include/config.h
parse.o: ../include/class.h ../include/dbuf.h ../include/common.h
parse.o: ../include/msg.h ../include/sys.h
parse.o: ../include/numeric.h parse.c
send.o: ../include/struct.h ../include/config.h ../include/class.h
send.o: ../include/dbuf.h ../include/common.h send.c
match.o: ../include/config.h ../include/common.h ../include/sys.h match.c
support.o: ../include/config.h ../include/common.h ../include/sys.h support.c

186
common/bsd.c Normal file
View File

@@ -0,0 +1,186 @@
/************************************************************************
* IRC - Internet Relay Chat, common/bsd.c
* Copyright (C) 1990 Jarkko Oikarinen and
* University of Oulu, Computing Center
*
* 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 1, 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.
*/
#ifndef lint
static char sccsid[] = "@(#)bsd.c 2.14 1/30/94 (C) 1988 University of Oulu, \
Computing Center and Jarkko Oikarinen";
#endif
#include "struct.h"
#include "common.h"
#include "sys.h"
#include "h.h"
#include <signal.h>
extern int errno; /* ...seems that errno.h doesn't define this everywhere */
#if !defined(__FreeBSD__) && !defined(__NetBSD__) && !defined(__bsdi__)
extern char *sys_errlist[];
#endif
extern char *last_dead_comment;
#ifdef DEBUGMODE
int writecalls = 0, writeb[10] = {0,0,0,0,0,0,0,0,0,0};
#endif
VOIDSIG dummy()
{
#ifndef HAVE_RELIABLE_SIGNALS
(void)signal(SIGALRM, dummy);
(void)signal(SIGPIPE, dummy);
#ifndef HPUX /* Only 9k/800 series require this, but don't know how to.. */
# ifdef SIGWINCH
(void)signal(SIGWINCH, dummy);
# endif
#endif
#else
# ifdef POSIX_SIGNALS
struct sigaction act;
act.sa_handler = dummy;
act.sa_flags = 0;
(void)sigemptyset(&act.sa_mask);
(void)sigaddset(&act.sa_mask, SIGALRM);
(void)sigaddset(&act.sa_mask, SIGPIPE);
# ifdef SIGWINCH
(void)sigaddset(&act.sa_mask, SIGWINCH);
# endif
(void)sigaction(SIGALRM, &act, (struct sigaction *)NULL);
(void)sigaction(SIGPIPE, &act, (struct sigaction *)NULL);
# ifdef SIGWINCH
(void)sigaction(SIGWINCH, &act, (struct sigaction *)NULL);
# endif
# endif
#endif
}
/*
** deliver_it
** Attempt to send a sequence of bytes to the connection.
** Returns
**
** < 0 Some fatal error occurred, (but not EWOULDBLOCK).
** This return is a request to close the socket and
** clean up the link.
**
** >= 0 No real error occurred, returns the number of
** bytes actually transferred. EWOULDBLOCK and other
** possibly similar conditions should be mapped to
** zero return. Upper level routine will have to
** decide what to do with those unwritten bytes...
**
** *NOTE* alarm calls have been preserved, so this should
** work equally well whether blocking or non-blocking
** mode is used...
**
** We don't use blocking anymore, that is impossible with the
** net.loads today anyway. Commented out the alarms to save cpu.
** --Run
*/
int deliver_it(cptr, str, len)
aClient *cptr;
int len;
char *str;
{
int retval;
aClient *acpt = cptr->acpt;
#ifdef DEBUGMODE
writecalls++;
#endif
/* (void)alarm(WRITEWAITDELAY); Bullshit */
#ifdef VMS
retval = netwrite(cptr->fd, str, len);
#else
retval = send(cptr->fd, str, len, 0);
/*
** Convert WOULDBLOCK to a return of "0 bytes moved". This
** should occur only if socket was non-blocking. Note, that
** all is Ok, if the 'write' just returns '0' instead of an
** error and errno=EWOULDBLOCK.
**
** ...now, would this work on VMS too? --msa
*/
if (retval < 0 && (errno == EWOULDBLOCK || errno == EAGAIN ||
errno == ENOBUFS))
{
retval = 0;
cptr->flags |= FLAGS_BLOCKED;
}
else if (retval > 0)
{
#ifdef pyr
(void)gettimeofday(&cptr->lw, NULL);
#endif
cptr->flags &= ~FLAGS_BLOCKED;
}
#endif
/* (void )alarm(0); */
#ifdef DEBUGMODE
if (retval < 0) {
writeb[0]++;
Debug((DEBUG_ERROR,"write error (%s) to %s",
sys_errlist[errno], cptr->name));
} else if (retval == 0)
writeb[1]++;
else if (retval < 16)
writeb[2]++;
else if (retval < 32)
writeb[3]++;
else if (retval < 64)
writeb[4]++;
else if (retval < 128)
writeb[5]++;
else if (retval < 256)
writeb[6]++;
else if (retval < 512)
writeb[7]++;
else if (retval < 1024)
writeb[8]++;
else
writeb[9]++;
#endif
if (retval > 0)
{
cptr->sendB += retval;
me.sendB += retval;
if (cptr->sendB > 1023)
{
cptr->sendK += (cptr->sendB >> 10);
cptr->sendB &= 0x03ff; /* 2^10 = 1024, 3ff = 1023 */
}
if (acpt != &me)
{
acpt->sendB += retval;
if (acpt->sendB > 1023)
{
acpt->sendK += (acpt->sendB >> 10);
acpt->sendB &= 0x03ff;
}
}
else if (me.sendB > 1023)
{
me.sendK += (me.sendB >> 10);
me.sendB &= 0x03ff;
}
}
return(retval);
}

345
common/dbuf.c Normal file
View File

@@ -0,0 +1,345 @@
/************************************************************************
* IRC - Internet Relay Chat, common/dbuf.c
* Copyright (C) 1990 Markku Savela
*
* 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 1, 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.
*/
/* -- Jto -- 20 Jun 1990
* extern void free() fixed as suggested by
* gruner@informatik.tu-muenchen.de
*/
/* -- Jto -- 10 May 1990
* Changed memcpy into bcopy and removed the declaration of memset
* because it was unnecessary.
* Added the #includes for "struct.h" and "sys.h" to get bcopy/memcpy
* work
*/
/*
** For documentation of the *global* functions implemented here,
** see the header file (dbuf.h).
**
*/
#ifndef lint
static char sccsid[] = "@(#)dbuf.c 2.17 1/30/94 (C) 1990 Markku Savela";
#endif
#include <stdio.h>
#include "struct.h"
#include "common.h"
#include "sys.h"
#if !defined(VALLOC) && !defined(valloc)
#define valloc malloc
#endif
int dbufalloc = 0, dbufblocks = 0;
static dbufbuf *freelist = NULL;
/* This is a dangerous define because a broken compiler will set DBUFSIZ
** to 4, which will work but will be very inefficient. However, there
** are other places where the code breaks badly if this is screwed
** up, so... -- Wumpus
*/
#define DBUFSIZ sizeof(((dbufbuf *)0)->data)
/*
** dbuf_alloc - allocates a dbufbuf structure either from freelist or
** creates a new one.
*/
static dbufbuf *dbuf_alloc()
{
#if defined(VALLOC) && !defined(DEBUGMODE)
Reg1 dbufbuf *dbptr, *db2ptr;
Reg2 int num;
#else
Reg1 dbufbuf *dbptr;
#endif
dbufalloc++;
if ((dbptr = freelist))
{
freelist = freelist->next;
return dbptr;
}
if (dbufalloc * DBUFSIZ > BUFFERPOOL)
{
dbufalloc--;
return NULL;
}
#if defined(VALLOC) && !defined(DEBUGMODE)
# if defined(SOL20) || defined(_SC_PAGESIZE)
num = sysconf(_SC_PAGESIZE)/sizeof(dbufbuf);
# else
num = getpagesize()/sizeof(dbufbuf);
# endif
if (num < 0)
num = 1;
dbufblocks += num;
dbptr = (dbufbuf *)valloc(num*sizeof(dbufbuf));
if (!dbptr)
return (dbufbuf *)NULL;
num--;
for (db2ptr = dbptr; num; num--)
{
db2ptr = (dbufbuf *)((char *)db2ptr + sizeof(dbufbuf));
db2ptr->next = freelist;
freelist = db2ptr;
}
return dbptr;
#else
dbufblocks++;
return (dbufbuf *)MyMalloc(sizeof(dbufbuf));
#endif
}
/*
** dbuf_free - return a dbufbuf structure to the freelist
*/
static void dbuf_free(ptr)
Reg1 dbufbuf *ptr;
{
dbufalloc--;
ptr->next = freelist;
freelist = ptr;
}
/*
** This is called when malloc fails. Scrap the whole content
** of dynamic buffer and return -1. (malloc errors are FATAL,
** there is no reason to continue this buffer...). After this
** the "dbuf" has consistent EMPTY status... ;)
*/
static int dbuf_malloc_error(dyn)
dbuf *dyn;
{
dbufbuf *p;
dyn->length = 0;
dyn->offset = 0;
while ((p = dyn->head) != NULL)
{
dyn->head = p->next;
dbuf_free(p);
}
dyn->tail = dyn->head;
return -1;
}
int dbuf_put(dyn, buf, length)
dbuf *dyn;
char *buf;
int length;
{
Reg1 dbufbuf **h, *d;
Reg2 int off;
Reg3 int chunk;
off = (dyn->offset + dyn->length) % DBUFSIZ;
/*
** Locate the last non-empty buffer. If the last buffer is
** full, the loop will terminate with 'd==NULL'. This loop
** assumes that the 'dyn->length' field is correctly
** maintained, as it should--no other check really needed.
*/
if (!dyn->length) h = &(dyn->head);
else {
if (off) h = &(dyn->tail);
else h = &(dyn->tail->next);
}
/*
** Append users data to buffer, allocating buffers as needed
*/
chunk = DBUFSIZ - off;
dyn->length += length;
for ( ;length > 0; h = &(d->next))
{
if ((d = *h) == NULL)
{
if ((d = (dbufbuf *)dbuf_alloc()) == NULL)
return dbuf_malloc_error(dyn);
dyn->tail = d;
*h = d;
d->next = NULL;
}
if (chunk > length)
chunk = length;
bcopy(buf, d->data + off, chunk);
length -= chunk;
buf += chunk;
off = 0;
chunk = DBUFSIZ;
}
return 1;
}
char *dbuf_map(dyn,length)
dbuf *dyn;
int *length;
{
if (dyn->head == NULL)
{
dyn->tail = NULL;
*length = 0;
return NULL;
}
*length = DBUFSIZ - dyn->offset;
if (*length > dyn->length)
*length = dyn->length;
return (dyn->head->data + dyn->offset);
}
int dbuf_delete(dyn,length)
dbuf *dyn;
int length;
{
dbufbuf *d;
int chunk;
if (length > dyn->length)
length = dyn->length;
chunk = DBUFSIZ - dyn->offset;
while (length > 0)
{
if (chunk > length)
chunk = length;
length -= chunk;
dyn->offset += chunk;
dyn->length -= chunk;
if (dyn->offset == DBUFSIZ || dyn->length == 0)
{
d = dyn->head;
dyn->head = d->next;
dyn->offset = 0;
dbuf_free(d);
}
chunk = DBUFSIZ;
}
if (dyn->head == (dbufbuf *)NULL) {
dyn->length = 0;
dyn->tail = 0;
}
return 0;
}
int dbuf_get(dyn, buf, length)
dbuf *dyn;
char *buf;
int length;
{
int moved = 0;
int chunk;
char *b;
while (length > 0 && (b = dbuf_map(dyn, &chunk)) != NULL)
{
if (chunk > length)
chunk = length;
bcopy(b, buf, (int)chunk);
(void)dbuf_delete(dyn, chunk);
buf += chunk;
length -= chunk;
moved += chunk;
}
return moved;
}
/*
** dbuf_getmsg
**
** Check the buffers to see if there is a string which is terminted with
** either a \r or \n prsent. If so, copy as much as possible (determined by
** length) into buf and return the amount copied - else return 0.
*/
int dbuf_getmsg(dyn, buf, length)
dbuf *dyn;
char *buf;
register int length;
{
dbufbuf *d;
register char *s;
register int dlen;
register int i;
int copy;
getmsg_init:
d = dyn->head;
dlen = dyn->length;
i = DBUFSIZ - dyn->offset;
if (i <= 0)
return -1;
copy = 0;
if (d && dlen)
s = dyn->offset + d->data;
else
return 0;
if (i > dlen)
i = dlen;
while (length > 0 && dlen > 0)
{
dlen--;
if (*s == '\n' || *s == '\r')
{
copy = dyn->length - dlen;
/*
** Shortcut this case here to save time elsewhere.
** -avalon
*/
if (copy == 1)
{
(void)dbuf_delete(dyn, 1);
goto getmsg_init;
}
break;
}
length--;
if (!--i)
{
if ((d = d->next))
{
s = d->data;
i = MIN(DBUFSIZ, dlen);
}
}
else
s++;
}
if (copy <= 0)
return 0;
/*
** copy as much of the message as wanted into parse buffer
*/
i = dbuf_get(dyn, buf, MIN(copy, length));
/*
** and delete the rest of it!
*/
if (copy - i > 0)
(void)dbuf_delete(dyn, copy - i);
if (i >= 0)
*(buf+i) = '\0'; /* mark end of messsage */
return i;
}

327
common/match.c Normal file
View File

@@ -0,0 +1,327 @@
/************************************************************************
* IRC - Internet Relay Chat, common/match.c
* Copyright (C) 1990 Jarkko Oikarinen
*
* 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 1, 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.
*/
#ifndef lint
static char sccsid[] = "%W% %G% (C) 1988 University of Oulu, \
Computing Center and Jarkko Oikarinen";
#endif
#include "struct.h"
#include "common.h"
#include "sys.h"
static int calls = 0;
#define MAX_CALLS 200
/*
** Compare if a given string (name) matches the given
** mask (which can contain wild cards: '*' - match any
** number of chars, '?' - match any single character.
**
** return 0, if match
** 1, if no match
*/
/*
** _match()
** Iterative matching function, rather than recursive.
** Written by Douglas A Lewis (dalewis@acsu.buffalo.edu)
*/
static int _match(mask, name)
char *mask, *name;
{
Reg1 u_char *m = (u_char *)mask, *n = (u_char *)name;
char *ma = mask, *na = name;
int wild = 0, q = 0;
while (1)
{
if (calls++ > MAX_CALLS)
return 1;
if (*m == '*')
{
while (*m == '*')
m++;
wild = 1;
ma = (char *)m;
na = (char *)n;
}
if (!*m)
{
if (!*n)
return 0;
for (m--; (m > (u_char *)mask) && (*m == '?'); m--)
;
if ((*m == '*') && (m > (u_char *)mask) &&
(m[-1] != '\\'))
return 0;
if (!wild)
return 1;
m = (u_char *)ma;
n = (u_char *)++na;
}
else if (!*n)
{
while(*m == '*')
m++;
return (*m != 0);
}
if ((*m == '\\') && ((m[1] == '*') || (m[1] == '?')))
{
m++;
q = 1;
}
else
q = 0;
if ((tolower(*m) != tolower(*n)) && ((*m != '?') || q))
{
if (!wild)
return 1;
m = (u_char *)ma;
n = (u_char *)++na;
}
else
{
if (*m)
m++;
if (*n)
n++;
}
}
}
/*
* External interfaces to the above matching routine.
*/
int match(ma, na)
char *ma, *na;
{
calls = 0;
return _match(ma, na);
}
int matches(ma, na)
char *ma,*na;
{
int r;
calls = 0;
return _match(ma, na);
}
/*
** collapse a pattern string into minimal components.
** This particular version is "in place", so that it changes the pattern
** which is to be reduced to a "minimal" size.
*/
char *collapse(pattern)
char *pattern;
{
Reg1 char *s = pattern, *s1, *t;
if (BadPtr(pattern))
return pattern;
/*
* Collapse all \** into \*, \*[?]+\** into \*[?]+
*/
for (; *s; s++)
if (*s == '\\')
if (!*(s + 1))
break;
else
s++;
else if (*s == '*')
{
if (*(t = s1 = s + 1) == '*')
while (*t == '*')
t++;
else if (*t == '?')
for (t++, s1++; *t == '*' || *t == '?'; t++)
if (*t == '?')
*s1++ = *t;
while ((*s1++ = *t++))
;
}
return pattern;
}
/*
** Case insensitive comparison of two NULL terminated strings.
**
** returns 0, if s1 equal to s2
** <0, if s1 lexicographically less than s2
** >0, if s1 lexicographically greater than s2
*/
int mycmp(s1, s2)
const char *s1;
const char *s2;
{
Reg1 const unsigned char *str1 = (const unsigned char *)s1;
Reg2 const unsigned char *str2 = (const unsigned char *)s2;
Reg3 int res;
while ((res = toupper(*str1) - toupper(*str2)) == 0)
{
if (*str1 == '\0')
return 0;
str1++;
str2++;
}
return (res);
}
int myncmp(str1, str2, n)
const char *str1;
const char *str2;
int n;
{
Reg1 const unsigned char *s1 = (const unsigned char *)str1;
Reg2 const unsigned char *s2 = (const unsigned char *)str2;
Reg3 int res;
while ((res = toupper(*s1) - toupper(*s2)) == 0)
{
s1++; s2++; n--;
if (n == 0 || (*s1 == '\0' && *s2 == '\0'))
return 0;
}
return (res);
}
unsigned char tolowertab[] =
{ 0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa,
0xb, 0xc, 0xd, 0xe, 0xf, 0x10, 0x11, 0x12, 0x13, 0x14,
0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d,
0x1e, 0x1f,
' ', '!', '"', '#', '$', '%', '&', 0x27, '(', ')',
'*', '+', ',', '-', '.', '/',
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
':', ';', '<', '=', '>', '?',
'@', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i',
'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's',
't', 'u', 'v', 'w', 'x', 'y', 'z', '{', '|', '}', '~',
'_',
'`', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i',
'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's',
't', 'u', 'v', 'w', 'x', 'y', 'z', '{', '|', '}', '~',
0x7f,
0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89,
0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99,
0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9,
0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9,
0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9,
0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9,
0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9,
0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9,
0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff };
unsigned char touppertab[] =
{ 0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa,
0xb, 0xc, 0xd, 0xe, 0xf, 0x10, 0x11, 0x12, 0x13, 0x14,
0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d,
0x1e, 0x1f,
' ', '!', '"', '#', '$', '%', '&', 0x27, '(', ')',
'*', '+', ',', '-', '.', '/',
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
':', ';', '<', '=', '>', '?',
'@', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I',
'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S',
'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '[', '\\', ']', '^',
0x5f,
'`', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I',
'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S',
'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '[', '\\', ']', '^',
0x7f,
0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89,
0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99,
0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9,
0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9,
0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9,
0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9,
0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9,
0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9,
0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff };
unsigned char char_atribs[] = {
/* 0-7 */ CNTRL, CNTRL, CNTRL, CNTRL, CNTRL, CNTRL, CNTRL, CNTRL,
/* 8-12 */ CNTRL, CNTRL|SPACE, CNTRL|SPACE, CNTRL|SPACE, CNTRL|SPACE,
/* 13-15 */ CNTRL|SPACE, CNTRL, CNTRL,
/* 16-23 */ CNTRL, CNTRL, CNTRL, CNTRL, CNTRL, CNTRL, CNTRL, CNTRL,
/* 24-31 */ CNTRL, CNTRL, CNTRL, CNTRL, CNTRL, CNTRL, CNTRL, CNTRL,
/* space */ PRINT|SPACE,
/* !"#$%&'( */ PRINT, PRINT, PRINT, PRINT, PRINT, PRINT, PRINT, PRINT,
/* )*+,-./ */ PRINT, PRINT, PRINT, PRINT, PRINT, PRINT, PRINT,
/* 0123 */ PRINT|DIGIT, PRINT|DIGIT, PRINT|DIGIT, PRINT|DIGIT,
/* 4567 */ PRINT|DIGIT, PRINT|DIGIT, PRINT|DIGIT, PRINT|DIGIT,
/* 89:; */ PRINT|DIGIT, PRINT|DIGIT, PRINT, PRINT,
/* <=>? */ PRINT, PRINT, PRINT, PRINT,
/* @ */ PRINT,
/* ABC */ PRINT|ALPHA, PRINT|ALPHA, PRINT|ALPHA,
/* DEF */ PRINT|ALPHA, PRINT|ALPHA, PRINT|ALPHA,
/* GHI */ PRINT|ALPHA, PRINT|ALPHA, PRINT|ALPHA,
/* JKL */ PRINT|ALPHA, PRINT|ALPHA, PRINT|ALPHA,
/* MNO */ PRINT|ALPHA, PRINT|ALPHA, PRINT|ALPHA,
/* PQR */ PRINT|ALPHA, PRINT|ALPHA, PRINT|ALPHA,
/* STU */ PRINT|ALPHA, PRINT|ALPHA, PRINT|ALPHA,
/* VWX */ PRINT|ALPHA, PRINT|ALPHA, PRINT|ALPHA,
/* YZ[ */ PRINT|ALPHA, PRINT|ALPHA, PRINT|ALPHA,
/* \]^ */ PRINT|ALPHA, PRINT|ALPHA, PRINT|ALPHA,
/* _` */ PRINT,PRINT,
/* abc */ PRINT|ALPHA, PRINT|ALPHA, PRINT|ALPHA,
/* def */ PRINT|ALPHA, PRINT|ALPHA, PRINT|ALPHA,
/* ghi */ PRINT|ALPHA, PRINT|ALPHA, PRINT|ALPHA,
/* jkl */ PRINT|ALPHA, PRINT|ALPHA, PRINT|ALPHA,
/* mno */ PRINT|ALPHA, PRINT|ALPHA, PRINT|ALPHA,
/* pqr */ PRINT|ALPHA, PRINT|ALPHA, PRINT|ALPHA,
/* stu */ PRINT|ALPHA, PRINT|ALPHA, PRINT|ALPHA,
/* vwx */ PRINT|ALPHA, PRINT|ALPHA, PRINT|ALPHA,
/* yz{ */ PRINT|ALPHA, PRINT|ALPHA, PRINT|ALPHA,
/* |}~ */ PRINT|ALPHA, PRINT|ALPHA, PRINT|ALPHA,
/* del */ 0,
/* 80-8f */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
/* 90-9f */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
/* a0-af */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
/* b0-bf */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
/* c0-cf */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
/* d0-df */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
/* e0-ef */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
/* f0-ff */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};

115
common/packet.c Normal file
View File

@@ -0,0 +1,115 @@
/************************************************************************
* IRC - Internet Relay Chat, common/packet.c
* Copyright (C) 1990 Jarkko Oikarinen and
* University of Oulu, Computing Center
*
* 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 1, 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.
*/
#ifndef lint
static char sccsid[] = "@(#)packet.c 2.12 1/30/94 (C) 1988 University of Oulu, \
Computing Center and Jarkko Oikarinen";
#endif
#include "struct.h"
#include "common.h"
#include "sys.h"
#include "msg.h"
#include "h.h"
extern char *last_dead_comment;
/*
** dopacket
** cptr - pointer to client structure for which the buffer data
** applies.
** buffer - pointr to the buffer containing the newly read data
** length - number of valid bytes of data in the buffer
**
** Note:
** It is implicitly assumed that dopacket is called only
** with cptr of "local" variation, which contains all the
** necessary fields (buffer etc..)
*/
int dopacket(cptr, buffer, length)
Reg3 aClient *cptr;
char *buffer;
Reg4 int length;
{
Reg1 char *ch1;
Reg2 char *ch2;
register char *cptrbuf;
aClient *acpt = cptr->acpt;
cptrbuf = cptr->buffer;
me.receiveB += length; /* Update bytes received */
cptr->receiveB += length;
if (cptr->receiveB > 1023)
{
cptr->receiveK += (cptr->receiveB >> 10);
cptr->receiveB &= 0x03ff; /* 2^10 = 1024, 3ff = 1023 */
}
if (acpt != &me)
{
acpt->receiveB += length;
if (acpt->receiveB > 1023)
{
acpt->receiveK += (acpt->receiveB >> 10);
acpt->receiveB &= 0x03ff;
}
}
else if (me.receiveB > 1023)
{
me.receiveK += (me.receiveB >> 10);
me.receiveB &= 0x03ff;
}
ch1 = cptrbuf + cptr->count;
ch2 = buffer;
while (--length >= 0)
{
register char g;
g = (*ch1 = *ch2++);
/*
* Yuck. Stuck. To make sure we stay backward compatible,
* we must assume that either CR or LF terminates the message
* and not CR-LF. By allowing CR or LF (alone) into the body
* of messages, backward compatibility is lost and major
* problems will arise. - Avalon
*/
if ( g < '\16' && (g== '\n' || g == '\r'))
{
if (ch1 == cptrbuf)
continue; /* Skip extra LF/CR's */
*ch1 = '\0';
me.receiveM += 1; /* Update messages received */
cptr->receiveM += 1;
if (cptr->acpt != &me)
cptr->acpt->receiveM += 1;
if (parse(cptr, cptr->buffer, ch1, msgtab) ==
CPTR_KILLED)
return CPTR_KILLED;
/*
** Socket is dead so exit
*/
if (IsDead(cptr))
return exit_client(cptr, cptr, &me, last_dead_comment);
ch1 = cptrbuf;
}
else if (ch1 < cptrbuf + (sizeof(cptr->buffer)-1))
ch1++; /* There is always room for the null */
}
cptr->count = ch1 - cptr->buffer;
return 0;
}

464
common/parse.c Normal file
View File

@@ -0,0 +1,464 @@
/************************************************************************
* IRC - Internet Relay Chat, common/parse.c
* Copyright (C) 1990 Jarkko Oikarinen and
* University of Oulu, Computing Center
*
* 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 1, 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.
*/
/* -- Jto -- 03 Jun 1990
* Changed the order of defines...
*/
#ifndef lint
static char sccsid[] = "@(#)parse.c 2.33 1/30/94 (C) 1988 University of Oulu, \
Computing Center and Jarkko Oikarinen";
#endif
#include "struct.h"
#include "common.h"
#define MSGTAB
#include "msg.h"
#undef MSGTAB
#include "sys.h"
#include "numeric.h"
#include "h.h"
/*
* NOTE: parse() should not be called recursively by other functions!
*/
static char *para[MAXPARA+1];
static char sender[HOSTLEN+1];
/*
** Find a client (server or user) by name.
**
** *Note*
** Semantics of this function has been changed from
** the old. 'name' is now assumed to be a null terminated
** string and the search is the for server and user.
*/
aClient *find_client(name, cptr)
char *name;
Reg1 aClient *cptr;
{
if (name)
cptr = hash_find_client(name, cptr);
return cptr;
}
aClient *find_nickserv(name, cptr)
char *name;
Reg1 aClient *cptr;
{
if (name)
cptr = hash_find_nickserver(name, cptr);
return cptr;
}
/*
** Find a user@host (server or user).
**
** *Note*
** Semantics of this function has been changed from
** the old. 'name' is now assumed to be a null terminated
** string and the search is the for server and user.
*/
aClient *find_userhost(user, host, cptr, count)
char *user, *host;
aClient *cptr;
int *count;
{
Reg1 aClient *c2ptr;
Reg2 aClient *res = cptr;
*count = 0;
if (collapse(user))
for (c2ptr = client; c2ptr; c2ptr = c2ptr->next)
{
if (!MyClient(c2ptr)) /* implies mine and a user */
continue;
if ((!host || !match(host, c2ptr->user->host)) &&
mycmp(user, c2ptr->user->username) == 0)
{
(*count)++;
res = c2ptr;
}
}
return res;
}
/*
** Find server by name.
**
** This implementation assumes that server and user names
** are unique, no user can have a server name and vice versa.
** One should maintain separate lists for users and servers,
** if this restriction is removed.
**
** *Note*
** Semantics of this function has been changed from
** the old. 'name' is now assumed to be a null terminated
** string.
*/
aClient *find_server(name, cptr)
char *name;
Reg1 aClient *cptr;
{
if (name)
cptr = hash_find_server(name, cptr);
return cptr;
}
aClient *find_match_server(mask)
char *mask;
{
aClient *acptr;
if (BadPtr(mask))
return NULL;
for (acptr = client, (void)collapse(mask); acptr; acptr = acptr->next)
{
if (!IsServer(acptr) && !IsMe(acptr))
continue;
if (!match(mask, acptr->name))
break; continue;
}
return acptr;
}
aClient *find_name(name, cptr)
char *name;
aClient *cptr;
{
Reg1 aClient *c2ptr = cptr;
if (!collapse(name))
return c2ptr;
if ((c2ptr = hash_find_server(name, cptr)))
return (c2ptr);
if (!index(name, '*'))
return c2ptr;
for (c2ptr = client; c2ptr; c2ptr = c2ptr->next)
{
if (!IsServer(c2ptr) && !IsMe(c2ptr))
continue;
if (match(name, c2ptr->name) == 0)
break;
if (index(c2ptr->name, '*'))
if (match(c2ptr->name, name) == 0)
break;
}
return (c2ptr ? c2ptr : cptr);
}
/*
** Find person by (nick)name.
*/
aClient *find_person(name, cptr)
char *name;
aClient *cptr;
{
Reg1 aClient *c2ptr = cptr;
c2ptr = find_client(name, c2ptr);
if (c2ptr && IsClient(c2ptr) && c2ptr->user)
return c2ptr;
else
return cptr;
}
/*
* parse a buffer.
*
* NOTE: parse() should not be called recusively by any other fucntions!
*/
int parse(cptr, buffer, bufend, mptr)
aClient *cptr;
char *buffer, *bufend;
struct Message *mptr;
{
Reg1 aClient *from = cptr;
Reg2 char *ch, *s;
Reg3 int len, i, numeric, paramcount, noprefix = 0;
Debug((DEBUG_DEBUG,"Parsing: %s", buffer));
if (IsDead(cptr))
return 0;
s = sender;
*s = '\0';
for (ch = buffer; *ch == ' '; ch++)
;
para[0] = from->name;
if (*ch == ':')
{
/*
** Copy the prefix to 'sender' assuming it terminates
** with SPACE (or NULL, which is an error, though).
*/
for (++ch, i = 0; *ch && *ch != ' '; ++ch )
if (s < (sender + sizeof(sender)-1))
*s++ = *ch; /* leave room for NULL */
*s = '\0';
/*
** Actually, only messages coming from servers can have
** the prefix--prefix silently ignored, if coming from
** a user client...
**
** ...sigh, the current release "v2.2PL1" generates also
** null prefixes, at least to NOTIFY messages (e.g. it
** puts "sptr->nickname" as prefix from server structures
** where it's null--the following will handle this case
** as "no prefix" at all --msa (": NOTICE nick ...")
*/
if (*sender && IsServer(cptr))
{
from = find_client(sender, (aClient *) NULL);
if (!from || matches(from->name, sender))
from = find_server(sender, (aClient *)NULL);
else if (!from && index(sender, '@'))
from = find_nickserv(sender, (aClient *)NULL);
para[0] = sender;
/* If the client corresponding to the
* prefix is not found. We must ignore it,
* it is simply a lagged message travelling
* upstream a SQUIT that removed the client
* --Run
*/
if (!from)
{
Debug((DEBUG_NOTICE,
"Unknown prefix (%s)(%s) from (%s)",
sender, buffer, cptr->name));
ircstp->is_unpf++;
while (*ch == ' ')
ch++;
/*
** However, the only thing that MUST be
** allowed to travel upstream against an
** squit, is an SQUIT itself (the timestamp
** protects us from being used wrong)
*/
if (strncmp(ch, "SQUIT ", 6)==0)
{
strcpy(sender, cptr->name);
from = cptr;
}
else
return 0;
}
else if (from->from != cptr)
{
ircstp->is_wrdi++;
Debug((DEBUG_NOTICE,
"Fake direction: Message (%s) coming from (%s)",
buffer, cptr->name));
return 0;
}
}
while (*ch == ' ')
ch++;
}
else
noprefix = 1;
if (*ch == '\0')
{
ircstp->is_empt++;
Debug((DEBUG_NOTICE, "Empty message from host %s:%s",
cptr->name, from->name));
return(-1);
}
/*
** Extract the command code from the packet. Point s to the end
** of the command code and calculate the length using pointer
** arithmetic. Note: only need length for numerics and *all*
** numerics must have paramters and thus a space after the command
** code. -avalon
*/
s = (char *)index(ch, ' '); /* s -> End of the command code */
len = (s) ? (s - ch) : 0;
if (len == 3 &&
isdigit(*ch) && isdigit(*(ch + 1)) && isdigit(*(ch + 2)))
{
mptr = NULL;
numeric = (*ch - '0') * 100 + (*(ch + 1) - '0') * 10
+ (*(ch + 2) - '0');
paramcount = MAXPARA;
ircstp->is_num++;
}
else
{
if (s)
*s++ = '\0';
for (; mptr->cmd; mptr++)
if (mycmp(mptr->cmd, ch) == 0)
break;
if (!mptr->cmd)
{
/*
** Note: Give error message *only* to recognized
** persons. It's a nightmare situation to have
** two programs sending "Unknown command"'s or
** equivalent to each other at full blast....
** If it has got to person state, it at least
** seems to be well behaving. Perhaps this message
** should never be generated, though... --msa
** Hm, when is the buffer empty -- if a command
** code has been found ?? -Armin
*/
if (buffer[0] != '\0')
{
if (IsPerson(from))
sendto_one(from,
":%s %d %s %s :Unknown command",
me.name, ERR_UNKNOWNCOMMAND,
from->name, ch);
Debug((DEBUG_ERROR,"Unknown (%s) from %s",
ch, get_client_name(cptr, TRUE)));
}
ircstp->is_unco++;
return(-1);
}
paramcount = mptr->parameters;
i = bufend - ((s) ? s : ch);
mptr->bytes += i;
if ((mptr->flags & 1) && !(IsServer(cptr) || IsService(cptr)))
cptr->since += (2 + i / 120);
/* Allow only 1 msg per 2 seconds
* (on average) to prevent dumping.
* to keep the response rate up,
* bursts of up to 5 msgs are allowed
* -SRB
*/
}
/*
** Must the following loop really be so devious? On
** surface it splits the message to parameters from
** blank spaces. But, if paramcount has been reached,
** the rest of the message goes into this last parameter
** (about same effect as ":" has...) --msa
*/
/* Note initially true: s==NULL || *(s-1) == '\0' !! */
i = 0;
if (s)
{
if (paramcount > MAXPARA)
paramcount = MAXPARA;
for (;;)
{
/*
** Never "FRANCE " again!! ;-) Clean
** out *all* blanks.. --msa
*/
while (*s == ' ')
*s++ = '\0';
if (*s == '\0')
break;
if (*s == ':')
{
/*
** The rest is single parameter--can
** include blanks also.
*/
para[++i] = s + 1;
break;
}
para[++i] = s;
if (i >= paramcount)
break;
for (; *s != ' ' && *s; s++)
;
}
}
para[++i] = NULL;
if (mptr == NULL)
return (do_numeric(numeric, cptr, from, i, para));
mptr->count++;
if (!IsRegistered(cptr) && (
/* patch to avoid server flooding from unregistered connects : --dl */
(mptr->func!=m_user)
&& (mptr->func!=m_quit)
&& (mptr->func!=m_admin)
&& (mptr->func!=m_version)
&& (mptr->func!=m_server)
&& (mptr->func!=m_pass)
&& (mptr->func!=m_nick)
&& (mptr->func!=m_pong)
&& (mptr->func!=m_error) ) )
{
sendto_one(from,
":%s %d %s %s :Register first.",
me.name, ERR_NOTREGISTERED,
from->name, ch);
return -1;
}
if (IsRegisteredUser(cptr) &&
#ifdef IDLE_FROM_MSG
mptr->func == m_private)
#else
mptr->func != m_ping && mptr->func != m_pong)
#endif
from->user->last = now;
/* Lame protocol 4 stuff... this if can be removed when all are 2.9 */
if (noprefix && IsServer(cptr) && i >= 2 && mptr->func == m_squit &&
(!(from = find_server(para[1], (aClient *)NULL)) ||
from->from != cptr))
{
Debug((DEBUG_DEBUG,"Ignoring protocol 4 \"%s %s %s ...\"",
para[0], para[1], para[2]));
return 0;
}
return (*mptr->func)(cptr, from, i, para);
}
/*
* field breakup for ircd.conf file.
*/
char *getfield(newline)
char *newline;
{
static char *line = NULL;
char *end, *field;
if (newline)
line = newline;
if (line == NULL)
return(NULL);
field = line;
if ((end = (char *)index(line,':')) == NULL)
{
line = NULL;
if ((end = (char *)index(field,'\n')) == NULL)
end = field + strlen(field);
}
else
line = end + 1;
*end = '\0';
return(field);
}

955
common/send.c Normal file
View File

@@ -0,0 +1,955 @@
/************************************************************************
* IRC - Internet Relay Chat, common/send.c
* Copyright (C) 1990 Jarkko Oikarinen and
* University of Oulu, Computing Center
*
* 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 1, 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.
*/
/* -- Run -- 28 sept 1994
* Corrected the wrong way varargs were treated...
*/
/* -- Jto -- 16 Jun 1990
* Added Armin's PRIVMSG patches...
*/
#ifndef lint
static char sccsid[] = "@(#)send.c 2.32 2/28/94 (C) 1988 University of Oulu, \
Computing Center and Jarkko Oikarinen";
#endif
#include "struct.h"
#include "common.h"
#include "sys.h"
#include "h.h"
#include <stdio.h>
static char sendbuf[2048];
static void sendbufto_one PROTO((aClient *));
static int sentalong[MAXCONNECTIONS];
/*
** dead_link
** An error has been detected. The link *must* be closed,
** but *cannot* call ExitClient (m_bye) from here.
** Instead, mark it with FLAGS_DEADSOCKET. This should
** generate ExitClient from the main loop.
**
** If 'notice' is not NULL, it is assumed to be a format
** for a message to local opers. I can contain only one
** '%s', which will be replaced by the sockhost field of
** the failing link.
**
** Also, the notice is skipped for "uninteresting" cases,
** like Persons and yet unknown connections...
*/
char *last_dead_comment = NULL;
static void dead_link(to, notice)
aClient *to;
char *notice;
{
char dead_comment_buf[256]; /* SHOULD be big enough */
to->flags |= FLAGS_DEADSOCKET;
/*
* If because of BUFFERPOOL problem then clean dbuf's now so that
* notices don't hurt operators below.
*/
DBufClear(&to->recvQ);
DBufClear(&to->sendQ);
/* Keep a copy of the last comment, for later use... */
sprintf(dead_comment_buf, notice, get_client_name(to, FALSE));
if (last_dead_comment)
MyFree(last_dead_comment);
last_dead_comment = (char *)MyMalloc(strlen(dead_comment_buf) + 1);
strcpy(last_dead_comment, dead_comment_buf);
if (!IsPerson(to) && !IsUnknown(to) && !(to->flags & FLAGS_CLOSING))
sendto_ops(last_dead_comment);
Debug((DEBUG_ERROR, last_dead_comment));
}
/*
** flush_connections
** Used to empty all output buffers for all connections. Should only
** be called once per scan of connections. There should be a select in
** here perhaps but that means either forcing a timeout or doing a poll.
** When flushing, all we do is empty the obuffer array for each local
** client and try to send it. if we cant send it, it goes into the sendQ
** -avalon
*/
void flush_connections(fd)
int fd;
{
Reg1 int i;
Reg2 aClient *cptr;
if (fd == me.fd)
{
for (i = highest_fd; i >= 0; i--)
if ((cptr = local[i]) && DBufLength(&cptr->sendQ) > 0)
send_queued(cptr);
}
else if (fd >= 0 && (cptr = local[fd]) && DBufLength(&cptr->sendQ) > 0)
send_queued(cptr);
}
/*
** send_queued
** This function is called from the main select-loop (or whatever)
** when there is a chance that some output would be possible. This
** attempts to empty the send queue as far as possible...
*/
void send_queued(to)
aClient *to;
{
#ifndef pyr
if (to->flags & FLAGS_BLOCKED)
return; /* Don't bother */
#endif
/*
** Once socket is marked dead, we cannot start writing to it,
** even if the error is removed...
*/
if (IsDead(to))
{
/*
** Actually, we should *NEVER* get here--something is
** not working correct if send_queued is called for a
** dead socket... --msa
*/
return;
}
while (DBufLength(&to->sendQ) > 0)
{
char *msg;
int len, rlen;
msg = dbuf_map(&to->sendQ, &len);
/* Returns always len > 0 */
if ((rlen = deliver_it(to, msg, len)) < 0)
{
dead_link(to,"Write error to %s, closing link");
return;
}
(void)dbuf_delete(&to->sendQ, rlen);
to->lastsq = DBufLength(&to->sendQ)/1024;
if (rlen < len)
{
to->flags |= FLAGS_BLOCKED; /* Wait till select() says we can write again */
break;
}
}
return;
}
/*
** send message to single client
*/
#ifdef USE_VARARGS
void sendto_one(to, pattern, va_alist)
aClient *to;
char *pattern;
va_dcl
{
va_list vl;
va_start(vl);
vsendto_one(to, pattern, vl);
va_end(vl);
}
void vsendto_one(to, pattern, vl)
aClient *to;
char *pattern;
va_list vl;
{
#else
void sendto_one(to, pattern, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11)
aClient *to;
char *pattern, *p1, *p2, *p3, *p4, *p5, *p6, *p7, *p8, *p9, *p10, *p11;
{
#endif
#ifdef USE_VARARGS
(void)vsprintf(sendbuf, pattern, vl);
#else
(void)sprintf(sendbuf, pattern, p1, p2, p3, p4, p5, p6,
p7, p8, p9, p10, p11);
#endif
sendbufto_one(to);
}
static void sendbufto_one(to)
aClient *to;
{
int len;
Debug((DEBUG_SEND,"Sending [%s] to %s", sendbuf,to->name));
if (to->from)
to = to->from;
if (IsDead(to))
return; /* This socket has already been marked as dead */
if (to->fd < 0)
{
/* This is normal when 'to' was being closed (via exit_client
** and close_connection) --Run
** Print the debug message anyway...
*/
Debug((DEBUG_ERROR,
"Local socket %s with negative fd %d... AARGH!",
to->name, to->fd));
return;
}
len = strlen(sendbuf);
if (sendbuf[len-1] != '\n')
{
#ifndef IRCII_KLUDGE
if (len > 510)
len = 510;
sendbuf[len++] = '\r';
#else
if (len > 511)
len = 511;
#endif
sendbuf[len++] = '\n';
sendbuf[len] = '\0';
}
if (IsMe(to))
{
char tmp_sendbuf[sizeof(sendbuf)];
strcpy(tmp_sendbuf, sendbuf);
sendto_ops("Trying to send [%s] to myself!", tmp_sendbuf);
return;
}
if (DBufLength(&to->sendQ) > get_sendq(to))
{
if (IsServer(to))
sendto_ops("Max SendQ limit exceeded for %s: %d > %d",
get_client_name(to, FALSE),
DBufLength(&to->sendQ), get_sendq(to));
dead_link(to, "Max Sendq exceeded");
return;
}
else if (dbuf_put(&to->sendQ, sendbuf, len) < 0)
{
dead_link(to, "Buffer allocation error for %s");
return;
}
/*
** Update statistics. The following is slightly incorrect
** because it counts messages even if queued, but bytes
** only really sent. Queued bytes get updated in SendQueued.
*/
to->sendM += 1;
me.sendM += 1;
if (to->acpt != &me)
to->acpt->sendM += 1;
/*
** This little bit is to stop the sendQ from growing too large when
** there is no need for it to. Thus we call send_queued() every time
** 2k has been added to the queue since the last non-fatal write.
** Also stops us from deliberately building a large sendQ and then
** trying to flood that link with data (possible during the net
** relinking done by servers with a large load).
*/
if (DBufLength(&to->sendQ)/1024 > to->lastsq)
send_queued(to);
}
# ifndef USE_VARARGS
/*VARARGS*/
void sendto_channel_butone(one, from, chptr, pattern,
p1, p2, p3, p4, p5, p6, p7, p8)
aClient *one, *from;
aChannel *chptr;
char *pattern, *p1, *p2, *p3, *p4, *p5, *p6, *p7, *p8;
{
# else
void sendto_channel_butone(one, from, chptr, pattern, va_alist)
aClient *one, *from;
aChannel *chptr;
char *pattern;
va_dcl
{
va_list vl;
# endif
Reg1 Link *lp;
Reg2 aClient *acptr;
Reg3 int i;
# ifdef USE_VARARGS
va_start(vl);
# endif
for (i = 0; i < MAXCONNECTIONS; i++)
sentalong[i] = 0;
for (lp = chptr->members; lp; lp = lp->next)
{
acptr = lp->value.cptr;
if (acptr->from == one || /* ...was the one I should skip */
(lp->flags & CHFL_ZOMBIE) || IsDeaf(acptr))
continue;
i = acptr->from->fd;
if (MyConnect(acptr) && IsRegisteredUser(acptr))
{
# ifdef USE_VARARGS
vsendto_prefix_one(acptr, from, pattern, vl);
# else
sendto_prefix_one(acptr, from, pattern, p1, p2,
p3, p4, p5, p6, p7, p8);
# endif
sentalong[i] = 1;
}
else
{
/* Now check whether a message has been sent to this
* remote link already */
if (sentalong[i] == 0)
{
# ifdef USE_VARARGS
vsendto_prefix_one(acptr, from, pattern, vl);
# else
sendto_prefix_one(acptr, from, pattern,
p1, p2, p3, p4,
p5, p6, p7, p8);
# endif
sentalong[i] = 1;
}
}
}
# ifdef USE_VARARGS
va_end(vl);
# endif
return;
}
/*
* sendto_server_butone
*
* Send a message to all connected servers except the client 'one'.
*/
# ifndef USE_VARARGS
/*VARARGS*/
void sendto_serv_butone(one, pattern, p1, p2, p3, p4, p5, p6, p7, p8)
aClient *one;
char *pattern, *p1, *p2, *p3, *p4, *p5, *p6, *p7, *p8;
{
# else
void sendto_serv_butone(one, pattern, va_alist)
aClient *one;
char *pattern;
va_dcl
{
va_list vl;
# endif
Reg1 Dlink *lp;
# ifdef USE_VARARGS
va_start(vl);
(void)vsprintf(sendbuf, pattern, vl);
va_end(vl);
# else
(void)sprintf(sendbuf, pattern, p1, p2, p3, p4, p5, p6, p7, p8);
# endif
for (lp = me.serv->down; lp; lp=lp->next)
{
if (one && lp->value.cptr == one->from)
continue;
sendbufto_one(lp->value.cptr);
}
}
/*
* sendto_common_channels()
*
* Sends a message to all people (inclusing user) on local server who are
* in same channel with user.
*/
# ifndef USE_VARARGS
/*VARARGS*/
void sendto_common_channels(user, pattern, p1, p2, p3, p4,
p5, p6, p7, p8)
aClient *user;
char *pattern, *p1, *p2, *p3, *p4, *p5, *p6, *p7, *p8;
{
# else
void sendto_common_channels(user, pattern, va_alist)
aClient *user;
char *pattern;
va_dcl
{
va_list vl;
# endif
Reg1 int i;
Reg2 aClient *cptr;
Reg3 Link *lp;
# ifdef USE_VARARGS
va_start(vl);
# endif
for (i = 0; i <= highest_fd; i++)
{
if (!(cptr = local[i]) || IsServer(cptr) ||
user == cptr || !user->user)
continue;
for (lp = user->user->channel; lp; lp = lp->next)
if (IsMember(user, lp->value.chptr) &&
IsMember(cptr, lp->value.chptr))
{
# ifdef USE_VARARGS
vsendto_prefix_one(cptr, user, pattern, vl);
# else
sendto_prefix_one(cptr, user, pattern,
p1, p2, p3, p4,
p5, p6, p7, p8);
# endif
break;
}
}
if (MyConnect(user))
# ifdef USE_VARARGS
vsendto_prefix_one(user, user, pattern, vl);
va_end(vl);
# else
sendto_prefix_one(user, user, pattern, p1, p2, p3, p4,
p5, p6, p7, p8);
# endif
return;
}
/*
* sendto_channel_butserv
*
* Send a message to all members of a channel that are connected to this
* server.
*/
#ifndef USE_VARARGS
/*VARARGS*/
void sendto_channel_butserv(chptr, from, pattern, p1, p2, p3,
p4, p5, p6, p7, p8)
aChannel *chptr;
aClient *from;
char *pattern, *p1, *p2, *p3, *p4, *p5, *p6, *p7, *p8;
{
#else
void sendto_channel_butserv(chptr, from, pattern, va_alist)
aChannel *chptr;
aClient *from;
char *pattern;
va_dcl
{
va_list vl;
#endif
Reg1 Link *lp;
Reg2 aClient *acptr;
#ifdef USE_VARARGS
for (va_start(vl), lp = chptr->members; lp; lp = lp->next)
if (MyConnect(acptr = lp->value.cptr) &&
!(lp->flags & CHFL_ZOMBIE))
vsendto_prefix_one(acptr, from, pattern, vl);
va_end(vl);
#else
for (lp = chptr->members; lp; lp = lp->next)
if (MyConnect(acptr = lp->value.cptr) &&
!(lp->flags & CHFL_ZOMBIE))
sendto_prefix_one(acptr, from, pattern,
p1, p2, p3, p4,
p5, p6, p7, p8);
#endif
return;
}
/*
** send a msg to all ppl on servers/hosts that match a specified mask
** (used for enhanced PRIVMSGs)
**
** addition -- Armin, 8jun90 (gruner@informatik.tu-muenchen.de)
*/
static int match_it(one, mask, what)
aClient *one;
char *mask;
int what;
{
switch (what)
{
case MATCH_HOST:
return (matches(mask, one->user->host)==0);
case MATCH_SERVER:
default:
return (matches(mask, one->user->server->name)==0);
}
}
/*
* sendto_match_servs
*
* send to all servers which match the mask at the end of a channel name
* (if there is a mask present) or to all if no mask.
*/
#ifndef USE_VARARGS
/*VARARGS*/
void sendto_match_servs(chptr, from, format, p1,p2,p3,p4,p5,p6,p7,p8,p9)
aChannel *chptr;
aClient *from;
char *format, *p1, *p2, *p3, *p4, *p5, *p6, *p7, *p8, *p9;
{
#else
void sendto_match_servs(chptr, from, format, va_alist)
aChannel *chptr;
aClient *from;
char *format;
va_dcl
{
va_list vl;
#endif
Reg1 Dlink *lp;
Reg2 aClient *cptr;
char *mask;
#ifdef USE_VARARGS
va_start(vl);
#endif
if (chptr)
{
if (*chptr->chname == '&')
return;
if (mask = (char *)rindex(chptr->chname, ':'))
mask++;
}
else
mask = NULL;
#ifdef USE_VARARGS
vsprintf(sendbuf, format, vl);
va_end(vl);
#else
sprintf(sendbuf, format, p1, p2, p3, p4, p5, p6, p7, p8, p9);
#endif
for (lp = me.serv->down; lp; lp = lp->next)
{
if ((cptr=lp->value.cptr) == from)
continue;
if (!BadPtr(mask) && matches(mask, cptr->name))
continue;
sendbufto_one(cptr);
}
}
/*
* sendto_match_butone
*
* Send to all clients which match the mask in a way defined on 'what';
* either by user hostname or user servername.
*/
#ifndef USE_VARARGS
/*VARARGS*/
void sendto_match_butone(one, from, mask, what, pattern,
p1, p2, p3, p4, p5, p6, p7, p8)
aClient *one, *from;
int what;
char *mask, *pattern, *p1, *p2, *p3, *p4, *p5, *p6, *p7, *p8;
{
#else
void sendto_match_butone(one, from, mask, what, pattern, va_alist)
aClient *one, *from;
int what;
char *mask, *pattern;
va_dcl
{
va_list vl;
#endif
Reg1 int i;
Reg2 aClient *cptr, *acptr;
#ifdef USE_VARARGS
va_start(vl);
#endif
for (i = 0; i <= highest_fd; i++)
{
if (!(cptr = local[i]))
continue; /* that clients are not mine */
if (cptr == one) /* must skip the origin !! */
continue;
if (IsServer(cptr))
{
for (acptr = client; acptr; acptr = acptr->next)
if (IsRegisteredUser(acptr)
&& match_it(acptr, mask, what)
&& acptr->from == cptr)
break;
/* a person on that server matches the mask, so we
** send *one* msg to that server ...
*/
if (acptr == NULL)
continue;
/* ... but only if there *IS* a matching person */
}
/* my client, does he match ? */
else if (!(IsRegisteredUser(cptr) &&
match_it(cptr, mask, what)))
continue;
#ifdef USE_VARARGS
vsendto_prefix_one(cptr, from, pattern, vl);
}
va_end(vl);
#else
sendto_prefix_one(cptr, from, pattern,
p1, p2, p3, p4, p5, p6, p7, p8);
}
#endif
return;
}
/*
* sendto_all_butone.
*
* Send a message to all connections except 'one'. The basic wall type
* message generator.
*/
#ifndef USE_VARARGS
/*VARARGS*/
void sendto_all_butone(one, from, pattern, p1, p2, p3, p4, p5, p6, p7, p8)
aClient *one, *from;
char *pattern, *p1, *p2, *p3, *p4, *p5, *p6, *p7, *p8;
{
#else
void sendto_all_butone(one, from, pattern, va_alist)
aClient *one, *from;
char *pattern;
va_dcl
{
va_list vl;
#endif
Reg1 int i;
Reg2 aClient *cptr;
#ifdef USE_VARARGS
for (va_start(vl), i = 0; i <= highest_fd; i++)
if ((cptr = local[i]) && !IsMe(cptr) && one != cptr)
vsendto_prefix_one(cptr, from, pattern, vl);
va_end(vl);
#else
for (i = 0; i <= highest_fd; i++)
if ((cptr = local[i]) && !IsMe(cptr) && one != cptr)
sendto_prefix_one(cptr, from, pattern,
p1, p2, p3, p4, p5, p6, p7, p8);
#endif
return;
}
/*
* sendto_lops_butone
*
* Send to *local* ops but one.
*/
#ifndef USE_VARARGS
/*VARARGS*/
void sendto_lops_butone(one, pattern, p1, p2, p3, p4, p5, p6, p7)
aClient *one;
char *pattern, *p1, *p2, *p3, *p4, *p5, *p6, *p7;
{
#else
void sendto_lops_butone(one, pattern, va_alist)
aClient *one;
char *pattern;
va_dcl
{
va_list vl;
#endif
Reg1 aClient *cptr;
Reg2 Dlink *lp;
char nbuf[1024];
(void)sprintf(nbuf, ":%s NOTICE %%s :*** Notice -- ", me.name);
#ifdef USE_VARARGS
va_start(vl);
(void)vsprintf(nbuf + strlen(nbuf), pattern, vl);
va_end(vl);
#else
(void)strncat(nbuf, pattern, sizeof(nbuf) - strlen(nbuf));
#endif
for (lp = me.serv->client; lp; lp=lp->next)
if ((cptr=lp->value.cptr)!=one && SendServNotice(cptr))
#ifdef USE_VARARGS
{
(void)sprintf(sendbuf, nbuf, cptr->name);
sendbufto_one(cptr);
}
#else
sendto_one(cptr, nbuf, cptr->name, p1, p2, p3, p4, p5, p6, p7);
#endif
return;
}
/*
* sendto_ops
*
* Send to *local* ops only.
*/
#ifndef USE_VARARGS
/*VARARGS*/
void sendto_ops(pattern, p1, p2, p3, p4, p5, p6, p7)
char *pattern, *p1, *p2, *p3, *p4, *p5, *p6, *p7;
{
#else
void sendto_ops(pattern, va_alist)
char *pattern;
va_dcl
{
va_list vl;
#endif
Reg1 aClient *cptr;
Reg2 int i;
char fmt[1024];
char *fmt_target;
#ifdef USE_VARARGS
va_start(vl);
#endif
(void)sprintf(fmt, ":%s NOTICE ", me.name);
fmt_target = &fmt[strlen(fmt)];
for (i = 0; i <= highest_fd; i++)
if ((cptr = local[i]) && !IsServer(cptr) && !IsMe(cptr) &&
SendServNotice(cptr))
{
strcpy(fmt_target, cptr->name);
strcat(fmt_target, " :*** Notice -- ");
strcat(fmt_target, pattern);
#ifdef USE_VARARGS
vsendto_one(cptr, fmt, vl);
#else
sendto_one(cptr, fmt, p1, p2, p3, p4, p5, p6, p7);
#endif
}
#ifdef USE_SERVICES
else if (cptr && IsService(cptr) &&
(cptr->service->wanted & SERVICE_WANT_SERVNOTE))
{
strcpy(fmt_target, cptr->name);
strcat(fmt, " :*** Notice -- ");
strcat(fmt, pattern);
# ifdef USE_VARARGS
vsendto_one(cptr, fmt, vl);
# else
sendto_one(cptr, fmt, cptr->name, p1, p2, p3, p4, p5, p6, p7);
# endif
}
#endif
#ifdef USE_VARARGS
va_end(vl);
#endif
return;
}
/*
** sendto_ops_butone
** Send message to all operators.
** one - client not to send message to
** from- client which message is from *NEVER* NULL!!
*/
#ifndef USE_VARARGS
/*VARARGS*/
void sendto_ops_butone(one, from, pattern, p1, p2, p3, p4, p5, p6, p7, p8)
aClient *one, *from;
char *pattern, *p1, *p2, *p3, *p4, *p5, *p6, *p7, *p8;
{
#else
void sendto_ops_butone(one, from, pattern, va_alist)
aClient *one, *from;
char *pattern;
va_dcl
{
va_list vl;
#endif
Reg1 int i;
Reg2 aClient *cptr;
#ifdef USE_VARARGS
va_start(vl);
#endif
for (i=0; i <= highest_fd; i++)
sentalong[i] = 0;
for (cptr = client; cptr; cptr = cptr->next)
{
if (!SendWallops(cptr))
continue;
i = cptr->from->fd; /* find connection oper is on */
if (sentalong[i]) /* sent message along it already ? */
continue;
if (cptr->from == one)
continue; /* ...was the one I should skip */
sentalong[i] = 1;
# ifdef USE_VARARGS
vsendto_prefix_one(cptr->from, from, pattern, vl);
}
va_end(vl);
# else
sendto_prefix_one(cptr->from, from, pattern,
p1, p2, p3, p4, p5, p6, p7, p8);
}
# endif
return;
}
/*
* to - destination client
* from - client which message is from
*
* NOTE: NEITHER OF THESE SHOULD *EVER* BE NULL!!
* -avalon
*/
#ifdef USE_VARARGS
void sendto_prefix_one(to, from, pattern, va_alist)
Reg1 aClient *to;
Reg2 aClient *from;
char *pattern;
va_dcl
{
va_list vl;
va_start(vl);
vsendto_prefix_one(to, from, pattern, vl);
va_end(vl);
}
void vsendto_prefix_one(to, from, pattern, vl)
Reg1 aClient *to;
Reg2 aClient *from;
char *pattern;
va_list vl;
{
#else
void sendto_prefix_one(to, from, pattern, p1, p2, p3, p4, p5, p6, p7, p8)
Reg1 aClient *to;
Reg2 aClient *from;
char *pattern, *p1, *p2, *p3, *p4, *p5, *p6, *p7, *p8;
{
#endif
static char sender[HOSTLEN+NICKLEN+USERLEN+5];
Reg3 anUser *user;
char *par;
int flag = 0;
#ifdef USE_VARARGS
par = va_arg(vl, char *);
#else
par = p1;
#endif
if (to && from && MyClient(to) && IsPerson(from) &&
!mycmp(par, from->name))
{
user = from->user;
(void)strcpy(sender, from->name);
if (user)
{
if (*user->username)
{
(void)strcat(sender, "!");
(void)strcat(sender, user->username);
}
if (*user->host && !MyConnect(from))
{
(void)strcat(sender, "@");
(void)strcat(sender, user->host);
flag = 1;
}
}
/*
** flag is used instead of index(sender, '@') for speed and
** also since username/nick may have had a '@' in them. -avalon
*/
if (!flag && MyConnect(from) && *user->host)
{
(void)strcat(sender, "@");
if (IsUnixSocket(from))
(void)strcat(sender, user->host);
else
(void)strcat(sender, from->sockhost);
}
par = sender;
}
#ifdef USE_VARARGS
/* Assuming 'pattern' always starts with ":%s ..." */
sprintf(sendbuf, ":%s", par);
vsprintf(sendbuf + strlen(sendbuf), &pattern[3], vl);
sendbufto_one(to);
#else
sendto_one(to, pattern, par, p2, p3, p4, p5, p6, p7, p8);
#endif
}
/*
* sendto_realops
*
* Send to *local* ops only but NOT +s nonopers.
*/
#ifndef USE_VARARGS
/*VARARGS*/
void sendto_realops(pattern, p1, p2, p3, p4, p5, p6, p7)
char *pattern, *p1, *p2, *p3, *p4, *p5, *p6, *p7;
{
#else
void sendto_realops(pattern, va_alist)
char *pattern;
va_dcl
{
va_list vl;
#endif
Reg1 aClient *cptr;
Reg2 int i;
char fmt[1024];
Reg3 char *fmt_target;
#ifdef USE_VARARGS
va_start(vl);
#endif
(void)sprintf(fmt, ":%s NOTICE ", me.name);
fmt_target = &fmt[strlen(fmt)];
for (i = 0; i <= highest_fd; i++)
if ((cptr = local[i]) && IsOper(cptr))
{
strcpy(fmt_target, cptr->name);
strcat(fmt_target, " :*** Notice -- ");
strcat(fmt_target, pattern);
#ifdef USE_VARARGS
vsendto_one(cptr, fmt, vl);
#else
sendto_one(cptr, fmt, p1, p2, p3, p4, p5, p6, p7);
#endif
}
#ifdef USE_VARARGS
va_end(vl);
#endif
return;
}

472
common/support.c Normal file
View File

@@ -0,0 +1,472 @@
/************************************************************************
* IRC - Internet Relay Chat, common/support.c
* Copyright (C) 1990, 1991 Armin Gruner
*
* 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 1, 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.
*/
#ifndef lint
static char sccsid[] = "@(#)support.c 2.21 4/13/94 1990, 1991 Armin Gruner;\
1992, 1993 Darren Reed";
#endif
#include "config.h"
#ifdef DYNIXPTX
#include <sys/timers.h>
#include <stddef.h>
#endif
#include "struct.h"
#include "common.h"
#include "sys.h"
extern int errno; /* ...seems that errno.h doesn't define this everywhere */
extern void outofmemory();
#ifdef NEED_STRTOKEN
/*
** strtoken.c -- walk through a string of tokens, using a set
** of separators
** argv 9/90
**
** $Id: support.c,v 1.1.1.1 1996/05/05 22:25:22 klmitch Exp $
*/
char *strtoken(save, str, fs)
char **save;
char *str, *fs;
{
char *pos = *save; /* keep last position across calls */
Reg1 char *tmp;
if (str)
pos = str; /* new string scan */
while (pos && *pos && index(fs, *pos) != NULL)
pos++; /* skip leading separators */
if (!pos || !*pos)
return (pos = *save = NULL); /* string contains only sep's */
tmp = pos; /* now, keep position of the token */
while (*pos && index(fs, *pos) == NULL)
pos++; /* skip content of the token */
if (*pos)
*pos++ = '\0'; /* remove first sep after the token */
else
pos = NULL; /* end of string */
*save = pos;
return(tmp);
}
#endif /* NEED_STRTOKEN */
#ifdef NEED_STRTOK
/*
** NOT encouraged to use!
*/
char *strtok(str, fs)
char *str, *fs;
{
static char *pos;
return strtoken(&pos, str, fs);
}
#endif /* NEED_STRTOK */
#ifdef NEED_STRERROR
/*
** strerror - return an appropriate system error string to a given errno
**
** argv 11/90
** $Id: support.c,v 1.1.1.1 1996/05/05 22:25:22 klmitch Exp $
*/
char *strerror(err_no)
int err_no;
{
extern char *sys_errlist[]; /* Sigh... hopefully on all systems */
extern int sys_nerr;
static char buff[40];
char *errp;
errp = (err_no > sys_nerr ? (char *)NULL : sys_errlist[err_no]);
if (errp == (char *)NULL)
{
errp = buff;
(void) sprintf(errp, "Unknown Error %d", err_no);
}
return errp;
}
#endif /* NEED_STRERROR */
/*
** inetntoa -- changed name to remove collision possibility and
** so behaviour is gaurunteed to take a pointer arg.
** -avalon 23/11/92
** inet_ntoa -- returned the dotted notation of a given
** internet number (some ULTRIX don't have this)
** argv 11/90).
** inet_ntoa -- its broken on some Ultrix/Dynix too. -avalon
** $Id: support.c,v 1.1.1.1 1996/05/05 22:25:22 klmitch Exp $
*/
char *inetntoa(in)
char *in;
{
static char buf[16];
Reg1 u_char *s = (u_char *)in;
Reg2 int a,b,c,d;
a = (int)*s++;
b = (int)*s++;
c = (int)*s++;
d = (int)*s++;
(void) sprintf(buf, "%d.%d.%d.%d", a,b,c,d );
return buf;
}
#ifdef NEED_INET_NETOF
/*
** inet_netof -- return the net portion of an internet number
** argv 11/90
** $Id: support.c,v 1.1.1.1 1996/05/05 22:25:22 klmitch Exp $
**
*/
int inet_netof(in)
struct in_addr in;
{
int addr = in.s_net;
if (addr & 0x80 == 0)
return ((int) in.s_net);
if (addr & 0x40 == 0)
return ((int) in.s_net * 256 + in.s_host);
return ((int) in.s_net * 256 + in.s_host * 256 + in.s_lh);
}
#endif /* NEED_INET_NETOF */
#ifdef DYNIXPTX
/* This is copied from ircu3.0.0 (with permission), not vica versa. */
int gettimeofday(tv, tz)
struct timeval *tv;
void *tz; /* Unused */
{
register int ret;
static struct timespec tp;
if ((ret=getclock(TIMEOFDAY, &tp)))
return ret;
tv->tv_sec=(long)tp.tv_sec;
tv->tv_usec=(tp.tv_nsec + 500) / 1000;
return 0;
}
#endif /* DYNIXPTX */
#if defined(DEBUGMODE)
void dumpcore(msg, p1, p2, p3, p4, p5, p6, p7, p8, p9)
char *msg, *p1, *p2, *p3, *p4, *p5, *p6, *p7, *p8, *p9;
{
static time_t lastd = 0;
static int dumps = 0;
char corename[12];
time_t now;
int p;
now = time(NULL);
if (!lastd)
lastd = now;
else if (now - lastd < 60 && dumps > 2)
(void)s_die();
if (now - lastd > 60)
{
lastd = now;
dumps = 1;
}
else
dumps++;
p = getpid();
if (fork()>0) {
kill(p, 3);
kill(p, 9);
}
write_pidfile();
(void)sprintf(corename, "core.%d", p);
(void)rename("core", corename);
Debug((DEBUG_FATAL, "Dumped core : core.%d", p));
sendto_ops("Dumped core : core.%d", p);
Debug((DEBUG_FATAL, msg, p1, p2, p3, p4, p5, p6, p7, p8, p9));
sendto_ops(msg, p1, p2, p3, p4, p5, p6, p7, p8, p9);
(void)s_die();
}
static char *marray[20000];
static int mindex = 0;
#define SZ_EX (sizeof(char *) + sizeof(size_t) + 4)
#define SZ_CHST (sizeof(char *) + sizeof(size_t))
#define SZ_CH (sizeof(char *))
#define SZ_ST (sizeof(size_t))
char *MyMalloc(x)
size_t x;
{
register int i;
register char **s;
char *ret;
ret = (char *)malloc(x + (size_t)SZ_EX);
if (!ret)
outofmemory();
bzero(ret, (int)x + SZ_EX);
bcopy((char *)&ret, ret, SZ_CH);
bcopy((char *)&x, ret + SZ_CH, SZ_ST);
bcopy("VAVA", ret + SZ_CHST + (int)x, 4);
Debug((DEBUG_MALLOC, "MyMalloc(%ld) = %#x", x, ret+8));
for(i = 0, s = marray; *s && i < mindex; i++, s++)
;
if (i < 20000)
{
*s = ret;
if (i == mindex)
mindex++;
}
return ret + SZ_CHST;
}
char *MyRealloc(x, y)
char *x;
size_t y;
{
register int l;
register char **s;
char *ret, *cp;
size_t i;
int k;
x -= SZ_CHST;
bcopy(x, (char *)&cp, SZ_CH);
bcopy(x + SZ_CH, (char *)&i, SZ_ST);
bcopy(x + (int)i + SZ_CHST, (char *)&k, 4);
if (bcmp((char *)&k, "VAVA", 4) || (x != cp))
dumpcore("MyRealloc %#x %d %d %#x %#x", x, y, i, cp, k);
ret = (char *)realloc(x, y + (size_t)SZ_EX);
if (!ret)
outofmemory();
bcopy((char *)&ret, ret, SZ_CH);
bcopy((char *)&y, ret + SZ_CH, SZ_ST);
bcopy("VAVA", ret + SZ_CHST + (int)y, 4);
Debug((DEBUG_NOTICE, "MyRealloc(%#x,%ld) = %#x", x, y, ret + SZ_CHST));
for(l = 0, s = marray; *s != x && l < mindex; l++, s++)
;
if (l < mindex)
*s = NULL;
else if (l == mindex)
Debug((DEBUG_MALLOC, "%#x !found", x));
for(l = 0, s = marray; *s && l < mindex; l++,s++)
;
if (l < 20000)
{
*s = ret;
if (l == mindex)
mindex++;
}
return ret + SZ_CHST;
}
void MyFree(x)
char *x;
{
size_t i;
char *j;
u_char k[4];
register int l;
register char **s;
if (!x)
return;
x -= SZ_CHST;
bcopy(x, (char *)&j, SZ_CH);
bcopy(x + SZ_CH, (char *)&i, SZ_ST);
bcopy(x + SZ_CHST + (int)i, (char *)k, 4);
if (bcmp((char *)k, "VAVA", 4) || (j != x))
dumpcore("MyFree %#x %ld %#x %#x", x, i, j,
(k[3]<<24) | (k[2]<<16) | (k[1]<<8) | k[0]);
#undef free
(void)free(x);
#define free(x) MyFree(x)
Debug((DEBUG_MALLOC, "MyFree(%#x)",x + SZ_CHST));
for (l = 0, s = marray; *s != x && l < mindex; l++, s++)
;
if (l < mindex)
*s = NULL;
else if (l == mindex)
Debug((DEBUG_MALLOC, "%#x !found", x));
}
#else
char *MyMalloc(x)
size_t x;
{
char *ret = (char *)malloc(x);
if (!ret)
outofmemory();
return ret;
}
char *MyRealloc(x, y)
char *x;
size_t y;
{
char *ret = (char *)realloc(x, y);
if (!ret)
outofmemory();
return ret;
}
#endif
/*
** read a string terminated by \r or \n in from a fd
**
** Created: Sat Dec 12 06:29:58 EST 1992 by avalon
** Returns:
** 0 - EOF
** -1 - error on read
** >0 - number of bytes returned (<=num)
** After opening a fd, it is necessary to init dgets() by calling it as
** dgets(x,y,0);
** to mark the buffer as being empty.
*/
int dgets(fd, buf, num)
int fd, num;
char *buf;
{
static char dgbuf[8192];
static char *head = dgbuf, *tail = dgbuf;
register char *s, *t;
register int n, nr;
/*
** Sanity checks.
*/
if (head == tail)
*head = '\0';
if (!num)
{
head = tail = dgbuf;
*head = '\0';
return 0;
}
if (num > sizeof(dgbuf) - 1)
num = sizeof(dgbuf) - 1;
dgetsagain:
if (head > dgbuf)
{
for (nr = tail - head, s = head, t = dgbuf; nr > 0; nr--)
*t++ = *s++;
tail = t;
head = dgbuf;
}
/*
** check input buffer for EOL and if present return string.
*/
if (head < tail &&
((s = index(head, '\n')) || (s = index(head, '\r'))) && s < tail)
{
n = MIN(s - head + 1, num); /* at least 1 byte */
dgetsreturnbuf:
bcopy(head, buf, n);
head += n;
if (head == tail)
head = tail = dgbuf;
return n;
}
if (tail - head >= num) /* dgets buf is big enough */
{
n = num;
goto dgetsreturnbuf;
}
n = sizeof(dgbuf) - (tail - dgbuf) - 1;
nr = read(fd, tail, n);
if (nr == -1)
{
head = tail = dgbuf;
return -1;
}
if (!nr)
{
if (head < tail)
{
n = MIN(tail - head, num);
goto dgetsreturnbuf;
}
head = tail = dgbuf;
return 0;
}
tail += nr;
*tail = '\0';
for (t = head; (s = index(t, '\n')); )
{
if ((s > head) && (s > dgbuf))
{
t = s-1;
for (nr = 0; *t == '\\'; nr++)
t--;
if (nr & 1)
{
t = s+1;
s--;
nr = tail - t;
while (nr--)
*s++ = *t++;
tail -= 2;
*tail = '\0';
}
else
s++;
}
else
s++;
t = s;
}
*tail = '\0';
goto dgetsagain;
}

40
doc/Advertisement Normal file
View File

@@ -0,0 +1,40 @@
The Internet Relay Chat Program - IRC
Author: Jeff Trim, April '89
Revised: Greg Lindahl, Oct '90 (gl8f@virginia.edu)
Re-Revised: Helen Rose, March '94 (hrose@kei.com)
Have you ever wanted to talk with other computer users in other parts of
the world? Well guess what? You can! The program is called IRC and it
is networked much over North America, Europe, and Asia, Oceania, and parts
of Africa. This program is a substitution for talk(1), ytalk(1) and many
other multiple talk programs you might have read about. When you are
talking in IRC, everything you type will instantly be transmitted around
the world to other users that might be watching their terminals at the
time - they can then type something and RESPOND to your messages - and
vise versa. I should warn you that the program can be very addictive once
you begin to make friends and contacts on IRC ;-) especially when you
learn how to cuss in 14 languages.
Topics of discussion on IRC are varied, just like the topics of Usenet
newsgroups are varied. Technical and political discussions are
popular, especially when world events are in progress. IRC is also a
way to expand your horizons, as people from many countries and
cultures are on, 24 hours a day. Most conversations are in English,
but there are always channels in German, Japanese, and Finnish, and
occasionally other languages.
How To Get IRC (technical)
IRC is a fully-distributed client-server system, much like
NNTP-Usenet, with several clients availble in C and elisp. You may ftp
documentation and clients from any of the following sites:
many kinds of clients (C, elisp, X11, VMS, REXX for VM, MSDOS, Macintosh):
cs.bu.edu:/irc/clients
ftp.acsu.buffalo.edu:/pub/irc
ftp.funet.fi:/pub/unix/irc
coombs.anu.edu.au:/pub/irc
If you have any questions about IRC installation, write to hrose@kei.com.

153
doc/Authors Normal file
View File

@@ -0,0 +1,153 @@
/************************************************************************
* IRC - Internet Relay Chat, doc/AUTHORS
* Copyright (C) 1990
*
* AUTHORS FILE:
* This file attempts to remember all contributors to the IRC
* developement. Names can be only added this file, no name
* should never be removed. This file must be included into all
* distributions of IRC and derived works.
*
* 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 1, 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.
*/
IRC was conceived of and written by Jarkko Oikarinen <jto@tolsun.oulu.fi>.
IRC was originally written in University of Oulu, Computing Center.
Jan 1991 - IRC 2.6 jto@tolsun.oulu.fi
- Multiple Channels and protocol changes
Contributions were made by a cast of dozens, including the following:
Markku Jarvinen <mta@tut.fi>: Emacs-like editing facility for the client
Kimmo Suominen <kim@kannel.lut.fi>: HP-UX port
Jeff Trim <jtrim@orion.cair.du.edu>: enhancements and advice
Vijay Subramaniam <vijay@lll-winken.llnl.gov>: advice and ruthless publicity
Karl Kleinpaste <karl@cis.ohio-state.edu>: user's manual
Greg Lindahl <gl8f@virginia.edu>: AUTOMATON code, the Wumpus GM automaton,
myriad bug fixes
Bill Wisner <wisner@hayes.fai.alaska.edu>: numerous bug fixes and code
enhancements
Tom Davis <conslt16@zeus.unl.edu> and Tim Russell <russell@zeus.unl.edu>:
VMS modifications
Markku Savela <msa@tel4.tel.vtt.fi>: advice, support, and being the
incentive to do some of our *own* coding. :)
Tom Hopkins <hoppie@buengf.bu.edu>: bug fixes, quarantine lines,
consolidation of various patches.
Christopher Davis <ckd@cs.bu.edu>: EFnet/Anet gateway coding,
many automata ;), documentation fixing.
Helen Rose <hrose@cs.bu.edu>: documentation updating, and fixing.
Tom Hinds <rocker@bucsf.bu.edu>: emacs client updating.
Tim Miller <cerebus@bu-pub.bu.edu>: various server and client-breaking
features.
Darren Reed <avalon@coombs.anu.edu.au>: various bug fixes and enhancements.
Introduced nickname and channelname hash tables into the server.
The version 2.2 release was coordinated by Mike Bolotski
<mikeb@salmon.ee.ubc.ca>.
The version 2.4 release was coordinated by Markku Savela and
Chelsea Ashley Dyerman
The version 2.5.2 release was coordinated by Christopher Davis, Helen Rose,
and Tom Hopkins.
The versions 2.6.2, 2.7 and 2.8 releases were coordinated by Darren Reed.
Contributions for the 2.8 release from the following people:
Matthew Green <phone@coombs.anu.edu.au>
Chuck Kane <ckane@ece.uiuc.edu>
Matt Lyle <matt@oc.com>
Vesa Ruokonen <ruokonen@lut.fi>
Markku Savela <Markku.Savela@vtt.fi> / April 1990
Fixed various bugs in 2.2PL1 release server (2.2msa.4) and changed
sockets to use non-blocking mode (2.2msa.9). [I have absolutely
nothing to do with clients :-]
Chelsea Ashley Dyerman <chelsea@earth.cchem.berkeley.edu> / April 1990
Rewrote the Makefiles, restructuring of source tree. Added libIrcd.a to
the Makefile macros, numerous reformatting of server text messages, and
added mkversion.sh to keep track of compilation statistics. Numerous
bug fixes and enhancements, and co-coordinator of the 2.4 release.
Jarle Lyngaas (nmijl@alf.uib.no) added Note functions to ircd.
Armin Gruner <gruner@informatik.tu-muenchen.de> / May, June 1990:
* Patched KILL-line feature for ircd.conf, works now.
Enhancement: Time intervals can be specified in passwd-field.
Result: KILL-Line is only active during these intervals
* Patched PRIVMSG handling, now OPER can specify masks for sending
private messages, advantage: msg to all at a specified server or host.
* Little tests on irc 2.5 alpha, fixed some little typos in client code.
Change: common/debug.c has been moved to ircd/s_debug.c, and a
irc/c_debug.c has been created, for the benefit that wrong server msg
are displayed if client does not recognize them. (strange, if a server
sends an 'unknown command', isn't it?)
Tom Hopkins <hoppie@buengf.bu.edu> / September, October 1990:
* Patched msa's K lines for servers (Q lines).
* Consolidated several patches, including Stealth's logging patch.
* Fixed several minor bugs.
* Has done lots of other stuff that I can't seem to remember, but he
always works on code, so he has to have done alot more than three
lines worth. :)
Thanks go to those persons not mentioned here who have added their advice,
opinions, and code to IRC.
Various modifications, bugreports, cleanups and testing by:
Hugo Calendar <hugo@ucscb.ucsc.edu>
Bo Adler <adler@csvax.cs.caltech.edu>
Michael Sandrof <ms5n+@andrew.cmu.edu>
Jon Solomon <jsol@cs.bu.edu>
Jan Peterson <jlp@hamblin.math.byu.edu>
Nathan Glasser <nathan@brokaw.lcs.mit.edu>
Helen Rose <hrose@eff.org>
Mike Pelletier <stealth@caen.engin.umich.edu>
Basalat Ali Raja <gwydion@tavi.rice.edu>
Eric P. Scott <eps@toaster.sfsu.edu>
Dan Goodwin <fornax@wpi.wpi.edu>
Noah Friedman <friedman@ai.mit.edu>
1991 - 1996 :
The Undernet version, starting off with 2.8.10, contains thousands of hours
of work by Run (carlo@runaway.xs4all.nl). The number of protocol enhancements,
changes and additions that have been added are too many to summarize.
Various additions and bugfixes have been contributed by:
SeKs <intru@step.polymtl.ca> - Review member coder-com
WildThang <dvmitche@antietam.nssl.uoknor.edu> - Review member coder-com
Kev <klmitch@mit.edu> - Secretary coder-com
Cym <cym@misha.net>
Xorath <vorac@wheel.dcn.davis.ca.us>
smg <smg@lm.com>
Chaos <simon@troll.elec.uow.edu.au>
Aaron <agifford@sci.dixie.edu>

126
doc/Crule.readme Normal file
View File

@@ -0,0 +1,126 @@
SmartRoute
Rule based connects
Draft 4 - Aug 19, 1994
by Tony Vencill
Rule based connects allow an admin to specify under what conditions
a connect should not be allowed. If no rules are specified for a
given C and/or N line it will be allowed under any condition.
A rule may consist of any legal combination of the following functions
and operators.
Functions
---------
connected(targetmask) - true if a server other than that processing
the rule is connected that matches the
target mask
directcon(targetmask) - true if a server other than that processing
the rule is directly connected that matches
the target mask
via(viamask, targetmask) - true if a server other than that processing
the rule matches the target mask and is
connected via a directly connected server
that matches the via mask
directop() - true if an oper is directly connected
Unary operators
---------------
! eg: !argument - true if the argument is false
Binary operartors
-----------------
&& eg: arg1&&arg2 - true if arg1 and arg2 are both true
|| eg: arg1||arg2 - true if arg1, arg2, or both are true
Parenthesis () are allowed for grouping arguments, but if no parenthesis
are included, && will take precedence over ||, ! will take precedence
over both && and ||, and the function will be evaluated from left to
right. White space in a rule is ignored. Invalid characters in a rule
will lead to the rule being ignored.
Examples
--------
A simple example of a connect rule might be:
connected(*eu.under*)
This might be used in a US undernet server for a Europe CN pair to
insure that a second Europe link is not allowed if one US-EU link
already exists. Note that on the undernet, US server names are
city.state.us.undernet.org and Europe server names are
city.country.eu.undernet.org.
A more interesting example might be:
connected(*eu.under*) &&
( !direct(*eu.under*) || via(manhat*, *eu.under*) )
Imagine the Boston undernet server uses this rule on its Europe CN
pairs. This says that if a Europe server is already connected, a
Boston-Europe connect will not be allowed. It also says that if a
Europe server does already exist and Boston is not directly connected
to one or more Europe servers or Manhattan is, the Boston-Europe
connect will not be allowed. This has the effect of allowing multiple
US-EU links but attempting to limit these links to one server (ie:
Boston will not initiate its first Europe link if another server is
already linking Europe). This rule will also prefer to let Manhattan
handle the US-EU link by disallowing Boston-Europe links if a Europe
server is already linked to Manhattan.
A example of the remaining function, directop(), is:
connected(*eu.under*) || directop()
If this line is used on Boston for the Paderborn CN pair, it will allow
connects to Paderborn only if another Europe server is not already
connected and there is not an oper on Boston. If this rule is
overrideable (ie: is applied only to autoconnects as described below),
then it will disallow Boston autoconnects to Paderborn while a Boston
oper is online, but allow oper-initiated connects to Paderborn under any
circumstance. This directop() function could be used to invoke less
prefered routes only when an oper is not present to handle routing, or
conversly to allow use of less preferable routes only when an oper is
present to monitor their performance.
ircd.conf entries
-----------------
A rule is listed in the ircd.conf file using a D or d line (which can
be thought of as a "disallow" line). D lines will apply to all oper
and server originated connects, while d lines will apply only to
autoconnects (ie: they are overrideable by opers). The formats are:
D:targetmask::rule
d:targetmask::rule
Remember that newlines are not allowed in conf lines. Two examples
(from above) are:
D:*eu.under*::connected(*eu.under*)
d:*eu.under*::connected(*eu.under*) || directop()
Connects originating from other servers will be checked against and
matching D lines, while matching d lines will be ignored as it will not
be clear whether or not the connection attempt is oper initiated.
Checking and viewing rules
--------------------------
The chkconf program that comes with the servers has been modified to
also check your connect rules. If running in debug mode, parsing errors
will show up at debug level 8. To view rules online, "/stats d" can be
used to see all rules and "/stats D" can be used to view those rules
which affect oper initiated connects and accepts.
Processing and storage
----------------------
The rules are parsed when the conf file is read and transformed into a
more efficiently computed form, then all applicable rules are
evaluated each time a connect command is given or an autoconnect is
due. If more than one applicable rule is given, only one need
evaluate to true for the connect to be allowed (ie: the rules are ored
together). Note that conditions that exist when the connect is
initiated might differ from conditions when the link is established.

84
doc/Etiquette Normal file
View File

@@ -0,0 +1,84 @@
/************************************************************************
* IRC - Internet Relay Chat, doc/etiquette
* Copyright (C) 1990, Lea Viljanen and Ari Husa
*
* 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 1, 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.
*/
HOW TO BEHAVE ON IRC
Authors: Lea Viljanen (LadyBug) viljanen@kreeta.helsinki.fi
Ari Husa (luru) so-luru@tolsun.oulu.fi
1) Language
The most widely understood and spoken language on IRC is English.
However! As IRC is used in many different countries, English is by
no means the only language. If you want to speak some other language
than English (for example with your friends), go to a separate channel
and set the topic (with /topic) to indicate that. For example
/topic Finnish only!
would mean that this channel would be reserved for Finnish discussion.
On the other hand, you should check the topic (with /list command)
before you move to a channel to see if there are any restrictions about
language.
On a channel not restricted by /topic, please speak a language
everybody can understand. If you want to do otherwise, change channels
and set the topic accordingly.
2) Hello/Goodbye
It's not necessary to greet everybody on a channel personally.
Usually one "Hello" or equivalent is enough. And don't expect everybody
to greet you back. On a channel with 20 people that would mean one
screenful of hellos. It's sensible not to greet, in order not to be rude
to the rest of the channel. If you must say hello, do it with a private /msg.
The same applies to goodbyes.
3) Discussion
When you come to a new channel it's advised you to listen
for a while to get an impression of what's discussed. Please feel free
to join in, but do not try to force your topic into the discussion
if that doesn't come naturally.
4) {}|[]\
IRC has quite a lot of people from Scandinavian countries,
the above characters are letters in their alphabet. This
has been explained on IRC about a thousand and one times, so
read the following, do not ask it on IRC:
{ is an A with 2 dots over it
} is an A with a small circle above it
| is either an O with 2 dots over it or an O with a dash (/) through it
[, ], and \ are the preceding three letters in upper case.
There are a lot of people from Japan as well, who use Kanji characters
which may look quite exotic as well. As I don't know Kanji I don't
even try to explain any of the characters.
5) ATTENTION!
Remember, people on IRC form their opinions about you only by
your actions, writings and comments on IRC. So think before you type.
Do not "dump" to a channel or user (send large amounts of unwanted
information). This is likely to get you /kicked off the channel or
/killed off from irc. Dumping causes network 'burbs', connections going
down because servers cannot handle the large amount of traffic any more.

63
doc/Europe/CoordEBIC Normal file
View File

@@ -0,0 +1,63 @@
############################################################################
If you like in future to establish a link inside the EBIC area,
please contact the coordinator of the affected toplevel domain.
This coordinator will discuss the link with affected local server
admins and inform other EBIC members about new links. Also a good
idea is to join #EU-Opers and discuss the new link there.
############################################################################
These toplevel domains are currently participating EBIC:
############################################################################
*.at *.ch *.de *.dk *.fi *.fr *.it *.nl *.no *.pl *.se *.uk
############################################################################
The following national coordinators have been choosen for 92/93:
############################################################################
*.at EASINET, ACONET
1. Tom Tom Kovar <Tom.Kovar@rcvie.co.at>
*.ch SWITCH, EUNET/CH
1. StarNet Karim Saouli <Karim.Saouli@epfl.ch>
2. Maxim Maxim Samo <samo@nessie.cs.id.ethz.ch>
*.de WIN, BelWue
1. YeggMan Volker Paulsen <Volker.Paulsen@gmd.de>
2. Haegar Thomas Thissen <tici@uni-paderborn.de>
*.dk DENET, DKNET
1. karthy Karsten Thygesen <karthy@iesd.auc.dk>
2. MAGNA Jens Fallesen <fallesen@login.dkuug.dk>
*.fi FUNET
1. Vesa Vesa Ruokonen <Vesa.Ruokonen@lut.fi>
2. Visti Hannu Visti <visti@sauna.cs.hut.fi>
*.fr EASINET/ROCAD, RENATER
1. Nono Arnaud Girsch <Arnaud.Girsch@insa-lyon.fr>
2. Le_Chat Laurent Montaron <irc@eurecom.fr>
*.it CILEA
1. Allanon Riccardo Facchetti <riccardo@cdc835.cdc.polimi.it>
2. mAu Maurizio Paoluzi <paoluzi@mercurio.dm.unirm1.it>
*.nl SURFNET/NLNET
1. scorpio Cor Bosman <bosman@gene.fwi.uva.nl>
2. Erwin Erwin Bolwidt <erwin@mars.let.uva.nl>
*.no UNINETT
1. Veggen Vegard Engen <vegard@bih.no>
*.pl POLIP
1. Artur Artur Jaroszek <artur@vulcan.mimuw.edu.pl>
*.se SUNET
1. Black Christer H. Jansson <svarten@solace.hsh.se>
2. Sorg Owe A Rasmussen <d1rasmus@dtek.chalmers.se>
*.uk JANET, JIPS
1. ScottM Scott A. McIntyre <scott@shrug.dur.ac.uk>

171
doc/Europe/IRCNO Normal file
View File

@@ -0,0 +1,171 @@
European Board of IRC Coordinators - Norway
Email: op-no@nvg.unit.no
Versjon: 1.01-001
Dokument: IRCNO-ORRO 06.07.93 - 03:51
File: flode.nvg.unit.no:/pub/irc/ircno/english
--------------------------------------------------------------------------------
IRCNO in English.
IRCNO is the Norwegian name for EBIC - Norway.
Introduction
~~~~~~~~~~~
The purpose of IRCNO is to make IRC in Norway as effective as
possible. To achieve this, it has to seperate components, an
administrative and a techincal.
The administrative component enforces compliance with the IRC rules in
Norway. The purpose of the rules is not to make operators net-police,
but action must nonetheless be taken when rules are not complied with.
Furthermore, we create national statistics on servers and users
connection time. (This info is however only available to the operators).
We also document IRC in Norway, and keep information files updated.
Finally, we give heavy user-support. All documentation, information
files, and user-support files are in the Norwegian language.
The technical component consist mainly of ensuring the proper and
reliable functioning of Norwegian servers and links, so that IRC in
Norway is compatible with the rest of the EBIC IRC Net.
IRCNO also has its own email adress for any inquiries: op-no@nvg.unit.no
IRCNO has official support from the Norwegian academic network provider
- UNINETT.
IRCNO tasks
~~~~~~~~~~
Here is a list that defines IRCNO's tasks.
1) Take care of the Norwegian IRC servers.
2) Enforce the rules for IRC use in Norway.
3) Be responsible toward UNINETT.
4) Make statistics.
5) Document IRC in Norway.
6) User support.
Rules of IRC use in Norway
~~~~~~~~~~~~~~~~~~~~~~~~~
We have 3 kinds of rules, user-bot, operator and server-admin.
Here is a short translation of the rules
USER-RULES - The following is not allowed:
1) Fake userids, or trying to hide the real user-id.
2) Being intentionally offensive to another user.
3) Dumping a lot of text to a public channel.
4) Constant beeping on a channel.
5) Anything that will reduce the techincal functionality of IRC.
6) Harrasement defined by Norwegian Civil Law.
7) Using offencive words in channel topics on public channels.
8) Destroys the integrity of information.
9) Compromise private communication.
BOT-RULES - The following guidelines must be followed:
1) Bots must not have fake userid unless given permission.
2) Bots must not send a message to a user not activating it.
3) Bots must be invisible unless they perform a good "irc-deed".
4) Bots must only answer to PRIVMSG by using NOTICE.
Dispensation from some of the bot-rules may be given under certain
circumstances.
OPERATOR RULES
This guide gives guidelines on what is not good and what is good.
Stuff that is not allowed:
- Using SQUIT / CONNECT to gain channel-operator-status.
- Mindless use of KILL.
- Using TRACE to find invisible users.
Stuff that is allowed:
- Using SQUIT / CONNECT to "fix" the net. This is normally not
allowed and should be used with care. The IRCNO tries to make
efficient use of automatic routing.
- KILL should only be used when a user ask to be killed. KILL can
also be used if it's based in a certain paragraph of the USER
rule file.
SERVER RULES
Following is the EBIC-Rules conserning linking. For domestic
linking we have our own rules.
1) To get a server connect to the Norwegian IRC-net:
a. New servers must only be leafs.
b. New servers must have one primary- and one secondary link.
c. New servers should only have one active link at a time.
d. The new server must have enough users.
2) New server connections should be discussed among the existing oper/admins.
3) Any link should follow the physical net-topology.
4) A server that is not close to a regional UNINETT net center should not
perform as a HUB server.
5) Every server in Norway takes part in the national user-staistic.
6) If hostmasking is to be used, every server behind a mask must be able
to connect to the up-host.
ADMIN RULES
1) An irc-admin must be available by email, unless he/she notifies IRCNO
about any longer planned absence.
2) A server-admin's duty is to have his/her server perform well for
the end-users and other servers on the irc-net.
3) An irc-admin must upgrade his/her server and tune it according to
something suitable as soon as a server-release is known to be
relatively stable.
4) An irc-admin that is not following these rules can loose his/her links
if 100% of IRCNO agrees.
Persons in IRCNO
~~~~~~~~~~~~~~~
We do not have any leader or jobs, but we do preform certain tasks.
Every decision is taken by discussion and voting. We do not have any
problem with this, and no nasty disagreements occur. This we belive
is because of our Norwegian Nature :-)
Who is Who is documentet in the file called irc-no. Norwegian titles
in paranthesis.
IRCNO secretary (IRCNO sekret{r)
Keeps track and system of all docs that are produced within IRCNO.
The updating of the various documents is left to the one who has
the administrative job with the document.
Filearchive (Filarkiv)
Keeps the anonymous FTP archie at flode.nvg.unit.no up-to date.
The archive is also accessible by FSP. The archive consist of
IRCNO docs, IRC docs in general, and IRC software.
This person also administrate the two mailinglists that exist (IRCNO
and a IRC-user list)
Statistics: (Statistikk)
Does the monthly stats of IRC-use in Norway.
EBIC contact (EBIC kontakt)
This task is defined in the EBIC-rules.
Link master (Link ansvarlig)
Job is to find the best links for Norwegian servers, and how they
should connect to each other. In link-matters this person often
has the last word. The link master write a link-report from time
to time (found on the archive as "links"). This report is the only
english document beside this one. This person must have good
knowlege on net-structure in Norway and how the server-linking works.
UNINETT contact (UNINETT kontakt)
UNINETT want one contact person. This person will likely aslo be
known as the one who is "responsible for IRC in Norway".
Other stuff
~~~~~~~~~~~
For a list of servers and their associated persons, see the file irc-no
under "servere in IRCNO".
This document is proof-read by Espen Anneling (anneling@uiowa.edu)

90
doc/Europe/RulesEBIC Normal file
View File

@@ -0,0 +1,90 @@
########################################################################
##### RULES FOR ESTABLISHING NEW IRC SERVERS IN EUROPE (v1.1) #####
########################################################################
1.) Establishing a new server and inner domain linking should be
a local toplevel domain (country) decision.
Guidelines:
+ New servers should be leafed until their admin(s)
have sufficient experience to handle their server
responsibly. (This avoids routing disasters).
+ Only a link for ONE server should be given to the new
server site, that means the new site shouldn't be able to
connect test-servers to other than its own server.
(This avoids confusion about linking hierachy).
+ Be sure that if a toplevel domain hostmask link is given,
all hubs of that domain can connect the masked server!
(this should avoid disagreement between serveral hub
admins in one domain).
2.) All other links between toplevel domains (countries) should be
dicussed between the major link coordinators of each toplevel
domain (country). These coordinators are called European Board
of IRC Coordinators (EBIC).
Guidelines:
+ Major link coordinators of each toplevel domain (country)
should be published with the server sourcecode in
directory ./doc/Europe
+ Each toplevel domain (country) participating in the
European IRC net must have a coordinator, who is
responsible for country-internal connections AND
represents the country in contacts with the rest of the
world. This person(s) is (are) chosen by their domain,
but must be approved by the EBIC.
+ The EBIC is the only executive in charge of European
interconnections and of connections from Europe to the
rest of the world. They will decide linking issues
WITH the affected local admins.
+ For establishing new links between several toplevel
domains the affected EBIC coordinators should be
consulted. If further coordination is needed it should
be discussed within the EBIC.
+ Additional note: International links should also take
care of the network topology, so even if several national
opers agree on a same international link, they might be
wrong and use unecessary network ressources. The EBIC
should avoid such linking.
+ Any major linking change should be announced in the
european mailing list:
IRC-Operators Europe <irc-eu@grasp.insa-lyon.fr>
3.) Cracked servers are the concern of EBIC, overiding all local
interests.
Guidelines:
+ In a server with non-standard source code which breaks
the current irc protocol (especially the incorrect
manipulation of channel modes and user/hostname authen-
tication) EBIC will take action.
+ The recommended action is permanent withdrawl of the
server from the IRC-net by removal from all its uplinks
configuration files.
4.) A prerequisite for getting a NEW server connection within
Europe is an understanding of and compliance to the above
rules.
Guideline:
+ All new admins should get a copy of these rules.
############################################################################

961
doc/INSTALL Normal file
View File

@@ -0,0 +1,961 @@
/************************************************************************
* IRC - Internet Relay Chat, doc/INSTALL
* Copyright (C) 1990,1991,1992, Jeff Trim, Mike Bolotski,
* Jarkko Oikarinen and Darren Reed.
*
* 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 1, 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.
*/
Installing IRC - The Internet Relay Chat Program
Overview of this document:
1) The config.h file
2) Editing the Makefile
3) Compiling IRC
4) The ircd.conf file
1) Edit the "config.h" file and make changes to the various #DEFINE's:
a) Copy the config.h.dist file to config.h before editing.
b) Define what type of UNIX your machine uses.
Pick the machine type which best describes your machine and change
the #undef to #define (if needed). Some flavours of Unix require no
#define and in such cases all others should be #undef'd.
c) DEBUGMODE
Define DEBUGMODE if you want to see the ircd debugging information
as the daemon is running. Normally this function will be undefined
as ircd produces a considerable amount of output. DEBUGMODE must be
defined for either of -t or -x command line options to work.
d) DPATH, SPATH, CPATH, MPATH, LPATH, PPATH
DPATH is provided so that the other pathnames (SPATH, CPATH, etc)
may be provided in just filename form. When the server starts, it
chdir's to DPATH before chroot or any other file operation, making
it the "current directory" for the server. This is where core files
will go if it core dumps.
Define SPATH to be the directory path to ircd. This is usually
/usr/local/bin/ircd, unless you don't have installation permission
there.
Define CPATH to be the directory path to the "irc.conf" file.
This path is usually /usr/local/lib/irc.conf. The format of this file
will be discussed later.
The LPATH #define should be set to "/dev/null" unless you plan to
debug the program. Note that the logfile grows very quickly.
Define MPATH to be the path to the 'motd' (message of the day) file
for the server. Keep in mind this is displayed whenever anyone
signs on to your server.
The PPATH is optional, but if defined, should point to a file which
either doesn't exist (but is creatable) or a previously used PPATH
file. It is used for storing the server's PID so a ps(1) isn't
necessary.
e) CHROOTDIR
To use the CHROOTDIR feature, make sure it is #define'd and that
the server is being run as root. The server will chroot to the
directory name provded by DPATH.
f) ENABLE_SUMMON, ENABLE_USERS
For security conscious server admins, they may wish to leave
ENABLE_USERS undefined, disabling the USERS command which can be used
to glean information the same as finger can. ENABLE_SUMMON toggles
whether the server will attempt to summon local users to irc by
writing a message similar to that from talk(1) to a user's tty.
g) SHOW_INVISIBLE_LUSERS, NO_DEFAULT_INVISIBLE
On large IRC networks, the number of invisible users is likely to
be large and reporting that number cause no pain. To aid and effect
this, SHOW_INVISIBLE_LUSERS is provided to cause the LUSERS command
to report the number of invisible users to all people and not just
operators. The NO_DEFAULT_INVISIBLE define is used to toggle whether
clients are automatically made invisible when they register.
h) OPER_KILL, OPER_REHASH, OPER_RESTART, LOCAL_KILL_ONLY
The three operator only commands, KILL, REHASH and RESTART, may all
be disabled to ensure that an operator who does not have the correct
privilidges does not have the power to cause untoward things to occur.
To further curb the actions of guest operators, LOCAL_KILL_ONLY can
be defined to only allow locally connected clients to be KILLed.
i) The rest of the user changable #define's should be pretty much self
explanatory in the config.h file. It is *NOT* recommended that any
of the file undef the line with "STOP STOP" in it be changed.
3) Configure and compile the code.
Edit the root Makefile for the server, uncomment/comment the correct
CFLAGS/IRCDLIBS lines as appropriate for your system.
Change DESTDIR to be the same as the path for DPATH in config.h.
Type "make". This will compile the server, the client, and the services.
At the end of this step, the server directory will contain 'ircd',
and the client directory will contain 'irc'. To get the server installed,
type "make install" which will build a default m4 file for preprocessing,
copy example.conf and put the server all in DESTDIR. The irc client and
a copy of the server will also be placed in BINDIR and the modes set
accordingly.
4) The ircd.conf file.
After installing the ircd and irc programs, edit the irc.conf file
as per the instructions in this section and install it in the
location you specified in the config.h file. There is a sample
conf file called example.conf in the /doc directory.
Appendix A describes the differences between IP addresses and host
names. If you are unfamiliar with this, you should probably scan
through it before proceeding.
The irc.conf file contains various records that specify configuration
options. The record types are as follows:
1. Server connections (C,N)
2. Machine information (M)
3. Client connections (I)
4. Default local server (U)
5. Operator priviliges (O)
6. Administrative info (A)
7. Excluded accounts (K)
8. Excluded machines (Q)
9. Connection Classes (Y)
10. Leaf connections (L)
11. Service connections (S)
12. Port connections (P)
13. Hub connections (H)
1. SERVER CONNECTIONS: How to connect to other servers
How other servers can connect to you
WARNING:
The hostnames used as examples are really only examples and
not meant to be used (simply because they don't work) in real life.
Now you must decide WHICH hosts you want to connect to and WHAT ORDER you
want to connect to them in. For my example let us assume I am on the
machine "rieska.oulu.fi" and I want to connect to irc daemons on 3 other
machines:
"garfield.mit.edu" - Tertiary Connection
"irc.nada.kth.se" - Secondary Connection
"nic.funet.fi" - Primary Connection
And I prefer to connect to them in that order, meaning I first want to
try connecting to "nic.funet.fi", then to "irc.nada.kth.edu", and
finally to "garfield.mit.edu". So if "nic.funet.fi" is down or
unreachable, the program will try to connect to "irc.nada.kth.se".
If irc.nada.kth.se is down it will try to connect to garfield and so forth.
PLEASE limit the number of hosts you will attempt to connect to down to 3.
This is because of two main reasons:
a) to save your server from causing extra load and delays
to users
b) to save internet from extra network traffic
(remember the old rwho program with traffic problems when
the number of machines increased).
The format for the CONNECT entry in the "irc.conf" is:
C:<TARGET Host Addr>:<Password>:<TARGET Host NAME>:<TARGET Host PORT>
Field: 1 2 3 4 5
for example:
C:nic.funet.fi:passwd:nic.funet.fi:6667
- or -
C:128.214.6.100:passwd:nic.funet.fi:6667
- or -
C:root@nic.funet.fi:passwd:nic.funet.fi:6667
Explanation:
Each field is separated with a ":" charcter:
Field 1: Field 1 tells the IRC program which option is being configured.
"C" corresponds to a server Connect option.
Field 2: Specifies the host name or IP address of the machine to connect
to. If "user@" prefixes the actual hostname or IP address
the server will require that the remote username returned by
the ident server be the same as the one given before the "@".
Field 3: The password of the other host. A password must always be
present for the line to be recognized.
Field 4: The full hostname of the target machine. This is the name that
the TARGET server will identify itself with when you connect
to it. If you were connecting to nic.funet.fi you would receive
"nic.funet.fi" and that is what you should place in
this field.
Field 5: The INTERNET Port that you want to connect to on the TARGET
machine. Most of the time this will be set to "6667".
If this field is left blank, then no connections will
be attempted to the TARGET host, and your host will accept
connections FROM the TARGET host instead.
Some examples:
C:nic.funet.fi::nic.funet.fi:6667
This reads: Connect to host "nic.funet.fi", with no password
and expect this server to identify itself to you as
"nic.funet.fi". Your machine will connect to this host to
PORT 6667.
C:18.72.0.252:Jeff:garfield.mit.edu:6667
This reads: Connect to a host at address "18.72.0.252", using a
password of "Jeff". The TARGET server should identify
itself as "garfield.mit.edu". You will connect to Internet
Port 6667 on this host.
C:irc.nada.kth.se::irc.nada.kth.se
This reads: do not attempt to connect to "irc.nada.kth.se",
but if "irc.nada.kth.se" requests a connection,
allow it to connect.
Now back to our original problem, we wanted OUR server CONNECT to 3
hosts, "nic.funet.fi", "irc.nada.kth.se" and "garfield.mit.edu" in
that order. So as we enter these entries into the file they must be
done in REVERSE order of how we could want to connect to them.
Here's how it would look if we connected "nic.funet.fi" first:
C:garfield.mit.edu::garfield.mit.edu:6667
C:irc.nada.kth.se::irc.nada.kth.se:6667
C:nic.funet.fi::nic.funet.fi:6667
Ircd will attempt to connect to nic.funet.fi first, then to irc.nada
and finally to garfield.
Reciprocal entries:
Each "C" entry requires a corresponding 'N' entry that specifies
connection priviliges to other hosts. The 'N' entry contains
the password, if any, that you require other hosts to have before
they can connect to you. These entries are of the same format as
the "C" entries.
Let us assume that "garfield.mit.edu" connects to your server
and you want to place password authorization authorization on garfield.
The "N" entry would be:
N:garfield.mit.edu:golden:garfield.mit.edu
This line says: expect a connection from host "garfield.mit.edu",
and expect a login password of "golden"
and expect the host to identify itself as "garfield.mit.edu".
N:18.72.0.252::garfield.mit.edu
This line says: expect a Connection from host "18.72.0.252", and
don't expect login password. The connecting host should identify itself
as "garfield.mit.edu".
Wildcards domains:
To reduce the great amount of servers in IRCnet wildcard
DOMAINS were introduced in 2.6. To explain the usage of
wildcard domains we take an example of such:
*.de - a domain name matching all machines
in Germany.
Wildcard domains are useful in that ALL SERVERS in Germany
(or any other domain area) can be shown as one to the
rest of the world. Imagine 100 servers in Germany, it
would be incredible waste of netwotk bandwidth to broadcast
all of them to all servers around the world.
So wildcard domains are a great help, but how to use them ?
They can be defined in the N-line for a given connection,
in place of port number you write a magic number called
wildcard count.
Wildcard count tells you HOW MANY PARTS of your server's name
should be replaced by a wildcard. For example, your server's
name is "tolsun.oulu.fi" and you want to represent it as
"*.oulu.fi" to "nic.funet.fi". In this case the wildcard count
is 1, because only one word (tolsun) is replaced by a wildcard.
If the wildcard count would be 2, then the wildcard domain would
be "*.fi". Note that with wildcard name "*.fi" you could NOT
connect to "nic.funet.fi", because that would result in a server
name COLLISION (*.fi matches nic.funet.fi).
I advice you to not to use wildcard servers before you know
for sure how they are used, they are mostly beneficial for
backbones of countries and other large areas with common domain.
2. MACHINE INFORMATION
IRC needs to know a few things about your UNIX site, and the "M" command
specifies this information for IRC. The fomat of this command is:
M:<YOUR Host NAME>:xxx:<Geographic Location>:<Internet Port>
Field: 1 2 3 4 5
Explanation:
Field 1: "M" specifies a Machine description line
Field 2: The name of YOUR host adding any Internet DOMAINNAME that
might also be present.
Field 3: -- NOT USED --: Set to Value NULL (No spaces at ALL!).
Field 4: Geographic Location is used to say WHERE YOUR SEVRER is,
and gives people in other parts of the world a good
idea of where you are! If your server is in the USA, it is
usually best to say: <CITY> <STATE>, USA. Like for Denver
I say: "Denver Colorado, USA". Finnish sites (like
tolsun.oulu.fi generally say something like "Oulu, Finland".
Field 5: The Internet port your server will use. Should be set to
the same value as in the config.h file.
Example:
M:tolsun.oulu.fi::Oulu, Finland:6667
This line reads: My Host's name is "tolsun.oulu.fi" and
my site is located in "Oulu, Finland". My ircd will use
Internet Port 6667.
M:orion.cair.du.edu::Denver Colorado, USA:6667
This line reads: My Hosts name is "orion.cair.du.edu"
and my site is located in "Denver Colorado, USA".
I have defined Internet Port number "6667" to be used
as my IRCD Socket Port.
3. CLIENT CONNECTIONS - How to let clients connect to your IRCD.
A client is a program that connects to the ircd daemon (ircd). Currently
there are clients written in C and in GNU Emacs Lisp. The "irc"
program is the C client. Each person that talks via IRC is running
their own client.
The irc.conf files contains entries that specify which clients are allowed
to connect to your irc daemon. Obviously you want to allow your cwn
machine's clients to connect. You may want to allow clients from
other sites to connect. These remote clients will use your server
as a connection point. All messages sent by these clients will pass
through your machine.
The format of this entry in the conf file is:
I:<TARGET Host Addr>:<Password>:<TARGET Hosts NAME>:<Internet Port>
Field:1 2 3 4 5
For example, if you were installing IRC on tolsun.oulu.fi and you wanted
to allow examples sake let us assume you were making this file for
tolsun and you wanted to let your own clients to connect to your
server, you would add this entry to the file:
I:128.214.5.6::tolsun.oulu.fi
or
I:tolsun.oulu.fi::tolsun.oulu.fi
If you wanted to let remote clients connect, you could add the
following lines:
I:*.du.edu::*.du.edu
Allow any clients from machines whose names end in "du.edu" to connect
with no password.
I:128.214.6.100::nic.funet.fi
Allow clients from a machine with that IP number and the name
nic.funet.fi to connect.
I:*.tut.fi:secret:*.tut.fi
Allow clients from machines matching *.tut.fi to connect
with the password 'secret'.
I:*::*
Allow anyone from anywhere to connect your server.
This is the easiest way, but it also allows people to for example
dump files to your server, or connect 1000 (or how many open
sockets per process your OS allows) clients to your machine
and take your network ports. Of course the same things can be
done by simply telnetting to your machine's SMTP port (for example).
NEW!!!
As of the 2.7.2d version of the server, the server is able to accept
connections on multiple ports. I-lines are required for each P-line
to allow connections to be accepted. For unix sockets, this means
either adding I:/path/port::/path/port or some variation (wildcards
are recognised here). For internet ports, there must be an I-line
which allows the host access as normal, but the port field of the
I-line must match that of the port of the socket accepting the
connectiion. A port number of 0 is a wildcard (matches all ports).
4. DEFAULT HOSTS (for local clients)
This defines the default connection for the irc client. If you are
running an ircd server on the same machine, you will want to define
this command to connect to your own host. If your site is not running
a server then this command should contain the TARGET host's connection
information and password (if any). The format for this command is:
U:<TARGET Host addr>:<Password>:<TARGET Host NAME>:<Internet Port>
Field: 1 2 3 4 5
For example:
U:tolsun.oulu.fi::tolsun.oulu.fi:6667
U:128.214.5.6::tolsun.oulu.fi:6667
U:tolsun.oulu.fi::tolsun.oulu.fi
If the port number is omitted, irc will default to using 6667.
5. OPERATOR Privileges: How to become the IRC administrator on your site
To become an IRC Administrator, IRC must know who is authorized to become
an operator and what their "Nickname" and "Password" is. To add this
information, EDIT your "irc.conf" file and add the following command
line to it:
O:<TARGET Host NAME>:<password>:<nickname>:<port>:<class>
Field: 1 2 3 4 5 6
Explanation:
Field 1: Speficies Operator record. If you use capital letter ('O')
in it, it specifies a global operator. Small letter ('o')
specifies a local operator. Local operator has basically the
same rights except global operator with some restrictions.
Field 2: Tells IRC which host you have the privileges FROM. This
means that you should be logged into this host when you
ask for the priviliges. If you specify "tolsun.oulu.fi"
then IRC will expect your CLIENT to be connected at
"tolsun.oulu.fi" - when you ask for OPERATOR privileges
from "tolsun.oulu.fi". You cannot be logged in at any
other host and be able to use your OPERATOR privileges
at tolsun, only when you are connected at TOLSUN will this
work - this is a safeguard against unauthorized sites.
Field 3: If your AUTHORIZATION Password - this is the password that
let's IRC know you are who you say you are! Never tell anyone
your password and always keep the "irc.conf" file protected
from all of the other users.
Field 4: The Nickname you usually go by - but you can make this what
you want. It is better to make this a NICKNAME that no one
else knows, but anything will do. I usually use my own
loginname.
Field 5: Unused.
Field 6: The class field should refer to an existing class (preferably
having a lower number than that for the relevant I-line) and
determines the maximum number of simultaneous uses of the
O-line allowable through the max. links field in the Y-line.
Example:
O:orion.cair.du.edu:pyunxc:Jeff
There is an OPERATOR at "orion.cair.du.edu" that can get
Operator priviliges if he specifies a password of "pyunxc"
and uses a NICKNAME of "Jeff".
6. ADMINISTRATIVE INFORMATION
The "A" command is used for administrative information about a site.
The e-mail address of the person running the server should be included
here in case problems arise.
A:<Your Name/Location>:<Your Electronic Mailing Addr>:<other>
Field: 1 2 3 4
Explanation:
Field 1: "A" specifies an Admin record.
Field 2: Use this field to say tell your FULL NAME and where in the
world your machine is. Be sure to add your City,
State/Province and Country.
Field 3: Use this field to specify your Electronic Mailing Address
preferably your Internet Mailing Address. If you have
a UUCP or ARAPnet address - please add that as well. Be
sure to add any extra DOMAIN information that is needed,
for example "mail jtrim@orion" probably won't work as a
mail address to me if you happen to be in Alaska. But
"mail jtrim@orion.cair.du.edu" would work because you
know that "orion" is part of the DOMAIN "cair.du.edu".
So be sure to add your DOMAINNAMES to your mailing addresses.
Field 4: Is really an OTHER field - you can add what you want here,
Examples (the line is just one line in the confuration file, here it
is cut into two lines to make it clearer to read):
A:Jeff Trim - Denver Colorado, USA:INET jtrim@orion.cair.du.edu UUCP {hao,
isis}!udenva!jtrim:Terve! Heippa! Have you said hello in Finnish today?;)
Would look like this when printed out with the /admin command:
Jeff Trim - Denver Colorado, USA
INET jtrim@orion.cair.du.edu UUCP {hao,isis}!udenva!jtrim
Terve! Hei! Heippa! Have you said hello in Finnish today? ;)
Note that the A record cannot be split across multiple lines; it will
typically be longer than 80 characters and will therefore wrap around
the screen.
7. REMOVING A USER FROM IRC Remove an errant user from IRC on your site.
Obviously it is hoped that you wouldn't have to use this command.
Unfortunately sometimes a user can become unmanageable and this is your
only recourse - the KILL USER command. THIS COMMAND ONLY AFFECTS YOUR
SERVER - If this user can connect to another SERVER somewhere else in
the IRC-Network then you would have to talk to the administrator on that
site to disable his access from that IRCD Server as well.
The format of this command is:
K:<Host Name>:<time interval(s)>:<User>
Field: 1 2 3 4
Explanation:
Field 1: "K" tells the IRCD that you are making a KILL USER command
entry.
Field 2: In this field you specify the Hostname that the user is
connecting from. If you wanted to REMOVE connects
to IRC from "orion.cair.du.edu" then you would want to enter
"orion.cair.du.edu". If you want to REMOVE ALL HOSTS
access you can use '*' (Wild Card notation) and no matter
what host the USERNAME (specified in Field 4) connects from
s/he will be denied access. Removing all hosts isn't
very smart thing to do though, why would you run an ircd
if you allow nobody to connect to it anyways ?
Field 3: Either leave this field empty (no spaces), then then lines
is active continuously for the specified user/host machine.
You may also specify intervals during the line should be
active, see examples above.
Field 4: The USERNAME of the user you want removed from IRC. For
example 'root'.
Some Examples:
K:orion.cair.du.edu::jtrim
If user 'jtrim' connects to IRC from host "orion.cair.du.edu"
then IMMEDIATELY REMOVE HIM from my IRCD.
K:*.cair.du.edu::root
If user 'root' connects to IRC from any host that has the
suffix "cair.du.edu" - then IMMEDIATELY REMOVE THEM from
my IRCD.
K:*::vijay
This line reads "I don't care WHAT HOST user 'vijay' is on,
I will NEVER allow username 'vijay' to login to my IRCD.
K:*.oulu.fi:0800-1200,1400-1900:*
This disallows all users from hosts with enddomain 'oulu.fi'
access to your server between 8 and 12am, 2 and 7pm.
Users get kicked off if they're already signed on when the
line becomes active (they'll get a warning 5 minutes ago).
8. Disallowing SERVERS in your irc net.
In some cases people run into difficulties in net administration.
For one reason or another you do not want a certain server to be
in your net (for example because of the security holes it opens
for every server if it's not secured carefully). In that case
you should use Q-lines in your server. When you specify a server
name in Q-line, everytime some server link tries to introduce you
a server (remember, all server names are broadcast around the net),
that name is checked if it matches the Q-lines in your server.
If it matches, then your server disconnects the link. Note that
just placing Q-lines to your server probably results in your server
being left alone, unless other servers have agreed to have the
same Q-line in their ircd configuration files as well.
Example:
Q::of the security holes:foo.bar.baz
This command excludes a server named "foo.bar.baz", the reason
is given to be security holes (you should give a reason, it is
polite). The first field is unused, so leave it empty.
9. Connection Classes.
To enable more efficient use of MAXIMUM_LINKS, connection classes
were implemented. To give a connection a class, add another field
(a sixth) to the C/N lines for a particular server.
Each line for a server should have the same number as the sixth
field. If it is absent, the server deaults it to 0, using the
defaults from the config.h file. To define a connection class,
you need to include a Y: line in the irc.conf file. This enables
you to define the ping frequency, connection frequency and maximum
number of links that class should have. Currently, the Y: line MUST
appear in the irc.conf file BEFORE it is used in any other way.
The format for the line is:
Y:<CLASS>:<PING FREQUENCY>:<CONNECT FREQUENCY>:<MAX LINKS>:<SENDQ>
Field: 1 2 3 4 5 6
Field 2: This is the class number which gains the following attributes
and should match that which is on the end of the C/N line.
Field 3: This field defines how long the server will let the connection
remain "silent" before sending a PING message to make sure it is still
alive. Unless you are sure of what you are doing, use the default value
which is in your config.h file.
Field 4: By changing this number, you change how often your server
checks to see if it can connect to this server. If you want to check
very occasionally, use a large value, but if it is an important
connection, you might want a smaller value so that you connect to it
as soon as possible.
Field 5: This field defines the maximum number of links this class
will allow from automatic connections. Using /CONNECT overrides this
feature.
Field 6: This field defines the 'sendq' value for this class. If this
field is not present, the default (from config.h) is assigned.
NOTE: leaving any of the fields out means their value is 0 (ZERO)!!
example:
Y:23:120:300:5
define class 23 to allow 5 auto-connections, which are checked every
300 seconds. The connection is allowed to remain silent for 120
seconds before a PING is sent. NOTE: fields 3 & 4 are in seconds.
You may also give I lines a class (again the sixth field to define
which class). This is only usefull (currently) for redefining the
ping frequency. It can also be useful as a diagnostic to see how
much each I line is used when combined with the TRACE output.
Another feature of connection class is the ability to do automatic
routing by using the class as a 'priority'. If you are connected
to a server which has a class lower than one of the servers that is
'behind' it, the server will disconnect the lower class one and
schedule a 'new' connection for the higher class server.
10. Leaf Connections.
To stop servers which should only act as leaves from hubs becoming
hubs accidently, the L line was introduced so that hubs can be aware
of which servers should and shouldnt be treated as leaves. A leaf
server is supposed to remain a node for the entirity of its life
whilst connected to the IRC server network. It is quite easy, however
for a leaf server to be incorrectly setup and create problems by
becoming a node of 2 or more servers, ending its life as a leaf. The
L line enables the administrator of an IRC 'Hub server' to 'stop' a
server which is meant to act as a leaf trying to make itself a hub.
If, for example, the leaf server connects to another server which doesnt
have an L-line for it, the one which does will drop the connection, once
again making the server a leaf.
L:<SERVER MASK>:*:<SERVER NAME>:<MAX DEPTH>
Field: 1 2 3 4 5
Field 2 is a mask of which servers the leaf-like attributes are used on
when the server receives SERVER messages. The wildcards * and ? may be
used within this field for matching purposes. If this field is empty,
it acts the same as if it were a single * (ie matches everything).
Field 4 is the the server connectted to you that for which you want to
enforce leaf-like attributes upon.
Field 5 is the maximum depth allowed on that leaf and if not specified,
a value of 1 is assumed. The depth is checked each time a SERVER message
is received by the server, the hops to the server being the field checked
against this max depth and if greater, the connection to the server that
made its leaf too deep has its connection dropped.
For the L-line to come into effect, both fields, 2 and 4, must match up
with the new server being introduced and the server which is responsible
for introducing this new server.
11. Service Connections (Not yet implemented)
Introduction.
The Service is a special kind of IRC client. It does not have the full
abilities of a normal user but can behave in a more active manner than
a normal client. Services as they stand now are not fully implemented.
The following line can be added to your ircd.conf file to enable a
service:
S:<TARGET Host Mask>:<password>:<service_name>
Field: 1 2 3 4
Explanation:
Field 2:
The host mask should be set to match the hosts(s) from which the
service will be connecting from. This may be either an IP# or full
name (prefered).
Field 3:
This is the password which must be passed in the SERVICE command.
Field 4:
The 'service name' is only used for the purpose of finding the
right S-line from the ircd.conf file for password matching. The
actual service name used is that set by NICK commands prior to
SERVICE being sent.
To connect a service to your server, you must first create an S-line
entry in your ircd.conf file and get your server to read this in (ie
rehash or reboot). Once your server has updated itself, you can then
attempt to register your connection as a service.
Registering as a service is similar to registering as a normal user
except that you must send NICK first and then SERVICE. The service
command should look something like this:
SERVICE secretpassword referencename :Service information
A successfull registering of a service at the server will result in
a RPL_YOURESERVICE (383) being sent back to you. Any other reply as
a result of sending service indicates an error has occured.
A service is not a very useful sort of client, it cannot join channels
or issue certain commands although most are available to it. Services,
however, are not affected by flood control. It is therefore wise to
oversee the use of S-lines with some care.
12. Port Connections
Introduction.
The port line adds flexibility to the server's ability to accept
connections. By use of this line in the ircd.conf file, it is easy
to setup both Unix Domain ports for the server to accept connections
on as well as extra internet ports.
P:<Internet IP# Mask>:<*>:<*>:<PORT>
Field: 1 2 3 4 5
or
P:<Directory>:<*>:<*>:<PORT>
Field: 1 2 3 4 5
Explanation
Internet Ports
Field 1
The internet IP mask defines where connections may come from and
be accepted. The IP mask uses either *'s or 0's as wildcards. The
following two lines are the same:
P:128.2.*:::6664
P:128.2.0.0:::6664
The incoming isnt matched against the mask, rather the ip# string
is decoded and compared segment by segment. Thus
P:128.2*.1.2:::6664
will not match 128.20.1.2.
Field 5
The port number field tells the server which port number it should
listen on for incoming connections.
Unix Socket Ports.
Field 1
The path set in field 1 should be the directory name in which to
create the unix socket for later listening to. The server will
attempt to create the directory before creating the unix socket.
Field 5
The port field when used in combination with a pathname in a P-line
is the filename created in the directory set in Field 1.
Example:
P:/tmp/.ircd:::6667
Creates a unix socket in the /tmp/.ircd directory called "6667".
The unix socket (file) must be a numerical.
13. Hub Connections
In direct contrast to L-lines, the server also implements H-lines to
determine which servers may act as a hub and what they may 'hub for'.
If a server is only going to supply its own name (ie act as a solitary
leaf) then no H-line is required for, else a H-line must be added as
follows:
H:<SERVER MASK>:*:<SERVER NAME>
Field: 1 2 3 4
Explanation:
Field 2
All servers that are allowed via this H-line must match the mask
given in this field.
Field 4
This field is used to match exactly against a server name, wildcards
being treated as literal characters.
Examples:
H:*.edu:*:*.bu.edu
Allows a server named "*.bu.edu" to introduce only servers that
match the "*.edu" name mask.
H:*:*:eff.org
Allow "eff.org" to introduce (and act as a hub for) any server.
Note: It is possible to have and use multiple H-lines (or L-lines) for
the one server. eg:
H:*.edu:*:*.bu.edu
H:*.au:*:*.bu.edu
is allowed as is
L:*.edu:*:*.au
L:*.com:*:*.au
Appendix A: Difference between IP addresses and hostnames
There are 2 different types of INTERNET addresses, NAME addresses and
NUMERIC addresses. NAME addresses look like ENGLISH words (and indeed
they are ENGLISH words that refer to a given host). A NAME address looks
like "tolsun.oulu.fi" - and that particular address refers to the machine
named TOLSUN in Finland. It is a UNIQUE address because no other machine
in the world has its NAME address the same as "tolsun.oulu.fi". Anytime
you say "telnet tolsun.oulu.fi" - you would always connect to TOLSUN in
Finland. NUMERIC addresses refer to those addresses that are made up of
NUMBERS for example "128.214.5.6" is the NUMERIC address for TOLSUN. This
address is also UNIQUE in that no other machine in the world will be use
those NUMERIC numbers. The NUMERIC address is usually more reliable than
the NAME address because not all sites can recognize and translate the
NAME address into it's numeric counterpart. NUMERIC always seems to work
best, but use a NAME address when you can because it is easier to tell
what host you are connected to.
Every Unix machine has a file called "/etc/hosts" on it. This file
contains NAME and NUMERIC addresses. When you supply IRC with a NAME
address it will at first try to find it in /etc/hosts, and then (if it's
really smart), use the local Domain Name Server (DNS) to find the NUMERIC
address for the host you want to connect to. Thus if you plan to use NAME
addresses keep in mind that on SOME sites the entry for the TARGET machine
must be found in /etc/hosts or the NAME address will fail. A typical
entry in /etc/hosts looks like this:
130.253.1.15 orion.cair.du.edu orion.du.edu orion # BSD 4.3
This particular example is the Host ORION at the University of Denver.
Notice that on the far left is the NUMERIC Address for orion. The
next few ENGLISH words are the NAME addresses that can be used for orion,
"orion.cair.du.edu", "orion.du.edu", "orion". ALL of these NAME addresses
will return the NUMERIC address "130.253.1.15" which IRC will use to
connect to the TARGET UNIX. (when I say TARGET UNIX I am refering to the
UNIX you want to connect to for IRC). Any futher questions about
/etc/hosts should be directed to "man hosts".
Appendix B: Enabling Summon Messages
+-----------------------------------------------------------------------+
| E N A B L I N G / S U M M O N M E S S A G E S |
+-----------------------------------------------------------------------+
*NOTE* You must have ROOT or special access to the GROUP tty ('/dev')
to do this. If you want to allow users around the world to summon
users at your site to irc, then you should make sure that summon works.
The "IRCD" program needs access to the GROUP of '/dev'. This
directory is where user TTY's are stored (as UNIX treats each Terminal
as a FILE!) IRCD needs GROUP ACCESS to /dev so that users can be
SUMMONED to the program by others users that are *in* the program.
This allows people from other Universities around the world to SUMMON
your users to IRC so that they can chat with them. Berkeley, SUN, HP-UX
and most of the newer versions of UNIX check to see if a USER is
accepting MESSAGES via the GROUP access rights on their TTY listing
in the /dev directory. For example an entry in '/dev' looks like this:
(Unix Path on BSD 4.3 UNIX is: /dev/ttyp0)
crw------- 1 jtrim 20, 0 Apr 29 10:35 ttyp0
You will note that 'jtrim' OWNS this terminal and can READ/WRITE to this
terminal as well (which makes sense because I am ENTERING DATA and
RECEIVEING DATA back from the UNIX). I logged into this particular
UNIX on "April 29th" at "10:35am" and my TTY is "ttyp0". But further
of *note* is that I do not have my MESSAGES ON! (mesg n) -- This is
how my terminal would look with MESSAGES ON (mesg y):
crw--w---- 1 jtrim 20, 0 Apr 29 10:35 ttyp0
With my MESSAGES ON (mesg y) I can receive TALK(1) requests, use the
UNIX WRITE(1) command and other commands that allow users to talk
to one another. In IRC this would also allow me to get IRC /SUMMON
messages. To set up the "IRCD" program to work with /SUMMON type
the following: (using ROOT or an account that has access to '/dev').
% chgrp tty ircd
% chmod 6111 ircd
The above commands read: "Give IRCD access to GROUP tty (which is /dev)
and then when ANYONE runs the IRCD allow SETUID and SETGID priviliges
so that they can use the /SUMMON command.

25
doc/Makefile Normal file
View File

@@ -0,0 +1,25 @@
#************************************************************************
#* IRC - Internet Relay Chat, Makefile
#* Copyright (C) 1990, Jarkko Oikarinen
#*
#* 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 1, 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.
#*/
MANDIR=/usr/local/man
all:
install: all
-../bsdinstall -c -m 644 ircd.8 ${MANDIR}/man8

255
doc/Manual Normal file
View File

@@ -0,0 +1,255 @@
/************************************************************************
* IRC - Internet Relay Chat, doc/MANUAL
* Copyright (C) 1990, Karl Kleinpaste
*
* 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 1, 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.
*/
Date: 04 Apr 1989
Author: Karl Kleinpaste
karl@cis.ohio-state.edu
Last modification: 15 May 1992
by Mauri Haikola
mjh@stekt.oulu.fi
Modified for undernet: 7 Feb 1995
by Carlo Kid
carlo@runaway.xs4all.nl
INTERNET RELAY CHAT
a real-time conversational system
* 1: Irc - replacement for talk(1)
Irc is a functional replacement for and improvement to talk(1). Talk
is an old, primitive, atrocious, minimalist sort of keyboard/screen
conversation tool, using a grotesque, machine-dependent protocol.
Irc does everything talk does, but with a better protocol, allowing
more than 2 users to talk at once, with access across the aggregate
Internet, and providing a whole raft of other useful features.
* 2: Entering Internet Relay Chat
To enter Internet Relay Chat you need to run a client, which will start
connecting to its default server. The best clients are the clients
conforming to 'ircII' but those are all unix clients. More info on
clients can be achieved from ftp.undernet.org:/pub/irc/docs/underfaq.1
* 3: How much can be seen from here
The universe - seriously.
This is most formally called Internet Relay Chat. Server hosts are
connected via a tree structure. The various servers relay control and
message data among themselves to advertise the existence of other
servers, users, and the channels and other resources being occupied by
those users.
* 4: Structure
There is quite a lot of structure to the operation of irc, as
compared to crufty old talk(1). Since so little could be done with
talk(1), it needed little structure. But to keep track of people
spread literally around the world (the system was written by Jarkko
Oikarinen of Finland, usually seen on the system as `Wiz'), the
structure is useful so that one can speak to exactly those people with
whom one wishes to speak.
** 4.1: Nicknames
All users of irc are known to the system by a `nickname.' By
default, one's nickname is one's login name. Nickname clashes are not
allowed; this is enforced by the servers. If one's intended nickname
clashes with someone else as one enters chat, one will not be able to
complete entry to irc until one changes one's nickname to something
else.
** 4.2: Presence on a channel
Fundamental to the operation of irc is the concept of a channel. All
users are `on a channel' while inside irc. One enters the `null
channel' first. One cannot send any messages while not in any
chatting channel unless one has set up a private conversation in some
way. The number of channels is essentially unlimited - whatever will
fit in a string of some ungodly length, that must start with a # sign.
** 4.3: Main modes of channels
Public
This is the default mode for a channel. When one is on a public
channel, one can be seen by all other users (if one's own user mode
permits this). Anyone can notice users on a public channel and join
such a channel's conversation.
Private
This means that, although anyone can see that one is using chat, no
one can tell what channel one is using unless one is already on that
channel with oneself. Since the number of potential channels is in
the billions, this is quite some security - all one gives away is the
acknowledgement that one is using chat.
Secret
While one is on a secret channel, no one who is not on one's channel
with oneself can even see that one is there. One's name does not show
up in a list of active users. The only indication of one's presence
is that, when entering chat, all new users are told that there are "N
users on P servers." If one checks on all users and finds less than N
of them, one knows that others are hiding on secret channels. But a
secret channel user still cannot be found except by brute-force
checking through all channels, a hopeless proposition in the face of
the huge number of possible channel names. Security through obscurity
finally means something. Of course, making a channel like '#test' secret
gives a huge change to be discovered anyway.
Changing the mode
The mode of a channel (private, secret, invite-only, moderated,
topic-limited, person-number-limited, no-messages-to-channel, ban
someone from channel) is set by the channel operator, who is the
first person to join a channel, or someone who has had channel
operatorship bestowed on them by another channel operator.
*** 4.4: Conversations not using channels
It is possible to conduct conversations with others without using the
formalized channel structure. Doing so requires that two people set
themselves up for private conversation using special commands; see
User Commands below.
** 5: Getting help
Type "/help." Follow the instructions. Since this is a client feature
it might not work for you, in which case you'd have to consult your
local irc guru or someone on the net.
** 5.1: User commands
In most clients, commands must start with a '/' (for example: /join #test).
The most important commands supported by irc are:
help quit who whois
list topic join part
links msg invite silence
names stats nick away
info clear query ignore
mode
*** 5.1.1: /quit [comment]
/quit exits chat. Optional comment may be included; see above.
*** 5.1.2: /who [#channelname_mask | user@host.mask]
/who returns information on who is using chat. /who without arguments
prints info on all users that can be seen. Users of public channels
show up with their channel identified. Users of private channels
appear, but they are specified as being on a private, unspecified
channel. Users of secret channels and users whose user mode is +i
(invisible) do not appear at all.
Giving a channel name as an argument to /who returns only those users of the
specified channel. This still doesn't show users of secret channel or
invisible users one is actually on the same channel with them. Users
of private channels are shown, if an exact channel name is given.
*** 5.1.3: /whois <nickname>
This returns information about individual users. Type "/whois nickname"
to get information on the login name and host from which the nicknamed
user comes.
*** 5.1.4: /topic <some topic string>
Channels can be given off-the-cuff "topics." Saying "/topic some
string of text" will associate that topic with the current channel.
*** 5.1.5: /list [#channel.mask]
/list will give lists of active channels, the number of users of each,
and the topics therewith associated. Again, secret channels do not
appear and private channels only appear as Prv.
*** 5.1.6: /join <channel>
/join <#channel_name> is the means to enter a channel. Give the channel
name as an argument. If this is a secret or hidden channel, /who
commands will show oneself and any other users of one's channel.
One's arrival on a channel is announced to the rest of the users
already on that channel. Silent, anonymous "lurking" is not
supported.
*** 5.1.7: /msg <nick> <some text string>
A single message can be sent privately to a certain user with /msg.
Type /msg nickname and the text to be sent. It will be sent privately
to the indicated nickname.
*** 5.1.8: /invite <#channel> <nick>
If there is a user online to whom one wishes to speak, one may invite
that user to join oneself on a certain channel. One types "/invite
nickname" with an optional channel name. The receiving user gets a
one-line message indicating the sender and the invitation. The
receiving user is free to ignore the invitation, of course.
*** 5.1.9: /ignore <nick!user@host.mask>
If one wants to ignore messages sent by some other user or users, it
may be done with /ignore command. One can ignore someone by their
nickname, or by their user@host data. Wildcards may be used. /ignore
is only intended to ignore annoying public messages (messages sent to
a channel), to stop flooding (a huge number of messages per second)
you have to use banning for channel messages, and /silence for private
messages. /mode <your nick> +d stops all messages to ALL channels.
*** 5.1.12: /silence [nick!user@host.mask]
This command effectively stops private message flooding at the server
of the flooder. You can use "/silence nick" to get a list of the
silence masks of 'nick'. This command is undernet specific and therefor
not supported by all clients unless you add specifically a line to your
clients configuration file.
*** 5.1.11: /nick <new_nick>
One can change nicknames by issuing "/nick new-nickname." All users
on one's channel will be informed about the change. NOTE: If one enters
chat with a nickname clash (e.g., one's login name is the same as
someone else's, and the other user got there first), the system will
not let one enter until one issues a /nick command with a unique
nickname.
*** 5.1.12: /mode #channel <lots of parameters>
This command can be used for altering the various modes of a channel
(see the explanation of channel modes above). /mode command can only
be issued by channel operators. Please use /help, or the manual of
your client to find out about this command.
* 6: Questions, problems, troubles?
If you have problems, please get and read the FAQs from
ftp.undernet.org:/pub/irc/docs/underfaq.1 and underfaq.2.
You can also ask for help on some of the operator channels on irc,
for example #wasteland. They will be able to assist you in whatever
problems you are having with IRC.

331
doc/NOTE Normal file
View File

@@ -0,0 +1,331 @@
Usages:
NOTE [USER] [&passwd] [+-flags] [+-maxtime] <nick!username@host> <msg>
or [SEND|SPY|FIND|WAITFOR|NEWS|Channel|Wall|Wallops|Deny|Key]
NOTE [[x]LS|COUNT|[x]RM|LOG] [&pwd][+-flags] <nick!user@host> [date]
NOTE [FLAG] [&passwd] [+-flags] <nick!username@host> <+-flags>
NOTE [SENT] [NAME|COUNT|Users] <f.nick!f.name@host> <date> [RM]
NOTE [STATS] [MSM|MSW|MUM|MUW|MST|MSF|USED|Reset] [Value]
NOTE [SAVE]
The Note utility has following main functions:
a) Let opers create news-like #head.channels listed with /list.
b) Let you send messages to users which they will get when they sign on.
Example: /note send nickname Hi, this is a note to you.
c) Let you spy on people to see when they sign/off, change nick etc.
Example: /note spy +100 !foo (spy on user with login foo for 100 days)
You may fill in none or any of the arguments listed above, including
* or ? at any place, as nick@*.edu, !username, ni?k!username etc...
NOTE <server> <COMMAND> sends request to <server> instead of local.
Note was developed by Jarle Lyngaas (jarlel@ii.uib.no)
Usage: NOTE [USER] [&passwd] [+-flags] [+-maxtime] <nick!username@host> <msg>
With USER you can queue a message in the server, and when the recipient
signs on/off IRC, change nick or join any channel, note checks for
valid messages. This works even if the sender is not on IRC. Read
NOTE FLAGS for more info.
Password can be up to ten characters long. You may specify password
using the &, % or $ character. & is equal to to $, except working much
better cause client use $ for other things...
The % character works like &, except it makes the queueing silent. It
also makes sense to use this without any following password.
If any request queued is equal to any previous except time and maxtime,
only maxtime is changed as specified. You then get "Joined" instead of
"Queued".
Read NOTE FLAGS for info about flag settings. Username can be specified
without @host. Do not use wildcards in username if you know what it
is, even if it's possible. Max time before the server automatically
remove the message from the queue, is specified with hours with a
'-' character first, or days if a '+' character is specified, as
-5 hours, or +10 days. Default maxtime is 7 days.
The received message is *directly* displayed on the screen, without the
need for a read or remove request.
NOTE USER &secret +WN +10 !jarlel@ii.uib.no Howdy!
- is an example of a message sent only to the specified recipient if
this person is an operator, and after receiving the message, the server
sends a note message back to sender to tell about the delivery.
NOTE USER +XR -5 Anybody <ctrl-G>
- is an example which makes the server to tell when Anybody signs
on/off irc, change nick etc. This process repeats for 5 hours.
NOTE USER +FL @*.edu *account*
- is an example which makes the server send a message back if any real-
name of any user matches *account*. Message is sent back as note from
server, or directly as a notice if sender is on IRC at this time.
Usage: NOTE [COUNT] [&passwd] [+-flags] <nick!username@host>
Displays the number of messages sent from your nick and username. Read
NOTE LS for more info. Read NOTE FLAG for more info about flag setting.
Usage: NOTE [FIND] [&passwd] [+-flags] [+-maxtime] <nick!username@host> <msg>
FIND is an alias for USER +FLR (default max 1 day)
This command makes the server search for any matching recipient, and
send a note message back if this is found. If <msg> field is used, this
should specify the realname of the person to be searched for.
Example: FIND -4 foo*!username@host
FIND @host Internet*
FIND nicky Annie*
FIND +7 * Annie*
Usage: NOTE [FLAG] [&passwd] [+-flags] <nick!username@host> <+-flags>
You can add or delete as many flags as you wish with +/-<flag>.
+ switch the flag on, and - switch it off. Example: -S+RL
Following flags with its default set specified first are available:
-S > News flag for subscribing.
-M > Request is removed after you sign off.
-Q > Ignore request if recipient's first nick is equal to username.
-I > Ignore request if recipient is not on same server as request.
-W > Ignore request if recipient is not an operator.
-Y > Ignore request if sender is not on IRC.
-N > Let server send a note to you if message is delivered.
-R > Repeat processing the request until timeout.
-F > Let server send note info for matching recipient(s). Any message
part specify what to match with the realname of the recipient.
-L > Head channel flag.
-P > Password set for head channel.
-D > Z or L flag requests are queued on other servers for one week.
-C > Make sender's nicks be valid in all cases username@host is valid.
-V > Make sender's "nick*" be valid in all cases username@host is valid.
-X > Let server display if recipient signs on/off IRC or change
nickname. Any message specified is returned to sender.
-A > Show what server matching user is on using X flag.
-J > Show what channel matching user is on using X flag.
-U > Do not display nick-change using X flag.
-E > Ignore request if nick, name and host matches the message text
starting with any number of this format: 'nick!name@host nick!... '
-B > Send a message to every account who match the nick!user@host
This creates a received list with flag H set. (Read LS +h)
-T > Send a message not all nicks on same accounts too using B flag.
-K > Give keys to unlock privileged flags by setting that flags on.
The recipient does also get privileges to queue unlimited
numer of requests, list privileged flags and see all stats.
-Z > Make it impossible for recipient to join head chn, or queue notes.
Other flags which are only displayed but can't be set by user:
-O > Request is queued by an operator.
-G > Notice message is generated by server.
-B > Broadcasting message.
-H > Flag list for who's received Broadcast message (B flag).
Notice: Message is not sent to recip. using F, L, R, X, K, Z or H
flag (except if B flag is set for R). For this flags, no msg. needed.
Example: FLAG * +cj : Switch on c and j flag for all requests.
FLAG +x * +c : Switch on c flag for all req. which have x flag.
FLAG nick -c+j : Switch off c flag and which on j flag for nick
Usage: NOTE [LOG] [&passwd] [+-flags] <nick!username@host>
Displays how long time since matching person was on IRC. This works
only after use of NOTE SPY. The log is protected to be seen for other
users than the person who queued the SPY request. To get short
output, do not specify any arguments.
Example: LOG : Print short log of all
LOG * : Print long log including real names of all
LOG nick : Print long log for user nick.
Usage: NOTE [LS] [&passwd] [+-flags] <nick!username@host> [date]
Displays requests you have queued. No arguments would show you
all requests without the message field.
Use flags for matching all messages which have the specified flags set
on or off. Read NOTE FLAG for more info about flag settings. Time
can be specified on the form day.month.year or only day, or day/month,
and separated with one of the three '.,/' characters. You can also
specify -n for n days ago. Examples: 1.jan-90, 1/1.90, 3, 3/5, 3.may.
If only '-' and no number is specified max time is set to all days.
The time specified is always the local time on your system.
Example: LS !user would show you all requests to username@*
LS +x would show all your SPY requests.
LS 300 would show you only request numbered 300.
Usage: NOTE [XLS] [&passwd] [+-flags] <nick!username@host> [date]
Displays requests with channel flag L or deny flag Z set independent of
which person who queued the requests.
Usage: NOTE [NEWS] [&passwd] [+-flags] [+-maxtime] <group!username@host>
NEWS with no message is an alias for USER +RS (default max 60 days)
This command is for subscribing on a specified newsgroup from any
user(s) or host(s). Wildcards may be used anywhere.
Example: NEWS irc.talk : Subscribe on irc.talk
NEWS irc.talk@*.no Hello : Send Hello to group irc.talk, but only
for users at host *.no
NEWS admin.users@*.no Hi : Send Hi to all users using note in
your server located at host *.no.
Advanced users may use USER +RS <...> <filter> where filter is a
string which must matches with field in received news message.
Only opers may send to grups matching admin.* as admin.note.
To send news add message and use same format as subscribing, except
that username field must matches with subscribed group as alt.irc!*.irc -
everybody subscribing on a*.irc or *.irc or alt.irc... would get the news.
A speciall case is the group admin.users which everybody using NOTE in the
server are member of.
Usage: NOTE [RM] [&passwd] [+-flags] <nick!username@host>
Deletes any messages sent from your nick and username which matches
with nick and username@host. Use flags for matching all messages which
have the specified flags set on or off. Read NOTE FLAG for more info
about flag settings, and NOTE LS for info about time.
Usage: NOTE [XRM] [&passwd] [+-flags] <nick!username@host> [date]
Remove requests with channel flag L (except combination of G and P flag
if not oper on the server) or deny flag Z - independent of which person
who queued the requests. Be very careful using this! The owner of the
request you removed is notified if Z flag was set.
Usage: NOTE [SEND] [&passwd] [+-flags] [+-maxtime] <nick!username@host> <msg>
SEND is an alias for USER +N (default max 60 days)
This command is for sending a message to recipient, and let the server
send a note + a notice to sender if this is on IRC - if message is sent.
Example: SEND foobar Hello, this is a test.
SEND +7 !username@*.edu Hello again!
Usage: NOTE [CHANNEL] [&passwd][+-flags][+-maxtime] <#chn!username@host><topic>
CHANNEL is an alias for USER +LR (default max 365 days)
This command creates a head channel which must include at least one dot "."
Any user can join this or make their own tail channel: #head.chn-tail where
tail can be anything. Channels matching all users should ALWAYS have the
same name as a newsgroup with NO EXCEPTIONS.
If you add P flag, the server send password for all such channels in E-mail
if you try do /join #chn <E-mail@addy>. Then you can do /join #chn pwd.
If you don't get the Email, check out EPATH in config.h.
D flag makes the request to be distributed to all servers with name
matching @host in request. Be sure that topic is at least 10 characters.
The request on other server will live one week, and may get back to you
during this time if you remove the root request which is the first one
you queue. The principle is that if your server stop distributing
the request, some other server starts distributing it for you rest of
the week. On the other hand your server will distribute and update the
channel on other servers, so they won't reach the timeout limit.
Example: CHANNEL #comp.unix.misc Miscellaneous unix topics (open for all)
CHANNEL +p #comp.unix.misc Miscellaneous unix topics (password)
CHANNEL #no.norway@*.no Norwegians only!
CHANNEL +7 +p #no.unix@*.no Norwegian one week lasting protected.
CHANNEL +7 +p #no.unix@*.no Norwegian one week lasting protected.
CHANNEL +d #unix@*.edu Queued on all .edu servers for a week.
Usage: NOTE [SENT] [NAME|COUNT|USERS] <f.nick!f.name@host> <date> [RM]
Displays host and time for messages which are queued without specifying
any password. If no option is specified SENT displays host/time for
messages sent from your nick and username.
NAME displays host/time for messages sent from your username
COUNT displays number of messages sent from your username
USERS Displays the number of messages in [], and names for all users
who have queued any message which matches with spec. nick/name/host.
RM means that the server removes the messages from the specified user.
Usage: NOTE [SPY] [&passwd] [+-flags] [+-maxtime] <nick!username@host> [msg]
SPY is an alias for USER +RX (default 1 max day)
SPY makes the server tell you if any matching recipient sign(s)
on/off IRC or change nick name. No message needs to be specified.
However, if a message is specified this is returned to sender including
with the message about recipient. Message could for example be one or
more Ctrl-G characters to activate the bell on senders machine.
As an alternative for using C flag, <msg> field could start with
any number of nicks on this format: %nick1 %nick2... %nickn, with
no space between % and the nick name you use. Spy messages would be
valid for any of the nicks specified.
SPY with no argument would tell you what users you have spy on who are
currently on IRC. The system logs last time the last matching person was
on IRC for each SPY request is queued in the server. Read NOTE LOG for this.
You may use flag +A to see what server matching user is on,
and/or +J flag to see what channel. (Read NOTE USER for more).
Example: SPY foobar!username@host <ctrl-G>
SPY +10 foobar
SPY +aj &secret * <ctrl-G>
SPY +365 +e !user nick!*@* <ctrl-G>
SPY % +7 foo!user
SPY +5 nicky %mynick %meenick
Usage: NOTE [STATS] [MSM|MSW|MUM|MUW|MST|MSF|USED|RESET] [value]
STATS with no option displays the values of the following variables:
MSM: Max number of server messages.
MSW: Max number of server messages with username-wildcards.
MUM: Max number of user messages.
MUW: Max number of user messages with username-wildcards.
MST: Max server time.
MSF: Note save frequency (checks for save only when an user register)
Only one of this variables are displayed if specified.
You can change any of the stats by specifying new value after it.
RESET sets the stats to the same values which is set when starting the
server daemon if no note file exist. Notice that this stats are saved
in same file as the other messages.
Usage: NOTE [WAITFOR [&pwd] [+-flags] [+-maxtime] <nick!username@host> [msg]
WAITFOR is an alias for USER +YD (default max 1 day)
Default message is; [Waiting]
This command is for telling the recipient if this appears on IRC that
you are waiting for him/her and notice that this got that message.
Example: WAITFOR foobar
WAITFOR -2 foobar!username@*
WAITFOR foobar Waiting for you until pm3:00..
Usage: NOTE [WALL] [&passwd] [+-flags] [+-maxtime] <nick!user@host> <msg>
WALL is an alias for USER +BR (default max 1 day)
This command is for sending a message once to every matching user
on IRC. Be careful using this command. WALL creates a list of
persons received the message (and should not have it once more time)
with H flag set. This list can be displayed using ls +h from the
nick and username@host which the WALL request is queued from.
Removing the headers (H) before WALL request is removed would cause
the message to be sent once more to what users specified in list.
WALL +7 @*.edu Do not do this! - Makes it clear for all users using
IRC on host @*.edu the next 7 days how stupid it is to send such WALL's ;)
Usage: NOTE [WALLOPS] [&passwd] [+-flags] [+-maxtime] <nick!user@host> <msg>
WALLOPS is an alias for USER +BRW (default max 1 day)
This command is same as WALL, except only opers could receive it.
Usage: NOTE [server] ANTIWALL
Switch off b flag for wall's which you have received on specified
server. The person who queued the wall is notified by the server
about the antiwall, and who requested this.
Usage: NOTE [DENY] [&passwd] [+-flags] [+-maxtime] <nick!user@host> <msg>
DENY is an alias for USER +RZ (default max 1 day)
This command makes it impossible for any matching recipient to
queue any Note requests until timeout. Read NOTE CHANNEL about D
flag settings. Warning: D flag distributes DENY to all other servers
independent of @host. If you use this flag, and want to remove it
again, you have to remove what you queued (the root), and wait a
week until it timeout on other servers, or you may try reach all
servers by doing NOTE *.* XRM nick!username@host
Usage: NOTE [KEY] [&passwd] [+-flags] [+-maxtime] <nick!user@host>
KEY is an alias for USER +KR (default max 1 day)
This command is for allowing no-opers to use oper-options by specifying
the flag to unlock. Be careful with this option!
Example: KEY +365 +s * would make it possible for everybody to use s flag.
Usage: NOTE SERVICE <nick> <note command>
Usefull in robots. Note will take the requests as if from <nick>
Usage: NOTE [SAVE]
SAVE saves all messages with the save flag set. Notice that the
messages are automatically saved (Read NOTE STATS). Each time server is
restarted, the save file is read and messages are restored. If no users
are connected to this server when saving, the ID number for each
message is renumbered.

242
doc/Operators Normal file
View File

@@ -0,0 +1,242 @@
Internet Relay Chat Operator Etiquette Guide
May, 1992
Welcome! You've either been selected to be an IRC Operator or you have set
up your server and thus have taken on the dual task of IRC Server
Administrator and IRC Operator. Your future days will be filled with hours
of fun chatting on IRC, and then wondering why everyone you talked to went
away, because the links had apparently broken.
Linking:
========
You will be assigned links from the IRC Routing Coordinators. Please
use these links and these links ONLY. The links have been designed to
maximize efficiency and make delays in chatting minimal. You will
usually be given two links, one to each regional backbone site.
Connect to the primary site first and then to the secondary site. You
should not need to connect to any other sites. You will be informed if
this policy changes.
Kills
=====
/kill is a special operator command. You should use it with
care, and only if absolutely needed. The format is as follows:
/kill NICKNAME comment. Comment can be a phrase of almost any length
(within reason) and should be used for specifying the reason of the kill.
Example: /kill Trillian She's a Ghost
IRC Ghosts are created after a net split has occured and the net has yet to
relink.
/wallops PHRASE This is used to talk to those users who have their
user mode set to +w. /wallops used to be a way for operators to talk
about important matters in linking etc., but it has little use
nowadays.
/TRACE command /TRACE is useful to know what servers are connected to
what. Sometimes /trace can be confusing, especially if you are using
it for the first time. Here is an example of a trace from
stekt1.oulu.fi to cdc835.cdc.polimi.it.
/TRACE cdc835.cdc.polimi.it
*** Link stekt1.oulu.fi<2.7.2> ==> cdc835.cdc.polimi.it
*** Link rieska.oulu.fi<2.7.1>e ==> cdc835.cdc.polimi.it
*** Link nic.funet.fi<2.7.1>e ==> cdc835.cdc.polimi.it
*** Link ircserver.et.tudelft.nl<2.7.1>e ==> cdc835.cdc.polimi.it
*** Link vesuv.unisg.ch<2.7.1>e ==> cdc835.cdc.polimi.it
*** Link apollo.di.unipi.it<2.7.1>e ==> cdc835.cdc.polimi.it
*** Oper Class[10] ==> Allanon[cdc835.cdc.polimi.it]
*** User Class[11] ==> Lupandy[plus2.usr.dsi.unimi.it]
*** Serv Class[3] ==> apollo.di.unipi.it[131.114.4.36] 132S 445C
*** User Class[11] ==> Punk[pluto.sm.dsi.unimi.it]
*** User Class[11] ==> TheEdge[pluto.sm.dsi.unimi.it]
*** User Class[10] ==> Mork[cdc835.cdc.polimi.it]
*** User Class[11] ==> Lollo[c700-2.sm.dsi.unimi.it]
*** User Class[11] ==> Attila[hp2.sm.dsi.unimi.it]
*** Class 0 Entries linked 1
*** Class 11 Entries linked 5
*** Class 10 Entries linked 2
*** Class 3 Entries linked 1
From this output you can see that the route goes first to
rieska.oulu.fi (running version 2.7.1e), then nic.funet.fi,
ircserver.et.tudelft.nl, vesuv.unisg.ch, and apollo.di.unipi.it, after
which cdc835 is the next server. Then we see the connections on
cdc835: One operator (Allanon) and 6 users are on line. The class of
each connection is given. There is only one server connected to cdc835
at the moment, and that server is apollo.di.unipi.it (cdc835 is said
to be a "leaf" server at the moment). The numbers 132S 445C in the end
of line tell us, that there are 132 servers and 445 clients connected
to the servers from apollo onwards. Finally we see a grand total of
connections in each connection class.
/SQUIT server {comment}
/squit isolates a specified server from the next closest server, when
you look at it along the trace path starting from your server.
This is usually used in conjunction with CONNECT (explained later) to
reroute traffic. This will be described in detail in the section
"routing", preceding CONNECT.
Usage (and examples):
/squit E
If the network looks like this initially (and you are on server A)
A <---> B <---> C <---> D
^
|
v
G <---> E <---> F <---> ... (rest of the net)
Then after issuing the previous /squit the network would look like this:
A <---> B <---> C <---> D
G <---> E <---> F <---> ...
/squit E {comment}
It usually helps to give a reason why you are sending a
SQUIT for a server. This can be accomplished by sending
the command "/squit server This link is making the US route
through Finland". The SQUIT will then be sent out, and the
server sending the squit will WALLOP sending the comment
so all operators can see it.
/CONNECT server {portnum server2}
/connect is used to establish a link between two servers. These
connections must be authorized by each server's ircd.conf file, but
any operator can issue a CONNECT between authorized servers. This
command is most often used in conjunction with SQUIT to reroute
traffic.
If only one argument is given, this command causes the server you
are on to attempt to connect to the server specified. For example,
"/connect B" (in the previous example) would cause your server (A) to
connect to B.
Suppose you wanted to reconnect server F to server E? You cannot
contact server F since it is no longer part of your network. However,
you can tell server E to connect to it. A remote CONNECT can be issued
to server E.
Examples (assume you are on server A):
/connect B
If the network initially looks like this:
A B <---> ... (rest of network)
Then afterwards (if the connection succeeds) the network will look
like this:
A <---> B <---> ...
In the example where you wanted to reconnect server E to F, the
following syntax would be appropriate (note: we are assuming that
F's irc socket port is 6667, which is the default)
/connect F 6667 E
If the network initially looks like this:
A <---> B <---> C <---> D
^
|
v
G <---> E F <---> ...
Then after your CONNECT request the network topology will look like this:
A <---> B <---> C <---> D
^
|
v
G <---> E <---> F <---> ...
Be careful when connecting servers that you know which command to
use! If you simply issued "/connect F" from your server, the
network would look like this:
... <---> F <---> A <---> B <---> C <---> D
^
|
v
G <---> E
which for various reasons (discussed below) might be very
undesirable.
Routing
=======
When and how should you do rerouting? This depends on where your
server is topologically located and whether you route traffic. If you
are a leaf node (i.e. only connect to one server at a time) then
chances are you won't need to do any routing at all. Your ircd.conf
file should be written to connect to the best possible servers first
before trying alternates. At the most, you may decide to squit an
alternate server and connect to your primary if/when it goes back up.
This only involves local squits, however.
If you are operating a backbone site, you may find yourself
rerouting things quite often. If the servers badger.ugcs.caltech.edu
(Pasadena, CA), irc.mit.edu (Boston, MA), minnie.cc.utexas.edu
(Austin, TX) and ucsu.colorado.edu (Boulder, CO) were routing traffic
in the following way:
... <---> minnie <---> badger <---> bucsd <---> ucsu <---> ...
It would make sense to either squit ucsu and reconnect it to minnie,
or disconnect minnie from badger and connect to ucsu, because
topologically (and geographically) ucsu and minnie are rather close.
There are occasions when US traffic for some reasons winds up being
routed through Australia. This is another case where traffic should
definitely be rerouted. However, there are sometimes occasions when
routing is going through "backdoor" methods. If you see something
totally outrageous (like the east coast and the west coast being
connected by eff.org) please ask for example on channel #twilight_zone
before you send any squits, because chances are, it's like that for a
reason.
Of course, any operator can remotely squit or connect servers, so
if you see a problem and you're sure you know how to fix it, it's a
good idea to do so. If the operator of a server which is is being
routed poorly is online, it's probably best to contact him/her first,
though.
Chances are that hub operators will be more familiar with the
general topology of the network and which servers connect to which
(which is why most of the manual routing is left to them), so if you
have any problems, talk to the other operators on operator channels
(#twilight_zone, #eu-opers etc.) That's what they are there for!
Also, be aware that servers will notify all the operators online of
remote SQUITs and CONNECTs via WALLOPS.
Please let us know if there should be any additions to this guide. Again,
this is not MANDATORY, this is just a GUIDE. Please conduct yourself as
an IRC Operator would...you are looked upon for assistance, both emotional
and mental.
Helen Rose Christopher Davis Noah Friedman
<hrose@cs.bu.edu> <ckd@cs.bu.edu> <friedman@ai.mit.edu>
January, 1991
Updated by
Mauri Haikola
<mjh@stekt.oulu.fi>
May, 1992

1901
doc/README.patches Normal file

File diff suppressed because it is too large Load Diff

156
doc/US-Admin/Networking Normal file
View File

@@ -0,0 +1,156 @@
/************************************************************************
* IRC - Internet Relay Chat, doc/NETWORKING
* Copyright (C) 1994, Helen Rose <hrose@kei.com>
*
* 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 1, 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.
*/
Author: Helen Rose
hrose@kei.com
Date: 3 March, 1994
*** Please read this before doing any connecting or writing to ask for
connections. The information contained in this section is crucial to the
way IRC is run.
Note that any old documentation referring to ANet vs EFnet is out of date
and no longer applies. ANet died so long ago that nobody can remember
*when* it died.
To qualify for a link on the irc network, several criteria must be
met. These criteria include (but are not limited to):
* A well established local irc userbase. A total of 100-150 local irc
users. An average of 15-20 irc users over a 24 hour period is also
acceptable. Note, these user counts are *unique, local* users. So
one person running fifteen clients doesn't count, and one local
person plus fifteen offsite people doesn't count. These are not
arbitrary numbers, it takes at least this many users to equate the
traffic of adding another server to the irc network.
* A userbase that uses irc *all the time* (15 users on at once but
just for a 3 hour period per day is not sufficient).
* A good, fast, internet link. Absolutely *NO* SLIP lines. 56k lines
are marginal, they usually cause more trouble than they are worth,
so we recommend a T1 or better.
It is well established that having a local irc server does not attract
local irc users. Often, your best bet is to set up a local client that is
accessible by everyone at your site, connect it to a nearby offsite
server, and then see if the usage level goes up. (See appendix for list of
open-client servers).
To see how many users you have, on irc do /m x@monitor.us show site.name
where site.name is your two-part domain name (eg "kei.com" or "bu.edu" or
"mit.edu"). monitor will tell you how many users you have. Once this
number gets over 125 or so, put the level it has reached in your note to
operlist-request@kei.com.
If you are in the United States and need a link, please mail to
"operlist-request@kei.com" supplying the information listed below.
(1) Find out if your system has /etc/ping (sometimes /usr/etc/ping) and
ping the following hosts:
server/machine name IP address Geographical Location
csa.bu.edu 129.197.10.3 Boston, MA
irc-2.mit.edu 18.180.0.2 Cambridge, MA
polaris.ctr.columbia.edu 128.59.68.10 New York, NY
poe.acc.virginia.edu 128.143.83.132 Charlottesville, VA
irc.iastate.edu 129.186.150.1 Ames, IA
dewey.cc.utexas.edu 128.83.135.3 Austin, TX
irc.netsys.com 198.175.9.8 Palo Alto, CA
w6yx.stanford.edu 36.55.0.50 Stanford, CA
goren.u.washington.edu 140.142.63.1 Seattle, WA
These are results of the typical /etc/ping command:
(note that the machine I am running this from runs SunOS so I have to use
ping -s ):
3:59pm hrose@csa : ~ % ping -s polaris.ctr.columbia.edu
PING polaris.ctr.columbia.edu: 56 data bytes
64 bytes from polaris.ctr.columbia.edu (128.59.68.10): icmp_seq=0. time=137. ms
64 bytes from polaris.ctr.columbia.edu (128.59.68.10): icmp_seq=1. time=163. ms
64 bytes from polaris.ctr.columbia.edu (128.59.68.10): icmp_seq=2. time=110. ms
64 bytes from polaris.ctr.columbia.edu (128.59.68.10): icmp_seq=3. time=111. ms
64 bytes from polaris.ctr.columbia.edu (128.59.68.10): icmp_seq=4. time=78. ms
64 bytes from polaris.ctr.columbia.edu (128.59.68.10): icmp_seq=5. time=82. ms
64 bytes from polaris.ctr.columbia.edu (128.59.68.10): icmp_seq=7. time=83. ms
64 bytes from polaris.ctr.columbia.edu (128.59.68.10): icmp_seq=8. time=91. ms
64 bytes from polaris.ctr.columbia.edu (128.59.68.10): icmp_seq=9. time=159. ms
[...]
^^ ^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^ ^^ ^^^^^^^
Size of packet hostname IP address packet number trip time
----polaris.ctr.columbia.edu PING Statistics----
25 packets transmitted, 25 packets received, 0% packet loss
round-trip (ms) min/avg/max = 78/136/327
When you send pings to operlist-request, please only send the results
(the above three lines)--we *don't* need each packet's time.
Guidelines:
Avg Time Connection is
======== =============
0-20ms Optimal
20-40ms Excellent
40-70ms Very Good
70-90ms Average
90-110ms Acceptable
110ms-150ms Below Average
150ms-200ms Bad
200ms-300ms You're on a very slow link and it is unlikely you will be
able to support a server successfully.
** *** WHERE TO FIND HELP!!! ***
**
** If you have any other questions about connecting to an irc server, please
** mail to operlist-request@kei.com. If you have problems mailing there,
** try mailing hrose@kei.com.
**
** *** WHERE TO FIND HELP!!! ***
Appendix
========
Open client servers.
USA:
csa.bu.edu
irc.colorado.edu
irc.uiuc.edu
Canada:
ug.cs.dal.ca
Europe:
irc.funet.fi
cismhp.univ-lyon1.fr
disuns2.epfl.ch
irc.nada.kth.se
sokrates.informatik.uni-kl.de
bim.itc.univie.ac.at
Australia:
jello.qabc.uq.oz.au

253
doc/US-Admin/Operators Normal file
View File

@@ -0,0 +1,253 @@
Internet Relay Chat Operator Etiquette Guide
January, 1991
Welcome! You've either been selected to be an IRC Operator or you have set
up your server and thus have taken on the dual task of IRC Server
Administrator and IRC Operator. Your future days will be filled with hours
of fun chatting on IRC, and then wondering why everyone you talked to went
away, because the links had apparently broken.
Linking:
========
You will be assigned links from the IRC Routing Coordinators. Please use
these links and these links ONLY. The links have been designed to maximize
efficiency and make delays in chatting minimal. You will be given two
links, one to each regional backbone site. Connect to the primary site
first and then to the secondary site. You should not need to connect to any
other sites. You will be informed if this policy changes.
Kills and Walls:
===============
/kill and /wall are special operator commands. You should use them with
care, and only if absolutely needed. The format are as follows:
/kill USERNAME comment. comment can be a phrase of almost any length
(within reason) and should be used for specifying the reason of the kill.
example: /kill Trillian She's a Ghost
IRC Ghosts are created after a net split has occured and the net has yet to
relink.
/wall PHRASE. This is used for an emergency command like the net is about
to split into little pieces, and everyone should reconfigure their links
as soon as possible. You will see a WALL when it happens, an operators
nickname will appear with # signs around it.
#Trillian# Server bucsd.bu.edu coming down for upgrade. Prepare to
reconfigure links.
/wallops PHRASE This is used to talk to ALL operators at once. It is not
often warranted, but is useful. Often, when there is an important IRC
situation that requires all the operators attention, /wallops is used. The
form for wallops is a nickname with ! signs around it.
!Trillian! Australia should leaf off of eris, not carry all the US traffic.
/TRACE command
/TRACE is useful to know what servers are connected to what. Sometimes
/trace can be confusing, especially you are using it for the first time.
Here is an example of a trace from bucsd.bu.edu to betwixt.cs.caltech.edu.
/TRACE betwixt.cs.caltech.edu
IRC log started Mon Aug 26 17:04
*** Link eff.org<2.6.1a> ==> h.ece.uiuc.edu
-bucsd.bu.edu- *** Link bucsd.bu.edu<2.6.1a> ==> h.ece.uiuc.edu
-h.ece.uiuc.edu- *** Serv Class[3] h.ece.uiuc.edu ==> ucsu.colorado.EDU
-h.ece.uiuc.edu- *** Serv Class[2] h.ece.uiuc.edu ==> bucsd.bu.edu
-h.ece.uiuc.edu- *** Serv Class[10] h.ece.uiuc.edu ==> silver.ucs.indiana.edu
-h.ece.uiuc.edu- *** Serv Class[11] h.ece.uiuc.edu ==> monitor.ece.uiuc.edu[h.ece.uiuc.edu]
-h.ece.uiuc.edu- *** User Class[0] h.ece.uiuc.edu ==> Razorbone[uxa.cso.uiuc.edu]
-h.ece.uiuc.edu- *** Serv Class[10] h.ece.uiuc.edu ==> MHD54.MOORHEAD.MSUS.EDU[134.29.97.1]
-h.ece.uiuc.edu- *** Serv Class[4] h.ece.uiuc.edu ==> *.umich.edu[mingin.engin.umich.edu]
-h.ece.uiuc.edu- *** User Class[0] h.ece.uiuc.edu ==> BooServ[sunc4.cs.uiuc.edu]
-h.ece.uiuc.edu- *** Serv Class[10] h.ece.uiuc.edu ==> nic.stolaf.edu
-h.ece.uiuc.edu- *** Oper Class[0] h.ece.uiuc.edu ==> SodaPop[h.ece.uiuc.edu]
-h.ece.uiuc.edu- *** Serv Class[4] h.ece.uiuc.edu ==> oddjob.uchicago.edu
-h.ece.uiuc.edu- *** User Class[0] h.ece.uiuc.edu ==> Deviant[isca01.isca.uiowa.edu]
-h.ece.uiuc.edu- *** Serv Class[10] h.ece.uiuc.edu ==> *.uc.edu[hilbert.che.uc.edu]
-h.ece.uiuc.edu- *** Class 0 Entries linked: 4
-h.ece.uiuc.edu- *** Class 11 Entries linked: 1
-h.ece.uiuc.edu- *** Class 10 Entries linked: 4
-h.ece.uiuc.edu- *** Class 4 Entries linked: 2
-h.ece.uiuc.edu- *** Class 3 Entries linked: 1
-h.ece.uiuc.edu- *** Class 2 Entries linked: 1
This shows that from eff.org (running version 2.6.1a to h.ece.uiuc.edu,
routing goes through bucsd.bu.edu before reaching h.ece.uiuc.edu.
"h" is connected to ucsu.colorado.edu, silver.ucs.indiana.edu,
monitor.ece.uiuc.edu (which resolves to [h.ece.uiuc.edu], hence the
square brackets), mhd54.moorhead.msus.edu, *.umich.edu (which resolves
to mingin.engin.umich.edu), nic.stolaf.edu, oddjob.uchicago.edu,
*.uc.edu (which resolves to hilbert.che.uc.edu), and bucsd.bu.edu, which
is known as its "uplink". It is quite normal for a server to have
several "uplinks" if it is busy. An uplink is the link towards the top
of the tree which carries alot of traffic. "h" also has several users on
it, RazorBone, BooServ, and Deviant. SodaPop is also an active operator
on h.ece.uiuc.edu. You can tell each host from what each person is
logged into by looking just past their nickname. For example, Deviant is
logged in from isca01.isca.uiowa.edu.
/SQUIT server {comment}
/squit isolates a specified link from the next closest uplink server.
This is usually used in conjunction with CONNECT (explained later) to
reroute traffic. This will be described in detail in the section
"routing", preceding CONNECT.
SQUIT can be used in one of two ways. It can be used on a local
server, which would cause the server name specified to be unlinked
relative to your path; or you can send a message to another server
instructing it to issue an SQUIT to that server, in which case the
break will be relative to the remote server.
Usage (and examples):
/squit E
If the network looks like this initially (and you are on server A)
A <---> B <---> C <---> D
^
|
v
G <---> E <---> F <---> ... (rest of the net)
Then after issuing the previous /squit the network would look like this:
A <---> B <---> C <---> D
G <---> E <---> F <---> ...
/squit E {comment}
It usually helps to give a reason why you are sending a
SQUIT for a server. This can be accomplished by sending
the command "/squit server This link is making the US route
through Finland". The SQUIT will then be sent out, and the
server sending the squit will WALLOP sending the comment
so all operators can see it.
/CONNECT server {portnum server2}
/connect is used to establish a link between two servers. These
connections must be authorized by each server's ircd.conf file, but
any operator can issue a CONNECT between authorized servers. This
command is most often used in conjunction with SQUIT to reroute
traffic.
If only one argument is given, this command causes the server you
are on to attempt to connect to the server specified. For example,
"/connect B" (in the previous example) would cause your server (A) to
connect to B.
Suppose you wanted to reconnect server F to server E? You cannot
contact server F since it is no longer part of your network. However,
you can tell server E to connect to it. A remote CONNECT can be issued
to server E.
Examples (assume you are on server A):
/connect B
If the network initially looks like this:
A B <---> ... (rest of network)
Then afterwards (if the connection succeeds) the network will look
like this:
A <---> B <---> ...
In the example where you wanted to reconnect server E to F, the
following syntax would be appropriate (note: we are assuming that
F's irc socket port is 6667, which is the default)
/connect F 6667 E
If the network initially looks like this:
A <---> B <---> C <---> D
^
|
v
G <---> E F <---> ...
Then after your CONNECT request the network topology will look like this:
A <---> B <---> C <---> D
^
|
v
G <---> E <---> F <---> ...
Be careful when connecting servers that you know which command to
use! If you simply issued "/connect F" from your server, the
network would look like this:
... <---> F <---> A <---> B <---> C <---> D
^
|
v
G <---> E
which for various reasons (discussed below) might be very
undesirable.
Routing
=======
When and how should you do rerouting? This depends on where your
server is topologically located and whether you route traffic. If you
are a leaf node (i.e. only connect to one server at a time) then
chances are you won't need to do any routing at all. Your ircd.conf
file should be written to connect to the best possible servers first
before trying alternates. At the most, you may decide to squit an
alternate server and connect to your primary if/when it goes back up.
This only involves local squits, however.
If you are operating a backbone site, you may find yourself
rerouting things quite often. If the EFnet servers (see the file
doc/networking) badger.ugcs.caltech.edu (Pasadena, CA),
irc.mit.edu (Boston, MA), minnie.cc.utexas.edu (Austin, TX) and
ucsu.colorado.edu (Boulder, CO) were routing traffic in the following way:
... <---> minnie <---> badger <---> bucsd <---> ucsu <---> ...
It would make sense to either squit ucsu and reconnect it to minnie,
or disconnect minnie from badger and connect to ucsu, because
topologically (and geographically) ucsu and minnie are rather close.
There are occasions when US traffic for some reasons winds up being
routed through Australia. This is another case where traffic should
definitely be rerouted. However, there are sometimes occasions when
routing is going through "backdoor" methods. If you see something
totally outrageous (like the east coast and the west coast being
connected by eff.org) please /WALLOPS and ask before you send any
squits, because chances are, it's like that for a reason.
Of course, any operator can remotely squit or connect servers, so
if you see a problem and you're sure you know how to fix it, it's a
good idea to do so. If the operator of a server which is is being
routed poorly is online, it's probably best to contact him/her first,
though.
Chances are that hub operators will be more familiar with the
general topology of the network and which servers connect to which
(which is why most of the manual routing is left to them), so if you
have any problems, talk to the other operators via /wallops. That's
what it's there for!
Also, be aware that servers will notify all the operators online of
remote SQUITs and CONNECTs via WALLOPS.
Please let us know if there should be any additions to this guide. Again,
this is not MANDATORY, this is just a GUIDE. Please conduct yourself as
an IRC Operator would...you are looked upon for assistance, both emotional
and mental.
Helen Rose Christopher Davis
<hrose@cs.bu.edu> <ckd@cs.bu.edu>
Noah Friedman
<friedman@ai.mit.edu>
January, 1991

332
doc/example.conf Normal file
View File

@@ -0,0 +1,332 @@
# IRC - Internet Relay Chat, doc/example.conf
# Copyright (C) 1994, Helen Rose
#
# 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 1, 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.
#
# This is an example configuration file for the IRC server
#
# You only need an ircd.conf (IRC server configuration file) if you are
# running an IRC server. If you are running a standalone client this file
# is not necessary.
#
# This file will explain the various lines in the IRC server
# configuration file. Not all lines are mandatory. You can check to make
# sure that your configuration file is correct by using the program
# "chkconf", provided in the server distribution (and when you do "make
# install" this program will be installed in the same directory as the irc
# server).
#
# The options for whether a line is needed or not are:
# MANDATORY: you absolutely MUST have this line
# NETWORKED: you must have this line if you are connecting this irc
# server to any other server (servers can run standalone).
# SUGGESTED: it is highly suggested that you use this line
# OPTIONAL: it's completely up to you whether to define this or not
# DISCOURAGED: you really really should not use this line if at all
# possible.
# NOT NECESSARY: an old or out of date line that isn't needed.
#
# MANDATORY lines are absolute *musts*, that is, if you do not have this
# line then your server will not work properly. SUGGESTED lines are
# close-to-mandatory (that is, the server will run without it, but you are
# highly encouraged to use these lines).
#
# Note that "*" in a field indicates an "unused" field.
#
#
# ========================================================================
# NOTE! this entire configuration file is read UPSIDE-DOWN! So if you have
# to put something in a specific order (for example, client-connection
# lines), put them in reverse order!
# ========================================================================
#
#
# M: [MANDATORY]. This line sets your server's name, description, and
# port number. Fields, in order, are:
#
# M:hostname:*:Description Of Your Server:6667
#
M:csa.bu.edu:*:Boston University Computer Science Department:6667
#
# A: [MANDATORY]. This line lists your administrative information
# (contact address, etc). To view this information, /admin (server) will
# show it to you.
#
# The A: line has no set information, in fact, you can put arbitrary text
# in there if you wish (it is encouraged that you put at *least* a contact
# address for a person responsible for the irc server, however)
#
A:Boston University CS Department:Main Client Server:Helen Rose <hrose@cs.bu.edu>
#
# Y: [SUGGESTED]. These lines define connection classes. Connection
# classes allow you to fine-tune your client and server connections. It is
# suggested that clients and servers be placed in seperate classes, and if
# you have lots of server connections (if you do have lots of servers you
# shouldn't be reading this file :-) each set of servers (defined
# arbitrarily by you) should have its own class. If you have clients
# coming in from lots of different sites, you may want to seperate them
# out into classes. For instance, you may want to put local users in one
# class, with remote users in another class.
#
# The class numbers are not arbitrary. In auto-connecting servers -- that
# is, servers that you have a port number (e.g. 6667) on the end of the C:
# line (see below) the higher the number the higher the priority in
# auto-connecting.
#
# The fields in order are: class number, ping frequency (in seconds),
# connect frequency (in seconds), maximum number of links (used for
# auto-connecting, and for limiting the number of clients in that class),
# and sendq (this overrides any value set in include/config.h for #define
# MAXSENDQLENGTH).
#
# Note that it is a good idea to have ping frequency the same at both ends
# of the link.
#
# in this case, connect-frequency is 0 indicating that this is a client
# class (servers never connect to clients, it is the other way around).
Y:1:90:0:20:100000
#
# this is a normal server connection (normal as of March, 1994)
Y:2:90:300:1:600000
#
Y:10:90:0:3:100000
#
# I: [MANDATORY]. The I: lines are client-authorization lines. Without
# these lines, no clients will be able to connect to your server.
# Wildcards ("*") are permitted. Passwords are also permitted (clients can
# be configured to send passwords).
#
# Ident (for more information on this, see rfc1413) can also be used by
# placing a @ in the appropriate fields.
#
# Fields are as follows:
# I:IP-address-mask:optional password:domain-mask::connection class (opt)
#
# With a password..... This will allow anyone from anywhere to connect
# as long as they know the password ("foobar"). Note listing this I: line
# first, it will be read *last*, meaning it is the "fall-through". That
# is, anyone who doesn't match the I: lines listed below must know the
# password ("foobar") to connect.
#
I:*@*:foobar:*@*::1
# This is a standard vanilla I: line which will permit anyone with an IP
# address starting with 128.197 OR with a hostname ending in .bu.edu to
# connect to the server. NOTE, the ircd matches on the *right-most* match,
# so if I connect as hrose@csa.bu.edu (which is hrose@128.197.10.3) I will
# show up on irc as hrose@csa.bu.edu since that is the first match it
# found. (Even though the second match is valid).
I:128.197.*::*.bu.edu::1
#
# using ident
I:*@128.197.*::*@*.bu.edu::1
# and you can even specify just certain usernames running ident (as long
# as the client's site is running the ident daemon):
I:NOMATCH::hrose@csa.bu.edu::1
# putting NOMATCH in the first field will stop the ircd from matching
# automatically against the IP address and it will force the server to
# match against the hostname. (the "NOMATCH" string is not mandatory, you
# can use any arbitrary text in the first field).
#
#
# O: [OPTIONAL]. These lines define operator access. You do not need to
# have an operator to run a server. A well configured leaf site should not
# need an operator online, if it's connections are well defined, the irc
# administrator can use kill -HUP on the ircd to reload the configuration
# file.
# The fields are as follows:
# O:hostname (ident "@" permitted):password:NickName
# if the person in "NickName" is not coming from the hostname defined in
# the first field then the person will get the error message "No O: lines
# for your host".
# NOTE that since Crypted Passwords are defined by default in
# include/config.h this text probably will not be plaintext. See
# ircd/crypt/README for more information.
#
O:*.bu.edu:Zaphod:Trillian::10
#
# and this line forces ident:
O:hrose@csa.bu.edu:Zaphod:Trillian::10
#
# This line is a "local operator", it is specified with a lower-case "o"
# -- it is the only lower-case type in the ircd.conf file.
#
# this line permits the nickname "jhs" with the password of "ITBites" to
# be a local operator only (be able to issue commands locally -- can /kill
# and /squit and /connect -- but *only* locally)
#
o:*.bu.edu:ITBites:jhs::10
#
# a crypted password line (NOTE that if you have crypted passwords, *all*
# of you passwords must be crypted! In fact, if you are getting an error
# "Incorrect Password" it may well be because crypted passwords are
# defined and you have used plaintext. So my example of plaintext and
# crypted strings in the same IRC server configuration file is an
# impossibility (but it is just theoretical, which is why I explained both).
#
O:rocker@csa.bu.edu:T0eiVgHrqeKTQ:Rocker::10
#
# U: [NOT NECESSARY]. This line defines the default server for the IRC
# client that ships with the server -- the default client is in irc/irc
# You should not use U: lines but instead use the UPHOST definition in
# include/config.h
U:csa.bu.edu:foobar:csa.bu.edu
#
# C: [NETWORKED]. These lines define what servers your server tries to
# connect to.
# N: [NETWORKED]. These lines define what servers your server permits
# connections to be initiated from.
# C/N lines MUST be used in pairs. You cannot have one without the other.
#
# C: lines contain the following fields:
# C:remote server's hostname:passwd:remote server's name:port:conn class
# (connection class)
# N: lines contain the following fields:
# N:remote server's hostname:passwd:remote server's name:host mask:conn class
# (connection class)
# "host mask" is the number of parts in *your* hostname to mask to. For
# instance, with my servername being "csa.bu.edu", if I wanted to present
# my servername to be "*.bu.edu" I would have a host-mask portion of "1".
#
# it is *strongly* advised that your C/N line passwords be different for
# security's sake.
#
# ident is allowed in the server's hostname part of the field.
# these lines tell the server to automatically (note the port number, that
# means automatic connection) connect to cs-ftp.bu.edu:
C:hrose@cs-ftp.bu.edu:bigspark:cs-ftp.bu.edu:6667:2
N:hrose@cs-ftp.bu.edu:bigalpha:cs-ftp.bu.edu::2
#
# This server's connection lines are more vanilla, masking the host to
# *.bu.edu (as described above):
C:irc-2.mit.edu:camelsrk00l:irc-2.mit.edu::2
N:irc-2.mit.edu:andsoarellamas:irc-2.mit.edu:1:2
#
# K: [OPTIONAL]. These lines define user@host patterns to be banned from
# this particular server (with an optional time field). Note that K: lines
# are *not* global, and if you ban a user they can still use any other IRC
# server (unless they have specifically been banned there as well).
#
# the fields are defined as:
# K:hostmask:time field:username
# wildcards are permitted in any one of the fields, in other words, you can
# K:*::* if you wanted (but your server wouldn't be used much ;-)
#
# This K: line bans the username "FSSPR" (the wildcards are used to make
# sure that any ident-checking character will match) on any machine from
# the University of Alaska.
K:*.alaska.edu::*FSSPR*
#
# This K: line bans any users from acs*.bu.edu between the hours of 8am
# and 12pm and 1pm and 5pm (the time is always the server's local time):
K:acs*.bu.edu:0800-1200,1300-1700:*
# Note that 24 hour time is used (no "AM" or "PM").
#
# R: [DISCOURAGED]. These lines restrict user access based on a more
# stringent checking system than is available in the K: line. It looks for
# a match (based on hostname and username) and then runs an outside
# program (which MUST be specified using a full pathname). The output of
# the program should be a string in the form "Y <message>" (which permits
# access for the user) or "N <message>" (which denies access for the
# user). If "Y <message>" is received by the server, the server ignores
# the message and permits access for the user. If "N <message>" is
# returned, the server tells the user that he/she is not permitted to
# access that irc server, and gives the reason.
#
# Again, like K: lines, R: lines are local and thus not very effective in
# blocking certain machines from having IRC access.
#
# Use of R: requires that you have defined R_LINES in include/config.h
#
# The fields are as follows:
# R:hostmask:/full/path/to/program:username
# you can use wildcards in either the hostmask or username portion
#
R:csl.bu.edu:/home/hrose/bin.sun3/sun3access:*
#
# Q: [DISCOURAGED]. These lines "quarantine" specified servers. Because
# of the way they operates, the same Q: lines MUST be installed by
# everyone or the net will keep breaking. I CANNOT EMPHASIZE THIS ENOUGH.
# Do NOT use Q: lines lightly!
#
# The fields are as follows:
# Q:*:reason why quarantine is in place:servername
#
Q::this server is too slow and lags the net:cm5.eng.umd.edu
#
# L: [OPTIONAL]. These lines "Leaf" specified servers. They are only
# useful if you are a non-leaf site yourself. There are two ways you can
# use L: lines. The first will limit one particular site to a particular
# tree depth (including 0, which would mean the server has to connect with
# no servers linked behind it otherwise the connection will fail). The
# second will allow you to be selective about which other servers you wish
# the connecting server to behave as a leaf towards.
#
# The fields are as follows:
# L:disallow connections to this hostmask::server name:depth
# For example, this will force kaja.gi.alaska.edu to connect only as a
# leaf (if it is not a leaf, the link will be dropped):
L:::kaja.gi.alaska.edu
# This line will force cm5.eng.umd.edu to have a depth of only 1 below it
# (that is, it is allowed to have only leaves connected to it):
L:::cm5.eng.umd.edu:1
#
# This line will prohibit anything matching *.edu to be connected behind
# any server matching *.au:
L:*.edu::*.au
#
# H: [OPTIONAL]. These lines define who you permit to act as a "hub" to
# you (that is, who you permit to connect non-leafed servers to you).
#
# the first field may use wildcards, the third field *must* be an exact
# match for a server's name (NOT a server's hostname, if they differ, the
# server's name must be used). If the servername is a wildcard (e.g. *.au)
# that is an acceptable name for the third field.
#
# The fields are as follows:
# H:servers which are permitted entry::hub server
#
# Example, permit cs-ftp.bu.edu to allow any servers behind it to connect:
H:*::cs-ftp.bu.edu
#
# Example, permit irc-2.mit.edu to allow any MIT servers behind it to
# connect:
H:*.mit.edu::irc-2.mit.edu
#
# T: [OPTIONAL]. These lines allow you to specify different motd's for
# different types of clients. This could be used to give *.edu users
# some informational message, while giving *.cl users a pointer to a
# closer server.
#
# The fields are as follows:
# T:hostmask:pathname
# for example, to give *.edu users the MOTD file /usr/ircd/lib/edu.motd:
T:*.edu:/usr/ircd/lib/edu.motd
#
# P: [OPTIONAL]. This field allows the server to listen on various ports
# (other than 6667) for connections. Any internet domain port that is
# below 1024 means the ircd has to be run from inetd. The server can
# listen to ports in the UNIX domain or the internet domain. If you wish
# to create a port in the UNIX domain you must compile with UNIXPORT
# defined in include/config.h. If you are permitting connections to a
# seperate port, you can control access to that port by the host field.
#
# The fields are as follows::
# P:hostmask or UNIX socket file:*:*:port number
# for example, an internet domain socket on port 6665 for South African
# users:
P:*.za:*:*:6665
#
# This line is an example of a UNIX domain socket in /tmp
P:/tmp/.ircd:*:*:6666

478
doc/history/2.4.notes Normal file
View File

@@ -0,0 +1,478 @@
/************************************************************************
* IRC - Internet Relay Chat, 2.4.notes
* Copyright (C) 1990 Markku Savela
*
* 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 1, 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.
*/
IRC 2.4 release notes 6 May 1990/msa (Markku.Savela@vtt.fi)
============================================================
This document explains the changes I have done up to this
point. Some additional changes and packaging has been made by
Chelsea (chelsea@earth.cchem.berkeley.edu). This is personal
view of the changes.
CHANGES TO LAST THE OFFICIAL RELEASE (2.2PL1)
This release of irc2.4 is based to 2.2PL1 release (see the
HISTORY chapter later in this document). Aside from fixing the
bugs, this version is in many ways different from the 2.2PL1.
The purpose of the most changes is to make it easier to run an
IRC server. Normal users benefit from these changes indirectly
by getting a better maintained server.
1. Changes visible to normal users
Even while mainly fixing bugs, some user visible changes have
crept in too.
1.1 General note on wildcards
Many commands accept now wildcard matching where applicable. All
compares are case insensitive (e.g. "a" == "A"). The wild cards are
? matches any single character
* matches any number of characters, also empty
string. [PL1 had a bug, which caused "*du*"
not match "....edu"].
1.2 Server supported wildcards for "/who mask" command.
Protocol message is "WHO mask", where mask can be
empty
0 List all users [No change from PL1]
* List all users on the same channel where the user is
(or all, if user is on 0) [No change from PL1].
number List all users on the specified channel [No change
from PL1]. Note, if the "mask" begings with a digit,
this form is assumed, and the remainder of mask is
ignored, e.g. "/who 12*.fi" gives all people from
channel 12 and ignores the "*.fi" part.
mask If the mask is any string, it will be compared
*separately* to each information field of the user
and if a match is found in any field, that user
is included into the list. The fields searched
are
nickname
loginname (account name)
real name (text shown in parenthesis)
hostname (users machine)
servername (server he/she is using)
Note: servername is not usually shown on WHO output,
but is included in anyway. Example: finding all users
somehow connected with Finnish sites, can be achieved
with mask "*.fi".
1.3 Changes to /whois command
As WHO, also /whois accepts wild cards as a parameters. WHOIS
returns information for all users whose nickname matches the specified
mask.
WHOIS automaticly calls WHOWAS [see below], if the attempted nickname
is not found.
1.4 Short term "WHOWAS" history
The server has a short in memory cache of the recent nickname changes
(the current default is set to 200 last changes). The design goal of
this is that it remembers changes in last few minutes, there is no
intention of this to be a long term history. That must be a separate
project, although it could use the hooks provided by this service.
"WHOWAS nickname" queries this cache and returns about the same
information that WHOIS would do, if the nickname is found. Wildcards
are not accepted here, this is a specifically designed feature. If
the name is not found, WHOWAS doesn't reply anything. This is because
the most useful use of WHOWAS is implicitly through "WHOIS".
This history is also implicitly utilized by KILL command.
1.5 New SERVER-SERVER/SERVER-CLIENT protocol message WALLOPS
The message ":source WALLOPS :Message" sends the message text
to all operators that are currently online. Any user can use this
command, it's not restricted. How this function is activated, depends
on the client, but if nothing else works, "/quote wallops text" should.
NOTE:This function will not be fully operational until *ALL*
servers have upgraded to version 2.4. Also, operators
must be using a client that recognizes this command.
This is really a hasty addition. But, done this way it follows
the general IRC message philosophy, where messages are sent only
to links where they are needed (e.g. WALLOPS goes only to servers
that have opers online--it's not broadcast to every server).
1.6 General use of wildcarding in server queries
All commands that previously took a servername as a parameter,
now accept also a wildcarded mask. The mask is replaced with
the first matching servername. The following user level commands
are affected
/admin server -- administrative info
/time server -- local time
/version server -- the server version
/motd server -- "the message of the day"
/info server -- info (usually same on same server version)
/stat f server -- statistics information
/users server -- users logged on server machine
Note: Remote capability is a new feature for "info" and "stat"
commands. Until all servers have upgraded, these commands may not
reach the intended target and may return the information from some
intermediate server.
1.7 Marking user AWAY
v2.2PL1 version and earlier showed the AWAY-state (G) only for
the local users of the same server. AWAY status could be queried
only by sending a message to a user. This release (or since msa.4)
broadcasts the away status to every server and the commands /WHO and
/WHOIS give this information reliably.
A side effect of this change is: when a user marks himself/herself
as AWAY, all pre-msa.4 servers that are reached will send back an
acknowlegde message. Until all servers are upgraged, use of AWAY
is somewhat inconvenient. If you get extra messages from AWAY,
they also contain the server information. Use /admin command and
send a *friendly* request for the admin to upgrage his/her server
to a working version, namely 2.4 :)
1.8 Servers don't restrict characters within messages
The parameter fields of the messages can now contain any characters
in range 1-255, except '\r', '\n' and '\0'. The client programs should
by default filter away the "dangerous" control characters, but intelligent
clients can utilize this change and allow exchanges with foreign
8-bit (or wider) charactersets. (The actual command parts must still be
represented with the ordinary 7-bit characters.)
2. Changes visible to the server administrator
2.1 Identifying servers
Servers/clients have now always two names (it was this way in
PL1, but I think this version makes the idea more clear):
Announced Name:
The official name of the server (the name you use in
/time, /quote connect, etc) or users nickname. Servers
name is usually the hostname, but can actually be almost
any string of characters resembling hostname. This one
is given in M-line of ircd.conf.
Socket hostname:
Socket hostname of the server or client. This is the hostname
of the connecting server/client and this is resolved from the
connection. If resolve cannot be done, ircd defaults to using
numeric IP-address. *ALL* access checks are based on this
name, especially noteworthy fact, if your resolver cannot find
hostnames by IP-address, you must allow the access by IP-numbers
in your ircd.conf.
In many places, where servers name is shown, actually both are
shown. The general format of the displayed name is
AnnouncedName[SocketHostName]
When a connection is yet unkown, there is no AnnouncedName, and if the
AnnouncedName is the same as SocketHostName, the "[..]"-part is omitted.
2.2 Many notices to local operators
If an oper is signed on the server, he/she will receive many
notices about exceptional conditions and servers actions. When
something goes wrong, it should be much easier to fix the problems.
Few often occurring, inportant error messages are
"Write error to SERVERNAME, closing link"
write() to socket returned with an error. Server is
closing the link. This means usually network problems
which you can do nothing about.
"Max buffering limit exceeded for SERVERNAME"
This is the situation where old server would have been
"frozen". The socket buffers in your OS have been filled and
even servers own predefined internal buffering MAX for a link
has been exceeded. Exceeding this limit most likely means
that the link is really dead, so the server closes the link
and scratches all queued output for it. If the limit is
set high ( > 20000 bytes), you won't usually see this, but
just "No responce from SERVERNAME, closing link" as the
server does not reply to PING as it should.
"Link SERVERNAME cancelled, server SERVERNAME already exits"
Two different servers from your net fragment attempted
to connect same other net fragment about the same time
and this collision is detected at your server. IRC routing
does not allow loops, the link causing the loop is closed.
(Which of the two links gets closed is mostly determined
by pure chance and timing--you may lose a better link this
way. Collisions should be rare in normal operation, if
the timers in "config.h" are not messed up too much...)
Of course, you get this too, if you try to connect to a
server that is already connected by some other route. In
that case your attempted connection is just safely cancelled.
The notices attempt to be self explaining.
2.3 Links statistics collecting
IRCD now counts the bytes and messages transmitted to each open
link. This information can be output with a command "/stats l"
("/stats" or "/stat m" will give the old message count statistics).
Sample output
Link SendQ SendM SendBytes RcveM RcveBytes Open since
oddjob.uchicago 0 203 8067 772 34321 Sun May 6 02:15:45 1990
cs.hut.fi[sauna 0 1916 79798 94 3082 Sun May 6 01:51:25 1990
otax.tky.hut.fi 0 3722 151511 426 22690 Sun May 6 00:25:54 1990
nada.kth.se 0 8775 355811 5333 223853 Sat May 5 14:11:49 1990
vehka.cs.uta.fi 0 23816 882000 901 41156 Fri May 4 22:50:23 1990
lut.fi 0 25145 943765 1068 35020 Fri May 4 22:34:16 1990
kreeta.helsinki 0 24286 899191 957 47085 Fri May 4 22:33:28 1990
naakka.tut.fi 0 27754 1067302 8288 362960 Fri May 4 22:33:14 1990
joyx.joensuu.fi 0 30003 1172949 2300 80053 Fri May 4 22:33:05 1990
tel4.tel.vtt.fi 04083771 167473890 863475 35022755 Mon Apr 23 00:15:17 1990
| | | | | |
| | | | | Link established
| | | | The number of bytes received
| | | The number protocol messages received
| | The number of bytes transmitted
| The number of protocol messages transmitted
The amount of queued data in bytes (if socket is hung)
The last row (with the local servername) contains the total
cumulative counts for all connections since the server was started.
One can query the statistics of a remote server by adding the servers
name to the command "/stat l servername". Of course, this only works,
if all intermediate servers have upgraged. The first "old" server
will stop the propagation and return the message counts by default.
2.4 Connecting servers
An oper can manually activate a connection phase to any server
defined in ircd.conf C-lines (to successfully complete the connection,
the N-line must be present too). The message achieving this is
CONNECT servername portnumber
where servername may be a mask string containing wildcards. This
name is matched against entries in ircd.conf (notice: the testing
is made in reverse order, e.g. the last C-line in ircd.conf is tested
first). If portnumber is omitted, the ircd uses the one given in the
found C-line. If the C-line does not have the portnumber, the compiled
default will be used (PORTNUM from config.h).
This release allows also for remote connecting. An oper can send
a connect request to remote server with
CONNECT servername portnumber remoteserver
This command is passed to the 'remoteserver' and it then tries to
execute it like it was given locally. (If there are opers online on
that server, they will get a notice about this happening.) Note, that
one can remotely connect only what is defined in ircd.conf. Usually
one needs and should use this only for immediate your neighbours. Nobody
should randomly go and give connect requests to distant servers, unless
one knows it's absolutely necessary and is very familiar about the
linking setup there.
2.4 Terminating connections
The SQUIT command in PL1 was not intended to be used manually and
was very dangerous to use (it also created so called "ghost servers").
Since msa.4, the SQUIT has been safer to use manually.
"SQUIT z" s a
\ /
\ /
------- x ------- y --| |-- z ------- b
/ ^ \
/ | \
p c
"SQUIT z" will break the link between "y" and "z" if injected
into system from "s". After that the net will be in two fragmets,
broken between "y" and "z". Server "z" never sees the actual
SQUIT, all it observers is that the link to "y" suddenly closes
(opers on z would see it as "Server y closed the connection"
notice. Opers on y would see it as "Received remote SQUIT from
x", note that the actual source "s" is not identified in the
current version--for reasons too complicated to be explained
here).
*WARNING* *WARNING* If the server "y" is still running pre-msa.4
(like PL1), don't *EVER* issue a SQUIT for its links (unless the
link is to a leaf node or verifiably a "ghost server").
Note, that when the link between "y" and "z" breaks, y will spit
out SQUIT's for "z", "a", "b" and "c" to "x". At same time "z"
is sending SQUIT's for "x", "s", "p", etc to "a", "b" and "c".
SQUIT is normally generated by servers automaticly, it's just
a later modification (msa.4) that allows an OPER to use this
same message to "simulate" a link break at certain point.
*IMPORTANT* If server "z" has configuration "C:y::y:6667", it
automaticly attempts to reconnect after a short delay (currently
10 seconds), but only *if* the connection has been up long enough
reliably (currently set to 10 minutes). If the thus formed link is
squit another time, it will not attempt to come back immeatedly.
This gives an oper time to reconfigure the links if that first
short delay is not enough.
As in all commands, also SQUIT accepts wildcards, but be careful to
give sufficient identification. SQUIT of wrong server is not nice...
2.5 KILL message
KILL will implicitly use the history database. If a KILL is
issued for a nick that has been changed to another, the server
will automaticly re-issue the kill with the new nickname, if
the change has happened recently (current value should be 90
seconds). If a "terrorist" is clearly distrupting channel by
bombarding it with garbage from negative channels and changing
nick all time, there is no need to consult the "WHOWAS" data
base, just use the nickname that was used to send the garbage
and ircd hunts the culprit down. When this change of target
happens, the oper issuing the kill is notified.
NOTE: With automatic, kill-proof-reconnecting clients, the
value of KILL is becoming insignificant...
2.6 Changing the server defaults from the command line
The servers activation command is now
ircd[ -f configfile][ -h servername][ -p portnumber][ -x debuglevel]
where parameters can be given in any order. If the "configfile"
is defined, it will override the default specified in the file
"config.h". If "servername" is defined, it will override the
one defined in the M-line on the configuration line. "portnumber"
will override the compiled default (from "config.h") or the
one from the M-line of the configuration file. The "debuglevel"
will determine the amout of logging the server does into a
log file that has been define in "config.h". The "debuglevel"
should never be defined for a server running normally, it can
quickly generate megabytes of trace. Usually needed only when
the server is incapable of starting properly at all, then one
run with "-x9" usually is enough to reveal the problem.
3. General cleaning up and commenting the code
This issue is controversial. My way of fixing bugs is not just
fix them, I also want to program defensively, make it difficult to
make new errors. Thus I have heavily reformatted and reorganized
those files that I have had to touch. Some functions have been
renamed intentionally to catch all uses of those functions [because
the functions semantics or calling sequences have been changed].
This release (2.4) will be the last IRC version I'm contributing
to. If you have any wishes or complains about the code or functioining
of IRC, use the source or ask whomever it happens to be the current
developer.
HISTORY
There have been many different versions of IRC and many of those
versions are still in use. The following attempt to bring some
clarification to the versions. This starts from 2.01.6, hopefully
no servers are running older versions...
...
...
2.01.6 A version from WiZ in summer 1989
...
2.01t6 A series of releases, which contained minor
2.01T6 adjustements and bug fixes to the base version.
2.01u6 Some of those fixes caused extra errors, of
2.01U6 this series versions 2.01U6 and 2.01v6 are at
2.01v6 least known to be rather stable.
2.1.0 Mike Bolotski created these versions from the sources
2.1.1 of 2.01U6, but unfortunale some devious bug crept in
and caused a lots of linking problems (the nasty "ghost
server problem" splintered the net constantly). These
versions must be deleted on sight :) [Autumn 1989]
2.2 This version is the 2.01v6 sources repackaged into
multiple directories by Mike again. Probably nobody
is running this base version, because is was promptly
followed by two patch releases [Autumn 1989]
2.2PL0 These two are the last major "official" releases
2.2PL1 and most of the servers upgraged to either of
these.
2.2msa Unfortunately 2.2PL1 version had a tendency to die
mysteriously very often. So, I started to look into the
code from March 1990 and that resulted a series of
patches to the 2.2PL1 server code, but finally
decided to release full server code releases of which
few have got wider distribution
2.2msa.4
Has most of the known PL1 bugs fixed and seems
to be very reliable. But once servers started
staying up, a new problem appeared: socket
buffers started getting full and servers tended
to freeze very often for long intervals.
2.3alpha
2.3 Is an attempt to make an official release from 2.2msa.4
code, but hassles with changed copyrights make this
version unacceptable. Besides, 2.3alpha or 2.2msa.4 are
now obsolete, old versions :)
2.2msa.x
To solve the freezing problems, the server code is changed
to use non-blocking sockets.
2.2msa.7
2.2msa.9
Are intermediate test versions, of which .9 seems
to have most of the problems solved.
2.2msa.10
Never released. This is slightly improved version
of msa.9, some new features.
2.4 Is a release which combines 2.2msa.10 and Chelsea's
modifications to the server. Also, this release has
once again reorganized the directories and makefiles.
-- msa (Markku.Savela@vtt.fi)

128
doc/history/2.7-New Normal file
View File

@@ -0,0 +1,128 @@
* WHOREPLY and NAMREPLY become numberics instead of strings.
* msa's patches to kick/mode to attempt to follow nick name changes
* spike's patches to get SUMMON to find last idle tty
* melazy's various DNS improvements.
* pjg's saber C check
* prefix changed for all server->client messages in which the origin
of the sender is a client to appear as follows:
nick!user@host
* TRACE output changed.
* # channel topics broadcast
* +-numeric channels removed from server
* numerics for TRACE output 201-209
* new switches for STATS: i,k,q,y
* numerics for stats output 211-219
* MODE changed to also operate on users
* deoper added as both mode and direct command. deoper sends out
":user OPER -" to other servers. (from Kaizzu)
* XTRA/VOICE/GRAPH removed.
* MODE +a scrapped.
* added custom ANSI-compatible ctype macros to ensure speed
* user modes i,w,s,o implemented as follows:
i - invisible. over rides any channel mode for those external
to your channel. you are invisible.
w - receive wallops
s - receive local service notices (errors, etc)
o - operator flag. (can not be set currently except using the
OPER command).
* MODE +b added to ban a user from a channel using "nick!user@host" as
the mask to match to the user. If the user matches the ban mask they
are not allowed in. MODE +b with no parameters returns the list of
ban masks currently in place. MODE +b <mask> and MODE -b <mask>
add/delete a ban mask respectively.
Thanks to HulkHogan (andy@lingua.cltr.uq.oz.au) for defining what
we needed here and the 'BlackBall' approach.
* Operator passwords may now be stored in the ircd.conf file as the
encrypted plaintext. Crypt(3) is used to generate the matching
plaintext from the OPER command. Thanks to the following people
for help with this:
Sean Batt (sean@coombs.anu.edu.au),
Andy. M. Jones (andy@lingua.cltr.uq.oz.au),
Nelson Minar (minar@reed.edu).
* Server now creates "ircd.pid" file when booted. Holds the current
pid of the server.
* Each O and I line in the ircd.conf file may be linked only a number
of times equal to or the max. links value for the class they belong
to.
* Server stores results of any successful DNS lookups for servers so
that future lookups are not needed. A rehash will wipe all previous
lookup results and cause the server to start over. The server will
attempt to lookup each hostname in a C/N line on booting. This may
cause a delay during starting the server.
* All functions should be of the form "function_name", macros of the
form "MacroName" and constants as CONSTANT.
* Services are now treated with some respect. A service is associated
with an S-line in the ircd.conf. A service must send a NICK/SERVICE
pair on connecting to achieve service status.
* JOIN/PART now accept a list of channels in the first parameter with
each separated by a ",". eg "JOIN #foo,#bar,#foobar"
* A hopcount for the distance to nicknames and servers has been
introduced (for better or worse). It is passed as the second
parameter to both NICK and SERVER.
WHO and LINKS both report the hopcount in the info field.
* Default for WALL and WALLOPS set "off"
* rearranged config.h
* ISON now returns nicknames with the actual case, i.e.
ISON wiz will answer WiZ
New into 2.7.1
* STATS u, r, z
u - uptime
r - CPU useage stats
z - counts and shows current memory useage
r & z are only available if DEBUGMODE is defined in config.h
* GETHOST which forces all reverse lookups of ip#'s to also match
when doing a forward lookup of the hostname returned.
* SENDQ_ALWAYS buffering policy for sending data over links.
(Server tries to buffer as much data as possible before attempting
a write).
New into 2.7.2
* NOTE (once again appears and in much better state)
* WHOWAS gives a list of known users of the nick in question
rather than just the most recent.
* Server can accept both server and client connections via a unix
domain socket. This provides greater security and reliability for
connections between the host and itself. (#define UNIXPORT)
* STATS C reports L-lines: New Numeric 241
* #define for showing all users the invisible count from LUSERS

71
doc/history/README-2.6 Normal file
View File

@@ -0,0 +1,71 @@
/************************************************************************
* IRC - Internet Relay Chat, README
* Copyright (C) 1990
*
* For the list of authors and their e-mail addresses, see
* file doc/AUTHORS
*
* 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 1, 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.
*/
To install the new server, there is just a few changes to be made.
* General Comments
Tue Nov 13 12:43:46 1990 Armin Gruner <gruner@informatik.tu-muenchen.de>
(APOLLO: Be sure to have NEED_INET_NETOF, NEED_INET_ADDR and
NEED_INET_NTOA undefined.)
Mon Nov 26 20:10:37 1990 Armin Gruner <gruner@informatik.tu-muenchen.de>
Comment: I just found that compiling on our SUN SPARC with GCC produces
code that dumps core.. (that might not happen on your machine, try it,
we may have out-of-date libraries). See netnews gnu.gcc.bug for a dis-
cussion about the matter. It seems that gcc passes struct's in a
different manner.
* Server configuration
Edit the include/config.h to your hearts content, avoiding going
beyond the warning line, unless you are *absolute* sure you know
what you are doing.
If you happen to not take to this warning, you may end up with
a server that will not function properly and annoy not only you,
but users all around the world.
Old irc client can be found in this package and if you want to use it,
check Makefile in directory irc before compiling. There are other,
better irc clients in distribution and the client distributed with
this version is simply something to begin with if you don't happen
to have other clients available.
This version was brought to you by jto@tolsun.oulu.fi and send any
bug fixes and suggestions to me.
NOTE: This server does *NOT* have MAIL system installed by default.
The reason is that it doesn't work with many systems.
This version introduces you string channels, starting with
a plus (+) sign. The first person joining a string channel
claims it's ownership and after that is entitiled to use /mode
command. Ownerships can be given and taken away with
/mode <channel> +o <nickname> and /mode <channel> -o <nickname>
Other flags are: s - secret, p - private, l - limited, i - inviteonly.
m - moderated, n - no private messages to channel,
t - topic settable by operator only
New command /KICK <channel> <user> kicks a user off channel.
--Jarkko (jto@oulu.fi)

51
doc/history/history.pre24 Normal file
View File

@@ -0,0 +1,51 @@
/************************************************************************
* IRC - Internet Relay Chat, doc/HISTORY
* Copyright (C) 1990
*
* 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 1, 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.
*/
HISTORY of Recent IRC Versions.
Previous version numbering schemes have caused some confusion, which this
document attempts to resolve.
The original test versions released by WiZ were numbered 2.01?6 where
the ? refers to a letter. The last known stable version was U6.
Version 2.1.0/1 was rewritten by Mike Bolotski from the U6 sources but
several bugs were introduced during the rewrite. After several weeks,
almost all servers backed up to U6. Version v6 contained comparatively
minor modifications from U6.
Version 2.2 consists of the v6 source repackaged into multiple directories,
and with modified documentation. From now on, the version number will
stay relatively constant. As minor changes and bug fixes are added, they
will be distributed in the form of context diffs, to be applied with the
'patch' command. Each bugfix will bump the patchlevel (PL) of the release
by 1. The PL is documented in the version.c file in the lib/misc directory.
Version 2.3 was unfortunate mistake containing copyright violations
so it was soon taken off distribution.
Version 2.4 contains *very* many bug fixes, enhancements, and "hooks" for
use in future releases. The source tree has been restructured, and the
Makefiles rewritten to be recursive and follow the new source tree layout.
Version 2.5 contains string channels and channel modes (as well as
channel operators). Also Wizible's MAIL system was included as an option.
Hopefully, whoever provides a fix will also update the respective
ChangeLogs to summarize the changes, as well as adding a description of
the bug to the BugList file.

82
doc/irc.1 Normal file
View File

@@ -0,0 +1,82 @@
.\" @(#)irc.1 2.6 7 Oct 90
.TH IRC 1 "7 October 1990"
.SH NAME
irc \- User Interface to Internet Relay Chat Protocol
.SH SYNOPSIS
\fBirc\fP [\fB-p\fP \fIportnum\fP] [\fB-c\fP \fIchannel\fP] [ \fInickname\fP [ \fIserver\fP ]]
.SH DESCRIPTION
.LP
\fBIrc\fP is a user interface to the Internet Relay Chat, a CB-like
interactive discussion environment. It is structured into \fIchannels\fP,
which are public discussion forums, and also allows for private intercommunication.
Each participant has a \fInickname\fP, which is the one specified in the command
line or else his login name.
.LP
Once invoked, \fBirc\fP connects as a client to the specified server,
\fIserver\fP or to the default one (see below). The screen splits into a dialogue
window (the major part
of the screen) and a command line, from which messages can be sent and
commands given to control irc.
.SH COMMAND SYNTAX
The syntax of irc commands is of the form \fB/COMMAND\fP. The most notable
ones are listed below. For an uptodate list, use the \fBHELP\fP command
of \fBirc\fP. Case is ignored.
.IP "\fB/ADMIN\fR [\fIserver\fP]"
Prints administrative information about an IRC \fIserver\fP.
.IP "\fB/AWAY\fP [\fImessage\fP]"
Mark yourself as being away (with an automatic reply \fImessage\fP
if specified)
.IP "\fB/BYE\fR, \fB/EXIT\fR, \fB/QUIT\fR"
Terminate the session
.IP "\fB/CHANNEL\fR [\fIchannel\fP]"
Join another \fIchannel\fP
.IP "\fB/CLEAR\fR"
Clear the screen
.IP "\fB/HELP\fR [\fIcommand\fP]"
Display a brief description of the \fIcommand\fP (or list all commands, if none
specified).
.IP "\fB/SUMMON\fR \fIuser\fP"
Allows to summon a \fIuser\fP specified as a full Internet address, i.e.,
\fIlogin@host.domain\fP, to an IRC dialogue session (in much the same
way as the talk(1) command). It is usable ONLY if the irc daemon runs on
the target machine (host.domain).
.IP "\fB/TOPIC\fR \fItopic\fP"
Sets the \fItopic\fP for the current channel
.IP "\fB/WHO\fR [\fIchannel\fP|*]"
Lists all users of IRC if no argument, of the specified \fIchannel\fP or of the
current channel (*).
.SH ARGUMENTS
.IP "\fB-p\fP \fIportnum\fP"
TCP/IP "port number. Default is 6667 and this option should seldom if ever"
be used.
.IP "\fB-c\fP \fIchannel\fP"
\fIChannel\fP number to join upon beginning of the session. Default is no channel.
.IP "\fInickname\fP"
\fINickname\fP used in the session (can be changed with the \fB/NICK\fP command).
Default is user login name.
.IP "\fIserver\fP"
\fIServer\fP to connect to. Default is specified in the irc system configuration
file, and can be superseded with the environment variable IRCSERVER.
.SH EXAMPLE
.RS
.nf
tolmoon% \fBirc -p6667 Wizard tolsun\fP
.fi
.RE
.LP
connects you to irc server in host tolsun (port 6667) with nickname Wizard
.SH COPYRIGHT
Copyright (c) 1988 University of Oulu, Computing Center, Finland.
.nf
Copyright (c) 1988,1989,1990 Jarkko Oikarinen
.nf
All rights reserved.
For full COPYRIGHT see LICENSE file with IRC package.
.SH "SEE ALSO"
ircd(8)
.SH BUGS
What bugs ?
.SH AUTHOR
Jarkko Oikarinen <jto@tolsun.oulu.fi>
.nf
Manual page updated by Michel Fingerhut <Michel.Fingerhut@ircam.fr>

140
doc/ircd.8 Normal file
View File

@@ -0,0 +1,140 @@
.\" @(#)ircd.8 2.0 (beta version) 29 Mar 1989
.TH IRCD 8 "29 March 1989"
.SH NAME
ircd \- The Internet Relay Chat Program Server
.SH SYNOPSIS
.hy 0
.IP \fBircd\fP
[-a] [-c] [-i] [-o] [-q] [-t] [-d directory]
[-f configfile] [-x debuglevel] [-h hostname] [-p portnum]
.SH DESCRIPTION
.LP
\fIircd\fP is the server (daemon) program for the Internet Relay Chat
Program. The \fIircd\fP is a server in that its function is to "serve"
the client program \fIirc(1)\fP with messages and commands. All commands
and user messages are passed directly to the \fIircd\fP for processing
and relaying to other ircd sites. The \fIirc(1)\fP program depends upon
there being an \fIircd\fP server running somewhere (either on your local
UNIX site or a remote ircd site) so that it will have somewhere to connect
to and thus allow the user to begin talking to other users.
.SH OPTIONS
.TP
.B \-d directory
This option tells the server to change to that directory and use
that as a reference point when opening \fIircd.conf\fP and other startup
files.
.TP
.B \-o
Starts up a local ircdaemon. Standard input can be used to send IRC
commands to the daemon. The user logging in from standard input will
be given operator privileges on this local ircd. If ircd is a setuid program,
it will call setuid(getuid()) before going to local mode. This option
can be used in inetd.conf to allow users to open their own irc clients
by simply connecting their clients to the correct ports. For example:
.TP
.B
irc stream tcp nowait irc /etc/ircd ircd \\-f/etc/ircd.conf \\-o
allows users connecting to irc port (specified in /etc/services) to start
up their own ircdaemon. The configuration file should be used to check from
which hosts these connections are allowed from. This option also turns
on the autodie option -a.
.TP
.B \-a
Instructs the server to automatically die off if it loses all it's clients.
.TP
.B \-t
Instructs the server to direct debugging output to standard output.
.TP
.B \-x#
Defines the debuglevel for ircd. The higher the debuglevel, the more stuff
gets directed to debugging file (or standard output if -t option was used
as well).
.TP
.B \-i
The server was started by inetd and it should start accepting connections
from standard input. The following inetd.conf-line could be used to start
up ircd automatically when needed:
.TP
.B
ircd stream tcp wait irc /etc/ircd ircd \-i
allows inetd to start up ircd on request.
.TP
.B \-f filename
Specifies the ircd.conf file to be used for this ircdaemon. The option
is used to override the default ircd.conf given at compile time.
.TP
.B \-c
This flag must be given if you are running ircd from \fI/dev/console\fP or
any other situation where fd 0 isnt a tty and you want the server to fork
off and run in the background. This needs to be given if you are starting
\fIircd\fP from an \fIrc\fP (such as \fI/etc/rc.local\fP) file.
.TP
.B \-q
Using the -q option stops the server from doing DNS lookups on all the
servers in your \fIircd.conf\fP file when it boots. This can take a lengthy
amount of time if you have a large number of servers and they are not all
close by.
.TP
.B \-h hostname
Allows the user to manually set the server name at startup. The default
name is hostname.domainname.
.B \-p portname
Specifies the port where the daemon should start waiting for connections.
This overrides the default which is given at compile time.
.TP
.SH
If you plan to connect your \fIircd\fP server to an existing Irc-Network,
you will need to alter your local IRC CONFIGURATION FILE (typically named
"ircd.conf") so that it will accept and make connections to other \fIircd\fP
servers. This file contains the hostnames, Network Addresses, and sometimes
passwords for connections to other ircds around the world. Because
description of the actual file format of the "ircs.conf" file is beyond the
scope of this document, please refer to the file INSTALL in the IRC source
files documentation directory.
.LP
BOOTING THE SERVER: The \fIircd\fP server can be started as part of the
UNIX boot procedure or just by placing the server into Unix Background.
Keep in mind that if it is *not* part of your UNIXES Boot-up procedure
then you will have to manually start the \fIircd\fP server each time your
UNIX is rebooted. This means if your UNIX is prone to crashing
or going for for repairs a lot it would make sense to start the \fIircd\fP
server as part of your UNIX bootup procedure. In some cases the \fIirc(1)\fP
will automatically attempt to boot the \fIircd\fP server if the user is
on the SAME UNIX that the \fIircd\fP is supposed to be running on. If the
\fIirc(1)\fP cannot connect to the \fIircd\fP server it will try to start
the server on it's own and will then try to reconnect to the newly booted
\fIircd\fP server.
.SH EXAMPLE
.RS
.nf
tolsun% \fBircd\fP
.fi
.RE
.LP
Places \fIircd\fP into UNIX Background and starts up the server for use.
Note: You do not have to add the "&" to this command, the program will
automatically detach itself from tty.
.SH COPYRIGHT
(c) 1988,1989 University of Oulu, Computing Center, Finland,
.LP
(c) 1988,1989 Department of Information Processing Science,
University of Oulu, Finland
.LP
(c) 1988,1989,1990,1991 Jarkko Oikarinen
.LP
For full COPYRIGHT see LICENSE file with IRC package.
.LP
.RE
.SH FILES
/etc/utmp
"irc.conf"
.SH "SEE ALSO"
irc(1)
.SH BUGS
None... ;-) if somebody finds one, please inform author
.SH AUTHOR
Jarkko Oikarinen, currently jto@tolsun.oulu.fi,
manual page written by Jeff Trim, jtrim@orion.cair.du.edu,
later modified by jto@tolsun.oulu.fi.

47
doc/m4macros Normal file
View File

@@ -0,0 +1,47 @@
The following macros are included in "ircd.m4" for use with the m4 text
preprocessor. "ircd.m4" is parsed before the IRC server conf file so they
are all available for use with that.
NOTE: The "ircd.m4" file is *ONLY* created by a "make install".
VERSION - current version string as in patchlevel.h
DEBUGMODE - if DEBUGMODE is define in config.h, is also defined for m4.
HOSTNAME - taken from hostname(1)
USER - username of person doing the "make install"
PORT - default port number as in config.h
PFREQ - default ping frequency as in config.h
CFREQ - default connect frequency as in config.h
MAXSENDQ - default max sendq as in config.h
CL - use this to wrap a class number
HOST - use this to wrap a hostname
HOSTM - use this to wrap the hostmask number in N-lines
ID - when wrapping the host field in an I-line, causes ident string return
to be used instead of user supplised username.
PASS - use this to wrap passwords in C/N/I/O lines
PING - use this to wrap the ping value in Y-lines
APORT - use this to wrap the port number in I-lines
CPORT - use this to wrap the port number in C-lines
SERV - use this to wrap server names
You might use some of these as
C:foo.bar.edu:PASS(boo):foo.bar.edu:APORT(6667)
I:ID(128.250.*)::ID(*.mu.oz.au):CPORT(6667)
In addition to these (rather weak macros), some more complete ones are
defined which already perform the above.
ADMIN - provide fields to it as you would an A-line
ALLOW - provide fields to it as you would an N-line
BAN - provide fields to it as you would an K-line
CLASS - provide fields to it as you would an Y-line
CLIENT - provide fields to it as you would an I-line
CONNECT - provide fields to it as you would an C-line
ME - provide fields to it as you would an M-line
HUB - first parameter is server you want to hub, second is optional and is
a mask against which other servers introduced must match against.
LEAF - works like HUB, except that the mask is matched against server names
to check if the link should be dropped.
SERVER - uses 6 fields, the first 4 as are found in an N-line, the last two
should be as you would use in a C-line. It expands out to provide
both a C and N line.

38
include/channel.h Normal file
View File

@@ -0,0 +1,38 @@
/************************************************************************
* IRC - Internet Relay Chat, ircd/channel.h
* Copyright (C) 1990 Jarkko Oikarinen
*
* 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 1, 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.
*/
#ifndef __channel_include__
#define __channel_include__
#define CREATE 1 /* whether a channel should be
created or just tested for existance */
#define MODEBUFLEN 200
#define NullChn ((aChannel *)0)
#define ChannelExists(n) (find_channel(n, NullChn) != NullChn)
#ifndef V28PlusOnly
#define MAXMODEPARAMS 6
#else
#include "msg.h"
#define MAXMODEPARAMS (MAXPARA-2)
#endif
#endif

69
include/class.h Normal file
View File

@@ -0,0 +1,69 @@
/************************************************************************
* IRC - Internet Relay Chat, include/class.h
* Copyright (C) 1990 Darren Reed
*
* 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 1, 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.
*/
#ifndef __class_include__
#define __class_include__
#ifndef PROTO
#if __STDC__
# define PROTO(x) x
#else
# define PROTO(x) ()
#endif
#endif
typedef struct Class {
int class;
int conFreq;
int pingFreq;
int maxLinks;
long maxSendq;
int links;
struct Class *next;
} aClass;
#define Class(x) ((x)->class)
#define ConFreq(x) ((x)->conFreq)
#define PingFreq(x) ((x)->pingFreq)
#define MaxLinks(x) ((x)->maxLinks)
#define MaxSendq(x) ((x)->maxSendq)
#define Links(x) ((x)->links)
#define ConfLinks(x) (Class(x)->links)
#define ConfMaxLinks(x) (Class(x)->maxLinks)
#define ConfClass(x) (Class(x)->class)
#define ConfConFreq(x) (Class(x)->conFreq)
#define ConfPingFreq(x) (Class(x)->pingFreq)
#define ConfSendq(x) (Class(x)->maxSendq)
#define FirstClass() classes
#define NextClass(x) ((x)->next)
extern aClass *classes;
extern aClass *find_class PROTO((int));
extern int get_conf_class PROTO((aConfItem *));
extern int get_client_class PROTO((aClient *));
extern int get_client_ping PROTO((aClient *));
extern int get_con_freq PROTO((aClass *));
extern void add_class PROTO((int, int, int, int, long));
extern void check_class PROTO((void));
extern void initclass PROTO((void));
#endif /* __class_include__ */

146
include/common.h Normal file
View File

@@ -0,0 +1,146 @@
/************************************************************************
* IRC - Internet Relay Chat, include/common.h
* Copyright (C) 1990 Armin Gruner
*
* 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 1, 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.
*/
#ifndef __common_include__
#define __common_include__
#include <time.h>
#ifdef PARAMH
#include <sys/param.h>
#endif
#ifndef PROTO
#if __STDC__
# define PROTO(x) x
#else
# define PROTO(x) ()
#endif
#endif
#ifndef NULL
#define NULL 0
#endif
#ifdef TRUE
#undef TRUE
#endif
#ifdef FALSE
#undef FALSE
#endif
#define FALSE (0)
#define TRUE (!FALSE)
#ifndef MALLOCH
char *malloc(), *calloc();
void free();
#else
#include MALLOCH
#endif
extern int matches PROTO((char *, char *));
extern int mycmp PROTO((const char *, const char *));
extern int myncmp PROTO((const char *, const char *, int));
#ifdef NEED_STRTOK
extern char *strtok PROTO((char *, char *));
#endif
#ifdef NEED_STRTOKEN
extern char *strtoken PROTO((char **, char *, char *));
#endif
#ifdef NEED_INET_ADDR
extern unsigned long inet_addr PROTO((char *));
#endif
#if defined(NEED_INET_NTOA) || defined(NEED_INET_NETOF)
#include <netinet/in.h>
#endif
#ifdef NEED_INET_NTOA
extern char *inet_ntoa PROTO((struct in_addr));
#endif
#ifdef NEED_INET_NETOF
extern int inet_netof PROTO((struct in_addr));
#endif
extern char *myctime PROTO((time_t));
extern char *strtoken PROTO((char **, char *, char *));
#ifndef MAX
#define MAX(a, b) ((a) > (b) ? (a) : (b))
#endif
#ifndef MIN
#define MIN(a, b) ((a) < (b) ? (a) : (b))
#endif
#define DupString(x,y) do{x=MyMalloc(strlen(y)+1);(void)strcpy(x,y);}while(0)
extern unsigned char tolowertab[];
#undef tolower
#define tolower(c) (tolowertab[(u_char)(c)])
extern unsigned char touppertab[];
#undef toupper
#define toupper(c) (touppertab[(u_char)(c)])
#undef isalpha
#undef isdigit
#undef isxdigit
#undef isalnum
#undef isprint
#undef isascii
#undef isgraph
#undef ispunct
#undef islower
#undef isupper
#undef isspace
#undef iscntrl
extern unsigned char char_atribs[];
#define PRINT 1
#define CNTRL 2
#define ALPHA 4
#define PUNCT 8
#define DIGIT 16
#define SPACE 32
#define iscntrl(c) (char_atribs[(u_char)(c)]&CNTRL)
#define isalpha(c) (char_atribs[(u_char)(c)]&ALPHA)
#define isspace(c) (char_atribs[(u_char)(c)]&SPACE)
#define islower(c) ((char_atribs[(u_char)(c)]&ALPHA) && ((u_char)(c) > 0x5f))
#define isupper(c) ((char_atribs[(u_char)(c)]&ALPHA) && ((u_char)(c) < 0x60))
#define isdigit(c) (char_atribs[(u_char)(c)]&DIGIT)
#define isxdigit(c) (isdigit(c) || 'a' <= (c) && (c) <= 'f' || \
'A' <= (c) && (c) <= 'F')
#define isalnum(c) (char_atribs[(u_char)(c)]&(DIGIT|ALPHA))
#define isprint(c) (char_atribs[(u_char)(c)]&PRINT)
#define isascii(c) ((u_char)(c) >= 0 && (u_char)(c) <= 0x7f)
#define isgraph(c) ((char_atribs[(u_char)(c)]&PRINT) && ((u_char)(c) != 0x32))
#define ispunct(c) (!(char_atribs[(u_char)(c)]&(CNTRL|ALPHA|DIGIT)))
extern char *MyMalloc();
extern void flush_connections();
extern struct SLink *find_user_link(/* struct SLink *, struct Client * */);
#endif /* __common_include__ */

727
include/config.h Normal file
View File

@@ -0,0 +1,727 @@
/************************************************************************
* IRC - Internet Relay Chat, include/config.h
* Copyright (C) 1990 Jarkko Oikarinen
*
* 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 1, 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.
*/
#ifndef __config_include__
#define __config_include__
#include "setup.h"
/* Type of host. These should be made redundant somehow. -avalon */
/* BSD Nothing Needed 4.{2,3} BSD, SunOS 3.x, 4.x */
/* HPUX Nothing needed (A.08/A.09) */
/* ULTRIX Nothing needed (4.2) */
/* OSF Nothing needed (1.2) */
#undef AIX /* IBM ugly so-called Unix, AIX */
#undef MIPS /* MIPS Unix */
/* SGI Nothing needed (IRIX 4.0.4) */
#undef SVR3 /* SVR3 stuff - being worked on where poss. */
#undef DYNIXPTX /* Sequents Brain-dead Posix implement. */
#undef SOL20 /* Solaris2 */
#undef ESIX /* ESIX */
#undef NEXT /* NeXTStep */
#undef SVR4
/*
* NOTE: It is important to set this to the correct "domain" for your server.
* Define this for the correct "domain" that your server is in. This
* is important for certain stats. -mlv
*/
#define DOMAINNAME "iastate.edu"
/* Random Number Generator Seed
*
* Set this to an 8-character random text string.
* Do not use the default text.
* If people are able to defeat the IP-spoofing protection on your
* server, consider changing the value and recompiling.
*/
#define RANDOM_SEED "12345678"
/*
* Define this if you'd like to run two or more servers on the same port
* of one machine, using IP aliasing. --Jamey
*
*/
#undef VIRTUAL_HOST
/*
** Define this to prevent mixed case userids that clonebots use.
** It is strongly advised to define this, unless you have a known reason
** not to.
*/
#define DISALLOW_MIXED_CASE
/*
** The mixed case patch can optionally notify opers when an invalid uid
** is received by the server. However, this can get to be very annoying
** when auto connect bots with invalid ids try connecting. Define at
** your own discretion
*/
#define NOTIFY_OPS_INVALID_UID
/*
** Clone bot detection on registration.
** This feature blocks connections if more than CHECK_CLONE_LIMIT
** clients connect from the same host within CHECK_CLONE_PERIOD seconds.
**
** The feature is enabled CHECK_CLONE_DELAY seconds after the server
** is started.
**
** Define CHECK_CLONE is you want this feature.
*/
#define CHECK_CLONE
#define CHECK_CLONE_LIMIT 5 /* recommended value 5 */
#define CHECK_CLONE_PERIOD 20 /* recommended value 20 */
#define CHECK_CLONE_DELAY 120 /* 120 secs should be ok */
/*
** Nick flood limit
** Minimum time between nick changes.
** (The first two changes are allowed quickly after another however).
**
** Define NICK_DELAY if you want this feature.
*/
#define NICK_DELAY 30 /* recommended value 30 */
/*
** Default LIST command parameters.
** Undefine if you like having your server flooded by mIRC users.
*/
#define DEFAULT_LIST_PARAM "T<10"
/*
** Define this if you wish to output a *file* to a K lined client rather
** than the K line comment (the comment field is treated as a filename)
*/
#undef COMMENT_IS_FILE
/* Do these work? I dunno... */
#undef VMS /* Should work for IRC client, not server */
#undef MAIL50 /* If you're running VMS 5.0 */
#undef PCS /* PCS Cadmus MUNIX, use with BSD flag! */
/*
* NOTE: On some systems, valloc() causes many problems.
*/
#undef VALLOC /* Define this if you have valloc(3) */
#ifdef APOLLO
#define RESTARTING_SYSTEMCALLS
#endif /* read/write are restarted after signals
defining this 1, gets siginterrupt call
compiled, which attempts to remove this
behaviour (apollo sr10.1/bsd4.3 needs
this) */
/*
* If your host supports varargs and has vsprintf(), vprintf() and vscanf()
* C calls in its library, then you can define USE_VARARGS to use varargs
* instead of imitation variable arg passing.
*/
#define USE_VARARGS
/*
* Define this if you want to find an existing bug.
* It makes your server EAT cpu time though...
* NEVER define this unless you are debugging a reproducable problem
* under test circumstances.
*/
#undef DEBUGMODE /* define DEBUGMODE to enable debugging mode.*/
/*
* defining FORCE_CORE will automatically "unlimit core", forcing the
* server to dump a core file whenever it has a fatal error. -mlv
*/
#define FORCE_CORE
/*
* NPATH is path to backup file for NOTE.
*/
/* #define NPATH "/usr/lib/irc/.ircdnote" */
/*
* Full pathnames and defaults of irc system's support files. Please note that
* these are only the recommened names and paths. Change as needed.
* You must define these to something, even if you don't really want them.
*/
#define DPATH "/usr/local/lib/ircd" /* dir where all ircd stuff is */
#define SPATH "/usr/local/bin/ircd" /* path to server executeable */
#define CPATH "ircd.conf" /* server configuration file */
#define MPATH "ircd.motd" /* server MOTD file */
#define LPATH "/tmp/ircd.log" /* Where the debug file lives, if DEBUGMODE */
#define PPATH "ircd.pid" /* file for server pid */
/* Define this if you want to keep a log of all G-lines that have been added
* and the changes that are made by U-lined servers or local operators. Do
* this; you can simply append this log to your ircd.conf to add the G-lines
* as K-lines!
*/
#define GPATH "gline.log"
/*
* Define this filename to maintain a list of persons who log
* into this server. Logging will stop when the file does not exist.
* Logging will be disable also if you do not define this.
* FNAME_USERLOG just logs user connections, FNAME_OPERLOG logs every
* successful use of /oper. These are either full paths or files within DPATH.
*/
#define FNAME_USERLOG "/usr/local/lib/ircd/users" /* */
/* #define FNAME_OPERLOG "/usr/local/lib/ircd/opers" /* */
/* CHROOTDIR
*
* Define for value added security if you are a rooter.
*
* All files you access must be in the directory you define as DPATH.
* (This may effect the PATH locations above, though you can symlink it)
*
* You may want to define IRC_UID and IRC_GID
*/
#undef CHROOTDIR
/* RELIABLE_CLOCK
*
* Define this if your host has an externally controlled system clock,
* like running xntp.
* If nobody defines this, it still works: The clock will be used of the
* server that was started first.
*/
#undef RELIABLE_CLOCK
/* ENABLE_SUMMON
*
* The SUMMON command requires the ircd to be run as group tty in order
* to work properly in many cases. If you are on a machine where it
* won't work, or simply don't want local users to be summoned, undefine
* this.
*/
#undef ENABLE_SUMMON /* local summon */
#undef ENABLE_USERS /* enables local /users (same as who/finger output) */
/* SHOW_ALL_INVISIBLE_USERS
*
* If this is defined operators on your server will see *ALL* +i users on the
* net. This can be advantagous when tracking clones. (Chaos)
* Only O:'s are affected, for o:'s (local operators) invisible users on
* other servers still have their privacy... -- Niels
*/
#define SHOW_ALL_INVISIBLE_USERS
/* SHOW_INVISIBLE_LUSERS
*
* As defined this will show the correct invisible count for anyone who does
* LUSERS on your server. On a large net this doesnt mean much, but on a
* small net it might be an advantage to undefine it.
* (This will get defined for you if you're using userload (stats w). -mlv)
*/
#define SHOW_INVISIBLE_LUSERS
/* OPER_KILL
*
* If you dont believe operators should be allowed to use the /KILL command
* or believe it is uncessary for them to use it, then leave OPER_KILL
* undefined. This will not affect other operators or servers issuing KILL
* commands however. OPER_REHASH and OPER_RESTART allow operators to
* issue the REHASH and RESTART commands when connected to your server.
* Left undefined they increase the security of your server from wayward
* operators and accidents. Defining OPER_REMOTE removes the restriction
* that O-lines only become fully effective for people on the 'same network'
* as the server. Undefined, it increases the secrity of the server by
* placing restrictions on where people can use operator powers from.
* The 'LOCOP_' #defines are for making the respective commands available
* to 'local' operators.
*/
#define OPER_KILL
#define OPER_REHASH
#define OPER_RESTART
#define OPER_DIE
#define OPER_REMOTE
#define LOCOP_REHASH
#undef LOCOP_RESTART
#undef LOCOP_DIE
/* MAXIMUM LINKS
*
* This define is useful for leaf nodes and gateways. It keeps you from
* connecting to too many places. It works by keeping you from
* connecting to more than "n" nodes which you have C:blah::blah:6667
* lines for.
*
* Note that any number of nodes can still connect to you. This only
* limits the number that you actively reach out to connect to.
*
* Leaf nodes are nodes which are on the edge of the tree. If you want
* to have a backup link, then sometimes you end up connected to both
* your primary and backup, routing traffic between them. To prevent
* this, #define MAXIMUM_LINKS 1 and set up both primary and
* secondary with C:blah::blah:6667 lines. THEY SHOULD NOT TRY TO
* CONNECT TO YOU, YOU SHOULD CONNECT TO THEM.
*
* Gateways such as the server which connects Australia to the US can
* do a similar thing. Put the American nodes you want to connect to
* in with C:blah::blah:6667 lines, and the Australian nodes with
* C:blah::blah lines. Have the Americans put you in with C:blah::blah
* lines. Then you will only connect to one of the Americans.
*
* This value is only used if you don't have server classes defined, and
* a server is in class 0 (the default class if none is set).
*
*/
#define MAXIMUM_LINKS 1
/*
* If your server is running as a a HUB Server then define this.
* A HUB Server has many servers connect to it at the same as opposed
* to a leaf which just has 1 server (typically the uplink). Define this
* correctly for performance reasons.
*/
#undef HUB
/* R_LINES: The conf file now allows the existence of R lines, or
* restrict lines. These allow more freedom in the ability to restrict
* who is to sign on and when. What the R line does is call an outside
* program which returns a reply indicating whether to let the person on.
* Because there is another program involved, Delays and overhead could
* result. It is for this reason that there is a line in config.h to
* decide whether it is something you want or need. -Hoppie
*
* The default is no R_LINES as most people probably don't need it. --Jto
*/
#undef R_LINES
#ifdef R_LINES
/* Also, even if you have R lines defined, you might not want them to be
checked everywhere, since it could cost lots of time and delay. Therefore,
The following two options are also offered: R_LINES_REHASH rechecks for
R lines after a rehash, and R_LINES_OFTEN, which rechecks it as often
as it does K lines. Note that R_LINES_OFTEN is *very* likely to cause
a resource drain, use at your own risk. R_LINES_REHASH shouldn't be too
bad, assuming the programs are fairly short. */
#define R_LINES_REHASH
#define R_LINES_OFTEN
#endif
/*
* NOTE: defining CMDLINE_CONFIG and installing ircd SUID or SGID is a MAJOR
* security problem - they can use the "-f" option to read any files
* that the 'new' access lets them. Note also that defining this is
* a major security hole if your ircd goes down and some other user
* starts up the server with a new conf file that has some extra
* O-lines. So don't use this unless you're debugging.
*/
#undef CMDLINE_CONFIG /* allow conf-file to be specified on command line */
/*
* To use m4 as a preprocessor on the ircd.conf file, define M4_PREPROC.
* The server will then call m4 each time it reads the ircd.conf file,
* reading m4 output as the server's ircd.conf file.
*/
#undef M4_PREPROC
/*
* If you wish to have the server send 'vital' messages about server
* through syslog, define USE_SYSLOG. Only system errors and events critical
* to the server are logged although if this is defined with FNAME_USERLOG,
* syslog() is used instead of the above file. It is not recommended that
* this option is used unless you tell the system administrator beforehand
* and obtain their permission to send messages to the system log files.
*/
#undef USE_SYSLOG
#ifdef USE_SYSLOG
/*
* If you use syslog above, you may want to turn some (none) of the
* spurious log messages for KILL/SQUIT off.
*/
#undef SYSLOG_KILL /* log all operator kills to syslog */
#undef SYSLOG_SQUIT /* log all remote squits for all servers to syslog */
#undef SYSLOG_CONNECT /* log remote connect messages for other all servs */
#undef SYSLOG_USERS /* send userlog stuff to syslog */
#undef SYSLOG_OPER /* log all users who successfully become an Op */
/*
* If you want to log to a different facility than DAEMON, change
* this define.
*/
#define LOG_FACILITY LOG_DAEMON
#endif /* USE_SYSLOG */
/*
* define this if you want to use crypted passwords for operators in your
* ircd.conf file. See ircd/crypt/README for more details on this.
*/
#define CRYPT_OPER_PASSWORD
/*
* If you want to store encrypted passwords in N-lines for server links,
* define this. For a C/N pair in your ircd.conf file, the password
* need not be the same for both, as long as hte opposite end has the
* right password in the opposite line. See INSTALL doc for more details.
*/
#undef CRYPT_LINK_PASSWORD
/*
* define this if you enable summon and if you want summon to look for the
* least idle tty a user is logged in on.
*/
#define LEAST_IDLE
/*
* IDLE_FROM_MSG
*
* Idle-time nullified only from privmsg, if undefined idle-time
* is nullified from everything except ping/pong.
* Added 3.8.1992, kny@cs.hut.fi (nam)
*/
#define IDLE_FROM_MSG
/*
* Max amount of internal send buffering when socket is stuck (bytes)
*/
#define MAXSENDQLENGTH 2000000 /* Recommended value: 300000 for leaves */
/* 2000000 for backbones */
/*
* BUFFERPOOL is the maximum size of the total of all sendq's.
* Recommended value is leaves: 3 * MAXSENDQLENGTH, for hubs: 5 - 7 *.
*/
#define BUFFERPOOL (6 * MAXSENDQLENGTH)
/*
* use these to setup a Unix domain socket to connect clients/servers to.
*/
#define UNIXPORT
/*
* IRC_UID
*
* If you start the server as root but wish to have it run as another user,
* define IRC_UID to that UID. This should only be defined if you are running
* as root and even then perhaps not.
*/
#undef IRC_UID
#undef IRC_GID
#ifdef notdef
#define IRC_UID 65534 /* eg for what to do to enable this feature */
#define IRC_GID 65534
#endif
/*
* CLIENT_FLOOD
*
* this controls the number of bytes the server will allow a client to
* send to the server without processing before disconnecting the client for
* flooding it. Values greater than 8000 make no difference to the server.
*/
#define CLIENT_FLOOD 1024
/* Define this if you want the server to accomplish ircII standard */
/* Sends an extra NOTICE in the beginning of client connection */
#undef IRCII_KLUDGE
/* STOP STOP STOP STOP STOP STOP STOP STOP STOP STOP STOP STOP STOP STOP */
/* You shouldn't change anything below this line, unless absolutely needed. */
#ifdef OPER_KILL
/* LOCAL_KILL_ONLY
*
* To be used, OPER_KILL must be defined.
* LOCAL_KILL_ONLY restricts KILLs to clients which are connected to the
* server the Operator is connected to (ie lets them deal with local
* problem users or 'ghost' clients
*
* NOTE: #define'ing this on an IRC net with servers which have a version
* earlier than 2.7 is prohibited. Such an action and subsequent use
* of KILL for non-local clients should be punished by removal of the
* server's links (if only for ignoring this warning!).
*/
#undef LOCAL_KILL_ONLY
#endif
/*
* Port where ircd resides. NOTE: This *MUST* be greater than 1024 if you
* plan to run ircd under any other uid than root.
*/
#define PORTNUM 6667 /* Recommended values: 6667 or 6666 */
/*
* Maximum number of network connections your server will allow. This should
* never exceed max. number of open file descrpitors and wont increase this.
* Should remain LOW as possible. Most sites will usually have under 30 or so
* connections. A busy hub or server may need this to be as high as 50 or 60.
* Making it over 100 decreases any performance boost gained from it being low.
* if you have a lot of server connections, it may be worth splitting the load
* over 2 or more servers.
* 1 server = 1 connection, 1 user = 1 connection.
* This should be at *least* 3: 1 listen port, 1 dns port + 1 client
*/
#define MAXCONNECTIONS 254
/*
* this defines the length of the nickname history. each time a user changes
* nickname or signs off, their old nickname is added to the top of the list.
* The following sizes are recommended:
* 8MB or less core memory : 500 (at least 1/4 of max users)
* 8MB-16MB core memory : 500-750 (1/4 -> 1/2 of max users)
* 16MB-32MB core memory : 750-1000 (1/2 -> 3/4 of max users)
* 32MB or more core memory : 1000+ (> 3/4 if max users)
* where max users is the expected maximum number of users.
* (100 nicks/users ~ 25k)
* NOTE: this is directly related to the amount of memory ircd will use whilst
* resident and running - it hardly ever gets swapped to disk! You can
* ignore these recommendations- they only are meant to serve as a guide
*/
#define NICKNAMEHISTORYLENGTH 800
/*
* Time interval to wait and if no messages have been received, then check for
* PINGFREQUENCY and CONNECTFREQUENCY
*/
#define TIMESEC 60 /* Recommended value: 60 */
/*
* If daemon doesn't receive anything from any of its links within
* PINGFREQUENCY seconds, then the server will attempt to check for
* an active link with a PING message. If no reply is received within
* (PINGFREQUENCY * 2) seconds, then the connection will be closed.
*/
#define PINGFREQUENCY 120 /* Recommended value: 120 */
/*
* If the connection to to uphost is down, then attempt to reconnect every
* CONNECTFREQUENCY seconds.
*/
#define CONNECTFREQUENCY 600 /* Recommended value: 600 */
/*
* Often net breaks for a short time and it's useful to try to
* establishing the same connection again faster than CONNECTFREQUENCY
* would allow. But, to keep trying on bad connection, we require
* that connection has been open for certain minimum time
* (HANGONGOODLINK) and we give the net few seconds to steady
* (HANGONRETRYDELAY). This latter has to be long enough that the
* other end of the connection has time to notice it broke too.
*/
#define HANGONRETRYDELAY 10 /* Recommended value: 10 seconds */
#define HANGONGOODLINK 300 /* Recommended value: 5 minutes */
/*
* Number of seconds to wait for write to complete if stuck.
*/
#define WRITEWAITDELAY 15 /* Recommended value: 15 */
/*
* Number of seconds to wait for a connect(2) call to complete.
* NOTE: this must be at *LEAST* 10. When a client connects, it has
* CONNECTTIMEOUT - 10 seconds for its host to respond to an ident lookup
* query and for a DNS answer to be retrieved.
* This value should consider the fact that users whose clients do not
* support NOSPOOF will have to type /QUOTE PING <bignumber> before
* registration.
*/
#define CONNECTTIMEOUT 90 /* Recommended value: 90 */
/*
* Max time from the nickname change that still causes KILL
* automaticly to switch for the current nick of that user. (seconds)
*/
#define KILLCHASETIMELIMIT 90 /* Recommended value: 90 */
/*
* Max number of channels a user is allowed to join.
*/
#define MAXCHANNELSPERUSER 10 /* Recommended value: 10 */
/*
* Maximum number of silences a user may set; recommended value: 15
*/
#define MAXSILES 15
/*
* SendQ-Always causes the server to put all outbound data into the sendq and
* flushing the sendq at the end of input processing. This should cause more
* efficient write's to be made to the network.
* There *shouldn't* be any problems with this method.
* -avalon
*/
#define SENDQ_ALWAYS
/* ------------------------- END CONFIGURATION SECTION -------------------- */
#define MOTD MPATH
#define MYNAME SPATH
#define CONFIGFILE CPATH
#define IRCD_PIDFILE PPATH
#ifdef __osf__
#define OSF
/* OSF defines BSD to be its version of BSD */
#undef BSD
#include <sys/param.h>
#ifndef BSD
#define BSD
#endif
#endif
#ifdef _SEQUENT_ /* Dynix 1.4 or 2.0 Generic Define.. */
#undef BSD
#define SYSV /* Also #define SYSV */
#endif
#ifdef ultrix
#define ULTRIX
#endif
#ifdef __hpux
#define HPUX
#endif
#ifdef sgi
#define SGI
#endif
#ifdef DEBUGMODE
extern void debug();
# define Debug(x) debug x
# define LOGFILE LPATH
#else
# define Debug(x) ;
# if VMS
# define LOGFILE "NLA0:"
# else
# define LOGFILE "/dev/null"
# endif
#endif
#ifndef ENABLE_SUMMON
# undef LEAST_IDLE
#endif
#if defined(mips) || defined(PCS)
#undef SYSV
#endif
#ifdef MIPS
#undef BSD
#define BSD 1 /* mips only works in bsd43 environment */
#endif
#ifdef sequent /* Dynix (sequent OS) */
#define SEQ_NOFILE 128 /* set to your current kernel impl, */
#endif /* max number of socket connections */
#ifdef _SEQUENT_
#define DYNIXPTX
#endif
#ifdef BSD_RELIABLE_SIGNALS
# if defined(SYSV_UNRELIABLE_SIGNALS) || defined(POSIX_SIGNALS)
error You stuffed up config.h signals #defines use only one.
# endif
#define HAVE_RELIABLE_SIGNALS
#endif
#ifdef SYSV_UNRELIABLE_SIGNALS
# ifdef POSIX_SIGNALS
error You stuffed up config.h signals #defines use only one.
# endif
#undef HAVE_RELIABLE_SIGNALS
#endif
#ifdef POSIX_SIGNALS
#define HAVE_RELIABLE_SIGNALS
#endif
/*
* safety margin so we can always have one spare fd, for motd/authd or
* whatever else. -4 allows "safety" margin of 1 and space reserved.
*/
#define MAXCLIENTS (MAXCONNECTIONS-4)
#ifdef HAVECURSES
# define DOCURSES
#else
# undef DOCURSES
#endif
#ifdef HAVETERMCAP
# define DOTERMCAP
#else
# undef DOTERMCAP
#endif
#ifndef UNIXPORT
#undef UNIXPORTPATH
#endif
#if defined(CLIENT_FLOOD)
# if (CLIENT_FLOOD > 8000) || (CLIENT_FLOOD < 512)
error CLIENT_FLOOD needs redefining.
# endif
#else
error CLIENT_FLOOD undefined
#endif
/*
* Some ugliness for AIX platforms.
*/
#ifdef AIX
# include <sys/machine.h>
# if BYTE_ORDER == BIG_ENDIAN
# define BIT_ZERO_ON_LEFT
# endif
# if BYTE_ORDER == LITTLE_ENDIAN
# define BIT_ZERO_ON_RIGHT
# endif
/*
* this one is used later in sys/types.h (or so i believe). -avalon
*/
# define BSD_INCLUDES
#endif
#define Reg1 register
#define Reg2 register
#define Reg3 register
#define Reg4 register
#define Reg5 register
#define Reg6 register
#define Reg7 register
#define Reg8 register
#define Reg9 register
#define Reg10 register
#endif /* __config_include__ */

727
include/config.h.dist Normal file
View File

@@ -0,0 +1,727 @@
/************************************************************************
* IRC - Internet Relay Chat, include/config.h
* Copyright (C) 1990 Jarkko Oikarinen
*
* 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 1, 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.
*/
#ifndef __config_include__
#define __config_include__
#include "setup.h"
/* Type of host. These should be made redundant somehow. -avalon */
/* BSD Nothing Needed 4.{2,3} BSD, SunOS 3.x, 4.x */
/* HPUX Nothing needed (A.08/A.09) */
/* ULTRIX Nothing needed (4.2) */
/* OSF Nothing needed (1.2) */
#undef AIX /* IBM ugly so-called Unix, AIX */
#undef MIPS /* MIPS Unix */
/* SGI Nothing needed (IRIX 4.0.4) */
#undef SVR3 /* SVR3 stuff - being worked on where poss. */
#undef DYNIXPTX /* Sequents Brain-dead Posix implement. */
#undef SOL20 /* Solaris2 */
#undef ESIX /* ESIX */
#undef NEXT /* NeXTStep */
#undef SVR4
/*
* NOTE: It is important to set this to the correct "domain" for your server.
* Define this for the correct "domain" that your server is in. This
* is important for certain stats. -mlv
*/
#define DOMAINNAME "iastate.edu"
/* Random Number Generator Seed
*
* Set this to an 8-character random text string.
* Do not use the default text.
* If people are able to defeat the IP-spoofing protection on your
* server, consider changing the value and recompiling.
*/
#define RANDOM_SEED "12345678"
/*
* Define this if you'd like to run two or more servers on the same port
* of one machine, using IP aliasing. --Jamey
*
*/
#undef VIRTUAL_HOST
/*
** Define this to prevent mixed case userids that clonebots use.
** It is strongly advised to define this, unless you have a known reason
** not to.
*/
#define DISALLOW_MIXED_CASE
/*
** The mixed case patch can optionally notify opers when an invalid uid
** is received by the server. However, this can get to be very annoying
** when auto connect bots with invalid ids try connecting. Define at
** your own discretion
*/
#define NOTIFY_OPS_INVALID_UID
/*
** Clone bot detection on registration.
** This feature blocks connections if more than CHECK_CLONE_LIMIT
** clients connect from the same host within CHECK_CLONE_PERIOD seconds.
**
** The feature is enabled CHECK_CLONE_DELAY seconds after the server
** is started.
**
** Define CHECK_CLONE is you want this feature.
*/
#define CHECK_CLONE
#define CHECK_CLONE_LIMIT 5 /* recommended value 5 */
#define CHECK_CLONE_PERIOD 20 /* recommended value 20 */
#define CHECK_CLONE_DELAY 120 /* 120 secs should be ok */
/*
** Nick flood limit
** Minimum time between nick changes.
** (The first two changes are allowed quickly after another however).
**
** Define NICK_DELAY if you want this feature.
*/
#define NICK_DELAY 30 /* recommended value 30 */
/*
** Default LIST command parameters.
** Undefine if you like having your server flooded by mIRC users.
*/
#define DEFAULT_LIST_PARAM "T<10"
/*
** Define this if you wish to output a *file* to a K lined client rather
** than the K line comment (the comment field is treated as a filename)
*/
#undef COMMENT_IS_FILE
/* Do these work? I dunno... */
#undef VMS /* Should work for IRC client, not server */
#undef MAIL50 /* If you're running VMS 5.0 */
#undef PCS /* PCS Cadmus MUNIX, use with BSD flag! */
/*
* NOTE: On some systems, valloc() causes many problems.
*/
#undef VALLOC /* Define this if you have valloc(3) */
#ifdef APOLLO
#define RESTARTING_SYSTEMCALLS
#endif /* read/write are restarted after signals
defining this 1, gets siginterrupt call
compiled, which attempts to remove this
behaviour (apollo sr10.1/bsd4.3 needs
this) */
/*
* If your host supports varargs and has vsprintf(), vprintf() and vscanf()
* C calls in its library, then you can define USE_VARARGS to use varargs
* instead of imitation variable arg passing.
*/
#define USE_VARARGS
/*
* Define this if you want to find an existing bug.
* It makes your server EAT cpu time though...
* NEVER define this unless you are debugging a reproducable problem
* under test circumstances.
*/
#undef DEBUGMODE /* define DEBUGMODE to enable debugging mode.*/
/*
* defining FORCE_CORE will automatically "unlimit core", forcing the
* server to dump a core file whenever it has a fatal error. -mlv
*/
#define FORCE_CORE
/*
* NPATH is path to backup file for NOTE.
*/
/* #define NPATH "/usr/lib/irc/.ircdnote" */
/*
* Full pathnames and defaults of irc system's support files. Please note that
* these are only the recommened names and paths. Change as needed.
* You must define these to something, even if you don't really want them.
*/
#define DPATH "/usr/local/lib/ircd" /* dir where all ircd stuff is */
#define SPATH "/usr/local/bin/ircd" /* path to server executeable */
#define CPATH "ircd.conf" /* server configuration file */
#define MPATH "ircd.motd" /* server MOTD file */
#define LPATH "/tmp/ircd.log" /* Where the debug file lives, if DEBUGMODE */
#define PPATH "ircd.pid" /* file for server pid */
/* Define this if you want to keep a log of all G-lines that have been added
* and the changes that are made by U-lined servers or local operators. Do
* this; you can simply append this log to your ircd.conf to add the G-lines
* as K-lines!
*/
#define GPATH "gline.log"
/*
* Define this filename to maintain a list of persons who log
* into this server. Logging will stop when the file does not exist.
* Logging will be disable also if you do not define this.
* FNAME_USERLOG just logs user connections, FNAME_OPERLOG logs every
* successful use of /oper. These are either full paths or files within DPATH.
*/
#define FNAME_USERLOG "/usr/local/lib/ircd/users" /* */
/* #define FNAME_OPERLOG "/usr/local/lib/ircd/opers" /* */
/* CHROOTDIR
*
* Define for value added security if you are a rooter.
*
* All files you access must be in the directory you define as DPATH.
* (This may effect the PATH locations above, though you can symlink it)
*
* You may want to define IRC_UID and IRC_GID
*/
#undef CHROOTDIR
/* RELIABLE_CLOCK
*
* Define this if your host has an externally controlled system clock,
* like running xntp.
* If nobody defines this, it still works: The clock will be used of the
* server that was started first.
*/
#undef RELIABLE_CLOCK
/* ENABLE_SUMMON
*
* The SUMMON command requires the ircd to be run as group tty in order
* to work properly in many cases. If you are on a machine where it
* won't work, or simply don't want local users to be summoned, undefine
* this.
*/
#undef ENABLE_SUMMON /* local summon */
#undef ENABLE_USERS /* enables local /users (same as who/finger output) */
/* SHOW_ALL_INVISIBLE_USERS
*
* If this is defined operators on your server will see *ALL* +i users on the
* net. This can be advantagous when tracking clones. (Chaos)
* Only O:'s are affected, for o:'s (local operators) invisible users on
* other servers still have their privacy... -- Niels
*/
#define SHOW_ALL_INVISIBLE_USERS
/* SHOW_INVISIBLE_LUSERS
*
* As defined this will show the correct invisible count for anyone who does
* LUSERS on your server. On a large net this doesnt mean much, but on a
* small net it might be an advantage to undefine it.
* (This will get defined for you if you're using userload (stats w). -mlv)
*/
#define SHOW_INVISIBLE_LUSERS
/* OPER_KILL
*
* If you dont believe operators should be allowed to use the /KILL command
* or believe it is uncessary for them to use it, then leave OPER_KILL
* undefined. This will not affect other operators or servers issuing KILL
* commands however. OPER_REHASH and OPER_RESTART allow operators to
* issue the REHASH and RESTART commands when connected to your server.
* Left undefined they increase the security of your server from wayward
* operators and accidents. Defining OPER_REMOTE removes the restriction
* that O-lines only become fully effective for people on the 'same network'
* as the server. Undefined, it increases the secrity of the server by
* placing restrictions on where people can use operator powers from.
* The 'LOCOP_' #defines are for making the respective commands available
* to 'local' operators.
*/
#define OPER_KILL
#define OPER_REHASH
#define OPER_RESTART
#define OPER_DIE
#define OPER_REMOTE
#define LOCOP_REHASH
#undef LOCOP_RESTART
#undef LOCOP_DIE
/* MAXIMUM LINKS
*
* This define is useful for leaf nodes and gateways. It keeps you from
* connecting to too many places. It works by keeping you from
* connecting to more than "n" nodes which you have C:blah::blah:6667
* lines for.
*
* Note that any number of nodes can still connect to you. This only
* limits the number that you actively reach out to connect to.
*
* Leaf nodes are nodes which are on the edge of the tree. If you want
* to have a backup link, then sometimes you end up connected to both
* your primary and backup, routing traffic between them. To prevent
* this, #define MAXIMUM_LINKS 1 and set up both primary and
* secondary with C:blah::blah:6667 lines. THEY SHOULD NOT TRY TO
* CONNECT TO YOU, YOU SHOULD CONNECT TO THEM.
*
* Gateways such as the server which connects Australia to the US can
* do a similar thing. Put the American nodes you want to connect to
* in with C:blah::blah:6667 lines, and the Australian nodes with
* C:blah::blah lines. Have the Americans put you in with C:blah::blah
* lines. Then you will only connect to one of the Americans.
*
* This value is only used if you don't have server classes defined, and
* a server is in class 0 (the default class if none is set).
*
*/
#define MAXIMUM_LINKS 1
/*
* If your server is running as a a HUB Server then define this.
* A HUB Server has many servers connect to it at the same as opposed
* to a leaf which just has 1 server (typically the uplink). Define this
* correctly for performance reasons.
*/
#undef HUB
/* R_LINES: The conf file now allows the existence of R lines, or
* restrict lines. These allow more freedom in the ability to restrict
* who is to sign on and when. What the R line does is call an outside
* program which returns a reply indicating whether to let the person on.
* Because there is another program involved, Delays and overhead could
* result. It is for this reason that there is a line in config.h to
* decide whether it is something you want or need. -Hoppie
*
* The default is no R_LINES as most people probably don't need it. --Jto
*/
#undef R_LINES
#ifdef R_LINES
/* Also, even if you have R lines defined, you might not want them to be
checked everywhere, since it could cost lots of time and delay. Therefore,
The following two options are also offered: R_LINES_REHASH rechecks for
R lines after a rehash, and R_LINES_OFTEN, which rechecks it as often
as it does K lines. Note that R_LINES_OFTEN is *very* likely to cause
a resource drain, use at your own risk. R_LINES_REHASH shouldn't be too
bad, assuming the programs are fairly short. */
#define R_LINES_REHASH
#define R_LINES_OFTEN
#endif
/*
* NOTE: defining CMDLINE_CONFIG and installing ircd SUID or SGID is a MAJOR
* security problem - they can use the "-f" option to read any files
* that the 'new' access lets them. Note also that defining this is
* a major security hole if your ircd goes down and some other user
* starts up the server with a new conf file that has some extra
* O-lines. So don't use this unless you're debugging.
*/
#undef CMDLINE_CONFIG /* allow conf-file to be specified on command line */
/*
* To use m4 as a preprocessor on the ircd.conf file, define M4_PREPROC.
* The server will then call m4 each time it reads the ircd.conf file,
* reading m4 output as the server's ircd.conf file.
*/
#undef M4_PREPROC
/*
* If you wish to have the server send 'vital' messages about server
* through syslog, define USE_SYSLOG. Only system errors and events critical
* to the server are logged although if this is defined with FNAME_USERLOG,
* syslog() is used instead of the above file. It is not recommended that
* this option is used unless you tell the system administrator beforehand
* and obtain their permission to send messages to the system log files.
*/
#undef USE_SYSLOG
#ifdef USE_SYSLOG
/*
* If you use syslog above, you may want to turn some (none) of the
* spurious log messages for KILL/SQUIT off.
*/
#undef SYSLOG_KILL /* log all operator kills to syslog */
#undef SYSLOG_SQUIT /* log all remote squits for all servers to syslog */
#undef SYSLOG_CONNECT /* log remote connect messages for other all servs */
#undef SYSLOG_USERS /* send userlog stuff to syslog */
#undef SYSLOG_OPER /* log all users who successfully become an Op */
/*
* If you want to log to a different facility than DAEMON, change
* this define.
*/
#define LOG_FACILITY LOG_DAEMON
#endif /* USE_SYSLOG */
/*
* define this if you want to use crypted passwords for operators in your
* ircd.conf file. See ircd/crypt/README for more details on this.
*/
#define CRYPT_OPER_PASSWORD
/*
* If you want to store encrypted passwords in N-lines for server links,
* define this. For a C/N pair in your ircd.conf file, the password
* need not be the same for both, as long as hte opposite end has the
* right password in the opposite line. See INSTALL doc for more details.
*/
#undef CRYPT_LINK_PASSWORD
/*
* define this if you enable summon and if you want summon to look for the
* least idle tty a user is logged in on.
*/
#define LEAST_IDLE
/*
* IDLE_FROM_MSG
*
* Idle-time nullified only from privmsg, if undefined idle-time
* is nullified from everything except ping/pong.
* Added 3.8.1992, kny@cs.hut.fi (nam)
*/
#define IDLE_FROM_MSG
/*
* Max amount of internal send buffering when socket is stuck (bytes)
*/
#define MAXSENDQLENGTH 2000000 /* Recommended value: 300000 for leaves */
/* 2000000 for backbones */
/*
* BUFFERPOOL is the maximum size of the total of all sendq's.
* Recommended value is leaves: 3 * MAXSENDQLENGTH, for hubs: 5 - 7 *.
*/
#define BUFFERPOOL (6 * MAXSENDQLENGTH)
/*
* use these to setup a Unix domain socket to connect clients/servers to.
*/
#define UNIXPORT
/*
* IRC_UID
*
* If you start the server as root but wish to have it run as another user,
* define IRC_UID to that UID. This should only be defined if you are running
* as root and even then perhaps not.
*/
#undef IRC_UID
#undef IRC_GID
#ifdef notdef
#define IRC_UID 65534 /* eg for what to do to enable this feature */
#define IRC_GID 65534
#endif
/*
* CLIENT_FLOOD
*
* this controls the number of bytes the server will allow a client to
* send to the server without processing before disconnecting the client for
* flooding it. Values greater than 8000 make no difference to the server.
*/
#define CLIENT_FLOOD 1024
/* Define this if you want the server to accomplish ircII standard */
/* Sends an extra NOTICE in the beginning of client connection */
#undef IRCII_KLUDGE
/* STOP STOP STOP STOP STOP STOP STOP STOP STOP STOP STOP STOP STOP STOP */
/* You shouldn't change anything below this line, unless absolutely needed. */
#ifdef OPER_KILL
/* LOCAL_KILL_ONLY
*
* To be used, OPER_KILL must be defined.
* LOCAL_KILL_ONLY restricts KILLs to clients which are connected to the
* server the Operator is connected to (ie lets them deal with local
* problem users or 'ghost' clients
*
* NOTE: #define'ing this on an IRC net with servers which have a version
* earlier than 2.7 is prohibited. Such an action and subsequent use
* of KILL for non-local clients should be punished by removal of the
* server's links (if only for ignoring this warning!).
*/
#undef LOCAL_KILL_ONLY
#endif
/*
* Port where ircd resides. NOTE: This *MUST* be greater than 1024 if you
* plan to run ircd under any other uid than root.
*/
#define PORTNUM 6667 /* Recommended values: 6667 or 6666 */
/*
* Maximum number of network connections your server will allow. This should
* never exceed max. number of open file descrpitors and wont increase this.
* Should remain LOW as possible. Most sites will usually have under 30 or so
* connections. A busy hub or server may need this to be as high as 50 or 60.
* Making it over 100 decreases any performance boost gained from it being low.
* if you have a lot of server connections, it may be worth splitting the load
* over 2 or more servers.
* 1 server = 1 connection, 1 user = 1 connection.
* This should be at *least* 3: 1 listen port, 1 dns port + 1 client
*/
#define MAXCONNECTIONS 254
/*
* this defines the length of the nickname history. each time a user changes
* nickname or signs off, their old nickname is added to the top of the list.
* The following sizes are recommended:
* 8MB or less core memory : 500 (at least 1/4 of max users)
* 8MB-16MB core memory : 500-750 (1/4 -> 1/2 of max users)
* 16MB-32MB core memory : 750-1000 (1/2 -> 3/4 of max users)
* 32MB or more core memory : 1000+ (> 3/4 if max users)
* where max users is the expected maximum number of users.
* (100 nicks/users ~ 25k)
* NOTE: this is directly related to the amount of memory ircd will use whilst
* resident and running - it hardly ever gets swapped to disk! You can
* ignore these recommendations- they only are meant to serve as a guide
*/
#define NICKNAMEHISTORYLENGTH 800
/*
* Time interval to wait and if no messages have been received, then check for
* PINGFREQUENCY and CONNECTFREQUENCY
*/
#define TIMESEC 60 /* Recommended value: 60 */
/*
* If daemon doesn't receive anything from any of its links within
* PINGFREQUENCY seconds, then the server will attempt to check for
* an active link with a PING message. If no reply is received within
* (PINGFREQUENCY * 2) seconds, then the connection will be closed.
*/
#define PINGFREQUENCY 120 /* Recommended value: 120 */
/*
* If the connection to to uphost is down, then attempt to reconnect every
* CONNECTFREQUENCY seconds.
*/
#define CONNECTFREQUENCY 600 /* Recommended value: 600 */
/*
* Often net breaks for a short time and it's useful to try to
* establishing the same connection again faster than CONNECTFREQUENCY
* would allow. But, to keep trying on bad connection, we require
* that connection has been open for certain minimum time
* (HANGONGOODLINK) and we give the net few seconds to steady
* (HANGONRETRYDELAY). This latter has to be long enough that the
* other end of the connection has time to notice it broke too.
*/
#define HANGONRETRYDELAY 10 /* Recommended value: 10 seconds */
#define HANGONGOODLINK 300 /* Recommended value: 5 minutes */
/*
* Number of seconds to wait for write to complete if stuck.
*/
#define WRITEWAITDELAY 15 /* Recommended value: 15 */
/*
* Number of seconds to wait for a connect(2) call to complete.
* NOTE: this must be at *LEAST* 10. When a client connects, it has
* CONNECTTIMEOUT - 10 seconds for its host to respond to an ident lookup
* query and for a DNS answer to be retrieved.
* This value should consider the fact that users whose clients do not
* support NOSPOOF will have to type /QUOTE PING <bignumber> before
* registration.
*/
#define CONNECTTIMEOUT 90 /* Recommended value: 90 */
/*
* Max time from the nickname change that still causes KILL
* automaticly to switch for the current nick of that user. (seconds)
*/
#define KILLCHASETIMELIMIT 90 /* Recommended value: 90 */
/*
* Max number of channels a user is allowed to join.
*/
#define MAXCHANNELSPERUSER 10 /* Recommended value: 10 */
/*
* Maximum number of silences a user may set; recommended value: 15
*/
#define MAXSILES 15
/*
* SendQ-Always causes the server to put all outbound data into the sendq and
* flushing the sendq at the end of input processing. This should cause more
* efficient write's to be made to the network.
* There *shouldn't* be any problems with this method.
* -avalon
*/
#define SENDQ_ALWAYS
/* ------------------------- END CONFIGURATION SECTION -------------------- */
#define MOTD MPATH
#define MYNAME SPATH
#define CONFIGFILE CPATH
#define IRCD_PIDFILE PPATH
#ifdef __osf__
#define OSF
/* OSF defines BSD to be its version of BSD */
#undef BSD
#include <sys/param.h>
#ifndef BSD
#define BSD
#endif
#endif
#ifdef _SEQUENT_ /* Dynix 1.4 or 2.0 Generic Define.. */
#undef BSD
#define SYSV /* Also #define SYSV */
#endif
#ifdef ultrix
#define ULTRIX
#endif
#ifdef __hpux
#define HPUX
#endif
#ifdef sgi
#define SGI
#endif
#ifdef DEBUGMODE
extern void debug();
# define Debug(x) debug x
# define LOGFILE LPATH
#else
# define Debug(x) ;
# if VMS
# define LOGFILE "NLA0:"
# else
# define LOGFILE "/dev/null"
# endif
#endif
#ifndef ENABLE_SUMMON
# undef LEAST_IDLE
#endif
#if defined(mips) || defined(PCS)
#undef SYSV
#endif
#ifdef MIPS
#undef BSD
#define BSD 1 /* mips only works in bsd43 environment */
#endif
#ifdef sequent /* Dynix (sequent OS) */
#define SEQ_NOFILE 128 /* set to your current kernel impl, */
#endif /* max number of socket connections */
#ifdef _SEQUENT_
#define DYNIXPTX
#endif
#ifdef BSD_RELIABLE_SIGNALS
# if defined(SYSV_UNRELIABLE_SIGNALS) || defined(POSIX_SIGNALS)
error You stuffed up config.h signals #defines use only one.
# endif
#define HAVE_RELIABLE_SIGNALS
#endif
#ifdef SYSV_UNRELIABLE_SIGNALS
# ifdef POSIX_SIGNALS
error You stuffed up config.h signals #defines use only one.
# endif
#undef HAVE_RELIABLE_SIGNALS
#endif
#ifdef POSIX_SIGNALS
#define HAVE_RELIABLE_SIGNALS
#endif
/*
* safety margin so we can always have one spare fd, for motd/authd or
* whatever else. -4 allows "safety" margin of 1 and space reserved.
*/
#define MAXCLIENTS (MAXCONNECTIONS-4)
#ifdef HAVECURSES
# define DOCURSES
#else
# undef DOCURSES
#endif
#ifdef HAVETERMCAP
# define DOTERMCAP
#else
# undef DOTERMCAP
#endif
#ifndef UNIXPORT
#undef UNIXPORTPATH
#endif
#if defined(CLIENT_FLOOD)
# if (CLIENT_FLOOD > 8000) || (CLIENT_FLOOD < 512)
error CLIENT_FLOOD needs redefining.
# endif
#else
error CLIENT_FLOOD undefined
#endif
/*
* Some ugliness for AIX platforms.
*/
#ifdef AIX
# include <sys/machine.h>
# if BYTE_ORDER == BIG_ENDIAN
# define BIT_ZERO_ON_LEFT
# endif
# if BYTE_ORDER == LITTLE_ENDIAN
# define BIT_ZERO_ON_RIGHT
# endif
/*
* this one is used later in sys/types.h (or so i believe). -avalon
*/
# define BSD_INCLUDES
#endif
#define Reg1 register
#define Reg2 register
#define Reg3 register
#define Reg4 register
#define Reg5 register
#define Reg6 register
#define Reg7 register
#define Reg8 register
#define Reg9 register
#define Reg10 register
#endif /* __config_include__ */

163
include/dbuf.h Normal file
View File

@@ -0,0 +1,163 @@
/************************************************************************
* IRC - Internet Relay Chat, include/dbuf.h
* Copyright (C) 1990 Markku Savela
*
* 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 1, 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.
*/
#ifndef __dbuf_include__
#define __dbuf_include__
#ifndef PROTO
#ifdef __STDC__
# define PROTO(x) x
#else
# define PROTO(x) ()
#endif /* __STDC__ */
#endif /* ! PROTO */
/*
** dbuf is a collection of functions which can be used to
** maintain a dynamic buffering of a byte stream.
** Functions allocate and release memory dynamically as
** required [Actually, there is nothing that prevents
** this package maintaining the buffer on disk, either]
*/
/*
** These structure definitions are only here to be used
** as a whole, *DO NOT EVER REFER TO THESE FIELDS INSIDE
** THE STRUCTURES*! It must be possible to change the internal
** implementation of this package without changing the
** interface.
*/
#if !defined(_SEQUENT_)
typedef struct dbuf
{
u_int length; /* Current number of bytes stored */
u_int offset; /* Offset to the first byte */
struct dbufbuf *head; /* First data buffer, if length > 0 */
/* added by mnystrom@mit.edu: */
struct dbufbuf *tail; /* last data buffer, if length > 0 */
} dbuf;
#else
typedef struct dbuf
{
uint length; /* Current number of bytes stored */
uint offset; /* Offset to the first byte */
struct dbufbuf *head; /* First data buffer, if length > 0 */
/* added by mnystrom@mit.edu: */
struct dbufbuf *tail; /* last data buffer, if length > 0 */
} dbuf;
#endif
/*
** And this 'dbufbuf' should never be referenced outside the
** implementation of 'dbuf'--would be "hidden" if C had such
** keyword...
** If it was possible, this would compile to be exactly 1 memory
** page in size. 2048 bytes seems to be the most common size, so
** as long as a pointer is 4 bytes, we get 2032 bytes for buffer
** data after we take away a bit for malloc to play with. -avalon
*/
typedef struct dbufbuf
{
struct dbufbuf *next; /* Next data buffer, NULL if this is last */
char data[2032]; /* Actual data stored here */
} dbufbuf;
/*
** dbuf_put
** Append the number of bytes to the buffer, allocating more
** memory as needed. Bytes are copied into internal buffers
** from users buffer.
**
** returns > 0, if operation successfull
** < 0, if failed (due memory allocation problem)
*/
int dbuf_put PROTO((dbuf *, char *, int));
/* Dynamic buffer header */
/* Pointer to data to be stored */
/* Number of bytes to store */
/*
** dbuf_get
** Remove number of bytes from the buffer, releasing dynamic
** memory, if applicaple. Bytes are copied from internal buffers
** to users buffer.
**
** returns the number of bytes actually copied to users buffer,
** if >= 0, any value less than the size of the users
** buffer indicates the dbuf became empty by this operation.
**
** Return 0 indicates that buffer was already empty.
**
** Negative return values indicate some unspecified
** error condition, rather fatal...
*/
int dbuf_get PROTO(( dbuf *, char *, int));
/* Dynamic buffer header */
/* Pointer to buffer to receive the data */
/* Max amount of bytes that can be received */
/*
** dbuf_map, dbuf_delete
** These functions are meant to be used in pairs and offer
** a more efficient way of emptying the buffer than the
** normal 'dbuf_get' would allow--less copying needed.
**
** map returns a pointer to a largest contiguous section
** of bytes in front of the buffer, the length of the
** section is placed into the indicated "long int"
** variable. Returns NULL *and* zero length, if the
** buffer is empty.
**
** delete removes the specified number of bytes from the
** front of the buffer releasing any memory used for them.
**
** Example use (ignoring empty condition here ;)
**
** buf = dbuf_map(&dyn, &count);
** <process N bytes (N <= count) of data pointed by 'buf'>
** dbuf_delete(&dyn, N);
**
** Note: delete can be used alone, there is no real binding
** between map and delete functions...
*/
char *dbuf_map PROTO((dbuf *, int *));
/* Dynamic buffer header */
/* Return number of bytes accessible */
int dbuf_delete PROTO((dbuf *, int));
/* Dynamic buffer header */
/* Number of bytes to delete */
/*
** DBufLength
** Return the current number of bytes stored into the buffer.
** (One should use this instead of referencing the internal
** length field explicitly...)
*/
#define DBufLength(dyn) ((dyn)->length)
/*
** DBufClear
** Scratch the current content of the buffer. Release all
** allocated buffers and make it empty.
*/
#define DBufClear(dyn) dbuf_delete((dyn),DBufLength(dyn))
extern int dbuf_getmsg PROTO((dbuf *, char *, int));
#endif /* __dbuf_include__ */

242
include/h.h Normal file
View File

@@ -0,0 +1,242 @@
/************************************************************************
* IRC - Internet Relay Chat, include/h.h
* Copyright (C) 1992 Darren Reed
*
* 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 1, 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.
*/
/*
* "h.h". - Headers file.
*
* Most of the externs and prototypes thrown in here to 'cleanup' things.
* -avalon
*/
extern time_t nextconnect, nextdnscheck, nextping, now;
extern aClient *client, me, *local[];
extern aChannel *channel;
extern struct stats *ircstp;
extern int bootopt;
extern aChannel *find_channel PROTO((char *, aChannel *));
extern void remove_user_from_channel PROTO((aClient *, aChannel *));
extern void del_invite PROTO((aClient *, aChannel *));
extern int del_silence PROTO((aClient *, char *));
extern void send_user_joins PROTO((aClient *, aClient *));
extern void clean_channelname PROTO((char *));
extern int can_send PROTO((aClient *, aChannel *));
extern int is_chan_op PROTO((aClient *, aChannel *));
extern int is_zombie PROTO((aClient *, aChannel *));
extern int has_voice PROTO((aClient *, aChannel *));
extern int count_channels PROTO((aClient *));
extern aClient *find_client PROTO((char *, aClient *));
extern aClient *find_name PROTO((char *, aClient *));
extern aClient *find_person PROTO((char *, aClient *));
extern aClient *find_server PROTO((char *, aClient *));
extern aClient *find_match_server PROTO((char *));
extern aClient *find_service PROTO((char *, aClient *));
extern aClient *find_userhost PROTO((char *, char *, aClient *, int *));
extern int attach_conf PROTO((aClient *, aConfItem *));
extern aConfItem *attach_confs PROTO((aClient*, const char *, int));
extern aConfItem *attach_confs_host PROTO((aClient*, char *, int));
extern int attach_Iline PROTO((aClient *, struct hostent *, char *));
extern aConfItem *conf, *find_me PROTO(()), *find_admin PROTO(());
extern aGline *gline;
extern aConfItem *count_cnlines PROTO((Link *));
extern void det_confs_butmask PROTO((aClient *, int));
extern int detach_conf PROTO((aClient *, aConfItem *));
extern aConfItem *det_confs_butone PROTO((aClient *, aConfItem *));
extern aConfItem *find_conf PROTO((Link *, char*, int));
extern aConfItem *find_conf_exact PROTO((char *, char *, char *, int));
extern aConfItem *find_conf_host PROTO((Link *, char *, int));
extern aConfItem *find_conf_ip PROTO((Link *, char *, char *, int));
extern aConfItem *find_conf_name PROTO((char *, int));
extern int find_kill PROTO((aClient *));
extern int find_restrict PROTO((aClient *));
extern int rehash PROTO((aClient *, aClient *, int));
extern int initconf PROTO((int));
extern char *MyMalloc PROTO((int)), *MyRealloc PROTO((char *, int));
extern char *debugmode, *configfile, *sbrk0;
extern char *getfield PROTO((char *));
extern void get_sockhost PROTO((aClient *, char *));
extern char *rpl_str PROTO((int)), *err_str PROTO((int));
extern char *strerror PROTO((int));
extern int dgets PROTO((int, char *, int));
extern char *inetntoa PROTO((char *));
extern int dbufalloc, dbufblocks, debuglevel, errno, h_errno;
extern int highest_fd, debuglevel, portnum, debugtty, maxusersperchannel;
extern int readcalls, udpfd, resfd;
extern aClient *add_connection PROTO((aClient *, int));
extern int add_listener PROTO((aConfItem *));
extern void add_local_domain PROTO((char *, int));
extern int check_client PROTO((aClient *));
extern int check_server PROTO((aClient *, struct hostent *, \
aConfItem *, aConfItem *));
extern int check_server_init PROTO((aClient *));
extern void close_connection PROTO((aClient *));
extern void close_listeners PROTO(());
extern int connect_server PROTO((aConfItem *, aClient *, struct hostent *));
extern void get_my_name PROTO((aClient *, char *, int));
extern int get_sockerr PROTO((aClient *));
extern int inetport PROTO((aClient *, char *, int));
extern void init_sys PROTO(());
extern int read_message PROTO((time_t));
extern void report_error PROTO((char *, aClient *));
extern void set_non_blocking PROTO((int, aClient *));
extern int setup_ping PROTO(());
extern void summon PROTO((aClient *, char *, char *, char *));
extern int unixport PROTO((aClient *, char *, int));
extern int utmp_open PROTO(());
extern int utmp_read PROTO((int, char *, char *, char *, int));
extern int utmp_close PROTO((int));
extern void start_auth PROTO((aClient *));
extern void read_authports PROTO((aClient *));
extern void send_authports PROTO((aClient *));
extern void restart PROTO((char *));
extern void send_channel_modes PROTO((aClient *, aChannel *));
extern void server_reboot PROTO(());
extern void terminate PROTO(()), write_pidfile PROTO(());
extern void end_ping PROTO((aClient *));
extern void cancel_ping PROTO((aClient *, aClient *));
extern void send_queued PROTO((aClient *));
/*VARARGS2*/
extern void sendto_one();
extern void vsendto_one();
/*VARARGS4*/
extern void sendto_channel_butone();
/*VARARGS2*/
extern void sendto_serv_butone();
/*VARARGS2*/
extern void sendto_common_channels();
/*VARARGS3*/
extern void sendto_channel_butserv();
/*VARARGS3*/
extern void sendto_match_servs();
/*VARARGS5*/
extern void sendto_match_butone();
/*VARARGS3*/
extern void sendto_all_butone();
/*VARARGS1*/
extern void sendto_ops();
/*VARARGS2*/
extern void sendto_lops_butone();
/*VARARGS3*/
extern void sendto_ops_butone();
/*VARARGS3*/
extern void sendto_prefix_one();
extern void vsendto_prefix_one();
/*VARARGS4*/
extern int exit_client_msg();
extern int writecalls, writeb[];
extern int deliver_it PROTO((aClient *, char *, int));
extern int check_registered PROTO((aClient *));
extern int check_registered_user PROTO((aClient *));
extern char *get_client_name PROTO((aClient *, int));
extern char *get_client_host PROTO((aClient *));
extern char *my_name_for_link PROTO((char *, aConfItem *));
extern char *myctime PROTO((time_t)), *date PROTO((time_t));
extern int exit_client PROTO((aClient *, aClient *, aClient *, char *));
extern void initstats PROTO(()), tstats PROTO((aClient *, char *));
extern int parse PROTO((aClient *, char *, char *, struct Message *));
extern int do_numeric PROTO((int, aClient *, aClient *, int, char **));
extern int hunt_server PROTO((aClient *,aClient *,char *,int,int,char **));
extern aClient *next_client PROTO((aClient *, char *));
extern int m_umode PROTO((aClient *, aClient *, int, char **));
extern int m_names PROTO((aClient *, aClient *, int, char **));
extern int m_server_estab PROTO((aClient *, aConfItem *, aConfItem *));
extern void send_umode PROTO((aClient *, aClient *, int, int, char *));
extern void send_umode_out PROTO((aClient*, aClient *, int));
extern void free_client PROTO((aClient *));
extern void free_link PROTO((Link *));
extern void free_conf PROTO((aConfItem *));
extern void free_class PROTO((aClass *));
extern void free_user PROTO((anUser *, aClient *));
extern void free_gline PROTO((aGline *, aGline *));
extern Link *make_link PROTO(());
extern Dlink *add_dlink PROTO((Dlink **, aClient *));
extern void remove_dlink PROTO((Dlink **, Dlink *));
extern anUser *make_user PROTO((aClient *));
extern aConfItem *make_conf PROTO(());
extern aClass *make_class PROTO(());
extern aServer *make_server PROTO((aClient *));
extern aClient *make_client PROTO((aClient *));
extern aGline *make_gline PROTO((char *, char *, char *, time_t));
extern aGline *find_gline PROTO((char *, char *, aGline **));
extern Link *find_user_link PROTO((Link *, aClient *));
extern int IsMember PROTO((aClient *, aChannel *));
extern char *pretty_mask PROTO((char *));
extern void add_client_to_list PROTO((aClient *));
extern void checklist PROTO(());
extern void remove_client_from_list PROTO((aClient *));
extern void initlists PROTO(());
extern void add_class PROTO((int, int, int, int, long));
extern void fix_class PROTO((aConfItem *, aConfItem *));
extern long get_sendq PROTO((aClient *));
extern int get_con_freq PROTO((aClass *));
extern int get_client_ping PROTO((aClient *));
extern int get_client_class PROTO((aClient *));
extern int get_conf_class PROTO((aConfItem *));
extern void report_classes PROTO((aClient *));
extern struct hostent *get_res PROTO((char *));
extern struct hostent *gethost_byaddr PROTO((struct in_addr *, Link *));
extern struct hostent *gethost_byname PROTO((char *, Link *));
extern void flush_cache PROTO(());
extern int init_resolver PROTO((int));
extern time_t timeout_query_list PROTO((void));
extern time_t expire_cache PROTO((void));
extern void del_queries PROTO((char *));
extern void clear_channel_hash_table PROTO(());
extern void clear_client_hash_table PROTO(());
extern int add_to_client_hash_table PROTO((char *, aClient *));
extern int del_from_client_hash_table PROTO((char *, aClient *));
extern int add_to_channel_hash_table PROTO((char *, aChannel *));
extern int del_from_channel_hash_table PROTO((char *, aChannel *));
extern aChannel *hash_find_channel PROTO((char *, aChannel *));
extern aClient *hash_find_client PROTO((char *, aClient *));
extern aClient *hash_find_nickserver PROTO((char *, aClient *));
extern aClient *hash_find_server PROTO((char *, aClient *));
extern void add_history PROTO((aClient *));
extern aClient *get_history PROTO((char *, time_t));
extern void initwhowas PROTO(());
extern void off_history PROTO((aClient *));
extern int dopacket PROTO((aClient *, char *, int));
/*VARARGS2*/
extern void debug();
#if defined(DEBUGMODE)
extern void send_usage PROTO((aClient *, char *));
extern void send_listinfo PROTO((aClient *, char *));
extern void count_memory PROTO((aClient *, char *));
#endif
char *crule_parse PROTO((char *));
int crule_eval PROTO((char *));
void crule_free PROTO((char **));

37
include/hash.h Normal file
View File

@@ -0,0 +1,37 @@
/************************************************************************
* IRC - Internet Relay Chat, include/hash.h
* Copyright (C) 1991 Darren Reed
*
* 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 1, 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.
*/
#ifndef __hash_include__
#define __hash_include__
typedef struct hashentry {
int hits;
int links;
void *list;
} aHashEntry;
#ifndef DEBUGMODE
#define HASHSIZE 10007 /* prime number */
#define CHANNELHASHSIZE 2003 /* prime number */
#else
extern int HASHSIZE;
extern int CHANNELHASHSIZE;
#endif
#endif /* __hash_include__ */

50
include/inet.h Normal file
View File

@@ -0,0 +1,50 @@
/*
* Copyright (c) 1983 Regents of the University of California.
* All rights reserved.
*
* Redistribution and use in source and binary forms are permitted
* provided that: (1) source distributions retain this entire copyright
* notice and comment, and (2) distributions including binaries display
* the following acknowledgement: ``This product includes software
* developed by the University of California, Berkeley and its contributors''
* in the documentation or other materials provided with the distribution
* and in all advertising materials mentioning features or use of this
* software. Neither the name of the University nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
* @(#)inet.h 5.4 (Berkeley) 6/1/90
*/
/* External definitions for functions in inet(3) */
#include "config.h" /* for system definitions */
#ifdef __alpha
#define __u_l unsigned int
#else
#define __u_l unsigned long
#endif
#ifdef __STDC__
extern __u_l inet_addr(char *);
extern char *inet_ntoa(char *);
extern __u_l inet_makeaddr(int , int);
extern __u_l inet_network(char *);
extern __u_l inet_lnaof(struct in_addr);
extern __u_l inet_netof(struct in_addr);
#else
extern __u_l inet_addr();
extern char *inet_ntoa();
#ifndef HPUX
extern __u_l inet_makeaddr();
#endif
#endif
#ifndef HPUX
extern __u_l inet_network();
extern __u_l inet_lnaof();
extern __u_l inet_netof();
#endif
#undef __u_l

187
include/msg.h Normal file
View File

@@ -0,0 +1,187 @@
/************************************************************************
* IRC - Internet Relay Chat, include/msg.h
* Copyright (C) 1990 Jarkko Oikarinen and
* University of Oulu, Computing Center
*
* 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 1, 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.
*/
#ifndef __msg_include__
#define __msg_include__
#define MSG_PRIVATE "PRIVMSG" /* PRIV */
#define MSG_WHO "WHO" /* WHO -> WHOC */
#define MSG_WHOIS "WHOIS" /* WHOI */
#define MSG_WHOWAS "WHOWAS" /* WHOW */
#define MSG_USER "USER" /* USER */
#define MSG_NICK "NICK" /* NICK */
#define MSG_SERVER "SERVER" /* SERV */
#define MSG_LIST "LIST" /* LIST */
#define MSG_TOPIC "TOPIC" /* TOPI */
#define MSG_INVITE "INVITE" /* INVI */
#define MSG_VERSION "VERSION" /* VERS */
#define MSG_QUIT "QUIT" /* QUIT */
#define MSG_SQUIT "SQUIT" /* SQUI */
#define MSG_KILL "KILL" /* KILL */
#define MSG_INFO "INFO" /* INFO */
#define MSG_LINKS "LINKS" /* LINK */
#define MSG_SUMMON "SUMMON" /* SUMM */
#define MSG_STATS "STATS" /* STAT */
#define MSG_USERS "USERS" /* USER -> USRS */
#define MSG_HELP "HELP" /* HELP */
#define MSG_ERROR "ERROR" /* ERRO */
#define MSG_AWAY "AWAY" /* AWAY */
#define MSG_CONNECT "CONNECT" /* CONN */
#define MSG_UPING "UPING" /* UPIN */
#define MSG_MAP "MAP" /* MAP */
#define MSG_PING "PING" /* PING */
#define MSG_PONG "PONG" /* PONG */
#define MSG_OPER "OPER" /* OPER */
#define MSG_PASS "PASS" /* PASS */
#define MSG_WALLOPS "WALLOPS" /* WALL */
#define MSG_TIME "TIME" /* TIME */
#define MSG_SETTIME "SETTIME" /* SETT */
#define MSG_RPING "RPING" /* RPIN */
#define MSG_RPONG "RPONG" /* RPON */
#define MSG_NAMES "NAMES" /* NAME */
#define MSG_ADMIN "ADMIN" /* ADMI */
#define MSG_TRACE "TRACE" /* TRAC */
#define MSG_NOTICE "NOTICE" /* NOTI */
#define MSG_JOIN "JOIN" /* JOIN */
#define MSG_PART "PART" /* PART */
#define MSG_LUSERS "LUSERS" /* LUSE */
#define MSG_MOTD "MOTD" /* MOTD */
#define MSG_MODE "MODE" /* MODE */
#define MSG_KICK "KICK" /* KICK */
#define MSG_SERVICE "SERVICE" /* SERV -> SRVI */
#define MSG_USERHOST "USERHOST" /* USER -> USRH */
#define MSG_ISON "ISON" /* ISON */
#define MSG_NOTE "NOTE" /* NOTE */
#define MSG_SQUERY "SQUERY" /* SQUE */
#define MSG_SERVLIST "SERVLIST" /* SERV -> SLIS */
#define MSG_SERVSET "SERVSET" /* SERV -> SSET */
#define MSG_REHASH "REHASH" /* REHA */
#define MSG_RESTART "RESTART" /* REST */
#define MSG_CLOSE "CLOSE" /* CLOS */
#define MSG_DIE "DIE"
#define MSG_HASH "HASH" /* HASH */
#define MSG_DNS "DNS" /* DNS -> DNSS */
#define MSG_SILENCE "SILENCE" /* SILE */
#define MSG_GLINE "GLINE" /* GLIN */
#define MAXPARA 15
extern int m_private(), m_topic(), m_join(), m_part(), m_mode();
extern int m_ping(), m_pong(), m_wallops(), m_kick();
extern int m_nick(), m_error(), m_notice();
extern int m_invite(), m_quit(), m_kill();
extern int m_motd(), m_who(), m_whois(), m_user(), m_list();
extern int m_server(), m_info(), m_links(), m_summon(), m_stats();
extern int m_users(), m_version(), m_help();
extern int m_squit(), m_away(), m_connect(), m_uping(), m_map();
extern int m_oper(), m_pass(), m_trace();
extern int m_time(), m_settime(), m_rping(), m_rpong(), m_names(), m_admin();
extern int m_lusers(), m_umode(), m_note(), m_close();
extern int m_motd(), m_whowas(), m_silence();
extern int m_service(), m_userhost(), m_ison();
extern int m_service(), m_servset(), m_servlist(), m_squery();
extern int m_gline();
#if defined(OPER_REHASH) || defined(LOCOP_REHASH)
extern int m_rehash();
#endif
#if defined(OPER_RESTART) || defined(LOCOP_RESTART)
extern int m_restart();
#endif
#if defined(OPER_DIE) || defined(LOCOP_DIE)
extern int m_die();
#endif
extern int m_hash(), m_dns();
#ifdef MSGTAB
struct Message msgtab[] = {
{ MSG_PRIVATE, m_private, 0, MAXPARA, 1 ,0L },
{ MSG_NICK, m_nick, 0, MAXPARA, 1 ,0L },
{ MSG_NOTICE, m_notice, 0, MAXPARA, 1 ,0L },
{ MSG_JOIN, m_join, 0, MAXPARA, 1 ,0L },
{ MSG_MODE, m_mode, 0, MAXPARA, 1 ,0L },
{ MSG_QUIT, m_quit, 0, MAXPARA, 1 ,0L },
{ MSG_PART, m_part, 0, MAXPARA, 1 ,0L },
{ MSG_TOPIC, m_topic, 0, MAXPARA, 1 ,0L },
{ MSG_INVITE, m_invite, 0, MAXPARA, 1 ,0L },
{ MSG_KICK, m_kick, 0, MAXPARA, 1 ,0L },
{ MSG_WALLOPS, m_wallops, 0, MAXPARA, 1 ,0L },
{ MSG_PING, m_ping, 0, MAXPARA, 1 ,0L },
{ MSG_PONG, m_pong, 0, MAXPARA, 1 ,0L },
{ MSG_ERROR, m_error, 0, MAXPARA, 1 ,0L },
{ MSG_KILL, m_kill, 0, MAXPARA, 1 ,0L },
{ MSG_USER, m_user, 0, MAXPARA, 1 ,0L },
{ MSG_AWAY, m_away, 0, MAXPARA, 1 ,0L },
{ MSG_ISON, m_ison, 0, 1, 1 ,0L },
{ MSG_SERVER, m_server, 0, MAXPARA, 1 ,0L },
{ MSG_SQUIT, m_squit, 0, MAXPARA, 1 ,0L },
{ MSG_WHOIS, m_whois, 0, MAXPARA, 1 ,0L },
{ MSG_WHO, m_who, 0, MAXPARA, 1 ,0L },
{ MSG_WHOWAS, m_whowas, 0, MAXPARA, 1 ,0L },
{ MSG_LIST, m_list, 0, MAXPARA, 1 ,0L },
{ MSG_NAMES, m_names, 0, MAXPARA, 1 ,0L },
{ MSG_USERHOST,m_userhost, 0, 1, 1 ,0L },
{ MSG_TRACE, m_trace, 0, MAXPARA, 1 ,0L },
{ MSG_PASS, m_pass, 0, MAXPARA, 1 ,0L },
{ MSG_LUSERS, m_lusers, 0, MAXPARA, 1 ,0L },
{ MSG_TIME, m_time, 0, MAXPARA, 1 ,0L },
{ MSG_SETTIME, m_settime, 0, MAXPARA, 1 ,0L },
{ MSG_RPING, m_rping, 0, MAXPARA, 1 ,0L },
{ MSG_RPONG, m_rpong, 0, MAXPARA, 1 ,0L },
{ MSG_OPER, m_oper, 0, MAXPARA, 1 ,0L },
{ MSG_CONNECT, m_connect, 0, MAXPARA, 1 ,0L },
{ MSG_UPING, m_uping, 0, MAXPARA, 1 ,0L },
{ MSG_MAP, m_map, 0, MAXPARA, 1 ,0L },
{ MSG_VERSION, m_version, 0, MAXPARA, 1 ,0L },
{ MSG_STATS, m_stats, 0, MAXPARA, 1 ,0L },
{ MSG_LINKS, m_links, 0, MAXPARA, 1 ,0L },
{ MSG_ADMIN, m_admin, 0, MAXPARA, 1 ,0L },
{ MSG_USERS, m_users, 0, MAXPARA, 1 ,0L },
{ MSG_SUMMON, m_summon, 0, MAXPARA, 1 ,0L },
{ MSG_HELP, m_help, 0, MAXPARA, 1 ,0L },
{ MSG_INFO, m_info, 0, MAXPARA, 1 ,0L },
{ MSG_MOTD, m_motd, 0, MAXPARA, 1 ,0L },
{ MSG_CLOSE, m_close, 0, MAXPARA, 1 ,0L },
{ MSG_SILENCE, m_silence, 0, MAXPARA, 1 ,0L },
{ MSG_GLINE, m_gline, 0, MAXPARA, 1 ,0L },
{ MSG_NOTE, m_note, 0, 1, 1 ,0L },
#undef USE_SERVICES
#ifdef USE_SERVICES
{ MSG_SERVICE, m_service, 0, MAXPARA, 1 ,0L },
{ MSG_SERVSET, m_servset, 0, MAXPARA, 1 ,0L },
{ MSG_SQUERY, m_squery, 0, MAXPARA, 1 ,0L },
{ MSG_SERVLIST,m_servlist, 0, MAXPARA, 1 ,0L },
#endif
{ MSG_HASH, m_hash, 0, MAXPARA, 1 ,0L },
{ MSG_DNS, m_dns, 0, MAXPARA, 1 ,0L },
#if defined(OPER_REHASH) || defined(LOCOP_REHASH)
{ MSG_REHASH, m_rehash, 0, MAXPARA, 1 ,0L },
#endif
#if defined(OPER_RESTART) || defined(LOCOP_RESTART)
{ MSG_RESTART, m_restart, 0, MAXPARA, 1 ,0L },
#endif
#if defined(OPER_DIE) || defined(LOCOP_DIE)
{ MSG_DIE, m_die, 0, MAXPARA, 1 ,0L },
#endif
{ (char *) 0, (int (*)()) 0 , 0, 0, 0, 0L}
};
#else
extern struct Message msgtab[];
#endif
#endif /* __msg_include__ */

248
include/nameser.h Normal file
View File

@@ -0,0 +1,248 @@
/*
* Copyright (c) 1983, 1989 Regents of the University of California.
* All rights reserved.
*
* Redistribution and use in source and binary forms are permitted
* provided that: (1) source distributions retain this entire copyright
* notice and comment, and (2) distributions including binaries display
* the following acknowledgement: ``This product includes software
* developed by the University of California, Berkeley and its contributors''
* in the documentation or other materials provided with the distribution
* and in all advertising materials mentioning features or use of this
* software. Neither the name of the University nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
* @(#)nameser.h 5.24 (Berkeley) 6/1/90
*/
/*
* Define constants based on rfc883
*/
#define PACKETSZ 512 /* maximum packet size */
#define MAXDNAME 256 /* maximum domain name */
#define MAXCDNAME 255 /* maximum compressed domain name */
#define MAXLABEL 63 /* maximum length of domain label */
/* Number of bytes of fixed size data in query structure */
#define QFIXEDSZ 4
/* number of bytes of fixed size data in resource record */
#define RRFIXEDSZ 10
/*
* Internet nameserver port number
*/
#define NAMESERVER_PORT 53
/*
* Currently defined opcodes
*/
#define QUERY 0x0 /* standard query */
#define IQUERY 0x1 /* inverse query */
#define STATUS 0x2 /* nameserver status query */
/*#define xxx 0x3 /* 0x3 reserved */
/* non standard */
#define UPDATEA 0x9 /* add resource record */
#define UPDATED 0xa /* delete a specific resource record */
#define UPDATEDA 0xb /* delete all nemed resource record */
#define UPDATEM 0xc /* modify a specific resource record */
#define UPDATEMA 0xd /* modify all named resource record */
#define ZONEINIT 0xe /* initial zone transfer */
#define ZONEREF 0xf /* incremental zone referesh */
/*
* Currently defined response codes
*/
#ifdef NOERROR /* defined by solaris2 in */
#undef NOERROR /* <sys/stream.h> to be -1 */
#endif
#define NOERROR 0 /* no error */
#define FORMERR 1 /* format error */
#define SERVFAIL 2 /* server failure */
#define NXDOMAIN 3 /* non existent domain */
#define NOTIMP 4 /* not implemented */
#define REFUSED 5 /* query refused */
/* non standard */
#define NOCHANGE 0xf /* update failed to change db */
/*
* Type values for resources and queries
*/
#define T_A 1 /* host address */
#define T_NS 2 /* authoritative server */
#define T_MD 3 /* mail destination */
#define T_MF 4 /* mail forwarder */
#define T_CNAME 5 /* connonical name */
#define T_SOA 6 /* start of authority zone */
#define T_MB 7 /* mailbox domain name */
#define T_MG 8 /* mail group member */
#define T_MR 9 /* mail rename name */
#define T_NULL 10 /* null resource record */
#define T_WKS 11 /* well known service */
#define T_PTR 12 /* domain name pointer */
#define T_HINFO 13 /* host information */
#define T_MINFO 14 /* mailbox information */
#define T_MX 15 /* mail routing information */
#define T_TXT 16 /* text strings */
/* non standard */
#define T_UINFO 100 /* user (finger) information */
#define T_UID 101 /* user ID */
#define T_GID 102 /* group ID */
#define T_UNSPEC 103 /* Unspecified format (binary data) */
/* Query type values which do not appear in resource records */
#define T_AXFR 252 /* transfer zone of authority */
#define T_MAILB 253 /* transfer mailbox records */
#define T_MAILA 254 /* transfer mail agent records */
#define T_ANY 255 /* wildcard match */
/*
* Values for class field
*/
#define C_IN 1 /* the arpa internet */
#define C_CHAOS 3 /* for chaos net at MIT */
#define C_HS 4 /* for Hesiod name server at MIT */
/* Query class values which do not appear in resource records */
#define C_ANY 255 /* wildcard match */
/*
* Status return codes for T_UNSPEC conversion routines
*/
#define CONV_SUCCESS 0
#define CONV_OVERFLOW -1
#define CONV_BADFMT -2
#define CONV_BADCKSUM -3
#define CONV_BADBUFLEN -4
#ifndef BYTE_ORDER
#define LITTLE_ENDIAN 1234 /* least-significant byte first (vax) */
#define BIG_ENDIAN 4321 /* most-significant byte first (IBM, net) */
#define PDP_ENDIAN 3412 /* LSB first in word, MSW first in long (pdp) */
#if defined(vax) || defined(ns32000) || defined(sun386) || defined(MIPSEL) || \
defined(BIT_ZERO_ON_RIGHT) || defined(sequent) || defined(i386) ||\
defined(___vax__) || defined(__ns32000__) || defined(__sun386__) ||\
defined(__alpha)
#define BYTE_ORDER LITTLE_ENDIAN
#endif
#if defined(sel) || defined(pyr) || defined(mc68000) || defined(sparc) || \
defined(is68k) || defined(tahoe) || defined(ibm032) || defined(ibm370) || \
defined(MIPSEB) || defined(__hpux) || defined(__convex__) || \
defined(__pyr__) || defined(__mc68000__) || defined(__sparc__) ||\
defined(_IBMR2) || defined (BIT_ZERO_ON_LEFT)
#define BYTE_ORDER BIG_ENDIAN
#endif
#endif /* BYTE_ORDER */
#ifndef BYTE_ORDER
/* you must determine what the correct bit order is for your compiler */
UNDEFINED_BIT_ORDER;
#endif
/*
* Structure for query header, the order of the fields is machine and
* compiler dependent, in our case, the bits within a byte are assignd
* least significant first, while the order of transmition is most
* significant first. This requires a somewhat confusing rearrangement.
*/
typedef struct {
u_short id; /* query identification number */
#if BYTE_ORDER == BIG_ENDIAN
/* fields in third byte */
u_char qr:1; /* response flag */
u_char opcode:4; /* purpose of message */
u_char aa:1; /* authoritive answer */
u_char tc:1; /* truncated message */
u_char rd:1; /* recursion desired */
/* fields in fourth byte */
u_char ra:1; /* recursion available */
u_char pr:1; /* primary server required (non standard) */
u_char unused:2; /* unused bits */
u_char rcode:4; /* response code */
#endif
#if BYTE_ORDER == LITTLE_ENDIAN || BYTE_ORDER == PDP_ENDIAN
/* fields in third byte */
u_char rd:1; /* recursion desired */
u_char tc:1; /* truncated message */
u_char aa:1; /* authoritive answer */
u_char opcode:4; /* purpose of message */
u_char qr:1; /* response flag */
/* fields in fourth byte */
u_char rcode:4; /* response code */
u_char unused:2; /* unused bits */
u_char pr:1; /* primary server required (non standard) */
u_char ra:1; /* recursion available */
#endif
/* remaining bytes */
u_short qdcount; /* number of question entries */
u_short ancount; /* number of answer entries */
u_short nscount; /* number of authority entries */
u_short arcount; /* number of resource entries */
} HEADER;
/*
* Defines for handling compressed domain names
*/
#define INDIR_MASK 0xc0
/*
* Structure for passing resource records around.
*/
struct rrec {
short r_zone; /* zone number */
short r_class; /* class number */
short r_type; /* type number */
#ifdef __alpha
u_int r_ttl; /* time to live */
#else
u_long r_ttl; /* time to live */
#endif
int r_size; /* size of data area */
char *r_data; /* pointer to data */
};
extern u_short _getshort();
#ifdef __alpha
extern u_int _getlong();
#else
extern u_long _getlong();
#endif
/*
* Inline versions of get/put short/long.
* Pointer is advanced; we assume that both arguments
* are lvalues and will already be in registers.
* cp MUST be u_char *.
*/
#define GETSHORT(s, cp) { \
(s) = *(cp)++ << 8; \
(s) |= *(cp)++; \
}
#define GETLONG(l, cp) { \
(l) = *(cp)++ << 8; \
(l) |= *(cp)++; (l) <<= 8; \
(l) |= *(cp)++; (l) <<= 8; \
(l) |= *(cp)++; \
}
#define PUTSHORT(s, cp) { \
*(cp)++ = (s) >> 8; \
*(cp)++ = (s); \
}
/*
* Warning: PUTLONG destroys its first argument.
*/
#define PUTLONG(l, cp) { \
(cp)[3] = l; \
(cp)[2] = (l >>= 8); \
(cp)[1] = (l >>= 8); \
(cp)[0] = l >> 8; \
(cp) += sizeof(u_long); \
}

363
include/numeric.h Normal file
View File

@@ -0,0 +1,363 @@
/************************************************************************
* IRC - Internet Relay Chat, include/numeric.h
* Copyright (C) 1990 Jarkko Oikarinen
*
* 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 1, 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.
*/
/*
* -- Run -- 30 Sept 1994
*
* Added RPL_MAP, RPL_MAPMORE, RPL_MAPEND
*/
/*
* -- Run -- 22 Sept 1994
*
* Added RPL_TRACEPING
*/
/*
* -- Tonto -- 18 Aug 1994
*
* Added RPL_STATSDLINE
*/
/*
* -- SIO -- 11 Aug 1993
*
* Added RPL_TOPICWHOTIME
*/
/*
* -- Avalon -- 1 Sep 1992
*
* Added RPL_TRACELOG, RPL_STATSOLINE
*/
/*
* -- Avalon -- 13 Aug 1992
*
* Added ERR_BADCHANNELKEY, ERR_KEYSET
*/
/*
* -- Avalon -- 10 Aug 1992
*
* Added RPL_SUMMONING
*/
/*
* -- Avalon -- 5 Jul 1992
*
* Added ERR_NICKCOLLISION
*/
/*
* -- Avalon -- 14 Jul 1992
*
* Added RPL_UNAWAY, RPL_NOWAWAY, ERR_NOORIGIN, ERR_FILEERROR, ERR_NOLOGIN,
* ERR_SUMMONDISABLED, ERR_USERSDISABLED, RPL_USERSSTART, RPL_USERS,
* RPL_ENDOFUSERS, RPL_NOUSERS
*/
/*
* -- Avalon -- 12 Jul 1992
*
* Added RPL_CLOSING RPL_CLOSEEND
*/
/*
* -- Avalon -- 10-11 Jul 1992
*
* Added RPL_MOTD, RPL_MOTDSTART, RPL_ENDOFMOTD, ERR_NOMOTD,
* RPL_INFO, RPL_INFOSTART, RPL_ENDOFINFO, ERR_CANTKILLSERVER,
* RPL_LUSERCLIENT, RPL_LUSEROP, RPL_LUSERUNKNOWN, RPL_LUSERCHAN, RPL_LUSERME,
* RPL_STATSUPTIME, RPL_ADMINLOC1, RPL_ADMINLOC2, RPL_ADMINME,
* RPL_ADMINEMAIL, ERR_NOADMININFO
*/
/*
* -- Avalon -- 28 Jun 1992
*
* Added ERR_BADCHANMASK and RPL_ENDOFWHOWAS
*/
/*
* -- Avalon -- 13 May 1992
*
* Added RPL_STATSLLINE
*/
/*
* -- Avalon -- 12 Jan 1992
*
* Added RPL_TRACELINK
*/
/*
* -- Wumpus -- 30 Nov 1991
*
* It's very important that you never change what a numeric means --
* you can delete old ones (maybe) and add new ones, but never ever
* take a number and make it suddenly mean something else, or change
* an old number just for the hell of it.
*/
/*
* -- avalon -- 19 Nov 1991
* Added ERR_USERSDONTMATCH
*
* -- avalon -- 06 Nov 1991
* Added RPL_BANLIST, RPL_BANLISTEND, ERR_BANNEDFROMCHAN
*
* -- avalon -- 15 Oct 1991
* Added RPL_TRACEs (201-209)
* Added RPL_STATSs (211-219)
*/
/* -- Jto -- 16 Jun 1990
* A couple of new numerics added...
*/
/* -- Jto -- 03 Jun 1990
* Added ERR_YOUWILLBEBANNED and Check defines (sigh, had to put 'em here..)
* Added ERR_UNKNOWNMODE...
* Added ERR_CANNOTSENDTOCHAN...
*/
/*
* Reserve numerics 000-099 for server-client connections where the client
* is local to the server. If any server is passed a numeric in this range
* from another server then it is remapped to 100-199. -avalon
*/
#define RPL_WELCOME 001
#define RPL_YOURHOST 002
#define RPL_CREATED 003
#define RPL_MYINFO 004
#define RPL_MAP 005
#define RPL_MAPMORE 006
#define RPL_MAPEND 007
/*
* Errors are in the range from 400-599 currently and are grouped by what
* commands they come from.
*/
#define ERR_NOSUCHNICK 401
#define ERR_NOSUCHSERVER 402
#define ERR_NOSUCHCHANNEL 403
#define ERR_CANNOTSENDTOCHAN 404
#define ERR_TOOMANYCHANNELS 405
#define ERR_WASNOSUCHNICK 406
#define ERR_TOOMANYTARGETS 407
#define ERR_NOSUCHSERVICE 408
#define ERR_NOORIGIN 409
#define ERR_NORECIPIENT 411
#define ERR_NOTEXTTOSEND 412
#define ERR_NOTOPLEVEL 413
#define ERR_WILDTOPLEVEL 414
#define ERR_UNKNOWNCOMMAND 421
#define ERR_NOMOTD 422
#define ERR_NOADMININFO 423
#define ERR_FILEERROR 424
#define ERR_NONICKNAMEGIVEN 431
#define ERR_ERRONEUSNICKNAME 432
#define ERR_NICKNAMEINUSE 433
#define ERR_SERVICENAMEINUSE 434
#define ERR_SERVICECONFUSED 435
#define ERR_NICKCOLLISION 436
#define ERR_BANNICKCHANGE 437
#define ERR_NICKTOOFAST 438
#define ERR_USERNOTINCHANNEL 441
#define ERR_NOTONCHANNEL 442
#define ERR_USERONCHANNEL 443
#define ERR_NOLOGIN 444
#define ERR_SUMMONDISABLED 445
#define ERR_USERSDISABLED 446
#define ERR_NOTREGISTERED 451
#define ERR_NEEDMOREPARAMS 461
#define ERR_ALREADYREGISTRED 462
#define ERR_NOPERMFORHOST 463
#define ERR_PASSWDMISMATCH 464
#define ERR_YOUREBANNEDCREEP 465
#define ERR_YOUWILLBEBANNED 466
#define ERR_KEYSET 467
#define ERR_CHANNELISFULL 471
#define ERR_UNKNOWNMODE 472
#define ERR_INVITEONLYCHAN 473
#define ERR_BANNEDFROMCHAN 474
#define ERR_BADCHANNELKEY 475
#define ERR_BADCHANMASK 476
#define ERR_BANLISTFULL 478
#define ERR_NOPRIVILEGES 481
#define ERR_CHANOPRIVSNEEDED 482
#define ERR_CANTKILLSERVER 483
#define ERR_ISCHANSERVICE 484
#define ERR_NOOPERHOST 491
#define ERR_NOSERVICEHOST 492
#define ERR_UMODEUNKNOWNFLAG 501
#define ERR_USERSDONTMATCH 502
#define ERR_SILELISTFULL 511
#define ERR_NOSUCHGLINE 512
#define ERR_BADPING 513
/*
* Numberic replies from server commands.
* These are currently in the range 200-399.
*/
#define RPL_NONE 300
#define RPL_AWAY 301
#define RPL_USERHOST 302
#define RPL_ISON 303
#define RPL_TEXT 304
#define RPL_UNAWAY 305
#define RPL_NOWAWAY 306
#define RPL_WHOISUSER 311
#define RPL_WHOISSERVER 312
#define RPL_WHOISOPERATOR 313
#define RPL_WHOWASUSER 314
/* rpl_endofwho below (315) */
#define RPL_ENDOFWHOWAS 369
#define RPL_WHOISCHANOP 316 /* redundant and not needed but reserved */
#define RPL_WHOISIDLE 317
#define RPL_ENDOFWHOIS 318
#define RPL_WHOISCHANNELS 319
#define RPL_LISTSTART 321
#define RPL_LIST 322
#define RPL_LISTEND 323
#define RPL_CHANNELMODEIS 324
#define RPL_CREATIONTIME 329
#define RPL_NOTOPIC 331
#define RPL_TOPIC 332
#define RPL_TOPICWHOTIME 333
#define RPL_LISTUSAGE 334
#define RPL_INVITING 341
#define RPL_SUMMONING 342
#define RPL_VERSION 351
#define RPL_WHOREPLY 352
#define RPL_ENDOFWHO 315
#define RPL_NAMREPLY 353
#define RPL_ENDOFNAMES 366
#define RPL_KILLDONE 361
#define RPL_CLOSING 362
#define RPL_CLOSEEND 363
#define RPL_LINKS 364
#define RPL_ENDOFLINKS 365
/* rpl_endofnames above (366) */
#define RPL_BANLIST 367
#define RPL_ENDOFBANLIST 368
/* rpl_endofwhowas above (369) */
#define RPL_INFO 371
#define RPL_MOTD 372
#define RPL_INFOSTART 373
#define RPL_ENDOFINFO 374
#define RPL_MOTDSTART 375
#define RPL_ENDOFMOTD 376
#define RPL_YOUREOPER 381
#define RPL_REHASHING 382
#define RPL_YOURESERVICE 383
#define RPL_MYPORTIS 384
#define RPL_NOTOPERANYMORE 385
#define RPL_TIME 391
#define RPL_USERSSTART 392
#define RPL_USERS 393
#define RPL_ENDOFUSERS 394
#define RPL_NOUSERS 395
#define RPL_TRACELINK 200
#define RPL_TRACECONNECTING 201
#define RPL_TRACEHANDSHAKE 202
#define RPL_TRACEUNKNOWN 203
#define RPL_TRACEOPERATOR 204
#define RPL_TRACEUSER 205
#define RPL_TRACESERVER 206
#define RPL_TRACESERVICE 207
#define RPL_TRACENEWTYPE 208
#define RPL_TRACECLASS 209
#define RPL_STATSLINKINFO 211
#define RPL_STATSCOMMANDS 212
#define RPL_STATSCLINE 213
#define RPL_STATSNLINE 214
#define RPL_STATSILINE 215
#define RPL_STATSKLINE 216
#define RPL_STATSQLINE 217
#define RPL_STATSYLINE 218
#define RPL_ENDOFSTATS 219
#define RPL_UMODEIS 221
#define RPL_SERVICEINFO 231
#define RPL_ENDOFSERVICES 232
#define RPL_SERVICE 233
#define RPL_SERVLIST 234
#define RPL_SERVLISTEND 235
#define RPL_STATSLLINE 241
#define RPL_STATSUPTIME 242
#define RPL_STATSOLINE 243
#define RPL_STATSHLINE 244
#define RPL_STATSSLINE 245
#define RPL_STATSTLINE 246
#define RPL_STATSGLINE 247
#define RPL_STATSULINE 248
#define RPL_STATSDEBUG 249
#define RPL_STATSCONN 250
#define RPL_LUSERCLIENT 251
#define RPL_LUSEROP 252
#define RPL_LUSERUNKNOWN 253
#define RPL_LUSERCHANNELS 254
#define RPL_LUSERME 255
#define RPL_ADMINME 256
#define RPL_ADMINLOC1 257
#define RPL_ADMINLOC2 258
#define RPL_ADMINEMAIL 259
#define RPL_TRACELOG 261
#define RPL_TRACEPING 262
#define RPL_SILELIST 271
#define RPL_ENDOFSILELIST 272
#define RPL_STATSDLINE 275
#define RPL_GLIST 280
#define RPL_ENDOFGLIST 281

141
include/patchlevel.h Normal file
View File

@@ -0,0 +1,141 @@
/************************************************************************
* IRC - Internet Relay Chat, include/patchlevel.h
*
* 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 1, 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.
*/
/*
* PATCHes
*
* Only put here ADDED special stuff, for instance: ".mu3" or ".ban"
* Please start the patchlevel with a '.'
*
* IMPORTANT: Since u2.9 there is a new format of this file. The reason
* is that this way it shouldn't be needed anymore for the user to edit
* this manually !!!
* If you do, be sure you know what you are doing!
*
* For patch devellopers:
* To make a diff of your patch, edit any of the below lines containing
* a "" (an EMPTY string). Your patch will then succeed, with only an
* offset, on the first empty place in the users patchlevel.h.
* Do not change anyother line, the '\' are to make sure that the 'fuzz'
* will stay 0. --Run
*
*/
#define PATCH1 \
\
\
\
".32"
/*
Deliberate empty lines
*/
#define PATCH2 \
\
\
\
""
/*
Deliberate empty lines
*/
#define PATCH3 \
\
\
\
""
/*
Deliberate empty lines
*/
#define PATCH4 \
\
\
\
""
/*
Deliberate empty lines
*/
#define PATCH5 \
\
\
\
""
/*
Deliberate empty lines
*/
#define PATCH6 \
\
\
\
""
/*
Deliberate empty lines
*/
#define PATCH7 \
\
\
\
""
/*
Deliberate empty lines
*/
#define PATCH8 \
\
\
\
""
/*
Deliberate empty lines
*/
#ifdef TESTNET
#define PATCH9 \
\
\
\
".testnet"
#else
#define PATCH9 ""
#endif
/*
Deliberate empty lines
*/
/* Do NOT edit those: */
#ifndef BASE_VERSION
#define BASE_VERSION "u2.9"
#endif
#ifndef MAJOR_PROTOCOL
#define MAJOR_PROTOCOL "09"
#endif

63
include/res.h Normal file
View File

@@ -0,0 +1,63 @@
/*
* irc2.7.2/ircd/res.h (C)opyright 1992 Darren Reed.
*/
#ifndef __res_include__
#define __res_include__
#define RES_INITLIST 1
#define RES_CALLINIT 2
#define RES_INITSOCK 4
#define RES_INITDEBG 8
#define RES_INITCACH 16
#define MAXPACKET 1024
#define MAXALIASES 35
#define MAXADDRS 35
#define AR_TTL 600 /* TTL in seconds for dns cache entries */
struct hent {
char *h_name; /* official name of host */
char *h_aliases[MAXALIASES]; /* alias list */
int h_addrtype; /* host address type */
int h_length; /* length of address */
/* list of addresses from name server */
struct in_addr h_addr_list[MAXADDRS];
#define h_addr h_addr_list[0] /* address, for backward compatiblity */
};
typedef struct reslist {
int id;
int sent; /* number of requests sent */
int srch;
time_t ttl;
char type;
char retries; /* retry counter */
char sends; /* number of sends (>1 means resent) */
char resend; /* send flag. 0 == dont resend */
time_t sentat;
time_t timeout;
struct in_addr addr;
char *name;
struct reslist *next;
Link cinfo;
struct hent he;
} ResRQ;
typedef struct cache {
time_t expireat;
time_t ttl;
struct hostent he;
struct cache *hname_next, *hnum_next, *list_next;
} aCache;
typedef struct cachetable {
aCache *num_list;
aCache *name_list;
} CacheTable;
#define ARES_CACSIZE 101
#define MAXCACHED 81
#endif /* __res_include__ */

78
include/resolv.h Normal file
View File

@@ -0,0 +1,78 @@
/*
* Copyright (c) 1983, 1987, 1989 The Regents of the University of California.
* All rights reserved.
*
* Redistribution and use in source and binary forms are permitted
* provided that: (1) source distributions retain this entire copyright
* notice and comment, and (2) distributions including binaries display
* the following acknowledgement: ``This product includes software
* developed by the University of California, Berkeley and its contributors''
* in the documentation or other materials provided with the distribution
* and in all advertising materials mentioning features or use of this
* software. Neither the name of the University nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
* @(#)resolv.h 5.10.1 (Berkeley) 6/1/90
*/
/*
* Resolver configuration file.
* Normally not present, but may contain the address of the
* inital name server(s) to query and the domain search list.
*/
#ifndef _PATH_RESCONF
#define _PATH_RESCONF "/etc/resolv.conf"
#endif
/*
* Global defines and variables for resolver stub.
*/
#define MAXNS 3 /* max # name servers we'll track */
#define MAXDFLSRCH 3 /* # default domain levels to try */
#define MAXDNSRCH 6 /* max # domains in search path */
#define LOCALDOMAINPARTS 2 /* min levels in name that is "local" */
#define MAXSERVICES 2 /* max # of services to search */
#define RES_TIMEOUT 5 /* min. seconds between retries */
struct state {
int retrans; /* retransmition time interval */
int retry; /* number of times to retransmit */
long options; /* option flags - see below. */
int nscount; /* number of name servers */
struct sockaddr_in nsaddr_list[MAXNS]; /* address of name server */
#define nsaddr nsaddr_list[0] /* for backward compatibility */
unsigned short id; /* current packet id */
char defdname[MAXDNAME]; /* default domain */
char *dnsrch[MAXDNSRCH+1]; /* components of domain to search */
unsigned short order[MAXSERVICES+1]; /* search service order */
};
#define RES_SERVICE_NONE 0
#define RES_SERVICE_BIND 1
#define RES_SERVICE_LOCAL 2
/*
* Resolver options
*/
#define RES_INIT 0x0001 /* address initialized */
#define RES_DEBUG 0x0002 /* print debug messages */
#define RES_AAONLY 0x0004 /* authoritative answers only */
#define RES_USEVC 0x0008 /* use virtual circuit */
#define RES_PRIMARY 0x0010 /* query primary server only */
#define RES_IGNTC 0x0020 /* ignore trucation errors */
#define RES_RECURSE 0x0040 /* recursion desired */
#define RES_DEFNAMES 0x0080 /* use default domain name */
#define RES_STAYOPEN 0x0100 /* Keep TCP socket open */
#define RES_DNSRCH 0x0200 /* search up local domain tree */
#define RES_DEFAULT (RES_RECURSE | RES_DEFNAMES | RES_DNSRCH)
extern struct state _res;
extern char *p_cdname(), *p_rr(), *p_type(), *p_class(), *p_time();

41
include/sock.h Normal file
View File

@@ -0,0 +1,41 @@
/************************************************************************
* IRC - Internet Relay Chat, include/sock.h
* Copyright (C) 1990 Jarkko Oikarinen and
* University of Oulu, Computing Center
*
* 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 1, 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.
*/
/*
* $Id: sock.h,v 1.1.1.1 1996/05/05 22:25:20 klmitch Exp $
*
* $Log: sock.h,v $
* Revision 1.1.1.1 1996/05/05 22:25:20 klmitch
* initial entry
*
* Revision 6.1 1991/07/04 21:04:35 gruner
* Revision 2.6.1 [released]
*
* Revision 6.0 1991/07/04 18:05:04 gruner
* frozen beta revision 2.6.1
*
*/
#ifndef FD_ZERO
#define FD_ZERO(set) (((set)->fds_bits[0]) = 0)
#define FD_SET(s1, set) (((set)->fds_bits[0]) |= 1 << (s1))
#define FD_ISSET(s1, set) (((set)->fds_bits[0]) & (1 << (s1)))
#define FD_SETSIZE 30
#endif

622
include/struct.h Normal file
View File

@@ -0,0 +1,622 @@
/************************************************************************
* IRC - Internet Relay Chat, include/struct.h
* Copyright (C) 1990 Jarkko Oikarinen and
* University of Oulu, Computing Center
*
* 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 1, 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.
*/
#ifndef __struct_include__
#define __struct_include__
#include "config.h"
#include "common.h"
#include "sys.h"
#include <stdio.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <netdb.h>
#ifdef STDDEFH
# include <stddef.h>
#endif
#ifdef USE_SYSLOG
# include <syslog.h>
# ifdef SYSSYSLOGH
# include <sys/syslog.h>
# endif
#endif
#ifdef pyr
#include <sys/time.h>
#endif
typedef struct ConfItem aConfItem;
typedef struct Gline aGline;
typedef struct Client aClient;
typedef struct Channel aChannel;
typedef struct User anUser;
typedef struct Server aServer;
typedef struct SLink Link;
typedef struct SMode Mode;
typedef struct DSlink Dlink;
#ifndef VMSP
#include "class.h"
#include "dbuf.h" /* THIS REALLY SHOULDN'T BE HERE!!! --msa */
#endif
#define HOSTLEN 63 /* Length of hostname. Updated to */
/* comply with RFC1123 */
#define NICKLEN 9 /* Necessary to put 9 here instead of 10
** if s_msg.c/m_nick has been corrected.
** This preserves compatibility with old
** servers --msa
*/
#define USERLEN 10
#define REALLEN 50
#define TOPICLEN 160
#define CHANNELLEN 200
#define PASSWDLEN 20
#define KEYLEN 23
#define BUFSIZE 512 /* WARNING: *DONT* CHANGE THIS!!!! */
#define MAXRECIPIENTS 20
#define MAXBANS 30
#define MAXBANLENGTH 1024
#define MAXSILELENGTH 128
#define USERHOST_REPLYLEN (NICKLEN+HOSTLEN+USERLEN+5)
#ifdef USE_SERVICES
#include "service.h"
#endif
/*
** 'offsetof' is defined in ANSI-C. The following definition
** is not absolutely portable (I have been told), but so far
** it has worked on all machines I have needed it. The type
** should be size_t but... --msa
*/
#ifndef offsetof
#define offsetof(t,m) (int)((&((t *)0L)->m))
#endif
#define elementsof(x) (sizeof(x)/sizeof(x[0]))
/*
** flags for bootup options (command line flags)
*/
#define BOOT_CONSOLE 1
#define BOOT_QUICK 2
#define BOOT_DEBUG 4
#define BOOT_INETD 8
#define BOOT_TTY 16
#define BOOT_OPER 32
#define BOOT_AUTODIE 64
#define STAT_PING -7
#define STAT_LOG -6 /* logfile for -x */
#define STAT_MASTER -5 /* Local ircd master before identification */
#define STAT_CONNECTING -4
#define STAT_HANDSHAKE -3
#define STAT_ME -2
#define STAT_UNKNOWN -1
#define STAT_SERVER 0
#define STAT_CLIENT 1
#define STAT_SERVICE 2 /* Services not implemented yet */
/*
* status macros.
*/
#define IsRegisteredUser(x) ((x)->status == STAT_CLIENT)
#define IsRegistered(x) ((x)->status >= STAT_SERVER)
#define IsConnecting(x) ((x)->status == STAT_CONNECTING)
#define IsHandshake(x) ((x)->status == STAT_HANDSHAKE)
#define IsMe(x) ((x)->status == STAT_ME)
#define IsUnknown(x) ((x)->status == STAT_UNKNOWN || \
(x)->status == STAT_MASTER)
#define IsServer(x) ((x)->status == STAT_SERVER)
#define IsClient(x) ((x)->status == STAT_CLIENT)
#define IsLog(x) ((x)->status == STAT_LOG)
#define IsService(x) ((x)->status == STAT_SERVICE)
#define IsPing(x) ((x)->status == STAT_PING)
#define SetMaster(x) ((x)->status = STAT_MASTER)
#define SetConnecting(x) ((x)->status = STAT_CONNECTING)
#define SetHandshake(x) ((x)->status = STAT_HANDSHAKE)
#define SetMe(x) ((x)->status = STAT_ME)
#define SetUnknown(x) ((x)->status = STAT_UNKNOWN)
#define SetServer(x) ((x)->status = STAT_SERVER)
#define SetClient(x) ((x)->status = STAT_CLIENT)
#define SetLog(x) ((x)->status = STAT_LOG)
#define SetService(x) ((x)->status = STAT_SERVICE)
#define SetPing(x) ((x)->status = STAT_PING)
#define FLAGS_PINGSENT 0x0001 /* Unreplied ping sent */
#define FLAGS_DEADSOCKET 0x0002 /* Local socket is dead--Exiting soon */
#define FLAGS_KILLED 0x0004 /* Prevents "QUIT" from being sent for this */
#define FLAGS_OPER 0x0008 /* Operator */
#define FLAGS_LOCOP 0x0010 /* Local operator -- SRB */
#define FLAGS_INVISIBLE 0x0020 /* makes user invisible */
#define FLAGS_WALLOP 0x0040 /* send wallops to them */
#define FLAGS_SERVNOTICE 0x0080 /* server notices such as kill */
#define FLAGS_BLOCKED 0x0100 /* socket is in a blocked condition */
#define FLAGS_UNIX 0x0200 /* socket is in the unix domain, not inet */
#define FLAGS_CLOSING 0x0400 /* set when closing to suppress errors */
#define FLAGS_LISTEN 0x0800 /* used to mark clients which we listen() on */
#define FLAGS_CHKACCESS 0x1000 /* ok to check clients access if set */
#define FLAGS_DOINGDNS 0x2000 /* client is waiting for a DNS response */
#define FLAGS_AUTH 0x4000 /* client is waiting on rfc931 response */
#define FLAGS_WRAUTH 0x8000 /* set if we havent writen to ident server */
#define FLAGS_LOCAL 0x10000 /* set for local clients */
#define FLAGS_GOTID 0x20000 /* successful ident lookup achieved */
#define FLAGS_DOID 0x40000 /* I-lines say must use ident return */
#define FLAGS_NONL 0x80000 /* No \n in buffer */
#define FLAGS_TS8 0x100000 /* Why do you want to know? */
#define FLAGS_PING 0x200000 /* Socket is waiting for udp ping response */
#define FLAGS_ASKEDPING 0x400000 /* Client asked for udp ping */
#define FLAGS_MAP 0x800000 /* Show server on the map */
#define FLAGS_JUNCTION 0x1000000 /* Junction causing the net.burst */
#define FLAGS_DEAF 0x2000000 /* Makes user deaf */
#define FLAGS_NOKICK 0x4000000 /* prevents the possibility of KICK or MODE
-o on the user; can only be set by server
connections, not by local users */
#define SEND_UMODES (FLAGS_INVISIBLE|FLAGS_OPER|FLAGS_WALLOP|FLAGS_DEAF|FLAGS_NOKICK)
#define ALL_UMODES (SEND_UMODES|FLAGS_SERVNOTICE|FLAGS_LOCOP)
/* FLAGS_LOCOP was originally left out; this was a bug */
#define FLAGS_ID (FLAGS_DOID|FLAGS_GOTID)
/*
* flags macros.
*/
#define IsOper(x) ((x)->flags & FLAGS_OPER)
#define IsLocOp(x) ((x)->flags & FLAGS_LOCOP)
#define IsInvisible(x) ((x)->flags & FLAGS_INVISIBLE)
#define IsDeaf(x) ((x)->flags & FLAGS_DEAF)
#define IsAnOper(x) ((x)->flags & (FLAGS_OPER|FLAGS_LOCOP))
#define IsPerson(x) ((x)->user && IsClient(x))
#define IsPrivileged(x) (IsAnOper(x) || IsServer(x))
#define SendWallops(x) ((x)->flags & FLAGS_WALLOP)
#define SendServNotice(x) ((x)->flags & FLAGS_SERVNOTICE)
#define IsUnixSocket(x) ((x)->flags & FLAGS_UNIX)
#define IsListening(x) ((x)->flags & FLAGS_LISTEN)
#define DoAccess(x) ((x)->flags & FLAGS_CHKACCESS)
#define IsLocal(x) ((x)->flags & FLAGS_LOCAL)
#define IsDead(x) ((x)->flags & FLAGS_DEADSOCKET)
#define IsJunction(x) ((x)->flags & FLAGS_JUNCTION)
#define SetOper(x) ((x)->flags |= FLAGS_OPER)
#define SetLocOp(x) ((x)->flags |= FLAGS_LOCOP)
#define SetInvisible(x) ((x)->flags |= FLAGS_INVISIBLE)
#define SetWallops(x) ((x)->flags |= FLAGS_WALLOP)
#define SetUnixSock(x) ((x)->flags |= FLAGS_UNIX)
#define SetDNS(x) ((x)->flags |= FLAGS_DOINGDNS)
#define DoingDNS(x) ((x)->flags & FLAGS_DOINGDNS)
#define SetAccess(x) ((x)->flags |= FLAGS_CHKACCESS)
#define DoingAuth(x) ((x)->flags & FLAGS_AUTH)
#define NoNewLine(x) ((x)->flags & FLAGS_NONL)
#define DoPing(x) ((x)->flags & FLAGS_PING)
#define SetAskedPing(x) ((x)->flags |= FLAGS_ASKEDPING)
#define AskedPing(x) ((x)->flags & FLAGS_ASKEDPING)
#define SetJunction(x) ((x)->flags |= FLAGS_JUNCTION)
#define ClearOper(x) ((x)->flags &= ~FLAGS_OPER)
#define ClearInvisible(x) ((x)->flags &= ~FLAGS_INVISIBLE)
#define ClearWallops(x) ((x)->flags &= ~FLAGS_WALLOP)
#define ClearDNS(x) ((x)->flags &= ~FLAGS_DOINGDNS)
#define ClearAuth(x) ((x)->flags &= ~FLAGS_AUTH)
#define ClearAccess(x) ((x)->flags &= ~FLAGS_CHKACCESS)
#define ClearPing(x) ((x)->flags &= ~FLAGS_PING)
#define ClearAskedPing(x) ((x)->flags &= ~FLAGS_ASKEDPING)
/*
* defined debugging levels
*/
#define DEBUG_FATAL 0
#define DEBUG_ERROR 1 /* report_error() and other errors that are found */
#define DEBUG_NOTICE 3
#define DEBUG_DNS 4 /* used by all DNS related routines - a *lot* */
#define DEBUG_INFO 5 /* general usful info */
#define DEBUG_NUM 6 /* numerics */
#define DEBUG_SEND 7 /* everything that is sent out */
#define DEBUG_DEBUG 8 /* anything to do with debugging, ie unimportant :) */
#define DEBUG_MALLOC 9 /* malloc/free calls */
#define DEBUG_LIST 10 /* debug list use */
/*
* defines for curses in client
*/
#define DUMMY_TERM 0
#define CURSES_TERM 1
#define TERMCAP_TERM 2
struct ConfItem {
unsigned int status; /* If CONF_ILLEGAL, delete when no clients */
int clients; /* Number of *LOCAL* clients using this */
struct in_addr ipnum; /* ip number of host field */
char *host;
char *passwd;
char *name;
int port;
time_t hold; /* Hold action until this time (calendar time) */
#ifndef VMSP
aClass *class; /* Class of connection */
#endif
struct ConfItem *next;
};
#define CONF_ILLEGAL 0x80000000
#define CONF_MATCH 0x40000000
#define CONF_QUARANTINED_SERVER 0x0001
#define CONF_CLIENT 0x0002
#define CONF_CONNECT_SERVER 0x0004
#define CONF_NOCONNECT_SERVER 0x0008
#define CONF_LOCOP 0x0010
#define CONF_OPERATOR 0x0020
#define CONF_ME 0x0040
#define CONF_KILL 0x0080
#define CONF_ADMIN 0x0100
#ifdef R_LINES
#define CONF_RESTRICT 0x0200
#endif
#define CONF_CLASS 0x0400
#define CONF_SERVICE 0x0800
#define CONF_LEAF 0x1000
#define CONF_LISTEN_PORT 0x2000
#define CONF_HUB 0x4000
#define CONF_UWORLD 0x8000
#define CONF_CRULEALL 0x00200000
#define CONF_CRULEAUTO 0x00400000
#define CONF_TLINES 0x00800000
#define CONF_OPS (CONF_OPERATOR | CONF_LOCOP)
#define CONF_SERVER_MASK (CONF_CONNECT_SERVER | CONF_NOCONNECT_SERVER)
#define CONF_CLIENT_MASK (CONF_CLIENT | CONF_SERVICE | CONF_OPS | \
CONF_SERVER_MASK)
#define CONF_CRULE (CONF_CRULEALL | CONF_CRULEAUTO)
#define IsIllegal(x) ((x)->status & CONF_ILLEGAL)
struct Gline {
struct Gline *next;
char *host;
char *reason;
char *name;
time_t expire;
int active;
};
#define GLINE_ACTIVE 1
#define GLINE_INACTIVE 0
/*
* Client structures
*/
struct User {
struct User *nextu;
aClient *server; /* client structure of server */
Dlink *clink; /* own Dlink in server->serv->client struct */
Link *channel; /* chain of channel pointer blocks */
Link *invited; /* chain of invite pointer blocks */
Link *silence; /* chain of silence pointer blocks */
char *away; /* pointer to away message */
time_t last;
int refcnt; /* Number of times this block is referenced */
int joined; /* number of channels joined */
char username[USERLEN+1];
char host[HOSTLEN+1];
#ifdef LIST_DEBUG
aClient *bcptr;
#endif
};
struct Server {
struct Server *nexts;
aClient *up; /* Server one closer to me */
Dlink *down; /* List with downlink servers */
Dlink *updown; /* own Dlink in up->serv->down struct */
Dlink *client; /* List with clients for this server */
anUser *user; /* who activated this connection */
char by[NICKLEN+1];
aConfItem *nline; /* N-line pointer for this server */
time_t timestamp; /* Remotely determined connect try time */
time_t ghost; /* Local time at which a new server caused a Ghost */
u_short prot; /* Major protocol */
#ifdef LIST_DEBUG
aClient *bcptr;
#endif
};
struct Client {
struct Client *next,*prev, *hnext;
anUser *user; /* ...defined, if this is a User */
aServer *serv; /* ...defined, if this is a server */
#ifdef USE_SERVICES
aService *service;
#endif
int hashv; /* raw hash value */
time_t lasttime; /* ...should be only LOCAL clients? --msa */
time_t firsttime; /* time client was created */
time_t since; /* last time we parsed something */
time_t lastnick; /* TimeStamp on nick */
long flags; /* client flags */
aClient *from; /* == self, if Local Client, *NEVER* NULL! */
int fd; /* >= 0, for local clients */
int hopcount; /* number of servers to this 0 = local */
short status; /* Client type */
char name[HOSTLEN+1]; /* Unique name of the client, nick or host */
char username[USERLEN+1]; /* username here now for auth stuff */
char info[REALLEN+1]; /* Free form additional client information */
/*
** The following fields are allocated only for local clients
** (directly connected to *this* server with a socket.
** The first of them *MUST* be the "count"--it is the field
** to which the allocation is tied to! *Never* refer to
** these fields, if (from != self).
*/
int count; /* Amount of data in buffer */
char buffer[BUFSIZE]; /* Incoming message buffer */
short lastsq; /* # of 2k blocks when sendqueued called last*/
#ifdef NICK_DELAY
time_t nextnick; /* Next time that a nick change is allowed */
#endif
u_long cookie; /* Random number the user must PONG */
dbuf sendQ; /* Outgoing message queue--if socket full */
dbuf recvQ; /* Hold for data incoming yet to be parsed */
long sendM; /* Statistics: protocol messages send */
long sendK; /* Statistics: total k-bytes send */
long receiveM; /* Statistics: protocol messages received */
long receiveK; /* Statistics: total k-bytes received */
u_short sendB; /* counters to count upto 1-k lots of bytes */
u_short receiveB; /* sent and received. */
aClient *acpt; /* listening client which we accepted from */
Link *confs; /* Configuration record associated */
int authfd; /* fd for rfc931 authentication */
struct in_addr ip; /* keep real ip# too */
unsigned short port; /* and the remote port# too :-) */
struct hostent *hostp;
aChannel *listing;
#ifdef pyr
struct timeval lw;
#endif
char sockhost[HOSTLEN+1]; /* This is the host name from the socket
** and after which the connection was
** accepted.
*/
char passwd[PASSWDLEN+1];
};
#define CLIENT_LOCAL_SIZE sizeof(aClient)
#define CLIENT_REMOTE_SIZE offsetof(aClient,count)
/*
* statistics structures
*/
struct stats {
unsigned int is_cl; /* number of client connections */
unsigned int is_sv; /* number of server connections */
unsigned int is_ni; /* connection but no idea who it was */
unsigned short is_cbs; /* bytes sent to clients */
unsigned short is_cbr; /* bytes received to clients */
unsigned short is_sbs; /* bytes sent to servers */
unsigned short is_sbr; /* bytes received to servers */
unsigned long is_cks; /* k-bytes sent to clients */
unsigned long is_ckr; /* k-bytes received to clients */
unsigned long is_sks; /* k-bytes sent to servers */
unsigned long is_skr; /* k-bytes received to servers */
time_t is_cti; /* time spent connected by clients */
time_t is_sti; /* time spent connected by servers */
unsigned int is_ac; /* connections accepted */
unsigned int is_ref; /* accepts refused */
unsigned int is_unco; /* unknown commands */
unsigned int is_wrdi; /* command going in wrong direction */
unsigned int is_unpf; /* unknown prefix */
unsigned int is_empt; /* empty message */
unsigned int is_num; /* numeric message */
unsigned int is_kill; /* number of kills generated on collisions */
unsigned int is_fake; /* MODE 'fakes' */
unsigned int is_asuc; /* successful auth requests */
unsigned int is_abad; /* bad auth requests */
unsigned int is_udp; /* packets recv'd on udp port */
unsigned int is_loc; /* local connections made */
};
/* mode structure for channels */
struct SMode {
unsigned int mode;
int limit;
char key[KEYLEN+1];
};
/* Message table structure */
struct Message {
char *cmd;
int (* func)();
unsigned int count;
int parameters;
char flags;
/* bit 0 set means that this command is allowed to be used
* only on the average of once per 2 seconds -SRB */
unsigned long bytes;
};
/* general link structure used for chains */
struct SLink {
struct SLink *next;
union {
aClient *cptr;
aChannel *chptr;
aConfItem *aconf;
char *cp;
struct {
char *banstr;
char *who;
time_t when;
} ban;
} value;
int flags;
};
struct DSlink {
struct DSlink *next;
struct DSlink *prev;
union {
aClient *cptr;
aChannel *chptr;
aConfItem *aconf;
char *cp;
} value;
};
/* channel structure */
struct Channel {
struct Channel *nextch, *prevch, *hnextch;
int hashv; /* raw hash value */
Mode mode;
time_t creationtime;
char topic[TOPICLEN+1];
char topic_nick[NICKLEN+1];
time_t topic_time;
int users;
Link *members;
Link *invites;
Link *banlist;
char chname[1];
};
/*
** Channel Related macros follow
*/
/* Channel related flags */
#define CHFL_CHANOP 0x0001 /* Channel operator */
#define CHFL_VOICE 0x0002 /* the power to speak */
#define CHFL_DEOPPED 0x0004 /* Is de-opped by a server */
#define CHFL_SERVOPOK 0x0008 /* Server op allowed */
#define CHFL_ZOMBIE 0x0010 /* Kicked from channel */
#define CHFL_BAN 0x0020 /* ban channel flag */
#define CHFL_OVERLAP (CHFL_CHANOP|CHFL_VOICE)
/* Channel Visibility macros */
#define MODE_CHANOP CHFL_CHANOP
#define MODE_VOICE CHFL_VOICE
#define MODE_PRIVATE 0x0004
#define MODE_SECRET 0x0008
#define MODE_MODERATED 0x0010
#define MODE_TOPICLIMIT 0x0020
#define MODE_INVITEONLY 0x0040
#define MODE_NOPRIVMSGS 0x0080
#define MODE_KEY 0x0100
#define MODE_BAN 0x0200
#define MODE_LIMIT 0x0400
#define MODE_LISTED 0x10000
/*
* mode flags which take another parameter (With PARAmeterS)
*/
#define MODE_WPARAS (MODE_CHANOP|MODE_VOICE|MODE_BAN|MODE_KEY|MODE_LIMIT)
/*
* Undefined here, these are used in conjunction with the above modes in
* the source.
#define MODE_DEL 0x20000000
#define MODE_ADD 0x40000000
*/
#define HoldChannel(x) (!(x))
/* name invisible */
#define SecretChannel(x) ((x) && ((x)->mode.mode & MODE_SECRET))
/* channel not shown but names are */
#define HiddenChannel(x) ((x) && ((x)->mode.mode & MODE_PRIVATE))
/* channel visible */
#define ShowChannel(v,c) (PubChannel(c) || IsMember((v),(c)))
#define PubChannel(x) ((!x) || ((x)->mode.mode &\
(MODE_PRIVATE | MODE_SECRET)) == 0)
#define is_listed(x) ((x)->mode.mode & MODE_LISTED)
#define IsChannelName(name) ((name) && (*(name) == '#' || *(name) == '&'))
/* Misc macros */
#define BadPtr(x) (!(x) || (*(x) == '\0'))
#define isvalid(c) (((c) >= 'A' && (c) <= '~') || isdigit(c) || (c) == '-')
#define MyConnect(x) ((x)->fd >= 0)
#define MyClient(x) (MyConnect(x) && IsClient(x))
#define MyOper(x) (MyConnect(x) && IsOper(x))
#define Protocol(x) ((x)->serv->prot)
#define TStime() (now+TSoffset)
/* String manipulation macros */
/* strncopynt --> strncpyzt to avoid confusion, sematics changed
N must be now the number of bytes in the array --msa */
#define strncpyzt(x, y, N) do{(void)strncpy(x,y,N);x[N-1]='\0';}while(0)
#define StrEq(x,y) (!strcmp((x),(y)))
/* used in SetMode() in channel.c and m_umode() in s_msg.c */
#define MODE_NULL 0
#define MODE_ADD 0x40000000
#define MODE_DEL 0x20000000
/* return values for hunt_server() */
#define HUNTED_NOSUCH (-1) /* if the hunted server is not found */
#define HUNTED_ISME 0 /* if this server should execute the command */
#define HUNTED_PASS 1 /* if message passed onwards successfully */
/* used when sending to #mask or $mask */
#define MATCH_SERVER 1
#define MATCH_HOST 2
/* used for async dns values */
#define ASYNC_NONE (-1)
#define ASYNC_CLIENT 0
#define ASYNC_CONNECT 1
#define ASYNC_CONF 2
#define ASYNC_PING 3
/* This is not used, and as soon as it is, I have to check if
make_server has been called before... --Run
#define ASYNC_SERVER 4
*/
/* misc variable externs */
extern char *version, *infotext[];
extern char *generation, *creation;
extern time_t TSoffset;
/* misc defines */
#define CPTR_KILLED -2
#define UTMP "/etc/utmp"
#define COMMA ","
#define UDP_PORT "7007"
#define MINOR_PROTOCOL "04"
#define MAJOR_PROTOCOL "09"
#define BASE_VERSION "u2.9"
#endif /* __struct_include__ */

114
include/sys.h Normal file
View File

@@ -0,0 +1,114 @@
/************************************************************************
* IRC - Internet Relay Chat, include/sys.h
* Copyright (C) 1990 University of Oulu, Computing Center
*
* 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 1, 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.
*/
#ifndef __sys_include__
#define __sys_include__
#ifdef ISC202
#include <net/errno.h>
#else
#include <sys/errno.h>
#endif
#include "setup.h"
#include <stdio.h>
#include <sys/types.h>
#include <sys/param.h>
#ifdef UNISTDH
#include <unistd.h>
#endif
#ifdef STDLIBH
#include <stdlib.h>
#endif
#ifdef STRINGSH
#include <strings.h>
#else
# ifdef STRINGH
# include <string.h>
# endif
#endif
#define strcasecmp mycmp
#define strncasecmp myncmp
#ifdef NOINDEX
#define index strchr
#define rindex strrchr
/*
extern char *index PROTO((char *, char));
extern char *rindex PROTO((char *, char));
*/
#endif
#ifdef AIX
#include <sys/select.h>
#endif
#if defined(HPUX )|| defined(AIX)
#include <time.h>
#ifdef AIX
#include <sys/time.h>
#endif
#else
#include <sys/time.h>
#endif
#if !defined(DEBUGMODE)
#define MyFree(x) if ((x) != NULL) free(x)
#else
#define free(x) MyFree(x)
#endif
#ifdef NEXT
#define VOIDSIG int /* whether signal() returns int of void */
#else
#define VOIDSIG void /* whether signal() returns int of void */
#endif
#ifdef SOL20
#define OPT_TYPE char /* opt type for get/setsockopt */
#else
#define OPT_TYPE void
#endif
/* Different name on NetBSD and FreeBSD --Skip */
#if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__bsdi__)
#define dn_skipname __dn_skipname
#endif
extern VOIDSIG dummy();
#ifdef DYNIXPTX
#define NO_U_TYPES
typedef unsigned short n_short; /* short as received from the net */
typedef unsigned long n_long; /* long as received from the net */
typedef unsigned long n_time; /* ms since 00:00 GMT, byte rev */
#define _NETINET_IN_SYSTM_INCLUDED
#endif
#ifdef NO_U_TYPES
typedef unsigned char u_char;
typedef unsigned short u_short;
typedef unsigned long u_long;
typedef unsigned int u_int;
#endif
#ifdef USE_VARARGS
#include <varargs.h>
#endif
#endif /* __sys_include__ */

49
include/userload.h Normal file
View File

@@ -0,0 +1,49 @@
/****************************************************************************
* Userload module by Michael L. VanLoon (mlv) <michaelv@iastate.edu>
* Written 2/93. Originally grafted into irc2.7.2g 4/93.
*
* IRC - Internet Relay Chat, ircd/userload.h
* Copyright (C) 1990 University of Oulu, Computing Center
*
* 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 1, 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.
****************************************************************************/
/* This needs to be defined for the counts to be correct--it should be the
* default anyway, as opers shouldn't be superior to lusers except where
* absolutely necessary, and here it isn't necessary. */
#ifndef SHOW_INVISIBLE_LUSERS
#define SHOW_INVISIBLE_LUSERS
#endif
struct current_load_struct {
u_short client_count, local_count, conn_count;
u_long entries;
};
extern struct current_load_struct current_load_data;
struct load_entry {
struct load_entry *prev;
u_short client_count, local_count, conn_count;
long time_incr;
};
extern struct load_entry *load_list_head, *load_list_tail,
*load_free_head, *load_free_tail;
extern void initload PROTO ((void));
extern void update_load PROTO ((void));
extern void calc_load PROTO ((aClient *, char *));

93
include/whowas.h Normal file
View File

@@ -0,0 +1,93 @@
/************************************************************************
* IRC - Internet Relay Chat, include/whowas.h
* Copyright (C) 1990 Markku Savela
*
* 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 1, 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.
*/
/*
* $Id: whowas.h,v 1.1.1.1 1996/05/05 22:25:20 klmitch Exp $
*
* $Log: whowas.h,v $
* Revision 1.1.1.1 1996/05/05 22:25:20 klmitch
* initial entry
*
* Revision 6.1 1991/07/04 21:04:39 gruner
* Revision 2.6.1 [released]
*
* Revision 6.0 1991/07/04 18:05:08 gruner
* frozen beta revision 2.6.1
*
*/
#ifndef __whowas_include__
#define __whowas_include__
#ifndef PROTO
#if __STDC__
# define PROTO(x) x
#else
# define PROTO(x) ()
#endif /* __STDC__ */
#endif /* ! PROTO */
/*
** WHOWAS structure moved here from whowas.c
*/
typedef struct aname {
anUser *ww_user;
aClient *ww_online;
time_t ww_logout;
char ww_nick[NICKLEN+1];
char ww_info[REALLEN+1];
char *ww_server;
} aName;
/*
** add_history
** Add the currently defined name of the client to history.
** usually called before changing to a new name (nick).
** Client must be a fully registered user (specifically,
** the user structure must have been allocated).
*/
void add_history PROTO((aClient *));
/*
** off_history
** This must be called when the client structure is about to
** be released. History mechanism keeps pointers to client
** structures and it must know when they cease to exist. This
** also implicitly calls AddHistory.
*/
void off_history PROTO((aClient *));
/*
** get_history
** Return the current client that was using the given
** nickname within the timelimit. Returns NULL, if no
** one found...
*/
aClient *get_history PROTO((char *, time_t));
/* Nick name */
/* Time limit in seconds */
int m_whowas PROTO((aClient *, aClient *, int, char *[]));
/*
** for debugging...counts related structures stored in whowas array.
*/
void count_whowas_memory PROTO((int *, int *, u_long *));
#endif /* __whowas_include__ */

291
ircd/Makefile Normal file
View File

@@ -0,0 +1,291 @@
#************************************************************************
#* IRC - Internet Relay Chat, ircd/Makefile
#* Copyright (C) 1990 Jarkko Oikarinen
#*
#* 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 1, 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.
#*/
CC=cc
RM=/bin/rm
CP=/bin/cp
TOUCH=touch
SHELL=/bin/sh
INSTALL=/usr/bin/install
# IRCDMODE given in top level Makefile, but added here to make sure
# compilation works if started in ircd subdirectory
IRCDMODE=711
INCLUDEDIR=../include
# CFLAGS/IRCDLIBS used in ../Makefile should also be used here. The list
# given below is less than complete.
# For MIPS, use the following:
#CFLAGS= -g -systype bsd43 -DSYSTYPE_BSD43 -I${INCLUDEDIR}
# For Irix 4.x (SGI), use the following:
#CFLAGS= -g -cckr -I$(INCLUDEDIR)
# else just this
CFLAGS= -g -I${INCLUDEDIR}
#
# use the following on SUN OS without nameserver libraries inside libc
# NOTE: most dont have the resolver libraries inside libc
#IRCDLIBS=-lresolv
#
#on NeXT other than 2.0:
#IRCDLIBS=-lsys_s
#
# HPUX:
#IRCDLIBS=-lBSD
#
# Solaris 2
#IRCDLIBS=-lsocket -lnsl
#
# ESIX
#CFLAGS=-O -I${INCLUDEDIR} -I/usr/ucbinclude
#IRCDLIBS=-L/usr/ucblib -L/usr/lib -lsocket -lucb -lns -lnsl
#
#When profiling:
#IRCDLIBS=-lc_p
LINTFLAGS=-hba
#
# LDFLAGS - flags to send the loader (ld). SunOS users may want to add
# -Bstatic here.
#
#LDFLAGS=-Bstatic
#LDFLAGS=-Wl,-a,archive
#
# RES - if you are missing the resolv library (man 5 resolv.conf), or you
# experience probems with ip# to hostname lookups for local machines or
# the server wont compile because _res is missing, uncomment RES.
# For those who know what these are, if you normally use the resolv+
# libraries and have setup /etc/resolv.conf, these are fromm resolv+ if they
# are not part of your system libraries. In all cases you should try your
# system libraries before these.
#
#RES=res_init.o res_comp.o res_mkquery.o
COMMONOBJS=../common/bsd.o ../common/dbuf.o ../common/packet.o \
../common/send.o ../common/match.o ../common/parse.o \
../common/support.o
OBJS=channel.o class.o hash.o ircd.o list.o res.o s_auth.o s_bsd.o s_conf.o \
s_debug.o s_err.o s_misc.o s_numeric.o s_serv.o s_user.o whowas.o \
note.o userload.o crule.o s_ping.o map.o random.o $(RES) $(COMMONOBJS)
SRC=$(OBJS:%.o=%.c)
COMMONSRC=$(COMMONOBJS:%.o=%.c)
MAKE = make 'CFLAGS=${CFLAGS}' 'CC=${CC}' 'IRCDLIBS=${IRCDLIBS}' \
'LDFLAGS=${LDFLAGS}' 'IRCDMODE=${IRCDMODE}'
all: build
build: ircd chkconf
ircd: $(OBJS) ../include/patchlevel.h
$(SHELL) version.c.SH
$(CC) $(CFLAGS) -c version.c
$(CC) $(CFLAGS) $(OBJS) version.o $(LDFLAGS) $(IRCDLIBS) -o ircd
chmod $(IRCDMODE) ircd
chkconf: ../include/struct.h ../include/config.h ../include/sys.h \
../include/common.h crule.c chkconf.c
$(CC) $(CFLAGS) -DCR_CHKCONF -o chkcrule.o -c crule.c
$(CC) $(CFLAGS) chkconf.c ../common/match.o chkcrule.o \
$(LDFLAGS) $(IRCDLIBS) -o chkconf
saber: $(SRC)
#load -I../include $(SRC) $(COMMONSRC) version.c $(IRCDLIBS)
lint:
lint $(LINTFLAGS) -I../include $(SRC) | egrep -v 'sendto_|debug'
../common/parse.o: ../common/parse.c ../include/msg.h ../include/config.h\
../include/struct.h ../include/sys.h ../include/numeric.h
(cd ../common; $(MAKE) build);
../common/bsd.o: ../common/bsd.c ../include/config.h ../include/common.h\
../include/struct.h ../include/sys.h
(cd ../common; $(MAKE) build);
../common/dbuf.o: ../common/dbuf.c ../include/config.h ../include/common.h\
../include/struct.h ../include/dbuf.h
(cd ../common; $(MAKE) build);
../common/packet.o: ../common/packet.c ../include/config.h ../include/common.h\
../include/struct.h ../include/msg.h
(cd ../common; $(MAKE) build);
../common/send.o: ../common/send.c ../include/config.h ../include/common.h\
../include/struct.h ../include/sys.h
(cd ../common; $(MAKE) build);
../common/match.o: ../common/match.c ../include/config.h ../include/common.h\
../include/sys.h
(cd ../common; $(MAKE) build);
../common/support.o: ../common/support.c ../include/config.h ../include/sys.h\
../include/common.h
(cd ../common; $(MAKE) build);
install: all
-if [ ! -d ${IRCDDIR} -a ! -f ${IRCDDIR} ] ; then \
mkdir ${IRCDDIR}; \
fi
../bsdinstall -c -s -m ${IRCDMODE} ircd ${BINDIR}
../bsdinstall -c -s -m 700 chkconf ${BINDIR}
$(CP) ../doc/example.conf ${IRCDDIR}
$(TOUCH) ${IRCDDIR}/ircd.motd
$(RM) -f ${IRCDDIR}/ircd.m4
$(TOUCH) ${IRCDDIR}/ircd.m4
chmod +x buildm4
./buildm4 ${IRCDDIR}
clean:
$(RM) -f *.o *~ core ircd version.c \#* *.bak chkconf *.orig
depend:
makedepend -I${INCLUDEDIR} ${SRC}
channel.o: ../include/struct.h ../include/config.h ../include/dbuf.h \
../include/numeric.h ../include/channel.h ../include/sys.h \
../include/common.h
$(CC) $(CFLAGS) -c channel.c
class.o: ../include/struct.h ../include/class.h ../include/numeric.h \
../include/common.h ../include/config.h ../include/sys.h
$(CC) $(CFLAGS) -c class.c
ircd.o: ircd.c ../include/struct.h ../include/config.h ../include/sys.h \
../include/dbuf.h ../include/numeric.h ../include/common.h
$(CC) $(CFLAGS) -c ircd.c
list.o: list.c ../include/struct.h ../include/config.h ../include/dbuf.h \
../include/sys.h ../include/common.h
$(CC) $(CFLAGS) -c list.c
res.o: res.c ../include/struct.h ../include/config.h ../include/res.h \
../include/sys.h ../include/common.h
$(CC) $(CFLAGS) -c res.c
s_bsd.o: s_bsd.c ../include/struct.h ../include/config.h ../include/dbuf.h \
../include/sys.h ../include/common.h
$(CC) $(CFLAGS) -c s_bsd.c
s_auth.o: s_auth.c ../include/struct.h ../include/config.h ../include/dbuf.h \
../include/sys.h ../include/common.h
$(CC) $(CFLAGS) -c s_auth.c
s_conf.o: s_conf.c ../include/struct.h ../include/config.h ../include/sys.h \
../include/common.h ../include/numeric.h ../include/dbuf.h
$(CC) $(CFLAGS) -c s_conf.c
s_debug.o: ../include/config.h ../include/struct.h ../include/common.h \
../include/sys.h s_debug.c
$(CC) $(CFLAGS) -c s_debug.c
s_err.o: ../include/config.h ../include/struct.h ../include/common.h \
../include/sys.h ../include/numeric.h ../include/msg.h s_err.c
$(CC) $(CFLAGS) -c s_err.c
s_misc.o: s_misc.c ../include/struct.h ../include/config.h ../include/dbuf.h \
../include/common.h ../include/sys.h ../include/numeric.h
$(CC) $(CFLAGS) -c s_misc.c
s_user.o: s_user.c ../include/struct.h ../include/config.h ../include/sys.h \
../include/common.h ../include/dbuf.h ../include/channel.h \
../include/msg.h ../include/numeric.h ../include/whowas.h
$(CC) $(CFLAGS) -c s_user.c
s_serv.o: s_serv.c ../include/struct.h ../include/config.h ../include/sys.h \
../include/common.h ../include/dbuf.h ../include/channel.h \
../include/msg.h ../include/numeric.h ../include/whowas.h
$(CC) $(CFLAGS) -c s_serv.c
s_numeric.o: s_numeric.c ../include/config.h ../include/sys.h \
../include/common.h ../include/struct.h ../include/dbuf.h \
../include/numeric.h
$(CC) $(CFLAGS) -c s_numeric.c
whowas.o: ../include/struct.h ../include/config.h ../include/sys.h \
../include/common.h ../include/dbuf.h ../include/numeric.h \
../include/whowas.h whowas.c
$(CC) $(CFLAGS) -c whowas.c
hash.o: ../include/struct.h ../include/sys.h ../include/hash.h hash.c \
../include/common.h ../include/config.h s_bsd.c s_serv.c s_user.c \
channel.c s_misc.c
@crypt/sums
$(CC) $(CFLAGS) -c hash.c
@/bin/rm -f hash.c
@/bin/mv -f hash.c.old hash.c
@touch hash.o
note.o: ../include/struct.h ../include/sys.h ../include/common.h \
../include/config.h note.c
$(CC) $(CFLAGS) -c note.c
crule.o: ../include/struct.h ../include/sys.h ../include/common.h \
../include/config.h crule.c
$(CC) $(CFLAGS) -c crule.c
s_ping.o: ../include/struct.h ../include/sys.h ../include/common.h \
../include/config.h s_ping.c
$(CC) $(CFLAGS) -c s_ping.c
random.o: ../include/struct.h ../include/sys.h random.c
$(CC) $(CFLAGS) -c random.c
map.o: ../include/struct.h ../include/sys.h map.c
$(CC) $(CFLAGS) -c map.c
# DO NOT DELETE THIS LINE -- make depend depends on it.
channel.o: ../include/struct.h ../include/config.h ../include/dbuf.h
channel.o: ../include/numeric.h ../include/channel.h channel.c
s_misc.o: ../include/struct.h ../include/config.h ../include/dbuf.h s_misc.c
ircd.o: ../include/struct.h ../include/config.h
ircd.o: ../include/dbuf.h ../include/numeric.h ircd.c
list.o: ../include/struct.h ../include/config.h ../include/dbuf.h
list.o: ../include/sys.h list.c
note.o: ../include/config.h note.c
res.o: ../include/struct.h ../include/config.h ../include/res.h res.c
s_bsd.o: ../include/struct.h ../include/config.h ../include/dbuf.h
s_bsd.o: ../include/sys.h s_bsd.c
s_auth.o: ../include/struct.h ../include/config.h ../include/dbuf.h
s_auth.o: ../include/sys.h s_auth.c
s_debug.o: ../include/config.h ../include/struct.h ../include/common.h
s_debug.o: ../include/sys.h s_debug.c
s_debug.o: ../include/struct.h ../include/common.h ../include/sys.h
s_err.o: ../include/struct.h ../include/config.h ../include/numeric.h
s_err.o: ../include/dbuf.h ../include/sys.h s_err.c
s_conf.o: ../include/struct.h ../include/config.h ../include/numeric.h
s_conf.o: ../include/dbuf.h ../include/sys.h s_conf.c
s_user.o: ../include/struct.h ../include/config.h
s_user.o: ../include/dbuf.h ../include/sys.h ../include/channel.h
s_user.o: ../include/msg.h ../include/numeric.h ../include/whowas.h s_user.c
s_serv.o: ../include/struct.h ../include/config.h
s_serv.o: ../include/dbuf.h ../include/sys.h ../include/channel.h
userload.o: ../include/common.h ../include/config.h ../include/userload.h
s_serv.o: ../include/msg.h ../include/numeric.h ../include/whowas.h s_serv.c
s_numeric.o: ../include/config.h ../include/sys.h ../include/struct.h
s_numeric.o: ../include/dbuf.h ../include/numeric.h s_numeric.c
whowas.o: ../include/struct.h ../include/config.h ../include/dbuf.h
whowas.o: ../include/numeric.h ../include/whowas.h ../include/sys.h whowas.c
class.o: ../include/struct.h ../include/class.h ../include/numeric.h
class.o: ../include/common.h ../include/config.h class.c
hash.o: ../include/config.h ../include/sys.h ../include/hash.h
hash.o: ../include/struct.h ../include/common.h s_serv.c s_user.c
hash.o: channel.c s_misc.c s_bsd.c ircd.c hash.c version.c.SH
version.o: version.c.SH version.c
crule.o: ../include/config.h ../include/sys.h ../include/struct.h
crule.o: ../include/common.h

84
ircd/buildm4 Executable file
View File

@@ -0,0 +1,84 @@
#!/bin/sh
# IRC - Internet Relay Chat, ircd/buildm4
# Copyright (C) 1993 Darren Reed
#
# 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 1, 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.
#
# If only this was a perl script...*sigh*
#
IRCDDIR=$1
M4=$IRCDDIR/ircd.m4
/bin/rm -f $M4
egrep "^#def[^P]*PATCHLEVEL" ../include/patchlevel.h | \
sed -e 's/[^\"]*\"\([^\"]*\)\"/define(VERSION,\1)/' >>$M4
DEBUG=`egrep "^#define[ ]*DEBUGMODE" ../include/config.h`
if [ -n "$DEBUG" ] ; then
echo "define(DEBUGMODE,1)" >>$M4
else
echo "undefine(DEBUGMODE)" >>$M4
fi
echo -n "define(HOSTNAME," >> $M4
echo "`hostname`" | sed -e 's/\([a-zA-Z0-9\-]*\).*/\1)/' >> $M4
echo "define(USER,$USER)" >>$M4
echo -n 'define(PORT,' >>$M4
PORT=`egrep '^#define[ ]*PORT[ ]*[0-9]*' ../include/config.h`
echo "$PORT" | sed -e 's/[^0-9]*\([0-9]*\).*/\1)/' >> $M4
echo -n 'define(PFREQ,' >>$M4
PING=`egrep '^#define[ ]*PINGFREQUENCY[ ]*[0-9]*' ../include/config.h`
echo "$PING" | sed -e 's/[^0-9]*\([0-9]*\).*/\1)/' >> $M4
echo -n 'define(CFREQ,' >>$M4
CONT=`egrep '^#define[ ]*CONNECTFREQUENCY[ ]*[0-9]*' ../include/config.h`
echo "$CONT" | sed -e 's/[^0-9]*\([0-9]*\).*/\1)/' >> $M4
echo -n "define(MAXSENDQ," >>$M4
MAXQ=`egrep '^#define[ ]*MAXSENDQLENGTH[ ]*[0-9]*' ../include/config.h`
echo "$MAXQ" | sed -e 's/[^0-9]*\([0-9]*\).*/\1)/' >> $M4
echo -n "define(MAXLINKS," >>$M4
MAXL=`egrep '^#define[ ]*MAXIMUM_LINKS[ ]*[0-9]* | head -1' \
../include/config.h`
echo "$MAXL" | sed -e 's/[^0-9]*\([0-9]*\).*/\1)/' >> $M4
DOM=`egrep '^domain' /etc/resolv.conf | \
sed -e 's/^domain[ ]*\([a-zA-Z\-\.0-9]*\).*/\1/'`
echo "define(DOMAIN,$DOM)" >> $M4
cat >>$M4 <<_EOF_
define(CL,\`ifelse(len(\$1),0,0,\$1)')
define(HOST,\$1)
define(HOSTM,\$1)
define(ID,*@\$1)
define(PASS,\$1)
define(PING,\`ifelse(len(\$1),0,PFREQ,\$1)')
define(APORT,\`ifelse(len(\$1),0,PORT,\$1)')
define(FREQ,\`ifelse(len(\$1),0,CFREQ,\$1)')
define(SENDQ,\`ifelse(len(\$1),0,MAXSENDQ,\$1)')
define(MAX,\`ifelse(len(\$1),0,MAXLINKS,\$1)')
define(CPORT,\$1)
define(SERV,\$1)
define(ADMIN,A:\$1:\$2:\$3:\$4:\$5)
define(ALLOW,N:\`HOST(\$1)':\`PASS(\$2)':\`SERV(\$3)':\`HOSTM(\$4)':\`CL(\$5)')
define(BAN,K:\$1:\$2:\$3)
define(CLASS,Y:\$1:\`PING(\$2)':\$3:\`MAX(\$4)':\`SENDQ(\$5)')
define(CLIENT,I:\`HOST(\$1)':\`PASS(\$2)':\`ifelse(len(HOST(\$3)),0,\$1,\$3)':\
\`APORT(\$4)':\`CL(\$5)')
define(CONNECT,C:\`HOST(\$1)':\`PASS(\$2)':\`SERV(\$3)':\
\`CPORT(\$4)':\`CL(\$5)')
define(ME,M:\$1:\$2:\$3:\$4:\$5)
define(HUB,H:\`ifelse(len(\$2),0,*,\$2)':*:\$1)
define(LEAF,L:\`ifelse(len(\$2),0,*,\$2)':*:\$1:1)
define(SERVER,\`
CONNECT(\$1,\$2,\$3,\$5,\$6)
ALLOW(\$1,\$2,\$3,\$4,\$6)
')
_EOF_

2676
ircd/channel.c Normal file

File diff suppressed because it is too large Load Diff

755
ircd/chkconf.c Normal file
View File

@@ -0,0 +1,755 @@
/************************************************************************
* IRC - Internet Relay Chat, ircd/chkconf.c
* Copyright (C) 1993 Darren Reed
*
* 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 1, 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.
*/
#ifndef lint
static char sccsid[] = "@(#)chkconf.c 1.9 1/30/94 (C) 1993 Darren Reed";
#endif
#include "struct.h"
#include "common.h"
#include "sys.h"
#include "numeric.h"
#include <sys/socket.h>
#include <sys/stat.h>
#include <fcntl.h>
#ifdef __hpux
#include "inet.h"
#endif
#ifdef PCS
#include <time.h>
#endif
#ifdef R_LINES
#include <signal.h>
#endif
#ifdef DYNIXPTX
#include <sys/types.h>
#include <time.h>
#endif
/* for the connect rule patch.. these really should be in a header,
** but i see h.h isn't included for some reason.. so they're here */
char *crule_parse PROTO((char *rule));
void crule_free PROTO((char **elem));
#undef free
#define MyMalloc(x) malloc(x)
static void new_class();
static char *getfield(), confchar ();
static int openconf(), validate();
static aClass *get_class();
static aConfItem *initconf();
static int numclasses = 0, *classarr = (int *)NULL, debugflag = 0;
static char *configfile = CONFIGFILE;
static char nullfield[] = "";
static char maxsendq[12];
main(argc, argv)
int argc;
char *argv[];
{
new_class(0);
if (chdir(DPATH))
{
perror("chdir");
exit(-1);
}
if (argc > 1 && !strncmp(argv[1], "-d", 2))
{
debugflag = 1;
if (argv[1][2])
debugflag = atoi(argv[1]+2);
argc--, argv++;
}
if (argc > 1)
configfile = argv[1];
return validate(initconf());
}
/*
* openconf
*
* returns -1 on any error or else the fd opened from which to read the
* configuration file from. This may either be th4 file direct or one end
* of a pipe from m4.
*/
static int openconf()
{
#ifdef M4_PREPROC
int pi[2];
if (pipe(pi) == -1)
return -1;
switch(fork())
{
case -1 :
return -1;
case 0 :
(void)close(pi[0]);
if (pi[1] != 1)
{
(void)dup2(pi[1], 1);
(void)close(pi[1]);
}
(void)dup2(1,2);
/*
* m4 maybe anywhere, use execvp to find it. Any error
* goes out with report_error. Could be dangerous,
* two servers running with the same fd's >:-) -avalon
*/
(void)execlp("m4", "m4", "ircd.m4", configfile, 0);
perror("m4");
exit(-1);
default :
(void)close(pi[1]);
return pi[0];
}
#else
return open(configfile, O_RDONLY);
#endif
}
/*
** initconf()
** Read configuration file.
**
** returns -1, if file cannot be opened
** 0, if file opened
*/
static aConfItem *initconf(opt)
int opt;
{
int fd;
char line[512], *tmp, c[80], *s, *crule;
int ccount = 0, ncount = 0, dh, flags = 0;
aConfItem *aconf = NULL, *ctop = NULL;
(void)fprintf(stderr, "initconf(): ircd.conf = %s\n", configfile);
if ((fd = openconf()) == -1)
{
#ifdef M4_PREPROC
(void)wait(0);
#endif
return NULL;
}
(void)dgets(-1, NULL, 0); /* make sure buffer is at empty pos */
while ((dh = dgets(fd, line, sizeof(line) - 1)) > 0)
{
if (aconf)
{
if (aconf->host)
(void)free(aconf->host);
if (aconf->passwd)
(void)free(aconf->passwd);
if (aconf->name)
(void)free(aconf->name);
}
else
aconf = (aConfItem *)malloc(sizeof(*aconf));
aconf->host = (char *)NULL;
aconf->passwd = (char *)NULL;
aconf->name = (char *)NULL;
aconf->class = (aClass *)NULL;
if (tmp = (char *)index(line, '\n'))
*tmp = 0;
else while(dgets(fd, c, sizeof(c) - 1))
if (tmp = (char *)index(c, '\n'))
{
*tmp = 0;
break;
}
/*
* Do quoting of characters and # detection.
*/
for (tmp = line; *tmp; tmp++)
{
if (*tmp == '\\')
{
switch (*(tmp+1))
{
case 'n' :
*tmp = '\n';
break;
case 'r' :
*tmp = '\r';
break;
case 't' :
*tmp = '\t';
break;
case '0' :
*tmp = '\0';
break;
default :
*tmp = *(tmp+1);
break;
}
if (!*(tmp+1))
break;
else
for (s = tmp; *s = *++s; )
;
tmp++;
}
else if (*tmp == '#')
*tmp = '\0';
}
if (!*line || *line == '#' || *line == '\n' ||
*line == ' ' || *line == '\t')
continue;
if (line[1] != ':')
{
(void)fprintf(stderr, "ERROR: Bad config line (%s)\n",
line);
continue;
}
if (debugflag)
(void)printf("\n%s\n",line);
(void)fflush(stdout);
tmp = getfield(line);
if (!tmp)
{
(void)fprintf(stderr, "\tERROR: no fields found\n");
continue;
}
aconf->status = CONF_ILLEGAL;
switch (*tmp)
{
case 'A': /* Name, e-mail address of administrator */
case 'a': /* of this server. */
aconf->status = CONF_ADMIN;
break;
case 'C': /* Server where I should try to connect */
case 'c': /* in case of lp failures */
ccount++;
aconf->status = CONF_CONNECT_SERVER;
break;
/* Connect rule */
case 'D':
aconf->status = CONF_CRULEALL;
break;
/* Connect rule - autos only */
case 'd':
aconf->status = CONF_CRULEAUTO;
break;
case 'H': /* Hub server line */
case 'h':
aconf->status = CONF_HUB;
break;
case 'I': /* Just plain normal irc client trying */
case 'i': /* to connect me */
aconf->status = CONF_CLIENT;
break;
case 'K': /* Kill user line on irc.conf */
case 'k':
aconf->status = CONF_KILL;
break;
/* Operator. Line should contain at least */
/* password and host where connection is */
case 'L': /* guaranteed leaf server */
case 'l':
aconf->status = CONF_LEAF;
break;
/* Me. Host field is name used for this host */
/* and port number is the number of the port */
case 'M':
case 'm':
aconf->status = CONF_ME;
break;
case 'N': /* Server where I should NOT try to */
case 'n': /* connect in case of lp failures */
/* but which tries to connect ME */
++ncount;
aconf->status = CONF_NOCONNECT_SERVER;
break;
case 'O':
aconf->status = CONF_OPERATOR;
break;
/* Local Operator, (limited privs --SRB) */
case 'o':
aconf->status = CONF_LOCOP;
break;
case 'P': /* listen port line */
case 'p':
aconf->status = CONF_LISTEN_PORT;
break;
case 'Q': /* a server that you don't want in your */
case 'q': /* network. USE WITH CAUTION! */
aconf->status = CONF_QUARANTINED_SERVER;
break;
#ifdef R_LINES
case 'R': /* extended K line */
case 'r': /* Offers more options of how to restrict */
aconf->status = CONF_RESTRICT;
break;
#endif
case 'S': /* Service. Same semantics as */
case 's': /* CONF_OPERATOR */
aconf->status = CONF_SERVICE;
break;
case 'T':
case 't':
aconf->status = CONF_TLINES;
break;
case 'U':
case 'u':
aconf->status = CONF_UWORLD;
break;
case 'Y':
case 'y':
aconf->status = CONF_CLASS;
break;
default:
(void)fprintf(stderr,
"\tERROR: unknown conf line letter (%c)\n",
*tmp);
break;
}
if (IsIllegal(aconf))
continue;
for (;;) /* Fake loop, that I can use break here --msa */
{
if ((tmp = getfield(NULL)) == NULL)
break;
DupString(aconf->host, tmp);
if ((tmp = getfield(NULL)) == NULL)
break;
DupString(aconf->passwd, tmp);
if ((tmp = getfield(NULL)) == NULL)
break;
DupString(aconf->name, tmp);
if ((tmp = getfield(NULL)) == NULL)
break;
aconf->port = atoi(tmp);
if ((tmp = getfield(NULL)) == NULL)
break;
if (!(aconf->status & CONF_CLASS))
aconf->class = get_class(atoi(tmp));
break;
}
if (!aconf->class && (aconf->status & (CONF_CONNECT_SERVER|
CONF_NOCONNECT_SERVER|CONF_OPS|CONF_CLIENT)))
{
(void)fprintf(stderr,
"\tWARNING: No class. Default 0\n");
aconf->class = get_class(0);
}
/*
** If conf line is a class definition, create a class entry
** for it and make the conf_line illegal and delete it.
*/
if (aconf->status & CONF_CLASS)
{
int class = 0;
if (!aconf->host)
{
(void)fprintf(stderr,"\tERROR: no class #\n");
continue;
}
if (!tmp)
{
(void)fprintf(stderr,
"\tWARNING: missing sendq field\n");
(void)fprintf(stderr, "\t\t default: %d\n",
MAXSENDQLENGTH);
(void)sprintf(maxsendq, "%d", MAXSENDQLENGTH);
}
else
(void)sprintf(maxsendq, "%d", atoi(tmp));
new_class(atoi(aconf->host));
aconf->class = get_class(atoi(aconf->host));
goto print_confline;
}
if (aconf->status & CONF_LISTEN_PORT)
{
#ifdef UNIXPORT
struct stat sb;
if (!aconf->host)
(void)fprintf(stderr, "\tERROR: %s\n",
"null host field in P-line");
else if (index(aconf->host, '/'))
{
if (stat(aconf->host, &sb) == -1)
{
(void)fprintf(stderr, "\tERROR: (%s) ",
aconf->host);
perror("stat");
}
else if ((sb.st_mode & S_IFMT) != S_IFDIR)
(void)fprintf(stderr,
"\tERROR: %s not directory\n",
aconf->host);
}
#else
if (!aconf->host)
(void)fprintf(stderr, "\tERROR: %s\n",
"null host field in P-line");
else if (index(aconf->host, '/'))
(void)fprintf(stderr, "\t%s %s\n",
"WARNING: / present in P-line",
"for non-UNIXPORT configuration");
#endif
aconf->class = get_class(0);
goto print_confline;
}
if (aconf->status & CONF_SERVER_MASK &&
(!aconf->host || index(aconf->host, '*') ||
index(aconf->host, '?')))
{
(void)fprintf(stderr, "\tERROR: bad host field\n");
continue;
}
if (aconf->status & CONF_SERVER_MASK && BadPtr(aconf->passwd))
{
(void)fprintf(stderr,
"\tERROR: empty/no password field\n");
continue;
}
if (aconf->status & CONF_SERVER_MASK && !aconf->name)
{
(void)fprintf(stderr, "\tERROR: bad name field\n");
continue;
}
if (aconf->status & (CONF_SERVER_MASK|CONF_OPS))
if (!index(aconf->host, '@'))
{
char *newhost;
int len = 3; /* *@\0 = 3 */
len += strlen(aconf->host);
newhost = (char *)MyMalloc(len);
(void)sprintf(newhost, "*@%s", aconf->host);
(void)free(aconf->host);
aconf->host = newhost;
}
/* parse the connect rules to detect errors, but free
** any allocated storage immediately -- we're just looking
** for errors.. */
if (aconf->status & CONF_CRULE)
if ((crule =
(char *) crule_parse (aconf->name)) != NULL)
crule_free (&crule);
if (!aconf->class)
aconf->class = get_class(0);
(void)sprintf(maxsendq, "%d", aconf->class->class);
if (!aconf->name)
aconf->name = nullfield;
if (!aconf->passwd)
aconf->passwd = nullfield;
if (!aconf->host)
aconf->host = nullfield;
if (aconf->status & (CONF_ME|CONF_ADMIN))
{
if (flags & aconf->status)
(void)fprintf(stderr,
"ERROR: multiple %c-lines\n",
toupper(confchar(aconf->status)));
else
flags |= aconf->status;
}
print_confline:
if (debugflag > 8)
(void)printf("(%d) (%s) (%s) (%s) (%d) (%s)\n",
aconf->status, aconf->host, aconf->passwd,
aconf->name, aconf->port, maxsendq);
(void)fflush(stdout);
if (aconf->status & (CONF_SERVER_MASK|CONF_HUB|CONF_LEAF))
{
aconf->next = ctop;
ctop = aconf;
aconf = NULL;
}
}
(void)close(fd);
#ifdef M4_PREPROC
(void)wait(0);
#endif
return ctop;
}
static aClass *get_class(cn)
int cn;
{
static aClass cls;
int i = numclasses - 1;
cls.class = -1;
for (; i >= 0; i--)
if (classarr[i] == cn)
{
cls.class = cn;
break;
}
if (i == -1)
(void)fprintf(stderr,"\tWARNING: class %d not found\n", cn);
return &cls;
}
static void new_class(cn)
int cn;
{
numclasses++;
if (classarr)
classarr = (int *)realloc(classarr, sizeof(int) * numclasses);
else
classarr = (int *)malloc(sizeof(int));
classarr[numclasses-1] = cn;
}
/*
* field breakup for ircd.conf file.
*/
static char *getfield(newline)
char *newline;
{
static char *line = NULL;
char *end, *field;
if (newline)
line = newline;
if (line == NULL)
return(NULL);
field = line;
if ((end = (char *)index(line,':')) == NULL)
{
line = NULL;
if ((end = (char *)index(field,'\n')) == NULL)
end = field + strlen(field);
}
else
line = end + 1;
*end = '\0';
return(field);
}
/*
** read a string terminated by \r or \n in from a fd
**
** Created: Sat Dec 12 06:29:58 EST 1992 by avalon
** Returns:
** 0 - EOF
** -1 - error on read
** >0 - number of bytes returned (<=num)
** After opening a fd, it is necessary to init dgets() by calling it as
** dgets(x,y,0);
** to mark the buffer as being empty.
*/
int dgets(fd, buf, num)
int fd, num;
char *buf;
{
static char dgbuf[8192];
static char *head = dgbuf, *tail = dgbuf;
register char *s, *t;
register int n, nr;
/*
** Sanity checks.
*/
if (head == tail)
*head = '\0';
if (!num)
{
head = tail = dgbuf;
*head = '\0';
return 0;
}
if (num > sizeof(dgbuf) - 1)
num = sizeof(dgbuf) - 1;
dgetsagain:
if (head > dgbuf)
{
for (nr = tail - head, s = head, t = dgbuf; nr > 0; nr--)
*t++ = *s++;
tail = t;
head = dgbuf;
}
/*
** check input buffer for EOL and if present return string.
*/
if (head < tail &&
((s = index(head, '\n')) || (s = index(head, '\r'))) && s < tail)
{
n = MIN(s - head + 1, num); /* at least 1 byte */
dgetsreturnbuf:
bcopy(head, buf, n);
head += n;
if (head == tail)
head = tail = dgbuf;
return n;
}
if (tail - head >= num) /* dgets buf is big enough */
{
n = num;
goto dgetsreturnbuf;
}
n = sizeof(dgbuf) - (tail - dgbuf) - 1;
nr = read(fd, tail, n);
if (nr == -1)
{
head = tail = dgbuf;
return -1;
}
if (!nr)
{
if (head < tail)
{
n = MIN(head - tail, num);
goto dgetsreturnbuf;
}
head = tail = dgbuf;
return 0;
}
tail += nr;
*tail = '\0';
for (t = head; (s = index(t, '\n')); )
{
if ((s > head) && (s > dgbuf))
{
t = s-1;
for (nr = 0; *t == '\\'; nr++)
t--;
if (nr & 1)
{
t = s+1;
s--;
nr = tail - t;
while (nr--)
*s++ = *t++;
tail -= 2;
*tail = '\0';
}
else
s++;
}
else
s++;
t = s;
}
*tail = '\0';
goto dgetsagain;
}
static int validate(top)
aConfItem *top;
{
Reg1 aConfItem *aconf, *bconf;
u_int otype, valid = 0;
if (!top)
return 0;
for (aconf = top; aconf; aconf = aconf->next)
{
if (aconf->status & CONF_MATCH)
continue;
if (aconf->status & CONF_SERVER_MASK)
{
if (aconf->status & CONF_CONNECT_SERVER)
otype = CONF_NOCONNECT_SERVER;
else if (aconf->status & CONF_NOCONNECT_SERVER)
otype = CONF_CONNECT_SERVER;
for (bconf = top; bconf; bconf = bconf->next)
{
if (bconf == aconf || !(bconf->status & otype))
continue;
if (bconf->class == aconf->class &&
!mycmp(bconf->name, aconf->name) &&
!mycmp(bconf->host, aconf->host))
{
aconf->status |= CONF_MATCH;
bconf->status |= CONF_MATCH;
break;
}
}
}
else
for (bconf = top; bconf; bconf = bconf->next)
{
if ((bconf == aconf) ||
!(bconf->status & CONF_SERVER_MASK))
continue;
if (!mycmp(bconf->name, aconf->name))
{
aconf->status |= CONF_MATCH;
break;
}
}
}
(void) fprintf(stderr, "\n");
for (aconf = top; aconf; aconf = aconf->next)
if (aconf->status & CONF_MATCH)
valid++;
else
(void)fprintf(stderr, "Unmatched %c:%s:%s:%s\n",
confchar(aconf->status), aconf->host,
aconf->passwd, aconf->name);
return valid ? 0 : -1;
}
static char confchar(status)
u_int status;
{
static char letrs[] = "QICNoOMKARYSLPH";
char *s = letrs;
status &= ~(CONF_MATCH|CONF_ILLEGAL);
for (; *s; s++, status >>= 1)
if (status & 1)
return *s;
return '-';
}
outofmemory()
{
(void)write(2, "Out of memory\n", 14);
exit(-1);
}

236
ircd/class.c Normal file
View File

@@ -0,0 +1,236 @@
/*
* IRC - Internet Relay Chat, ircd/class.c
* Copyright (C) 1990 Darren Reed
*
* 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 1, 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.
*/
#ifndef lint
static char sccsid[] = "@(#)class.c 1.4 6/28/93 (C) 1990 Darren Reed";
#endif
#include "struct.h"
#include "common.h"
#include "numeric.h"
#include "h.h"
#define BAD_CONF_CLASS -1
#define BAD_PING -2
#define BAD_CLIENT_CLASS -3
aClass *classes;
int get_conf_class(aconf)
aConfItem *aconf;
{
if ((aconf) && Class(aconf))
return (ConfClass(aconf));
Debug((DEBUG_DEBUG,"No Class For %s",
(aconf) ? aconf->name : "*No Conf*"));
return (BAD_CONF_CLASS);
}
static int get_conf_ping(aconf)
aConfItem *aconf;
{
if ((aconf) && Class(aconf))
return (ConfPingFreq(aconf));
Debug((DEBUG_DEBUG,"No Ping For %s",
(aconf) ? aconf->name : "*No Conf*"));
return (BAD_PING);
}
int get_client_class(acptr)
aClient *acptr;
{
Reg1 Link *tmp;
Reg2 aClass *cl;
int i = 0, retc = BAD_CLIENT_CLASS;
if (acptr && !IsMe(acptr) && !IsPing(acptr) && (acptr->confs))
for (tmp = acptr->confs; tmp; tmp = tmp->next)
{
if (!tmp->value.aconf ||
!(cl = tmp->value.aconf->class))
continue;
if (Class(cl) > retc)
retc = Class(cl);
}
Debug((DEBUG_DEBUG,"Returning Class %d For %s",retc,acptr->name));
return (retc);
}
int get_client_ping(acptr)
aClient *acptr;
{
int ping = 0, ping2;
aConfItem *aconf;
Link *link;
link = acptr->confs;
if (link)
while (link)
{
aconf = link->value.aconf;
if (aconf->status & (CONF_CLIENT|CONF_CONNECT_SERVER|
CONF_NOCONNECT_SERVER))
{
ping2 = get_conf_ping(aconf);
if ((ping2 != BAD_PING) && ((ping > ping2) ||
!ping))
ping = ping2;
}
link = link->next;
}
else
{
ping = PINGFREQUENCY;
Debug((DEBUG_DEBUG,"No Attached Confs"));
}
if (ping <= 0)
ping = PINGFREQUENCY;
Debug((DEBUG_DEBUG,"Client %s Ping %d", acptr->name, ping));
return (ping);
}
int get_con_freq(clptr)
aClass *clptr;
{
if (clptr)
return (ConFreq(clptr));
else
return (CONNECTFREQUENCY);
}
/*
* When adding a class, check to see if it is already present first.
* if so, then update the information for that class, rather than create
* a new entry for it and later delete the old entry.
* if no present entry is found, then create a new one and add it in
* immeadiately after the first one (class 0).
*/
void add_class(class, ping, confreq, maxli, sendq)
int class, ping, confreq, maxli;
long sendq;
{
aClass *t, *p;
t = find_class(class);
if ((t == classes) && (class != 0))
{
p = (aClass *)make_class();
NextClass(p) = NextClass(t);
NextClass(t) = p;
}
else
p = t;
Debug((DEBUG_DEBUG,
"Add Class %d: p %x t %x - cf: %d pf: %d ml: %d sq: %l",
class, p, t, confreq, ping, maxli, sendq));
Class(p) = class;
ConFreq(p) = confreq;
PingFreq(p) = ping;
MaxLinks(p) = maxli;
MaxSendq(p) = (sendq > 0) ? sendq : MAXSENDQLENGTH;
if (p != t)
Links(p) = 0;
}
aClass *find_class(cclass)
int cclass;
{
aClass *cltmp;
for (cltmp = FirstClass(); cltmp; cltmp = NextClass(cltmp))
if (Class(cltmp) == cclass)
return cltmp;
return classes;
}
void check_class()
{
Reg1 aClass *cltmp, *cltmp2;
Debug((DEBUG_DEBUG, "Class check:"));
for (cltmp2 = cltmp = FirstClass(); cltmp; cltmp = NextClass(cltmp2))
{
Debug((DEBUG_DEBUG,
"Class %d : CF: %d PF: %d ML: %d LI: %d SQ: %ld",
Class(cltmp), ConFreq(cltmp), PingFreq(cltmp),
MaxLinks(cltmp), Links(cltmp), MaxSendq(cltmp)));
if (MaxLinks(cltmp) < 0)
{
NextClass(cltmp2) = NextClass(cltmp);
if (Links(cltmp) <= 0)
free_class(cltmp);
}
else
cltmp2 = cltmp;
}
}
void initclass()
{
classes = (aClass *)make_class();
Class(FirstClass()) = 0;
ConFreq(FirstClass()) = CONNECTFREQUENCY;
PingFreq(FirstClass()) = PINGFREQUENCY;
MaxLinks(FirstClass()) = MAXIMUM_LINKS;
MaxSendq(FirstClass()) = MAXSENDQLENGTH;
Links(FirstClass()) = 0;
NextClass(FirstClass()) = NULL;
}
void report_classes(sptr)
aClient *sptr;
{
Reg1 aClass *cltmp;
for (cltmp = FirstClass(); cltmp; cltmp = NextClass(cltmp))
sendto_one(sptr, rpl_str(RPL_STATSYLINE), me.name, sptr->name,
'Y', Class(cltmp), PingFreq(cltmp), ConFreq(cltmp),
MaxLinks(cltmp), MaxSendq(cltmp));
}
long get_sendq(cptr)
aClient *cptr;
{
Reg1 int sendq = MAXSENDQLENGTH, retc = BAD_CLIENT_CLASS;
Reg2 Link *tmp;
Reg2 aClass *cl;
if (cptr && !IsMe(cptr) && (cptr->confs))
for (tmp = cptr->confs; tmp; tmp = tmp->next)
{
if (!tmp->value.aconf ||
!(cl = tmp->value.aconf->class))
continue;
if (Class(cl) > retc)
sendq = MaxSendq(cl);
}
return sendq;
}

775
ircd/crule.c Normal file
View File

@@ -0,0 +1,775 @@
/*
* SmartRoute phase 1
* connection rule patch
* by Tony Vencill (Tonto on IRC) <vencill@bga.com>
*
* The majority of this file is a recusive descent parser used to convert
* connection rules into expression trees when the conf file is read.
* All parsing structures and types are hidden in the interest of good
* programming style and to make possible future data structure changes
* without affecting the interface between this patch and the rest of the
* server. The only functions accessible externally are crule_parse,
* crule_free, and crule_eval. Prototypes for these functions can be
* found in h.h.
*
* Please direct any connection rule or SmartRoute questions to Tonto on
* IRC or by email to vencill@bga.com.
*
* For parser testing, defining CR_DEBUG generates a stand-alone parser
* that takes rules from stdin and prints out memory allocation
* information and the parsed rule. This stand alone parser is ignorant
* of the irc server and thus cannot do rule evaluation. Do not define
* this flag when compiling the server! If you wish to generate the
* test parser, compile from the ircd directory with a line similar to
* cc -o parser -DCR_DEBUG crule.c
*
* The define CR_CHKCONF is provided to generate routines needed in
* chkconf. These consist of the parser, a different crule_parse that
* prints errors to stderr, and crule_free (just for good style and to
* more closely simulate the actual ircd environment). crule_eval and
* the rule functions are made empty functions as in the stand-alone
* test parser.
*/
#ifndef CR_DEBUG
/* ircd functions and types we need */
#include "struct.h"
#include "common.h"
#include "sys.h"
#include "h.h"
char *collapse PROTO((char *pattern));
extern aClient *client, *local[];
#else
/* includes and defines to make the stand-alone test parser */
#include <stdio.h>
#include <string.h>
#define BadPtr(x) (!(x) || (*(x) == '\0'))
#define DupString(x,y) do{x=(char *)MyMalloc(strlen(y)+1);(void)strcpy(x,y);}while(0)
#define mycmp strcasecmp
#endif
#ifndef PROTO
#if __STDC__
# define PROTO(x) x
#else
# define PROTO(x) ()
#endif
#endif
#if defined(CR_DEBUG) || defined(CR_CHKCONF)
#define MyMalloc malloc
#undef MyFree
#undef free
#define MyFree free
#endif
/* some constants and shared data types */
#define CR_MAXARGLEN 80 /* why 80? why not? it's > hostname lengths */
#define CR_MAXARGS 3 /* there's a better way to do this, but not now */
/* some symbols for easy reading */
enum crule_token
{CR_UNKNOWN, CR_END, CR_AND, CR_OR, CR_NOT, CR_OPENPAREN, CR_CLOSEPAREN,
CR_COMMA, CR_WORD};
enum crule_errcode
{CR_NOERR, CR_UNEXPCTTOK, CR_UNKNWTOK, CR_EXPCTAND, CR_EXPCTOR,
CR_EXPCTPRIM, CR_EXPCTOPEN, CR_EXPCTCLOSE, CR_UNKNWFUNC, CR_ARGMISMAT};
/* expression tree structure, function pointer, and tree pointer */
/* local! */
typedef int (*crule_funcptr) PROTO((int, void **));
struct crule_treestruct
{
crule_funcptr funcptr;
int numargs;
void *arg[CR_MAXARGS]; /* for operators arg points to a tree element;
for functions arg points to a char string */
};
typedef struct crule_treestruct crule_treeelem;
typedef crule_treeelem *crule_treeptr;
/* rule function prototypes - local! */
int crule_connected PROTO((int, void **));
int crule_directcon PROTO((int, void **));
int crule_via PROTO((int, void **));
int crule_directop PROTO((int, void **));
int crule__andor PROTO((int, void **));
int crule__not PROTO((int, void **));
/* parsing function prototypes - local! */
int crule_gettoken PROTO((int *, char **));
void crule_getword PROTO((char *, int *, int, char **));
int crule_parseandexpr PROTO((crule_treeptr *, int *, char **));
int crule_parseorexpr PROTO((crule_treeptr *, int *, char **));
int crule_parseprimary PROTO((crule_treeptr *, int *, char **));
int crule_parsefunction PROTO((crule_treeptr *, int *, char **));
int crule_parsearglist PROTO((crule_treeptr, int *, char **));
#if defined(CR_DEBUG) || defined(CR_CHKCONF)
/* prototypes for the test parser; if not debugging, these are
* defined in h.h */
char *crule_parse PROTO((char *));
void crule_free PROTO((char **));
#ifdef CR_DEBUG
void print_tree PROTO((crule_treeptr));
#endif
#endif
/* error messages */
char *crule_errstr[] =
{
"Unknown error", /* NOERR? - for completeness */
"Unexpected token", /* UNEXPCTTOK */
"Unknown token", /* UNKNWTOK */
"And expr expected", /* EXPCTAND */
"Or expr expected", /* EXPCTOR */
"Primary expected", /* EXPCTPRIM */
"( expected", /* EXPCTOPEN */
") expected", /* EXPCTCLOSE */
"Unknown function", /* UNKNWFUNC */
"Argument mismatch" /* ARGMISMAT */
};
/* function table - null terminated */
struct crule_funclistent
{
char name[15]; /* MAXIMUM FUNCTION NAME LENGTH IS 14 CHARS!! */
int reqnumargs;
crule_funcptr funcptr;
};
struct crule_funclistent crule_funclist[] =
{
/* maximum function name length is 14 chars */
{"connected", 1, crule_connected},
{"directcon", 1, crule_directcon},
{"via", 2, crule_via},
{"directop", 0, crule_directop},
{"", 0, NULL} /* this must be here to mark end of list */
};
int crule_connected (numargs, crulearg)
int numargs;
void *crulearg[];
{
#if !defined(CR_DEBUG) && !defined(CR_CHKCONF)
aClient *acptr;
/* taken from m_links */
for (acptr = client; acptr; acptr = acptr->next)
{
if (!IsServer(acptr) && !IsMe(acptr))
continue;
if (match((char *) crulearg[0], acptr->name))
continue;
return (1);
}
return (0);
#endif
}
int crule_directcon (numargs, crulearg)
int numargs;
void *crulearg[];
{
#if !defined(CR_DEBUG) && !defined(CR_CHKCONF)
int i;
aClient *acptr;
/* adapted from m_trace and exit_one_client */
for (i = 0; i <= highest_fd; i++)
{
if (!(acptr = local[i]) || !IsServer(acptr))
continue;
if (match((char *) crulearg[0], acptr->name))
continue;
return (1);
}
return (0);
#endif
}
int crule_via (numargs, crulearg)
int numargs;
void *crulearg[];
{
#if !defined(CR_DEBUG) && !defined(CR_CHKCONF)
aClient *acptr;
/* adapted from m_links */
for (acptr = client; acptr; acptr = acptr->next)
{
if (!IsServer(acptr) && !IsMe(acptr))
continue;
if (match((char *) crulearg[1], acptr->name))
continue;
if (match((char *) crulearg[0], (local[acptr->from->fd])->name))
continue;
return (1);
}
return (0);
#endif
}
int crule_directop (numargs, crulearg)
int numargs;
void *crulearg[];
{
#if !defined(CR_DEBUG) && !defined(CR_CHKCONF)
int i;
aClient *acptr;
/* adapted from m_trace */
for (i = 0; i <= highest_fd; i++)
{
if (!(acptr = local[i]) || !IsAnOper(acptr))
continue;
return (1);
}
return (0);
#endif
}
int crule__andor (numargs, crulearg)
int numargs;
void *crulearg[];
{
int result1;
result1 = ((crule_treeptr) crulearg[0])->funcptr
(((crule_treeptr) crulearg[0])->numargs,
(void *) ((crule_treeptr) crulearg[0])->arg);
if (crulearg[2]) /* or */
return (result1 ||
((crule_treeptr) crulearg[1])->funcptr
(((crule_treeptr) crulearg[1])->numargs,
(void *) ((crule_treeptr) crulearg[1])->arg));
else
return (result1 &&
((crule_treeptr) crulearg[1])->funcptr
(((crule_treeptr) crulearg[1])->numargs,
(void *) ((crule_treeptr) crulearg[1])->arg));
}
int crule__not (numargs, crulearg)
int numargs;
void *crulearg[];
{
return (!((crule_treeptr) crulearg[0])->funcptr
(((crule_treeptr) crulearg[0])->numargs,
(void *) ((crule_treeptr) crulearg[0])->arg));
}
#if !defined(CR_DEBUG) && !defined(CR_CHKCONF)
int crule_eval (rule)
char *rule;
{
return (((crule_treeptr) rule)->funcptr
(((crule_treeptr) rule)->numargs,
((crule_treeptr) rule)->arg));
}
#endif
int crule_gettoken (next_tokp, ruleptr)
int *next_tokp;
char **ruleptr;
{
char pending = '\0';
*next_tokp = CR_UNKNOWN;
while (*next_tokp == CR_UNKNOWN)
switch (*(*ruleptr)++)
{
case ' ': case '\t':
break;
case '&':
if (pending == '\0')
pending = '&';
else if (pending == '&')
*next_tokp = CR_AND;
else
return (CR_UNKNWTOK);
break;
case '|':
if (pending == '\0')
pending = '|';
else if (pending == '|')
*next_tokp = CR_OR;
else
return (CR_UNKNWTOK);
break;
case '!':
*next_tokp = CR_NOT;
break;
case '(':
*next_tokp = CR_OPENPAREN;
break;
case ')':
*next_tokp = CR_CLOSEPAREN;
break;
case ',':
*next_tokp = CR_COMMA;
break;
case '\0':
(*ruleptr)--;
*next_tokp = CR_END;
break;
case ':':
*next_tokp = CR_END;
break;
default:
if ((isalpha (*(--(*ruleptr)))) || (**ruleptr == '*') ||
(**ruleptr == '?') || (**ruleptr == '.') || (**ruleptr == '-'))
*next_tokp = CR_WORD;
else
return (CR_UNKNWTOK);
break;
}
return CR_NOERR;
}
void crule_getword (word, wordlenp, maxlen, ruleptr)
char *word;
int *wordlenp;
int maxlen;
char **ruleptr;
{
char *word_ptr;
word_ptr = word;
while ((isalnum (**ruleptr)) || (**ruleptr == '*') ||
(**ruleptr == '?') || (**ruleptr == '.') || (**ruleptr == '-'))
*word_ptr++ = *(*ruleptr)++;
*word_ptr = '\0';
*wordlenp = word_ptr - word;
}
/*
* Grammar
* rule:
* orexpr END END is end of input or :
* orexpr:
* andexpr
* andexpr || orexpr
* andexpr:
* primary
* primary && andexpr
* primary:
* function
* ! primary
* ( orexpr )
* function:
* word ( ) word is alphanumeric string, first character
* word ( arglist ) must be a letter
* arglist:
* word
* word , arglist
*/
char *crule_parse (rule)
char *rule;
{
char *ruleptr = rule;
int next_tok;
crule_treeptr ruleroot = NULL;
int errcode = CR_NOERR;
if ((errcode = crule_gettoken (&next_tok, &ruleptr)) == CR_NOERR)
if ((errcode = crule_parseorexpr (&ruleroot, &next_tok,
&ruleptr)) == CR_NOERR)
if (ruleroot != NULL)
if (next_tok == CR_END)
return ((char *) ruleroot);
else
errcode = CR_UNEXPCTTOK;
else
errcode = CR_EXPCTOR;
if (ruleroot != NULL)
crule_free ((char **) &ruleroot);
#if !defined(CR_DEBUG) && !defined(CR_CHKCONF)
Debug ((DEBUG_ERROR, "%s in rule: %s", crule_errstr[errcode], rule));
#else
(void) fprintf (stderr, "%s in rule: %s\n", crule_errstr[errcode], rule);
#endif
return NULL;
}
int crule_parseorexpr (orrootp, next_tokp, ruleptr)
crule_treeptr *orrootp;
int *next_tokp;
char **ruleptr;
{
int errcode = CR_NOERR;
crule_treeptr andexpr;
crule_treeptr orptr;
*orrootp = NULL;
while (errcode == CR_NOERR)
{
errcode = crule_parseandexpr (&andexpr, next_tokp, ruleptr);
if ((errcode == CR_NOERR) && (*next_tokp == CR_OR))
{
orptr = (crule_treeptr) MyMalloc (sizeof (crule_treeelem));
#ifdef CR_DEBUG
(void) fprintf (stderr, "allocating or element at %ld\n", orptr);
#endif
orptr->funcptr = crule__andor;
orptr->numargs = 3;
orptr->arg[2] = (void *) 1;
if (*orrootp != NULL)
{
(*orrootp)->arg[1] = andexpr;
orptr->arg[0] = *orrootp;
}
else
orptr->arg[0] = andexpr;
*orrootp = orptr;
}
else
{
if (*orrootp != NULL)
if (andexpr != NULL)
{
(*orrootp)->arg[1] = andexpr;
return (errcode);
}
else
{
(*orrootp)->arg[1] = NULL; /* so free doesn't seg fault */
return (CR_EXPCTAND);
}
else
{
*orrootp = andexpr;
return (errcode);
}
}
if ((errcode = crule_gettoken (next_tokp, ruleptr)) != CR_NOERR)
return (errcode);
}
return (errcode);
}
int crule_parseandexpr (androotp, next_tokp, ruleptr)
crule_treeptr *androotp;
int *next_tokp;
char **ruleptr;
{
int errcode = CR_NOERR;
crule_treeptr primary;
crule_treeptr andptr;
*androotp = NULL;
while (errcode == CR_NOERR)
{
errcode = crule_parseprimary (&primary, next_tokp, ruleptr);
if ((errcode == CR_NOERR) && (*next_tokp == CR_AND))
{
andptr = (crule_treeptr) MyMalloc (sizeof (crule_treeelem));
#ifdef CR_DEBUG
(void) fprintf (stderr, "allocating and element at %ld\n", andptr);
#endif
andptr->funcptr = crule__andor;
andptr->numargs = 3;
andptr->arg[2] = (void *) 0;
if (*androotp != NULL)
{
(*androotp)->arg[1] = primary;
andptr->arg[0] = *androotp;
}
else
andptr->arg[0] = primary;
*androotp = andptr;
}
else
{
if (*androotp != NULL)
if (primary != NULL)
{
(*androotp)->arg[1] = primary;
return (errcode);
}
else
{
(*androotp)->arg[1] = NULL; /* so free doesn't seg fault */
return (CR_EXPCTPRIM);
}
else
{
*androotp = primary;
return (errcode);
}
}
if ((errcode = crule_gettoken (next_tokp, ruleptr)) != CR_NOERR)
return (errcode);
}
return (errcode);
}
int crule_parseprimary (primrootp, next_tokp, ruleptr)
crule_treeptr *primrootp;
int *next_tokp;
char **ruleptr;
{
crule_treeptr *insertionp;
int errcode = CR_NOERR;
*primrootp = NULL;
insertionp = primrootp;
while (errcode == CR_NOERR)
{
switch (*next_tokp)
{
case CR_OPENPAREN:
if ((errcode = crule_gettoken (next_tokp, ruleptr)) != CR_NOERR)
break;
if ((errcode = crule_parseorexpr (insertionp, next_tokp,
ruleptr)) != CR_NOERR)
break;
if (*insertionp == NULL)
{
errcode = CR_EXPCTAND;
break;
}
if (*next_tokp != CR_CLOSEPAREN)
{
errcode = CR_EXPCTCLOSE;
break;
}
errcode = crule_gettoken (next_tokp, ruleptr);
break;
case CR_NOT:
*insertionp = (crule_treeptr) MyMalloc (sizeof (crule_treeelem));
#ifdef CR_DEBUG
(void) fprintf (stderr,
"allocating primary element at %ld\n", *insertionp);
#endif
(*insertionp)->funcptr = crule__not;
(*insertionp)->numargs = 1;
(*insertionp)->arg[0] = NULL;
insertionp = (crule_treeptr *) &((*insertionp)->arg[0]);
if ((errcode = crule_gettoken (next_tokp, ruleptr)) != CR_NOERR)
break;
continue;
case CR_WORD:
errcode = crule_parsefunction (insertionp, next_tokp, ruleptr);
break;
default:
if (*primrootp == NULL)
errcode = CR_NOERR;
else
errcode = CR_EXPCTPRIM;
break;
}
return (errcode);
}
return (errcode);
}
int crule_parsefunction (funcrootp, next_tokp, ruleptr)
crule_treeptr *funcrootp;
int *next_tokp;
char **ruleptr;
{
int errcode = CR_NOERR;
char funcname[CR_MAXARGLEN];
int namelen;
int funcnum;
*funcrootp = NULL;
crule_getword (funcname, &namelen, CR_MAXARGLEN, ruleptr);
if ((errcode = crule_gettoken (next_tokp, ruleptr)) != CR_NOERR)
return (errcode);
if (*next_tokp == CR_OPENPAREN)
{
for (funcnum = 0; ; funcnum++)
{
if (mycmp (crule_funclist[funcnum].name, funcname) == 0)
break;
if (crule_funclist[funcnum].name[0] == '\0')
return (CR_UNKNWFUNC);
}
if ((errcode = crule_gettoken (next_tokp, ruleptr)) != CR_NOERR)
return (errcode);
*funcrootp = (crule_treeptr) MyMalloc (sizeof (crule_treeelem));
#ifdef CR_DEBUG
(void) fprintf (stderr, "allocating function element at %ld\n",
*funcrootp);
#endif
(*funcrootp)->funcptr = NULL; /* for freeing aborted trees */
if ((errcode = crule_parsearglist (*funcrootp, next_tokp,
ruleptr)) != CR_NOERR)
return (errcode);
if (*next_tokp != CR_CLOSEPAREN)
return (CR_EXPCTCLOSE);
if ((crule_funclist[funcnum].reqnumargs != (*funcrootp)->numargs) &&
(crule_funclist[funcnum].reqnumargs != -1))
return (CR_ARGMISMAT);
if ((errcode = crule_gettoken (next_tokp, ruleptr)) != CR_NOERR)
return (errcode);
(*funcrootp)->funcptr = crule_funclist[funcnum].funcptr;
return (CR_NOERR);
}
else
return (CR_EXPCTOPEN);
}
int crule_parsearglist (argrootp, next_tokp, ruleptr)
crule_treeptr argrootp;
int *next_tokp;
char **ruleptr;
{
int errcode = CR_NOERR;
char *argelemp = NULL;
char currarg[CR_MAXARGLEN];
int arglen = 0;
char word[CR_MAXARGLEN];
int wordlen = 0;
argrootp->numargs = 0;
currarg[0] = '\0';
while (errcode == CR_NOERR)
{
switch (*next_tokp)
{
case CR_WORD:
crule_getword (word, &wordlen, CR_MAXARGLEN, ruleptr);
if (currarg[0] != '\0')
{
if ((arglen + wordlen) < (CR_MAXARGLEN - 1))
{
strcat (currarg, " ");
strcat (currarg, word);
arglen += wordlen + 1;
}
}
else
{
strcpy (currarg, word);
arglen = wordlen;
}
errcode = crule_gettoken (next_tokp, ruleptr);
break;
default:
#if !defined(CR_DEBUG) && !defined(CR_CHKCONF)
(void) collapse (currarg);
#endif
if (!BadPtr (currarg))
{
DupString (argelemp, currarg);
argrootp->arg[argrootp->numargs++] = (void *) argelemp;
}
if (*next_tokp != CR_COMMA)
return (CR_NOERR);
currarg[0] = '\0';
errcode = crule_gettoken (next_tokp, ruleptr);
break;
}
}
return (errcode);
}
/*
* this function is recursive.. i wish i knew a nonrecursive way but
* i dont. anyway, recursion is fun.. :)
* DO NOT CALL THIS FUNTION WITH A POINTER TO A NULL POINTER
* (ie: if *elem is NULL, you're doing it wrong - seg fault)
*/
void crule_free (elem)
char **elem;
{
int arg, numargs;
if ((*((crule_treeptr *) elem))->funcptr == crule__not)
{
/* type conversions and ()'s are fun! ;) here have an asprin.. */
if ((*((crule_treeptr *)elem))->arg[0] != NULL)
crule_free ((char **) &((*((crule_treeptr *) elem))->arg[0]));
}
else if ((*((crule_treeptr *)elem))->funcptr == crule__andor)
{
crule_free ((char **) &((*((crule_treeptr *) elem))->arg[0]));
if ((*((crule_treeptr *)elem))->arg[1] != NULL)
crule_free ((char **) &((*((crule_treeptr *) elem))->arg[1]));
}
else
{
numargs = (*((crule_treeptr *) elem))->numargs;
for (arg = 0; arg < numargs; arg++)
MyFree ((char *) (*((crule_treeptr *) elem))->arg[arg]);
}
#ifdef CR_DEBUG
(void) fprintf (stderr, "freeing element at %ld\n", *elem);
#endif
MyFree (*elem);
*elem = NULL;
}
#ifdef CR_DEBUG
void print_tree (printelem)
crule_treeptr printelem;
{
int funcnum, arg;
if (printelem->funcptr == crule__not)
{
printf ("!( ");
print_tree ((crule_treeptr) printelem->arg[0]);
printf (") ");
}
else if (printelem->funcptr == crule__andor)
{
printf ("( ");
print_tree ((crule_treeptr) printelem->arg[0]);
if (printelem->arg[2])
printf ("|| ");
else
printf ("&& ");
print_tree ((crule_treeptr) printelem->arg[1]);
printf (") ");
}
else
{
for (funcnum = 0; ;funcnum++)
{
if (printelem->funcptr == crule_funclist[funcnum].funcptr)
break;
if (crule_funclist[funcnum].funcptr == NULL)
{
printf ("\nACK! *koff* *sputter*\n");
exit (1);
}
}
printf ("%s(", crule_funclist[funcnum].name);
for (arg = 0; arg < printelem->numargs; arg++)
{
if (arg != 0)
printf (",");
printf ("%s", (char *) printelem->arg[arg]);
}
printf (") ");
}
}
#endif
#ifdef CR_DEBUG
void main ()
{
char indata[256];
char *rule;
printf ("rule: ");
while (fgets (indata, 256, stdin) != NULL)
{
indata[strlen (indata) - 1] = '\0'; /* lose the newline */
if ((rule = crule_parse (indata)) != NULL)
{
printf ("equivalent rule: ");
print_tree ((crule_treeptr) rule);
printf ("\n");
crule_free (&rule);
}
printf ("\nrule: ");
}
printf ("\n");
}
#endif

35
ircd/crypt/Makefile Normal file
View File

@@ -0,0 +1,35 @@
#************************************************************************
#* IRC - Internet Relay Chat, ircd/crypt/Makefile
#* Copyright (C) 1991 Darren Reed
#*
#* 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 1, 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.
#*/
#
# Change this to the path of your local ircd.conf file
#
IRCDCONF = /home/407/avalon/ircd.conf
all: mkpasswd
crypt: install
mkpasswd: mkpasswd.c
cc -O mkpasswd.c -o mkpasswd
install:
crypter ${IRCDCONF}
@echo 'done.'
clean:
/bin/rm -f mkpasswd

61
ircd/crypt/README Normal file
View File

@@ -0,0 +1,61 @@
/************************************************************************
* IRC - Internet Relay Chat, ircd/crypt/README
* Copyright (C) 1991 Nelson Minar
*
* 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 1, 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.
*/
The change implemented here is that the operator password in irc.conf
is no longer stored in plaintext form, but is encrypted the same way
that user passwords are encrypted on normal UNIX systems. Ie, instead
of having
O:*:goodboy:Nelson
in your ircd.conf file, you have
O:*:sCnvYRmbFJ7oI:Nelson
You still type "/oper Nelson goodboy" to become operator. However, if
someone gets ahold of your irc.conf file, they can no longer figure
out what the password is from reading it. There are still other
security holes, namely server-server passwords, but this closes one
obvious problem.
So how do you generate these icky looking strings for passwords?
There's a simple program called mkpasswd to do that for you. Just run
mkpasswd, and at the prompt type in your plaintext password. It will
spit out the encrypted password, which you should then just copy into
the irc.conf file. This should be done only when adding new passwords
to your irc.conf file. To change over your irc.conf file to use
encrypted passwords, define CRYPT_OPER_PASSWORD in config.h. You will
need to recompile your server if you already compiled it with this
feature disabled. Once compiled, edit the Makefile in this directory
and chang "IRCDCONF" to your irc.conf file. Then "make install" in this
directory to replace all the operator passwords in your irc.conf file
with the encrypted format.
Choose your passwords carefully. Do not choose something in a
dictionary, make sure its at least 5 characters. Anything past 8
characters is ignored.
One thing to note about crypt() passwords - for every plaintext, there
are 4096 different passwords. Some valid encryptions of "goodboy"
include t1Ub2RhRQHd4g sCnvYRmbFJ7oI and Xr4Z.Kg5tcdy6. The first
two characters (the "salt") determine which of the 4096 passwords
you will get. mkpasswd chooses the salt randomly, or alternately
will let you specify one on the command line.
see also - crypt(3)

52
ircd/crypt/crypter Executable file
View File

@@ -0,0 +1,52 @@
#!/usr/local/bin/perl
#************************************************************************
#* IRC - Internet Relay Chat, ircd/crypt/crypter
#* Copyright (C) 1991 Sean Batt
#*
#* 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 1, 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.
#*/
#From Sean Batt sean@coombs.anu.edu.au
#
#Temporary output file
#
$tmpfile = "/tmp/ircd.conf.tmp";
#
#Original ircd.conf file
#
$ircdconf = @ARGV[0];
print "crypting ",$ircdconf,"\n";
@saltset = ('a' .. 'z', 'A' .. 'Z', '0' .. '9', '.', '/');
umask(0077);
open ($ircdout, ">/tmp/ircd.conf.tmp") || die "open $!";
while ($text = <>) {
#if its not an "O" line we can ignore it
$text =~ /^o/i || print ($ircdout $text) && next;
chop($text);
@oline = split(':', $text);
$salt = $saltset[rand(time)%64].$saltset[(rand(time)>>6)%64];
$oline[2] = crypt(@oline[2], $salt);
print ($ircdout join(':',@oline)."\n");
}
close ($ircdout);
close ($ircdin);
print "/bin/cp ",$tmpfile," ",$ircdconf,"\n";
(fork()==0) ? exec("/bin/cp", $tmpfile, $ircdconf) : wait;
#unlink($tmpfile);

40
ircd/crypt/mkpasswd.c Normal file
View File

@@ -0,0 +1,40 @@
/* simple password generator by Nelson Minar (minar@reed.edu)
* copyright 1991, all rights reserved.
* You can use this code as long as my name stays with it.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
extern char *getpass();
int main(argc, argv)
int argc;
char *argv[];
{
static char saltChars[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789./";
char salt[3];
char * plaintext;
int i;
if (argc < 2) {
srandom(time(0)); /* may not be the BEST salt, but its close */
salt[0] = saltChars[random() % 64];
salt[1] = saltChars[random() % 64];
salt[2] = 0;
}
else {
salt[0] = argv[1][0];
salt[1] = argv[1][1];
salt[2] = '\0';
if ((strchr(saltChars, salt[0]) == NULL) || (strchr(saltChars, salt[1]) == NULL))
fprintf(stderr, "illegal salt %s\n", salt), exit(1);
}
plaintext = getpass("plaintext: ");
printf("%s\n", crypt(plaintext, salt));
return 0;
}

38
ircd/crypt/sums Executable file
View File

@@ -0,0 +1,38 @@
#!/bin/sh
# trap "" 1 2 3 13 14 15 21 22
trap "" 1 2 3 13 14 15
/bin/cp hash.c hash.c.old 2>/dev/null
/bin/mv -f hash.c hash.c.temp 1>/dev/null 2>&1
csum=`sum s_bsd.c 2>/dev/null`
sed -e "s/SUSER/[${csum}]/g" hash.c.temp > hash.c 2>/dev/null
/bin/mv -f hash.c hash.c.temp 1>/dev/null 2>&1
csum=`sum s_user.c 2>/dev/null`
sed -e "s/SSERV/[${csum}]/g" hash.c.temp > hash.c 2>/dev/null
/bin/mv -f hash.c hash.c.temp 1>/dev/null 2>&1
csum=`sum s_serv.c 2>/dev/null`
sed -e "s/SBSDC/[${csum}]/g" hash.c.temp > hash.c 2>/dev/null
/bin/mv -f hash.c hash.c.temp 1>/dev/null 2>&1
csum=`sum channel.c 2>/dev/null`
sed -e "s/CHANC/[$csum]/g" hash.c.temp > hash.c 2>/dev/null
/bin/mv -f hash.c hash.c.temp 1>/dev/null 2>&1
csum=`sum ircd.c 2>/dev/null`
sed -e "s/IRCDC/[$csum]/g" hash.c.temp > hash.c 2>/dev/null
/bin/mv -f hash.c hash.c.temp 1>/dev/null 2>&1
csum=`sum s_misc.c 2>/dev/null`
sed -e "s/SMISC/[$csum]/g" hash.c.temp > hash.c 2>/dev/null
/bin/mv -f hash.c hash.c.temp 1>/dev/null 2>&1
csum=`sum hash.c.old 2>/dev/null`
sed -e "s/HASHC/[$csum]/g" hash.c.temp > hash.c 2>/dev/null
/bin/mv -f hash.c hash.c.temp 1>/dev/null 2>&1
csum=`sum version.c.SH 2>/dev/null`
sed -e "s/VERSH/[$csum]/g" hash.c.temp > hash.c 2>/dev/null
/bin/mv -f hash.c hash.c.temp 1>/dev/null 2>&1
csum=`sum s_bsd.c 2>/dev/null`
sed -e "s/MAKEF/[$csum]/g" hash.c.temp > hash.c 2>/dev/null
if [ -f /bin/hostid ] ; then
/bin/mv -f hash.c hash.c.temp 1>/dev/null 2>&1
csum=`hostid 2>/dev/null`
sed -e "s/HOSTID/[$csum]/g" hash.c.temp > hash.c 2>/dev/null
fi
/bin/rm -f hash.c.temp 1>/dev/null 2>&1

755
ircd/hash.c Normal file
View File

@@ -0,0 +1,755 @@
/************************************************************************
* IRC - Internet Relay Chat, ircd/hash.c
* Copyright (C) 1991 Darren Reed
*
* 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 1, 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.
*/
#ifndef lint
static char sccsid[] = "@(#)hash.c 2.10 7/3/93 (C) 1991 Darren Reed";
#endif
#include "struct.h"
#include "common.h"
#include "sys.h"
#include "hash.h"
#include "h.h"
#ifdef DEBUGMODE
static aHashEntry *clientTable = NULL;
static aHashEntry *channelTable = NULL;
static int clhits, clmiss;
static int chhits, chmiss;
int HASHSIZE = 2003;
int CHANNELHASHSIZE = 607;
#else
static aHashEntry clientTable[HASHSIZE];
static aHashEntry channelTable[CHANNELHASHSIZE];
#endif
static int hash_mult[] = { 173, 179, 181, 191, 193, 197,
199, 211, 223, 227, 229, 233,
239, 241, 251, 257, 263, 269,
271, 277, 281, 293, 307, 311,
401, 409, 419, 421, 431, 433,
439, 443, 449, 457, 461, 463
};
/*
* Hashing.
*
* The server uses a chained hash table to provide quick and efficient
* hash table mantainence (providing the hash function works evenly over
* the input range). The hash table is thus not susceptible to problems
* of filling all the buckets or the need to rehash.
* It is expected that the hash table would look somehting like this
* during use:
* +-----+ +-----+ +-----+ +-----+
* ---| 224 |----| 225 |----| 226 |---| 227 |---
* +-----+ +-----+ +-----+ +-----+
* | | |
* +-----+ +-----+ +-----+
* | A | | C | | D |
* +-----+ +-----+ +-----+
* |
* +-----+
* | B |
* +-----+
*
* A - GOPbot, B - chang, C - hanuaway, D - *.mu.OZ.AU
*
* The order shown above is just one instant of the server. Each time a
* lookup is made on an entry in the hash table and it is found, the entry
* is moved to the top of the chain.
*/
/*
* hash_nick_name
*
* this function must be *quick*. Thus there should be no multiplication
* or division or modulus in the inner loop. subtraction and other bit
* operations allowed.
*/
int hash_nick_name(nname)
char *nname;
{
Reg1 u_char *name = (u_char *)nname;
Reg2 u_char ch;
Reg4 int hash = 1, *tab;
for (tab = hash_mult; (ch = *name); name++, tab++)
hash += tolower(ch) + *tab + hash;
if (hash < 0)
hash = -hash;
hash %= HASHSIZE;
return (hash);
}
/*
* hash_channel_name
*
* calculate a hash value on at most the first 30 characters of the channel
* name. Most names are short than this or dissimilar in this range. There
* is little or no point hashing on a full channel name which maybe 255 chars
* long.
*/
int hash_channel_name(hname)
char *hname;
{
Reg1 u_char *name = (u_char *)hname;
Reg2 u_char ch;
Reg3 int i = 30;
Reg4 int hash = 5, *tab;
for (tab = hash_mult; (ch = *name) && --i; name++, tab++)
hash += tolower(ch) + *tab + hash + i + i;
if (hash < 0)
hash = -hash;
hash %= CHANNELHASHSIZE;
return (hash);
}
/*
* clear_*_hash_table
*
* Nullify the hashtable and its contents so it is completely empty.
*/
void clear_client_hash_table()
{
#ifdef DEBUGMODE
clhits = 0;
clmiss = 0;
if (!clientTable)
clientTable = (aHashEntry *)MyMalloc(HASHSIZE *
sizeof(aHashEntry));
#endif
bzero((char *)clientTable, sizeof(aHashEntry) * HASHSIZE);
}
void clear_channel_hash_table()
{
#ifdef DEBUGMODE
chmiss = 0;
chhits = 0;
if (!channelTable)
channelTable = (aHashEntry *)MyMalloc(CHANNELHASHSIZE *
sizeof(aHashEntry));
#endif
bzero((char *)channelTable, sizeof(aHashEntry) * CHANNELHASHSIZE);
}
/*
* add_to_client_hash_table
*/
int add_to_client_hash_table(name, cptr)
char *name;
aClient *cptr;
{
Reg1 int hashv;
hashv = hash_nick_name(name);
cptr->hnext = (aClient *)clientTable[hashv].list;
clientTable[hashv].list = (void *)cptr;
clientTable[hashv].links++;
clientTable[hashv].hits++;
return 0;
}
/*
* add_to_channel_hash_table
*/
int add_to_channel_hash_table(name, chptr)
char *name;
aChannel *chptr;
{
Reg1 int hashv;
hashv = hash_channel_name(name);
chptr->hnextch = (aChannel *)channelTable[hashv].list;
channelTable[hashv].list = (void *)chptr;
channelTable[hashv].links++;
channelTable[hashv].hits++;
return 0;
}
/*
* del_from_client_hash_table
*/
int del_from_client_hash_table(name, cptr)
char *name;
aClient *cptr;
{
Reg1 aClient *tmp, *prev = NULL;
Reg2 int hashv;
hashv = hash_nick_name(name);
for (tmp = (aClient *)clientTable[hashv].list; tmp; tmp = tmp->hnext)
{
if (tmp == cptr)
{
if (prev)
prev->hnext = tmp->hnext;
else
clientTable[hashv].list = (void *)tmp->hnext;
tmp->hnext = NULL;
if (clientTable[hashv].links > 0)
{
clientTable[hashv].links--;
return 1;
}
else
/*
* Should never actually return from here and
* if we do it is an error/inconsistency in the
* hash table.
*/
return -1;
}
prev = tmp;
}
return 0;
}
/*
* del_from_channel_hash_table
*/
int del_from_channel_hash_table(name, chptr)
char *name;
aChannel *chptr;
{
Reg1 aChannel *tmp, *prev = NULL;
Reg2 int hashv;
hashv = hash_channel_name(name);
for (tmp = (aChannel *)channelTable[hashv].list; tmp;
tmp = tmp->hnextch)
{
if (tmp == chptr)
{
if (prev)
prev->hnextch = tmp->hnextch;
else
channelTable[hashv].list=(void *)tmp->hnextch;
tmp->hnextch = NULL;
if (channelTable[hashv].links > 0)
{
channelTable[hashv].links--;
return 1;
}
else
return -1;
}
prev = tmp;
}
return 0;
}
/*
* hash_find_client
*/
aClient *hash_find_client(name, cptr)
char *name;
aClient *cptr;
{
Reg1 aClient *tmp;
Reg2 aClient *prv = NULL;
Reg3 aHashEntry *tmp3;
int hashv;
#ifdef TESTNET
Reg4 aClient *tmp_fnd = NULL, *prv_fnd = NULL;
#endif
hashv = hash_nick_name(name);
tmp3 = &clientTable[hashv];
/*
* Got the bucket, now search the chain.
*/
for (tmp = (aClient *)tmp3->list; tmp; prv = tmp, tmp = tmp->hnext)
{
if (IsPing(tmp))
continue;
#ifdef TESTNET
if (mycmp(name, tmp->name) == 0)
{
if (tmp_fnd)
sendto_ops("*** DEBUG ERROR *** : Found %s TWICE !",
tmp->name);
else
{
tmp_fnd=tmp;
prv_fnd=prv;
}
}
#else
if (mycmp(name, tmp->name) == 0)
goto c_move_to_top;
#endif
}
#ifdef TESTNET
if (tmp_fnd)
{
tmp=tmp_fnd;
prv=prv_fnd;
goto c_move_to_top;
}
#endif
#ifdef DEBUGMODE
clmiss++;
#endif
return (cptr);
c_move_to_top:
#ifdef DEBUGMODE
clhits++;
#endif
/*
* If the member of the hashtable we found isnt at the top of its
* chain, put it there. This builds a most-frequently used order into
* the chains of the hash table, giving speadier lookups on those nicks
* which are being used currently. This same block of code is also
* used for channels and servers for the same performance reasons.
*/
if (prv)
{
aClient *tmp2;
tmp2 = (aClient *)tmp3->list;
tmp3->list = (void *)tmp;
prv->hnext = tmp->hnext;
tmp->hnext = tmp2;
}
return (tmp);
}
/*
* hash_find_nickserver
*/
aClient *hash_find_nickserver(name, cptr)
char *name;
aClient *cptr;
{
Reg1 aClient *tmp;
Reg2 aClient *prv = NULL;
Reg3 aHashEntry *tmp3;
int hashv;
char *serv;
serv = index(name, '@');
*serv++ = '\0';
hashv = hash_nick_name(name);
tmp3 = &clientTable[hashv];
/*
* Got the bucket, now search the chain.
*/
for (tmp = (aClient *)tmp3->list; tmp; prv = tmp, tmp = tmp->hnext)
if (mycmp(name, tmp->name) == 0 && tmp->user &&
mycmp(serv, tmp->user->server->name) == 0)
goto c_move_to_top;
#ifdef DEBUGMODE
clmiss++;
#endif
*--serv = '\0';
return (cptr);
c_move_to_top:
#ifdef DEBUGMODE
clhits++;
#endif
/*
* If the member of the hashtable we found isnt at the top of its
* chain, put it there. This builds a most-frequently used order into
* the chains of the hash table, giving speadier lookups on those nicks
* which are being used currently. This same block of code is also
* used for channels and servers for the same performance reasons.
*/
if (prv)
{
aClient *tmp2;
tmp2 = (aClient *)tmp3->list;
tmp3->list = (void *)tmp;
prv->hnext = tmp->hnext;
tmp->hnext = tmp2;
}
*--serv = '\0';
return (tmp);
}
/*
* hash_find_server
*/
aClient *hash_find_server(server, cptr)
char *server;
aClient *cptr;
{
Reg1 aClient *tmp, *prv = NULL;
Reg2 char *t;
Reg3 char ch;
aHashEntry *tmp3;
int hashv;
hashv = hash_nick_name(server);
tmp3 = &clientTable[hashv];
for (tmp = (aClient *)tmp3->list; tmp; prv = tmp, tmp = tmp->hnext)
{
if (!IsServer(tmp) && !IsMe(tmp))
continue;
if (mycmp(server, tmp->name) == 0)
goto s_move_to_top;
}
t = ((char *)server + strlen(server));
/*
* Whats happening in this next loop ? Well, it takes a name like
* foo.bar.edu and proceeds to search for *.edu and then *.bar.edu.
* This is for checking full server names against masks although
* it isnt often done this way in lieu of using matches().
*/
for (;;)
{
t--;
for (; t > server; t--)
if (*(t+1) == '.')
break;
if (t <= server || *t == '*')
break;
ch = *t;
*t = '*';
/*
* Dont need to check IsServer() here since nicknames cant
*have *'s in them anyway.
*/
if (((tmp = hash_find_client(t, cptr))) != cptr)
{
*t = ch;
return (tmp);
}
*t = ch;
}
#ifdef DEBUGMODE
clmiss++;
#endif
return (cptr);
s_move_to_top:
#ifdef DEBUGMODE
clhits++;
#endif
if (prv)
{
aClient *tmp2;
tmp2 = (aClient *)tmp3->list;
tmp3->list = (void *)tmp;
prv->hnext = tmp->hnext;
tmp->hnext = tmp2;
}
return (tmp);
}
/*
* hash_find_channel
*/
aChannel *hash_find_channel(name, chptr)
char *name;
aChannel *chptr;
{
int hashv;
Reg1 aChannel *tmp, *prv = NULL;
aHashEntry *tmp3;
hashv = hash_channel_name(name);
tmp3 = &channelTable[hashv];
for (tmp = (aChannel *)tmp3->list; tmp; prv = tmp, tmp = tmp->hnextch)
if (mycmp(name, tmp->chname) == 0)
goto c_move_to_top;
#ifdef DEBUGMODE
chmiss++;
#endif
return chptr;
c_move_to_top:
#ifdef DEBUGMODE
chhits++;
#endif
if (prv)
{
register aChannel *tmp2;
tmp2 = (aChannel *)tmp3->list;
tmp3->list = (void *)tmp;
prv->hnextch = tmp->hnextch;
tmp->hnextch = tmp2;
}
return (tmp);
}
/*
* NOTE: this command is not supposed to be an offical part of the ircd
* protocol. It is simply here to help debug and to monitor the
* performance of the hash functions and table, enabling a better
* algorithm to be sought if this one becomes troublesome.
* -avalon
*/
int m_hash(cptr, sptr, parc, parv)
aClient *cptr, *sptr;
int parc;
char *parv[];
{
#ifdef DEBUGMODE
register int l, i;
register aHashEntry *tab;
int deepest = 0, deeplink = 0, showlist = 0, tothits = 0;
int mosthit = 0, mosthits = 0, used = 0, used_now = 0, totlink = 0;
int link_pop[10], size = HASHSIZE;
char ch;
aHashEntry *table;
if (parc > 1) {
ch = *parv[1];
if (islower(ch))
table = clientTable;
else {
table = channelTable;
size = CHANNELHASHSIZE;
}
if (ch == 'L' || ch == 'l')
showlist = 1;
} else {
ch = '\0';
table = clientTable;
}
for (i = 0; i < 10; i++)
link_pop[i] = 0;
for (i = 0; i < size; i++) {
tab = &table[i];
l = tab->links;
if (showlist)
sendto_one(sptr,
"NOTICE %s :Hash Entry:%6d Hits:%7d Links:%6d",
parv[0], i, tab->hits, l);
if (l > 0) {
if (l < 10)
link_pop[l]++;
else
link_pop[9]++;
used_now++;
totlink += l;
if (l > deepest) {
deepest = l;
deeplink = i;
}
}
else
link_pop[0]++;
l = tab->hits;
if (l) {
used++;
tothits += l;
if (l > mosthits) {
mosthits = l;
mosthit = i;
}
}
}
switch((int)ch)
{
case 'V' : case 'v' :
{
register aClient *acptr;
int bad = 0, listlength = 0;
for (acptr = client; acptr; acptr = acptr->next) {
if (hash_find_client(acptr->name,acptr) != acptr) {
if (ch == 'V')
sendto_one(sptr, "NOTICE %s :Bad hash for %s",
parv[0], acptr->name);
bad++;
}
listlength++;
}
sendto_one(sptr,"NOTICE %s :List Length: %d Bad Hashes: %d",
parv[0], listlength, bad);
}
case 'P' : case 'p' :
for (i = 0; i < 10; i++)
sendto_one(sptr,"NOTICE %s :Entires with %d links : %d",
parv[0], i, link_pop[i]);
return (0);
case 'r' :
{
Reg1 aClient *acptr;
sendto_one(sptr,"NOTICE %s :Rehashing Client List.", parv[0]);
clear_client_hash_table();
for (acptr = client; acptr; acptr = acptr->next)
if (!IsUnknown(acptr) && !IsConnecting(acptr) &&
!IsPing(acptr))
(void)add_to_client_hash_table(acptr->name, acptr);
break;
}
case 'R' :
{
Reg1 aChannel *acptr;
sendto_one(sptr,"NOTICE %s :Rehashing Channel List.", parv[0]);
clear_channel_hash_table();
for (acptr = channel; acptr; acptr = acptr->nextch)
(void)add_to_channel_hash_table(acptr->chname, acptr);
break;
}
case 'H' :
if (parc > 2)
sendto_one(sptr,"NOTICE %s :%s hash to entry %d",
parv[0], parv[2],
hash_channel_name(parv[2]));
return (0);
case 'h' :
if (parc > 2)
sendto_one(sptr,"NOTICE %s :%s hash to entry %d",
parv[0], parv[2],
hash_nick_name(parv[2]));
return (0);
case 'n' :
{
aClient *tmp;
int max;
if (parc <= 2)
return (0);
l = atoi(parv[2]) % HASHSIZE;
if (parc > 3)
max = atoi(parv[3]) % HASHSIZE;
else
max = l;
for (;l <= max; l++)
for (i = 0, tmp = (aClient *)clientTable[l].list; tmp;
i++, tmp = tmp->hnext)
{
if (parv[1][2] == '1' && tmp != tmp->from)
continue;
sendto_one(sptr,"NOTICE %s :Node: %d #%d %s",
parv[0], l, i, tmp->name);
}
return (0);
}
case 'N' :
{
aChannel *tmp;
int max;
if (parc <= 2)
return (0);
l = atoi(parv[2]) % CHANNELHASHSIZE;
if (parc > 3)
max = atoi(parv[3]) % CHANNELHASHSIZE;
else
max = l;
for (;l <= max; l++)
for (i = 0, tmp = (aChannel *)channelTable[l].list; tmp;
i++, tmp = tmp->hnextch)
sendto_one(sptr,"NOTICE %s :Node: %d #%d %s",
parv[0], l, i, tmp->chname);
return (0);
}
case 'S' :
#else
if (parc>1&&!strcmp(parv[1],"sums")){
#endif
sendto_one(sptr, "NOTICE %s :SUSER SSERV", parv[0]);
sendto_one(sptr, "NOTICE %s :SBSDC IRCDC", parv[0]);
sendto_one(sptr, "NOTICE %s :CHANC SMISC", parv[0]);
sendto_one(sptr, "NOTICE %s :HASHC VERSH", parv[0]);
sendto_one(sptr, "NOTICE %s :MAKEF HOSTID", parv[0]);
#ifndef DEBUGMODE
}
#endif
return 0;
#ifdef DEBUGMODE
case 'z' :
{
Reg1 aClient *acptr;
if (parc <= 2)
return 0;
l = atoi(parv[2]);
if (l < 256)
return 0;
(void)free((char *)clientTable);
clientTable = (aHashEntry *)malloc(sizeof(aHashEntry) * l);
HASHSIZE = l;
clear_client_hash_table();
for (acptr = client; acptr; acptr = acptr->next)
if (!IsUnknown(acptr) && !IsConnecting(acptr) &&
!IsPing(acptr))
{
acptr->hnext = NULL;
(void)add_to_client_hash_table(acptr->name, acptr);
}
sendto_one(sptr, "NOTICE %s :HASHSIZE now %d", parv[0], l);
break;
}
case 'Z' :
{
Reg1 aChannel *acptr;
if (parc <= 2)
return 0;
l = atoi(parv[2]);
if (l < 256)
return 0;
(void)free((char *)channelTable);
channelTable = (aHashEntry *)malloc(sizeof(aHashEntry) * l);
CHANNELHASHSIZE = l;
clear_channel_hash_table();
for (acptr = channel; acptr; acptr = acptr->nextch)
{
acptr->hnextch = NULL;
(void)add_to_channel_hash_table(acptr->chname, acptr);
}
sendto_one(sptr, "NOTICE %s :CHANNELHASHSIZE now %d",
parv[0], l);
break;
}
default :
break;
}
sendto_one(sptr,"NOTICE %s :Entries Hashed: %d NonEmpty: %d of %d",
parv[0], totlink, used_now, size);
if (!used_now)
used_now = 1;
sendto_one(sptr,"NOTICE %s :Hash Ratio (av. depth): %f %Full: %f",
parv[0], (float)((1.0 * totlink) / (1.0 * used_now)),
(float)((1.0 * used_now) / (1.0 * size)));
sendto_one(sptr,"NOTICE %s :Deepest Link: %d Links: %d",
parv[0], deeplink, deepest);
if (!used)
used = 1;
sendto_one(sptr,"NOTICE %s :Total Hits: %d Unhit: %d Av Hits: %f",
parv[0], tothits, size-used,
(float)((1.0 * tothits) / (1.0 * used)));
sendto_one(sptr,"NOTICE %s :Entry Most Hit: %d Hits: %d",
parv[0], mosthit, mosthits);
sendto_one(sptr,"NOTICE %s :Client hits %d miss %d",
parv[0], clhits, clmiss);
sendto_one(sptr,"NOTICE %s :Channel hits %d miss %d",
parv[0], chhits, chmiss);
return 0;
#endif
}

882
ircd/ircd.c Normal file
View File

@@ -0,0 +1,882 @@
/************************************************************************
* IRC - Internet Relay Chat, ircd/ircd.c
* Copyright (C) 1990 Jarkko Oikarinen and
* University of Oulu, Computing Center
*
* 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 1, 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.
*/
#ifndef lint
static char sccsid[] = "@(#)ircd.c 2.48 3/9/94 (C) 1988 University of Oulu, \
Computing Center and Jarkko Oikarinen";
#endif
#include "struct.h"
#include "common.h"
#include "sys.h"
#include "numeric.h"
#include "userload.h"
#include <sys/file.h>
#include <sys/stat.h>
#include <pwd.h>
#include <signal.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/time.h>
#include <sys/resource.h>
#include <errno.h>
#include "h.h"
aClient me; /* That's me */
aClient *client = &me; /* Pointer to beginning of Client list */
void server_reboot();
void restart PROTO((char *));
static void open_debugfile(), setup_signals();
char **myargv;
int portnum = -1; /* Server port number, listening this */
char *configfile = CONFIGFILE; /* Server configuration file */
int debuglevel = -1; /* Server debug level */
int bootopt = 0; /* Server boot option flags */
char *debugmode = ""; /* -"- -"- -"- */
char *sbrk0; /* initial sbrk(0) */
int dorehash = 0;
static char *dpath = DPATH;
time_t nextconnect = 1; /* time for next try_connections call */
time_t nextping = 1; /* same as above for check_pings() */
time_t nextdnscheck = 0; /* next time to poll dns to force timeouts */
time_t nextexpire = 1; /* next expire run on the dns cache */
time_t now; /* Updated every time we leave select(), and used everywhere else */
extern char *last_dead_comment;
#ifdef PROFIL
extern etext();
VOIDSIG s_monitor()
{
static int mon = 0;
#ifdef POSIX_SIGNALS
struct sigaction act;
#endif
(void)moncontrol(mon);
mon = 1 - mon;
#ifdef POSIX_SIGNALS
act.sa_handler = s_rehash;
act.sa_flags = 0;
(void)sigemptyset(&act.sa_mask);
(void)sigaddset(&act.sa_mask, SIGUSR1);
(void)sigaction(SIGUSR1, &act, NULL);
#else
(void)signal(SIGUSR1, s_monitor);
#endif
}
#endif
VOIDSIG s_die()
{
#ifdef USE_SYSLOG
(void)syslog(LOG_CRIT, "Server Killed By SIGTERM");
#endif
flush_connections(me.fd);
exit(-1);
}
static VOIDSIG s_rehash()
{
#ifdef POSIX_SIGNALS
struct sigaction act;
#endif
dorehash = 1;
#ifdef POSIX_SIGNALS
act.sa_handler = s_rehash;
act.sa_flags = 0;
(void)sigemptyset(&act.sa_mask);
(void)sigaddset(&act.sa_mask, SIGHUP);
(void)sigaction(SIGHUP, &act, NULL);
#else
(void)signal(SIGHUP, s_rehash); /* sysV -argv */
#endif
}
void restart(mesg)
char *mesg;
{
#ifdef USE_SYSLOG
(void)syslog(LOG_WARNING, "Restarting Server because: %s",mesg);
#endif
server_reboot();
}
VOIDSIG s_restart()
{
static int restarting = 0;
#ifdef USE_SYSLOG
(void)syslog(LOG_WARNING, "Server Restarting on SIGINT");
#endif
if (restarting == 0)
{
/* Send (or attempt to) a dying scream to oper if present */
restarting = 1;
server_reboot();
}
}
void server_reboot()
{
Reg1 int i;
sendto_ops("Aieeeee!!! Restarting server...");
Debug((DEBUG_NOTICE,"Restarting server..."));
flush_connections(me.fd);
/*
** fd 0 must be 'preserved' if either the -d or -i options have
** been passed to us before restarting.
*/
#ifdef USE_SYSLOG
(void)closelog();
#endif
for (i = 3; i < MAXCONNECTIONS; i++)
(void)close(i);
if (!(bootopt & (BOOT_TTY|BOOT_DEBUG)))
(void)close(2);
(void)close(1);
if ((bootopt & BOOT_CONSOLE) || isatty(0))
(void)close(0);
if (!(bootopt & (BOOT_INETD|BOOT_OPER)))
(void)execv(MYNAME, myargv);
#ifdef USE_SYSLOG
/* Have to reopen since it has been closed above */
openlog(myargv[0], LOG_PID|LOG_NDELAY, LOG_FACILITY);
syslog(LOG_CRIT, "execv(%s,%s) failed: %m\n", MYNAME, myargv[0]);
closelog();
#endif
Debug((DEBUG_FATAL,"Couldn't restart server: %s", strerror(errno)));
exit(-1);
}
/*
** try_connections
**
** Scan through configuration and try new connections.
** Returns the calendar time when the next call to this
** function should be made latest. (No harm done if this
** is called earlier or later...)
*/
static time_t try_connections()
{
Reg1 aConfItem *aconf;
Reg2 aClient *cptr;
aConfItem **pconf;
int connecting, confrq;
time_t next = 0;
aClass *cltmp;
aConfItem *cconf, *con_conf;
int con_class = 0;
connecting = FALSE;
Debug((DEBUG_NOTICE,"Connection check at : %s", myctime(now)));
for (aconf = conf; aconf; aconf = aconf->next )
{
/* Also when already connecting! (update holdtimes) --SRB */
if (!(aconf->status & CONF_CONNECT_SERVER) || aconf->port <= 0)
continue;
cltmp = Class(aconf);
/*
** Skip this entry if the use of it is still on hold until
** future. Otherwise handle this entry (and set it on hold
** until next time). Will reset only hold times, if already
** made one successfull connection... [this algorithm is
** a bit fuzzy... -- msa >;) ]
*/
if ((aconf->hold > now))
{
if ((next > aconf->hold) || (next == 0))
next = aconf->hold;
continue;
}
confrq = get_con_freq(cltmp);
aconf->hold = now + confrq;
/*
** Found a CONNECT config with port specified, scan clients
** and see if this server is already connected?
*/
cptr = find_name(aconf->name, (aClient *)NULL);
if (!cptr && (Links(cltmp) < MaxLinks(cltmp)) &&
(!connecting || (Class(cltmp) > con_class)))
{
/* Check connect rules to see if we're allowed to try */
for (cconf = conf; cconf; cconf = cconf->next)
if ((cconf->status & CONF_CRULE) &&
(matches(cconf->host, aconf->name) == 0))
if (crule_eval (cconf->passwd))
break;
if (!cconf)
{
con_class = Class(cltmp);
con_conf = aconf;
/* We connect only one at time... */
connecting = TRUE;
}
}
if ((next > aconf->hold) || (next == 0))
next = aconf->hold;
}
if (connecting)
{
if (con_conf->next) /* are we already last? */
{
for (pconf = &conf; (aconf = *pconf);
pconf = &(aconf->next))
/* put the current one at the end and
* make sure we try all connections
*/
if (aconf == con_conf)
*pconf = aconf->next;
(*pconf = con_conf)->next = 0;
}
if (connect_server(con_conf, (aClient *)NULL,
(struct hostent *)NULL) == 0)
sendto_ops("Connection to %s[%s] activated.",
con_conf->name, con_conf->host);
}
Debug((DEBUG_NOTICE,"Next connection check : %s", myctime(next)));
return (next);
}
static time_t check_pings()
{
Reg1 aClient *cptr;
int ping = 0, i, rflag = 0;
time_t oldest = 0, timeout;
for (i = 0; i <= highest_fd; i++)
{
if (!(cptr = local[i]) || IsMe(cptr) ||
IsLog(cptr) || IsPing(cptr)) continue;
/*
** Note: No need to notify opers here. It's
** already done when "FLAGS_DEADSOCKET" is set.
*/
if (IsDead(cptr))
{
(void)exit_client(cptr, cptr, &me, last_dead_comment);
continue;
}
#ifdef R_LINES_OFTEN
rflag = IsPerson(cptr) ? find_restrict(cptr) : 0;
#endif
ping = IsRegistered(cptr) ? get_client_ping(cptr) :
CONNECTTIMEOUT;
Debug((DEBUG_DEBUG, "c(%s)=%d p %d r %d a %d",
cptr->name, cptr->status, ping, rflag,
now - cptr->lasttime));
/*
* Ok, so goto's are ugly and can be avoided here but this code
* is already indented enough so I think its justified. -avalon
*/
if (!rflag && IsRegistered(cptr) &&
(ping >= now - cptr->lasttime))
goto ping_timeout;
/*
* If the server hasnt talked to us in 2*ping seconds
* and it has a ping time, then close its connection.
* If the client is a user and a KILL line was found
* to be active, close this connection too.
*/
if (rflag ||
((now - cptr->lasttime) >= (2 * ping) &&
(cptr->flags & FLAGS_PINGSENT)) ||
(!IsRegistered(cptr) && !IsHandshake(cptr) &&
(now - cptr->firsttime) >= ping))
{
if (!IsRegistered(cptr) &&
(DoingDNS(cptr) || DoingAuth(cptr)))
{
if (cptr->authfd >= 0)
{
(void)close(cptr->authfd);
cptr->authfd = -1;
cptr->count = 0;
*cptr->buffer = '\0';
}
Debug((DEBUG_NOTICE,
"DNS/AUTH timeout %s",
get_client_name(cptr,TRUE)));
del_queries((char *)cptr);
ClearAuth(cptr);
ClearDNS(cptr);
SetAccess(cptr);
cptr->firsttime = now;
cptr->lasttime = now;
continue;
}
if (IsServer(cptr) || IsConnecting(cptr) ||
IsHandshake(cptr))
{
sendto_ops("No response from %s, closing link",
get_client_name(cptr, FALSE));
(void)exit_client(cptr, cptr, &me,
"Ping timeout");
continue;
}
/*
* this is used for KILL lines with time restrictions
* on them - send a messgae to the user being killed
* first.
*/
#if defined(R_LINES) && defined(R_LINES_OFTEN)
else if (IsPerson(cptr) && rflag)
{
sendto_ops("Restricting %s, closing link.",
get_client_name(cptr,FALSE));
(void)exit_client(cptr, cptr, &me, "R-lined");
}
#endif
else
{
if((!IsRegistered(cptr)) && (cptr->name) &&
(cptr->user->username))
{
sendto_one(cptr,
":%s %d %s :Your client may not be compatible with this server.",
me.name, ERR_BADPING, cptr->name);
sendto_one(cptr,
":%s %d %s :Compatible clients are available at ftp://ftp.undernet.org/pub/irc/clients",
me.name, ERR_BADPING, cptr->name);
}
(void)exit_client_msg(cptr, cptr, &me,
"Ping timeout for %s",
get_client_name(cptr,FALSE));
}
continue;
}
else if (IsRegistered(cptr) &&
(cptr->flags & FLAGS_PINGSENT) == 0)
{
/*
* if we havent PINGed the connection and we havent
* heard from it in a while, PING it to make sure
* it is still alive.
*/
cptr->flags |= FLAGS_PINGSENT;
/* not nice but does the job */
cptr->lasttime = now - ping;
sendto_one(cptr, "PING :%s", me.name);
}
ping_timeout:
timeout = cptr->lasttime + ping;
while (timeout <= now)
timeout += ping;
if (timeout < oldest || !oldest)
oldest = timeout;
}
if (!oldest || oldest < now)
oldest = now + PINGFREQUENCY;
Debug((DEBUG_NOTICE,"Next check_ping() call at: %s, %d %d %d",
myctime(oldest), ping, oldest, now));
return (oldest);
}
/*
** bad_command
** This is called when the commandline is not acceptable.
** Give error message and exit without starting anything.
*/
static int bad_command()
{
(void)printf(
"Usage: ircd %s[-h servername] [-p portnumber] [-x loglevel] [-t]\n",
#ifdef CMDLINE_CONFIG
"[-f config] "
#else
""
#endif
);
(void)printf("Server not started\n\n");
return (-1);
}
int main(argc, argv)
int argc;
char *argv[];
{
int portarg = 0;
uid_t uid, euid;
time_t delay = 0;
#ifdef FORCE_CORE
struct rlimit corelim;
#endif
sbrk0 = (char *)sbrk((size_t)0);
uid = getuid();
euid = geteuid();
now = time(NULL);
#ifdef PROFIL
(void)monstartup(0, etext);
(void)moncontrol(1);
(void)signal(SIGUSR1, s_monitor);
#endif
#ifdef CHROOTDIR
if (chdir(dpath))
{
perror("chdir");
exit(-1);
}
res_init();
if (chroot(DPATH))
{
(void)fprintf(stderr,"ERROR: Cannot chdir/chroot\n");
exit(5);
}
#endif /*CHROOTDIR*/
myargv = argv;
(void)umask(077); /* better safe than sorry --SRB */
bzero((char *)&me, sizeof(me));
setup_signals();
initload();
#ifdef FORCE_CORE
corelim.rlim_cur = corelim.rlim_max = RLIM_INFINITY;
if (setrlimit(RLIMIT_CORE, &corelim))
printf("unlimit core size failed; errno = %d\n", errno);
#endif
/*
** All command line parameters have the syntax "-fstring"
** or "-f string" (e.g. the space is optional). String may
** be empty. Flag characters cannot be concatenated (like
** "-fxyz"), it would conflict with the form "-fstring".
*/
while (--argc > 0 && (*++argv)[0] == '-')
{
char *p = argv[0]+1;
int flag = *p++;
if (flag == '\0' || *p == '\0')
if (argc > 1 && argv[1][0] != '-')
{
p = *++argv;
argc -= 1;
}
else
p = "";
switch (flag)
{
case 'a':
bootopt |= BOOT_AUTODIE;
break;
case 'c':
bootopt |= BOOT_CONSOLE;
break;
case 'q':
bootopt |= BOOT_QUICK;
break;
case 'd' :
(void)setuid((uid_t)uid);
dpath = p;
break;
case 'o': /* Per user local daemon... */
(void)setuid((uid_t)uid);
bootopt |= BOOT_OPER;
break;
#ifdef CMDLINE_CONFIG
case 'f':
(void)setuid((uid_t)uid);
configfile = p;
break;
#endif
case 'h':
strncpyzt(me.name, p, sizeof(me.name));
break;
case 'i':
bootopt |= BOOT_INETD|BOOT_AUTODIE;
break;
case 'p':
if ((portarg = atoi(p)) > 0 )
portnum = portarg;
break;
case 't':
(void)setuid((uid_t)uid);
bootopt |= BOOT_TTY;
break;
case 'v':
(void)printf("ircd %s\n", version);
exit(0);
case 'x':
#ifdef DEBUGMODE
(void)setuid((uid_t)uid);
debuglevel = atoi(p);
debugmode = *p ? p : "0";
bootopt |= BOOT_DEBUG;
break;
#else
(void)fprintf(stderr,
"%s: DEBUGMODE must be defined for -x y\n",
myargv[0]);
exit(0);
#endif
default:
bad_command();
break;
}
}
#ifndef CHROOT
if (chdir(dpath))
{
perror("chdir");
exit(-1);
}
#endif
#ifndef IRC_UID
if ((uid != euid) && !euid)
{
(void)fprintf(stderr,
"ERROR: do not run ircd setuid root. Make it setuid a\
normal user.\n");
exit(-1);
}
#endif
#if !defined(CHROOTDIR) || (defined(IRC_UID) && defined(IRC_GID))
# ifndef AIX
(void)setuid((uid_t)uid);
(void)setuid((uid_t)euid);
# endif
if ((int)getuid() == 0)
{
# if defined(IRC_UID) && defined(IRC_GID)
/* run as a specified user */
(void)fprintf(stderr,"WARNING: running ircd with uid = %d\n",
IRC_UID);
(void)fprintf(stderr," changing to gid %d.\n",IRC_GID);
(void)setuid(IRC_UID);
(void)setgid(IRC_GID);
#else
/* check for setuid root as usual */
(void)fprintf(stderr,
"ERROR: do not run ircd setuid root. Make it setuid a\
normal user.\n");
exit(-1);
# endif
}
#endif /*CHROOTDIR/UID/GID*/
/* didn't set debuglevel */
/* but asked for debugging output to tty */
if ((debuglevel < 0) && (bootopt & BOOT_TTY))
{
(void)fprintf(stderr,
"you specified -t without -x. use -x <n>\n");
exit(-1);
}
if (argc > 0)
return bad_command(); /* This should exit out */
clear_client_hash_table();
clear_channel_hash_table();
initlists();
initclass();
initwhowas();
initstats();
open_debugfile();
if (portnum < 0)
portnum = PORTNUM;
me.port = portnum;
(void)init_sys();
me.flags = FLAGS_LISTEN;
if (bootopt & BOOT_INETD)
{
me.fd = 0;
local[0] = &me;
me.flags = FLAGS_LISTEN;
}
else
me.fd = -1;
#ifdef USE_SYSLOG
openlog(myargv[0], LOG_PID|LOG_NDELAY, LOG_FACILITY);
#endif
if (initconf(bootopt) == -1)
{
Debug((DEBUG_FATAL, "Failed in reading configuration file %s",
configfile));
(void)printf("Couldn't open configuration file %s\n",
configfile);
exit(-1);
}
if (!(bootopt & BOOT_INETD))
{
static char star[] = "*";
aConfItem *aconf;
if ((aconf = find_me()) && portarg <= 0 && aconf->port > 0)
portnum = aconf->port;
Debug((DEBUG_ERROR, "Port = %d", portnum));
if (inetport(&me, star, portnum))
exit(1);
}
else if (inetport(&me, "*", 0))
exit(1);
(void)setup_ping();
(void)get_my_name(&me, me.sockhost, sizeof(me.sockhost)-1);
if (me.name[0] == '\0')
strncpyzt(me.name, "undernet.org", sizeof(me.name));
now = time(NULL);
me.hopcount = 0;
me.authfd = -1;
me.confs = NULL;
me.next = NULL;
me.user = NULL;
me.from = &me;
SetMe(&me);
make_server(&me);
/* Abuse own link timestamp as start timestamp: */
me.serv->timestamp = TStime();
me.serv->prot = atoi(MAJOR_PROTOCOL);
me.serv->up = &me;
me.serv->down = NULL;
me.serv->client = NULL;
me.lasttime = me.since = me.firsttime = now;
(void)add_to_client_hash_table(me.name, &me);
check_class();
if (bootopt & BOOT_OPER)
{
aClient *tmp = add_connection(&me, 0);
if (!tmp)
exit(1);
SetMaster(tmp);
}
else
write_pidfile();
Debug((DEBUG_NOTICE,"Server ready..."));
#ifdef USE_SYSLOG
syslog(LOG_NOTICE, "Server Ready");
#endif
for (;;)
{
/*
** We only want to connect if a connection is due,
** not every time through. Note, if there are no
** active C lines, this call to Tryconnections is
** made once only; it will return 0. - avalon
*/
if (nextconnect && now >= nextconnect)
nextconnect = try_connections();
/*
** DNS checks. One to timeout queries, one for cache expiries.
*/
if (now >= nextdnscheck)
nextdnscheck = timeout_query_list();
if (now >= nextexpire)
nextexpire = expire_cache();
/*
** take the smaller of the two 'timed' event times as
** the time of next event (stops us being late :) - avalon
** WARNING - nextconnect can return 0!
*/
if (nextconnect)
delay = MIN(nextping, nextconnect);
else
delay = nextping;
delay = MIN(nextdnscheck, delay);
delay = MIN(nextexpire, delay);
delay -= now;
/*
** Adjust delay to something reasonable [ad hoc values]
** (one might think something more clever here... --msa)
** We don't really need to check that often and as long
** as we don't delay too long, everything should be ok.
** waiting too long can cause things to timeout...
** i.e. PINGS -> a disconnection :(
** - avalon
*/
if (delay < 1)
delay = 1;
else
delay = MIN(delay, TIMESEC);
(void)read_message(delay);
Debug((DEBUG_DEBUG ,"Got message(s)"));
/*
** ...perhaps should not do these loops every time,
** but only if there is some chance of something
** happening (but, note that conf->hold times may
** be changed elsewhere--so precomputed next event
** time might be too far away... (similarly with
** ping times) --msa
*/
if (now >= nextping)
nextping = check_pings();
if (dorehash)
{
(void)rehash(&me, &me, 1);
dorehash = 0;
}
/*
** Flush output buffers on all connections now if they
** have data in them (or at least try to flush)
** -avalon
*/
/* What is this doing here ??? Pure cpu waste...
flush_connections(me.fd);
writes are already done in read_message(), which
uses select(). flush_connections doesn't even !!!
--Run
*/
}
}
/*
* open_debugfile
*
* If the -t option is not given on the command line when the server is
* started, all debugging output is sent to the file set by LPATH in config.h
* Here we just open that file and make sure it is opened to fd 2 so that
* any fprintf's to stderr also goto the logfile. If the debuglevel is not
* set from the command line by -x, use /dev/null as the dummy logfile as long
* as DEBUGMODE has been defined, else dont waste the fd.
*/
static void open_debugfile()
{
#ifdef DEBUGMODE
int fd;
aClient *cptr;
if (debuglevel >= 0)
{
cptr = make_client(NULL);
cptr->fd = 2;
SetLog(cptr);
cptr->port = debuglevel;
cptr->flags = 0;
cptr->acpt = cptr;
local[2] = cptr;
(void)strcpy(cptr->sockhost, me.sockhost);
(void)printf("isatty = %d ttyname = %#x\n",
isatty(2), (u_int)ttyname(2));
if (!(bootopt & BOOT_TTY)) /* leave debugging output on fd 2 */
{
(void)truncate(LOGFILE, 0);
if ((fd = open(LOGFILE, O_WRONLY | O_CREAT, 0600)) < 0)
if ((fd = open("/dev/null", O_WRONLY)) < 0)
exit(-1);
if (fd != 2)
{
(void)dup2(fd, 2);
(void)close(fd);
}
strncpyzt(cptr->name, LOGFILE, sizeof(cptr->name));
}
else if (isatty(2) && ttyname(2))
strncpyzt(cptr->name, ttyname(2), sizeof(cptr->name));
else
(void)strcpy(cptr->name, "FD2-Pipe");
Debug((DEBUG_FATAL, "Debug: File <%s> Level: %d at %s",
cptr->name, cptr->port, myctime(now)));
}
else
local[2] = NULL;
#endif
return;
}
static void setup_signals()
{
#ifdef POSIX_SIGNALS
struct sigaction act;
act.sa_handler = SIG_IGN;
act.sa_flags = 0;
(void)sigemptyset(&act.sa_mask);
(void)sigaddset(&act.sa_mask, SIGPIPE);
(void)sigaddset(&act.sa_mask, SIGALRM);
# ifdef SIGWINCH
(void)sigaddset(&act.sa_mask, SIGWINCH);
(void)sigaction(SIGWINCH, &act, NULL);
# endif
(void)sigaction(SIGPIPE, &act, NULL);
act.sa_handler = dummy;
(void)sigaction(SIGALRM, &act, NULL);
act.sa_handler = s_rehash;
(void)sigemptyset(&act.sa_mask);
(void)sigaddset(&act.sa_mask, SIGHUP);
(void)sigaction(SIGHUP, &act, NULL);
act.sa_handler = s_restart;
(void)sigaddset(&act.sa_mask, SIGINT);
(void)sigaction(SIGINT, &act, NULL);
act.sa_handler = s_die;
(void)sigaddset(&act.sa_mask, SIGTERM);
(void)sigaction(SIGTERM, &act, NULL);
#else
# ifndef HAVE_RELIABLE_SIGNALS
(void)signal(SIGPIPE, dummy);
# ifdef SIGWINCH
(void)signal(SIGWINCH, dummy);
# endif
# else
# ifdef SIGWINCH
(void)signal(SIGWINCH, SIG_IGN);
# endif
(void)signal(SIGPIPE, SIG_IGN);
# endif
(void)signal(SIGALRM, dummy);
(void)signal(SIGHUP, s_rehash);
(void)signal(SIGTERM, s_die);
(void)signal(SIGINT, s_restart);
#endif
#ifdef RESTARTING_SYSTEMCALLS
/*
** At least on Apollo sr10.1 it seems continuing system calls
** after signal is the default. The following 'siginterrupt'
** should change that default to interrupting calls.
*/
(void)siginterrupt(SIGALRM, 1);
#endif
}

543
ircd/list.c Normal file
View File

@@ -0,0 +1,543 @@
/************************************************************************
* IRC - Internet Relay Chat, ircd/list.c
* Copyright (C) 1990 Jarkko Oikarinen and
* University of Oulu, Finland
*
* 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 1, 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.
*/
/* -- Jto -- 20 Jun 1990
* extern void free() fixed as suggested by
* gruner@informatik.tu-muenchen.de
*/
/* -- Jto -- 03 Jun 1990
* Added chname initialization...
*/
/* -- Jto -- 24 May 1990
* Moved is_full() to channel.c
*/
/* -- Jto -- 10 May 1990
* Added #include <sys.h>
* Changed memset(xx,0,yy) into bzero(xx,yy)
*/
#ifndef lint
static char sccsid[] = "@(#)list.c 2.24 4/20/94 (C) 1988 University of Oulu, \
Computing Center and Jarkko Oikarinen";
#endif
#include "struct.h"
#include "common.h"
#include "sys.h"
#include "h.h"
#include "numeric.h"
#ifdef DBMALLOC
#include "malloc.h"
#endif
void free_link PROTO((Link *));
Link *make_link PROTO(());
#ifdef DEBUGMODE
static struct liststats {
int inuse;
} cloc, crem, users, servs, links, classs, aconfs;
#endif
void outofmemory();
int numclients = 0;
void initlists()
{
#ifdef DEBUGMODE
bzero((char *)&cloc, sizeof(cloc));
bzero((char *)&crem, sizeof(crem));
bzero((char *)&users, sizeof(users));
bzero((char *)&servs, sizeof(servs));
bzero((char *)&links, sizeof(links));
bzero((char *)&classs, sizeof(classs));
bzero((char *)&aconfs, sizeof(aconfs));
#endif
}
void outofmemory()
{
Debug((DEBUG_FATAL, "Out of memory: restarting server..."));
restart("Out of Memory");
}
/*
** Create a new aClient structure and set it to initial state.
**
** from == NULL, create local client (a client connected
** to a socket).
**
** from, create remote client (behind a socket
** associated with the client defined by
** 'from'). ('from' is a local client!!).
*/
aClient *make_client(from)
aClient *from;
{
Reg1 aClient *cptr = NULL;
Reg2 unsigned size = CLIENT_REMOTE_SIZE;
/*
* Check freelists first to see if we can grab a client without
* having to call malloc.
*/
if (!from)
size = CLIENT_LOCAL_SIZE;
if (!(cptr = (aClient *)MyMalloc(size)))
outofmemory();
bzero((char *)cptr, (int)size);
#ifdef DEBUGMODE
if (size == CLIENT_LOCAL_SIZE)
cloc.inuse++;
else
crem.inuse++;
#endif
/* Note: structure is zero (calloc) */
cptr->from = from ? from : cptr; /* 'from' of local client is self! */
cptr->next = NULL; /* For machines with NON-ZERO NULL pointers >;) */
cptr->prev = NULL;
cptr->hnext = NULL;
cptr->user = NULL;
cptr->serv = NULL;
cptr->status = STAT_UNKNOWN;
cptr->fd = -1;
(void)strcpy(cptr->username, "unknown");
if (size == CLIENT_LOCAL_SIZE)
{
cptr->since = cptr->lasttime = cptr->firsttime = now;
cptr->lastnick = TStime();
#ifdef NICK_DELAY
cptr->nextnick = now - NICK_DELAY;
#endif /* NICK_DELAY */
cptr->cookie = 0;
cptr->confs = NULL;
cptr->sockhost[0] = '\0';
cptr->buffer[0] = '\0';
cptr->authfd = -1;
cptr->listing = NULL;
}
return (cptr);
}
void free_client(cptr)
aClient *cptr;
{
MyFree((char *)cptr);
}
/*
** 'make_user' add's an User information block to a client
** if it was not previously allocated.
*/
anUser *make_user(cptr)
aClient *cptr;
{
Reg1 anUser *user;
user = cptr->user;
if (!user)
{
user = (anUser *)MyMalloc(sizeof(anUser));
#ifdef DEBUGMODE
users.inuse++;
#endif
user->away = NULL;
user->refcnt = 1;
user->joined = 0;
user->channel = NULL;
user->invited = NULL;
user->silence = NULL;
cptr->user = user;
}
return user;
}
aServer *make_server(cptr)
aClient *cptr;
{
Reg1 aServer *serv = cptr->serv;
if (!serv)
{
serv = (aServer *)MyMalloc(sizeof(aServer));
#ifdef DEBUGMODE
servs.inuse++;
#endif
serv->ghost = 0;
cptr->serv = serv;
serv->user = NULL;
serv->nexts = NULL;
*serv->by = '\0';
serv->up = NULL;
serv->down = NULL;
serv->client = NULL;
}
return cptr->serv;
}
/*
** free_user
** Decrease user reference count by one and realease block,
** if count reaches 0
*/
void free_user(user, cptr)
Reg1 anUser *user;
aClient *cptr;
{
if (--user->refcnt <= 0)
{
if (user->away)
MyFree((char *)user->away);
/*
* sanity check
*/
if (user->joined || user->refcnt < 0 ||
user->invited || user->channel)
#ifdef DEBUGMODE
dumpcore("%#x user (%s!%s@%s) %#x %#x %#x %d %d",
cptr, cptr ? cptr->name : "<noname>",
user->username, user->host, user,
user->invited, user->channel, user->joined,
user->refcnt);
#else
sendto_ops("* %#x user (%s!%s@%s) %#x %#x %#x %d %d *",
cptr, cptr ? cptr->name : "<noname>",
user->username, user->host, user,
user->invited, user->channel, user->joined,
user->refcnt);
#endif
MyFree((char *)user);
#ifdef DEBUGMODE
users.inuse--;
#endif
}
}
/*
* taken the code from ExitOneClient() for this and placed it here.
* - avalon
*/
void remove_client_from_list(cptr)
Reg1 aClient *cptr;
{
checklist();
if (cptr->prev)
cptr->prev->next = cptr->next;
else
{
client = cptr->next;
client->prev = NULL;
}
if (cptr->next)
cptr->next->prev = cptr->prev;
if (IsPerson(cptr) && cptr->user)
{
add_history(cptr);
off_history(cptr);
}
if (cptr->user)
{
cptr->user->clink = NULL;
(void)free_user(cptr->user, cptr);
}
if (cptr->serv)
{
if (cptr->serv->user)
free_user(cptr->serv->user, cptr);
MyFree((char *)cptr->serv);
#ifdef DEBUGMODE
servs.inuse--;
#endif
}
#ifdef DEBUGMODE
if (cptr->fd == -2)
cloc.inuse--;
else
crem.inuse--;
#endif
(void)free_client(cptr);
numclients--;
return;
}
/*
* although only a small routine, it appears in a number of places
* as a collection of a few lines...functions like this *should* be
* in this file, shouldnt they ? after all, this is list.c, isnt it ?
* -avalon
*/
void add_client_to_list(cptr)
aClient *cptr;
{
/*
* since we always insert new clients to the top of the list,
* this should mean the "me" is the bottom most item in the list.
*/
cptr->next = client;
client = cptr;
if (cptr->next)
cptr->next->prev = cptr;
return;
}
/*
* Look for ptr in the linked listed pointed to by link.
*/
Link *find_user_link(lp, ptr)
Reg1 Link *lp;
Reg2 aClient *ptr;
{
if (ptr)
while (lp)
{
if (lp->value.cptr == ptr)
return (lp);
lp = lp->next;
}
return NULL;
}
Link *make_link()
{
Reg1 Link *lp;
lp = (Link *)MyMalloc(sizeof(Link));
#ifdef DEBUGMODE
links.inuse++;
#endif
return lp;
}
void free_link(lp)
Reg1 Link *lp;
{
MyFree((char *)lp);
#ifdef DEBUGMODE
links.inuse--;
#endif
}
Dlink *add_dlink(lpp, cp)
Dlink **lpp;
aClient *cp;
{ register Dlink *lp;
lp = (Dlink *)MyMalloc(sizeof(Dlink));
lp->value.cptr = cp;
lp->prev = NULL;
if ((lp->next = *lpp))
lp->next->prev = lp;
*lpp = lp;
return lp;
}
void remove_dlink(lpp, lp)
Dlink **lpp, *lp;
{
if (lp->prev)
{ if ((lp->prev->next = lp->next))
lp->next->prev = lp->prev; }
else if ((*lpp = lp->next))
lp->next->prev = NULL;
MyFree(lp);
}
aClass *make_class()
{
Reg1 aClass *tmp;
tmp = (aClass *)MyMalloc(sizeof(aClass));
#ifdef DEBUGMODE
classs.inuse++;
#endif
return tmp;
}
void free_class(tmp)
Reg1 aClass *tmp;
{
MyFree((char *)tmp);
#ifdef DEBUGMODE
classs.inuse--;
#endif
}
aConfItem *make_conf()
{
Reg1 aConfItem *aconf;
aconf = (struct ConfItem *)MyMalloc(sizeof(aConfItem));
#ifdef DEBUGMODE
aconfs.inuse++;
#endif
bzero((char *)&aconf->ipnum, sizeof(struct in_addr));
aconf->next = NULL;
aconf->host = aconf->passwd = aconf->name = NULL;
aconf->status = CONF_ILLEGAL;
aconf->clients = 0;
aconf->port = 0;
aconf->hold = 0;
Class(aconf) = 0;
return (aconf);
}
void delist_conf(aconf)
aConfItem *aconf;
{
if (aconf == conf)
conf = conf->next;
else
{
aConfItem *bconf;
for (bconf = conf; aconf != bconf->next; bconf = bconf->next)
;
bconf->next = aconf->next;
}
aconf->next = NULL;
}
void free_conf(aconf)
aConfItem *aconf;
{
aClient *cptr = &me;
del_queries((char *)aconf);
MyFree(aconf->host);
if (aconf->passwd)
bzero(aconf->passwd, strlen(aconf->passwd));
MyFree(aconf->passwd);
MyFree(aconf->name);
MyFree((char *)aconf);
#ifdef DEBUGMODE
aconfs.inuse--;
#endif
return;
}
aGline *make_gline(host, reason, name, expire)
char *host, *reason, *name;
time_t expire;
{
Reg4 aGline *agline;
agline = (struct Gline *)MyMalloc(sizeof(aGline)); /* alloc memory */
DupString(agline->host, host); /* copy vital information */
DupString(agline->reason, reason);
DupString(agline->name, name);
agline->expire = expire;
agline->active = GLINE_ACTIVE; /* gline is active */
agline->next = gline; /* link it into the list */
return (gline = agline);
}
aGline *find_gline(host, name, pgline)
Reg1 char *host, *name;
aGline **pgline;
{
Reg3 aGline *agline = gline, *a2gline = NULL;
while (agline) { /* look through all glines */
if (agline->expire <= TStime()) { /* handle expired glines */
free_gline(agline, a2gline);
agline = a2gline ? a2gline->next : gline;
if (!agline) break; /* agline == NULL means gline == NULL */
continue;
}
/* does gline match? */
if (match(agline->host, host) == 0 && match(agline->name, name) == 0) {
if (pgline) *pgline = a2gline; /* if they need it, give them the
previous gline entry (probably
for free_gline, below) */
return agline;
}
a2gline = agline;
agline = agline->next;
}
return NULL; /* found no glines */
}
void free_gline(agline, pgline)
aGline *agline, *pgline;
{
if (pgline) pgline->next = agline->next; /* squeeze agline out */
else gline = agline->next;
MyFree(agline->host); /* and free up the memory */
MyFree(agline->reason);
MyFree(agline->name);
MyFree((char *)agline);
}
#ifdef DEBUGMODE
void send_listinfo(cptr, name)
aClient *cptr;
char *name;
{
int inuse = 0, mem = 0, tmp = 0;
sendto_one(cptr, ":%s %d %s :Local: inuse: %d(%d)",
me.name, RPL_STATSDEBUG, name, inuse += cloc.inuse,
tmp = cloc.inuse * CLIENT_LOCAL_SIZE);
mem += tmp;
sendto_one(cptr, ":%s %d %s :Remote: inuse: %d(%d)",
me.name, RPL_STATSDEBUG, name,
crem.inuse, tmp = crem.inuse * CLIENT_REMOTE_SIZE);
mem += tmp;
inuse += crem.inuse;
sendto_one(cptr, ":%s %d %s :Users: inuse: %d(%d)",
me.name, RPL_STATSDEBUG, name, users.inuse,
tmp = users.inuse * sizeof(anUser));
mem += tmp;
inuse += users.inuse,
sendto_one(cptr, ":%s %d %s :Servs: inuse: %d(%d)",
me.name, RPL_STATSDEBUG, name, servs.inuse,
tmp = servs.inuse * sizeof(aServer));
mem += tmp;
inuse += servs.inuse,
sendto_one(cptr, ":%s %d %s :Links: inuse: %d(%d)",
me.name, RPL_STATSDEBUG, name, links.inuse,
tmp = links.inuse * sizeof(Link));
mem += tmp;
inuse += links.inuse,
sendto_one(cptr, ":%s %d %s :Classes: inuse: %d(%d)",
me.name, RPL_STATSDEBUG, name, classs.inuse,
tmp = classs.inuse * sizeof(aClass));
mem += tmp;
inuse += classs.inuse,
sendto_one(cptr, ":%s %d %s :Confs: inuse: %d(%d)",
me.name, RPL_STATSDEBUG, name, aconfs.inuse,
tmp = aconfs.inuse * sizeof(aConfItem));
mem += tmp;
inuse += aconfs.inuse,
sendto_one(cptr, ":%s %d %s :Totals: inuse %d %d",
me.name, RPL_STATSDEBUG, name, inuse, mem);
}
#endif

97
ircd/map.c Normal file
View File

@@ -0,0 +1,97 @@
/************************************************************************
* IRC - Internet Relay Chat, ircd/s_ping.c
* Copyright (C) 1994 Carlo K ( Run @ undernet.org )
*
* 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 1, 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.
*/
#ifndef lint
static char sccsid[] = "@(#)s_ping.c 1.0 9/30/94 (C) 1994 Carlo Kid";
#endif
#include "struct.h"
#include "common.h"
#include "sys.h"
#include "h.h"
#include "numeric.h"
void dump_map(cptr, server, mask, prompt_length)
aClient *cptr, *server;
char *mask;
register int prompt_length;
{
static char prompt[64];
register Dlink *lp;
register char *p = &prompt[prompt_length];
register int cnt = 0;
*p='\0';
if (prompt_length > 60)
sendto_one(cptr, rpl_str(RPL_MAPMORE), me.name, cptr->name,
prompt, server->name);
else
sendto_one(cptr, rpl_str(RPL_MAP), me.name, cptr->name,
prompt, server->name);
if (prompt_length > 0)
{
p[-1] = ' ';
if (p[-2] == '`')
p[-2] = ' ';
}
if (prompt_length > 60)
return;
strcpy(p, "|-");
for (lp=server->serv->down; lp; lp=lp->next)
if (matches(mask, lp->value.cptr->name))
lp->value.cptr->flags &= ~FLAGS_MAP;
else
{
lp->value.cptr->flags |= FLAGS_MAP;
cnt++;
}
for (lp=server->serv->down; lp; lp=lp->next)
{
if ((lp->value.cptr->flags & FLAGS_MAP) == 0)
continue;
if (--cnt == 0)
*p = '`';
dump_map(cptr, lp->value.cptr, mask, prompt_length+2);
}
if (prompt_length > 0)
p[-1] = '-';
}
/*
** m_map -- by Run
**
** parv[0] = sender prefix
** parv[1] = server mask
**/
int m_map(cptr, sptr, parc, parv)
aClient *cptr, *sptr;
int parc;
char *parv[];
{
if (check_registered_user(sptr))
return 0;
if (parc < 2)
parv[1]="*";
dump_map(sptr, &me, parv[1], 0);
sendto_one(sptr, rpl_str(RPL_MAPEND), me.name, parv[0]);
return 0;
}

3563
ircd/note.c Normal file

File diff suppressed because it is too large Load Diff

158
ircd/random.c Normal file
View File

@@ -0,0 +1,158 @@
/************************************************************************
* IRC - Internet Relay Chat, ircd/random.c
*
* 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 1, 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.
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sys/time.h>
#include "config.h"
char localkey[8] = RANDOM_SEED;
/*
* MD5 transform algorithm, taken from code written by Colin Plumb,
* and put into the public domain
*
* Kev: Taken from Ted T'so's /dev/random random.c code and modified to
* be slightly simpler. That code is released under a BSD-style copyright
* OR under the terms of the GNU Public License, which should be included
* at the top of this source file.
*
* record: Cleaned up to work with ircd. RANDOM_TOKEN is defined in
* setup.h by the make script; if people start to "guess" your cookies,
* consider recompiling your server with a different random token.
*/
/* The four core functions - F1 is optimized somewhat */
#define F1(x, y, z) (z ^ (x & (y ^ z)))
#define F2(x, y, z) F1(z, x, y)
#define F3(x, y, z) (x ^ y ^ z)
#define F4(x, y, z) (y ^ (x | ~z))
/* This is the central step in the MD5 algorithm. */
#define MD5STEP(f, w, x, y, z, data, s) \
( w += f(x, y, z) + data, w = w<<s | w>>(32-s), w += x )
/*
* The core of the MD5 algorithm, this alters an existing MD5 hash to
* reflect the addition of 16 longwords of new data. MD5Update blocks
* the data and converts bytes into longwords for this routine.
*
* original comment left in; this used to be called MD5Transform and took
* two arguments; I've internalized those arguments, creating the character
* array "localkey," which should contain 8 bytes of data. The function also
* originally returned nothing; now it returns an unsigned long that is the
* random number. It appears to be reallyrandom, so... -Kev
*
* I don't really know what this does. I tried to figure it out and got
* a headache. If you know what's good for you, you'll leave this stuff
* for the smart people and do something else. -record
*/
unsigned long ircrandom(void)
{
unsigned long a, b, c, d;
unsigned char in[16];
struct timeval tv;
(void)gettimeofday(&tv, NULL);
(void)memcpy((void *)in, (void *)localkey, 8);
(void)memcpy((void *)(in+8), (void *)&tv.tv_sec, 4);
(void)memcpy((void *)(in+12), (void *)&tv.tv_usec, 4);
a = 0x67452301;
b = 0xefcdab89;
c = 0x98badcfe;
d = 0x10325476;
MD5STEP(F1, a, b, c, d, (long)in[ 0]+0xd76aa478, 7);
MD5STEP(F1, d, a, b, c, (long)in[ 1]+0xe8c7b756, 12);
MD5STEP(F1, c, d, a, b, (long)in[ 2]+0x242070db, 17);
MD5STEP(F1, b, c, d, a, (long)in[ 3]+0xc1bdceee, 22);
MD5STEP(F1, a, b, c, d, (long)in[ 4]+0xf57c0faf, 7);
MD5STEP(F1, d, a, b, c, (long)in[ 5]+0x4787c62a, 12);
MD5STEP(F1, c, d, a, b, (long)in[ 6]+0xa8304613, 17);
MD5STEP(F1, b, c, d, a, (long)in[ 7]+0xfd469501, 22);
MD5STEP(F1, a, b, c, d, (long)in[ 8]+0x698098d8, 7);
MD5STEP(F1, d, a, b, c, (long)in[ 9]+0x8b44f7af, 12);
MD5STEP(F1, c, d, a, b, (long)in[10]+0xffff5bb1, 17);
MD5STEP(F1, b, c, d, a, (long)in[11]+0x895cd7be, 22);
MD5STEP(F1, a, b, c, d, (long)in[12]+0x6b901122, 7);
MD5STEP(F1, d, a, b, c, (long)in[13]+0xfd987193, 12);
MD5STEP(F1, c, d, a, b, (long)in[14]+0xa679438e, 17);
MD5STEP(F1, b, c, d, a, (long)in[15]+0x49b40821, 22);
MD5STEP(F2, a, b, c, d, (long)in[ 1]+0xf61e2562, 5);
MD5STEP(F2, d, a, b, c, (long)in[ 6]+0xc040b340, 9);
MD5STEP(F2, c, d, a, b, (long)in[11]+0x265e5a51, 14);
MD5STEP(F2, b, c, d, a, (long)in[ 0]+0xe9b6c7aa, 20);
MD5STEP(F2, a, b, c, d, (long)in[ 5]+0xd62f105d, 5);
MD5STEP(F2, d, a, b, c, (long)in[10]+0x02441453, 9);
MD5STEP(F2, c, d, a, b, (long)in[15]+0xd8a1e681, 14);
MD5STEP(F2, b, c, d, a, (long)in[ 4]+0xe7d3fbc8, 20);
MD5STEP(F2, a, b, c, d, (long)in[ 9]+0x21e1cde6, 5);
MD5STEP(F2, d, a, b, c, (long)in[14]+0xc33707d6, 9);
MD5STEP(F2, c, d, a, b, (long)in[ 3]+0xf4d50d87, 14);
MD5STEP(F2, b, c, d, a, (long)in[ 8]+0x455a14ed, 20);
MD5STEP(F2, a, b, c, d, (long)in[13]+0xa9e3e905, 5);
MD5STEP(F2, d, a, b, c, (long)in[ 2]+0xfcefa3f8, 9);
MD5STEP(F2, c, d, a, b, (long)in[ 7]+0x676f02d9, 14);
MD5STEP(F2, b, c, d, a, (long)in[12]+0x8d2a4c8a, 20);
MD5STEP(F3, a, b, c, d, (long)in[ 5]+0xfffa3942, 4);
MD5STEP(F3, d, a, b, c, (long)in[ 8]+0x8771f681, 11);
MD5STEP(F3, c, d, a, b, (long)in[11]+0x6d9d6122, 16);
MD5STEP(F3, b, c, d, a, (long)in[14]+0xfde5380c, 23);
MD5STEP(F3, a, b, c, d, (long)in[ 1]+0xa4beea44, 4);
MD5STEP(F3, d, a, b, c, (long)in[ 4]+0x4bdecfa9, 11);
MD5STEP(F3, c, d, a, b, (long)in[ 7]+0xf6bb4b60, 16);
MD5STEP(F3, b, c, d, a, (long)in[10]+0xbebfbc70, 23);
MD5STEP(F3, a, b, c, d, (long)in[13]+0x289b7ec6, 4);
MD5STEP(F3, d, a, b, c, (long)in[ 0]+0xeaa127fa, 11);
MD5STEP(F3, c, d, a, b, (long)in[ 3]+0xd4ef3085, 16);
MD5STEP(F3, b, c, d, a, (long)in[ 6]+0x04881d05, 23);
MD5STEP(F3, a, b, c, d, (long)in[ 9]+0xd9d4d039, 4);
MD5STEP(F3, d, a, b, c, (long)in[12]+0xe6db99e5, 11);
MD5STEP(F3, c, d, a, b, (long)in[15]+0x1fa27cf8, 16);
MD5STEP(F3, b, c, d, a, (long)in[ 2]+0xc4ac5665, 23);
MD5STEP(F4, a, b, c, d, (long)in[ 0]+0xf4292244, 6);
MD5STEP(F4, d, a, b, c, (long)in[ 7]+0x432aff97, 10);
MD5STEP(F4, c, d, a, b, (long)in[14]+0xab9423a7, 15);
MD5STEP(F4, b, c, d, a, (long)in[ 5]+0xfc93a039, 21);
MD5STEP(F4, a, b, c, d, (long)in[12]+0x655b59c3, 6);
MD5STEP(F4, d, a, b, c, (long)in[ 3]+0x8f0ccc92, 10);
MD5STEP(F4, c, d, a, b, (long)in[10]+0xffeff47d, 15);
MD5STEP(F4, b, c, d, a, (long)in[ 1]+0x85845dd1, 21);
MD5STEP(F4, a, b, c, d, (long)in[ 8]+0x6fa87e4f, 6);
MD5STEP(F4, d, a, b, c, (long)in[15]+0xfe2ce6e0, 10);
MD5STEP(F4, c, d, a, b, (long)in[ 6]+0xa3014314, 15);
MD5STEP(F4, b, c, d, a, (long)in[13]+0x4e0811a1, 21);
MD5STEP(F4, a, b, c, d, (long)in[ 4]+0xf7537e82, 6);
MD5STEP(F4, d, a, b, c, (long)in[11]+0xbd3af235, 10);
MD5STEP(F4, c, d, a, b, (long)in[ 2]+0x2ad7d2bb, 15);
MD5STEP(F4, b, c, d, a, (long)in[ 9]+0xeb86d391, 21);
/*
* we have 4 unsigned longs generated by the above sequence; this scrambles
* them together so that if there is any pattern, it will be obscured.
*/
return (a ^ b ^ c ^ d);
}

1417
ircd/res.c Normal file

File diff suppressed because it is too large Load Diff

329
ircd/res_comp.c Normal file
View File

@@ -0,0 +1,329 @@
/*
* Copyright (c) 1985 Regents of the University of California.
* All rights reserved.
*
* Redistribution and use in source and binary forms are permitted provided
* that: (1) source distributions retain this entire copyright notice and
* comment, and (2) distributions including binaries display the following
* acknowledgement: ``This product includes software developed by the
* University of California, Berkeley and its contributors'' in the
* documentation or other materials provided with the distribution and in
* all advertising materials mentioning features or use of this software.
* Neither the name of the University nor the names of its contributors may
* be used to endorse or promote products derived from this software without
* specific prior written permission.
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
#if defined(LIBC_SCCS) && !defined(lint)
static char sccsid[] = "@(#)res_comp.c 6.18 (Berkeley) 6/27/90";
#endif /* LIBC_SCCS and not lint */
#include <sys/types.h>
#include <stdio.h>
#include "nameser.h"
static dn_find();
/*
* Expand compressed domain name 'comp_dn' to full domain name.
* 'msg' is a pointer to the begining of the message,
* 'eomorig' points to the first location after the message,
* 'exp_dn' is a pointer to a buffer of size 'length' for the result.
* Return size of compressed name or -1 if there was an error.
*/
dn_expand(msg, eomorig, comp_dn, exp_dn, length)
u_char *msg, *eomorig, *comp_dn, *exp_dn;
int length;
{
register u_char *cp, *dn;
register int n, c;
u_char *eom;
int len = -1, checked = 0;
dn = exp_dn;
cp = comp_dn;
eom = exp_dn + length;
/*
* fetch next label in domain name
*/
while (n = *cp++) {
/*
* Check for indirection
*/
switch (n & INDIR_MASK) {
case 0:
if (dn != exp_dn) {
if (dn >= eom)
return (-1);
*dn++ = '.';
}
if (dn+n >= eom)
return (-1);
checked += n + 1;
while (--n >= 0) {
if ((c = *cp++) == '.') {
if (dn + n + 2 >= eom)
return (-1);
*dn++ = '\\';
}
*dn++ = c;
if (cp >= eomorig) /* out of range */
return(-1);
}
break;
case INDIR_MASK:
if (len < 0)
len = cp - comp_dn + 1;
cp = msg + (((n & 0x3f) << 8) | (*cp & 0xff));
if (cp < msg || cp >= eomorig) /* out of range */
return(-1);
checked += 2;
/*
* Check for loops in the compressed name;
* if we've looked at the whole message,
* there must be a loop.
*/
if (checked >= eomorig - msg)
return (-1);
break;
default:
return (-1); /* flag error */
}
}
*dn = '\0';
if (len < 0)
len = cp - comp_dn;
return (len);
}
/*
* Compress domain name 'exp_dn' into 'comp_dn'.
* Return the size of the compressed name or -1.
* 'length' is the size of the array pointed to by 'comp_dn'.
* 'dnptrs' is a list of pointers to previous compressed names. dnptrs[0]
* is a pointer to the beginning of the message. The list ends with NULL.
* 'lastdnptr' is a pointer to the end of the arrary pointed to
* by 'dnptrs'. Side effect is to update the list of pointers for
* labels inserted into the message as we compress the name.
* If 'dnptr' is NULL, we don't try to compress names. If 'lastdnptr'
* is NULL, we don't update the list.
*/
dn_comp(exp_dn, comp_dn, length, dnptrs, lastdnptr)
u_char *exp_dn, *comp_dn;
int length;
u_char **dnptrs, **lastdnptr;
{
register u_char *cp, *dn;
register int c, l;
u_char **cpp, **lpp, *sp, *eob;
u_char *msg;
dn = exp_dn;
cp = comp_dn;
eob = cp + length;
if (dnptrs != NULL) {
if ((msg = *dnptrs++) != NULL) {
for (cpp = dnptrs; *cpp != NULL; cpp++)
;
lpp = cpp; /* end of list to search */
}
} else
msg = NULL;
for (c = *dn++; c != '\0'; ) {
/* look to see if we can use pointers */
if (msg != NULL) {
if ((l = dn_find(dn-1, msg, dnptrs, lpp)) >= 0) {
if (cp+1 >= eob)
return (-1);
*cp++ = (l >> 8) | INDIR_MASK;
*cp++ = l % 256;
return (cp - comp_dn);
}
/* not found, save it */
if (lastdnptr != NULL && cpp < lastdnptr-1) {
*cpp++ = cp;
*cpp = NULL;
}
}
sp = cp++; /* save ptr to length byte */
do {
if (c == '.') {
c = *dn++;
break;
}
if (c == '\\') {
if ((c = *dn++) == '\0')
break;
}
if (cp >= eob) {
if (msg != NULL)
*lpp = NULL;
return (-1);
}
*cp++ = c;
} while ((c = *dn++) != '\0');
/* catch trailing '.'s but not '..' */
if ((l = cp - sp - 1) == 0 && c == '\0') {
cp--;
break;
}
if (l <= 0 || l > MAXLABEL) {
if (msg != NULL)
*lpp = NULL;
return (-1);
}
*sp = l;
}
if (cp >= eob) {
if (msg != NULL)
*lpp = NULL;
return (-1);
}
*cp++ = '\0';
return (cp - comp_dn);
}
/*
* Skip over a compressed domain name. Return the size or -1.
*/
dn_skipname(comp_dn, eom)
u_char *comp_dn, *eom;
{
register u_char *cp;
register int n;
cp = comp_dn;
while (cp < eom && (n = *cp++)) {
/*
* check for indirection
*/
switch (n & INDIR_MASK) {
case 0: /* normal case, n == len */
cp += n;
continue;
default: /* illegal type */
return (-1);
case INDIR_MASK: /* indirection */
cp++;
}
break;
}
return (cp - comp_dn);
}
/*
* Search for expanded name from a list of previously compressed names.
* Return the offset from msg if found or -1.
* dnptrs is the pointer to the first name on the list,
* not the pointer to the start of the message.
*/
static
dn_find(exp_dn, msg, dnptrs, lastdnptr)
u_char *exp_dn, *msg;
u_char **dnptrs, **lastdnptr;
{
register u_char *dn, *cp, **cpp;
register int n;
u_char *sp;
for (cpp = dnptrs; cpp < lastdnptr; cpp++) {
dn = exp_dn;
sp = cp = *cpp;
while (n = *cp++) {
/*
* check for indirection
*/
switch (n & INDIR_MASK) {
case 0: /* normal case, n == len */
while (--n >= 0) {
if (*dn == '.')
goto next;
if (*dn == '\\')
dn++;
if (*dn++ != *cp++)
goto next;
}
if ((n = *dn++) == '\0' && *cp == '\0')
return (sp - msg);
if (n == '.')
continue;
goto next;
default: /* illegal type */
return (-1);
case INDIR_MASK: /* indirection */
cp = msg + (((n & 0x3f) << 8) | *cp);
}
}
if (*dn == '\0')
return (sp - msg);
next: ;
}
return (-1);
}
/*
* Routines to insert/extract short/long's. Must account for byte
* order and non-alignment problems. This code at least has the
* advantage of being portable.
*
* used by sendmail.
*/
u_short
_getshort(msgp)
u_char *msgp;
{
register u_char *p = (u_char *) msgp;
#ifdef vax
/*
* vax compiler doesn't put shorts in registers
*/
register u_long u;
#else
register u_short u;
#endif
u = *p++ << 8;
return ((u_short)(u | *p));
}
u_long
_getlong(msgp)
u_char *msgp;
{
register u_char *p = (u_char *) msgp;
register u_long u;
u = *p++; u <<= 8;
u |= *p++; u <<= 8;
u |= *p++; u <<= 8;
return (u | *p);
}
putshort(s, msgp)
register u_short s;
register u_char *msgp;
{
msgp[1] = s;
msgp[0] = s >> 8;
}
putlong(l, msgp)
register u_long l;
register u_char *msgp;
{
msgp[3] = l;
msgp[2] = (l >>= 8);
msgp[1] = (l >>= 8);
msgp[0] = l >> 8;
}

206
ircd/res_init.c Normal file
View File

@@ -0,0 +1,206 @@
/*-
* Copyright (c) 1985, 1989 Regents of the University of California.
* All rights reserved.
*
* Redistribution and use in source and binary forms are permitted provided
* that: (1) source distributions retain this entire copyright notice and
* comment, and (2) distributions including binaries display the following
* acknowledgement: ``This product includes software developed by the
* University of California, Berkeley and its contributors'' in the
* documentation or other materials provided with the distribution and in
* all advertising materials mentioning features or use of this software.
* Neither the name of the University nor the names of its contributors may
* be used to endorse or promote products derived from this software without
* specific prior written permission.
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
#if defined(LIBC_SCCS) && !defined(lint)
static char sccsid[] = "@(#)res_init.c 6.14.1 (Berkeley) 6/27/90";
#endif /* LIBC_SCCS and not lint */
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <stdio.h>
#include "config.h" /* To get #define SOL20 Vesa */
#include "sys.h"
#include "nameser.h"
#include "resolv.h"
/*
* Resolver state default settings
*/
struct state _res = {
RES_TIMEOUT, /* retransmition time interval */
4, /* number of times to retransmit */
RES_DEFAULT, /* options flags */
1, /* number of name servers */
};
/*
* Set up default settings. If the configuration file exist, the values
* there will have precedence. Otherwise, the server address is set to
* INADDR_ANY and the default domain name comes from the gethostname().
*
* The configuration file should only be used if you want to redefine your
* domain or run without a server on your machine.
*
* Return 0 if completes successfully, -1 on error
*/
res_init()
{
register FILE *fp;
register char *cp, *dp, **pp;
register int n;
char buf[BUFSIZ];
extern u_long inet_addr();
extern char *getenv();
int nserv = 0; /* number of nameserver records read from file */
int norder = 0;
int haveenv = 0;
int havesearch = 0;
_res.nsaddr.sin_addr.s_addr = INADDR_ANY;
_res.nsaddr.sin_family = AF_INET;
_res.nsaddr.sin_port = htons(NAMESERVER_PORT);
_res.nscount = 1;
/* Allow user to override the local domain definition */
if ((cp = getenv("LOCALDOMAIN")) != NULL) {
(void)strncpy(_res.defdname, cp, sizeof(_res.defdname));
haveenv++;
}
if ((fp = fopen(_PATH_RESCONF, "r")) != NULL) {
/* read the config file */
while (fgets(buf, sizeof(buf), fp) != NULL) {
/* read default domain name */
if (!strncmp(buf, "domain", sizeof("domain") - 1)) {
if (haveenv) /* skip if have from environ */
continue;
cp = buf + sizeof("domain") - 1;
while (*cp == ' ' || *cp == '\t')
cp++;
if ((*cp == '\0') || (*cp == '\n'))
continue;
(void)strncpy(_res.defdname, cp, sizeof(_res.defdname) - 1);
if ((cp = index(_res.defdname, '\n')) != NULL)
*cp = '\0';
havesearch = 0;
continue;
}
/* set search list */
if (!strncmp(buf, "search", sizeof("search") - 1)) {
if (haveenv) /* skip if have from environ */
continue;
cp = buf + sizeof("search") - 1;
while (*cp == ' ' || *cp == '\t')
cp++;
if ((*cp == '\0') || (*cp == '\n'))
continue;
(void)strncpy(_res.defdname, cp, sizeof(_res.defdname) - 1);
if ((cp = index(_res.defdname, '\n')) != NULL)
*cp = '\0';
/*
* Set search list to be blank-separated strings
* on rest of line.
*/
cp = _res.defdname;
pp = _res.dnsrch;
*pp++ = cp;
for (n = 0; *cp && pp < _res.dnsrch + MAXDNSRCH; cp++) {
if (*cp == ' ' || *cp == '\t') {
*cp = 0;
n = 1;
} else if (n) {
*pp++ = cp;
n = 0;
}
}
/* null terminate last domain if there are excess */
while (*cp != '\0' && *cp != ' ' && *cp != '\t')
cp++;
*cp = '\0';
*pp++ = 0;
havesearch = 1;
continue;
}
/* read nameservers to query */
if (!strncmp(buf, "nameserver", sizeof("nameserver") - 1) &&
nserv < MAXNS) {
cp = buf + sizeof("nameserver") - 1;
while (*cp == ' ' || *cp == '\t')
cp++;
if ((*cp == '\0') || (*cp == '\n'))
continue;
if ((_res.nsaddr_list[nserv].sin_addr.s_addr =
inet_addr(cp)) == (unsigned)-1) {
_res.nsaddr_list[nserv].sin_addr.s_addr
= INADDR_ANY;
continue;
}
_res.nsaddr_list[nserv].sin_family = AF_INET;
_res.nsaddr_list[nserv].sin_port = htons(NAMESERVER_PORT);
nserv++;
continue;
}
/* read service order */
if (!strncmp(buf, "order", sizeof("order") - 1)) {
cp = buf + sizeof("order") - 1;
while (*cp == ' ' || *cp == '\t')
cp++;
if ((*cp == '\0') || (*cp == '\n'))
continue;
norder = 0;
do {
if ((dp = index(cp, ',')) != NULL)
*dp = '\0';
if (norder >= MAXSERVICES)
continue;
if (!strncmp(cp, "bind", sizeof("bind") - 1))
_res.order[norder++] = RES_SERVICE_BIND;
else if (!strncmp(cp, "local", sizeof("local") - 1))
_res.order[norder++] = RES_SERVICE_LOCAL;
cp = dp + 1;
} while (dp != NULL);
_res.order[norder] = RES_SERVICE_NONE;
continue;
}
}
if (nserv > 1)
_res.nscount = nserv;
(void) fclose(fp);
}
if (_res.defdname[0] == 0) {
if (gethostname(buf, sizeof(_res.defdname)) == 0 &&
(cp = index(buf, '.')))
(void)strcpy(_res.defdname, cp + 1);
}
/* find components of local domain that might be searched */
if (havesearch == 0) {
pp = _res.dnsrch;
*pp++ = _res.defdname;
for (cp = _res.defdname, n = 0; *cp; cp++)
if (*cp == '.')
n++;
cp = _res.defdname;
for (; n >= LOCALDOMAINPARTS && pp < _res.dnsrch + MAXDFLSRCH;
n--) {
cp = index(cp, '.');
*pp++ = ++cp;
}
*pp++ = 0;
}
/* default search order to bind only */
if (norder == 0) {
_res.order[0] = RES_SERVICE_BIND;
_res.order[1] = RES_SERVICE_NONE;
}
_res.options |= RES_INIT;
return (0);
}

192
ircd/res_mkquery.c Normal file
View File

@@ -0,0 +1,192 @@
/*
* Copyright (c) 1985 Regents of the University of California.
* All rights reserved.
*
* Redistribution and use in source and binary forms are permitted
* provided that: (1) source distributions retain this entire copyright
* notice and comment, and (2) distributions including binaries display
* the following acknowledgement: ``This product includes software
* developed by the University of California, Berkeley and its contributors''
* in the documentation or other materials provided with the distribution
* and in all advertising materials mentioning features or use of this
* software. Neither the name of the University nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
#if defined(LIBC_SCCS) && !defined(lint)
static char sccsid[] = "@(#)res_mkquery.c 6.12 (Berkeley) 6/1/90";
#endif /* LIBC_SCCS and not lint */
#include <stdio.h>
#include <sys/types.h>
#include <netinet/in.h>
#include "config.h"
#include "sys.h"
#include "nameser.h"
#include "resolv.h"
/*
* Form all types of queries.
* Returns the size of the result or -1.
*/
res_mkquery(op, dname, class, type, data, datalen, newrr, buf, buflen)
int op; /* opcode of query */
char *dname; /* domain name */
int class, type; /* class and type of query */
char *data; /* resource record data */
int datalen; /* length of data */
struct rrec *newrr; /* new rr for modify or append */
char *buf; /* buffer to put query */
int buflen; /* size of buffer */
{
register HEADER *hp;
register char *cp;
register int n;
char *dnptrs[10], **dpp, **lastdnptr;
#ifdef DEBUG
if (_res.options & RES_DEBUG)
printf("res_mkquery(%d, %s, %d, %d)\n", op, dname, class, type);
#endif /*DEBUG*/
/*
* Initialize header fields.
*/
if ((buf == NULL) || (buflen < sizeof(HEADER)))
return(-1);
bzero(buf, sizeof(HEADER));
hp = (HEADER *) buf;
hp->id = htons(++_res.id);
hp->opcode = op;
hp->pr = (_res.options & RES_PRIMARY) != 0;
hp->rd = (_res.options & RES_RECURSE) != 0;
hp->rcode = NOERROR;
cp = buf + sizeof(HEADER);
buflen -= sizeof(HEADER);
dpp = dnptrs;
*dpp++ = buf;
*dpp++ = NULL;
lastdnptr = dnptrs + sizeof(dnptrs)/sizeof(dnptrs[0]);
/*
* perform opcode specific processing
*/
switch (op) {
case QUERY:
if ((buflen -= QFIXEDSZ) < 0)
return(-1);
if ((n = dn_comp(dname, cp, buflen, dnptrs, lastdnptr)) < 0)
return (-1);
cp += n;
buflen -= n;
putshort(type, cp);
cp += sizeof(u_short);
putshort(class, cp);
cp += sizeof(u_short);
hp->qdcount = htons(1);
if (op == QUERY || data == NULL)
break;
/*
* Make an additional record for completion domain.
*/
buflen -= RRFIXEDSZ;
if ((n = dn_comp(data, cp, buflen, dnptrs, lastdnptr)) < 0)
return (-1);
cp += n;
buflen -= n;
putshort(T_NULL, cp);
cp += sizeof(u_short);
putshort(class, cp);
cp += sizeof(u_short);
putlong(0, cp);
cp += sizeof(u_long);
putshort(0, cp);
cp += sizeof(u_short);
hp->arcount = htons(1);
break;
case IQUERY:
/*
* Initialize answer section
*/
if (buflen < 1 + RRFIXEDSZ + datalen)
return (-1);
*cp++ = '\0'; /* no domain name */
putshort(type, cp);
cp += sizeof(u_short);
putshort(class, cp);
cp += sizeof(u_short);
putlong(0, cp);
cp += sizeof(u_long);
putshort(datalen, cp);
cp += sizeof(u_short);
if (datalen) {
bcopy(data, cp, datalen);
cp += datalen;
}
hp->ancount = htons(1);
break;
#ifdef ALLOW_UPDATES
/*
* For UPDATEM/UPDATEMA, do UPDATED/UPDATEDA followed by UPDATEA
* (Record to be modified is followed by its replacement in msg.)
*/
case UPDATEM:
case UPDATEMA:
case UPDATED:
/*
* The res code for UPDATED and UPDATEDA is the same; user
* calls them differently: specifies data for UPDATED; server
* ignores data if specified for UPDATEDA.
*/
case UPDATEDA:
buflen -= RRFIXEDSZ + datalen;
if ((n = dn_comp(dname, cp, buflen, dnptrs, lastdnptr)) < 0)
return (-1);
cp += n;
putshort(type, cp);
cp += sizeof(u_short);
putshort(class, cp);
cp += sizeof(u_short);
putlong(0, cp);
cp += sizeof(u_long);
putshort(datalen, cp);
cp += sizeof(u_short);
if (datalen) {
bcopy(data, cp, datalen);
cp += datalen;
}
if ( (op == UPDATED) || (op == UPDATEDA) ) {
hp->ancount = htons(0);
break;
}
/* Else UPDATEM/UPDATEMA, so drop into code for UPDATEA */
case UPDATEA: /* Add new resource record */
buflen -= RRFIXEDSZ + datalen;
if ((n = dn_comp(dname, cp, buflen, dnptrs, lastdnptr)) < 0)
return (-1);
cp += n;
putshort(newrr->r_type, cp);
cp += sizeof(u_short);
putshort(newrr->r_class, cp);
cp += sizeof(u_short);
putlong(0, cp);
cp += sizeof(u_long);
putshort(newrr->r_size, cp);
cp += sizeof(u_short);
if (newrr->r_size) {
bcopy(newrr->r_data, cp, newrr->r_size);
cp += newrr->r_size;
}
hp->ancount = htons(0);
break;
#endif /* ALLOW_UPDATES */
}
return (cp - buf);
}

267
ircd/s_auth.c Normal file
View File

@@ -0,0 +1,267 @@
/************************************************************************
* IRC - Internet Relay Chat, ircd/s_auth.c
* Copyright (C) 1992 Darren Reed
*
* 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 1, 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.
*/
#ifndef lint
static char sccsid[] = "@(#)s_auth.c 1.18 4/18/94 (C) 1992 Darren Reed";
#endif
#include "struct.h"
#include "common.h"
#include "sys.h"
#include "res.h"
#include "numeric.h"
#include "patchlevel.h"
#include <sys/socket.h>
#include <sys/file.h>
#include <sys/ioctl.h>
#ifdef UNIXPORT
# include <sys/un.h>
#endif
#if defined(__hpux)
# include "inet.h"
#endif
#include <fcntl.h>
#include "sock.h" /* If FD_ZERO isn't define up to this point, */
/* define it (BSD4.2 needs this) */
#include "h.h"
/*
* start_auth
*
* Flag the client to show that an attempt to contact the ident server on
* the client's host. The connect and subsequently the socket are all put
* into 'non-blocking' mode. Should the connect or any later phase of the
* identifing process fail, it is aborted and the user is given a username
* of "unknown".
*/
void start_auth(cptr)
Reg1 aClient *cptr;
{
struct sockaddr_in sock;
int err;
#ifdef VIRTUAL_HOST
extern struct sockaddr_in vserv;
#endif
Debug((DEBUG_NOTICE,"start_auth(%x) fd %d status %d",
cptr, cptr->fd, cptr->status));
(void)alarm(2);
cptr->authfd = socket(AF_INET, SOCK_STREAM, 0);
err = errno;
(void)alarm(0);
if (cptr->authfd < 0 && err == EAGAIN)
sendto_ops(
"Can't allocate fd for auth on %s : socket: No more sockets",
get_client_name(cptr, TRUE));
if (cptr->authfd < 0)
{
#ifdef USE_SYSLOG
syslog(LOG_ERR, "Unable to create auth socket for %s:%m",
get_client_name(cptr, TRUE));
#endif
Debug((DEBUG_ERROR, "Unable to create auth socket for %s:%s",
get_client_name(cptr, TRUE),
strerror(get_sockerr(cptr))));
if (!DoingDNS(cptr))
SetAccess(cptr);
ircstp->is_abad++;
return;
}
if (cptr->authfd >= (MAXCONNECTIONS - 2))
{
sendto_ops("Can't allocate fd for auth on %s",
get_client_name(cptr, TRUE));
(void)close(cptr->authfd);
return;
}
set_non_blocking(cptr->authfd, cptr);
#ifdef VIRTUAL_HOST
if (bind(cptr->authfd, (struct sockaddr *)&vserv,
sizeof(vserv)) == -1)
{
report_error("binding auth stream socket %s:%s", cptr);
(void)close(cptr->fd);
return;
}
#endif
bcopy((char *)&cptr->ip, (char *)&sock.sin_addr,
sizeof(struct in_addr));
sock.sin_port = htons(113);
sock.sin_family = AF_INET;
(void)alarm((unsigned)4);
if (connect(cptr->authfd, (struct sockaddr *)&sock,
sizeof(sock)) == -1 && errno != EINPROGRESS)
{
ircstp->is_abad++;
/*
* No error report from this...
*/
(void)alarm((unsigned)0);
(void)close(cptr->authfd);
cptr->authfd = -1;
if (!DoingDNS(cptr))
SetAccess(cptr);
return;
}
(void)alarm((unsigned)0);
cptr->flags |= (FLAGS_WRAUTH|FLAGS_AUTH);
if (cptr->authfd > highest_fd)
highest_fd = cptr->authfd;
return;
}
/*
* send_authports
*
* Send the ident server a query giving "theirport , ourport".
* The write is only attempted *once* so it is deemed to be a fail if the
* entire write doesn't write all the data given. This shouldnt be a
* problem since the socket should have a write buffer far greater than
* this message to store it in should problems arise. -avalon
*/
void send_authports(cptr)
aClient *cptr;
{
struct sockaddr_in us, them;
char authbuf[32];
int ulen, tlen;
Debug((DEBUG_NOTICE,"write_authports(%x) fd %d authfd %d stat %d",
cptr, cptr->fd, cptr->authfd, cptr->status));
tlen = ulen = sizeof(us);
if (getsockname(cptr->fd, (struct sockaddr *)&us, &ulen) ||
getpeername(cptr->fd, (struct sockaddr *)&them, &tlen))
{
#ifdef USE_SYSLOG
syslog(LOG_ERR, "auth get{sock,peer}name error for %s:%m",
get_client_name(cptr, TRUE));
#endif
goto authsenderr;
}
(void)sprintf(authbuf, "%u , %u\r\n",
(unsigned int)ntohs(them.sin_port),
(unsigned int)ntohs(us.sin_port));
Debug((DEBUG_SEND, "sending [%s] to auth port %s.113",
authbuf, inetntoa((char *)&them.sin_addr)));
if (write(cptr->authfd, authbuf, strlen(authbuf)) != strlen(authbuf))
{
authsenderr:
ircstp->is_abad++;
(void)close(cptr->authfd);
if (cptr->authfd == highest_fd)
while (!local[highest_fd])
highest_fd--;
cptr->authfd = -1;
cptr->flags &= ~FLAGS_AUTH;
if (!DoingDNS(cptr))
SetAccess(cptr);
}
cptr->flags &= ~FLAGS_WRAUTH;
return;
}
/*
* read_authports
*
* read the reply (if any) from the ident server we connected to.
* The actual read processijng here is pretty weak - no handling of the reply
* if it is fragmented by IP.
*/
void read_authports(cptr)
Reg1 aClient *cptr;
{
Reg1 char *s, *t;
Reg2 int len;
char ruser[USERLEN+1], system[8];
u_short remp = 0, locp = 0;
*system = *ruser = '\0';
Debug((DEBUG_NOTICE,"read_authports(%x) fd %d authfd %d stat %d",
cptr, cptr->fd, cptr->authfd, cptr->status));
/*
* Nasty. Cant allow any other reads from client fd while we're
* waiting on the authfd to return a full valid string. Use the
* client's input buffer to buffer the authd reply.
* Oh. this is needed because an authd reply may come back in more
* than 1 read! -avalon
*/
if ((len = read(cptr->authfd, cptr->buffer + cptr->count,
sizeof(cptr->buffer) - 1 - cptr->count)) >= 0)
{
cptr->count += len;
cptr->buffer[cptr->count] = '\0';
}
cptr->lasttime = now;
if ((len > 0) && (cptr->count != (sizeof(cptr->buffer) - 1)) &&
(sscanf(cptr->buffer, "%hd , %hd : USERID : %*[^:]: %10s",
&remp, &locp, ruser) == 3))
{
s = rindex(cptr->buffer, ':');
*s++ = '\0';
for (t = (rindex(cptr->buffer, ':') + 1); *t; t++)
if (!isspace(*t))
break;
strncpyzt(system, t, sizeof(system));
for (t = ruser; *s && (t < ruser + sizeof(ruser)); s++)
if (!isspace(*s) && *s != ':' && *s != '@')
*t++ = *s;
*t = '\0';
Debug((DEBUG_INFO,"auth reply ok [%s] [%s]", system, ruser));
}
else if (len != 0)
{
if (!index(cptr->buffer, '\n') && !index(cptr->buffer, '\r'))
return;
Debug((DEBUG_ERROR,"local %d remote %d", locp, remp));
Debug((DEBUG_ERROR,"bad auth reply in [%s]", cptr->buffer));
*ruser = '\0';
}
(void)close(cptr->authfd);
if (cptr->authfd == highest_fd)
while (!local[highest_fd])
highest_fd--;
cptr->count = 0;
cptr->authfd = -1;
ClearAuth(cptr);
if (!DoingDNS(cptr))
SetAccess(cptr);
if (len > 0)
Debug((DEBUG_INFO,"ident reply: [%s]", cptr->buffer));
if (!locp || !remp || !*ruser)
{
ircstp->is_abad++;
return;
}
ircstp->is_asuc++;
strncpyzt(cptr->username, ruser, USERLEN+1);
if (strncmp(system, "OTHER", 5))
cptr->flags |= FLAGS_GOTID;
Debug((DEBUG_INFO, "got username [%s]", ruser));
return;
}

2601
ircd/s_bsd.c Normal file

File diff suppressed because it is too large Load Diff

1438
ircd/s_conf.c Normal file

File diff suppressed because it is too large Load Diff

475
ircd/s_debug.c Normal file
View File

@@ -0,0 +1,475 @@
/************************************************************************
* IRC - Internet Relay Chat, ircd/s_debug.c
* Copyright (C) 1990 Jarkko Oikarinen and
* University of Oulu, Computing Center
*
* 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 1, 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.
*/
#ifndef lint
static char sccsid[] = "@(#)s_debug.c 2.30 1/3/94 (C) 1988 University of Oulu, \
Computing Center and Jarkko Oikarinen";
#endif
#include "struct.h"
/*
* Option string. Must be before #ifdef DEBUGMODE.
*/
char serveropts[] = {
#ifdef CHROOTDIR
'c',
#endif
#ifdef CMDLINE_CONFIG
'C',
#endif
#ifdef DO_ID
'd',
#endif
#ifdef DEBUGMODE
'D',
#endif
#ifdef LOCOP_REHASH
'e',
#endif
#ifdef OPER_REHASH
'E',
#endif
#ifdef NOTE_FORWARDER
'f',
#endif
#ifdef HUB
'H',
#endif
#ifdef SHOW_INVISIBLE_LUSERS
'i',
#endif
#ifdef OPER_KILL
# ifdef LOCAL_KILL_ONLY
'k',
# else
'K',
# endif
#endif
#ifdef LEAST_IDLE
'L',
#endif
#ifdef M4_PREPROC
'm',
#endif
#ifdef IDLE_FROM_MSG
'M',
#endif
#ifdef CRYPT_OPER_PASSWORD
'p',
#endif
#ifdef CRYPT_LINK_PASSWORD
'P',
#endif
#ifdef NPATH
'N',
#endif
#ifdef LOCOP_RESTART
'r',
#endif
#ifdef OPER_RESTART
'R',
#endif
#ifdef ENABLE_SUMMON
'S',
#endif
#ifdef OPER_REMOTE
't',
#endif
#ifdef IRCII_KLUDGE
'u',
#endif
#ifdef ENABLE_USERS
'U',
#endif
#ifdef VALLOC
'V',
#endif
#ifdef UNIXPORT
'X',
#endif
#ifdef USE_SYSLOG
'Y',
#endif
#ifdef V28PlusOnly
'8',
#endif
'\0'};
#include "numeric.h"
#include "common.h"
#include "sys.h"
#include "whowas.h"
#include "hash.h"
#include <sys/file.h>
#ifdef HPUX
#include <fcntl.h>
#endif
#if !defined(ULTRIX) && !defined(SGI) && !defined(sequent) && \
!defined(__convex__)
# include <sys/param.h>
#endif
#ifdef HPUX
# include <sys/syscall.h>
# define getrusage(a,b) syscall(SYS_GETRUSAGE, a, b)
#endif
#ifdef GETRUSAGE_2
# ifdef SOL20
# include <sys/time.h>
# include <sys/rusage.h>
# endif
# include <sys/resource.h>
#else
# ifdef TIMES_2
# include <sys/times.h>
# endif
#endif
#ifdef PCS
# include <time.h>
#endif
#ifdef HPUX
#include <unistd.h>
#ifdef DYNIXPTX
#include <sys/types.h>
#include <time.h>
#endif
#endif
#include "h.h"
#ifndef ssize_t
#define ssize_t unsigned int
#endif
#ifdef DEBUGMODE
static char debugbuf[1024];
#ifndef USE_VARARGS
/*VARARGS2*/
void debug(level, form, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10)
int level;
char *form, *p1, *p2, *p3, *p4, *p5, *p6, *p7, *p8, *p9, *p10;
{
int err = errno;
#else
void debug(level, form, va_alist)
int level;
char *form;
va_dcl
{
va_list vl;
int err = errno;
va_start(vl);
#endif
if ((debuglevel >= 0) && (level <= debuglevel))
{
#ifndef USE_VARARGS
(void)sprintf(debugbuf, form,
p1, p2, p3, p4, p5, p6, p7, p8, p9, p10);
#else
(void)vsprintf(debugbuf, form, vl);
#endif
if (local[2])
{
local[2]->sendM++;
local[2]->sendB += strlen(debugbuf);
}
(void)fprintf(stderr, "%s", debugbuf);
(void)fputc('\n', stderr);
}
errno = err;
}
/*
* This is part of the STATS replies. There is no offical numeric for this
* since this isnt an official command, in much the same way as HASH isnt.
* It is also possible that some systems wont support this call or have
* different field names for "struct rusage".
* -avalon
*/
void send_usage(cptr, nick)
aClient *cptr;
char *nick;
{
#ifdef GETRUSAGE_2
struct rusage rus;
time_t secs, rup;
#ifdef hz
# define hzz hz
#else
# ifdef HZ
# define hzz HZ
# else
int hzz = 1;
# ifdef HPUX
hzz = (int)sysconf(_SC_CLK_TCK);
# endif
# endif
#endif
if (getrusage(RUSAGE_SELF, &rus) == -1)
{
#if !defined(__FreeBSD__) && !defined(__NetBSD__)
extern char *sys_errlist[];
#endif
sendto_one(cptr,":%s NOTICE %s :Getruseage error: %s.",
me.name, nick, sys_errlist[errno]);
return;
}
secs = rus.ru_utime.tv_sec + rus.ru_stime.tv_sec;
rup = now - me.since;
if (secs == 0)
secs = 1;
sendto_one(cptr,
":%s %d %s :CPU Secs %d:%d User %d:%d System %d:%d",
me.name, RPL_STATSDEBUG, nick, secs/60, secs%60,
rus.ru_utime.tv_sec/60, rus.ru_utime.tv_sec%60,
rus.ru_stime.tv_sec/60, rus.ru_stime.tv_sec%60);
sendto_one(cptr, ":%s %d %s :RSS %d ShMem %d Data %d Stack %d",
me.name, RPL_STATSDEBUG, nick, rus.ru_maxrss,
rus.ru_ixrss / (rup * hzz), rus.ru_idrss / (rup * hzz),
rus.ru_isrss / (rup * hzz));
sendto_one(cptr, ":%s %d %s :Swaps %d Reclaims %d Faults %d",
me.name, RPL_STATSDEBUG, nick, rus.ru_nswap,
rus.ru_minflt, rus.ru_majflt);
sendto_one(cptr, ":%s %d %s :Block in %d out %d",
me.name, RPL_STATSDEBUG, nick, rus.ru_inblock,
rus.ru_oublock);
sendto_one(cptr, ":%s %d %s :Msg Rcv %d Send %d",
me.name, RPL_STATSDEBUG, nick, rus.ru_msgrcv, rus.ru_msgsnd);
sendto_one(cptr, ":%s %d %s :Signals %d Context Vol. %d Invol %d",
me.name, RPL_STATSDEBUG, nick, rus.ru_nsignals,
rus.ru_nvcsw, rus.ru_nivcsw);
#else
# ifdef TIMES_2
struct tms tmsbuf;
time_t secs, mins;
int hzz = 1, ticpermin;
int umin, smin, usec, ssec;
# ifdef HPUX
hzz = sysconf(_SC_CLK_TCK);
# endif
ticpermin = hzz * 60;
umin = tmsbuf.tms_utime / ticpermin;
usec = (tmsbuf.tms_utime%ticpermin)/(float)hzz;
smin = tmsbuf.tms_stime / ticpermin;
ssec = (tmsbuf.tms_stime%ticpermin)/(float)hzz;
secs = usec + ssec;
mins = (secs/60) + umin + smin;
secs %= hzz;
if (times(&tmsbuf) == -1)
{
sendto_one(cptr,":%s %d %s :times(2) error: %s.",
me.name, RPL_STATSDEBUG, nick, strerror(errno));
return;
}
secs = tmsbuf.tms_utime + tmsbuf.tms_stime;
sendto_one(cptr,
":%s %d %s :CPU Secs %d:%d User %d:%d System %d:%d",
me.name, RPL_STATSDEBUG, nick, mins, secs, umin, usec,
smin, ssec);
# endif
#endif
sendto_one(cptr, ":%s %d %s :Reads %d Writes %d",
me.name, RPL_STATSDEBUG, nick, readcalls, writecalls);
sendto_one(cptr, ":%s %d %s :DBUF alloc %d blocks %d",
me.name, RPL_STATSDEBUG, nick, dbufalloc, dbufblocks);
sendto_one(cptr,
":%s %d %s :Writes: <0 %d 0 %d <16 %d <32 %d <64 %d",
me.name, RPL_STATSDEBUG, nick,
writeb[0], writeb[1], writeb[2], writeb[3], writeb[4]);
sendto_one(cptr,
":%s %d %s :<128 %d <256 %d <512 %d <1024 %d >1024 %d",
me.name, RPL_STATSDEBUG, nick,
writeb[5], writeb[6], writeb[7], writeb[8], writeb[9]);
return;
}
#endif
void count_memory(cptr, nick)
aClient *cptr;
char *nick;
{
extern aChannel *channel;
extern aClass *classes;
extern aConfItem *conf;
Reg1 aClient *acptr;
Reg2 Link *link;
Reg3 aChannel *chptr;
Reg4 aConfItem *aconf;
Reg5 aClass *cltmp;
int lc = 0, /* local clients */
ch = 0, /* channels */
lcc = 0, /* local client conf links */
rc = 0, /* remote clients */
us = 0, /* user structs */
chu = 0, /* channel users */
chi = 0, /* channel invites */
chb = 0, /* channel bans */
wwu = 0, /* whowas users */
cl = 0, /* classes */
co = 0; /* conf lines */
int usi = 0, /* users invited */
usc = 0, /* users in channels */
aw = 0, /* aways set */
wwa = 0; /* whowas aways */
u_long chm = 0, /* memory used by channels */
chbm = 0, /* memory used by channel bans */
lcm = 0, /* memory used by local clients */
rcm = 0, /* memory used by remote clients */
awm = 0, /* memory used by aways */
wwam = 0, /* whowas away memory used */
wwm = 0, /* whowas array memory used */
com = 0, /* memory used by conf lines */
db = 0, /* memory used by dbufs */
rm = 0, /* res memory used */
totcl = 0,
totch = 0,
totww = 0,
tot = 0;
count_whowas_memory(&wwu, &wwa, &wwam);
wwm = sizeof(aName) * NICKNAMEHISTORYLENGTH;
for (acptr = client; acptr; acptr = acptr->next)
{
if (IsPing(acptr))
continue;
if (MyConnect(acptr))
{
lc++;
for (link = acptr->confs; link; link = link->next)
lcc++;
}
else
rc++;
if (acptr->user)
{
us++;
for (link = acptr->user->invited; link;
link = link->next)
usi++;
for (link = acptr->user->channel; link;
link = link->next)
usc++;
if (acptr->user->away)
{
aw++;
awm += (strlen(acptr->user->away)+1);
}
}
}
lcm = lc * CLIENT_LOCAL_SIZE;
rcm = rc * CLIENT_REMOTE_SIZE;
for (chptr = channel; chptr; chptr = chptr->nextch)
{
ch++;
chm += (strlen(chptr->chname) + sizeof(aChannel));
for (link = chptr->members; link; link = link->next)
chu++;
for (link = chptr->invites; link; link = link->next)
chi++;
for (link = chptr->banlist; link; link = link->next)
{
chb++;
chbm += (strlen(link->value.cp)+1+sizeof(Link));
}
}
for (aconf = conf; aconf; aconf = aconf->next)
{
co++;
com += aconf->host ? strlen(aconf->host)+1 : 0;
com += aconf->passwd ? strlen(aconf->passwd)+1 : 0;
com += aconf->name ? strlen(aconf->name)+1 : 0;
com += sizeof(aConfItem);
}
for (cltmp = classes; cltmp; cltmp = cltmp->next)
cl++;
sendto_one(cptr, ":%s %d %s :Client Local %d(%d) Remote %d(%d)",
me.name, RPL_STATSDEBUG, nick, lc, lcm, rc, rcm);
sendto_one(cptr, ":%s %d %s :Users %d(%d) Invites %d(%d)",
me.name, RPL_STATSDEBUG, nick, us, us*sizeof(anUser), usi,
usi * sizeof(Link));
sendto_one(cptr, ":%s %d %s :User channels %d(%d) Aways %d(%d)",
me.name, RPL_STATSDEBUG, nick, usc, usc*sizeof(Link),
aw, awm);
sendto_one(cptr, ":%s %d %s :Attached confs %d(%d)",
me.name, RPL_STATSDEBUG, nick, lcc, lcc*sizeof(Link));
totcl = lcm + rcm + us*sizeof(anUser) + usc*sizeof(Link) + awm;
totcl += lcc*sizeof(Link) + usi*sizeof(Link);
sendto_one(cptr, ":%s %d %s :Conflines %d(%d)",
me.name, RPL_STATSDEBUG, nick, co, com);
sendto_one(cptr, ":%s %d %s :Classes %d(%d)",
me.name, RPL_STATSDEBUG, nick, cl, cl*sizeof(aClass));
sendto_one(cptr, ":%s %d %s :Channels %d(%d) Bans %d(%d)",
me.name, RPL_STATSDEBUG, nick, ch, chm, chb, chbm);
sendto_one(cptr, ":%s %d %s :Channel membrs %d(%d) invite %d(%d)",
me.name, RPL_STATSDEBUG, nick, chu, chu*sizeof(Link),
chi, chi*sizeof(Link));
totch = chm + chbm + chu*sizeof(Link) + chi*sizeof(Link);
sendto_one(cptr, ":%s %d %s :Whowas users %d(%d) away %d(%d)",
me.name, RPL_STATSDEBUG, nick, wwu, wwu*sizeof(anUser),
wwa, wwam);
sendto_one(cptr, ":%s %d %s :Whowas array %d(%d)",
me.name, RPL_STATSDEBUG, nick, NICKNAMEHISTORYLENGTH, wwm);
totww = wwu*sizeof(anUser) + wwam + wwm;
sendto_one(cptr, ":%s %d %s :Hash: client %d(%d) chan %d(%d)",
me.name, RPL_STATSDEBUG, nick, HASHSIZE,
sizeof(aHashEntry) * HASHSIZE,
CHANNELHASHSIZE, sizeof(aHashEntry) * CHANNELHASHSIZE);
db = dbufblocks * sizeof(dbufbuf);
sendto_one(cptr, ":%s %d %s :Dbuf blocks %d(%d)",
me.name, RPL_STATSDEBUG, nick, dbufblocks, db);
rm = cres_mem(cptr);
tot = totww + totch + totcl + com + cl*sizeof(aClass) + db + rm;
tot += sizeof(aHashEntry) * HASHSIZE;
tot += sizeof(aHashEntry) * CHANNELHASHSIZE;
sendto_one(cptr, ":%s %d %s :Total: ww %d ch %d cl %d co %d db %d",
me.name, RPL_STATSDEBUG, nick, totww, totch, totcl, com, db);
sendto_one(cptr, ":%s %d %s :TOTAL: %d sbrk(0)-etext: %u",
me.name, RPL_STATSDEBUG, nick, tot,
(u_int)sbrk((size_t)0)-(u_int)sbrk0);
return;
}

367
ircd/s_err.c Normal file
View File

@@ -0,0 +1,367 @@
/************************************************************************
* IRC - Internet Relay Chat, ircd/s_err.c
* Copyright (C) 1992 Darren Reed
*
* 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 1, 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.
*/
#include "struct.h"
#include "numeric.h"
#ifndef lint
static char sccsid[] = "@(#)s_err.c 1.12 11/1/93 (C) 1992 Darren Reed";
#endif
typedef struct {
int num_val;
char *num_form;
} Numeric;
static char *prepbuf PROTO((char *, int, char *));
static char numbuff[512];
static char numbers[] = "0123456789";
static Numeric local_replies[] = {
/* 000 */ 0, (char *)NULL,
/* 001 */ RPL_WELCOME, ":Welcome to the Internet Relay Network %s",
/* 002 */ RPL_YOURHOST, ":Your host is %s, running version %s",
/* 003 */ RPL_CREATED, ":This server was created %s",
/* 004 */ RPL_MYINFO, "%s %s dioswk biklmnopstv",
/* 005 */ RPL_MAP, ":%s%s",
/* 006 */ RPL_MAPMORE, ":%s%s --> *more*",
/* 007 */ RPL_MAPEND, ":End of /MAP",
0, (char *)NULL
};
static Numeric numeric_errors[] = {
/* 401 */ ERR_NOSUCHNICK, "%s :No such nick/channel",
/* 402 */ ERR_NOSUCHSERVER, "%s :No such server",
/* 402 */ ERR_NOSUCHCHANNEL, "%s :No such channel",
/* 402 */ ERR_CANNOTSENDTOCHAN, "%s :Cannot send to channel",
/* 402 */ ERR_TOOMANYCHANNELS, "%s :You have joined too many channels",
/* 402 */ ERR_WASNOSUCHNICK, "%s :There was no such nickname",
/* 402 */ ERR_TOOMANYTARGETS,
"%s :Duplicate recipients. No message delivered",
/* 402 */ ERR_NOSUCHSERVICE, (char *)NULL,
/* 402 */ ERR_NOORIGIN, ":No origin specified",
0, (char *)NULL,
/* 411 */ ERR_NORECIPIENT, ":No recipient given (%s)",
/* 411 */ ERR_NOTEXTTOSEND, ":No text to send",
/* 411 */ ERR_NOTOPLEVEL, "%s :No toplevel domain specified",
/* 411 */ ERR_WILDTOPLEVEL, "%s :Wildcard in toplevel Domain",
0, (char *)NULL, 0, (char *)NULL, 0, (char *)NULL,
0, (char *)NULL, 0, (char *)NULL, 0, (char *)NULL,
/* 421 */ ERR_UNKNOWNCOMMAND, "%s :Unknown command",
/* 422 */ ERR_NOMOTD, ":MOTD File is missing",
/* 422 */ ERR_NOADMININFO,
"%s :No administrative info available",
/* 422 */ ERR_FILEERROR, ":File error doing %s on %s",
0, (char *)NULL, 0, (char *)NULL, 0, (char *)NULL,
0, (char *)NULL, 0, (char *)NULL, 0, (char *)NULL,
/* 431 */ ERR_NONICKNAMEGIVEN, ":No nickname given",
/* 432 */ ERR_ERRONEUSNICKNAME, "%s :Erroneus Nickname",
/* 433 */ ERR_NICKNAMEINUSE, "%s :Nickname is already in use.",
/* 434 */ ERR_SERVICENAMEINUSE, (char *)NULL,
/* 435 */ ERR_SERVICECONFUSED, (char *)NULL,
/* 436 */ ERR_NICKCOLLISION, "%s :Nickname collision KILL",
/* 437 */ ERR_BANNICKCHANGE,
"%s :Cannot change nickname while banned on channel",
/* 438 */ ERR_NICKTOOFAST, "%s :Nick change too fast. Please wait %d seconds.",
0, (char *)NULL, 0, (char *)NULL,
/* 441 */ ERR_USERNOTINCHANNEL, "%s %s :They aren't on that channel",
/* 442 */ ERR_NOTONCHANNEL, "%s :You're not on that channel",
/* 443 */ ERR_USERONCHANNEL, "%s %s :is already on channel",
/* 444 */ ERR_NOLOGIN, "%s :User not logged in",
#ifndef ENABLE_SUMMON
/* 445 */ ERR_SUMMONDISABLED, ":SUMMON has been disabled",
#else
0, (char *)NULL,
#endif
#ifndef ENABLE_USERS
/* 446 */ ERR_USERSDISABLED, ":USERS has been disabled",
#else
0, (char *)NULL,
#endif
0, (char *)NULL, 0, (char *)NULL, 0, (char *)NULL,
0, (char *)NULL,
/* 451 */ ERR_NOTREGISTERED, ":You have not registered",
0, (char *)NULL, 0, (char *)NULL, 0, (char *)NULL,
0, (char *)NULL, 0, (char *)NULL, 0, (char *)NULL,
0, (char *)NULL, 0, (char *)NULL, 0, (char *)NULL,
/* 461 */ ERR_NEEDMOREPARAMS, "%s :Not enough parameters",
/* 462 */ ERR_ALREADYREGISTRED, ":You may not reregister",
/* 463 */ ERR_NOPERMFORHOST, ":Your host isn't among the privileged",
/* 464 */ ERR_PASSWDMISMATCH, ":Password Incorrect",
/* 465 */ ERR_YOUREBANNEDCREEP, ":You are banned from this server",
/* 466 */ ERR_YOUWILLBEBANNED, (char *)NULL,
/* 467 */ ERR_KEYSET, "%s :Channel key already set",
0, (char *)NULL, 0, (char *)NULL, 0, (char *)NULL,
/* 471 */ ERR_CHANNELISFULL, "%s :Cannot join channel (+l)",
/* 472 */ ERR_UNKNOWNMODE , "%c :is unknown mode char to me",
/* 473 */ ERR_INVITEONLYCHAN, "%s :Cannot join channel (+i)",
/* 474 */ ERR_BANNEDFROMCHAN, "%s :Cannot join channel (+b)",
/* 475 */ ERR_BADCHANNELKEY, "%s :Cannot join channel (+k)",
/* 476 */ ERR_BADCHANMASK, "%s :Bad Channel Mask",
0, (char *)NULL,
/* 478 */ ERR_BANLISTFULL, "%s %s :Channel ban/ignore list is full",
0, (char *)NULL, 0, (char *)NULL,
/* 481 */ ERR_NOPRIVILEGES,
":Permission Denied- You're not an IRC operator",
/* 482 */ ERR_CHANOPRIVSNEEDED, "%s :You're not channel operator",
/* 483 */ ERR_CANTKILLSERVER, ":You cant kill a server!",
/* 484 */ ERR_ISCHANSERVICE, "%s %s :Cannot kick or deop channel service",
0, (char *)NULL, 0, (char *)NULL, 0, (char *)NULL,
0, (char *)NULL, 0, (char *)NULL, 0, (char *)NULL,
/* 491 */ ERR_NOOPERHOST, ":No O-lines for your host",
/* 492 */ ERR_NOSERVICEHOST, (char *)NULL,
0, (char *)NULL, 0, (char *)NULL, 0, (char *)NULL,
0, (char *)NULL, 0, (char *)NULL, 0, (char *)NULL,
0, (char *)NULL, 0, (char *)NULL,
/* 501 */ ERR_UMODEUNKNOWNFLAG, ":Unknown MODE flag",
/* 502 */ ERR_USERSDONTMATCH, ":Cant change mode for other users",
0, (char *)NULL, 0, (char *)NULL, 0, (char *)NULL,
0, (char *)NULL, 0, (char *)NULL, 0, (char *)NULL,
0, (char *)NULL, 0, (char *)NULL,
/* 511 */ ERR_SILELISTFULL, "%s :Your silence list is full",
/* 512 */ ERR_NOSUCHGLINE, "%s@%s :No such gline",
/* 513 */ ERR_BADPING, (char*)NULL
};
static Numeric numeric_replies[] = {
/* 300 */ RPL_NONE, (char *)NULL,
/* 301 */ RPL_AWAY, "%s :%s",
/* 302 */ RPL_USERHOST, ":",
/* 303 */ RPL_ISON, ":",
/* 304 */ RPL_TEXT, (char *)NULL,
/* 305 */ RPL_UNAWAY, ":You are no longer marked as being away",
/* 306 */ RPL_NOWAWAY, ":You have been marked as being away",
0, (char *)NULL, 0, (char *)NULL, 0, (char *)NULL,
0, (char *)NULL,
/* 311 */ RPL_WHOISUSER, "%s %s %s * :%s",
/* 312 */ RPL_WHOISSERVER, "%s %s :%s",
/* 313 */ RPL_WHOISOPERATOR, "%s :is an IRC Operator",
/* 314 */ RPL_WHOWASUSER, "%s %s %s * :%s",
/* 315 */ RPL_ENDOFWHO, "%s :End of /WHO list.",
/* 316 */ RPL_WHOISCHANOP, (char *)NULL,
/* 317 */ RPL_WHOISIDLE, "%s %ld %ld :seconds idle, signon time",
/* 318 */ RPL_ENDOFWHOIS, "%s :End of /WHOIS list.",
/* 319 */ RPL_WHOISCHANNELS, "%s :%s",
0, (char *)NULL,
/* 321 */ RPL_LISTSTART, "Channel :Users Name",
/* 322 */ RPL_LIST, "%s %d :%s",
/* 323 */ RPL_LISTEND, ":End of /LIST",
/* 324 */ RPL_CHANNELMODEIS, "%s %s %s",
0, (char *)NULL, 0, (char *)NULL, 0, (char *)NULL,
0, (char *)NULL,
/* 329 */ RPL_CREATIONTIME, "%s %lu",
0, (char *)NULL,
/* 331 */ RPL_NOTOPIC, "%s :No topic is set.",
/* 332 */ RPL_TOPIC, "%s :%s",
/* 333 */ RPL_TOPICWHOTIME, "%s %s %lu",
/* 334 */ RPL_LISTUSAGE, ":%s",
0, (char *)NULL, 0, (char *)NULL,
0, (char *)NULL, 0, (char *)NULL, 0, (char *)NULL,
0, (char *)NULL,
/* 341 */ RPL_INVITING, "%s %s",
/* 342 */ RPL_SUMMONING, "%s :User summoned to irc",
0, (char *)NULL, 0, (char *)NULL,
0, (char *)NULL, 0, (char *)NULL, 0, (char *)NULL,
0, (char *)NULL, 0, (char *)NULL, 0, (char *)NULL,
/* 351 */ RPL_VERSION, "%s.%s %s :%s",
/* 352 */ RPL_WHOREPLY, "%s %s %s %s %s %s :%d %s",
/* 353 */ RPL_NAMREPLY, "%s",
0, (char *)NULL, 0, (char *)NULL, 0, (char *)NULL,
0, (char *)NULL, 0, (char *)NULL, 0, (char *)NULL,
0, (char *)NULL,
/* 361 */ RPL_KILLDONE, (char *)NULL,
/* 362 */ RPL_CLOSING, "%s :Closed. Status = %d",
/* 363 */ RPL_CLOSEEND, "%d: Connections Closed",
/* 364 */ RPL_LINKS, "%s %s :%d P%u %s",
/* 365 */ RPL_ENDOFLINKS, "%s :End of /LINKS list.",
/* 366 */ RPL_ENDOFNAMES, "%s :End of /NAMES list.",
/* 367 */ RPL_BANLIST, "%s %s %s %lu",
/* 368 */ RPL_ENDOFBANLIST, "%s :End of Channel Ban List",
/* 369 */ RPL_ENDOFWHOWAS, "%s :End of WHOWAS",
0, (char *)NULL,
/* 371 */ RPL_INFO, ":%s",
/* 372 */ RPL_MOTD, ":- %s",
/* 373 */ RPL_INFOSTART, ":Server INFO",
/* 374 */ RPL_ENDOFINFO, ":End of /INFO list.",
/* 375 */ RPL_MOTDSTART, ":- %s Message of the Day - ",
/* 376 */ RPL_ENDOFMOTD, ":End of /MOTD command.",
0, (char *)NULL, 0, (char *)NULL, 0, (char *)NULL,
0, (char *)NULL,
/* 381 */ RPL_YOUREOPER, ":You are now an IRC Operator",
/* 382 */ RPL_REHASHING, "%s :Rehashing",
/* 383 */ RPL_YOURESERVICE, (char *)NULL,
/* 384 */ RPL_MYPORTIS, "%d :Port to local server is\r\n",
/* 385 */ RPL_NOTOPERANYMORE, (char *)NULL,
0, (char *)NULL, 0, (char *)NULL, 0, (char *)NULL,
0, (char *)NULL, 0, (char *)NULL,
/* 391 */ RPL_TIME, "%s %lu %ld :%s",
#ifdef ENABLE_USERS
/* 392 */ RPL_USERSSTART, ":UserID Terminal Host",
/* 393 */ RPL_USERS, ":%-8s %-9s %-8s",
/* 394 */ RPL_ENDOFUSERS, ":End of Users",
/* 395 */ RPL_NOUSERS, ":Nobody logged in.",
#else
0, (char *)NULL, 0, (char *)NULL, 0, (char *)NULL,
0, (char *)NULL,
#endif
0, (char *)NULL, 0, (char *)NULL, 0, (char *)NULL,
0, (char *)NULL,
/* 200 */ RPL_TRACELINK, "Link %s%s %s %s",
/* 201 */ RPL_TRACECONNECTING, "Try. %d %s",
/* 202 */ RPL_TRACEHANDSHAKE, "H.S. %d %s",
/* 203 */ RPL_TRACEUNKNOWN, "???? %d %s",
/* 204 */ RPL_TRACEOPERATOR, "Oper %d %s %ld",
/* 205 */ RPL_TRACEUSER, "User %d %s %ld",
/* 206 */ RPL_TRACESERVER, "Serv %d %dS %dC %s %s!%s@%s %ld",
/* 207 */ RPL_TRACESERVICE, "Service %d %s",
/* 208 */ RPL_TRACENEWTYPE, "<newtype> 0 %s",
/* 209 */ RPL_TRACECLASS, "Class %d %d",
0, (char *)NULL,
/* 211 */ RPL_STATSLINKINFO, (char *)NULL,
/* 212 */ RPL_STATSCOMMANDS, "%s %u %u",
/* 213 */ RPL_STATSCLINE, "%c %s * %s %d %d",
/* 214 */ RPL_STATSNLINE, "%c %s * %s %d %d",
/* 215 */ RPL_STATSILINE, "%c %s * %s %d %d",
/* 216 */ RPL_STATSKLINE, "%c %s %s %s %d %d",
/* 217 */ RPL_STATSQLINE, "%c %s * %s %d %d",
/* 218 */ RPL_STATSYLINE, "%c %d %d %d %d %ld",
/* 219 */ RPL_ENDOFSTATS, "%c :End of /STATS report",
0, (char *)NULL,
/* 221 */ RPL_UMODEIS, "%s",
0, (char *)NULL, 0, (char *)NULL, 0, (char *)NULL,
0, (char *)NULL, 0, (char *)NULL, 0, (char *)NULL,
0, (char *)NULL, 0, (char *)NULL, 0, (char *)NULL,
/* 231 */ RPL_SERVICEINFO, (char *)NULL,
/* 232 */ RPL_ENDOFSERVICES, (char *)NULL,
/* 233 */ RPL_SERVICE, (char *)NULL,
/* 234 */ RPL_SERVLIST, (char *)NULL,
/* 235 */ RPL_SERVLISTEND, (char *)NULL,
0, (char *)NULL, 0, (char *)NULL, 0, (char *)NULL,
0, (char *)NULL, 0, (char *)NULL,
/* 241 */ RPL_STATSLLINE, "%c %s * %s %d %d",
/* 242 */ RPL_STATSUPTIME, ":Server Up %d days, %d:%02d:%02d",
/* 243 */ RPL_STATSOLINE, "%c %s * %s %d %d",
/* 244 */ RPL_STATSHLINE, "%c %s * %s %d %d",
/* 245 */ RPL_STATSSLINE, "%c %s * %s %d %d",
/* 246 */ RPL_STATSTLINE, "%c %s %s",
/* 247 */ RPL_STATSGLINE, "%c %s@%s %lu :%s",
/* 248 */ RPL_STATSULINE, "%c %s * %s %d %d",
0, (char *)NULL,
/* 250 */ RPL_STATSCONN,
":Highest connection count: %d (%d clients)",
/* 251 */ RPL_LUSERCLIENT,
":There are %d users and %d invisible on %d servers",
/* 252 */ RPL_LUSEROP, "%d :operator(s) online",
/* 253 */ RPL_LUSERUNKNOWN, "%d :unknown connection(s)",
/* 254 */ RPL_LUSERCHANNELS, "%d :channels formed",
/* 255 */ RPL_LUSERME, ":I have %d clients and %d servers",
/* 256 */ RPL_ADMINME, ":Administrative info about %s",
/* 257 */ RPL_ADMINLOC1, ":%s",
/* 258 */ RPL_ADMINLOC2, ":%s",
/* 259 */ RPL_ADMINEMAIL, ":%s",
0, (char *)NULL,
/* 261 */ RPL_TRACELOG, "File %s %d",
/* 262 */ RPL_TRACEPING, "Ping %s %s",
0, (char *)NULL, 0, (char *)NULL,
0, (char *)NULL, 0, (char *)NULL, 0, (char *)NULL,
0, (char *)NULL, 0, (char *)NULL, 0, (char *)NULL,
/* 271 */ RPL_SILELIST, "%s %s",
/* 272 */ RPL_ENDOFSILELIST, ":End of Silence List",
0, (char *)NULL, 0, (char *)NULL,
/* 275 */ RPL_STATSDLINE, "%c %s %s",
0, (char *)NULL, 0, (char *)NULL, 0, (char *)NULL,
0, (char *)NULL,
/* 280 */ RPL_GLIST, "%s@%s %lu %s%s",
/* 281 */ RPL_ENDOFGLIST, ":End of G-line List"
};
char *err_str(numeric)
int numeric;
{
Reg1 Numeric *nptr;
Reg2 int num = numeric;
num -= numeric_errors[0].num_val;
if (num < 0 || num > ERR_USERSDONTMATCH)
(void)sprintf(numbuff,
":%%s %d %%s :INTERNAL ERROR: BAD NUMERIC! %d",
numeric, num);
else
{
nptr = &numeric_errors[num];
if (!nptr->num_form || !nptr->num_val)
(void)sprintf(numbuff,
":%%s %d %%s :NO ERROR FOR NUMERIC ERROR %d",
numeric, num);
else
(void)prepbuf(numbuff, nptr->num_val, nptr->num_form);
}
return numbuff;
}
char *rpl_str(numeric)
int numeric;
{
Reg1 Numeric *nptr;
Reg2 int num = numeric;
if (num > 7)
num -= (num > 300) ? 300 : 100;
if (num < 0 || num > 200)
(void)sprintf(numbuff,
":%%s %d %%s :INTERNAL REPLY ERROR: BAD NUMERIC! %d",
numeric, num);
else
{
if (numeric > 99)
nptr = &numeric_replies[num];
else
nptr = &local_replies[num];
Debug((DEBUG_NUM, "rpl_str: numeric %d num %d nptr %x %d %x",
numeric, num, nptr, nptr->num_val, nptr->num_form));
if (!nptr->num_form || !nptr->num_val)
(void)sprintf(numbuff,
":%%s %d %%s :NO REPLY FOR NUMERIC ERROR %d",
numeric, num);
else
(void)prepbuf(numbuff, nptr->num_val, nptr->num_form);
}
return numbuff;
}
static char *prepbuf(buffer, num, tail)
char *buffer;
Reg1 int num;
char *tail;
{
Reg1 char *s;
(void)strcpy(buffer, ":%s ");
s = buffer + 4;
*s++ = numbers[num/100];
num %= 100;
*s++ = numbers[num/10];
*s++ = numbers[num%10];
(void)strcpy(s, " %s ");
(void)strcpy(s+4, tail);
return buffer;
}

777
ircd/s_misc.c Normal file
View File

@@ -0,0 +1,777 @@
/************************************************************************
* IRC - Internet Relay Chat, ircd/s_misc.c (formerly ircd/date.c)
* Copyright (C) 1990 Jarkko Oikarinen and
* University of Oulu, Computing Center
*
* See file AUTHORS in IRC package for additional names of
* the programmers.
*
* 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 1, 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.
*/
#ifndef lint
static char sccsid[] = "@(#)s_misc.c 2.42 3/1/94 (C) 1988 University of Oulu, \
Computing Center and Jarkko Oikarinen";
#endif
#include <sys/time.h>
#include "struct.h"
#include "common.h"
#include "sys.h"
#include "numeric.h"
#include "userload.h"
#include <sys/stat.h>
#include <fcntl.h>
#if !defined(ULTRIX) && !defined(SGI) && !defined(sequent) && \
!defined(__convex__)
# include <sys/param.h>
#endif
#if defined(PCS) || defined(AIX) || defined(SVR3)
# include <time.h>
#endif
#ifdef HPUX
#include <unistd.h>
#endif
#ifdef DYNIXPTX
#include <sys/types.h>
#include <time.h>
#endif
#include "h.h"
static void exit_one_client PROTO((aClient *,aClient *,char *,int));
static char *months[] = {
"January", "February", "March", "April",
"May", "June", "July", "August",
"September", "October", "November", "December"
};
static char *weekdays[] = {
"Sunday", "Monday", "Tuesday", "Wednesday",
"Thursday", "Friday", "Saturday"
};
/*
* stats stuff
*/
struct stats ircst, *ircstp = &ircst;
char *date(clock)
time_t clock;
{
static char buf[80], plus;
Reg1 struct tm *lt, *gm;
struct tm gmbuf;
int minswest;
if (!clock)
clock = now;
gm = gmtime(&clock);
bcopy((char *)gm, (char *)&gmbuf, sizeof(gmbuf));
gm = &gmbuf;
lt = localtime(&clock);
if (lt->tm_yday == gm->tm_yday)
minswest = (gm->tm_hour - lt->tm_hour) * 60 +
(gm->tm_min - lt->tm_min);
else if (lt->tm_yday > gm->tm_yday)
minswest = (gm->tm_hour - (lt->tm_hour + 24)) * 60;
else
minswest = ((gm->tm_hour + 24) - lt->tm_hour) * 60;
plus = (minswest > 0) ? '-' : '+';
if (minswest < 0)
minswest = -minswest;
(void)sprintf(buf, "%s %s %d 19%02d -- %02d:%02d %c%02d:%02d",
weekdays[lt->tm_wday], months[lt->tm_mon],lt->tm_mday,
lt->tm_year, lt->tm_hour, lt->tm_min,
plus, minswest/60, minswest%60);
return buf;
}
/**
** myctime()
** This is like standard ctime()-function, but it zaps away
** the newline from the end of that string. Also, it takes
** the time value as parameter, instead of pointer to it.
** Note that it is necessary to copy the string to alternate
** buffer (who knows how ctime() implements it, maybe it statically
** has newline there and never 'refreshes' it -- zapping that
** might break things in other places...)
**
**/
char *myctime(value)
time_t value;
{
static char buf[28];
Reg1 char *p;
(void)strcpy(buf, ctime(&value));
if ((p = (char *)index(buf, '\n')) != NULL)
*p = '\0';
return buf;
}
/*
** check_registered_user is used to cancel message, if the
** originator is a server or not registered yet. In other
** words, passing this test, *MUST* guarantee that the
** sptr->user exists (not checked after this--let there
** be coredumps to catch bugs... this is intentional --msa ;)
**
** There is this nagging feeling... should this NOT_REGISTERED
** error really be sent to remote users? This happening means
** that remote servers have this user registered, althout this
** one has it not... Not really users fault... Perhaps this
** error message should be restricted to local clients and some
** other thing generated for remotes...
*/
int check_registered_user(sptr)
aClient *sptr;
{
if (!IsRegisteredUser(sptr))
{
sendto_one(sptr, err_str(ERR_NOTREGISTERED), me.name, "*");
return -1;
}
return 0;
}
/*
** check_registered user cancels message, if 'x' is not
** registered (e.g. we don't know yet whether a server
** or user)
*/
int check_registered(sptr)
aClient *sptr;
{
if (!IsRegistered(sptr))
{
sendto_one(sptr, err_str(ERR_NOTREGISTERED), me.name, "*");
return -1;
}
return 0;
}
/*
** get_client_name
** Return the name of the client for various tracking and
** admin purposes. The main purpose of this function is to
** return the "socket host" name of the client, if that
** differs from the advertised name (other than case).
** But, this can be used to any client structure.
**
** Returns:
** "name[user@ip#.port]" if 'showip' is true;
** "name[sockethost]", if name and sockhost are different and
** showip is false; else
** "name".
**
** NOTE 1:
** Watch out the allocation of "nbuf", if either sptr->name
** or sptr->sockhost gets changed into pointers instead of
** directly allocated within the structure...
**
** NOTE 2:
** Function return either a pointer to the structure (sptr) or
** to internal buffer (nbuf). *NEVER* use the returned pointer
** to modify what it points!!!
*/
char *get_client_name(sptr, showip)
aClient *sptr;
int showip;
{
static char nbuf[HOSTLEN * 2 + USERLEN + 5];
if (MyConnect(sptr))
{
if (IsUnixSocket(sptr))
{
if (showip)
(void) sprintf(nbuf, "%s[%s]",
sptr->name, sptr->sockhost);
else
(void) sprintf(nbuf, "%s[%s]",
sptr->name, me.sockhost);
}
else
{
if (showip)
(void)sprintf(nbuf, "%s[%s@%s]",
sptr->name,
(!(sptr->flags & FLAGS_GOTID)) ? "" :
sptr->username,
inetntoa((char *)&sptr->ip));
else
{
if (mycmp(sptr->name, sptr->sockhost))
(void)sprintf(nbuf, "%s[%s]",
sptr->name, sptr->sockhost);
else
return sptr->name;
}
}
return nbuf;
}
return sptr->name;
}
char *get_client_host(cptr)
aClient *cptr;
{
static char nbuf[HOSTLEN * 2 + USERLEN + 5];
if (!MyConnect(cptr))
return cptr->name;
if (!cptr->hostp)
return get_client_name(cptr, FALSE);
if (IsUnixSocket(cptr))
(void) sprintf(nbuf, "%s[%s]", cptr->name, me.name);
else
(void)sprintf(nbuf, "%s[%-.*s@%-.*s]",
cptr->name, USERLEN,
(!(cptr->flags & FLAGS_GOTID)) ? "" : cptr->username,
HOSTLEN, cptr->hostp->h_name);
return nbuf;
}
/*
* Form sockhost such that if the host is of form user@host, only the host
* portion is copied.
*/
void get_sockhost(cptr, host)
Reg1 aClient *cptr;
Reg2 char *host;
{
Reg3 char *s;
if ((s = (char *)index(host, '@')))
s++;
else
s = host;
strncpyzt(cptr->sockhost, s, sizeof(cptr->sockhost));
}
/*
* Return wildcard name of my server name according to given config entry
* --Jto
*/
char *my_name_for_link(name, aconf)
char *name;
aConfItem *aconf;
{
static char namebuf[HOSTLEN];
register int count = aconf->port;
register char *start = name;
if (count <= 0 || count > 5)
return start;
while (count-- && name)
{
name++;
name = (char *)index(name, '.');
}
if (!name)
return start;
namebuf[0] = '*';
(void)strncpy(&namebuf[1], name, HOSTLEN - 1);
namebuf[HOSTLEN - 1] = '\0';
return namebuf;
}
/*
** exit_downlinks - added by Run 25-9-94
**
** Removes all clients and downlinks (+clients) of any server
** QUITs are generated and sent to local users.
**
** cptr : server that must have all dependents removed
** sptr : source who thought that this was a good idea
** comment : comment sent as sign off message to local clients
*/
void exit_downlinks(cptr, sptr, comment)
aClient *cptr, *sptr;
char *comment;
{
Reg1 aClient *acptr;
Reg2 Dlink *next;
Reg3 Dlink *lp;
/* Run over all its downlinks */
for (lp=cptr->serv->down; lp; lp=next)
{
next=lp->next;
acptr=lp->value.cptr;
/* Remove the downlinks and client of the downlink */
exit_downlinks(acptr, sptr, comment);
/* Remove the downlink itself */
exit_one_client(acptr, sptr, me.name, 1);
}
/* Remove all clients of this server */
for (lp=cptr->serv->client; lp; lp=next)
{
next=lp->next;
exit_one_client(lp->value.cptr, sptr, comment, 1);
}
}
/*
** exit_client, rewritten 25-9-94 by Run
**
** This function exits a client of *any* type (user, server, etc)
** from this server. Also, this generates all necessary prototol
** messages that this exit may cause.
**
** This function implicitly exits all other clients depending on
** this connection.
**
** For convenience, this function returns a suitable value for
** m_funtion return value:
**
** CPTR_KILLED if (cptr == bcptr)
** 0 if (cptr != bcptr)
**
** This function can be called in two ways:
** 1) From before or in parse(), exitting the 'cptr', in which case it was
** invoked as exit_client(cptr, cptr, &me,...), causing it to always
** return CPTR_KILLED.
** 2) Via parse from a m_function call, in which case it was invoked as
** exit_client(cptr, acptr, sptr, ...). Here 'sptr' is known; the client
** that generated the message in a way that we can assume he already
** did remove acptr from memory himself (or in other cases we don't mind
** because he will be delinked.) Or invoked as:
** exit_client(cptr, acptr/sptr, &me, ...) when WE decide this one should
** be removed.
** In general: No generated SQUIT or QUIT should be sent to source link
** sptr->from. And CPTR_KILLED should be returned if cptr got removed (too).
**
** --Run
*/
int exit_client(cptr, bcptr, sptr, comment)
aClient *cptr; /* Connection being handled by read_message right now */
aClient *bcptr; /* Client being killed */
aClient *sptr; /* The client that made the decision to remove this
one, never NULL */
char *comment; /* Reason for the exit */
{
Reg1 aClient *acptr;
Reg2 aClient *next;
Reg3 Dlink *dlp;
#ifdef FNAME_USERLOG
time_t on_for;
#endif
char comment1[HOSTLEN + HOSTLEN + 2];
if (MyConnect(bcptr))
{
bcptr->flags |= FLAGS_CLOSING;
current_load_data.conn_count--;
if (IsPerson(bcptr))
{
char mydom_mask[HOSTLEN + 1];
mydom_mask[0] = '*';
sendto_realops ("Client exiting: %s (%s@%s) [%s]",
bcptr->name, bcptr->user->username, bcptr->user->host, comment);
strncpy(&mydom_mask[1], DOMAINNAME, HOSTLEN - 1);
current_load_data.client_count--;
if (matches(mydom_mask, bcptr->sockhost) == 0)
current_load_data.local_count--;
}
update_load();
#ifdef FNAME_USERLOG
on_for = now - bcptr->firsttime;
# if defined(USE_SYSLOG) && defined(SYSLOG_USERS)
if (IsPerson(bcptr))
syslog(LOG_NOTICE, "%s (%3d:%02d:%02d): %s@%s (%s)\n",
myctime(bcptr->firsttime), on_for / 3600, (on_for % 3600)/60,
on_for % 60, bcptr->user->username, bcptr->sockhost, bcptr->name);
# else
{
char linebuf[160];
int logfile;
/*
* This conditional makes the logfile active only after
* it's been created - thus logging can be turned off by
* removing the file.
*
* stop NFS hangs...most systems should be able to open a
* file in 3 seconds. -avalon (curtesy of wumpus)
*/
(void)alarm(3);
if (IsPerson(bcptr) &&
(logfile = open(FNAME_USERLOG, O_WRONLY|O_APPEND)) != -1)
{
(void)alarm(0);
(void)sprintf(linebuf,
"%s (%3d:%02d:%02d): %s@%s [%s]\n",
myctime(bcptr->firsttime),
on_for / 3600, (on_for % 3600)/60,
on_for % 60,
bcptr->user->username, bcptr->user->host,
bcptr->username);
(void)alarm(3);
(void)write(logfile, linebuf, strlen(linebuf));
(void)alarm(0);
(void)close(logfile);
}
(void)alarm(0);
/* Modification by stealth@caen.engin.umich.edu */
}
# endif
#endif
if (bcptr != sptr->from && bcptr->status >= STAT_MASTER)
/* the source knows already --Run */
{
if (IsServer(bcptr) || IsHandshake(bcptr))
{
if (IsServer(bcptr) && Protocol(bcptr->from)<9)
sendto_one(bcptr, ":%s SQUIT %s :%s", sptr->name,
me.name, comment);
else /* If we are handshaking, use the newest protocol :/ */
sendto_one(bcptr, ":%s SQUIT %s 0 :%s", sptr->name,
me.name, comment);
}
else if (!IsConnecting(bcptr))
sendto_one(bcptr, "ERROR :Closing Link: %s by %s (%s)",
get_client_name(bcptr,FALSE), sptr->name, comment);
if ((IsServer(bcptr) || IsHandshake(bcptr) || IsConnecting(bcptr)) &&
(sptr == &me || (IsServer(sptr) &&
(strncmp(comment, "Leaf-only link", 14) ||
strncmp(comment, "Non-Hub link", 12)))))
{
if (bcptr->serv->user && (acptr=find_client(bcptr->serv->by, NULL)) &&
acptr->user == bcptr->serv->user)
sendto_one(acptr,
":%s NOTICE %s :Link with %s cancelled: %s",
me.name, acptr->name, bcptr->name, comment);
else
acptr = NULL;
if (sptr == &me)
sendto_lops_butone(acptr, "Link with %s cancelled: %s",
bcptr->name, comment);
}
}
/*
** Close the Client connection first.
*/
close_connection(bcptr);
}
if (IsServer(bcptr))
{
(void)strcpy(comment1, bcptr->serv->up->name);
(void)strcat(comment1," ");
(void)strcat(comment1, bcptr->name);
if (!IsServer(sptr) || Protocol(sptr)>4)
{
if (IsPerson(sptr))
sendto_lops_butone(sptr, "%s SQUIT by %s [%s]:",
(sptr->user->server == bcptr ||
sptr->user->server == bcptr->serv->up) ? "Local" : "Remote",
get_client_name(sptr,TRUE), sptr->user->server->name);
else if (sptr != &me && bcptr->serv->up != sptr)
sendto_ops("Received SQUIT %s from %s :", bcptr->name,
IsServer(sptr) ? sptr->name : get_client_name(sptr,TRUE));
sendto_ops("Net break: %s (%s)", comment1, comment);
}
exit_downlinks(bcptr, sptr, comment1);
}
/*
** Now generate the needed protocol for the other server links
** except the source: USE_SERVICES not supported
*/
for (dlp = me.serv->down; dlp; dlp = dlp->next)
if (dlp->value.cptr != sptr->from &&
dlp->value.cptr != bcptr)
{
if (IsServer(bcptr))
sendto_one(dlp->value.cptr, ":%s SQUIT %s %lu :%s",
sptr->name, bcptr->name, bcptr->serv->timestamp, comment);
else if (IsClient(bcptr) && (bcptr->flags & FLAGS_KILLED) == 0)
sendto_one(dlp->value.cptr, ":%s QUIT :%s", bcptr->name, comment);
}
exit_one_client(bcptr, sptr, comment, 0);
/*
** cptr can only have been killed if it was cptr itself that got killed here,
** because cptr can never have been a dependant of bcptr --Run
*/
return (cptr == bcptr) ? CPTR_KILLED : 0;
}
/*
** Exit client with formatted message, added 25-9-94 by Run
*/
#ifndef USE_VARARGS
/*VARARGS*/
int exit_client_msg(cptr, bcptr, sptr, pattern, p1, p2, p3, p4, p5, p6)
aClient *cptr, *bcptr, *sptr;
char *pattern, *p1, *p2, *p3, *p4, *p5, *p6;
{
#else
int exit_client_msg(cptr, bcptr, sptr, pattern, va_alist)
aClient *cptr, *bcptr, *sptr;
char *pattern;
va_dcl
{
va_list vl;
#endif
char msgbuf[1024];
#ifdef USE_VARARGS
va_start(vl);
(void)vsprintf(msgbuf, pattern, vl);
va_end(vl);
#else
(void)sprintf(msgbuf, pattern, p1, p2, p3, p4, p5, p6);
#endif
return exit_client(cptr, bcptr, sptr, msgbuf);
}
/*
** Exit one client, local or remote. Assuming for local client that
** all dependants already have been removed, and socket is closed.
**
** Rewritten by Run - 24 sept 94
**
** bcptr : client being (s)quitted
** sptr : The source (prefix) of the QUIT or SQUIT
**
** --Run
*/
static void exit_one_client(bcptr, sptr, comment, OldProtocolFlag)
aClient *bcptr, *sptr;
char *comment;
int OldProtocolFlag;
{
Reg1 aClient *acptr;
Reg2 int i;
Reg3 Link *lp;
Reg4 Link *prev;
Reg5 Dlink *dlp;
if (IsClient(bcptr))
{
/* Stop a running /LIST clean */
if (MyClient(bcptr) && bcptr->listing)
{
bcptr->listing->mode.mode &= ~MODE_LISTED;
bcptr->listing = NULL;
}
if (AskedPing(bcptr))
cancel_ping(bcptr, NULL);
/*
** If this exit is generated from "m_kill", then there
** is no sense in sending the QUIT--KILL's have been
** sent instead.
*/
/* Old Protocol : */
if ((bcptr->flags & FLAGS_KILLED) == 0)
{
for (dlp = me.serv->down; dlp; dlp = dlp->next)
if (Protocol(dlp->value.cptr)<9 && bcptr->from != dlp->value.cptr)
sendto_one(dlp->value.cptr,":%s QUIT :%s", bcptr->name, comment);
}
/*
** If a person is on a channel, send a QUIT notice
** to every client (person) on the same channel (so
** that the client can show the "**signoff" message).
** (Note: The notice is to the local clients *only*)
*/
sendto_common_channels(bcptr, ":%s QUIT :%s", bcptr->name, comment);
#ifdef NPATH
note_signoff(bcptr);
#endif
while ((lp = bcptr->user->channel))
remove_user_from_channel(bcptr,lp->value.chptr);
/* Clean up invitefield */
while ((lp = bcptr->user->invited))
del_invite(bcptr, lp->value.chptr);
/* Clean up silencefield */
while ((lp = bcptr->user->silence))
(void)del_silence(bcptr, lp->value.cp);
/* Remove from serv->client list */
remove_dlink(&bcptr->user->server->serv->client, bcptr->user->clink);
}
else if (IsServer(bcptr))
{
/* Old Protocol : */
for (dlp = me.serv->down; dlp; dlp = dlp->next)
if (Protocol(dlp->value.cptr)<9 && dlp->value.cptr->fd >= 0)
{
if (bcptr->from != dlp->value.cptr &&
(sptr->from != dlp->value.cptr->from || OldProtocolFlag))
sendto_one(dlp->value.cptr, "SQUIT %s :%s", bcptr->name, comment);
else if (sptr->from != dlp->value.cptr->from && !OldProtocolFlag)
sendto_one(dlp->value.cptr, ":%s SQUIT %s :%s", sptr->name,
bcptr->name, comment);
}
/* Remove downlink list node of uplink */
remove_dlink(&bcptr->serv->up->serv->down, bcptr->serv->updown);
}
else if (IsPing(bcptr)) /* Apperently, we are closing ALL links */
{
del_queries((char *)bcptr);
end_ping(bcptr);
return;
}
else if (IsService(bcptr))
{
/* Lame, lamer, Avalon. */
sendto_ops("ERROR: exit_one_client: Service? Whaisda?");
}
else if (IsMe(bcptr))
{
sendto_ops("ERROR: tried to exit me! : %s", comment);
return; /* ...must *never* exit self! */
}
/* Remove bcptr from the client list */
if (del_from_client_hash_table(bcptr->name, bcptr) != 1)
Debug((DEBUG_ERROR, "%#x !in tab %s[%s] %#x %#x %#x %d %d %#x",
bcptr, bcptr->name, bcptr->from ? bcptr->from->sockhost : "??host",
bcptr->from, bcptr->next, bcptr->prev, bcptr->fd,
bcptr->status, bcptr->user));
remove_client_from_list(bcptr);
return;
}
void checklist()
{
Reg1 aClient *acptr;
Reg2 int i,j;
if (!(bootopt & BOOT_AUTODIE))
return;
for (j = i = 0; i <= highest_fd; i++)
if (!(acptr = local[i]))
continue;
else if (IsClient(acptr))
j++;
if (!j)
{
#ifdef USE_SYSLOG
syslog(LOG_WARNING,"ircd exiting: autodie");
#endif
exit(0);
}
return;
}
void initstats()
{
bzero((char *)&ircst, sizeof(ircst));
}
void tstats(cptr, name)
aClient *cptr;
char *name;
{
Reg1 aClient *acptr;
Reg2 int i;
Reg3 struct stats *sp;
struct stats tmp;
sp = &tmp;
bcopy((char *)ircstp, (char *)sp, sizeof(*sp));
for (i = 0; i < MAXCONNECTIONS; i++)
{
if (!(acptr = local[i]))
continue;
if (IsServer(acptr))
{
sp->is_sbs += acptr->sendB;
sp->is_sbr += acptr->receiveB;
sp->is_sks += acptr->sendK;
sp->is_skr += acptr->receiveK;
sp->is_sti += now - acptr->firsttime;
sp->is_sv++;
if (sp->is_sbs > 1023)
{
sp->is_sks += (sp->is_sbs >> 10);
sp->is_sbs &= 0x3ff;
}
if (sp->is_sbr > 1023)
{
sp->is_skr += (sp->is_sbr >> 10);
sp->is_sbr &= 0x3ff;
}
}
else if (IsClient(acptr))
{
sp->is_cbs += acptr->sendB;
sp->is_cbr += acptr->receiveB;
sp->is_cks += acptr->sendK;
sp->is_ckr += acptr->receiveK;
sp->is_cti += now - acptr->firsttime;
sp->is_cl++;
if (sp->is_cbs > 1023)
{
sp->is_cks += (sp->is_cbs >> 10);
sp->is_cbs &= 0x3ff;
}
if (sp->is_cbr > 1023)
{
sp->is_ckr += (sp->is_cbr >> 10);
sp->is_cbr &= 0x3ff;
}
}
else if (IsUnknown(acptr))
sp->is_ni++;
}
sendto_one(cptr, ":%s %d %s :accepts %u refused %u",
me.name, RPL_STATSDEBUG, name, sp->is_ac, sp->is_ref);
sendto_one(cptr, ":%s %d %s :unknown commands %u prefixes %u",
me.name, RPL_STATSDEBUG, name, sp->is_unco, sp->is_unpf);
sendto_one(cptr, ":%s %d %s :nick collisions %u unknown closes %u",
me.name, RPL_STATSDEBUG, name, sp->is_kill, sp->is_ni);
sendto_one(cptr, ":%s %d %s :wrong direction %u empty %u",
me.name, RPL_STATSDEBUG, name, sp->is_wrdi, sp->is_empt);
sendto_one(cptr, ":%s %d %s :numerics seen %u mode fakes %u",
me.name, RPL_STATSDEBUG, name, sp->is_num, sp->is_fake);
sendto_one(cptr, ":%s %d %s :auth successes %u fails %u",
me.name, RPL_STATSDEBUG, name, sp->is_asuc, sp->is_abad);
sendto_one(cptr, ":%s %d %s :local connections %u udp packets %u",
me.name, RPL_STATSDEBUG, name, sp->is_loc, sp->is_udp);
sendto_one(cptr, ":%s %d %s :Client Server",
me.name, RPL_STATSDEBUG, name);
sendto_one(cptr, ":%s %d %s :connected %u %u",
me.name, RPL_STATSDEBUG, name, sp->is_cl, sp->is_sv);
sendto_one(cptr, ":%s %d %s :bytes sent %u.%uK %u.%uK",
me.name, RPL_STATSDEBUG, name,
sp->is_cks, sp->is_cbs, sp->is_sks, sp->is_sbs);
sendto_one(cptr, ":%s %d %s :bytes recv %u.%uK %u.%uK",
me.name, RPL_STATSDEBUG, name,
sp->is_ckr, sp->is_cbr, sp->is_skr, sp->is_sbr);
sendto_one(cptr, ":%s %d %s :time connected %u %u",
me.name, RPL_STATSDEBUG, name, sp->is_cti, sp->is_sti);
}

129
ircd/s_numeric.c Normal file
View File

@@ -0,0 +1,129 @@
/************************************************************************
* IRC - Internet Relay Chat, ircd/s_numeric.c
* Copyright (C) 1990 Jarkko Oikarinen
*
* Numerous fixes by Markku Savela
*
* 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 1, 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.
*/
#ifndef lint
static char sccsid[] = "@(#)s_numeric.c 2.14 1/30/94 (C) 1988 University of Oulu, \
Computing Center and Jarkko Oikarinen";
#endif
#include "struct.h"
#include "common.h"
#include "sys.h"
#include "numeric.h"
#include "h.h"
static char buffer[1024];
/*
** DoNumeric (replacement for the old do_numeric)
**
** parc number of arguments ('sender' counted as one!)
** parv[0] pointer to 'sender' (may point to empty string) (not used)
** parv[1]..parv[parc-1]
** pointers to additional parameters, this is a NULL
** terminated list (parv[parc] == NULL).
**
** *WARNING*
** Numerics are mostly error reports. If there is something
** wrong with the message, just *DROP* it! Don't even think of
** sending back a neat error message -- big danger of creating
** a ping pong error message...
*/
int do_numeric(numeric, cptr, sptr, parc, parv)
int numeric;
aClient *cptr, *sptr;
int parc;
char *parv[];
{
aClient *acptr;
aChannel *chptr;
char *nick, *p;
int i;
if (parc < 1 || !IsServer(sptr))
return 0;
/* Remap low number numerics. */
if (numeric < 100)
numeric += 100;
/*
** Prepare the parameter portion of the message into 'buffer'.
** (Because the buffer is twice as large as the message buffer
** for the socket, no overflow can occur here... ...on current
** assumptions--bets are off, if these are changed --msa)
** Note: if buffer is non-empty, it will begin with SPACE.
*/
buffer[0] = '\0';
if (parc > 1)
{
for (i = 2; i < (parc - 1); i++)
{
(void)strcat(buffer, " ");
(void)strcat(buffer, parv[i]);
}
(void)strcat(buffer, " :");
(void)strcat(buffer, parv[parc-1]);
}
for (; (nick = strtoken(&p, parv[1], ",")); parv[1] = NULL)
{
if ((acptr = find_client(nick, (aClient *)NULL)))
{
/*
** Drop to bit bucket if for me...
** ...one might consider sendto_ops
** here... --msa
** And so it was done. -avalon
** And regretted. Dont do it that way. Make sure
** it goes only to non-servers. -avalon
** Check added to make sure servers don't try to loop
** with numerics which can happen with nick collisions.
** - Avalon
*/
if (!IsMe(acptr) && IsPerson(acptr))
{
/* Added for .U3.2. drop remote 'You are not on
** that channel', we should be synced anyway,
** and this is an annoying message with TSpre7
** still on the net; would result in numeric 442 for
** every KICK... Can be removed when TSpre7 is gone.
** --Run
*/
if (numeric==ERR_NOTONCHANNEL) return 0;
sendto_prefix_one(acptr, sptr,":%s %d %s%s",
parv[0], numeric, nick, buffer);
}
else if (IsServer(acptr) && acptr->from != cptr)
sendto_prefix_one(acptr, sptr,":%s %d %s%s",
parv[0], numeric, nick, buffer);
}
else if ((acptr = find_server(nick, (aClient *)NULL)))
{
if (!IsMe(acptr) && acptr->from != cptr)
sendto_prefix_one(acptr, sptr,":%s %d %s%s",
parv[0], numeric, nick, buffer);
}
else if ((chptr = find_channel(nick, (aChannel *)NULL)))
sendto_channel_butone(cptr,sptr,chptr,":%s %d %s%s",
parv[0],
numeric, chptr->chname, buffer);
}
return 0;
}

500
ircd/s_ping.c Normal file
View File

@@ -0,0 +1,500 @@
/************************************************************************
* IRC - Internet Relay Chat, ircd/s_ping.c
* Copyright (C) 1994 Carlo K ( Run @ undernet.org )
*
* 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 1, 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.
*/
#ifndef lint
static char sccsid[] = "@(#)s_ping.c 1.0 9/21/94 (C) 1994 Carlo Kid";
#endif
#include "struct.h"
#include "common.h"
#include "sys.h"
#include "numeric.h"
#include "patchlevel.h"
#include <sys/socket.h>
#include <sys/file.h>
#include <sys/ioctl.h>
#ifdef UNIXPORT
# include <sys/un.h>
#endif
#if defined(__hpux)
# include "inet.h"
#endif
#include <fcntl.h>
#include "sock.h" /* If FD_ZERO isn't defined up to this point, */
/* define it (BSD4.2 needs this) */
#include "h.h"
#define UPINGBUFSIZE 2000 /* Lot bigger then 1024, bit smaller then 2048 */
#define UPINGTIMEOUT 120 /* Timeout waitting for first ping response */
extern u_long inet_addr();
/*
* start_ping
*
* As for now, I am abusing the client structure for a ping connection.
* Used members are:
* These are used by existing routines as well, and do have their own meaning:
* fd : The socket file descriptor.
* status : To flag that this IS one of these abused ping structures
* sockhost : Name of requested server to ping (aconf->host).
* name : aconf->name
* ip : ip#
* These have more or less their own meaning,
* but are not used by existing routines:
* flags : To flag that a next ping is requested.
* port : Requested remote port.
* These are only used by the 'uping' routines
* and have totally different meanings:
* buffer : buffer hold pingtimes of received packets
* confs : recv/send (char *) buffer.
* hopcount : Total number of requested pings
* count : Number of pings left to send.
* hashv : Number of pings left to be received.
* acpt : client asking for this ping
* lasttime : last time a ping was sent
* firsttime: recvfrom timeout
* since : timeout in seconds to next recvfrom
* receiveK : minimum in ms
* sendM : average in ms
* receiveM : maximum in ms
*/
int start_ping(cptr)
Reg1 aClient *cptr;
{
struct sockaddr_in remote_addr;
Debug((DEBUG_NOTICE,"start_ping(%x) status %d", cptr, cptr->status));
if (!(cptr->acpt)) return -1;
bcopy((char *)&cptr->ip, (char *)&remote_addr.sin_addr,
sizeof(struct in_addr));
#ifdef TESTNET
remote_addr.sin_port = htons(cptr->port + 10000);
#else
remote_addr.sin_port = htons(cptr->port);
#endif
remote_addr.sin_family = AF_INET;
sendto_one(cptr->acpt,
":%s NOTICE %s :Sending %d ping%s to %s[%s] port %d",
me.name, cptr->acpt->name, cptr->hopcount,
(cptr->hopcount == 1) ? "" : "s", cptr->name,
#ifdef TESTNET
inetntoa((char *)&remote_addr.sin_addr), ntohs(remote_addr.sin_port)
- 10000);
#else
inetntoa((char *)&remote_addr.sin_addr), ntohs(remote_addr.sin_port));
#endif
cptr->firsttime = now + UPINGTIMEOUT;
cptr->since = UPINGTIMEOUT;
cptr->flags |= (FLAGS_PING);
return 0;
}
/*
* send_ping
*
*/
void send_ping(cptr)
aClient *cptr;
{
struct sockaddr_in remote_addr;
struct timeval tv;
bcopy((char *)&cptr->ip, (char *)&remote_addr.sin_addr,
sizeof(struct in_addr));
#ifdef TESTNET
remote_addr.sin_port = htons(cptr->port + 10000);
#else
remote_addr.sin_port = htons(cptr->port);
#endif
remote_addr.sin_family = AF_INET;
(void) gettimeofday(&tv, NULL);
(void)sprintf((char *)cptr->confs, " %10lu%c%6lu",
tv.tv_sec, '\0', tv.tv_usec);
Debug((DEBUG_SEND, "send_ping: sending [%s %s] to %s.%d on %d",
(char *)cptr->confs, (char *)cptr->confs + 12,
inetntoa((char *)&remote_addr.sin_addr), ntohs(remote_addr.sin_port),
cptr->fd));
if (sendto(cptr->fd, (char *)cptr->confs, 1024, 0,
(struct sockaddr *)&remote_addr, sizeof(struct sockaddr_in)) != 1024)
{
int err=errno;
if (cptr->acpt)
sendto_one(cptr->acpt, ":%s NOTICE %s :UPING: sendto() failed: %s",
me.name, cptr->acpt->name, strerror(get_sockerr(cptr)));
Debug((DEBUG_SEND, "send_ping: sendto failed on %d (%d)", cptr->fd, err));
end_ping(cptr);
}
else if (--(cptr->count) <= 0 )
{
ClearPing(cptr);
if (cptr->hashv <= 0) end_ping(cptr);
}
return;
}
/*
* read_ping
*
*/
void read_ping(cptr)
Reg1 aClient *cptr;
{
int addr_len = sizeof(struct sockaddr_in);
struct sockaddr_in remote_addr;
struct timeval tv;
int len;
unsigned long int pingtime;
char *s;
bcopy((char *)&cptr->ip, (char *)&remote_addr.sin_addr,
sizeof(struct in_addr));
#ifdef TESTNET
remote_addr.sin_port = htons(cptr->port + 10000);
#else
remote_addr.sin_port = htons(cptr->port);
#endif
remote_addr.sin_family = AF_INET;
(void)gettimeofday(&tv, NULL);
if ((len=recvfrom(cptr->fd, (char *)cptr->confs, UPINGBUFSIZE, 0,
(struct sockaddr *)&remote_addr, &addr_len)) == -1)
{
int err = errno;
sendto_one(cptr->acpt,
":%s NOTICE %s :UPING: recvfrom: %s",
me.name, cptr->acpt->name, strerror(get_sockerr(cptr)));
Debug((DEBUG_SEND, "read_ping: recvfrom: %d", err));
if (err != EAGAIN) end_ping(cptr);
return;
}
if (len<19) return; /* Broken packet */
pingtime = (tv.tv_sec - atoi((char *)cptr->confs + 1)) * 1000 +
(tv.tv_usec - atoi((char *)cptr->confs + strlen((char *)cptr->confs) +
1)) / 1000;
cptr->sendM += pingtime;
if (!(cptr->receiveK) || (cptr->receiveK > pingtime))
cptr->receiveK = pingtime;
if (pingtime > cptr->receiveM)
cptr->receiveM = pingtime;
/* Wait at most 10 times the average pingtime for the next one: */
if ((cptr->since =
cptr->sendM / ( 100 * (cptr->hopcount - cptr->hashv + 1))) < 2)
cptr->since = 2;
cptr->firsttime = tv.tv_sec + cptr->since;
Debug(("read_ping: %d bytes, ti %lu: [%s %s] %u ms",
len, cptr->since, (char *)cptr->confs,
(char *)cptr->confs + strlen((char *)cptr->confs) + 1, pingtime));
s = cptr->buffer + strlen(cptr->buffer);
sprintf(s, " %lu", pingtime);
if ((--(cptr->hashv) <= 0 && !DoPing(cptr)) || !(cptr->acpt))
end_ping(cptr);
return;
}
int ping_server(cptr, hp)
aClient *cptr;
struct hostent *hp;
{
if ( ( !cptr->ip.s_addr )
#ifdef UNIXPORT
&& ( ( cptr->sockhost[2] ) != '/' )
#endif
)
{
struct hostent *hp;
char *s;
Link lin;
if (!(cptr->acpt)) return -1; /* Oper left already */
lin.flags = ASYNC_PING;
lin.value.cptr = cptr;
nextdnscheck = 1;
s = (char *)index(cptr->sockhost, '@');
s++; /* should never be NULL; cptr->sockhost is actually a conf->host */
if ((cptr->ip.s_addr = inet_addr(s)) == -1)
{
cptr->ip.s_addr = 0;
hp = gethost_byname(s, &lin);
Debug((DEBUG_NOTICE, "ping_sv: hp %x ac %x ho %s", hp, cptr, s));
if (!hp) return 0;
bcopy(hp->h_addr, (char *)&cptr->ip, sizeof(struct in_addr));
}
}
return start_ping(cptr);
}
/*
** m_uping -- by Run
**
** parv[0] = sender prefix
** parv[1] = pinged server
** parv[2] = port
** parv[3] = hunted server
** parv[4] = number of requested pings
*/
int m_uping(cptr, sptr, parc, parv)
aClient *cptr, *sptr;
int parc;
char *parv[];
{
aConfItem *aconf;
int port, fd, opt;
if (!IsPrivileged(sptr))
{
sendto_one(sptr, err_str(ERR_NOPRIVILEGES), me.name, parv[0]);
return -1;
}
if (parc < 2)
{
sendto_one(sptr, err_str(ERR_NEEDMOREPARAMS),
me.name, parv[0], "UPING");
return 0;
}
if (MyClient(sptr))
{
if (parc == 2)
{
parv[parc++]=UDP_PORT;
parv[parc++]=me.name;
parv[parc++]="5";
}
else if (parc == 3)
{
if (isdigit(*parv[2]))
{
parv[parc++]=me.name;
}
else
{
parv[parc++]=parv[2];
parv[2]=UDP_PORT;
}
parv[parc++]="5";
}
else if (parc == 4)
{
if (isdigit(*parv[2]))
{
if (isdigit(*parv[3]))
{
parv[parc++]=parv[3];
parv[3]=me.name;
}
else
parv[parc++]="5";
}
else
{
parv[parc++]=parv[3];
parv[3]=parv[2];
parv[2]=UDP_PORT;
}
}
}
if (hunt_server(cptr,sptr,":%s UPING %s %s %s %s",3,parc,parv) != HUNTED_ISME)
return 0;
if (BadPtr(parv[4]) || atoi(parv[4])<=0)
{
sendto_one(sptr,":%s NOTICE %s :UPING: Illegal number of packets: %s",
me.name, parv[0], parv[4]);
return 0;
}
/* Check if a CONNECT would be possible at all (adapted from m_connect) */
for (aconf = conf; aconf; aconf = aconf->next)
if (aconf->status == CONF_CONNECT_SERVER &&
matches(parv[1], aconf->name) == 0)
break;
if (!aconf)
for (aconf = conf; aconf; aconf = aconf->next)
if (aconf->status == CONF_CONNECT_SERVER &&
(matches(parv[1], aconf->host) == 0 ||
matches(parv[1], index(aconf->host, '@')+1) == 0))
break;
if (!aconf)
{
sendto_one(sptr, "NOTICE %s :UPING: Host %s not listed in ircd.conf",
parv[0], parv[1]);
return 0;
}
if (AskedPing(sptr))
cancel_ping(sptr, sptr); /* Cancel previous ping request */
/*
* Determine port: First user supplied, then default : 7007
*/
if (!BadPtr(parv[2]) && (port = atoi(parv[2])) <= 0) port=atoi(UDP_PORT);
(void)alarm(2);
if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
{
int err = errno;
(void)alarm(0);
sendto_ops("m_uping: socket: %s", (err != EAGAIN) ?
strerror(err) : "No more sockets");
sendto_one(sptr, ":%s NOTICE %s :UPING: Unable to create udp ping socket",
me.name, parv[0]);
#ifdef USE_SYSLOG
syslog(LOG_ERR, "Unable to create udp ping socket");
#endif
return 0;
}
(void)alarm(0);
if (fcntl(fd, F_SETFL, FNDELAY)==-1)
{
sendto_ops("m_uping: fcntl FNDELAY: %s", strerror(errno));
sendto_one(sptr, ":%s NOTICE %s :UPING: Can't set fd non-blocking",
me.name, parv[0]);
close(fd);
return 0;
}
/*
** On some systems, receive and send buffers must be equal in size.
** Others block select() when the buffers are too small
** (Linux 1.1.50 blocks when < 2048) --Run
*/
opt = 2048;
if (setsockopt(fd, SOL_SOCKET, SO_SNDBUF, (OPT_TYPE *)&opt, sizeof(opt)) < 0 ||
setsockopt(fd, SOL_SOCKET, SO_RCVBUF, (OPT_TYPE *)&opt, sizeof(opt)) < 0)
{
int err=errno;
sendto_ops("m_uping: setsockopt SO_SNDBUF|SO_RCVBUF: %s",
strerror(err));
sendto_one(sptr, ":%s NOTICE %s :UPING: error in setsockopt: %s",
me.name, parv[0], strerror(err));
close(fd);
return 0;
}
if (fd >= MAXCONNECTIONS)
{
sendto_ops("Can't allocate fd for uping (all connections in use)");
sendto_one(sptr, ":%s NOTICE %s :UPING: All connections in use",
me.name, parv[0]);
close(fd);
return 0;
}
if (fd > highest_fd)
highest_fd = fd;
local[fd] = cptr = make_client(NULL);
cptr->confs = (Link *)MyMalloc(UPINGBUFSIZE); /* Really a (char *) */
cptr->fd = fd;
cptr->port = port;
cptr->hopcount = cptr->hashv = cptr->count = MIN(20, atoi(parv[4]));
strcpy(cptr->sockhost, aconf->host);
cptr->acpt = sptr;
SetAskedPing(sptr);
bcopy((void *)&aconf->ipnum, (void *)&cptr->ip, sizeof(struct in_addr));
strcpy(cptr->name, aconf->name);
cptr->firsttime = 0;
SetPing(cptr);
switch (ping_server(cptr, NULL))
{
case 0:
break;
case -1:
del_queries((char *)cptr);
end_ping(cptr);
break;
}
return 0;
}
void end_ping(cptr)
register aClient *cptr;
{
Debug((DEBUG_DEBUG,"end_ping: %x", cptr));
if (cptr->acpt)
{
if (cptr->firsttime) /* Started at all ? */
{
if (cptr->hashv != cptr->hopcount) /* Received any pings at all ? */
{
sendto_one(cptr->acpt, ":%s NOTICE %s :UPING %s%s",
me.name, cptr->acpt->name, cptr->name, cptr->buffer);
sendto_one(cptr->acpt,
":%s NOTICE %s :UPING Stats: sent %d recvd %d ; min/avg/max = %lu/%lu/%lu ms",
me.name, cptr->acpt->name, cptr->hopcount - cptr->count,
cptr->hopcount - cptr->hashv, cptr->receiveK,
(2 * cptr->sendM + cptr->hopcount - cptr->hashv) /
(2 * ( cptr->hopcount - cptr->hashv)),
cptr->receiveM);
}
else
sendto_one(cptr->acpt,
":%s NOTICE %s :UPING: no response from %s within %d seconds",
me.name, cptr->acpt->name, cptr->name,
now + cptr->since - cptr->firsttime);
}
else
sendto_one(cptr->acpt,
":%s NOTICE %s :UPING: Could not start ping to %s %d",
me.name, cptr->acpt->name, cptr->name, cptr->port);
}
(void)close(cptr->fd);
local[cptr->fd] = NULL;
if (cptr->acpt)
ClearAskedPing(cptr->acpt);
MyFree((char *)cptr->confs);
free_client(cptr);
}
void cancel_ping(sptr, acptr)
aClient *sptr, *acptr;
{
int i;
aClient *cptr;
Debug((DEBUG_DEBUG, "Cancelling uping for %x (%s)", sptr, sptr->name));
for (i = highest_fd; i >= 0; i--)
if ((cptr = local[i]) && IsPing(cptr) && cptr->acpt == sptr)
{ cptr->acpt = acptr;
del_queries((char *)cptr);
end_ping(cptr);
break; }
ClearAskedPing(sptr);
}

3017
ircd/s_serv.c Normal file

File diff suppressed because it is too large Load Diff

2802
ircd/s_user.c Normal file

File diff suppressed because it is too large Load Diff

251
ircd/userload.c Normal file
View File

@@ -0,0 +1,251 @@
/****************************************************************************
* Userload module by Michael L. VanLoon (mlv) <michaelv@iastate.edu>
* Written 2/93. Originally grafted into irc2.7.2g 4/93.
*
* IRC - Internet Relay Chat, ircd/userload.c
* Copyright (C) 1990 University of Oulu, Computing Center
*
* 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 1, 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.
****************************************************************************/
#include "struct.h"
#include "common.h"
#include "sys.h"
#include "userload.h"
#include <stdio.h>
#include <sys/types.h>
#include <sys/time.h>
#include <sys/errno.h>
#include <string.h>
#include <signal.h>
#include <sys/resource.h>
#include "h.h"
struct current_load_struct current_load_data;
struct load_entry *load_list_head = NULL, *load_list_tail = NULL,
*load_free_head = NULL, *load_free_tail = NULL;
void update_load()
{
static struct timeval nowt, last;
register struct load_entry *cur_load_entry;
/* This seems to get polluted on startup by an exit_client()
* before any connections have been recorded.
*/
if (current_load_data.local_count > MAXCONNECTIONS ||
current_load_data.client_count > MAXCONNECTIONS ||
current_load_data.conn_count > MAXCONNECTIONS)
bzero((char *)&current_load_data, sizeof(struct current_load_struct));
memcpy(&last, &nowt, sizeof(struct timeval));
if (gettimeofday(&nowt, NULL) != 0)
return; /* error getting time of day--can't calculate time diff */
if (load_free_tail == NULL) {
if ((cur_load_entry =
(struct load_entry *) malloc(sizeof(struct load_entry))) == NULL)
return;
/* printf("malloc pointer: %x\n", cur_load_entry); */
} else {
cur_load_entry = load_free_tail;
load_free_tail = cur_load_entry->prev;
if (load_free_tail == NULL)
load_free_head = NULL;
/* printf("free pointer: %x\n", cur_load_entry); */
}
if (load_list_tail != NULL) {
cur_load_entry->time_incr = ((nowt.tv_sec * 1000 + nowt.tv_usec / 1000 + 5)
- (last.tv_sec * 1000 + last.tv_usec / 1000)) / 10;
cur_load_entry->local_count = current_load_data.local_count;
cur_load_entry->client_count = current_load_data.client_count;
cur_load_entry->conn_count = current_load_data.conn_count;
} else {
load_list_head = cur_load_entry;
bzero((char *)cur_load_entry, sizeof(struct load_entry));
cur_load_entry->time_incr = 1;
}
cur_load_entry->prev = load_list_tail;
load_list_tail = cur_load_entry;
}
void calc_load(sptr, parv)
aClient *sptr;
char *parv; /* we only get passed the original parv[0] */
{
register struct load_entry *cur_load_entry;
struct load_entry *last;
u_long secs = 0, adj_secs, total[3], adj[3];/*[local,client,conn]*/
int i, times[5][3]; /* [min,hour,day,Yest,YYest][local,client,conn] */
char what[3][HOSTLEN + 1];
bzero((char *)total, 3 * sizeof(u_long));
current_load_data.entries = 0;
update_load(); /* we want stats accurate as of *now* */
for (cur_load_entry = load_list_tail; (secs < 6000) &&
(cur_load_entry != NULL); cur_load_entry = cur_load_entry->prev) {
u_long time_incr = cur_load_entry->time_incr;
total[0] += time_incr * cur_load_entry->local_count;
total[1] += time_incr * cur_load_entry->client_count;
total[2] += time_incr * cur_load_entry->conn_count;
last = cur_load_entry;
secs += cur_load_entry->time_incr;
current_load_data.entries++;
}
if ((secs > 6000) && (last != NULL)) {
adj_secs = secs - 6000;
adj[0] = adj_secs * last->local_count;
adj[1] = adj_secs * last->client_count;
adj[2] = adj_secs * last->conn_count;
} else
adj_secs = adj[0] = adj[1] = adj[2] = 0;
for (i = 0; i < 3; i++) {
times[0][i] = ((total[i] - adj[i]) * 1000 / (secs - adj_secs) + 5) / 10;
}
secs = (secs + 5) / 10;
for (i = 0; i < 3; i++)
total[i] = (total[i] + 5) / 10;
for ( ; (secs < 36000) && (cur_load_entry != NULL); secs +=
(cur_load_entry->time_incr + 5) / 10, cur_load_entry =
cur_load_entry->prev, current_load_data.entries++) {
u_long time_incr = (cur_load_entry->time_incr + 5) / 10;
total[0] += time_incr * cur_load_entry->local_count;
total[1] += time_incr * cur_load_entry->client_count;
total[2] += time_incr * cur_load_entry->conn_count;
last = cur_load_entry;
}
if ((secs > 36000) && (last != NULL)) {
adj_secs = secs - 36000;
adj[0] = adj_secs * last->local_count;
adj[1] = adj_secs * last->client_count;
adj[2] = adj_secs * last->conn_count;
} else
adj_secs = adj[0] = adj[1] = adj[2] = 0;
for (i = 0; i < 3; i++) {
times[1][i] = ((total[i] - adj[i]) * 100 / (secs - adj_secs) + 5) / 10;
}
secs = (secs + 5) / 10;
for (i = 0; i < 3; i++)
total[i] = (total[i] + 5) / 10;
for ( ; (secs < 86400) && (cur_load_entry != NULL); secs +=
(cur_load_entry->time_incr + 50) / 100, cur_load_entry =
cur_load_entry->prev, current_load_data.entries++) {
u_long time_incr = (cur_load_entry->time_incr + 50) / 100;
total[0] += time_incr * cur_load_entry->local_count;
total[1] += time_incr * cur_load_entry->client_count;
total[2] += time_incr * cur_load_entry->conn_count;
last = cur_load_entry;
}
if ((secs > 86400) && (last != NULL)) {
adj_secs = secs - 86400;
adj[0] = adj_secs * last->local_count;
adj[1] = adj_secs * last->client_count;
adj[2] = adj_secs * last->conn_count;
} else
adj_secs = adj[0] = adj[1] = adj[2] = 0;
for (i = 0; i < 3; i++) {
times[2][i] = ((total[i] - adj[i]) * 10 / (secs - adj_secs) + 5) / 10;
}
bzero((char *)total, 3 * sizeof(u_long));
for (secs = 1 ; (secs < 86400) && (cur_load_entry != NULL); secs +=
(cur_load_entry->time_incr + 50) / 100, cur_load_entry =
cur_load_entry->prev, current_load_data.entries++) {
u_long time_incr = (cur_load_entry->time_incr + 50) / 100;
total[0] += time_incr * cur_load_entry->local_count;
total[1] += time_incr * cur_load_entry->client_count;
total[2] += time_incr * cur_load_entry->conn_count;
last = cur_load_entry;
}
if ((secs > 86400) && (last != NULL)) {
adj_secs = secs - 86400;
adj[0] = adj_secs * last->local_count;
adj[1] = adj_secs * last->client_count;
adj[2] = adj_secs * last->conn_count;
} else
adj_secs = adj[0] = adj[1] = adj[2] = 0;
for (i = 0; i < 3; i++) {
times[3][i] = ((total[i] - adj[i]) * 10 / (secs - adj_secs) + 5) / 10;
}
bzero((char *)total, 3 * sizeof(u_long));
for (secs = 1 ; (secs < 86400) && (cur_load_entry != NULL); secs +=
(cur_load_entry->time_incr + 50) / 100, cur_load_entry =
cur_load_entry->prev, current_load_data.entries++) {
u_long time_incr = (cur_load_entry->time_incr + 50) / 100;
total[0] += time_incr * cur_load_entry->local_count;
total[1] += time_incr * cur_load_entry->client_count;
total[2] += time_incr * cur_load_entry->conn_count;
last = cur_load_entry;
}
if ((secs > 86400) && (last != NULL)) {
adj_secs = secs - 86400;
adj[0] = adj_secs * last->local_count;
adj[1] = adj_secs * last->client_count;
adj[2] = adj_secs * last->conn_count;
} else
adj_secs = adj[0] = adj[1] = adj[2] = 0;
for (i = 0; i < 3; i++) {
times[4][i] = ((total[i] - adj[i]) * 10 / (secs - adj_secs) + 5) / 10;
}
if ((cur_load_entry != NULL) && (cur_load_entry->prev != NULL) &&
(secs > 86400)) { /* have nodes to free -- more than 3 days old */
struct load_entry *cur_free_entry = load_free_head;
load_free_head = load_list_head;
load_list_head = cur_load_entry;
if (cur_free_entry != NULL)
cur_free_entry->prev = cur_load_entry->prev;
else
load_free_tail = cur_load_entry->prev;
/* printf("freeing: %x (head: %x, tail: %x)\n", cur_load_entry->prev,
load_free_head, load_free_tail); */
cur_load_entry->prev = NULL;
}
strcpy(what[0], DOMAINNAME);
strcat(what[0], " clients");
strcpy(what[1], "total clients");
strcpy(what[2], "total connections");
sendto_one(sptr,
":%s NOTICE %s :Minute Hour Day Yest. YYest. Userload for:",
me.name, parv);
for (i = 0; i < 3; i++)
sendto_one(sptr,
":%s NOTICE %s :%3d.%02d %3d.%01d %3d %3d %3d %s",
me.name, parv, times[0][i] / 100, times[0][i] % 100, times[1][i] / 10,
times[1][i] % 10, times[2][i], times[3][i], times[4][i], what[i]);
}
void initload()
{
bzero((char *)&current_load_data, sizeof(struct current_load_struct));
update_load(); /* Initialize the load list */
}

118
ircd/version.c.SH Executable file
View File

@@ -0,0 +1,118 @@
case $CONFIG in
'') if test -r ../config.sh
then
. ../config.sh ;
else
spitshell=cat
package=IRC
fi
;;
esac
echo "Extracting $package/ircd/version.c..."
if test -r version.c
then
generation=`sed -n 's/^char \*generation = \"\(.*\)\";/\1/p' < version.c`
if test ! "$generation" ; then generation=0; fi
else
generation=0
fi
generation=`expr $generation + 1`
sumsserv=`sum s_serv.c`;
sumsuser=`sum s_user.c`;
sumchan=`sum channel.c`;
sumsbsd=`sum s_bsd.c`;
sumhash=`sum hash.c`;
sumsmisc=`sum s_misc.c`;
sumircd=`sum ircd.c`;
creation=`date | \
awk '{if (NF == 6) \
{ print $1 " " $2 " " $3 " " $6 " at " $4 " " $5 } \
else \
{ print $1 " " $2 " " $3 " " $7 " at " $4 " " $5 " " $6 }}'`
$spitshell >version.c <<!SUB!THIS!
/*
* IRC - Internet Relay Chat, ircd/version.c
* Copyright (C) 1990 Chelsea Ashley Dyerman
*
* 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 1, 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.
*/
/*
* This file is generated by version.c.SH. Any changes made will go away.
*/
#include "struct.h"
#include "patchlevel.h"
char *generation = "$generation";
char *creation = "$creation";
char *version = BASE_VERSION PATCH1 PATCH2 PATCH3 PATCH4\
PATCH5 PATCH6 PATCH7 PATCH8 PATCH9;
char *infotext[] =
{
"$package --",
"Based on the original code written by Jarkko Oikarinen",
"Copyright 1988, 1989, 1990, 1991 University of Oulu, Computing Center",
"",
"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 1, or",
"(at your option) any later version.",
"",
"The following persons have made many changes and enhancements to the",
"code and still know how IRC really works if you have questions about it:",
"",
"Run Carlo Kid carlo@runaway.xs4all.nl",
"Avalon Darren Reed avalon@coombs.anu.edu.au",
"msa Markku Savela Markku.Savela@vtt.fi",
"Wumpus Greg Lindahl gl8f@virginia.edu",
"WiZ Jarkko Oikarinen jto@tolsun.oulu.fi",
"Argv Armin Gruner Armin.Gruner@Informatik.TU-Muenchen.de",
"",
"Thanks to the following people for help with preparing 2.8",
"",
"phone Matthew Green phone@coombs.anu.edu.au",
"Sodapop Chuck Kane ckane@ece.uiuc.edu",
"Skygod Matt Lyle matt@oc.com",
"Vesa Vesa Ruokonen ruokonen@lut.fi",
"Nap Nicolas PIOCH pioch@poly.polytechnique.fr",
"",
"Those who helped in prior versions and continue to be helpful:",
"",
"Stellan Klebom Dan Goodwin Mike Bolotski",
"Ian Frechette Markku Jarvinen Kimmo Suominen",
"Jeff Trim Vijay Subramaniam Karl Kleinpaste",
"Bill Wisner Tom Davis Hugo Calendar",
"Tom Hopkins Stephen van den Berg",
"Bo Adler Michael Sandrof Jon Solomon",
"Jan Peterson Helen Rose Paul Graham",
"",
"Thanks also goes to those persons not mentioned here who have added",
"their advice, opinions, and code to IRC.",
"Thanks also to those who provide the kind sys admins who let me and",
"others continue to develop IRC.",
"",
"[$sumsserv] [$sumchan] [$sumsbsd] [$sumsuser]",
"[$sumhash] [$sumsmisc] [$sumircd]",
0,
};
!SUB!THIS!

224
ircd/whowas.c Normal file
View File

@@ -0,0 +1,224 @@
/************************************************************************
* IRC - Internet Relay Chat, ircd/whowas.c
* Copyright (C) 1990 Markku Savela
*
* 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 1, 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.
*/
/*
* --- avalon --- 6th April 1992
* rewritten to scrap linked lists and use a table of structures which
* is referenced like a circular loop. Should be faster and more efficient.
*/
#ifndef lint
static char sccsid[] = "@(#)whowas.c 2.16 08 Nov 1993 (C) 1988 Markku Savela";
#endif
#include "struct.h"
#include "common.h"
#include "sys.h"
#include "numeric.h"
#include "whowas.h"
#include "h.h"
static aName was[NICKNAMEHISTORYLENGTH];
static int ww_index = 0;
void add_history(cptr)
Reg1 aClient *cptr;
{
aName ntmp;
Reg2 aName *np = &ntmp, *np2;
strncpyzt(np->ww_nick, cptr->name, NICKLEN+1);
strncpyzt(np->ww_info, cptr->info, REALLEN+1);
np->ww_user = cptr->user;
np->ww_logout = now;
np->ww_online = (cptr->from != NULL) ? cptr : NULL;
np->ww_user->refcnt++;
np->ww_server = (char *)MyMalloc(strlen(np->ww_user->server->name)+1);
strcpy(np->ww_server, np->ww_user->server->name);
np2 = &was[ww_index];
if (np2->ww_user)
{
free_user(np2->ww_user, np2->ww_online);
MyFree(np2->ww_server);
}
bcopy((char *)&ntmp, (char *)np2, sizeof(aName));
ww_index++;
if (ww_index >= NICKNAMEHISTORYLENGTH)
ww_index = 0;
return;
}
/*
** get_history
** Return the current client that was using the given
** nickname within the timelimit. Returns NULL, if no
** one found...
*/
aClient *get_history(nick, timelimit)
char *nick;
time_t timelimit;
{
Reg1 aName *wp, *wp2;
Reg2 int i = 0;
if (ww_index == 0)
wp = wp2 = &was[NICKNAMEHISTORYLENGTH - 1];
else
wp = wp2 = &was[ww_index - 1];
timelimit = now-timelimit;
do {
if (!mycmp(nick, wp->ww_nick) && wp->ww_logout >= timelimit)
break;
if (wp == was)
{
i = 1;
wp = &was[NICKNAMEHISTORYLENGTH - 1];
}
else
wp--;
} while (wp != wp2);
if (wp != wp2 || !i)
return (wp->ww_online);
return (NULL);
}
void off_history(cptr)
Reg3 aClient *cptr;
{
Reg1 aName *wp;
Reg2 int i;
for (i = NICKNAMEHISTORYLENGTH, wp = was; i; wp++, i--)
if (wp->ww_online == cptr)
wp->ww_online = NULL;
return;
}
void initwhowas()
{
bzero((char *)was, NICKNAMEHISTORYLENGTH * sizeof(aName));
}
/*
** m_whowas
** parv[0] = sender prefix
** parv[1] = nickname queried
*/
int m_whowas(cptr, sptr, parc, parv)
aClient *cptr, *sptr;
int parc;
char *parv[];
{
Reg1 aName *wp, *wp2 = NULL;
Reg2 int j = 0;
Reg3 anUser *up = NULL;
int max = -1;
char *p, *nick, *s;
if (parc < 2)
{
sendto_one(sptr, err_str(ERR_NONICKNAMEGIVEN),
me.name, parv[0]);
return 0;
}
if (parc > 2)
max = atoi(parv[2]);
if (parc > 3)
if (hunt_server(cptr,sptr,":%s WHOWAS %s %s :%s", 3,parc,parv))
return 0;
for (s = parv[1]; (nick = strtoken(&p, s, ",")); s = NULL)
{
wp = wp2 = &was[ww_index - 1];
do {
if (wp < was)
wp = &was[NICKNAMEHISTORYLENGTH - 1];
if (mycmp(nick, wp->ww_nick) == 0)
{
up = wp->ww_user;
sendto_one(sptr, rpl_str(RPL_WHOWASUSER),
me.name, parv[0], wp->ww_nick,
up->username,
up->host, wp->ww_info);
sendto_one(sptr, rpl_str(RPL_WHOISSERVER),
me.name, parv[0], wp->ww_nick,
wp->ww_server,
myctime(wp->ww_logout));
if (up->away)
sendto_one(sptr, rpl_str(RPL_AWAY),
me.name, parv[0],
wp->ww_nick, up->away);
j++;
}
if (max > 0 && j >= max)
break;
wp--;
} while (wp != wp2);
if (up == NULL)
sendto_one(sptr, err_str(ERR_WASNOSUCHNICK),
me.name, parv[0], nick);
up = NULL;
if (p)
p[-1] = ',';
}
sendto_one(sptr, rpl_str(RPL_ENDOFWHOWAS), me.name, parv[0], parv[1]);
return 0;
}
void count_whowas_memory(wwu, wwa, wwam)
int *wwu, *wwa;
u_long *wwam;
{
Reg1 anUser *tmp;
Reg2 int i, j;
int u = 0, a = 0;
u_long am = 0;
for (i = 0; i < NICKNAMEHISTORYLENGTH; i++)
if ((tmp = was[i].ww_user))
if (!was[i].ww_online)
{
for (j = 0; j < i; j++)
if (was[j].ww_user == tmp)
break;
if (j < i)
continue;
u++;
if (tmp->away)
{
a++;
am += (strlen(tmp->away)+1);
}
}
*wwu = u;
*wwa = a;
*wwam = am;
return;
}