1 /* +------------------------------------+
2 * | Inspire Internet Relay Chat Daemon |
3 * +------------------------------------+
5 * Inspire is copyright (C) 2002-2004 ChatSpike-Dev.
7 * <brain@chatspike.net>
8 * <Craig@chatspike.net>
10 * Written by Craig Edwards, Craig McLure, and others.
11 * This program is free but copyrighted software; see
12 * the file COPYING for details.
14 * ---------------------------------------------------
19 #include "inspircd_config.h"
21 #include "inspircd_io.h"
24 #include <sys/errno.h>
28 #include <ext/hash_map>
36 #include "connection.h"
47 #include "inspstring.h"
48 #include "helperfuncs.h"
53 extern std::vector<Module*> modules;
54 extern ServerConfig *Config;
55 extern InspIRCd* ServerInstance;
57 extern char lowermap[255];
58 static char list[MAXBUF];
59 extern userrec* fd_ref_table[65536];
60 static char already_sent[65536];
61 extern std::vector<userrec*> all_opers;
62 extern user_hash clientlist;
63 extern chan_hash chanlist;
64 extern Module* IOHookModule;
66 void log(int level,char *text, ...)
70 if (level < Config->LogLevel)
72 char textbuffer[MAXBUF];
73 timeinfo = localtime(&TIME);
78 va_start (argsPtr, text);
79 vsnprintf(textbuffer, MAXBUF, text, argsPtr);
81 strlcpy(b,asctime(timeinfo),MAXBUF);
82 b[24] = ':'; // we know this is the end of the time string
84 fprintf(Config->log_file,"%s %s\n",b,textbuffer);
87 // nofork enabled? display it on terminal too
88 printf("%s %s\n",b,textbuffer);
93 void readfile(file_cache &F, const char* fname)
98 log(DEBUG,"readfile: loading %s",fname);
100 file = fopen(fname,"r");
105 fgets(linebuf,sizeof(linebuf),file);
106 linebuf[strlen(linebuf)-1]='\0';
113 F.push_back(linebuf);
120 log(DEBUG,"readfile: failed to load file: %s",fname);
122 log(DEBUG,"readfile: loaded %s, %lu lines",fname,(unsigned long)F.size());
125 void Write(int sock,char *text, ...)
131 log(DEFAULT,"*** BUG *** Write was given an invalid parameter");
135 char textbuffer[MAXBUF],tb[MAXBUF];
136 va_start (argsPtr, text);
137 vsnprintf(textbuffer, MAXBUF, text, argsPtr);
139 int bytes = snprintf(tb,MAXBUF,"%s\r\n",textbuffer);
141 if (fd_ref_table[sock])
145 IOHookModule->OnRawSocketWrite(sock,tb,bytes);
149 fd_ref_table[sock]->AddWriteBuf(tb);
151 ServerInstance->stats->statsSent += bytes;
153 else log(DEFAULT,"ERROR! attempted write to a user with no fd_ref_table entry!!!");
156 /* write a server formatted numeric response to a single socket */
158 void WriteServ(int sock, char* text, ...)
164 log(DEFAULT,"*** BUG *** WriteServ was given an invalid parameter");
168 va_start (argsPtr, text);
169 char textbuffer[MAXBUF],tb[MAXBUF];
170 vsnprintf(textbuffer, MAXBUF, text, argsPtr);
172 int bytes = snprintf(tb,MAXBUF,":%s %s\r\n",Config->ServerName,textbuffer);
174 if (fd_ref_table[sock])
178 IOHookModule->OnRawSocketWrite(sock,tb,bytes);
182 fd_ref_table[sock]->AddWriteBuf(tb);
184 ServerInstance->stats->statsSent += bytes;
186 else log(DEFAULT,"ERROR! attempted write to a user with no fd_ref_table entry!!!");
189 /* write text from an originating user to originating user */
191 void WriteFrom(int sock, userrec *user,char* text, ...)
195 if ((!text) || (!user))
197 log(DEFAULT,"*** BUG *** WriteFrom was given an invalid parameter");
201 va_start (argsPtr, text);
202 char textbuffer[MAXBUF],tb[MAXBUF];
203 vsnprintf(textbuffer, MAXBUF, text, argsPtr);
205 int bytes = snprintf(tb,MAXBUF,":%s!%s@%s %s\r\n",user->nick,user->ident,user->dhost,textbuffer);
207 if (fd_ref_table[sock])
211 IOHookModule->OnRawSocketWrite(sock,tb,bytes);
215 fd_ref_table[sock]->AddWriteBuf(tb);
217 ServerInstance->stats->statsSent += bytes;
219 else log(DEFAULT,"ERROR! attempted write to a user with no fd_ref_table entry!!!");
222 /* write text to an destination user from a source user (e.g. user privmsg) */
224 void WriteTo(userrec *source, userrec *dest,char *data, ...)
226 if ((!dest) || (!data))
228 log(DEFAULT,"*** BUG *** WriteTo was given an invalid parameter");
231 if (dest->fd == FD_MAGIC_NUMBER)
233 char textbuffer[MAXBUF],tb[MAXBUF];
235 va_start (argsPtr, data);
236 vsnprintf(textbuffer, MAXBUF, data, argsPtr);
240 // if no source given send it from the server.
243 WriteServ(dest->fd,":%s %s",Config->ServerName,textbuffer);
247 WriteFrom(dest->fd,source,"%s",textbuffer);
251 /* write formatted text from a source user to all users on a channel
252 * including the sender (NOT for privmsg, notice etc!) */
254 void WriteChannel(chanrec* Ptr, userrec* user, char* text, ...)
256 if ((!Ptr) || (!user) || (!text))
258 log(DEFAULT,"*** BUG *** WriteChannel was given an invalid parameter");
261 char textbuffer[MAXBUF];
263 va_start (argsPtr, text);
264 vsnprintf(textbuffer, MAXBUF, text, argsPtr);
267 std::vector<char*> *ulist = Ptr->GetUsers();
268 unsigned int x = ulist->size();
269 for (unsigned int j = 0; j < x; j++)
271 char* o = (*ulist)[j];
272 userrec* otheruser = (userrec*)o;
273 if (otheruser->fd != FD_MAGIC_NUMBER)
274 WriteTo(user,otheruser,"%s",textbuffer);
278 /* write formatted text from a source user to all users on a channel
279 * including the sender (NOT for privmsg, notice etc!) doesnt send to
280 * users on remote servers */
282 void WriteChannelLocal(chanrec* Ptr, userrec* user, char* text, ...)
284 if ((!Ptr) || (!text))
286 log(DEFAULT,"*** BUG *** WriteChannel was given an invalid parameter");
289 char textbuffer[MAXBUF];
291 va_start (argsPtr, text);
292 vsnprintf(textbuffer, MAXBUF, text, argsPtr);
295 std::vector<char*> *ulist = Ptr->GetUsers();
296 unsigned int x = ulist->size();
297 for (unsigned int j = 0; j < x; j++)
299 char* o = (*ulist)[j];
300 userrec* otheruser = (userrec*)o;
301 if ((otheruser->fd != FD_MAGIC_NUMBER) && (otheruser->fd != -1) && (otheruser != user))
305 WriteServ(otheruser->fd,"%s",textbuffer);
309 WriteTo(user,otheruser,"%s",textbuffer);
315 void WriteChannelWithServ(char* ServName, chanrec* Ptr, char* text, ...)
317 if ((!Ptr) || (!text))
319 log(DEFAULT,"*** BUG *** WriteChannelWithServ was given an invalid parameter");
322 char textbuffer[MAXBUF];
324 va_start (argsPtr, text);
325 vsnprintf(textbuffer, MAXBUF, text, argsPtr);
329 std::vector<char*> *ulist = Ptr->GetUsers();
330 unsigned int x = ulist->size();
331 for (unsigned int j = 0; j < x; j++)
333 char* o = (*ulist)[j];
334 userrec* otheruser = (userrec*)o;
335 if (otheruser->fd != FD_MAGIC_NUMBER)
336 WriteServ(otheruser->fd,"%s",textbuffer);
340 /* write formatted text from a source user to all users on a channel except
341 * for the sender (for privmsg etc) */
343 void ChanExceptSender(chanrec* Ptr, userrec* user, char* text, ...)
345 if ((!Ptr) || (!user) || (!text))
347 log(DEFAULT,"*** BUG *** ChanExceptSender was given an invalid parameter");
350 char textbuffer[MAXBUF];
352 va_start (argsPtr, text);
353 vsnprintf(textbuffer, MAXBUF, text, argsPtr);
356 std::vector<char*> *ulist = Ptr->GetUsers();
357 unsigned int x = ulist->size();
358 for (unsigned int j = 0; j < x; j++)
360 char* o = (*ulist)[j];
361 userrec* otheruser = (userrec*)o;
362 if ((otheruser->fd != FD_MAGIC_NUMBER) && (user != otheruser))
363 WriteFrom(otheruser->fd,user,"%s",textbuffer);
367 std::string GetServerDescription(char* servername)
369 std::string description = "";
370 FOREACH_MOD OnGetServerDescription(servername,description);
371 if (description != "")
377 return Config->ServerDesc; // not a remote server that can be found, it must be me.
381 /* write a formatted string to all users who share at least one common
382 * channel, including the source user e.g. for use in NICK */
384 void WriteCommon(userrec *u, char* text, ...)
388 log(DEFAULT,"*** BUG *** WriteCommon was given an invalid parameter");
392 if (u->registered != 7) {
393 log(DEFAULT,"*** BUG *** WriteCommon on an unregistered user");
397 char textbuffer[MAXBUF];
399 va_start (argsPtr, text);
400 vsnprintf(textbuffer, MAXBUF, text, argsPtr);
403 // FIX: Stops a message going to the same person more than once
404 memset(&already_sent,0,MAXCLIENTS);
406 bool sent_to_at_least_one = false;
408 unsigned int y = u->chans.size();
409 for (unsigned int i = 0; i < y; i++)
411 if (u->chans[i].channel)
413 std::vector<char*> *ulist = u->chans[i].channel->GetUsers();
414 unsigned int x = ulist->size();
415 for (unsigned int j = 0; j < x; j++)
417 char* o = (*ulist)[j];
418 userrec* otheruser = (userrec*)o;
419 if ((otheruser->fd > -1) && (!already_sent[otheruser->fd]))
421 already_sent[otheruser->fd] = 1;
422 WriteFrom(otheruser->fd,u,"%s",textbuffer);
423 sent_to_at_least_one = true;
428 // if the user was not in any channels, no users will receive the text. Make sure the user
429 // receives their OWN message for WriteCommon
430 if (!sent_to_at_least_one)
432 WriteFrom(u->fd,u,"%s",textbuffer);
436 /* write a formatted string to all users who share at least one common
437 * channel, NOT including the source user e.g. for use in QUIT */
439 void WriteCommonExcept(userrec *u, char* text, ...)
443 log(DEFAULT,"*** BUG *** WriteCommon was given an invalid parameter");
447 if (u->registered != 7) {
448 log(DEFAULT,"*** BUG *** WriteCommon on an unregistered user");
452 char textbuffer[MAXBUF];
454 va_start (argsPtr, text);
455 vsnprintf(textbuffer, MAXBUF, text, argsPtr);
458 memset(&already_sent,0,MAXCLIENTS);
460 unsigned int y = u->chans.size();
461 for (unsigned int i = 0; i < y; i++)
463 if (u->chans[i].channel)
465 std::vector<char*> *ulist = u->chans[i].channel->GetUsers();
466 unsigned int x = ulist->size();
467 for (unsigned int j = 0; j < x; j++)
469 char* o = (*ulist)[j];
470 userrec* otheruser = (userrec*)o;
473 if ((otheruser->fd > -1) && (!already_sent[otheruser->fd]))
475 already_sent[otheruser->fd] = 1;
476 WriteFrom(otheruser->fd,u,"%s",textbuffer);
484 void WriteOpers(char* text, ...)
488 log(DEFAULT,"*** BUG *** WriteOpers was given an invalid parameter");
492 char textbuffer[MAXBUF];
494 va_start (argsPtr, text);
495 vsnprintf(textbuffer, MAXBUF, text, argsPtr);
498 for (std::vector<userrec*>::iterator i = all_opers.begin(); i != all_opers.end(); i++)
501 if ((a) && (a->fd != FD_MAGIC_NUMBER))
503 if (strchr(a->modes,'s'))
505 // send server notices to all with +s
506 WriteServ(a->fd,"NOTICE %s :%s",a->nick,textbuffer);
512 void ServerNoticeAll(char* text, ...)
517 char textbuffer[MAXBUF];
519 va_start (argsPtr, text);
520 vsnprintf(textbuffer, MAXBUF, text, argsPtr);
523 for (user_hash::const_iterator i = clientlist.begin(); i != clientlist.end(); i++)
525 if ((i->second) && (i->second->fd != FD_MAGIC_NUMBER))
527 WriteServ(i->second->fd,"NOTICE $%s :%s",Config->ServerName,textbuffer);
532 void ServerPrivmsgAll(char* text, ...)
537 char textbuffer[MAXBUF];
539 va_start (argsPtr, text);
540 vsnprintf(textbuffer, MAXBUF, text, argsPtr);
543 for (user_hash::const_iterator i = clientlist.begin(); i != clientlist.end(); i++)
545 if ((i->second) && (i->second->fd != FD_MAGIC_NUMBER))
547 WriteServ(i->second->fd,"PRIVMSG $%s :%s",Config->ServerName,textbuffer);
552 void WriteMode(const char* modes, int flags, const char* text, ...)
554 if ((!text) || (!modes) || (!flags))
556 log(DEFAULT,"*** BUG *** WriteMode was given an invalid parameter");
560 char textbuffer[MAXBUF];
562 va_start (argsPtr, text);
563 vsnprintf(textbuffer, MAXBUF, text, argsPtr);
565 int modelen = strlen(modes);
567 for (user_hash::const_iterator i = clientlist.begin(); i != clientlist.end(); i++)
569 if ((i->second) && (i->second->fd != FD_MAGIC_NUMBER))
571 bool send_to_user = false;
576 for (int n = 0; n < modelen; n++)
578 if (!hasumode(i->second,modes[n]))
580 send_to_user = false;
585 else if (flags == WM_OR)
587 send_to_user = false;
588 for (int n = 0; n < modelen; n++)
590 if (hasumode(i->second,modes[n]))
600 WriteServ(i->second->fd,"NOTICE %s :%s",i->second->nick,textbuffer);
606 void NoticeAll(userrec *source, bool local_only, char* text, ...)
608 if ((!text) || (!source))
610 log(DEFAULT,"*** BUG *** NoticeAll was given an invalid parameter");
614 char textbuffer[MAXBUF];
616 va_start (argsPtr, text);
617 vsnprintf(textbuffer, MAXBUF, text, argsPtr);
620 for (user_hash::const_iterator i = clientlist.begin(); i != clientlist.end(); i++)
622 if ((i->second) && (i->second->fd != FD_MAGIC_NUMBER))
624 WriteFrom(i->second->fd,source,"NOTICE $* :%s",textbuffer);
631 void WriteWallOps(userrec *source, bool local_only, char* text, ...)
633 if ((!text) || (!source))
635 log(DEFAULT,"*** BUG *** WriteOpers was given an invalid parameter");
639 char textbuffer[MAXBUF];
641 va_start (argsPtr, text);
642 vsnprintf(textbuffer, MAXBUF, text, argsPtr);
645 for (user_hash::const_iterator i = clientlist.begin(); i != clientlist.end(); i++)
647 if ((i->second) && (i->second->fd != FD_MAGIC_NUMBER))
649 if (strchr(i->second->modes,'w'))
651 WriteTo(source,i->second,"WALLOPS :%s",textbuffer);
657 /* convert a string to lowercase. Note following special circumstances
658 * taken from RFC 1459. Many "official" server branches still hold to this
659 * rule so i will too;
661 * Because of IRC's scandanavian origin, the characters {}| are
662 * considered to be the lower case equivalents of the characters []\,
663 * respectively. This is a critical issue when determining the
664 * equivalence of two nicknames.
667 void strlower(char *n)
671 for (char* t = n; *t; t++)
672 *t = lowermap[(unsigned)*t];
676 /* Find a user record by nickname and return a pointer to it */
678 userrec* Find(std::string nick)
680 user_hash::iterator iter = clientlist.find(nick);
682 if (iter == clientlist.end())
683 /* Couldn't find it */
689 /* find a channel record by channel name and return a pointer to it */
691 chanrec* FindChan(const char* chan)
695 log(DEFAULT,"*** BUG *** Findchan was given an invalid parameter");
699 chan_hash::iterator iter = chanlist.find(chan);
701 if (iter == chanlist.end())
702 /* Couldn't find it */
709 long GetMaxBans(char* name)
712 for (int count = 0; count < Config->ConfValueEnum("banlist",&Config->config_f); count++)
714 Config->ConfValue("banlist","chan",count,CM,&Config->config_f);
717 Config->ConfValue("banlist","limit",count,CM,&Config->config_f);
724 void purge_empty_chans(userrec* u)
729 // firstly decrement the count on each channel
730 for (unsigned int f = 0; f < u->chans.size(); f++)
732 if (u->chans[f].channel)
734 u->chans[f].channel->DelUser((char*)u);
738 for (unsigned int i = 0; i < u->chans.size(); i++)
740 if (u->chans[i].channel)
742 if (!usercount(u->chans[i].channel))
744 chan_hash::iterator i2 = chanlist.find(u->chans[i].channel->name);
745 /* kill the record */
746 if (i2 != chanlist.end())
748 log(DEBUG,"del_channel: destroyed: %s",i2->second->name);
753 u->chans[i].channel = NULL;
758 log(DEBUG,"skipped purge for %s",u->chans[i].channel->name);
762 log(DEBUG,"completed channel purge, killed %lu",(unsigned long)purge);
768 char* chanmodes(chanrec *chan)
770 static char scratch[MAXBUF];
771 static char sparam[MAXBUF];
772 char* offset = scratch;
776 log(DEFAULT,"*** BUG *** chanmodes was given an invalid parameter");
783 if (chan->binarymodes & CM_NOEXTERNAL)
785 if (chan->binarymodes & CM_TOPICLOCK)
791 if (chan->binarymodes & CM_INVITEONLY)
793 if (chan->binarymodes & CM_MODERATED)
795 if (chan->binarymodes & CM_SECRET)
797 if (chan->binarymodes & CM_PRIVATE)
800 snprintf(sparam,MAXBUF," %s",chan->key);
804 sprintf(foo," %lu",(unsigned long)chan->limit);
805 strlcat(sparam,foo,MAXBUF);
807 if (*chan->custom_modes)
809 for (char* t = chan->custom_modes; *t; t++)
811 for (int z = 0; chan->custom_modes[z]; z++)
813 std::string extparam = chan->GetModeParameter(chan->custom_modes[z]);
816 strlcat(sparam," ",MAXBUF);
817 strlcat(sparam,extparam.c_str(),MAXBUF);
821 /* Null terminate scratch */
823 strlcat(scratch,sparam,MAXMODES);
828 /* compile a userlist of a channel into a string, each nick seperated by
829 * spaces and op, voice etc status shown as @ and + */
831 void userlist(userrec *user,chanrec *c)
835 log(DEFAULT,"*** BUG *** userlist was given an invalid parameter");
839 snprintf(list,MAXBUF,"353 %s = %s :", user->nick, c->name);
841 std::vector<char*> *ulist = c->GetUsers();
842 for (unsigned int i = 0; i < ulist->size(); i++)
844 char* o = (*ulist)[i];
845 userrec* otheruser = (userrec*)o;
846 if ((!has_channel(user,c)) && (strchr(otheruser->modes,'i')))
848 /* user is +i, and source not on the channel, does not show
849 * nick in NAMES list */
852 strlcat(list,cmode(otheruser,c),MAXBUF);
853 strlcat(list,otheruser->nick,MAXBUF);
854 strlcat(list," ",MAXBUF);
855 if (strlen(list)>(480-NICKMAX))
857 /* list overflowed into
858 * multiple numerics */
859 WriteServ(user->fd,"%s",list);
860 snprintf(list,MAXBUF,"353 %s = %s :", user->nick, c->name);
863 /* if whats left in the list isnt empty, send it */
864 if (list[strlen(list)-1] != ':')
866 WriteServ(user->fd,"%s",list);
870 /* return a count of the users on a specific channel accounting for
871 * invisible users who won't increase the count. e.g. for /LIST */
873 int usercount_i(chanrec *c)
879 log(DEFAULT,"*** BUG *** usercount_i was given an invalid parameter");
883 for (user_hash::const_iterator i = clientlist.begin(); i != clientlist.end(); i++)
887 if (has_channel(i->second,c))
889 if (isnick(i->second->nick))
891 if ((!has_channel(i->second,c)) && (strchr(i->second->modes,'i')))
893 /* user is +i, and source not on the channel, does not show
894 * nick in NAMES list */
902 log(DEBUG,"usercount_i: %s %lu",c->name,(unsigned long)count);
907 int usercount(chanrec *c)
911 log(DEFAULT,"*** BUG *** usercount was given an invalid parameter");
914 int count = c->GetUserCounter();
915 log(DEBUG,"usercount: %s %lu",c->name,(unsigned long)count);
920 // looks up a users password for their connection class (<ALLOW>/<DENY> tags)
922 char* Passwd(userrec *user)
924 for (ClassVector::iterator i = Config->Classes.begin(); i != Config->Classes.end(); i++)
926 if ((i->type == CC_ALLOW) && match(user->host,i->host))
934 bool IsDenied(userrec *user)
936 for (ClassVector::iterator i = Config->Classes.begin(); i != Config->Classes.end(); i++)
938 if ((i->type == CC_DENY) && match(user->host,i->host))
949 /* sends out an error notice to all connected clients (not to be used
952 void send_error(char *s)
954 log(DEBUG,"send_error: %s",s);
955 for (user_hash::const_iterator i = clientlist.begin(); i != clientlist.end(); i++)
957 if (IS_LOCAL(i->second))
959 if (i->second->registered == 7)
961 WriteServ(i->second->fd,"NOTICE %s :%s",i->second->nick,s);
965 // fix - unregistered connections receive ERROR, not NOTICE
966 Write(i->second->fd,"ERROR :%s",s);
972 void Error(int status)
974 signal (SIGALRM, SIG_IGN);
975 signal (SIGPIPE, SIG_IGN);
976 signal (SIGTERM, SIG_IGN);
977 signal (SIGABRT, SIG_IGN);
978 signal (SIGSEGV, SIG_IGN);
979 signal (SIGURG, SIG_IGN);
980 signal (SIGKILL, SIG_IGN);
981 log(DEFAULT,"*** fell down a pothole in the road to perfection ***");
982 send_error("Error! Segmentation fault! save meeeeeeeeeeeeee *splat!*");
986 // this function counts all users connected, wether they are registered or NOT.
989 return clientlist.size();
992 // this counts only registered users, so that the percentages in /MAP don't mess up when users are sitting in an unregistered state
993 int registered_usercount(void)
996 for (user_hash::const_iterator i = clientlist.begin(); i != clientlist.end(); i++)
998 if (i->second->registered == 7) c++;
1003 int usercount_invisible(void)
1006 for (user_hash::const_iterator i = clientlist.begin(); i != clientlist.end(); i++)
1008 if ((isnick(i->second->nick)) && (strchr(i->second->modes,'i'))) c++;
1013 int usercount_opers(void)
1016 for (user_hash::const_iterator i = clientlist.begin(); i != clientlist.end(); i++)
1018 if ((isnick(i->second->nick)) && (strchr(i->second->modes,'o'))) c++;
1023 int usercount_unknown(void)
1027 for (user_hash::const_iterator i = clientlist.begin(); i != clientlist.end(); i++)
1029 if ((i->second->fd > -1) && (i->second->registered != 7))
1035 long chancount(void)
1037 return chanlist.size();
1043 for (user_hash::const_iterator i = clientlist.begin(); i != clientlist.end(); i++)
1045 if ((isnick(i->second->nick)) && (i->second->fd > -1)) c++;
1050 void ShowMOTD(userrec *user)
1052 static char mbuf[MAXBUF];
1053 static char crud[MAXBUF];
1054 std::string WholeMOTD = "";
1055 if (!Config->MOTD.size())
1057 WriteServ(user->fd,"422 %s :Message of the day file is missing.",user->nick);
1060 snprintf(crud,MAXBUF,":%s 372 %s :- ", Config->ServerName, user->nick);
1061 snprintf(mbuf,MAXBUF,":%s 375 %s :- %s message of the day\r\n", Config->ServerName, user->nick, Config->ServerName);
1062 WholeMOTD = WholeMOTD + mbuf;
1063 for (unsigned int i = 0; i < Config->MOTD.size(); i++)
1064 WholeMOTD = WholeMOTD + std::string(crud) + Config->MOTD[i].c_str() + std::string("\r\n");
1065 snprintf(mbuf,MAXBUF,":%s 376 %s :End of message of the day.\r\n", Config->ServerName, user->nick);
1066 WholeMOTD = WholeMOTD + mbuf;
1067 // only one write operation
1070 IOHookModule->OnRawSocketWrite(user->fd,(char*)WholeMOTD.c_str(),WholeMOTD.length());
1074 user->AddWriteBuf(WholeMOTD);
1076 ServerInstance->stats->statsSent += WholeMOTD.length();
1079 void ShowRULES(userrec *user)
1081 if (!Config->RULES.size())
1083 WriteServ(user->fd,"NOTICE %s :Rules file is missing.",user->nick);
1086 WriteServ(user->fd,"NOTICE %s :%s rules",user->nick,Config->ServerName);
1087 for (unsigned int i = 0; i < Config->RULES.size(); i++)
1088 WriteServ(user->fd,"NOTICE %s :%s",user->nick,Config->RULES[i].c_str());
1089 WriteServ(user->fd,"NOTICE %s :End of %s rules.",user->nick,Config->ServerName);
1092 // this returns 1 when all modules are satisfied that the user should be allowed onto the irc server
1093 // (until this returns true, a user will block in the waiting state, waiting to connect up to the
1094 // registration timeout maximum seconds)
1095 bool AllModulesReportReady(userrec* user)
1097 for (int i = 0; i <= MODCOUNT; i++)
1099 int res = modules[i]->OnCheckReady(user);
1106 bool DirValid(char* dirandfile)
1109 char buffer[MAXBUF], otherdir[MAXBUF];
1110 strlcpy(work,dirandfile,MAXBUF);
1111 int p = strlen(work);
1112 // we just want the dir
1122 // Get the current working directory
1123 if( getcwd( buffer, MAXBUF ) == NULL )
1126 if( getcwd( otherdir, MAXBUF ) == NULL )
1129 if (strlen(otherdir) >= strlen(work))
1131 otherdir[strlen(work)] = '\0';
1132 if (!strcmp(otherdir,work))
1141 std::string GetFullProgDir(char** argv, int argc)
1144 char buffer[MAXBUF], otherdir[MAXBUF];
1145 strlcpy(work,argv[0],MAXBUF);
1146 int p = strlen(work);
1147 // we just want the dir
1157 // Get the current working directory
1158 if( getcwd( buffer, MAXBUF ) == NULL )
1161 if( getcwd( otherdir, MAXBUF ) == NULL )