init
This commit is contained in:
79
ADD-TO-IRCRC
Normal file
79
ADD-TO-IRCRC
Normal 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
694
Config
Executable 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
249
LICENCE
Normal 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
139
Makefile
Normal 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
139
Makefile.dist
Normal 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
4
NOTICE
Normal file
@@ -0,0 +1,4 @@
|
||||
|
||||
This software package includes source code supplied by the University of
|
||||
California of Berkeley.
|
||||
|
||||
14
READTHIS.NOW
Normal file
14
READTHIS.NOW
Normal 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
83
bsdinstall
Executable 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
63
common/Makefile
Normal 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
186
common/bsd.c
Normal 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
345
common/dbuf.c
Normal 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
327
common/match.c
Normal 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
115
common/packet.c
Normal 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
464
common/parse.c
Normal 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
955
common/send.c
Normal 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
472
common/support.c
Normal 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
40
doc/Advertisement
Normal 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
153
doc/Authors
Normal 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
126
doc/Crule.readme
Normal 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
84
doc/Etiquette
Normal 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
63
doc/Europe/CoordEBIC
Normal 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
171
doc/Europe/IRCNO
Normal 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
90
doc/Europe/RulesEBIC
Normal 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
961
doc/INSTALL
Normal 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
25
doc/Makefile
Normal 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
255
doc/Manual
Normal 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
331
doc/NOTE
Normal 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
242
doc/Operators
Normal 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
1901
doc/README.patches
Normal file
File diff suppressed because it is too large
Load Diff
156
doc/US-Admin/Networking
Normal file
156
doc/US-Admin/Networking
Normal 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
253
doc/US-Admin/Operators
Normal 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
332
doc/example.conf
Normal 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
478
doc/history/2.4.notes
Normal 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
128
doc/history/2.7-New
Normal 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
71
doc/history/README-2.6
Normal 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
51
doc/history/history.pre24
Normal 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
82
doc/irc.1
Normal 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
140
doc/ircd.8
Normal 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
47
doc/m4macros
Normal 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
38
include/channel.h
Normal 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
69
include/class.h
Normal 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
146
include/common.h
Normal 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
727
include/config.h
Normal 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
727
include/config.h.dist
Normal 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
163
include/dbuf.h
Normal 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
242
include/h.h
Normal 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
37
include/hash.h
Normal 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
50
include/inet.h
Normal 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
187
include/msg.h
Normal 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
248
include/nameser.h
Normal 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
363
include/numeric.h
Normal 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
141
include/patchlevel.h
Normal 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
63
include/res.h
Normal 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
78
include/resolv.h
Normal 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
41
include/sock.h
Normal 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
622
include/struct.h
Normal 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
114
include/sys.h
Normal 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
49
include/userload.h
Normal 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
93
include/whowas.h
Normal 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
291
ircd/Makefile
Normal 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
84
ircd/buildm4
Executable 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
2676
ircd/channel.c
Normal file
File diff suppressed because it is too large
Load Diff
755
ircd/chkconf.c
Normal file
755
ircd/chkconf.c
Normal 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
236
ircd/class.c
Normal 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
775
ircd/crule.c
Normal 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
35
ircd/crypt/Makefile
Normal 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
61
ircd/crypt/README
Normal 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
52
ircd/crypt/crypter
Executable 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
40
ircd/crypt/mkpasswd.c
Normal 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
38
ircd/crypt/sums
Executable 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
755
ircd/hash.c
Normal 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
882
ircd/ircd.c
Normal 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
543
ircd/list.c
Normal 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
97
ircd/map.c
Normal 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
3563
ircd/note.c
Normal file
File diff suppressed because it is too large
Load Diff
158
ircd/random.c
Normal file
158
ircd/random.c
Normal 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
1417
ircd/res.c
Normal file
File diff suppressed because it is too large
Load Diff
329
ircd/res_comp.c
Normal file
329
ircd/res_comp.c
Normal 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
206
ircd/res_init.c
Normal 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
192
ircd/res_mkquery.c
Normal 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
267
ircd/s_auth.c
Normal 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
2601
ircd/s_bsd.c
Normal file
File diff suppressed because it is too large
Load Diff
1438
ircd/s_conf.c
Normal file
1438
ircd/s_conf.c
Normal file
File diff suppressed because it is too large
Load Diff
475
ircd/s_debug.c
Normal file
475
ircd/s_debug.c
Normal 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
367
ircd/s_err.c
Normal 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
777
ircd/s_misc.c
Normal 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
129
ircd/s_numeric.c
Normal 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
500
ircd/s_ping.c
Normal 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
3017
ircd/s_serv.c
Normal file
File diff suppressed because it is too large
Load Diff
2802
ircd/s_user.c
Normal file
2802
ircd/s_user.c
Normal file
File diff suppressed because it is too large
Load Diff
251
ircd/userload.c
Normal file
251
ircd/userload.c
Normal 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 *)¤t_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 *)¤t_load_data, sizeof(struct current_load_struct));
|
||||
update_load(); /* Initialize the load list */
|
||||
}
|
||||
118
ircd/version.c.SH
Executable file
118
ircd/version.c.SH
Executable 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
224
ircd/whowas.c
Normal 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;
|
||||
}
|
||||
Reference in New Issue
Block a user