From 8cc12805d727007d79643fcad676656407444315 Mon Sep 17 00:00:00 2001 From: Valery Yatsko Date: Mon, 7 Apr 2008 18:26:59 +0400 Subject: [PATCH 1/9] m_sjoin.c gone, merged with m_join.c --- TODO | 11 + modules/Makefile.in | 1 - modules/core/m_join.c | 611 +++++++++++++++++++++++++++- modules/core/m_sjoin.c | 890 ----------------------------------------- 4 files changed, 619 insertions(+), 894 deletions(-) delete mode 100644 modules/core/m_sjoin.c diff --git a/TODO b/TODO index 6cdcf83d1..de59a29cf 100644 --- a/TODO +++ b/TODO @@ -14,7 +14,18 @@ [x] clean up maxconnections kludges &c [x] in-process SSL [x] port and use ratbox ssld for server links +[x] ssl stuff + [x] client-to-client ssl + [x] server-to-server ssl + [x] ssl usermode (+Z) + [ ] ssl channelmode (by module?) [ ] merge some stuff from ircd-seven directly (to be determined what) [?] remote d:lines support? + [?] +C (noctcp) channel/usermode [ ] gk:line/akill syncing [ ] drop non-TS6 (legacy protocol) support +[ ] module engine rework + [ ] more beautiful way of adding new channel modes by module +[ ] other stuff + [ ] merge m_join.c and m_sjoin.c in one module (same functions, done in ratbox3) + [ ] merge s_gline.c and m_gline.c in one module (for pretty look, done in ratbox3) diff --git a/modules/Makefile.in b/modules/Makefile.in index ceb027a71..73421d8f4 100644 --- a/modules/Makefile.in +++ b/modules/Makefile.in @@ -47,7 +47,6 @@ CORE_SRCS = \ core/m_part.c \ core/m_quit.c \ core/m_server.c \ - core/m_sjoin.c \ core/m_squit.c TSRCS = \ diff --git a/modules/core/m_join.c b/modules/core/m_join.c index 7c5d38464..1b8120a91 100644 --- a/modules/core/m_join.c +++ b/modules/core/m_join.c @@ -44,6 +44,7 @@ static int m_join(struct Client *, struct Client *, int, const char **); static int ms_join(struct Client *, struct Client *, int, const char **); +static int ms_sjoin(struct Client *, struct Client *, int, const char **); static int h_can_create_channel; static int h_channel_join; @@ -53,7 +54,12 @@ struct Message join_msgtab = { {mg_unreg, {m_join, 2}, {ms_join, 2}, mg_ignore, mg_ignore, {m_join, 2}} }; -mapi_clist_av1 join_clist[] = { &join_msgtab, NULL }; +struct Message sjoin_msgtab = { + "SJOIN", 0, 0, 0, MFLG_SLOW, + {mg_unreg, mg_ignore, mg_ignore, {ms_sjoin, 0}, mg_ignore, mg_ignore} +}; + +mapi_clist_av1 join_clist[] = { &join_msgtab, &sjoin_msgtab, NULL }; mapi_hlist_av1 join_hlist[] = { { "can_create_channel", &h_can_create_channel }, @@ -69,9 +75,14 @@ static int check_channel_name_loc(struct Client *source_p, const char *name); static void set_final_mode(struct Mode *mode, struct Mode *oldmode); static void remove_our_modes(struct Channel *chptr, struct Client *source_p); +static void remove_ban_list(struct Channel *chptr, struct Client *source_p, + rb_dlink_list * list, char c, int cap, int mems); + static char modebuf[MODEBUFLEN]; static char parabuf[MODEBUFLEN]; +static const char *para[MAXMODEPARAMS]; static char *mbuf; +static int pargs; /* Check what we will forward to, without sending any notices to the user * -- jilles @@ -516,6 +527,527 @@ ms_join(struct Client *client_p, struct Client *source_p, int parc, const char * return 0; } +static int +ms_sjoin(struct Client *client_p, struct Client *source_p, int parc, const char *parv[]) +{ + static char buf_nick[BUFSIZE]; + static char buf_uid[BUFSIZE]; + static const char empty_modes[] = "0"; + struct Channel *chptr; + struct Client *target_p, *fakesource_p; + time_t newts; + time_t oldts; + static struct Mode mode, *oldmode; + const char *modes; + int args = 0; + int keep_our_modes = 1; + int keep_new_modes = 1; + int fl; + int isnew; + int mlen_nick, mlen_uid; + int len_nick; + int len_uid; + int len; + int joins = 0; + const char *s; + char *ptr_nick; + char *ptr_uid; + char *p; + int i, joinc = 0, timeslice = 0; + static char empty[] = ""; + rb_dlink_node *ptr, *next_ptr; + + if(!IsChannelName(parv[2]) || !check_channel_name(parv[2])) + return 0; + + /* SJOIN's for local channels can't happen. */ + if(*parv[2] == '&') + return 0; + + modebuf[0] = parabuf[0] = mode.key[0] = mode.forward[0] = '\0'; + pargs = mode.mode = mode.limit = mode.join_num = mode.join_time = 0; + + /* Hide connecting server on netburst -- jilles */ + if (ConfigServerHide.flatten_links && !HasSentEob(source_p)) + fakesource_p = &me; + else + fakesource_p = source_p; + + mbuf = modebuf; + newts = atol(parv[1]); + + s = parv[3]; + while (*s) + { + switch (*(s++)) + { + case 'i': + mode.mode |= MODE_INVITEONLY; + break; + case 'n': + mode.mode |= MODE_NOPRIVMSGS; + break; + case 'p': + mode.mode |= MODE_PRIVATE; + break; + case 's': + mode.mode |= MODE_SECRET; + break; + case 'm': + mode.mode |= MODE_MODERATED; + break; + case 't': + mode.mode |= MODE_TOPICLIMIT; + break; + case 'r': + mode.mode |= MODE_REGONLY; + break; + case 'L': + mode.mode |= MODE_EXLIMIT; + break; + case 'P': + mode.mode |= MODE_PERMANENT; + break; + case 'c': + mode.mode |= MODE_NOCOLOR; + break; + case 'g': + mode.mode |= MODE_FREEINVITE; + break; + case 'z': + mode.mode |= MODE_OPMODERATE; + break; + case 'F': + mode.mode |= MODE_FREETARGET; + break; + case 'Q': + mode.mode |= MODE_DISFORWARD; + break; + case 'f': + strlcpy(mode.forward, parv[4 + args], sizeof(mode.forward)); + args++; + if(parc < 5 + args) + return 0; + break; + case 'j': + sscanf(parv[4 + args], "%d:%d", &joinc, ×lice); + args++; + mode.join_num = joinc; + mode.join_time = timeslice; + if(parc < 5 + args) + return 0; + break; + case 'k': + strlcpy(mode.key, parv[4 + args], sizeof(mode.key)); + args++; + if(parc < 5 + args) + return 0; + break; + case 'l': + mode.limit = atoi(parv[4 + args]); + args++; + if(parc < 5 + args) + return 0; + break; + } + } + + if(parv[args + 4]) + { + s = parv[args + 4]; + + /* remove any leading spaces */ + while (*s == ' ') + s++; + } + else + s = ""; + + if((chptr = get_or_create_channel(source_p, parv[2], &isnew)) == NULL) + return 0; /* channel name too long? */ + + + oldts = chptr->channelts; + oldmode = &chptr->mode; + +#ifdef IGNORE_BOGUS_TS + if(newts < 800000000) + { + sendto_realops_snomask(SNO_DEBUG, L_ALL, + "*** Bogus TS %ld on %s ignored from %s", + (long) newts, chptr->chname, client_p->name); + + newts = (oldts == 0) ? oldts : 800000000; + } +#else + if(!isnew && !newts && oldts) + { + sendto_channel_local(ALL_MEMBERS, chptr, + ":%s NOTICE %s :*** Notice -- TS for %s " + "changed from %ld to 0", + me.name, chptr->chname, chptr->chname, (long) oldts); + sendto_realops_snomask(SNO_GENERAL, L_ALL, + "Server %s changing TS on %s from %ld to 0", + source_p->name, chptr->chname, (long) oldts); + } +#endif + + if(isnew) + chptr->channelts = newts; + + else if(newts == 0 || oldts == 0) + chptr->channelts = 0; + else if(newts == oldts) + ; + else if(newts < oldts) + { + /* If configured, kick people trying to join +i/+k + * channels by recreating them on split servers. + * Don't kick if the source has sent EOB (services + * deopping everyone by TS-1 SJOIN). + * -- jilles */ + if (ConfigChannel.kick_on_split_riding && + !HasSentEob(source_p) && + ((mode.mode & MODE_INVITEONLY) || + (mode.key[0] != 0 && irccmp(mode.key, oldmode->key) != 0))) + { + struct membership *msptr; + struct Client *who; + int l = rb_dlink_list_length(&chptr->members); + int b = rb_dlink_list_length(&chptr->banlist) + + rb_dlink_list_length(&chptr->exceptlist) + + rb_dlink_list_length(&chptr->invexlist) + + rb_dlink_list_length(&chptr->quietlist); + + RB_DLINK_FOREACH_SAFE(ptr, next_ptr, chptr->locmembers.head) + { + msptr = ptr->data; + who = msptr->client_p; + sendto_one(who, ":%s KICK %s %s :Net Rider", + me.name, chptr->chname, who->name); + + sendto_server(NULL, chptr, CAP_TS6, NOCAPS, + ":%s KICK %s %s :Net Rider", + me.id, chptr->chname, + who->id); + sendto_server(NULL, chptr, NOCAPS, CAP_TS6, + ":%s KICK %s %s :Net Rider", + me.name, chptr->chname, who->name); + remove_user_from_channel(msptr); + if (--l == 0) + break; + } + if (l == 0) + { + /* Channel was emptied, create a new one */ + if((chptr = get_or_create_channel(source_p, parv[2], &isnew)) == NULL) + return 0; /* oops! */ + + /* If the source does not do TS6, + * nontimestamped bans have been sent to it, + * but we have just lost those here. Let's + * warn the channel about this. Because + * of the kicks, any users on the channel + * will be at client_p. -- jilles */ + if (!has_id(source_p) && b > 0) + sendto_one(client_p, ":%s NOTICE %s :*** Notice -- possible ban desync on %s, please remove any bans just added by servers", get_id(&me, client_p), parv[2], parv[2]); + oldmode = &chptr->mode; + } + } + keep_our_modes = NO; + chptr->channelts = newts; + } + else + keep_new_modes = NO; + + if(!keep_new_modes) + mode = *oldmode; + else if(keep_our_modes) + { + mode.mode |= oldmode->mode; + if(oldmode->limit > mode.limit) + mode.limit = oldmode->limit; + if(strcmp(mode.key, oldmode->key) < 0) + strcpy(mode.key, oldmode->key); + if(oldmode->join_num > mode.join_num || + (oldmode->join_num == mode.join_num && + oldmode->join_time > mode.join_time)) + { + mode.join_num = oldmode->join_num; + mode.join_time = oldmode->join_time; + } + if(irccmp(mode.forward, oldmode->forward) < 0) + strcpy(mode.forward, oldmode->forward); + } + else + { + /* If setting -j, clear join throttle state -- jilles */ + if (!mode.join_num) + chptr->join_count = chptr->join_delta = 0; + } + + set_final_mode(&mode, oldmode); + chptr->mode = mode; + + /* Lost the TS, other side wins, so remove modes on this side */ + if(!keep_our_modes) + { + remove_our_modes(chptr, fakesource_p); + RB_DLINK_FOREACH_SAFE(ptr, next_ptr, chptr->invites.head) + { + del_invite(chptr, ptr->data); + } + sendto_channel_local(ALL_MEMBERS, chptr, + ":%s NOTICE %s :*** Notice -- TS for %s changed from %ld to %ld", + me.name, chptr->chname, chptr->chname, + (long) oldts, (long) newts); + /* Update capitalization in channel name, this makes the + * capitalization timestamped like modes are -- jilles */ + strcpy(chptr->chname, parv[2]); + } + + if(*modebuf != '\0') + sendto_channel_local(ALL_MEMBERS, chptr, ":%s MODE %s %s %s", + fakesource_p->name, chptr->chname, modebuf, parabuf); + + *modebuf = *parabuf = '\0'; + + if(parv[3][0] != '0' && keep_new_modes) + modes = channel_modes(chptr, source_p); + else + modes = empty_modes; + + mlen_nick = rb_sprintf(buf_nick, ":%s SJOIN %ld %s %s :", + source_p->name, (long) chptr->channelts, parv[2], modes); + ptr_nick = buf_nick + mlen_nick; + + /* working on the presumption eventually itll be more efficient to + * build a TS6 buffer without checking its needed.. + */ + mlen_uid = rb_sprintf(buf_uid, ":%s SJOIN %ld %s %s :", + use_id(source_p), (long) chptr->channelts, parv[2], modes); + ptr_uid = buf_uid + mlen_uid; + + mbuf = modebuf; + para[0] = para[1] = para[2] = para[3] = empty; + pargs = 0; + len_nick = len_uid = 0; + + /* if theres a space, theres going to be more than one nick, change the + * first space to \0, so s is just the first nick, and point p to the + * second nick + */ + if((p = strchr(s, ' ')) != NULL) + { + *p++ = '\0'; + } + + *mbuf++ = '+'; + + while (s) + { + fl = 0; + + for (i = 0; i < 2; i++) + { + if(*s == '@') + { + fl |= CHFL_CHANOP; + s++; + } + else if(*s == '+') + { + fl |= CHFL_VOICE; + s++; + } + } + + /* if the client doesnt exist or is fake direction, skip. */ + if(!(target_p = find_client(s)) || + (target_p->from != client_p) || !IsPerson(target_p)) + goto nextnick; + + /* we assume for these we can fit at least one nick/uid in.. */ + + /* check we can fit another status+nick+space into a buffer */ + if((mlen_nick + len_nick + NICKLEN + 3) > (BUFSIZE - 3)) + { + *(ptr_nick - 1) = '\0'; + sendto_server(client_p->from, NULL, NOCAPS, CAP_TS6, "%s", buf_nick); + ptr_nick = buf_nick + mlen_nick; + len_nick = 0; + } + + if((mlen_uid + len_uid + IDLEN + 3) > (BUFSIZE - 3)) + { + *(ptr_uid - 1) = '\0'; + sendto_server(client_p->from, NULL, CAP_TS6, NOCAPS, "%s", buf_uid); + ptr_uid = buf_uid + mlen_uid; + len_uid = 0; + } + + if(keep_new_modes) + { + if(fl & CHFL_CHANOP) + { + *ptr_nick++ = '@'; + *ptr_uid++ = '@'; + len_nick++; + len_uid++; + } + if(fl & CHFL_VOICE) + { + *ptr_nick++ = '+'; + *ptr_uid++ = '+'; + len_nick++; + len_uid++; + } + } + + /* copy the nick to the two buffers */ + len = rb_sprintf(ptr_nick, "%s ", target_p->name); + ptr_nick += len; + len_nick += len; + len = rb_sprintf(ptr_uid, "%s ", use_id(target_p)); + ptr_uid += len; + len_uid += len; + + if(!keep_new_modes) + fl = 0; + + if(!IsMember(target_p, chptr)) + { + add_user_to_channel(chptr, target_p, fl); + sendto_channel_local(ALL_MEMBERS, chptr, ":%s!%s@%s JOIN :%s", + target_p->name, + target_p->username, target_p->host, parv[2]); + joins++; + } + + if(fl & CHFL_CHANOP) + { + *mbuf++ = 'o'; + para[pargs++] = target_p->name; + + /* a +ov user.. bleh */ + if(fl & CHFL_VOICE) + { + /* its possible the +o has filled up MAXMODEPARAMS, if so, start + * a new buffer + */ + if(pargs >= MAXMODEPARAMS) + { + *mbuf = '\0'; + sendto_channel_local(ALL_MEMBERS, chptr, + ":%s MODE %s %s %s %s %s %s", + fakesource_p->name, chptr->chname, + modebuf, + para[0], para[1], para[2], para[3]); + mbuf = modebuf; + *mbuf++ = '+'; + para[0] = para[1] = para[2] = para[3] = NULL; + pargs = 0; + } + + *mbuf++ = 'v'; + para[pargs++] = target_p->name; + } + } + else if(fl & CHFL_VOICE) + { + *mbuf++ = 'v'; + para[pargs++] = target_p->name; + } + + if(pargs >= MAXMODEPARAMS) + { + *mbuf = '\0'; + sendto_channel_local(ALL_MEMBERS, chptr, + ":%s MODE %s %s %s %s %s %s", + fakesource_p->name, + chptr->chname, + modebuf, para[0], para[1], para[2], para[3]); + mbuf = modebuf; + *mbuf++ = '+'; + para[0] = para[1] = para[2] = para[3] = NULL; + pargs = 0; + } + + nextnick: + /* p points to the next nick */ + s = p; + + /* if there was a trailing space and p was pointing to it, then we + * need to exit.. this has the side effect of breaking double spaces + * in an sjoin.. but that shouldnt happen anyway + */ + if(s && (*s == '\0')) + s = p = NULL; + + /* if p was NULL due to no spaces, s wont exist due to the above, so + * we cant check it for spaces.. if there are no spaces, then when + * we next get here, s will be NULL + */ + if(s && ((p = strchr(s, ' ')) != NULL)) + { + *p++ = '\0'; + } + } + + *mbuf = '\0'; + if(pargs) + { + sendto_channel_local(ALL_MEMBERS, chptr, + ":%s MODE %s %s %s %s %s %s", + fakesource_p->name, chptr->chname, modebuf, + para[0], CheckEmpty(para[1]), + CheckEmpty(para[2]), CheckEmpty(para[3])); + } + + if(!joins && !(chptr->mode.mode & MODE_PERMANENT) && isnew) + { + destroy_channel(chptr); + + return 0; + } + + /* Keep the colon if we're sending an SJOIN without nicks -- jilles */ + if (joins) + { + *(ptr_nick - 1) = '\0'; + *(ptr_uid - 1) = '\0'; + } + + sendto_server(client_p->from, NULL, CAP_TS6, NOCAPS, "%s", buf_uid); + sendto_server(client_p->from, NULL, NOCAPS, CAP_TS6, "%s", buf_nick); + + /* if the source does TS6 we have to remove our bans. Its now safe + * to issue -b's to the non-ts6 servers, as the sjoin we've just + * sent will kill any ops they have. + */ + if(!keep_our_modes && source_p->id[0] != '\0') + { + if(rb_dlink_list_length(&chptr->banlist) > 0) + remove_ban_list(chptr, fakesource_p, &chptr->banlist, 'b', NOCAPS, ALL_MEMBERS); + + if(rb_dlink_list_length(&chptr->exceptlist) > 0) + remove_ban_list(chptr, fakesource_p, &chptr->exceptlist, + 'e', CAP_EX, ONLY_CHANOPS); + + if(rb_dlink_list_length(&chptr->invexlist) > 0) + remove_ban_list(chptr, fakesource_p, &chptr->invexlist, + 'I', CAP_IE, ONLY_CHANOPS); + + if(rb_dlink_list_length(&chptr->quietlist) > 0) + remove_ban_list(chptr, fakesource_p, &chptr->quietlist, + 'q', NOCAPS, ALL_MEMBERS); + + chptr->bants++; + } + + return 0; +} + /* * do_join_0 * @@ -592,7 +1124,7 @@ set_final_mode(struct Mode *mode, struct Mode *oldmode) int i; /* ok, first get a list of modes we need to add */ - for(i = 0; chmode_flags[i].letter; i++) + for (i = 0; chmode_flags[i].letter; i++) { if((mode->mode & chmode_flags[i].mode) && !(oldmode->mode & chmode_flags[i].mode)) { @@ -606,7 +1138,7 @@ set_final_mode(struct Mode *mode, struct Mode *oldmode) } /* now the ones we need to remove. */ - for(i = 0; chmode_flags[i].letter; i++) + for (i = 0; chmode_flags[i].letter; i++) { if((oldmode->mode & chmode_flags[i].mode) && !(mode->mode & chmode_flags[i].mode)) { @@ -638,6 +1170,7 @@ set_final_mode(struct Mode *mode, struct Mode *oldmode) *mbuf++ = 'k'; len = rb_sprintf(pbuf, "%s ", oldmode->key); pbuf += len; + pargs++; } if(oldmode->join_num && !mode->join_num) { @@ -667,6 +1200,7 @@ set_final_mode(struct Mode *mode, struct Mode *oldmode) *mbuf++ = 'l'; len = rb_sprintf(pbuf, "%d ", mode->limit); pbuf += len; + pargs++; } if(mode->key[0] && strcmp(oldmode->key, mode->key)) { @@ -678,6 +1212,7 @@ set_final_mode(struct Mode *mode, struct Mode *oldmode) *mbuf++ = 'k'; len = rb_sprintf(pbuf, "%s ", mode->key); pbuf += len; + pargs++; } if(mode->join_num && (oldmode->join_num != mode->join_num || oldmode->join_time != mode->join_time)) { @@ -689,6 +1224,7 @@ set_final_mode(struct Mode *mode, struct Mode *oldmode) *mbuf++ = 'j'; len = rb_sprintf(pbuf, "%d:%d ", mode->join_num, mode->join_time); pbuf += len; + pargs++; } if(mode->forward[0] && strcmp(oldmode->forward, mode->forward) && ConfigChannel.use_forward) { @@ -700,6 +1236,7 @@ set_final_mode(struct Mode *mode, struct Mode *oldmode) *mbuf++ = 'f'; len = rb_sprintf(pbuf, "%s ", mode->forward); pbuf += len; + pargs++; } *mbuf = '\0'; } @@ -801,3 +1338,71 @@ remove_our_modes(struct Channel *chptr, struct Client *source_p) } } + +/* remove_ban_list() + * + * inputs - channel, source, list to remove, char of mode, caps needed + * outputs - + * side effects - given list is removed, with modes issued to local clients + * and non-TS6 servers. + */ +static void +remove_ban_list(struct Channel *chptr, struct Client *source_p, + rb_dlink_list * list, char c, int cap, int mems) +{ + static char lmodebuf[BUFSIZE]; + static char lparabuf[BUFSIZE]; + struct Ban *banptr; + rb_dlink_node *ptr; + rb_dlink_node *next_ptr; + char *pbuf; + int count = 0; + int cur_len, mlen, plen; + + pbuf = lparabuf; + + cur_len = mlen = rb_sprintf(lmodebuf, ":%s MODE %s -", source_p->name, chptr->chname); + mbuf = lmodebuf + mlen; + + RB_DLINK_FOREACH_SAFE(ptr, next_ptr, list->head) + { + banptr = ptr->data; + + /* trailing space, and the mode letter itself */ + plen = strlen(banptr->banstr) + 2; + + if(count >= MAXMODEPARAMS || (cur_len + plen) > BUFSIZE - 4) + { + /* remove trailing space */ + *mbuf = '\0'; + *(pbuf - 1) = '\0'; + + sendto_channel_local(mems, chptr, "%s %s", lmodebuf, lparabuf); + /* Tricky tricky. If we changed source_p to &me + * in ms_sjoin(), this still won't send stuff + * where it should not be sent, because the + * real source_p does TS6 -- jilles */ + sendto_server(source_p, chptr, cap, CAP_TS6, "%s %s", lmodebuf, lparabuf); + + cur_len = mlen; + mbuf = lmodebuf + mlen; + pbuf = lparabuf; + count = 0; + } + + *mbuf++ = c; + cur_len += plen; + pbuf += rb_sprintf(pbuf, "%s ", banptr->banstr); + count++; + + free_ban(banptr); + } + + *mbuf = '\0'; + *(pbuf - 1) = '\0'; + sendto_channel_local(mems, chptr, "%s %s", lmodebuf, lparabuf); + sendto_server(source_p, chptr, cap, CAP_TS6, "%s %s", lmodebuf, lparabuf); + + list->head = list->tail = NULL; + list->length = 0; +} diff --git a/modules/core/m_sjoin.c b/modules/core/m_sjoin.c deleted file mode 100644 index b8eda6aec..000000000 --- a/modules/core/m_sjoin.c +++ /dev/null @@ -1,890 +0,0 @@ -/* - * ircd-ratbox: A slightly useful ircd. - * m_sjoin.c: Joins a user to a channel. - * - * Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center - * Copyright (C) 1996-2002 Hybrid Development Team - * Copyright (C) 2002-2005 ircd-ratbox development team - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA - * - * $Id: m_sjoin.c 3434 2007-04-28 23:47:25Z jilles $ - */ - -#include "stdinc.h" -#include "channel.h" -#include "client.h" -#include "hash.h" -#include "irc_string.h" -#include "sprintf_irc.h" -#include "ircd.h" -#include "numeric.h" -#include "send.h" -#include "common.h" -#include "msg.h" -#include "parse.h" -#include "modules.h" -#include "s_serv.h" -#include "s_conf.h" - -static int ms_sjoin(struct Client *, struct Client *, int, const char **); - -struct Message sjoin_msgtab = { - "SJOIN", 0, 0, 0, MFLG_SLOW, - {mg_unreg, mg_ignore, mg_ignore, {ms_sjoin, 0}, mg_ignore, mg_ignore} -}; - -mapi_clist_av1 sjoin_clist[] = { &sjoin_msgtab, NULL }; - -DECLARE_MODULE_AV1(sjoin, NULL, NULL, sjoin_clist, NULL, NULL, "$Revision: 3434 $"); - -/* - * ms_sjoin - * parv[0] - sender - * parv[1] - TS - * parv[2] - channel - * parv[3] - modes + n arguments (key and/or limit) - * parv[4+n] - flags+nick list (all in one parameter) - * - * process a SJOIN, taking the TS's into account to either ignore the - * incoming modes or undo the existing ones or merge them, and JOIN - * all the specified users while sending JOIN/MODEs to local clients - */ - - -static char modebuf[MODEBUFLEN]; -static char parabuf[MODEBUFLEN]; -static const char *para[MAXMODEPARAMS]; -static char *mbuf; -static int pargs; - -static void set_final_mode(struct Mode *mode, struct Mode *oldmode); -static void remove_our_modes(struct Channel *chptr, struct Client *source_p); -static void remove_ban_list(struct Channel *chptr, struct Client *source_p, - rb_dlink_list * list, char c, int cap, int mems); - -static int -ms_sjoin(struct Client *client_p, struct Client *source_p, int parc, const char *parv[]) -{ - static char buf_nick[BUFSIZE]; - static char buf_uid[BUFSIZE]; - static const char empty_modes[] = "0"; - struct Channel *chptr; - struct Client *target_p, *fakesource_p; - time_t newts; - time_t oldts; - static struct Mode mode, *oldmode; - const char *modes; - int args = 0; - int keep_our_modes = 1; - int keep_new_modes = 1; - int fl; - int isnew; - int mlen_nick, mlen_uid; - int len_nick; - int len_uid; - int len; - int joins = 0; - const char *s; - char *ptr_nick; - char *ptr_uid; - char *p; - int i, joinc = 0, timeslice = 0; - static char empty[] = ""; - rb_dlink_node *ptr, *next_ptr; - - if(!IsChannelName(parv[2]) || !check_channel_name(parv[2])) - return 0; - - /* SJOIN's for local channels can't happen. */ - if(*parv[2] == '&') - return 0; - - modebuf[0] = parabuf[0] = mode.key[0] = mode.forward[0] = '\0'; - pargs = mode.mode = mode.limit = mode.join_num = mode.join_time = 0; - - /* Hide connecting server on netburst -- jilles */ - if (ConfigServerHide.flatten_links && !HasSentEob(source_p)) - fakesource_p = &me; - else - fakesource_p = source_p; - - mbuf = modebuf; - newts = atol(parv[1]); - - s = parv[3]; - while (*s) - { - switch (*(s++)) - { - case 'i': - mode.mode |= MODE_INVITEONLY; - break; - case 'n': - mode.mode |= MODE_NOPRIVMSGS; - break; - case 'p': - mode.mode |= MODE_PRIVATE; - break; - case 's': - mode.mode |= MODE_SECRET; - break; - case 'm': - mode.mode |= MODE_MODERATED; - break; - case 't': - mode.mode |= MODE_TOPICLIMIT; - break; - case 'r': - mode.mode |= MODE_REGONLY; - break; - case 'L': - mode.mode |= MODE_EXLIMIT; - break; - case 'P': - mode.mode |= MODE_PERMANENT; - break; - case 'c': - mode.mode |= MODE_NOCOLOR; - break; - case 'g': - mode.mode |= MODE_FREEINVITE; - break; - case 'z': - mode.mode |= MODE_OPMODERATE; - break; - case 'F': - mode.mode |= MODE_FREETARGET; - break; - case 'Q': - mode.mode |= MODE_DISFORWARD; - break; - case 'f': - strlcpy(mode.forward, parv[4 + args], sizeof(mode.forward)); - args++; - if(parc < 5 + args) - return 0; - break; - case 'j': - sscanf(parv[4 + args], "%d:%d", &joinc, ×lice); - args++; - mode.join_num = joinc; - mode.join_time = timeslice; - if(parc < 5 + args) - return 0; - break; - case 'k': - strlcpy(mode.key, parv[4 + args], sizeof(mode.key)); - args++; - if(parc < 5 + args) - return 0; - break; - case 'l': - mode.limit = atoi(parv[4 + args]); - args++; - if(parc < 5 + args) - return 0; - break; - } - } - - if(parv[args + 4]) - { - s = parv[args + 4]; - - /* remove any leading spaces */ - while (*s == ' ') - s++; - } - else - s = ""; - - if((chptr = get_or_create_channel(source_p, parv[2], &isnew)) == NULL) - return 0; /* channel name too long? */ - - - oldts = chptr->channelts; - oldmode = &chptr->mode; - -#ifdef IGNORE_BOGUS_TS - if(newts < 800000000) - { - sendto_realops_snomask(SNO_DEBUG, L_ALL, - "*** Bogus TS %ld on %s ignored from %s", - (long) newts, chptr->chname, client_p->name); - - newts = (oldts == 0) ? oldts : 800000000; - } -#else - if(!isnew && !newts && oldts) - { - sendto_channel_local(ALL_MEMBERS, chptr, - ":%s NOTICE %s :*** Notice -- TS for %s " - "changed from %ld to 0", - me.name, chptr->chname, chptr->chname, (long) oldts); - sendto_realops_snomask(SNO_GENERAL, L_ALL, - "Server %s changing TS on %s from %ld to 0", - source_p->name, chptr->chname, (long) oldts); - } -#endif - - if(isnew) - chptr->channelts = newts; - - else if(newts == 0 || oldts == 0) - chptr->channelts = 0; - else if(newts == oldts) - ; - else if(newts < oldts) - { - /* If configured, kick people trying to join +i/+k - * channels by recreating them on split servers. - * Don't kick if the source has sent EOB (services - * deopping everyone by TS-1 SJOIN). - * -- jilles */ - if (ConfigChannel.kick_on_split_riding && - !HasSentEob(source_p) && - ((mode.mode & MODE_INVITEONLY) || - (mode.key[0] != 0 && irccmp(mode.key, oldmode->key) != 0))) - { - struct membership *msptr; - struct Client *who; - int l = rb_dlink_list_length(&chptr->members); - int b = rb_dlink_list_length(&chptr->banlist) + - rb_dlink_list_length(&chptr->exceptlist) + - rb_dlink_list_length(&chptr->invexlist) + - rb_dlink_list_length(&chptr->quietlist); - - RB_DLINK_FOREACH_SAFE(ptr, next_ptr, chptr->locmembers.head) - { - msptr = ptr->data; - who = msptr->client_p; - sendto_one(who, ":%s KICK %s %s :Net Rider", - me.name, chptr->chname, who->name); - - sendto_server(NULL, chptr, CAP_TS6, NOCAPS, - ":%s KICK %s %s :Net Rider", - me.id, chptr->chname, - who->id); - sendto_server(NULL, chptr, NOCAPS, CAP_TS6, - ":%s KICK %s %s :Net Rider", - me.name, chptr->chname, who->name); - remove_user_from_channel(msptr); - if (--l == 0) - break; - } - if (l == 0) - { - /* Channel was emptied, create a new one */ - if((chptr = get_or_create_channel(source_p, parv[2], &isnew)) == NULL) - return 0; /* oops! */ - - /* If the source does not do TS6, - * nontimestamped bans have been sent to it, - * but we have just lost those here. Let's - * warn the channel about this. Because - * of the kicks, any users on the channel - * will be at client_p. -- jilles */ - if (!has_id(source_p) && b > 0) - sendto_one(client_p, ":%s NOTICE %s :*** Notice -- possible ban desync on %s, please remove any bans just added by servers", get_id(&me, client_p), parv[2], parv[2]); - oldmode = &chptr->mode; - } - } - keep_our_modes = NO; - chptr->channelts = newts; - } - else - keep_new_modes = NO; - - if(!keep_new_modes) - mode = *oldmode; - else if(keep_our_modes) - { - mode.mode |= oldmode->mode; - if(oldmode->limit > mode.limit) - mode.limit = oldmode->limit; - if(strcmp(mode.key, oldmode->key) < 0) - strcpy(mode.key, oldmode->key); - if(oldmode->join_num > mode.join_num || - (oldmode->join_num == mode.join_num && - oldmode->join_time > mode.join_time)) - { - mode.join_num = oldmode->join_num; - mode.join_time = oldmode->join_time; - } - if(irccmp(mode.forward, oldmode->forward) < 0) - strcpy(mode.forward, oldmode->forward); - } - else - { - /* If setting -j, clear join throttle state -- jilles */ - if (!mode.join_num) - chptr->join_count = chptr->join_delta = 0; - } - - set_final_mode(&mode, oldmode); - chptr->mode = mode; - - /* Lost the TS, other side wins, so remove modes on this side */ - if(!keep_our_modes) - { - remove_our_modes(chptr, fakesource_p); - RB_DLINK_FOREACH_SAFE(ptr, next_ptr, chptr->invites.head) - { - del_invite(chptr, ptr->data); - } - sendto_channel_local(ALL_MEMBERS, chptr, - ":%s NOTICE %s :*** Notice -- TS for %s changed from %ld to %ld", - me.name, chptr->chname, chptr->chname, - (long) oldts, (long) newts); - /* Update capitalization in channel name, this makes the - * capitalization timestamped like modes are -- jilles */ - strcpy(chptr->chname, parv[2]); - } - - if(*modebuf != '\0') - sendto_channel_local(ALL_MEMBERS, chptr, ":%s MODE %s %s %s", - fakesource_p->name, chptr->chname, modebuf, parabuf); - - *modebuf = *parabuf = '\0'; - - if(parv[3][0] != '0' && keep_new_modes) - modes = channel_modes(chptr, source_p); - else - modes = empty_modes; - - mlen_nick = rb_sprintf(buf_nick, ":%s SJOIN %ld %s %s :", - source_p->name, (long) chptr->channelts, parv[2], modes); - ptr_nick = buf_nick + mlen_nick; - - /* working on the presumption eventually itll be more efficient to - * build a TS6 buffer without checking its needed.. - */ - mlen_uid = rb_sprintf(buf_uid, ":%s SJOIN %ld %s %s :", - use_id(source_p), (long) chptr->channelts, parv[2], modes); - ptr_uid = buf_uid + mlen_uid; - - mbuf = modebuf; - para[0] = para[1] = para[2] = para[3] = empty; - pargs = 0; - len_nick = len_uid = 0; - - /* if theres a space, theres going to be more than one nick, change the - * first space to \0, so s is just the first nick, and point p to the - * second nick - */ - if((p = strchr(s, ' ')) != NULL) - { - *p++ = '\0'; - } - - *mbuf++ = '+'; - - while (s) - { - fl = 0; - - for (i = 0; i < 2; i++) - { - if(*s == '@') - { - fl |= CHFL_CHANOP; - s++; - } - else if(*s == '+') - { - fl |= CHFL_VOICE; - s++; - } - } - - /* if the client doesnt exist or is fake direction, skip. */ - if(!(target_p = find_client(s)) || - (target_p->from != client_p) || !IsPerson(target_p)) - goto nextnick; - - /* we assume for these we can fit at least one nick/uid in.. */ - - /* check we can fit another status+nick+space into a buffer */ - if((mlen_nick + len_nick + NICKLEN + 3) > (BUFSIZE - 3)) - { - *(ptr_nick - 1) = '\0'; - sendto_server(client_p->from, NULL, NOCAPS, CAP_TS6, "%s", buf_nick); - ptr_nick = buf_nick + mlen_nick; - len_nick = 0; - } - - if((mlen_uid + len_uid + IDLEN + 3) > (BUFSIZE - 3)) - { - *(ptr_uid - 1) = '\0'; - sendto_server(client_p->from, NULL, CAP_TS6, NOCAPS, "%s", buf_uid); - ptr_uid = buf_uid + mlen_uid; - len_uid = 0; - } - - if(keep_new_modes) - { - if(fl & CHFL_CHANOP) - { - *ptr_nick++ = '@'; - *ptr_uid++ = '@'; - len_nick++; - len_uid++; - } - if(fl & CHFL_VOICE) - { - *ptr_nick++ = '+'; - *ptr_uid++ = '+'; - len_nick++; - len_uid++; - } - } - - /* copy the nick to the two buffers */ - len = rb_sprintf(ptr_nick, "%s ", target_p->name); - ptr_nick += len; - len_nick += len; - len = rb_sprintf(ptr_uid, "%s ", use_id(target_p)); - ptr_uid += len; - len_uid += len; - - if(!keep_new_modes) - fl = 0; - - if(!IsMember(target_p, chptr)) - { - add_user_to_channel(chptr, target_p, fl); - sendto_channel_local(ALL_MEMBERS, chptr, ":%s!%s@%s JOIN :%s", - target_p->name, - target_p->username, target_p->host, parv[2]); - joins++; - } - - if(fl & CHFL_CHANOP) - { - *mbuf++ = 'o'; - para[pargs++] = target_p->name; - - /* a +ov user.. bleh */ - if(fl & CHFL_VOICE) - { - /* its possible the +o has filled up MAXMODEPARAMS, if so, start - * a new buffer - */ - if(pargs >= MAXMODEPARAMS) - { - *mbuf = '\0'; - sendto_channel_local(ALL_MEMBERS, chptr, - ":%s MODE %s %s %s %s %s %s", - fakesource_p->name, chptr->chname, - modebuf, - para[0], para[1], para[2], para[3]); - mbuf = modebuf; - *mbuf++ = '+'; - para[0] = para[1] = para[2] = para[3] = NULL; - pargs = 0; - } - - *mbuf++ = 'v'; - para[pargs++] = target_p->name; - } - } - else if(fl & CHFL_VOICE) - { - *mbuf++ = 'v'; - para[pargs++] = target_p->name; - } - - if(pargs >= MAXMODEPARAMS) - { - *mbuf = '\0'; - sendto_channel_local(ALL_MEMBERS, chptr, - ":%s MODE %s %s %s %s %s %s", - fakesource_p->name, - chptr->chname, - modebuf, para[0], para[1], para[2], para[3]); - mbuf = modebuf; - *mbuf++ = '+'; - para[0] = para[1] = para[2] = para[3] = NULL; - pargs = 0; - } - - nextnick: - /* p points to the next nick */ - s = p; - - /* if there was a trailing space and p was pointing to it, then we - * need to exit.. this has the side effect of breaking double spaces - * in an sjoin.. but that shouldnt happen anyway - */ - if(s && (*s == '\0')) - s = p = NULL; - - /* if p was NULL due to no spaces, s wont exist due to the above, so - * we cant check it for spaces.. if there are no spaces, then when - * we next get here, s will be NULL - */ - if(s && ((p = strchr(s, ' ')) != NULL)) - { - *p++ = '\0'; - } - } - - *mbuf = '\0'; - if(pargs) - { - sendto_channel_local(ALL_MEMBERS, chptr, - ":%s MODE %s %s %s %s %s %s", - fakesource_p->name, chptr->chname, modebuf, - para[0], CheckEmpty(para[1]), - CheckEmpty(para[2]), CheckEmpty(para[3])); - } - - if(!joins && !(chptr->mode.mode & MODE_PERMANENT) && isnew) - { - destroy_channel(chptr); - - return 0; - } - - /* Keep the colon if we're sending an SJOIN without nicks -- jilles */ - if (joins) - { - *(ptr_nick - 1) = '\0'; - *(ptr_uid - 1) = '\0'; - } - - sendto_server(client_p->from, NULL, CAP_TS6, NOCAPS, "%s", buf_uid); - sendto_server(client_p->from, NULL, NOCAPS, CAP_TS6, "%s", buf_nick); - - /* if the source does TS6 we have to remove our bans. Its now safe - * to issue -b's to the non-ts6 servers, as the sjoin we've just - * sent will kill any ops they have. - */ - if(!keep_our_modes && source_p->id[0] != '\0') - { - if(rb_dlink_list_length(&chptr->banlist) > 0) - remove_ban_list(chptr, fakesource_p, &chptr->banlist, 'b', NOCAPS, ALL_MEMBERS); - - if(rb_dlink_list_length(&chptr->exceptlist) > 0) - remove_ban_list(chptr, fakesource_p, &chptr->exceptlist, - 'e', CAP_EX, ONLY_CHANOPS); - - if(rb_dlink_list_length(&chptr->invexlist) > 0) - remove_ban_list(chptr, fakesource_p, &chptr->invexlist, - 'I', CAP_IE, ONLY_CHANOPS); - - if(rb_dlink_list_length(&chptr->quietlist) > 0) - remove_ban_list(chptr, fakesource_p, &chptr->quietlist, - 'q', NOCAPS, ALL_MEMBERS); - - chptr->bants++; - } - - return 0; -} - -static void -set_final_mode(struct Mode *mode, struct Mode *oldmode) -{ - int dir = MODE_QUERY; - char *pbuf = parabuf; - int len; - int i; - - /* ok, first get a list of modes we need to add */ - for (i = 0; chmode_flags[i].letter; i++) - { - if((mode->mode & chmode_flags[i].mode) && !(oldmode->mode & chmode_flags[i].mode)) - { - if(dir != MODE_ADD) - { - *mbuf++ = '+'; - dir = MODE_ADD; - } - *mbuf++ = chmode_flags[i].letter; - } - } - - /* now the ones we need to remove. */ - for (i = 0; chmode_flags[i].letter; i++) - { - if((oldmode->mode & chmode_flags[i].mode) && !(mode->mode & chmode_flags[i].mode)) - { - if(dir != MODE_DEL) - { - *mbuf++ = '-'; - dir = MODE_DEL; - } - *mbuf++ = chmode_flags[i].letter; - } - } - - if(oldmode->limit && !mode->limit) - { - if(dir != MODE_DEL) - { - *mbuf++ = '-'; - dir = MODE_DEL; - } - *mbuf++ = 'l'; - } - if(oldmode->key[0] && !mode->key[0]) - { - if(dir != MODE_DEL) - { - *mbuf++ = '-'; - dir = MODE_DEL; - } - *mbuf++ = 'k'; - len = rb_sprintf(pbuf, "%s ", oldmode->key); - pbuf += len; - pargs++; - } - if(oldmode->join_num && !mode->join_num) - { - if(dir != MODE_DEL) - { - *mbuf++ = '-'; - dir = MODE_DEL; - } - *mbuf++ = 'j'; - } - if(oldmode->forward[0] && !mode->forward[0]) - { - if(dir != MODE_DEL) - { - *mbuf++ = '-'; - dir = MODE_DEL; - } - *mbuf++ = 'f'; - } - if(mode->limit && oldmode->limit != mode->limit) - { - if(dir != MODE_ADD) - { - *mbuf++ = '+'; - dir = MODE_ADD; - } - *mbuf++ = 'l'; - len = rb_sprintf(pbuf, "%d ", mode->limit); - pbuf += len; - pargs++; - } - if(mode->key[0] && strcmp(oldmode->key, mode->key)) - { - if(dir != MODE_ADD) - { - *mbuf++ = '+'; - dir = MODE_ADD; - } - *mbuf++ = 'k'; - len = rb_sprintf(pbuf, "%s ", mode->key); - pbuf += len; - pargs++; - } - if(mode->join_num && (oldmode->join_num != mode->join_num || oldmode->join_time != mode->join_time)) - { - if(dir != MODE_ADD) - { - *mbuf++ = '+'; - dir = MODE_ADD; - } - *mbuf++ = 'j'; - len = rb_sprintf(pbuf, "%d:%d ", mode->join_num, mode->join_time); - pbuf += len; - pargs++; - } - if(mode->forward[0] && strcmp(oldmode->forward, mode->forward) && ConfigChannel.use_forward) - { - if(dir != MODE_ADD) - { - *mbuf++ = '+'; - dir = MODE_ADD; - } - *mbuf++ = 'f'; - len = rb_sprintf(pbuf, "%s ", mode->forward); - pbuf += len; - pargs++; - } - *mbuf = '\0'; -} - -/* - * remove_our_modes - * - * inputs - - * output - - * side effects - - */ -static void -remove_our_modes(struct Channel *chptr, struct Client *source_p) -{ - struct membership *msptr; - rb_dlink_node *ptr; - char lmodebuf[MODEBUFLEN]; - char *lpara[MAXMODEPARAMS]; - int count = 0; - int i; - - mbuf = lmodebuf; - *mbuf++ = '-'; - - for (i = 0; i < MAXMODEPARAMS; i++) - lpara[i] = NULL; - - RB_DLINK_FOREACH(ptr, chptr->members.head) - { - msptr = ptr->data; - - if(is_chanop(msptr)) - { - msptr->flags &= ~CHFL_CHANOP; - lpara[count++] = msptr->client_p->name; - *mbuf++ = 'o'; - - /* +ov, might not fit so check. */ - if(is_voiced(msptr)) - { - if(count >= MAXMODEPARAMS) - { - *mbuf = '\0'; - sendto_channel_local(ALL_MEMBERS, chptr, - ":%s MODE %s %s %s %s %s %s", - me.name, chptr->chname, - lmodebuf, lpara[0], lpara[1], - lpara[2], lpara[3]); - - /* preserve the initial '-' */ - mbuf = lmodebuf; - *mbuf++ = '-'; - count = 0; - - for (i = 0; i < MAXMODEPARAMS; i++) - lpara[i] = NULL; - } - - msptr->flags &= ~CHFL_VOICE; - lpara[count++] = msptr->client_p->name; - *mbuf++ = 'v'; - } - } - else if(is_voiced(msptr)) - { - msptr->flags &= ~CHFL_VOICE; - lpara[count++] = msptr->client_p->name; - *mbuf++ = 'v'; - } - else - continue; - - if(count >= MAXMODEPARAMS) - { - *mbuf = '\0'; - sendto_channel_local(ALL_MEMBERS, chptr, - ":%s MODE %s %s %s %s %s %s", - me.name, chptr->chname, lmodebuf, - lpara[0], lpara[1], lpara[2], lpara[3]); - mbuf = lmodebuf; - *mbuf++ = '-'; - count = 0; - - for (i = 0; i < MAXMODEPARAMS; i++) - lpara[i] = NULL; - } - } - - if(count != 0) - { - *mbuf = '\0'; - sendto_channel_local(ALL_MEMBERS, chptr, - ":%s MODE %s %s %s %s %s %s", - me.name, chptr->chname, lmodebuf, - EmptyString(lpara[0]) ? "" : lpara[0], - EmptyString(lpara[1]) ? "" : lpara[1], - EmptyString(lpara[2]) ? "" : lpara[2], - EmptyString(lpara[3]) ? "" : lpara[3]); - - } -} - -/* remove_ban_list() - * - * inputs - channel, source, list to remove, char of mode, caps needed - * outputs - - * side effects - given list is removed, with modes issued to local clients - * and non-TS6 servers. - */ -static void -remove_ban_list(struct Channel *chptr, struct Client *source_p, - rb_dlink_list * list, char c, int cap, int mems) -{ - static char lmodebuf[BUFSIZE]; - static char lparabuf[BUFSIZE]; - struct Ban *banptr; - rb_dlink_node *ptr; - rb_dlink_node *next_ptr; - char *pbuf; - int count = 0; - int cur_len, mlen, plen; - - pbuf = lparabuf; - - cur_len = mlen = rb_sprintf(lmodebuf, ":%s MODE %s -", source_p->name, chptr->chname); - mbuf = lmodebuf + mlen; - - RB_DLINK_FOREACH_SAFE(ptr, next_ptr, list->head) - { - banptr = ptr->data; - - /* trailing space, and the mode letter itself */ - plen = strlen(banptr->banstr) + 2; - - if(count >= MAXMODEPARAMS || (cur_len + plen) > BUFSIZE - 4) - { - /* remove trailing space */ - *mbuf = '\0'; - *(pbuf - 1) = '\0'; - - sendto_channel_local(mems, chptr, "%s %s", lmodebuf, lparabuf); - /* Tricky tricky. If we changed source_p to &me - * in ms_sjoin(), this still won't send stuff - * where it should not be sent, because the - * real source_p does TS6 -- jilles */ - sendto_server(source_p, chptr, cap, CAP_TS6, "%s %s", lmodebuf, lparabuf); - - cur_len = mlen; - mbuf = lmodebuf + mlen; - pbuf = lparabuf; - count = 0; - } - - *mbuf++ = c; - cur_len += plen; - pbuf += rb_sprintf(pbuf, "%s ", banptr->banstr); - count++; - - free_ban(banptr); - } - - *mbuf = '\0'; - *(pbuf - 1) = '\0'; - sendto_channel_local(mems, chptr, "%s %s", lmodebuf, lparabuf); - sendto_server(source_p, chptr, cap, CAP_TS6, "%s %s", lmodebuf, lparabuf); - - list->head = list->tail = NULL; - list->length = 0; -} From 69986379a72d4de61f4b4063d7ad7a69729cdc5b Mon Sep 17 00:00:00 2001 From: Valery Yatsko Date: Mon, 7 Apr 2008 19:05:29 +0400 Subject: [PATCH 2/9] 'pargs' gone from set_final_mode - should be correct --- modules/core/m_join.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/modules/core/m_join.c b/modules/core/m_join.c index 1b8120a91..d4b10361b 100644 --- a/modules/core/m_join.c +++ b/modules/core/m_join.c @@ -1170,7 +1170,6 @@ set_final_mode(struct Mode *mode, struct Mode *oldmode) *mbuf++ = 'k'; len = rb_sprintf(pbuf, "%s ", oldmode->key); pbuf += len; - pargs++; } if(oldmode->join_num && !mode->join_num) { @@ -1200,7 +1199,6 @@ set_final_mode(struct Mode *mode, struct Mode *oldmode) *mbuf++ = 'l'; len = rb_sprintf(pbuf, "%d ", mode->limit); pbuf += len; - pargs++; } if(mode->key[0] && strcmp(oldmode->key, mode->key)) { @@ -1212,7 +1210,6 @@ set_final_mode(struct Mode *mode, struct Mode *oldmode) *mbuf++ = 'k'; len = rb_sprintf(pbuf, "%s ", mode->key); pbuf += len; - pargs++; } if(mode->join_num && (oldmode->join_num != mode->join_num || oldmode->join_time != mode->join_time)) { @@ -1224,7 +1221,6 @@ set_final_mode(struct Mode *mode, struct Mode *oldmode) *mbuf++ = 'j'; len = rb_sprintf(pbuf, "%d:%d ", mode->join_num, mode->join_time); pbuf += len; - pargs++; } if(mode->forward[0] && strcmp(oldmode->forward, mode->forward) && ConfigChannel.use_forward) { @@ -1236,7 +1232,6 @@ set_final_mode(struct Mode *mode, struct Mode *oldmode) *mbuf++ = 'f'; len = rb_sprintf(pbuf, "%s ", mode->forward); pbuf += len; - pargs++; } *mbuf = '\0'; } From bbe968ca0c5976a2be6e46ce08ba0ca95f0c3c3d Mon Sep 17 00:00:00 2001 From: Valery Yatsko Date: Mon, 7 Apr 2008 20:06:04 +0400 Subject: [PATCH 3/9] Make charybdis not search m_sjoin as its a core module --- src/modules.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/modules.c b/src/modules.c index 068ab75e3..0a9a8838c 100644 --- a/src/modules.c +++ b/src/modules.c @@ -69,7 +69,6 @@ static const char *core_module_table[] = { "m_part", "m_quit", "m_server", - "m_sjoin", "m_squit", NULL }; From f4a759c5605890af194251781f0f7a4c3a419d90 Mon Sep 17 00:00:00 2001 From: Valery Yatsko Date: Mon, 7 Apr 2008 20:21:09 +0400 Subject: [PATCH 4/9] show_capabilities cleanup and now show whether we are TS or TS6 and SSL link --- src/s_serv.c | 135 ++++++++++++++++++++++++--------------------------- 1 file changed, 64 insertions(+), 71 deletions(-) diff --git a/src/s_serv.c b/src/s_serv.c index 60768e4f4..397ae0575 100644 --- a/src/s_serv.c +++ b/src/s_serv.c @@ -238,8 +238,8 @@ try_connections(void *unused) if(ServerConfIllegal(tmp_p) || !ServerConfAutoconn(tmp_p)) continue; - /* don't allow ssl connections if ssl isn't setup */ - if(ServerConfSSL(tmp_p) && (!ssl_ok || !get_ssld_count())) + /* don't allow ssl connections if ssl isn't setup */ + if(ServerConfSSL(tmp_p) && (!ssl_ok || !get_ssld_count())) continue; cltmp = tmp_p->class; @@ -369,9 +369,9 @@ check_server(const char *name, struct Client *client_p) if(server_p == NULL) return error; - if(ServerConfSSL(server_p) && client_p->localClient->ssl_ctl == NULL) - { - return -5; + if(ServerConfSSL(server_p) && client_p->localClient->ssl_ctl == NULL) + { + return -5; } attach_server_conf(client_p, server_p); @@ -838,32 +838,25 @@ show_capabilities(struct Client *target_p) { static char msgbuf[BUFSIZE]; struct Capability *cap; - char *t; - int tl; - t = msgbuf; - tl = rb_sprintf(msgbuf, "TS "); - t += tl; + if(has_id(target_p)) + rb_strlcpy(msgbuf, " TS6", sizeof(msgbuf)); + else + rb_strlcpy(msgbuf, " TS", sizeof(msgbuf)); + + if(IsSSL(target_p)) + rb_strlcat(msgbuf, " SSL", sizeof(msgbuf)); if(!IsServer(target_p) || !target_p->serv->caps) /* short circuit if no caps */ - { - msgbuf[2] = '\0'; - return msgbuf; - } + return msgbuf + 1; for (cap = captab; cap->cap; ++cap) { if(cap->cap & target_p->serv->caps) - { - tl = rb_sprintf(t, "%s ", cap->name); - t += tl; - } + rb_snprintf_append(msgbuf, sizeof(msgbuf), " %s", cap->name); } - t--; - *t = '\0'; - - return msgbuf; + return msgbuf + 1; } /* @@ -950,10 +943,10 @@ server_estab(struct Client *client_p) ilog_error("rb_set_buffers failed for server"); /* Enable compression now */ - if(IsCapable(client_p, CAP_ZIP)) - { - start_zlib_session(client_p); - } + if(IsCapable(client_p, CAP_ZIP)) + { + start_zlib_session(client_p); + } sendto_one(client_p, "SVINFO %d %d 0 :%ld", TS_CURRENT, TS_MIN, rb_current_time()); client_p->servptr = &me; @@ -1009,7 +1002,7 @@ server_estab(struct Client *client_p) hdata.target = client_p; call_hook(h_server_introduced, &hdata); - rb_snprintf(note, sizeof(note), "Server: %s", client_p->name); + rb_snprintf(note, sizeof(note), "Server: %s", client_p->name); rb_note(client_p->localClient->F, note); /* @@ -1103,7 +1096,7 @@ server_estab(struct Client *client_p) free_pre_client(client_p); - if (!IsCapable(client_p, CAP_ZIP)) + if (!IsCapable(client_p, CAP_ZIP)) send_pop_queue(client_p); return 0; @@ -1171,15 +1164,15 @@ serv_connect_resolved(struct Client *client_p) #endif (server_p->aftype == AF_INET ? "IPv4" : "?")); - if(ServerConfSSL(server_p)) - { - rb_connect_tcp(client_p->localClient->F, (struct sockaddr *)&client_p->localClient->ip, - NULL, 0, serv_connect_ssl_callback, - client_p, ConfigFileEntry.connect_timeout); - } - else - rb_connect_tcp(client_p->localClient->F, (struct sockaddr *)&client_p->localClient->ip, - NULL, 0, serv_connect_callback, + if(ServerConfSSL(server_p)) + { + rb_connect_tcp(client_p->localClient->F, (struct sockaddr *)&client_p->localClient->ip, + NULL, 0, serv_connect_ssl_callback, + client_p, ConfigFileEntry.connect_timeout); + } + else + rb_connect_tcp(client_p->localClient->F, (struct sockaddr *)&client_p->localClient->ip, + NULL, 0, serv_connect_callback, client_p, ConfigFileEntry.connect_timeout); return 1; } @@ -1193,15 +1186,15 @@ serv_connect_resolved(struct Client *client_p) (server_p->aftype == AF_INET ? "IPv4" : "?"), vhoststr); - if(ServerConfSSL(server_p)) - rb_connect_tcp(client_p->localClient->F, (struct sockaddr *)&client_p->localClient->ip, - (struct sockaddr *) &myipnum, - GET_SS_LEN(&myipnum), serv_connect_ssl_callback, client_p, - ConfigFileEntry.connect_timeout); - else - rb_connect_tcp(client_p->localClient->F, (struct sockaddr *)&client_p->localClient->ip, - (struct sockaddr *) &myipnum, - GET_SS_LEN(&myipnum), serv_connect_callback, client_p, + if(ServerConfSSL(server_p)) + rb_connect_tcp(client_p->localClient->F, (struct sockaddr *)&client_p->localClient->ip, + (struct sockaddr *) &myipnum, + GET_SS_LEN(&myipnum), serv_connect_ssl_callback, client_p, + ConfigFileEntry.connect_timeout); + else + rb_connect_tcp(client_p->localClient->F, (struct sockaddr *)&client_p->localClient->ip, + (struct sockaddr *) &myipnum, + GET_SS_LEN(&myipnum), serv_connect_callback, client_p, ConfigFileEntry.connect_timeout); return 1; @@ -1386,32 +1379,32 @@ serv_connect(struct server_conf *server_p, struct Client *by) } } -static void -serv_connect_ev(void *data) -{ - struct Client *client_p = data; - serv_connect_callback(client_p->localClient->F, RB_OK, client_p); +static void +serv_connect_ev(void *data) +{ + struct Client *client_p = data; + serv_connect_callback(client_p->localClient->F, RB_OK, client_p); } -static void -serv_connect_ssl_callback(rb_fde_t *F, int status, void *data) -{ - struct Client *client_p = data; - rb_fde_t *xF[2]; - if(status != RB_OK) - { - /* XXX deal with failure */ - return; - } - rb_connect_sockaddr(F, (struct sockaddr *)&client_p->localClient->ip, sizeof(client_p->localClient->ip)); - rb_socketpair(AF_UNIX, SOCK_STREAM, 0, &xF[0], &xF[1], "Outgoing ssld connection"); - del_from_cli_fd_hash(client_p); - client_p->localClient->F = xF[0]; - add_to_cli_fd_hash(client_p); - - client_p->localClient->ssl_ctl = start_ssld_connect(F, xF[1], rb_get_fd(xF[0])); - SetSSL(client_p); - rb_event_addonce("serv_connect_ev", serv_connect_ev, client_p, 1); +static void +serv_connect_ssl_callback(rb_fde_t *F, int status, void *data) +{ + struct Client *client_p = data; + rb_fde_t *xF[2]; + if(status != RB_OK) + { + /* XXX deal with failure */ + return; + } + rb_connect_sockaddr(F, (struct sockaddr *)&client_p->localClient->ip, sizeof(client_p->localClient->ip)); + rb_socketpair(AF_UNIX, SOCK_STREAM, 0, &xF[0], &xF[1], "Outgoing ssld connection"); + del_from_cli_fd_hash(client_p); + client_p->localClient->F = xF[0]; + add_to_cli_fd_hash(client_p); + + client_p->localClient->ssl_ctl = start_ssld_connect(F, xF[1], rb_get_fd(xF[0])); + SetSSL(client_p); + rb_event_addonce("serv_connect_ev", serv_connect_ev, client_p, 1); } /* @@ -1446,7 +1439,7 @@ serv_connect_callback(rb_fde_t *F, int status, void *data) return; } - if(client_p->localClient->ssl_ctl == NULL) + if(client_p->localClient->ssl_ctl == NULL) rb_connect_sockaddr(F, (struct sockaddr *)&client_p->localClient->ip, sizeof(client_p->localClient->ip)); /* Check the status */ From aa6c90dec7764a6389d6a860dad303f212a3db99 Mon Sep 17 00:00:00 2001 From: Valery Yatsko Date: Tue, 8 Apr 2008 15:36:56 +0400 Subject: [PATCH 5/9] It seems that we don't use data structs version anywhere since 1.2.0 - removed --- include/ircd_defs.h | 8 -------- src/ircd.c | 6 ------ 2 files changed, 14 deletions(-) diff --git a/include/ircd_defs.h b/include/ircd_defs.h index cea2978a5..f365d6987 100644 --- a/include/ircd_defs.h +++ b/include/ircd_defs.h @@ -94,14 +94,6 @@ # error Incorrect config.h for this revision of ircd. #endif -/* - * This defines the version of the data structures used in the ircd. - * In the event of a mismatch (i.e. this is incremented due to a major - * change that cannot be accomidated for in the ircd), then a hard - * restart occurs. - */ -#define CHARYBDIS_DV 0x00010200 /* 1.2.0 */ - #define HOSTLEN 63 /* Length of hostname. Updated to */ /* comply with RFC1123 */ diff --git a/src/ircd.c b/src/ircd.c index 9d659efaf..dc5ec3782 100644 --- a/src/ircd.c +++ b/src/ircd.c @@ -67,12 +67,6 @@ #include "serno.h" #include "sslproc.h" -/* - * Try and find the correct name to use with getrlimit() for setting the max. - * number of files allowed to be open by this process. - */ -int _charybdis_data_version = CHARYBDIS_DV; - extern int ServerRunning; extern struct LocalUser meLocalUser; extern char **myargv; From 31fd33171e9e564334fffb62a508d6d45581d8da Mon Sep 17 00:00:00 2001 From: Valery Yatsko Date: Tue, 8 Apr 2008 15:38:18 +0400 Subject: [PATCH 6/9] ServerRunning is not used too --- src/ircd.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/ircd.c b/src/ircd.c index dc5ec3782..76d7efbbc 100644 --- a/src/ircd.c +++ b/src/ircd.c @@ -67,7 +67,6 @@ #include "serno.h" #include "sslproc.h" -extern int ServerRunning; extern struct LocalUser meLocalUser; extern char **myargv; @@ -445,7 +444,6 @@ main(int argc, char *argv[]) */ setup_corefile(); - ServerRunning = 0; /* It ain't random, but it ought to be a little harder to guess */ srand(SystemTime.tv_sec ^ (SystemTime.tv_usec | (getpid() << 20))); memset(&me, 0, sizeof(me)); @@ -648,8 +646,6 @@ main(int argc, char *argv[]) if(splitmode) check_splitmode_ev = rb_event_add("check_splitmode", check_splitmode, NULL, 2); - ServerRunning = 1; - print_startup(getpid()); rb_lib_loop(250); From 72324d1052be0f80822133ce32404cc2eb47547f Mon Sep 17 00:00:00 2001 From: Valery Yatsko Date: Tue, 8 Apr 2008 15:41:41 +0400 Subject: [PATCH 7/9] ircd_state.{c,h} gone - let us redesign it in future really --- include/ircd_state.h | 55 ---------------- src/Makefile.in | 1 - src/ircd_state.c | 145 ------------------------------------------- 3 files changed, 201 deletions(-) delete mode 100644 include/ircd_state.h delete mode 100644 src/ircd_state.c diff --git a/include/ircd_state.h b/include/ircd_state.h deleted file mode 100644 index 8d488b399..000000000 --- a/include/ircd_state.h +++ /dev/null @@ -1,55 +0,0 @@ -/* - * charybdis: An advanced ircd. - * ircd_state.h: Functions for backing up and synchronizing IRCd's state - * - * Copyright (c) 2006 William Pitcock - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, - * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - * $Id: main.c 867 2006-02-16 14:25:09Z nenolod $ - */ - -#ifndef _IRCD_STATE_H -#define _IRCD_STATE_H - -#include "stdinc.h" -#include "setup.h" -#include "config.h" -#include "ircd_defs.h" -#include "ircd_linker.h" -#include "ircd_state.h" - -#ifdef NOTYET - -/* I haven't designed this structure yet, so this is a placeholder. */ -struct IRCdState { - void *moo; -}; - -#endif - -#endif diff --git a/src/Makefile.in b/src/Makefile.in index 9c6227801..c9256cc04 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -69,7 +69,6 @@ SRCS = \ irc_dictionary.c \ ircd.c \ ircd_signal.c \ - ircd_state.c \ kdparse.c \ listener.c \ logger.c \ diff --git a/src/ircd_state.c b/src/ircd_state.c deleted file mode 100644 index 077646133..000000000 --- a/src/ircd_state.c +++ /dev/null @@ -1,145 +0,0 @@ -/* - * charybdis: An advanced ircd. - * ircd_state.c: Functions for backing up and synchronizing IRCd's state - * - * Copyright (c) 2006 William Pitcock - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, - * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - * $Id: main.c 867 2006-02-16 14:25:09Z nenolod $ - */ - -#include "stdinc.h" -#include "setup.h" -#include "config.h" - -#include "client.h" -#include "ircd.h" -#include "channel.h" -#include "class.h" -#include "client.h" -#include "common.h" -#include "hash.h" -#include "irc_string.h" -#include "ircd_signal.h" -#include "sprintf_irc.h" -#include "s_gline.h" -#include "msg.h" /* msgtab */ -#include "hostmask.h" -#include "numeric.h" -#include "parse.h" -#include "res.h" -#include "restart.h" -#include "s_auth.h" -#include "s_conf.h" -#include "logger.h" -#include "s_serv.h" /* try_connections */ -#include "s_user.h" -#include "s_stats.h" -#include "scache.h" -#include "send.h" -#include "whowas.h" -#include "modules.h" -#include "hook.h" -#include "ircd_getopt.h" -#include "newconf.h" -#include "reject.h" -#include "s_conf.h" -#include "s_newconf.h" -#include "cache.h" -#include "monitor.h" -#include "patchlevel.h" -#include "serno.h" - -rb_dlink_list lclient_list = { NULL, NULL, 0 }; -rb_dlink_list global_client_list = { NULL, NULL, 0 }; -rb_dlink_list global_channel_list = { NULL, NULL, 0 }; - -rb_dlink_list unknown_list; /* unknown clients ON this server only */ -rb_dlink_list serv_list; /* local servers to this server ONLY */ -rb_dlink_list global_serv_list; /* global servers on the network */ -rb_dlink_list local_oper_list; /* our opers, duplicated in lclient_list */ -rb_dlink_list oper_list; /* network opers */ - -struct timeval SystemTime; -int ServerRunning; /* GLOBAL - server execution state */ -struct Client me; /* That's me */ -struct LocalUser meLocalUser; /* That's also part of me */ - -time_t startup_time; - -int default_server_capabs = CAP_MASK; - -int splitmode; -int splitchecking; -int split_users; -int split_servers; -int eob_count; - -unsigned long initialVMTop = 0; /* top of virtual memory at init */ -const char *logFileName = LPATH; -const char *pidFileName = PPATH; - -char **myargv; -int dorehash = 0; -int dorehashbans = 0; -int doremotd = 0; -int kline_queued = 0; -int server_state_foreground = 0; -int opers_see_all_users = 0; - -int testing_conf = 0; - -struct config_channel_entry ConfigChannel; -rb_bh *channel_heap; -rb_bh *ban_heap; -rb_bh *topic_heap; -rb_bh *member_heap; - -rb_bh *client_heap = NULL; -rb_bh *lclient_heap = NULL; -rb_bh *pclient_heap = NULL; - -char current_uid[IDLEN]; - -/* patricia */ -rb_bh *prefix_heap; -rb_bh *node_heap; -rb_bh *patricia_heap; - -rb_bh *linebuf_heap; - -rb_bh *dnode_heap; - -#ifdef NOTYET - -void charybdis_initstate(struct IRCdState *self) -{ - -} - -#endif From 1aad97824ba216be8c21ca5263551767ed5c78b6 Mon Sep 17 00:00:00 2001 From: Valery Yatsko Date: Tue, 8 Apr 2008 15:50:39 +0400 Subject: [PATCH 8/9] Cleaned up ircd.c a bit and added additional check to ircd_die_cb() --- src/ircd.c | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/src/ircd.c b/src/ircd.c index 76d7efbbc..2a7376e5f 100644 --- a/src/ircd.c +++ b/src/ircd.c @@ -67,11 +67,6 @@ #include "serno.h" #include "sslproc.h" -extern struct LocalUser meLocalUser; -extern char **myargv; - -int maxconnections; - /* /quote set variables */ struct SetOptions GlobalSetOptions; @@ -80,11 +75,16 @@ struct config_file_entry ConfigFileEntry; /* server info set from ircd.conf */ struct server_info ServerInfo; /* admin info set from ircd.conf */ -struct admin_info AdminInfo; - +struct admin_info AdminInfo; + struct Counter Count; struct ServerStatistics ServerStats; +int maxconnections; +struct Client me; /* That's me */ +struct LocalUser meLocalUser; /* That's also part of me */ + +char **myargv; int ssl_ok = 0; int zlib_ok = 1; @@ -132,9 +132,12 @@ ircd_restart_cb(const char *str) static void ircd_die_cb(const char *str) { - /* Try to get the message out to currently logged in operators. */ - sendto_realops_snomask(SNO_GENERAL, L_NETWIDE, "Server panic! %s", str); - inotice("server panic: %s", str); + if(str != NULL) + { + /* Try to get the message out to currently logged in operators. */ + sendto_realops_snomask(SNO_GENERAL, L_NETWIDE, "Server panic! %s", str); + inotice("server panic: %s", str); + } unlink(pidFileName); exit(EXIT_FAILURE); From b5b84cad5dc98cd11cfdc4dd58f36d3801ddc84a Mon Sep 17 00:00:00 2001 From: Valery Yatsko Date: Tue, 8 Apr 2008 16:01:16 +0400 Subject: [PATCH 9/9] Oups, declarations related to ircd.c returned from ircd_state.c --- src/ircd.c | 56 +++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 55 insertions(+), 1 deletion(-) diff --git a/src/ircd.c b/src/ircd.c index 2a7376e5f..51f89a14f 100644 --- a/src/ircd.c +++ b/src/ircd.c @@ -81,12 +81,66 @@ struct Counter Count; struct ServerStatistics ServerStats; int maxconnections; +struct timeval SystemTime; struct Client me; /* That's me */ struct LocalUser meLocalUser; /* That's also part of me */ +rb_dlink_list lclient_list = { NULL, NULL, 0 }; +rb_dlink_list global_client_list = { NULL, NULL, 0 }; +rb_dlink_list global_channel_list = { NULL, NULL, 0 }; + +rb_dlink_list unknown_list; /* unknown clients ON this server only */ +rb_dlink_list serv_list; /* local servers to this server ONLY */ +rb_dlink_list global_serv_list; /* global servers on the network */ +rb_dlink_list local_oper_list; /* our opers, duplicated in lclient_list */ +rb_dlink_list oper_list; /* network opers */ + +time_t startup_time; + +int default_server_capabs = CAP_MASK; + +int splitmode; +int splitchecking; +int split_users; +int split_servers; +int eob_count; + +unsigned long initialVMTop = 0; /* top of virtual memory at init */ +const char *logFileName = LPATH; +const char *pidFileName = PPATH; + char **myargv; +int dorehash = 0; +int dorehashbans = 0; +int doremotd = 0; +int kline_queued = 0; +int server_state_foreground = 0; +int opers_see_all_users = 0; int ssl_ok = 0; -int zlib_ok = 1; +int zlib_ok = 1; + +int testing_conf = 0; + +struct config_channel_entry ConfigChannel; +rb_bh *channel_heap; +rb_bh *ban_heap; +rb_bh *topic_heap; +rb_bh *member_heap; + +rb_bh *client_heap = NULL; +rb_bh *lclient_heap = NULL; +rb_bh *pclient_heap = NULL; + +char current_uid[IDLEN]; + +/* patricia */ +rb_bh *prefix_heap; +rb_bh *node_heap; +rb_bh *patricia_heap; + +rb_bh *linebuf_heap; + +rb_bh *dnode_heap; /* * print_startup - print startup information