X-Git-Url: https://arthur.barton.de/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Fngircd%2Firc-server.c;h=e7ff726a208dce9c4c857962d3ed84fcdc4bc1b5;hb=5462c6c50fd01fd516e29a42ee0b15c946c11d27;hp=b75a34f9834abf6267d5ebb60faae753cff51a17;hpb=bce16c2864309d5fc7da8d0591120466303aa966;p=ngircd-alex.git diff --git a/src/ngircd/irc-server.c b/src/ngircd/irc-server.c index b75a34f9..e7ff726a 100644 --- a/src/ngircd/irc-server.c +++ b/src/ngircd/irc-server.c @@ -22,12 +22,10 @@ #include #include "defines.h" -#include "resolve.h" #include "conn.h" #include "conn-func.h" #include "conn-zip.h" #include "conf.h" -#include "client.h" #include "channel.h" #include "irc-write.h" #include "lists.h" @@ -37,6 +35,7 @@ #include "numeric.h" #include "ngircd.h" #include "irc-info.h" +#include "op.h" #include "exp.h" #include "irc-server.h" @@ -273,21 +272,40 @@ IRC_NJOIN( CLIENT *Client, REQUEST *Req ) GLOBAL bool IRC_SQUIT(CLIENT * Client, REQUEST * Req) { - CLIENT *target; - char msg[LINE_LEN + 64]; + char msg[COMMAND_LEN], logmsg[COMMAND_LEN]; + CLIENT *from, *target; + CONN_ID con; assert(Client != NULL); assert(Req != NULL); + if (Client_Type(Client) != CLIENT_SERVER + && !Client_HasMode(Client, 'o')) + return Op_NoPrivileges(Client, Req); + /* Bad number of arguments? */ if (Req->argc != 2) return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG, Client_ID(Client), Req->command); + if (Client_Type(Client) == CLIENT_SERVER && Req->prefix) { + from = Client_Search(Req->prefix); + if (Client_Type(from) != CLIENT_SERVER + && !Op_Check(Client, Req)) + return Op_NoPrivileges(Client, Req); + } else + from = Client; + if (!from) + return IRC_WriteStrClient(Client, ERR_NOSUCHNICK_MSG, + Client_ID(Client), Req->prefix); + Log(LOG_DEBUG, "Got SQUIT from %s for \"%s\": \"%s\" ...", - Client_ID(Client), Req->argv[0], Req->argv[1]); + Client_ID(from), Req->argv[0], Req->argv[1]); target = Client_Search(Req->argv[0]); + if (Client_Type(Client) != CLIENT_SERVER && + target == Client_ThisServer()) + return Op_NoPrivileges(Client, Req); if (!target) { /* The server is (already) unknown */ Log(LOG_WARNING, @@ -296,27 +314,50 @@ IRC_SQUIT(CLIENT * Client, REQUEST * Req) return CONNECTED; } - if (Req->argv[1][0]) { - if (strlen(Req->argv[1]) > LINE_LEN) - Req->argv[1][LINE_LEN] = '\0'; - snprintf(msg, sizeof(msg), "%s (SQUIT from %s).", Req->argv[1], - Client_ID(Client)); - } else - snprintf(msg, sizeof(msg), "Got SQUIT from %s.", - Client_ID(Client)); - - if (Client_Conn(target) > NONE) { - /* We are directly connected to this server */ - if (Req->argv[1][0]) - Conn_Close(Client_Conn(target), msg, Req->argv[1], - true); + con = Client_Conn(target); + + if (Req->argv[1][0]) + if (Client_NextHop(from) != Client || con > NONE) + snprintf(msg, sizeof(msg), "%s (SQUIT from %s)", + Req->argv[1], Client_ID(from)); else - Conn_Close(Client_Conn(target), msg, NULL, true); - return DISCONNECTED; + strlcpy(msg, Req->argv[1], sizeof(msg)); + else + snprintf(msg, sizeof(msg), "Got SQUIT from %s", + Client_ID(from)); + + if (con > NONE) { + /* We are directly connected to the target server, so we + * have to tear down the connection and to inform all the + * other remaining servers in the network */ + IRC_SendWallops(Client_ThisServer(), Client_ThisServer(), + "Received SQUIT %s from %s: %s", + Req->argv[0], Client_ID(from), + Req->argv[1][0] ? Req->argv[1] : "-"); + Conn_Close(con, NULL, msg, true); + if (con == Client_Conn(Client)) + return DISCONNECTED; } else { - Client_Destroy(target, msg, Req->argv[1], false); - return CONNECTED; + /* This server is not directly connected, so the SQUIT must + * be forwarded ... */ + if (Client_Type(from) != CLIENT_SERVER) { + /* The origin is not an IRC server, so don't evaluate + * this SQUIT but simply forward it */ + IRC_WriteStrClientPrefix(Client_NextHop(target), + from, "SQUIT %s :%s", Req->argv[0], Req->argv[1]); + } else { + /* SQUIT has been generated by another server, so + * remove the target server from the network! */ + logmsg[0] = '\0'; + if (!strchr(msg, '(')) + snprintf(logmsg, sizeof(logmsg), + "%s (SQUIT from %s)", Req->argv[1], + Client_ID(from)); + Client_Destroy(target, logmsg[0] ? logmsg : msg, + msg, false); + } } + return CONNECTED; } /* IRC_SQUIT */ /* -eof- */