commit ab64084f63ce24ffaecf3e551e55320c9d40c9b8 Author: Philippe L'Heureux Date: Tue Dec 26 16:40:53 2023 -0500 init diff --git a/ADD-TO-IRCRC b/ADD-TO-IRCRC new file mode 100644 index 0000000..c1db017 --- /dev/null +++ b/ADD-TO-IRCRC @@ -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 "*" diff --git a/Config b/Config new file mode 100755 index 0000000..63539da --- /dev/null +++ b/Config @@ -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 +#include +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 +#include +#include +#include +#include +#include +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 + +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 +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 +#endif +#ifdef STRINGSH +#include +#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 +#include +#include +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 +#include +#include +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 +#endif +#ifdef STRINGSH +#include +#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 +#endif +#ifdef STRINGSH +#include +#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 +#include +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 +#include +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 +#include +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 diff --git a/LICENCE b/LICENCE new file mode 100644 index 0000000..9a17037 --- /dev/null +++ b/LICENCE @@ -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. + + + Copyright (C) 19yy + + 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. + + , 1 April 1989 + Ty Coon, President of Vice + +That's all there is to it! diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..1bbd7db --- /dev/null +++ b/Makefile @@ -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 + diff --git a/Makefile.dist b/Makefile.dist new file mode 100644 index 0000000..1bbd7db --- /dev/null +++ b/Makefile.dist @@ -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 + diff --git a/NOTICE b/NOTICE new file mode 100644 index 0000000..a70d906 --- /dev/null +++ b/NOTICE @@ -0,0 +1,4 @@ + +This software package includes source code supplied by the University of +California of Berkeley. + diff --git a/READTHIS.NOW b/READTHIS.NOW new file mode 100644 index 0000000..f3ccfeb --- /dev/null +++ b/READTHIS.NOW @@ -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 diff --git a/bsdinstall b/bsdinstall new file mode 100755 index 0000000..277d8f3 --- /dev/null +++ b/bsdinstall @@ -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 diff --git a/common/Makefile b/common/Makefile new file mode 100644 index 0000000..94d59ab --- /dev/null +++ b/common/Makefile @@ -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 diff --git a/common/bsd.c b/common/bsd.c new file mode 100644 index 0000000..9853d56 --- /dev/null +++ b/common/bsd.c @@ -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 + +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); +} diff --git a/common/dbuf.c b/common/dbuf.c new file mode 100644 index 0000000..f81b475 --- /dev/null +++ b/common/dbuf.c @@ -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 +#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; +} diff --git a/common/match.c b/common/match.c new file mode 100644 index 0000000..4f0a90e --- /dev/null +++ b/common/match.c @@ -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 + }; + diff --git a/common/packet.c b/common/packet.c new file mode 100644 index 0000000..4d9b877 --- /dev/null +++ b/common/packet.c @@ -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; +} diff --git a/common/parse.c b/common/parse.c new file mode 100644 index 0000000..c452e16 --- /dev/null +++ b/common/parse.c @@ -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); +} diff --git a/common/send.c b/common/send.c new file mode 100644 index 0000000..c9e1484 --- /dev/null +++ b/common/send.c @@ -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 + +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; +} diff --git a/common/support.c b/common/support.c new file mode 100644 index 0000000..22d62a0 --- /dev/null +++ b/common/support.c @@ -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 +#include +#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; +} diff --git a/doc/Advertisement b/doc/Advertisement new file mode 100644 index 0000000..af810d1 --- /dev/null +++ b/doc/Advertisement @@ -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. + diff --git a/doc/Authors b/doc/Authors new file mode 100644 index 0000000..5c5a5f6 --- /dev/null +++ b/doc/Authors @@ -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 . +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 : Emacs-like editing facility for the client + +Kimmo Suominen : HP-UX port + +Jeff Trim : enhancements and advice + +Vijay Subramaniam : advice and ruthless publicity + +Karl Kleinpaste : user's manual + +Greg Lindahl : AUTOMATON code, the Wumpus GM automaton, +myriad bug fixes + +Bill Wisner : numerous bug fixes and code +enhancements + +Tom Davis and Tim Russell : +VMS modifications + +Markku Savela : advice, support, and being the +incentive to do some of our *own* coding. :) + +Tom Hopkins : bug fixes, quarantine lines, +consolidation of various patches. + +Christopher Davis : EFnet/Anet gateway coding, +many automata ;), documentation fixing. + +Helen Rose : documentation updating, and fixing. + +Tom Hinds : emacs client updating. + +Tim Miller : various server and client-breaking +features. + +Darren Reed : various bug fixes and enhancements. +Introduced nickname and channelname hash tables into the server. + +The version 2.2 release was coordinated by Mike Bolotski +. + +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 +Chuck Kane +Matt Lyle +Vesa Ruokonen + +Markku Savela / 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 / 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 / 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 / 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 +Bo Adler +Michael Sandrof +Jon Solomon +Jan Peterson +Nathan Glasser +Helen Rose +Mike Pelletier +Basalat Ali Raja +Eric P. Scott +Dan Goodwin +Noah Friedman + +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 - Review member coder-com +WildThang - Review member coder-com +Kev - Secretary coder-com +Cym +Xorath +smg +Chaos +Aaron diff --git a/doc/Crule.readme b/doc/Crule.readme new file mode 100644 index 0000000..803f06f --- /dev/null +++ b/doc/Crule.readme @@ -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. diff --git a/doc/Etiquette b/doc/Etiquette new file mode 100644 index 0000000..ba6bb82 --- /dev/null +++ b/doc/Etiquette @@ -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. diff --git a/doc/Europe/CoordEBIC b/doc/Europe/CoordEBIC new file mode 100644 index 0000000..3b38398 --- /dev/null +++ b/doc/Europe/CoordEBIC @@ -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 + +*.ch SWITCH, EUNET/CH + 1. StarNet Karim Saouli + 2. Maxim Maxim Samo + +*.de WIN, BelWue + 1. YeggMan Volker Paulsen + 2. Haegar Thomas Thissen + +*.dk DENET, DKNET + 1. karthy Karsten Thygesen + 2. MAGNA Jens Fallesen + +*.fi FUNET + 1. Vesa Vesa Ruokonen + 2. Visti Hannu Visti + +*.fr EASINET/ROCAD, RENATER + 1. Nono Arnaud Girsch + 2. Le_Chat Laurent Montaron + +*.it CILEA + 1. Allanon Riccardo Facchetti + 2. mAu Maurizio Paoluzi + +*.nl SURFNET/NLNET + 1. scorpio Cor Bosman + 2. Erwin Erwin Bolwidt + +*.no UNINETT + 1. Veggen Vegard Engen + +*.pl POLIP + 1. Artur Artur Jaroszek + +*.se SUNET + 1. Black Christer H. Jansson + 2. Sorg Owe A Rasmussen + +*.uk JANET, JIPS + 1. ScottM Scott A. McIntyre + + diff --git a/doc/Europe/IRCNO b/doc/Europe/IRCNO new file mode 100644 index 0000000..6fafd8d --- /dev/null +++ b/doc/Europe/IRCNO @@ -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) + diff --git a/doc/Europe/RulesEBIC b/doc/Europe/RulesEBIC new file mode 100644 index 0000000..613fe89 --- /dev/null +++ b/doc/Europe/RulesEBIC @@ -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 + + + 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. + + +############################################################################ + diff --git a/doc/INSTALL b/doc/INSTALL new file mode 100644 index 0000000..753daea --- /dev/null +++ b/doc/INSTALL @@ -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:::: +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::xxx:: + 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: , 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:::: + 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:::: + 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::::: + 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::: + 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::