This patch enables ngIRCd to handle IRC services as real services, and not
as "fake users":
- Set correct client type CLIENT_SERVICE for services,
- Change log messages to include correct client type,
- PRIVMSG: allow users to send messages to services,
- Send services nick names to other servers (as users).
Please note that this patch doesn't announce services as services in the
network, but as regular users (as before). Only the local server knows
of services as services (see LUSERS command, for example). It is up to
one of the next patches to fix this and to introduce the SERVICE command
in server to server communication.
The propagation of services as regular users between servers doesn't limit
the functionality of the IRC services and will be the fallback for servers
that don't support "real" services propagation in the future.
assert( Txt != NULL );
strlcpy( Client->away, Txt, sizeof( Client->away ));
assert( Txt != NULL );
strlcpy( Client->away, Txt, sizeof( Client->away ));
- Log( LOG_DEBUG, "User \"%s\" is away: %s", Client_Mask( Client ), Txt );
+ LogDebug("%s \"%s\" is away: %s", Client_TypeText(Client),
+ Client_Mask(Client), Txt);
/* Set new topic */
Channel_SetTopic(chan, from, Req->argv[1]);
/* Set new topic */
Channel_SetTopic(chan, from, Req->argv[1]);
- Log(LOG_DEBUG, "User \"%s\" set topic on \"%s\": %s",
- Client_Mask(from), Channel_Name(chan),
- Req->argv[1][0] ? Req->argv[1] : "<none>");
+ LogDebug("%s \"%s\" set topic on \"%s\": %s",
+ Client_TypeText(from), Client_Mask(from), Channel_Name(chan),
+ Req->argv[1][0] ? Req->argv[1] : "<none>");
/* im Channel bekannt machen und an Server weiterleiten */
IRC_WriteStrServersPrefix( Client, from, "TOPIC %s :%s", Req->argv[0], Req->argv[1] );
/* im Channel bekannt machen und an Server weiterleiten */
IRC_WriteStrServersPrefix( Client, from, "TOPIC %s :%s", Req->argv[0], Req->argv[1] );
if (strcmp(Client_Password(Client), Conf_ServerPwd) != 0) {
/* Bad password! */
Log(LOG_ERR,
if (strcmp(Client_Password(Client), Conf_ServerPwd) != 0) {
/* Bad password! */
Log(LOG_ERR,
- "User \"%s\" rejected (connection %d): Bad password!",
+ "Client \"%s\" rejected (connection %d): Bad password!",
Client_Mask(Client), Client_Conn(Client));
Conn_Close(Client_Conn(Client), NULL, "Bad password", true);
return DISCONNECTED;
Client_Mask(Client), Client_Conn(Client));
Conn_Close(Client_Conn(Client), NULL, "Bad password", true);
return DISCONNECTED;
if (From) {
if (Conf_IsService(Conf_GetServer(Client_Conn(From)), Client_ID(Client))) {
type = "Service";
if (From) {
if (Conf_IsService(Conf_GetServer(Client_Conn(From)), Client_ID(Client))) {
type = "Service";
+ Client_SetType(Client, CLIENT_SERVICE);
} else
type = "User";
LogDebug("%s \"%s\" (+%s) registered (via %s, on %s, %d hop%s).",
} else
type = "User";
LogDebug("%s \"%s\" (+%s) registered (via %s, on %s, %d hop%s).",
ok = IRC_WriteStrClientPrefix( Client, Origin, "MODE %s :%s", Client_ID( Target ), the_modes );
IRC_WriteStrServersPrefix( Client, Origin, "MODE %s :%s", Client_ID( Target ), the_modes );
}
ok = IRC_WriteStrClientPrefix( Client, Origin, "MODE %s :%s", Client_ID( Target ), the_modes );
IRC_WriteStrServersPrefix( Client, Origin, "MODE %s :%s", Client_ID( Target ), the_modes );
}
- Log( LOG_DEBUG, "User \"%s\": Mode change, now \"%s\".", Client_Mask( Target ), Client_Modes( Target ));
+ LogDebug("%s \"%s\": Mode change, now \"%s\".",
+ Client_TypeText(Target), Client_Mask(Target),
+ Client_Modes(Target));
}
IRC_SetPenalty( Client, 1 );
}
IRC_SetPenalty( Client, 1 );
if (cl) {
/* Target is a user, enforce type */
if (cl) {
/* Target is a user, enforce type */
+#ifndef STRICT_RFC
+ if (Client_Type(cl) != ForceType &&
+ !(ForceType == CLIENT_USER &&
+ (Client_Type(cl) == CLIENT_USER ||
+ Client_Type(cl) == CLIENT_SERVICE))) {
+#else
if (Client_Type(cl) != ForceType) {
if (Client_Type(cl) != ForceType) {
if (!SendErrors)
return CONNECTED;
return IRC_WriteStrClient(from, ERR_NOSUCHNICK_MSG,
if (!SendErrors)
return CONNECTED;
return IRC_WriteStrClient(from, ERR_NOSUCHNICK_MSG,
/* Announce all the users to the new server */
c = Client_First();
while (c) {
/* Announce all the users to the new server */
c = Client_First();
while (c) {
- if (Client_Type(c) == CLIENT_USER) {
+ if (Client_Type(c) == CLIENT_USER ||
+ Client_Type(c) == CLIENT_SERVICE) {
if (!Announce_User(Client, c))
return DISCONNECTED;
}
if (!Announce_User(Client, c))
return DISCONNECTED;
}