| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024 |
- #ifdef LEAF
- #define MODULE_NAME "server"
- #define MAKING_SERVER
- #include "src/mod/module.h"
- #include "server.h"
- static Function *global = NULL, *encryption_funcs;
- extern struct cfg_entry CFG_OPTIMESLACK;
- static int ctcp_mode;
- static int serv;
- static int strict_host;
- static char newserver[121];
- static int newserverport;
- static char newserverpass[121];
- static time_t trying_server;
- static int server_lag;
- static char altnick[NICKLEN];
- static char raltnick[NICKLEN];
- static int curserv;
- static int flud_thr;
- static int flud_time;
- static int flud_ctcp_thr;
- static int flud_ctcp_time;
- static char initserver[121];
- static char botuserhost[121];
- static int keepnick;
- static int nick_juped = 0;
- static int check_stoned;
- static int serverror_quit;
- static int quiet_reject;
- static int waiting_for_awake;
- static time_t server_online;
- static time_t server_cycle_wait;
- static char botrealname[121];
- static int min_servs;
- static int server_timeout;
- static int never_give_up;
- static int strict_servernames;
- static struct server_list *serverlist;
- static int cycle_time;
- static int default_port;
- static char oldnick[NICKLEN];
- static int trigger_on_ignore;
- static int answer_ctcp;
- static int lowercase_ctcp;
- static int check_mode_r;
- static int net_type;
- static char connectserver[121];
- static int resolvserv;
- static int double_mode;
- static int double_server;
- static int double_help;
- static int double_warned;
- static int lastpingtime;
- static char stackablecmds[511];
- static char stackable2cmds[511];
- static time_t last_time;
- static int use_penalties;
- static int use_fastdeq;
- static int nick_len;
- static int kick_method;
- static int optimize_kicks;
- static p_tcl_bind_list H_wall, H_raw, H_notc, H_msgm, H_msg, H_flud, H_ctcr,
- H_ctcp;
- static void empty_msgq (void);
- static void next_server (int *, char *, unsigned int *, char *);
- static void disconnect_server (int);
- static char *get_altbotnick (void);
- static int calc_penalty (char *);
- static int fast_deq (int);
- static char *splitnicks (char **);
- static void check_queues (char *, char *);
- static void parse_q (struct msgq_head *, char *, char *);
- static void purge_kicks (struct msgq_head *);
- static int deq_kick (int);
- static void msgq_clear (struct msgq_head *qh);
- static int stack_limit;
- #include "servmsg.c"
- #define MAXPENALTY 10
- #define msgrate 2
- static int maxqmsg;
- static struct msgq_head mq, hq, modeq;
- static int burst;
- #include "cmdsserv.c"
- #include "tclserv.c"
- static void
- deq_msg ()
- {
- struct msgq *q;
- int ok = 0;
- if ((now - last_time) >= msgrate || now < (last_time - 90))
- {
- last_time = now;
- if (burst > 0)
- burst--;
- ok = 1;
- }
- if (serv < 0)
- return;
- if (modeq.head)
- {
- while (modeq.head && (burst < 4) && ((last_time - now) < MAXPENALTY))
- {
- if (deq_kick (DP_MODE))
- {
- burst++;
- continue;
- }
- if (!modeq.head)
- break;
- if (fast_deq (DP_MODE))
- {
- burst++;
- continue;
- }
- tputs (serv, modeq.head->msg, modeq.head->len);
- if (debug_output)
- {
- modeq.head->msg[strlen (modeq.head->msg) - 1] = 0;
- putlog (LOG_SRVOUT, "@", "[m->] %s", modeq.head->msg);
- }
- modeq.tot--;
- last_time += calc_penalty (modeq.head->msg);
- q = modeq.head->next;
- nfree (modeq.head->msg);
- nfree (modeq.head);
- modeq.head = q;
- burst++;
- }
- if (!modeq.head)
- modeq.last = 0;
- return;
- }
- if (burst > 1)
- return;
- if (mq.head)
- {
- burst++;
- if (deq_kick (DP_SERVER))
- return;
- if (fast_deq (DP_SERVER))
- return;
- tputs (serv, mq.head->msg, mq.head->len);
- if (debug_output)
- {
- mq.head->msg[strlen (mq.head->msg) - 1] = 0;
- putlog (LOG_SRVOUT, "@", "[s->] %s", mq.head->msg);
- }
- mq.tot--;
- last_time += calc_penalty (mq.head->msg);
- q = mq.head->next;
- nfree (mq.head->msg);
- nfree (mq.head);
- mq.head = q;
- if (!mq.head)
- mq.last = NULL;
- return;
- }
- if (!hq.head || burst || !ok)
- return;
- if (deq_kick (DP_HELP))
- return;
- if (fast_deq (DP_HELP))
- return;
- tputs (serv, hq.head->msg, hq.head->len);
- if (debug_output)
- {
- hq.head->msg[strlen (hq.head->msg) - 1] = 0;
- putlog (LOG_SRVOUT, "*", "[h->] %s", hq.head->msg);
- }
- hq.tot--;
- last_time += calc_penalty (hq.head->msg);
- q = hq.head->next;
- nfree (hq.head->msg);
- nfree (hq.head);
- hq.head = q;
- if (!hq.head)
- hq.last = NULL;
- }
- static int
- calc_penalty (char *msg)
- {
- char *cmd, *par1, *par2, *par3;
- register int penalty, i, ii;
- if (!use_penalties && net_type != NETT_UNDERNET
- && net_type != NETT_HYBRID_EFNET)
- return 0;
- if (msg[strlen (msg) - 1] == '\n')
- msg[strlen (msg) - 1] = '\0';
- cmd = newsplit (&msg);
- if (msg)
- i = strlen (msg);
- else
- i = strlen (cmd);
- last_time -= 2;
- if (net_type == NETT_UNDERNET || net_type == NETT_HYBRID_EFNET)
- {
- last_time += (2 + i / 120);
- return 0;
- }
- penalty = (1 + i / 100);
- if (!egg_strcasecmp (cmd, "KICK"))
- {
- par1 = newsplit (&msg);
- par2 = newsplit (&msg);
- par3 = splitnicks (&par2);
- penalty++;
- while (strlen (par3) > 0)
- {
- par3 = splitnicks (&par2);
- penalty++;
- }
- ii = penalty;
- par3 = splitnicks (&par1);
- while (strlen (par1) > 0)
- {
- par3 = splitnicks (&par1);
- penalty += ii;
- }
- }
- else if (!egg_strcasecmp (cmd, "MODE"))
- {
- i = 0;
- par1 = newsplit (&msg);
- par2 = newsplit (&msg);
- if (!strlen (par2))
- i++;
- while (strlen (par2) > 0)
- {
- if (strchr ("ntimps", par2[0]))
- i += 3;
- else if (!strchr ("+-", par2[0]))
- i += 1;
- par2++;
- }
- while (strlen (msg) > 0)
- {
- newsplit (&msg);
- i += 2;
- }
- ii = 0;
- while (strlen (par1) > 0)
- {
- splitnicks (&par1);
- ii++;
- }
- penalty += (ii * i);
- }
- else if (!egg_strcasecmp (cmd, "TOPIC"))
- {
- penalty++;
- par1 = newsplit (&msg);
- par2 = newsplit (&msg);
- if (strlen (par2) > 0)
- {
- penalty += 2;
- par3 = splitnicks (&par1);
- while (strlen (par1) > 0)
- {
- par3 = splitnicks (&par1);
- penalty += 2;
- }
- }
- }
- else if (!egg_strcasecmp (cmd, "PRIVMSG")
- || !egg_strcasecmp (cmd, "NOTICE"))
- {
- par1 = newsplit (&msg);
- while (strlen (par1) > 0)
- {
- splitnicks (&par1);
- penalty++;
- }
- }
- else if (!egg_strcasecmp (cmd, "WHO"))
- {
- par1 = newsplit (&msg);
- par2 = par1;
- while (strlen (par1) > 0)
- {
- par2 = splitnicks (&par1);
- if (strlen (par2) > 4)
- penalty += 3;
- else
- penalty += 5;
- }
- }
- else if (!egg_strcasecmp (cmd, "AWAY"))
- {
- if (strlen (msg) > 0)
- penalty += 2;
- else
- penalty += 1;
- }
- else if (!egg_strcasecmp (cmd, "INVITE"))
- {
- penalty += 3;
- }
- else if (!egg_strcasecmp (cmd, "JOIN"))
- {
- penalty += 2;
- }
- else if (!egg_strcasecmp (cmd, "PART"))
- {
- penalty += 4;
- }
- else if (!egg_strcasecmp (cmd, "VERSION"))
- {
- penalty += 2;
- }
- else if (!egg_strcasecmp (cmd, "TIME"))
- {
- penalty += 2;
- }
- else if (!egg_strcasecmp (cmd, "TRACE"))
- {
- penalty += 2;
- }
- else if (!egg_strcasecmp (cmd, "NICK"))
- {
- penalty += 3;
- }
- else if (!egg_strcasecmp (cmd, "ISON"))
- {
- penalty += 1;
- }
- else if (!egg_strcasecmp (cmd, "WHOIS"))
- {
- penalty += 2;
- }
- else if (!egg_strcasecmp (cmd, "DNS"))
- {
- penalty += 2;
- }
- else
- penalty++;
- if (penalty > 99)
- penalty = 99;
- if (penalty < 2)
- {
- putlog (LOG_SRVOUT, "*", "Penalty < 2sec, that's impossible!");
- penalty = 2;
- }
- if (debug_output && penalty != 0)
- putlog (LOG_SRVOUT, "*", "Adding penalty: %i", penalty);
- return penalty;
- }
- char *
- splitnicks (char **rest)
- {
- register char *o, *r;
- if (!rest)
- return *rest = "";
- o = *rest;
- while (*o == ' ')
- o++;
- r = o;
- while (*o && *o != ',')
- o++;
- if (*o)
- *o++ = 0;
- *rest = o;
- return r;
- }
- static int
- fast_deq (int which)
- {
- struct msgq_head *h;
- struct msgq *m, *nm;
- char msgstr[511], nextmsgstr[511], tosend[511], victims[511],
- stackable[511], *msg, *nextmsg, *cmd, *nextcmd, *to, *nextto, *stckbl;
- int len, doit = 0, found = 0, cmd_count = 0, stack_method = 1;
- if (!use_fastdeq)
- return 0;
- switch (which)
- {
- case DP_MODE:
- h = &modeq;
- break;
- case DP_SERVER:
- h = &mq;
- break;
- case DP_HELP:
- h = &hq;
- break;
- default:
- return 0;
- }
- m = h->head;
- strncpyz (msgstr, m->msg, sizeof msgstr);
- msg = msgstr;
- cmd = newsplit (&msg);
- if (use_fastdeq > 1)
- {
- strncpyz (stackable, stackablecmds, sizeof stackable);
- stckbl = stackable;
- while (strlen (stckbl) > 0)
- if (!egg_strcasecmp (newsplit (&stckbl), cmd))
- {
- found = 1;
- break;
- }
- if (use_fastdeq == 2 && !found)
- return 0;
- if (use_fastdeq == 3 && found)
- return 0;
- strncpyz (stackable, stackable2cmds, sizeof stackable);
- stckbl = stackable;
- while (strlen (stckbl) > 0)
- if (!egg_strcasecmp (newsplit (&stckbl), cmd))
- {
- stack_method = 2;
- break;
- }
- }
- to = newsplit (&msg);
- len = strlen (to);
- if (to[len - 1] == '\n')
- to[len - 1] = 0;
- simple_sprintf (victims, "%s", to);
- while (m)
- {
- nm = m->next;
- if (!nm)
- break;
- strncpyz (nextmsgstr, nm->msg, sizeof nextmsgstr);
- nextmsg = nextmsgstr;
- nextcmd = newsplit (&nextmsg);
- nextto = newsplit (&nextmsg);
- len = strlen (nextto);
- if (nextto[len - 1] == '\n')
- nextto[len - 1] = 0;
- if (strcmp (to, nextto) && !strcmp (cmd, nextcmd)
- && !strcmp (msg, nextmsg)
- &&
- ((strlen (cmd) + strlen (victims) + strlen (nextto) + strlen (msg) +
- 2) < 510) && (!stack_limit || cmd_count < stack_limit - 1))
- {
- cmd_count++;
- if (stack_method == 1)
- simple_sprintf (victims, "%s,%s", victims, nextto);
- else
- simple_sprintf (victims, "%s %s", victims, nextto);
- doit = 1;
- m->next = nm->next;
- if (!nm->next)
- h->last = m;
- nfree (nm->msg);
- nfree (nm);
- h->tot--;
- }
- else
- m = m->next;
- }
- if (doit)
- {
- simple_sprintf (tosend, "%s %s %s", cmd, victims, msg);
- len = strlen (tosend);
- tosend[len - 1] = '\n';
- tputs (serv, tosend, len);
- m = h->head->next;
- nfree (h->head->msg);
- nfree (h->head);
- h->head = m;
- if (!h->head)
- h->last = 0;
- h->tot--;
- if (debug_output)
- {
- tosend[len - 1] = 0;
- switch (which)
- {
- case DP_MODE:
- putlog (LOG_SRVOUT, "*", "[m=>] %s", tosend);
- break;
- case DP_SERVER:
- putlog (LOG_SRVOUT, "*", "[s=>] %s", tosend);
- break;
- case DP_HELP:
- putlog (LOG_SRVOUT, "*", "[h=>] %s", tosend);
- break;
- }
- }
- last_time += calc_penalty (tosend);
- return 1;
- }
- return 0;
- }
- static void
- check_queues (char *oldnick, char *newnick)
- {
- if (optimize_kicks == 2)
- {
- if (modeq.head)
- parse_q (&modeq, oldnick, newnick);
- if (mq.head)
- parse_q (&mq, oldnick, newnick);
- if (hq.head)
- parse_q (&hq, oldnick, newnick);
- }
- }
- static void
- parse_q (struct msgq_head *q, char *oldnick, char *newnick)
- {
- struct msgq *m, *lm = NULL;
- char buf[511], *msg, *nicks, *nick, *chan, newnicks[511], newmsg[511];
- int changed;
- for (m = q->head; m;)
- {
- changed = 0;
- if (optimize_kicks == 2 && !egg_strncasecmp (m->msg, "KICK ", 5))
- {
- newnicks[0] = 0;
- strncpyz (buf, m->msg, sizeof buf);
- if (buf[0] && (buf[strlen (buf) - 1] == '\n'))
- buf[strlen (buf) - 1] = '\0';
- msg = buf;
- newsplit (&msg);
- chan = newsplit (&msg);
- nicks = newsplit (&msg);
- while (strlen (nicks) > 0)
- {
- nick = splitnicks (&nicks);
- if (!egg_strcasecmp (nick, oldnick)
- &&
- ((9 + strlen (chan) + strlen (newnicks) + strlen (newnick) +
- strlen (nicks) + strlen (msg)) < 510))
- {
- if (newnick)
- egg_snprintf (newnicks, sizeof newnicks, "%s,%s",
- newnicks, newnick);
- changed = 1;
- }
- else
- egg_snprintf (newnicks, sizeof newnicks, ",%s", nick);
- }
- egg_snprintf (newmsg, sizeof newmsg, "KICK %s %s %s\n", chan,
- newnicks + 1, msg);
- }
- if (changed)
- {
- if (newnicks[0] == 0)
- {
- if (!lm)
- q->head = m->next;
- else
- lm->next = m->next;
- nfree (m->msg);
- nfree (m);
- m = lm;
- q->tot--;
- if (!q->head)
- q->last = 0;
- }
- else
- {
- nfree (m->msg);
- m->msg = nmalloc (strlen (newmsg) + 1);
- m->len = strlen (newmsg);
- strcpy (m->msg, newmsg);
- }
- }
- lm = m;
- if (m)
- m = m->next;
- else
- m = q->head;
- }
- }
- static void
- purge_kicks (struct msgq_head *q)
- {
- struct msgq *m, *lm = NULL;
- char buf[511], *reason, *nicks, *nick, *chan, newnicks[511], newmsg[511],
- chans[511], *chns, *ch;
- int changed, found;
- struct chanset_t *cs;
- for (m = q->head; m;)
- {
- if (!egg_strncasecmp (m->msg, "KICK", 4))
- {
- newnicks[0] = 0;
- changed = 0;
- strncpyz (buf, m->msg, sizeof buf);
- if (buf[0] && (buf[strlen (buf) - 1] == '\n'))
- buf[strlen (buf) - 1] = '\0';
- reason = buf;
- newsplit (&reason);
- chan = newsplit (&reason);
- nicks = newsplit (&reason);
- while (strlen (nicks) > 0)
- {
- found = 0;
- nick = splitnicks (&nicks);
- strncpyz (chans, chan, sizeof chans);
- chns = chans;
- while (strlen (chns) > 0)
- {
- ch = newsplit (&chns);
- cs = findchan (ch);
- if (!cs)
- continue;
- if (ismember (cs, nick))
- found = 1;
- }
- if (found)
- egg_snprintf (newnicks, sizeof newnicks, "%s,%s", newnicks,
- nick);
- else
- {
- putlog (LOG_SRVOUT, "*",
- "%s isn't on any target channel, removing "
- "kick...", nick);
- changed = 1;
- }
- }
- if (changed)
- {
- if (newnicks[0] == 0)
- {
- if (!lm)
- q->head = m->next;
- else
- lm->next = m->next;
- nfree (m->msg);
- nfree (m);
- m = lm;
- q->tot--;
- if (!q->head)
- q->last = 0;
- }
- else
- {
- nfree (m->msg);
- egg_snprintf (newmsg, sizeof newmsg, "KICK %s %s %s\n",
- chan, newnicks + 1, reason);
- m->msg = nmalloc (strlen (newmsg) + 1);
- m->len = strlen (newmsg);
- strcpy (m->msg, newmsg);
- }
- }
- }
- lm = m;
- if (m)
- m = m->next;
- else
- m = q->head;
- }
- }
- static int
- deq_kick (int which)
- {
- struct msgq_head *h;
- struct msgq *msg, *m, *lm;
- char buf[511], buf2[511], *reason2, *nicks, *chan, *chan2, *reason, *nick,
- newnicks[511], newnicks2[511], newmsg[511];
- int changed = 0, nr = 0;
- if (!optimize_kicks)
- return 0;
- newnicks[0] = 0;
- switch (which)
- {
- case DP_MODE:
- h = &modeq;
- break;
- case DP_SERVER:
- h = &mq;
- break;
- case DP_HELP:
- h = &hq;
- break;
- default:
- return 0;
- }
- if (egg_strncasecmp (h->head->msg, "KICK", 4))
- return 0;
- if (optimize_kicks == 2)
- {
- purge_kicks (h);
- if (!h->head)
- return 1;
- }
- if (egg_strncasecmp (h->head->msg, "KICK", 4))
- return 0;
- msg = h->head;
- strncpyz (buf, msg->msg, sizeof buf);
- reason = buf;
- newsplit (&reason);
- chan = newsplit (&reason);
- nicks = newsplit (&reason);
- while (strlen (nicks) > 0)
- {
- egg_snprintf (newnicks, sizeof newnicks, "%s,%s", newnicks,
- newsplit (&nicks));
- nr++;
- }
- for (m = msg->next, lm = NULL; m && (nr < kick_method);)
- {
- if (!egg_strncasecmp (m->msg, "KICK", 4))
- {
- changed = 0;
- newnicks2[0] = 0;
- strncpyz (buf2, m->msg, sizeof buf2);
- if (buf2[0] && (buf2[strlen (buf2) - 1] == '\n'))
- buf2[strlen (buf2) - 1] = '\0';
- reason2 = buf2;
- newsplit (&reason2);
- chan2 = newsplit (&reason2);
- nicks = newsplit (&reason2);
- if (!egg_strcasecmp (chan, chan2)
- && !egg_strcasecmp (reason, reason2))
- {
- while (strlen (nicks) > 0)
- {
- nick = splitnicks (&nicks);
- if ((nr < kick_method)
- &&
- ((9 + strlen (chan) + strlen (newnicks) +
- strlen (nick) + strlen (reason)) < 510))
- {
- egg_snprintf (newnicks, sizeof newnicks, "%s,%s",
- newnicks, nick);
- nr++;
- changed = 1;
- }
- else
- egg_snprintf (newnicks2, sizeof newnicks2, "%s,%s",
- newnicks2, nick);
- }
- }
- if (changed)
- {
- if (newnicks2[0] == 0)
- {
- if (!lm)
- h->head->next = m->next;
- else
- lm->next = m->next;
- nfree (m->msg);
- nfree (m);
- m = lm;
- h->tot--;
- if (!h->head)
- h->last = 0;
- }
- else
- {
- nfree (m->msg);
- egg_snprintf (newmsg, sizeof newmsg, "KICK %s %s %s\n",
- chan2, newnicks2 + 1, reason);
- m->msg = nmalloc (strlen (newmsg) + 1);
- m->len = strlen (newmsg);
- strcpy (m->msg, newmsg);
- }
- }
- }
- lm = m;
- if (m)
- m = m->next;
- else
- m = h->head->next;
- }
- egg_snprintf (newmsg, sizeof newmsg, "KICK %s %s %s\n", chan, newnicks + 1,
- reason);
- tputs (serv, newmsg, strlen (newmsg));
- if (debug_output)
- {
- newmsg[strlen (newmsg) - 1] = 0;
- switch (which)
- {
- case DP_MODE:
- putlog (LOG_SRVOUT, "@", "[m->] %s", newmsg);
- break;
- case DP_SERVER:
- putlog (LOG_SRVOUT, "@", "[s->] %s", newmsg);
- break;
- case DP_HELP:
- putlog (LOG_SRVOUT, "@", "[h->] %s", newmsg);
- break;
- }
- debug3 ("Changed: %d, kick-method: %d, nr: %d", changed, kick_method,
- nr);
- }
- h->tot--;
- last_time += calc_penalty (newmsg);
- m = h->head->next;
- nfree (h->head->msg);
- nfree (h->head);
- h->head = m;
- if (!h->head)
- h->last = 0;
- return 1;
- }
- static void
- empty_msgq ()
- {
- msgq_clear (&modeq);
- msgq_clear (&mq);
- msgq_clear (&hq);
- burst = 0;
- } static void
- queue_server (int which, char *buf, int len)
- {
- struct msgq_head *h = NULL, tempq;
- struct msgq *q, *tq, *tqq;
- int doublemsg = 0, qnext = 0;
- if (serv < 0)
- return;
- if (!egg_strncasecmp (buf, "PING", 4) || !egg_strncasecmp (buf, "PONG", 4))
- {
- if (buf[1] == 'I' || buf[1] == 'i')
- lastpingtime = now;
- tputs (serv, buf, len);
- if (debug_output)
- {
- if (buf[len - 1] == '\n')
- buf[len - 1] = 0;
- putlog (LOG_SRVOUT, "@", "[m->] %s", buf);
- }
- return;
- }
- switch (which)
- {
- case DP_MODE_NEXT:
- qnext = 1;
- case DP_MODE:
- h = &modeq;
- tempq = modeq;
- if (double_mode)
- doublemsg = 1;
- break;
- case DP_SERVER_NEXT:
- qnext = 1;
- case DP_SERVER:
- h = &mq;
- tempq = mq;
- if (double_server)
- doublemsg = 1;
- break;
- case DP_HELP_NEXT:
- qnext = 1;
- case DP_HELP:
- h = &hq;
- tempq = hq;
- if (double_help)
- doublemsg = 1;
- break;
- default:
- putlog (LOG_MISC, "*", "!!! queuing unknown type to server!!");
- return;
- }
- if (h->tot < maxqmsg)
- {
- if (!doublemsg)
- for (tq = tempq.head; tq; tq = tqq)
- {
- tqq = tq->next;
- if (!egg_strcasecmp (tq->msg, buf))
- {
- if (!double_warned)
- {
- if (buf[len - 1] == '\n')
- buf[len - 1] = 0;
- debug1 ("msg already queued. skipping: %s", buf);
- double_warned = 1;
- }
- return;
- }
- }
- q = nmalloc (sizeof (struct msgq));
- if (qnext)
- q->next = h->head;
- else
- q->next = NULL;
- if (h->head)
- {
- if (!qnext)
- h->last->next = q;
- }
- else
- h->head = q;
- if (qnext)
- h->head = q;
- h->last = q;
- q->len = len;
- q->msg = nmalloc (len + 1);
- strncpyz (q->msg, buf, len + 1);
- h->tot++;
- h->warned = 0;
- double_warned = 0;
- }
- else
- {
- if (!h->warned)
- {
- switch (which)
- {
- case DP_MODE_NEXT:
- case DP_MODE:
- putlog (LOG_MISC, "*", "!!! OVER MAXIMUM MODE QUEUE");
- break;
- case DP_SERVER_NEXT:
- case DP_SERVER:
- putlog (LOG_MISC, "*", "!!! OVER MAXIMUM SERVER QUEUE");
- break;
- case DP_HELP_NEXT:
- case DP_HELP:
- putlog (LOG_MISC, "*", "!!! OVER MAXIMUM HELP QUEUE");
- break;
- }
- }
- h->warned = 1;
- }
- if (debug_output && !h->warned)
- {
- if (buf[len - 1] == '\n')
- buf[len - 1] = 0;
- switch (which)
- {
- case DP_MODE:
- putlog (LOG_SRVOUT, "@", "[!m] %s", buf);
- break;
- case DP_SERVER:
- putlog (LOG_SRVOUT, "@", "[!s] %s", buf);
- break;
- case DP_HELP:
- putlog (LOG_SRVOUT, "@", "[!h] %s", buf);
- break;
- case DP_MODE_NEXT:
- putlog (LOG_SRVOUT, "@", "[!!m] %s", buf);
- break;
- case DP_SERVER_NEXT:
- putlog (LOG_SRVOUT, "@", "[!!s] %s", buf);
- break;
- case DP_HELP_NEXT:
- putlog (LOG_SRVOUT, "@", "[!!h] %s", buf);
- break;
- }
- }
- if (which == DP_MODE || which == DP_MODE_NEXT)
- deq_msg ();
- }
- static void
- add_server (char *ss)
- {
- struct server_list *x, *z;
- char *p, *q;
- for (z = serverlist; z && z->next; z = z->next);
- while (ss)
- {
- p = strchr (ss, ',');
- if (p)
- *p++ = 0;
- x = nmalloc (sizeof (struct server_list));
- x->next = 0;
- x->realname = 0;
- x->port = 0;
- if (z)
- z->next = x;
- else
- serverlist = x;
- z = x;
- q = strchr (ss, ':');
- if (!q)
- {
- x->port = default_port;
- x->pass = 0;
- x->name = nmalloc (strlen (ss) + 1);
- strcpy (x->name, ss);
- }
- else
- {
- *q++ = 0;
- x->name = nmalloc (q - ss);
- strcpy (x->name, ss);
- ss = q;
- q = strchr (ss, ':');
- if (!q)
- {
- x->pass = 0;
- }
- else
- {
- *q++ = 0;
- x->pass = nmalloc (strlen (q) + 1);
- strcpy (x->pass, q);
- }
- x->port = atoi (ss);
- }
- ss = p;
- }
- }
- static void
- clearq (struct server_list *xx)
- {
- struct server_list *x;
- while (xx)
- {
- x = xx->next;
- if (xx->name)
- nfree (xx->name);
- if (xx->pass)
- nfree (xx->pass);
- if (xx->realname)
- nfree (xx->realname);
- nfree (xx);
- xx = x;
- }
- }
- void
- servers_describe (struct cfg_entry *entry, int idx)
- {
- } void
- servers6_describe (struct cfg_entry *entry, int idx)
- {
- } int
- count (const char *s)
- {
- char *ele;
- int i = 0;
- char count[1000];
- strcpy (count, s);
- ele = strtok (count, ",");
- while (ele && *ele)
- {
- i++;
- ele = strtok ((char *) NULL, ",");
- } return i - 1;
- }
- int
- rrand (int a, int b)
- {
- b++;
- return ((random () % (b - a)) + a);
- }
- char *
- randomize (char *line, char **new)
- {
- char *str, *words[1000], *bak;
- int i, o, b, r, u = 0;
- Context;
- bak = line;
- i = count (line);
- b = i + 1;
- str = strtok (line, ",");
- o = 0;
- while (str && *str)
- {
- words[o] = str;
- o++;
- str = strtok ((char *) NULL, ",");
- } while (b)
- {
- if (u > 200)
- {
- sprintf (*new, "%s", bak);
- return *new;
- }
- r = rrand (0, i);
- if (strstr (*new, words[r]) == NULL)
- {
- if (b == i + 1)
- sprintf (*new, "%s", words[r]);
- else
- sprintf (*new, "%s,%s", *new, words[r]);
- b--;
- }
- else
- u++;
- }
- return *new;
- }
- void
- servers_changed (struct cfg_entry *entry, char *olddata, int *valid)
- {
- #ifdef LEAF
- char *slist, *p;
- #ifdef S_RANDSERVERS
- char *new;
- if (hostname6[0])
- return;
- #endif
- slist =
- (char *) (entry->ldata ? entry->
- ldata : (entry->gdata ? entry->gdata : ""));
- if (serverlist)
- {
- clearq (serverlist);
- serverlist = NULL;
- }
- p = nmalloc (strlen (slist) + 1);
- strcpy (p, slist);
- #ifdef S_RANDSERVERS
- new = nmalloc (strlen (slist) + 1);
- randomize (p, &new);
- strcpy (p, new);
- #endif
- add_server (p);
- nfree (p);
- nfree (new);
- #endif
- }
- void
- servers6_changed (struct cfg_entry *entry, char *olddata, int *valid)
- {
- #ifdef LEAF
- char *slist, *p;
- #ifdef S_RANDSERVERS
- char *new;
- if (!hostname6[0])
- return;
- #endif
- slist =
- (char *) (entry->ldata ? entry->
- ldata : (entry->gdata ? entry->gdata : ""));
- if (serverlist)
- {
- clearq (serverlist);
- serverlist = NULL;
- }
- p = nmalloc (strlen (slist) + 1);
- strcpy (p, slist);
- #ifdef S_RANDSERVERS
- new = nmalloc (strlen (slist) + 1);
- randomize (p, &new);
- strcpy (p, new);
- #endif
- add_server (p);
- nfree (p);
- nfree (new);
- #endif
- }
- void
- nick_describe (struct cfg_entry *entry, int idx)
- {
- } void
- nick_changed (struct cfg_entry *entry, char *olddata, int *valid)
- {
- #ifdef LEAF
- char *p;
- if (entry->ldata)
- p = entry->ldata;
- else if (entry->gdata)
- p = entry->gdata;
- else
- p = NULL;
- if (p && p[0])
- {
- strncpy0 (origbotname, p, NICKMAX + 1);
- }
- else
- {
- strncpy0 (origbotname, botnetnick, NICKMAX + 1);
- }
- #endif
- }
- void
- realname_describe (struct cfg_entry *entry, int idx)
- {
- } void
- realname_changed (struct cfg_entry *entry, char *olddata, int *valid)
- {
- #ifdef LEAF
- if (entry->ldata)
- {
- strncpy0 (botrealname, (char *) entry->ldata, 120);
- }
- else if (entry->gdata)
- {
- strncpy0 (botrealname, (char *) entry->gdata, 120);
- }
- #endif
- } struct cfg_entry CFG_SERVERS =
- { "servers", CFGF_LOCAL | CFGF_GLOBAL, NULL, NULL, servers_changed,
- servers_changed, servers_describe };
- struct cfg_entry CFG_SERVERS6 =
- { "servers6", CFGF_LOCAL | CFGF_GLOBAL, NULL, NULL, servers6_changed,
- servers6_changed, servers6_describe };
- struct cfg_entry CFG_NICK =
- { "nick", CFGF_LOCAL | CFGF_GLOBAL, NULL, NULL, nick_changed, nick_changed,
- nick_describe };
- struct cfg_entry CFG_REALNAME =
- { "realname", CFGF_LOCAL | CFGF_GLOBAL, NULL, NULL, realname_changed,
- realname_changed, realname_describe };
- static void
- next_server (int *ptr, char *serv, unsigned int *port, char *pass)
- {
- struct server_list *x = serverlist;
- int i = 0;
- if (x == NULL)
- return;
- if (*ptr == (-1))
- {
- for (; x; x = x->next)
- {
- if (x->port == *port)
- {
- if (!egg_strcasecmp (x->name, serv))
- {
- *ptr = i;
- return;
- }
- else if (x->realname && !egg_strcasecmp (x->realname, serv))
- {
- *ptr = i;
- strncpyz (serv, x->realname, sizeof serv);
- return;
- }
- }
- i++;
- }
- x = nmalloc (sizeof (struct server_list));
- x->next = 0;
- x->realname = 0;
- x->name = nmalloc (strlen (serv) + 1);
- strcpy (x->name, serv);
- x->port = *port ? *port : default_port;
- if (pass && pass[0])
- {
- x->pass = nmalloc (strlen (pass) + 1);
- strcpy (x->pass, pass);
- }
- else
- x->pass = NULL;
- list_append ((struct list_type **) (&serverlist),
- (struct list_type *) x);
- *ptr = i;
- return;
- }
- i = (*ptr);
- while (i > 0 && x != NULL)
- {
- x = x->next;
- i--;
- }
- if (x != NULL)
- {
- x = x->next;
- (*ptr)++;
- }
- if (x == NULL)
- {
- x = serverlist;
- *ptr = 0;
- }
- strcpy (serv, x->name);
- *port = x->port ? x->port : default_port;
- if (x->pass)
- strcpy (pass, x->pass);
- else
- pass[0] = 0;
- }
- static int server_6char STDVAR
- {
- Function F = (Function) cd;
- char x[20];
- BADARGS (7, 7, " nick user@host handle desto/chan keyword/nick text");
- CHECKVALIDITY (server_6char);
- egg_snprintf (x, sizeof x, "%d",
- F (argv[1], argv[2], argv[3], argv[4], argv[5], argv[6]));
- Tcl_AppendResult (irp, x, NULL);
- return TCL_OK;
- }
- static int server_5char STDVAR
- {
- Function F = (Function) cd;
- BADARGS (6, 6, " nick user@host handle channel text");
- CHECKVALIDITY (server_5char);
- F (argv[1], argv[2], argv[3], argv[4], argv[5]);
- return TCL_OK;
- }
- static int server_2char STDVAR
- {
- Function F = (Function) cd;
- BADARGS (3, 3, " nick msg");
- CHECKVALIDITY (server_2char);
- F (argv[1], argv[2]);
- return TCL_OK;
- }
- static int server_msg STDVAR
- {
- Function F = (Function) cd;
- BADARGS (5, 5, " nick uhost hand buffer");
- CHECKVALIDITY (server_msg);
- F (argv[1], argv[2], get_user_by_handle (userlist, argv[3]), argv[4]);
- return TCL_OK;
- }
- static int server_raw STDVAR
- {
- Function F = (Function) cd;
- BADARGS (4, 4, " from code args");
- CHECKVALIDITY (server_raw);
- Tcl_AppendResult (irp, int_to_base10 (F (argv[1], argv[3])), NULL);
- return TCL_OK;
- }
- #if (((TCL_MAJOR_VERSION == 8) && (TCL_MINOR_VERSION >= 4)) || (TCL_MAJOR_VERSION > 8))
- static char *
- nick_change (ClientData cdata, Tcl_Interp * irp, CONST char *name1,
- CONST char *name2, int flags)
- #else
- static char *
- nick_change (ClientData cdata, Tcl_Interp * irp, char *name1, char *name2,
- int flags)
- #endif
- {
- #if (((TCL_MAJOR_VERSION == 8) && (TCL_MINOR_VERSION >= 4)) || (TCL_MAJOR_VERSION > 8))
- CONST char *new;
- #else
- char *new;
- #endif
- if (flags & (TCL_TRACE_READS | TCL_TRACE_UNSETS))
- {
- Tcl_SetVar2 (interp, name1, name2, origbotname, TCL_GLOBAL_ONLY);
- if (flags & TCL_TRACE_UNSETS)
- Tcl_TraceVar (irp, name1,
- TCL_TRACE_READS | TCL_TRACE_WRITES | TCL_TRACE_UNSETS,
- nick_change, cdata);
- }
- else
- {
- new = Tcl_GetVar2 (interp, name1, name2, TCL_GLOBAL_ONLY);
- if (rfc_casecmp (origbotname, (char *) new))
- {
- if (origbotname[0])
- {
- putlog (LOG_MISC, "*", "* IRC NICK CHANGE: %s -> %s",
- origbotname, new);
- nick_juped = 0;
- }
- strncpyz (origbotname, new, NICKLEN);
- if (server_online)
- dprintf (DP_SERVER, "NICK %s\n", origbotname);
- }
- }
- return NULL;
- }
- static void
- rand_nick (char *nick)
- {
- register char *p = nick;
- while ((p = strchr (p, '?')) != NULL)
- {
- *p = '0' + random () % 10;
- p++;
- }
- }
- static char *
- get_altbotnick (void)
- {
- if (strchr (altnick, '?'))
- {
- if (!raltnick[0])
- {
- strncpyz (raltnick, altnick, NICKLEN);
- rand_nick (raltnick);
- }
- return raltnick;
- }
- else
- return altnick;
- }
- #if (((TCL_MAJOR_VERSION == 8) && (TCL_MINOR_VERSION >= 4)) || (TCL_MAJOR_VERSION > 8))
- static char *
- altnick_change (ClientData cdata, Tcl_Interp * irp, CONST char *name1,
- CONST char *name2, int flags)
- #else
- static char *
- altnick_change (ClientData cdata, Tcl_Interp * irp, char *name1, char *name2,
- int flags)
- #endif
- {
- raltnick[0] = 0;
- return NULL;
- }
- #if (((TCL_MAJOR_VERSION == 8) && (TCL_MINOR_VERSION >= 4)) || (TCL_MAJOR_VERSION > 8))
- static char *
- traced_server (ClientData cdata, Tcl_Interp * irp, CONST char *name1,
- CONST char *name2, int flags)
- #else
- static char *
- traced_server (ClientData cdata, Tcl_Interp * irp, char *name1, char *name2,
- int flags)
- #endif
- {
- char s[1024];
- if (server_online)
- {
- int servidx = findanyidx (serv);
- simple_sprintf (s, "%s:%u", dcc[servidx].host, dcc[servidx].port);
- }
- else
- s[0] = 0;
- Tcl_SetVar2 (interp, name1, name2, s, TCL_GLOBAL_ONLY);
- if (flags & TCL_TRACE_UNSETS)
- Tcl_TraceVar (irp, name1,
- TCL_TRACE_READS | TCL_TRACE_WRITES | TCL_TRACE_UNSETS,
- traced_server, cdata);
- return NULL;
- }
- #if (((TCL_MAJOR_VERSION == 8) && (TCL_MINOR_VERSION >= 4)) || (TCL_MAJOR_VERSION > 8))
- static char *
- traced_botname (ClientData cdata, Tcl_Interp * irp, CONST char *name1,
- CONST char *name2, int flags)
- #else
- static char *
- traced_botname (ClientData cdata, Tcl_Interp * irp, char *name1, char *name2,
- int flags)
- #endif
- {
- char s[1024];
- simple_sprintf (s, "%s%s%s", botname, botuserhost[0] ? "!" : "",
- botuserhost[0] ? botuserhost : "");
- Tcl_SetVar2 (interp, name1, name2, s, TCL_GLOBAL_ONLY);
- if (flags & TCL_TRACE_UNSETS)
- Tcl_TraceVar (irp, name1,
- TCL_TRACE_READS | TCL_TRACE_WRITES | TCL_TRACE_UNSETS,
- traced_botname, cdata);
- return NULL;
- }
- static void
- do_nettype (void)
- {
- switch (net_type)
- {
- case NETT_EFNET:
- check_mode_r = 0;
- nick_len = 9;
- break;
- case NETT_IRCNET:
- check_mode_r = 1;
- use_penalties = 1;
- use_fastdeq = 3;
- nick_len = 9;
- simple_sprintf (stackablecmds, "INVITE AWAY VERSION NICK");
- kick_method = 4;
- break;
- case NETT_UNDERNET:
- check_mode_r = 0;
- use_fastdeq = 2;
- nick_len = 9;
- simple_sprintf (stackablecmds,
- "PRIVMSG NOTICE TOPIC PART WHOIS USERHOST USERIP ISON");
- simple_sprintf (stackable2cmds, "USERHOST USERIP ISON");
- break;
- case NETT_DALNET:
- check_mode_r = 0;
- use_fastdeq = 2;
- nick_len = 32;
- simple_sprintf (stackablecmds,
- "PRIVMSG NOTICE PART WHOIS WHOWAS USERHOST ISON WATCH DCCALLOW");
- simple_sprintf (stackable2cmds, "USERHOST ISON WATCH");
- break;
- case NETT_HYBRID_EFNET:
- check_mode_r = 0;
- nick_len = 9;
- break;
- }
- }
- #if (((TCL_MAJOR_VERSION == 8) && (TCL_MINOR_VERSION >= 4)) || (TCL_MAJOR_VERSION > 8))
- static char *
- traced_nettype (ClientData cdata, Tcl_Interp * irp, CONST char *name1,
- CONST char *name2, int flags)
- #else
- static char *
- traced_nettype (ClientData cdata, Tcl_Interp * irp, char *name1, char *name2,
- int flags)
- #endif
- {
- do_nettype ();
- return NULL;
- }
- #if (((TCL_MAJOR_VERSION == 8) && (TCL_MINOR_VERSION >= 4)) || (TCL_MAJOR_VERSION > 8))
- static char *
- traced_nicklen (ClientData cdata, Tcl_Interp * irp, CONST char *name1,
- CONST char *name2, int flags)
- #else
- static char *
- traced_nicklen (ClientData cdata, Tcl_Interp * irp, char *name1, char *name2,
- int flags)
- #endif
- {
- if (flags & (TCL_TRACE_READS | TCL_TRACE_UNSETS))
- {
- char s[40];
- egg_snprintf (s, sizeof s, "%d", nick_len);
- Tcl_SetVar2 (interp, name1, name2, s, TCL_GLOBAL_ONLY);
- if (flags & TCL_TRACE_UNSETS)
- Tcl_TraceVar (irp, name1, TCL_TRACE_WRITES | TCL_TRACE_UNSETS,
- traced_nicklen, cdata);
- }
- else
- {
- #if (((TCL_MAJOR_VERSION == 8) && (TCL_MINOR_VERSION >= 4)) || (TCL_MAJOR_VERSION > 8))
- CONST char *cval = Tcl_GetVar2 (interp, name1, name2, TCL_GLOBAL_ONLY);
- #else
- char *cval = Tcl_GetVar2 (interp, name1, name2, TCL_GLOBAL_ONLY);
- #endif
- long lval = 0;
- Context;
- if (cval && Tcl_ExprLong (interp, cval, &lval) != TCL_ERROR)
- {
- if (lval > NICKMAX)
- lval = NICKMAX;
- nick_len = (int) lval;
- }
- } return NULL;
- }
- static tcl_strings my_tcl_strings[] =
- { {"botnick", NULL, 0, STR_PROTECT}, {"altnick", altnick, NICKMAX, 0},
- {"realname", botrealname, 80, 0}, {"init-server", initserver, 120, 0},
- {"connect-server", connectserver, 120, 0}, {"stackable-commands",
- stackablecmds, 510, 0},
- {"stackable2-commands", stackable2cmds, 510, 0}, {NULL, NULL, 0, 0} };
- static tcl_coups my_tcl_coups[] =
- { {"flood-msg", &flud_thr, &flud_time}, {"flood-ctcp", &flud_ctcp_thr,
- &flud_ctcp_time}, {NULL, NULL,
- NULL} };
- static tcl_ints my_tcl_ints[] =
- { {"use-console-r", NULL, 1}, {"servlimit", &min_servs, 0},
- {"server-timeout", &server_timeout, 0}, {"lowercase-ctcp", &lowercase_ctcp,
- 0}, {"server-online",
- (int *) &server_online, 2},
- {"never-give-up", &never_give_up, 0}, {"keep-nick", &keepnick, 0},
- {"strict-servernames", &strict_servernames, 0}, {"check-stoned",
- &check_stoned, 0},
- {"serverror-quit", &serverror_quit, 0}, {"quiet-reject", &quiet_reject, 0},
- {"max-queue-msg", &maxqmsg, 0}, {"trigger-on-ignore", &trigger_on_ignore,
- 0}, {"answer-ctcp", &answer_ctcp, 0},
- {"server-cycle-wait", (int *) &server_cycle_wait, 0}, {"default-port",
- &default_port, 0},
- {"check-mode-r", &check_mode_r, 0}, {"net-type", &net_type, 0},
- {"ctcp-mode", &ctcp_mode, 0}, {"double-mode", &double_mode, 0},
- {"double-server", &double_server, 0}, {"double-help", &double_help, 0},
- {"use-penalties", &use_penalties, 0}, {"use-fastdeq", &use_fastdeq, 0},
- {"nicklen", &nick_len, 0}, {"nick-len", &nick_len, 0}, {"optimize-kicks",
- &optimize_kicks, 0},
- {"isjuped", &nick_juped, 0}, {"stack-limit", &stack_limit, 0}, {NULL, NULL,
- 0} };
- static void dcc_chat_hostresolved (int);
- static int
- ctcp_DCC_CHAT (char *nick, char *from, char *handle, char *object,
- char *keyword, char *text)
- {
- char *action, *param, *ip, *prt, buf[512], *msg = buf;
- int i, ok;
- struct userrec *u = get_user_by_handle (userlist, handle);
- struct flag_record fr = { FR_GLOBAL | FR_CHAN | FR_ANYWH, 0, 0, 0, 0, 0 };
- if (!ischanhub () && !issechub ())
- return 0;
- strcpy (msg, text);
- action = newsplit (&msg);
- param = newsplit (&msg);
- ip = newsplit (&msg);
- prt = newsplit (&msg);
- if (egg_strcasecmp (action, "CHAT") || egg_strcasecmp (object, botname)
- || !u)
- return 0;
- get_user_flagrec (u, &fr, 0);
- ok = 1;
- if (issechub () && !glob_huba (fr))
- ok = 0;
- if (ischanhub () && !glob_chuba (fr))
- ok = 0;
- if (dcc_total == max_dcc)
- {
- if (!quiet_reject)
- dprintf (DP_HELP, "NOTICE %s :%s\n", nick, DCC_TOOMANYDCCS1);
- putlog (LOG_MISC, "*", DCC_TOOMANYDCCS2, "CHAT", param, nick, from);
- }
- else if (!ok)
- {
- if (!quiet_reject)
- dprintf (DP_HELP, "NOTICE %s :%s\n", nick, DCC_REFUSED2);
- putlog (LOG_MISC, "*", "%s: %s!%s", DCC_REFUSED, nick, from);
- }
- else if (u_pass_match (u, "-"))
- {
- if (!quiet_reject)
- dprintf (DP_HELP, "NOTICE %s :%s\n", nick, DCC_REFUSED3);
- putlog (LOG_MISC, "*", "%s: %s!%s", DCC_REFUSED4, nick, from);
- }
- else if (atoi (prt) < 1024 || atoi (prt) > 65535)
- {
- if (!quiet_reject)
- dprintf (DP_HELP, "NOTICE %s :%s (invalid port)\n", nick,
- DCC_CONNECTFAILED1);
- putlog (LOG_MISC, "*", "%s: CHAT (%s!%s)", DCC_CONNECTFAILED3, nick,
- from);
- }
- else
- {
- if (!sanitycheck_dcc (nick, from, ip, prt))
- return 1;
- i = new_dcc (&DCC_DNSWAIT, sizeof (struct dns_info));
- if (i < 0)
- {
- putlog (LOG_MISC, "*", "DCC connection: CHAT (%s!%s)", dcc[i].nick,
- ip);
- return 1;
- }
- dcc[i].addr = my_atoul (ip);
- dcc[i].port = atoi (prt);
- dcc[i].sock = -1;
- strcpy (dcc[i].nick, u->handle);
- strcpy (dcc[i].host, from);
- dcc[i].timeval = now;
- dcc[i].user = u;
- dcc[i].u.dns->ip = dcc[i].addr;
- dcc[i].u.dns->dns_type = RES_HOSTBYIP;
- dcc[i].u.dns->dns_success = dcc_chat_hostresolved;
- dcc[i].u.dns->dns_failure = dcc_chat_hostresolved;
- dcc[i].u.dns->type = &DCC_CHAT_PASS;
- dcc_dnshostbyip (dcc[i].addr);
- }
- return 1;
- }
- static void
- dcc_chat_hostresolved (int i)
- {
- char buf[512], ip[512];
- int ok;
- struct flag_record fr = { FR_GLOBAL | FR_CHAN | FR_ANYWH, 0, 0, 0, 0, 0 };
- egg_snprintf (buf, sizeof buf, "%d", dcc[i].port);
- if (!hostsanitycheck_dcc
- (dcc[i].nick, dcc[i].host, dcc[i].addr, dcc[i].u.dns->host, buf))
- {
- lostdcc (i);
- return;
- }
- egg_snprintf (ip, sizeof ip, "%lu", iptolong (htonl (dcc[i].addr)));
- dcc[i].sock = getsock (0, getprotocol (ip));
- if (dcc[i].sock < 0 || open_telnet_dcc (dcc[i].sock, ip, buf) < 0)
- {
- neterror (buf);
- if (!quiet_reject)
- dprintf (DP_HELP, "NOTICE %s :%s (%s)\n", dcc[i].nick,
- DCC_CONNECTFAILED1, buf);
- putlog (LOG_MISC, "*", "%s: CHAT (%s!%s)", DCC_CONNECTFAILED2,
- dcc[i].nick, dcc[i].host);
- putlog (LOG_MISC, "*", " (%s)", buf);
- killsock (dcc[i].sock);
- lostdcc (i);
- }
- else
- {
- changeover_dcc (i, &DCC_CHAT_PASS, sizeof (struct chat_info));
- dcc[i].status = STAT_ECHO;
- get_user_flagrec (dcc[i].user, &fr, 0);
- ok = 1;
- if (issechub () && !glob_huba (fr))
- ok = 0;
- if (ischanhub () && !glob_chuba (fr))
- ok = 0;
- if (ok)
- dcc[i].status |= STAT_PARTY;
- strcpy (dcc[i].u.chat->con_chan, (chanset) ? chanset->dname : "*");
- dcc[i].timeval = now;
- putlog (LOG_MISC, "*", "DCC connection: CHAT (%s!%s)", dcc[i].nick,
- dcc[i].host);
- dprintf (i, "%s", rand_dccresp ());
- }
- return;
- }
- static void
- server_secondly ()
- {
- if (cycle_time)
- cycle_time--;
- deq_msg ();
- if (!resolvserv && serv < 0)
- connect_server ();
- }
- static void
- server_5minutely ()
- {
- if (check_stoned && server_online)
- {
- if (waiting_for_awake)
- {
- int servidx = findanyidx (serv);
- disconnect_server (servidx);
- lostdcc (servidx);
- putlog (LOG_SERV, "*", IRC_SERVERSTONED);
- }
- else if (!trying_server)
- {
- dprintf (DP_MODE, "PING :%lu\n", (unsigned long) now);
- waiting_for_awake = 1;
- }
- }
- } static void
- server_prerehash ()
- {
- strcpy (oldnick, botname);
- } static void
- server_postrehash ()
- {
- strncpyz (botname, origbotname, NICKLEN);
- if (oldnick[0] && !rfc_casecmp (oldnick, botname)
- && !rfc_casecmp (oldnick, get_altbotnick ()))
- {
- strcpy (botname, oldnick);
- dprintf (DP_SERVER, "NICK %s\n", origbotname);
- }
- else if (oldnick[0])
- strcpy (botname, oldnick);
- }
- static void
- server_die ()
- {
- cycle_time = 100;
- if (server_online)
- {
- dprintf (-serv, "QUIT :%s\n", quit_msg[0] ? quit_msg : "");
- sleep (3);
- }
- nuke_server (NULL);
- }
- static void
- server_report (int idx, int details)
- {
- char s1[64], s[128];
- int servidx;
- if (server_online)
- {
- dprintf (idx, " Online as: %s%s%s (%s)\n", botname,
- botuserhost[0] ? "!" : "", botuserhost[0] ? botuserhost : "",
- botrealname);
- if (nick_juped)
- dprintf (idx, " NICK IS JUPED: %s %s\n", origbotname,
- keepnick ? "(trying)" : "");
- nick_juped = 0;
- daysdur (now, server_online, s1);
- egg_snprintf (s, sizeof s, "(connected %s)", s1);
- if (server_lag && !waiting_for_awake)
- {
- if (server_lag == (-1))
- egg_snprintf (s1, sizeof s1, " (bad pong replies)");
- else
- egg_snprintf (s1, sizeof s1, " (lag: %ds)", server_lag);
- strcat (s, s1);
- }
- }
- if ((trying_server || server_online)
- && ((servidx = findanyidx (serv)) != (-1)))
- {
- dprintf (idx, " Server %s:%d %s\n", dcc[servidx].host,
- dcc[servidx].port, trying_server ? "(trying)" : s);
- }
- else
- dprintf (idx, " %s\n", IRC_NOSERVER);
- if (modeq.tot)
- dprintf (idx, " %s %d%%, %d msgs\n", IRC_MODEQUEUE,
- (int) ((float) (modeq.tot * 100.0) / (float) maxqmsg),
- (int) modeq.tot);
- if (mq.tot)
- dprintf (idx, " %s %d%%, %d msgs\n", IRC_SERVERQUEUE,
- (int) ((float) (mq.tot * 100.0) / (float) maxqmsg),
- (int) mq.tot);
- if (hq.tot)
- dprintf (idx, " %s %d%%, %d msgs\n", IRC_HELPQUEUE,
- (int) ((float) (hq.tot * 100.0) / (float) maxqmsg),
- (int) hq.tot);
- if (details)
- {
- if (min_servs)
- dprintf (idx, " Requiring a net of at least %d server(s)\n",
- min_servs);
- if (initserver[0])
- dprintf (idx, " On connect, I do: %s\n", initserver);
- if (connectserver[0])
- dprintf (idx, " Before connect, I do: %s\n", connectserver);
- dprintf (idx, " Flood is: %d msg/%ds, %d ctcp/%ds\n", flud_thr,
- flud_time, flud_ctcp_thr, flud_ctcp_time);
- }
- }
- static void
- msgq_clear (struct msgq_head *qh)
- {
- register struct msgq *q, *qq;
- for (q = qh->head; q; q = qq)
- {
- qq = q->next;
- nfree (q->msg);
- nfree (q);
- }
- qh->head = qh->last = NULL;
- qh->tot = qh->warned = 0;
- }
- static int
- msgq_expmem (struct msgq_head *qh)
- {
- register int tot = 0;
- register struct msgq *m;
- for (m = qh->head; m; m = m->next)
- {
- tot += m->len + 1;
- tot += sizeof (struct msgq);
- } return tot;
- }
- static int
- server_expmem ()
- {
- int tot = 0;
- struct server_list *s = serverlist;
- for (; s; s = s->next)
- {
- if (s->name)
- tot += strlen (s->name) + 1;
- if (s->pass)
- tot += strlen (s->pass) + 1;
- if (s->realname)
- tot += strlen (s->realname) + 1;
- tot += sizeof (struct server_list);
- } tot += msgq_expmem (&mq) + msgq_expmem (&hq) + msgq_expmem (&modeq);
- return tot;
- }
- static cmd_t my_ctcps[] =
- { {"DCC", "", ctcp_DCC_CHAT, "server:DCC"}, {NULL, NULL, NULL, NULL} };
- static char *
- server_close ()
- {
- cycle_time = 100;
- nuke_server ("Connection reset by peer");
- clearq (serverlist);
- rem_builtins_dcc (H_dcc, C_dcc_serv);
- rem_builtins (H_raw, my_raw_binds);
- rem_builtins (H_ctcp, my_ctcps);
- del_bind_table (H_wall);
- del_bind_table (H_raw);
- del_bind_table (H_notc);
- del_bind_table (H_msgm);
- del_bind_table (H_msg);
- del_bind_table (H_flud);
- del_bind_table (H_ctcr);
- del_bind_table (H_ctcp);
- rem_tcl_coups (my_tcl_coups);
- rem_tcl_strings (my_tcl_strings);
- rem_tcl_ints (my_tcl_ints);
- rem_tcl_commands (my_tcl_cmds);
- Tcl_UntraceVar (interp, "nick",
- TCL_TRACE_READS | TCL_TRACE_WRITES | TCL_TRACE_UNSETS,
- nick_change, NULL);
- Tcl_UntraceVar (interp, "altnick", TCL_TRACE_WRITES | TCL_TRACE_UNSETS,
- altnick_change, NULL);
- Tcl_UntraceVar (interp, "botname",
- TCL_TRACE_READS | TCL_TRACE_WRITES | TCL_TRACE_UNSETS,
- traced_botname, NULL);
- Tcl_UntraceVar (interp, "server",
- TCL_TRACE_READS | TCL_TRACE_WRITES | TCL_TRACE_UNSETS,
- traced_server, NULL);
- Tcl_UntraceVar (interp, "net-type",
- TCL_TRACE_READS | TCL_TRACE_WRITES | TCL_TRACE_UNSETS,
- traced_nettype, NULL);
- Tcl_UntraceVar (interp, "nick-len",
- TCL_TRACE_READS | TCL_TRACE_WRITES | TCL_TRACE_UNSETS,
- traced_nicklen, NULL);
- empty_msgq ();
- del_hook (HOOK_SECONDLY, (Function) server_secondly);
- del_hook (HOOK_5MINUTELY, (Function) server_5minutely);
- del_hook (HOOK_QSERV, (Function) queue_server);
- del_hook (HOOK_MINUTELY, (Function) minutely_checks);
- del_hook (HOOK_PRE_REHASH, (Function) server_prerehash);
- del_hook (HOOK_REHASH, (Function) server_postrehash);
- del_hook (HOOK_DIE, (Function) server_die);
- module_undepend (MODULE_NAME);
- return NULL;
- }
- EXPORT_SCOPE char *server_start ();
- static Function server_table[] =
- { (Function) server_start, (Function) server_close,
- (Function) server_expmem, (Function) server_report, (Function) NULL, (Function) botuserhost,
- (Function) & quiet_reject, (Function) & serv, (Function) & flud_thr, (Function) & flud_time,
- (Function) & flud_ctcp_thr, (Function) & flud_ctcp_time, (Function) match_my_nick,
- (Function) check_tcl_flud, (Function) NULL, (Function) & answer_ctcp, (Function) & trigger_on_ignore,
- (Function) check_tcl_ctcpr, (Function) detect_avalanche, (Function) nuke_server, (Function) newserver,
- (Function) & newserverport, (Function) newserverpass, (Function) & cycle_time, (Function) & default_port,
- (Function) & server_online, (Function) & min_servs, (Function) & H_raw, (Function) & H_wall,
- (Function) & H_msg, (Function) & H_msgm, (Function) & H_notc, (Function) & H_flud, (Function) & H_ctcp,
- (Function) & H_ctcr, (Function) ctcp_reply, (Function) get_altbotnick, (Function) & nick_len,
- (Function) check_tcl_notc, (Function) & server_lag, (Function) & curserv, (Function) cursrvname,
- (Function) botrealname, };
- char *
- server_start (Function * global_funcs)
- {
- #if (((TCL_MAJOR_VERSION == 8) && (TCL_MINOR_VERSION >= 4)) || (TCL_MAJOR_VERSION > 8))
- CONST char *s;
- #else
- char *s;
- #endif
- global = global_funcs;
- serv = -1;
- strict_host = 1;
- botname[0] = 0;
- trying_server = 0L;
- server_lag = 0;
- altnick[0] = 0;
- raltnick[0] = 0;
- curserv = 0;
- flud_thr = 5;
- flud_time = 60;
- flud_ctcp_thr = 3;
- flud_ctcp_time = 60;
- initserver[0] = 0;
- connectserver[0] = 0;
- botuserhost[0] = 0;
- keepnick = 1;
- check_stoned = 1;
- serverror_quit = 1;
- quiet_reject = 1;
- waiting_for_awake = 0;
- server_online = 0;
- server_cycle_wait = 15;
- strcpy (botrealname, "A deranged product of evil coders");
- min_servs = 0;
- server_timeout = 15;
- never_give_up = 1;
- strict_servernames = 1;
- serverlist = NULL;
- cycle_time = 0;
- default_port = 6667;
- oldnick[0] = 0;
- trigger_on_ignore = 0;
- answer_ctcp = 1;
- lowercase_ctcp = 0;
- check_mode_r = 0;
- maxqmsg = 300;
- burst = 0;
- net_type = NETT_EFNET;
- double_mode = 0;
- double_server = 0;
- double_help = 0;
- use_penalties = 0;
- use_fastdeq = 0;
- stackablecmds[0] = 0;
- strcpy (stackable2cmds, "USERHOST ISON");
- resolvserv = 0;
- lastpingtime = 0;
- last_time = 0;
- nick_len = 9;
- kick_method = 1;
- optimize_kicks = 0;
- stack_limit = 4;
- server_table[4] = (Function) botname;
- module_register (MODULE_NAME, server_table, 1, 2);
- if (!(encryption_funcs = module_depend (MODULE_NAME, "encryption", 0, 0)))
- {
- module_undepend (MODULE_NAME);
- return "This module requires an encryption modules.";
- }
- s = Tcl_GetVar (interp, "nick", TCL_GLOBAL_ONLY);
- if (s)
- strncpyz (origbotname, s, NICKLEN);
- Tcl_TraceVar (interp, "nick",
- TCL_TRACE_READS | TCL_TRACE_WRITES | TCL_TRACE_UNSETS,
- nick_change, NULL);
- Tcl_TraceVar (interp, "altnick", TCL_TRACE_WRITES | TCL_TRACE_UNSETS,
- altnick_change, NULL);
- Tcl_TraceVar (interp, "botname",
- TCL_TRACE_READS | TCL_TRACE_WRITES | TCL_TRACE_UNSETS,
- traced_botname, NULL);
- Tcl_TraceVar (interp, "server",
- TCL_TRACE_READS | TCL_TRACE_WRITES | TCL_TRACE_UNSETS,
- traced_server, NULL);
- Tcl_TraceVar (interp, "net-type",
- TCL_TRACE_READS | TCL_TRACE_WRITES | TCL_TRACE_UNSETS,
- traced_nettype, NULL);
- Tcl_TraceVar (interp, "nick-len",
- TCL_TRACE_READS | TCL_TRACE_WRITES | TCL_TRACE_UNSETS,
- traced_nicklen, NULL);
- H_wall = add_bind_table ("wall", HT_STACKABLE, server_2char);
- H_raw = add_bind_table ("raw", HT_STACKABLE, server_raw);
- H_notc = add_bind_table ("notc", HT_STACKABLE, server_6char);
- H_msgm = add_bind_table ("msgm", HT_STACKABLE, server_msg);
- H_msg = add_bind_table ("msg", 0, server_msg);
- H_flud = add_bind_table ("flud", HT_STACKABLE, server_5char);
- H_ctcr = add_bind_table ("ctcr", HT_STACKABLE, server_6char);
- H_ctcp = add_bind_table ("ctcp", HT_STACKABLE, server_6char);
- add_builtins (H_raw, my_raw_binds);
- add_builtins_dcc (H_dcc, C_dcc_serv);
- add_builtins (H_ctcp, my_ctcps);
- my_tcl_strings[0].buf = botname;
- add_tcl_strings (my_tcl_strings);
- my_tcl_ints[0].val = &use_console_r;
- add_tcl_ints (my_tcl_ints);
- add_tcl_commands (my_tcl_cmds);
- add_tcl_coups (my_tcl_coups);
- add_hook (HOOK_SECONDLY, (Function) server_secondly);
- add_hook (HOOK_10SECONDLY, (Function) server_10secondly);
- add_hook (HOOK_5MINUTELY, (Function) server_5minutely);
- add_hook (HOOK_MINUTELY, (Function) minutely_checks);
- add_hook (HOOK_QSERV, (Function) queue_server);
- add_hook (HOOK_PRE_REHASH, (Function) server_prerehash);
- add_hook (HOOK_REHASH, (Function) server_postrehash);
- add_hook (HOOK_DIE, (Function) server_die);
- mq.head = hq.head = modeq.head = NULL;
- mq.last = hq.last = modeq.last = NULL;
- mq.tot = hq.tot = modeq.tot = 0;
- mq.warned = hq.warned = modeq.warned = 0;
- double_warned = 0;
- newserver[0] = 0;
- newserverport = 0;
- curserv = 999;
- do_nettype ();
- add_cfg (&CFG_NICK);
- add_cfg (&CFG_SERVERS);
- add_cfg (&CFG_SERVERS6);
- add_cfg (&CFG_REALNAME);
- set_cfg_str (NULL, STR ("realname"), "A deranged product of evil coders");
- return NULL;
- }
- #endif
|