- int MOD_RESULT = 0;
-
- std::string temp = parameters[1];
- FOREACH_RESULT(OnUserPreMessage(user,dest,TYPE_USER,temp));
- if (MOD_RESULT) {
- return;
- }
- parameters[1] = (char*)temp.c_str();
-
- if (!strcmp(dest->server,ServerName))
- {
- // direct write, same server
- log(DEBUG,"*** CALL WRITETO");
- WriteTo(user, dest, "PRIVMSG %s :%s", dest->nick, parameters[1]);
- }
-
- FOREACH_MOD OnUserMessage(user,dest,TYPE_USER,parameters[1]);
- }
- else
- {
- /* no such nick/channel */
- WriteServ(user->fd,"401 %s %s :No such nick/channel",user->nick, parameters[0]);
- }
-}
-
-void handle_notice(char **parameters, int pcnt, userrec *user)
-{
- userrec *dest;
- chanrec *chan;
-
- user->idle_lastmsg = TIME;
-
- if (loop_call(handle_notice,parameters,pcnt,user,0,pcnt-2,0))
- return;
- if (parameters[0][0] == '$')
- {
- // notice to server mask
- char* servermask = parameters[0];
- servermask++;
- if (match(ServerName,servermask))
- {
- NoticeAll(user, true, "%s",parameters[1]);
- }
- return;
- }
- else if (parameters[0][0] == '#')
- {
- chan = FindChan(parameters[0]);
- if (chan)
- {
- if ((chan->binarymodes & CM_NOEXTERNAL) && (!has_channel(user,chan)))
- {
- WriteServ(user->fd,"404 %s %s :Cannot send to channel (no external messages)", user->nick, chan->name);
- return;
- }
- if ((chan->binarymodes & CM_MODERATED) && (cstatus(user,chan)<STATUS_VOICE))
- {
- WriteServ(user->fd,"404 %s %s :Cannot send to channel (+m)", user->nick, chan->name);
- return;
- }
-
- int MOD_RESULT = 0;
-
- std::string temp = parameters[1];
- FOREACH_RESULT(OnUserPreNotice(user,chan,TYPE_CHANNEL,temp));
- if (MOD_RESULT) {
- return;
- }
- parameters[1] = (char*)temp.c_str();
-
- if (temp == "")
- {
- WriteServ(user->fd,"412 %s No text to send", user->nick);
- return;
- }
-
- ChanExceptSender(chan, user, "NOTICE %s :%s", chan->name, parameters[1]);
-
- FOREACH_MOD OnUserNotice(user,chan,TYPE_CHANNEL,parameters[1]);
- }
- else
- {
- /* no such nick/channel */
- WriteServ(user->fd,"401 %s %s :No such nick/channel",user->nick, parameters[0]);
- }
- return;
- }
-
- dest = Find(parameters[0]);
- if (dest)
- {
- int MOD_RESULT = 0;
-
- std::string temp = parameters[1];
- FOREACH_RESULT(OnUserPreNotice(user,dest,TYPE_USER,temp));
- if (MOD_RESULT) {
- return;
- }
- parameters[1] = (char*)temp.c_str();
-
- if (!strcmp(dest->server,ServerName))
- {
- // direct write, same server
- WriteTo(user, dest, "NOTICE %s :%s", dest->nick, parameters[1]);
- }
-
- FOREACH_MOD OnUserNotice(user,dest,TYPE_USER,parameters[1]);
- }
- else
- {
- /* no such nick/channel */
- WriteServ(user->fd,"401 %s %s :No such nick/channel",user->nick, parameters[0]);
- }
-}
-
-void handle_server(char **parameters, int pcnt, userrec *user)
-{
- WriteServ(user->fd,"666 %s :You cannot identify as a server, you are a USER. IRC Operators informed.",user->nick);
- WriteOpers("*** WARNING: %s attempted to issue a SERVER command and is registered as a user!",user->nick);
-}
-
-void handle_info(char **parameters, int pcnt, userrec *user)
-{
- WriteServ(user->fd,"371 %s :. o O (The Inspire Internet Relay Chat Server) O o .",user->nick);
- WriteServ(user->fd,"371 %s : ",user->nick);
- WriteServ(user->fd,"371 %s :Core developers: Craig Edwards (Brain)",user->nick);
- WriteServ(user->fd,"371 %s : Craig McLure",user->nick);
- WriteServ(user->fd,"371 %s : ",user->nick);
- WriteServ(user->fd,"371 %s :Contributors: typobox43",user->nick);
- WriteServ(user->fd,"371 %s : w00t",user->nick);
- WriteServ(user->fd,"371 %s : Om",user->nick);
- WriteServ(user->fd,"371 %s : Jazza",user->nick);
- WriteServ(user->fd,"371 %s : ",user->nick);
- WriteServ(user->fd,"371 %s :Testers: CC",user->nick);
- WriteServ(user->fd,"371 %s : Om",user->nick);
- WriteServ(user->fd,"371 %s : Piggles",user->nick);
- WriteServ(user->fd,"371 %s : Foamy",user->nick);
- WriteServ(user->fd,"371 %s : Hart",user->nick);
- WriteServ(user->fd,"371 %s : RageD",user->nick);
- WriteServ(user->fd,"371 %s : [ed]",user->nick);
- WriteServ(user->fd,"371 %s : Azhrarn",user->nick);
- WriteServ(user->fd,"371 %s : nenolod",user->nick);
- WriteServ(user->fd,"371 %s : luigiman",user->nick);
- WriteServ(user->fd,"371 %s : Chu",user->nick);
- WriteServ(user->fd,"371 %s : aquanight",user->nick);
- WriteServ(user->fd,"371 %s : xptek",user->nick);
- WriteServ(user->fd,"371 %s : Grantlinks",user->nick);
- WriteServ(user->fd,"371 %s : Rob",user->nick);
- WriteServ(user->fd,"371 %s : angelic",user->nick);
- WriteServ(user->fd,"371 %s : Jason",user->nick);
- WriteServ(user->fd,"371 %s : ThaPrince",user->nick);
- WriteServ(user->fd,"371 %s : ",user->nick);
- WriteServ(user->fd,"371 %s :Thanks to irc-junkie and searchirc",user->nick);
- WriteServ(user->fd,"371 %s :for the nice comments and the help",user->nick);
- WriteServ(user->fd,"371 %s :you gave us in attracting users to",user->nick);
- WriteServ(user->fd,"371 %s :this software.",user->nick);
- WriteServ(user->fd,"371 %s : ",user->nick);
- WriteServ(user->fd,"371 %s :Best experienced with: An IRC client.",user->nick);
- FOREACH_MOD OnInfo(user);
- WriteServ(user->fd,"374 %s :End of /INFO list",user->nick);
-}
-
-void handle_time(char **parameters, int pcnt, userrec *user)
-{
- time_t rawtime;
- struct tm * timeinfo;
-
- time ( &rawtime );
- timeinfo = localtime ( &rawtime );
- WriteServ(user->fd,"391 %s %s :%s",user->nick,ServerName, asctime (timeinfo) );
-
-}
-
-void handle_whois(char **parameters, int pcnt, userrec *user)
-{
- userrec *dest;
-
- if (loop_call(handle_whois,parameters,pcnt,user,0,pcnt-1,0))
- return;
- dest = Find(parameters[0]);
- if (dest)
- {
- // bug found by phidjit - were able to whois an incomplete connection if it had sent a NICK or USER
- if (dest->registered == 7)
- {
- WriteServ(user->fd,"311 %s %s %s %s * :%s",user->nick, dest->nick, dest->ident, dest->dhost, dest->fullname);
- if ((user == dest) || (strchr(user->modes,'o')))
- {
- WriteServ(user->fd,"378 %s %s :is connecting from *@%s %s",user->nick, dest->nick, dest->host, dest->ip);
- }
- char* cl = chlist(dest,user);
- if (*cl)
- {
- WriteServ(user->fd,"319 %s %s :%s",user->nick, dest->nick, cl);
- }
- WriteServ(user->fd,"312 %s %s %s :%s",user->nick, dest->nick, dest->server, GetServerDescription(dest->server).c_str());
- if (*dest->awaymsg)
- {
- WriteServ(user->fd,"301 %s %s :%s",user->nick, dest->nick, dest->awaymsg);
- }
- if (strchr(dest->modes,'o'))
- {
- if (*dest->oper)
- {
- WriteServ(user->fd,"313 %s %s :is %s %s on %s",user->nick, dest->nick, (strchr("aeiou",dest->oper[0]) ? "an" : "a"),dest->oper, Network);
- }
- else
- {
- WriteServ(user->fd,"313 %s %s :is opered but has an unknown type",user->nick, dest->nick);
- }
- }
- FOREACH_MOD OnWhois(user,dest);
- if (!strcasecmp(user->server,dest->server))
- {
- // idle time and signon line can only be sent if youre on the same server (according to RFC)
- WriteServ(user->fd,"317 %s %s %d %d :seconds idle, signon time",user->nick, dest->nick, abs((dest->idle_lastmsg)-TIME), dest->signon);
- }
-
- WriteServ(user->fd,"318 %s %s :End of /WHOIS list.",user->nick, dest->nick);
- }
- else
- {
- WriteServ(user->fd,"401 %s %s :No such nick/channel",user->nick, parameters[0]);
- WriteServ(user->fd,"318 %s %s :End of /WHOIS list.",user->nick, parameters[0]);
- }
- }
- else
- {
- /* no such nick/channel */
- WriteServ(user->fd,"401 %s %s :No such nick/channel",user->nick, parameters[0]);
- WriteServ(user->fd,"318 %s %s :End of /WHOIS list.",user->nick, parameters[0]);
- }
-}
-
-void handle_quit(char **parameters, int pcnt, userrec *user)
-{
- user_hash::iterator iter = clientlist.find(user->nick);
- char* reason;
-
- if (user->registered == 7)
- {
- /* theres more to do here, but for now just close the socket */
- if (pcnt == 1)
- {
- if (parameters[0][0] == ':')
- {
- *parameters[0]++;
- }
- reason = parameters[0];
-
- if (strlen(reason)>MAXQUIT)
- {
- reason[MAXQUIT-1] = '\0';
- }
-
- /* We should only prefix the quit for a local user. Remote users have
- * already been prefixed, where neccessary, by the upstream server.
- */
- if (!strcasecmp(user->server,ServerName))
- {
- Write(user->fd,"ERROR :Closing link (%s@%s) [%s%s]",user->ident,user->host,PrefixQuit,parameters[0]);
- WriteOpers("*** Client exiting: %s!%s@%s [%s%s]",user->nick,user->ident,user->host,PrefixQuit,parameters[0]);
- WriteCommonExcept(user,"QUIT :%s%s",PrefixQuit,parameters[0]);
- }
- else
- {
- WriteOpers("*** Client exiting at %s: %s!%s@%s [%s]",user->server,user->nick,user->ident,user->host,parameters[0]);
- WriteCommonExcept(user,"QUIT :%s",parameters[0]);
- }
- FOREACH_MOD OnUserQuit(user,std::string(PrefixQuit)+std::string(parameters[0]));
-
- }
- else
- {
- Write(user->fd,"ERROR :Closing link (%s@%s) [QUIT]",user->ident,user->host);
- WriteOpers("*** Client exiting: %s!%s@%s [Client exited]",user->nick,user->ident,user->host);
- WriteCommonExcept(user,"QUIT :Client exited");
- FOREACH_MOD OnUserQuit(user,"Client exited");
-
- }
- AddWhoWas(user);
- }
-
- FOREACH_MOD OnUserDisconnect(user);
-
- /* push the socket on a stack of sockets due to be closed at the next opportunity */
- if (user->fd > -1)
- {
-#ifdef USE_KQUEUE
- struct kevent ke;
- EV_SET(&ke, user->fd, EVFILT_READ, EV_DELETE, 0, 0, NULL);
- int i = kevent(kq, &ke, 1, 0, 0, NULL);
- if (i == -1)
- {
- log(DEBUG,"kqueue: Failed to remove user from queue!");
- }
-#endif
-#ifdef USE_EPOLL
- struct epoll_event ev;
- ev.events = EPOLLIN | EPOLLET;
- ev.data.fd = user->fd;
- int i = epoll_ctl(ep, EPOLL_CTL_DEL, user->fd, &ev);
- if (i < 0)
- {
- log(DEBUG,"epoll: List deletion failure!");
- }
-#endif
- user->CloseSocket();
- }
-
- if (iter != clientlist.end())
- {
- clientlist.erase(iter);
- }
-
- if (user->registered == 7) {
- purge_empty_chans(user);
- }
- if (user->fd > -1)
- fd_ref_table[user->fd] = NULL;
- delete user;
-}
-
-void handle_who(char **parameters, int pcnt, userrec *user)
-{
- chanrec* Ptr = NULL;
- char tmp[10];
-
- /* theres more to do here, but for now just close the socket */
- if (pcnt == 1)
- {
- if ((!strcmp(parameters[0],"0")) || (!strcmp(parameters[0],"*")))
- {
- if (user->chans[0].channel)
- {
- int n_list = 0;
- for (user_hash::const_iterator i = clientlist.begin(); i != clientlist.end(); i++)
- {
- Ptr = i->second->chans[0].channel;
- // suggested by phidjit and FCS
- if ((!common_channels(user,i->second)) && (isnick(i->second->nick)))
- {
- // Bug Fix #29
- strcpy(tmp, "");
- if (strcmp(i->second->awaymsg, "")) {
- strlcat(tmp, "G", 9);
- } else {
- strlcat(tmp, "H", 9);
- }
- if (strchr(i->second->modes,'o')) { strlcat(tmp, "*", 9); }
- WriteServ(user->fd,"352 %s %s %s %s %s %s %s :0 %s",user->nick, Ptr ? Ptr->name : "*", i->second->ident, i->second->dhost, i->second->server, i->second->nick, tmp, i->second->fullname);
- n_list++;
- if (n_list > MaxWhoResults)
- {
- WriteServ(user->fd,"523 %s WHO :Command aborted: More results than configured limit",user->nick);
- break;
- }
- }
- }
- }
- if (Ptr)
- {
- WriteServ(user->fd,"315 %s %s :End of /WHO list.",user->nick , parameters[0]);
- }
- else
- {
- WriteServ(user->fd,"315 %s %s :End of /WHO list.",user->nick, parameters[0]);
- }
- return;
- }
- if (parameters[0][0] == '#')
- {
- Ptr = FindChan(parameters[0]);
- if (Ptr)
- {
- int n_list = 0;
- for (user_hash::const_iterator i = clientlist.begin(); i != clientlist.end(); i++)
- {
- if ((has_channel(i->second,Ptr)) && (isnick(i->second->nick)))
- {
- // Fix Bug #29 - Part 2..
- strcpy(tmp, "");
- if (strcmp(i->second->awaymsg, "")) {
- strlcat(tmp, "G", 9);
- } else {
- strlcat(tmp, "H", 9);
- }
- if (strchr(i->second->modes,'o')) { strlcat(tmp, "*", 9); }
- strlcat(tmp, cmode(i->second, Ptr),5);
- WriteServ(user->fd,"352 %s %s %s %s %s %s %s :0 %s",user->nick, Ptr->name, i->second->ident, i->second->dhost, i->second->server, i->second->nick, tmp, i->second->fullname);
- n_list++;
- if (n_list > MaxWhoResults)
- {
- WriteServ(user->fd,"523 %s WHO :Command aborted: More results than configured limit",user->nick);
- break;
- }
-
- }
- }
- WriteServ(user->fd,"315 %s %s :End of /WHO list.",user->nick, parameters[0]);
- }
- else
- {
- WriteServ(user->fd,"401 %s %s :No such nick/channel",user->nick, parameters[0]);
- }
- }
- else
- {
- userrec* u = Find(parameters[0]);
- if (u)
- {
- // Bug Fix #29 -- Part 29..
- strcpy(tmp, "");
- if (strcmp(u->awaymsg, "")) {
- strlcat(tmp, "G" ,9);
- } else {
- strlcat(tmp, "H" ,9);
- }
- if (strchr(u->modes,'o')) { strlcat(tmp, "*" ,9); }
- WriteServ(user->fd,"352 %s %s %s %s %s %s %s :0 %s",user->nick, u->chans[0].channel ? u->chans[0].channel->name
- : "*", u->ident, u->dhost, u->server, u->nick, tmp, u->fullname);
- }
- WriteServ(user->fd,"315 %s %s :End of /WHO list.",user->nick, parameters[0]);
- }
- }
- if (pcnt == 2)
- {
- if ((!strcmp(parameters[0],"0")) || (!strcmp(parameters[0],"*")) && (!strcmp(parameters[1],"o")))
- {
- for (std::vector<userrec*>::iterator i = all_opers.begin(); i != all_opers.end(); i++)
- {
- // If i were a rich man.. I wouldn't need to me making these bugfixes..
- // But i'm a poor bastard with nothing better to do.
- userrec* oper = *i;
- strcpy(tmp, "");
- if (strcmp(oper->awaymsg, "")) {
- strlcat(tmp, "G" ,9);
- } else {
- strlcat(tmp, "H" ,9);
- }
- WriteServ(user->fd,"352 %s %s %s %s %s %s %s* :0 %s", user->nick, oper->chans[0].channel ? oper->chans[0].channel->name
- : "*", oper->ident, oper->dhost, oper->server, oper->nick, tmp, oper->fullname);
- }
- WriteServ(user->fd,"315 %s %s :End of /WHO list.",user->nick, parameters[0]);
- return;
- }
- }
-}
-
-void handle_wallops(char **parameters, int pcnt, userrec *user)
-{
- WriteWallOps(user,false,"%s",parameters[0]);
- FOREACH_MOD OnWallops(user,parameters[0]);
-}
-
-void handle_list(char **parameters, int pcnt, userrec *user)
-{
- WriteServ(user->fd,"321 %s Channel :Users Name",user->nick);
- for (chan_hash::const_iterator i = chanlist.begin(); i != chanlist.end(); i++)
- {
- // if the channel is not private/secret, OR the user is on the channel anyway
- if (((!(i->second->binarymodes & CM_PRIVATE)) && (!(i->second->binarymodes & CM_SECRET))) || (has_channel(user,i->second)))
- {
- WriteServ(user->fd,"322 %s %s %d :[+%s] %s",user->nick,i->second->name,usercount_i(i->second),chanmodes(i->second),i->second->topic);
- }
- }
- WriteServ(user->fd,"323 %s :End of channel list.",user->nick);
-}
-
-
-void handle_rehash(char **parameters, int pcnt, userrec *user)
-{
- WriteServ(user->fd,"382 %s %s :Rehashing",user->nick,CleanFilename(CONFIG_FILE));
- std::string parameter = "";
- if (pcnt)
- {
- parameter = parameters[0];
- }
- else
- {
- WriteOpers("%s is rehashing config file %s",user->nick,CleanFilename(CONFIG_FILE));
- ReadConfig(false,user);
- }
- FOREACH_MOD OnRehash(parameter);
-}
-
-void handle_lusers(char **parameters, int pcnt, userrec *user)
-{
- // this lusers command shows one server at all times because
- // a protocol module must override it to show those stats.
- WriteServ(user->fd,"251 %s :There are %d users and %d invisible on 1 server",user->nick,usercnt()-usercount_invisible(),usercount_invisible());
- WriteServ(user->fd,"252 %s %d :operator(s) online",user->nick,usercount_opers());
- WriteServ(user->fd,"253 %s %d :unknown connections",user->nick,usercount_unknown());
- WriteServ(user->fd,"254 %s %d :channels formed",user->nick,chancount());
- WriteServ(user->fd,"254 %s :I have %d clients and 0 servers",user->nick,local_count());
-}
-
-void handle_admin(char **parameters, int pcnt, userrec *user)
-{
- WriteServ(user->fd,"256 %s :Administrative info for %s",user->nick,ServerName);
- WriteServ(user->fd,"257 %s :Name - %s",user->nick,AdminName);
- WriteServ(user->fd,"258 %s :Nickname - %s",user->nick,AdminNick);
- WriteServ(user->fd,"258 %s :E-Mail - %s",user->nick,AdminEmail);
-}
-
-void handle_ping(char **parameters, int pcnt, userrec *user)
-{
- WriteServ(user->fd,"PONG %s :%s",ServerName,parameters[0]);
-}
-
-void handle_pong(char **parameters, int pcnt, userrec *user)
-{
- // set the user as alive so they survive to next ping
- user->lastping = 1;
-}
-
-void handle_motd(char **parameters, int pcnt, userrec *user)
-{
- ShowMOTD(user);
-}
-
-void handle_rules(char **parameters, int pcnt, userrec *user)
-{
- ShowRULES(user);
-}
-
-void handle_user(char **parameters, int pcnt, userrec *user)
-{
- if (user->registered < 3)
- {
- if (isident(parameters[0]) == 0) {
- // This kinda Sucks, According to the RFC thou, its either this,
- // or "You have already registered" :p -- Craig
- WriteServ(user->fd,"461 %s USER :Not enough parameters",user->nick);
- }
- else {
- /* We're not checking ident, but I'm not sure I like the idea of '~' prefixing.. */
- /* XXX - Should this IDENTMAX + 1 be IDENTMAX - 1? Ok, users.h has it defined as
- * char ident[IDENTMAX+2]; - WTF?
- */
- snprintf(user->ident, IDENTMAX+1, "~%s", parameters[0]);
- strlcpy(user->fullname,parameters[3],MAXGECOS);
- user->registered = (user->registered | 1);
- }
- }
- else
- {
- WriteServ(user->fd,"462 %s :You may not reregister",user->nick);
- return;
- }
- /* parameters 2 and 3 are local and remote hosts, ignored when sent by client connection */
- if (user->registered == 3)
- {
- /* user is registered now, bit 0 = USER command, bit 1 = sent a NICK command */
- FOREACH_MOD OnUserRegister(user);
- ConnectUser(user);
- }
-}
-
-void handle_userhost(char **parameters, int pcnt, userrec *user)
-{
- char Return[MAXBUF],junk[MAXBUF];
- snprintf(Return,MAXBUF,"302 %s :",user->nick);
- for (int i = 0; i < pcnt; i++)
- {
- userrec *u = Find(parameters[i]);
- if (u)
- {
- if (strchr(u->modes,'o'))
- {
- snprintf(junk,MAXBUF,"%s*=+%s@%s ",u->nick,u->ident,u->host);
- strlcat(Return,junk,MAXBUF);
- }
- else
- {
- snprintf(junk,MAXBUF,"%s=+%s@%s ",u->nick,u->ident,u->host);
- strlcat(Return,junk,MAXBUF);
- }
- }
- }
- WriteServ(user->fd,Return);
-}
-
-
-void handle_ison(char **parameters, int pcnt, userrec *user)
-{
- char Return[MAXBUF];
- snprintf(Return,MAXBUF,"303 %s :",user->nick);
- for (int i = 0; i < pcnt; i++)
- {
- userrec *u = Find(parameters[i]);
- if (u)
- {
- strlcat(Return,u->nick,MAXBUF);
- strlcat(Return," ",MAXBUF);
- }
- }
- WriteServ(user->fd,Return);
-}
-
-
-void handle_away(char **parameters, int pcnt, userrec *user)
-{
- if (pcnt)
- {
- strlcpy(user->awaymsg,parameters[0],MAXAWAY);
- WriteServ(user->fd,"306 %s :You have been marked as being away",user->nick);
- }
- else
- {
- strlcpy(user->awaymsg,"",MAXAWAY);
- WriteServ(user->fd,"305 %s :You are no longer marked as being away",user->nick);
- }
-}