+#ifdef ITIMER_REAL
+ struct itimerval disable;
+ xzero (disable);
+ setitimer (ITIMER_REAL, &disable, NULL);
+#else /* not ITIMER_REAL */
+ alarm (0);
+#endif /* not ITIMER_REAL */
+}
+
+/* Call FUN(ARG), but don't allow it to run for more than TIMEOUT
+ seconds. Returns non-zero if the function was interrupted with a
+ timeout, zero otherwise.
+
+ This works by setting up SIGALRM to be delivered in TIMEOUT seconds
+ using setitimer() or alarm(). The timeout is enforced by
+ longjumping out of the SIGALRM handler. This has several
+ advantages compared to the traditional approach of relying on
+ signals causing system calls to exit with EINTR:
+
+ * The callback function is *forcibly* interrupted after the
+ timeout expires, (almost) regardless of what it was doing and
+ whether it was in a syscall. For example, a calculation that
+ takes a long time is interrupted as reliably as an IO
+ operation.
+
+ * It works with both SYSV and BSD signals because it doesn't
+ depend on the default setting of SA_RESTART.
+
+ * It doesn't require special handler setup beyond a simple call
+ to signal(). (It does use sigsetjmp/siglongjmp, but they're
+ optional.)
+
+ The only downside is that, if FUN allocates internal resources that
+ are normally freed prior to exit from the functions, they will be
+ lost in case of timeout. */
+
+int
+run_with_timeout (double timeout, void (*fun) (void *), void *arg)
+{
+ int saved_errno;
+
+ if (timeout == 0)
+ {
+ fun (arg);
+ return 0;
+ }
+
+ signal (SIGALRM, abort_run_with_timeout);
+ if (SETJMP (run_with_timeout_env) != 0)
+ {
+ /* Longjumped out of FUN with a timeout. */
+ signal (SIGALRM, SIG_DFL);
+ return 1;
+ }
+ alarm_set (timeout);
+ fun (arg);
+
+ /* Preserve errno in case alarm() or signal() modifies it. */
+ saved_errno = errno;
+ alarm_cancel ();
+ signal (SIGALRM, SIG_DFL);
+ errno = saved_errno;
+
+ return 0;
+}
+
+#else /* not USE_SIGNAL_TIMEOUT */
+
+#ifndef WINDOWS
+/* A stub version of run_with_timeout that just calls FUN(ARG). Don't
+ define it under Windows, because Windows has its own version of
+ run_with_timeout that uses threads. */
+
+int
+run_with_timeout (double timeout, void (*fun) (void *), void *arg)
+{
+ fun (arg);
+ return 0;
+}
+#endif /* not WINDOWS */
+#endif /* not USE_SIGNAL_TIMEOUT */
+\f
+#ifndef WINDOWS
+
+/* Sleep the specified amount of seconds. On machines without
+ nanosleep(), this may sleep shorter if interrupted by signals. */
+
+void
+xsleep (double seconds)
+{
+#ifdef HAVE_NANOSLEEP
+ /* nanosleep is the preferred interface because it offers high
+ accuracy and, more importantly, because it allows us to reliably
+ restart receiving a signal such as SIGWINCH. (There was an
+ actual Debian bug report about --limit-rate malfunctioning while
+ the terminal was being resized.) */
+ struct timespec sleep, remaining;
+ sleep.tv_sec = (long) seconds;
+ sleep.tv_nsec = 1000000000 * (seconds - (long) seconds);
+ while (nanosleep (&sleep, &remaining) < 0 && errno == EINTR)
+ /* If nanosleep has been interrupted by a signal, adjust the
+ sleeping period and return to sleep. */
+ sleep = remaining;
+#else /* not HAVE_NANOSLEEP */
+#ifdef HAVE_USLEEP
+ /* If usleep is available, use it in preference to select. */
+ if (seconds >= 1)
+ {
+ /* On some systems, usleep cannot handle values larger than
+ 1,000,000. If the period is larger than that, use sleep
+ first, then add usleep for subsecond accuracy. */
+ sleep (seconds);
+ seconds -= (long) seconds;
+ }
+ usleep (seconds * 1000000);
+#else /* not HAVE_USLEEP */
+#ifdef HAVE_SELECT
+ /* Note that, although Windows supports select, this sleeping
+ strategy doesn't work there because Winsock's select doesn't
+ implement timeout when it is passed NULL pointers for all fd
+ sets. (But it does work under Cygwin, which implements its own
+ select.) */
+ struct timeval sleep;
+ sleep.tv_sec = (long) seconds;
+ sleep.tv_usec = 1000000 * (seconds - (long) seconds);
+ select (0, NULL, NULL, NULL, &sleep);
+ /* If select returns -1 and errno is EINTR, it means we were
+ interrupted by a signal. But without knowing how long we've
+ actually slept, we can't return to sleep. Using gettimeofday to
+ track sleeps is slow and unreliable due to clock skew. */
+#else /* not HAVE_SELECT */
+ sleep (seconds);
+#endif /* not HAVE_SELECT */
+#endif /* not HAVE_USLEEP */
+#endif /* not HAVE_NANOSLEEP */
+}
+
+#endif /* not WINDOWS */
+
+/* Encode the string S of length LENGTH to base64 format and place it
+ to STORE. STORE will be 0-terminated, and must point to a writable
+ buffer of at least 1+BASE64_LENGTH(length) bytes. */
+
+void
+base64_encode (const char *s, char *store, int length)
+{
+ /* Conversion table. */
+ static char tbl[64] = {
+ 'A','B','C','D','E','F','G','H',
+ 'I','J','K','L','M','N','O','P',
+ 'Q','R','S','T','U','V','W','X',
+ 'Y','Z','a','b','c','d','e','f',
+ 'g','h','i','j','k','l','m','n',
+ 'o','p','q','r','s','t','u','v',
+ 'w','x','y','z','0','1','2','3',
+ '4','5','6','7','8','9','+','/'
+ };