+static time_t check_pings(void)
+{
+ int expire=0;
+ /* Temp to figure out what time this connection will next need
+ * to be checked.
+ */
+ int next_check = CurrentTime + PINGFREQUENCY;
+ /*
+ * The current lowest expire time - ie: the time that check_pings
+ * needs to be called next.
+ */
+ int max_ping = 0;
+ /*
+ * The time you've got before a ping is sent/your connection is
+ * terminated.
+ */
+
+ int i=0; /* loop counter */
+
+ /* Scan through the client table */
+ for (i=0; i <= HighestFd; i++) {
+ struct Client *cptr;
+
+ cptr = LocalClientArray[i];
+
+ /* Skip empty entries */
+ if (!cptr)
+ continue;
+
+ assert(&me != cptr); /* I should never be in the local client array,
+ * so if I am, dying is a good thing(tm).
+ */
+
+ /* Remove dead clients.
+ * We will have sent opers a message when we set the dead flag,
+ * so don't bother to send one now.
+ */
+ if (IsDead(cptr)) {
+ exit_client(cptr, cptr, &me, cptr->info);
+ continue;
+ }
+
+ /* Should we concider adding a class 0 for 'unregistered clients',
+ * where we can specify their 'ping timeout' etc?
+ */
+ max_ping = IsRegistered(cptr) ? get_client_ping(cptr) : CONNECTTIMEOUT;
+
+ /* Ok, the thing that will happen most frequently, is that someone will
+ * have sent something recently. Cover this first for speed.
+ */
+ if (CurrentTime-cptr->lasttime <= max_ping) {
+ expire=cptr->lasttime + max_ping;
+ if (next_check<expire)
+ next_check=expire;
+ continue;
+ }
+
+ /* Quit the client after max_ping*2 - they should have answered by now */
+ if (CurrentTime-cptr->lasttime <= (max_ping*2) ) {
+
+ /* If it was a server, then tell ops about it. */
+ if (IsServer(cptr) || IsConnecting(cptr) || IsHandshake(cptr))
+ sendto_ops("No response from %s, closing link", cptr->name);
+
+ exit_client_msg(cptr, cptr, &me, "Ping timeout");
+ continue;
+ } /* of testing to see if ping has been sent */
+
+ /* Unregistered clients pingout after max_ping seconds, they don't
+ * get given a second chance.
+ */
+ if (!IsRegistered(cptr)) {
+ /* Display message if they have sent a NICK and a USER but no
+ * nospoof PONG.
+ */
+ if (*cptr->name && *cptr->user->username) {
+ sendto_one(cptr,
+ ":%s %d %s :Your client may not be compatible with this server.",
+ me.name, ERR_BADPING, cptr->name);
+ sendto_one(cptr,
+ ":%s %d %s :Compatible clients are available at "
+ "ftp://ftp.undernet.org/pub/irc/clients",
+ me.name, ERR_BADPING, cptr->name);
+ }
+ exit_client_msg(cptr,cptr,&me, "Ping Timeout");
+ continue;
+ } /* of not registered */
+
+ if (0 == (cptr->flags & FLAGS_PINGSENT)) {
+ /*
+ * If we havent PINGed the connection and we havent heard from it in a
+ * while, PING it to make sure it is still alive.
+ */
+ cptr->flags |= FLAGS_PINGSENT;
+
+ /*
+ * If we're late in noticing don't hold it against them :)
+ */
+ cptr->lasttime = CurrentTime - max_ping;
+
+ if (IsUser(cptr))
+ sendto_one(cptr, "PING :%s", me.name);
+ else
+ sendto_one(cptr, "%s " TOK_PING " :%s", NumServ(&me), me.name);
+ } /* of if not ping sent... */
+
+ expire=cptr->lasttime+max_ping*2;
+
+ if (expire<next_check)
+ next_check=expire;
+
+ } /* end of loop over clients */
+
+ assert(next_check>=CurrentTime);
+
+ return next_check;
+}
+
+#if 0