diff --git a/Makefile b/Makefile index 36bf10b..79a9f2e 100644 --- a/Makefile +++ b/Makefile @@ -62,7 +62,7 @@ SRCFILES = src/alias.c src/auth.c src/bounce.c src/calc.c src/channel.c src/core src/irc.c src/main.c src/net.c src/note.c src/ons.c src/parse.c src/partyline.c \ src/perl.c src/prot.c src/python.c src/reset.c src/seen.c src/shit.c src/io.c \ src/spy.c src/tcl.c src/toybox.c src/uptime.c src/user.c src/vars.c src/web.c \ - src/lib/md5.c src/lib/md5.h src/lib/string.c + src/lib/md5.c src/lib/md5.h src/string.c HDRFILES = src/commands.h src/defines.h src/global.h src/h.h src/onhash.h src/settings.h \ src/structs.h src/text.h src/usage.h diff --git a/VERSIONS b/VERSIONS index 89ff1cd..6d5e429 100644 --- a/VERSIONS +++ b/VERSIONS @@ -1,5 +1,9 @@ 3.5(.dev) -- + * Changed: Rewrote how SERVERGROUP works. Config files might need changes. + * Removed: SERVERGROUP command. + * Changed: Nicks/Wantnick/Userhost dynamically allocated only for 'too long' strings. + * Removed: IDWRAP code. It was my personal thing. * Changed: on_msg now matches commands using a hash function instead of iterating through the list of commands using strcasecmp. * Changed: Bumped version because of undocumented changes. diff --git a/sample.conf b/sample.conf index d828935..ab97138 100644 --- a/sample.conf +++ b/sample.conf @@ -9,35 +9,40 @@ set ctimeout 60 ; We don't currently support SSL or ipv6 but there's an easy workaround ; see socat.sh -servergroup undernet -server amsterdam.nl.eu.undernet.org 6663 -server amsterdam2.nl.eu.undernet.org 6663 -server bucharest.ro.eu.undernet.org 6663 -server carouge.ch.eu.undernet.org 6663 -server ede.nl.eu.undernet.org 6669 -server elsene.be.eu.undernet.org 6669 -server fulda.de.eu.undernet.org 6663 -server geneva.ch.eu.undernet.org 6663 -server graz.at.eu.undernet.org 6663 -server graz2.at.eu.undernet.org 6663 -server helsinki.fi.eu.undernet.org 6669 -server lelystad.nl.eu.undernet.org 6668 -server london.uk.eu.undernet.org 6666 -server london2.uk.eu.undernet.org 6663 -server milan.it.eu.undernet.org 6663 -server oslo1.no.eu.undernet.org 6663 -server oslo2.no.eu.undernet.org 6663 -server stockholm.se.eu.undernet.org 6669 -server surrey.uk.eu.undernet.org 6669 -server zagreb.hr.eu.undernet.org 6666 -server panamacity.pa.undernet.org 6663 -server ashburn.va.us.undernet.org 6663 -server fairfax.va.us.undernet.org 6666 -server mesa.az.us.undernet.org 6666 -server miami.fl.us.undernet.org 6669 -server princeton.nj.us.undernet.org 6663 -server sanjose.ca.us.undernet.org 6663 -server sterling.va.us.undernet.org 6669 +; Use only undernet servers +set servergroup undernet + +; Our list of servers +; server [port] [@group] ["password"] +; +server amsterdam.nl.eu.undernet.org 6663 @undernet +server amsterdam2.nl.eu.undernet.org 6663 @undernet +server bucharest.ro.eu.undernet.org 6663 @undernet +server carouge.ch.eu.undernet.org 6663 @undernet +server ede.nl.eu.undernet.org 6669 @undernet +server elsene.be.eu.undernet.org 6669 @undernet +server fulda.de.eu.undernet.org 6663 @undernet +server geneva.ch.eu.undernet.org 6663 @undernet +server graz.at.eu.undernet.org 6663 @undernet +server graz2.at.eu.undernet.org 6663 @undernet +server helsinki.fi.eu.undernet.org 6669 @undernet +server lelystad.nl.eu.undernet.org 6668 @undernet +server london.uk.eu.undernet.org 6666 @undernet +server london2.uk.eu.undernet.org 6663 @undernet +server milan.it.eu.undernet.org 6663 @undernet +server oslo1.no.eu.undernet.org 6663 @undernet +server oslo2.no.eu.undernet.org 6663 @undernet +server stockholm.se.eu.undernet.org 6669 @undernet +server surrey.uk.eu.undernet.org 6669 @undernet +server zagreb.hr.eu.undernet.org 6666 @undernet +server panamacity.pa.undernet.org 6663 @undernet +server ashburn.va.us.undernet.org 6663 @undernet +server fairfax.va.us.undernet.org 6666 @undernet +server mesa.az.us.undernet.org 6666 @undernet +server miami.fl.us.undernet.org 6669 @undernet +server princeton.nj.us.undernet.org 6663 @undernet +server sanjose.ca.us.undernet.org 6663 @undernet +server sterling.va.us.undernet.org 6669 @undernet ; ; this is sorta how a botnet configuration would look like... diff --git a/src/Makefile.in b/src/Makefile.in index 044e334..464ce34 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -49,13 +49,13 @@ TESTFILES = aliastest calctest safepathtest OFILES = alias.o auth.o bounce.o calc.o channel.o core.o ctcp.o debug.o dns.o function.o greet.o \ help.o hostinfo.o io.o irc.o main.o net.o note.o ons.o parse.o partyline.o \ - perl.o prot.o python.o reset.o seen.o shit.o spy.o tcl.o toybox.o \ - uptime.o user.o vars.o web.o lib/string.o @MD5_O@ @SHA_O@ + perl.o prot.o python.o reset.o seen.o shit.o spy.o string.o tcl.o toybox.o \ + uptime.o user.o vars.o web.o @MD5_O@ @SHA_O@ SRCFILES = alias.c auth.c bounce.c calc.c channel.c core.c ctcp.c debug.c dns.c function.c greet.c \ help.c hostinfo.c io.c irc.c main.c net.c note.c ons.c parse.c partyline.c \ - perl.c prot.c python.c reset.c seen.c shit.c spy.c tcl.c toybox.c \ - uptime.c user.c vars.c web.c lib/string.c @MD5_C@ @SHA_C@ + perl.c prot.c python.c reset.c seen.c shit.c spy.c string.c tcl.c toybox.c \ + uptime.c user.c vars.c web.c @MD5_C@ @SHA_C@ .PHONY: all clean mega-install mega mega-static test commands @@ -152,9 +152,6 @@ lib/sha1.o: lib/sha1.c $(INCS) lib/sha512.o: lib/sha512.c $(INCS) $(CROSS_COMPILE)$(CC) $(CFLAGS) -c $< -o $@ -Ilib $(CPROF) -lib/string.o: lib/string.c $(BASEINCLUDES) - $(CROSS_COMPILE)$(CC) $(CFLAGS) -c $< -o $@ -I. $(CPROF) - alias.o: alias.c $(INCS) $(CROSS_COMPILE)$(CC) $(CFLAGS) -c $< $(CPROF) @@ -239,6 +236,9 @@ shit.o: shit.c $(INCS) spy.o: spy.c $(INCS) $(CROSS_COMPILE)$(CC) $(CFLAGS) -c $< $(CPROF) +string.o: string.c $(BASEINCLUDES) + $(CROSS_COMPILE)$(CC) $(CFLAGS) -c $< $(CPROF) + tcl.o: tcl.c $(INCS) $(CROSS_COMPILE)$(CC) $(CFLAGS) -c $< $(CPROF) $(TCLINCLUDE) diff --git a/src/auth.c b/src/auth.c index 76cf49f..b60032f 100644 --- a/src/auth.c +++ b/src/auth.c @@ -418,6 +418,25 @@ int make_auth(const char *userhost, const User *user) * */ +void do_auth_noargs(const char *from) +{ + Auth *au; + + if (get_authaccess(from,MATCH_ALL) < 100) + return; + + /* no args + owner: List active auths */ + table_buffer("\037Active Auths\037"); + if (current->authlist == NULL) + table_buffer("(none)"); + for(au=current->authlist;au;au=au->next) + { + table_buffer("%s\t%i\t%s\t%s",au->user->name,au->user->x.x.access,au->nuh, + idle2str(au->active,TRUE)); + } + table_send(from,3); +} + /* help:AUTH help:VERIFY @@ -443,22 +462,7 @@ void do_auth(COMMAND_ARGS) char *pass; int hostmatch; - if ((pass = chop(&rest)) == NULL) - { - if (get_authaccess(from,MATCH_ALL) == 100) - { - /* empty pass + owner: List active auths */ - table_buffer("\037Active Auths\037"); - if (current->authlist == NULL) - table_buffer("(none)"); - for(au=current->authlist;au;au=au->next) - { - table_buffer("%s\t%i\t%s\t%s",au->user->name,au->user->x.x.access,au->nuh,idle2str(now - au->active,TRUE)); - } - table_send(from,3); - } - return; - } + pass = chop(&rest); /* * chop chop diff --git a/src/bounce.c b/src/bounce.c index ce9cfba..e7e7463 100644 --- a/src/bounce.c +++ b/src/bounce.c @@ -181,7 +181,10 @@ void bounce_parse(ircLink *irc, char *message) } } -void new_port_bounce(const struct Setting *no_op) +/* + * any time setting is changed + */ +void new_port_bounce(const struct Setting *dontcare) { if (bounce_sock != -1) close(bounce_sock); diff --git a/src/channel.c b/src/channel.c index df03e67..02d0778 100644 --- a/src/channel.c +++ b/src/channel.c @@ -40,13 +40,15 @@ void check_idlekick(void) for(chan=current->chanlist;chan;chan=chan->next) { + if (!chan->bot_is_op) + continue; limit = chan->setting[INT_IKT].int_var; + if (limit == 0) + continue; timeout = (now - (60 * limit)); for(cu=chan->users;cu;cu=cu->next) { cu->flags &= ~CU_KSWARN; /* remove KS warnings */ - if (!chan->bot_is_op || limit == 0) - continue; if (cu->flags & CU_CHANOP) continue; if (timeout < cu->idletime) @@ -1188,7 +1190,7 @@ void do_showidle(COMMAND_ARGS) { if (n >= (now - cu->idletime)) continue; - table_buffer("%s\r %s\t%s",idle2str((now - cu->idletime),TRUE),cu->nick,cu->userhost); + table_buffer("%s\r %s\t%s",idle2str(cu->idletime,TRUE),cu->nick,cu->userhost); } table_send(from,1); } @@ -1219,5 +1221,5 @@ void do_idle(COMMAND_ARGS) to_user(from,TEXT_UNKNOWNUSER,rest); return; } - to_user(from,"%s has been idle for %s",rest,idle2str(now - cu2->idletime,TRUE)); + to_user(from,"%s has been idle for %s",rest,idle2str(cu2->idletime,TRUE)); } diff --git a/src/commands.h b/src/commands.h index ad04bce..5d375b5 100644 --- a/src/commands.h +++ b/src/commands.h @@ -36,6 +36,7 @@ CBANG 0x040000 command may be prefixed with a bang (!) ACCHAN 0x080000 needs an active channel SUPRES 0x100000 command is not suitable to run on many bots at once, try to suppress it + NOARGF 0x200000 run a special function if no arguments are supplied CLEVEL 0x000ff @@ -56,8 +57,8 @@ struct /* * public access commands */ - { 0, "AUTH", "do_auth", 0 | NOPUB | CBANG }, // double up on AUTH/VERIFY to better - { 0, "VERIFY", "do_auth", 0 | NOPUB | CBANG }, // catch login attempts + { 0, "AUTH", "do_auth", 0 | NOPUB | CBANG | NOARGF }, // double up on AUTH/VERIFY to better + { 0, "VERIFY", "do_auth", 0 | NOPUB | CBANG | NOARGF }, // catch login attempts #ifdef TOYBOX { 0, "8BALL", "do_8ball", 0 | CBANG | SUPRES }, { 0, "RAND", "do_rand", 0 | CBANG | SUPRES }, @@ -199,8 +200,7 @@ struct { 0, "MSG", "do_msg", 80 | CCPW | CARGS }, { 0, "NEXTSERVER", "do_server", 80 | CCPW | GAXS }, { 0, "SAVE", "do_save", 80 | CCPW | GAXS }, - { 0, "SERVER", "do_server", 80 | CCPW | GAXS | REDIR | LBUF }, - { 0, "SERVERGROUP", "do_servergroup", 80 | CCPW | GAXS | REDIR | LBUF }, + { 0, "SERVER", "do_server", 80 | CCPW | GAXS | REDIR | NOPUB | NOARGF }, { 0, "STATS", "do_ircstats", 80 | CCPW | DCC | CARGS }, #ifdef ALIAS { 0, "ALIAS", "do_alias", 80 | CCPW | GAXS }, @@ -219,7 +219,7 @@ struct { 0, "RSPY", "do_rspy", 90 | CCPW | CARGS }, { 0, "SPY", "do_spy", 90 | CCPW }, #ifdef BOTNET - { 0, "LINK", "do_link", 90 | CCPW | GAXS }, + { 0, "LINK", "do_link", 90 | CCPW | GAXS | NOPUB | NOARGF }, #endif /* BOTNET */ #ifdef DYNCMD { 0, "CHACCESS", "do_chaccess", 90 | CCPW | GAXS | CARGS }, diff --git a/src/config.h.in b/src/config.h.in index a661338..618de6c 100644 --- a/src/config.h.in +++ b/src/config.h.in @@ -355,6 +355,9 @@ #define NAMELEN 79 #define NAMEBUF NAMELEN+1 +#define SERVERGROUPBUF 16 +#define SERVERGROUPLEN SERVERGROUPBUF-1 + #define MINPASSCHARS 4 #define MAXPASSCHARS 50 @@ -394,6 +397,7 @@ #define CBANG 0x040000 /* command may be prefixed with a bang (!) */ #define ACCHAN 0x080000 /* needs an active channel */ #define SUPRES 0x100000 /* command is not suitable to run on many bots at once, try to suppress it */ +#define NOARGF 0x200000 /* run a special function if no arguments are supplied */ /* * integer only version of RANDOM() diff --git a/src/core.c b/src/core.c index c796e63..ae4d562 100644 --- a/src/core.c +++ b/src/core.c @@ -107,7 +107,7 @@ void readcfgfile(void) to_file(1,", ..."); break; } - to_file(1,"%s%s",(oc > 0) ? ", " : "",getbotnick(bot)); + to_file(1,"%s%s",(oc > 0) ? ", " : EMPTYSTR,getbotnick(bot)); oc += getbotnicklen(bot); } to_file(1," ]\n"); @@ -152,7 +152,7 @@ int write_session(void) for(sp=serverlist;sp;sp=sp->next) { to_file(sf,"server %s %i %s\n",sp->name,(sp->port) ? sp->port : 6667, - (sp->pass[0]) ? sp->pass : ""); + (sp->pass[0]) ? sp->pass : EMPTYSTR); } #ifdef BOTNET @@ -261,7 +261,7 @@ int write_session(void) { if (!chan->active && !chan->rejoin) continue; - to_file(sf,"join %s %s\n",chan->name,(chan->key) ? chan->key : ""); + to_file(sf,"join %s %s\n",chan->name,(chan->key) ? chan->key : EMPTYSTR); /* * using CHANSET_SIZE: only the first settings contain stuff */ @@ -387,7 +387,7 @@ void signoff(char *from, char *reason) { if (!reason) reason = randstring(SIGNOFFSFILE); - to_server("QUIT :%s\n",(reason) ? reason : ""); + to_server("QUIT :%s\n",(reason) ? reason : EMPTYSTR); killsock(current->sock); current->sock = -1; } @@ -473,10 +473,13 @@ void kill_all_bots(char *reason) /* * Server lists, connects, etc... */ -Server *add_server(char *host, int port, char *pass) +Server *add_server(const char *host, const int port, const char *pass, const char *group) { Server *sp,**pp; +#ifdef DEBUG + debug("(add_server) host = %s, port = %i, group = %s, pass = '%s'.\n",host,port,group,pass); +#endif /* DEBUG */ pp = &serverlist; while(*pp) { @@ -485,42 +488,21 @@ Server *add_server(char *host, int port, char *pass) return(sp); pp = &sp->next; } +#ifdef DEBUG + debug("(add_server) creating new entry: id %i.\n",serverident+1); +#endif /* DEBUG */ set_mallocdoer(add_server); *pp = sp = (Server*)Calloc(sizeof(Server)); sp->ident = serverident++; + sp->maxontime = -1; + /* caller must make sure host, pass, port and group is all valid */ stringcpy_n(sp->name,host,NAMELEN); - if (pass && *pass) - stringcpy_n(sp->pass,pass,PASSLEN); - sp->port = (port) ? port : DEFAULT_IRC_PORT; - if (currentservergroup) - sp->servergroup = currentservergroup->servergroup; + stringcpy_n(sp->pass,pass,PASSLEN); + stringcpy_n(sp->group,group,SERVERGROUPLEN); + sp->port = port; return(sp); } -ServerGroup *getservergroup(const char *name) -{ - ServerGroup *sg; - - for(sg=servergrouplist;sg;sg=sg->next) - { - if (!stringcasecmp(sg->name,name)) - return(sg); - } - return(NULL); -} - -ServerGroup *getservergroupid(int id) -{ - ServerGroup *sg; - - for(sg=servergrouplist;sg;sg=sg->next) - { - if (sg->servergroup == id) - return(sg); - } - return(NULL); -} - Server *find_server(int id) { Server *sp; @@ -582,11 +564,9 @@ int try_server(Server *sp, char *hostname) void connect_to_server(void) { - ServerGroup *sg; Server *sp,*sptry; Chan *chan; - char *s; - int sgi; + char *sgroup; /* * This should prevent the bot from chewing up too @@ -634,64 +614,54 @@ void connect_to_server(void) * The purpose of this kludge is to find the least used server * July 7th: added logic for servergroup */ - sptry = NULL; - if ((s = current->setting[STR_SERVERGROUP].str_var)) + if ((sgroup = current->setting[STR_SERVERGROUP].str_var)) { - if ((sg = getservergroup(s))) - sgi = sg->servergroup; #ifdef DEBUG - if (sg) - debug("[CtS] trying servergroup \"%s\" (%i)\n",s,sg->servergroup); - else - debug("[CtS] trying servergroup \"%s\" (not found)\n",s); + debug("[CtS] servergroup set to \"%s\"\n",sgroup); #endif /* DEBUG */ } - else - { - sgi = 0; - } + sptry = NULL; for(sp=serverlist;sp;sp=sp->next) { - if ((sgi == 0 || sp->servergroup == sgi || sp->servergroup == 0) && sp->lastattempt != now) - { - if ((!sptry) || (sp->usenum < sptry->usenum)) - { - if (sp->err == 0 || sp->err == SP_ERRCONN) - sptry = sp; - else - if ( - (sp->err == SP_THROTTLED && (sp->lastattempt + 45) < now) || /* retry throttled after 45 seconds */ - (sp->err == SP_KLINED && (sp->lastattempt + 86400) < now) /* retry Klined after a day */ - ) - sptry = sp; - } - } + if (sp->lastattempt == now) + continue; + if (sgroup && (stringcasecmp(sgroup,sp->group) != 0)) + continue; + if (sptry && (sp->usenum > sptry->usenum)) + continue; + + if (sp->err == 0 || sp->err == SP_ERRCONN) + sptry = sp; + else + if ((sp->err == SP_THROTTLED && (sp->lastattempt + 45) < now) || /* retry throttled after 45 seconds */ + (sp->err == SP_KLINED && (sp->lastattempt + 86400) < now)) /* retry Klined after a day */ + sptry = sp; } /* * Connect... */ if (sptry) - try_server(sptry,NULL); - else { -#ifdef DEBUG - const char *errtxt; - - if (current->connect != CN_SPINNING) - { - debug("[CtS] Serverlist Exhausted:\n"); - for(sp=serverlist;sp;sp=sp->next) - { - errtxt = (const char *[]){"No error","SP_NOAUTH","SP_KLINED","SP_FULLCLASS", - "SP_TIMEOUT","SP_ERRCONN","SP_DIFFPORT","SP_NO_DNS","SP_THROTTLED"}[sp->err]; - debug("[CtS] (%i) %s[%i]: %s(%i) / servergroup %i\n",sp->ident,(sp->realname[0]) ? sp->realname : sp->name, - sp->port,errtxt,sp->err,sp->servergroup); - } - debug("[CtS] Server connection is spinning...\n"); - } - current->connect = CN_SPINNING; -#endif /* DEBUG */ + try_server(sptry,NULL); + return; } +#ifdef DEBUG + if (current->connect != CN_SPINNING) + { + const char *errtxt; + debug("[CtS] Serverlist Exhausted:\n"); + for(sp=serverlist;sp;sp=sp->next) + { + errtxt = (const char *[]){"No error","SP_NOAUTH","SP_KLINED","SP_FULLCLASS", + "SP_TIMEOUT","SP_ERRCONN","SP_DIFFPORT","SP_NO_DNS","SP_THROTTLED"}[sp->err]; + debug("[CtS] (%i) %s[%i]: %s(%i) / servergroup %i\n",sp->ident, + (*sp->realname) ? sp->realname : sp->name, + sp->port,errtxt,sp->err,sp->group); + } + debug("[CtS] Server connection is spinning...\n"); + } + current->connect = CN_SPINNING; +#endif /* DEBUG */ } /* @@ -714,7 +684,7 @@ void register_with_server(void) sendpass = (sp && *sp->pass); to_server((sendpass) ? "PASS :%s\nNICK %s\nUSER %s " MECHUSERLOGIN " 0 :%s\n" : "%sNICK %s\nUSER %s " MECHUSERLOGIN " 0 :%s\n", - (sendpass) ? sp->pass : "", + (sendpass) ? sp->pass : EMPTYSTR, getbotwantnick(current), (ident) ? ident : BOTLOGIN, (ircname) ? ircname : VERSION); @@ -935,7 +905,7 @@ void update(SequenceTime *this) debug("\n"); #endif /* DEBUG */ - short_tv &= ~TV_REJOIN; + cx.short_tv &= ~TV_REJOIN; for(current=botlist;current;current=current->next) { if (current->reset || current->connect != CN_ONLINE) @@ -948,7 +918,7 @@ void update(SequenceTime *this) current->rejoin = FALSE; current->lastrejoin = now; } - short_tv |= TV_REJOIN; + cx.short_tv |= TV_REJOIN; } #ifdef NOTIFY @@ -1029,10 +999,8 @@ void update(SequenceTime *this) temp = TEXT_NOTINSERVLIST; if ((sp = find_server(current->server))) { - int ot = (uint32_t)(now - current->ontime); - - if (sp->maxontime < ot) - sp->maxontime = ot; + if (sp->maxontime > current->ontime) + sp->maxontime = current->ontime; sprintf(globaldata,"%s:%i",(*sp->realname) ? sp->realname : sp->name,sp->port); temp = globaldata; } @@ -1219,11 +1187,12 @@ void do_core(COMMAND_ARGS) char *h,hostname[256]; struct utsname un; #endif /* HOSTINFO */ + const char *extra; char tmp[MSGLEN]; /* big buffers at the top */ Server *sp; Chan *chan; User *user; - char *pt; + char *pt; int i,u,su,bu; u = su = bu = 0; @@ -1274,20 +1243,20 @@ void do_core(COMMAND_ARGS) if (current->setting[STR_VIRTUAL].str_var) { if ((current->vhost_type & VH_IPALIAS_FAIL) == 0) - pt = ""; + extra = EMPTYSTR; else - pt = TEXT_VHINACTIVE; - table_buffer(TEXT_VIRTHOST,current->setting[STR_VIRTUAL].str_var,pt); + extra = TEXT_VHINACTIVE; + table_buffer(TEXT_VIRTHOST,current->setting[STR_VIRTUAL].str_var,extra); } #ifdef WINGATE if (current->setting[STR_WINGATE].str_var && current->setting[INT_WINGPORT].int_var) { if ((current->vhost_type & VH_WINGATE_FAIL) == 0) - pt = ""; + extra = EMPTYSTR; else - pt = TEXT_VHINACTIVE; + extra = TEXT_VHINACTIVE; table_buffer(TEXT_VIRTHOSTWINGATE,current->setting[STR_WINGATE].str_var, - current->setting[INT_WINGPORT].int_var,pt); + current->setting[INT_WINGPORT].int_var,extra); } #endif /* WINGATE */ sp = find_server(current->server); @@ -1296,7 +1265,7 @@ void do_core(COMMAND_ARGS) (sp->realname[0]) ? sp->realname : sp->name,sp->port); else table_buffer(TEXT_CURRSERVERNOT); - table_buffer(TEXT_SERVERONTIME,idle2str(now - current->ontime,FALSE)); + table_buffer(TEXT_SERVERONTIME,idle2str(current->ontime,FALSE)); table_buffer(TEXT_BOTMODES,(*current->modes) ? current->modes : TEXT_NONE); #ifdef HOSTINFO hostname[255] = 0; @@ -1310,12 +1279,17 @@ void do_core(COMMAND_ARGS) #endif /* HOSTINFO */ table_buffer(TEXT_CURRENTTIME,time2str(now)); table_buffer(TEXT_BOTSTARTED,time2str(uptime)); - table_buffer(TEXT_BOTUPTIME,idle2str(now - uptime,FALSE)); + table_buffer(TEXT_BOTUPTIME,idle2str(uptime,FALSE)); table_buffer(TEXT_BOTVERSION,VERSION,SRCDATE); table_buffer(TEXT_BOTFEATURES,__mx_opts); #ifdef DEBUG - table_buffer("Debug\t%s%s%s",(const char *[]){"Off","On, Output = "}[dodebug], - (debugfile==NULL) ? ((dodebug==TRUE) ? "Stdout" : "") : debugfile); +#ifdef __profiling__ + table_buffer("Debug\t%s%s%s, Compiled with Profiling", +#else + table_buffer("Debug\t%s%s%s", +#endif + (const char *[]){"Off","On, Output = "}[dodebug], + (debugfile==NULL) ? ((dodebug==TRUE) ? "Stdout" : EMPTYSTR) : debugfile); #endif /* DEBUG */ table_send(from,2); } @@ -1366,196 +1340,143 @@ void do_shutdown(COMMAND_ARGS) /* NOT REACHED */ } -void do_servergroup(COMMAND_ARGS) +void do_server_noargs(const char *from) { - ServerGroup *sg,*new,**sgp; - char *name; + Server *sp; + const char *str_currentserver,*str_ago; + char maxontimebuf[36],*maxontime,*lastconnect; - name = chop(&rest); - - /* - * no args, list servergroups - */ - if (!name) - { - table_buffer(str_underline("id") "\t" str_underline("name")); - for(sg=servergrouplist;sg;sg=sg->next) - { - table_buffer("%i\t%s%s",sg->servergroup,sg->name,(sg == currentservergroup) ? " (current)" : ""); - } - table_send(from,2); + if (partyline_only_command(from)) return; - } + table_buffer(str_underline("server") "\t" str_underline("last connect") "\t" + str_underline("maxontime") "\t" str_underline("group")); - /* - * find pre-existing severgroup by the same name (case-insensitive) - */ - sg = getservergroup(name); - if (!sg) + for(sp=serverlist;sp;sp=sp->next) { -#ifdef DEBUG - debug("(do_servergroup) creating new servergroup: %s\n",name); -#endif /* DEBUG */ - set_mallocdoer(do_servergroup); - new = (ServerGroup*)Calloc(sizeof(ServerGroup) + strlen(name)); - servergroupid++; - new->servergroup = servergroupid; - stringcpy(new->name,name); - sgp = &servergrouplist; - while(*sgp) - sgp = &(*sgp)->next; - sg = *sgp = new; -#ifdef DEBUG + str_ago = str_currentserver = EMPTYSTR; + if (sp->ident == current->server) { - ServerGroup *g; - - for (g=servergrouplist;g;g=g->next) - { - debug("(do_servergroup) %s (%i)\n",g->name,g->servergroup); - } + if (sp->maxontime == -1 || sp->maxontime > current->ontime) + sp->maxontime = current->ontime; + str_currentserver = TEXT_CURRENT; } -#endif /* DEBUG */ + + if (sp->maxontime == -1) + maxontime = TEXT_NEVER; + else + { + maxontime = maxontimebuf; + stringcpy(maxontimebuf,idle2str(sp->maxontime,FALSE)); + } + + if (sp->lastconnect) + { + str_ago = TEXT_AGO; + lastconnect = idle2str(sp->lastconnect,FALSE); + } + else + switch(sp->err) + { + case SP_NOAUTH: + lastconnect = TEXT_SP_NOAUTH; + break; + case SP_KLINED: + lastconnect = TEXT_SP_KLINED; + break; + case SP_FULLCLASS: + lastconnect = TEXT_SP_FULLCLASS; + break; + case SP_TIMEOUT: + lastconnect = TEXT_SP_TIMEOUT; + break; + case SP_ERRCONN: + lastconnect = TEXT_SP_ERRCONN; + break; + case SP_DIFFPORT: + lastconnect = TEXT_SP_DIFFPORT; + break; + case SP_NO_DNS: + lastconnect = TEXT_SP_NO_DNS; + break; + default: + lastconnect = TEXT_NEVER; + } + table_buffer("%s:%i%s\t%s%s\t%s\t%s",(*sp->realname) ? sp->realname : sp->name,sp->port, + str_currentserver,lastconnect,str_ago,maxontime,sp->group); } - currentservergroup = sg; -#ifdef DEBUG - debug("(do_servergroup) current servergroup set to \"%s\" (%i)\n",sg->name,sg->servergroup); -#endif /* DEBUG */ + table_send(from,2); } void do_server(COMMAND_ARGS) { - ServerGroup *sg; Server *sp,*dp,**spp; - char *server,*aport,*pass; - char addc,*last,*quitmsg = TEXT_TRYNEWSERVER; - int n,iport,sgi; + char *server,*aport,*temp; + const char *pass,*group; + char add_or_sub,*quitmsg = TEXT_TRYNEWSERVER; + int n,iport; if (CurrentCmd->name == C_NEXTSERVER) { - quitmsg = TEXT_SWITCHSERVER; - to_user(from,FMT_PLAIN,quitmsg); + to_user(from,FMT_PLAIN,TEXT_SWITCHSERVER); goto do_server_jump; } + + + add_or_sub = *rest; + if (*rest == '-' || *rest == '+') + rest++; + + if (*rest == 0) + goto do_server_einval; + server = chop(&rest); - - /* - * no args, list all known servers - */ - if (!server) - { - char maxontime[36],*cuur; - int ot; - - if (partyline_only_command(from)) - return; - if (servergrouplist->next) - table_buffer(str_underline("server") "\t" str_underline("last connect") "\t" - str_underline("maxontime") "\t" str_underline("group")); - else - table_buffer(str_underline("server") "\t" str_underline("last connect") "\t" str_underline("maxontime")); - sgi = -1; - for(sp=serverlist;sp;sp=sp->next) - { - cuur = ""; - if (sp->ident == current->server) - { - cuur = TEXT_CURRENT; - ot = now - current->ontime; - if (sp->maxontime < ot) - sp->maxontime = ot; - } - stringcpy(maxontime,(sp->maxontime == 0) ? TEXT_NEVER : idle2str(sp->maxontime,FALSE)); - if (sp->lastconnect) - last = idle2str(now - sp->lastconnect,FALSE); - else - { - switch(sp->err) - { - case SP_NOAUTH: - last = TEXT_SP_NOAUTH; - break; - case SP_KLINED: - last = TEXT_SP_KLINED; - break; - case SP_FULLCLASS: - last = TEXT_SP_FULLCLASS; - break; - case SP_TIMEOUT: - last = TEXT_SP_TIMEOUT; - break; - case SP_ERRCONN: - last = TEXT_SP_ERRCONN; - break; - case SP_DIFFPORT: - last = TEXT_SP_DIFFPORT; - break; - case SP_NO_DNS: - last = TEXT_SP_NO_DNS; - break; - default: - last = TEXT_NEVER; - } - } - if (servergrouplist->next) - { - if (sgi != sp->servergroup) - { - sg = getservergroupid(sp->servergroup); - if (sg) - sgi = sg->servergroup; - } - table_buffer("%s:%i\t%s%s%s\t%s\t%s",(*sp->realname) ? sp->realname : sp->name,sp->port, - last,(sp->lastconnect) ? TEXT_AGO : "",cuur,maxontime,(sg) ? sg->name : "(unknown)"); - } - else - table_buffer("%s:%i\t%s%s%s\t%s",(*sp->realname) ? sp->realname : sp->name,sp->port, - last,(sp->lastconnect) ? TEXT_AGO : "",cuur,maxontime); - } - table_send(from,2); - return; - } - - addc = *server; - if (addc == '-' || addc == '+') - { - server++; - if (!*server) - { - usage(from); - return; - } - } - if (strlen(server) >= MAXHOSTLEN) + if ((cx.chop_end - server) >= MAXHOSTLEN) { to_user(from,TEXT_NAMETOOLONG); return; } - aport = chop(&rest); - pass = chop(&rest); + aport = "6667"; + group = DEFAULTSTR; + pass = EMPTYSTR; + do + { + if (*rest == COMMENT_CHAR) + break; + temp = chop(&rest); + if (temp == NULL) + break; + + if (*temp >= '1' && *temp <= '9') + aport = temp; + else + if (*temp == '@' && ((cx.chop_end - temp) <= SERVERGROUPLEN)) + group = temp + 1; + else + if (*temp == '"') + { + char *c; + + temp++; + c = stringchr(temp,'"'); + if (c && ((c - temp) <= PASSLEN)) + pass = temp, *c = 0; + } + else + goto do_server_einval; + } + while(*rest); + iport = asc2int(aport); - if (aport && *aport == COMMENT_CHAR) - { - aport = pass = NULL; - } - else - if (pass && *pass == COMMENT_CHAR) - { - pass = NULL; - } - - if (aport && (errno || iport < 1 || iport > 65534)) + if (errno || iport < 1 || iport > 65534) { +do_server_einval: usage(from); return; } - if (!aport) - { - iport = 0; - } - if (addc == '-') + if (add_or_sub == '-') { if (!serverlist) { @@ -1597,13 +1518,8 @@ void do_server(COMMAND_ARGS) } return; } - sp = add_server(server,iport,pass); - if (!sp) - { - to_user(from,"Problem adding server: %s",server); - return; - } - if (addc || from == CoreUser.name) + sp = add_server(server,iport,pass,group); /* add_server has no failure mode */ + if (add_or_sub == '+' || from == CoreUser.name) return; current->nextserver = sp->ident; @@ -1721,8 +1637,10 @@ void do_time(COMMAND_ARGS) void do_upontime(COMMAND_ARGS) { - to_user_q(from,CurrentCmd->cmdarg, - idle2str(now - ((CurrentCmd->name == C_UPTIME) ? uptime : current->ontime),FALSE)); + time_t temp; + + temp = ((CurrentCmd->name == C_UPTIME) ? uptime : current->ontime); + to_user_q(from,CurrentCmd->cmdarg,idle2str(temp,FALSE)); } void do_msg(COMMAND_ARGS) diff --git a/src/debug.c b/src/debug.c index 22af7ac..94ebec7 100644 --- a/src/debug.c +++ b/src/debug.c @@ -92,7 +92,6 @@ LS const struct { "Seen", sizeof(Seen) }, #endif /* SEEN */ { "Server", sizeof(Server) }, -{ "ServerGroup", sizeof(ServerGroup) }, { "Setting", sizeof(Setting) }, { "Shit", sizeof(Shit) }, { "Spy\t", sizeof(Spy) }, @@ -142,7 +141,6 @@ LS struct { do_die, "do_die" RARE_SE }, { do_nick, "do_nick" CMD1_SE }, { do_kicksay, "do_kicksay" CMD1_SE }, -{ do_servergroup, "do_servergroup" CMD1_SE }, { do_set, "do_set" CMD1_SE }, { do_spy, "do_spy" CMD1_SE }, { join_channel, "join_channel" CFG1_SE }, @@ -169,6 +167,7 @@ LS struct { send_mode, "send_mode" }, { set_str_varc, "set_str_varc" CFG1_SE }, { set_mix16, "set_mix16" CORE_SE }, +{ set_mix64, "set_mix64" CORE_SE }, { sig_hup, "sig_hup" RARE_SE }, { table_buffer, "table_buffer" }, #ifdef ALIAS @@ -502,7 +501,6 @@ char *atime(time_t when) void debug_server(Server *sp, char *pad) { - ServerGroup *sg; char *pl; if (!sp) @@ -516,17 +514,9 @@ void debug_server(Server *sp, char *pad) debug("%s; ident\t\t%i\n",pad,sp->ident); debug("%s; name\t\t\"%s\"\n",pad,nullbuf(sp->name)); debug("%s; pass\t\t\"%s\"\n",pad,nullbuf(sp->pass)); + debug("%s; group\t\t\"%s\"\n",pad,nullbuf(sp->group)); debug("%s; realname\t\t\"%s\"\n",pad,nullbuf(sp->realname)); debug("%s; usenum\t\t%i\n",pad,sp->usenum); - sg = getservergroupid(sp->servergroup); - if (sg) - { - debug("%s; servergroup\t%s%i \"%s\"\n",pad,pl,sp->servergroup,sg->name); - } - else - { - debug("%s; servergroup\t%s%i (unknown)\n",pad,pl,sp->servergroup); - } debug("%s; port\t\t%i\n",pad,sp->port); debug("%s; err\t\t%s%s (%i)\n",pad,pl,strdef(SPdefs,sp->err),sp->err); debug("%s; lastconnect\t%s%s (%lu)\n",pad,pl,atime(sp->lastconnect),sp->lastconnect); @@ -825,7 +815,6 @@ void debug_core(void) Seen *seen; #endif /* SEEN */ Server *sp; - ServerGroup *sg; Spy *spy; Strp *st; Shit *shit; @@ -856,25 +845,7 @@ void debug_core(void) debug("; executable\t\t\"%s\"\n",executable); debug("; configfile\t\t\"%s\"\n",configfile); debug("; uptime\t\t%s (%lu)\n",atime(uptime),uptime); - debug("; short_tv\t\t%s (%is wait)\n",boolstr(short_tv),(short_tv) ? 1 : 30); - debug("> currentservergroup\t"mx_pfmt"\n",(mx_ptr)currentservergroup); - if (currentservergroup) - { - sg = currentservergroup; - debug(" ; next\t\t"mx_pfmt"\n",(mx_ptr)sg->next); - debug(" ; servergroup\t\t%i\n",sg->servergroup); - debug(" ; name\t\t\"%s\"\n",nullbuf(sg->name)); - debug(" ; ---\n"); - } - debug("> servergrouplist\t"mx_pfmt"\n",(mx_ptr)servergrouplist); - for(sg=servergrouplist;sg;sg=sg->next) - { - memtouch(sg); - debug(" ; next\t\t"mx_pfmt"\n",(mx_ptr)sg->next); - debug(" ; servergroup\t\t%i\n",sg->servergroup); - debug(" ; name\t\t\"%s\"\n",nullbuf(sg->name)); - debug(" ; ---\n"); - } + debug("; short_tv\t\t%s (%is wait)\n",boolstr(cx.short_tv),(cx.short_tv) ? 1 : 30); debug("> serverlist\t\t"mx_pfmt"\n",(mx_ptr)serverlist); for(sp=serverlist;sp;sp=sp->next) { @@ -1448,7 +1419,7 @@ void do_debug(COMMAND_ARGS) int m; arg = chop(&rest); - if (strcasecmp(arg,"off") == 0) + if (arg && strcasecmp(arg,"off") == 0) { if (debugfile && debugfilemalloc == TRUE) Free(&debugfile); @@ -1458,7 +1429,7 @@ void do_debug(COMMAND_ARGS) to_user(from,"Debug output turned off"); return; } - if (strcasecmp(arg,"on") == 0) + if (arg && strcasecmp(arg,"on") == 0) { m = is_safepath(rest,FILE_MAY_EXIST); debug("(do_debug) turn on, rest = '%s', %i\n",rest,m); @@ -1468,7 +1439,7 @@ void do_debug(COMMAND_ARGS) Free(&debugfile); debugfilemalloc = TRUE; set_mallocdoer(do_debug); - debugfile = strdup(rest); + debugfile = stringdup(rest); dodebug = TRUE; to_user(from,"Debug output turned on, Output = %s",rest); } diff --git a/src/dns.c b/src/dns.c index 8f84673..9e641fa 100644 --- a/src/dns.c +++ b/src/dns.c @@ -59,9 +59,6 @@ typedef struct dnsRType #define MAX_QUESTIONS 16 -LS int dnssock = -1; -LS int dnsserver = 0; - #ifdef DEBUG char *type_textlist[] = { NULL, "A", "NS", "MD", "MF", "CNAME", "SOA", "MB", "MG", "MR", "NULL", "WKS", "PTR", "HINFO", "MINFO", "MX", "TXT", }; @@ -643,8 +640,6 @@ void process_rawdns(void) char packet[512]; int sz,n; - if (dnssock == -1) - return; if (FD_ISSET(dnssock,&read_fds)) { sz = sizeof(sai); diff --git a/src/function.c b/src/function.c index aee4fb2..7bef4ff 100644 --- a/src/function.c +++ b/src/function.c @@ -511,6 +511,8 @@ char *idle2str(time_t when, int small) char *dst; int n,z[4]; + when = now - when; + z[0] = when / 86400; z[1] = (when -= z[0] * 86400) / 3600; z[2] = (when -= z[1] * 3600) / 60; @@ -522,7 +524,7 @@ char *idle2str(time_t when, int small) /* xx : "59 seconds" */ if (small) { - char *f[] = {"day","hour","minute","second"}; + const char *f[] = {"day","hour","minute","second"}; *idlestr = 0; for(n=0;n<4;n++) diff --git a/src/gencmd.c b/src/gencmd.c index 45b24e3..90e7026 100644 --- a/src/gencmd.c +++ b/src/gencmd.c @@ -176,11 +176,11 @@ void make_mcmd(int mode) } if (pass == __struct_acces_2) { - to_file(fd,"LS OnMsg_access acmd[] =\n{\n"); + to_file(fd,"OnMsg_access acmd[] =\n{\n"); } if (pass == __struct_print_1) { - to_file(fd,"LS const OnMsg mcmd[] =\n{\n"); + to_file(fd,"const OnMsg mcmd[] =\n{\n"); } #ifdef HEATMAP @@ -229,6 +229,7 @@ void make_mcmd(int mode) } if (pass == __struct_print_1) { + char noargfunc[64]; h = mkhash(cmdstr); hashmap[h] = i; @@ -249,8 +250,9 @@ void make_mcmd(int mode) v.cbang = (pre_mcmd[cmdidx].flags & CBANG) ? 1 : 0; v.acchan = (pre_mcmd[cmdidx].flags & ACCHAN) ? 1 : 0; v.supres = (pre_mcmd[cmdidx].flags & SUPRES) ? 1 : 0; + v.noargf = (pre_mcmd[cmdidx].flags & NOARGF) ? 1 : 0; - sprintf(tmp,"%3i,%2i,%2i,%2i,%2i,%2i,%2i,%2i,%2i,%2i,%2i,%2i,%2i,%2i", + sprintf(tmp,"%3i,%2i,%2i,%2i,%2i,%2i,%2i,%2i,%2i,%2i,%2i,%2i,%2i,%2i,%2i", v.defaultaccess, v.dcc, v.cc, @@ -264,7 +266,8 @@ void make_mcmd(int mode) v.lbuf, v.cbang, v.acchan, - v.supres + v.supres, + v.noargf ); tabs = "\t\t\t"; @@ -278,14 +281,21 @@ void make_mcmd(int mode) else tabx = tabs + 3; + if (v.noargf) + sprintf(noargfunc,"%s_noargs",pre_mcmd[cmdidx].func); + else + strcpy(noargfunc,"0"); adj = strlen(pre_mcmd[cmdidx].func); tabs += 1 + ((adj > 6)); //to_file(fd,"/""* %3i=%3i *""/",h,i); - to_file(fd,(pre_mcmd[cmdidx].cmdarg) ? "{ C_%s,%s\t%s,%s%s\t, \"%s\"\t},\n" : "{ C_%s,%s\t%s,%s%s\t},\n", + to_file(fd,(pre_mcmd[cmdidx].cmdarg) ? + "{ C_%s,%s\t%s,%s,%s%s\t, \"%s\"\t},\n" : + "{ C_%s,%s\t%s,%s,%s%s\t},\n", cmdstr, tabx, pre_mcmd[cmdidx].func, + noargfunc, tabs, tmp, pre_mcmd[cmdidx].cmdarg diff --git a/src/global.h b/src/global.h index 6ab0c1a..9217b4f 100644 --- a/src/global.h +++ b/src/global.h @@ -1,7 +1,7 @@ /* EnergyMech, IRC bot software - Copyright (c) 1997-2024 proton + Copyright (c) 1997-2025 proton 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 @@ -24,7 +24,7 @@ #ifdef MAIN_C #define MDEF(x) = x -#define BEG LS +#define BEG #else /* MAIN_C */ @@ -39,6 +39,22 @@ * */ +struct CoreData /* Collect core data all in one place */ +{ + time_t now; + Mech *current; + char *rest_end; + char *chop_end; + int socksmodified; + int hisock; + int short_tv; +}; + +BEG struct CoreData cx; + +#define now cx.now +#define current cx.current + #define DEFAULTCMDCHAR '-' #define MECHUSERLOGIN "v3.energymech.net" @@ -52,6 +68,10 @@ BEG const char BOTCLASS[] MDEF("EnergyMech"); BEG const char BOTLOGIN[] MDEF("emech"); BEG const char NULLSTR[] MDEF(""); +#define EMPTYSTR (&NULLSTR[6]) +BEG const char DEFAULTSTR[] MDEF("default"); +BEG const char UNKNOWNATUNKNOWN[] MDEF("unknown@unknown"); +#define UNKNOWN (&UNKNOWNATUNKNOWN[8]) BEG const char ERR_CHAN[] MDEF("I'm not on %s"); BEG const char ERR_FILEOPEN[] MDEF("Couldn't open the file %s"); @@ -80,7 +100,6 @@ BEG const char FMT_6XSTRTAB[] MDEF("%s\t%s\t%s\t%s\t%s\t%s"); #define FMT_PLAIN &FMT_6XSTRTAB[15] BEG Mech *botlist MDEF(NULL); -BEG Mech *current; BEG char *executable; BEG char *configfile MDEF(CFGFILE); @@ -98,9 +117,6 @@ BEG ino_t parent_inode; BEG KillSock *killsocks MDEF(NULL); BEG Server *serverlist MDEF(NULL); -BEG ServerGroup *servergrouplist MDEF(NULL); -BEG ServerGroup *currentservergroup MDEF(NULL); -BEG int servergroupid MDEF(0); BEG int serverident MDEF(1); BEG char CurrentNick[NUHLEN]; @@ -130,14 +146,6 @@ BEG char nuh_buf[NUHLEN]; BEG fd_set read_fds; BEG fd_set write_fds; -BEG int hisock; -BEG int short_tv; - -/* - * current UNIX timestamp - */ - -BEG time_t now; /* * defined features @@ -151,9 +159,6 @@ BEG Alias *aliaslist MDEF(NULL); #ifdef BOTNET -BEG const char UNKNOWNATUNKNOWN[] MDEF("unknown@unknown"); -#define UNKNOWN (&UNKNOWNATUNKNOWN[8]) - BEG BotNet *botnetlist MDEF(NULL); BEG NetCfg *netcfglist MDEF(NULL); BEG char *linkpass MDEF(NULL); /* proc var */ @@ -204,6 +209,8 @@ BEG Note *notelist MDEF(NULL); #ifdef RAWDNS +BEG int dnssock MDEF(-1); +BEG int dnsserver MDEF(0); BEG dnsList *dnslist MDEF(NULL); BEG dnsAuthority *dnsroot MDEF(NULL); BEG struct in_addr ia_ns[MAX_NAMESERVERS]; @@ -308,7 +315,7 @@ BEG int spawning_lamer MDEF(0); /* * tolowertab blatantly ripped from ircu2.9.32 */ -LS const uchar tolowertab[256] = +const uchar tolowertab[256] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, @@ -347,7 +354,7 @@ LS const uchar tolowertab[256] = /* * be wary, this is not a normal upper-to-lower table... */ -LS const uchar nickcmptab[256] = +const uchar nickcmptab[256] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, @@ -383,7 +390,7 @@ LS const uchar nickcmptab[256] = 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff }; -LS const uchar attrtab[256] = +const uchar attrtab[256] = { 0, 0, 0, 0, 0, 0, 0, 0, /* 0x00 - 0x07 */ 0, 0, CRLF, 0, 0, CRLF, 0, 0, /* 0x08 - 0x0F */ @@ -426,7 +433,7 @@ LS const uchar attrtab[256] = /* * user struct for the core client */ -LS const Strp CMA = +const Strp CMA = { NULL, "*" @@ -435,7 +442,7 @@ LS const Strp CMA = /* * client struct for the core client */ -LS ShortClient CoreClient = +ShortClient CoreClient = { NULL, /* next */ (User*)&CoreUser, /* user */ @@ -445,27 +452,13 @@ LS ShortClient CoreClient = 0 /* lasttime */ }; -LS ShortChan CoreChan = +ShortChan CoreChan = { NULL, NULL }; -typedef struct coreServerGroup -{ - ServerGroup *next; - int servergroup; - char name[8]; -} coreServerGroup; - -LS coreServerGroup defaultServerGroup = -{ - NULL, /* next */ - 0, /* servergroup */ - "default" /* name */ -}; - -LS struct +struct { const char *string; const int id; @@ -487,7 +480,6 @@ extern const User xxCoreUser; extern const User xxLocalBot; extern ShortClient CoreClient; extern ShortChan CoreChan; -extern ServerGroup defaultServerGroup; #endif /* MAIN_C */ diff --git a/src/h.h b/src/h.h index b250362..f2b8bfe 100644 --- a/src/h.h +++ b/src/h.h @@ -21,12 +21,18 @@ #ifndef H_H #define H_H 1 +#if !defined(__STRICT_ANSI__) +#define __INLINE__ inline +#else +#define __INLINE__ +#endif + #define ischannel(x) (*x == '#') -#define nullstr(x) ((x)) ? (x) : NULLSTR +#define nullstr(x) ((x) ? x : NULLSTR) #define nullbuf(x) (x && *x) ? x : NULLSTR -#define chkhigh(x) if (x > hisock) { hisock = x; } +#define chkhigh(x) if (x > cx.hisock) { cx.hisock = x; } #define COMMAND_ARGS char *from, const char *to, char *rest, const int cmdaccess @@ -110,23 +116,24 @@ /* alias.c */ -LS void afmt(char *, const char *, const char *) __page(CORE_SEG); -LS void do_alias(COMMAND_ARGS) __page(CMD1_SEG); -LS void do_unalias(COMMAND_ARGS) __page(CMD1_SEG); +void afmt(char *, const char *, const char *) __page(CORE_SEG); +void do_alias(COMMAND_ARGS) __page(CMD1_SEG); +void do_unalias(COMMAND_ARGS) __page(CMD1_SEG); /* auth.c */ -LS char *cipher(char *) __page(CMD1_SEG); -LS char *makepass(char *) __page(CMD1_SEG); -LS int passmatch(char *, char *) __page(CMD1_SEG); -LS void delete_auth(char *) __page(CMD1_SEG); -LS void remove_auth(Auth *) __page(CMD1_SEG); -LS void change_authnick(char *, char *) __page(CORE_SEG); -LS void aucheck(User *) __page(CORE_SEG); -LS User *get_authuser(const char *, const char *) __page(CORE_SEG); -LS int get_authaccess(const char *, const char *) __page(CORE_SEG); -LS int make_auth(const char *, const User *) __page(CMD1_SEG); -LS void do_auth(COMMAND_ARGS) __page(CMD1_SEG); +char *cipher(char *) __page(CMD1_SEG); +char *makepass(char *) __page(CMD1_SEG); +int passmatch(char *, char *) __page(CMD1_SEG); +void delete_auth(char *) __page(CMD1_SEG); +void remove_auth(Auth *) __page(CMD1_SEG); +void change_authnick(char *, char *) __page(CORE_SEG); +void aucheck(User *) __page(CORE_SEG); +User *get_authuser(const char *, const char *) __page(CORE_SEG); +int get_authaccess(const char *, const char *) __page(CORE_SEG); +int make_auth(const char *, const User *) __page(CMD1_SEG); +void do_auth_noargs(const char *) __page(CMD1_SEG); +void do_auth(COMMAND_ARGS) __page(CMD1_SEG); /* bounce.c */ @@ -138,15 +145,15 @@ void process_bounce(void) __page(CORE_SEG); /* calc.c */ -LS void do_convert(COMMAND_ARGS) __page(CMD1_SEG); -LS void do_calc(COMMAND_ARGS) __page(CMD1_SEG); +void do_convert(COMMAND_ARGS) __page(CMD1_SEG); +void do_calc(COMMAND_ARGS) __page(CMD1_SEG); /* channel.c */ void check_idlekick(void); -LS Chan *find_channel(const char *, int) __attr(CORE_SEG, __regparm(2)); -LS Chan *find_channel_ac(const char *) __attr(CORE_SEG, __regparm(1)); -LS Chan *find_channel_ny(const char *) __attr(CORE_SEG, __regparm(1)); +Chan *find_channel(const char *, int) __attr(CORE_SEG, __regparm(2)); +Chan *find_channel_ac(const char *) __attr(CORE_SEG, __regparm(1)); +Chan *find_channel_ny(const char *) __attr(CORE_SEG, __regparm(1)); void remove_chan(Chan *) __page(CMD1_SEG); void join_channel(char *, char *) __page(CFG1_SEG); void reverse_topic(Chan *, char *, char *) __page(CORE_SEG); @@ -159,23 +166,23 @@ void delete_ban(Chan *, char *); void delete_modemask(Chan *, char *, int); void channel_massmode(const Chan *, char *, int, char, char); void channel_massunban(Chan *, char *, time_t); -LS ChanUser *find_chanuser(Chan *, const char *) __page(CORE_SEG); -LS ChanUser *find_chanbot(Chan *, const char *) __page(CORE_SEG); -LS void remove_chanuser(Chan *, const char *) __page(CORE_SEG); -LS void make_chanuser(char *, char *) __page(CORE_SEG); -LS void purge_chanusers(Chan *) __page(CMD1_SEG); -LS char *get_nuh(const ChanUser *) __page(CORE_SEG); -LS void do_join(COMMAND_ARGS) __page(CMD1_SEG); -LS void do_part(COMMAND_ARGS) __page(CMD1_SEG); -LS void do_cycle(COMMAND_ARGS) __page(CMD1_SEG); -LS void do_forget(COMMAND_ARGS) __page(CMD1_SEG); -LS void do_channels(COMMAND_ARGS) __page(CMD1_SEG); -LS void do_wall(COMMAND_ARGS) __page(CMD1_SEG); -LS void do_mode(COMMAND_ARGS) __page(CMD1_SEG); -LS void do_names(COMMAND_ARGS) __page(CMD1_SEG); -LS void do_cchan(COMMAND_ARGS) __page(CMD1_SEG); -LS void do_invite(COMMAND_ARGS) __page(CMD1_SEG); -LS void do_sayme(COMMAND_ARGS) __page(CMD1_SEG); +ChanUser *find_chanuser(Chan *, const char *) __page(CORE_SEG); +ChanUser *find_chanbot(Chan *, const char *) __page(CORE_SEG); +void remove_chanuser(Chan *, const char *) __page(CORE_SEG); +void make_chanuser(char *, char *) __page(CORE_SEG); +void purge_chanusers(Chan *) __page(CMD1_SEG); +char *get_nuh(const ChanUser *) __page(CORE_SEG); +void do_join(COMMAND_ARGS) __page(CMD1_SEG); +void do_part(COMMAND_ARGS) __page(CMD1_SEG); +void do_cycle(COMMAND_ARGS) __page(CMD1_SEG); +void do_forget(COMMAND_ARGS) __page(CMD1_SEG); +void do_channels(COMMAND_ARGS) __page(CMD1_SEG); +void do_wall(COMMAND_ARGS) __page(CMD1_SEG); +void do_mode(COMMAND_ARGS) __page(CMD1_SEG); +void do_names(COMMAND_ARGS) __page(CMD1_SEG); +void do_cchan(COMMAND_ARGS) __page(CMD1_SEG); +void do_invite(COMMAND_ARGS) __page(CMD1_SEG); +void do_sayme(COMMAND_ARGS) __page(CMD1_SEG); LS void do_who(COMMAND_ARGS) __page(CMD1_SEG); LS void do_topic(COMMAND_ARGS) __page(CMD1_SEG); LS void do_showidle(COMMAND_ARGS) __page(CMD1_SEG); @@ -196,14 +203,12 @@ void set_mix16(Mix16 *, const char *) __page(CORE_SEG); void set_mix64(Mix64 *, const char *) __page(CORE_SEG); int conf_callback(char *line) __page(CFG1_SEG); -void readcfgfile(void) __page(CFG1_SEG); +void readcfgfile(void) __page(INIT_SEG); int write_session(void) __page(CORE_SEG); Mech *add_bot(int guid, char *nick) __page(CFG1_SEG); void signoff(char *from, char *reason) __page(RARE_SEG); void kill_all_bots(char *reason) __attr(RARE_SEG, __noreturn__);; -Server *add_server(char *host, int port, char *pass) __page(CFG1_SEG); -ServerGroup *getservergroup(const char *name); -ServerGroup *getservergroupid(int id); +Server *add_server(const char *host, const int port, const char *pass, const char *group) __page(CFG1_SEG); Server *find_server(int id) __page(CORE_SEG); int try_server(Server *sp, char *hostname) __page(CORE_SEG); void connect_to_server(void) __page(CORE_SEG); @@ -216,7 +221,7 @@ void do_version(COMMAND_ARGS) __page(CMD1_SEG); void do_core(COMMAND_ARGS) __page(CMD1_SEG); void do_die(COMMAND_ARGS) __page(RARE_SEG); void do_shutdown(COMMAND_ARGS) __page(RARE_SEG); -void do_servergroup(COMMAND_ARGS) __page(CMD1_SEG); +void do_server_noargs(const char *from) __page(CMD1_SEG); void do_server(COMMAND_ARGS) __page(CMD1_SEG); void do_cserv(COMMAND_ARGS) __page(CMD1_SEG); void do_away(COMMAND_ARGS) __page(CMD1_SEG); @@ -428,8 +433,9 @@ LS void sig_segv(int, siginfo_t *, void *) __attr(RARE_SEG, __noreturn__); LS void sig_segv(int) __attr(RARE_SEG, __noreturn__); #endif LS void sig_term(int) __attr(RARE_SEG, __noreturn__); /* rare */ -LS void doit(void) __page(CORE_SEG); -LS int main(int argc, char **argv, char **envp) __page(INIT_SEG); +int main(int argc, char **argv, char **envp) __page(INIT_SEG); +int parse_commandline(int argc, char **argv, char **envp) __page(INIT_SEG); +void mainloop(void) __attr(CORE_SEG, __noreturn__); /* net.c */ @@ -444,15 +450,15 @@ void botnet_binfo_relay(BotNet *source, BotInfo *binfo); void botnet_binfo_tofile(int sock, BotInfo *binfo); void botnet_dumplinklist(BotNet *bn); int connect_to_bot(NetCfg *cfg); -LS void check_botjoin(Chan *chan, ChanUser *cu); -LS void check_botinfo(BotInfo *binfo, const char *channel); +void check_botjoin(Chan *chan, ChanUser *cu); +void check_botinfo(BotInfo *binfo, const char *channel); void basicAuth(BotNet *bn, char *rest); void basicAuthOK(BotNet *bn, char *rest); void basicBanner(BotNet *bn, char *rest); void basicLink(BotNet *bn, char *version); void basicQuit(BotNet *bn, char *rest); -LS void netchanNeedop(BotNet *source, char *rest); -LS void netchanSuppress(BotNet *, char *) __page(CORE_SEG); +void netchanNeedop(BotNet *source, char *rest); +void netchanSuppress(BotNet *, char *) __page(CORE_SEG); void partyAuth(BotNet *bn, char *rest); int commandlocal(int dg, int sg, char *from, char *command); void partyCommand(BotNet *bn, char *rest); @@ -464,12 +470,13 @@ void parse_botnet(BotNet *bn, char *rest); void botnet_newsock(void); void select_botnet(void) __page(CORE_SEG); void process_botnet(void) __page(CORE_SEG); +void do_link_noargs(const char *) __page(CMD1_SEG); void do_link(COMMAND_ARGS) __page(CMD1_SEG); void do_cmd(COMMAND_ARGS) __page(CMD1_SEG); /* note.c */ -int catch_note(char *from, char *to, char *rest); +int catch_note(char *from, char *to, char *rest) __page(CMD1_SEG); void do_note(COMMAND_ARGS) __page(CMD1_SEG); void do_read(COMMAND_ARGS) __page(CMD1_SEG); @@ -519,37 +526,37 @@ LS void parse_privmsg(char *from, char *rest) __page(CORE_SEG); LS void parse_quit(char *from, char *rest) __page(CORE_SEG); LS void parse_topic(char *from, char *rest) __page(CORE_SEG); LS void parse_wallops(char *from, char *rest) __page(CORE_SEG); -LS void parse_213(char *from, char *rest); -LS void parse_219(char *from, char *rest); -LS void parse_251(char *from, char *rest); -LS void parse_252(char *from, char *rest); -LS void parse_253(char *from, char *rest); -LS void parse_254(char *from, char *rest); -LS void parse_255(char *from, char *rest); -LS void parse_301(char *from, char *rest); -LS void parse_303(char *from, char *rest); -LS void parse_311(char *from, char *rest); -LS void parse_312(char *from, char *rest); -LS void parse_313(char *from, char *rest); -LS void parse_315(char *from, char *rest); -LS void parse_317(char *from, char *rest); -LS void parse_318(char *from, char *rest); -LS void parse_319(char *from, char *rest); -LS void parse_324(char *from, char *rest); -LS void parse_352(char *from, char *rest); -LS void parse_367(char *from, char *rest); -LS void parse_376(char *from, char *rest); -LS void parse_401(char *from, char *rest); -LS void parse_433(char *from, char *rest); -LS void parse_451(char *from, char *rest); -LS void parse_471(char *from, char *rest); -LS void parse_473(char *from, char *rest); -LS void parse_346(char *from, char *rest); -LS void parse_348(char *from, char *rest); -LS void parse_368(char *from, char *rest); -LS void parse_005(char *from, char *rest); -LS uint32_t stringhash(char *s) __page(CORE_SEG); -LS void parse_server_input(char *rest) __page(CORE_SEG); +void parse_213(char *from, char *rest); +void parse_219(char *from, char *rest); +void parse_251(char *from, char *rest); +void parse_252(char *from, char *rest); +void parse_253(char *from, char *rest); +void parse_254(char *from, char *rest); +void parse_255(char *from, char *rest); +void parse_301(char *from, char *rest); +void parse_303(char *from, char *rest); +void parse_311(char *from, char *rest); +void parse_312(char *from, char *rest); +void parse_313(char *from, char *rest); +void parse_315(char *from, char *rest); +void parse_317(char *from, char *rest); +void parse_318(char *from, char *rest); +void parse_319(char *from, char *rest); +void parse_324(char *from, char *rest); +void parse_352(char *from, char *rest); +void parse_367(char *from, char *rest); +void parse_376(char *from, char *rest); +void parse_401(char *from, char *rest); +void parse_433(char *from, char *rest); +void parse_451(char *from, char *rest); +void parse_471(char *from, char *rest); +void parse_473(char *from, char *rest); +void parse_346(char *from, char *rest); +void parse_348(char *from, char *rest); +void parse_368(char *from, char *rest); +void parse_005(char *from, char *rest); +static __INLINE__ uint32_t stringhash(char *) __page(CORE_SEG); +void parse_server_input(char *) __page(CORE_SEG); /* partyline.c */ diff --git a/src/io.c b/src/io.c index 65a0d21..ea98788 100644 --- a/src/io.c +++ b/src/io.c @@ -458,7 +458,7 @@ void to_user(const char *target, const char *format, ...) * 2: If data is insufficient, try to read in more * 3: Try again to make a whole line */ -char *sockread(int s, char *rest, char *line) +char *sockread(int socket, char *rest, char *output) { char *src,*dst,*rdst; int n; @@ -466,7 +466,7 @@ char *sockread(int s, char *rest, char *line) errno = EAGAIN; src = rest; - dst = line; + dst = output; while(*src) { @@ -476,20 +476,26 @@ char *sockread(int s, char *rest, char *line) while(*src == '\n' || *src == '\r') src++; *dst = 0; +#if !defined(GENCMD_C) + cx.rest_end = dst; +#endif /* !defined(GENCMD_C) */ + + /* move remainder of rest to the beginning of the buffer */ + /* src can be end of rest or globaldata */ dst = rest; while(*src) *(dst++) = *(src++); *dst = 0; + #if defined(DEBUG) && !defined(GENCMD_C) - debug("(in) {%i} %s\n",s,line); + debug("(in) {%i} %s\n",socket,output); #endif /* DEBUG */ - return((*line) ? line : NULL); + return((*output) ? output : NULL); } *(dst++) = *(src++); } - rdst = src; - n = read(s,globaldata,MSGLEN-2); + n = read(socket,globaldata,MSGLEN-2); switch(n) { case 0: @@ -498,14 +504,15 @@ char *sockread(int s, char *rest, char *line) return(NULL); } + rdst = src; globaldata[n] = 0; src = globaldata; while(*src) { if (*src == '\r' || *src == '\n') - goto gotline; - if ((dst - line) >= (MSGLEN-2)) + goto gotline; /* gotline will move the rest of globaldata to rest */ + if ((dst - output) >= (MSGLEN-2)) { /* * line is longer than buffer, let the wheel spin diff --git a/src/main.c b/src/main.c index 198dfb8..deba8e9 100755 --- a/src/main.c +++ b/src/main.c @@ -51,7 +51,6 @@ #include "hostinfo.c" #include "io.c" #include "irc.c" -#include "lib/string.c" #include "net.c" #include "note.c" #include "ons.c" @@ -67,6 +66,7 @@ #include "seen.c" #include "shit.c" #include "spy.c" +#include "string.c" #include "tcl.c" #include "toybox.c" #include "uptime.c" @@ -522,18 +522,16 @@ void sig_term(int signum) * */ -#ifdef __GNUC__ -LS void doit(void) __attribute__ ((__noreturn__, __sect(CORE_SEG))); -#endif -void doit(void) +void mainloop(void) { - struct timeval tv; + SequenceTime this; Chan *chan; Client *client; - SequenceTime this; Strp *qm; + struct timeval tv; time_t last_update; + last_update = now; /* @@ -574,7 +572,7 @@ mainloop: FD_ZERO(&read_fds); FD_ZERO(&write_fds); - hisock = -1; + cx.hisock = -1; #ifdef BOTNET select_botnet(); @@ -599,7 +597,7 @@ mainloop: /* * unset here, reset if needed in bot loop */ - short_tv &= ~(TV_SERVCONNECT|TV_LINEBUF); + cx.short_tv &= ~(TV_SERVCONNECT|TV_LINEBUF); for(current=botlist;current;current=current->next) { if (current->sock == -1) @@ -644,7 +642,7 @@ mainloop: else { doit_jumptonext: - short_tv |= TV_SERVCONNECT; + cx.short_tv |= TV_SERVCONNECT; if ((now - current->conntry) >= 2) connect_to_server(); } @@ -657,7 +655,7 @@ doit_jumptonext: } else { - short_tv |= TV_SERVCONNECT; + cx.short_tv |= TV_SERVCONNECT; if ((now - current->conntry) >= 2) connect_to_server(); } @@ -677,7 +675,7 @@ doit_jumptonext: } if ((current->connect == CN_TRYING) || (current->connect == CN_CONNECTED)) { - short_tv |= TV_SERVCONNECT; + cx.short_tv |= TV_SERVCONNECT; if ((now - current->conntry) > ctimeout) { #ifdef DEBUG @@ -692,7 +690,7 @@ doit_jumptonext: } if (current->sendq) { - short_tv |= TV_LINEBUF; + cx.short_tv |= TV_LINEBUF; } else { @@ -700,7 +698,7 @@ doit_jumptonext: { if (chan->kicklist || chan->modelist) { - short_tv |= TV_LINEBUF; + cx.short_tv |= TV_LINEBUF; break; } } @@ -746,13 +744,13 @@ restart_dcc: * Longer delay saves CPU but some features require shorter delays */ #ifdef NOTIFY - tv.tv_sec = (short_tv) ? 1 : 5; + tv.tv_sec = (cx.short_tv) ? 1 : 5; #else /* NOTIFY */ - tv.tv_sec = (short_tv) ? 1 : 30; + tv.tv_sec = (cx.short_tv) ? 1 : 30; #endif /* NOTIFY */ tv.tv_usec = 0; - if ((select(hisock+1,&read_fds,&write_fds,0,&tv) == -1) && (errno == EINTR)) + if ((select(cx.hisock+1,&read_fds,&write_fds,0,&tv) == -1) && (errno == EINTR)) goto mainloop; /* @@ -851,7 +849,8 @@ restart_die: #endif /* BOTNET */ #ifdef BOUNCE - process_bounce(); + if (bounce_sock != -1 || bnclist) + process_bounce(); #endif /* BOUNCE */ #ifdef CHANBAN @@ -859,7 +858,8 @@ restart_die: #endif /* CHANBAN */ #ifdef RAWDNS - process_rawdns(); + if (dnssock != -1) + process_rawdns(); #endif /* RAWDNS */ #ifdef UPTIME @@ -889,15 +889,12 @@ restart_die: } /* - * main(), we love it and cant live without it + * parse commandline */ -LS char *bad_exe = "init: Error: Improper executable name\n"; +const char *bad_exe = "init: Error: Improper executable name\n"; -#ifdef __GNUC__ -int main(int argc, char **argv, char **envp) __attribute__ ((__sect(INIT_SEG))); -#endif -int main(int argc, char **argv, char **envp) +int parse_commandline(int argc, char **argv, char **envp) { struct stat st; char *opt; @@ -1084,9 +1081,6 @@ int main(int argc, char **argv, char **envp) } } - servergrouplist = (ServerGroup*)&defaultServerGroup; - currentservergroup = (ServerGroup*)&defaultServerGroup; - if (!mechresetenv) { to_file(1,TEXT_HDR_VERS,VERSION,SRCDATE); @@ -1191,7 +1185,10 @@ int main(int argc, char **argv, char **envp) } if (current->userlist == NULL) { - to_file(1,"init: No userlist loaded for %s\n",nullstr(current->nick)); + char *nick; + + nick = getbotnick(current); + to_file(1,"init: No userlist loaded for %s\n",nullstr(nick)); n++; } } @@ -1291,7 +1288,16 @@ int main(int argc, char **argv, char **envp) } startup = STARTUP_RUNNING; #ifdef DEBUG - debug("(main) entering doit()...\n"); + debug("(main) entering main loop...\n"); #endif - doit(); +} + +/* + * Make main short and sweet, reduce stack data + * Main(), we love it and cant live without it + */ +int main(int argc, char **argv, char **envp) +{ + parse_commandline(argc, argv, envp); + mainloop(); } diff --git a/src/net.c b/src/net.c index 05fe957..a963ae4 100644 --- a/src/net.c +++ b/src/net.c @@ -409,7 +409,7 @@ void basicAuth(BotNet *bn, char *rest) { case BNAUTH_PLAINTEXT: /* ->> plain text given: "DomoOmiGato" stored "kooplook0988" +>> plain text given: "DomoOmiGato" stored "........." (reset_linkable) guid 1337 reset to linkable (basicAuth) bad password [ guid = 1337 ] */ @@ -420,6 +420,12 @@ void basicAuth(BotNet *bn, char *rest) goto badpass; break; #ifdef SHACRYPT +/* +(in) {6} BB1881 634704033 PTA SHA +(out) {6} BB9344 1233037145 PTA SHA +>> sha pass exchange: "........ ......... 634704033 1233037145" +(out) {2} BASHA $6$5525$mZLr762...... +*/ case BNAUTH_SHA: { char *enc,temppass[24 + Strlen2(pass,linkpass)]; /* linkpass is never NULL */ @@ -1474,14 +1480,14 @@ void select_botnet(void) } } - short_tv &= ~TV_BOTNET; + cx.short_tv &= ~TV_BOTNET; for(bn=botnetlist;bn;bn=bn->next) { chkhigh(bn->sock); if (bn->status == BN_CONNECT) { FD_SET(bn->sock,&write_fds); - short_tv |= TV_BOTNET; + cx.short_tv |= TV_BOTNET; } else { @@ -1639,6 +1645,22 @@ clean: * */ +void do_link_noargs(const char *from) +{ + NetCfg *cfg; + + /* + * list all the known links + */ + table_buffer("guid\tpass\thost\tport"); + for(cfg=netcfglist;cfg;cfg=cfg->next) + { + table_buffer("%i\t%s\t%s\t%i",cfg->guid,(cfg->pass) ? cfg->pass : EMPTYSTR, + (cfg->host) ? cfg->host : EMPTYSTR,cfg->port); + } + table_send(from,2); +} + void do_link(COMMAND_ARGS) { /* @@ -1649,21 +1671,6 @@ void do_link(COMMAND_ARGS) int iguid,iport; int mode; - /* - * list all the known links - */ - if (!*rest) - { - table_buffer("guid\tpass\thost\tport"); - for(cfg=netcfglist;cfg;cfg=cfg->next) - { - table_buffer("%i\t%s\t%s\t%i",cfg->guid,(cfg->pass) ? cfg->pass : "", - (cfg->host) ? cfg->host : "",cfg->port); - } - table_send(from,2); - return; - } - guid = chop(&rest); if (*guid == '+' || *guid == '-') mode = *guid++; @@ -1726,6 +1733,7 @@ usage: if (mode == '-') { + to_user(from,"removing link guid: %i",iguid); *pp = cfg->next; Free((char**)&cfg); return; diff --git a/src/ons.c b/src/ons.c index 24df1c1..c118be7 100644 --- a/src/ons.c +++ b/src/ons.c @@ -402,6 +402,11 @@ void on_msg(char *from, char *to, char *rest) * non-NULL and non-zerolength */ + /* + * remember where the string started + */ + origstart = rest; + /* * Are we recording a note? */ @@ -415,10 +420,7 @@ void on_msg(char *from, char *to, char *rest) * public commands, we can go directly to common_public() */ if (CurrentChan && !CurrentChan->setting[TOG_PUB].int_var) - { - common_public(CurrentChan,from,"<%s> %s",rest); - return; - } + goto public_msg_unchopped; if (CurrentDCC) { @@ -433,10 +435,6 @@ void on_msg(char *from, char *to, char *rest) return; } - /* - * remember where the string started - */ - origstart = rest; if (from == CoreUser.name) { @@ -537,179 +535,178 @@ recheck_alias: if (i == 255) goto public_msg; - if (!has_cc && mcmd[i].cc && !(has_bang && mcmd[i].cbang)) - goto public_msg; - if (uaccess < acmd[i]) - goto public_msg; - /* - * The string hash matches a command, but is it a false positive? - */ - if (stringcasecmp(mcmd[i].name,command) != 0) - goto public_msg; + if (!has_cc && mcmd[i].cc && !(has_bang && mcmd[i].cbang)) + goto public_msg; + if (uaccess < acmd[i]) + goto public_msg; + /* + * The string hash matches a command, but is it a false positive? + */ + if (stringcasecmp(mcmd[i].name,command) != 0) + goto public_msg; #if defined(BOTNET) && defined(REDIRECT) - if (mcmd[i].nocmd && redirect.to) - return; + if (mcmd[i].nocmd && redirect.to) + return; #endif /* BOTNET && REDIRECT */ - if (mcmd[i].nopub && CurrentChan) - { + if (mcmd[i].nopub && CurrentChan) + { #ifdef DEBUG - debug("(on_msg) Public command (%s) ignored\n",command); + debug("(on_msg) Public command (%s) ignored\n",command); #endif /* DEBUG */ - return; - } + return; + } - CurrentCmd = &mcmd[i]; + CurrentCmd = &mcmd[i]; #ifdef SUPPRESS #ifdef BOTNET - /* experimental command supression */ - if (CurrentCmd->name == current->supres_cmd) - { - int crc; + /* experimental command supression */ + if (CurrentCmd->name == current->supres_cmd) + { + int crc; - crc = makecrc(rest); - if (current->supres_crc == crc) - { - /* another bot has already executed this command and is trying to supress its execution on other bots */ - current->supres_cmd = NULL; - current->supres_crc = 0; -#ifdef DEBUG - debug("(on_msg) command \"%s\" from %s was supressed\n",CurrentCmd->name,CurrentNick); -#endif - return; - } - } - /*if command should be supressed ... */ - if (mcmd[i].supres && CurrentChan) + crc = makecrc(rest); + if (current->supres_crc == crc) { - send_suppress(CurrentCmd->name,rest); + /* another bot has already executed this command and is trying to supress its execution on other bots */ + current->supres_cmd = NULL; + current->supres_crc = 0; +#ifdef DEBUG + debug("(on_msg) command \"%s\" from %s was supressed\n",CurrentCmd->name,CurrentNick); +#endif + return; } + } + /*if command should be supressed ... */ + if (mcmd[i].supres && CurrentChan) + { + send_suppress(CurrentCmd->name,rest); + } #endif #endif /* SUPPRESS */ - /* - * convert the command to uppercase - */ - stringcpy(command,mcmd[i].name); + /* + * convert the command to uppercase + */ + stringcpy(command,mcmd[i].name); - /* - * send statmsg with info on the command executed - */ - if (current->setting[TOG_SPY].int_var) + /* + * send statmsg with info on the command executed + */ + if (current->setting[TOG_SPY].int_var) + { + send_spy(SPYSTR_STATUS,":%s[%i]: Executing %s[%i]", + CurrentNick,uaccess,command,(int)acmd[i]); + } + + /* + * CAXS check: first argument might be a channel + * check user access on target channel + */ + if (mcmd[i].caxs) + { + /* get channel name; 1: msg, 2: to, 3: active channel */ + to = (char*)get_channel(to,&rest); + if (!ischannel(to)) + return; + uaccess = get_authaccess(from,to); + if (uaccess < acmd[i]) + return; + CurrentChan = find_channel_ny(to); + if (mcmd[i].acchan && (CurrentChan == NULL || CurrentChan->active == 0)) { - send_spy(SPYSTR_STATUS,":%s[%i]: Executing %s[%i]", - CurrentNick,uaccess,command,(int)acmd[i]); + to_user(from,ERR_CHAN,to); + return; } + } + else + /* + * GAXS check: user needs global access + */ + if (mcmd[i].gaxs) + { + uaccess = get_authaccess(from,MATCH_ALL); + if (uaccess < acmd[i]) + return; + } - /* - * CAXS check: first argument might be a channel - * check user access on target channel - */ - if (mcmd[i].caxs) + /* + * list of last LASTCMDSIZE commands + */ + if (from != CoreUser.name) + { + Free(¤t->lastcmds[LASTCMDSIZE-1]); + for(j=LASTCMDSIZE-2;j>=0;j--) + current->lastcmds[j+1] = current->lastcmds[j]; + if ((pt = STRCHR(from,'@')) == NULL) + pt = from; + set_mallocdoer(on_msg); + current->lastcmds[0] = (char*)Calloc(strlen(pt) + 45); + if (CurrentUser) { - /* get channel name; 1: msg, 2: to, 3: active channel */ - to = (char*)get_channel(to,&rest); - if (!ischannel(to)) - return; - uaccess = get_authaccess(from,to); - if (uaccess < acmd[i]) - return; - CurrentChan = find_channel_ny(to); - if (mcmd[i].acchan && (CurrentChan == NULL || CurrentChan->active == 0)) - { - to_user(from,ERR_CHAN,to); - return; - } + sprintf(current->lastcmds[0],"[%s] %s\r%s[%-3i]\t(*%s)", + time2medium(now),command,CurrentUser->name, + (CurrentUser->x.x.access),pt); } else - /* - * GAXS check: user needs global access - */ - if (mcmd[i].gaxs) { - uaccess = get_authaccess(from,MATCH_ALL); - if (uaccess < acmd[i]) - return; + sprintf(current->lastcmds[0],"[%s] %s\r%s[---]\t(*%s)", + time2medium(now),command,CurrentNick,pt); } + } - /* - * list of last LASTCMDSIZE commands - */ - if (from != CoreUser.name) - { - Free(¤t->lastcmds[LASTCMDSIZE-1]); - for(j=LASTCMDSIZE-2;j>=0;j--) - current->lastcmds[j+1] = current->lastcmds[j]; - if ((pt = STRCHR(from,'@')) == NULL) - pt = from; - set_mallocdoer(on_msg); - current->lastcmds[0] = (char*)Calloc(strlen(pt) + 45); - if (CurrentUser) - { - sprintf(current->lastcmds[0],"[%s] %s\r%s[%-3i]\t(*%s)", - time2medium(now),command,CurrentUser->name, - (CurrentUser->x.x.access),pt); - } - else - { - sprintf(current->lastcmds[0],"[%s] %s\r%s[---]\t(*%s)", - time2medium(now),command,CurrentNick,pt); - } - } - - /* - * CARGS check: at least one argument is required - */ - if (mcmd[i].args && !*rest) - { - if (uaccess) usage_command(from,command); - return; - } + /* + * CARGS check: at least one argument is required + */ + if (mcmd[i].args && !*rest) + { + if (uaccess) usage_command(from,command); + return; + } #ifdef REDIRECT - /* - * can this command be redirected? - */ - if (!redirect.to && mcmd[i].redir) + /* + * can this command be redirected? + */ + if (!redirect.to && mcmd[i].redir) + { + if (mcmd[i].lbuf && ischannel(orig_to)) { - if (mcmd[i].lbuf && ischannel(orig_to)) - { - set_mallocdoer(on_msg); - redirect.to = stringdup(to); - redirect.method = R_PRIVMSG; - } - else - if (begin_redirect(from,rest) < 0) - return; + set_mallocdoer(on_msg); + redirect.to = stringdup(to); + redirect.method = R_PRIVMSG; } + else + if (begin_redirect(from,rest) < 0) + return; + } #endif /* REDIRECT */ - if (mcmd[i].dcc && partyline_only_command(from)) - return; + if (mcmd[i].dcc && partyline_only_command(from)) + return; + /* + * Run command function + */ + if (mcmd[i].noargfunc && *rest == 0) + mcmd[i].noargfunc(from); + else mcmd[i].func(from,to,rest,acmd[i]); -#ifdef DEBUG - CurrentCmd = NULL; -#endif /* DEBUG */ #ifdef REDIRECT - end_redirect(); + end_redirect(); #endif /* REDIRECT */ - /* - * be quick to exit afterwards, there are "dangerous" commands like DIE and USER -... - */ - return; -/* todo: delete - hash - } -*/ + /* + * be quick to exit afterwards, there are "dangerous" commands like DIE and USER -... + */ + return; /* * If the input isnt a command or the sender lacks access */ public_msg: - /* * un-chop() the message string */ @@ -717,6 +714,7 @@ public_msg: if (CurrentChan) { +public_msg_unchopped: common_public(CurrentChan,from,"<%s> %s",origstart); } else diff --git a/src/parse.c b/src/parse.c index 29c2672..0c182e1 100644 --- a/src/parse.c +++ b/src/parse.c @@ -367,7 +367,7 @@ void parse_pong(char *from, char *rest) ot = (ot * 10) + (*src++ - '0'); current->ontime = ot; #ifdef DEBUG - debug("(parse_pong) recovering ontime = %lu (%s)\n",ot,idle2str(now - ot,TRUE)); + debug("(parse_pong) recovering ontime = %lu (%s)\n",ot,idle2str(ot,TRUE)); #endif } } @@ -1444,7 +1444,7 @@ LS const struct { 0, 0, NULL } }; -uint32_t stringhash(char *s) +static __INLINE__ uint32_t stringhash(char *s) { uint32_t hash; int i; @@ -1459,6 +1459,7 @@ void parse_server_input(char *rest) { #ifdef SCRIPTING Hook *hook; + int skip; #endif /* SCRIPTING */ char *from,*command; uint32_t cmdhash; @@ -1467,8 +1468,8 @@ void parse_server_input(char *rest) if (current->spy & (SPYF_RAWIRC|SPYF_RANDSRC)) send_spy(SPYSTR_RAWIRC,rest); -/*new undernet amusements */ -/*(in) {5} NOTICE AUTH :*** You have identd disabled (or broken), to continue to connect you must type /QUOTE PASS 17071 */ +/* New undernet amusements */ +/* NOTICE AUTH :*** You have identd disabled (or broken), to continue to connect you must type /QUOTE PASS 17071 */ if (current->connect == CN_CONNECTED && *rest == 'N' && !matches("NOTICE AUTH * /QUOTE PASS *",rest)) { from = STREND(rest); @@ -1498,7 +1499,7 @@ void parse_server_input(char *rest) rest++; #ifdef SCRIPTING - cmdhash = 1; + skip = 0; for(hook=hooklist;hook;hook=hook->next) { /* @@ -1511,18 +1512,16 @@ void parse_server_input(char *rest) */ if (hook->flags == MEV_PARSE && !stringcasecmp(command,hook->type.command)) { - if (hook->func(from,rest,hook)) - /* if the hook returns non-zero, the input should not be parsed internally */ - cmdhash = 0; + /* if the hook returns non-zero, the input should not be parsed internally */ + skip += hook->func(from,rest,hook); } } - if (cmdhash == 0) + if (skip) return; #endif /* SCRIPTING */ cmdhash = stringhash(command); - /*debug("cmdhash = %08X\n",cmdhash); */ for(i=0;pFuncs[i].hash;i++) { if (cmdhash == pFuncs[i].hash) @@ -1535,5 +1534,4 @@ void parse_server_input(char *rest) return; } } - /*debug("unmatched cmdhash %08X\n",cmdhash); */ } diff --git a/src/prot.c b/src/prot.c index 9db1f22..b1ac6d5 100644 --- a/src/prot.c +++ b/src/prot.c @@ -498,14 +498,14 @@ void process_chanbans(void) { #ifdef DEBUG debug("(process_chanbans) skipping %s (%i), (lastchanban (%lu) > now - 10 (%lu)\n", - current->nick,current->guid,current->lastchanban,(now - 10)); + getbotnick(current),current->guid,current->lastchanban,(now - 10)); #endif /* DEBUG */ continue; } if (current->sendq) /* only do chanbans on empty queue */ { #ifdef DEBUG - debug("(process_chanbans) skipping %s (%i), sendq not empty\n",current->nick,current->guid); + debug("(process_chanbans) skipping %s (%i), sendq not empty\n",getbotnick(current),current->guid); #endif /* DEBUG */ continue; } diff --git a/src/python.c b/src/python.c index 1b8ee35..7252698 100644 --- a/src/python.c +++ b/src/python.c @@ -88,11 +88,11 @@ static PyObject *python_getvar(PyObject *self, PyObject *args) case PYVAR_currentnick: return Py_BuildValue("s", CurrentNick); case PYVAR_botnick: - return Py_BuildValue("s", current && current->nick ? current->nick : ""); + return Py_BuildValue("s", current && getbotnick(current)); case PYVAR_wantnick: - return Py_BuildValue("s", current && current->wantnick ? current->wantnick : ""); + return Py_BuildValue("s", current && getbotwantnick(current)); case PYVAR_userhost: - return Py_BuildValue("s", current && current->userhost ? current->userhost : ""); + return Py_BuildValue("s", current && getbotuserhost(current)); case PYVAR_server: return Py_BuildValue("i", current && current->server ? current->server : -1); case PYVAR_nextserver: diff --git a/src/seen.c b/src/seen.c index dbc2622..b3a19a8 100644 --- a/src/seen.c +++ b/src/seen.c @@ -847,7 +847,7 @@ void do_seen(COMMAND_ARGS) return; } - if (!nickcmp(n,current->nick)) + if (!nickcmp(n,getbotnick(current))) { fmt = "%s is me you dweeb!"; } diff --git a/src/lib/string.c b/src/string.c similarity index 93% rename from src/lib/string.c rename to src/string.c index 2f8f7f3..9abebdb 100644 --- a/src/lib/string.c +++ b/src/string.c @@ -34,24 +34,25 @@ char *chop(char **src) { char *tok,*cut = *src; - while(*cut && *cut == ' ') + /* skip leading spaces */ + while(*cut == ' ') cut++; - if (*cut) - { - tok = cut; - while(*cut && *cut != ' ') - cut++; - *src = cut; - while(*cut && *cut == ' ') - cut++; - **src = 0; - *src = cut; - } - else - { - tok = NULL; - } + if (*cut == 0) + return(NULL); + + tok = cut; + while(*cut && *cut != ' ') + cut++; + *src = cut; + + /* skip more spaces */ + while(*cut == ' ') + cut++; + + **src = 0; + cx.chop_end = *src = cut; + return(tok); } diff --git a/src/structs.h b/src/structs.h index c8579cb..9c1a7f3 100644 --- a/src/structs.h +++ b/src/structs.h @@ -79,6 +79,7 @@ typedef struct OnMsg { const char *name; void (*func)(char *, const char *, char *, const int); + void (*noargfunc)(const char *); uint32_t defaultaccess:8, /* defaultaccess */ dcc:1, cc:1, @@ -92,7 +93,8 @@ typedef struct OnMsg lbuf:1, cbang:1, acchan:1, - supres:1; /* -- 21 bits */ + supres:1, /* -- 21 bits */ + noargf:1; /* -- 22 bits */ const char *cmdarg; } OnMsg; @@ -233,7 +235,7 @@ typedef struct Setting } v; char *name; int max; - void (*func)(const struct Setting *); + void (*onchangefunc)(const struct Setting *); } Setting; @@ -515,7 +517,6 @@ typedef struct Server int ident; int usenum; - int servergroup; int port; int err; time_t lastconnect; @@ -524,19 +525,11 @@ typedef struct Server char realname[NAMEBUF]; char name[NAMEBUF]; - char pass[PASSLEN]; + char pass[PASSBUF]; + char group[SERVERGROUPBUF]; } Server; -typedef struct ServerGroup -{ - struct ServerGroup *next; - - int servergroup; - char name[1]; - -} ServerGroup; - typedef struct FileMon { struct FileMon *next; diff --git a/src/tcl.c b/src/tcl.c index 6f020a3..b026986 100644 --- a/src/tcl.c +++ b/src/tcl.c @@ -99,7 +99,7 @@ char *tcl_var_read(Tcl_TVInfo *vinfo, Tcl_Interp *I, char *n1, char *n2, int fla rdata.i = (current) ? current->guid : -1; break; case TVINFO_nick: - rdata.c = (current) ? current->nick : "(undefined variable)"; + rdata.c = (current) ? getbotnick(current) : "(undefined variable)"; break; case TVINFO_wantnick: rdata.c = (current) ? current->wantnick : "(undefined variable)"; diff --git a/src/toybox.c b/src/toybox.c index 3f64098..151efe6 100644 --- a/src/toybox.c +++ b/src/toybox.c @@ -58,7 +58,7 @@ LS int triv_halt_flag; #endif /* TRIVIA */ -#define BIGSAY_DEFAULTFONT "default" +#define BIGSAY_DEFAULTFONT DEFAULTSTR #define FONT_EXTENSION ".bigchars" BigC *newchar; @@ -544,7 +544,7 @@ stop_trivia: triv_chan = NULL; triv_next_time = 0; triv_halt_flag = FALSE; - short_tv &= ~TV_TRIVIA; + cx.short_tv &= ~TV_TRIVIA; return; } @@ -1068,7 +1068,7 @@ void do_trivia(COMMAND_ARGS) triv_next_time = now + triv_qdelay; triv_weektop10 = now; lastwinner = NULL; - short_tv |= TV_TRIVIA; + cx.short_tv |= TV_TRIVIA; if (!scorelist) { read_triviascore(); diff --git a/src/uptime.c b/src/uptime.c index 495574e..91d018d 100644 --- a/src/uptime.c +++ b/src/uptime.c @@ -41,7 +41,7 @@ typedef struct uint32_t cookie; uint32_t uptime; uint32_t ontime; - uint32_t now; + uint32_t mytime; uint32_t sysup; } PackStub; @@ -54,7 +54,7 @@ typedef struct uint32_t cookie; uint32_t uptime; uint32_t ontime; - uint32_t now; + uint32_t mytime; uint32_t sysup; char string[512]; @@ -137,7 +137,7 @@ void send_uptime(int type) uptimecookie = (uptimecookie + 1) * 18457; upPack.cookie = htonl(uptimecookie); - upPack.now = htonl(now); + upPack.mytime = htonl(now); upPack.regnr = uptimeregnr; upPack.type = htonl(type); upPack.uptime = htonl(uptime); diff --git a/src/usage.h b/src/usage.h index 928eb9c..12a86b3 100644 --- a/src/usage.h +++ b/src/usage.h @@ -115,6 +115,9 @@ LS const UsageList ulist[] = #endif /* CTCP */ { C_QSHIT, " [reason]" }, #ifdef NOTE +#ifdef TOYBOX +{ C_RAND, "[#|#-#|# #|\"nick\"|\"luser\"]" }, +#endif /* TOYBOX */ { C_READ, "[-]" }, #endif /* NOTE */ { C_RESET, NULL }, @@ -137,7 +140,6 @@ LS const UsageList ulist[] = { C_SEND, "[to] " }, #endif /* DCC_FILE */ { C_SERVER, "[[+|-]servername] [port] [pass]" }, -{ C_SERVERGROUP,"[identifier]" }, { C_SET, "[channel|*] [setting [value]]" }, { C_SETPASS, " " }, { C_SHIT, " [expire] " }, diff --git a/src/vars.c b/src/vars.c index bb92186..c2377dd 100644 --- a/src/vars.c +++ b/src/vars.c @@ -257,7 +257,7 @@ void ec_set(char *from, const char *to) void ec_on(char *from, const char *to) { - nobo_strcpy(idle2str(now - current->ontime,FALSE)); + nobo_strcpy(idle2str(current->ontime,FALSE)); } void ec_server(char *from, const char *to) @@ -274,7 +274,7 @@ void ec_server(char *from, const char *to) void ec_up(char *from, const char *to) { - nobo_strcpy(idle2str(now - uptime,FALSE)); + nobo_strcpy(idle2str(uptime,FALSE)); } void ec_ver(char *from, const char *to) @@ -594,6 +594,9 @@ num_data_ok: } to_user(from,"Var: %s On: %s Set to: %s",VarName[which].name, (which >= CHANSET_SIZE) ? "(global)" : channel,(*rest) ? rest : NULLSTR); - if (VarName[which].func) - VarName[which].func(&VarName[which]); + /* + * if there is an onchange function + */ + if (VarName[which].onchangefunc) + VarName[which].onchangefunc(&VarName[which]); } diff --git a/src/web.c b/src/web.c index 533b664..e2cca93 100644 --- a/src/web.c +++ b/src/web.c @@ -165,7 +165,7 @@ restart: client->echan = (client->ebot) ? client->ebot->chanlist : NULL; break; case 'b': - src = (client->ebot) ? client->ebot->nick : (char*)NULLSTR; + src = (client->ebot) ? getbotnick(client->ebot) : (char*)NULLSTR; while(*src) { NOBO; @@ -328,7 +328,7 @@ void web_botstatus(WebSock *client, char *url) "

EnergyMech Status

\r\n" "Uptime: %s

\r\n" "Current bots:
\r\n", - idle2str(now - uptime,FALSE)); + idle2str(uptime,FALSE)); for(;bot;bot=bot->next) {