From 1ee70571e0cae37f155f59d4382bc7109138cf09 Mon Sep 17 00:00:00 2001
From: Bart Van Assche <bvanassche@acm.org>
Date: Sat, 15 Aug 2020 17:29:25 -0700
Subject: [PATCH] apps/snmpnetstat: Stop using obsolete signal functions

This was reported by Rosen Penev. See also
https://github.com/net-snmp/net-snmp/pull/162.
---
 apps/snmpnetstat/if.c | 111 +++++++++++-------------------------------
 1 file changed, 28 insertions(+), 83 deletions(-)
 mode change 100644 => 100755 apps/snmpnetstat/if.c

diff --git a/apps/snmpnetstat/if.c b/apps/snmpnetstat/if.c
old mode 100644
new mode 100755
index 16768151d..84b87b531
--- a/apps/snmpnetstat/if.c
+++ b/apps/snmpnetstat/if.c
@@ -64,8 +64,6 @@
 #define	NO	0
 
 static void sidewaysintpr(u_int);
-static void timerSet(int interval_seconds);
-static void timerPause(void);
 
     struct _if_info {
         char            name[128];
@@ -92,6 +90,34 @@ static void timerPause(void);
     };
 
 
+static struct timeval deadline;
+
+static void
+timerSet(int interval_seconds)
+{
+    const struct timeval interval = { interval_seconds, 0 };
+
+    netsnmp_get_monotonic_clock(&deadline);
+    NETSNMP_TIMERADD(&deadline, &interval, &deadline);
+}
+
+static void
+timerPause(void)
+{
+    struct timeval now, delta;
+
+    netsnmp_get_monotonic_clock(&now);
+    NETSNMP_TIMERSUB(&deadline, &now, &delta);
+    if (delta.tv_sec < 0)
+        return;
+#ifdef WIN32
+    Sleep(delta.tv_sec * 1000 + delta.tv_usec / 1000);
+#else
+    if (select(0, NULL, NULL, NULL, &delta) < 0)
+        snmp_perror("select");
+#endif
+}
+
 /*
  * Retrieve the interface addressing information
  * XXX - This could also be extended to handle non-IP interfaces
@@ -845,84 +871,3 @@ sidewaysintpr(unsigned int interval)
     	goto loop;
     /*NOTREACHED*/
 }
-
-
-/*
- * timerSet sets or resets the timer to fire in "interval" seconds.
- * timerPause waits only if the timer has not fired.
- * timing precision is not considered important.
- */
-
-#if (defined(WIN32) || defined(cygwin))
-static int      sav_int;
-static time_t   timezup;
-static void
-timerSet(int interval_seconds)
-{
-    sav_int = interval_seconds;
-    timezup = time(0) + interval_seconds;
-}
-
-/*
- * you can do better than this ! 
- */
-static void
-timerPause(void)
-{
-    time_t          now;
-    while (time(&now) < timezup)
-#ifdef WIN32
-        Sleep(400);
-#else
-    {
-        struct timeval  tx;
-        tx.tv_sec = 0;
-        tx.tv_usec = 400 * 1000;        /* 400 milliseconds */
-        select(0, 0, 0, 0, &tx);
-    }
-#endif
-}
-
-#else
-
-/*
- * Called if an interval expires before sidewaysintpr has completed a loop.
- * Sets a flag to not wait for the alarm.
- */
-RETSIGTYPE
-catchalarm(int sig)
-{
-    signalled = YES;
-}
-
-static void
-timerSet(int interval_seconds)
-{
-#ifdef HAVE_SIGSET
-    (void) sigset(SIGALRM, catchalarm);
-#else
-    (void) signal(SIGALRM, catchalarm);
-#endif
-    signalled = NO;
-    (void) alarm(interval_seconds);
-}
-
-static void
-timerPause(void)
-{
-#ifdef HAVE_SIGHOLD
-    sighold(SIGALRM);
-    if (!signalled) {
-        sigpause(SIGALRM);
-    }
-#else
-    int             oldmask;
-    oldmask = sigblock(sigmask(SIGALRM));
-    if (!signalled) {
-        sigpause(0);
-    }
-    sigsetmask(oldmask);
-#endif
-}
-
-#endif                          /* !WIN32 && !cygwin */
