+
+bool CommandParser::ReloadCommand(const char* cmd, User* user)
+{
+ char filename[MAXBUF];
+ char commandname[MAXBUF];
+ int y = 0;
+
+ for (const char* x = cmd; *x; x++, y++)
+ commandname[y] = toupper(*x);
+
+ commandname[y] = 0;
+
+ SharedObjectList::iterator command = RFCCommands.find(commandname);
+
+ if (command != RFCCommands.end())
+ {
+ Command* cmdptr = cmdlist.find(commandname)->second;
+ cmdlist.erase(cmdlist.find(commandname));
+
+ for (char* x = commandname; *x; x++)
+ *x = tolower(*x);
+
+
+ delete cmdptr;
+ dlclose(command->second);
+ RFCCommands.erase(command);
+
+ snprintf(filename, MAXBUF, "cmd_%s.so", commandname);
+ const char* err = this->LoadCommand(filename);
+ if (err)
+ {
+ if (user)
+ user->WriteServ("NOTICE %s :*** Error loading 'cmd_%s.so': %s", user->nick, cmd, err);
+ return false;
+ }
+
+ return true;
+ }
+
+ return false;
+}
+
+CmdResult cmd_reload::Handle(const char** parameters, int pcnt, User *user)
+{
+ user->WriteServ("NOTICE %s :*** Reloading command '%s'",user->nick, parameters[0]);
+ if (ServerInstance->Parser->ReloadCommand(parameters[0], user))
+ {
+ user->WriteServ("NOTICE %s :*** Successfully reloaded command '%s'", user->nick, parameters[0]);
+ ServerInstance->WriteOpers("*** RELOAD: %s reloaded the '%s' command.", user->nick, parameters[0]);
+ return CMD_SUCCESS;
+ }
+ else
+ {
+ user->WriteServ("NOTICE %s :*** Could not reload command '%s' -- fix this problem, then /REHASH as soon as possible!", user->nick, parameters[0]);
+ return CMD_FAILURE;
+ }
+}
+
+const char* CommandParser::LoadCommand(const char* name)
+{
+ char filename[MAXBUF];
+ void* h;
+ Command* (*cmd_factory_func)(InspIRCd*);
+
+ /* Command already exists? Succeed silently - this is needed for REHASH */
+ if (RFCCommands.find(name) != RFCCommands.end())
+ {
+ ServerInstance->Log(DEBUG,"Not reloading command %s/%s, it already exists", LIBRARYDIR, name);
+ return NULL;
+ }
+
+ snprintf(filename, MAXBUF, "%s/%s", LIBRARYDIR, name);
+ h = dlopen(filename, RTLD_NOW | RTLD_GLOBAL);
+
+ if (!h)
+ {
+ const char* n = dlerror();
+ ServerInstance->Log(SPARSE, "Error loading core command %s: %s", name, n);
+ return n;
+ }
+
+ if (this->FindSym((void **)&cmd_factory_func, h, name))
+ {
+ Command* newcommand = cmd_factory_func(ServerInstance);
+ this->CreateCommand(newcommand, h);
+ }
+ return NULL;
+}
+
+void CommandParser::SetupCommandTable(User* user)
+{
+ RFCCommands.clear();
+
+ if (!user)
+ {
+ printf("\nLoading core commands");
+ fflush(stdout);
+ }
+
+ DIR* library = opendir(LIBRARYDIR);
+ if (library)
+ {
+ dirent* entry = NULL;
+ while ((entry = readdir(library)))
+ {
+ if (match(entry->d_name, "cmd_*.so"))
+ {
+ if (!user)
+ {
+ printf(".");
+ fflush(stdout);
+ }
+ const char* err = this->LoadCommand(entry->d_name);
+ if (err)
+ {
+ if (user)
+ {
+ user->WriteServ("NOTICE %s :*** Failed to load core command %s: %s", user->nick, entry->d_name, err);
+ }
+ else
+ {
+ printf("Error loading %s: %s", entry->d_name, err);
+ exit(EXIT_STATUS_BADHANDLER);
+ }
+ }
+ }
+ }
+ closedir(library);
+ if (!user)
+ printf("\n");
+ }
+
+ if (cmdlist.find("RELOAD") == cmdlist.end())
+ this->CreateCommand(new cmd_reload(ServerInstance));
+}
+
+int CommandParser::TranslateUIDs(TranslateType to, const std::string &source, std::string &dest)
+{
+ User* user = NULL;
+ std::string item;
+ int translations = 0;
+ dest.clear();
+
+ switch (to)
+ {
+ case TR_NICK:
+ /* Translate single nickname */
+ user = ServerInstance->FindNick(source);
+ if (user)
+ {
+ dest = user->uuid;
+ translations++;
+ }
+ else
+ dest = source;
+ break;
+ case TR_NICKLIST:
+ {
+ /* Translate comma seperated list of nicknames */
+ irc::commasepstream items(source);
+ while (items.GetToken(item))
+ {
+ user = ServerInstance->FindNick(item);
+ if (user)
+ {
+ dest.append(user->uuid);
+ translations++;
+ }
+ else
+ dest.append(item);
+ dest.append(",");
+ }
+ if (!dest.empty())
+ dest.erase(dest.end() - 1);
+ }
+ break;
+ case TR_SPACENICKLIST:
+ {
+ /* Translate space seperated list of nicknames */
+ irc::spacesepstream items(source);
+ while (items.GetToken(item))
+ {
+ user = ServerInstance->FindNick(item);
+ if (user)
+ {
+ dest.append(user->uuid);
+ translations++;
+ }
+ else
+ dest.append(item);
+ dest.append(" ");
+ }
+ if (!dest.empty())
+ dest.erase(dest.end() - 1);
+ }
+ break;
+ case TR_END:
+ case TR_TEXT:
+ default:
+ /* Do nothing */
+ dest = source;
+ break;
+ }
+
+ return translations;
+}
+