- if (1)
- {
- struct Client* c2ptr = 0;
- struct Client* c3ptr = acptr;
- struct Client* ac2ptr;
- struct Client* ac3ptr;
-
- /* Search youngest link: */
- for (ac3ptr = acptr; ac3ptr != &me; ac3ptr = cli_serv(ac3ptr)->up)
- if (cli_serv(ac3ptr)->timestamp > cli_serv(c3ptr)->timestamp)
- c3ptr = ac3ptr;
-
- if (IsServer(sptr))
- {
- for (ac3ptr = sptr; ac3ptr != &me; ac3ptr = cli_serv(ac3ptr)->up)
- if (cli_serv(ac3ptr)->timestamp > cli_serv(c3ptr)->timestamp)
- c3ptr = ac3ptr;
- }
-
- if (timestamp > cli_serv(c3ptr)->timestamp)
- {
- c3ptr = 0;
- c2ptr = acptr; /* Make sure they differ */
- }
-
- /* Search second youngest link: */
- for (ac2ptr = acptr; ac2ptr != &me; ac2ptr = cli_serv(ac2ptr)->up)
- if (ac2ptr != c3ptr &&
- cli_serv(ac2ptr)->timestamp >
- (c2ptr ? cli_serv(c2ptr)->timestamp : timestamp))
- c2ptr = ac2ptr;
-
- if (IsServer(sptr))
- {
- for (ac2ptr = sptr; ac2ptr != &me; ac2ptr = cli_serv(ac2ptr)->up)
- if (ac2ptr != c3ptr &&
- cli_serv(ac2ptr)->timestamp >
- (c2ptr ? cli_serv(c2ptr)->timestamp : timestamp))
- c2ptr = ac2ptr;
- }
-
- if (c3ptr && timestamp > (c2ptr ? cli_serv(c2ptr)->timestamp : timestamp))
- c2ptr = 0;
-
- /* If timestamps are equal, decide which link to break
- * by name.
- */
- if ((c2ptr ? cli_serv(c2ptr)->timestamp : timestamp) ==
- (c3ptr ? cli_serv(c3ptr)->timestamp : timestamp))
- {
- char* n2;
- char* n2up;
- char* n3;
- char* n3up;
-
- if (c2ptr)
- {
- n2 = cli_name(c2ptr);
- n2up = MyConnect(c2ptr) ? cli_name(&me) : cli_name(cli_serv(c2ptr)->up);
- }
- else
- {
- n2 = host;
- n2up = IsServer(sptr) ? cli_name(sptr) : cli_name(&me);
- }
-
- if (c3ptr)
- {
- n3 = cli_name(c3ptr);
- n3up = MyConnect(c3ptr) ? cli_name(&me) : cli_name(cli_serv(c3ptr)->up);
- }
- else
- {
- n3 = host;
- n3up = IsServer(sptr) ? cli_name(sptr) : cli_name(&me);
- }
-
- if (strcmp(n2, n2up) > 0)
- n2 = n2up;
- if (strcmp(n3, n3up) > 0)
- n3 = n3up;
-
- if (strcmp(n3, n2) > 0)
- {
- ac2ptr = c2ptr;
- c2ptr = c3ptr;
- c3ptr = ac2ptr;
- }
- }
- /* Now squit the second youngest link: */
- if (!c2ptr)
- return exit_new_server(cptr, sptr, host, timestamp,
- "server %s already exists and is %ld seconds younger.",
- host, (long)cli_serv(acptr)->timestamp - (long)timestamp);
- else if (cli_from(c2ptr) == cptr || IsServer(sptr))
- {
- struct Client *killedptrfrom = cli_from(c2ptr);
- if (active_lh_line)
- {
- /*
- * If the L: or H: line also gets rid of this link,
- * we sent just one squit.
- */
- if (LHcptr && a_kills_b_too(LHcptr, c2ptr))
- break;
- /*
- * If breaking the loop here solves the L: or H:
- * line problem, we don't squit that.
- */
- if (cli_from(c2ptr) == cptr || (LHcptr && a_kills_b_too(c2ptr, LHcptr)))
- active_lh_line = 0;
- else
- {
- /*
- * If we still have a L: or H: line problem,
- * we prefer to squit the new server, solving
- * loop and L:/H: line problem with only one squit.
- */
- LHcptr = 0;
- break;
- }
- }
- /*
- * If the new server was introduced by a server that caused a
- * Ghost less then 20 seconds ago, this is probably also
- * a Ghost... (20 seconds is more then enough because all
- * SERVER messages are at the beginning of a net.burst). --Run
- */
- if (CurrentTime - cli_serv(cptr)->ghost < 20)
- {
- killedptrfrom = cli_from(acptr);
- if (exit_client(cptr, acptr, &me, "Ghost loop") == CPTR_KILLED)
- return CPTR_KILLED;
- }
- else if (exit_client_msg(cptr, c2ptr, &me,
- "Loop <-- %s (new link is %ld seconds younger)", host,
- (c3ptr ? (long)cli_serv(c3ptr)->timestamp : timestamp) -
- (long)cli_serv(c2ptr)->timestamp) == CPTR_KILLED)
- return CPTR_KILLED;
- /*
- * Did we kill the incoming server off already ?
- */
- if (killedptrfrom == cptr)
- return 0;
- }
- else
- {
- if (active_lh_line)
- {
- if (LHcptr && a_kills_b_too(LHcptr, acptr))
- break;
- if (cli_from(acptr) == cptr || (LHcptr && a_kills_b_too(acptr, LHcptr)))
- active_lh_line = 0;
- else
- {
- LHcptr = 0;
- break;
- }
- }
- /*
- * We can't believe it is a lagged server message
- * when it directly connects to us...
- * kill the older link at the ghost, rather then
- * at the second youngest link, assuming it isn't
- * a REAL loop.
- */
- ghost = CurrentTime; /* Mark that it caused a ghost */
- if (exit_client(cptr, acptr, &me, "Ghost") == CPTR_KILLED)
- return CPTR_KILLED;
- break;
- }
- }