+
+ /* Bad number of parameters? */
+ if (Req->argc != 6)
+ return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG,
+ Client_ID(Client), Req->command);
+
+ nick = Req->argv[0];
+ user = NULL; host = NULL;
+ token = atoi(Req->argv[1]);
+ hops = atoi(Req->argv[4]);
+ info = Req->argv[5];
+
+ /* Validate service name ("nick name") */
+ c = Client_Search(nick);
+ if(c) {
+ /* Nick name collission: disconnect (KILL) both clients! */
+ Log(LOG_ERR, "Server %s introduces already registered service \"%s\"!",
+ Client_ID(Client), nick);
+ Kill_Nick(nick, "Nick collision");
+ return CONNECTED;
+ }
+
+ /* Get the server to which the service is connected */
+ intr_c = Client_GetFromToken(Client, token);
+ if (! intr_c) {
+ Log(LOG_ERR, "Server %s introduces service \"%s\" on unknown server!?",
+ Client_ID(Client), nick);
+ Kill_Nick(nick, "Unknown server");
+ return CONNECTED;
+ }
+
+ /* Get user and host name */
+ ptr = strchr(nick, '@');
+ if (ptr) {
+ *ptr = '\0';
+ host = ++ptr;
+ }
+ if (!host)
+ host = Client_Hostname(intr_c);
+ ptr = strchr(nick, '!');
+ if (ptr) {
+ *ptr = '\0';
+ user = ++ptr;
+ }
+ if (!user)
+ user = nick;
+
+ /* According to RFC 2812/2813 parameter 4 <type> "is currently reserved
+ * for future usage"; but we use it to transfer the modes and check
+ * that the first character is a '+' sign and ignore it otherwise. */
+ modes = (Req->argv[3][0] == '+') ? ++Req->argv[3] : "";
+
+ c = Client_NewRemoteUser(intr_c, nick, hops, user, host,
+ token, modes, info, true);
+ if (! c) {
+ /* Couldn't create client structure, so KILL the service to
+ * keep network status consistent ... */
+ Log(LOG_ALERT, "Can't create client structure! (on connection %d)",
+ Client_Conn(Client));
+ Kill_Nick(nick, "Server error");
+ return CONNECTED;
+ }
+
+ Introduce_Client(Client, c, CLIENT_SERVICE);
+ return CONNECTED;