void do_signal(int sig) { switch (sig) { case SIGHUP: tell_chans("SIGHUP received!"); rehash(); return; case SIGINT: case SIGQUIT: case SIGTERM: me.crashing = 1; write_db(0); if (me.servtype == SERV_IRCNN) toserv(":%s OPERWALL :services terminating!\r\n", me.sclients[OS].nick, sig); else toserv(":%s OPERWALL :services terminating!\r\n", me.servname, sig); toserv(":%s QUIT :bye!\r\n", me.sclients[OS].nick); fclose(me.logfd); close_all_connections(); exit(1); case SIGILL: case SIGTRAP: case SIGBUS: case SIGSEGV: case SIGSYS: signal(sig, SIG_DFL); if (me.crashing == 1) abort(); me.crashing = 1; toserv(":%s OPERWALL :\2ACK!\2 signal %d recieved!\r\n", me.servname, sig); kill(getpid(), sig); } }
void InitJupes() { struct Jupe *tmpjupe; char sendstr[MAXLINE + 1]; char **av; for (tmpjupe = JupeList; tmpjupe; tmpjupe = tmpjupe->next) { if (tmpjupe->isnick) { #ifdef DANCER ircsprintf(sendstr, "NICK %s 1 1 +i juped juped.com %s :%s\r\n", tmpjupe->name, Me.name, tmpjupe->reason ? tmpjupe->reason : "Jupitered Nickname"); #else /* collide the nickname */ ircsprintf(sendstr, "NICK %s 1 1 +i %s %s %s :%s\r\n", tmpjupe->name, JUPED_USERNAME, JUPED_HOSTNAME, Me.name, tmpjupe->reason ? tmpjupe->reason : "Jupitered Nickname"); #endif /* DANCER */ toserv("%s", sendstr); SplitBuf(sendstr, &av); AddClient(av); MyFree(av); } else { char *tptr; /* check for wildcards */ for (tptr = tmpjupe->name; *tptr != '\0' && !IsMWildChar(*tptr); tptr++) ; if (*tptr == '\0') { ircsprintf(sendstr, ":%s SERVER %s 2 :Juped: %s", Me.name, tmpjupe->name, tmpjupe->reason); toserv(":%s SQUIT %s :%s (%s)\r\n%s\r\n", Me.name, tmpjupe->name, tmpjupe->reason, tmpjupe->who, sendstr); SplitBuf(sendstr, &av); AddServer(5, av); MyFree(av); } } } } /* InitJupes() */
void join_channels(u_short nicknum) { channel *chan; u_short i; switch (me.servtype) { case SERV_IRCNN: switch (nicknum) { case CS: for (i = 0; me.chans[i]; i++) { toserv(":%s JOIN %s\r\n", me.sclients[CS].nick, me.chans[i]); hackops(me.chans[i], me.sclients[CS].nick); } break; case OS: for (i = 0; me.chans[i]; i++) { toserv(":%s JOIN %s\r\n", me.sclients[OS].nick, me.chans[i]); hackops(me.chans[i], me.sclients[OS].nick); } if (me.eob == 0) { tell_chans("\2[EOB]\2 Receiving burst from %s", me.hub->name); me.htmtime = time(NULL); } /* XXX - eskimo's lame services doesn't know what this channel is */ toserv(":%s JOIN # 1\r\n", me.sclients[OS].nick); hackops("#", me.sclients[OS].nick); toserv(":%s MODE # +b *!*@*\r\n", me.sclients[OS].nick); toserv(":%s MODE # +inmsl 1\r\n", me.sclients[OS].nick); /* XXX - reaper sux */ toserv(":%s JOIN #debug 1\r\n", me.sclients[OS].nick); servmode("#debug", me.sclients[OS].nick); toserv(":%s MODE #debug +b *!*@*\r\n", me.sclients[OS].nick); toserv(":%s MODE #debug +inmsl 1\r\n", me.sclients[OS].nick); break; default: return; } break; case SERV_HYBRD: /* :h6.wiz.cx SJOIN 1021703401 #stuff +tn :@wiz6 */ if (nicknum != CS && nicknum != OS) break; for (i = 0; me.chans[i]; i++) if ((chan = find_channel(me.chans[i]))) { toserv(":%s SJOIN %lu %s + :@%s\r\n", me.servname, chan->ts, me.chans[i], me.sclients[nicknum].nick); add_user_to_channel(find_client(me.sclients[nicknum].nick), find_channel(me.chans[i]), OP); } else { toserv(":%s SJOIN %lu %s + :@%s\r\n", me.servname, time(NULL), me.chans[i], me.sclients[nicknum].nick); add_user_to_channel(find_client(me.sclients[nicknum].nick), add_channel(me.chans[i], time(NULL), 0), OP); } break; } }
void SetModes(char *source, int plus, char mode, struct Channel *chptr, char *args) { int acnt, mcnt, ii; char done[MAXLINE], sendstr[MAXLINE]; char **av, *temp, *mtmp; if (!source || !chptr || !args) return; temp = MyStrdup(args); acnt = SplitBuf(temp, &av); memset(&done, 0, MAXLINE); mcnt = 1; for (ii = 0; ii < acnt; ii++) { strcat(done, av[ii]); /* Rewrote this to fix that nasty " " at the end of done[] -kre */ if (mcnt != MaxModes) strcat(done, " "); else { mcnt = 0; mtmp = modestr(MaxModes, mode); ircsprintf(sendstr, "%s%s %s", plus ? "+" : "-", mtmp, done); toserv(":%s MODE %s %s\n", source, chptr->name, sendstr); UpdateChanModes(0, source, chptr, sendstr); MyFree(mtmp); memset(&done, 0, MAXLINE); } mcnt++; } if (done[0] != '\0') { mtmp = modestr(mcnt - 1, mode); ircsprintf(sendstr, "%s%s %s", plus ? "+" : "-", mtmp, done); toserv(":%s MODE %s %s\n", source, chptr->name, sendstr); UpdateChanModes(0, source, chptr, sendstr); MyFree(mtmp); } MyFree(temp); MyFree(av); } /* SetModes() */
int m_admin(user_t *cptr, int parc, char **parv) { if (!cptr) return 0; sendto_admins("admin requested by %s (%s@%s) [%s]", cptr->nick, cptr->username, cptr->host, cptr->server->nick); toserv(":%s 256 %s :Administrative contact for %s:\r\n", me.servname, parv[0], me.servname); toserv(":%s 257 %s :%s\r\n", me.servname, parv[0], VER_STR); toserv(":%s 258 %s :written and maintained by:\r\n", me.servname, parv[0]); toserv(":%s 259 %s :%s\r\n", me.servname, parv[0], MYEMAIL); return 1; }
int m_version(user_t *cptr, int parc, char **parv) { if (cptr) toserv(":%s 351 %s zorak-services(%s) :%s TS3\r\n", me.servname, cptr->nick, SERIALNUM, me.servname); return 1; }
void jupe(char *name, char *reason) { user_t *sptr = find_client(name); if (sptr && IsServer(sptr)) squit(sptr->nick, "JUPED"); add_linked_server(me.servname, name, reason); switch (me.servtype) { case SERV_IRCNN: toserv(":%s SERVER %s 2 %lu %lu P09 :%s\r\n", me.servname, name, time(NULL), time(NULL) + 1, reason); break; case SERV_HYBRD: toserv(":%s SERVER %s 1 :%s\r\n", me.servname, name, reason); break; } }
int m_eob(user_t *cptr, int parc, char **parv) { toserv(":%s EOB\r\n", me.servname); tell_chans("\2[EOB]\2 End of burst (took %d seconds)", time(NULL) - me.htmtime); me.eob = 1; return 1; }
void intro_nicks(u_short nicknum) { short i = nicknum; if (i == ALL) i--; switch (me.servtype) { case SERV_IRCNN: for (; i >= 0; i--) { toserv(":%s NICK %s 1 %lu %s %s %s :%s\r\n", me.servname, me.sclients[i].nick, time(NULL), me.sclients[i].username, me.servname, me.servname, me.sclients[i].realname); toserv(":%s MODE %s :+ko\r\n", me.sclients[i].nick, me.sclients[i].nick); me.opers++; add_user(me.sclients[i].nick, me.sclients[i].username, me.servname, me.sclients[i].realname, me.servname, NOKILL); /* XXX - lame services will kill operserv2 if not identified */ if (i == OS) toserv(":%s PRIVMSG NickServ :identify abcd123\r\n", me.sclients[i].nick); if (nicknum != ALL) break; } break; case SERV_HYBRD: for (; i >= 0; i--) { /* NICK wiz6 1 1021703400 +iw jason rr.wiz.cx h6.wiz.cx :monkey mushroom */ toserv(":%s NICK %s 1 %lu +omw %s %s %s :%s\r\n", me.servname, me.sclients[i].nick, time(NULL), me.sclients[i].username, me.servname, me.servname, me.sclients[i].realname); add_user(me.sclients[i].nick, me.sclients[i].username, me.servname, me.sclients[i].realname, me.servname, NOKILL); me.htmtime = time(NULL); if (me.eob == 1) join_channels(i); if (nicknum != ALL) break; } break; } }
void DoMode(struct Channel *chptr, char *modes, int joinpart) { #ifdef SAVE_TS struct Chanlist *chanptr; #endif if (!chptr || !modes) return; #ifdef SAVE_TS chanptr = IsChannel(chptr->name); #ifndef HYBRID_ONLY /* no need to join on hybrid */ if (joinpart && !chanptr) /* make sure its not already a monitored channel */ os_join(chptr); #endif toserv(":%s MODE %s %s\n", n_OperServ, chptr->name, modes); UpdateChanModes(Me.osptr, n_OperServ, chptr, modes); #ifndef HYBRID_ONLY if (joinpart && !chanptr) os_part(chptr); #endif #else toserv(":%s MODE %s %s\n", Me.name, chptr->name, modes); UpdateChanModes(0, Me.name, chptr, modes); #endif /* SAVE_TS */ } /* DoMode() */
/* * signon() * * args: none * purpose: send the PASS / CAPAB / SERVER handshake * return: none */ void signon(void) { /* Hybrid6 and 7 handshake -kre */ #ifdef HYBRID_ONLY toserv("PASS %s :TS\r\nCAPAB :EX" #ifdef DANCER " DNCR SRV" #endif /* DANCER */ #ifdef GECOSBANS /* Send gecosbans capab -Janos */ " DE" #endif /* GECOSBANS */ #ifdef HYBRID7 /* Send most of Hybrid7 CAPABS -kre && Janos */ " KLN GLN HOPS IE HUB AOPS" #endif /* HYBRID7 */ "\r\n", currenthub->password); #endif /* HYBRID_ONLY */ toserv("SERVER %s 1 :%s\r\n", Me.name, Me.info); } /* signon() */
void ping_hub(void) { if (me.conn != 1) return; if (me.hub->last + SERVTIMEOUT <= time(NULL)) { log("HUB: %s is not responding!", me.hub->name); alldcc("HUB: %s is not responding!", me.hub->name); del_sock(NULL); } else { toserv(":%s PING :%s\r\n", me.servname, me.servname); } }
int m_kick(user_t *cptr, int parc, char **parv) { channel *chan; user_t *kptr; u_short snick; if (parc < 3 || !(chan = find_channel(parv[1])) || !(kptr = find_client(parv[2]))) return 0; if ((snick = is_services_client(parv[2])) > 0) { switch (me.servtype) { case SERV_IRCNN: toserv(":%s JOIN %s\r\n", me.sclients[snick].nick, chan->name); hackops(chan->name, me.sclients[snick].nick); break; case SERV_HYBRD: toserv(":%s SJOIN %lu %s + :@%s\r\n", me.servname, chan->ts, chan->name, me.sclients[snick].nick); break; } return 1; } return del_user_from_channel(kptr, chan); }
void KickBan(int ban, char *source, struct Channel *channel, char *nicks, char *reason) { char *mask, *tempnix, **av, *bans; char temp[MAXLINE]; int ac, ii; struct Luser *lptr; if (!source || !channel || !nicks) return; tempnix = MyStrdup(nicks); ac = SplitBuf(tempnix, &av); if (ban) { bans = (char *) MyMalloc(sizeof(char)); bans[0] = '\0'; for (ii = 0; ii < ac; ii++) { if (!(lptr = FindClient(av[ii]))) continue; mask = HostToMask(lptr->username, lptr->hostname); ircsprintf(temp, "*!%s", mask); bans = (char *) MyRealloc(bans, strlen(bans) + strlen(temp) + (2 * sizeof(char))); strcat(bans, temp); strcat(bans, " "); MyFree(mask); } SetModes(source, 1, 'b', channel, bans); MyFree(bans); } for (ii = 0; ii < ac; ii++) { toserv(":%s REMOVE %s %s :%s\n", source, channel->name, av[ii], reason ? reason : ""); RemoveFromChannel(channel, FindClient(av[ii])); } MyFree(tempnix); MyFree(av); } /* KickBan() */
int m_ping(user_t *cptr, int parc, char **parv) { if (cptr) toserv(":%s PONG %s :%s\r\n", me.servname, me.servname, cptr->nick); else toserv("PONG :%s\r\n", parv[1]); /* XXX this is all shitty code */ if (me.gotping == 0) me.gotping = 1; if (!me.eob && me.servtype == SERV_HYBRD) m_eob(NULL, 0, NULL); if (me.settime < time(NULL)) { tell_chans("syncronizing servers' clocks..."); settime(); me.settime = time(NULL) + (60*60*4); } if (me.lifesux && me.htmtime && me.htmtime <= time(NULL)) { tell_chans("\2[HTM]\2 resuming normal operation...."); me.lifesux = 0; me.htmtime = time(NULL); } return 1; }
void FakeServer(char *serv, char *reason) { char **arv, sendstr[MAXLINE + 1]; int arc; ircsprintf(sendstr, ":%s SERVER %s 2 :Juped: %s\r\n", Me.name, serv, reason); toserv("%s", sendstr); arc = SplitBuf(sendstr, &arv); AddServer(arc, arv); MyFree(arv); }
void DoJupeSquit(char *serv, char *reason, char *who) { struct Server *tempserv, *prev; char *servptr; int nowild; /* check for wildcards */ for (servptr = serv; *servptr != '\0' && !IsMWildChar(*servptr); servptr++) ; nowild = (*servptr == '\0'); for (tempserv = ServerList; tempserv; ) { if (match(serv, tempserv->name)) { /* squit the server */ toserv("SQUIT %s :Juped: %s (%s)\r\n", tempserv->name, reason, who); prev = tempserv->next; DeleteServer(tempserv); /* remove server from list */ tempserv = prev; /* If the fake server is introduced before the remote server has quited, * we get "server already exists" and services get SQUIT'ed, * so we'll introduce it in s_squit() */ if (nowild) return; } else tempserv = tempserv->next; } /* we don't want to introduce servers such as "irc.*" */ if (nowild) FakeServer(serv, reason); } /* DoJupeSquit() */
int m_motd(user_t *cptr, int parc, char **parv) { u_short i = 0; sendto_admins("motd requested by %s (%s@%s) [%s]", cptr->nick, cptr->username, cptr->host, cptr->server->nick); toserv(":%s 375 %s :- %s is running %s by %s\r\n", me.servname, parv[0], me.servname, VER_STR, MYEMAIL); toserv(":%s 372 %s :-\r\n", me.servname, cptr->nick); toserv(":%s 372 %s :- The following services are ready to take your order:\r\n", me.servname, cptr->nick); while (++i < ALL) if (i != OS && IsOper(cptr)) toserv(":%s 372 %s :- /msg %s help\r\n", me.servname, cptr->nick, me.sclients[i].nick); toserv(":%s 372 %s :-\r\n", me.servname, cptr->nick); toserv(":%s 376 %s :End of MOTD command\r\n", me.servname, parv[0]); return 1; }
int m_whois(user_t *cptr, int parc, char **parv) { user_t *who; if (!(who = find_client(parv[2]))) { toserv(":%s 401 %s %s :No such nick/channel\r\n", me.servname, parv[0], parv[2]); return 0; } toserv(":%s 311 %s %s %s %s * :%s\r\n", me.servname, parv[0], who->nick, who->username, who->host, who->realname); if (cptr && IsOper(cptr)) toserv(":%s 312 %s %s %s :%s\r\n", me.servname, parv[0], who->nick, who->server->nick, who->server->realname); else toserv(":%s 312 %s %s %s :%s\r\n", me.servname, parv[0], who->nick, me.servname, me.servdesc); if (IsOper(who)) toserv(":%s 313 %s %s :is being synflooded (IRC Operator)\r\n", me.servname, parv[0], who->nick); else if (is_services_client(who->nick)) toserv(":%s 313 %s %s :is an official services client\r\n", me.servname, parv[0], who->nick); if (is_me(who->server->nick)) toserv(":%s 317 %s %s %lu %lu :seconds idle, signon time\r\n", me.servname, parv[0], who->nick, time(NULL) - who->ts, who->ts); toserv(":%s 318 %s %s :End of /WHOIS list.\r\n", me.servname, parv[0], who->nick); return 1; }
void DoPings() { struct Server *tempserv; struct timeval timer; GetTime(&timer); for (tempserv = ServerList; tempserv; tempserv = tempserv->next) { /* * Do not ping services itself, or any juped servers * services is hubbing */ if ((!(tempserv->flags & SERV_MYHUB) && (tempserv->uplink == Me.sptr)) || (tempserv == Me.sptr)) continue; if (tempserv->lastping_sec || tempserv->lastping_usec) { /* * We still have not received their reply from the last * time we pinged them - don't ping them again until we * do. */ continue; } /* * Record the TS of when we're pinging them */ tempserv->lastping_sec = timer.tv_sec; tempserv->lastping_usec = timer.tv_usec; toserv(":%s PING %s :%s\r\n", Me.name, Me.name, tempserv->name); } } /* DoPings() */
void CheckJupes() { struct Server *tempserv, *next; if (!Me.sptr) return; for (tempserv = ServerList; tempserv; ) { /* * Make sure tempserv is using us as an uplink, which * would qualify it as a pseudo-server. But also make * sure it's not OUR current hub server - we never * want to squit our hub. */ if ((tempserv->uplink == Me.sptr) && (Me.hub != tempserv)) { /* * We found a server who has us as a hub - check if there * is a J: line for it */ if (!IsJupe(tempserv->name)) { toserv("SQUIT %s :Unjuped\r\n", tempserv->name); next = tempserv->next; DeleteServer(tempserv); tempserv = next; } else tempserv = tempserv->next; } else tempserv = tempserv->next; } } /* CheckJupes() */
void UpdateChanModes(struct Luser *lptr, char *who, struct Channel *cptr, char *modes) { int add; char *tmp, *p; register char ch; struct Luser *userptr; #if defined(NICKSERVICES) && defined(CHANNELSERVICES) int cs_deoped = 0; /* was chanserv deoped? */ #endif char **modeargs; /* arguements to +l/k/o/v modes */ char tempargs[MAXLINE]; int argcnt; /* number of arguements */ int argidx; /* current index in modeargs[] */ #ifndef SAVE_TS char sendstr[MAXLINE]; #endif if (!cptr) return; assert(lptr || who); if (lptr) { SendUmode(OPERUMODE_M, "*** %s: Mode [%s] by %s!%s@%s", cptr->name, modes, lptr->nick, lptr->username, lptr->hostname); putlog(LOG3, "%s: mode change \"%s\" by %s!%s@%s", cptr->name, modes, lptr->nick, lptr->username, lptr->hostname); } else { SendUmode(OPERUMODE_M, "*** %s: Mode [%s] by %s", cptr->name, modes, who); putlog(LOG3, "%s: mode change \"%s\" by %s", cptr->name, modes, who); } if ((tmp = strchr(modes, ' '))) strcpy(tempargs, *(tmp + 1) ? tmp + 1 : ""); else tempargs[0] = '\0'; argcnt = SplitBuf(tempargs, &modeargs); /* * This routine parses the given channel modes and keeps * the corresponding lists correctly updated - also make * sure OperServ and ChanServ remain opped */ add = 0; argidx = (-1); for (tmp = modes; *tmp; ++tmp) { ch = *tmp; if (IsSpace(ch)) break; switch (ch) { case ' ': case '\n': case '\r': break; case '-': { add = 0; break; } case '+': { add = 1; break; } /* * Op/DeOp */ case 'o': { ++argidx; if (argidx >= argcnt) { /* * there are more 'o' flags than there are nicknames, * just break */ break; } if (!(userptr = FindClient(modeargs[argidx]))) break; SetChannelMode(cptr, add, MODE_O, userptr, 0); if (add) { #ifdef STATSERVICES if (lptr) ++lptr->numops; #endif } /* if (add) */ else { if (userptr == Me.osptr) { if (!FloodCheck(cptr, lptr, Me.osptr, 0)) { #ifdef SAVE_TS os_part(cptr); os_join(cptr); #else toserv(":%s MODE %s +o %s\n", n_OperServ, cptr->name, n_OperServ); #endif } if (!lptr) { putlog(LOG1, "%s: %s attempted to deop %s", cptr->name, who, n_OperServ); } else { putlog(LOG1, "%s: %s!%s@%s attempted to deop %s", cptr->name, lptr->nick, lptr->username, lptr->hostname, n_OperServ); } } #if defined(NICKSERVICES) && defined(CHANNELSERVICES) else if (userptr == Me.csptr) { cs_deoped = 1; } #endif /* defined(NICKSERVICES) && defined(CHANNELSERVICES) */ #ifdef STATSERVICES if (lptr) ++lptr->numdops; #endif } /* else if (!add) */ #if defined(NICKSERVICES) && defined(CHANNELSERVICES) cs_CheckModes(lptr, FindChan(cptr->name), !add, MODE_O, userptr); #endif break; } /* case 'o' */ /* * Voice/DeVoice */ case 'v': { ++argidx; if (argidx >= argcnt) break; if (!(userptr = FindClient(modeargs[argidx]))) break; SetChannelMode(cptr, add, MODE_V, userptr, 0); if (add) { #ifdef STATSERVICES if (lptr) ++lptr->numvoices; #endif } else { #ifdef STATSERVICES if (lptr) ++lptr->numdvoices; #endif } /* else if (!add) */ #if defined(NICKSERVICES) && defined(CHANNELSERVICES) cs_CheckModes(lptr, FindChan(cptr->name), !add, MODE_V, userptr); #endif break; } /* case 'v' */ #ifdef HYBRID7 /* HalfOp/DeHalfOp -Janos */ case 'h': { ++argidx; if (argidx >= argcnt) break; if (!(userptr = FindClient(modeargs[argidx]))) break; SetChannelMode(cptr, add, MODE_H, userptr, 0); if (add) { #ifdef STATSERVICES if (lptr) ++lptr->numhops; #endif } else { #ifdef STATSERVICES if (lptr) ++lptr->numdhops; #endif } /* else if (!add) */ #if defined(NICKSERVICES) && defined(CHANNELSERVICES) cs_CheckModes(lptr, FindChan(cptr->name), !add, MODE_H, userptr); #endif break; } /* case 'h'*/ #endif /* HYBRID7 */ /* * Channel limit */ case 'l': { if (add) { ++argidx; if (argidx >= argcnt) break; cptr->limit = atoi(modeargs[argidx]); } else cptr->limit = 0; #if defined(NICKSERVICES) && defined(CHANNELSERVICES) cs_CheckModes(lptr, FindChan(cptr->name), !add, MODE_L, 0); #endif break; } /* case 'l' */ /* * Channel key */ case 'k': { ++argidx; if (argidx >= argcnt) break; #ifndef BLOCK_ALLOCATION if (cptr->key) MyFree(cptr->key); #endif if (add) { #ifdef BLOCK_ALLOCATION strncpy(cptr->key, modeargs[argidx], KEYLEN); cptr->key[KEYLEN] = '\0'; #else cptr->key = MyStrdup(modeargs[argidx]); #endif /* BLOCK_ALLOCATION */ } else { #ifdef BLOCK_ALLOCATION cptr->key[0] = '\0'; #else cptr->key = 0; #endif /* BLOCK_ALLOCATION */ } #if defined(NICKSERVICES) && defined(CHANNELSERVICES) cs_CheckModes(lptr, FindChan(cptr->name), !add, MODE_K, 0); #endif break; } /* case 'k' */ /* * Channel forwarding target */ case 'f': { ++argidx; if (argidx >= argcnt) break; #ifndef BLOCK_ALLOCATION if (cptr->forward) MyFree(cptr->forward); #endif if (add) { #ifdef BLOCK_ALLOCATION strncpy(cptr->forward, modeargs[argidx], CHANNELLEN); cptr->forward[CHANNELLEN] = '\0'; #else cptr->forward = MyStrdup(modeargs[argidx]); #endif /* BLOCK_ALLOCATION */ } else { #ifdef BLOCK_ALLOCATION cptr->forward[0] = '\0'; #else cptr->forward = 0; #endif /* BLOCK_ALLOCATION */ } #if defined(NICKSERVICES) && defined(CHANNELSERVICES) cs_CheckModes(lptr, FindChan(cptr->name), !add, MODE_F, 0); #endif break; } /* case 'f' */ /* * Channel ban */ case 'b': { ++argidx; if (argidx >= argcnt) break; /* if it's a forwarding ban like nick!ident@host!#channel * just drop the forward channel * found by CheeToS -- jilles */ p = strchr(modeargs[argidx], '!'); if (p != NULL) { p = strchr(p + 1, '!'); if (p != NULL) *p = '\0'; } if (add) AddBan(who, cptr, modeargs[argidx]); else DeleteBan(cptr, modeargs[argidx]); if (p != NULL) *p = '!'; break; } /* case 'b' */ #ifdef GECOSBANS /* * Channel deny */ case 'd': { ++argidx; if (argidx >= argcnt) break; if (add) AddGecosBan(who, cptr, modeargs[argidx]); else DeleteGecosBan(cptr, modeargs[argidx]); break; } /* case 'd' */ #endif /* GECOSBANS */ /* * Channel exception */ case 'e': { ++argidx; if (argidx >= argcnt) break; if (add) AddException(who, cptr, modeargs[argidx]); else DeleteException(cptr, modeargs[argidx]); break; } /* case 'e' */ #ifdef HYBRID7 /* Channel invite exception -Janos */ case 'I': { ++argidx; if (argidx >= argcnt) break; if (add) AddInviteException(who, cptr, modeargs[argidx]); else DeleteInviteException(cptr, modeargs[argidx]); break; } /* case 'I' */ #endif /* HYBRID7 */ default: { int modeflag = 0; if (ch == 's') modeflag = MODE_S; else if (ch == 'p') modeflag = MODE_P; else if (ch == 'n') modeflag = MODE_N; else if (ch == 't') modeflag = MODE_T; else if (ch == 'm') modeflag = MODE_M; else if (ch == 'i') modeflag = MODE_I; else if (ch == 'r') modeflag = MODE_R; else if (ch == 'z') modeflag = MODE_Z; else if (ch == 'P') modeflag = MODE_CAPP; #if 0 /* doesn't exist in 1.0.34 */ else if (ch == 'F') modeflag = MODE_CAPF; #endif else if (ch == 'Q') modeflag = MODE_CAPQ; #ifdef HYBRID7 else if (ch == 'a') modeflag = MODE_A; #endif else if (ch == 'c') modeflag = MODE_C; else if (ch == 'g') modeflag = MODE_G; else if (ch == 'L') modeflag = MODE_CAPL; else if (ch == 'R') modeflag = MODE_CAPR; if (modeflag) { if (add) cptr->modes |= modeflag; else cptr->modes &= ~modeflag; } #if defined(NICKSERVICES) && defined(CHANNELSERVICES) if (modeflag) cs_CheckModes(lptr, FindChan(cptr->name), !add, modeflag, 0); #endif break; } /* default: */ } /* switch (*tmp) */ } /* for (tmp = modes; *tmp; ++tmp) */ MyFree(modeargs); #if defined(NICKSERVICES) && defined(CHANNELSERVICES) if ((cs_deoped) && (!FloodCheck(cptr, lptr, Me.csptr, 0))) { /* reop ChanServ */ #ifdef SAVE_TS cs_part(cptr); cs_join(FindChan(cptr->name)); #else toserv(":%s MODE %s +o %s\n", n_ChanServ, cptr->name, n_ChanServ); #endif if (!lptr) putlog(LOG1, "%s: %s attempted to deop %s", cptr->name, who, n_ChanServ); else putlog(LOG1, "%s: %s!%s@%s attempted to deop %s", cptr->name, lptr->nick, lptr->username, lptr->hostname, n_ChanServ); } #endif /* defined(NICKSERVICES) && defined(CHANNELSERVICES) */ } /* UpdateChanModes() */
int CheckJuped(char *name) { struct Jupe *tempjupe; struct Server *tempserv; char sendstr[MAXLINE + 1], **arv; for (tempjupe = JupeList; tempjupe; tempjupe = tempjupe->next) { if (match(tempjupe->name, name)) { if (tempjupe->isnick) { struct Luser *lptr; if (!(lptr = FindClient(name))) return 0; /* its a nick jupe, not a server jupe */ #ifdef DANCER ircsprintf(sendstr, "NICK %s 1 %ld +i juped juped.com %s %lu :%s\r\n", tempjupe->name, #ifdef NICKSERVICES (long) (lptr->nick_ts - 1), #else (long) (lptr->since - 1), #endif /* NICKSERVICES */ Me.name, 0xffffffffL, tempjupe->reason ? tempjupe->reason : "Jupitered Nickname"); #else /* collide the nickname */ ircsprintf(sendstr, "NICK %s 1 %ld +i %s %s %s :%s\r\n", tempjupe->name, #ifdef NICKSERVICES (long) (lptr->nick_ts - 1), #else (long) (lptr->since - 1), #endif /* NICKSERVICES */ JUPED_USERNAME, JUPED_HOSTNAME, Me.name, tempjupe->reason ? tempjupe->reason : "Jupitered Nickname"); #endif /* DANCER */ toserv("%s", sendstr); DeleteClient(lptr); SplitBuf(sendstr, &arv); AddClient(arv); MyFree(arv); if (Me.sptr) Me.sptr->numoperkills++; Network->TotalOperKills++; #ifdef STATSERVICES if (Network->TotalOperKills > Network->OperKillsT) Network->OperKillsT = Network->TotalOperKills; #endif } else { toserv("SQUIT %s :Juped: %s (%s)\r\n", name, tempjupe->reason, tempjupe->who); tempserv = FindServer(name); DeleteServer(tempserv); /* If the fake server is introduced before the remote server has quited, * we get "server already exists" and services get SQUIT'ed, * so we'll introduce it in s_squit() */ } return 1; } } return 0; } /* CheckJuped */
void io_loop(void) { int r, i, errv, errlen = sizeof(errv); struct timeval tv = { 1, 0 }; struct sockaddr_in sin; size_t ssin = sizeof(sin); char buffer[BUFSIZE]; sock_t *sock, *tmp; memset(buffer, 0, BUFSIZE); loop: /* wiz is leet */ FD_ZERO(&me.readfds); FD_ZERO(&me.writefds); for (sock = main_sock; sock;) { if (sock->flags & SOCK_DEL) { tmp = sock->next; del_sock(sock); sock = tmp; continue; } if (sock->flags & (SOCK_LISTEN|SOCK_CONN)) FD_SET(sock->socket, &me.readfds); else FD_SET(sock->socket, &me.writefds); sock = sock->next; } while ((r = select(FD_SETSIZE, &me.readfds, &me.writefds, NULL, &tv)) == -1) if (errno != EINTR) { log("FATAL! select() == -1: %s", ERR); exit(1); } do_events(time(NULL)); for (sock = main_sock; r > 0 && sock;) { if (FD_ISSET(sock->socket, &me.readfds) && r--) { if (sock->flags & SOCK_LISTEN) { memset(&sin, 0, sizeof(sin)); if ((i = accept(sock->socket, (struct sockaddr *)&sin, &ssin)) == -1) goto nextsock; log("NET: connection from %s:%d", inet_ntoa(sin.sin_addr), ntohs(sin.sin_port)); tmp = add_sock_to_list(); if ((tmp->socket = nonblock_sock(i)) == -1) { del_sock(tmp); goto nextsock; } else if (!(tmp->fd = fdopen(tmp->socket, "r"))) { log("fdopen(%d) failed: %s", tmp->socket, strerror(errno)); del_sock(tmp); goto nextsock; } tmp->conn = time(NULL); tmp->addr = sin.sin_addr; tmp->port = ntohs(sin.sin_port); tmp->buffer = leetcalloc(BUFSIZE, 1); tmp->flags |= (SOCK_CONN|sock->flags); tmp->flags &= ~SOCK_LISTEN; greet_dcc(tmp); goto nextsock; } if (!fgets(sock->buffer, BUFSIZE, sock->fd)) { errv = 0; if (getsockopt(sock->socket, SOL_SOCKET, SO_ERROR, &errv, &errlen) < 0) { log("NET: getsockopt(SO_ERROR) failed: %s", ERR); goto delsock; } goto readerr; } sock->last = time(NULL); for(i = 0; i < BUFSIZE; i++) if (sock->buffer[i] == '\r' || sock->buffer[i] == '\n') sock->buffer[i] = 0; if (sock->flags & SOCK_HUB) parse(sock->buffer); else if (sock->flags & (SOCK_DCC|SOCK_TELNET)) parse_dcc(sock, sock->buffer); memset(sock->buffer, 0, BUFSIZE); } else if (FD_ISSET(sock->socket, &me.writefds) && r--) { errv = 0; if (getsockopt(sock->socket, SOL_SOCKET, SO_ERROR, &errv, &errlen) < 0) { log("NET: getsockopt(SO_ERROR) failed: %s", ERR); goto delsock; } if (errv > 0) { if (sock->flags & SOCK_HUB) { log("HUB: error connecting to %s: %s", sock->name, strerror(errv)); alldcc("HUB: error connecting to %s: %s", sock->name, strerror(errv)); #if 0 } else if (sock->flags & SOCK_DCC && find_client(sock->name)) reply(OS, sock->name, "Error DCC connecting: %s", strerror(errv)); #else } #endif goto delsock; } if (sock->flags & SOCK_HUB) { log("HUB: connected to %s", sock->name); alldcc("HUB: connected to %s", sock->name); del_event_func(&try_next_hub); sock->conn = time(NULL); me.conn = 1; switch (me.servtype) { case SERV_IRCNN: toserv("PASS :%s\r\n", servpass); toserv("SERVER %s 1 %lu %lu J09 :%s\r\n", me.servname, time(NULL), time(NULL), me.servdesc); add_linked_server(me.servname, me.servname, me.servdesc); intro_nicks(ALL); join_channels(OS); break; case SERV_HYBRD: toserv("CAPAB :QS EX IE EOB UNKLN KLN HOPS HUB TBURST\r\n"); toserv("PASS %s :TS\r\n", servpass); toserv("SERVER %s 0 :%s\r\n", me.servname, me.servdesc); toserv("SVINFO 5 5 0 :%lu\r\n", time(NULL)); add_linked_server(me.servname, me.servname, me.servdesc); break; } } else if (sock->flags & SOCK_DCC) { log("DCC: %s connected from %s:%d", sock->name, inet_ntoa(sock->addr), sock->port); me.dcc++; } sock->flags |= SOCK_CONN; } nextsock: { sock = sock->next; continue; } readerr: { log("NET: read error from %s: %s", (sock->name ? sock->name : inet_ntoa(sock->addr)), strerror(errv)); } delsock: { sock->flags |= SOCK_DEL; goto nextsock; } }
struct Luser * AddClient(char **line) { char *ch; struct Luser *tempuser, *newptr; #ifdef BLOCK_ALLOCATION tempuser = (struct Luser *) BlockSubAllocate(ClientHeap); if (!tempuser) /* shouldn't happen - but I'm paranoid :) */ return (NULL); memset(tempuser, 0, sizeof(struct Luser)); strlcpy(tempuser->nick, line[1], NICKLEN + 1); strlcpy(tempuser->username, line[5], USERLEN + 1); strlcpy(tempuser->hostname, line[6], HOSTLEN + 1); strlcpy(tempuser->realname, line[8] + 1, REALLEN + 1); #else tempuser = (struct Luser *) MyMalloc(sizeof(struct Luser)); memset(tempuser, 0, sizeof(struct Luser)); tempuser->nick = MyStrdup(line[1]); tempuser->username = MyStrdup(line[5]); tempuser->hostname = MyStrdup(line[6]); tempuser->realname = MyStrdup(line[8] + 1); #endif /* BLOCK_ALLOCATION */ tempuser->since = atol(line[3]); #ifdef NICKSERVICES tempuser->nick_ts = tempuser->since; #if defined SVSNICK || defined FORCENICK tempuser->flags &= ~(UMODE_NOFORCENICK); #endif #endif /* NICKSERVICES */ if ((tempuser->server = FindServer(line[7]))) { tempuser->server->numusers++; #ifdef STATSERVICES if (tempuser->server->numusers > tempuser->server->maxusers) { tempuser->server->maxusers = tempuser->server->numusers; tempuser->server->maxusers_ts = current_ts; } #endif } ch = &line[4][1]; while (*ch) { switch (*ch) { case 'i': case 'I': { tempuser->umodes |= UMODE_I; break; } case 's': case 'S': { tempuser->umodes |= UMODE_S; break; } case 'w': case 'W': { tempuser->umodes |= UMODE_W; break; } case 'o': case 'O': { tempuser->umodes |= UMODE_O; Network->TotalOperators++; #ifdef STATSERVICES if (Network->TotalOperators > Network->MaxOperators) { Network->MaxOperators = Network->TotalOperators; Network->MaxOperators_ts = current_ts; if ((Network->MaxOperators % 5) == 0) { /* inform +y people of new max oper count */ SendUmode(OPERUMODE_Y, "*** New Max Operator Count: %ld", Network->MaxOperators); putlog(LOG2, "New Max Operator Count: %ld", Network->MaxOperators); } } if (Network->TotalOperators > Network->MaxOperatorsT) { Network->MaxOperatorsT = Network->TotalOperators; Network->MaxOperatorsT_ts = current_ts; } #endif if (tempuser->server) { tempuser->server->numopers++; #ifdef STATSERVICES if (tempuser->server->numopers > tempuser->server->maxopers) { tempuser->server->maxopers = tempuser->server->numopers; tempuser->server->maxopers_ts = current_ts; } #endif } break; } /* case 'O' */ #ifdef DANCER case 'e': case 'E': { struct NickInfo *realptr; realptr = FindNick(tempuser->nick); if (realptr) { realptr->flags |= NS_IDENTIFIED; tempuser->umodes |= UMODE_E; RecordCommand("User %s has +e umode, marking as identified", tempuser->nick); } else { /* Is it one of mine? */ int mine = 0; struct aService *sptr; for (sptr = ServiceBots; sptr->name; ++sptr) if (!irccmp(tempuser->nick, *(sptr->name))) { mine = 1; break; } if (!mine) { /* Blech, who is screwing with us? */ toserv(":%s MODE %s -e\r\n", Me.name, tempuser->nick); RecordCommand("User %s has +e umode but is not known to me, setting -e", tempuser->nick); } } break; } #endif /* DANCER */ default: break; } /* switch (*ch) */ ch++; } tempuser->next = ClientList; tempuser->prev = NULL; if (tempuser->next) tempuser->next->prev = tempuser; ClientList = tempuser; /* add client to the hash table */ newptr = HashAddClient(ClientList, 0); Network->TotalUsers++; #ifdef STATSERVICES if (Network->TotalUsers > Network->MaxUsers) { Network->MaxUsers = Network->TotalUsers; Network->MaxUsers_ts = current_ts; if ((Network->MaxUsers % 10) == 0) { /* notify +y people of new max user count */ SendUmode(OPERUMODE_Y, "*** New Max Client Count: %ld", Network->MaxUsers); putlog(LOG2, "New Max Client Count: %ld", Network->MaxUsers); } } if (Network->TotalUsers > Network->MaxUsersT) { Network->MaxUsersT = Network->TotalUsers; Network->MaxUsersT_ts = current_ts; } #endif /* STATSERVICES */ #ifdef ALLOW_GLINES /* * It's possible the client won't exist anymore, because if the user * is a clone and AutoKillClones is enabled, HashAddClient() would * have already killed the user, in which case newptr will be * NULL - CheckGlined() checks for null pointers */ CheckGlined(newptr); /* Check if new user is glined */ #endif return (tempuser); } /* AddClient() */
void UpdateUserModes(struct Luser *user, char *modes) { int PLUS = 1; int umode; unsigned int ii; if (!modes || !user) return; for (ii = 0; ii < strlen(modes); ii++) { if (modes[ii] == '+') { PLUS = 1; continue; } if (modes[ii] == '-') { PLUS = 0; continue; } umode = 0; if (modes[ii] == 'i') umode = UMODE_I; if (modes[ii] == 's') umode = UMODE_S; if (modes[ii] == 'w') umode = UMODE_W; if (modes[ii] == 'o') umode = UMODE_O; #ifdef DANCER if (modes[ii] == 'e') if (PLUS) { struct NickInfo* realptr = FindNick(user->nick); if (realptr) { realptr->flags |= NS_IDENTIFIED; RecordCommand("User %s has +e umode, marking as identified",user->nick); umode = UMODE_E; } else { /* Blech, who is screwing with us? */ toserv(":%s MODE %s -e\r\n", Me.name, user->nick); RecordCommand("User %s has +e umode but is not known to me, setting -e", user->nick); umode = 0; } } #endif /* DANCER */ if (!umode) continue; if (PLUS) { if ((umode == UMODE_O) && (!IsOperator(user))) { #ifdef STATSERVICES char *hostname, *domain; struct HostHash *hosth, *domainh; time_t currtime = current_ts; #endif #ifdef NICKSERVICES CheckOper(user); #endif Network->TotalOperators++; if (SafeConnect) SendUmode(OPERUMODE_O, "*** New Operator: %s (%s@%s) [%s]", user->nick, user->username, user->hostname, user->server ? user->server->name : "*unknown*"); #ifdef STATSERVICES if (Network->TotalOperators > Network->MaxOperators) { Network->MaxOperators = Network->TotalOperators; Network->MaxOperators_ts = current_ts; if ((Network->MaxOperators % 5) == 0) { /* inform +y people of new max oper count */ SendUmode(OPERUMODE_Y, "*** New Max Operator Count: %ld", Network->MaxOperators); putlog(LOG2, "New Max Operator Count: %ld", Network->MaxOperators); } } if (Network->TotalOperators > Network->MaxOperatorsT) { Network->MaxOperatorsT = Network->TotalOperators; Network->MaxOperatorsT_ts = current_ts; } #endif if (user->server) { user->server->numopers++; #ifdef STATSERVICES if (user->server->numopers > user->server->maxopers) { user->server->maxopers = user->server->numopers; user->server->maxopers_ts = current_ts; } #endif } #ifdef STATSERVICES hostname = user->hostname; if ((hosth = FindHost(hostname))) { hosth->curropers++; if (hosth->curropers > hosth->maxopers) { hosth->maxopers = hosth->curropers; hosth->maxopers_ts = currtime; } } if ((domain = GetDomain(hostname))) { if ((domainh = FindDomain(domain))) { domainh->curropers++; if (domainh->curropers > domainh->maxopers) { domainh->maxopers = domainh->curropers; domainh->maxopers_ts = currtime; } } } #endif /* STATSERVICES */ } user->umodes |= umode; } else { if ((umode == UMODE_O) && (IsOperator(user))) { #ifdef STATSERVICES char *hostname, *domain; struct HostHash *hosth, *domainh; #endif Network->TotalOperators--; if (user->server) user->server->numopers--; #ifdef STATSERVICES hostname = user->hostname; if ((hosth = FindHost(hostname))) hosth->curropers--; if ((domain = GetDomain(hostname))) if ((domainh = FindDomain(domain))) domainh->curropers--; #endif } user->umodes &= ~umode; } } } /* UpdateUserModes() */