+flag_t getservertype(server *server) {
+ flag_t result = 0;
+ char *server_name;
+ int server_len;
+
+ if(server == NULL || server->name == NULL)
+ return 0;
+
+ server_name = server->name->content;
+ server_len = server->name->length;
+
+ if(server->flags & SMODE_SERVICE)
+ result|=SERVERTYPEFLAG_SERVICE;
+
+ if(!strcmp(server_name, q_server->content)) {
+ result|=SERVERTYPEFLAG_CHANSERV;
+ result|=SERVERTYPEFLAG_CRITICAL_SERVICE;
+ } else if(!strcmp(server_name, s_server->content)) {
+ result|=SERVERTYPEFLAG_SPAMSCAN;
+ result|=SERVERTYPEFLAG_CRITICAL_SERVICE;
+ } else {
+ if(service_re && (pcre_exec(service_re, NULL, server_name, server_len, 0, 0, NULL, 0) >= 0)) {
+ /* matches service re */
+ if((server->flags & SMODE_SERVICE) == 0) {
+ /* is not a service */
+ Error("serverlist", ERR_WARNING, "Non-service server (%s) matched service RE.", server_name);
+ }
+ } else {
+ /* does not match service re */
+ if((server->flags & SMODE_SERVICE) != 0) {
+ result|=SERVERTYPEFLAG_SERVICE;
+ Error("serverlist", ERR_WARNING, "Service server (%s) that does not match service RE.", server_name);
+ }
+ }
+ }
+
+ if(hub_re && (pcre_exec(hub_re, NULL, server_name, server_len, 0, 0, NULL, 0) >= 0)) {
+ if((server->flags & SMODE_HUB) != 0) {
+ result|=SERVERTYPEFLAG_HUB;
+ } else {
+ Error("serverlist", ERR_WARNING, "Server matched hub re but isn't a hub (%s).", server_name);
+ }
+ }
+
+ if(not_client_re && (pcre_exec(not_client_re, NULL, server_name, server_len, 0, 0, NULL, 0) >= 0)) {
+ /* noop */
+ } else if(result == 0) {
+ result|=SERVERTYPEFLAG_CLIENT_SERVER;
+ }
+
+ return result;
+}
+
+void serverlist_pingservers(void *arg) {
+ int i;
+ server *from, *to;
+ char fnum[10], tnum[10];
+ struct timeval tv;
+
+ if (!mynick)
+ return;
+
+ for(i=0;i<MAXSERVERS;i++) {
+ to = &serverlist[i];
+
+ if (to->parent == -1)
+ continue;
+
+ from = &serverlist[to->parent];
+
+ if (to->linkstate != LS_LINKED || from->linkstate != LS_LINKED)
+ continue;
+
+ strcpy(fnum, longtonumeric(to->parent,2));
+ strcpy(tnum, longtonumeric(i, 2));
+
+ if (from->parent == -1) { /* Are we the source? */
+ (void) gettimeofday(&tv, NULL);
+ irc_send("%s RI %s %s %jd %jd :RP", mynumeric->content, tnum, longtonumeric(mynick->numeric,5), (intmax_t)tv.tv_sec, (intmax_t)tv.tv_usec);
+ } else {
+ strcpy(fnum, longtonumeric(to->parent,2));
+ strcpy(tnum, longtonumeric(i, 2));
+ irc_send("%s RI %s %s :RP", longtonumeric(mynick->numeric,5), to->name->content, fnum);
+ }
+ }
+}
+
+int serverlist_rpong(void *source, int cargc, char **cargv) {
+ int to, lag;
+ struct timeval tv;
+
+ if (cargc < 4)
+ return CMD_ERROR;
+
+ if (cargc == 5) { /* From target to source server */
+ if (strcmp(cargv[4], "RP") != 0)
+ return CMD_OK;
+
+ to = numerictolong(source, 2);
+
+ (void) gettimeofday(&tv, NULL);
+ lag = (tv.tv_sec - strtoull(cargv[2], NULL, 10)) * 1000 + (tv.tv_usec - strtoull(cargv[3], NULL, 10)) / 1000;
+ } else { /* From source server to client */
+ if (strcmp(cargv[3], "RP") != 0)
+ return CMD_OK;
+
+ to = findserver(cargv[1]);
+
+ if (to == -1)
+ return CMD_ERROR;
+
+ lag = atoi(cargv[2]);
+ }
+
+ serverinfo[to].lag = lag;
+
+ return CMD_OK;
+}