diff -c -r -N irc2.8.21+CSr23/Makefile irc2.8.21+CSr24/Makefile *** irc2.8.21+CSr23/Makefile Fri Apr 5 20:24:40 1996 --- irc2.8.21+CSr24/Makefile Wed Jul 24 21:31:56 1996 *************** *** 55,61 **** #IRCDLIBS=-lresolv # # Solaris 2 ! #IRCDLIBS=-lsocket -lnsl #IRCLIBS=-lcurses -ltermcap -lresolv -lsocket -lnsl # # ESIX --- 55,61 ---- #IRCDLIBS=-lresolv # # Solaris 2 ! #IRCDLIBS=-lsocket -lnsl -lresolv #IRCLIBS=-lcurses -ltermcap -lresolv -lsocket -lnsl # # ESIX diff -c -r -N irc2.8.21+CSr23/README.CS irc2.8.21+CSr24/README.CS *** irc2.8.21+CSr23/README.CS Wed May 29 19:49:11 1996 --- irc2.8.21+CSr24/README.CS Wed Jul 24 22:26:44 1996 *************** *** 1,5 **** --- 1,31 ---- + --- + + This is the README for irc2.8.21+CSr24. Basically, this is just a list + of changes...more information can be found in include/comstud.h. + + Any questions or comments can be directed to cbehrens@stealth.net + + --- + NOTE: Please change values in comstud.h and dog3.h to your liking... The default values are probably less than ideal for you! + + New in CSr24: + + 1) BUFFERED_LOGS were not logging at all...this is fixed. + 2) Patched match.c to fix coredumps + 3) Attempted to add poll(), using basically all of the code from 2.9 + This is for Solaris folks only, of course. There is a #define in + config.h for "USE_POLL" after the section where you #define SOL20 + 4) Added #define LIMIT_UH. You can now limit your server to only allow + a certain # of connections from a u@h...For example, LIMIT_UH 1 will + only allow 1 u@h per client. If another person with the same u@h tries + to connect, they will be rejected. While on IRC, you can /QUOTE LIMITUH # + 5) Added a notice to opers when a person tries to "evade" identd. + I had this in one of my 2.8.16 ircds, but when ds2 added it to his, it + reminded me that I had forgotten to carry it over to my 2.8.21 series... + Thanks, buddy =) Sorry, I am going to stick with using identd replies + for clients' usernames. New in CSr23: diff -c -r -N irc2.8.21+CSr23/common/inet_addr.c irc2.8.21+CSr24/common/inet_addr.c *** irc2.8.21+CSr23/common/inet_addr.c Fri Apr 5 20:22:35 1996 --- irc2.8.21+CSr24/common/inet_addr.c Wed Jul 24 20:23:43 1996 *************** *** 61,66 **** --- 61,70 ---- #include "nameser.h" #include "resolv.h" + #ifndef INADDR_NONE + #define INADDR_NONE -1 + #endif + /* this is a compatibility routine, not needed on recent BSD releases */ #ifdef NEED_INET_ADDR /* diff -c -r -N irc2.8.21+CSr23/common/match.c irc2.8.21+CSr24/common/match.c *** irc2.8.21+CSr23/common/match.c Fri Apr 5 20:22:34 1996 --- irc2.8.21+CSr24/common/match.c Sat Jul 20 01:10:06 1996 *************** *** 27,34 **** #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 --- 27,32 ---- *************** *** 53,60 **** while (1) { - if (calls++ > MAX_CALLS) - return 1; if (*m == '*') { while (*m == '*') --- 51,56 ---- *************** *** 115,128 **** int match(ma, na) char *ma, *na; { - calls = 0; return _match(ma, na); } int matches(ma, na) char *ma,*na; { - calls = 0; return _match(ma, na); } --- 111,122 ---- diff -c -r -N irc2.8.21+CSr23/include/comstud.h irc2.8.21+CSr24/include/comstud.h *** irc2.8.21+CSr23/include/comstud.h Thu May 30 00:29:11 1996 --- irc2.8.21+CSr24/include/comstud.h Wed Jul 24 23:46:24 1996 *************** *** 1,6 **** --- 1,21 ---- #ifndef COMSTUD_H #define COMSTUD_H + /* LIMIT_UH - If you want to limit clients to 1 u@h on your server, + define this to 1. You can also define this to 0 + which disables the check...but it will compile the + code into the server, and then you can /quote limituh # + while opered. + If you never want to use this, #undef it. + Examples: + + #define LIMIT_UH 1 - Starts out limiting 1 client per user@host + #define LIMIT_UH 0 - Starts out with no checking, but you can /quote + #undef LIMIT_UH - Doesn't compile in the code.../quote won't work. + */ + + #define LIMIT_UH 0 + /* BUFFERED_LOGS - define this to reduce disk IO when writing users.log and clones.log *************** *** 220,226 **** want them logged */ ! #define FNAME_FAILED_OPER "/home/irc/irc2.8.21+CSr23/lib/logs/failed.log" /* CLIENT_NOTICES - define this if you wish to see client connecting and exiting notices via /umode +c --- 235,241 ---- want them logged */ ! #define FNAME_FAILED_OPER "/home/irc/irc2.8.21+CSr24/lib/logs/failed.log" /* CLIENT_NOTICES - define this if you wish to see client connecting and exiting notices via /umode +c *************** *** 310,316 **** and you wish to log clones */ ! #define FNAME_CLONELOG "/home/irc/irc2.8.21+CSr23/lib/logs/clones.log" /* DEFAULT_IDLELIMIT - if you have CHECK_IDLE defined above, this value is the default # a client --- 325,331 ---- and you wish to log clones */ ! #define FNAME_CLONELOG "/home/irc/irc2.8.21+CSr24/lib/logs/clones.log" /* DEFAULT_IDLELIMIT - if you have CHECK_IDLE defined above, this value is the default # a client diff -c -r -N irc2.8.21+CSr23/include/config.h irc2.8.21+CSr24/include/config.h *** irc2.8.21+CSr23/include/config.h Thu May 30 00:29:19 1996 --- irc2.8.21+CSr24/include/config.h Wed Jul 24 21:32:06 1996 *************** *** 54,59 **** --- 54,67 ---- #undef MAIL50 /* If you're running VMS 5.0 */ #undef PCS /* PCS Cadmus MUNIX, use with BSD flag! */ + #ifdef SOL20 + + #define USE_POLL /* Define this if you want to use poll() + on lame Solaris */ + + #endif + + /* * NOTE: On some systems, valloc() causes many problems. */ *************** *** 108,115 **** * these are only the recommened names and paths. Change as needed. * You must define these to something, even if you don't really want them. */ ! #define DPATH "/home/irc/irc2.8.21+CSr23/lib" /* dir where all ircd stuff is */ ! #define SPATH "/home/irc/irc2.8.21+CSr23/lib/ircd" #define CPATH "ircd.conf" /* server configuration file */ #define MPATH "ircd.motd" /* server MOTD file */ #define LPATH "ircd.log" /* Where the debug file lives, if DEBUGMODE */ --- 116,123 ---- * these are only the recommened names and paths. Change as needed. * You must define these to something, even if you don't really want them. */ ! #define DPATH "/home/irc/irc2.8.21+CSr24/lib" /* dir where all ircd stuff is */ ! #define SPATH "/home/irc/irc2.8.21+CSr24/lib/ircd" #define CPATH "ircd.conf" /* server configuration file */ #define MPATH "ircd.motd" /* server MOTD file */ #define LPATH "ircd.log" /* Where the debug file lives, if DEBUGMODE */ *************** *** 123,130 **** * successful use of /oper. These are either full paths or files within DPATH. */ ! #define FNAME_USERLOG "/home/irc/irc2.8.21+CSr23/logs/users.log" /* */ ! #define FNAME_OPERLOG "/home/irc/irc2.8.21+CSr23/logs/opers.log" /* */ /* CHROOTDIR * --- 131,138 ---- * successful use of /oper. These are either full paths or files within DPATH. */ ! #define FNAME_USERLOG "/home/irc/irc2.8.21+CSr24/logs/users.log" /* */ ! #define FNAME_OPERLOG "/home/irc/irc2.8.21+CSr24/logs/opers.log" /* */ /* CHROOTDIR * diff -c -r -N irc2.8.21+CSr23/include/h.h irc2.8.21+CSr24/include/h.h *** irc2.8.21+CSr23/include/h.h Sat Apr 27 16:28:15 1996 --- irc2.8.21+CSr24/include/h.h Wed Jul 24 21:31:34 1996 *************** *** 26,31 **** --- 26,35 ---- #include "comstud.h" + #ifdef LIMIT_UH + extern int uhlimit; + #endif + #ifdef HIGHEST_CONNECTION extern void check_max_count(); #endif /* HIGHEST_CONNECTION */ diff -c -r -N irc2.8.21+CSr23/include/msg.h irc2.8.21+CSr24/include/msg.h *** irc2.8.21+CSr23/include/msg.h Fri Apr 5 20:22:34 1996 --- irc2.8.21+CSr24/include/msg.h Wed Jul 24 21:34:14 1996 *************** *** 90,95 **** --- 90,98 ---- #ifdef IDLE_CHECK #define MSG_IDLE "IDLE" /* IDLE */ #endif + #ifdef LIMIT_UH + #define MSG_LIMITUH "LIMITUH" /* LIMITUH */ + #endif #define MAXPARA 15 #ifdef DOG3 *************** *** 102,107 **** --- 105,113 ---- #ifdef IDLE_CHECK extern int m_idle(); #endif + #ifdef LIMIT_UH + extern int m_limituh(); + #endif extern int m_private(), m_topic(), m_join(), m_part(), m_mode(); extern int m_ping(), m_pong(), m_wallops(), m_kick(); extern int m_nick(), m_error(), m_notice(); *************** *** 191,196 **** --- 197,205 ---- #endif #ifdef IDLE_CHECK { MSG_IDLE, m_idle, 0, MAXPARA, 1 ,0L }, + #endif + #ifdef LIMIT_UH + { MSG_LIMITUH, m_limituh, 0, MAXPARA, 1 ,0L }, #endif #if defined(NPATH) && !defined(CLIENT_COMPILE) { MSG_NOTE, m_note, 0, 1, 1 ,0L }, diff -c -r -N irc2.8.21+CSr23/include/patchlevel.h irc2.8.21+CSr24/include/patchlevel.h *** irc2.8.21+CSr23/include/patchlevel.h Thu May 30 00:29:02 1996 --- irc2.8.21+CSr24/include/patchlevel.h Wed Jul 24 22:29:51 1996 *************** *** 17,21 **** */ #ifndef PATCHLEVEL ! #define PATCHLEVEL "2.8.21+CSr23" #endif --- 17,21 ---- */ #ifndef PATCHLEVEL ! #define PATCHLEVEL "2.8.21+CSr24" #endif diff -c -r -N irc2.8.21+CSr23/ircd/ircd.c irc2.8.21+CSr24/ircd/ircd.c *** irc2.8.21+CSr23/ircd/ircd.c Wed May 29 19:45:15 1996 --- irc2.8.21+CSr24/ircd/ircd.c Wed Jul 24 21:31:15 1996 *************** *** 98,103 **** --- 98,107 ---- int idlelimit = DEFAULT_IDLELIMIT; #endif + #ifdef LIMIT_UH + int uhlimit = LIMIT_UH; + #endif + time_t NOW; aClient me; /* That's me */ aClient *client = &me; /* Pointer to beginning of Client list */ diff -c -r -N irc2.8.21+CSr23/ircd/s_bsd.c irc2.8.21+CSr24/ircd/s_bsd.c *** irc2.8.21+CSr23/ircd/s_bsd.c Fri Apr 5 20:22:35 1996 --- irc2.8.21+CSr24/ircd/s_bsd.c Wed Jul 24 20:25:14 1996 *************** *** 61,66 **** --- 61,72 ---- #include #include #include + + #ifdef USE_POLL + #include + #include + #endif /* USE_POLL_ */ + #ifdef AIX # include # include *************** *** 1374,1386 **** ** Do some tricky stuff for client connections to make sure they don't do ** any flooding >:-) -avalon */ ! static int read_packet(cptr, rfd) Reg1 aClient *cptr; ! fd_set *rfd; { Reg1 int dolen = 0, length = 0, done; ! if (FD_ISSET(cptr->fd, rfd) && !(IsPerson(cptr) && DBufLength(&cptr->recvQ) > 6090)) { errno = 0; --- 1380,1392 ---- ** Do some tricky stuff for client connections to make sure they don't do ** any flooding >:-) -avalon */ ! static int read_packet(cptr, msg_ready) Reg1 aClient *cptr; ! int msg_ready; { Reg1 int dolen = 0, length = 0, done; ! if (msg_ready && !(IsPerson(cptr) && DBufLength(&cptr->recvQ) > 6090)) { errno = 0; *************** *** 1489,1494 **** --- 1495,1502 ---- } + #ifndef USE_POLL + /* * Check all connections for new connections and input data that is to be * processed. Also check for connections with data queued and whether we can *************** *** 1762,1768 **** } length = 1; /* for fall through case */ if (!NoNewLine(cptr) || FD_ISSET(i, &read_set)) ! length = read_packet(cptr, &read_set); #ifndef DOG3 if (length > 0) flush_connections(i); --- 1770,1776 ---- } length = 1; /* for fall through case */ if (!NoNewLine(cptr) || FD_ISSET(i, &read_set)) ! length = read_packet(cptr, FD_ISSET(i, &read_set)); #ifndef DOG3 if (length > 0) flush_connections(i); *************** *** 1807,1812 **** --- 1815,2192 ---- } return 0; } + + #else /* USE_POLL */ + + #ifdef DOG3 + + int read_message(delay, listp) + time_t delay; /* Don't ever use ZERO here, unless you mean to poll and then + * you have to have sleep/wait somewhere else in the code.--msa + */ + fdlist *listp; + + #else + + int read_message(delay) + time_t delay; + + #endif + + { + /* + * eliminate the direct FD_ macros as they are select() specific + * and replace them with a higher level abstraction that also works for + * poll()... + */ + #define POLLREADFLAGS (POLLIN|POLLRDNORM) + #define POLLWRITEFLAGS (POLLOUT|POLLWRNORM) + #define SET_READ_EVENT( thisfd ){ CHECK_PFD( thisfd );\ + pfd->events |= POLLREADFLAGS;} + #define SET_WRITE_EVENT( thisfd ){ CHECK_PFD( thisfd );\ + pfd->events |= POLLWRITEFLAGS;} + #define CHECK_PFD( thisfd ) \ + if ( pfd->fd != thisfd ) { \ + pfd = &poll_fdarray[nbr_pfds++];\ + pfd->fd = thisfd; \ + pfd->events = 0; \ + } + + register aClient *cptr; + register int nfds; + struct timeval wait; + + #ifdef pyr + struct timeval nowt; + u_long us; + #endif + pollfd_t poll_fdarray[MAXCONNECTIONS]; + pollfd_t * pfd = poll_fdarray; + pollfd_t * res_pfd = NULL; + pollfd_t * udp_pfd = NULL; + aClient * authclnts[MAXCONNECTIONS]; /* mapping of auth fds to client */ + int nbr_pfds = 0; + time_t delay2 = delay; + u_long usec = 0; + int res, length, fd, i, fdnew; + int auth = 0; + #ifdef DOG3 + register int j; + + /* if it is called with NULL we check all active fd's */ + if (!listp) + { + listp = &default_fdlist; + listp->last_entry = highest_fd+1; /* remember the 0th entry isnt */ + } + + #endif + + #ifdef NPATH + note_delay(&delay); + #endif + #ifdef pyr + (void) gettimeofday(&nowt, NULL); + NOW = nowt.tv_sec; + #endif + + for (res = 0;;) + { + /* set up such that CHECK_FD works */ + nbr_pfds = 0; + pfd = poll_fdarray; + pfd->fd = -1; + auth = 0; + res_pfd = NULL; + udp_pfd = NULL; + + #ifndef DOG3 + for (i = highest_fd; i >= 0; i--) + #else + for (i=listp->entry[j=1];j<=listp->last_entry; + i=listp->entry[++j]) + #endif + { + if (!(cptr = local[i]) || IsLog(cptr)) + continue; + Debug((DEBUG_NOTICE, "fd %d cptr %#x %d %#x %s", + i, cptr, cptr->status, cptr->flags, + get_client_name(cptr,TRUE))); + if (DoingAuth(cptr)) + { + if ( auth == 0 ) + bzero( (char *)&authclnts, + sizeof(authclnts) ); + auth++; + Debug((DEBUG_NOTICE,"auth on %x %d", cptr, + i)); + SET_READ_EVENT(cptr->authfd); + if (cptr->flags & FLAGS_WRAUTH) + SET_WRITE_EVENT(cptr->authfd); + authclnts[cptr->authfd] = cptr; + } + if (DoingDNS(cptr) || DoingAuth(cptr)) + continue; + if (IsListening(cptr)) + { + if ((NOW > cptr->lasttime + 2)) { + SET_READ_EVENT( i ); + } + else if (delay2 > 2) + delay2 = 2; + } + else + { + if (DBufLength(&cptr->recvQ) && delay2 > 2) + delay2 = 1; + if (DBufLength(&cptr->recvQ) < 4088) + SET_READ_EVENT( i ); + } + + if (DBufLength(&cptr->sendQ) || IsConnecting(cptr)) + #ifndef pyr + SET_WRITE_EVENT( i ); + #else + { + if (!(cptr->flags & FLAGS_BLOCKED)) + SET_WRITE_EVENT( i ); + else + delay2 = 0, usec = 500000; + } + if (NOW - cptr->lw.tv_sec && + nowt.tv_usec - cptr->lw.tv_usec < 0) + us = 1000000; + else + us = 0; + us += nowt.tv_usec; + if (us - cptr->lw.tv_usec > 500000) + cptr->flags &= ~FLAGS_BLOCKED; + #endif + } + + if (udpfd >= 0) + { + SET_READ_EVENT(udpfd); + udp_pfd = pfd; + } + if (resfd >= 0) + { + SET_READ_EVENT(resfd); + res_pfd = pfd; + } + Debug((DEBUG_NOTICE, "udpfd %d resfd %d", + udpfd, resfd )); + + wait.tv_sec = MIN(delay2, delay); + wait.tv_usec = usec; + + /* do the wait */ + nfds = poll( poll_fdarray, nbr_pfds, + wait.tv_sec * 1000 + wait.tv_usec/1000); + + if (nfds == -1 && errno == EINTR) + return -1; + else if (nfds >= 0) + break; + report_error("poll %s:%s", &me); + res++; + if (res > 5) + restart("too many poll errors"); + sleep(10); + NOW = time(NULL); + } + + if (res_pfd && (res_pfd->revents & POLLREADFLAGS) ) + { + do_dns_async(); + nfds--; + res_pfd->revents &= ~POLLREADFLAGS; + } + if (udp_pfd && (udp_pfd->revents & POLLREADFLAGS) ) + { + polludp(); + nfds--; + udp_pfd->revents &= ~POLLREADFLAGS; + } + + /* + * loop through all the polled fds testing for whether any + * has an I/O ready + */ + for ( pfd = poll_fdarray, i = 0; + (nfds > 0) && (i < nbr_pfds); + i++, pfd++ ) { + + /* most tests (idle fds) should keep going here */ + if ( pfd->revents == 0 ) + continue; + + /* found something that completed */ + nfds--; + fd = pfd->fd; + + /* check for the auth completions - previously, this was it's + own loop through the fds */ + if (( auth > 0 ) && ( cptr = authclnts[fd]) && ( cptr->authfd == fd)) { + + /* auth I/O ready */ + auth--; + if (pfd->revents & POLLWRITEFLAGS) + send_authports(cptr); + else if (pfd->revents & POLLREADFLAGS) + read_authports(cptr); + continue; + } + + /* + * get the client pointer -- all the previous incarnations + * of this code embedded this test within the subsequent + * 'if' statements - put it here for reusability + */ + if ( !(cptr = local[fd])) + continue; + + /* + * accept connections + */ + if ((pfd->revents & POLLREADFLAGS) && IsListening(cptr)) + { + pfd->revents &= ~POLLREADFLAGS; + cptr->lasttime = NOW; + /* + ** There may be many reasons for error return, but + ** in otherwise correctly working environment the + ** probable cause is running out of file descriptors + ** (EMFILE, ENFILE or others?). The man pages for + ** accept don't seem to list these as possible, + ** although it's obvious that it may happen here. + ** Thus no specific errors are tested at this + ** point, just assume that connections cannot + ** be accepted until some old is closed first. + */ + if ((fdnew = accept(fd, NULL, NULL)) < 0) + { + report_error("Cannot accept connections %s:%s", + cptr); + continue; + } + ircstp->is_ac++; + if (fdnew >= MAXCLIENTS) + { + ircstp->is_ref++; + sendto_ops("All connections in use. (%s)", + get_client_name(cptr, TRUE)); + (void)send(fdnew, + "ERROR :All connections in use\r\n", + 32, 0); + (void)close(fdnew); + continue; + } + /* + * Use of add_connection (which never fails :) meLazy + */ + #ifdef UNIXPORT + if (IsUnixSocket(cptr)) + add_unixconnection(cptr, fdnew); + else + #endif + (void)add_connection(cptr, fdnew); + nextping = NOW; + continue; + } + + /* + * was the next loop - check for actual work to be done + */ + if (IsMe( cptr )) + continue; + if (pfd->revents & POLLWRITEFLAGS ) + { + int write_err = 0; + /* + ** ...room for writing, empty some queue then... + */ + if (IsConnecting(cptr)) + write_err = completed_connection(cptr); + if (!write_err) + (void)send_queued(cptr); + if (IsDead(cptr) || write_err) + { + deadsocket: + (void)exit_client(cptr, cptr, &me, + strerror(get_sockerr(cptr))); + continue; + } + } + length = 1; /* for fall through case */ + if ((!NoNewLine(cptr) || pfd->revents & POLLREADFLAGS) && + !(DoingAuth(cptr) && NOW - cptr->firsttime < 5)) + length = read_packet(cptr, ((pfd->revents & POLLREADFLAGS )!= 0)); + + readcalls++; + if (length == FLUSH_BUFFER) + continue; + else if (length > 0) + flush_connections(cptr->fd); + if (IsDead(cptr)) + goto deadsocket; + if (length > 0) + continue; + + /* Ghost! Unknown users are tagged in parse() since 2.9. + * Let's not drop the uplink but just the ghost's message. + */ + if (length == -3) + continue; + + /* + ** NB: This following section has been modofied to *expect* + ** cptr to be valid (ie if (length == FLUSH_BUFFER) is + ** above and stays there). - avalon 24/9/94 + */ + /* + ** ...hmm, with non-blocking sockets we might get + ** here from quite valid reasons, although.. why + ** would select report "data available" when there + ** wasn't... so, this must be an error anyway... --msa + ** actually, EOF occurs when read() returns 0 and + ** in due course, select() returns that fd as ready + ** for reading even though it ends up being an EOF. -avalon + */ + Debug((DEBUG_ERROR, "READ ERROR: fd = %d %d %d", + cptr->fd, errno, length)); + + if (IsServer(cptr) || IsHandshake(cptr)) + { + int timeconnected = NOW - cptr->firsttime; + + if (length == 0) + sendto_ops("Server %s closed the connection (%d, %2d:%02d:%02d)", + get_client_name(cptr, FALSE), + timeconnected / 86400, + (timeconnected % 86400) / 3600, + (timeconnected % 3600)/60, + timeconnected % 60); + else /* this must be for -1 */ + { + report_error("Lost connection to %s:%s",cptr); + sendto_ops("%s had been connected for %d, %2d:%02d:%02d", + get_client_name(cptr, FALSE), + timeconnected / 86400, + (timeconnected % 86400) / 3600, + (timeconnected % 3600)/60, + timeconnected % 60); + } + } + (void)exit_client(cptr, cptr, &me, length >= 0 ? + "EOF From client" : + strerror(get_sockerr(cptr))); + } + return 0; + } + + #endif /* USE_POLL */ + /* * connect_server diff -c -r -N irc2.8.21+CSr23/ircd/s_conf.c irc2.8.21+CSr24/ircd/s_conf.c *** irc2.8.21+CSr23/ircd/s_conf.c Wed May 29 19:32:04 1996 --- irc2.8.21+CSr24/ircd/s_conf.c Wed Jul 24 21:49:12 1996 *************** *** 1233,1238 **** --- 1233,1269 ---- me.name, cptr->name, (BadPtr(tmp->passwd) || !is_comment(tmp->passwd)) ? "" : tmp->passwd); + + /* Oh, what the fuck...let's put the user@host limit check right here. + I'm not sure that I actually like this patch since you have to loop + through every client on every client-connect...but oh well... - CS + */ + + #ifdef LIMIT_UH + if (!tmp && uhlimit) + { + register aClient *sptr; + register int i; + int num = 0; + + for (i = highest_fd; i >= 0; i--) + { + if (!(sptr=local[i]) || !IsPerson(sptr)) + continue; + if (!strcmp(sptr->user->username, name) && + !strcmp(sptr->sockhost, host)) + if (++num >= uhlimit) + { + sendto_one(cptr, ":%s NOTICE %s :This server is currently limited to %i client%s per user", + me.name, cptr->name, uhlimit, uhlimit==1?"":"s"); + sendto_flagops(5, "Rejecting for too many clients: %s [%s@%s]", + cptr->name, cptr->user->username, cptr->user->host); + return 1; + } + } + } + #endif /* LIMIT_UH */ + return (tmp ? -1 : 0); } diff -c -r -N irc2.8.21+CSr23/ircd/s_debug.c irc2.8.21+CSr24/ircd/s_debug.c *** irc2.8.21+CSr23/ircd/s_debug.c Fri Apr 5 20:22:35 1996 --- irc2.8.21+CSr24/ircd/s_debug.c Wed Jul 24 20:29:07 1996 *************** *** 219,225 **** --- 219,227 ---- #ifdef GETRUSAGE_2 # ifdef SOL20 # include + /* # include + */ # endif # include #else diff -c -r -N irc2.8.21+CSr23/ircd/s_misc.c irc2.8.21+CSr24/ircd/s_misc.c *** irc2.8.21+CSr23/ircd/s_misc.c Sat Apr 27 21:09:26 1996 --- irc2.8.21+CSr24/ircd/s_misc.c Sat Jun 8 15:39:29 1996 *************** *** 319,325 **** static char userbuf[ULOGBUFFERLEN]; static char clonebuf[CLOGBUFFERLEN]; ! int userbuflen = 0, clonebuflen = 0, doit=0; char *filename, *buffer; int fd, *len2; --- 319,326 ---- static char userbuf[ULOGBUFFERLEN]; static char clonebuf[CLOGBUFFERLEN]; ! static int userbuflen = 0, clonebuflen = 0; ! int doit=0; char *filename, *buffer; int fd, *len2; diff -c -r -N irc2.8.21+CSr23/ircd/s_serv.c irc2.8.21+CSr24/ircd/s_serv.c *** irc2.8.21+CSr23/ircd/s_serv.c Wed May 29 19:45:59 1996 --- irc2.8.21+CSr24/ircd/s_serv.c Wed Jul 24 23:38:36 1996 *************** *** 289,294 **** --- 289,343 ---- #endif + #ifdef LIMIT_UH + + int m_limituh(cptr, sptr, parc, parv) + aClient *cptr, *sptr; + int parc; + char *parv[]; + { + int temp; + + if (!MyClient(sptr) || !IsAnOper(sptr)) + { + sendto_one(sptr, err_str(ERR_NOPRIVILEGES), me.name, parv[0]); + return 0; + } + if (!parv[1] || !*parv[1]) + { + if (uhlimit) + sendto_one(sptr, ":%s NOTICE %s :The current limit for the number of same u@h's is %i", + me.name, parv[0], uhlimit); + else + sendto_one(sptr, ":%s NOTICE %s :There is currently no limit for the number of same u@h's", + me.name, parv[0]); + return 0; + } + temp = atoi(parv[1]); + if (temp < 0) + { + sendto_one(sptr, ":%s NOTICE %s :Hello??? Try a number >= 0.", + me.name, parv[0]); + return 0; + } + if (uhlimit = temp) + { + sendto_flagops(1,"%s has changed the u@h limit to %i.", + parv[0], uhlimit); + sendto_one(sptr, ":%s NOTICE %s :The u@h limit is now set to %i.", + me.name, parv[0], uhlimit); + } + else + { + sendto_flagops(1,"%s has disabled the u@h limit.", parv[0]); + sendto_one(sptr, ":%s NOTICE %s :The u@h limit is now disabled.", + me.name, parv[0]); + } + return 0; + } + + #endif + /* ** m_version ** parv[0] = sender prefix *************** *** 880,886 **** check_fdlists(); #endif nextping = NOW; ! sendto_ops("Link with %s established.", inpath); (void)add_to_client_hash_table(cptr->name, cptr); /* doesnt duplicate cptr->serv if allocted this struct already */ (void)make_server(cptr); --- 929,935 ---- check_fdlists(); #endif nextping = NOW; ! sendto_ops("Link with %s (%s) established.", inpath, DoesTS(cptr) ? "TS" : "NoTS"); (void)add_to_client_hash_table(cptr->name, cptr); /* doesnt duplicate cptr->serv if allocted this struct already */ (void)make_server(cptr); *************** *** 1324,1330 **** aClient *acptr; char stat = parc > 1 ? parv[1][0] : '\0'; Reg1 int i; ! int doall = 0, wilds = 0; char *name; if (check_registered(sptr)) --- 1373,1379 ---- aClient *acptr; char stat = parc > 1 ? parv[1][0] : '\0'; Reg1 int i; ! int doall = 0, wilds = 0, j; char *name; if (check_registered(sptr)) *************** *** 1352,1357 **** --- 1401,1427 ---- #endif switch (stat) { + case '?': + #ifndef DOG3 + for(i=0;i<=highest_fd;i++) + { + if (!(acptr=local[i]) || !IsServer(acptr)) + continue; + #else + for (i=serv_fdlist.entry[j=1];j<=serv_fdlist.last_entry; + i=serv_fdlist.entry[++j]) + if (!(acptr=local[i])) + continue; + { + #endif + sendto_one(sptr, ":%s NOTICE %s :%s %s %u :%u", + me.name, parv[0], + get_client_name(acptr, TRUE), + DoesTS(acptr) ? "TS" : "NoTS", + (int)DBufLength(&acptr->sendQ), + NOW - acptr->firsttime); + } + break; case 'L' : case 'l' : /* * send info about connections which match, or all if the diff -c -r -N irc2.8.21+CSr23/ircd/s_user.c irc2.8.21+CSr24/ircd/s_user.c *** irc2.8.21+CSr23/ircd/s_user.c Wed May 29 19:30:10 1996 --- irc2.8.21+CSr24/ircd/s_user.c Wed Jul 24 22:16:19 1996 *************** *** 389,394 **** --- 389,395 ---- int i; int reject = 0; char *bottype = ""; + char origuser[USERLEN+1]; parv[0] = sptr->name; parv[1] = parv[2] = NULL; *************** *** 396,401 **** --- 397,403 ---- if (MyConnect(sptr)) { + strncpyzt(origuser, username, USERLEN+1); if (strstr(sptr->info, "^GuArDiAn^")) reject = 4; /* Reject Guardian Bots */ else if (!strcmp(user->host, "null")) *************** *** 429,439 **** aconf = sptr->confs->value.aconf; if ((sptr->flags & FLAGS_DOID) && !(sptr->flags & FLAGS_GOTID)) { - char temp[USERLEN+1]; - - strncpyzt(temp, username, USERLEN+1); *user->username = '~'; ! (void)strncpy(&user->username[1], temp, USERLEN); user->username[USERLEN] = '\0'; #ifdef IDENTD_ONLY ircstp->is_ref++; --- 431,438 ---- aconf = sptr->confs->value.aconf; if ((sptr->flags & FLAGS_DOID) && !(sptr->flags & FLAGS_GOTID)) { *user->username = '~'; ! (void)strncpy(&user->username[1], origuser, USERLEN); user->username[USERLEN] = '\0'; #ifdef IDENTD_ONLY ircstp->is_ref++; *************** *** 446,456 **** strncpyzt(user->username, sptr->username, USERLEN+1); else { - char temp[USERLEN+1]; - - strncpyzt(temp, username, USERLEN+1); *user->username = '~'; ! (void)strncpy(&user->username[1], temp, USERLEN); user->username[USERLEN] = '\0'; } if (!BadPtr(aconf->passwd) && --- 445,452 ---- strncpyzt(user->username, sptr->username, USERLEN+1); else { *user->username = '~'; ! (void)strncpy(&user->username[1], origuser, USERLEN); user->username[USERLEN] = '\0'; } if (!BadPtr(aconf->passwd) && *************** *** 655,660 **** --- 651,659 ---- sendto_flagops(2,"Client connecting: %s [%s@%s]", nick, user->username, user->host); #endif /* CLIENT_NOTICES */ + if (sptr->flags & FLAGS_GOTID) + if (strcmp(origuser, sptr->username)) + sendto_flagops(1,"Identd response differs: %s [%s]", nick, origuser); } else strncpyzt(user->username, username, USERLEN+1);