diff -urNp current/common/parse.c current+fic/common/parse.c --- current/common/parse.c Tue Dec 21 07:28:16 2004 +++ current+fic/common/parse.c Tue Dec 21 07:29:03 2004 @@ -96,7 +96,11 @@ struct Message msgtab[] = { #ifdef USE_SERVICES { "SERVSET", 1, MPAR, { _m(m_nop), _m(m_nop), _m(m_nop), _m(m_servset), _m(m_nop) } }, #endif +#ifdef SERVICE_CAN_SQUERY +{ "SQUERY", 2, MPAR, { _m(m_nop), _m(m_squery), _m(m_squery), _m(m_squery), _m(m_unreg) } }, +#else { "SQUERY", 2, MPAR, { _m(m_nop), _m(m_squery), _m(m_squery), _m(m_nop), _m(m_unreg) } }, +#endif { "SERVLIST", 0, MPAR, { _m(m_servlist), _m(m_servlist), _m(m_servlist), _m(m_nop), _m(m_unreg) } }, { "HAZH", 0, MPAR, { _m(m_nop), _m(m_nopriv), _m(m_hash), _m(m_nop), _m(m_nop) } }, { "DNS", 0, MPAR, { _m(m_nop), _m(m_nopriv), _m(m_dns), _m(m_nop), _m(m_nop) } }, @@ -109,6 +113,12 @@ struct Message msgtab[] = { #ifdef TKLINE { "TKLINE", 3, MPAR, { _m(m_nop), _m(m_nopriv), _m(m_tkline), _m(m_tkline), _m(m_unreg) } }, { "UNTKLINE", 1, MPAR, { _m(m_nop), _m(m_nopriv), _m(m_untkline), _m(m_untkline), _m(m_unreg) } }, +#endif +#ifdef CHANJUPE +{ "RESV", 2, MPAR, { _m(m_nop), _m(m_nopriv), _m(m_resv), _m(m_nop), _m(m_unreg) } }, +#endif +#ifdef KLINE +{ "KLINE", 2, MPAR, { _m(m_nop), _m(m_nopriv), _m(m_kline), _m(m_kline), _m(m_unreg) } }, #endif { NULL, 0, 0, { _m(NULL), _m(NULL), _m(NULL), _m(NULL), _m(NULL) } } }; diff -urNp current/common/struct_def.h current+fic/common/struct_def.h --- current/common/struct_def.h Tue Dec 21 07:28:16 2004 +++ current+fic/common/struct_def.h Tue Dec 21 07:29:03 2004 @@ -192,8 +192,32 @@ typedef enum Status { #ifdef XLINE #define FLAGS_XLINED 0x0100 /* X-lined client */ #endif + #define SEND_UMODES (FLAGS_INVISIBLE|FLAGS_OPER|FLAGS_WALLOP|FLAGS_AWAY) -#define ALL_UMODES (SEND_UMODES|FLAGS_LOCOP|FLAGS_RESTRICT) + +#ifdef IGNORE_STRANGERS +# define FLAGS_CMODE 0x0200 /* user is ignoring strangers */ +#endif + +#ifdef HIDE_IDLETIME +# define FLAGS_HMODE 0x0400 /* oper is hidding his idletime */ +#endif + +#if defined(IGNORE_STRANGERS) && defined(HIDE_IDLETIME) +# define ALL_UMODES (SEND_UMODES|FLAGS_LOCOP|FLAGS_RESTRICT|FLAGS_CMODE|FLAGS_HMODE) +#endif + +#if defined(IGNORE_STRANGERS) && !defined(HIDE_IDLETIME) +# define ALL_UMODES (SEND_UMODES|FLAGS_LOCOP|FLAGS_RESTRICT|FLAGS_CMODE) +#endif + +#if !defined(IGNORE_STRANGERS) && defined(HIDE_IDLETIME) +# define ALL_UMODES (SEND_UMODES|FLAGS_LOCOP|FLAGS_RESTRICT|FLAGS_HMODE) +#endif + +#if !defined(IGNORE_STRANGERS) && !defined(HIDE_IDLETIME) +# define ALL_UMODES (SEND_UMODES|FLAGS_LOCOP|FLAGS_RESTRICT) +#endif /* * user flags macros. @@ -218,6 +242,13 @@ typedef enum Status { #define IsBursting(x) (!((x)->flags & FLAGS_EOB)) #define IsKlineExempt(x) ((x)->user && (x)->user->flags & FLAGS_EXEMPT) +#ifdef IGNORE_STRANGERS +# define IsIgnoringStrangers(x) ((x)->user && (x)->user->flags & FLAGS_CMODE) +#endif +#ifdef HIDE_IDLETIME +# define IsHiddingIdletime(x) ((x)->user && is_allowed(x, ACL_HIDEIDLE) && (x)->user->flags & FLAGS_HMODE) +#endif + #define SetDead(x) ((x)->flags |= FLAGS_DEADSOCK) #define CBurst(x) ((x)->flags & FLAGS_CBURST) #define SetOper(x) ((x)->user->flags |= FLAGS_OPER, \ @@ -353,6 +384,13 @@ struct ListItem { #define CONF_XLINE 0x800000 #endif #define CONF_OPS CONF_OPERATOR +#ifdef WLINE +#define CONF_WLINE 0x1000000 +#endif +#ifdef CHANJUPE +#define CONF_CHANJUPE 0x2000000 +#define CONF_CHANJUPE_CREATE 0x4000000 +#endif #define CONF_SERVER_MASK (CONF_CONNECT_SERVER | CONF_NOCONNECT_SERVER |\ CONF_ZCONNECT_SERVER) #define CONF_CLIENT_MASK (CONF_CLIENT | CONF_SERVICE | CONF_OPS | \ @@ -725,7 +763,13 @@ struct Channel { #define MODE_INVITE 0x08000 #define MODE_REOP 0x10000 #define MODE_REOPLIST 0x20000 +#ifdef CHANJUPE +#define MODE_JUPED 0x40000 +#define MODE_FLAGS 0x7ffff +#else #define MODE_FLAGS 0x3ffff +#endif + /* * mode flags which take another parameter (With PARAmeterS) */ @@ -998,32 +1042,41 @@ typedef struct } iconf_t; /* O:line flags, used also in is_allowed() */ -#define ACL_LOCOP 0x00001 -#define ACL_KILLLOCAL 0x00002 -#define ACL_KILLREMOTE 0x00004 +#define ACL_LOCOP 0x000001 +#define ACL_KILLLOCAL 0x000002 +#define ACL_KILLREMOTE 0x000004 #define ACL_KILL (ACL_KILLLOCAL|ACL_KILLREMOTE) -#define ACL_SQUITLOCAL 0x00008 -#define ACL_SQUITREMOTE 0x00010 +#define ACL_SQUITLOCAL 0x000008 +#define ACL_SQUITREMOTE 0x000010 #define ACL_SQUIT (ACL_SQUITLOCAL|ACL_SQUITREMOTE) -#define ACL_CONNECTLOCAL 0x00020 -#define ACL_CONNECTREMOTE 0x00040 +#define ACL_CONNECTLOCAL 0x000020 +#define ACL_CONNECTREMOTE 0x000040 #define ACL_CONNECT (ACL_CONNECTLOCAL|ACL_CONNECTREMOTE) -#define ACL_CLOSE 0x00080 -#define ACL_HAZH 0x00100 -#define ACL_DNS 0x00200 -#define ACL_REHASH 0x00400 -#define ACL_RESTART 0x00800 -#define ACL_DIE 0x01000 -#define ACL_SET 0x02000 -#define ACL_TKLINE 0x04000 +#define ACL_CLOSE 0x000080 +#define ACL_HAZH 0x000100 +#define ACL_DNS 0x000200 +#define ACL_REHASH 0x000400 +#define ACL_RESTART 0x000800 +#define ACL_DIE 0x001000 +#define ACL_SET 0x002000 +#define ACL_TKLINE 0x004000 #define ACL_UNTKLINE ACL_TKLINE -#define ACL_CLIENTS 0x08000 -#define ACL_CANFLOOD 0x10000 -#define ACL_NOPENALTY 0x20000 -#define ACL_TRACE 0x40000 +#define ACL_CLIENTS 0x008000 +#define ACL_CANFLOOD 0x010000 +#define ACL_NOPENALTY 0x020000 +#define ACL_TRACE 0x040000 +#ifdef CHANJUPE +#define ACL_CHANJUPE 0x080000 +#endif +#ifdef HIDE_IDLETIME +#define ACL_HIDEIDLE 0x100000 +#endif +#ifdef KLINE +#define ACL_KLINE 0x200000 +#endif #define ACL_ALL_REMOTE (ACL_KILLREMOTE|ACL_SQUITREMOTE|ACL_CONNECTREMOTE) -#define ACL_ALL 0xFFFFF +#define ACL_ALL 0x3FFFFF #ifdef CLIENTS_CHANNEL /* information scope of &CLIENTS channel. */ @@ -1032,5 +1085,7 @@ typedef struct #define CCL_QUIT 0x04 /* quits */ #define CCL_QUITINFO 0x08 /* if quits, then with quit message */ #define CCL_NICK 0x10 /* nick changes */ +#define CCL_STATS 0x20 /* clients doing stats */ +#define CCL_CHANJUPE 0x40 /* channel jupe messages */ #endif diff -urNp current/common/support.c current+fic/common/support.c --- current/common/support.c Tue Dec 21 07:28:16 2004 +++ current+fic/common/support.c Tue Dec 21 07:29:03 2004 @@ -742,7 +742,7 @@ dgetsreturnbuf: char *make_version(void) { 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 */ @@ -754,6 +754,8 @@ char *make_version(void) sprintf(ver + strlen(ver), "%c%d", DEVLEVEL, dv); if (pl) /* patchlevel */ sprintf(ver + strlen(ver), "p%d", pl); + strcat(ver, "+fic"); + return mystrdup(ver); } diff -urNp current/fic.txt current+fic/fic.txt --- current/fic.txt Thu Jan 1 01:00:00 1970 +++ current+fic/fic.txt Mon Dec 27 13:57:57 2004 @@ -0,0 +1,78 @@ +The +fic patch for 2.11 ircd includes: + + - Ability to change default awaymessage. + + - ERR_TOOMANYCHANS now shows also MAXCHANNELSPERUSER + + - IGNORE_STRANGERS + When you have +c usermode set only people sharing at least one common channel with you can message you. + If the one who sends a message to you is on the same server and is not allowed to message you + he gets a RPL_AWAY with TXT_STRANGERS. Opers are exempted from +c. + + - NO_COMMENT_ABUSE + People that can't speak on a certain channel are not able to annoy with their PART / QUIT / JOIN 0 comment. + For channels where the user is not allowed to speak PARTs are generated artificially and sent out. + + - HIDE_IDLETIME + Opers with the H O:line flag are allowed to set +H usermode which hides their idle time when a + non-oper whoises them. (Actually any user can set +H but it will have no effect.) + + - CCL_STATS + Show STATS requests on &CLIENTS (as with 2.10 and the hemp patch, just a different 2.11 consistent syntax) + + *** CPU INTENSIVE - /rehash might take a long time when you have a lot of channel jupes *** + - CHANJUPE - a possibility to jupe channels on the local server. People + trying to join a juped channel will get ERR_UNAVAILRESOURCE error + (seems as it would be caused by netsplit) + It's not possible to jupe server &flagchans. It's configurable via J O:line flag. + Opers with the J flag can also join channels which are jupped. + + The command used to jupe a channel is RESV. Syntax RESV channel :reason. + In the JUPE_FILE (usually ircd.conf or an included file) a jupe is specified via J:line. + J:channel:reason:: + Instead of RESV + - CCL_CHANJUPE + The usage of RESV is displayed on &clients. Additionally also tries of people to join the + certain (blocked) channel are displayed. + - STATS J shows the blocked channels to local opers with J O:line flag + - Bad characters in channel name or reason are escaped before writing to the JUPE_FILE. + - j:line is the same as J:line (which is written by RESV) just that + it prevents the creation of new channels with the given name. + - wildcards work + NOTE: JUPE_FILE must exist. + *** *** + + - WLINE + When an unregistered user quits due to an error print the contents of the W:line from the ircd.conf. + It's supposed to be an URL where he can get more info. + (IMPORTANT: ':' is usually the ircd.conf delimiter. To write http://www.example.net your W:line + needs to be ala: + W:http\\://www.example.net. You can avoid that by using a different IRCDCONF_DELIMITER) + + - STATS_L_OPERONLY + Make /stats L oper only. /stats l (lower case) still works. + - Other /stats (upper and lower case) can also get blocked, + STATS_C_OPERONLY, STATS_D_OPERONLY, STATS_H_OPERONLY, STATS_I_OPERONLY, STATS_O_OPERONLY, STATS_Y_OPERONLY + + - KLINE + The O:line flag to allow it is 1. (it is included when you give the A O:line flag however) + The usage is "KLINE user@host :comment". It will add a permanent(!) K:line - removing all matching + clients and adding an entry in KLINE_FILE (ircd.conf per default). Note that there is no way + to remove that without editing the config file! UNKLINE is too risky as it could + delete some other line by accident. + - Bad characters in the reason (such as #, delimiter) are not + problematic anymore (they get escaped). + NOTE: KLINE_FILE must exist. + - A service can now have SERVICE_WANT_KLINE privilege (for permanent + K:lines) + + - TKLINE now also shows a NOTICE to the oper when successful + - A lifetime of 0 with TKLINE means "infinity" (if TKLINE_MAXTIME is + defined 0 means maximum lifetime). + + - A service is allowed to SQUERY another service when compiled with + #define SERVICE_CAN_SQUERY. (This breaks the RFC and could cause looping - + one service sending data and the other one reply, which will cause reply from + the first service again). + + - X:lines matches are reported to SCH_OPER now. diff -urNp current/ircd/channel.c current+fic/ircd/channel.c --- current/ircd/channel.c Tue Dec 21 07:28:17 2004 +++ current+fic/ircd/channel.c Sun Dec 26 22:45:47 2004 @@ -2063,6 +2063,30 @@ static aChannel *get_channel(aClient *cp return chptr; } +#ifdef IGNORE_STRANGERS +/* + * Return first common channel users aptr and bptr are on. + * NullChn if none. + */ +aChannel *CommonChannel(anUser *aptr, anUser *bptr) +{ + Link *lp, *lp2; + + if (!aptr || !bptr) { return NullChn; } + for (lp = aptr->channel; lp; lp=lp->next) + { + for (lp2 = bptr->channel; lp2; lp2=lp2->next) { + if ((lp->value.chptr == lp2->value.chptr) && + (!IsAnonymous(lp->value.chptr))) + { + return lp->value.chptr; + } + } + } + return NullChn; +} +#endif + /* * add_invite(): * sptr: who invites @@ -2403,7 +2427,11 @@ int m_join(aClient *cptr, aClient *sptr, sendto_channel_butserv(chptr, sptr, PartFmt, parv[0], chptr->chname, +#ifdef NO_COMMENT_ABUSE + (key && can_send(sptr, chptr)) ? key : ""); +#else key ? key : ""); +#endif remove_user_from_channel(sptr, chptr); } sendto_match_servs(NULL, cptr, ":%s JOIN 0 :%s", @@ -2436,7 +2464,7 @@ int m_join(aClient *cptr, aClient *sptr, sptr->user->joined >= MAXCHANNELSPERUSER) { sendto_one(sptr, replies[ERR_TOOMANYCHANNELS], - ME, BadTo(parv[0]), name); + ME, BadTo(parv[0]), name, MAXCHANNELSPERUSER); /* can't return, need to send the info everywhere */ continue; } @@ -2449,20 +2477,57 @@ int m_join(aClient *cptr, aClient *sptr, return exit_client(sptr, sptr, &me, "Virus Carrier"); } - if (!chptr) - { - /* Oh well, create the channel. */ - chptr = get_channel(sptr, name, CREATE); - } - - if (!chptr) - { - /* Should NEVER happen. */ - sendto_flag(SCH_ERROR, "Could not create channel!"); - sendto_one(sptr, "%s *** %s :Could not create channel!", - ME, BadTo(parv[0])); - continue; - } +#ifdef CHANJUPE + { + if (MyConnect(sptr) && !is_allowed(sptr, ACL_CHANJUPE)) + { + if (chptr) + { + /* Channel is already existing */ + if ((chptr->mode.mode & (MODE_JUPED|MODE_QUIET)) == MODE_JUPED) + { + /* Channel is juped and not quiet */ + sendto_one(sptr, replies[ERR_UNAVAILRESOURCE], + ME, BadTo(parv[0]), name); +# if defined(CLIENTS_CHANNEL) && (CLIENTS_CHANNEL_LEVEL & CCL_CHANJUPE) + sendto_flag(SCH_CLIENT, "%s %s %s %s JOIN %s", + sptr->user->uid, sptr->name, sptr->user->username, + sptr->user->host, name); +#endif + continue; + } + } else { + aConfItem *aconf = NULL; + /* A new channel will be created later */ + if (aconf = (aConfItem*)find_chanjupe(name, CONF_CHANJUPE|CONF_CHANJUPE_CREATE)) + { + sendto_one(sptr, replies[ERR_UNAVAILRESOURCE], + ME, BadTo(parv[0]), name); +# if defined(CLIENTS_CHANNEL) && (CLIENTS_CHANNEL_LEVEL & CCL_CHANJUPE) + sendto_flag(SCH_CLIENT, "%s %s %s %s JOIN %s (%s)", + sptr->user->uid, sptr->name, sptr->user->username, + sptr->user->host, name, BadTo(aconf->passwd)); +#endif + continue; + } + } + } + } +#endif + if (!chptr) + { + /* Oh well, create the channel. */ + chptr = get_channel(sptr, name, CREATE); + } + + if (!chptr) + { + /* Should NEVER happen. */ + sendto_flag(SCH_ERROR, "Could not create channel!"); + sendto_one(sptr, "%s *** %s :Could not create channel!", + ME, BadTo(parv[0])); + continue; + } if (MyConnect(sptr) && (i = can_join(sptr, chptr, key))) { @@ -2922,6 +2987,11 @@ int m_part(aClient *cptr, aClient *sptr, name); continue; } +#ifdef NO_COMMENT_ABUSE + if (can_send(sptr, chptr)) { + comment = mystrdup(""); + } +#endif /* ** Remove user from the old channel (if any) */ diff -urNp current/ircd/channel_ext.h current+fic/ircd/channel_ext.h --- current/ircd/channel_ext.h Tue Dec 21 07:28:17 2004 +++ current+fic/ircd/channel_ext.h Tue Dec 21 07:29:03 2004 @@ -34,6 +34,7 @@ extern aChannel *channel; #else /* CHANNEL_C */ #define EXTERN #endif /* CHANNEL_C */ +EXTERN aChannel *CommonChannel (anUser *aptr, anUser *bptr); EXTERN void remove_user_from_channel (aClient *sptr, aChannel *chptr); EXTERN int is_chan_op (aClient *cptr, aChannel *chptr); EXTERN int has_voice (aClient *cptr, aChannel *chptr); diff -urNp current/ircd/chkconf.c current+fic/ircd/chkconf.c --- current/ircd/chkconf.c Tue Dec 21 07:28:17 2004 +++ current+fic/ircd/chkconf.c Tue Dec 21 07:29:03 2004 @@ -419,6 +419,14 @@ static aConfItem *initconf() aconf->status = CONF_CLIENT; mandatory_found |= CONF_CLIENT; break; +#ifdef CHANJUPE + case 'J': /* Channel jupe */ + aconf->status = CONF_CHANJUPE; + break; + case 'j': /* Channel creation jupe */ + aconf->status = CONF_CHANJUPE_CREATE; + break; +#endif case 'K': /* Kill user line on irc.conf */ aconf->status = CONF_KILL; break; @@ -473,6 +481,12 @@ static aConfItem *initconf() aconf->status = CONF_XLINE; break; #endif +#ifdef WLINE + case 'W': + case 'w': + aconf->status = CONF_WLINE; + break; +#endif default: config_error(CF_WARN, CK_FILE, CK_LINE, "unknown conf line letter (%c)\n", *tmp); @@ -561,6 +575,15 @@ static aConfItem *initconf() case 'p': case 'P': case 't': +#ifdef CHANJUPE + case 'J': +#endif +#ifdef HIDE_IDLETIME + case 'H': +#endif +#ifdef KLINE + case '1': +#endif break; default: config_error(CF_WARN, CK_FILE, CK_LINE, @@ -674,6 +697,14 @@ static aConfItem *initconf() aconf->passwd = nullfield; if (!aconf->host) aconf->host = nullfield; +#ifdef WLINE + if (aconf->status & CONF_WLINE) + { + if (flags & aconf->status) + config_error(CF_ERR, CK_FILE, CK_LINE, + "multiple W-lines"); + } +#endif if (aconf->status & CONF_ME) { if (flags & aconf->status) @@ -1133,8 +1164,19 @@ static void mywc() static char confchar(u_int status) { - static char letrs[] = "QIicNCoOMKARYSLPHV"; - char *s = letrs; +#if !defined(WLINE) && !defined(CHANJUPE) + static char letters[] = "QIicNCoOMKARYSLPHV"; +#endif +#if !defined(WLINE) && defined(CHANJUPE) + static char letters[] = "QIiJcNCoOMKARYSLPHV"; +#endif +#if defined(WLINE) && !defined(CHANJUPE) + static char letters[] = "QIcNCoOMKARYSLPHVWw"; +#endif +#if defined(WLINE) && defined(CHANJUPE) + static char letters[] = "QIiJcNCoOMKARYSLPHVWw"; +#endif + char *s = letters; status &= ~(CONF_MATCH|CONF_ILLEGAL); diff -urNp current/ircd/ircd.c current+fic/ircd/ircd.c --- current/ircd/ircd.c Tue Dec 21 07:28:17 2004 +++ current+fic/ircd/ircd.c Tue Dec 21 07:29:03 2004 @@ -482,6 +482,40 @@ static int delayed_kills(time_t currentt return rehashed; } +#ifdef CHANJUPE +void checkjupes() +{ + Reg aConfItem *aconf; + Reg aChannel *chptr; + int found; + + /* Very CPU intensive :( */ + for (chptr = channel; chptr; chptr = chptr->nextch) + { + found = 0; + for (aconf = jconf; aconf; aconf = aconf->next) + { + if (aconf->status != CONF_CHANJUPE) + { + continue; + } + if (!match(aconf->host, chptr->chname)) + { + found = 1; + break; + } + } + + if (found) + { + chptr->mode.mode |= MODE_JUPED; + } else { + chptr->mode.mode &= ~MODE_JUPED; + } + } +} +#endif + static time_t check_pings(time_t currenttime) { #ifdef TIMEDKLINES diff -urNp current/ircd/ircd_ext.h current+fic/ircd/ircd_ext.h --- current/ircd/ircd_ext.h Tue Dec 21 07:28:17 2004 +++ current+fic/ircd/ircd_ext.h Tue Dec 21 07:29:03 2004 @@ -66,4 +66,5 @@ EXTERN RETSIGTYPE s_restart (int s); EXTERN void server_reboot(void); EXTERN void ircd_writetune (char *filename); EXTERN void ircd_readtune (char *filename); +EXTERN void checkjupes (); #undef EXTERN diff -urNp current/ircd/s_conf.c current+fic/ircd/s_conf.c --- current/ircd/s_conf.c Tue Dec 21 07:28:17 2004 +++ current+fic/ircd/s_conf.c Tue Dec 21 07:29:03 2004 @@ -72,6 +72,9 @@ char *networkname = NULL; #ifdef TKLINE aConfItem *tkconf = NULL; #endif +#ifdef CHANJUPE +aConfItem *jconf = NULL; +#endif /* Parse I-lines flags from string. * D - Restricted, if no DNS. @@ -265,6 +268,18 @@ char *oline_flags_to_string(long flags) *s++ = 'p'; if (flags & ACL_TRACE) *s++ = 't'; +#ifdef CHANJUPE + if (flags & ACL_CHANJUPE) + *s++ = 'J'; +#endif +#ifdef HIDE_IDLETIME + if (flags & ACL_HIDEIDLE) + *s++ = 'H'; +#endif +#ifdef KLINE + if (flags & ACL_KLINE) + *s++ = '1'; +#endif if (s == ofsbuf) *s++ = '-'; *s++ = '\0'; @@ -283,6 +298,14 @@ long oline_flags_parse(char *string) case 'L': tmp |= ACL_LOCOP; break; case 'A': tmp |= (ACL_ALL & ~(ACL_LOCOP|ACL_CLIENTS|ACL_NOPENALTY|ACL_CANFLOOD)); +#ifdef CHANJUPE + /* The possibility of channel juping (J) must be specified explicitly - not within A */ + tmp &= ~ACL_CHANJUPE; +#endif +#ifdef HIDE_IDLETIME + /* same with H flag */ + tmp &= ~ACL_HIDEIDLE; +#endif break; case 'K': tmp |= ACL_KILL; break; case 'k': tmp |= ACL_KILLLOCAL; break; @@ -304,6 +327,15 @@ long oline_flags_parse(char *string) case 'P': tmp |= ACL_NOPENALTY; break; case 'p': tmp |= ACL_CANFLOOD; break; case 't': tmp |= ACL_TRACE; break; +#ifdef CHANJUPE + case 'J': tmp |= ACL_CHANJUPE; break; +#endif +#ifdef HIDE_IDLETIME + case 'H': tmp |= ACL_HIDEIDLE; break; +#endif +#ifdef KLINE + case '1': tmp |= ACL_KLINE; break; +#endif } } if (tmp & ACL_LOCOP) @@ -817,6 +849,44 @@ aConfItem *find_me(void) return (aconf); } +#ifdef WLINE +aConfItem *find_wline(void) +{ + Reg aConfItem *aconf; + for (aconf = conf; aconf; aconf = aconf->next) + if (aconf->status & CONF_WLINE) + break; + + return (aconf); +} +#endif + +#ifdef CHANJUPE +aConfItem *find_chanjupe(char *name, int status) +{ + Reg aConfItem *aconf; + if (!name) + { + return NULL; + } + for (aconf = jconf; aconf; aconf = aconf->next) + { + if (!(aconf->status & status)) + { + /* Not a line we want! */ + continue; + } + + if (!match(aconf->host, name)) + { + /* We found it */ + return aconf; + } + } + return NULL; +} +#endif + /* * attach_confs * Attach a CONF line to a client if the name passed matches that for @@ -1178,6 +1248,15 @@ int rehash(aClient *cptr, aClient *sptr, free_conf(tmp2); } +#ifdef CHANJUPE + tmp = &jconf; + while ((tmp2 = *tmp)) + { + *tmp = tmp2->next; + free_conf(tmp2); + } +#endif + /* * We don't delete the class table, rather mark all entries * for deletion. The table is cleaned up by check_class. - avalon @@ -1209,6 +1288,9 @@ int rehash(aClient *cptr, aClient *sptr, } read_motd(IRCDMOTD_PATH); +#ifdef CHANJUPE + checkjupes(); +#endif if (rehashed == 1) { /* queue another rehash for later */ @@ -1495,6 +1577,14 @@ int initconf(int opt) case 'I': aconf->status = CONF_CLIENT; break; +#ifdef CHANJUPE + case 'J' : /* Channel jupe */ + aconf->status = CONF_CHANJUPE; + break; + case 'j' : /* Channel creation jupe */ + aconf->status = CONF_CHANJUPE_CREATE; + break; +#endif case 'K': /* Kill user line on irc.conf */ aconf->status = CONF_KILL; break; @@ -1548,6 +1638,12 @@ int initconf(int opt) aconf->status = CONF_XLINE; break; #endif +#ifdef WLINE + case 'W': + case 'w': + aconf->status = CONF_WLINE; + break; +#endif default: Debug((DEBUG_ERROR, "Error in config file: %s", line)); break; @@ -1572,6 +1668,13 @@ int initconf(int opt) #else DupString(aconf->host, tmp); #endif +#ifdef WLINE + if (aconf->status == CONF_WLINE) + { + /* We just need to read 1st field */ + break; + } +#endif if ((tmp = getfield(NULL)) == NULL) break; DupString(aconf->passwd, tmp); @@ -1799,9 +1902,16 @@ int initconf(int opt) kconf = aconf; } else +#ifdef CHANJUPE + if (aconf->status & (CONF_CHANJUPE|CONF_CHANJUPE_CREATE)) + { + aconf->next = jconf; + jconf = aconf; + } else +#endif { - aconf->next = conf; - conf = aconf; + aconf->next = conf; + conf = aconf; } aconf = NULL; } @@ -2392,7 +2502,7 @@ int m_tkline(aClient *cptr, aClient *spt } /* All parameters are now sane. Do the stuff. */ - do_tkline(parv[0], time, user, host, reason, status); + do_tkline(sptr, time, user, host, reason, status); return 1; } @@ -2403,7 +2513,7 @@ int m_tkline(aClient *cptr, aClient *spt * * Returns created tkline expire time. */ -void do_tkline(char *who, int time, char *user, char *host, char *reason, int status) +void do_tkline(aClient *sptr, int time, char *user, char *host, char *reason, int status) { char buff[BUFSIZE]; aClient *acptr; @@ -2427,7 +2537,11 @@ void do_tkline(char *who, int time, char aconf = make_conf(); aconf->next = NULL; aconf->status = status; - aconf->hold = timeofday + time; +#ifdef TKLINE_MAXTIME + aconf->hold = (time)?(timeofday + time):(timeofday + TKLINE_MAXTIME); +#else + aconf->hold = (time)?(timeofday + time):0; +#endif aconf->port = 0; Class(aconf) = find_class(0); DupString(aconf->name, BadTo(user)); @@ -2444,8 +2558,11 @@ void do_tkline(char *who, int time, char } tkconf = aconf; } + sendto_flag(SCH_TKILL, "TKLINE %s@%s (%d) by %s :%s", - aconf->name, aconf->host, time, who, reason); + aconf->name, aconf->host, time, sptr->name, reason); + sendto_one(sptr, ":%s NOTICE %s :Added TKLINE for %s@%s with reason %s", + ME, sptr->name, aconf->name, aconf->host, aconf->passwd); /* get rid of tklined clients */ for (i = highest_fd; i >= 0; i--) @@ -2554,7 +2671,7 @@ int m_untkline(aClient *cptr, aClient *s { sendto_one(sptr, ":%s NOTICE %s " ":UNTKLINE: Incorrect format", - ME, parv[0]); + ME, BadTo(parv[0])); return exit_client(cptr, cptr, &me, "UNTKLINE: Incorrect format"); } @@ -2588,6 +2705,8 @@ int m_untkline(aClient *cptr, aClient *s { sendto_flag(SCH_TKILL, "UNTKLINE %s@%s by %s", user, host, parv[0]); + sendto_one(sptr, ":%s NOTICE %s :Removed TKLINE for %s@%s", + ME, sptr->name, user, host); } return 1; } @@ -2600,7 +2719,7 @@ time_t tkline_expire(int all) while ((tmp = tmp2)) { tmp2 = tmp->next; - if (all || tmp->hold <= timeofday) + if (all || (tmp->hold && tmp->hold <= timeofday)) { if (tmp == tkconf) tkconf = tmp->next; @@ -2620,3 +2739,349 @@ time_t tkline_expire(int all) return min; } #endif + +#if defined(KLINE) || defined(CHANJUPE) +char *escape_strncpy(char *dst, char *src, int n) +{ + char *tmp = dst; + while (*src && (n-- > 1)) + { + /* # or \ is escaped in conf with one \ (Example: \#) */ + if ((*src == '#') || (*src == '\\')) + { + /* There needs to be room for another character... */ + if (n-- > 1) + { + *tmp++ = '\\'; + } else { + break; + } + } + /* delimiter is escaped with two \ (Example \\:) */ + else if ((*src == IRCDCONF_DELIMITER)) + { + /* There needs to be room for two characters... */ + if (n-- > 2) + { + *tmp++ = '\\'; + *tmp++ = '\\'; + } else { + break; + } + } + *tmp++ = *src++; + } + /* ...and for the terminating '\0' of course */ + *tmp++ = '\0'; + return dst; +} +#endif + +#ifdef KLINE +/* Very similar to m_tkline() and do_tkline() still too much fuss to just change the other one */ + +/* + * parv[0] - source + * parv[1] - user@host + * parv[2] - reason + */ +int m_kline(aClient *cptr, aClient *sptr, int parc, char **parv) +{ + int status = CONF_KILL; + char *user, *host, *reason; + + if (!is_allowed(sptr, ACL_KLINE)) + return m_nopriv(cptr, sptr, parc, parv); + + user = parv[1]; + host = strchr(user, '@'); + if (!host) + { + /* error */ + if (!IsPerson(sptr)) + { + sendto_one(sptr, ":%s NOTICE %s " + ":KLINE: Incorrect format", + ME, parv[0]); + return exit_client(cptr, cptr, &me, + "KLINE: Incorrect format"); + } + sendto_one(sptr, ":%s NOTICE %s :KLINE: Incorrect format", + ME, BadTo(parv[0])); + return 2; + } + + if (*user == '=') + { + status = CONF_OTHERKILL; + user++; + } + *host++ = '\0'; + reason = parv[2]; + if (strlen(reason) > TOPICLEN) + { + reason[TOPICLEN] = '\0'; + } + + /* All parameters are now sane. Do the stuff. */ + do_kline(sptr, user, host, reason, status); + + return 1; +} + +void do_kline(aClient *sptr, char *user, char *host, char *reason, int status) +{ + char buff[BUFSIZE*2]; + aClient *acptr; + aConfItem *aconf; + int i, count = 0; + time_t current_time; + char myuser[(USERLEN*2)+1], myhost[(HOSTLEN*2)+1], myreason[(TOPICLEN*2)+1]; + + buff[0] = '\0'; + + /* Check if such u@h already exists in kconf. */ + for (aconf = kconf; aconf; aconf = aconf->next) + { + if (0==strcasecmp(aconf->host, host) && + 0==strcasecmp(aconf->name, user)) + { + return; + } + } + + time(¤t_time); + + if (aconf == NULL) + { + aconf = make_conf(); + aconf->next = NULL; + aconf->status = status; + aconf->port = 0; + Class(aconf) = find_class(0); + DupString(aconf->name, BadTo(user)); + DupString(aconf->host, BadTo(host)); + DupString(aconf->passwd, reason); + istat.is_confmem += strlen(aconf->name) + 1; + istat.is_confmem += strlen(aconf->host) + 1; + istat.is_confmem += strlen(aconf->passwd) + 1; + + /* put on top of kconf */ + if (kconf) + { + aconf->next = kconf; + } + kconf = aconf; + } + sendto_flag(SCH_OPER, "KLINE %s@%s (%d) by %s", + aconf->name, aconf->host, time, sptr->name); + + /* get rid of klined clients */ + for (i = highest_fd; i >= 0; i--) + { + if (!(acptr = local[i]) || !IsPerson(acptr) + || IsKlineExempt(acptr)) + { + continue; + } + if (!strcmp(acptr->sockhost, acptr->user->sip)) + { + /* unresolved */ + if (strchr(aconf->host, '/')) + { + if (match_ipmask(*aconf->host == '=' ? + aconf->host + 1 : aconf->host, + acptr, 1)) + { + continue; + } + } + else + { + if (match(*aconf->host == '=' ? + aconf->host + 1 : aconf->host, + acptr->sockhost)) + { + continue; + } + } + } + else + { + /* resolved */ + if (*aconf->host == '=') + { + /* IP only */ + continue; + } + if (strchr(aconf->host, '/')) + { + if (match_ipmask(aconf->host, acptr, 1)) + { + continue; + } + } + else + { + if (match(aconf->host, acptr->user->sip) + && match(aconf->host, + acptr->user->host)) + { + continue; + } + } + } + if (match(aconf->name, aconf->status == CONF_OTHERKILL ? + acptr->auth : (IsRestricted(acptr) && + acptr->user->username[0] == '+' ? + acptr->user->username+1 : + acptr->user->username)) == 0) + { + count++; + sendto_one(acptr, replies[ERR_YOUREBANNEDCREEP], + ME, acptr->name, aconf->name, aconf->host, + ": ", aconf->passwd); + sendto_flag(SCH_NOTICE, + "Kill line active for %s", + get_client_name(acptr, FALSE)); + if (buff[0] == '\0') + { + sprintf(buff, "Kill line active: %.80s", + aconf->passwd); + } + (void) exit_client(acptr, acptr, &me, buff); + } + } + if (count) + { + sendto_flag(SCH_NOTICE, "Kill reaped %d souls", count); + } + + /* Escape parameters and write to the file */ + + escape_strncpy(myuser, user, sizeof(myuser)); + escape_strncpy(myhost, host, sizeof(myhost)); + escape_strncpy(myreason, reason, sizeof(myreason)); + + if ((i = open(KLINE_FILE, O_WRONLY|O_APPEND))==-1) + { + sendto_one(sptr,":%s NOTICE %s :Problem opening server configfile", + ME, sptr->name); + return; + } + + /* Better safe than sorry */ + if (sptr->user) + { + sprintf(buff,"# Added by %s (%s@%s) on %s", + sptr->name, sptr->user->username, sptr->user->host, + asctime(localtime(¤t_time))); + } + else + { + sprintf(buff,"# Added by %s on %s", + sptr->name, asctime(localtime(¤t_time))); + + } + + if (write(i, buff, strlen(buff)) <= 0) + { + sendto_one(sptr, ":%s NOTICE %s :Problem writing to the configfile", + ME, sptr->name); + close(i); + return; + } + sprintf(buff, "K%c%s%c%s%c%s%c%c\n\n", IRCDCONF_DELIMITER, myhost, IRCDCONF_DELIMITER, myreason, + IRCDCONF_DELIMITER, myuser, IRCDCONF_DELIMITER, IRCDCONF_DELIMITER); + if (write(i, buff, strlen(buff)) <= 0) + { + sendto_one(sptr, ":%s NOTICE %s :Problem writing to the configfile", + ME, sptr->name); + } + close(i); + + sendto_one(sptr, ":%s NOTICE %s :Added KLINE for %s@%s with reason %s", + ME, sptr->name, user, host, reason); + + return; +} +#endif + +#ifdef CHANJUPE +/* + * parv[0] - source + * parv[1] - channel + * parv[2] - reason + */ +int m_resv(aClient *cptr, aClient *sptr, int parc, char *parv[]) + { + aConfItem *aconf; + int out; + char buff[BUFSIZE*2]; + time_t current_time; + char channel[(CHANNELLEN*2)+1], reason[(TOPICLEN*2)+1]; + + if (!is_allowed(sptr, ACL_CHANJUPE)) + return m_nopriv(cptr, sptr, parc, parv); + + aconf = make_conf(); + aconf->status = CONF_CHANJUPE; + DupString(aconf->host, parv[1]); + DupString(aconf->passwd, parv[2]); + aconf->port = 0; + aconf->next = jconf; + jconf = aconf; + + /* Do the escaping of the parameters */ + + escape_strncpy(channel, parv[1], sizeof(channel)); + escape_strncpy(reason, parv[2], sizeof(reason)); + + if ((out = open(JUPE_FILE, O_WRONLY|O_APPEND))==-1) + { + sendto_one(sptr,":%s NOTICE %s :Problem opening server configfile", + ME, parv[0]); + return 1; + } + time(¤t_time); + + /* Better safe than sorry */ + if (sptr->user) + { + sprintf(buff,"# Added by %s (%s@%s) on %s", + sptr->name, sptr->user->username, sptr->user->host, + asctime(localtime(¤t_time))); + } + else + { + sprintf(buff,"# Added by %s on %s", + sptr->name, asctime(localtime(¤t_time))); + + } + if (write(out, buff, strlen(buff)) <= 0) + { + sendto_one(sptr, ":%s NOTICE %s :Problem writing to the configfile", + ME, BadPtr(parv[0])); + close(out); + return 1; + } + sprintf(buff, "J%c%s%c%s%c%c\n\n", IRCDCONF_DELIMITER, channel, IRCDCONF_DELIMITER, reason, + IRCDCONF_DELIMITER, IRCDCONF_DELIMITER); + if (write(out, buff, strlen(buff)) <= 0) + { + sendto_one(sptr, ":%s NOTICE %s :Problem writing to the configfile", + ME, BadTo(parv[0])); + close(out); + return 1; + } + close(out); +# if defined(CLIENTS_CHANNEL) && (CLIENTS_CHANNEL_LEVEL & CCL_CHANJUPE) + sendto_flag(SCH_CLIENT, "%s added a RESV for %s with reason: %s", + BadTo(parv[0]), parv[1], parv[2]); +# endif + sendto_one(sptr, ":%s NOTICE %s :Added RESV for %s with reason: %s", + ME, BadTo(parv[0]), parv[1], parv[2]); + return 1; + } +#endif + diff -urNp current/ircd/s_conf_ext.h current+fic/ircd/s_conf_ext.h --- current/ircd/s_conf_ext.h Tue Dec 21 07:28:17 2004 +++ current+fic/ircd/s_conf_ext.h Tue Dec 21 07:29:03 2004 @@ -28,6 +28,9 @@ extern aConfItem *conf, *kconf; #ifdef TKLINE extern aConfItem *tkconf; #endif +#ifdef CHANJUPE +extern aConfItem *jconf; +#endif extern char *networkname; #endif /* S_CONF_C */ @@ -83,6 +86,13 @@ EXTERN char *ipv6_convert (char *orig); EXTERN int m_tkline(aClient *, aClient *, int, char **); EXTERN int m_untkline(aClient *, aClient *, int, char **); EXTERN time_t tkline_expire(int); -EXTERN void do_tkline(char *, int, char *, char *, char *, int); +EXTERN void do_tkline(aClient *, int, char *, char *, char *, int); +#endif +#ifdef KLINE +EXTERN int m_kline(aClient *, aClient *, int, char **); +EXTERN void do_kline(aClient *, char *, char *, char *, int); +#endif +#ifdef CHANJUPE +EXTERN int m_resv(aClient *, aClient *, int, char **); #endif #undef EXTERN diff -urNp current/ircd/s_debug.c current+fic/ircd/s_debug.c --- current/ircd/s_debug.c Tue Dec 21 07:28:17 2004 +++ current+fic/ircd/s_debug.c Mon Dec 27 13:57:25 2004 @@ -129,6 +129,55 @@ char serveropts[] = { #endif '\0'}; +#define FICDATE "27.12.2004" +char ficopts[] = { +#ifdef STATS_C_OPERONLY +'c', +#endif +#ifdef STATS_D_OPERONLY +'d', +#endif +#ifdef STATS_H_OPERONLY +'h', +#endif +#ifdef STATS_I_OPERONLY +'i', +#endif +#ifdef STATS_O_OPERONLY +'o', +#endif +#ifdef STATS_Y_OPERONLY +'y', +#endif +#ifdef STATS_L_OPERONLY +'l', +#endif +#ifdef NO_COMMENT_ABUSE +'N', +#endif +#ifdef IGNORE_STRANGERS +'C', +#endif +#ifdef HIDE_IDLETIME +'H', +#endif +#ifdef CHANJUPE +'J', +#endif +#ifdef KLINE +'K', +#endif +#ifdef SERVICE_CAN_SQUERY +'S', +#endif +/* W:line needs to be last for nice output - ..W (data)! */ +#ifdef WLINE +'W', +#endif +'\0' +}; + + #ifdef DEBUGMODE static char debugbuf[2*READBUF_SIZE]; /* needs to be big.. */ @@ -277,6 +326,11 @@ void send_usage(aClient *cptr, char *nic void send_defines(aClient *cptr, char *nick) { + +#ifdef WLINE + Reg aConfItem *aconf = NULL; +#endif + sendto_one(cptr, ":%s %d %s :HUB:%s MS:%d", ME, RPL_STATSDEFINE, nick, #ifdef HUB @@ -325,6 +379,16 @@ void send_defines(aClient *cptr, char *n sendto_one(cptr, ":%s %d %s :CCL:0x%X", ME, RPL_STATSDEFINE, nick, CLIENTS_CHANNEL_LEVEL); #endif +#ifdef WLINE + if ((aconf = (aConfItem*)find_wline()) && !BadPtr(aconf->host)) + { + sendto_one(cptr, ":%s %d %s :fiction:%s (%.200s) version: %s", ME, RPL_STATSDEFINE, + nick, ficopts, aconf->host, FICDATE); + } else +#endif + sendto_one(cptr, ":%s %d %s :fiction:%s version: %s", ME, RPL_STATSDEFINE, + nick, ficopts, FICDATE); +#undef FICDATE } void count_memory(aClient *cptr, char *nick, int debug) diff -urNp current/ircd/s_err.c current+fic/ircd/s_err.c --- current/ircd/s_err.c Tue Dec 21 07:28:17 2004 +++ current+fic/ircd/s_err.c Tue Dec 21 07:29:03 2004 @@ -32,7 +32,18 @@ char * replies[] = { /* 001 RPL_WELCOME */ ":%s 001 %s :Welcome to the Internet Relay Network %s", /* 002 RPL_YOURHOST */ ":%s 002 %s :Your host is %s, running version %s", /* 003 RPL_CREATED */ ":%s 003 %s :This server was created %s", +#if defined(IGNORE_STRANGERS) && defined(HIDE_IDLETIME) +/* 004 RPL_MYINFO */ ":%s 004 %s %s %s acHoOirw abeiIklmnoOpqrRstv", +#endif +#if !defined(IGNORE_STRANGERS) && defined(HIDE_IDLETIME) +/* 004 RPL_MYINFO */ ":%s 004 %s %s %s aHoOirw abeiIklmnoOpqrRstv", +#endif +#if defined(IGNORE_STRANGERS) && !defined(HIDE_IDLETIME) +/* 004 RPL_MYINFO */ ":%s 004 %s %s %s acoOirw abeiIklmnoOpqrRstv", +#endif +#if !defined(IGNORE_STRANGERS) && !defined(HIDE_IDLETIME) /* 004 RPL_MYINFO */ ":%s 004 %s %s %s aoOirw abeiIklmnoOpqrRstv", +#endif /* 005 RPL_ISUPPORT */ ":%s 005 %s %s :are supported by this server", /* 006 */ (char *)NULL, /* 007 */ (char *)NULL, @@ -444,7 +455,7 @@ char * replies[] = { /* 402 ERR_NOSUCHSERVER */ ":%s 402 %s %s :No such server", /* 403 ERR_NOSUCHCHANNEL */ ":%s 403 %s %s :No such channel", /* 404 ERR_CANNOTSENDTOCHAN */ ":%s 404 %s %s :Cannot send to channel", -/* 405 ERR_TOOMANYCHANNELS */ ":%s 405 %s %s :You have joined too many channels", +/* 405 ERR_TOOMANYCHANNELS */ ":%s 405 %s %s :You have joined too many channels (maximum is %d)", /* 406 ERR_WASNOSUCHNICK */ ":%s 406 %s %s :There was no such nickname", /* 407 ERR_TOOMANYTARGETS */ ":%s 407 %s %s :%s recipients. %s", /* 408 ERR_NOSUCHSERVICE */ ":%s 408 %s %s :No such service", diff -urNp current/ircd/s_misc.c current+fic/ircd/s_misc.c --- current/ircd/s_misc.c Tue Dec 21 07:28:17 2004 +++ current+fic/ircd/s_misc.c Tue Dec 21 07:29:04 2004 @@ -448,6 +448,9 @@ static void exit_server(aClient *cptr, a int exit_client(aClient *cptr, aClient *sptr, aClient *from, const char *comment) { +#ifdef WLINE + Reg aConfItem *aconf = NULL; +#endif char comment1[HOSTLEN + HOSTLEN + 2]; if (MyConnect(sptr)) @@ -558,6 +561,12 @@ int exit_client(aClient *cptr, aClient * if (cptr != NULL && sptr != cptr) { +#ifdef WLINE + if ((comment[0] != '"') && !IsClient(sptr) && (sptr->exitc != EXITC_PING) && + ((aconf = (aConfItem*)find_wline())) && !BadPtr(aconf->host)) { + sendto_one(sptr, ":%s NOTICE %s :%.200s", ME, BadTo(sptr->name), aconf->host); + } +#endif sendto_one(sptr, "ERROR :Closing Link: " "%s %s (%s)", get_client_name(sptr,FALSE), @@ -565,6 +574,12 @@ int exit_client(aClient *cptr, aClient * } else { +#ifdef WLINE + if ((comment[0] != '"') && !IsClient(sptr) && (sptr->exitc != EXITC_PING) && + ((aconf = (aConfItem*)find_wline())) && !BadPtr(aconf->host)) { + sendto_one(sptr, ":%s NOTICE %s :%.200s", ME, BadTo(sptr->name), aconf->host); + } +#endif sendto_one(sptr, "ERROR :Closing Link: %s (%s)", get_client_name(sptr,FALSE), comment); } @@ -803,6 +818,33 @@ static void exit_one_client(aClient *cpt { if ((sptr->flags & FLAGS_SPLIT) == 0) { +#ifdef NOCOMMENTABUSE + /* + ** For those channels where user can't speak + ** a part is generated and user removed. + ** If user is local also send to all + ** servers that he parted. --fiction + */ + if ((comment[0] == '"')) { + /* No point to check if the user didn't generate the QUIT himself */ + if ((sptr->user) && (lp = sptr->user->channel)) { + while (lp) { + if (!IsQuiet(lp->value.chptr) && can_send(sptr, lp->value.chptr)) { + sendto_channel_butserv(lp->value.chptr, sptr, ":%s PART %s :", + sptr->name, lp->value.chptr->chname); + if (sptr == cptr) { /* exiting user is local? */ + sendto_match_servs(lp->value.chptr, sptr, ":%s PART %s :", + sptr->name, lp->value.chptr->chname); + } + remove_user_from_channel(sptr, lp->value.chptr); + lp = sptr->user->channel; + } else { + lp=lp->next; + } /* if you remove one element next becomes current anyway */ + } + } + } +#endif sendto_serv_butone(cptr, ":%s QUIT :%s", sptr->name, comment); #ifdef USE_SERVICES @@ -897,7 +939,7 @@ static void exit_one_client(aClient *cpt if (IsAnonymous(lp->value.chptr) && !IsQuiet(lp->value.chptr)) { - sendto_channel_butserv(lp->value.chptr, sptr, ":%s PART %s :None", sptr->name, lp->value.chptr->chname); + sendto_channel_butserv(lp->value.chptr, sptr, ":%s PART %s :", sptr->name, lp->value.chptr->chname); } remove_user_from_channel(sptr,lp->value.chptr); } diff -urNp current/ircd/s_serv.c current+fic/ircd/s_serv.c --- current/ircd/s_serv.c Tue Dec 21 07:28:17 2004 +++ current+fic/ircd/s_serv.c Tue Dec 21 07:29:04 2004 @@ -1914,7 +1914,7 @@ static void report_configured_links(aCli #endif else tmp = conf; - + for (; tmp; tmp = tmp->next) if (tmp->status & mask) { @@ -1948,7 +1948,7 @@ static void report_configured_links(aCli { sendto_one(sptr, replies[p[1]], ME, BadTo(to), c, host, (pass) ? pass : null, - name, tmp->hold - timeofday, + name, ((tmp->hold)?(tmp->hold - timeofday):0), get_conf_class(tmp)); } #endif @@ -2033,6 +2033,26 @@ static void report_fd(aClient *sptr, aCl ); } +#ifdef CHANJUPE +int report_jline(aClient *sptr, char *to) + { + aConfItem *aconf; + + if (!MyConnect(sptr) || !is_allowed(sptr, ACL_CHANJUPE)) + { + sendto_one(sptr, replies[ERR_NOPRIVILEGES], ME, BadTo(to)); + return 0; + } + + for (aconf = jconf; aconf; aconf = aconf->next) + { + sendto_one(sptr,":%s %d %s %c %s :%s", ME, RPL_STATSQLINE, BadTo(to), + ((aconf->status == CONF_CHANJUPE) ? 'J': 'j'), aconf->host, aconf->passwd); + } + return 1; + } +#endif + int m_stats(aClient *cptr, aClient *sptr, int parc, char *parv[]) { static char Lformat[] = ":%s %d %s %s %u %lu %llu %lu %llu :%u"; @@ -2081,6 +2101,13 @@ int m_stats(aClient *cptr, aClient *sptr doall = !match(name, ME) && !match(cm, ME); wilds = index(cm, '*') || index(cm, '?') || index(cm, '#'); +#if defined(CLIENTS_CHANNEL) && (CLIENTS_CHANNEL_LEVEL & CCL_STATS) + if (sptr->user && stat) { + sendto_flag(SCH_CLIENT, "%s %s %s %s STATS %c %s", + sptr->user->uid, sptr->name, sptr->user->username, sptr->user->host, stat, name); + } +#endif + if (parc > 1 && parv[1][1] != '\0') { stat = '*'; @@ -2125,6 +2152,13 @@ int m_stats(aClient *cptr, aClient *sptr * are invisible not being visible to 'foreigners' who use * a wild card based search to list it. */ +#ifdef STATS_L_OPERONLY + if (!IsAnOper(sptr) && (stat=='L')) + { + sendto_one(sptr, replies[ERR_NOPRIVILEGES], ME, BadTo(parv[0])); + return 2; + } +#endif if (doall || wilds) { if (check_link(sptr)) @@ -2173,20 +2207,56 @@ int m_stats(aClient *cptr, aClient *sptr report_configured_links(cptr, parv[0], CONF_BOUNCE); break; case 'c': /* C and N conf lines */ +#ifdef STATS_C_OPERONLY + if (!IsAnOper(sptr)) + { + sendto_one(sptr, replies[ERR_NOPRIVILEGES], ME, BadTo(parv[0])); + return 2; + } +#endif report_configured_links(cptr, parv[0], CONF_CONNECT_SERVER| CONF_ZCONNECT_SERVER| CONF_NOCONNECT_SERVER); break; case 'd' : case 'D' : /* defines */ +#ifdef STATS_D_OPERONLY + if (!IsAnOper(sptr)) + { + sendto_one(sptr, replies[ERR_NOPRIVILEGES], ME, BadTo(parv[0])); + return 2; + } +#endif send_defines(cptr, parv[0]); break; case 'H' : case 'h' : /* H, L and D conf lines */ +#ifdef STATS_H_OPERONLY + if (!IsAnOper(sptr)) + { + sendto_one(sptr, replies[ERR_NOPRIVILEGES], ME, BadTo(parv[0])); + return 2; + } +#endif report_configured_links(cptr, parv[0], CONF_HUB|CONF_LEAF|CONF_DENY); break; case 'I' : case 'i' : /* I (and i) conf lines */ +#ifdef STATS_I_OPERONLY + if (!IsAnOper(sptr)) + { + sendto_one(sptr, replies[ERR_NOPRIVILEGES], ME, BadTo(parv[0])); + return 2; + } +#endif report_configured_links(cptr, parv[0], CONF_CLIENT); break; +#ifdef CHANJUPE + case 'J': case 'j' : /* J conf lines */ + if (!report_jline(sptr, parv[0])) + { + return 2; + } + break; +#endif case 'k' : /* temporary K lines */ #ifdef TKLINE #ifdef DISABLE_STATSTKLINE @@ -2239,6 +2309,13 @@ int m_stats(aClient *cptr, aClient *sptr } break; case 'o' : case 'O' : /* O (and o) lines */ +#ifdef STATS_O_OPERONLY + if (!IsAnOper(sptr)) + { + sendto_one(sptr, replies[ERR_NOPRIVILEGES], ME, BadTo(parv[0])); + return 2; + } +#endif report_configured_links(cptr, parv[0], CONF_OPS); break; case 'P': /* ports listening */ @@ -2285,6 +2362,13 @@ int m_stats(aClient *cptr, aClient *sptr #endif break; case 'Y' : case 'y' : /* Y lines */ +#ifdef STATS_Y_OPERONLY + if (!IsAnOper(sptr)) + { + sendto_one(sptr, replies[ERR_NOPRIVILEGES], ME, BadTo(parv[0])); + return 2; + } +#endif report_classes(cptr, parv[0]); break; case 'Z': diff -urNp current/ircd/s_user.c current+fic/ircd/s_user.c --- current/ircd/s_user.c Tue Dec 21 07:28:17 2004 +++ current+fic/ircd/s_user.c Mon Dec 27 13:57:11 2004 @@ -41,6 +41,12 @@ static int user_modes[] = { FLAGS_O FLAGS_WALLOP, 'w', FLAGS_RESTRICT, 'r', FLAGS_AWAY, 'a', +#ifdef IGNORE_STRANGERS + FLAGS_CMODE, 'c', +#endif +#ifdef HIDE_IDLETIME + FLAGS_HMODE, 'H', +#endif 0, 0 }; /* @@ -607,6 +613,8 @@ int register_user(aClient *cptr, aClient if (IsXlined(sptr)) { sptr->exitc = EXITC_XLINE; + sendto_flag(SCH_OPER, "X-lined %s@%s.", + user->username, sptr->sockhost); return exit_client(cptr, sptr, &me, XLINE_EXIT_REASON); } @@ -1594,6 +1602,15 @@ static int m_message(aClient *cptr, aCli if ((IsServer(cptr) && (acptr = find_uid(nick, NULL))) || (acptr = find_person(nick, NULL))) { +#ifdef IGNORE_STRANGERS + if (IsClient(sptr) && !IsAnOper(sptr) && IsIgnoringStrangers(acptr) && (acptr!=sptr) && + !CommonChannel(sptr->user, acptr->user)) { + if (MyConnect(sptr) && !notice) { + sendto_one(sptr, replies[RPL_AWAY], ME, BadTo(parv[0]), acptr->name, TXT_STRANGER); + } + continue; + } +#endif if (!notice && MyConnect(sptr) && acptr->user && (acptr->user->flags & FLAGS_AWAY)) send_away(sptr, acptr); @@ -1607,6 +1624,18 @@ static int m_message(aClient *cptr, aCli if ((IsPerson(sptr) || IsService(sptr) || IsServer(sptr)) && (chptr = find_channel(nick, NullChn))) { +#ifdef CHANJUPE + if (MyConnect(sptr) && !is_allowed(sptr, ACL_CHANJUPE)) + { + if (chptr->mode.mode & MODE_JUPED) + { + if (!notice) + sendto_one(sptr, replies[ERR_CANNOTSENDTOCHAN], ME, + BadTo(parv[0]), nick); + continue; + } + } +#endif if (can_send(sptr, chptr) == 0 || IsServer(sptr)) sendto_channel_butone(cptr, sptr, chptr, ":%s %s %s :%s", @@ -1714,6 +1743,17 @@ static int m_message(aClient *cptr, aCli !mycmp(user+1, acptr->user->username) && !mycmp(host+1, acptr->user->host)) { +#ifdef IGNORE_STRANGERS + if (IsClient(sptr) && !IsAnOper(sptr) && IsIgnoringStrangers(acptr) && (acptr!=sptr) && + !CommonChannel(sptr->user, acptr->user)) { + if (MyConnect(sptr) && !notice) { + sendto_one(sptr, replies[RPL_AWAY], ME, BadTo(parv[0]), acptr->name, TXT_STRANGER); + } + *user = '!'; + *host = '@'; + continue; + } +#endif sendto_prefix_one(acptr, sptr, ":%s %s %s :%s", parv[0], cmd, nick, parv[2]); *user = '!'; @@ -1756,11 +1796,22 @@ static int m_message(aClient *cptr, aCli *--host = '%'; if (acptr) { - if (count == 1) - sendto_prefix_one(acptr, sptr, + if (count == 1) + { +#ifdef IGNORE_STRANGERS + if (IsClient(sptr) && !IsAnOper(sptr) && IsIgnoringStrangers(acptr) && (acptr!=sptr) && + !CommonChannel(sptr->user, acptr->user)) { + if (MyConnect(sptr) && !notice) { + sendto_one(sptr, replies[RPL_AWAY], ME, BadTo(parv[0]), acptr->name, TXT_STRANGER); + } + continue; + } +#endif + sendto_prefix_one(acptr, sptr, ":%s %s %s :%s", parv[0], cmd, nick, parv[2]); + } else if (!notice) sendto_one(sptr, replies[ERR_TOOMANYTARGETS], ME, BadTo(parv[0]), "Duplicate", nick, @@ -1778,22 +1829,33 @@ static int m_message(aClient *cptr, aCli *--host = '%'; if (acptr) { - if (count == 1) + if (count == 1) + { +#ifdef IGNORE_STRANGERS + if (IsClient(sptr) && !IsAnOper(sptr) && IsIgnoringStrangers(acptr) && (acptr!=sptr) && + !CommonChannel(sptr->user, acptr->user)) { + if (MyConnect(sptr) && !notice) { + sendto_one(sptr, replies[RPL_AWAY], ME, BadTo(parv[0]), acptr->name, TXT_STRANGER); + } + continue; + } +#endif sendto_prefix_one(acptr, sptr, ":%s %s %s :%s", parv[0], cmd, nick, parv[2]); + } + } else if (!notice) sendto_one(sptr, replies[ERR_TOOMANYTARGETS], ME, BadTo(parv[0]), "Duplicate", nick, "No Message Delivered"); continue; } - } if (!notice) sendto_one(sptr, replies[ERR_NOSUCHNICK], ME, BadTo(parv[0]), nick); - } + } return penalty; } @@ -2192,12 +2254,15 @@ static void send_whois(aClient *sptr, aC sendto_one(sptr, replies[RPL_WHOISOPERATOR], ME, BadTo(sptr->name), name); if (acptr->user && MyConnect(acptr)) - sendto_one(sptr, replies[RPL_WHOISIDLE], ME, BadTo(sptr->name), - name, timeofday - user->last +#ifdef HIDE_IDLETIME + if (!IsHiddingIdletime(acptr) || IsAnOper(sptr)) +#endif + sendto_one(sptr, replies[RPL_WHOISIDLE], ME, BadTo(sptr->name), + name, timeofday - user->last #ifdef WHOIS_SIGNON_TIME - , acptr->firsttime + , acptr->firsttime #endif - ); + ); } /* @@ -3640,9 +3705,16 @@ int is_allowed(aClient *cptr, long funct /* minimal control, but nothing else service can do anyway. */ if (IsService(cptr)) { +#ifdef TKLINE if (function == ACL_TKLINE && (cptr->service->wants & SERVICE_WANT_TKLINE)) return 1; +#endif +#ifdef KLINE + if (function == ACL_KLINE && + (cptr->service->wants & SERVICE_WANT_KLINE)) + return 1; +#endif return 0; } @@ -3676,13 +3748,13 @@ void send_away(aClient *sptr, aClient *a /* Building buffer and using it instead of "Gone" would be * a better code, but a bit slower; just rememeber about this * one when ever changing RPL_AWAY --B. */ - sendto_one(sptr, ":%s 301 %s %s :" - "Gone, for more info use WHOIS %s %s", - ME, sptr->name, acptr->name, + sendto_one(sptr, ":%s %d %s %s :" + "%s%s %s %s", + ME, RPL_AWAY, sptr->name, acptr->name, + TXT_AWAY, TXT_AWAY_INFO, acptr->name, acptr->name); -#else - sendto_one(sptr, replies[RPL_AWAY], ME, sptr->name, - acptr->name, "Gone"); +#else + sendto_one(sptr, replies[RPL_AWAY], ME, BadTo(parv[0]), acptr->name, TXT_AWAY); #endif } } diff -urNp current/ircd/service_def.h current+fic/ircd/service_def.h --- current/ircd/service_def.h Tue Dec 21 07:28:17 2004 +++ current+fic/ircd/service_def.h Tue Dec 21 07:29:04 2004 @@ -28,9 +28,10 @@ #define SERVICE_WANT_CONNLOG 0x20000000 /* FNAME_CONNLOG */ #define SERVICE_WANT_TKLINE 0x40000000 /* service wants to TKLINE */ +#define SERVICE_WANT_KLINE 0x80000000 /* service wants to KLINE */ /* masks */ -#define SERVICE_MASK_GLOBAL 0x00007000 /*for these,service must be global*/ +#define SERVICE_MASK_GLOBAL 0xF0007000 /*for these,service must be global*/ #define SERVICE_MASK_PREFIX 0x00000FFF /* these actions have a prefix */ #define SERVICE_MASK_ALL 0x7F00FFFF /* all possible actions */ #define SERVICE_MASK_NUM (SERVICE_WANT_NICK|SERVICE_WANT_USER|\ diff -urNp current/support/config.h.dist current+fic/support/config.h.dist --- current/support/config.h.dist Tue Dec 21 07:28:16 2004 +++ current+fic/support/config.h.dist Sun Dec 26 22:46:36 2004 @@ -140,7 +140,7 @@ * 1 server = 1 connection, 1 user = 1 connection. * Due to various sanity checks during startup, minimum is 13. */ -#define MAXCONNECTIONS 50 +#define MAXCONNECTIONS 1024 /* MAXIMUM LINKS * @@ -222,7 +222,7 @@ * If file is not absolute path, ircd etc path is prepended. * Note that "#include" must be at the beginning of the line. */ -#undef CONFIG_DIRECTIVE_INCLUDE +#define CONFIG_DIRECTIVE_INCLUDE /* * If you wish to have the server send 'vital' messages about server @@ -275,7 +275,7 @@ * Define this if you want to use crypted passwords for operators in your * ircd.conf file. See contrib/mkpasswd/README for more details on this. */ -#undef CRYPT_OPER_PASSWORD +#define CRYPT_OPER_PASSWORD /* * If you want to store encrypted passwords in N-lines for server links, @@ -324,7 +324,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 @@ -359,7 +359,7 @@ * The library and the include files must have been found by configure, * if you have installed the zlib after running configure, run it again. */ -#undef ZIP_LINKS +#define ZIP_LINKS /* * Defining this will add an artificial 2 seconds delay for accepting @@ -385,7 +385,7 @@ * and the rest via ip6.int. * Note that ip6.int is officially discontinued. */ -#undef SIXBONE_HACK +#define SIXBONE_HACK /* ** Servers with many clients and lots of K:lines are having noticable @@ -418,15 +418,18 @@ ** Define this to get oper-only &CLIENTS channel with clients connects, ** quits and nick changes. */ -#undef CLIENTS_CHANNEL +#define CLIENTS_CHANNEL /* ** Bitmask defining type of information sent to &CLIENTS, combine from ** CCL_CONN (client uid, nick, username, host and IP), CCL_CONNINFO ** (also user info), CCL_QUIT (client uid, nick, username, host and IP), -** CCL_QUITINFO (also quit reason), CCL_NICK (all nick changes). +** CCL_QUITINFO (also quit reason), CCL_NICK (all nick changes), +** CCL_STATS (show STATS requests), CCL_CHANJUPE (show info about +** added jupes or messages about clients trying to join a juped channel +** - needs defined CHANJUPE to work). */ -/* #define CLIENTS_CHANNEL_LEVEL (CCL_CONN|CCL_QUIT) */ +#define CLIENTS_CHANNEL_LEVEL (CCL_CONN|CCL_QUIT) /* ** This adds ability to ban users with specified realnames from @@ -481,7 +484,7 @@ /* * Max number of channels a user is allowed to join. */ -#define MAXCHANNELSPERUSER 21 /* Recommended value: 21 */ +#define MAXCHANNELSPERUSER 30 /* Recommended value: 21 */ /* * USE_IAUTH makes ircd use the iauth program for authentication. @@ -534,6 +537,88 @@ */ #undef NO_OPER_REMOTE +/* begin of +fic */ + +/* + * Usermode +c means that a user who wants to send a message to you must share + * at least one common channel. + */ +#undef IGNORE_STRANGERS + +/* + * If a user is not allowed to speak on a channel, disallow him to + * annoy with his PART / QUIT / JOIN 0 message aswell. + */ +#define NO_COMMENT_ABUSE + +/* + * If an unregistered client disconnects not because himself did QUIT + * contents of the W:line from the ircd.conf are shown as a NOTICE. + * (There should only be one such line, else latest is used.) + * It is supposed to be an URL where the user can get more info. + */ +#define WLINE + +/* + * Disable stats L (stats l still works) for non-opers. + * This is BOFH and should never be used. + */ +#undef STATS_L_OPERONLY + +/* + * Disable other stats (upper and lower case) for non-opers. + * This is BOFH and should never be used. + */ +#undef STATS_C_OPERONLY +#undef STATS_D_OPERONLY +#undef STATS_H_OPERONLY +#undef STATS_I_OPERONLY +#undef STATS_O_OPERONLY +#undef STATS_Y_OPERONLY + +/* + * Hide idle time from non-opers (+H usermode) + * Yet another feature for the lazy BOFH. + */ +#undef HIDE_IDLETIME + +/* + * A cool idea is to have jupes in a different file than K:lines + * and just #include them in ircd.conf! + */ + +/* + * Channel jupe (original by jv) + * (IMPORTANT: the JUPE_FILE needs to exist! So make sure to touch filename before using RESV) + */ +#undef CHANJUPE +#ifdef CHANJUPE +#define JUPE_FILE IRCDCONF_PATH +#endif + +/* + * K:line in ircd.conf (taken tkline as the source, original idea from Cr-patch) + * (IMPORTANT: the KLINE_FILE needs to exist! So make sure to touch filename before using KLINE) + */ +#define KLINE +#ifdef KLINE +#define KLINE_FILE IRCDCONF_PATH +#endif + +/* Various texts */ + +#ifdef IGNORE_STRANGERS +# define TXT_STRANGER "User is ignoring messages from strangers." +#endif + +/* + * Breaks the RFC by allowing a SERVICE to do SQUERY + * (useful for BOPM using TkServ) + */ +#undef SERVICE_CAN_SQUERY + +/* end of +fic */ + /* ** CLCHNO defines changes in local clients count, which are shown ** as "Local in/de-crease" @@ -558,6 +643,13 @@ ** Leave defined for more helpful message. */ #define AWAY_MOREINFO + +/* Default away message */ +#define TXT_AWAY "Gone" +#ifdef AWAY_MOREINFO +#define TXT_AWAY_INFO ", for more info use WHOIS" +/* nick nick is appended aswell */ +#endif /* ** If you do not wish your clients to use "nick 0" during registration,