diff -ru --exclude=CVS irc2.10.3p6/common/common_def.h irc2.10.3p6+hemp/common/common_def.h --- irc2.10.3p6/common/common_def.h Fri Feb 5 00:26:35 1999 +++ irc2.10.3p6+hemp/common/common_def.h Sat Feb 28 00:27:32 2004 @@ -54,6 +54,7 @@ #define PUNCT 8 #define DIGIT 16 #define SPACE 32 +#define VALID 64 #define isalpha(c) (char_atribs[(u_char)(c)]&ALPHA) #define isspace(c) (char_atribs[(u_char)(c)]&SPACE) @@ -74,6 +75,9 @@ #define isgraph(c) ((char_atribs[(u_char)(c)]&PRINT) && \ ((u_char)(c) != (u_char)0x20)) #define ispunct(c) (!(char_atribs[(u_char)(c)]&(CNTRL|ALPHA|DIGIT))) +#ifdef RESTRICT_USERNAMES +#define isvaliduser(c) (char_atribs[(u_char)(c)]&VALID) +#endif #ifdef DEBUGMODE # define Debug(x) debug x diff -ru --exclude=CVS irc2.10.3p6/common/match.c irc2.10.3p6+hemp/common/match.c --- irc2.10.3p6/common/match.c Wed Jul 4 23:44:40 2001 +++ irc2.10.3p6+hemp/common/match.c Sat Feb 28 00:27:32 2004 @@ -110,34 +110,37 @@ /* 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, +/* !"#$ */ PRINT, PRINT, PRINT, PRINT, +/* %&'( */ PRINT, PRINT, PRINT, PRINT, +/* )*+ */ PRINT, PRINT, PRINT, +/* ,-. */ PRINT, PRINT|VALID, PRINT|VALID, +/* /01 */ PRINT, PRINT|DIGIT|VALID, PRINT|DIGIT|VALID, +/* 234 */ PRINT|DIGIT|VALID, PRINT|DIGIT|VALID, PRINT|DIGIT|VALID, +/* 567 */ PRINT|DIGIT|VALID, PRINT|DIGIT|VALID, PRINT|DIGIT|VALID, +/* 89: */ PRINT|DIGIT|VALID, PRINT|DIGIT|VALID, PRINT, +/* ;<= */ PRINT, PRINT, PRINT, +/* >?@ */ PRINT, PRINT, PRINT, +/* ABC */ PRINT|ALPHA|VALID, PRINT|ALPHA|VALID, PRINT|ALPHA|VALID, +/* DEF */ PRINT|ALPHA|VALID, PRINT|ALPHA|VALID, PRINT|ALPHA|VALID, +/* GHI */ PRINT|ALPHA|VALID, PRINT|ALPHA|VALID, PRINT|ALPHA|VALID, +/* JKL */ PRINT|ALPHA|VALID, PRINT|ALPHA|VALID, PRINT|ALPHA|VALID, +/* MNO */ PRINT|ALPHA|VALID, PRINT|ALPHA|VALID, PRINT|ALPHA|VALID, +/* PQR */ PRINT|ALPHA|VALID, PRINT|ALPHA|VALID, PRINT|ALPHA|VALID, +/* STU */ PRINT|ALPHA|VALID, PRINT|ALPHA|VALID, PRINT|ALPHA|VALID, +/* VWX */ PRINT|ALPHA|VALID, PRINT|ALPHA|VALID, PRINT|ALPHA|VALID, +/* YZ[ */ PRINT|ALPHA|VALID, PRINT|ALPHA|VALID, PRINT|ALPHA|VALID, +/* \]^ */ PRINT|ALPHA|VALID, PRINT|ALPHA|VALID, PRINT|ALPHA, +/* _` */ PRINT|VALID,PRINT, +/* abc */ PRINT|ALPHA|VALID, PRINT|ALPHA|VALID, PRINT|ALPHA|VALID, +/* def */ PRINT|ALPHA|VALID, PRINT|ALPHA|VALID, PRINT|ALPHA|VALID, +/* ghi */ PRINT|ALPHA|VALID, PRINT|ALPHA|VALID, PRINT|ALPHA|VALID, +/* jkl */ PRINT|ALPHA|VALID, PRINT|ALPHA|VALID, PRINT|ALPHA|VALID, +/* mno */ PRINT|ALPHA|VALID, PRINT|ALPHA|VALID, PRINT|ALPHA|VALID, +/* pqr */ PRINT|ALPHA|VALID, PRINT|ALPHA|VALID, PRINT|ALPHA|VALID, +/* stu */ PRINT|ALPHA|VALID, PRINT|ALPHA|VALID, PRINT|ALPHA|VALID, +/* vwx */ PRINT|ALPHA|VALID, PRINT|ALPHA|VALID, PRINT|ALPHA|VALID, +/* yz{ */ PRINT|ALPHA|VALID, PRINT|ALPHA|VALID, PRINT|ALPHA|VALID, +/* \}~ */ PRINT|ALPHA|VALID, PRINT|ALPHA|VALID, 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, diff -ru --exclude=CVS irc2.10.3p6/common/msg_def.h irc2.10.3p6+hemp/common/msg_def.h --- irc2.10.3p6/common/msg_def.h Wed Feb 25 17:28:48 2004 +++ irc2.10.3p6+hemp/common/msg_def.h Sat Feb 28 00:45:54 2004 @@ -32,6 +32,12 @@ #define MSG_QUIT "QUIT" /* QUIT */ #define MSG_SQUIT "SQUIT" /* SQUI */ #define MSG_KILL "KILL" /* KILL */ +#if defined(OPER_KLINE) || defined(LOCOP_KLINE) +#define MSG_KLINE "KLINE" /* KLIN */ +#endif +#if defined(OPER_TKLINE) || defined(LOCOP_TKLINE) +#define MSG_TKLINE "TKLINE" /* TKLI */ +#endif #define MSG_INFO "INFO" /* INFO */ #define MSG_LINKS "LINKS" /* LINK */ #define MSG_SUMMON "SUMMON" /* SUMM */ @@ -73,6 +79,12 @@ #define MSG_DIE "DIE" #define MSG_HASH "HAZH" /* HASH */ #define MSG_DNS "DNS" /* DNS -> DNSS */ -#define MSG_POST "POST" - +#define MSG_POST "POST" +#ifdef SERVER_MAP +#define MSG_MAP "MAP" +#endif +#ifdef OPER_SET +#define MSG_SET "SET" /* SET */ +#endif +#define MAXPARA 15 #define MAXPARA 15 diff -ru --exclude=CVS irc2.10.3p6/common/numeric_def.h irc2.10.3p6+hemp/common/numeric_def.h --- irc2.10.3p6/common/numeric_def.h Sat Feb 10 20:11:05 2001 +++ irc2.10.3p6+hemp/common/numeric_def.h Sat Feb 28 00:27:32 2004 @@ -123,8 +123,18 @@ #define RPL_YOURHOST 002 #define RPL_CREATED 003 #define RPL_MYINFO 004 +#ifdef SEND_ISUPPORT +#define RPL_ISUPPORT 005 +#define RPL_BOUNCE 10 +#else #define RPL_BOUNCE 005 - +#endif +#ifdef SERVER_MAP +#define RPL_MAP 15 /* Undernet extension */ +#define RPL_MAPMORE 16 /* Undernet extension */ +#define RPL_MAPEND 17 /* Undernet extension */ +#define RPL_MAPSTART 18 /* +hemp */ +#endif /* * Errors are in the range from 400-599 currently and are grouped by what * commands they come from. @@ -232,6 +242,7 @@ #define RPL_NOTOPIC 331 #define RPL_TOPIC 332 +#define RPL_TOPICWHOTIME 333 #define RPL_INVITING 341 #define RPL_SUMMONING 342 @@ -299,7 +310,7 @@ #define RPL_STATSQLINE 217 #define RPL_STATSYLINE 218 #define RPL_ENDOFSTATS 219 - +#define RPL_STATSPLINE 220 #define RPL_UMODEIS 221 #define RPL_SERVICEINFO 231 @@ -335,3 +346,5 @@ #define RPL_TRACEEND 262 #define RPL_TRYAGAIN 263 +#define RPL_LOCALUSERS 265 +#define RPL_GLOBALUSERS 266 diff -ru --exclude=CVS irc2.10.3p6/common/parse.c irc2.10.3p6+hemp/common/parse.c --- irc2.10.3p6/common/parse.c Thu Feb 26 20:51:31 2004 +++ irc2.10.3p6+hemp/common/parse.c Sat Feb 28 00:32:57 2004 @@ -64,6 +64,12 @@ { MSG_KILL, m_kill, MAXPARA, MSG_LAG|MSG_REG|MSG_NOU, 0, 0, 0L}, #endif #ifndef CLIENT_COMPILE +#if defined(OPER_KLINE) || defined(LOCOP_KLINE) + { MSG_KLINE, m_kline, MAXPARA, MSG_LAG|MSG_REG|MSG_OP|MSG_LOP, 0,0, 0L}, +#endif +#if defined(OPER_TKLINE) || defined(LOCOP_TKLINE) + { MSG_TKLINE, m_tkline, MAXPARA, MSG_LAG|MSG_REG|MSG_OP|MSG_LOP, 0,0, 0L}, +#endif { MSG_USER, m_user, MAXPARA, MSG_LAG|MSG_NOU, 0, 0, 0L}, { MSG_AWAY, m_away, MAXPARA, MSG_LAG|MSG_REGU, 0, 0, 0L}, { MSG_UMODE, m_umode, MAXPARA, MSG_LAG|MSG_REGU, 0, 0, 0L}, @@ -122,6 +128,14 @@ , 0, 0, 0L}, #endif { MSG_POST, m_post, MAXPARA, MSG_NOU, 0, 0, 0L}, + +#ifdef SERVER_MAP + { MSG_MAP, m_map, MAXPARA, MSG_LAG|MSG_REG, 0, 0, 0L}, +#endif +#ifdef OPER_SET + { MSG_SET, m_set, MAXPARA, MSG_LAG|MSG_REGU|MSG_OP|MSG_LOP , 0, 0, 0L}, +#endif + #endif /* !CLIENT_COMPILE */ { (char *) 0, (int (*)()) 0, 0, 0, 0, 0, 0L} }; @@ -173,6 +187,71 @@ return acptr; } +aClient *find_matching_client(mask,cptr) +char *mask; +Reg aClient *cptr; +{ + aClient *acptr = cptr; + Reg char *ch; + int wild = 0; + + /* try to find exact match */ + acptr = find_client(mask,NULL); + if (!acptr) + { + aServer *asptr; + int wild = 0, dot = 0; + /* check if we should check against wilds */ + for (ch = mask; *ch; ch++) + { + if (*ch == '*' || *ch == '?') + { + wild = 1; + break; + } + if (*ch == '.') + { + dot = 1; + break; + } + } + + if (!wild && !dot) + { + return cptr; + } + (void) collapse(mask); + + /* try to match some servername against mask */ + for (asptr = svrtop; asptr; asptr = asptr->nexts) + { + if (!match(asptr->bcptr->name,mask) || + !match(mask,asptr->bcptr->name)) + { + acptr = asptr->bcptr; + break; + } + } + + /* no match, try services */ + if (!acptr) + { + aService *sp; + for (sp = svctop;sp;sp = sp->nexts) + { + if (!match(sp->bcptr->name,mask) || + !match(mask,sp->bcptr->name)) + { + acptr = sp->bcptr; + break; + } + } + } + + } + + return acptr ? acptr : cptr; +} #else /* CLIENT_COMPILE */ aClient *find_client(name, cptr) @@ -190,7 +269,7 @@ return cptr; } #endif /* CLIENT_COMPILE */ - +#ifndef CLIENT_COMPILE /* ** Find a user@host (server or user). ** @@ -209,20 +288,39 @@ *count = 0; if (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; - } - } + { + if (host) + { + anUser *auptr; + for (auptr = hash_find_hostname(host,NULL); auptr; auptr = auptr->hnext) + { + if (MyConnect(auptr->bcptr) && !mycmp(user,auptr->username)) + { + (*count)++; + res = auptr->bcptr; + } + } + } + else + { + int i; + for (i = 0; i <= highest_fd; i++) + { + if (!(c2ptr = local[i]) || !IsRegisteredUser(c2ptr)) + { + continue; + } + if (!mycmp(user,c2ptr->user->username)) + { + (*count)++; + res = c2ptr; + } + } + } + } return res; } - +#endif /* !CLIENT_COMPILE */ /* ** Find server by name. ** @@ -766,7 +864,12 @@ if (index(sender, '.') /* <- buggy, it could be a service! */ && !index(sender, '@')) /* better.. */ { - sendto_flag(SCH_LOCAL, "Squitting unknown %s brought by %s.", +#ifdef LOCAL_REJECTIONS_ONLY + sendto_flag(SCH_NOTICE, +#else + sendto_flag(SCH_LOCAL, +#endif + "Squitting unknown %s brought by %s.", sender, get_client_name(cptr, FALSE)); sendto_one(cptr, ":%s SQUIT %s :(Unknown from %s)", me.name, sender, get_client_name(cptr, FALSE)); @@ -781,7 +884,12 @@ * if we get here and sender is a service, we should probably issue * a kill in this case! -krys */ - sendto_flag(SCH_LOCAL, "Dropping unknown %s brought by %s.", +#ifdef LOCAL_REJECTIONS_ONLY + sendto_flag(SCH_NOTICE, +#else + sendto_flag(SCH_LOCAL, +#endif + "Dropping unknown %s brought by %s.", sender, get_client_name(cptr, FALSE)); } #endif diff -ru --exclude=CVS irc2.10.3p6/common/parse_ext.h irc2.10.3p6+hemp/common/parse_ext.h --- irc2.10.3p6/common/parse_ext.h Wed Sep 3 19:45:17 1997 +++ irc2.10.3p6+hemp/common/parse_ext.h Sat Feb 28 00:27:32 2004 @@ -44,6 +44,7 @@ EXTERN aClient *find_mask __P((char *name, aClient *cptr)); EXTERN aServer *find_tokserver __P((int token, aClient *cptr, aClient *c2ptr)); EXTERN aClient *find_name __P((char *name, aClient *cptr)); +EXTERN aClient *find_matching_client __P((char *mask, aClient *cptr)); #else /* CLIENT_COMPILE */ EXTERN aClient *find_client __P((char *name, aClient *cptr)); EXTERN aClient *find_server __P((char *name, aClient *cptr)); diff -ru --exclude=CVS irc2.10.3p6/common/send.c irc2.10.3p6+hemp/common/send.c --- irc2.10.3p6/common/send.c Sat Oct 11 03:09:36 2003 +++ irc2.10.3p6+hemp/common/send.c Sat Feb 28 00:27:32 2004 @@ -1391,6 +1391,9 @@ { SCH_SERVICE, "&SERVICES", NULL }, { SCH_DEBUG, "&DEBUG", NULL }, { SCH_AUTH, "&AUTH", NULL }, +#ifdef CLIENTS_CHANNEL + { SCH_CLIENTS, "&CLIENTS", NULL }, +#endif }; @@ -1515,6 +1518,12 @@ ** And the rest... just count, I got 154 --Beeth */ char linebuf[1500]; +#ifdef LOG_IP + char *rip,*lip; +#ifndef INET6 + char tip[18]; +#endif +#endif /* LOG_IP */ /* ** This is a potential buffer overflow. ** I mean, when you manage to keep ircd @@ -1522,6 +1531,9 @@ */ char buf[12]; int logfile; +#ifdef LOG_IP + u_short rport,lport; +#endif /* LOG_IP */ logfile = msg ? connlog : userlog; @@ -1543,15 +1555,63 @@ (int) (duration % 60)); } +#ifdef LOG_IP + /*- + * New connection log format after looooong discussion: + * [ident@remoteip#remoteport,localip#localport] + * --Yegg, 2001-05-09 + */ + lport = cptr->acpt != NULL ? cptr->acpt->port : 0; + rport = cptr->port; + +#ifdef INET6 + lip = cptr->acpt != NULL ? inetntop(AF_INET6, (char *)&cptr->acpt->ip, + mydummy, MYDUMMY_SIZE) : ""; + rip = inetntop(AF_INET6, (char *)&cptr->ip, + mydummy2, MYDUMMY_SIZE); +#else + if (cptr->acpt != NULL) + { + lip = inetntoa((char *)&cptr->acpt->ip); + strncpyzt(tip, lip, 18); + lip = tip; + } + else + { + lip = ""; + } + rip = inetntoa((char *)&cptr->ip); +#endif + +#endif /* LOG_IP */ + /* ** Aha, cptr->firsttime is time when user connected, ** so we syslog() it anyway. I'm waving big ** "rewrite log format" flag --Beeth. */ (void)sprintf(linebuf, - "%s (%s): %s@%s [%s] %c %lu %luKb %lu %luKb\n", +#ifndef LOG_IP +#ifdef LOG_IRCNAME + "%s (%s): %s@%s [%s] [%s] %c %lu %luKb %lu %luKb\n", +#else + "%s (%s): %s@%s [%s] %c %lu %luKb %lu %luKb\n", +#endif +#else /* LOG_IP */ +#ifdef LOG_IRCNAME + "%s (%s): %s@%s [%s@%s#%u,%s#%u] [%s] %c %lu %luKb %lu %luKb\n", +#else + "%s (%s): %s@%s [%s@%s#%u,%s#%u] %c %lu %luKb %lu %luKb\n", +#endif +#endif /* LOG_IP */ myctime(cptr->firsttime), msg ? msg : buf, username, hostname, cptr->auth, +#ifdef LOG_IP + rip,rport,lip,lport, +#endif /* LOG_IP */ +#ifdef LOG_IRCNAME + cptr->info, +#endif cptr->exitc, cptr->sendM, cptr->sendK, cptr->receiveM, cptr->receiveK); diff -ru --exclude=CVS irc2.10.3p6/common/struct_def.h irc2.10.3p6+hemp/common/struct_def.h --- irc2.10.3p6/common/struct_def.h Mon May 14 14:02:08 2001 +++ irc2.10.3p6+hemp/common/struct_def.h Sat Feb 28 00:27:32 2004 @@ -25,6 +25,7 @@ typedef struct Server aServer; typedef struct Service aService; typedef struct SLink Link; +typedef struct invSLink invLink; typedef struct SMode Mode; typedef struct fdarray FdAry; typedef struct CPing aCPing; @@ -47,7 +48,7 @@ */ #define USERLEN 10 #define REALLEN 50 -#define TOPICLEN 80 +#define TOPICLEN 160 #define CHANNELLEN 50 #define PASSWDLEN 20 #define KEYLEN 23 @@ -60,7 +61,8 @@ #define CHIDLEN 5 /* WARNING: *DONT* CHANGE THIS!!!! */ #define READBUF_SIZE 16384 /* used in s_bsd.c *AND* s_zip.c ! */ - + +#define MAXMODEPARAMS 3 /* do _!not!_ change this */ /* * Make up some numbers which should reflect average leaf server connect * queue max size. @@ -166,6 +168,9 @@ #define FLAGS_ZIP 0x400000 /* link is zipped */ #define FLAGS_ZIPRQ 0x800000 /* zip requested */ #define FLAGS_ZIPSTART 0x1000000 /* start of zip (ignore any CRLF) */ +#ifdef SPLIT_HANDLE +#define FLAGS_EOBWAIT 0x2000000 /* waiting for EOB */ +#endif #define FLAGS_HELD 0x8000000 /* connection held and reconnect try */ #define FLAGS_OPER 0x0001 /* Operator */ @@ -175,6 +180,11 @@ #define FLAGS_RESTRICTED 0x0010 /* Restricted user */ #define FLAGS_AWAY 0x0020 /* user is away */ +#define FLAGS_BADBOY 0x10000 /* delay close this client */ +#ifdef ILINE_FLAGS +#define FLAGS_EXEMPT 0x20000 /* user is exempt from k-lines */ + +#endif #define SEND_UMODES (FLAGS_INVISIBLE|FLAGS_OPER|FLAGS_WALLOP|FLAGS_AWAY) #define ALL_UMODES (SEND_UMODES|FLAGS_LOCOP|FLAGS_RESTRICTED) @@ -222,6 +232,14 @@ #define ClearXAuth(x) ((x)->flags &= ~FLAGS_XAUTH) #define ClearWXAuth(x) ((x)->flags &= ~FLAGS_WXAUTH) +#ifdef SPLIT_HANDLE +#define SetBurst(x) ((x)->flags |= FLAGS_EOBWAIT) +#define ClearBurst(x) ((x)->flags &= ~FLAGS_EOBWAIT) +#define IsBurst(x) ((x)->flags & FLAGS_EOBWAIT) +#endif +#ifdef ILINE_FLAGS +#define IsKlineExempt(x) ((x)->user && (x)->user->flags & FLAGS_EXEMPT) +#endif /* * defined debugging levels */ @@ -268,6 +286,7 @@ u_int pref; /* preference value */ struct CPing *ping; time_t hold; /* Hold action until this time (calendar time) */ + char *source_ip; #ifndef VMSP aClass *class; /* Class of connection */ #endif @@ -276,6 +295,15 @@ #define CONF_ILLEGAL 0x80000000 #define CONF_MATCH 0x40000000 +#ifdef DELAY_ACCEPT +#define CONF_DELAY 0x20000000 +#define CONF_ACTIVE 0x10000000 +#define CONF_SERVERONLY 0x8000000 +#endif +#ifdef ILINE_FLAGS +#define CONF_EXEMPT 0x4000000 /* user is exempted from K: */ +#define CONF_RNODNS 0x2000000 +#endif #define CONF_QUARANTINED_SERVER 0x000001 #define CONF_CLIENT 0x000002 #define CONF_RCLIENT 0x000004 @@ -307,7 +335,6 @@ CONF_SERVER_MASK) #define IsIllegal(x) ((x)->status & CONF_ILLEGAL) - typedef struct { u_long pi_id; u_long pi_seq; @@ -345,7 +372,7 @@ */ struct User { Link *channel; /* chain of channel pointer blocks */ - Link *invited; /* chain of invite pointer blocks */ + invLink *invited; /* chain of invite pointer blocks */ Link *uwas; /* chain of whowas pointer blocks */ char *away; /* pointer to away message */ time_t last; /* "idle" time */ @@ -368,6 +395,8 @@ char username[USERLEN+1]; char host[HOSTLEN+1]; char *server; + struct User *hnext; + int hashv; }; struct Server { @@ -382,6 +411,10 @@ ** from anUser (field servp), aService (field ** servp) and aClient (field serv) */ + int usercnt[3]; /* # of clients - all, invisible, opers */ +#ifdef EXTRA_STATISTICS + int usermax; /* max # of users on this server */ +#endif struct Server *nexts, *prevs, *shnext; aClient *bcptr; char by[NICKLEN+1]; @@ -389,6 +422,7 @@ time_t lastload; /* penalty like counters, see s_serv.c ** should be in the local part, but.. */ + Link *down; /* list of downlinks */ }; struct Service { @@ -451,6 +485,7 @@ ** accepted. */ char passwd[PASSWDLEN+1]; + char *reason; /* internal quit reason */ char exitc; }; @@ -531,6 +566,16 @@ u_long bytes; }; +#ifdef SPLIT_HANDLE +#define SET_TYPE_INT 0 +#define SET_TYPE_STRING 1 +struct Set_Message { + char *cmd; + int *value; + char **values; +}; +#endif + #define MSG_LAG 0x0001 #define MSG_NOU 0x0002 /* Not available to users */ #define MSG_SVC 0x0004 /* Services only */ @@ -563,6 +608,20 @@ int flags; }; +/* invite link structure used for chains */ +struct invSLink { + struct invSLink *next; + union { + aClient *cptr; + aChannel *chptr; + aConfItem *aconf; + char *cp; + int i; + } value; + int flags; + char *who; +}; + /* channel structure */ struct Channel { @@ -570,6 +629,10 @@ u_int hashv; /* raw hash value */ Mode mode; char topic[TOPICLEN+1]; +#ifdef TOPICWHOTIME + char topic_nuh[BANLEN+1]; + time_t topic_time; +#endif int users; /* current membership total */ Link *members; /* channel members */ Link *invites; /* outstanding invitations */ @@ -674,6 +737,16 @@ x->prev->service->servp == x->serv))) typedef struct { +#ifdef EXTRA_STATISTICS + time_t is_last_cnt_t; /* timestamp for last count */ + u_long is_last_cnt; /* last count */ + u_long is_m_users; /* maximum users connected */ + u_long is_m_serv; /* maximum servers connected */ + u_long is_m_service; /* maximum services connected */ + u_long is_m_myclnt; /* maximum local clients */ + u_long is_m_myserv; /* maximum local servers */ + u_long is_m_myservice; /* maximum local services */ +#endif u_long is_user[2]; /* users, non[0] invis and invis[1] */ u_long is_serv; /* servers */ u_long is_service; /* services */ @@ -715,8 +788,21 @@ u_int is_dbufmin; /* min number of dbuf in use */ u_int is_dbufmax; /* max number of dbuf in use */ u_int is_dbufmore; /* how many times we increased the bufferpool*/ +#ifdef DELAY_CLOSE + u_long is_delayclosed; +#endif +#ifdef SPLIT_HANDLE + u_long is_eobservers; /* # of servers which sent EOB */ +#endif } istat_t; +typedef struct { + u_int split; + u_int aconnect; /* if we want aconnect or not */ +#ifdef DELAY_ACCEPT + u_int caccept; /* enable/disable client ports */ +#endif +} iconf_t; /* String manipulation macros */ /* strncopynt --> strncpyzt to avoid confusion, sematics changed @@ -771,8 +857,13 @@ #define SCH_SERVICE 9 #define SCH_DEBUG 10 #define SCH_AUTH 11 -#define SCH_MAX 11 +#ifdef CLIENTS_CHANNEL +#define SCH_CLIENTS 12 +#define SCH_MAX 13 +#else +#define SCH_MAX 12 +#endif /* used for async dns values */ #define ASYNC_NONE (-1) diff -ru --exclude=CVS irc2.10.3p6/common/support.c irc2.10.3p6+hemp/common/support.c --- irc2.10.3p6/common/support.c Thu May 31 16:00:02 2001 +++ irc2.10.3p6+hemp/common/support.c Sat Feb 28 00:27:32 2004 @@ -849,7 +849,7 @@ char *make_version() { int ve, re, mi, dv, pl; - char ver[15]; + char ver[50]; sscanf(PATCHLEVEL, "%2d%2d%2d%2d%2d", &ve, &re, &mi, &dv, &pl); /* version & revision */ @@ -861,9 +861,30 @@ sprintf(ver + strlen(ver), "%c%d", DEVLEVEL, dv); if (pl) /* patchlevel */ sprintf(ver + strlen(ver), "p%d", pl); + strcat(ver,"+hemp2"); return mystrdup(ver); } +#ifndef CLIENTCOMPILE +#ifdef SEND_ISUPPORT +/* + * Make ISUPPORT string + */ +char *make_isupport() +{ + char tisupport[200]; + char *p = tisupport; +#ifdef SERVER_MAP + strcpy(tisupport,"MAP "); + p +=4; +#endif + SPRINTF(p,"PREFIX=(ov)@+ MODES=%d CHANTYPES=#&!+ MAXCHANNELS=%d NICKLEN=%d TOPICLEN=%d KICKLEN=%d NETWORK=%s CHANMODES=beI,k,l,imnpstaqr", + MAXMODEPARAMS, MAXCHANNELSPERUSER, NICKLEN, TOPICLEN, TOPICLEN,NETWORKNAME); + + return mystrdup(tisupport); +} +#endif +#endif #ifndef HAVE_TRUNCATE /* truncate: set a file to a specified length * I don't know of any UNIX that doesn't have truncate, but CYGWIN32 beta18 diff -ru --exclude=CVS irc2.10.3p6/common/support_ext.h irc2.10.3p6+hemp/common/support_ext.h --- irc2.10.3p6/common/support_ext.h Fri Dec 8 23:15:21 2000 +++ irc2.10.3p6+hemp/common/support_ext.h Sat Feb 28 00:27:32 2004 @@ -72,6 +72,9 @@ #endif /* USE_STDARG */ EXTERN int dgets __P((int fd, char *buf, int num)); EXTERN char *make_version(); +#ifdef SEND_ISUPPORT +EXTERN char *make_isupport(); +#endif #if SOLARIS_2_3 EXTERN struct hostent *solaris_gethostbyname __P((const char *name)); #endif /* SOLARIS_2_3 */ diff -ru --exclude=CVS irc2.10.3p6/i386-unknown-freebsd4.9/Makefile irc2.10.3p6+hemp/i386-unknown-freebsd4.9/Makefile --- irc2.10.3p6/i386-unknown-freebsd4.9/Makefile Sat Feb 28 00:50:42 2004 +++ irc2.10.3p6+hemp/i386-unknown-freebsd4.9/Makefile Sat Feb 28 00:34:58 2004 @@ -105,6 +105,8 @@ IRCDPID_PATH = $(ircd_var_dir)/ircd.pid # server state file IRCDTUNE_PATH = $(ircd_var_dir)/ircd.tune +# iauth PID file +IAUTHPID_PATH = $(ircd_var_dir)/iauth.pid # ircdwatch PID file IRCDWATCHPID_PATH = $(ircd_var_dir)/ircdwatch.pid @@ -158,7 +160,7 @@ IAUTH_COMMON_OBJS = clsupport.o clmatch.o # This is a little evil IAUTH_OBJS = iauth.o a_conf.o a_io.o a_log.o \ - mod_lhex.o mod_pipe.o mod_rfc931.o mod_socks.o + mod_lhex.o mod_pipe.o mod_rfc931.o mod_socks.o mod_webproxy.o IAUTH = iauth CHKCONF_COMMON_OBJS = match.o @@ -409,7 +411,8 @@ $(CC) $(S_CFLAGS) -c -o $@ ../ircd/s_id.c s_misc.o: ../ircd/s_misc.c setup.h config.h - $(CC) $(S_CFLAGS) -DFNAME_USERLOG="\"$(FNAME_USERLOG)\"" -DFNAME_CONNLOG="\"$(FNAME_CONNLOG)\"" -c -o $@ ../ircd/s_misc.c + $(CC) $(S_CFLAGS) -DFNAME_USERLOG="\"$(FNAME_USERLOG)\"" \ + -DIRCDCONF_PATH="\"$(IRCDCONF_PATH)\"" -DFNAME_CONNLOG="\"$(FNAME_CONNLOG)\"" -c -o $@ ../ircd/s_misc.c s_numeric.o: ../ircd/s_numeric.c setup.h config.h $(CC) $(S_CFLAGS) -c -o $@ ../ircd/s_numeric.c @@ -439,7 +442,7 @@ $(CC) $(S_CFLAGS) -c -o $@ ../ircd/res_mkquery.c iauth.o: ../iauth/iauth.c config.h setup.h - $(CC) $(A_CFLAGS) -c -o $@ ../iauth/iauth.c + $(CC) $(A_CFLAGS) -DIAUTHPID_PATH="\"$(IAUTHPID_PATH)\"" -c -o $@ ../iauth/iauth.c a_conf.o: ../iauth/a_conf.c config.h setup.h $(CC) $(A_CFLAGS) -DIAUTHCONF_PATH="\"$(IAUTHCONF_PATH)\"" -c -o $@ ../iauth/a_conf.c @@ -464,6 +467,9 @@ mod_socks.o: ../iauth/mod_socks.c config.h setup.h $(CC) $(A_CFLAGS) -c -o $@ ../iauth/mod_socks.c + +mod_webproxy.o: ../iauth/mod_webproxy.c config.h setup.h + $(CC) $(A_CFLAGS) -c -o $@ ../iauth/mod_webproxy.c -Wall chkconf.o: ../ircd/chkconf.c setup.h config.h $(CC) $(CC_CFLAGS) -DCHKCONF_COMPILE -DIRCDCONF_PATH="\"$(IRCDCONF_PATH)\"" -DIRCDM4_PATH="\"$(IRCDM4_PATH)\"" -c -o $@ ../ircd/chkconf.c Only in irc2.10.3p6+hemp/i386-unknown-freebsd4.9: a_conf.o Only in irc2.10.3p6+hemp/i386-unknown-freebsd4.9: a_io.o Only in irc2.10.3p6+hemp/i386-unknown-freebsd4.9: a_log.o Only in irc2.10.3p6+hemp/i386-unknown-freebsd4.9: bsd.o Only in irc2.10.3p6+hemp/i386-unknown-freebsd4.9: channel.o Only in irc2.10.3p6+hemp/i386-unknown-freebsd4.9: chkconf Only in irc2.10.3p6+hemp/i386-unknown-freebsd4.9: chkconf.o Only in irc2.10.3p6+hemp/i386-unknown-freebsd4.9: class.o Only in irc2.10.3p6+hemp/i386-unknown-freebsd4.9: clmatch.o Only in irc2.10.3p6+hemp/i386-unknown-freebsd4.9: clsupport.o diff -ru --exclude=CVS irc2.10.3p6/i386-unknown-freebsd4.9/config.h irc2.10.3p6+hemp/i386-unknown-freebsd4.9/config.h --- irc2.10.3p6/i386-unknown-freebsd4.9/config.h Sat Oct 11 15:25:14 2003 +++ irc2.10.3p6+hemp/i386-unknown-freebsd4.9/config.h Sat Feb 28 00:27:32 2004 @@ -138,7 +138,7 @@ * This should be at *least* 4: 2 listen ports (1 tcp, 1 udp) * 1 dns port, 1 client */ -#define MAXCONNECTIONS 50 +#define MAXCONNECTIONS 1024 /* MAXIMUM LINKS * @@ -323,7 +323,7 @@ * send to the server without processing before disconnecting the client for * flooding it. Values greater than 8000 make no difference to the server. */ -#define CLIENT_FLOOD 1000 +#define CLIENT_FLOOD 8000 /* Remote query flood protection. */ #define CHREPLLEN 8192 @@ -339,6 +339,7 @@ */ #undef USE_SERVICES + /* * Define the following to make the delay for nicks random. * Some people believe a bot can exactly time the delay and don't like it, @@ -389,6 +390,175 @@ */ #define SIXBONE_HACK +/* + * Disclaimer: The following part concerns the Cr-patches. By defining this + * you will end up with "no warranty" whatsoever - use at your + * own risk. + * The Cr patch does not compromize the anonymity and does + * not affect users integrity in any way. The new features will + * only provide extra functionality and statistics for local + * IRC operators. + */ +#define RESTRICT_USERNAMES + +/* + * Define this if you want to allow online K-lining (permanent) for + * regular and local operators. + */ +#undef OPER_KLINE +#undef LOCOP_KLINE + +/* + * Define this if you want to allow online K-lining to memory only + * which is removed after rehashing the configuration file or by + * restarting the server. + */ +#undef OPER_TKLINE +#undef LOCOP_TKLINE + +/* + * Define this if you want (t)kline requests to go to syslog + * Note that you must also have USE_SYSLOG defined otherwise + * it won't work + * this is a part of patch f2 by fantomas + */ +#define SYSLOG_KLINE + +/* + * This will give some extra statistics, such as highest usercount, + * connection duration and local client incrementation. + * + * Note: will also show local/global max in /lusers - jv + */ +#define EXTRA_STATISTICS + +/* CrXXe8 related stuff follows. It makes the TKLINE/KLINE servernotice + * show the k-linereason too and does two cosmetical corrections to the + * "Local increase..." and the RPL_YOUREOPER servernotices. Also it + * doesn't suppress iauth statistics for opers using stats t. + * + * Define this to show and log failed /oper attempts too! + * Define LOG_IP for logging [ident@remoteip#remoteport,localip#localport]. + */ + +#undef FAILED_OPERLOG +#undef LOG_IP + +/* Fl4 related stuff follows - so far, the only stuff retained from Fl3c + * for Fl4 is the &clients channel ; this is because the TKLINE/KLINE code + * from Fl3c is also present in the Cr15 code. + */ + +/* define this to enable an extra local channel '&clients', which only + * IRC operators may join. Notification of nick-changes, connects, exits, + * and requests for server statistics will be sent to this channel. + * Some people regard this as a breach of privacy, hence (unlike Fl3c) + * it is turned off by default. + * f2 - easy clients merged - jv + */ +#undef CLIENTS_CHANNEL + + + +/* + * Define this to see when a channel topic was set and who it was set by. + */ +#define TOPICWHOTIME + +/* + * Define this if you want msgs normally sent to &local moved to ¬ices + * - EXCEPT unauth/rejection/too many connection notices. The reasoning + * behind this is if you want to see local information except the annoying + * and resource wasting unauths and rejections.. + */ +#define LOCAL_REJECTIONS_ONLY + + +/* +jv patch defines follows */ + +/* New stats - F show FDs and remote&local ports (local oper only) + */ +#define STATS_F + +/* show signon time of local clients in whois */ +#define WHOIS_SIGNON_TIME + +/* no RPL_TRYAGAIN for opers - i think it's right and doesn't add + * privileges for opers, just allows them to administrate net better. + */ +#define NO_OPER_TRYAGAIN +/* If you want to notify users that doing /LIST is bad and they should + use ALIS instead, define this. Notice is sent BEFORE any output. + */ + +// #define LIST_ALIS_NOTE "Usage of /list for listing all channels is deprecated. Please use \"/squery alis help\" instead." + +/* If you want to send server IS_SUPPORT upon connect and along with + VERSION reply. Also moves redirect numerics from 5 to 10. + also define Networkname. + */ +#define SEND_ISUPPORT +#define NETWORKNAME "IRCnet" + +/* support for /MAP a'la ircu. */ +#define SERVER_MAP + +/* quick info about connected servers */ +#define STATS_QMARK + +/* define if you want to set some values - delay accept mode, disable/enable autoconnects */ +#define OPER_SET + +/* wait with closing sockets of rejected clients, in seconds */ +#define DELAY_CLOSE +#define DELAYCLOSETIME 10 + +/* Split handling - replaces QPI + * works as follows: + * PINGs all servers behind the link and waits for PONG. + * Note: Currently does not compile when undefined. To disable split + * protection set following values to 0. + */ +#define SPLIT_HANDLE + +/* defines minimum for GLOBAL channels */ +#define SPLIT_SERV 10 +#define SPLIT_USERS 15000 + +/* Delay binding to listening ports with 'D' in second field until server + * is out of split. + * Requires SPLIT_HANDLE defined + */ +#define DELAY_ACCEPT + +/* I-line flags. Allows to specify aditional flags at the beginning of + * name field. + * current meaning: + * < exempted from k-lines + * + restrict client if no reverse dns found. + */ +#define ILINE_FLAGS + +/* + * Undefining this enables old portions of code, which are more precise + * in local u@h limit checking by comparing user's ip against all other + * users on server. Usable only for case when client creates another + * connection from same ip, but with changed hostname. + * This check won't be needed on pure 2.11 network. + * Note: He can connect to other server without any problem. + * + */ +#define NO_EXTENSIVE_LOCAL_LIMIT_CHECK + +/* define file which is used for saving k-lines added by /kline + */ +#define KLINE_FILE IRCDCONF_PATH + +/* undef if you don't want to have Denied connection because of open proxy */ +#define IAUTH_VERBOSE_REJECTS + +/* end of +jv patch */ + /* STOP STOP STOP STOP STOP STOP STOP STOP STOP STOP STOP STOP STOP STOP */ /* STOP STOP STOP STOP STOP STOP STOP STOP STOP STOP STOP STOP STOP STOP */ /* STOP STOP STOP STOP STOP STOP STOP STOP STOP STOP STOP STOP STOP STOP */ @@ -403,18 +573,20 @@ * server the Operator is connected to (ie lets them deal with local * problem users or 'ghost' clients */ -#define LOCAL_KILL_ONLY +#undef LOCAL_KILL_ONLY #endif /* Default server port, used by client. */ #define PORTNUM 6667 /* Maximum length the queue of pending connections to one port may grow to. */ -#define LISTENQUEUE 128 +#define LISTENQUEUE 512 /* define DEBUGMODE to enable debugging mode.*/ #undef DEBUGMODE +/* log ircname to logfile */ +#define LOG_IRCNAME /* * Time interval to wait and if no messages have been received, then check for * PINGFREQUENCY and CONNECTFREQUENCY @@ -484,7 +656,7 @@ /* * Max number of channels a user is allowed to join. */ -#define MAXCHANNELSPERUSER 10 /* Recommended value: 10 */ +#define MAXCHANNELSPERUSER 20 /* Recommended value: 10 */ /* * USE_IAUTH makes ircd use the iauth program for authentication. @@ -519,6 +691,7 @@ /* #undef NO_IDENT */ /* #undef NO_PREFIX */ + /* ------------------------- END CONFIGURATION SECTION -------------------- */ #ifndef ENABLE_SUMMON # undef LEAST_IDLE @@ -603,4 +776,8 @@ ** Conformance of the internal resolver to RFC1123. */ #define RESTRICT_HOSTNAMES 1 + +#if defined(DELAY_ACCEPT) && !defined(SPLIT_HANDLE) +error DELAY_ACCEPT requires SPLIT_HANDLE defined. +#endif diff -ru --exclude=CVS irc2.10.3p6/i386-unknown-freebsd4.9/config.log irc2.10.3p6+hemp/i386-unknown-freebsd4.9/config.log --- irc2.10.3p6/i386-unknown-freebsd4.9/config.log Sat Feb 28 00:50:42 2004 +++ irc2.10.3p6+hemp/i386-unknown-freebsd4.9/config.log Sat Feb 28 00:34:58 2004 @@ -258,8 +258,8 @@ ; return 0; } configure:2821: checking library containing pow configure:2835: gcc -o conftest -O2 conftest.c -lcrypt 1>&5 -/tmp/cc8p5l7o.o: In function `main': -/tmp/cc8p5l7o.o(.text+0x15): undefined reference to `pow' +/tmp/ccfJQA9q.o: In function `main': +/tmp/ccfJQA9q.o(.text+0x15): undefined reference to `pow' configure: failed program was: #line 2828 "configure" #include "confdefs.h" @@ -360,8 +360,8 @@ configure:3546: gcc -o conftest -O2 conftest.c -lcrypt 1>&5 configure:3518: checking for strtoken configure:3546: gcc -o conftest -O2 conftest.c -lcrypt 1>&5 -/tmp/cccF7Mck.o: In function `main': -/tmp/cccF7Mck.o(.text+0x7): undefined reference to `strtoken' +/tmp/ccK8x0Ug.o: In function `main': +/tmp/ccK8x0Ug.o(.text+0x7): undefined reference to `strtoken' configure: failed program was: #line 3523 "configure" #include "confdefs.h" @@ -391,8 +391,8 @@ configure:3546: gcc -o conftest -O2 conftest.c -lcrypt 1>&5 configure:3518: checking for sigset configure:3546: gcc -o conftest -O2 conftest.c -lcrypt 1>&5 -/tmp/ccJoU1gF.o: In function `main': -/tmp/ccJoU1gF.o(.text+0x7): undefined reference to `sigset' +/tmp/ccK8xPgo.o: In function `main': +/tmp/ccK8xPgo.o(.text+0x7): undefined reference to `sigset' configure: failed program was: #line 3523 "configure" #include "confdefs.h" Only in irc2.10.3p6+hemp/i386-unknown-freebsd4.9: dbuf.o Only in irc2.10.3p6+hemp/i386-unknown-freebsd4.9: hash.o Only in irc2.10.3p6+hemp/i386-unknown-freebsd4.9: iauth Only in irc2.10.3p6+hemp/i386-unknown-freebsd4.9: iauth.o Only in irc2.10.3p6+hemp/i386-unknown-freebsd4.9: ircd Only in irc2.10.3p6+hemp/i386-unknown-freebsd4.9: ircd-mkpasswd Only in irc2.10.3p6+hemp/i386-unknown-freebsd4.9: ircd.o Only in irc2.10.3p6+hemp/i386-unknown-freebsd4.9: ircdwatch Only in irc2.10.3p6+hemp/i386-unknown-freebsd4.9: ircdwatch.o Only in irc2.10.3p6+hemp/i386-unknown-freebsd4.9: list.o Only in irc2.10.3p6+hemp/i386-unknown-freebsd4.9: match.o Only in irc2.10.3p6+hemp/i386-unknown-freebsd4.9: mkpasswd.o Only in irc2.10.3p6+hemp/i386-unknown-freebsd4.9: mod_lhex.o Only in irc2.10.3p6+hemp/i386-unknown-freebsd4.9: mod_pipe.o Only in irc2.10.3p6+hemp/i386-unknown-freebsd4.9: mod_rfc931.o Only in irc2.10.3p6+hemp/i386-unknown-freebsd4.9: mod_socks.o Only in irc2.10.3p6+hemp/i386-unknown-freebsd4.9: mod_webproxy.o Only in irc2.10.3p6+hemp/i386-unknown-freebsd4.9: packet.o Only in irc2.10.3p6+hemp/i386-unknown-freebsd4.9: parse.o Only in irc2.10.3p6+hemp/i386-unknown-freebsd4.9: res.o Only in irc2.10.3p6+hemp/i386-unknown-freebsd4.9: res_comp.o Only in irc2.10.3p6+hemp/i386-unknown-freebsd4.9: res_init.o Only in irc2.10.3p6+hemp/i386-unknown-freebsd4.9: res_mkquery.o Only in irc2.10.3p6+hemp/i386-unknown-freebsd4.9: s_auth.o Only in irc2.10.3p6+hemp/i386-unknown-freebsd4.9: s_bsd.o Only in irc2.10.3p6+hemp/i386-unknown-freebsd4.9: s_conf.o Only in irc2.10.3p6+hemp/i386-unknown-freebsd4.9: s_debug.o Only in irc2.10.3p6+hemp/i386-unknown-freebsd4.9: s_err.o Only in irc2.10.3p6+hemp/i386-unknown-freebsd4.9: s_id.o Only in irc2.10.3p6+hemp/i386-unknown-freebsd4.9: s_misc.o Only in irc2.10.3p6+hemp/i386-unknown-freebsd4.9: s_numeric.o Only in irc2.10.3p6+hemp/i386-unknown-freebsd4.9: s_serv.o Only in irc2.10.3p6+hemp/i386-unknown-freebsd4.9: s_service.o Only in irc2.10.3p6+hemp/i386-unknown-freebsd4.9: s_user.o Only in irc2.10.3p6+hemp/i386-unknown-freebsd4.9: s_zip.o Only in irc2.10.3p6+hemp/i386-unknown-freebsd4.9: send.o Only in irc2.10.3p6+hemp/i386-unknown-freebsd4.9: support.o diff -ru --exclude=CVS irc2.10.3p6/i386-unknown-freebsd4.9/tkconf.h irc2.10.3p6+hemp/i386-unknown-freebsd4.9/tkconf.h --- irc2.10.3p6/i386-unknown-freebsd4.9/tkconf.h Sat Feb 28 00:50:42 2004 +++ irc2.10.3p6+hemp/i386-unknown-freebsd4.9/tkconf.h Sat Feb 28 00:34:58 2004 @@ -28,8 +28,8 @@ #undef TKSERV_DEBUG /* The name of the ircd config file backup (suffix after CPATH) */ -#define TKSERV_IRCD_CONFIG_BAK CPATH".tkserv" +#define TKSERV_IRCD_CONFIG_BAK TKSERV_IRCD_CONF".tkserv" /* The name of the ircd temp config file (suffix after CPATH) */ -#define TKSERV_IRCD_CONFIG_TMP CPATH".tmp" +#define TKSERV_IRCD_CONFIG_TMP TKSERV_IRCD_CONF".tmp" Only in irc2.10.3p6+hemp/i386-unknown-freebsd4.9: version.c diff -ru --exclude=CVS irc2.10.3p6/i386-unknown-freebsd4.9/version.c.SH irc2.10.3p6+hemp/i386-unknown-freebsd4.9/version.c.SH --- irc2.10.3p6/i386-unknown-freebsd4.9/version.c.SH Sat Feb 28 00:50:42 2004 +++ irc2.10.3p6+hemp/i386-unknown-freebsd4.9/version.c.SH Sat Feb 28 00:34:58 2004 @@ -63,6 +63,7 @@ char *generation = "$generation"; char *creation = "$creation"; char *version; /* Filled by make_version() */ +char *isupport; /* Filled by make_isupport() */ char *pass_version = PATCHLEVEL; char *infotext[] = @@ -108,6 +109,9 @@ "", "[$sumsserv] [$sumchan] [$sumsbsd] [$sumsuser]", "[$sumhash] [$sumsmisc] [$sumircd]", + "", + "This server has been patched by hemp2 patch, revision 2003121203.", + "See http://jv.irc.cz/irc/ for more information about this patch.", 0, }; !SUB!THIS! Only in irc2.10.3p6+hemp/i386-unknown-freebsd4.9: version.o Only in irc2.10.3p6+hemp/i386-unknown-freebsd4.9: whowas.o diff -ru --exclude=CVS irc2.10.3p6/iauth/a_conf.c irc2.10.3p6+hemp/iauth/a_conf.c --- irc2.10.3p6/iauth/a_conf.c Sat Oct 11 16:22:56 2003 +++ irc2.10.3p6+hemp/iauth/a_conf.c Sat Feb 28 00:27:32 2004 @@ -26,6 +26,7 @@ #define A_CONF_C #include "a_externs.h" #undef A_CONF_C +#undef USE_DSM static aModule *Mlist[16]; @@ -87,6 +88,7 @@ Mlist[Mcnt++] = &Module_rfc931; Mlist[Mcnt++] = &Module_socks; + Mlist[Mcnt++] = &Module_webproxy; Mlist[Mcnt++] = &Module_pipe; Mlist[Mcnt++] = &Module_lhex; Mlist[Mcnt] = NULL; @@ -248,6 +250,7 @@ (*last)->hostname = NULL; (*last)->address = NULL; (*last)->timeout = timeout; + (*last)->reason = NULL; if (Mlist[i] == &Module_rfc931) ident = *last; @@ -291,6 +294,17 @@ mystrdup(buffer + 10); continue; } + if (!strncasecmp(buffer+1, "reason = ", 9)) + { + if ((*last)->reason) + conf_err(lnnb, + "Duplicate reason keyword: ignored.", + cfile); + else + (*last)->reason = + mystrdup(buffer + 10); + continue; + } if (!strncasecmp(buffer+1, "host = ", 7)) { needh = 1; Only in irc2.10.3p6+hemp/iauth: a_conf.c.orig diff -ru --exclude=CVS irc2.10.3p6/iauth/a_conf_def.h irc2.10.3p6+hemp/iauth/a_conf_def.h --- irc2.10.3p6/iauth/a_conf_def.h Mon Jul 5 00:09:09 1999 +++ irc2.10.3p6+hemp/iauth/a_conf_def.h Sat Feb 28 00:27:32 2004 @@ -40,6 +40,7 @@ u_char in; /* instance number */ aModule *mod; /* module */ char *opt; /* options read from file */ + char *reason; /* reject reason */ char *popt; /* options to send to ircd */ void *data; /* private data: stats, ... */ aTarget *address; Only in irc2.10.3p6+hemp/iauth: a_conf_def.h.orig diff -ru --exclude=CVS irc2.10.3p6/iauth/a_externs.h irc2.10.3p6+hemp/iauth/a_externs.h --- irc2.10.3p6/iauth/a_externs.h Mon Apr 12 21:45:04 1999 +++ irc2.10.3p6+hemp/iauth/a_externs.h Sat Feb 28 00:27:32 2004 @@ -30,5 +30,6 @@ #include "mod_rfc931_ext.h" #include "mod_socks_ext.h" +#include "mod_webproxy_ext.h" #include "mod_pipe_ext.h" #include "mod_lhex_ext.h" Only in irc2.10.3p6+hemp/iauth: a_externs.h.orig diff -ru --exclude=CVS irc2.10.3p6/iauth/a_log_def.h irc2.10.3p6+hemp/iauth/a_log_def.h --- irc2.10.3p6/iauth/a_log_def.h Thu Oct 18 21:51:08 2001 +++ irc2.10.3p6+hemp/iauth/a_log_def.h Sat Feb 28 00:27:32 2004 @@ -37,5 +37,7 @@ #define ALOG_DSOCKSC 0x040000 /* debug: module socks cache */ #define ALOG_DPIPE 0x080000 /* debug: module pipe */ #define ALOG_DLHEX 0x100000 /* debug: module pipe */ +#define ALOG_DWEBPROXY 0x200000 /* debug: module webproxy */ +#define ALOG_DWEBPROXYC 0x400000 /* debug: module webproxy */ -#define ALOG_DALL 0x1F3700 /* any debug flag */ +#define ALOG_DALL 0x7F3700 /* any debug flag */ Only in irc2.10.3p6+hemp/iauth: a_log_def.h.orig diff -ru --exclude=CVS irc2.10.3p6/iauth/iauth.c irc2.10.3p6+hemp/iauth/iauth.c --- irc2.10.3p6/iauth/iauth.c Wed May 16 12:42:51 2001 +++ irc2.10.3p6+hemp/iauth/iauth.c Sat Feb 28 00:27:32 2004 @@ -135,6 +135,24 @@ #endif } +void write_pidfile() +{ + int fd; + char buff[20]; + (void)truncate(IAUTHPID_PATH, 0); + if ((fd = open(IAUTHPID_PATH, O_CREAT|O_WRONLY, 0600))>=0) + { + bzero(buff, sizeof(buff)); + (void)sprintf(buff,"%5d\n", (int)getpid()); + if (write(fd, buff, strlen(buff)) == -1) + (void)printf("Error writing to pid file %s", + IAUTHPID_PATH); + (void)close(fd); + return; + } +} + + int main(argc, argv) int argc; char *argv[]; @@ -197,6 +215,7 @@ #endif sendto_ircd("G 0"); + write_pidfile(); while (1) { loop_io(); Only in irc2.10.3p6+hemp/iauth: iauth.c.orig diff -ru --exclude=CVS irc2.10.3p6/iauth/mod_socks.c irc2.10.3p6+hemp/iauth/mod_socks.c --- irc2.10.3p6/iauth/mod_socks.c Mon Oct 13 02:11:43 2003 +++ irc2.10.3p6+hemp/iauth/mod_socks.c Sat Feb 28 00:27:32 2004 @@ -67,6 +67,7 @@ struct socks_private { struct proxylog *cache; + char *reason; u_int lifetime; u_char options; /* stats */ @@ -86,13 +87,19 @@ char *strver; { struct socks_private *mydata = cldata[cl].instance->data; + char *reason = mydata->reason; +#ifdef IAUTH_VERBOSE_REJECTS + char verbose = 'K'; +#else + char verbose = 'k'; +#endif /* open proxy */ if (mydata->options & OPT_DENY) { cldata[cl].state |= A_DENY; - sendto_ircd("k %d %s %u ", cl, cldata[cl].itsip, - cldata[cl].itsport); + sendto_ircd("%c %d %s %u #socks %s", verbose, cl, cldata[cl].itsip, + cldata[cl].itsport,reason ? reason : ""); } if (mydata->options & OPT_LOG) sendto_log(ALOG_FLOG, LOG_INFO, "socks%s: open proxy: %s[%s]", @@ -559,7 +566,10 @@ sprintf(cbuf, ", Cache %d (min)", mydata->lifetime); strcat(txtbuf, cbuf); mydata->lifetime *= 60; - + if (self->reason) + { + mydata->reason = mystrdup(self->reason); + } self->popt = mystrdup(tmpbuf+1); self->data = mydata; return txtbuf+2; Only in irc2.10.3p6+hemp/iauth: mod_socks.c.orig Only in irc2.10.3p6+hemp/iauth: mod_webproxy.c Only in irc2.10.3p6+hemp/iauth: mod_webproxy.c.orig Only in irc2.10.3p6+hemp/iauth: mod_webproxy_ext.h Only in irc2.10.3p6+hemp/iauth: mod_webproxy_ext.h.orig diff -ru --exclude=CVS irc2.10.3p6/ircd/channel.c irc2.10.3p6+hemp/ircd/channel.c --- irc2.10.3p6/ircd/channel.c Wed Feb 25 17:47:41 2004 +++ irc2.10.3p6+hemp/ircd/channel.c Sat Feb 28 00:27:32 2004 @@ -43,7 +43,7 @@ aChannel *channel = NullChn; -static void add_invite __P((aClient *, aChannel *)); +static void add_invite __P((aClient *, aClient *, aChannel *)); static int can_join __P((aClient *, aChannel *, char *)); void channel_modes __P((aClient *, char *, char *, aChannel *)); static int check_channelmask __P((aClient *, aClient *, char *)); @@ -55,6 +55,7 @@ static int add_modeid __P((int, aClient *, aChannel *, char *)); static int del_modeid __P((int, aChannel *, char *)); static Link *match_modeid __P((int, aClient *, aChannel *)); +static void send_names_one __P((aClient *,aClient *,char *,aChannel *,int)); static char *PartFmt = ":%s PART %s :%s"; @@ -611,6 +612,13 @@ add_user_to_channel(chptr, mp, CHFL_CHANOP); chptr->mode.mode = smode|MODE_SECRET; +#ifdef CLIENTS_CHANNEL + chptr = get_channel(mp, "&CLIENTS", CREATE); + strcpy(chptr->topic,"SERVER MESSAGES: client activities [various]"); + add_user_to_channel(chptr, mp, CHFL_CHANOP); + chptr->mode.mode = smode|MODE_SECRET; +#endif + setup_svchans(); } @@ -1004,6 +1012,7 @@ aClient *who; Mode *mode, oldm; Link *plp = NULL; + char buf[KEYLEN+1]; int compat = -1; /* to prevent mixing old/new modes */ *mbuf = *pbuf = '\0'; @@ -1166,8 +1175,17 @@ break; case 'k': *penalty += 1; - if (--parc <= 0) - break; + if (--parc <= 0) { /* a channel key query --fiction */ + *(curr+1) = '\0'; /* Stop MODE # bb.. */ + if ((*chptr->mode.key) && IsMember(sptr, chptr)) { + strncpy(buf, chptr->mode.key, KEYLEN); + } + else { *buf = '\0'; }; + + sendto_one(sptr, rpl_str(RPL_CHANNELMODEIS, sptr->name), + chptr->chname, (*chptr->mode.key) ? "+k" : "+", buf); + break; + } parv++; /* check now so we eat the parameter if present */ if (keychange) @@ -1366,7 +1384,33 @@ * limit 'l' to only *1* change per mode command but * eat up others. */ - if (limitset || !ischop) + + /* channel limit query ("mode -l" is an exception to also unset limit + * without extra parameter). To not break stuff. --fiction + */ + + if ((parc-1 <= 0) && (whatt != MODE_DEL)) { + *(curr+1) = '\0'; /* Stop MODE # bb.. */ + if ((chptr->mode.limit) && IsMember(sptr, chptr)) { + SPRINTF(buf, "%d", chptr->mode.limit); + } + else { *buf = '\0'; }; + + sendto_one(sptr, rpl_str(RPL_CHANNELMODEIS, sptr->name), + chptr->chname, (chptr->mode.limit) ? "+l" : "+" , buf); + break; + } + + /* just pretend that there was a mode change to be able to + * return an error later --fiction + */ + + if (!ischop) { + count++; + break; + } + + if (limitset) { if (whatt == MODE_ADD && --parc > 0) parv++; @@ -1398,9 +1442,14 @@ *penalty += 2; break; } - sendto_one(cptr, err_str(ERR_NEEDMOREPARAMS, - cptr->name), "MODE +l"); - break; +/* sendto_one(cptr, err_str(ERR_NEEDMOREPARAMS, + cptr->name), "MODE +l"); + break; + +Obosleted by new syntax - "mode +l" or just +"mode l" gives current limit --fiction +*/ + case 'i' : /* falls through for default case */ if (whatt == MODE_DEL && ischop) while ((lp = chptr->invites)) @@ -1452,9 +1501,13 @@ if (whatt == MODE_ADD) { if (*ip == MODE_PRIVATE) + { new &= ~MODE_SECRET; + } else if (*ip == MODE_SECRET) + { new &= ~MODE_PRIVATE; + } new |= *ip; } else @@ -1469,6 +1522,7 @@ break; } curr++; + /* * Make sure modes strings such as "+m +t +p +i" are parsed * fully. @@ -1745,7 +1799,9 @@ Reg aChannel *chptr; char *key; { - Link *lp = NULL, *banned; + invLink *lp = NULL; + Link *banned; + int limit = 0; if (chptr->users == 0 && (bootopt & BOOT_PROT) && chptr->history != 0 && *chptr->chname != '!') @@ -1761,6 +1817,12 @@ else if (lp == NULL) return (ERR_BANNEDFROMCHAN); +#ifdef CLIENTS_CHANNEL + if (chptr->chname[0]=='&') { + if (!strcmp(chptr->chname,"&CLIENTS") && !IsAnOper(sptr)) + return (ERR_INVITEONLYCHAN); + } +#endif if ((chptr->mode.mode & MODE_INVITEONLY) && !match_modeid(CHFL_INVITE, sptr, chptr) && (lp == NULL)) @@ -1769,15 +1831,31 @@ if (*chptr->mode.key && (BadPtr(key) || mycmp(chptr->mode.key, key))) return (ERR_BADCHANNELKEY); - if (chptr->mode.limit && (chptr->users >= chptr->mode.limit) && - (lp == NULL)) + if (chptr->mode.limit && (chptr->users >= chptr->mode.limit)) + { + if (lp == NULL) return (ERR_CHANNELISFULL); + else + limit = 1; + } + if (banned) + { sendto_channel_butone(&me, &me, chptr, - ":%s NOTICE %s :%s carries an invitation (overriding ban on %s).", - ME, chptr->chname, sptr->name, - banned->value.cp); + ":%s NOTICE %s :%s carries an invitation from %s" + " (overriding%s ban on %s).", + ME, chptr->chname, sptr->name, lp->who, + limit ? " channel limit and" : "", + banned->value.cp); + } + else if (limit) + { + sendto_channel_butone(&me, &me, chptr, + ":%s NOTICE %s :%s carries an invitation from %s" + " (overriding channel limit).", ME, chptr->chname, + sptr->name, lp->who); + } return 0; } @@ -1867,11 +1945,12 @@ return chptr; } -static void add_invite(cptr, chptr) + +static void add_invite(sptr, cptr, chptr) +aClient *sptr; aClient *cptr; aChannel *chptr; { - Reg Link *inv, **tmp; del_invite(cptr, chptr); /* @@ -1889,21 +1968,36 @@ /* * add client to channel invite list */ - inv = make_link(); - inv->value.cptr = cptr; - inv->next = chptr->invites; - chptr->invites = inv; - istat.is_useri++; + { + Reg Link *inv; + + inv = make_link(); + inv->value.cptr = cptr; + inv->next = chptr->invites; + chptr->invites = inv; + istat.is_useri++; + } /* * add channel to the end of the client invite list */ - for (tmp = &(cptr->user->invited); *tmp; tmp = &((*tmp)->next)) - ; - inv = make_link(); - inv->value.chptr = chptr; - inv->next = NULL; - (*tmp) = inv; - istat.is_invite++; + { + Reg invLink *inv, **tmp; + char who[NICKLEN+USERLEN+HOSTLEN+3]; + int len; + + for (tmp = &(cptr->user->invited); *tmp; tmp = &((*tmp)->next)) + ; + inv = make_invlink(); + inv->value.chptr = chptr; + inv->next = NULL; + len = sprintf(who, "%s!%s@%s", sptr->name, + sptr->user->username, sptr->user->host); + inv->who = (char *)MyMalloc(len + 1); + istat.is_banmem += len; + strcpy(inv->who, who); + (*tmp) = inv; + istat.is_invite++; + } } /* @@ -1913,25 +2007,36 @@ aClient *cptr; aChannel *chptr; { - Reg Link **inv, *tmp; + { + Reg Link **inv, *tmp; - for (inv = &(chptr->invites); (tmp = *inv); inv = &tmp->next) - if (tmp->value.cptr == cptr) - { - *inv = tmp->next; - free_link(tmp); - istat.is_invite--; - break; - } + for (inv = &(chptr->invites); (tmp = *inv); inv = &tmp->next) + { + if (tmp->value.cptr == cptr) + { + *inv = tmp->next; + free_link(tmp); + istat.is_invite--; + break; + } + } + } + { + Reg invLink **inv, *tmp; - for (inv = &(cptr->user->invited); (tmp = *inv); inv = &tmp->next) - if (tmp->value.chptr == chptr) - { - *inv = tmp->next; - free_link(tmp); - istat.is_useri--; - break; - } + for (inv = &(cptr->user->invited); (tmp = *inv); inv = &tmp->next) + { + if (tmp->value.chptr == chptr) + { + *inv = tmp->next; + istat.is_banmem -= (strlen(tmp->who)+1); + free(tmp->who); + free_invlink(tmp); + istat.is_useri--; + break; + } + } + } } /* @@ -2245,11 +2350,32 @@ ** channel so make them (rightfully) the Channel ** Operator. */ + /* do not make them Channel Operator if the server seems + ** to be splitted (i.e. if total server count is less + ** than a given number and channel count is less + ** than another given number or user count is + ** less than a third number. (francesco) + */ flags = 0; chop[0] = '\0'; - if (MyConnect(sptr) && UseModes(name) && - (!IsRestricted(sptr) || (*name == '&')) && !chptr->users && - !(chptr->history && *chptr->chname == '!')) +#ifdef SPLIT_HANDLE + if (MyConnect(sptr) && UseModes(name) && + ((*name != '#') || !iconf.split) && +#else + if ( + MyConnect(sptr) && + UseModes(name) && +#endif + ( + !IsRestricted(sptr) || + (*name == '&') + ) && + !chptr->users && + !( + chptr->history && + *chptr->chname == '!' + ) + ) { if (*name == '!') strcpy(chop, "\007O"); @@ -2306,10 +2432,20 @@ { del_invite(sptr, chptr); if (chptr->topic[0] != '\0') + { sendto_one(sptr, rpl_str(RPL_TOPIC, parv[0]), name, chptr->topic); +#ifdef TOPICWHOTIME + if (chptr->topic_time>0) + { + sendto_one(sptr, rpl_str(RPL_TOPICWHOTIME, parv[0]), + name, IsAnonymous(chptr) ? "Anonymous!Anonymous@Anomyous" : chptr->topic_nuh, + chptr->topic_time); + } +#endif + } parv[1] = name; - (void)m_names(cptr, sptr, 2, parv); + send_names_one(cptr,sptr,parv[0],chptr,1); if (IsAnonymous(chptr) && !IsQuiet(chptr)) { sendto_one(sptr, ":%s NOTICE %s :Channel %s has the anonymous flag set.", ME, chptr->chname, chptr->chname); @@ -2755,27 +2891,6 @@ return penalty; } -int count_channels(sptr) -aClient *sptr; -{ -Reg aChannel *chptr; - Reg int count = 0; - - for (chptr = channel; chptr; chptr = chptr->nextch) - { - if (chptr->users) /* don't count channels in history */ -#ifdef SHOW_INVISIBLE_LUSERS - if (SecretChannel(chptr)) - { - if (IsAnOper(sptr)) - count++; - } - else -#endif - count++; - } - return (count); -} /* ** m_topic @@ -2835,14 +2950,28 @@ if (chptr->topic[0] == '\0') sendto_one(sptr, rpl_str(RPL_NOTOPIC, parv[0]), chptr->chname); - else + else { sendto_one(sptr, rpl_str(RPL_TOPIC, parv[0]), chptr->chname, chptr->topic); +#ifdef TOPICWHOTIME + sendto_one(sptr, rpl_str(RPL_TOPICWHOTIME, parv[0]), + chptr->chname, IsAnonymous(chptr) ? "Anonymous!anonymous@anonymous" : chptr->topic_nuh, + chptr->topic_time); +#endif + } } else if ((chptr->mode.mode & MODE_TOPICLIMIT) == 0 || is_chan_op(sptr, chptr)) { /* setting a topic */ strncpyzt(chptr->topic, topic, sizeof(chptr->topic)); +#ifdef TOPICWHOTIME + strcpy(chptr->topic_nuh, sptr->name); + strcat(chptr->topic_nuh, "!"); + strcat(chptr->topic_nuh, sptr->user->username); + strcat(chptr->topic_nuh, "@"); + strcat(chptr->topic_nuh, sptr->user->host); + chptr->topic_time = timeofday; +#endif sendto_match_servs(chptr, cptr,":%s TOPIC %s :%s", parv[0], chptr->chname, chptr->topic); @@ -2947,14 +3076,13 @@ if (MyConnect(acptr)) if (chptr && /* (chptr->mode.mode & MODE_INVITEONLY) && */ sptr->user && is_chan_op(sptr, chptr)) - add_invite(acptr, chptr); + add_invite(sptr, acptr, chptr); sendto_prefix_one(acptr, sptr, ":%s INVITE %s :%s",parv[0], acptr->name, ((chptr) ? (chptr->chname) : parv[2])); return 2; } - /* ** m_list ** parv[0] = sender prefix @@ -2971,22 +3099,90 @@ if (parc > 2 && hunt_server(cptr, sptr, ":%s LIST %s %s", 2, parc, parv)) - return 10; + return MAXPENALTY; + if (BadPtr(parv[1])) + { + int maxsendq = 0; + Reg Link *lp; + int listedchannels = 0; + + if (!sptr->user) + { + sendto_one(sptr, rpl_str(RPL_LISTEND, parv[0])); + return 2; + } + +#ifdef LIST_ALIS_NOTE + if (MyConnect(sptr)) + { + sendto_one(sptr,":%s NOTICE %s :%s",ME,parv[0],LIST_ALIS_NOTE); + } +#endif + + /* Keep 10% of sendQ free + * Note: Definition of LIST command prevents obtaining + * of complete LIST from remote server, if this + * behaviour is changed, MyConnect() check needs to be added + * here and within following loops as well. - jv + */ + maxsendq = (int) ((float) get_sendq(sptr) * (float) 0.9); + /* First, show all +s/+p user is on */ + for (lp = sptr->user->channel; lp; lp = lp->next) + { + chptr = lp->value.chptr; + if (SecretChannel(chptr) || HiddenChannel(chptr)) + { + sendto_one(sptr, rpl_str(RPL_LIST, parv[0]), + chptr->chname,chptr->users, + chptr->topic); + listedchannels++; + if (DBufLength(&sptr->sendQ) > maxsendq) + { + sendto_one(sptr, + err_str(ERR_TOOMANYMATCHES, + parv[0]), "LIST"); + goto end_of_list; + } + } + } + + /* Second, show all visible channels + * +p channels users is not on, are not reported anymore - jv + */ for (chptr = channel; chptr; chptr = chptr->nextch) - { - if (!sptr->user || - !chptr->users || /* empty locked channel */ - (SecretChannel(chptr) && !IsMember(sptr, chptr))) + { + if (!chptr->users || /* empty locked channel */ + SecretChannel(chptr) || HiddenChannel(chptr)) continue; - name = ShowChannel(sptr, chptr) ? chptr->chname : NULL; - rlen += sendto_one(sptr, rpl_str(RPL_LIST, parv[0]), - name ? name : "*", chptr->users, - name ? chptr->topic : ""); - if (!MyConnect(sptr) && rlen > CHREPLLEN) + + sendto_one(sptr, rpl_str(RPL_LIST, parv[0]), + chptr->chname, chptr->users, + chptr->topic); + listedchannels++; + if (DBufLength(&sptr->sendQ) > maxsendq) + { + sendto_one(sptr, + err_str(ERR_TOOMANYMATCHES, parv[0]), + "LIST"); break; - } - else { + } + + } +end_of_list: +#ifdef LIST_ALIS_NOTE + /* Send second notice if we listed more than 24 channels + * - usual height of irc client in text mode. + */ + if (MyConnect(sptr) && (listedchannels > 24)) + { + sendto_one(sptr, ":%s NOTICE %s :%s", ME, parv[0], + LIST_ALIS_NOTE); + } +#endif + } + else + { parv[1] = canonize(parv[1]); for (; (name = strtoken(&p, parv[1], ",")); parv[1] = NULL) { @@ -3028,9 +3224,138 @@ return 2; } +/* + * send_names_one - send NAMES for one specific channel + * sends RPL_ENDOFNAMES when sendeon > 0 + */ +static void send_names_one(cptr,sptr,to,chptr,sendeon) +aClient *cptr,*sptr; +char *to; +aChannel *chptr; +int sendeon; +{ + Reg Link *lp; + Reg aClient *acptr; + char *pbuf = buf; + int pxlen,ismember,nlen,maxlen,showusers = 1, sent = 0; + + if (!chptr->users) /* channel in ND */ + { + showusers = 0; + } + else + { + ismember = (lp = find_channel_link(sptr->user->channel,chptr)) ? 1 : 0; + } + if (SecretChannel(chptr)) + { + if (!ismember) + { + showusers = 0; + } + else + { + *pbuf++ = '@'; + } + } + else if (HiddenChannel(chptr)) + { + *pbuf++ = '*'; + } + else + { + *pbuf++ = '='; + } + + if (showusers) + { + *pbuf++ = ' '; + pxlen = strlen(chptr->chname); + memcpy(pbuf,chptr->chname,pxlen); + pbuf += pxlen; + *pbuf++ = ' '; + *pbuf++ = ':'; + *pbuf = 0; + pxlen += 4; + if (IsAnonymous(chptr)) + { + if (ismember) + { + if (lp->flags & CHFL_CHANOP) + { + *pbuf++ = '@'; + } + else if (lp->flags & CHFL_VOICE) + { + *pbuf++ = '+'; + } + strcpy(pbuf,to); + } + sendto_one(sptr, rpl_str(RPL_NAMREPLY, to), buf); + } + else + { + /* server names + : : + spaces + "353" + nick length +\r\n + space for last + * entry. + */ + maxlen = BUFSIZE - 2 - 1 - strlen(ME) - 5 - strlen(to) - pxlen - NICKLEN - 2; + + for (lp = chptr->members;lp;lp=lp->next) + { + acptr = lp->value.cptr; + if (!ismember && IsInvisible(acptr)) + { + continue; + } + if (lp->flags & CHFL_CHANOP) + { + *pbuf++ = '@'; + } + else if (lp->flags & CHFL_VOICE) + { + *pbuf++ = '+'; + } + nlen = strlen(acptr->name); + /* This check is needed for server channels + * when someone removes +a mode from them. + * (server is member of such channel). + */ + if (nlen > NICKLEN) + { + nlen = NICKLEN; + } + memcpy(pbuf,acptr->name,nlen); + pbuf +=nlen; + *pbuf++ = ' '; + sent = 0; + if (((size_t) pbuf - (size_t) buf) > maxlen) + { + *pbuf = '\0'; + sendto_one(sptr, rpl_str(RPL_NAMREPLY, to), buf); + pbuf = buf + pxlen; + pbuf[0] = '\0'; + sent = 1; + } + } + if (!sent) + { + *pbuf = '\0'; + sendto_one(sptr, rpl_str(RPL_NAMREPLY, to), buf); + } + } + } + if (sendeon) + { + sendto_one(sptr, rpl_str(RPL_ENDOFNAMES, to), chptr->chname); + } + return; + +} + /************************************************************************ * m_names() - Added by Jto 27 Apr 1989 + * Rewritten by jv 27 Apr 2001 ************************************************************************/ /* @@ -3042,184 +3367,124 @@ aClient *cptr, *sptr; int parc; char *parv[]; -{ +{ Reg aChannel *chptr; - Reg aClient *c2ptr; + Reg aClient *acptr; Reg Link *lp; - aChannel *ch2ptr = NULL; - int idx, flag, len, mlen, rlen = 0; - char *s, *para = parc > 1 ? parv[1] : NULL; - + int maxlen ,pxlen,nlen,cansend = 0, sent = 1; + char *para = parc > 1 ? parv[1] : NULL,*name, *p = NULL, *pbuf = buf; + if (parc > 2 && hunt_server(cptr, sptr, ":%s NAMES %s %s", 2, parc, parv)) - return 10; - - mlen = strlen(ME) + 10; /* server names + : : + spaces + "353" */ - mlen += strlen(parv[0]); + { + return MAXPENALTY; + } + if (!BadPtr(para)) - { - s = index(para, ','); - if (s && MyConnect(sptr) && s != para) - { - parv[1] = ++s; - (void)m_names(cptr, sptr, parc, parv); - } - clean_channelname(para); - ch2ptr = find_channel(para, (aChannel *)NULL); - } - - *buf = '\0'; - - /* - * First, do all visible channels (public and the one user self is) + { + for (; (name = strtoken(&p,parv[1], ",")); parv[1] = NULL) + { + clean_channelname(name); + if BadPtr(name) + { + continue; + } + chptr = find_channel(name, NULL); + if (chptr) + { + send_names_one(cptr,sptr,parv[0],chptr,1); + } + else + { + sendto_one(sptr, rpl_str(RPL_ENDOFNAMES, parv[0]), name); + } + sent++; + if (!MyConnect(sptr) || sent > MAXPENALTY / 3) + { + break; + } + } + return sent ? 2 * sent : 2; + } + /* Client wants all nicks/channels which is seriously cpu intensive + * Allowed for local clients only. + * First, list all secret channels user is on */ - + for (lp = sptr->user->channel; lp; lp = lp->next) + { + chptr = lp->value.chptr; + if (SecretChannel(chptr)) + { + send_names_one(cptr,sptr,parv[0],chptr,0); + } + } + + /* Second, list all non-secret channels */ for (chptr = channel; chptr; chptr = chptr->nextch) - { - if (!chptr->users || /* locked empty channel */ - ((chptr != ch2ptr) && !BadPtr(para))) /* 'wrong' channel */ - continue; - if (!MyConnect(sptr) && (BadPtr(para) || (rlen > CHREPLLEN))) - break; - if ((BadPtr(para) || !HiddenChannel(chptr)) && - !ShowChannel(sptr, chptr)) - continue; /* -- users on this are not listed */ - - /* Find users on same channel (defined by chptr) */ - - (void)strcpy(buf, "* "); - len = strlen(chptr->chname); - (void)strcpy(buf + 2, chptr->chname); - (void)strcpy(buf + 2 + len, " :"); - - if (PubChannel(chptr)) - *buf = '='; - else if (SecretChannel(chptr)) - *buf = '@'; - - if (IsAnonymous(chptr)) - { - if ((lp = find_user_link(chptr->members, sptr))) - { - if (lp->flags & CHFL_CHANOP) - (void)strcat(buf, "@"); - else if (lp->flags & CHFL_VOICE) - (void)strcat(buf, "+"); - (void)strcat(buf, parv[0]); - } - rlen += strlen(buf); - sendto_one(sptr, rpl_str(RPL_NAMREPLY, parv[0]), buf); + { + if (!chptr->users || /* channel in CD */ + SecretChannel(chptr)) + { continue; - } - idx = len + 4; /* channel name + [@=] + 2?? */ - flag = 1; - for (lp = chptr->members; lp; lp = lp->next) - { - c2ptr = lp->value.cptr; - if (IsInvisible(c2ptr) && !IsMember(sptr,chptr)) - continue; - if (lp->flags & CHFL_CHANOP) - { - (void)strcat(buf, "@"); - idx++; - } - else if (lp->flags & CHFL_VOICE) - { - (void)strcat(buf, "+"); - idx++; - } - (void)strncat(buf, c2ptr->name, NICKLEN); - idx += strlen(c2ptr->name) + 1; - flag = 1; - (void)strcat(buf," "); - if (mlen + idx + NICKLEN + 1 > BUFSIZE - 2) - { - sendto_one(sptr, rpl_str(RPL_NAMREPLY, - parv[0]), buf); - (void)strncpy(buf, "* ", 3); - (void)strncpy(buf+2, chptr->chname, - len + 1); - (void)strcat(buf, " :"); - if (PubChannel(chptr)) - *buf = '='; - else if (SecretChannel(chptr)) - *buf = '@'; - idx = len + 4; - flag = 0; - } - } - if (flag) - { - rlen += strlen(buf); - sendto_one(sptr, rpl_str(RPL_NAMREPLY, parv[0]), buf); - } - } /* for(channels) */ - if (!BadPtr(para)) - { - if (!MyConnect(sptr) && (rlen > CHREPLLEN)) - sendto_one(sptr, err_str(ERR_TOOMANYMATCHES, parv[0]), - para); - sendto_one(sptr, rpl_str(RPL_ENDOFNAMES, parv[0]), para); - return(1); - } - - /* Second, do all non-public, non-secret channels in one big sweep */ - - (void)strncpy(buf, "* * :", 6); - idx = 5; - flag = 0; - for (c2ptr = client; c2ptr; c2ptr = c2ptr->next) - { - aChannel *ch3ptr; - int showflag = 0, secret = 0; - - if (!IsPerson(c2ptr) || IsInvisible(c2ptr)) + } + send_names_one(cptr,sptr,parv[0],chptr,0); + } + /* Third, list all remaining users + * ie, those which aren't on any channel, or are at Anonymous one + */ + strcpy(pbuf,"* * :"); + pxlen = 5; + pbuf += pxlen; + maxlen = BUFSIZE - 2 - 1 - strlen(ME) - 5 - strlen(parv[0]) - 5 - NICKLEN - 2; + for (acptr = client; acptr ;acptr = acptr->next) + { + if (!IsPerson(acptr) || IsInvisible(acptr)) + { continue; - if (!MyConnect(sptr) && (BadPtr(para) || (rlen > CHREPLLEN))) - break; - lp = c2ptr->user->channel; - /* - * don't show a client if they are on a secret channel or - * they are on a channel sptr is on since they have already - * been show earlier. -avalon - */ + } + + lp = acptr->user->channel; + cansend = 1; while (lp) - { - ch3ptr = lp->value.chptr; - if (PubChannel(ch3ptr) || IsMember(sptr, ch3ptr)) - showflag = 1; - if (SecretChannel(ch3ptr)) - secret = 1; + { + chptr = lp->value.chptr; + if (PubChannel(chptr) || SecretChannel(chptr) || IsMember(sptr,chptr)) + { /* already shown */ + cansend = 0; + break; + } lp = lp->next; - } - if (showflag) /* have we already shown them ? */ - continue; - if (secret) /* on any secret channels ? */ + } + if (!cansend) + { continue; - (void)strncat(buf, c2ptr->name, NICKLEN); - idx += strlen(c2ptr->name) + 1; - (void)strcat(buf," "); - flag = 1; - if (mlen + idx + NICKLEN > BUFSIZE - 2) - { - rlen += strlen(buf); - sendto_one(sptr, rpl_str(RPL_NAMREPLY, parv[0]), buf); - (void)strncpy(buf, "* * :", 6); - idx = 5; - flag = 0; - } - } - if (flag) - { - rlen += strlen(buf); - sendto_one(sptr, rpl_str(RPL_NAMREPLY, parv[0]), buf); - } - if (!MyConnect(sptr) && rlen > CHREPLLEN) - sendto_one(sptr, err_str(ERR_TOOMANYMATCHES, parv[0]), - para ? para : "*"); - /* This is broken.. remove the recursion? */ + } + nlen = strlen(acptr->name); + if (nlen > NICKLEN) + { + nlen = NICKLEN; + } + + memcpy(pbuf, acptr->name, nlen); + pbuf += nlen; + *pbuf++ = ' '; + sent = 0; + if ((size_t) pbuf - (size_t) buf > maxlen) + { + *pbuf = '\0'; + sendto_one(sptr, rpl_str(RPL_NAMREPLY, parv[0]), buf,0); + sent = 1; + pbuf = buf + pxlen; + pbuf[0] = '\0'; + } + } + if (!sent) + { + *pbuf = '\0'; + sendto_one(sptr, rpl_str(RPL_NAMREPLY, parv[0]), buf,0); + } sendto_one(sptr, rpl_str(RPL_ENDOFNAMES, parv[0]), "*"); - return 2; + return MAXPENALTY; } void send_user_joins(cptr, user) @@ -3462,7 +3727,11 @@ if (curh_nb == 0) { #ifdef DEBUGMODE +#ifdef LOCAL_REJECTIONS_ONLY + sendto_flag(SCH_NOTICE, +#else sendto_flag(SCH_LOCAL, +#endif "Channel garbage: live %u (max %u), hist %u (extended)", cur_nb - 1, max_nb - 1, curh_nb); #endif @@ -3499,7 +3768,11 @@ } #ifdef DEBUGMODE +#ifdef LOCAL_REJECTIONS_ONLY + sendto_flag(SCH_NOTICE, +#else sendto_flag(SCH_LOCAL, +#endif "Channel garbage: live %u (max %u), hist %u (removed %u)%s", cur_nb - 1, max_nb - 1, curh_nb, del - istat.is_hchan, (split) ? " split detected" : ""); diff -ru --exclude=CVS irc2.10.3p6/ircd/channel_def.h irc2.10.3p6+hemp/ircd/channel_def.h --- irc2.10.3p6/ircd/channel_def.h Wed Sep 3 19:45:47 1997 +++ irc2.10.3p6+hemp/ircd/channel_def.h Sat Feb 28 00:27:32 2004 @@ -25,5 +25,3 @@ #define NullChn ((aChannel *)0) #define ChannelExists(n) (find_channel(n, NullChn) != NullChn) - -#define MAXMODEPARAMS 3 diff -ru --exclude=CVS irc2.10.3p6/ircd/channel_ext.h irc2.10.3p6+hemp/ircd/channel_ext.h --- irc2.10.3p6/ircd/channel_ext.h Fri Jan 23 14:28:13 1998 +++ irc2.10.3p6+hemp/ircd/channel_ext.h Sat Feb 28 00:27:32 2004 @@ -53,7 +53,6 @@ char *parv[])); EXTERN int m_part __P((aClient *cptr, aClient *sptr, int parc, char *parv[])); EXTERN int m_kick __P((aClient *cptr, aClient *sptr, int parc, char *parv[])); -EXTERN int count_channels __P((aClient *sptr)); EXTERN int m_topic __P((aClient *cptr, aClient *sptr, int parc, char *parv[])); EXTERN int m_invite __P((aClient *cptr, aClient *sptr, int parc, char *parv[])); diff -ru --exclude=CVS irc2.10.3p6/ircd/hash.c irc2.10.3p6+hemp/ircd/hash.c --- irc2.10.3p6/ircd/hash.c Sat Oct 11 00:32:05 2003 +++ irc2.10.3p6+hemp/ircd/hash.c Sat Feb 28 00:27:32 2004 @@ -29,13 +29,16 @@ static aHashEntry *clientTable = NULL; static aHashEntry *channelTable = NULL; static aHashEntry *serverTable = NULL; +static aHashEntry *hostnameTable = NULL; static unsigned int *hashtab = NULL; static int clhits = 0, clmiss = 0, clsize = 0; static int chhits = 0, chmiss = 0, chsize = 0; +static int cnhits = 0, cnmiss = 0 ,cnsize = 0; static int svsize = 0; int _HASHSIZE = 0; int _CHANNELHASHSIZE = 0; int _SERVERSIZE = 0; +int _HOSTNAMEHASHSIZE = 0; /* * Hashing. @@ -74,6 +77,7 @@ char *nname; int *store; { + Reg u_char *name = (u_char *)nname; Reg u_char ch; Reg u_int hash = 1; @@ -123,6 +127,31 @@ return (hash); } + + +/* + * hash_host_name + */ +static u_int hash_host_name(hname, store) +char *hname; +int *store; +{ + + Reg u_char *name = (u_char *)hname; + Reg u_int hash = 0; + + for (; *name; name++) + { + hash = 31 * hash + hashtab[*name]; + } + + if (store) + *store = hash; + hash %= _HOSTNAMEHASHSIZE; + return (hash); +} + + /* bigger prime * * given a positive integer, return a prime number that's larger @@ -195,6 +224,21 @@ Debug((DEBUG_DEBUG, "Channel Hash Table Init: %d (%d)", _CHANNELHASHSIZE, size)); } +static void clear_hostname_hash_table(size) +int size; +{ + _HOSTNAMEHASHSIZE = bigger_prime(size); + cnhits = 0; + cnmiss = 0; + cnsize = 0; + if (!hostnameTable) + hostnameTable = (aHashEntry *)MyMalloc(_HOSTNAMEHASHSIZE * + sizeof(aHashEntry)); + bzero((char *)hostnameTable, sizeof(aHashEntry) * _HOSTNAMEHASHSIZE); + Debug((DEBUG_DEBUG, "Client Hash Table Init: %d (%d)", + _HOSTNAMEHASHSIZE, size)); +} + static void clear_server_hash_table(size) int size; @@ -218,6 +262,7 @@ : CHANNELHASHSIZE); clear_server_hash_table((_SERVERSIZE) ? _SERVERSIZE : SERVERSIZE); + clear_hostname_hash_table((_HOSTNAMEHASHSIZE) ? _HOSTNAMEHASHSIZE : HOSTNAMEHASHSIZE); /* * Moved multiplication out from the hashfunctions and into * a pre-generated lookup table. Should save some CPU usage @@ -236,6 +281,8 @@ Reg aClient *cptr; Reg aChannel *chptr; Reg aServer *sptr; + Reg anUser *user; + aHashEntry *otab = table; int osize = *size; @@ -282,19 +329,44 @@ clhits = 0; clsize = 0; clientTable = table; - + for (i = 0; i < osize; i++) { for (cptr = (aClient *)otab[i].list; cptr; cptr = next) { next = cptr->hnext; - (void)add_to_client_hash_table(cptr->name, + (void)add_to_client_hash_table(cptr->name, cptr); } } MyFree(otab); } + else if (otab == hostnameTable) + { + int i; + anUser *next; + Debug((DEBUG_ERROR, "Hostname Hash Table from %d to %d (%d)", + osize, new, clsize)); + sendto_flag(SCH_HASH, "Hostname Hash Table from %d to %d (%d)", + osize, new, clsize); + cnmiss = 0; + cnhits = 0; + cnsize = 0; + hostnameTable = table; + + for (i = 0; i < osize; i++) + { + for (user = (anUser *)otab[i].list; user; + user = next) + { + next = user->hnext; + (void)add_to_hostname_hash_table(user->host, + user); + } + } + MyFree(otab); + } else if (otab == serverTable) { Debug((DEBUG_ERROR, "Server Hash Table from %d to %d (%d)", @@ -352,6 +424,26 @@ } /* + * add_to_client_hash_table + */ +int add_to_hostname_hash_table(hostname, user) +char *hostname; +anUser *user; +{ + Reg u_int hashv; + + hashv = hash_host_name(hostname, &user->hashv); + user->hnext = (anUser *)hostnameTable[hashv].list; + hostnameTable[hashv].list = (void *)user; + hostnameTable[hashv].links++; + hostnameTable[hashv].hits++; + cnsize++; + if (cnsize > _HOSTNAMEHASHSIZE) + bigger_hash_table(&_HOSTNAMEHASHSIZE, hostnameTable, 0); + return 0; +} + +/* * add_to_server_hash_table */ int add_to_server_hash_table(sptr, cptr) @@ -456,7 +548,49 @@ } return 0; } +/* + * del_from_hostname_hash_table + */ +int del_from_hostname_hash_table(hostname, user) +char *hostname; +anUser *user; +{ + Reg anUser *tmp, *prev = NULL; + Reg u_int hashv; + hashv = user->hashv; + hashv %= _HOSTNAMEHASHSIZE; + for (tmp = (anUser *)hostnameTable[hashv].list; tmp; tmp = tmp->hnext) + { + if (tmp == user) + { + if (prev) + prev->hnext = tmp->hnext; + else + hostnameTable[hashv].list = (void *)tmp->hnext; + tmp->hnext = NULL; + if (hostnameTable[hashv].links > 0) + { + hostnameTable[hashv].links--; + cnsize--; + return 1; + } + else + { + sendto_flag(SCH_ERROR, "hn-hash table failure"); + Debug((DEBUG_ERROR, "hn-hash table failure")); + /* + * Should never actually return from here and + * if we do it is an error/inconsistency in the + * hash table. + */ + return -1; + } + } + prev = tmp; + } + return 0; +} /* * del_from_server_hash_table @@ -649,6 +783,30 @@ chmiss++; return chptr; } +/* + * hash_find_hostname + */ +anUser *hash_find_hostname(hostname, user) +char *hostname; +anUser *user; +{ + Reg anUser *tmp, *prv = NULL; + Reg aHashEntry *tmp3; + u_int hashv, hv; + + hashv = hash_host_name(hostname, &hv); + tmp3 = &hostnameTable[hashv]; + + for (tmp = (anUser *)tmp3->list; tmp; prv = tmp, tmp = tmp->hnext) + if (hv == tmp->hashv && !mycmp(hostname, tmp->host)) + { + cnhits++; + return (tmp); + } + cnmiss++; + return user; +} + /* * hash_find_channels @@ -746,14 +904,23 @@ if (parc > 1) { ch = *parv[1]; - if (islower(ch)) - table = clientTable; - else { - table = channelTable; - size = _CHANNELHASHSIZE; + switch (tolower(ch)) + { + case 'c': + table = channelTable; + size = _CHANNELHASHSIZE; + break; + case 'q': + table = hostnameTable; + size = _HOSTNAMEHASHSIZE; + break; + default: + table = clientTable; } - if (ch == 'L' || ch == 'l') + if (isupper(ch)) + { showlist = 1; + } } else { ch = '\0'; table = clientTable; @@ -950,6 +1117,8 @@ parv[0], clhits, clmiss); sendto_one(sptr,"NOTICE %s :Channel hits %d miss %d", parv[0], chhits, chmiss); + sendto_one(sptr,"NOTICE %s :Hostnames hits %d miss %d", + parv[0], cnhits, cnmiss); return 2; #endif } diff -ru --exclude=CVS irc2.10.3p6/ircd/hash_def.h irc2.10.3p6+hemp/ircd/hash_def.h --- irc2.10.3p6/ircd/hash_def.h Wed Sep 3 19:45:50 1997 +++ irc2.10.3p6+hemp/ircd/hash_def.h Sat Feb 28 00:27:32 2004 @@ -30,3 +30,5 @@ #define HASHSIZE ((int)((float)MAXCONNECTIONS*1.75)) #define CHANNELHASHSIZE ((int)(((float)MAXCONNECTIONS*1.75)/2.0)) #define SERVERSIZE (MAXCONNECTIONS/10) +#define HOSTNAMEHASHSIZE ((int)((float)MAXCONNECTIONS*1.75)) + diff -ru --exclude=CVS irc2.10.3p6/ircd/hash_ext.h irc2.10.3p6+hemp/ircd/hash_ext.h --- irc2.10.3p6/ircd/hash_ext.h Sun Jan 17 02:13:54 1999 +++ irc2.10.3p6+hemp/ircd/hash_ext.h Sat Feb 28 00:27:32 2004 @@ -40,10 +40,13 @@ EXTERN int add_to_client_hash_table __P((char *name, aClient *cptr)); EXTERN int add_to_channel_hash_table __P((char *name, aChannel *chptr)); EXTERN int add_to_server_hash_table __P((aServer *sptr, aClient *cptr)); +EXTERN int add_to_hostname_hash_table __P((char *hostname, anUser *user)); EXTERN int del_from_client_hash_table __P((char *name, aClient *cptr)); EXTERN int del_from_channel_hash_table __P((char *name, aChannel *chptr)); EXTERN int del_from_server_hash_table __P((aServer *sptr, aClient *cptr)); +EXTERN int del_from_hostname_hash_table __P((char *hostname, anUser *user)); EXTERN aClient *hash_find_client __P((char *name, aClient *cptr)); +EXTERN anUser *hash_find_hostname __P((char *hostname, anUser *user)); EXTERN aClient *hash_find_server __P((char *server, aClient *cptr)); EXTERN aChannel *hash_find_channel __P((char *name, aChannel *chptr)); EXTERN aChannel *hash_find_channels __P((char *name, aChannel *chptr)); diff -ru --exclude=CVS irc2.10.3p6/ircd/ircd.c irc2.10.3p6+hemp/ircd/ircd.c --- irc2.10.3p6/ircd/ircd.c Sat Oct 11 19:13:03 2003 +++ irc2.10.3p6+hemp/ircd/ircd.c Sat Feb 28 00:27:32 2004 @@ -33,7 +33,13 @@ static void open_debugfile(), setup_signals(), io_loop(); +#if defined(OPER_KLINE) || defined(LOCOP_KLINE) || \ + defined(OPER_TKLINE) || defined(LOCOP_TKLINE) +int kline_added = 0; +#endif + istat_t istat; +iconf_t iconf; char **myargv; int rehashed = 0; int portnum = -1; /* Server port number, listening this */ @@ -43,6 +49,7 @@ char *debugmode = ""; /* -"- -"- -"- -"- */ char *sbrk0; /* initial sbrk(0) */ char *tunefile = IRCDTUNE_PATH; +int initialconf = 1; static int dorehash = 0, dorestart = 0, restart_iauth = 0; @@ -54,6 +61,10 @@ time_t nextexpire = 1; /* next expire run on the dns cache */ time_t nextiarestart = 1; /* next time to check if iauth is alive */ +#ifdef DELAY_CLOSE +time_t nextdelayclose = 0; +#endif + #ifdef PROFIL extern etext(); @@ -337,6 +348,147 @@ return; } } +#ifdef DELAY_CLOSE +time_t delay_close(fd,reason) +int fd; +char *reason; +{ + struct fdlog + { + struct fdlog *next; + int fd; + time_t time; + char reason[BUFSIZE]; + }; + static struct fdlog *first = NULL, *last = NULL; + static int delayedfdnum = 0; + struct fdlog *next = first, *tmp; + + while (tmp = next) + if ((fd == -2) || (delayedfdnum == MAXCONNECTIONS / 10) + || tmp->time + DELAYCLOSETIME < timeofday) + { + next = tmp->next; + if (*(tmp->reason)) + { + send(tmp->fd,tmp->reason,strlen(tmp->reason),0); + } + close(tmp->fd); + delayedfdnum--; + MyFree(tmp); + if (!next) + { + if (first != last) + abort(); + first = last = NULL; + break; + } + first = next; + } + else + break; + + if (fd == -2) + { + nextdelayclose = 0; + return 0; + } + if (fd < 0) + return first ? first->time + DELAYCLOSETIME : 0; + /* disallow further receives */ + /* this should be shutdown(fd, SHUT_RD) but some OSes do- + * not define this. Check shutdown(2) if it matches. + * -- Beeth + */ +#ifndef SHUT_RD +#define SHUT_RD 0 +#endif + shutdown(fd, SHUT_RD); + + /* first create a new entry with fd and time */ + tmp = (struct fdlog *)MyMalloc(sizeof(*tmp)); + tmp->next = NULL; + tmp->fd = fd; + tmp->time = timeofday; + if (reason) + { + strncpy(tmp->reason,reason,BUFSIZE-3); + tmp->reason[BUFSIZE-3] = 0; + strcat(tmp->reason,"\r\n"); + } + delayedfdnum++; + istat.is_delayclosed++; + /* then add it to the list */ + if (last) + { + last->next = tmp; + last = tmp; + } + else + first = last = tmp; + + nextdelayclose = first ? first->time + DELAYCLOSETIME : 0; + return nextdelayclose; + +} + +#endif /* DELAY_CLOSE */ + +#if defined(OPER_KLINE) || defined(LOCOP_KLINE) || \ + defined(OPER_TKLINE) || defined(LOCOP_TKLINE) +void check_klines(void) +{ + Reg aClient *cptr; + int kflag, i; + char *reason; + + kline_added=0; + + for (i = highest_fd ; i>=0; i--) + { + + if (!(cptr = local[i]) || IsListening(cptr) || IsLog(cptr) || + IsHeld(cptr)) + continue; +#ifdef ILINE_FLAGS + if (IsKlineExempt(cptr)) + { + continue; + } +#endif + if ( IsPerson(cptr) +#ifdef ILINE_FLAGS + && !IsKlineExempt(cptr) +#endif + ) + { + kflag = find_kill(cptr, 1, &reason); + } + else + { + kflag = 0; + reason = NULL; + } + + if (kflag && IsPerson(cptr)) + { + char buf[100]; + + sendto_flag(SCH_NOTICE, + "Kill line active for %s", + get_client_name(cptr, FALSE)); + cptr->exitc = EXITC_KLINE; + if (reason) + sprintf(buf, "Kill line active: %.80s", + reason); + (void)exit_client(cptr, cptr, &me, (reason) ? + buf : "Kill line active"); + } + } + + return; +} +#endif static time_t check_pings(currenttime) @@ -354,7 +506,6 @@ if (!(cptr = local[i]) || IsListening(cptr) || IsLog(cptr) || IsHeld(cptr)) continue; - /* * K and R lines once per minute, max. This is the max. * granularity in K-lines anyway (with time field). @@ -365,7 +516,11 @@ #endif /* TIMEDKLINES */ rehashed) { - if (IsPerson(cptr)) + if (IsPerson(cptr) +#ifdef ILINE_FLAGS + && !IsKlineExempt(cptr) +#endif + ) { kflag = find_kill(cptr, rehashed, &reason); #ifdef R_LINES_OFTEN @@ -680,7 +835,9 @@ bzero((char *)&me, sizeof(me)); version = make_version(); /* Generate readable version string */ - +#ifdef SEND_ISUPPORT + isupport = make_isupport(); /* generate 005 numeric */ +#endif /* ** All command line parameters have the syntax "-fstring" ** or "-f string" (e.g. the space is optional). String may @@ -908,7 +1065,7 @@ if (!find_me()) exit(-1); } - + initialconf = 0; dbuf_init(); setup_me(&me); check_class(); @@ -984,7 +1141,11 @@ ** active C lines, this call to Tryconnections is ** made once only; it will return 0. - avalon */ +#ifdef OPER_SET + if (iconf.aconnect && nextconnect && timeofday >= nextconnect) +#else if (nextconnect && timeofday >= nextconnect) +#endif nextconnect = try_connections(timeofday); /* ** Every once in a while, hunt channel structures that @@ -1065,6 +1226,19 @@ nextping = check_pings(timeofday); rehashed = 0; } + +#ifdef DELAY_CLOSE + if (nextdelayclose && (timeofday >= nextdelayclose)) + { + nextdelayclose = delay_close(-1,NULL); + } +#endif + +#if defined(OPER_KLINE) || defined(LOCOP_KLINE) || \ + defined(OPER_TKLINE) || defined(LOCOP_TKLINE) + if (kline_added) + check_klines(); +#endif if (dorestart) restart("Caught SIGINT"); diff -ru --exclude=CVS irc2.10.3p6/ircd/ircd_ext.h irc2.10.3p6+hemp/ircd/ircd_ext.h --- irc2.10.3p6/ircd/ircd_ext.h Fri Feb 12 05:00:47 1999 +++ irc2.10.3p6+hemp/ircd/ircd_ext.h Sat Feb 28 00:27:32 2004 @@ -27,6 +27,7 @@ extern aClient me; extern aClient *client; extern istat_t istat; +extern iconf_t iconf; extern char **myargv; extern int rehashed; extern int portnum; @@ -41,6 +42,10 @@ extern time_t nextping; extern time_t nextdnscheck; extern time_t nextexpire; +extern int initialconf; +#ifdef DELAY_CLOSE +extern time_t nextdelayclose; +#endif #endif /* IRCD_C */ /* External definitions for global functions. @@ -59,4 +64,7 @@ EXTERN void server_reboot(); EXTERN void ircd_writetune __P((char *filename)); EXTERN void ircd_readtune __P((char *filename)); +#ifdef DELAY_CLOSE +EXTERN time_t delay_close __P((int fd,char *reason)); +#endif #undef EXTERN diff -ru --exclude=CVS irc2.10.3p6/ircd/list.c irc2.10.3p6+hemp/ircd/list.c --- irc2.10.3p6/ircd/list.c Sun May 6 23:36:55 2001 +++ irc2.10.3p6+hemp/ircd/list.c Sat Feb 28 00:27:32 2004 @@ -147,6 +147,11 @@ istat.is_auth -= 1; MyFree(cptr->auth); } + if (cptr->hopcount == 0) + { + if (cptr->reason) + MyFree(cptr->reason); + } MyFree((char *)cptr); } @@ -190,6 +195,7 @@ if (!serv) { serv = (aServer *)MyMalloc(sizeof(aServer)); + memset((char *) serv, 0, sizeof(aServer)); #ifdef DEBUGMODE servs.inuse++; #endif @@ -201,8 +207,11 @@ serv->up = NULL; serv->refcnt = 1; serv->nexts = NULL; +#ifdef SERVER_MAP + serv->down = NULL; +#endif cptr->serv = serv; - + bzero((void *)serv->usercnt,3*sizeof(int)); for (sp = svrtop; sp; spp = sp, sp = sp->nexts) if (spp && ((spp->ltok) + 1 < sp->ltok)) break; @@ -309,6 +318,10 @@ cptr, cptr ? cptr->name : "", buf); #endif } + if (serv->up && serv->up != ME) + { + MyFree((char *)serv->up); + } MyFree((char *)serv); } } @@ -497,6 +510,18 @@ return lp; } +invLink *make_invlink() +{ + Reg invLink *lp; + + lp = (invLink *)MyMalloc(sizeof(invLink)); +#ifdef DEBUGMODE + links.inuse++; +#endif + lp->flags = 0; + return lp; +} + void free_link(lp) Reg Link *lp; { @@ -506,6 +531,14 @@ #endif } +void free_invlink(lp) +Reg invLink *lp; +{ + MyFree((char *)lp); +#ifdef DEBUGMODE + links.inuse--; +#endif +} aClass *make_class() { @@ -547,6 +580,7 @@ aconf->status = CONF_ILLEGAL; aconf->pref = -1; aconf->hold = time(NULL); + aconf->source_ip = NULL; Class(aconf) = NULL; return (aconf); } @@ -584,6 +618,8 @@ bzero(aconf->passwd, strlen(aconf->passwd)); if (aconf->ping) MyFree((char *)aconf->ping); + if (aconf->source_ip) + MyFree(aconf->source_ip); MyFree(aconf->passwd); MyFree(aconf->name); MyFree((char *)aconf); diff -ru --exclude=CVS irc2.10.3p6/ircd/list_ext.h irc2.10.3p6+hemp/ircd/list_ext.h --- irc2.10.3p6/ircd/list_ext.h Fri Jul 2 18:49:37 1999 +++ irc2.10.3p6+hemp/ircd/list_ext.h Sat Feb 28 00:27:32 2004 @@ -55,7 +55,9 @@ EXTERN Link *find_user_link __P((Reg Link *lp, Reg aClient *ptr)); EXTERN Link *find_channel_link __P((Reg Link *lp, Reg aChannel *ptr)); EXTERN Link *make_link(); +EXTERN invLink *make_invlink(); EXTERN void free_link __P((Reg Link *lp)); +EXTERN void free_invlink __P((Reg invLink *lp)); EXTERN aClass *make_class(); EXTERN void free_class __P((Reg aClass *tmp)); EXTERN aConfItem *make_conf(); diff -ru --exclude=CVS irc2.10.3p6/ircd/res.c irc2.10.3p6+hemp/ircd/res.c --- irc2.10.3p6/ircd/res.c Tue Oct 21 00:34:02 2003 +++ irc2.10.3p6+hemp/ircd/res.c Sat Feb 28 00:27:32 2004 @@ -497,7 +497,8 @@ (u_int)(cp[1]&0xf), (u_int)(cp[1]>>4), (u_int)(cp[0]&0xf), (u_int)(cp[0]>>4), #ifdef SIXBONE_HACK - (cp[0] == 0x3f && cp[1] == 0xfe) ? "int" : + ((cp[0] == 0x3f && cp[1] == 0xfe) || + (cp[0] == 0x20 && cp[1] == 0x02)) ? "int" : #endif "arpa"); } diff -ru --exclude=CVS irc2.10.3p6/ircd/s_auth.c irc2.10.3p6+hemp/ircd/s_auth.c --- irc2.10.3p6/ircd/s_auth.c Sat Oct 11 22:04:29 2003 +++ irc2.10.3p6+hemp/ircd/s_auth.c Sat Feb 28 00:27:32 2004 @@ -291,15 +291,15 @@ } iauth_stats = (aExtData *) MyMalloc(sizeof(aExtData)); - iauth_stats->line = MyMalloc(60); + iauth_stats->line = MyMalloc(80); sprintf(iauth_stats->line, "iauth modules statistics (%s)", myctime(timeofday)); iauth_stats->next = (aExtData *) MyMalloc(sizeof(aExtData)); - iauth_stats->next->line = MyMalloc(60); + iauth_stats->next->line = MyMalloc(80); sprintf(iauth_stats->next->line, - "spawned: %d, current options: %X (%.11s)", + "spawned: %d, current options: %X (%.20s)", iauth_spawn, iauth_options, (iauth_version) ? iauth_version : "???"); iauth_stats->next->next = NULL; @@ -459,6 +459,13 @@ ** yet: we don't even know if this is a server ** or a user connection! */ + int i; + char *reason; + reason = strchr(start,'#'); + if (reason) + { + cptr->reason = mystrdup(reason+1); + } if (start[0] == 'K') cptr->exitc = EXITC_AREF; else diff -ru --exclude=CVS irc2.10.3p6/ircd/s_bsd.c irc2.10.3p6+hemp/ircd/s_bsd.c --- irc2.10.3p6/ircd/s_bsd.c Wed Feb 25 17:33:21 2004 +++ irc2.10.3p6+hemp/ircd/s_bsd.c Sat Feb 28 00:27:32 2004 @@ -327,7 +327,6 @@ #endif if (inetport(cptr, aconf->host, aconf->name, aconf->port)) cptr->fd = -2; - if (cptr->fd >= 0) { cptr->confs = make_link(); @@ -341,7 +340,32 @@ free_client(cptr); return 0; } - +#ifdef DELAY_ACCEPT +void activate_delayed_listeners() +{ + aConfItem *aconf = NULL; + int pcnt = 0; + + for (aconf = conf; aconf; aconf = aconf->next) + { + if (!(aconf->status & CONF_LISTEN_PORT) + || (conf->status & CONF_ILLEGAL)) + { + continue; + } + if (!(aconf->status & CONF_ACTIVE)) + { + aconf->status |= CONF_ACTIVE; + pcnt++; + add_listener(aconf); + } + } + if (pcnt) + { + sendto_flag(SCH_NOTICE,"Activating delayed listening ports"); + } +} +#endif #ifdef UNIXPORT /* * unixport @@ -1324,8 +1348,21 @@ } del_fd(i, &fdall); local[i] = NULL; - (void)close(i); - +#ifdef DELAY_CLOSE + if (cptr->user && (cptr->user->flags & FLAGS_BADBOY)) + { + delay_close(i,cptr->buffer); + if (!nextdelayclose) + { + nextdelayclose = timeofday + DELAYCLOSETIME; + } + } + else +#endif + { + (void)close(i); + } + cptr->fd = -2; DBufClear(&cptr->sendQ); DBufClear(&cptr->recvQ); @@ -1584,15 +1621,23 @@ report_error("Failed in connecting to %s :%s", cptr); add_con_refuse: + (void)close(fd); +add_con_delay_refuse: ircstp->is_ref++; acptr->fd = -2; free_client(acptr); - (void)close(fd); return NULL; } /* don't want to add "Failed in connecting to" here.. */ if (aconf && IsIllegal(aconf)) goto add_con_refuse; +#ifdef DELAY_ACCEPT + /* we are not accepting connections because of split */ + if (aconf && (aconf->status & CONF_DELAY) && (iconf.caccept < 2)) + { + goto add_con_refuse; + } +#endif /* Copy ascii address to 'sockhost' just in case. Then we * have something valid to put into error messages... */ @@ -1634,10 +1679,15 @@ (acptr->hostp) ? acptr->hostp->h_name : acptr->sockhost); del_queries((char *)acptr); +#ifdef DELAY_CLOSE + delay_close(fd,"ERROR :Too rapid connections from your host"); + goto add_con_delay_refuse; +#else (void)send(fd, "ERROR :Too rapid connections from your host\r\n", 46, 0); goto add_con_refuse; +#endif } #endif acptr->fd = fd; @@ -2544,6 +2594,8 @@ int *lenp; { static struct SOCKADDR_IN server; + struct SOCKADDR_IN outip; + Reg struct hostent *hp; aClient *acptr; int i; @@ -2563,7 +2615,25 @@ bzero((char *)&server, sizeof(server)); server.SIN_FAMILY = AFINET; get_sockhost(cptr, aconf->host); - + + if (aconf->source_ip) + { + memset(&outip, 0, sizeof(outip)); + outip.SIN_PORT = 0; + outip.SIN_FAMILY = AFINET; +#ifdef INET6 + if (!inetpton(AF_INET6, aconf->source_ip, outip.sin6_addr.s6_addr)) +#else + if ((outip.sin_addr.s_addr = inetaddr(aconf->source_ip)) == -1) +#endif + { + memcpy(&mysk, &outip, sizeof(mysk)); + } + } + else + { + memcpy(&outip, &mysk, sizeof(mysk)); + } if (cptr->fd == -1) { report_error("opening stream socket to server %s:%s", cptr); @@ -2575,7 +2645,7 @@ ** with more than one IP#. ** With VIFs, M:line defines outgoing IP# and initialises mysk. */ - if (bind(cptr->fd, (SAP)&mysk, sizeof(mysk)) == -1) + if (bind(cptr->fd, (SAP)&outip, sizeof(outip)) == -1) { report_error("error binding to local port for %s:%s", cptr); return NULL; diff -ru --exclude=CVS irc2.10.3p6/ircd/s_bsd_ext.h irc2.10.3p6+hemp/ircd/s_bsd_ext.h --- irc2.10.3p6/ircd/s_bsd_ext.h Fri Feb 5 00:50:21 1999 +++ irc2.10.3p6+hemp/ircd/s_bsd_ext.h Sat Feb 28 00:27:32 2004 @@ -61,6 +61,9 @@ EXTERN void get_my_name __P((aClient *cptr, char *name, int len)); EXTERN int setup_ping __P((aConfItem *aconf)); EXTERN void send_ping __P((aConfItem *aconf)); +#ifdef DELAY_ACCEPT +EXTERN void activate_delayed_listeners(); +#endif #if defined(ENABLE_SUMMON) || defined(ENABLE_USERS) EXTERN int utmp_open(); EXTERN int utmp_read __P((int fd, char *name, char *line, char *host, diff -ru --exclude=CVS irc2.10.3p6/ircd/s_conf.c irc2.10.3p6+hemp/ircd/s_conf.c --- irc2.10.3p6/ircd/s_conf.c Wed Dec 10 00:03:48 2003 +++ irc2.10.3p6+hemp/ircd/s_conf.c Sat Feb 28 00:27:32 2004 @@ -177,8 +177,9 @@ for (aconf = conf; aconf; aconf = aconf->next) { - if ((aconf->status != CONF_CLIENT) && - (aconf->status != CONF_RCLIENT)) + if (IsIllegal(aconf)) + continue; + if (!(aconf->status & (CONF_CLIENT | CONF_RCLIENT))) continue; if (aconf->port && aconf->port != cptr->acpt->port) continue; @@ -229,6 +230,16 @@ attach_iline: if (aconf->status & CONF_RCLIENT) SetRestricted(cptr); +#ifdef ILINE_FLAGS + if (aconf->status & CONF_EXEMPT) + { + cptr->user->flags |= FLAGS_EXEMPT; + } + if (!hp && (aconf->status & CONF_RNODNS)) + { + SetRestricted(cptr); + } +#endif get_sockhost(cptr, uhost); if ((i = attach_conf(cptr, aconf)) < -1) find_bounce(cptr, ConfClass(aconf), -1); @@ -301,6 +312,7 @@ *aconf2 = aconf3->next; aconf3->next = NULL; free_conf(aconf); + } else { @@ -345,7 +357,7 @@ aClient *cptr; { Reg Link *lp; - + if (is_attached(aconf, cptr)) return 1; if (IsIllegal(aconf)) @@ -358,9 +370,10 @@ return -3; /* Use this for printing error message */ } if ((aconf->status & (CONF_CLIENT | CONF_RCLIENT))) - { + { int hcnt = 0, ucnt = 0; - + int ghcnt = 0, gucnt = 0; + Reg anUser *user = NULL; /* check on local/global limits per host and per user@host */ /* @@ -368,7 +381,64 @@ ** host check is done on the IP address. ** user check is done on the IDENT reply. */ - if (ConfMaxHLocal(aconf) > 0 || ConfMaxUHLocal(aconf) > 0) { + if (ConfMaxHLocal(aconf) > 0 || ConfMaxUHLocal(aconf) > 0 || + ConfMaxHGlobal(aconf) > 0 || ConfMaxUHGlobal(aconf) > 0 ) + { + for ((user = hash_find_hostname(cptr->sockhost,NULL));user;user=user->hnext) + { + if (!mycmp(cptr->sockhost,user->host)) + { + ghcnt++; + if (MyConnect(user->bcptr)) + { + hcnt++; + if (!mycmp(user->bcptr->auth,cptr->auth)) + { + ucnt++; + gucnt++; + } + } + else + { + if (!mycmp(user->username,cptr->user->username)) + { + gucnt++; + } + } + if (ConfMaxUHLocal(aconf) > 0 && + ucnt >= ConfMaxUHLocal(aconf)) + { + return -5; + } + + if (ConfMaxHLocal(aconf) > 0 && + hcnt >= ConfMaxHLocal(aconf)) + { + return -4; + } + if (ConfMaxUHGlobal(aconf) > 0 && + gucnt >= ConfMaxUHGlobal(aconf)) + { + return -7; + } + if (ConfMaxHGlobal(aconf) > 0 && + ghcnt >= ConfMaxHGlobal(aconf)) + { + return -6; + } + } + } + } +#ifndef NO_EXTENSIVE_LOCAL_LIMIT_CHECK + /* Part of old cpu intensive code which is checking user's + * ip against all all other local clients. Needed only when + * client changes it's hostname between connects. + * Won't be needed on pure 2.11 net -- jv + */ + + /* now, check local IP too */ + if (ConfMaxHLocal(aconf) > 0 || ConfMaxUHLocal(aconf) > 0) + { Reg aClient *acptr; Reg int i; @@ -390,38 +460,8 @@ ucnt >= ConfMaxUHLocal(aconf)) return -5; /* for error message */ } - /* - ** Global limits - ** host check is done on the hostname (IP if unresolved) - ** user check is done on username - */ - if (ConfMaxHGlobal(aconf) > 0 || ConfMaxUHGlobal(aconf) > 0) - { - Reg aClient *acptr; - Reg int ghcnt = hcnt, gucnt = ucnt; - - for (acptr = client; acptr; acptr = acptr->next) - { - if (!IsPerson(acptr)) - continue; - if (MyConnect(acptr) && - (ConfMaxHLocal(aconf) > 0 || - ConfMaxUHLocal(aconf) > 0)) - continue; - if (!strcmp(cptr->sockhost, acptr->user->host)) - { - if (ConfMaxHGlobal(aconf) > 0 && - ++ghcnt >= ConfMaxHGlobal(aconf)) - return -6; - if (ConfMaxUHGlobal(aconf) > 0 && - !strcmp(cptr->user->username, - acptr->user->username) && - (++gucnt >=ConfMaxUHGlobal(aconf))) - return -7; - } - } - } - } +#endif + } lp = make_link(); istat.is_conflink++; @@ -729,12 +769,20 @@ if (!BadPtr(bconf->host) && mycmp(bconf->host, aconf->host)) continue; +#ifdef DELAY_ACCEPT + /* ignore ->passwd field */ + if (!(aconf->status & CONF_LISTEN_PORT)) + { +#endif if ((BadPtr(bconf->passwd) && !BadPtr(aconf->passwd)) || (BadPtr(aconf->passwd) && !BadPtr(bconf->passwd))) continue; if (!BadPtr(bconf->passwd) && mycmp(bconf->passwd, aconf->passwd)) continue; +#ifdef DELAY_ACCEPT + } +#endif if ((BadPtr(bconf->name) && !BadPtr(aconf->name)) || (BadPtr(aconf->name) && !BadPtr(bconf->name))) @@ -850,12 +898,11 @@ if (!(tmp2->status & CONF_ILLEGAL) || tmp2->clients) tmp = &tmp2->next; else - { + { *tmp = tmp2->next; tmp2->next = NULL; free_conf(tmp2); - } - + } #ifdef CACHED_MOTD read_motd(IRCDMOTD_PATH); #endif @@ -1189,7 +1236,27 @@ DupString(aconf->passwd, tmp); if ((tmp = getfield(NULL)) == NULL) break; - DupString(aconf->name, tmp); +#ifdef ILINE_FLAGS + if ((aconf->status & (CONF_CLIENT | CONF_RCLIENT))) + { + int shiftname = 0; + if (*tmp == '<' || (*tmp && *(tmp + 1) == '<')) + { + shiftname++; + aconf->status |= CONF_EXEMPT; + } + if (*tmp == '+' || (*tmp && *(tmp + 1) == '+')) + { + shiftname++; + aconf->status |= CONF_RNODNS; + } + DupString(aconf->name,tmp+shiftname); + } + else +#endif + { + DupString(aconf->name, tmp); + } if ((tmp = getfield(NULL)) == NULL) break; aconf->port = 0; @@ -1248,26 +1315,109 @@ if (MaxLinks(Class(aconf)) < 0) Class(aconf) = find_class(0); } +#ifdef DELAY_ACCEPT + if (aconf->status & (CONF_LISTEN_PORT)) + { + if (aconf->passwd && strchr(aconf->passwd,'D')) + { + aconf->status |= CONF_DELAY; + } + if (aconf->passwd && strchr(aconf->passwd,'S')) + { + aconf->status |= CONF_SERVERONLY; + /* feature, remove delay if serveronly */ + aconf->status &= ~CONF_DELAY; + } + } +#endif + if (aconf->status & (CONF_LISTEN_PORT|CONF_CLIENT|CONF_RCLIENT)) { - aConfItem *bconf; + aConfItem *bconf = NULL; if ((bconf = find_conf_entry(aconf, aconf->status))) { delist_conf(bconf); bconf->status &= ~CONF_ILLEGAL; - if (aconf->status == CONF_CLIENT) + if (aconf->status & (CONF_CLIENT | CONF_RCLIENT)) { +#ifdef ILINE_FLAGS + if (aconf->status & CONF_EXEMPT) + { + bconf->status |= CONF_EXEMPT; + } + else + { + bconf->status &= ~CONF_EXEMPT; + } + if (aconf->status & CONF_RNODNS) + { + bconf->status |= CONF_RNODNS; + } + else + { + bconf->status &= ~CONF_RNODNS; + } +#endif bconf->class->links -= bconf->clients; bconf->class = aconf->class; bconf->class->links += bconf->clients; } +#ifdef DELAY_ACCEPT + if (aconf->status & CONF_LISTEN_PORT) + { + if (aconf->status & CONF_DELAY) + { + bconf->status &= ~CONF_SERVERONLY; + bconf->status |= CONF_DELAY; + } + else + { + bconf->status &= ~CONF_DELAY; + } + if (aconf->status & CONF_SERVERONLY) + { + bconf->status &= ~CONF_DELAY; + bconf->status |= CONF_SERVERONLY; + } + else + { + bconf->status &= ~CONF_SERVERONLY; + } + } +#endif + free_conf(aconf); aconf = bconf; } - else if (aconf->host && - aconf->status == CONF_LISTEN_PORT) - (void)add_listener(aconf); + + if (aconf->host && + aconf->status & CONF_LISTEN_PORT) + { +#ifdef DELAY_ACCEPT + if (aconf->status & CONF_DELAY) + { + /* we have Delayed ports and we + * are starting, don't bind them. + */ + if (initialconf) + iconf.caccept = 1; + } + if (!((iconf.caccept < 2) && + (aconf->status & CONF_DELAY))) + { + aconf->status |= CONF_ACTIVE; + } + + if (aconf->status & CONF_ACTIVE) +#endif + { + if (!bconf) + { + add_listener(aconf); + } + } + } } if (aconf->status & CONF_SERVICE) aconf->port &= SERVICE_MASK_ALL; @@ -1312,6 +1462,10 @@ MyFree(tmp2); tmp2 = NULL; } + if (tmp3) + { + DupString(aconf->source_ip, tmp3); + } } /* diff -ru --exclude=CVS irc2.10.3p6/ircd/s_debug.c irc2.10.3p6+hemp/ircd/s_debug.c --- irc2.10.3p6/ircd/s_debug.c Fri Oct 19 20:44:27 2001 +++ irc2.10.3p6+hemp/ircd/s_debug.c Sat Feb 28 00:27:32 2004 @@ -36,6 +36,9 @@ #ifndef NO_IDENT 'a', #endif +#ifdef MIN_CHANOP_SERV +'B', +#endif #ifdef CHROOTDIR 'c', #endif @@ -88,6 +91,9 @@ 'K', # endif #endif +#ifdef FAILED_OPERLOG +'l', +#endif #ifdef LEAST_IDLE 'L', #endif @@ -123,6 +129,9 @@ #endif #ifdef OPER_REMOTE 't', +#ifdef TOPICWHOTIME +'T', +#endif #endif #ifndef NO_PREFIX 'u', @@ -150,6 +159,113 @@ #endif '\0'}; +/* + * Option string. Must be before #ifdef DEBUGMODE. + * spaces are not allowed. + */ +char cropts[] = { +#ifdef EXTRA_STATISTICS +'E', +#endif +#ifdef FAILED_OPERLOG +'F', +#endif +#ifdef LOG_IP +'I', +#endif +#ifdef OPER_KLINE +'K', +#endif +#ifdef LOCOP_KLINE +'k', +#endif +#ifdef OPER_TKLINE +'T', +#endif +#ifdef LOCOP_TKLINE +'t', +#endif +#ifdef RESTRICT_USERNAMES +'u', +#endif +'\0'}; + +char flopts[] = { +#ifdef CLIENTS_CHANNEL +'C', +#endif +'\0'}; + +char scopts[] = { +#ifdef EXTRA_STATISTICS +'C', +#endif +#ifdef FAILED_OPERLOG +'f', +#endif +#ifdef OPER_KLINE +# ifdef LOCOP_KLINE +'K', +# else +'k', +# endif +#endif +#ifdef LOCAL_REJECTIONS_ONLY +'r', +#endif +#ifdef TOPICWHOTIME +'t', +#endif +'\0' }; + +char jvopts[] = { +#ifdef NO_EXTENSIVE_LOCAL_LIMIT_CHECK +'L', +#endif +#ifdef STATS_F +'F', +#endif +#ifdef WHOIS_SIGNON_TIME +'s', +#endif +#ifdef NO_OPER_TRYAGAIN +'N', +#endif +#ifdef DELAY_ACCEPT +'d', +#endif +#ifdef DELAY_CLOSE +'D', +#endif +#ifdef SEND_ISUPPORT +'5', +#endif +#ifdef STATS_QMARK +'?', +#endif +#ifdef SERVER_MAP +'M', +#endif +#ifdef LIST_ALIS_NOTE +'A', +#endif +#ifdef SPLIT_HANDLE +'S', +#endif +#ifdef OPER_SET +'o', +#endif +#ifdef ILINE_FLAGS +'I', +#endif +#ifdef IAUTH_VERBOSE_REJECTS +'v', +#endif +#ifdef LOG_IRCNAME +'i', +#endif +'\0' +}; #ifdef DEBUGMODE static char debugbuf[2*READBUF_SIZE]; /* needs to be big.. */ @@ -358,6 +474,26 @@ -1, -1 #endif ); + sendto_one(cptr, ":%s %d %s :Sc:%s", ME, RPL_STATSDEFINE, nick, + scopts); +#ifdef EXTRA_STATISTICS + sendto_one(cptr, ":%s %d %s :Cr:%s %d/%d/%d/%d/%d/%d Fl:%s", + ME, RPL_STATSDEFINE, nick, cropts, + istat.is_m_users, istat.is_m_myclnt, + istat.is_m_service, istat.is_m_myservice, + istat.is_m_serv, istat.is_m_myserv,flopts); +#else + sendto_one(cptr, ":%s %d %s :Cr:%s Fl:%s", + ME, RPL_STATSDEFINE, nick, cropts,flopts); +#endif + sendto_one(cptr, ":%s %d %s :jv:%s Split Servers: %d (%d) Users: %d", + ME, RPL_STATSDEFINE,nick,jvopts, +#ifdef SPLIT_HANDLE + SPLIT_SERV,istat.is_eobservers,SPLIT_USERS +#else + -1,-1,-1 +#endif + ); } void count_memory(cptr, nick, debug) diff -ru --exclude=CVS irc2.10.3p6/ircd/s_err.c irc2.10.3p6+hemp/ircd/s_err.c --- irc2.10.3p6/ircd/s_err.c Sat Oct 11 00:30:37 2003 +++ irc2.10.3p6+hemp/ircd/s_err.c Sat Feb 28 00:27:32 2004 @@ -41,7 +41,31 @@ /* 002 */ { RPL_YOURHOST, ":Your host is %s, running version %s" }, /* 003 */ { RPL_CREATED, ":This server was created %s" }, /* 004 */ { RPL_MYINFO, "%s %s aoOirw abeiIklmnoOpqrstv" }, +#ifdef SEND_ISUPPORT +/* 005 */ //{ RPL_ISUPPORT, "MAP PREFIX=(ov)@+ MODES=3 CHANTYPES=#&!+ MAXCHANNELS=%d NICKLEN=%d TOPICLEN=%d KICKLEN=%d NETWORK=%s CHANMODES=beI,k,l,imnpstaqr :are supported by this server" }, +/* 005 */ { RPL_ISUPPORT, "%s :are supported by this server" }, +#else /* 005 */ { RPL_BOUNCE, ":Try server %s, port %d" }, +#endif +/* 006 */ { 0, (char *)NULL }, +/* 007 */ { 0, (char *)NULL }, +/* 008 */ { 0, (char *)NULL }, +/* 009 */ { 0, (char *)NULL }, +#ifdef SEND_ISUPPORT +/* 010 */ { RPL_BOUNCE, "%s %d :Please use this Server/Port instead" }, +#else +/* 010 */ { 0, (char *)NULL }, +#endif +/* 011 */ { 0, (char *)NULL }, +/* 012 */ { 0, (char *)NULL }, +/* 013 */ { 0, (char *)NULL }, +#ifdef SERVER_MAP +/* 014 */ { 0, (char *)NULL }, +/* 015 */ { RPL_MAP, ":%s" }, +/* 016 */ { 0, (char *)NULL }, +/* 017 */ { RPL_MAPEND, ":End of /MAP" }, +/* 018 */ { RPL_MAPSTART, ":%-53s | %s" }, +#endif { 0, (char *)NULL } }; @@ -62,7 +86,7 @@ /* 413 */ { ERR_NOTOPLEVEL, "%s :No toplevel domain specified" }, /* 414 */ { ERR_WILDTOPLEVEL, "%s :Wildcard in toplevel Domain" }, /* 415 */ { ERR_BADMASK, "%s :Bad Server/host mask" }, -/* 416 */ { ERR_TOOMANYMATCHES, "%s :Output too long (try locally)" }, +/* 416 */ { ERR_TOOMANYMATCHES, "%s :Output too long." }, { 0, (char *)NULL }, { 0, (char *)NULL }, { 0, (char *)NULL }, @@ -183,7 +207,11 @@ /* 314 */ { RPL_WHOWASUSER, "%s %s %s * :%s" }, /* 315 */ { RPL_ENDOFWHO, "%s :End of WHO list." }, /* 316 */ { RPL_WHOISCHANOP, (char *)NULL }, +#ifdef WHOIS_SIGNON_TIME +/* 317 */ { RPL_WHOISIDLE, "%s %ld %ld :seconds idle, signon time" }, +#else /* 317 */ { RPL_WHOISIDLE, "%s %ld :seconds idle" }, +#endif /* 318 */ { RPL_ENDOFWHOIS, "%s :End of WHOIS list." }, /* 319 */ { RPL_WHOISCHANNELS, "%s :%s" }, { 0, (char *)NULL }, @@ -199,7 +227,11 @@ { 0, (char *)NULL }, /* 331 */ { RPL_NOTOPIC, "%s :No topic is set." }, /* 332 */ { RPL_TOPIC, "%s :%s" }, +#ifdef TOPICWHOTIME +/* 333 */ { RPL_TOPICWHOTIME, "%s %s %lu" }, +#else { 0, (char *)NULL }, +#endif { 0, (char *)NULL }, { 0, (char *)NULL }, { 0, (char *)NULL }, @@ -247,7 +279,8 @@ { 0, (char *)NULL }, { 0, (char *)NULL }, { 0, (char *)NULL }, -/* 381 */ { RPL_YOUREOPER, ":You are now an IRC Operator" }, +/* 381 */ { RPL_YOUREOPER, ":You are now known as an IRC supermouse\ + ~(,,^>." }, /* 382 */ { RPL_REHASHING, "%s :Rehashing" }, /* 383 */ { RPL_YOURESERVICE, ":You are service %s" }, /* 384 */ { RPL_MYPORTIS, "%d :Port to local server is\r\n" }, @@ -293,7 +326,7 @@ /* 217 */ { RPL_STATSQLINE, "%c %s %s %s %d %d" }, /* 218 */ { RPL_STATSYLINE, "%c %d %d %d %d %ld %d.%d %d.%d" }, /* 219 */ { RPL_ENDOFSTATS, "%c :End of STATS report" }, - { 0, (char *)NULL }, +/* 220 */ { RPL_STATSPLINE, "%c %d %s %d :%s %s" }, /* 221 */ { RPL_UMODEIS, "%s" }, { 0, (char *)NULL }, { 0, (char *)NULL }, @@ -338,7 +371,13 @@ /* 261 */ { RPL_TRACELOG, "File %s %d" }, /* 262 */ { RPL_TRACEEND, "%s %s.%s :End of TRACE" }, /* 263 */ { RPL_TRYAGAIN, "%s :Please wait a while and try again." }, +#ifdef EXTRA_STATISTICS + { 0, (char *)NULL }, +/* 265 */ { RPL_LOCALUSERS, ":Current local users: %d Max: %d" }, +/* 266 */ { RPL_GLOBALUSERS, ":Current global users: %d Max: %d" } +#else { 0, (char *)NULL } +#endif }; char *err_str(numeric, to) diff -ru --exclude=CVS irc2.10.3p6/ircd/s_misc.c irc2.10.3p6+hemp/ircd/s_misc.c --- irc2.10.3p6/ircd/s_misc.c Fri Oct 19 20:44:27 2001 +++ irc2.10.3p6+hemp/ircd/s_misc.c Sat Feb 28 00:27:32 2004 @@ -370,7 +370,11 @@ { if (sptr->flags & FLAGS_KILLED) { +#ifdef LOCAL_REJECTIONS_ONLY + sendto_flag(SCH_NOTICE, "Killed: %s.", +#else sendto_flag(SCH_LOCAL, "Killed: %s.", +#endif get_client_name(sptr, TRUE)); sptr->exitc = EXITC_KILL; } @@ -386,6 +390,11 @@ sendto_flog(sptr, NULL, sptr->user->username, sptr->user->host); # endif +#ifdef CLIENTS_CHANNEL + sendto_flag(SCH_CLIENTS, "Client exiting: %s was %s from %s reason: %s", + sptr->name,sptr->user->username,sptr->user->host,comment); + +#endif } else if (sptr->exitc != EXITC_REF && sptr->exitc != EXITC_AREF) { @@ -408,16 +417,30 @@ istat.is_myservice--; else istat.is_unknown--; - - if (cptr != NULL && sptr != cptr) - sendto_one(sptr, "ERROR :Closing Link: %s %s (%s)", - get_client_name(sptr,FALSE), - cptr->name, comment); - else - sendto_one(sptr, "ERROR :Closing Link: %s (%s)", - get_client_name(sptr,FALSE), comment); - - if (sptr->auth != sptr->username) +#ifdef DELAY_CLOSE + if (cptr && cptr->user && (cptr->user->flags + & FLAGS_BADBOY)) + { + SPRINTF(cptr->buffer, "ERROR :Closing Link: %s (%s)", + get_client_name(sptr,FALSE), comment); + } + else +#endif + { + if (cptr != NULL && sptr != cptr) + { + sendto_one(sptr, "ERROR :Closing Link: %s %s (%s)", + get_client_name(sptr,FALSE), + cptr->name, comment); + } + else + { + sendto_one(sptr, "ERROR :Closing Link: %s (%s)", + get_client_name(sptr,FALSE), comment); + + } + } + if (sptr->auth != sptr->username) { istat.is_authmem -= strlen(sptr->auth) + 1; istat.is_auth -= 1; @@ -504,6 +527,15 @@ } } } /* If (IsServer(sptr)) */ +#ifdef SPLIT_HANDLE + if ((istat.is_user[0] + istat.is_user[1]) < SPLIT_USERS || istat.is_eobservers < SPLIT_SERV) + { + if (!iconf.split) + { + check_split(); + } + } +#endif } /* if (MyConnect(sptr) || (sptr->flags & FLAGS_HELD)) */ if (IsServer(sptr) && GotDependantClient(sptr)) @@ -531,6 +563,16 @@ acptr->flags |= flags; exit_one_client(cptr, acptr, &me, comment1); } +#ifdef SPLIT_HANDLE + if ((istat.is_user[0] + istat.is_user[1]) < SPLIT_USERS || istat.is_eobservers < SPLIT_SERV) + { + if (!iconf.split) + { + check_split(); + } + } +#endif + } /* @@ -577,6 +619,15 @@ cptr->name, comment); exit_one_client(cptr, sptr, from, (*comment1) ? comment1 : comment); +#ifdef SPLIT_HANDLE + if ((istat.is_user[0] + istat.is_user[1]) < SPLIT_USERS || istat.is_eobservers < SPLIT_SERV) + { + if (!iconf.split) + { + check_split(); + } + } +#endif return cptr == sptr ? FLUSH_BUFFER : 0; } @@ -604,13 +655,65 @@ "ERROR: tried to exit me! : %s", comment); return; /* ...must *never* exit self!! */ } - else if (IsServer(sptr)) { + else if (IsServer(sptr)) + { + Link *lpu,**tmp; + aClient *auptr; + int dcnt = 0; + + /* ** Old sendto_serv_but_one() call removed because we now ** need to send different names to different servers ** (domain name matching) */ istat.is_serv--; +#ifdef SPLIT_HANDLE + if (!IsBurst(sptr)) + { + istat.is_eobservers--; + } +#endif + /* we have also remove the server from ->down */ + auptr = find_client(sptr->serv->up,NULL); + /* hmm.. if it doesn't exist, it means it squitted before */ + if (auptr) + { + lpu = auptr->serv->down; + if (lpu) + { + dcnt = --lpu->flags; + } + for (tmp = &(auptr->serv->down); (lpu = *tmp); tmp = &lpu->next) + { + if (lpu->value.cptr == sptr) + { + *tmp = lpu->next; + free_link(lpu); + break; + } + } + if (auptr->serv->down) + { + auptr->serv->down->flags = dcnt; + } + } + /* and free my downlinks. The squit code is SOOO broken btw */ + if (sptr->serv->down) + { + Link *lp2; + lp2 = sptr->serv->down; + while (lp2) + { + lpu = lp2; + lp2 = lp2->next; + free_link(lpu); + } + sptr->serv->down = NULL; + } +#ifdef EXTRA_STATISTICS + save_server_max(sptr->name,sptr->serv->usermax); +#endif for (i = fdas.highest; i >= 0; i--) { Reg aConfItem *aconf; @@ -696,11 +799,21 @@ if (sptr->user) { if (IsInvisible(sptr)) + { istat.is_user[1]--; - else - istat.is_user[0]--; + sptr->user->servp->usercnt[1]--; + } + else + { + sptr->user->servp->usercnt[0]--; + istat.is_user[0]--; + } + if (IsAnOper(sptr)) + { istat.is_oper--; + sptr->user->servp->usercnt[2]--; + } sendto_common_channels(sptr, ":%s QUIT :%s", sptr->name, comment); @@ -745,6 +858,8 @@ add_history(sptr, (sptr == cptr) ? &me : NULL); #endif off_history(sptr); + del_from_hostname_hash_table(sptr->user->host,sptr->user); + } } else if (sptr->name[0] && IsService(sptr)) @@ -825,16 +940,33 @@ istat.is_serv = 1; istat.is_remc = 1; /* don't ask me why, I forgot. */ bzero((char *)&ircst, sizeof(ircst)); + + bzero((char *)&iconf, sizeof(iconf)); + iconf.aconnect = 1; + iconf.split = 1; +#ifdef DELAY_ACCEPT + iconf.caccept = 2; +#endif } +#ifdef EXTRA_STATISTICS +void tstats(cptr, name, level) +aClient *cptr; +char *name; +int level; +#else void tstats(cptr, name) aClient *cptr; char *name; +#endif { Reg aClient *acptr; Reg int i; Reg struct stats *sp; struct stats tmp; +#ifdef EXTRA_STATISTICS + Reg time_t now; +#endif sp = &tmp; bcopy((char *)ircstp, (char *)sp, sizeof(*sp)); @@ -884,6 +1016,173 @@ sp->is_ni++; } +#ifdef EXTRA_STATISTICS + switch (level) { + case 2: now = timeofday - me.since; + if (now == 0) + now = 1; + + sendto_one(cptr, + ":%s %d %s :------------------------------------------------------", + ME, RPL_STATSDEBUG, name); + sendto_one(cptr, + ":%s %d %s :Current uptime: %4d day%s, %2d:%02d:%02d%s %10d s", + ME, RPL_STATSDEBUG, name, now/86400, ( now/86400 == 1 ? "" : "s"), + (now/3600)%24, (now/60)%60, now%60, ( now/86400 == 1 ? " " : ""), now); + sendto_one(cptr, + ":%s %d %s :------------------------------------------------------", + ME, RPL_STATSDEBUG, name); + sendto_one(cptr, + ":%s %d %s :Connected Current Highest Average Total NetHigh", + ME, RPL_STATSDEBUG, name); + sendto_one(cptr, + ":%s %d %s :Clients: %6u %8u %8.1f %8u %8u", + ME, RPL_STATSDEBUG, name, istat.is_myclnt, istat.is_m_myclnt, + (float )((double ) sp->is_cti / (double ) (now)), sp->is_cl, + istat.is_m_users); + if (istat.is_m_myservice != 0) + sendto_one(cptr, + ":%s %d %s :Services: %6u %8u %8u", + ME, RPL_STATSDEBUG, name, istat.is_myservice, + istat.is_m_myservice, istat.is_m_service); + sendto_one(cptr, + ":%s %d %s :Servers: %6u %8u %8.1f %8u %8u", + ME, RPL_STATSDEBUG, name, istat.is_myserv, istat.is_m_myserv, + ((float ) sp->is_sti / (float ) (now)), sp->is_sv, istat.is_m_serv); + sendto_one(cptr, + ":%s %d %s :------------------------------------------------------", + ME, RPL_STATSDEBUG, name); + sendto_one(cptr, + ":%s %d %s :Duration Average Total", + ME, RPL_STATSDEBUG, name); + sendto_one(cptr, + ":%s %d %s :Clients: %4d:%02d:%02d %12lu s", + ME, RPL_STATSDEBUG, name, + ((sp->is_cti / (sp->is_cl ? sp->is_cl : 1))/3600), + (((sp->is_cti / (sp->is_cl ? sp->is_cl : 1))/60)%60), + ((sp->is_cti / (sp->is_cl ? sp->is_cl : 1))%60), sp->is_cti); + sendto_one(cptr, + ":%s %d %s :Servers: %4d:%02d:%02d %12lu s", + ME, RPL_STATSDEBUG, name, + ((sp->is_sti / (sp->is_sv ? sp->is_sv : 1))/3600), + (((sp->is_sti / (sp->is_sv ? sp->is_sv : 1))/60)%60), + ((sp->is_sti / (sp->is_sv ? sp->is_sv : 1))%60), sp->is_sti); + sendto_one(cptr, + ":%s %d %s :------------------------------------------------------", + ME, RPL_STATSDEBUG, name); + sendto_one(cptr, + ":%s %d %s :Data received Average Rate Total", + ME, RPL_STATSDEBUG, name); + sendto_one(cptr, + ":%s %d %s :Clients: %8lu Kb %6.2f Kb/s %10lu Kb", + ME, RPL_STATSDEBUG, name, (sp->is_ckr / ( sp->is_cl ? sp->is_cl : 1 )), + ((double ) sp->is_ckr / (double ) (now)), sp->is_ckr); + sendto_one(cptr, + ":%s %d %s :Servers: %8lu Kb %6.2f Kb/s %10lu Kb", + ME, RPL_STATSDEBUG, name, + ( sp->is_skr / ( sp->is_sv ? sp->is_sv : 1 )), + (float )((double ) sp->is_skr / (double ) (now)), sp->is_skr); + sendto_one(cptr, + ":%s %d %s :UDP: %8u", + ME, RPL_STATSDEBUG, name, sp->is_udpok); + sendto_one(cptr, + ":%s %d %s :------------------------------------------------------", + ME, RPL_STATSDEBUG, name); + sendto_one(cptr, + ":%s %d %s :Data sent Average Rate Total", + ME, RPL_STATSDEBUG, name); + sendto_one(cptr, + ":%s %d %s :Clients: %8lu Kb %6.2f Kb/s %10lu Kb", + ME, RPL_STATSDEBUG, name, (sp->is_cks / (sp->is_cl ? sp->is_cl : 1)), + (float )((double ) sp->is_cks / (double ) (now)), sp->is_cks); + sendto_one(cptr, + ":%s %d %s :Servers: %8lu Kb %6.2f Kb/s %10lu Kb", + ME, RPL_STATSDEBUG, name, (sp->is_sks / (sp->is_sv ? sp->is_sv : 1)), + (float )((double ) sp->is_sks / (double ) (now)), sp->is_sks); + sendto_one(cptr, + ":%s %d %s :------------------------------------------------------", + ME, RPL_STATSDEBUG, name); + return; + + case 1: sendto_one(cptr, + ":%s %d %s :------------------------------------------------------", + ME, RPL_STATSDEBUG, name); +#if !defined(USE_IAUTH) + sendto_one(cptr, + ":%s %d %s :Authorization fails: %8lu", + ME, RPL_STATSDEBUG, name, sp->is_abad); + sendto_one(cptr, + ":%s %d %s :Authorization successes: %8lu", + ME, RPL_STATSDEBUG, name, sp->is_asuc); +#endif + sendto_one(cptr, + ":%s %d %s :Connections accepted: %8lu", + ME, RPL_STATSDEBUG, name, sp->is_ac); + sendto_one(cptr, + ":%s %d %s :Connections refused: %8lu", + ME, RPL_STATSDEBUG, name, sp->is_ref); + sendto_one(cptr, + ":%s %d %s :Local connections made: %8lu", + ME, RPL_STATSDEBUG, name, sp->is_loc); + sendto_one(cptr, + ":%s %d %s :------------------------------------------------------", + ME, RPL_STATSDEBUG, name); + sendto_one(cptr, + ":%s %d %s :Fakes: %8lu", + ME, RPL_STATSDEBUG, name, sp->is_fake); + sendto_one(cptr, + ":%s %d %s :Nick Collisions: %8lu", + ME, RPL_STATSDEBUG, name, sp->is_kill); + sendto_one(cptr, + ":%s %d %s :Unknown connections dropped: %8lu", + ME, RPL_STATSDEBUG, name, sp->is_ni); + sendto_one(cptr, + ":%s %d %s :Users without servers: %8lu", + ME, RPL_STATSDEBUG, name, sp->is_nosrv); + sendto_one(cptr, + ":%s %d %s :Empty messages: %8lu", + ME, RPL_STATSDEBUG, name, sp->is_empt); + sendto_one(cptr, + ":%s %d %s :Numerics seen: %8lu", + ME, RPL_STATSDEBUG, name, sp->is_num); + sendto_one(cptr, + ":%s %d %s :Unknown commands: %8lu", + ME, RPL_STATSDEBUG, name, sp->is_unco); + sendto_one(cptr, + ":%s %d %s :Unknown prefixes: %8lu", + ME, RPL_STATSDEBUG, name, sp->is_unpf); + sendto_one(cptr, + ":%s %d %s :Wrong directions: %8lu", + ME, RPL_STATSDEBUG, name, sp->is_wrdi); + sendto_one(cptr, + ":%s %d %s :------------------------------------------------------", + ME, RPL_STATSDEBUG, name); + sendto_one(cptr, + ":%s %d %s :Elapsed time Minimum Average Maximum Limit", + ME, RPL_STATSDEBUG, name); + sendto_one(cptr, + ":%s %d %s :Nick Delay: %8lu %8lu %8lu %8lu", + ME, RPL_STATSDEBUG, name, sp->is_wwmt, + (u_int) (sp->is_wwt / (sp->is_wwcnt ? sp->is_wwcnt : 1 )), + sp->is_wwMt, KILLCHASETIMELIMIT); + sendto_one(cptr, + ":%s %d %s :Whowas: %8lu %8lu %8lu %8lu", + ME, RPL_STATSDEBUG, name, sp->is_lkmt, + (u_int) (sp->is_lkt / (sp->is_lkcnt ? sp->is_lkcnt : 1)), + sp->is_lkMt, DELAYCHASETIMELIMIT); + sendto_one(cptr, + ":%s %d %s :------------------------------------------------------", + ME, RPL_STATSDEBUG, name); +#if defined(USE_IAUTH) + report_iauth_stats(cptr, name); + sendto_one(cptr, + ":%s %d %s :------------------------------------------------------", + ME, RPL_STATSDEBUG, name); +#endif + return; + } +#endif + sendto_one(cptr, ":%s %d %s :accepts %lu refused %lu", ME, RPL_STATSDEBUG, name, sp->is_ac, sp->is_ref); sendto_one(cptr, ":%s %d %s :unknown: commands %lu prefixes %lu", @@ -931,6 +1230,13 @@ sp->is_ckr, sp->is_cbr, sp->is_skr, sp->is_sbr); sendto_one(cptr, ":%s %d %s :time connected %lu %lu", ME, RPL_STATSDEBUG, name, sp->is_cti, sp->is_sti); +#ifdef DELAY_CLOSE + if (IsAnOper(cptr)) + { + sendto_one(cptr, ":%s %d %s :delay closed %lu", + ME,RPL_STATSDEBUG, name, istat.is_delayclosed); + } +#endif #if defined(USE_IAUTH) report_iauth_stats(cptr, name); #endif @@ -985,4 +1291,326 @@ (void)dgets(-1, NULL, 0); /* make sure buffer is at empty pos */ close(fd); } +#endif + + +#if defined(OPER_KLINE) || defined(LOCOP_KLINE) +int m_kline(cptr,sptr,parc,parv) +aClient *cptr, *sptr; +int parc; +char *parv[]; +{ + +#if defined(OPER_KLINE) && defined(LOCOP_KLINE) + if (!MyClient(sptr) || !IsAnOper(sptr)) +#else +# if defined(OPER_KLINE) + if (!MyClient(sptr) || !IsOper(sptr)) +# else + if (!MyClient(sptr) || !IsLocOp(sptr)) +# endif +#endif + { + sendto_one(sptr, err_str(ERR_NOPRIVILEGES, parv[0]), me.name, + parv[0]); + return 0; + } + + return m_dokline(cptr,sptr,parc,parv,1); +} +#endif + + +#if defined(OPER_TKLINE) || defined(LOCOP_TKLINE) +int m_tkline(cptr,sptr,parc,parv) +aClient *cptr, *sptr; +int parc; +char *parv[]; +{ + +#if defined(OPER_TKLINE) && defined(LOCOP_TKLINE) + if (!MyClient(sptr) || !IsAnOper(sptr)) +#else +# if defined(OPER_TKLINE) + if (!MyClient(sptr) || !IsOper(sptr)) +# else + if (!MyClient(sptr) || !IsLocOp(sptr)) +# endif +#endif + { + sendto_one(sptr, err_str(ERR_NOPRIVILEGES, parv[0]), me.name, + parv[0]); + return 0; + } + + return m_dokline(cptr,sptr,parc,parv,0); +} +#endif + + +#if defined(OPER_KLINE) || defined(LOCOP_KLINE) || \ + defined(OPER_TKLINE) || defined(LOCOP_TKLINE) +extern int kline_added; + +int m_dokline(cptr, sptr, parc, parv, perm) +aClient *cptr, *sptr; +int parc; +char *parv[]; +int perm; +{ + aConfItem *aconf; + aClient *acptr; + int out, i; + char buffer[1024]; + char *user, *host; + char kline_reason[256]; + time_t current_time; + + if (parc < 3) + { + sendto_one(sptr, ":%s NOTICE %s :Not enough parameters", + me.name, parv[0]); + return 0; + } + + if (match("*@*", parv[1])) + { + sendto_one(sptr, + ":%s NOTICE %s :Sorry but \"%s\" needs to be of the format\ + of user@host", me.name, parv[0], parv[1]); + return 0; + } + + user = parv[1]; + while (*user) + { + if ((*user == ' ') || (*user =='#') || (*user == IRCDCONF_DELIMITER)) + break; + user++; + } + + if (*user && (*user != ' ')) + { + sendto_one(sptr, + ":%s NOTICE %s :The user@host may not contain '%c'", + me.name, parv[0], *user); + return 0; + } + + host = strchr(parv[1], '@'); + *(host++) = '\0'; + + if ((user = strchr(host, ' ')) != NULL) + *user = '\0'; + user = parv[1]; + + if (!match(user, "dummyuser") && !match(host, "dumm.ystring.xx")) + { + sendto_one(sptr, + ":%s NOTICE %s :Sorry can not %skline *@*", + me.name, parv[0], ( perm ? "" : "t" )); + return 0; + } + + kline_reason[0] = '\0'; + if (isdigit(*parv[2])) + { + sendto_one(sptr, + ":%s NOTICE %s :The %skline reason may not start\ + with a digit", + me.name, parv[0], ( perm ? "" : "t" )); + return 0; + } + + for (i = 2; i < parc; i++) + { + if (strlen(parv[i]) + strlen(kline_reason) + 2 < 256) + { + strcat(kline_reason, parv[i]); + strcat(kline_reason, "\240"); + } + } + kline_reason[strlen(kline_reason) - 1] = '\0'; + + for (i = strlen(kline_reason) - 1; i >= 0; i--) + { + if ((kline_reason[i] == '#') || (kline_reason[i] == IRCDCONF_DELIMITER)) + { + sendto_one(sptr, + ":%s NOTICE %s :The %skline reason may not\ + contain '%c'", + me.name, parv[0], ( perm ? "" : "t" ), + kline_reason[i]); + return 0; + } + } + + aconf = make_conf(); + aconf->status = CONF_KILL; + DupString(aconf->host, host); + DupString(aconf->passwd, kline_reason); + DupString(aconf->name, user); + aconf->port = 0; + Class(aconf) = find_class(0); + aconf->next = kconf; + kconf = aconf; + aconf = NULL; + + kline_added = 1; + rehashed = 1; + + if (perm) + { + if ((out = open(KLINE_FILE, O_WRONLY|O_APPEND))==-1) + { + sendto_one(sptr, + ":%s NOTICE %s :Problem opening server configfile", + me.name, parv[0]); + return 0; + } + + time(¤t_time); + + sprintf(buffer, "# Added by %s (%s@%s) on %s", + sptr->name, sptr->user->username, sptr->user->host, + asctime(localtime(¤t_time))); + if (write(out, buffer, strlen(buffer)) <= 0) + { + sendto_one(sptr, + ":%s NOTICE %s :Problem writing to the configfile", + me.name, parv[0]); + close(out); + return 0; + } + + sprintf(buffer, "K%c%s%c%s%c%s%c\n\n", IRCDCONF_DELIMITER, host, IRCDCONF_DELIMITER, kline_reason, + IRCDCONF_DELIMITER, user, IRCDCONF_DELIMITER); + + if (write(out, buffer, strlen(buffer)) <= 0) + { + sendto_one(sptr, + ":%s NOTICE %s :Problem writing to the configfile", + me.name, parv[0]); + close(out); + return 0; + } + close(out); + } + + sendto_flag(SCH_LOCAL, "%s added a %skline for %s@%s with reason: %s", + parv[0], ( perm ? "" : "t" ), user, host, kline_reason); + sendto_one(sptr, + ":%s NOTICE %s :Added %skline for %s@%s%s with reason: %s", + me.name, parv[0], ( perm ? "" : "t" ), user, host, + ( perm ? " to the server configfile" : "" ), kline_reason); +#if defined(USE_SYSLOG) && defined(SYSLOG_KLINE) + syslog(LOG_INFO, "%s!%s@%s %skline %s@%s (%s)", + sptr->name, sptr->user->username, sptr->user->host, + ( perm ? "" : "t" ), user, host, kline_reason); +#endif + + + return 0; +} +#endif + +#ifdef EXTRA_STATISTICS +static Link *saved_servers = NULL; +void save_server_max(server,clients) +char *server; +int clients; +{ + Link *lp; + char *servername; + + for (lp = saved_servers; lp ; lp = lp->next) + { + if (!mycmp(lp->value.cp,server)) + { + sendto_flag(SCH_ERROR,"Tried to save server's user maximum for already saved server"); + return; + } + } + + servername = mystrdup(server); + lp = make_link(); + lp->value.cp = servername; + lp->flags = clients; + lp->next = saved_servers; + saved_servers = lp; +} + + +int restore_server_max(server) +char *server; +{ + Link *lp, **curr; + int users = 0; + + for (curr = &saved_servers ; (lp = *curr); curr = &lp->next) + { + if (!mycmp(lp->value.cp,server)) + { + users = lp->flags; + *curr = lp->next; + free_link(lp); + break; + } + } + return users; +} +#endif + +#ifdef SPLIT_HANDLE +void check_split() +{ + if (istat.is_eobservers < SPLIT_SERV || + (istat.is_user[0] + istat.is_user[1] < SPLIT_USERS)) + { + if (!iconf.split) + { + sendto_flag(SCH_NOTICE,"Network split detected, split mode activated"); + } + iconf.split = 1; + } + else + { + if (iconf.split) + { + sendto_flag(SCH_NOTICE,"Network rejoined, split mode deactivated"); +#ifdef DELAY_ACCEPT + if (iconf.caccept == 1) + { + activate_delayed_listeners(); + iconf.caccept = 2; + } +#endif + } + iconf.split = 0; + + } + +} +void bubble_eob(sptr) +aClient *sptr; +{ + aClient *acptr = sptr; + char *up = sptr->serv->up; + while (up && mycmp(up,me.name)) + { + up = acptr->serv->up; + acptr = find_server(up,NULL); + if (!acptr) + { + sendto_flag(SCH_ERROR,"Unknown uplink %s while bubbling EOB ?!",up); + break; + } + if (IsBurst(acptr)) + { + ClearBurst(acptr); + istat.is_eobservers++; + sendto_flag(SCH_DEBUG,"EOB from %s (bubbled)",up); + } + } +} #endif diff -ru --exclude=CVS irc2.10.3p6/ircd/s_misc_ext.h irc2.10.3p6+hemp/ircd/s_misc_ext.h --- irc2.10.3p6/ircd/s_misc_ext.h Mon Aug 3 16:09:23 1998 +++ irc2.10.3p6+hemp/ircd/s_misc_ext.h Sat Feb 28 00:27:32 2004 @@ -51,8 +51,27 @@ char *comment)); EXTERN void checklist(); EXTERN void initstats(); +#ifdef EXTRA_STATISTICS +EXTERN void tstats __P((aClient *cptr, char *name, int level)); +#else EXTERN void tstats __P((aClient *cptr, char *name)); +#endif #ifdef CACHED_MOTD EXTERN void read_motd __P((char *filename)); #endif /* CACHED_MOTD */ +#if defined(OPER_KLINE) || defined(LOCOP_KLINE) +EXTERN int m_kline __P((aClient *cptr, aClient *sptr, int parc, char *parv[])); +#endif +#if defined(OPER_TKLINE) || defined(LOCOP_TKLINE) +EXTERN int m_tkline __P((aClient *cptr, aClient *sptr, int parc, + char *parv[])); +#endif +#ifdef EXTRA_STATISTICS +EXTERN void save_server_max __P((char *server,int clients)); +EXTERN int restore_server_max __P((char *server)); +#endif +#ifdef SPLIT_HANDLE +EXTERN void check_split(); +EXTERN void bubble_eob __P((aClient *sptr)); +#endif #undef EXTERN diff -ru --exclude=CVS irc2.10.3p6/ircd/s_numeric.c irc2.10.3p6+hemp/ircd/s_numeric.c --- irc2.10.3p6/ircd/s_numeric.c Sun Dec 13 00:48:17 1998 +++ irc2.10.3p6+hemp/ircd/s_numeric.c Sat Feb 28 00:27:32 2004 @@ -82,7 +82,8 @@ } for (; (nick = strtoken(&p, parv[1], ",")); parv[1] = NULL) { - if ((acptr = find_client(nick, (aClient *)NULL))) + if ((acptr = find_client(nick, (aClient *)NULL)) || + (acptr = find_server(nick, NULL))) { /* ** Drop to bit bucket if for me... @@ -96,11 +97,27 @@ ** - Avalon */ if (IsMe(acptr) || acptr->from == cptr) + { +#ifdef SPLIT_HANDLE + if (IsServer(sptr) && IsBurst(sptr) && + numeric == ERR_NOSUCHSERVER) + { /* we got EOB-emulation reply */ + ClearBurst(sptr); + sendto_flag(SCH_DEBUG,"End of burst from %s (emulated)",sptr->name); + istat.is_eobservers++; + bubble_eob(sptr); + check_split(); + } + else +#endif + { sendto_flag(SCH_NUM, "From %s for %s: %s %d %s %s.", get_client_name(cptr, TRUE), acptr->name, sptr->name, numeric, nick, buffer); + } + } else if (IsPerson(acptr) || IsServer(acptr) || IsService(acptr)) sendto_prefix_one(acptr, sptr,":%s %d %s%s", diff -ru --exclude=CVS irc2.10.3p6/ircd/s_serv.c irc2.10.3p6+hemp/ircd/s_serv.c --- irc2.10.3p6/ircd/s_serv.c Thu Feb 26 14:28:41 2004 +++ irc2.10.3p6+hemp/ircd/s_serv.c Sat Feb 28 00:49:26 2004 @@ -510,7 +510,11 @@ /* A server can only be introduced by another server. */ if (!IsServer(sptr)) { - sendto_flag(SCH_LOCAL, +#ifdef LOCAL_REJECTIONS_ONLY + sendto_flag(SCH_NOTICE, +#else + sendto_flag(SCH_LOCAL, +#endif "Squitting %s brought by %s (introduced by %s)", host, get_client_name(cptr, FALSE), sptr->name); @@ -598,11 +602,38 @@ if (acptr->info != DefInfo) MyFree(acptr->info); acptr->info = mystrdup(info); - acptr->serv->up = sptr->name; + acptr->serv->up = mystrdup(sptr->name); acptr->serv->stok = token; acptr->serv->snum = find_server_num(acptr->name); SetServer(acptr); istat.is_serv++; +#ifdef EXTRA_STATISTICS + /* + ** Keep track of the highest number of connected + ** servers (hostmasks) to this network. + **/ + if (istat.is_serv > istat.is_m_serv) + istat.is_m_serv = istat.is_serv; + acptr->serv->usermax = restore_server_max(acptr->name); +#endif +#ifdef SPLIT_HANDLE + SetBurst(acptr); + sendto_one(cptr,":%s PING %s :%s",my_name_for_link(ME,cptr->serv->nline->port), + my_name_for_link(ME,cptr->serv->nline->port), + acptr->name); +#endif + /* add server to downlink list */ + { + Link *lp; + + lp = make_link(); + bzero((char *)lp, sizeof(Link)); + lp->value.cptr = acptr; + lp->next = sptr->serv->down; + /* we keep number of downlinks in flags */ + lp->flags = sptr->serv->down ? sptr->serv->down->flags + 1 : 1; + sptr->serv->down = lp; + } add_client_to_list(acptr); (void)add_to_client_hash_table(acptr->name, acptr); (void)add_to_server_hash_table(acptr->serv, cptr); @@ -850,16 +881,50 @@ ** code is more neat this way... --msa */ SetServer(cptr); +#ifdef SPLIT_HANDLE + SetBurst(cptr); +#endif istat.is_unknown--; istat.is_serv++; +#ifdef EXTRA_STATISTICS + /* + ** Keep track of the highest number of connected + ** servers to this network. + **/ + if (istat.is_serv > istat.is_m_serv) + istat.is_m_serv = istat.is_serv; +#endif istat.is_myserv++; +#ifdef EXTRA_STATISTICS + /* + ** Keep track of the highest number of servers which + ** this server has had connected simultaniously. + */ + if (istat.is_myserv > istat.is_m_myserv) + istat.is_m_myserv = istat.is_myserv; +#endif + +#ifdef SERVER_MAP + /* add server to downlink list */ + { + Link *lp; + + lp = make_link(); + bzero((char *)lp, sizeof(Link)); + lp->value.cptr = cptr; + lp->next = me.serv->down; + /* we keep number of downlinks in flags */ + lp->flags = me.serv->down ? me.serv->down->flags + 1 : 1; + me.serv->down = lp; + } +#endif nextping = timeofday; sendto_flag(SCH_NOTICE, "Link with %s established. (%X%s)", inpath, cptr->hopcount, (cptr->flags & FLAGS_ZIP) ? "z" : ""); (void)add_to_client_hash_table(cptr->name, cptr); /* doesnt duplicate cptr->serv if allocted this struct already */ (void)make_server(cptr); - cptr->serv->up = me.name; + cptr->serv->up = mystrdup(me.name); cptr->serv->nline = aconf; cptr->serv->version = cptr->hopcount; /* temporary location */ cptr->hopcount = 1; /* local server connection */ @@ -870,6 +935,9 @@ Debug((DEBUG_NOTICE, "Server link established with %s V%X %d", cptr->name, cptr->serv->version, cptr->serv->stok)); add_fd(cptr->fd, &fdas); +#ifdef EXTRA_STATISTICS + cptr->serv->usermax = restore_server_max(cptr->name); +#endif #ifdef USE_SERVICES check_services_butone(SERVICE_WANT_SERVER, cptr->name, cptr, ":%s SERVER %s %d %s :%s", ME, cptr->name, @@ -997,7 +1065,10 @@ send_channel_modes(cptr, chptr); } } - +#ifdef SPLIT_HANDLE + /* send PING- emulate EOB */ + sendto_one(cptr,":%s PING %s %s",my_name_for_link(ME, aconf->port),my_name_for_link(ME, aconf->port),cptr->name); +#endif cptr->flags &= ~FLAGS_CBURST; #ifdef ZIP_LINKS /* @@ -1072,7 +1143,11 @@ { char **text = infotext; - if (IsServer(cptr) && check_link(cptr)) + if ( +#ifdef NO_OPER_TRYAGAIN + !IsOper(sptr) && +#endif + IsServer(cptr) && check_link(cptr)) { sendto_one(sptr, rpl_str(RPL_TRYAGAIN, parv[0]), "INFO"); @@ -1297,7 +1372,6 @@ { CONF_DENY, RPL_STATSDLINE, 'D'}, { 0, 0, 0} }; - static void report_configured_links(sptr, to, mask) aClient *sptr; char *to; @@ -1305,6 +1379,9 @@ { static char null[] = ""; aConfItem *tmp; +#ifdef ILINE_FLAGS + char nmbuf[HOSTLEN*2]; +#endif int *p, port; char c, *host, *pass, *name; @@ -1313,14 +1390,61 @@ if (tmp->status & mask) { for (p = &report_array[0][0]; *p; p += 3) - if (*p == tmp->status) + if ((*p & tmp->status) && !(*p & CONF_ILLEGAL)) break; if (!*p) continue; c = (char)*(p+2); host = BadPtr(tmp->host) ? null : tmp->host; pass = BadPtr(tmp->passwd) ? NULL : tmp->passwd; - name = BadPtr(tmp->name) ? null : tmp->name; +#ifdef ILINE_FLAGS + if ((tmp->status & (CONF_CLIENT | CONF_RCLIENT)) && + tmp->status & (CONF_EXEMPT|CONF_RNODNS)) + { + if ((tmp->status & CONF_EXEMPT) && + tmp->status & CONF_RNODNS) + { + if (BadPtr(tmp->name)) + { + name = ""; + } + else + { + sprintf(nmbuf,"+<%s",tmp->name); + name = nmbuf; + } + } + else if (tmp->status & CONF_EXEMPT) + { + if (BadPtr(tmp->name)) + { + name = ""; + } + else + { + sprintf(nmbuf,"<%s",tmp->name); + name = nmbuf; + } + + } + else + { + if (BadPtr(tmp->name)) + { + name = ""; + } + else + { + sprintf(nmbuf,"+%s",tmp->name); + name = nmbuf; + } + } + } + else +#endif + { + name = BadPtr(tmp->name) ? null : tmp->name; + } port = (int)tmp->port; /* * On K/V lines the passwd contents can be @@ -1362,7 +1486,151 @@ } return; } +#ifdef STATS_F +static void report_fd(sptr,acptr,to) +aClient *sptr, *acptr; +char *to; +{ + static char locip[100], *ret; + int s; + + if (IsMe(acptr) || !acptr->acpt || !IsRegistered(acptr)) + return; + ret = +#ifdef INET6 + inetntop(AF_INET6, + (char *)&acptr->acpt->ip, + mydummy, MYDUMMY_SIZE), +#else + inetntoa((char *)&acptr->acpt->ip); +#endif + s = strlen(ret) + 1; + memcpy(locip, ret, s < sizeof(locip) ? s : sizeof(locip)); + locip[sizeof(locip) - 1] = 0; + sendto_one(sptr,":%s %d %s %d %s %d %s %d %s %s %d", + ME,RPL_STATSLINKINFO,to, + acptr->fd, + locip, + acptr->acpt->port, +#ifdef INET6 + inetntop(AF_INET6, + (char *)&acptr->ip, + mydummy, MYDUMMY_SIZE), +#else + inetntoa((char *)&acptr->ip), +#endif + acptr->port,acptr->name, + acptr->user ? acptr->user->username : acptr->auth, + acptr->user ? timeofday - acptr->user->last : -1 + ); +} +#endif /* STATS_F */ +#ifdef STATS_QMARK +/* show quick info about connected servers */ +static void report_myservers(sptr,to) +aClient *sptr; +char *to; +{ + int i; + int timeconnected; + aClient *acptr; + aServer *asptr; + int users = 0, servers = 0; + for (i = fdas.highest; i >= 0; i--) + { + if (!(acptr = local[fdas.fd[i]])) + { + continue; + } + + if (IsMe(acptr) || !IsServer(acptr)) + { + continue; + } + users = 0; + servers = 0; + + timeconnected = timeofday - acptr->firsttime; +#ifdef HUB + for (asptr = svrtop;asptr;asptr = asptr->nexts) + { + if (asptr->bcptr->from == acptr) + { + servers++; + users += asptr->usercnt[0]; + users += asptr->usercnt[1]; + } + } +#else /* !HUB */ + servers = istat.is_serv - 1; + users = istat.is_user[0] + istat.is_user[1]; + users -= istat.is_myclnt; +#endif + sendto_one(sptr,":%s %d %s : %s (%d, %02d:%02d:%02d) %dS %dC %ldkB sent %ldkB recv %ldkB sq%s", + ME,RPL_STATSDEBUG,to,acptr->name, + timeconnected / 86400,(timeconnected % 86400) / 3600, + (timeconnected % 3600)/60, + timeconnected % 60,servers,users,acptr->sendK,acptr->receiveK,(int) ( + (int)DBufLength(&acptr->sendQ) / 1024), +#ifdef SPLIT_HANDLE + IsBurst(acptr) ? " BURST" : "" +#else + "" +#endif + ); + } +} +#endif +#ifdef DELAY_ACCEPT +static void report_listeners(sptr,to) +aClient *sptr; +char *to; +{ + aConfItem *tmp; + int active,comma; + for (tmp = conf; tmp; tmp = tmp->next) + { + if (!(tmp->status & CONF_LISTEN_PORT)) + { + continue; + } + + /* this SUUUUX, we need some nice list of all listeners! + * - jv + */ + if (tmp->status & CONF_ACTIVE) + { + active = 1; + } + else + { + active = 0; + } + *buf = 0; + comma = 0; + if (tmp->status & CONF_DELAY) + { + strcat(buf,"delay"); + comma = 1; + } + + if (tmp->status & CONF_SERVERONLY) + { + if (comma) + { + strcat(buf,","); + } + strcat(buf,"server-only"); + } + + sendto_one(sptr,":%s %d %s :%d %s %s",ME,RPL_STATSDEFINE,to, + tmp->port,active ? "active" : "inactive",buf); + + } +} + +#endif int m_stats(cptr, sptr, parc, parv) aClient *cptr, *sptr; int parc; @@ -1423,14 +1691,35 @@ 2, parc, parv) != HUNTED_ISME) return 5; } - name = (parc > 2) ? parv[2] : ME; cm = (parc > 3) ? parv[3]: name; doall = !match(name, ME) && !match(cm, ME); wilds = index(cm, '*') || index(cm, '?'); + + /* no stats, just dumb client */ + if (parv[1] && !mycmp(parv[1],ME)) + { + return 2; + } + +#ifdef CLIENTS_CHANNEL + if (stat && (sptr->user)) { + sendto_flag(SCH_CLIENTS,"Stats %c by %s from %s on %s", + stat,sptr->name,sptr->user->username,sptr->user->host); + } +#endif switch (stat) { +#ifdef STATS_F + case 'f' : case 'F' : /* send FD list */ + if (!IsOper(sptr) || !MyConnect(sptr)) + { + stat = '*'; + break; + } + stat = 'f'; +#endif case 'L' : case 'l' : /* * send info about connections which match, or all if the @@ -1450,6 +1739,13 @@ { if (!(acptr = local[i])) continue; +#ifdef STATS_F + if (stat == 'f') + { + report_fd(sptr, acptr, parv[0]); + continue; + } +#endif if (IsPerson(acptr) && !(MyConnect(sptr) && IsAnOper(sptr)) && acptr != sptr) continue; @@ -1468,7 +1764,12 @@ else { if ((acptr = find_client(cm, NULL)) && MyConnect(acptr)) - sendto_one(cptr, Lformat, ME, +#ifdef STATS_F + if (stat == 'f') + report_fd(sptr, acptr, parv[0]); + else +#endif + sendto_one(cptr, Lformat, ME, RPL_STATSLINKINFO, parv[0], get_client_name(acptr, isupper(stat)), (int)DBufLength(&acptr->sendQ), @@ -1519,8 +1820,11 @@ report_configured_links(cptr, parv[0], CONF_OPS); break; case 'P' : /* ports listening */ - report_listeners(sptr, parv[0]); - break; + if (IsAnOper(sptr)) + { + report_listeners(sptr,parv[0]); + break; + } case 'p' : /* ircd ping stats */ report_ping(sptr, parv[0]); break; @@ -1533,8 +1837,24 @@ case 'S' : case 's' : /* S lines */ report_configured_links(cptr, parv[0], CONF_SERVICE); break; +#ifdef EXTRA_STATISTICS + case 'T' : /* various statistics for operators only */ + if (MyOper(sptr)) { + tstats(cptr, parv[0], 2); + break; + } + case 't' : /* various statistics for operators only */ + if (MyOper(sptr)) { + tstats(cptr, parv[0], 1); + break; + } + + /* various statistics */ + tstats(cptr, parv[0], 0); +#else case 'T' : case 't' : /* various statistics */ tstats(cptr, parv[0]); +#endif break; case 'U' : case 'u' : /* uptime */ { @@ -1565,6 +1885,11 @@ case 'z' : /* memory use */ count_memory(cptr, parv[0], 0); break; +#ifdef STATS_QMARK + case '?' : + report_myservers(sptr,parv[0]); + break; +#endif default : stat = '*'; break; @@ -1683,122 +2008,118 @@ int parc; char *parv[]; { - int s_count = 0, /* server */ - c_count = 0, /* client (visible) */ - u_count = 0, /* unknown */ - i_count = 0, /* invisible client */ - o_count = 0, /* oparator */ - v_count = 0; /* service */ - int m_client = 0, /* my clients */ - m_server = 0, /* my server links */ - m_service = 0; /* my services */ - aClient *acptr; - + int s_count = 0, /* server */ + c_count = 0, /* visible client */ + u_count = 0, /* unknown */ + i_count = 0, /* invisible client */ + o_count = 0, /* operator */ + v_count = 0; /* service */ + int m_client = 0, /* my clients */ + m_server = 0, /* my server links */ + m_service = 0; /* my services */ + int mask_max = 0; /* max of given mask */ + if (parc > 2) if (hunt_server(cptr, sptr, ":%s LUSERS %s :%s", 2, parc, parv) != HUNTED_ISME) return 3; if (parc == 1 || !MyConnect(sptr)) - { - sendto_one(sptr, rpl_str(RPL_LUSERCLIENT, parv[0]), - istat.is_user[0] + istat.is_user[1], - istat.is_service, istat.is_serv); - if (istat.is_oper) - sendto_one(sptr, rpl_str(RPL_LUSEROP, parv[0]), - istat.is_oper); - if (istat.is_unknown > 0) - sendto_one(sptr, rpl_str(RPL_LUSERUNKNOWN, parv[0]), - istat.is_unknown); - if (istat.is_chan) - sendto_one(sptr, rpl_str(RPL_LUSERCHANNELS, parv[0]), - istat.is_chan); - sendto_one(sptr, rpl_str(RPL_LUSERME, parv[0]), - istat.is_myclnt, istat.is_myservice, - istat.is_myserv); - return 2; - } - (void)collapse(parv[1]); - for (acptr = client; acptr; acptr = acptr->next) - { - if (!IsServer(acptr) && acptr->user) - { - if (match(parv[1], acptr->user->server)) - continue; - } - else - if (match(parv[1], acptr->name)) - continue; + { + s_count = istat.is_serv; + c_count = istat.is_user[0]; + i_count = istat.is_user[1]; + u_count = istat.is_unknown; + o_count = istat.is_oper; + v_count = istat.is_service; + m_client = istat.is_myclnt; + m_server = istat.is_myserv; + m_service = istat.is_myservice; +#ifdef EXTRA_STATISTICS + mask_max = istat.is_m_users; +#endif + } + else + { + aClient *acptr; + aServer *asptr; + aService *svcp; + + (void)collapse(parv[1]); + + /* LUSERS */ + for (asptr = svrtop;asptr;asptr = asptr->nexts) + { + if (!match(parv[1],asptr->bcptr->name)) + { + s_count++; + + c_count += asptr->usercnt[0]; + i_count += asptr->usercnt[1]; + o_count += asptr->usercnt[2]; + /* not exact probably, but oh well... */ +#ifdef EXTRA_STATISTICS + mask_max += asptr->usermax; +#endif + if (IsMe(asptr->bcptr)) + { + m_client = istat.is_myclnt; + m_server = istat.is_myserv; + m_service = istat.is_myservice; + u_count = istat.is_unknown; - switch (acptr->status) + } + } + } + + /* Count services, but only if we found some matching server + * before (to prevent wrong matches on masks like *irc*). - jv + */ + if (s_count) { - case STAT_SERVER: - if (MyConnect(acptr)) - m_server++; - /* flow thru */ - case STAT_ME: - s_count++; - break; - case STAT_SERVICE: - if (MyConnect(acptr)) - m_service++; - v_count++; - break; - case STAT_CLIENT: - if (IsOper(acptr)) - o_count++; -#ifdef SHOW_INVISIBLE_LUSERS - if (MyConnect(acptr)) - m_client++; - if (!IsInvisible(acptr)) - c_count++; - else - i_count++; -#else - if (MyConnect(acptr)) - { - if (IsInvisible(acptr)) - { - if (IsAnOper(sptr)) - m_client++; - } - else - m_client++; - } - if (!IsInvisible(acptr)) - c_count++; - else - i_count++; -#endif - break; - default: - u_count++; - break; - } - } -#ifndef SHOW_INVISIBLE_LUSERS - if (IsAnOper(sptr) && i_count) + for (svcp = svctop;svcp;svcp = svcp->nexts) + { + if (!match(parv[1],svcp->servp->bcptr->name)) + { + v_count++; + } + } + } + } + +#ifndef SHOW_INVISIBLE_LUSERS + if (!IsOper(sptr)) + { + i_count = 0; + } #endif sendto_one(sptr, rpl_str(RPL_LUSERCLIENT, parv[0]), c_count + i_count, v_count, s_count); -#ifndef SHOW_INVISIBLE_LUSERS - else - sendto_one(sptr, rpl_str(RPL_LUSERCLIENT, parv[0]), - c_count, v_count, s_count); -#endif if (o_count) + { sendto_one(sptr, rpl_str(RPL_LUSEROP, parv[0]), o_count); - if (u_count > 0) + } + if (u_count) + { sendto_one(sptr, rpl_str(RPL_LUSERUNKNOWN, parv[0]), u_count); - if ((c_count = count_channels(sptr))>0) - sendto_one(sptr, rpl_str(RPL_LUSERCHANNELS, parv[0]), - count_channels(sptr)); + } + sendto_one(sptr, rpl_str(RPL_LUSERCHANNELS, parv[0]),istat.is_chan); sendto_one(sptr, rpl_str(RPL_LUSERME, parv[0]), m_client, m_service, m_server); +#ifdef EXTRA_STATISTICS + if (m_client) + { + sendto_one(sptr, rpl_str(RPL_LOCALUSERS, parv[0]), + istat.is_myclnt, istat.is_m_myclnt); + } + sendto_one(sptr, rpl_str(RPL_GLOBALUSERS, parv[0]), + c_count + i_count, mask_max); +#endif + return 2; } - + /*********************************************************************** * m_connect() - Added by Jto 11 Feb 1989 ***********************************************************************/ @@ -1829,7 +2150,7 @@ 3,parc,parv) != HUNTED_ISME) return 1; - if (parc < 3 || *parv[1] == '\0') + if (parc < 2 || *parv[1] == '\0') { sendto_one(sptr, err_str(ERR_NEEDMOREPARAMS, parv[0]), "CONNECT"); @@ -1872,18 +2193,34 @@ ** from there, then use the precompiled default. */ tmpport = port = aconf->port; - if ((port = atoi(parv[2])) <= 0) - { + + if (parc > 2) + { + port = atoi(parv[2]); + } + if (parc < 3 || !port) + { + if (tmpport < 0) + { + port = 0 - port; + } + else + { + port = tmpport; + } + + if (!port) + { + sendto_one(sptr, ":%s NOTICE %s :Connect: missing port number", + ME, parv[0]); + return 0; + } + } + if (port < 0) + { sendto_one(sptr, "NOTICE %s :Connect: Illegal port number", parv[0]); - return 0; - } - else if (port <= 0) - { - sendto_one(sptr, ":%s NOTICE %s :Connect: missing port number", - ME, parv[0]); - return 0; - } + } /* ** Notify all operators about remote connect requests */ @@ -2033,6 +2370,14 @@ #ifdef USE_SYSLOG syslog(LOG_INFO, "REHASH From %s\n", get_client_name(sptr, FALSE)); #endif +#ifdef DELAY_CLOSE + if (parc >1 && parv[1] && *parv[1] == 'd') + { + delay_close(-2,NULL); + sendto_flag(SCH_NOTICE, + "%s is forcing closing of delay closed sockets", parv[0]); + } +#endif return rehash(cptr, sptr, (parc > 1) ? ((*parv[1] == 'q')?2:0) : 0); } #endif @@ -2080,171 +2425,236 @@ } #endif -/* -** m_trace -** parv[0] = sender prefix -** parv[1] = servername -*/ -int m_trace(cptr, sptr, parc, parv) -aClient *cptr, *sptr; -int parc; -char *parv[]; +void trace_one(to,sptr,acptr) +char *to; +aClient *sptr,*acptr; { - Reg int i; - Reg aClient *acptr; - aClass *cltmp; - char *tname; - int doall, link_s[MAXCONNECTIONS], link_u[MAXCONNECTIONS]; - int wilds, dow; - - if (parc > 1) - tname = parv[1]; - else - tname = ME; - - switch (hunt_server(cptr, sptr, ":%s TRACE :%s", 1, parc, parv)) - { - case HUNTED_PASS: /* note: gets here only if parv[1] exists */ - { - aClient *ac2ptr; + char *name; + int class; - ac2ptr = next_client(client, parv[1]); - sendto_one(sptr, rpl_str(RPL_TRACELINK, parv[0]), - version, debugmode, tname, ac2ptr->from->name, - ac2ptr->from->serv->version, - (ac2ptr->from->flags & FLAGS_ZIP) ? "z" : "", - timeofday - ac2ptr->from->firsttime, - (int)DBufLength(&ac2ptr->from->sendQ), - (int)DBufLength(&sptr->from->sendQ)); - return 5; - } - case HUNTED_ISME: - break; - default: - return 1; - } - - doall = (parv[1] && (parc > 1)) ? !match(tname, ME): TRUE; - wilds = !parv[1] || index(tname, '*') || index(tname, '?'); - dow = wilds || doall; - - if (doall) { - for (i = 0; i < MAXCONNECTIONS; i++) - link_s[i] = 0, link_u[i] = 0; - for (acptr = client; acptr; acptr = acptr->next) -#ifdef SHOW_INVISIBLE_LUSERS - if (IsPerson(acptr)) - link_u[acptr->from->fd]++; -#else - if (IsPerson(acptr) && - (!IsInvisible(acptr) || IsOper(sptr))) - link_u[acptr->from->fd]++; -#endif - else if (IsServer(acptr)) - link_s[acptr->from->fd]++; - } - - /* report all direct connections */ + name = get_client_name(acptr,FALSE); + class = get_client_class(acptr); - for (i = 0; i <= highest_fd; i++) - { - char *name; - int class; - - if (!(acptr = local[i])) /* Local Connection? */ - continue; - if (IsPerson(acptr) && IsInvisible(acptr) && dow && - !(MyConnect(sptr) && IsAnOper(sptr)) && - !IsAnOper(acptr) && (acptr != sptr)) - continue; - if (!doall && wilds && match(tname, acptr->name)) - continue; - if (!dow && mycmp(tname, acptr->name)) - continue; - name = get_client_name(acptr,FALSE); - class = get_client_class(acptr); - - switch(acptr->status) - { + switch (acptr->status) + { case STAT_CONNECTING: sendto_one(sptr, rpl_str(RPL_TRACECONNECTING, - parv[0]), class, name); - break; + to), class, name); + break; + case STAT_HANDSHAKE: - sendto_one(sptr, rpl_str(RPL_TRACEHANDSHAKE, parv[0]), - class, name); + sendto_one(sptr, rpl_str(RPL_TRACEHANDSHAKE, to), + class, name); break; + case STAT_ME: break; + case STAT_UNKNOWN: - if (IsAnOper(sptr) || (MyPerson(sptr) && SendWallops(sptr))) - sendto_one(sptr, - rpl_str(RPL_TRACEUNKNOWN, parv[0]), + sendto_one(sptr,rpl_str(RPL_TRACEUNKNOWN, to), class, name); break; + case STAT_CLIENT: - /* Only opers see users if there is a wildcard - * but anyone can see all the opers. - */ if (IsAnOper(acptr)) - sendto_one(sptr, - rpl_str(RPL_TRACEOPERATOR, parv[0]), - class, name); - else if (!dow || (MyConnect(sptr) && IsAnOper(sptr))) - sendto_one(sptr, - rpl_str(RPL_TRACEUSER, parv[0]), - class, name); + { + sendto_one(sptr,rpl_str(RPL_TRACEOPERATOR, + to),class, name); + } + else + { + sendto_one(sptr,rpl_str(RPL_TRACEUSER, + to),class, name); + } + break; + case STAT_SERVER: + { + /* we need to count servers/users behind this link */ + int servers = 0, users = 0; + aServer *asptr; + aClient *next; +#ifdef HUB + for (asptr = svrtop;asptr;asptr = asptr->nexts) + { + if (asptr->bcptr->from == acptr) + { + servers++; + users += asptr->usercnt[0]; +#ifdef SHOW_INVISIBLE_LUSERS + users += asptr->usercnt[1]; +#endif + } + } +#else /* !HUB */ + /* we can have only one server linked */ + servers = istat.is_serv - 1; + users = istat.is_user[0]; +#ifdef SHOW_INVISIBLE_LUSERS + users += istat.is_user[1]; + users -= istat.is_myclnt; +#else + users -= me.usercnt[0]; +#endif +#endif /* HUB */ + if (acptr->serv->user) - sendto_one(sptr, rpl_str(RPL_TRACESERVER, - parv[0]), class, link_s[i], - link_u[i], name, acptr->serv->by, - acptr->serv->user->username, - acptr->serv->user->host, - acptr->serv->version, - (acptr->flags & FLAGS_ZIP) ?"z":""); + { + sendto_one(sptr, rpl_str(RPL_TRACESERVER, + to), class, servers, users, name, + acptr->serv->by, acptr->serv->user->username, + acptr->serv->user->host, acptr->serv->version, + (acptr->flags & FLAGS_ZIP) ?"z":""); + } else + { sendto_one(sptr, rpl_str(RPL_TRACESERVER, - parv[0]), class, link_s[i], - link_u[i], name, - *(acptr->serv->by) ? - acptr->serv->by : "*", "*", ME, - acptr->serv->version, - (acptr->flags & FLAGS_ZIP) ?"z":""); break; + to), class, servers, users, name, + *(acptr->serv->by) ? acptr->serv->by : "*", "*", + ME, acptr->serv->version, + (acptr->flags & FLAGS_ZIP) ?"z":""); + } + break; + } case STAT_RECONNECT: - sendto_one(sptr, rpl_str(RPL_TRACERECONNECT, parv[0]), - class, name); + sendto_one(sptr, rpl_str(RPL_TRACERECONNECT, to), + class, name); break; + case STAT_SERVICE: - sendto_one(sptr, rpl_str(RPL_TRACESERVICE, parv[0]), - class, name, acptr->service->type, - acptr->service->wants); + sendto_one(sptr, rpl_str(RPL_TRACESERVICE, to), + class, name, acptr->service->type, + acptr->service->wants); break; + case STAT_LOG: - sendto_one(sptr, rpl_str(RPL_TRACELOG, parv[0]), - ME, acptr->port); + sendto_one(sptr, rpl_str(RPL_TRACELOG, to), + ME, acptr->port); break; + default: /* ...we actually shouldn't come here... --msa */ - sendto_one(sptr, rpl_str(RPL_TRACENEWTYPE, parv[0]), - name); - break; - } - } + sendto_one(sptr, rpl_str(RPL_TRACENEWTYPE, to), + name); + break; + } +} - /* - * Add these lines to summarize the above which can get rather long - * and messy when done remotely - Avalon - */ - if (IsPerson(sptr) && SendWallops(sptr)) - for (cltmp = FirstClass(); doall && cltmp; cltmp = NextClass(cltmp)) - if (Links(cltmp) > 0) - sendto_one(sptr, rpl_str(RPL_TRACECLASS, parv[0]), - Class(cltmp), Links(cltmp)); - sendto_one(sptr, rpl_str(RPL_TRACEEND, parv[0]), tname, version, +/* + * m_trace + * parv[0] = sender prefix + * parv[1] = traced nick/server/service + */ +int m_trace(cptr, sptr, parc, parv) +aClient *cptr, *sptr; +int parc; +char *parv[]; +{ + aClient *acptr; + int maskedserv = 0; + int i = 0; + + if (parc > 1) + { + /* wildcards now allowed only in server/service names */ + acptr = find_matching_client(parv[1],NULL); + if (!acptr) + { + sendto_one(sptr, err_str(ERR_NOSUCHSERVER, + parv[0]), parv[1]); + return 1; + } + if (IsServer(acptr)) + { + if (!match(acptr->name,parv[1])) + { + /* if we are tracing masked server, + * we have to send parv[1], not acptr->name + */ + maskedserv = 1; + } + } + } + else + { + acptr = &me; + } + if (!IsMe(acptr)) + { + if (!MyConnect(acptr) || IsServer(acptr)) + { +#ifdef RESTRICT_RESTRICTED + if (MyConnect(sptr) && IsRestricted(sptr)) + { + sendto_one(sptr,err_str(ERR_RESTRICTED,parv[0])); + return 5; + } +#endif + if (acptr->from == cptr) + { /* eek ?! */ + return 1; + } + /* passthru */ + sendto_one(sptr, rpl_str(RPL_TRACELINK, parv[0]), + version, debugmode, (maskedserv) ? parv[1] : acptr->name, acptr->from->name, + acptr->from->serv->version, + (acptr->from->flags & FLAGS_ZIP) ? "z" : "", + timeofday - acptr->from->firsttime, + (int)DBufLength(&acptr->from->sendQ), + (int)DBufLength(&sptr->from->sendQ)); + sendto_one(acptr,":%s TRACE :%s",sptr->name, (maskedserv) ? parv[1] : acptr->name); + return 5; + } + else + { + /* tracing something local */ + trace_one(parv[0],sptr,acptr); + } + } + else + { + /* well, report everything */ + aClient *a2cptr; + + for (i = 0; i <= highest_fd; i++) + { + if (!(a2cptr = local[i])) + { + continue; + } + if (IsMe(a2cptr)) + { + continue; + } + if (IsPerson(a2cptr) && !(a2cptr == sptr || IsAnOper(a2cptr) || + (IsAnOper(sptr) && MyConnect(sptr))) ) + { + continue; + } + if (IsUnknown(a2cptr) && !((IsAnOper(sptr) || MyClient(sptr)) + && SendWallops(sptr)) ) + { + continue; + } + trace_one(parv[0],sptr,a2cptr); + } + if (IsPerson(sptr) && SendWallops(sptr)) + { + aClass *cltmp; + for (cltmp = FirstClass(); cltmp; cltmp = NextClass(cltmp)) + { + if (Links(cltmp) > 0) + { + sendto_one(sptr, rpl_str(RPL_TRACECLASS, parv[0]), + Class(cltmp), Links(cltmp)); + } + } + } + } + sendto_one(sptr, rpl_str(RPL_TRACEEND, parv[0]), acptr->name, version, debugmode); return 2; - } +} /* ** m_motd @@ -2267,7 +2677,11 @@ struct tm *tm; #endif - if (check_link(cptr)) + if ( +#ifdef NO_OPER_TRYAGAIN + !IsOper(sptr) && +#endif + check_link(cptr)) { sendto_one(sptr, rpl_str(RPL_TRYAGAIN, parv[0]), "MOTD"); return 5; @@ -2387,6 +2801,293 @@ return 0; } #endif +#ifdef SERVER_MAP +static void dump_map(sptr,root,pbuf) +aClient *sptr; +aClient *root; +char *pbuf; +{ + Link *lp; + int cnt,i = 0; + int len; + int pad = 53; /* at which position we add stats */ + int users,max; + aClient *acptr; + + *pbuf= '\0'; + strcat(pbuf,root->name); + len = strlen(buf); + buf[len] = ' '; + if (len < pad ) + { + for (i = len+1 ; i < pad ; i++) + { + buf[i] = '-'; + } + } + if (IsMe(root)) + { + max = istat.is_m_myclnt; + } + else + { + max = root->serv->usermax; + } + users = root->serv->usercnt[0] + root->serv->usercnt[1]; + SPRINTF(buf + pad ," | %5d %4.1f %5d",users, 100 * (float) users / + (float) (istat.is_user[0] + istat.is_user[1]), + max); + + sendto_one(sptr,rpl_str(RPL_MAP,sptr->name),buf); + + i = 1; + if ((lp = root->serv->down)) + { + cnt = lp->flags; + if (cnt) + { + if (pbuf > buf + 3) + { + pbuf[-2] = ' '; + if (pbuf[-3] == '`') + { + pbuf[-3] = ' '; + } + } + } + } + + for (; lp; lp = lp->next) + { + *pbuf = ' '; + if (i < cnt) + { + *(pbuf + 1) = '|'; + } + else + { + *(pbuf + 1) = '`'; + } + + *(pbuf + 2) = '-'; + *(pbuf + 3) = ' '; + acptr = lp->value.cptr; + dump_map(sptr,acptr,pbuf+4); + i++; + } + +} +/* based on ircu's m_map and kreynet's format */ +int m_map(cptr, sptr, parc, parv) +aClient *cptr, *sptr; +int parc; +char *parv[]; +{ +sendto_one(sptr,rpl_str(RPL_MAPSTART,parv[0]),"Server name","Users % Max"); + dump_map(sptr,&me,buf,0); + sendto_one(sptr,rpl_str(RPL_MAPEND,parv[0])); + return 2; +} +#endif +#ifdef OPER_SET +static char *def_values[] = +{ + "OFF", + "ON", + NULL +}; +static char *caccept_values[] = +{ + "OFF", + "SPLIT", + "ON", + NULL +}; +static struct Set_Message set_msgtab[] = +{ + {"ACONNECT",&iconf.aconnect,def_values}, +#ifdef DELAY_ACCEPT + {"CACCEPT",&iconf.caccept,caccept_values}, +#endif + {NULL,NULL,NULL} +}; +static void set_action(option,value) +char *option; +int value; +{ + if (!mycmp(option,"ACONNECT")) + { + if (value == 1) + { + nextconnect = timeofday; + } + } +#ifdef DELAY_ACCEPT + else if (!mycmp(option,"CACCEPT")) + { + if (value == 2) + { + activate_delayed_listeners(); + } + } +#endif +} +int m_set(cptr, sptr, parc, parv) +aClient *cptr, *sptr; +int parc; +char *parv[]; +{ + + struct Set_Message *mptr; + int val,i = 0; + char *endptr; + char **valstr; + char obuf[BUFSIZE]; + + obuf[0] = 0; + + /* query for values */ + if (parc < 2) + { + for (mptr = set_msgtab; mptr->cmd; mptr++) + { + sendto_one(sptr,":%s NOTICE %s :Value of %s is %s",ME,parv[0], + mptr->cmd, mptr->values[*(mptr->value)]); + } + + return 1; + } + + /* query for one value */ + if (parc == 2) + { + for (mptr = set_msgtab; mptr->cmd; mptr++) + { + if (mycmp(parv[1],mptr->cmd)) + { + continue; + } + + sendto_one(sptr,":%s NOTICE %s :Value of %s is %s",ME,parv[0], + mptr->cmd, mptr->values[*(mptr->value)]); + return 1; + } + sendto_one(sptr,":%s NOTICE %s :Unknown option %s",ME,parv[0],parv[1]); + + return 1; + } + /* setting value */ + for (mptr = set_msgtab; mptr->cmd; mptr++) + { + if (!mycmp(parv[1],mptr->cmd)) + { + break; + } + } + if (!mptr->cmd) + { + sendto_one(sptr,":%s NOTICE %s :Unknown option %s",ME,parv[0],parv[1]); + return 1; + } + val = strtol(parv[2],&endptr,10); + + if (endptr != parv[2]) + { + /* ha! a number! */ + if (mptr->values) + { /* value has symbolical names */ + i = 0; + for (valstr = mptr->values; *valstr; valstr++) + { + if (i == val) + { + break; + } + strcat(obuf,*valstr); + strcat(obuf," "); + i++; + } + if (!*valstr) + { + sendto_one(sptr,":%s NOTICE %s :Uknown value %d for option %d, avaible values are %s", + ME,parv[0],val,mptr->cmd,obuf); + return 1; + + } + if (*(mptr->value) == i) + { + sendto_one(sptr,":%s NOTICE %s :Value of %s was already set to %s", + ME,parv[0],mptr->cmd,*valstr); + return 1; + + } + + *(mptr->value) = val; + sendto_one(sptr,":%s NOTICE %s :Value of %s set to %s", + ME,parv[0],mptr->cmd,*valstr); + sendto_flag(SCH_NOTICE,"%s changed value of %s to %s", + parv[0],mptr->cmd,*valstr); + set_action(mptr->cmd,val); + return 1; + } + else + { /* numeric only */ + if (*(mptr->value) == val) + { + sendto_one(sptr, ":%s NOTICE %s :Value of %s was already set to %d", + ME,parv[0],mptr->cmd,val); + + return 1; + } + *(mptr->value) = val; + sendto_one(sptr, ":%s NOTICE %s :Value of %s set to %d", + ME,parv[0],mptr->cmd,val); + sendto_flag(SCH_NOTICE,"%s changed value of %s to %d", + parv[0],mptr->cmd,val); + + set_action(mptr->cmd,val); + return 1; + } + } + else + { + i = 0; + for (valstr = mptr->values; *valstr; valstr++) + { + if (!mycmp(parv[2],*valstr)) + { /* found value */ + break; + } + i++; + strcat(obuf,*valstr); + strcat(obuf," "); + } + if (!*valstr) + { + sendto_one(sptr,":%s NOTICE %s :Unknown value for %s, avaible options are %s", + ME,parv[0],mptr->cmd,obuf); + return 1; + } + if (*(mptr->value) == i) + { + sendto_one(sptr, ":%s NOTICE %s :Value of %s was already set to %d", + ME,parv[0],mptr->cmd,val); + return 1; + } + + *(mptr->value) = i; + sendto_one(sptr, ":%s NOTICE %s :Value of %s set to %s", + ME,parv[0],mptr->cmd,*valstr); + sendto_flag(SCH_NOTICE,"%s changed value of %s to %s", + parv[0],mptr->cmd,*valstr); + + set_action(mptr->cmd,i); + return 1; + + } + +} +#endif /* ** storing server names in User structures is a real waste, @@ -2496,18 +3197,3 @@ return -1; } -static void report_listeners(aClient *sptr, char *to) -{ - aConfItem *tmp; - - for (tmp = conf; tmp; tmp = tmp->next) - { - if ((tmp->status & CONF_LISTEN_PORT)) - { - sendto_one(sptr, ":%s %d %s :%s %d %d", ME, - RPL_STATSDEFINE, to, BadPtr(tmp->host) ? - "*" : tmp->host, tmp->port, - tmp->clients); - } - } -} diff -ru --exclude=CVS irc2.10.3p6/ircd/s_serv_ext.h irc2.10.3p6+hemp/ircd/s_serv_ext.h --- irc2.10.3p6/ircd/s_serv_ext.h Wed Sep 3 19:46:04 1997 +++ irc2.10.3p6+hemp/ircd/s_serv_ext.h Sat Feb 28 00:27:32 2004 @@ -69,4 +69,10 @@ #if defined(OPER_DIE) || defined(LOCOP_DIE) EXTERN int m_die __P((aClient *cptr, aClient *sptr, int parc, char *parv[])); #endif /* OPER_DIE || LOCOP_DIE */ +#ifdef SERVER_MAP +EXTERN int m_map __P((aClient *cptr, aClient *sptr, int parc, char *parv[])); +#endif +#ifdef OPER_SET +EXTERN int m_set __P((aClient *cptr, aClient *sptr, int parc, char *parv[])); +#endif #undef EXTERN diff -ru --exclude=CVS irc2.10.3p6/ircd/s_service.c irc2.10.3p6+hemp/ircd/s_service.c --- irc2.10.3p6/ircd/s_service.c Mon May 14 06:12:32 2001 +++ irc2.10.3p6+hemp/ircd/s_service.c Sat Feb 28 00:27:32 2004 @@ -440,10 +440,26 @@ get_client_name(sptr, TRUE)); istat.is_unknown--; istat.is_myservice++; +#ifdef EXTRA_STATISTICS + /* + ** Keep track of maximum number of simultanious + ** services to this server. + */ + if (istat.is_myservice > istat.is_m_myservice) + istat.is_m_myservice = istat.is_myservice; +#endif } #endif istat.is_service++; +#ifdef EXTRA_STATISTICS + /* + ** Keep track of maximum number of services + ** simultaniously connected to this network. + */ + if (istat.is_service > istat.is_m_service) + istat.is_m_service = istat.is_service; +#endif svc = make_service(sptr); SetService(sptr); svc->servp = sp; diff -ru --exclude=CVS irc2.10.3p6/ircd/s_user.c irc2.10.3p6+hemp/ircd/s_user.c --- irc2.10.3p6/ircd/s_user.c Thu Feb 26 19:00:59 2004 +++ irc2.10.3p6+hemp/ircd/s_user.c Sat Feb 28 00:27:32 2004 @@ -324,6 +324,12 @@ (IsUnixSocket(cptr)) ? me.sockhost : ((cptr->hostp) ? cptr->hostp->h_name : cptr->sockhost)); #endif +#ifdef DELAY_CLOSE + if (cptr->user) + { + cptr->user->flags |= FLAGS_BADBOY; + } +#endif return exit_client(cptr, cptr, &me, longm); } @@ -363,6 +369,9 @@ #ifndef NO_PREFIX char prefix; #endif +#ifdef RESTRICT_USERNAMES + char *hptr; +#endif int i; user->last = timeofday; @@ -372,7 +381,6 @@ if (MyConnect(sptr)) { char *reason = NULL; - #if defined(USE_IAUTH) static time_t last = 0; static u_int count = 0; @@ -484,12 +492,49 @@ if (sptr->exitc == EXITC_AREF || sptr->exitc == EXITC_AREFQ) { + char *showres = NULL; + if (sptr->reason) + { + showres = strchr(sptr->reason,' '); + if (showres) + { + *showres = '\0'; + } + } if (sptr->exitc == EXITC_AREF) - sendto_flag(SCH_LOCAL, - "Denied connection from %s.", + { + if (showres) + { + sendto_flag(SCH_LOCAL, + "Denied connection from %s. (%s)", + get_client_host(sptr),sptr->reason); + *showres = ' '; + } + else + sendto_flag(SCH_LOCAL, + "Denied connection from %s. ", get_client_host(sptr)); - return ereject_user(cptr, " Denied ","Denied access"); + + } + if (showres && !*(showres+1)) + { + showres = NULL; + } + return ereject_user(cptr, " Denied ",showres ? showres+1 : "Denied access"); } +#ifdef DELAY_ACCEPT + /* well, this is not exactly the correct place for this + * check, but oh well.. -jv */ + { + aConfItem *bconf; + bconf = sptr->acpt->confs->value.aconf; + if (bconf->status & CONF_SERVERONLY) + { + sendto_flag(SCH_LOCAL,"User connection to server-only port from %s",get_client_host(sptr)); + return ereject_user(cptr, " serveronly ", "This port is avaible for servers only."); + } + } +#endif if ((i = check_client(sptr))) { struct msg_set { char *shortm; char *longm; }; @@ -514,7 +559,6 @@ return ereject_user(cptr, exit_msg[i].shortm, exit_msg[i].longm); } - #ifndef NO_PREFIX if (IsRestricted(sptr)) { @@ -546,10 +590,32 @@ return exit_client(cptr, sptr, &me, "Bad Password"); } bzero(sptr->passwd, sizeof(sptr->passwd)); +#ifdef RESTRICT_USERNAMES + /* + * Do not allow special characters in the username. + */ + hptr = user->username; + if (prefix) + hptr++; + while (*hptr && isvaliduser(*hptr)) + hptr++; + if (*hptr) { + ircstp->is_ref++; + sendto_flag(SCH_LOCAL, "Invalid username: %s@%s.", + sptr->user->username, sptr->sockhost); + return exit_client(cptr, sptr, &me, + "Invalid username"); + } +#endif /* * following block for the benefit of time-dependent K:-lines */ +#ifdef ILINE_FLAGS + if (!IsKlineExempt(sptr) && find_kill(sptr, 1, &reason)) + +#else if (find_kill(sptr, 1, &reason)) +#endif { /*char buf[100];*/ @@ -582,6 +648,21 @@ return exit_client(cptr, sptr, &me , "R-lined"); } #endif + +#ifdef CLIENTS_CHANNEL + sendto_flag(SCH_CLIENTS,"Client connecting: %s is %s from %s [%s] named %s", + nick,user->username,user->host, +#ifdef INET6 + inetntop(AF_INET6, + (char *)&sptr->ip, + mydummy, MYDUMMY_SIZE), +#else + inetntoa((char *)&sptr->ip), +#endif + + sptr->info); +#endif + if (oldstatus == STAT_MASTER && MyConnect(sptr)) (void)m_oper(&me, sptr, 1, parv); /* *user->tok = '1'; @@ -629,13 +710,70 @@ (*buf) ? buf : "+", sptr->info); } /* for(my-leaf-servers) */ if (IsInvisible(sptr)) /* Can be initialized in m_user() */ + { istat.is_user[1]++; /* Local and server defaults +i */ + user->servp->usercnt[1]++; + } else + { istat.is_user[0]++; + user->servp->usercnt[0]++; + + } + if (istat.is_user[1] + istat.is_user[0] >= SPLIT_USERS) + { + check_split(); + } +#ifdef EXTRA_STATISTICS + /* + ** Keep track of maximum number of global users. + */ + if ((istat.is_user[1] + istat.is_user[0]) > istat.is_m_users) { + istat.is_m_users = istat.is_user[1] + istat.is_user[0]; + if ((istat.is_m_users % 1000) == 0) + sendto_flag(SCH_NOTICE, + "New highest global client connection: %d", + istat.is_m_users); + } + if (user->servp->usercnt[0] + user->servp->usercnt[1] > user->servp->usermax) + { + user->servp->usermax = user->servp->usercnt[0] + user->servp->usercnt[1]; + } +#endif if (MyConnect(sptr)) { istat.is_unknown--; istat.is_myclnt++; +#ifdef EXTRA_STATISTICS + /* + ** Inform of highest client connection. + */ + if (istat.is_myclnt > istat.is_m_myclnt) { + istat.is_m_myclnt = istat.is_myclnt; + if ((istat.is_m_myclnt % 10) == 0) + sendto_flag(SCH_NOTICE, + "New highest local client connection: %d", + istat.is_m_myclnt); + } + /* + ** Small cludge to try and warn of some fast clonebots. + */ + if ((istat.is_myclnt % 10) == 0) { + if (istat.is_myclnt > istat.is_last_cnt) { + if (istat.is_last_cnt_t == 0) + istat.is_last_cnt_t = me.since; + + sendto_flag(SCH_NOTICE, + "Local increase from %d to %d clients in %d second%s", + (istat.is_myclnt - 10),istat.is_myclnt, + (timeofday - istat.is_last_cnt_t), + ((timeofday - istat.is_last_cnt_t == 1) ? "" + : "s")); + } + istat.is_last_cnt_t = timeofday; + istat.is_last_cnt = istat.is_myclnt; + } +#endif sprintf(buf, "%s!%s@%s", nick, user->username, user->host); sptr->exitc = EXITC_REG; sendto_one(sptr, rpl_str(RPL_WELCOME, nick), buf); @@ -645,13 +783,30 @@ sendto_one(sptr, rpl_str(RPL_CREATED, nick), creation); sendto_one(sptr, rpl_str(RPL_MYINFO, parv[0]), ME, version); +#ifdef SEND_ISUPPORT + sendto_one(sptr, rpl_str(RPL_ISUPPORT, parv[0]), + isupport); +#endif (void)m_lusers(sptr, sptr, 1, parv); (void)m_motd(sptr, sptr, 1, parv); if (IsRestricted(sptr)) sendto_one(sptr, err_str(ERR_RESTRICTED, nick)); send_umode(sptr, sptr, 0, ALL_UMODES, buf); +#ifdef SPLIT_HANDLE + if (iconf.split) + { + sendto_one(sptr,":%s NOTICE %s :Server is currently in split-mode. You will NOT get channel operator status on new channels.",ME,nick); + } +#endif +#ifdef DELAY_ACCEPT + if (iconf.caccept < 2) + { + sendto_one(sptr,":%s NOTICE %s :Server is currently in delay-accept mode. Users can't connect.",ME,nick); + } +#endif nextping = timeofday; } + #ifdef USE_SERVICES #if 0 check_services_butone(SERVICE_WANT_NICK, user->server, NULL, @@ -668,6 +823,7 @@ send_umode(NULL, sptr, 0, ALL_UMODES, buf); check_services_num(sptr, buf); #endif + add_to_hostname_hash_table(user->host,user); return 1; } @@ -1050,6 +1206,13 @@ ** on that channel. Propagate notice to other servers. */ sendto_common_channels(sptr, ":%s NICK :%s", parv[0], nick); +#ifdef CLIENTS_CHANNEL + if (MyConnect(sptr) && IsRegisteredUser(sptr)) { + sendto_flag(SCH_CLIENTS,"Nick change %s to %s for %s from %s", + parv[0],nick,sptr->user->username,sptr->user->host); + } +#endif + if (sptr->user) /* should always be true.. */ { add_history(sptr, sptr); @@ -1403,7 +1566,7 @@ who_one(sptr, lp->value.cptr, chptr, lp); } } - else if (lp = find_user_link(chptr->members, sptr)) + else if ((lp = find_user_link(chptr->members, sptr))) who_one(sptr, lp->value.cptr, chptr, lp); } @@ -1411,73 +1574,92 @@ ** who_find ** lists all (matching) users. ** CPU intensive, but what can be done? +** +** Reduced CPU load - 05/2001 */ static void who_find(sptr, mask, oper) aClient *sptr; char *mask; int oper; { - aChannel *chptr, *ch2ptr; - Link *lp; - int member; - int showperson, isinvis; - aClient *acptr; - + Reg Link *lp,*lp2; + int myoper = 0; + Reg aClient *acptr; + aChannel *chptr = NULL; + if (MyConnect(sptr) && IsAnOper(sptr)) + { + myoper = 1; + } + + /* first, show INvisible matching users on common channels */ + for (lp = sptr->user->channel; lp ;lp = lp->next) + { + chptr = lp->value.chptr; + if (IsAnonymous(chptr)) + continue; + for (lp2 = chptr->members; lp2 ;lp2 = lp2->next) + { + acptr = lp2->value.cptr; + + if (!IsInvisible(acptr) || (acptr->flags & FLAGS_HIDDEN)) + { + continue; + } + + if (oper && !IsAnOper(acptr)) + { + continue; + } + + acptr->flags |= FLAGS_HIDDEN; + if (!mask || + match(mask, acptr->name) == 0 || + match(mask, acptr->user->username) == 0 || + match(mask, acptr->user->host) == 0 || + match(mask, acptr->user->server) == 0 || + match(mask, acptr->info) == 0) + who_one(sptr, acptr, chptr, NULL); + + } + } + + /* second, show all matching visible clients */ for (acptr = client; acptr; acptr = acptr->next) { - ch2ptr = NULL; if (!IsPerson(acptr)) continue; + + /* clear the flag */ + if (acptr->flags & FLAGS_HIDDEN) + { + acptr->flags &= ~FLAGS_HIDDEN; + continue; + } + + /* allow local opers to see matching clients on _LOCAL_ server */ + if (IsInvisible(acptr) && !(MyConnect(acptr) && myoper)) + { + continue; + } + /* we wanted only opers */ if (oper && !IsAnOper(acptr)) + { continue; - showperson = 0; - /* - * Show user if they are on the same channel, or not - * invisible and on a non secret channel (if any). - * Do this before brute force match on all relevant - * fields since these are less cpu intensive (I - * hope :-) and should provide better/more shortcuts - * -avalon - */ - isinvis = IsInvisible(acptr); - for (lp = acptr->user->channel; lp; lp = lp->next) - { - chptr = lp->value.chptr; - if (IsAnonymous(chptr)) - continue; - member = IsMember(sptr, chptr); - if (isinvis && !member) - continue; - if (member || (!isinvis && PubChannel(chptr))) - { - showperson = 1; - if (!IsAnonymous(chptr) || - acptr != sptr) - { - ch2ptr = chptr; - break; - } - } - if (HiddenChannel(chptr) && - !SecretChannel(chptr) && !isinvis) - showperson = 1; - } - if (!acptr->user->channel && !isinvis) - showperson = 1; + } + /* - ** This is brute force solution, not efficient...? ;( + ** This is brute force solution, not efficient...? ;( ** Show entry, if no mask or any of the fields match ** the mask. --msa */ - if (showperson && - (!mask || + if (!mask || match(mask, acptr->name) == 0 || match(mask, acptr->user->username) == 0 || match(mask, acptr->user->host) == 0 || match(mask, acptr->user->server) == 0 || - match(mask, acptr->info) == 0)) - who_one(sptr, acptr, ch2ptr, NULL); + match(mask, acptr->info) == 0) + who_one(sptr, acptr, NULL, NULL); } } @@ -1511,7 +1693,7 @@ for (p = NULL, mask = strtoken(&p, parv[1], ","); mask && penalty <= MAXPENALTY; mask = strtoken(&p, NULL, ",")) - { + { channame = NULL; penalty += 1; @@ -1523,12 +1705,11 @@ /* I think it's useless --Beeth */ clean_channelname(mask); #endif - /* simplify mask */ (void)collapse(mask); /* - ** We can never have here !mask + ** We can never have here !mask ** or *mask == '\0', since it would be equal ** to parc == 1, that is 'WHO' and/or would not ** pass through above for loop. @@ -1603,6 +1784,7 @@ ** All nice chances lost above. ** We must hog our server with that. */ + who_find(sptr, mask, oper); penalty += MAXPENALTY; } @@ -1695,7 +1877,11 @@ if (acptr->user && MyConnect(acptr)) sendto_one(sptr, rpl_str(RPL_WHOISIDLE, sptr->name), +#ifdef WHOIS_SIGNON_TIME + name, timeofday - user->last,acptr->firsttime); +#else name, timeofday - user->last); +#endif } /* @@ -2336,10 +2522,35 @@ cptr->flags &= ~FLAGS_PINGSENT; sptr->flags &= ~FLAGS_PINGSENT; - if (!BadPtr(destination) && mycmp(destination, ME) != 0) +#ifdef SPLIT_HANDLE + if (IsServer(cptr) && IsServer(sptr) && (BadPtr(destination) || !match(destination,ME))) + { + if (IsBurst(sptr)) + { + ClearBurst(sptr); + istat.is_eobservers++; + if (MyConnect(sptr)) + { + sendto_flag(SCH_NOTICE,"End of burst from %s. Lasted %d seconds.", + cptr->name,timeofday - cptr->firsttime); + } + else + { + sendto_flag(SCH_DEBUG,"EOB from %s (PONG)",sptr->name); + } + bubble_eob(sptr); + if (iconf.split) + { + check_split(); + } + } + } +#endif + if (!BadPtr(destination) && match(destination, ME) != 0) { if ((acptr = find_client(destination, NULL)) || - (acptr = find_server(destination, NULL))) { + (acptr = find_server(destination, NULL))) + { if (!(MyClient(sptr) && mycmp(origin, sptr->name))) sendto_one(acptr,":%s PONG %s %s", parv[0], origin, destination); @@ -2508,12 +2719,60 @@ parv[0], IsOper(sptr) ? 'o' : 'O'); #endif if (IsAnOper(sptr)) + { istat.is_oper++; + sptr->user->servp->usercnt[2]++; + } } else { (void)detach_conf(sptr, aconf); sendto_one(sptr,err_str(ERR_PASSWDMISMATCH, parv[0])); +#ifdef FAILED_OPERLOG + sendto_flag(SCH_NOTICE, "FAILED OPER %s attempt by %s!%s@%s", + name, parv[0], sptr->user->username, sptr->user->host); +# if defined(USE_SYSLOG) && defined(SYSLOG_OPER) + syslog(LOG_INFO, "FAILED OPER %s attempt by %s!%s@%s [%s@%s]", + name, parv[0], sptr->user->username, sptr->user->host, + sptr->auth, IsUnixSocket(sptr) ? sptr->sockhost : +#ifdef INET6 + inet_ntop(AF_INET6, (char *)&sptr->ip, mydummy, MYDUMMY_SIZE)); +#else + + inetntoa((char *)&sptr->ip)); +#endif +# endif +# ifdef FNAME_OPERLOG + { + int logfile; + + (void)alarm(3); + if (IsPerson(sptr) && + (logfile = open(FNAME_OPERLOG, O_WRONLY|O_APPEND)) != -1) + { + (void)alarm(0); + SPRINTF(buf, "%s FAILED OPER %s attempt by %s!%s@%s [%s@%s]\n", + myctime(timeofday), name, parv[0], sptr->user->username, + sptr->user->host, sptr->auth, IsUnixSocket(sptr) ? + sptr->sockhost : +#ifdef INET6 + inetntop(AF_INET6, (char *)&sptr->ip, mydummy, + MYDUMMY_SIZE) + +#else + inetntoa((char *)&sptr->ip) +#endif + ); + (void)alarm(3); + (void)write(logfile, buf, strlen(buf)); + (void)alarm(0); + (void)close(logfile); + } + (void)alarm(0); + } +# endif +#endif + } return 3; } @@ -2834,11 +3093,15 @@ { istat.is_user[1]--; istat.is_user[0]++; + sptr->user->servp->usercnt[1]--; + sptr->user->servp->usercnt[0]++; } if (IsInvisible(sptr) && !(setflags & FLAGS_INVISIBLE)) { istat.is_user[1]++; istat.is_user[0]--; + sptr->user->servp->usercnt[1]++; + sptr->user->servp->usercnt[0]--; } send_umode_out(cptr, sptr, setflags); } @@ -2847,6 +3110,7 @@ if (IsOper(sptr) && !(setflags & FLAGS_OPER)) { istat.is_oper++; + sptr->user->servp->usercnt[2]++; #ifdef USE_SERVICES check_services_butone(SERVICE_WANT_OPER, sptr->user->server, sptr, ":%s MODE %s :+o", parv[0], @@ -2856,6 +3120,7 @@ else if (!IsOper(sptr) && (setflags & FLAGS_OPER)) { istat.is_oper--; + sptr->user->servp->usercnt[2]--; #ifdef USE_SERVICES check_services_butone(SERVICE_WANT_OPER, sptr->user->server, sptr, ":%s MODE %s :-o", parv[0], @@ -2865,6 +3130,7 @@ else if (MyConnect(sptr) && !IsLocOp(sptr) && (setflags & FLAGS_LOCOP)) { istat.is_oper--; + sptr->user->servp->usercnt[2]--; #ifdef USE_SERVICES check_services_butone(SERVICE_WANT_OPER, sptr->user->server, sptr, ":%s MODE %s :-O", parv[0], diff -ru --exclude=CVS irc2.10.3p6/ircd/version.c.SH.in irc2.10.3p6+hemp/ircd/version.c.SH.in --- irc2.10.3p6/ircd/version.c.SH.in Thu Jul 22 00:59:54 1999 +++ irc2.10.3p6+hemp/ircd/version.c.SH.in Sat Feb 28 00:27:32 2004 @@ -63,6 +63,7 @@ char *generation = "$generation"; char *creation = "$creation"; char *version; /* Filled by make_version() */ +char *isupport; /* Filled by make_isupport() */ char *pass_version = PATCHLEVEL; char *infotext[] = @@ -108,6 +109,9 @@ "", "[$sumsserv] [$sumchan] [$sumsbsd] [$sumsuser]", "[$sumhash] [$sumsmisc] [$sumircd]", + "", + "This server has been patched by hemp2 patch, revision 2003121203.", + "See http://jv.irc.cz/irc/ for more information about this patch.", 0, }; !SUB!THIS! diff -ru --exclude=CVS irc2.10.3p6/ircd/version_ext.h irc2.10.3p6+hemp/ircd/version_ext.h --- irc2.10.3p6/ircd/version_ext.h Wed Sep 3 19:46:08 1997 +++ irc2.10.3p6+hemp/ircd/version_ext.h Sat Feb 28 00:27:32 2004 @@ -27,6 +27,7 @@ extern char *generation; extern char *creation; extern char *version; +extern char *isupport; extern char *pass_version; extern char *infotext[]; #endif /* VERSION_C */ diff -ru --exclude=CVS irc2.10.3p6/support/Makefile.in irc2.10.3p6+hemp/support/Makefile.in --- irc2.10.3p6/support/Makefile.in Fri Feb 9 14:47:07 2001 +++ irc2.10.3p6+hemp/support/Makefile.in Sat Feb 28 00:27:32 2004 @@ -104,6 +104,8 @@ IRCDPID_PATH = $(ircd_var_dir)/ircd.pid # server state file IRCDTUNE_PATH = $(ircd_var_dir)/ircd.tune +# iauth PID file +IAUTHPID_PATH = $(ircd_var_dir)/iauth.pid # ircdwatch PID file IRCDWATCHPID_PATH = $(ircd_var_dir)/ircdwatch.pid @@ -157,7 +159,7 @@ IAUTH_COMMON_OBJS = clsupport.o clmatch.o # This is a little evil IAUTH_OBJS = iauth.o a_conf.o a_io.o a_log.o \ - mod_lhex.o mod_pipe.o mod_rfc931.o mod_socks.o + mod_lhex.o mod_pipe.o mod_rfc931.o mod_socks.o mod_webproxy.o IAUTH = iauth CHKCONF_COMMON_OBJS = match.o @@ -408,7 +410,8 @@ $(CC) $(S_CFLAGS) -c -o $@ ../ircd/s_id.c s_misc.o: ../ircd/s_misc.c setup.h config.h - $(CC) $(S_CFLAGS) -DFNAME_USERLOG="\"$(FNAME_USERLOG)\"" -DFNAME_CONNLOG="\"$(FNAME_CONNLOG)\"" -c -o $@ ../ircd/s_misc.c + $(CC) $(S_CFLAGS) -DFNAME_USERLOG="\"$(FNAME_USERLOG)\"" \ + -DIRCDCONF_PATH="\"$(IRCDCONF_PATH)\"" -DFNAME_CONNLOG="\"$(FNAME_CONNLOG)\"" -c -o $@ ../ircd/s_misc.c s_numeric.o: ../ircd/s_numeric.c setup.h config.h $(CC) $(S_CFLAGS) -c -o $@ ../ircd/s_numeric.c @@ -438,7 +441,7 @@ $(CC) $(S_CFLAGS) -c -o $@ ../ircd/res_mkquery.c iauth.o: ../iauth/iauth.c config.h setup.h - $(CC) $(A_CFLAGS) -c -o $@ ../iauth/iauth.c + $(CC) $(A_CFLAGS) -DIAUTHPID_PATH="\"$(IAUTHPID_PATH)\"" -c -o $@ ../iauth/iauth.c a_conf.o: ../iauth/a_conf.c config.h setup.h $(CC) $(A_CFLAGS) -DIAUTHCONF_PATH="\"$(IAUTHCONF_PATH)\"" -c -o $@ ../iauth/a_conf.c @@ -463,6 +466,9 @@ mod_socks.o: ../iauth/mod_socks.c config.h setup.h $(CC) $(A_CFLAGS) -c -o $@ ../iauth/mod_socks.c + +mod_webproxy.o: ../iauth/mod_webproxy.c config.h setup.h + $(CC) $(A_CFLAGS) -c -o $@ ../iauth/mod_webproxy.c -Wall chkconf.o: ../ircd/chkconf.c setup.h config.h $(CC) $(CC_CFLAGS) -DCHKCONF_COMPILE -DIRCDCONF_PATH="\"$(IRCDCONF_PATH)\"" -DIRCDM4_PATH="\"$(IRCDM4_PATH)\"" -c -o $@ ../ircd/chkconf.c Only in irc2.10.3p6+hemp/support: Makefile.in.orig diff -ru --exclude=CVS irc2.10.3p6/support/config.h.dist irc2.10.3p6+hemp/support/config.h.dist --- irc2.10.3p6/support/config.h.dist Sat Oct 11 15:25:14 2003 +++ irc2.10.3p6+hemp/support/config.h.dist Sat Feb 28 00:27:32 2004 @@ -138,7 +138,7 @@ * This should be at *least* 4: 2 listen ports (1 tcp, 1 udp) * 1 dns port, 1 client */ -#define MAXCONNECTIONS 50 +#define MAXCONNECTIONS 1024 /* MAXIMUM LINKS * @@ -323,7 +323,7 @@ * send to the server without processing before disconnecting the client for * flooding it. Values greater than 8000 make no difference to the server. */ -#define CLIENT_FLOOD 1000 +#define CLIENT_FLOOD 8000 /* Remote query flood protection. */ #define CHREPLLEN 8192 @@ -339,6 +339,7 @@ */ #undef USE_SERVICES + /* * Define the following to make the delay for nicks random. * Some people believe a bot can exactly time the delay and don't like it, @@ -389,6 +390,175 @@ */ #define SIXBONE_HACK +/* + * Disclaimer: The following part concerns the Cr-patches. By defining this + * you will end up with "no warranty" whatsoever - use at your + * own risk. + * The Cr patch does not compromize the anonymity and does + * not affect users integrity in any way. The new features will + * only provide extra functionality and statistics for local + * IRC operators. + */ +#define RESTRICT_USERNAMES + +/* + * Define this if you want to allow online K-lining (permanent) for + * regular and local operators. + */ +#undef OPER_KLINE +#undef LOCOP_KLINE + +/* + * Define this if you want to allow online K-lining to memory only + * which is removed after rehashing the configuration file or by + * restarting the server. + */ +#undef OPER_TKLINE +#undef LOCOP_TKLINE + +/* + * Define this if you want (t)kline requests to go to syslog + * Note that you must also have USE_SYSLOG defined otherwise + * it won't work + * this is a part of patch f2 by fantomas + */ +#define SYSLOG_KLINE + +/* + * This will give some extra statistics, such as highest usercount, + * connection duration and local client incrementation. + * + * Note: will also show local/global max in /lusers - jv + */ +#define EXTRA_STATISTICS + +/* CrXXe8 related stuff follows. It makes the TKLINE/KLINE servernotice + * show the k-linereason too and does two cosmetical corrections to the + * "Local increase..." and the RPL_YOUREOPER servernotices. Also it + * doesn't suppress iauth statistics for opers using stats t. + * + * Define this to show and log failed /oper attempts too! + * Define LOG_IP for logging [ident@remoteip#remoteport,localip#localport]. + */ + +#undef FAILED_OPERLOG +#undef LOG_IP + +/* Fl4 related stuff follows - so far, the only stuff retained from Fl3c + * for Fl4 is the &clients channel ; this is because the TKLINE/KLINE code + * from Fl3c is also present in the Cr15 code. + */ + +/* define this to enable an extra local channel '&clients', which only + * IRC operators may join. Notification of nick-changes, connects, exits, + * and requests for server statistics will be sent to this channel. + * Some people regard this as a breach of privacy, hence (unlike Fl3c) + * it is turned off by default. + * f2 - easy clients merged - jv + */ +#undef CLIENTS_CHANNEL + + + +/* + * Define this to see when a channel topic was set and who it was set by. + */ +#define TOPICWHOTIME + +/* + * Define this if you want msgs normally sent to &local moved to ¬ices + * - EXCEPT unauth/rejection/too many connection notices. The reasoning + * behind this is if you want to see local information except the annoying + * and resource wasting unauths and rejections.. + */ +#define LOCAL_REJECTIONS_ONLY + + +/* +jv patch defines follows */ + +/* New stats - F show FDs and remote&local ports (local oper only) + */ +#define STATS_F + +/* show signon time of local clients in whois */ +#define WHOIS_SIGNON_TIME + +/* no RPL_TRYAGAIN for opers - i think it's right and doesn't add + * privileges for opers, just allows them to administrate net better. + */ +#define NO_OPER_TRYAGAIN +/* If you want to notify users that doing /LIST is bad and they should + use ALIS instead, define this. Notice is sent BEFORE any output. + */ + +// #define LIST_ALIS_NOTE "Usage of /list for listing all channels is deprecated. Please use \"/squery alis help\" instead." + +/* If you want to send server IS_SUPPORT upon connect and along with + VERSION reply. Also moves redirect numerics from 5 to 10. + also define Networkname. + */ +#define SEND_ISUPPORT +#define NETWORKNAME "IRCnet" + +/* support for /MAP a'la ircu. */ +#define SERVER_MAP + +/* quick info about connected servers */ +#define STATS_QMARK + +/* define if you want to set some values - delay accept mode, disable/enable autoconnects */ +#define OPER_SET + +/* wait with closing sockets of rejected clients, in seconds */ +#define DELAY_CLOSE +#define DELAYCLOSETIME 10 + +/* Split handling - replaces QPI + * works as follows: + * PINGs all servers behind the link and waits for PONG. + * Note: Currently does not compile when undefined. To disable split + * protection set following values to 0. + */ +#define SPLIT_HANDLE + +/* defines minimum for GLOBAL channels */ +#define SPLIT_SERV 10 +#define SPLIT_USERS 15000 + +/* Delay binding to listening ports with 'D' in second field until server + * is out of split. + * Requires SPLIT_HANDLE defined + */ +#define DELAY_ACCEPT + +/* I-line flags. Allows to specify aditional flags at the beginning of + * name field. + * current meaning: + * < exempted from k-lines + * + restrict client if no reverse dns found. + */ +#define ILINE_FLAGS + +/* + * Undefining this enables old portions of code, which are more precise + * in local u@h limit checking by comparing user's ip against all other + * users on server. Usable only for case when client creates another + * connection from same ip, but with changed hostname. + * This check won't be needed on pure 2.11 network. + * Note: He can connect to other server without any problem. + * + */ +#define NO_EXTENSIVE_LOCAL_LIMIT_CHECK + +/* define file which is used for saving k-lines added by /kline + */ +#define KLINE_FILE IRCDCONF_PATH + +/* undef if you don't want to have Denied connection because of open proxy */ +#define IAUTH_VERBOSE_REJECTS + +/* end of +jv patch */ + /* STOP STOP STOP STOP STOP STOP STOP STOP STOP STOP STOP STOP STOP STOP */ /* STOP STOP STOP STOP STOP STOP STOP STOP STOP STOP STOP STOP STOP STOP */ /* STOP STOP STOP STOP STOP STOP STOP STOP STOP STOP STOP STOP STOP STOP */ @@ -403,18 +573,20 @@ * server the Operator is connected to (ie lets them deal with local * problem users or 'ghost' clients */ -#define LOCAL_KILL_ONLY +#undef LOCAL_KILL_ONLY #endif /* Default server port, used by client. */ #define PORTNUM 6667 /* Maximum length the queue of pending connections to one port may grow to. */ -#define LISTENQUEUE 128 +#define LISTENQUEUE 512 /* define DEBUGMODE to enable debugging mode.*/ #undef DEBUGMODE +/* log ircname to logfile */ +#define LOG_IRCNAME /* * Time interval to wait and if no messages have been received, then check for * PINGFREQUENCY and CONNECTFREQUENCY @@ -484,7 +656,7 @@ /* * Max number of channels a user is allowed to join. */ -#define MAXCHANNELSPERUSER 10 /* Recommended value: 10 */ +#define MAXCHANNELSPERUSER 20 /* Recommended value: 10 */ /* * USE_IAUTH makes ircd use the iauth program for authentication. @@ -519,6 +691,7 @@ /* #undef NO_IDENT */ /* #undef NO_PREFIX */ + /* ------------------------- END CONFIGURATION SECTION -------------------- */ #ifndef ENABLE_SUMMON # undef LEAST_IDLE @@ -603,4 +776,8 @@ ** Conformance of the internal resolver to RFC1123. */ #define RESTRICT_HOSTNAMES 1 + +#if defined(DELAY_ACCEPT) && !defined(SPLIT_HANDLE) +error DELAY_ACCEPT requires SPLIT_HANDLE defined. +#endif Only in irc2.10.3p6+hemp/support: config.h.dist.orig diff -ru --exclude=CVS irc2.10.3p6/support/iauth.conf irc2.10.3p6+hemp/support/iauth.conf --- irc2.10.3p6/support/iauth.conf Mon Jul 5 00:15:43 1999 +++ irc2.10.3p6+hemp/support/iauth.conf Sat Feb 28 00:27:32 2004 @@ -14,5 +14,10 @@ module rfc931 # Check and reject open SOCKS proxies -#module socks -# option = reject,paranoid +module socks + option = reject,paranoid + timeout = 5 + +module webproxy + option = log,reject,ports=3128;8080 + timeout = 10 Only in irc2.10.3p6+hemp/support: iauth.conf.orig diff -ru --exclude=CVS irc2.10.3p6/support/tkconf.h.dist irc2.10.3p6+hemp/support/tkconf.h.dist --- irc2.10.3p6/support/tkconf.h.dist Sun Feb 21 01:33:47 1999 +++ irc2.10.3p6+hemp/support/tkconf.h.dist Sat Feb 28 00:27:32 2004 @@ -28,8 +28,8 @@ #undef TKSERV_DEBUG /* The name of the ircd config file backup (suffix after CPATH) */ -#define TKSERV_IRCD_CONFIG_BAK CPATH".tkserv" +#define TKSERV_IRCD_CONFIG_BAK TKSERV_IRCD_CONF".tkserv" /* The name of the ircd temp config file (suffix after CPATH) */ -#define TKSERV_IRCD_CONFIG_TMP CPATH".tmp" +#define TKSERV_IRCD_CONFIG_TMP TKSERV_IRCD_CONF".tmp" Only in irc2.10.3p6+hemp/support: tkconf.h.dist.orig