+ return false;
+ }
+
+ if (newnick)
+ {
+ strlcpy(this->nick, newnick, NICKMAX - 1);
+ }
+ if (this->registered == REG_ALL)
+ {
+ const char* pars[1];
+ pars[0] = nick;
+ std::string cmd = "NICK";
+ ServerInstance->Parser->CallHandler(cmd, pars, 1, this);
+ }
+ return true;
+}
+
+void userrec::SetSockAddr(int protocol_family, const char* ip, int port)
+{
+ switch (protocol_family)
+ {
+#ifdef SUPPORT_IP6LINKS
+ case AF_INET6:
+ {
+ ServerInstance->Log(DEBUG,"Set inet6 protocol address");
+ sockaddr_in6* sin = new sockaddr_in6;
+ sin->sin6_family = AF_INET6;
+ sin->sin6_port = port;
+ inet_pton(AF_INET6, ip, &sin->sin6_addr);
+ this->ip = (sockaddr*)sin;
+ }
+ break;
+#endif
+ case AF_INET:
+ {
+ ServerInstance->Log(DEBUG,"Set inet4 protocol address");
+ sockaddr_in* sin = new sockaddr_in;
+ sin->sin_family = AF_INET;
+ sin->sin_port = port;
+ inet_pton(AF_INET, ip, &sin->sin_addr);
+ this->ip = (sockaddr*)sin;
+ }
+ break;
+ default:
+ ServerInstance->Log(DEBUG,"Ut oh, I dont know protocol %d to be set on '%s'!", protocol_family, this->nick);
+ break;
+ }
+}
+
+int userrec::GetPort()
+{
+ if (this->ip == NULL)
+ return 0;
+
+ switch (this->GetProtocolFamily())
+ {
+#ifdef SUPPORT_IP6LINKS
+ case AF_INET6:
+ {
+ sockaddr_in6* sin = (sockaddr_in6*)this->ip;
+ return sin->sin6_port;
+ }
+ break;
+#endif
+ case AF_INET:
+ {
+ sockaddr_in* sin = (sockaddr_in*)this->ip;
+ return sin->sin_port;
+ }
+ break;
+ default:
+ ServerInstance->Log(DEBUG,"Ut oh, '%s' has an unknown protocol family!",this->nick);
+ break;
+ }
+ return 0;
+}
+
+int userrec::GetProtocolFamily()
+{
+ if (this->ip == NULL)
+ return 0;
+
+ sockaddr_in* sin = (sockaddr_in*)this->ip;
+ return sin->sin_family;
+}
+
+const char* userrec::GetIPString()
+{
+ static char buf[1024];
+ static char temp[1024];
+
+ if (this->ip == NULL)
+ return "";
+
+ switch (this->GetProtocolFamily())
+ {
+#ifdef SUPPORT_IP6LINKS
+ case AF_INET6:
+ {
+ sockaddr_in6* sin = (sockaddr_in6*)this->ip;
+ inet_ntop(sin->sin6_family, &sin->sin6_addr, buf, sizeof(buf));
+ /* IP addresses starting with a : on irc are a Bad Thing (tm) */
+ if (*buf == ':')
+ {
+ strlcpy(&temp[1], buf, sizeof(temp));
+ *temp = '0';
+ return temp;
+ }
+ return buf;
+ }
+ break;
+#endif
+ case AF_INET:
+ {
+ sockaddr_in* sin = (sockaddr_in*)this->ip;
+ inet_ntop(sin->sin_family, &sin->sin_addr, buf, sizeof(buf));
+ return buf;
+ }
+ break;
+ default:
+ ServerInstance->Log(DEBUG,"Ut oh, '%s' has an unknown protocol family!",this->nick);
+ break;
+ }
+ return "";
+}
+
+const char* userrec::GetIPString(char* buf)
+{
+ static char temp[1024];
+
+ if (this->ip == NULL)
+ {
+ *buf = 0;
+ return buf;
+ }
+
+ switch (this->GetProtocolFamily())
+ {
+#ifdef SUPPORT_IP6LINKS
+ case AF_INET6:
+ {
+ sockaddr_in6* sin = (sockaddr_in6*)this->ip;
+ inet_ntop(sin->sin6_family, &sin->sin6_addr, buf, sizeof(buf));
+ /* IP addresses starting with a : on irc are a Bad Thing (tm) */
+ if (*buf == ':')
+ {
+ strlcpy(&temp[1], buf, sizeof(temp));
+ *temp = '0';
+ strlcpy(buf, temp, sizeof(temp));
+ }
+ return buf;
+ }
+ break;
+#endif
+ case AF_INET:
+ {
+ sockaddr_in* sin = (sockaddr_in*)this->ip;
+ inet_ntop(sin->sin_family, &sin->sin_addr, buf, sizeof(buf));
+ return buf;
+ }
+ break;
+
+ default:
+ ServerInstance->Log(DEBUG,"Ut oh, '%s' has an unknown protocol family!",this->nick);
+ break;
+ }
+ return "";
+}
+
+
+void userrec::Write(const std::string &text)
+{
+ if ((this->fd < 0) || (this->fd > MAX_DESCRIPTORS))
+ return;
+
+ std::string crlf = text;
+ crlf.append("\r\n");
+
+ if (ServerInstance->Config->GetIOHook(this->GetPort()))
+ {
+ try
+ {
+ ServerInstance->Config->GetIOHook(this->GetPort())->OnRawSocketWrite(this->fd, crlf.data(), crlf.length());
+ }
+ catch (ModuleException& modexcept)
+ {
+ ServerInstance->Log(DEBUG,"Module exception caught: %s",modexcept.GetReason());
+ }
+ }
+ else
+ {
+ this->AddWriteBuf(crlf);
+ }
+ ServerInstance->stats->statsSent += crlf.length();
+}
+
+/** Write()
+ */
+void userrec::Write(const char *text, ...)
+{
+ va_list argsPtr;
+ char textbuffer[MAXBUF];
+
+ va_start(argsPtr, text);
+ vsnprintf(textbuffer, MAXBUF, text, argsPtr);
+ va_end(argsPtr);
+
+ this->Write(std::string(textbuffer));
+}
+
+void userrec::WriteServ(const std::string& text)
+{
+ char textbuffer[MAXBUF];
+
+ snprintf(textbuffer,MAXBUF,":%s %s",ServerInstance->Config->ServerName,text.c_str());
+ this->Write(std::string(textbuffer));
+}
+
+/** WriteServ()
+ * Same as Write(), except `text' is prefixed with `:server.name '.
+ */
+void userrec::WriteServ(const char* text, ...)
+{
+ va_list argsPtr;
+ char textbuffer[MAXBUF];
+
+ va_start(argsPtr, text);
+ vsnprintf(textbuffer, MAXBUF, text, argsPtr);
+ va_end(argsPtr);
+
+ this->WriteServ(std::string(textbuffer));
+}
+
+
+void userrec::WriteFrom(userrec *user, const std::string &text)
+{
+ char tb[MAXBUF];
+
+ snprintf(tb,MAXBUF,":%s %s",user->GetFullHost(),text.c_str());
+
+ this->Write(std::string(tb));
+}
+
+
+/* write text from an originating user to originating user */
+
+void userrec::WriteFrom(userrec *user, const char* text, ...)
+{
+ va_list argsPtr;
+ char textbuffer[MAXBUF];
+
+ va_start(argsPtr, text);
+ vsnprintf(textbuffer, MAXBUF, text, argsPtr);
+ va_end(argsPtr);
+
+ this->WriteFrom(user, std::string(textbuffer));
+}
+
+
+/* write text to an destination user from a source user (e.g. user privmsg) */
+
+void userrec::WriteTo(userrec *dest, const char *data, ...)
+{
+ char textbuffer[MAXBUF];
+ va_list argsPtr;
+
+ va_start(argsPtr, data);
+ vsnprintf(textbuffer, MAXBUF, data, argsPtr);
+ va_end(argsPtr);
+
+ this->WriteTo(dest, std::string(textbuffer));
+}
+
+void userrec::WriteTo(userrec *dest, const std::string &data)
+{
+ dest->WriteFrom(this, data);
+}
+
+
+void userrec::WriteCommon(const char* text, ...)
+{
+ char textbuffer[MAXBUF];
+ va_list argsPtr;
+
+ if (this->registered != REG_ALL)