From f62de63955ff77e800360eb140f108b5d2c6c075 Mon Sep 17 00:00:00 2001 From: brain Date: Mon, 19 Dec 2005 18:32:09 +0000 Subject: Design flaw my ass. git-svn-id: http://svn.inspircd.org/repository/trunk/inspircd@2580 e03df62e-2008-0410-955e-edbf42e46eb7 --- docs/module-doc/channels_8cpp-source.html | 559 ------------------------------ 1 file changed, 559 deletions(-) delete mode 100644 docs/module-doc/channels_8cpp-source.html (limited to 'docs/module-doc/channels_8cpp-source.html') diff --git a/docs/module-doc/channels_8cpp-source.html b/docs/module-doc/channels_8cpp-source.html deleted file mode 100644 index 41388ca5d..000000000 --- a/docs/module-doc/channels_8cpp-source.html +++ /dev/null @@ -1,559 +0,0 @@ - - -InspIRCd: channels.cpp Source File - - - -
Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members
- -

channels.cpp

Go to the documentation of this file.
00001 /*       +------------------------------------+
-00002  *       | Inspire Internet Relay Chat Daemon |
-00003  *       +------------------------------------+
-00004  *
-00005  *  Inspire is copyright (C) 2002-2005 ChatSpike-Dev.
-00006  *                       E-mail:
-00007  *                <brain@chatspike.net>
-00008  *                <Craig@chatspike.net>
-00009  *     
-00010  * Written by Craig Edwards, Craig McLure, and others.
-00011  * This program is free but copyrighted software; see
-00012  *            the file COPYING for details.
-00013  *
-00014  * ---------------------------------------------------
-00015  */
-00016 
-00017 using namespace std;
-00018 
-00019 #include "inspircd_config.h"
-00020 #include "inspircd.h"
-00021 #include "inspircd_io.h"
-00022 #include <unistd.h>
-00023 #include <sys/errno.h>
-00024 #include <sys/ioctl.h>
-00025 #include <sys/utsname.h>
-00026 #include <time.h>
-00027 #include <string>
-00028 #ifdef GCC3
-00029 #include <ext/hash_map>
-00030 #else
-00031 #include <hash_map>
-00032 #endif
-00033 #include <map>
-00034 #include <sstream>
-00035 #include <vector>
-00036 #include <deque>
-00037 #include "users.h"
-00038 #include "ctables.h"
-00039 #include "globals.h"
-00040 #include "modules.h"
-00041 #include "dynamic.h"
-00042 #include "commands.h"
-00043 #include "wildcard.h"
-00044 #include "message.h"
-00045 #include "mode.h"
-00046 #include "xline.h"
-00047 #include "inspstring.h"
-00048 #include "helperfuncs.h"
-00049 #include "typedefs.h"
-00050 
-00051 #ifdef GCC3
-00052 #define nspace __gnu_cxx
-00053 #else
-00054 #define nspace std
-00055 #endif
-00056 
-00057 extern ServerConfig* Config;
-00058 
-00059 extern int MODCOUNT;
-00060 extern std::vector<Module*> modules;
-00061 extern std::vector<ircd_module*> factory;
-00062 extern int WHOWAS_STALE;
-00063 extern int WHOWAS_MAX;
-00064 extern time_t TIME;
-00065 extern chan_hash chanlist;
-00066 
-00067 using namespace std;
-00068 
-00069 std::vector<ModeParameter> custom_mode_params;
-00070 
-00071 chanrec* ForceChan(chanrec* Ptr,ucrec &a,userrec* user, int created);
-00072 
-00073 chanrec::chanrec()
-00074 {
-00075         strcpy(name,"");
-00076         strcpy(custom_modes,"");
-00077         strcpy(topic,"");
-00078         strcpy(setby,"");
-00079         strcpy(key,"");
-00080         created = topicset = limit = 0;
-00081         binarymodes = 0;
-00082         internal_userlist.clear();
-00083 }
-00084 
-00085 void chanrec::SetCustomMode(char mode,bool mode_on)
-00086 {
-00087         if (mode_on) {
-00088                 static char m[3];
-00089                 m[0] = mode;
-00090                 m[1] = '\0';
-00091                 if (!strchr(this->custom_modes,mode))
-00092                 {
-00093                         strlcat(custom_modes,m,MAXMODES);
-00094                 }
-00095                 log(DEBUG,"Custom mode %c set",mode);
-00096         }
-00097         else {
-00098 
-00099                 std::string a = this->custom_modes;
-00100                 int pos = a.find(mode);
-00101                 a.erase(pos,1);
-00102                 strncpy(this->custom_modes,a.c_str(),MAXMODES);
-00103 
-00104                 log(DEBUG,"Custom mode %c removed: modelist='%s'",mode,this->custom_modes);
-00105                 this->SetCustomModeParam(mode,"",false);
-00106         }
-00107 }
-00108 
-00109 
-00110 void chanrec::SetCustomModeParam(char mode,char* parameter,bool mode_on)
-00111 {
-00112 
-00113         log(DEBUG,"SetCustomModeParam called");
-00114         ModeParameter M;
-00115         M.mode = mode;
-00116         strlcpy(M.channel,this->name,CHANMAX);
-00117         strlcpy(M.parameter,parameter,MAXBUF);
-00118         if (mode_on)
-00119         {
-00120                 log(DEBUG,"Custom mode parameter %c %s added",mode,parameter);
-00121                 custom_mode_params.push_back(M);
-00122         }
-00123         else
-00124         {
-00125                 if (custom_mode_params.size())
-00126                 {
-00127                         for (vector<ModeParameter>::iterator i = custom_mode_params.begin(); i < custom_mode_params.end(); i++)
-00128                         {
-00129                                 if ((i->mode == mode) && (!strcasecmp(this->name,i->channel)))
-00130                                 {
-00131                                         log(DEBUG,"Custom mode parameter %c %s removed",mode,parameter);
-00132                                         custom_mode_params.erase(i);
-00133                                         return;
-00134                                 }
-00135                         }
-00136                 }
-00137                 log(DEBUG,"*** BUG *** Attempt to remove non-existent mode parameter!");
-00138         }
-00139 }
-00140 
-00141 bool chanrec::IsCustomModeSet(char mode)
-00142 {
-00143         return (strchr(this->custom_modes,mode));
-00144 }
-00145 
-00146 std::string chanrec::GetModeParameter(char mode)
-00147 {
-00148         if (custom_mode_params.size())
-00149         {
-00150                 for (vector<ModeParameter>::iterator i = custom_mode_params.begin(); i < custom_mode_params.end(); i++)
-00151                 {
-00152                         if ((i->mode == mode) && (!strcasecmp(this->name,i->channel)))
-00153                         {
-00154                                 return i->parameter;
-00155                         }
-00156                 }
-00157         }
-00158         return "";
-00159 }
-00160 
-00161 long chanrec::GetUserCounter()
-00162 {
-00163         return (this->internal_userlist.size());
-00164 }
-00165 
-00166 void chanrec::AddUser(char* castuser)
-00167 {
-00168         internal_userlist.push_back(castuser);
-00169         log(DEBUG,"Added casted user to channel's internal list");
-00170 }
-00171 
-00172 void chanrec::DelUser(char* castuser)
-00173 {
-00174         for (std::vector<char*>::iterator a = internal_userlist.begin(); a < internal_userlist.end(); a++)
-00175         {
-00176                 if (*a == castuser)
-00177                 {
-00178                         log(DEBUG,"Removed casted user from channel's internal list");
-00179                         internal_userlist.erase(a);
-00180                         return;
-00181                 }
-00182         }
-00183         log(DEBUG,"BUG BUG BUG! Attempt to remove an uncasted user from the internal list of %s!",name);
-00184 }
-00185 
-00186 std::vector<char*> *chanrec::GetUsers()
-00187 {
-00188         return &internal_userlist;
-00189 }
-00190 
-00191 /* add a channel to a user, creating the record for it if needed and linking
-00192  * it to the user record */
-00193 
-00194 chanrec* add_channel(userrec *user, const char* cn, const char* key, bool override)
-00195 {
-00196         if ((!user) || (!cn))
-00197         {
-00198                 log(DEFAULT,"*** BUG *** add_channel was given an invalid parameter");
-00199                 return 0;
-00200         }
-00201 
-00202         int created = 0;
-00203         char cname[MAXBUF];
-00204         int MOD_RESULT = 0;
-00205         strncpy(cname,cn,CHANMAX);
-00206 
-00207         log(DEBUG,"add_channel: %s %s",user->nick,cname);
-00208 
-00209         chanrec* Ptr = FindChan(cname);
-00210 
-00211         if (!Ptr)
-00212         {
-00213                 if (user->fd > -1)
-00214                 {
-00215                         MOD_RESULT = 0;
-00216                         FOREACH_RESULT(OnUserPreJoin(user,NULL,cname));
-00217                         if (MOD_RESULT == 1)
-00218                                 return NULL;
-00219                 }
-00220                 /* create a new one */
-00221                 chanlist[cname] = new chanrec();
-00222                 strlcpy(chanlist[cname]->name, cname,CHANMAX);
-00223                 chanlist[cname]->binarymodes = CM_TOPICLOCK | CM_NOEXTERNAL;
-00224                 chanlist[cname]->created = TIME;
-00225                 strcpy(chanlist[cname]->topic, "");
-00226                 strncpy(chanlist[cname]->setby, user->nick,NICKMAX);
-00227                 chanlist[cname]->topicset = 0;
-00228                 Ptr = chanlist[cname];
-00229                 log(DEBUG,"add_channel: created: %s",cname);
-00230                 /* set created to 2 to indicate user
-00231                  * is the first in the channel
-00232                  * and should be given ops */
-00233                 created = 2;
-00234         }
-00235         else
-00236         {
-00237                 /* Already on the channel */
-00238                 if (has_channel(user,Ptr))
-00239                         return NULL;
-00240 
-00241                 // remote users are allowed us to bypass channel modes
-00242                 // and bans (used by servers)
-00243                 if (user->fd > -1)
-00244                 {
-00245                         MOD_RESULT = 0;
-00246                         FOREACH_RESULT(OnUserPreJoin(user,Ptr,cname));
-00247                         if (MOD_RESULT == 1)
-00248                         {
-00249                                 return NULL;
-00250                         }
-00251                         else
-00252                         {
-00253                                 if (*Ptr->key)
-00254                                 {
-00255                                         MOD_RESULT = 0;
-00256                                         FOREACH_RESULT(OnCheckKey(user, Ptr, key ? key : ""));
-00257                                         if (!MOD_RESULT)
-00258                                         {
-00259                                                 if (!key)
-00260                                                 {
-00261                                                         log(DEBUG,"add_channel: no key given in JOIN");
-00262                                                         WriteServ(user->fd,"475 %s %s :Cannot join channel (Requires key)",user->nick, Ptr->name);
-00263                                                         return NULL;
-00264                                                 }
-00265                                                 else
-00266                                                 {
-00267                                                         if (strcasecmp(key,Ptr->key))
-00268                                                         {
-00269                                                                 log(DEBUG,"add_channel: bad key given in JOIN");
-00270                                                                 WriteServ(user->fd,"475 %s %s :Cannot join channel (Incorrect key)",user->nick, Ptr->name);
-00271                                                                 return NULL;
-00272                                                         }
-00273                                                 }
-00274                                         }
-00275                                 }
-00276                                 if (Ptr->binarymodes & CM_INVITEONLY)
-00277                                 {
-00278                                         MOD_RESULT = 0;
-00279                                         irc::string xname(Ptr->name);
-00280                                         FOREACH_RESULT(OnCheckInvite(user, Ptr));
-00281                                         if (!MOD_RESULT)
-00282                                         {
-00283                                                 log(DEBUG,"add_channel: channel is +i");
-00284                                                 if (user->IsInvited(xname))
-00285                                                 {
-00286                                                         /* user was invited to channel */
-00287                                                         /* there may be an optional channel NOTICE here */
-00288                                                 }
-00289                                                 else
-00290                                                 {
-00291                                                         WriteServ(user->fd,"473 %s %s :Cannot join channel (Invite only)",user->nick, Ptr->name);
-00292                                                         return NULL;
-00293                                                 }
-00294                                         }
-00295                                         user->RemoveInvite(xname);
-00296                                 }
-00297                                 if (Ptr->limit)
-00298                                 {
-00299                                         MOD_RESULT = 0;
-00300                                         FOREACH_RESULT(OnCheckLimit(user, Ptr));
-00301                                         if (!MOD_RESULT)
-00302                                         {
-00303                                                 if (usercount(Ptr) >= Ptr->limit)
-00304                                                 {
-00305                                                         WriteServ(user->fd,"471 %s %s :Cannot join channel (Channel is full)",user->nick, Ptr->name);
-00306                                                         return NULL;
-00307                                                 }
-00308                                         }
-00309                                 }
-00310                                 if (Ptr->bans.size())
-00311                                 {
-00312                                         log(DEBUG,"add_channel: about to walk banlist");
-00313                                         MOD_RESULT = 0;
-00314                                         FOREACH_RESULT(OnCheckBan(user, Ptr));
-00315                                         if (!MOD_RESULT)
-00316                                         {
-00317                                                 for (BanList::iterator i = Ptr->bans.begin(); i != Ptr->bans.end(); i++)
-00318                                                 {
-00319                                                         if (match(user->GetFullHost(),i->data))
-00320                                                         {
-00321                                                                 WriteServ(user->fd,"474 %s %s :Cannot join channel (You're banned)",user->nick, Ptr->name);
-00322                                                                 return NULL;
-00323                                                         }
-00324                                                 }
-00325                                         }
-00326                                 }
-00327                         }
-00328                 }
-00329                 else
-00330                 {
-00331                         log(DEBUG,"Overridden checks");
-00332                 }
-00333                 created = 1;
-00334         }
-00335 
-00336         log(DEBUG,"Passed channel checks");
-00337 
-00338         for (unsigned int index =0; index < user->chans.size(); index++)
-00339         {
-00340                 if (user->chans[index].channel == NULL)
-00341                 {
-00342                         return ForceChan(Ptr,user->chans[index],user,created);
-00343                 }
-00344         }
-00345         /* XXX: If the user is an oper here, we can just extend their user->chans vector by one
-00346          * and put the channel in here. Same for remote users which are not bound by
-00347          * the channel limits. Otherwise, nope, youre boned.
-00348          */
-00349         if (user->fd < 0)
-00350         {
-00351                 ucrec a;
-00352                 chanrec* c = ForceChan(Ptr,a,user,created);
-00353                 user->chans.push_back(a);
-00354                 return c;
-00355         }
-00356         else if (strchr(user->modes,'o'))
-00357         {
-00358                 /* Oper allows extension up to the OPERMAXCHANS value */
-00359                 if (user->chans.size() < OPERMAXCHANS)
-00360                 {
-00361                         ucrec a;
-00362                         chanrec* c = ForceChan(Ptr,a,user,created);
-00363                         user->chans.push_back(a);
-00364                         return c;
-00365                 }
-00366         }
-00367         log(DEBUG,"add_channel: user channel max exceeded: %s %s",user->nick,cname);
-00368         WriteServ(user->fd,"405 %s %s :You are on too many channels",user->nick, cname);
-00369         return NULL;
-00370 }
-00371 
-00372 chanrec* ForceChan(chanrec* Ptr,ucrec &a,userrec* user, int created)
-00373 {
-00374         if (created == 2)
-00375         {
-00376                 /* first user in is given ops */
-00377                 a.uc_modes = UCMODE_OP;
-00378         }
-00379         else
-00380         {
-00381                 a.uc_modes = 0;
-00382         }
-00383         a.channel = Ptr;
-00384         Ptr->AddUser((char*)user);
-00385         WriteChannel(Ptr,user,"JOIN :%s",Ptr->name);
-00386         log(DEBUG,"Sent JOIN to client");
-00387         if (Ptr->topicset)
-00388         {
-00389                 WriteServ(user->fd,"332 %s %s :%s", user->nick, Ptr->name, Ptr->topic);
-00390                 WriteServ(user->fd,"333 %s %s %s %lu", user->nick, Ptr->name, Ptr->setby, (unsigned long)Ptr->topicset);
-00391         }
-00392         userlist(user,Ptr);
-00393         WriteServ(user->fd,"366 %s %s :End of /NAMES list.", user->nick, Ptr->name);
-00394         FOREACH_MOD OnUserJoin(user,Ptr);
-00395         return Ptr;
-00396 }
-00397 
-00398 /* remove a channel from a users record, and remove the record from memory
-00399  * if the channel has become empty */
-00400 
-00401 chanrec* del_channel(userrec *user, const char* cname, const char* reason, bool local)
-00402 {
-00403         if ((!user) || (!cname))
-00404         {
-00405                 log(DEFAULT,"*** BUG *** del_channel was given an invalid parameter");
-00406                 return NULL;
-00407         }
-00408 
-00409         chanrec* Ptr = FindChan(cname);
-00410 
-00411         if (!Ptr)
-00412                 return NULL;
-00413 
-00414         FOREACH_MOD OnUserPart(user,Ptr);
-00415         log(DEBUG,"del_channel: removing: %s %s",user->nick,Ptr->name);
-00416 
-00417         for (unsigned int i =0; i < user->chans.size(); i++)
-00418         {
-00419                 /* zap it from the channel list of the user */
-00420                 if (user->chans[i].channel == Ptr)
-00421                 {
-00422                         if (reason)
-00423                         {
-00424                                 WriteChannel(Ptr,user,"PART %s :%s",Ptr->name, reason);
-00425                         }
-00426                         else
-00427                         {
-00428                                 WriteChannel(Ptr,user,"PART :%s",Ptr->name);
-00429                         }
-00430                         user->chans[i].uc_modes = 0;
-00431                         user->chans[i].channel = NULL;
-00432                         log(DEBUG,"del_channel: unlinked: %s %s",user->nick,Ptr->name);
-00433                         break;
-00434                 }
-00435         }
-00436 
-00437         Ptr->DelUser((char*)user);
-00438 
-00439         /* if there are no users left on the channel */
-00440         if (!usercount(Ptr))
-00441         {
-00442                 chan_hash::iterator iter = chanlist.find(Ptr->name);
-00443 
-00444                 log(DEBUG,"del_channel: destroying channel: %s",Ptr->name);
-00445 
-00446                 /* kill the record */
-00447                 if (iter != chanlist.end())
-00448                 {
-00449                         log(DEBUG,"del_channel: destroyed: %s",Ptr->name);
-00450                         delete Ptr;
-00451                         chanlist.erase(iter);
-00452                 }
-00453         }
-00454 
-00455         return NULL;
-00456 }
-00457 
-00458 
-00459 void kick_channel(userrec *src,userrec *user, chanrec *Ptr, char* reason)
-00460 {
-00461         if ((!src) || (!user) || (!Ptr) || (!reason))
-00462         {
-00463                 log(DEFAULT,"*** BUG *** kick_channel was given an invalid parameter");
-00464                 return;
-00465         }
-00466 
-00467         if ((!Ptr) || (!user) || (!src))
-00468         {
-00469                 return;
-00470         }
-00471 
-00472         log(DEBUG,"kick_channel: removing: %s %s %s",user->nick,Ptr->name,src->nick);
-00473 
-00474         if (!has_channel(user,Ptr))
-00475         {
-00476                 WriteServ(src->fd,"441 %s %s %s :They are not on that channel",src->nick, user->nick, Ptr->name);
-00477                 return;
-00478         }
-00479 
-00480         int MOD_RESULT = 0;
-00481         FOREACH_RESULT(OnAccessCheck(src,user,Ptr,AC_KICK));
-00482         if ((MOD_RESULT == ACR_DENY) && (!is_uline(src->server)))
-00483                 return;
-00484 
-00485         if ((MOD_RESULT == ACR_DEFAULT) || (!is_uline(src->server)))
-00486         {
-00487                 if ((cstatus(src,Ptr) < STATUS_HOP) || (cstatus(src,Ptr) < cstatus(user,Ptr)))
-00488                 {
-00489                         if (cstatus(src,Ptr) == STATUS_HOP)
-00490                         {
-00491                                 WriteServ(src->fd,"482 %s %s :You must be a channel operator",src->nick, Ptr->name);
-00492                         }
-00493                         else
-00494                         {
-00495                                 WriteServ(src->fd,"482 %s %s :You must be at least a half-operator to change modes on this channel",src->nick, Ptr->name);
-00496                         }
-00497 
-00498                         return;
-00499                 }
-00500         }
-00501 
-00502         if (!is_uline(src->server))
-00503         {
-00504                 MOD_RESULT = 0;
-00505                 FOREACH_RESULT(OnUserPreKick(src,user,Ptr,reason));
-00506                 if (MOD_RESULT)
-00507                         return;
-00508         }
-00509 
-00510         FOREACH_MOD OnUserKick(src,user,Ptr,reason);
-00511 
-00512         for (unsigned int i =0; i < user->chans.size(); i++)
-00513         {
-00514                 /* zap it from the channel list of the user */
-00515                 if (user->chans[i].channel)
-00516                 if (!strcasecmp(user->chans[i].channel->name,Ptr->name))
-00517                 {
-00518                         WriteChannel(Ptr,src,"KICK %s %s :%s",Ptr->name, user->nick, reason);
-00519                         user->chans[i].uc_modes = 0;
-00520                         user->chans[i].channel = NULL;
-00521                         log(DEBUG,"del_channel: unlinked: %s %s",user->nick,Ptr->name);
-00522                         break;
-00523                 }
-00524         }
-00525 
-00526         Ptr->DelUser((char*)user);
-00527 
-00528         /* if there are no users left on the channel */
-00529         if (!usercount(Ptr))
-00530         {
-00531                 chan_hash::iterator iter = chanlist.find(Ptr->name);
-00532 
-00533                 log(DEBUG,"del_channel: destroying channel: %s",Ptr->name);
-00534 
-00535                 /* kill the record */
-00536                 if (iter != chanlist.end())
-00537                 {
-00538                         log(DEBUG,"del_channel: destroyed: %s",Ptr->name);
-00539                         delete Ptr;
-00540                         chanlist.erase(iter);
-00541                 }
-00542         }
-00543 }
-00544 
-00545 
-

Generated on Mon Dec 19 18:05:19 2005 for InspIRCd by  - -doxygen 1.4.4-20050815
- - -- cgit v1.3.1-10-gc9f91