+/**
+ * Handler for the IRC "SQUERY" command.
+ *
+ * @param Client The client from which this command has been received.
+ * @param Req Request structure with prefix and all parameters.
+ * @return CONNECTED or DISCONNECTED.
+ */
+GLOBAL bool
+IRC_SQUERY(CLIENT *Client, REQUEST *Req)
+{
+ return Send_Message(Client, Req, CLIENT_SERVICE, true);
+} /* IRC_SQUERY */
+
+/*
+ * Handler for the IRC "TRACE" command.
+ *
+ * @param Client The client from which this command has been received.
+ * @param Req Request structure with prefix and all parameters.
+ * @return CONNECTED or DISCONNECTED.
+ */
+ GLOBAL bool
+IRC_TRACE(CLIENT *Client, REQUEST *Req)
+{
+ CLIENT *from, *target, *c;
+ CONN_ID idx, idx2;
+ char user[CLIENT_USER_LEN];
+
+ assert(Client != NULL);
+ assert(Req != NULL);
+
+ IRC_SetPenalty(Client, 3);
+
+ /* Bad number of arguments? */
+ if (Req->argc > 1)
+ return IRC_WriteStrClient(Client, ERR_NORECIPIENT_MSG,
+ Client_ID(Client), Req->command);
+
+ _IRC_GET_SENDER_OR_RETURN_(from, Req, Client)
+ _IRC_GET_TARGET_SERVER_OR_RETURN_(target, Req, 0, from)
+
+ /* Forward command to other server? */
+ if (target != Client_ThisServer()) {
+ /* Send RPL_TRACELINK back to initiator */
+ idx = Client_Conn(Client);
+ assert(idx > NONE);
+ idx2 = Client_Conn(Client_NextHop(target));
+ assert(idx2 > NONE);
+
+ if (!IRC_WriteStrClient(from, RPL_TRACELINK_MSG,
+ Client_ID(from), PACKAGE_NAME,
+ PACKAGE_VERSION, Client_ID(target),
+ Client_ID(Client_NextHop(target)),
+ Option_String(idx2),
+ time(NULL) - Conn_StartTime(idx2),
+ Conn_SendQ(idx), Conn_SendQ(idx2)))
+ return DISCONNECTED;
+
+ /* Forward command */
+ IRC_WriteStrClientPrefix(target, from, "TRACE %s", Req->argv[0]);
+ return CONNECTED;
+ }
+
+ /* Infos about all connected servers */
+ c = Client_First();
+ while (c) {
+ if (Client_Conn(c) > NONE) {
+ /* Local client */
+ if (Client_Type(c) == CLIENT_SERVER) {
+ /* Server link */
+ strlcpy(user, Client_User(c), sizeof(user));
+ if (user[0] == '~')
+ strlcpy(user, "unknown", sizeof(user));
+ if (!IRC_WriteStrClient(from,
+ RPL_TRACESERVER_MSG,
+ Client_ID(from), Client_ID(c),
+ user, Client_Hostname(c),
+ Client_Mask(Client_ThisServer()),
+ Option_String(Client_Conn(c))))
+ return DISCONNECTED;
+ }
+ if (Client_Type(c) == CLIENT_USER
+ && Client_HasMode(c, 'o')) {
+ /* IRC Operator */
+ if (!IRC_WriteStrClient(from,
+ RPL_TRACEOPERATOR_MSG,
+ Client_ID(from), Client_ID(c)))
+ return DISCONNECTED;
+ }
+ }
+ c = Client_Next( c );
+ }