void CChan::ModeChange(const CString& sModes, const CString& sOpNick) { CString sModeArg = sModes.Token(0); CString sArgs = sModes.Token(1, true); bool bAdd = true; #ifdef _MODULES CNick* pOpNick = FindNick(sOpNick); if (pOpNick) { MODULECALL(OnRawMode(*pOpNick, *this, sModeArg, sArgs), m_pUser, NULL, ); } #endif for (unsigned int a = 0; a < sModeArg.size(); a++) { const unsigned char& uMode = sModeArg[a]; if (uMode == '+') { bAdd = true; } else if (uMode == '-') { bAdd = false; } else if (m_pUser->GetIRCSock()->IsPermMode(uMode)) { CString sArg = GetModeArg(sArgs); CNick* pNick = FindNick(sArg); if (pNick) { unsigned char uPerm = m_pUser->GetIRCSock()->GetPermFromMode(uMode); if (uPerm) { if (bAdd) { pNick->AddPerm(uPerm); if (pNick->GetNick().Equals(m_pUser->GetCurNick())) { AddPerm(uPerm); } } else { pNick->RemPerm(uPerm); if (pNick->GetNick().Equals(m_pUser->GetCurNick())) { RemPerm(uPerm); } } #ifdef _MODULES bool bNoChange = (pNick->HasPerm(uPerm) == bAdd); if (uMode && pOpNick) { MODULECALL(OnChanPermission(*pOpNick, *pNick, *this, uMode, bAdd, bNoChange), m_pUser, NULL, ); if (uMode == CChan::M_Op) { if (bAdd) { MODULECALL(OnOp(*pOpNick, *pNick, *this, bNoChange), m_pUser, NULL, ); } else { MODULECALL(OnDeop(*pOpNick, *pNick, *this, bNoChange), m_pUser, NULL, ); } } else if (uMode == CChan::M_Voice) { if (bAdd) { MODULECALL(OnVoice(*pOpNick, *pNick, *this, bNoChange), m_pUser, NULL, ); } else { MODULECALL(OnDevoice(*pOpNick, *pNick, *this, bNoChange), m_pUser, NULL, ); } } }
void CChan::OnWho(const CString& sNick, const CString& sIdent, const CString& sHost) { CNick* pNick = FindNick(sNick); if (pNick) { pNick->SetIdent(sIdent); pNick->SetHost(sHost); } }
void sSocket::ParseData(int bytes) { Reader.Reset(); while(Reader.GetOffset() < bytes) { int opcode = Reader.ReadWord(); switch(opcode) { case C_MESSAGE: SendToAll(bytes); break; //case C_REQ_NICK_LIST: // Writer.WriteWord(S_SEND_NICK_LIST); // Writer.WriteByte(TotalMembers); //how many members // for(int x = 0; x < 20; x++) // { // if(NickPar[x].nick_size > 0) // { // Writer.WriteByte(NickPar[x].nick_size); //nick size // Writer.WriteString((unsigned char*)NickPar[x].nick, NickPar[x].nick_size); //nick // } // } // Send((char*)Writer.Buffer, Writer.offset); // break; case C_WHO_I_AM: //client told us who he is: unsigned int size = Reader.ReadByte(); //size unsigned char *nick; nick = new unsigned char[size]; Reader.ReadString(nick, size); //get nick //add to the list if(FindNick((char*)nick, size) == -1) //there's no nick AddNick((char*)nick, size); else //send that nick already exists { Writer.WriteWord(S_NICK_EXISTS); Send((char*)Writer.Buffer, Writer.offset); //now client should close the connection... break; } //notice all SendToAllNotice((char*)nick, size, 0); SendNickList(); break; } } }
bool CChan::AddNick(const CString& sNick) { const char* p = sNick.c_str(); CString sPrefix, sTmp, sIdent, sHost; while (m_pNetwork->GetIRCSock()->IsPermChar(*p)) { sPrefix += *p; if (!*++p) { return false; } } sTmp = p; // The UHNames extension gets us nick!ident@host instead of just plain nick sIdent = sTmp.Token(1, true, "!"); sHost = sIdent.Token(1, true, "@"); sIdent = sIdent.Token(0, false, "@"); // Get the nick sTmp = sTmp.Token(0, false, "!"); CNick tmpNick(sTmp); CNick* pNick = FindNick(sTmp); if (!pNick) { pNick = &tmpNick; pNick->SetNetwork(m_pNetwork); } if (!sIdent.empty()) pNick->SetIdent(sIdent); if (!sHost.empty()) pNick->SetHost(sHost); for (CString::size_type i = 0; i < sPrefix.length(); i++) { pNick->AddPerm(sPrefix[i]); } if (pNick->GetNick().Equals(m_pNetwork->GetCurNick())) { for (CString::size_type i = 0; i < sPrefix.length(); i++) { AddPerm(sPrefix[i]); } } m_msNicks[pNick->GetNick()] = *pNick; return true; }
void CChan::ModeChange(const CString& sModes, const CNick* pOpNick) { CString sModeArg = sModes.Token(0); CString sArgs = sModes.Token(1, true); bool bAdd = true; /* Try to find a CNick* from this channel so that pOpNick->HasPerm() * works as expected. */ if (pOpNick) { CNick* OpNick = FindNick(pOpNick->GetNick()); /* If nothing was found, use the original pOpNick, else use the * CNick* from FindNick() */ if (OpNick) pOpNick = OpNick; } if (pOpNick) { NETWORKMODULECALL(OnRawMode(*pOpNick, *this, sModeArg, sArgs), m_pNetwork->GetUser(), m_pNetwork, NULL, NOTHING); } for (unsigned int a = 0; a < sModeArg.size(); a++) { const unsigned char& uMode = sModeArg[a]; if (uMode == '+') { bAdd = true; } else if (uMode == '-') { bAdd = false; } else if (m_pNetwork->GetIRCSock()->IsPermMode(uMode)) { CString sArg = GetModeArg(sArgs); CNick* pNick = FindNick(sArg); if (pNick) { unsigned char uPerm = m_pNetwork->GetIRCSock()->GetPermFromMode(uMode); if (uPerm) { if (bAdd) { pNick->AddPerm(uPerm); if (pNick->GetNick().Equals(m_pNetwork->GetCurNick())) { AddPerm(uPerm); } } else { pNick->RemPerm(uPerm); if (pNick->GetNick().Equals(m_pNetwork->GetCurNick())) { RemPerm(uPerm); } } bool bNoChange = (pNick->HasPerm(uPerm) == bAdd); if (uMode && pOpNick) { NETWORKMODULECALL(OnChanPermission(*pOpNick, *pNick, *this, uMode, bAdd, bNoChange), m_pNetwork->GetUser(), m_pNetwork, NULL, NOTHING); if (uMode == CChan::M_Op) { if (bAdd) { NETWORKMODULECALL(OnOp(*pOpNick, *pNick, *this, bNoChange), m_pNetwork->GetUser(), m_pNetwork, NULL, NOTHING); } else { NETWORKMODULECALL(OnDeop(*pOpNick, *pNick, *this, bNoChange), m_pNetwork->GetUser(), m_pNetwork, NULL, NOTHING); } } else if (uMode == CChan::M_Voice) { if (bAdd) { NETWORKMODULECALL(OnVoice(*pOpNick, *pNick, *this, bNoChange), m_pNetwork->GetUser(), m_pNetwork, NULL, NOTHING); } else { NETWORKMODULECALL(OnDevoice(*pOpNick, *pNick, *this, bNoChange), m_pNetwork->GetUser(), m_pNetwork, NULL, NOTHING); } } } } } } else { bool bList = false; CString sArg; switch (m_pNetwork->GetIRCSock()->GetModeType(uMode)) { case CIRCSock::ListArg: bList = true; sArg = GetModeArg(sArgs); break; case CIRCSock::HasArg: sArg = GetModeArg(sArgs); break; case CIRCSock::NoArg: break; case CIRCSock::ArgWhenSet: if (bAdd) { sArg = GetModeArg(sArgs); } break; } bool bNoChange; if (bList) { bNoChange = false; } else if (bAdd) { bNoChange = HasMode(uMode) && GetModeArg(uMode) == sArg; } else { bNoChange = !HasMode(uMode); } NETWORKMODULECALL(OnMode(*pOpNick, *this, uMode, sArg, bAdd, bNoChange), m_pNetwork->GetUser(), m_pNetwork, NULL, NOTHING); if (!bList) { (bAdd) ? AddMode(uMode, sArg) : RemMode(uMode); } } } }
int ReloadData() { #ifdef NICKSERVICES struct NickInfo *temp, *newnick, *nnext; int ii; #ifdef CHANNELSERVICES struct ChanInfo *ctemp, *cnext; #endif #ifdef MEMOSERVICES struct MemoInfo *mtemp, *mnext; #endif #endif /* NICKSERVICES */ #ifdef NICKSERVICES for (ii = 0; ii < NICKLIST_MAX; ++ii) for (temp = nicklist[ii]; temp; temp = temp->next) temp->flags |= NS_DELETE; if (ns_loaddata() == (-2)) { /* * Reload had fatal errors, so use the old database - * go through and KEEP all structures marked for deletion * and DELETE structures not marked, because they are the * ones that were just added in the failed reload */ for (ii = 0; ii < NICKLIST_MAX; ++ii) { for (temp = nicklist[ii]; temp; temp = nnext) { nnext = temp->next; if (!(temp->flags & NS_DELETE)) DeleteNick(temp); else { /* remove the deletion flag */ temp->flags &= ~NS_DELETE; } } } return 0; } else { /* * Reload was ok - now go through and remove the old nick * structures marked for deletion */ for (ii = 0; ii < NICKLIST_MAX; ++ii) { for (temp = nicklist[ii]; temp; temp = nnext) { nnext = temp->next; if (temp->flags & NS_DELETE) { /* * We should try to preserve the old identification * data. Before deleting this nickname, attempt * to find the corresponding one that was just * read from the configuration file, and set it's * ident/collide/split_ts variables correctly. * It is safe to use FindNick() because it will * return the most current entry. If the entry * was deleted, FindNick() will return 'temp' * so we're still not losing anything. */ if ((newnick = FindNick(temp->nick))) { newnick->flags |= (temp->flags & NS_IDENTIFIED); newnick->collide_ts = temp->collide_ts; #ifdef RECORD_SPLIT_TS newnick->split_ts = temp->split_ts; newnick->whensplit = temp->whensplit; #endif /* RECORD_SPLIT_TS */ } DeleteNick(temp); } /* if (temp->flags & NS_DELETE) */ } /* for (temp = nicklist[ii]; temp; temp = nnext) */ } /* for (ii = 0; ii < NICKLIST_MAX; ++ii) */ } #ifdef CHANNELSERVICES for (ii = 0; ii < CHANLIST_MAX; ++ii) for (ctemp = chanlist[ii]; ctemp; ctemp = ctemp->next) ctemp->flags |= CS_DELETE; if (cs_loaddata() == (-2)) { /* * Reload had fatal errors, so use the old database - * go through and KEEP all structures marked for deletion * and DELETE structures not marked, because they are the * ones that were just added in the failed reload */ for (ii = 0; ii < CHANLIST_MAX; ++ii) { for (ctemp = chanlist[ii]; ctemp; ctemp = cnext) { cnext = ctemp->next; if (!(ctemp->flags & CS_DELETE)) DeleteChan(ctemp); else { /* remove the deletion flag */ ctemp->flags &= ~CS_DELETE; } } } return 0; } else { struct Channel *cptr; /* * Reload was ok - now go through and remove the old chan * structures marked for deletion */ for (ii = 0; ii < CHANLIST_MAX; ++ii) { for (ctemp = chanlist[ii]; ctemp; ctemp = cnext) { cnext = ctemp->next; if (ctemp->flags & CS_DELETE) DeleteChan(ctemp); else { /* * It must be a new channel entry, have ChanServ * join the channel */ cptr = FindChannel(ctemp->name); if (cptr && !IsChannelMember(cptr, Me.csptr)) cs_join(ctemp); } } } /* * Now go through the list and have ChanServ part any old chans */ if (Me.csptr) { struct UserChannel *uc, *ucprev; ucprev = NULL; for (uc = Me.csptr->firstchan; uc; ) { if (!FindChan(uc->chptr->name)) { if (ucprev) { ucprev->next = uc->next; cs_part(uc->chptr); uc = ucprev; } else { Me.csptr->firstchan = uc->next; cs_part(uc->chptr); uc = NULL; } } ucprev = uc; if (uc) uc = uc->next; else uc = Me.csptr->firstchan; } } } /* if (Me.csptr) */ #endif /* CHANNELSERVICES */ #ifdef MEMOSERVICES for (ii = 0; ii < MEMOLIST_MAX; ++ii) for (mtemp = memolist[ii]; mtemp; mtemp = mtemp->next) mtemp->flags |= MS_RDELETE; if (ms_loaddata() == (-2)) { /* * Reload had fatal errors, so use the old database - * go through and KEEP all structures marked for deletion * and DELETE structures not marked, because they are the * ones that were just added in the failed reload */ for (ii = 0; ii < MEMOLIST_MAX; ++ii) { for (mtemp = memolist[ii]; mtemp; mtemp = mnext) { mnext = mtemp->next; if (!(mtemp->flags & MS_RDELETE)) DeleteMemoList(mtemp); else { /* remove the deletion flag */ mtemp->flags &= ~MS_RDELETE; } } } return 0; } else { /* * Reload was ok - now go through and remove the old memo * structures marked for deletion */ for (ii = 0; ii < MEMOLIST_MAX; ++ii) { for (mtemp = memolist[ii]; mtemp; mtemp = mnext) { mnext = mtemp->next; if (mtemp->flags & MS_RDELETE) DeleteMemoList(mtemp); } } } #endif /* MEMOSERVICES */ #endif /* NICKSERVICES */ #ifdef STATSERVICES if (ss_loaddata() == (-2)) return 0; #endif /* STATSERVICES */ #ifdef SEENSERVICES if (es_loaddata() == (-2)) return 0; #endif /* SEENSERVICES */ if (os_loaddata() == (-2)) return 0; return 1; } /* ReloadData() */
void DeleteClient(struct Luser *user) { struct UserChannel *chnext; #ifdef NICKSERVICES struct NickInfo *nptr, *realptr; #ifdef CHANNELSERVICES struct aChannelPtr *fnext; #endif #endif /* NICKSERVICES */ if (user == NULL) return; SendUmode(OPERUMODE_CAPE, "*** Client exit: %s!%s@%s [%s]", user->nick, user->username, user->hostname, user->server ? user->server->name : "*unknown*"); #ifdef NICKSERVICES realptr = FindNick(user->nick); nptr = GetMaster(realptr); if (nptr && realptr) { if (LastSeenInfo && (realptr->flags & NS_IDENTIFIED)) { /* * Update last seen user@host info */ if (realptr->lastu) MyFree(realptr->lastu); if (realptr->lasth) MyFree(realptr->lasth); realptr->lastu = MyStrdup(user->username); realptr->lasth = MyStrdup(user->hostname); } /* * they're quitting - unmark them as identified */ realptr->flags &= ~NS_IDENTIFIED; } #ifdef CHANNELSERVICES while (user->founder_channels) { fnext = user->founder_channels->next; RemFounder(user, user->founder_channels->cptr); user->founder_channels = fnext; } #endif #endif /* NICKSERVICES */ #ifdef ALLOW_FUCKOVER /* check if user was a target of o_fuckover() */ CheckFuckoverTarget(user, NULL); #endif if (user->server) user->server->numusers--; while (user->firstchan) { chnext = user->firstchan->next; RemoveFromChannel(user->firstchan->chptr, user); user->firstchan = chnext; } HashDelClient(user, 0); /* keep oper count updated */ if (user->umodes & UMODE_O) { Network->TotalOperators--; if (user->server) user->server->numopers--; } #ifndef BLOCK_ALLOCATION MyFree(user->nick); MyFree(user->username); MyFree(user->hostname); MyFree(user->realname); #endif /* BLOCK_ALLOCATION */ if (user->prev) user->prev->next = user->next; else ClientList = user->next; if (user->next) user->next->prev = user->prev; #ifdef BLOCK_ALLOCATION BlockSubFree(ClientHeap, user); #else MyFree(user); #endif /* BLOCK_ALLOCATION */ Network->TotalUsers--; } /* DeleteClient() */
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() */
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 ms_process(char *nick, char *command) { int acnt; char **arv; struct Command *mptr; struct Luser *lptr; struct NickInfo *nptr, *master; if (!command || !(lptr = FindClient(nick))) return; if (Network->flags & NET_OFF) { notice(n_MemoServ, lptr->nick, "Services are currently \002disabled\002"); return; } acnt = SplitBuf(command, &arv); if (acnt == 0) { MyFree(arv); return; } mptr = GetCommand(memocmds, arv[0]); if (!mptr || (mptr == (struct Command *) -1)) { notice(n_MemoServ, lptr->nick, "%s command [%s]", (mptr == (struct Command *) -1) ? "Ambiguous" : "Unknown", arv[0]); MyFree(arv); return; } /* * Check if the command is for admins only - if so, * check if they match an admin O: line. If they do, * check if they are EITHER oper'd, or registered with OperServ, * if either of these is true, allow the command */ if ((mptr->level == LVL_ADMIN) && !(IsValidAdmin(lptr))) { notice(n_MemoServ, lptr->nick, "Unknown command [%s]", arv[0]); MyFree(arv); return; } nptr = FindNick(lptr->nick); master = GetMaster(nptr); if (!nptr && !master && (mptr->level != LVL_NONE)) { /* the command requires a registered nickname */ notice(n_MemoServ, lptr->nick, "Your nickname is not registered"); notice(n_MemoServ, lptr->nick, ERR_MORE_INFO, n_NickServ, "REGISTER"); MyFree(arv); return; } if (nptr) { if (nptr->flags & NS_FORBID) { notice(n_MemoServ, lptr->nick, "Cannot execute commands for forbidden nicknames"); MyFree(arv); return; } if (mptr->level != LVL_NONE) { if (!(nptr->flags & NS_IDENTIFIED)) { notice(n_MemoServ, lptr->nick, "Password identification is required for [\002%s\002]", mptr->cmd); notice(n_MemoServ, lptr->nick, "Type \002/msg %s IDENTIFY <password>\002 and retry", n_NickServ); MyFree(arv); return; } } } /* if (nptr) */ /* call mptr->func to execute command */ (*mptr->func)(lptr, master, acnt, arv); MyFree(arv); return; } /* ms_process() */
static void m_send(struct Luser *lptr, struct NickInfo *nptr, int ac, char **av) { char *memotext, /* memo text */ *to; /* who the memo is sent to */ int index; struct NickInfo *master = NULL, *realptr = NULL; #ifdef CHANNELSERVICES struct ChanInfo *ci = NULL; #endif if (ac < 3) { notice(n_MemoServ, lptr->nick, "Syntax: SEND <nick/channel> <text>"); notice(n_MemoServ, lptr->nick, ERR_MORE_INFO, n_MemoServ, "SEND"); return; } if (*av[1] == '#') { #ifndef CHANNELSERVICES notice(n_MemoServ, lptr->nick, "Channel services are disabled"); return; #else if (!(ci = FindChan(av[1]))) { notice(n_MemoServ, lptr->nick, ERR_CH_NOT_REGGED, av[1]); return; } if (!HasAccess(ci, lptr, CA_AUTOOP)) { notice(n_MemoServ, lptr->nick, "AutoOp access is required to send a memo to [\002%s\002]", ci->name); return; } to = ci->name; #endif /* CHANNELSERVICES */ } else { /* it was sent to a nickname */ if (!(realptr = FindNick(av[1]))) { notice(n_MemoServ, lptr->nick, ERR_NOT_REGGED, av[1]); return; } master = GetMaster(realptr); assert(master != 0); if (!(master->flags & NS_MEMOS)) { notice(n_MemoServ, lptr->nick, "[\002%s\002] is rejecting all memos", av[1]); return; } to = master->nick; } /* get the actual memo text now */ if (ac < 3) memotext = MyStrdup(""); else memotext = GetString(ac - 2, av + 2); index = StoreMemo(to, memotext, lptr); if (index) { notice(n_MemoServ, lptr->nick, "Memo has been recorded for [\002%s\002]", realptr ? realptr->nick : to); if (realptr && master) { /* * It was sent to a nickname - check if they are online * and identified and optionally notify them * * we should have here linklist traversal and notifying all clients. * however, that could be a bit cpu intensitive to do for every * memo, so i haven't done it so far. -kre */ if ((master->flags & NS_MEMONOTIFY) && (realptr->flags & NS_IDENTIFIED) && FindClient(realptr->nick)) { notice(n_MemoServ, realptr->nick, "You have a new memo from \002%s\002 (#%d)", lptr->nick, index); notice(n_MemoServ, realptr->nick, "Type \002/msg %s READ %d\002 to read it", n_MemoServ, index); } } /* if (ni) */ #ifdef CHANNELSERVICES else { struct Channel *chptr; struct ChanAccess *ca; char *newtext; /* * It was sent to a channel - notify every AOP or higher */ if ((ci) && (chptr = FindChannel(to))) { struct ChannelUser *cu; struct NickInfo *tmpn; for (cu = chptr->firstuser; cu; cu = cu->next) { if (FindService(cu->lptr)) continue; tmpn = GetLink(cu->lptr->nick); if (HasAccess(ci, cu->lptr, CA_AUTOOP)) { if (tmpn) { /* don't notify people who don't want memos */ if (!(tmpn->flags & NS_MEMOS) || !(tmpn->flags & NS_MEMONOTIFY)) continue; } notice(n_MemoServ, cu->lptr->nick, "New channel memo from \002%s\002 (#%d)", lptr->nick, index); notice(n_MemoServ, cu->lptr->nick, "Type \002/msg %s READ %s %d\002 to read it", n_MemoServ, chptr->name, index); } } } newtext = (char *) MyMalloc(strlen(memotext) + strlen(ci->name) + 4); ircsprintf(newtext, "(%s) %s", ci->name, memotext); for (ca = ci->access; ca; ca = ca->next) { if (ca->nptr) StoreMemo(ca->nptr->nick, newtext, lptr); } MyFree(newtext); } /* else */ #endif /* CHANNELSERVICES */ } /* if (index) */ MyFree (memotext); } /* m_send() */
int ms_loaddata() { FILE *fp; char line[MAXLINE], **av; char *keyword; int ac, ret = 1, cnt; struct MemoInfo *mi = NULL; struct NickInfo *nickptr; if (!(fp = fopen(MemoServDB, "r"))) { /* MemoServ data file doesn't exist */ return -1; } cnt = 0; /* load data into list */ while (fgets(line, MAXLINE - 1, fp)) { cnt++; ac = SplitBuf(line, &av); if (!ac) { /* probably a blank line */ MyFree(av); continue; } if (av[0][0] == ';') { /* its a comment */ MyFree(av); continue; } if (!ircncmp("->", av[0], 2)) { /* * check if there are enough args */ if (ac < 5) { fatal(1, "%s:%d Invalid database format (FATAL)", MemoServDB, cnt); ret = -2; MyFree(av); continue; } /* check if there is no nickname before it */ if (!mi) { fatal(1, "%s:%d No nickname associated with data", MemoServDB, cnt); if (ret > 0) ret = -1; MyFree(av); continue; } keyword = av[0] + 2; if (!ircncmp(keyword, "TEXT", 4)) { struct Memo *memoptr; memoptr = MakeMemo(); memoptr->sender = MyStrdup(av[1]); memoptr->sent = atol(av[2]); memoptr->flags = atol(av[3]); if (!(memoptr->flags & MS_READ)) mi->newmemos++; memoptr->text = MyStrdup(av[4] + 1); memoptr->index = ++mi->memocnt; AddMemo(mi, memoptr); } } /* if (!ircncmp("->", keyword, 2)) */ else { if (mi) { if (!mi->memos) { fatal(1, "%s:%d No memos for entry [%s] (skipping)", MemoServDB, cnt, mi->name); MyFree(mi->name); MyFree(mi); mi = NULL; if (ret > 0) ret = -1; } else AddMemoList(mi); } /* * make sure there are enough args on the line: * <nickname> */ if (ac < 1) { fatal(1, "%s:%d Invalid database format (FATAL)", MemoServDB, cnt); ret = -2; mi = NULL; MyFree(av); continue; } if (!(nickptr = FindNick(av[0]))) { fatal(1, "%s:%d Memo entry [%s] is not a registered nickname (skipping)", MemoServDB, cnt, av[0]); if (ret > 0) ret = -1; mi = NULL; MyFree(av); continue; } #ifdef LINKED_NICKNAMES if (nickptr->master) { /* * nickptr is a leaf nickname - they should not have * memo entries */ fatal(1, "%s:%d Memo entry [%s] is not a master nickname (skipping)", MemoServDB, cnt, av[0]); if (ret > 0) ret = (-1); mi = NULL; MyFree(av); continue; } #endif /* LINKED_NICKNAMES */ mi = MakeMemoList(); mi->name = MyStrdup(av[0]); } MyFree(av); } /* while (fgets(line, MAXLINE - 1, fp)) */ if (mi) { if (!mi->memos) { fatal(1, "%s:%d No memos for entry [%s] (skipping)", MemoServDB, cnt, mi->name); MyFree(mi->name); MyFree(mi); if (ret > 0) ret = -1; } else AddMemoList(mi); } fclose (fp); return (ret); } /* ms_loaddata() */
static void m_reply(struct Luser *lptr, struct NickInfo *nptr, int ac, char **av) { struct MemoInfo *from; struct Memo *memoptr; struct NickInfo *master, *realptr; char *memotext; int index, ii; if (!nptr) return; if (ac < 3) { notice(n_MemoServ, lptr->nick, "Syntax: REPLY <index> <text>"); notice(n_MemoServ, lptr->nick, ERR_MORE_INFO, n_MemoServ, "REPLY"); return; } if (!(from = FindMemoList(nptr->nick))) { notice(n_MemoServ, lptr->nick, "You have no recorded memos"); return; } index = IsNum(av[1]); if ((index < 0) || (index > from->memocnt)) { notice(n_MemoServ, lptr->nick, "[\002%s\002] is an invalid index", av[1]); return; } master = realptr = NULL; for (memoptr = from->memos; memoptr; memoptr = memoptr->next) { if (memoptr->index == index) { if (!(realptr = FindNick(memoptr->sender))) { notice(n_MemoServ, lptr->nick, ERR_NOT_REGGED, av[2]); return; } master = GetMaster(realptr); assert(master != 0); if (!(master->flags & NS_MEMOS)) { notice(n_MemoServ, lptr->nick, "[\002%s\002] is rejecting all memos", master->nick); return; } break; } } if (!master || !realptr) return; if (ac >= 3) { memotext = (char *) MyMalloc(strlen("[Re]: ") + strlen(av[2]) + 1); ircsprintf(memotext, "[Re]: %s", av[2]); ii = 3; while (ii < ac) { memotext = (char *) MyRealloc(memotext, strlen(memotext) + strlen(av[ii]) + (2 * sizeof(char))); strcat(memotext, " "); strcat(memotext, av[ii]); ii++; } } else memotext = MyStrdup(""); index = StoreMemo(master->nick, memotext, lptr); if (index) { notice(n_MemoServ, lptr->nick, "Memo has been recorded for [\002%s\002]", master->nick); /* * It was sent to a nickname - check if they are online * and notify them */ if ((master->flags & NS_MEMONOTIFY) && (realptr->flags & NS_IDENTIFIED) && FindClient(realptr->nick)) { notice(n_MemoServ, realptr->nick, "You have a new memo from \002%s\002 (#%d)", lptr->nick, index); notice(n_MemoServ, realptr->nick, "Type \002/msg %s READ %d\002 to read it", n_MemoServ, index); } } /* if (index) */ MyFree(memotext); } /* m_reply() */
static void m_forward(struct Luser *lptr, struct NickInfo *nptr, int ac, char **av) { struct MemoInfo *from, *target; struct Memo *memoptr = NULL; struct Memo *fromptr; char *to; /* who the memo is sent to */ int index, cnt; char buf[MAXLINE]; struct NickInfo *master, *realptr; #ifdef CHANNELSERVICES struct ChanInfo *ci = NULL; #endif if (!nptr) return; if (ac < 3) { notice(n_MemoServ, lptr->nick, "Syntax: FORWARD <index|ALL> <nick/channel>"); notice(n_MemoServ, lptr->nick, ERR_MORE_INFO, n_MemoServ, "FORWARD"); return; } if (!(from = FindMemoList(nptr->nick))) { notice(n_MemoServ, lptr->nick, "You have no recorded memos"); return; } index = IsNum(av[1]); if ((index < 0) || (index > from->memocnt) || (!index && (irccmp(av[1], "ALL") != 0))) { notice(n_MemoServ, lptr->nick, "[\002%s\002] is an invalid index", av[1]); return; } master = realptr = NULL; if (*av[2] == '#') { #ifndef CHANNELSERVICES notice(n_MemoServ, lptr->nick, "Channel services are disabled"); return; #else if (!(ci = FindChan(av[2]))) { notice(n_MemoServ, lptr->nick, ERR_CH_NOT_REGGED, av[2]); return; } if (!HasAccess(ci, lptr, CA_AUTOOP)) { notice(n_MemoServ, lptr->nick, "AutoOp access is required to forward a memo to [\002%s\002]", ci->name); return; } to = ci->name; #endif } else { /* it was sent to a nickname */ if (!(realptr = FindNick(av[2]))) { notice(n_MemoServ, lptr->nick, ERR_NOT_REGGED, av[2]); return; } master = GetMaster(realptr); assert(master != 0); if (!(master->flags & NS_MEMOS)) { notice(n_MemoServ, lptr->nick, "[\002%s\002] is rejecting all memos", realptr->nick); return; } to = master->nick; } if (!(target = FindMemoList(to))) { target = MakeMemoList(); target->name = MyStrdup(to); AddMemoList(target); } else if (from == target) { /* * If we let someone forward memos to themselves, * the below loop will never end, eventually malloc()'ing too * much and crashing - head it off at the pass */ notice(n_MemoServ, lptr->nick, "You cannot forward memos to yourself"); return; } if (MaxMemos && (target->memocnt >= MaxMemos)) { notice(n_MemoServ, lptr->nick, "%s has reached the maximum memo limit, and cannot receive more", to); return; } cnt = 0; for (fromptr = from->memos; fromptr; fromptr = fromptr->next) { if (!index || (fromptr->index == index)) { memset(&buf, 0, MAXLINE); target->memocnt++; target->newmemos++; cnt++; memoptr = MakeMemo(); memoptr->sender = MyStrdup(lptr->nick); memoptr->sent = current_ts; memoptr->index = target->memocnt; strcpy(buf, "[Fwd]: "); strncat(buf, fromptr->text, MAXLINE - 8); memoptr->text = MyStrdup(buf); AddMemo(target, memoptr); if (MaxMemos && (target->memocnt >= MaxMemos)) break; } } if (!index) ircsprintf(buf, "All memos have"); else ircsprintf(buf, "Memo #%d has", index); notice(n_MemoServ, lptr->nick, "%s been forwarded to [\002%s\002]", buf, target->name); if (master && realptr) { /* * It was sent to a nickname - check if they are online * and notify them */ if ((master->flags & NS_MEMONOTIFY) && (realptr->flags & NS_IDENTIFIED) && FindClient(realptr->nick)) { notice(n_MemoServ, realptr->nick, "You have %d new forwarded memo%s from \002%s\002", cnt, (cnt == 1) ? "" : "s", memoptr->sender); notice(n_MemoServ, realptr->nick, "Type \002/msg %s LIST\002 to view %s", n_MemoServ, (cnt == 1) ? "it" : "them"); } } /* if (master && realptr) */ #ifdef CHANNELSERVICES else { struct Channel *chptr; /* * It was sent to a channel - notify every AOP or higher */ if ((ci) && (chptr = FindChannel(target->name))) { struct ChannelUser *cu; struct NickInfo *tmpn; for (cu = chptr->firstuser; cu; cu = cu->next) { if (FindService(cu->lptr)) continue; tmpn = GetLink(cu->lptr->nick); if (HasAccess(ci, cu->lptr, CA_AUTOOP)) { if (tmpn) { if (!(tmpn->flags & NS_MEMOS) || !(tmpn->flags & NS_MEMONOTIFY)) continue; } notice(n_MemoServ, cu->lptr->nick, "%d new forwarded channel memo%s from \002%s\002", cnt, (cnt == 1) ? "" : "s", memoptr->sender); notice(n_MemoServ, cu->lptr->nick, "Type \002/msg %s LIST %s\002 to view %s", n_MemoServ, chptr->name, (cnt == 1) ? "it" : "them"); } } } } /* else */ #endif /* CHANNELSERVICES */ } /* m_forward() */
void Socket::ParseData(int bytes) { Reader.Reset(); while(Reader.GetOffset() < bytes) { unsigned short opcode = Reader.ReadWord(); switch(opcode) { case C_MESSAGE: //text message { unsigned char *msg; unsigned char *nick; unsigned short size_nick = Reader.ReadByte(); //read nick nick = new unsigned char[size_nick]; Reader.ReadString(nick, size_nick); //read nick string unsigned short size_text = Reader.ReadByte(); //read text size msg = new unsigned char[size_text]; Reader.ReadString(msg, size_text); //read text ShowMessage((char*)msg, size_text, (char*)nick, size_nick); delete [] nick; delete [] msg; break; } case C_CONNECT: //connected { unsigned char *nick; unsigned short size = Reader.ReadByte(); nick = new unsigned char[size]; Reader.ReadString(nick, size); MemberNotice((char*)nick, size, 0); //notice everyone //AddNick((char*)nick, size); delete [] nick; break; } case C_DISCONNECT: //disconnected { unsigned char *nick; unsigned short size = Reader.ReadByte(); nick = new unsigned char[size]; Reader.ReadString(nick, size); MemberNotice((char*)nick, size, 1); delete [] nick; break; } case S_SEND_NICK_LIST: //got from server { for(int x = 0; x < 20; x++) //delete old list ZeroMemory(&NickPar[x], sizeof(Nick)); for(int x = 0; x < 20; x++) //delete nick list SendMessage(NickList, LB_DELETESTRING, 0, 0); int TotalMembers = Reader.ReadByte(); //get total members cur_chatters = TotalMembers; //used for deleting list for(int x = 0; x < TotalMembers; x++) { unsigned int size = Reader.ReadByte(); //get size unsigned char *nick; nick = new unsigned char[size]; Reader.ReadString(nick, size); //get nick if(FindNick((char*)nick, size) > -1) { //nick found do nothing... } else { AddNick((char*)nick, size); UpdateWindow(NickList); } } break; } case S_WHO_ARE_YOU: { Writer.WriteWord(C_WHO_I_AM); // Writer.WriteByte(MyNick.nick_size); //size Writer.WriteString((unsigned char*)MyNick.nick, MyNick.nick_size); //nick Send((char*)Writer.Buffer, Writer.offset); break; } default: { SetText("Unknown opcode"); Reader.SetOffset(1000); break; } } } }
void RemoveFromChannel(struct Channel *cptr, struct Luser *lptr) { struct UserChannel *tempchan, *prev = NULL; struct ChannelUser *tempuser, *prev2 = NULL; if (!cptr || !lptr) return; SendUmode(OPERUMODE_P, "*** Channel part: %s (%s)", lptr->nick, cptr->name); /* Is this the contact? */ #ifdef CHANNELSERVICES { struct NickInfo *nptr; struct ChanInfo *ciptr; if ((nptr = FindNick(lptr->nick)) && (ciptr = FindChan(cptr->name))) { if (nptr->flags & NS_IDENTIFIED) { if (ciptr->contact && irccmp(lptr->nick, ciptr->contact) == 0) /* That's the contact joining. Update activity timer */ ciptr->last_contact_active = current_ts; if (ciptr->alternate && irccmp(lptr->nick, ciptr->alternate) == 0) ciptr->last_alternate_active = current_ts; } } } #endif /* remove cptr from lptr's chan list */ for (tempchan = lptr->firstchan; tempchan; tempchan = tempchan->next) { if (cptr == tempchan->chptr) { if (prev) prev->next = tempchan->next; else lptr->firstchan = tempchan->next; MyFree(tempchan); tempchan = NULL; break; } prev = tempchan; } /* remove lptr from cptr's nick list */ for (tempuser = cptr->firstuser; tempuser; tempuser = tempuser->next) { if (lptr == tempuser->lptr) { if (prev2) prev2->next = tempuser->next; else cptr->firstuser = tempuser->next; MyFree(tempuser); tempuser = NULL; --cptr->numusers; break; } prev2 = tempuser; } if (cptr->numusers == 0) DeleteChannel(cptr); /* the last nick left the chan, erase it */ } /* RemoveFromChannel() */