00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #include "inspircd.h"
00017 #include "xline.h"
00018 #include "exitcodes.h"
00019
00020 std::string InspIRCd::GetServerDescription(const char* servername)
00021 {
00022 std::string description;
00023
00024 FOREACH_MOD_I(this,I_OnGetServerDescription,OnGetServerDescription(servername,description));
00025
00026 if (!description.empty())
00027 {
00028 return description;
00029 }
00030 else
00031 {
00032
00033 return Config->ServerDesc;
00034 }
00035 }
00036
00037
00038 User* InspIRCd::FindNick(const std::string &nick)
00039 {
00040 if (!nick.empty() && isdigit(*nick.begin()))
00041 return FindUUID(nick);
00042
00043 user_hash::iterator iter = this->Users->clientlist->find(nick);
00044
00045 if (iter == this->Users->clientlist->end())
00046
00047 return NULL;
00048
00049 return iter->second;
00050 }
00051
00052 User* InspIRCd::FindNick(const char* nick)
00053 {
00054 if (isdigit(*nick))
00055 return FindUUID(nick);
00056
00057 user_hash::iterator iter = this->Users->clientlist->find(nick);
00058
00059 if (iter == this->Users->clientlist->end())
00060 return NULL;
00061
00062 return iter->second;
00063 }
00064
00065 User* InspIRCd::FindNickOnly(const std::string &nick)
00066 {
00067 user_hash::iterator iter = this->Users->clientlist->find(nick);
00068
00069 if (iter == this->Users->clientlist->end())
00070 return NULL;
00071
00072 return iter->second;
00073 }
00074
00075 User* InspIRCd::FindNickOnly(const char* nick)
00076 {
00077 user_hash::iterator iter = this->Users->clientlist->find(nick);
00078
00079 if (iter == this->Users->clientlist->end())
00080 return NULL;
00081
00082 return iter->second;
00083 }
00084
00085 User *InspIRCd::FindUUID(const std::string &uid)
00086 {
00087 return FindUUID(uid.c_str());
00088 }
00089
00090 User *InspIRCd::FindUUID(const char *uid)
00091 {
00092 user_hash::iterator finduuid = this->Users->uuidlist->find(uid);
00093
00094 if (finduuid == this->Users->uuidlist->end())
00095 return NULL;
00096
00097 return finduuid->second;
00098 }
00099
00100
00101 Channel* InspIRCd::FindChan(const char* chan)
00102 {
00103 chan_hash::iterator iter = chanlist->find(chan);
00104
00105 if (iter == chanlist->end())
00106
00107 return NULL;
00108
00109 return iter->second;
00110 }
00111
00112 Channel* InspIRCd::FindChan(const std::string &chan)
00113 {
00114 chan_hash::iterator iter = chanlist->find(chan);
00115
00116 if (iter == chanlist->end())
00117
00118 return NULL;
00119
00120 return iter->second;
00121 }
00122
00123
00124 void InspIRCd::SendError(const std::string &s)
00125 {
00126 for (std::vector<User*>::const_iterator i = this->Users->local_users.begin(); i != this->Users->local_users.end(); i++)
00127 {
00128 if ((*i)->registered == REG_ALL)
00129 {
00130 (*i)->WriteServ("NOTICE %s :%s",(*i)->nick.c_str(),s.c_str());
00131 }
00132 else
00133 {
00134
00135 (*i)->Write("ERROR :" + s);
00136 }
00137
00138
00139
00140
00141 (*i)->FlushWriteBuf();
00142 }
00143 }
00144
00145
00146 long InspIRCd::ChannelCount()
00147 {
00148 return chanlist->size();
00149 }
00150
00151 bool InspIRCd::IsValidMask(const std::string &mask)
00152 {
00153 char* dest = (char*)mask.c_str();
00154 int exclamation = 0;
00155 int atsign = 0;
00156
00157 for (char* i = dest; *i; i++)
00158 {
00159
00160 if (*i < 32 || *i > 126)
00161 {
00162 return false;
00163 }
00164
00165 switch (*i)
00166 {
00167 case '!':
00168 exclamation++;
00169 break;
00170 case '@':
00171 atsign++;
00172 break;
00173 }
00174 }
00175
00176
00177 if (exclamation != 1 || atsign != 1)
00178 return false;
00179
00180 return true;
00181 }
00182
00183
00184 bool IsChannelHandler::Call(const char *chname, size_t max)
00185 {
00186 const char *c = chname + 1;
00187
00188
00189 if (!chname || *chname != '#')
00190 {
00191 return false;
00192 }
00193
00194 while (*c)
00195 {
00196 switch (*c)
00197 {
00198 case ' ':
00199 case ',':
00200 case 7:
00201 return false;
00202 }
00203
00204 c++;
00205 }
00206
00207 size_t len = c - chname;
00208
00209 if (len > max)
00210 {
00211 return false;
00212 }
00213
00214 return true;
00215 }
00216
00217
00218 bool IsNickHandler::Call(const char* n, size_t max)
00219 {
00220 if (!n || !*n)
00221 return false;
00222
00223 unsigned int p = 0;
00224 for (const char* i = n; *i; i++, p++)
00225 {
00226 if ((*i >= 'A') && (*i <= '}'))
00227 {
00228
00229 continue;
00230 }
00231
00232 if ((((*i >= '0') && (*i <= '9')) || (*i == '-')) && (i > n))
00233 {
00234
00235 continue;
00236 }
00237
00238
00239 return false;
00240 }
00241
00242
00243 return (p < max);
00244 }
00245
00246
00247 bool IsIdentHandler::Call(const char* n)
00248 {
00249 if (!n || !*n)
00250 return false;
00251
00252 for (const char* i = n; *i; i++)
00253 {
00254 if ((*i >= 'A') && (*i <= '}'))
00255 {
00256 continue;
00257 }
00258
00259 if (((*i >= '0') && (*i <= '9')) || (*i == '-') || (*i == '.'))
00260 {
00261 continue;
00262 }
00263
00264 return false;
00265 }
00266
00267 return true;
00268 }
00269
00270 bool IsSIDHandler::Call(const std::string &str)
00271 {
00272
00273
00274
00275 return ((str.length() == 3) && isdigit(str[0]) &&
00276 ((str[1] >= 'A' && str[1] <= 'Z') || isdigit(str[1])) &&
00277 ((str[2] >= 'A' && str[2] <= 'Z') || isdigit(str[2])));
00278 }
00279
00280
00281 bool InspIRCd::OpenLog(char**, int)
00282 {
00283
00284 if (Config->nofork)
00285 {
00286 this->Logs->SetupNoFork();
00287 }
00288 Config->MyDir = Config->GetFullProgDir();
00289
00290
00291 const char* home = getenv("HOME");
00292 if (!home)
00293 {
00294
00295 home = getenv("USERPROFILE");
00296 if (!home)
00297 {
00298
00299 Config->logpath = "./startup.log";
00300 }
00301 }
00302
00303 if (!Config->writelog) return true;
00304
00305 if (!*this->LogFileName)
00306 {
00307 if (Config->logpath.empty())
00308 {
00309 std::string path = std::string(home) + "/.inspircd";
00310
00311
00312
00313 if (!mkdir(path.c_str(), 0700) || errno == EEXIST)
00314 {
00315
00316 Config->logpath = path + "/startup.log";
00317 FILE* fd = fopen(Config->logpath.c_str(), "a+");
00318 if (!fd)
00319 {
00320
00321 if (errno == ENOTDIR)
00322
00323 printf("\nWARNING: Unable to create directory: %s (Exists and is not a directory)\n", path.c_str());
00324 else
00325
00326 printf("\nWARNING: No write access to %s (%s)\n", Config->logpath.c_str(), strerror(errno));
00327 Config->logpath = "./startup.log";
00328 }
00329 else
00330 {
00331 Config->log_file = fd;
00332 }
00333 }
00334 else
00335 {
00336
00337 Config->logpath = "./startup.log";
00338 printf("\nWARNING: Unable to create directory: %s (%s)\n", path.c_str(), strerror(errno));
00339 }
00340 }
00341
00342 if (!Config->log_file)
00343 Config->log_file = fopen(Config->logpath.c_str(),"a+");
00344 }
00345 else
00346 {
00347 Config->log_file = fopen(this->LogFileName,"a+");
00348 }
00349
00350 if (!Config->log_file)
00351 {
00352 return false;
00353 }
00354
00355 FileWriter* fw = new FileWriter(this, Config->log_file);
00356 FileLogStream *f = new FileLogStream(this, (Config->forcedebug ? DEBUG : DEFAULT), fw);
00357
00358 this->Logs->AddLogType("*", f, true);
00359
00360 return true;
00361 }
00362
00363 void InspIRCd::CheckRoot()
00364 {
00365 if (geteuid() == 0)
00366 {
00367 printf("WARNING!!! You are running an irc server as ROOT!!! DO NOT DO THIS!!!\n\n");
00368 this->Logs->Log("STARTUP",DEFAULT,"Cant start as root");
00369 Exit(EXIT_STATUS_ROOT);
00370 }
00371 }
00372
00373 void InspIRCd::CheckDie()
00374 {
00375 if (*Config->DieValue)
00376 {
00377 printf("WARNING: %s\n\n",Config->DieValue);
00378 this->Logs->Log("CONFIG",DEFAULT,"Died because of <die> tag: %s",Config->DieValue);
00379 Exit(EXIT_STATUS_DIETAG);
00380 }
00381 }
00382
00383 void InspIRCd::SendWhoisLine(User* user, User* dest, int numeric, const std::string &text)
00384 {
00385 std::string copy_text = text;
00386
00387 int MOD_RESULT = 0;
00388 FOREACH_RESULT_I(this, I_OnWhoisLine, OnWhoisLine(user, dest, numeric, copy_text));
00389
00390 if (!MOD_RESULT)
00391 user->WriteServ("%d %s", numeric, copy_text.c_str());
00392 }
00393
00394 void InspIRCd::SendWhoisLine(User* user, User* dest, int numeric, const char* format, ...)
00395 {
00396 char textbuffer[MAXBUF];
00397 va_list argsPtr;
00398 va_start (argsPtr, format);
00399 vsnprintf(textbuffer, MAXBUF, format, argsPtr);
00400 va_end(argsPtr);
00401
00402 this->SendWhoisLine(user, dest, numeric, std::string(textbuffer));
00403 }
00404
00408 long InspIRCd::Duration(const std::string &str)
00409 {
00410 unsigned char multiplier = 0;
00411 long total = 0;
00412 long times = 1;
00413 long subtotal = 0;
00414
00415
00416 for (std::string::const_reverse_iterator i = str.rbegin(); i != str.rend(); ++i)
00417 {
00418
00419 if ((*i >= '0') && (*i <= '9'))
00420 {
00421 subtotal = subtotal + ((*i - '0') * times);
00422 times = times * 10;
00423 }
00424 else
00425 {
00426
00427
00428
00429
00430 if (subtotal)
00431 total += subtotal * duration_multi[multiplier];
00432
00433
00434 subtotal = 0;
00435 multiplier = *i;
00436 times = 1;
00437 }
00438 }
00439 if (multiplier)
00440 {
00441 total += subtotal * duration_multi[multiplier];
00442 subtotal = 0;
00443 }
00444
00445 return total + subtotal;
00446 }
00447
00448 bool InspIRCd::ULine(const char* sserver)
00449 {
00450 if (!sserver)
00451 return false;
00452 if (!*sserver)
00453 return true;
00454
00455 return (Config->ulines.find(sserver) != Config->ulines.end());
00456 }
00457
00458 bool InspIRCd::SilentULine(const char* sserver)
00459 {
00460 std::map<irc::string,bool>::iterator n = Config->ulines.find(sserver);
00461 if (n != Config->ulines.end())
00462 return n->second;
00463 else return false;
00464 }
00465
00466 std::string InspIRCd::TimeString(time_t curtime)
00467 {
00468 return std::string(ctime(&curtime),24);
00469 }
00470
00471
00472 void InspIRCd::AddExtBanChar(char c)
00473 {
00474 std::string &tok = Config->data005;
00475 std::string::size_type ebpos;
00476
00477 if ((ebpos = tok.find(" EXTBAN=,")) == std::string::npos)
00478 {
00479 tok.append(" EXTBAN=,");
00480 tok.push_back(c);
00481 }
00482 else
00483 tok.insert(ebpos + 9, 1, c);
00484 }