--- Unreal3.2/src/modules/m_svsmode.c	2006-02-05 16:03:17.000000000 -0200
+++ Unreal3.2-avenger/src/modules/m_svsmode.c	2006-05-29 21:03:48.000000000 -0300
@@ -1,4 +1,5 @@
 /*
+ * vim: set tabstop=2:
  *   IRC - Internet Relay Chat, src/modules/m_svsmode.c
  *   (C) 2001 The UnrealIRCd Team
  *
@@ -28,6 +29,7 @@
 #include "numeric.h"
 #include "msg.h"
 #include "channel.h"
+#include "macros.h"
 #include <time.h>
 #include <sys/stat.h>
 #include <stdio.h>
@@ -401,6 +403,7 @@
 int  what, setflags;
 char *xmsg = show_change ? MSG_SVS2MODE : MSG_SVSMODE;
 char *xtok = show_change ? TOK_SVS2MODE : TOK_SVSMODE;
+short modex_err = 0;
 
 	if (!IsULine(sptr))
 		return 0;
@@ -510,6 +513,36 @@
 					acptr->user->servicestamp = strtoul(parv[3], NULL, 10);
 					break;
 				}
+			case 'x':
+				/* Restore vhost? So restore the generated cloak if applicable. */
+        switch (UHOST_ALLOWED) {
+				case UHALLOW_ALWAYS:
+					goto setmodex;
+				case UHALLOW_NEVER:
+					if (MyClient(acptr))
+					{
+						if (!modex_err) {
+							sendto_one(acptr, ":%s %s %s :*** Setting %cx is disabled", me.name, IsWebTV(acptr) ? "PRIVMSG" : "NOTICE", acptr->name, what == MODE_ADD ? '+' : '-');
+							modex_err = 1;
+						}
+						break;
+					}
+					goto setmodex;
+				case UHALLOW_NOCHANS:
+					if (MyClient(acptr) && acptr->user->joined)
+					{
+						if (!modex_err) {
+							sendto_one(acptr, ":%s %s %s :*** Setting %cx can not be done while you are on channels", me.name, IsWebTV(acptr) ? "PRIVMSG" : "NOTICE", acptr->name, what == MODE_ADD ? '+' : '-');
+							modex_err = 1;
+						}
+						break;
+					}
+					goto setmodex;
+				case UHALLOW_REJOIN:
+					/* Handled later */
+					goto setmodex;
+			  }
+			  break;
 			default:
 				setmodex:
 				for (i = 0; i <= Usermode_highest; i++)
@@ -528,6 +561,55 @@
 				break;
 		} /*switch*/
 
+	if (IsHidden(acptr) && !(setflags & UMODE_HIDE)) {
+		if (acptr->user->virthost) {
+			MyFree(acptr->user->virthost);
+			acptr->user->virthost = NULL;
+		}
+		acptr->user->virthost = (char *)make_virthost(acptr->user->realhost,
+	    acptr->user->virthost, 1);
+		if (!dontspread)
+			sendto_serv_butone_token_opt(cptr, OPT_VHP, acptr->name,
+				MSG_SETHOST, TOK_SETHOST, "%s", acptr->user->virthost);
+		if (UHOST_ALLOWED == UHALLOW_REJOIN) {
+			DYN_LOCAL(char, did_parts, acptr->user->joined);
+			/* LOL, this is ugly ;) */
+			acptr->umodes &= ~UMODE_HIDE;
+			rejoin_doparts(acptr, did_parts);
+			acptr->umodes |= UMODE_HIDE;
+			rejoin_dojoinandmode(acptr, did_parts);
+			if (MyClient(acptr))
+				acptr->since += 7; /* Add fake lag */
+			DYN_FREE(did_parts);
+		}
+	}
+
+	if (!IsHidden(acptr) && (setflags & UMODE_HIDE))
+	{
+		if (UHOST_ALLOWED == UHALLOW_REJOIN)
+		{
+			DYN_LOCAL(char, did_parts, acptr->user->joined);
+			/* LOL, this is ugly ;) */
+			acptr->umodes |= UMODE_HIDE;
+			rejoin_doparts(acptr, did_parts);
+			acptr->umodes &= ~UMODE_HIDE;
+			rejoin_dojoinandmode(acptr, did_parts);
+			if (MyClient(acptr))
+				acptr->since += 7; /* Add fake lag */
+			DYN_FREE(did_parts);
+		}
+		if (acptr->user->virthost)
+		{
+			MyFree(acptr->user->virthost);
+			acptr->user->virthost = NULL;
+		}
+		/* (Re)create the cloaked virthost, because it will be used
+		 * for ban-checking... free+recreate here because it could have
+		 * been a vhost for example. -- Syzop
+		 */
+		acptr->user->virthost = (char *)make_virthost(acptr->user->realhost, acptr->user->virthost, 1);
+	}
+
 	if (parc > 3)
 		sendto_serv_butone_token(cptr, parv[0], xmsg, xtok,
 			"%s %s %s", parv[1], parv[2], parv[3]);
