*/
-#ifndef COMMAND_PARSE_H
-#define COMMAND_PARSE_H
+#pragma once
- /** A list of dll/so files containing the command handlers for the core
- */
- typedef std::map<std::string, void*> SharedObjectList;
-
/** This class handles command management and parsing.
* It allows you to add and remove commands from the map,
* call command handlers by name, and chop up comma seperated
* @param user The user to parse the command for
* @param cmd The command string to process
*/
- bool ProcessCommand(LocalUser *user, std::string &cmd);
+ void ProcessCommand(LocalUser* user, std::string& cmd);
-
-
public:
/** Command list, a hash_map of command names to Command*
*/
std::vector<std::string> whoresults;
std::string initial = "352 " + user->nick + " ";
- char matchtext[MAXBUF];
- bool usingwildcards = false;
-
/* Change '0' into '*' so the wildcard matcher can grok it */
- if (parameters[0] == "0")
- strlcpy(matchtext, "*", MAXBUF);
- else
- strlcpy(matchtext, parameters[0].c_str(), MAXBUF);
+ std::string matchtext = ((parameters[0] == "0") ? "*" : parameters[0]);
- for (const char* check = matchtext; *check; check++)
- {
- if (*check == '*' || *check == '?' || *check == '.')
- {
- usingwildcards = true;
- break;
- }
- }
+ // WHO flags count as a wildcard
- bool usingwildcards = ((parameters.size() > 1) || (matchtext.find_first_of("*?") != std::string::npos));
++ bool usingwildcards = ((parameters.size() > 1) || (matchtext.find_first_of("*?.") != std::string::npos));
if (parameters.size() > 1)
{
std::cout << con_green << "(C) InspIRCd Development Team." << con_reset << std::endl << std::endl;
std::cout << "Developers:" << std::endl;
std::cout << con_green << "\tBrain, FrostyCoolSlug, w00t, Om, Special, peavey" << std::endl;
- std::cout << "\taquanight, psychon, dz, danieldg, jackmcbarn" << con_reset << std::endl << std::endl;
- std::cout << "\taquanight, psychon, dz, danieldg, jackmcbarn" << std::endl;\r
++ std::cout << "\taquanight, psychon, dz, danieldg, jackmcbarn" << std::endl;
+ std::cout << "\tAttila" << con_reset << std::endl << std::endl;
std::cout << "Others:\t\t\t" << con_green << "See /INFO Output" << con_reset << std::endl;
this->Modes = new ModeParser;
if (rv >= 0)
rv = ServerInstance->SE->Listen(this->fd, ServerInstance->Config->MaxConn);
- #ifdef IPV6_V6ONLY
- /* This OS supports IPv6 sockets that can also listen for IPv4
- * connections. If our address is "*" or empty, enable both v4 and v6 to
- * allow for simpler configuration on dual-stack hosts. Otherwise, if it
- * is "::" or an IPv6 address, disable support so that an IPv4 bind will
- * work on the port (by us or another application).
- */
- if (bind_to.sa.sa_family == AF_INET6)
- {
- std::string addr = tag->getString("address");
- const char enable = (addr.empty() || addr == "*") ? 0 : 1;
- setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &enable, sizeof(enable));
- // errors ignored intentionally
- }
- #endif
-
+ int timeout = tag->getInt("defer", 0);
+ if (timeout && !rv)
+ {
+#ifdef USE_TCP_DEFER_ACCEPT
+ setsockopt(fd, IPPROTO_TCP, TCP_DEFER_ACCEPT, &timeout, sizeof(timeout));
+#elif defined USE_SO_ACCEPTFILTER
+ struct accept_filter_arg afa;
+ memset(&afa, 0, sizeof(afa));
+ strcpy(afa.af_name, "dataready");
+ setsockopt(fd, SOL_SOCKET, SO_ACCEPTFILTER, &afa, sizeof(afa));
+#endif
+ }
+
if (rv < 0)
{
int errstore = errno;
ModeAction ModeUserOperator::OnModeChange(User* source, User* dest, Channel*, std::string&, bool adding)
{
/* Only opers can execute this class at all */
- if (!ServerInstance->ULine(source->nick.c_str()) && !ServerInstance->ULine(source->server) && !source->IsOper())
- if (!ServerInstance->ULine(source->server) && !IS_OPER(source))
++ if (!ServerInstance->ULine(source->server) && !source->IsOper())
return MODEACTION_DENY;
/* Not even opers can GIVE the +o mode, only take it away */
LocalStringExt ext;
GeoIP* gi;
- void SetExt(LocalUser* user)
+ std::string* SetExt(LocalUser* user)
{
- const char* c = GeoIP_country_code_by_addr(gi, user->GetIPString());
+ const char* c = GeoIP_country_code_by_addr(gi, user->GetIPString().c_str());
if (!c)
c = "UNK";
if (param < p.size())
{
std::string parm = p[param++];
- char buffer[MAXBUF];
+ std::vector<char> buffer(parm.length() * 2 + 1);
#ifdef PGSQL_HAS_ESCAPECONN
int error;
- PQescapeStringConn(sql, buffer, parm.c_str(), parm.length(), &error);
+ size_t escapedsize = PQescapeStringConn(sql, &buffer[0], parm.data(), parm.length(), &error);
if (error)
- ServerInstance->Logs->Log("m_pgsql", DEBUG, "BUG: Apparently PQescapeStringConn() failed");
+ ServerInstance->Logs->Log("m_pgsql", LOG_DEBUG, "BUG: Apparently PQescapeStringConn() failed");
#else
- PQescapeString (buffer, parm.c_str(), parm.length());
+ size_t escapedsize = PQescapeString(&buffer[0], parm.data(), parm.length());
#endif
- res.append(buffer);
+ res.append(&buffer[0], escapedsize);
}
}
}
if (it != p.end())
{
std::string parm = it->second;
- char buffer[MAXBUF];
+ std::vector<char> buffer(parm.length() * 2 + 1);
#ifdef PGSQL_HAS_ESCAPECONN
int error;
- PQescapeStringConn(sql, buffer, parm.c_str(), parm.length(), &error);
+ size_t escapedsize = PQescapeStringConn(sql, &buffer[0], parm.data(), parm.length(), &error);
if (error)
- ServerInstance->Logs->Log("m_pgsql", DEBUG, "BUG: Apparently PQescapeStringConn() failed");
+ ServerInstance->Logs->Log("m_pgsql", LOG_DEBUG, "BUG: Apparently PQescapeStringConn() failed");
#else
- PQescapeString (buffer, parm.c_str(), parm.length());
+ size_t escapedsize = PQescapeString(&buffer[0], parm.data(), parm.length());
#endif
- res.append(buffer);
+ res.append(&buffer[0], escapedsize);
}
}
}
return str ? str : "UNKNOWN";
}
+ static ssize_t gnutls_pull_wrapper(gnutls_transport_ptr_t session_wrap, void* buffer, size_t size)
+ {
+ issl_session* session = reinterpret_cast<issl_session*>(session_wrap);
+ if (session->socket->GetEventMask() & FD_READ_WILL_BLOCK)
+ {
+ #ifdef _WIN32
+ gnutls_transport_set_errno(session->sess, EAGAIN);
+ #else
+ errno = EAGAIN;
+ #endif
+ return -1;
+ }
+
+ int rv = ServerInstance->SE->Recv(session->socket, reinterpret_cast<char *>(buffer), size, 0);
+
+ #ifdef _WIN32
+ if (rv < 0)
+ {
+ /* Windows doesn't use errno, but gnutls does, so check SocketEngine::IgnoreError()
+ * and then set errno appropriately.
+ * The gnutls library may also have a different errno variable than us, see
+ * gnutls_transport_set_errno(3).
+ */
+ gnutls_transport_set_errno(session->sess, SocketEngine::IgnoreError() ? EAGAIN : errno);
+ }
+ #endif
+
+ if (rv < (int)size)
+ ServerInstance->SE->ChangeEventMask(session->socket, FD_READ_WILL_BLOCK);
+ return rv;
+ }
+
+ static ssize_t gnutls_push_wrapper(gnutls_transport_ptr_t session_wrap, const void* buffer, size_t size)
+ {
+ issl_session* session = reinterpret_cast<issl_session*>(session_wrap);
+ if (session->socket->GetEventMask() & FD_WRITE_WILL_BLOCK)
+ {
+ #ifdef _WIN32
+ gnutls_transport_set_errno(session->sess, EAGAIN);
+ #else
+ errno = EAGAIN;
+ #endif
+ return -1;
+ }
+
+ int rv = ServerInstance->SE->Send(session->socket, reinterpret_cast<const char *>(buffer), size, 0);
+
+ #ifdef _WIN32
+ if (rv < 0)
+ {
+ /* Windows doesn't use errno, but gnutls does, so check SocketEngine::IgnoreError()
+ * and then set errno appropriately.
+ * The gnutls library may also have a different errno variable than us, see
+ * gnutls_transport_set_errno(3).
+ */
+ gnutls_transport_set_errno(session->sess, SocketEngine::IgnoreError() ? EAGAIN : errno);
+ }
+ #endif
+
+ if (rv < (int)size)
+ ServerInstance->SE->ChangeEventMask(session->socket, FD_WRITE_WILL_BLOCK);
+ return rv;
+ }
+
public:
-
ModuleSSLGnuTLS()
: starttls(this), capHandler(this, "tls"), iohook(this, "ssl/gnutls", SERVICE_IOHOOK)
{
*/
class CBan : public XLine
{
-public:
+private:
+ std::string displaytext;
irc::string matchtext;
- CBan(time_t s_time, long d, std::string src, std::string re, std::string ch)
+public:
+ CBan(time_t s_time, long d, const std::string& src, const std::string& re, const std::string& ch)
: XLine(s_time, d, src, re, "CBAN")
{
+ this->displaytext = ch;
this->matchtext = ch.c_str();
}
}
else
{
- length = ServerInstance->Duration(parameters[1]);
+ length = InspIRCd::Duration(parameters[1]);
}
- if (!ServerInstance->IsValidMask(mask.c_str()))
+ if (!ServerInstance->IsValidMask(mask))
{
return CMD_FAILURE;
}
std::vector<HTTPACL> acl_list;
public:
- void ReadConfig()
-
+ void OnRehash(User* user)
{
acl_list.clear();
ConfigTagList acls = ServerInstance->Config->ConfTags("httpdacl");
}
}
- void init()
+ void init() CXX11_OVERRIDE
{
- ReadConfig();
- Implementation eventlist[] = { I_OnEvent };
+ OnRehash(NULL);
+ Implementation eventlist[] = { I_OnEvent, I_OnRehash };
ServerInstance->Modules->Attach(eventlist, this, sizeof(eventlist)/sizeof(Implementation));
}
public:
std::string matchtext;
- Shun(time_t s_time, long d, std::string src, std::string re, std::string shunmask)
+ Shun(time_t s_time, long d, const std::string& src, const std::string& re, const std::string& shunmask)
: XLine(s_time, d, src, re, "SHUN")
+ , matchtext(shunmask)
{
- this->matchtext = shunmask;
}
- ~Shun()
- {
- }
-
bool Matches(User *u)
{
// E: overrides shun
class SVSHold : public XLine
{
public:
- irc::string nickname;
+ std::string nickname;
- SVSHold(time_t s_time, long d, std::string src, std::string re, std::string nick)
+ SVSHold(time_t s_time, long d, const std::string& src, const std::string& re, const std::string& nick)
: XLine(s_time, d, src, re, "SVSHOLD")
{
- this->nickname = nick.c_str();
- }
-
- ~SVSHold()
- {
+ this->nickname = nick;
}
bool Matches(User *u)
User *u = ServerInstance->FindNick(parameters[i]);
if ((u) && (u->registered == REG_ALL))
{
- retbuf = retbuf + u->nick + (IS_OPER(u) ? "*" : "") + "=";
- if (IS_AWAY(u))
+ // Anyone may query their own IP
+ if (u != user)
+ {
+ if (!checked_privs)
+ {
+ // Do not trigger the insufficient priviliges message more than once
+ checked_privs = true;
+ has_privs = user->HasPrivPermission("users/auspex");
+ if (!has_privs)
+ user->WriteNumeric(ERR_NOPRIVILEGES, "%s :Permission Denied - You do not have the required operator privileges",user->nick.c_str());
+ }
+
+ if (!has_privs)
+ continue;
+ }
+
+ retbuf = retbuf + u->nick + (u->IsOper() ? "*" : "") + "=";
+ if (u->IsAway())
retbuf += "-";
else
retbuf += "+";
// overwritten in UserManager::AddUser() with the real iterator so this check
// is only a precaution currently.
if (localuseriter != ServerInstance->Users->local_users.end())
+ {
+ ServerInstance->Users->local_count--;
ServerInstance->Users->local_users.erase(localuseriter);
+ }
else
- ServerInstance->Logs->Log("USERS", DEFAULT, "ERROR: LocalUserIter does not point to a valid entry for " + this->nick);
+ ServerInstance->Logs->Log("USERS", LOG_DEFAULT, "ERROR: LocalUserIter does not point to a valid entry for " + this->nick);
ClearInvites();
eh.cull();
CoreExport int insp_inet_pton(int af, const char *src, void *dst)
{
- sockaddr_in sa;
- int len = sizeof(SOCKADDR);
- int rv = WSAStringToAddressA((LPSTR)src, af, NULL, (LPSOCKADDR)&sa, &len);
- if(rv >= 0)
+ int address_length;
+ sockaddr_storage sa;
+ sockaddr_in* sin = reinterpret_cast<sockaddr_in*>(&sa);
+ sockaddr_in6* sin6 = reinterpret_cast<sockaddr_in6*>(&sa);
+
+ switch (af)
{
- if(WSAGetLastError() == WSAEINVAL)
- rv = 0;
- else
- rv = 1;
+ case AF_INET:
+ address_length = sizeof(sockaddr_in);
+ break;
+ case AF_INET6:
+ address_length = sizeof(sockaddr_in6);
+ break;
+ default:
+ return -1;
}
- memcpy(dst, &sa.sin_addr, sizeof(struct in_addr));
- return rv;
+
+ if (!WSAStringToAddress(static_cast<LPSTR>(const_cast<char *>(src)), af, NULL, reinterpret_cast<LPSOCKADDR>(&sa), &address_length))
+ {
+ switch (af)
+ {
+ case AF_INET:
+ memcpy(dst, &sin->sin_addr, sizeof(in_addr));
+ break;
+ case AF_INET6:
+ memcpy(dst, &sin6->sin6_addr, sizeof(in6_addr));
+ break;
+ }
+ return 1;
+ }
-
++
+ return 0;
}
CoreExport DIR * opendir(const char * path)
// optind++; // Trash this next argument, we won't be needing it.
par = ___argv[optind-1];
}
-- }
++ }
// increment the argument for next time
// optind++;
{
if (__longopts[i].val == -1 || par == 0)
return 1;
--
++
return __longopts[i].val;
-- }
++ }
break;
}
}