From ab64084f63ce24ffaecf3e551e55320c9d40c9b8 Mon Sep 17 00:00:00 2001 From: Philippe L'Heureux Date: Tue, 26 Dec 2023 16:40:53 -0500 Subject: [PATCH] init --- ADD-TO-IRCRC | 79 + Config | 694 ++++++++ LICENCE | 249 +++ Makefile | 139 ++ Makefile.dist | 139 ++ NOTICE | 4 + READTHIS.NOW | 14 + bsdinstall | 83 + common/Makefile | 63 + common/bsd.c | 186 ++ common/dbuf.c | 345 ++++ common/match.c | 327 ++++ common/packet.c | 115 ++ common/parse.c | 464 +++++ common/send.c | 955 ++++++++++ common/support.c | 472 +++++ doc/Advertisement | 40 + doc/Authors | 153 ++ doc/Crule.readme | 126 ++ doc/Etiquette | 84 + doc/Europe/CoordEBIC | 63 + doc/Europe/IRCNO | 171 ++ doc/Europe/RulesEBIC | 90 + doc/INSTALL | 961 ++++++++++ doc/Makefile | 25 + doc/Manual | 255 +++ doc/NOTE | 331 ++++ doc/Operators | 242 +++ doc/README.patches | 1901 ++++++++++++++++++++ doc/US-Admin/Networking | 156 ++ doc/US-Admin/Operators | 253 +++ doc/example.conf | 332 ++++ doc/history/2.4.notes | 478 +++++ doc/history/2.7-New | 128 ++ doc/history/README-2.6 | 71 + doc/history/history.pre24 | 51 + doc/irc.1 | 82 + doc/ircd.8 | 140 ++ doc/m4macros | 47 + include/channel.h | 38 + include/class.h | 69 + include/common.h | 146 ++ include/config.h | 727 ++++++++ include/config.h.dist | 727 ++++++++ include/dbuf.h | 163 ++ include/h.h | 242 +++ include/hash.h | 37 + include/inet.h | 50 + include/msg.h | 187 ++ include/nameser.h | 248 +++ include/numeric.h | 363 ++++ include/patchlevel.h | 141 ++ include/res.h | 63 + include/resolv.h | 78 + include/sock.h | 41 + include/struct.h | 622 +++++++ include/sys.h | 114 ++ include/userload.h | 49 + include/whowas.h | 93 + ircd/Makefile | 291 +++ ircd/buildm4 | 84 + ircd/channel.c | 2676 ++++++++++++++++++++++++++++ ircd/chkconf.c | 755 ++++++++ ircd/class.c | 236 +++ ircd/crule.c | 775 ++++++++ ircd/crypt/Makefile | 35 + ircd/crypt/README | 61 + ircd/crypt/crypter | 52 + ircd/crypt/mkpasswd.c | 40 + ircd/crypt/sums | 38 + ircd/hash.c | 755 ++++++++ ircd/ircd.c | 882 +++++++++ ircd/list.c | 543 ++++++ ircd/map.c | 97 + ircd/note.c | 3563 +++++++++++++++++++++++++++++++++++++ ircd/random.c | 158 ++ ircd/res.c | 1417 +++++++++++++++ ircd/res_comp.c | 329 ++++ ircd/res_init.c | 206 +++ ircd/res_mkquery.c | 192 ++ ircd/s_auth.c | 267 +++ ircd/s_bsd.c | 2601 +++++++++++++++++++++++++++ ircd/s_conf.c | 1438 +++++++++++++++ ircd/s_debug.c | 475 +++++ ircd/s_err.c | 367 ++++ ircd/s_misc.c | 777 ++++++++ ircd/s_numeric.c | 129 ++ ircd/s_ping.c | 500 ++++++ ircd/s_serv.c | 3017 +++++++++++++++++++++++++++++++ ircd/s_user.c | 2802 +++++++++++++++++++++++++++++ ircd/userload.c | 251 +++ ircd/version.c.SH | 118 ++ ircd/whowas.c | 224 +++ 93 files changed, 40857 insertions(+) create mode 100644 ADD-TO-IRCRC create mode 100755 Config create mode 100644 LICENCE create mode 100644 Makefile create mode 100644 Makefile.dist create mode 100644 NOTICE create mode 100644 READTHIS.NOW create mode 100755 bsdinstall create mode 100644 common/Makefile create mode 100644 common/bsd.c create mode 100644 common/dbuf.c create mode 100644 common/match.c create mode 100644 common/packet.c create mode 100644 common/parse.c create mode 100644 common/send.c create mode 100644 common/support.c create mode 100644 doc/Advertisement create mode 100644 doc/Authors create mode 100644 doc/Crule.readme create mode 100644 doc/Etiquette create mode 100644 doc/Europe/CoordEBIC create mode 100644 doc/Europe/IRCNO create mode 100644 doc/Europe/RulesEBIC create mode 100644 doc/INSTALL create mode 100644 doc/Makefile create mode 100644 doc/Manual create mode 100644 doc/NOTE create mode 100644 doc/Operators create mode 100644 doc/README.patches create mode 100644 doc/US-Admin/Networking create mode 100644 doc/US-Admin/Operators create mode 100644 doc/example.conf create mode 100644 doc/history/2.4.notes create mode 100644 doc/history/2.7-New create mode 100644 doc/history/README-2.6 create mode 100644 doc/history/history.pre24 create mode 100644 doc/irc.1 create mode 100644 doc/ircd.8 create mode 100644 doc/m4macros create mode 100644 include/channel.h create mode 100644 include/class.h create mode 100644 include/common.h create mode 100644 include/config.h create mode 100644 include/config.h.dist create mode 100644 include/dbuf.h create mode 100644 include/h.h create mode 100644 include/hash.h create mode 100644 include/inet.h create mode 100644 include/msg.h create mode 100644 include/nameser.h create mode 100644 include/numeric.h create mode 100644 include/patchlevel.h create mode 100644 include/res.h create mode 100644 include/resolv.h create mode 100644 include/sock.h create mode 100644 include/struct.h create mode 100644 include/sys.h create mode 100644 include/userload.h create mode 100644 include/whowas.h create mode 100644 ircd/Makefile create mode 100755 ircd/buildm4 create mode 100644 ircd/channel.c create mode 100644 ircd/chkconf.c create mode 100644 ircd/class.c create mode 100644 ircd/crule.c create mode 100644 ircd/crypt/Makefile create mode 100644 ircd/crypt/README create mode 100755 ircd/crypt/crypter create mode 100644 ircd/crypt/mkpasswd.c create mode 100755 ircd/crypt/sums create mode 100644 ircd/hash.c create mode 100644 ircd/ircd.c create mode 100644 ircd/list.c create mode 100644 ircd/map.c create mode 100644 ircd/note.c create mode 100644 ircd/random.c create mode 100644 ircd/res.c create mode 100644 ircd/res_comp.c create mode 100644 ircd/res_init.c create mode 100644 ircd/res_mkquery.c create mode 100644 ircd/s_auth.c create mode 100644 ircd/s_bsd.c create mode 100644 ircd/s_conf.c create mode 100644 ircd/s_debug.c create mode 100644 ircd/s_err.c create mode 100644 ircd/s_misc.c create mode 100644 ircd/s_numeric.c create mode 100644 ircd/s_ping.c create mode 100644 ircd/s_serv.c create mode 100644 ircd/s_user.c create mode 100644 ircd/userload.c create mode 100755 ircd/version.c.SH create mode 100644 ircd/whowas.c 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::