+static bool
+Send_Message(CLIENT * Client, REQUEST * Req, int ForceType)
+{
+ CLIENT *cl, *from;
+ CHANNEL *chan;
+
+ assert(Client != NULL);
+ assert(Req != NULL);
+
+ if (Req->argc == 0)
+ return IRC_WriteStrClient(Client, ERR_NORECIPIENT_MSG,
+ Client_ID(Client), Req->command);
+ if (Req->argc == 1)
+ return IRC_WriteStrClient(Client, ERR_NOTEXTTOSEND_MSG,
+ Client_ID(Client));
+ if (Req->argc > 2)
+ return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG,
+ Client_ID(Client), Req->command);
+
+ if (Client_Type(Client) == CLIENT_SERVER)
+ from = Client_Search(Req->prefix);
+ else
+ from = Client;
+ if (!from)
+ return IRC_WriteStrClient(Client, ERR_NOSUCHNICK_MSG,
+ Client_ID(Client), Req->prefix);
+
+ cl = Client_Search(Req->argv[0]);
+ if (cl) {
+ /* Target is a user, enforce type */
+ if (Client_Type(cl) != ForceType)
+ return IRC_WriteStrClient(from, ERR_NOSUCHNICK_MSG,
+ Client_ID(from),
+ Req->argv[0]);
+
+ if ((Client_Type(Client) != CLIENT_SERVER)
+ && (strchr(Client_Modes(cl), 'a'))) {
+ /* Target is away */
+ if (!IRC_WriteStrClient
+ (from, RPL_AWAY_MSG, Client_ID(from), Client_ID(cl),
+ Client_Away(cl)))
+ return DISCONNECTED;
+ }
+
+ if (Client_Conn(from) > NONE)
+ Conn_UpdateIdle(Client_Conn(from));
+ return IRC_WriteStrClientPrefix(cl, from, "PRIVMSG %s :%s",
+ Client_ID(cl), Req->argv[1]);
+ }
+
+ chan = Channel_Search(Req->argv[0]);
+ if (chan)
+ return Channel_Write(chan, from, Client, Req->argv[1]);
+
+ return IRC_WriteStrClient(from, ERR_NOSUCHNICK_MSG,
+ Client_ID(from), Req->argv[0]);
+} /* Send_Message */
+
+