]> The Tcpdump Group git mirrors - libpcap/blobdiff - fmtutils.c
In the open request, reject capture sources that are URLs.
[libpcap] / fmtutils.c
index 0c527453547f2c2e68d60518f9d070a22b3c6db6..d89a3976159da50b7786721ac3c7981a55c01ea4 100644 (file)
@@ -65,14 +65,9 @@ pcap_fmt_errmsg_for_errno(char *errbuf, size_t errbuflen, int errnum,
        size_t msglen;
        char *p;
        size_t errbuflen_remaining;
-#if defined(HAVE_STRERROR_S)
-       errno_t err;
-#elif defined(HAVE_STRERROR_R)
-       int err;
-#endif
 
        va_start(ap, fmt);
-       pcap_vsnprintf(errbuf, errbuflen, fmt, ap);
+       vsnprintf(errbuf, errbuflen, fmt, ap);
        va_end(ap);
        msglen = strlen(errbuf);
 
@@ -96,29 +91,48 @@ pcap_fmt_errmsg_for_errno(char *errbuf, size_t errbuflen, int errnum,
         * Now append the string for the error code.
         */
 #if defined(HAVE_STRERROR_S)
-       err = strerror_s(p, errbuflen_remaining, errnum);
+       /*
+        * We have a Windows-style strerror_s().
+        */
+       errno_t err = strerror_s(p, errbuflen_remaining, errnum);
        if (err != 0) {
                /*
                 * It doesn't appear to be documented anywhere obvious
                 * what the error returns from strerror_s().
                 */
-               pcap_snprintf(p, errbuflen_remaining, "Error %d", errnum);
+               snprintf(p, errbuflen_remaining, "Error %d", errnum);
        }
-#elif defined(HAVE_STRERROR_R)
-       err = strerror_r(errnum, p, errbuflen_remaining);
+#elif defined(HAVE_GNU_STRERROR_R)
+       /*
+        * We have a GNU-style strerror_r(), which is *not* guaranteed to
+        * do anything to the buffer handed to it, and which returns a
+        * pointer to the error string, which may or may not be in
+        * the buffer.
+        *
+        * It is, however, guaranteed to succeed.
+        */
+       char strerror_buf[PCAP_ERRBUF_SIZE];
+       char *errstring = strerror_r(errnum, strerror_buf, PCAP_ERRBUF_SIZE);
+       snprintf(p, errbuflen_remaining, "%s", errstring);
+#elif defined(HAVE_POSIX_STRERROR_R)
+       /*
+        * We have a POSIX-style strerror_r(), which is guaranteed to fill
+        * in the buffer, but is not guaranteed to succeed.
+        */
+       int err = strerror_r(errnum, p, errbuflen_remaining);
        if (err == EINVAL) {
                /*
                 * UNIX 03 says this isn't guaranteed to produce a
                 * fallback error message.
                 */
-               pcap_snprintf(p, errbuflen_remaining, "Unknown error: %d",
+               snprintf(p, errbuflen_remaining, "Unknown error: %d",
                    errnum);
        } else if (err == ERANGE) {
                /*
                 * UNIX 03 says this isn't guaranteed to produce a
                 * fallback error message.
                 */
-               pcap_snprintf(p, errbuflen_remaining,
+               snprintf(p, errbuflen_remaining,
                    "Message for error %d is too long", errnum);
        }
 #else
@@ -126,24 +140,50 @@ pcap_fmt_errmsg_for_errno(char *errbuf, size_t errbuflen, int errnum,
         * We have neither strerror_s() nor strerror_r(), so we're
         * stuck with using pcap_strerror().
         */
-       pcap_snprintf(p, errbuflen_remaining, "%s", pcap_strerror(errnum));
+       snprintf(p, errbuflen_remaining, "%s", pcap_strerror(errnum));
 #endif
 }
 
 #ifdef _WIN32
 /*
- * Generate a string for a Win32-specific error (i.e. an error generated when
- * calling a Win32 API).
- * For errors occurred during standard C calls, we still use pcap_strerror().
+ * Generate an error message based on a format, arguments, and a
+ * Win32 error, with a message for the Win32 error after the formatted output.
  */
 void
-pcap_win32_err_to_str(DWORD error, char *errbuf)
+pcap_fmt_errmsg_for_win32_err(char *errbuf, size_t errbuflen, DWORD errnum,
+    const char *fmt, ...)
 {
-       DWORD retval;
-       size_t errlen;
+       va_list ap;
+       size_t msglen;
        char *p;
+       size_t errbuflen_remaining;
+       DWORD retval;
+       char win32_errbuf[PCAP_ERRBUF_SIZE+1];
+
+       va_start(ap, fmt);
+       vsnprintf(errbuf, errbuflen, fmt, ap);
+       va_end(ap);
+       msglen = strlen(errbuf);
 
        /*
+        * Do we have enough space to append ": "?
+        * Including the terminating '\0', that's 3 bytes.
+        */
+       if (msglen + 3 > errbuflen) {
+               /* No - just give them what we've produced. */
+               return;
+       }
+       p = errbuf + msglen;
+       errbuflen_remaining = errbuflen - msglen;
+       *p++ = ':';
+       *p++ = ' ';
+       *p = '\0';
+       msglen += 2;
+       errbuflen_remaining -= 2;
+
+       /*
+        * Now append the string for the error code.
+        *
         * XXX - what language ID to use?
         *
         * For UN*Xes, pcap_strerror() may or may not return localized
@@ -158,30 +198,17 @@ pcap_win32_err_to_str(DWORD error, char *errbuf)
         * happen to understand.
         */
        retval = FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS|FORMAT_MESSAGE_MAX_WIDTH_MASK,
-           NULL, error, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
-           errbuf, PCAP_ERRBUF_SIZE, NULL);
+           NULL, errnum, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
+           win32_errbuf, PCAP_ERRBUF_SIZE, NULL);
        if (retval == 0) {
                /*
                 * Failed.
                 */
-               pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
-                   "Couldn't get error message for error (%lu)", error);
+               snprintf(p, errbuflen_remaining,
+                   "Couldn't get error message for error (%lu)", errnum);
                return;
        }
 
-       /*
-        * "FormatMessage()" "helpfully" sticks CR/LF at the end of the
-        * message.  Get rid of it.
-        *
-        * XXX - still true with FORMAT_MESSAGE_MAX_WIDTH_MASK?
-        */
-       errlen = strlen(errbuf);
-       if (errlen >= 2 &&
-           errbuf[errlen - 2] == '\r' && errbuf[errlen - 1] == '\n') {
-               errbuf[errlen - 2] = '\0';
-               errbuf[errlen - 1] = '\0';
-       }
-       p = strchr(errbuf, '\0');
-       pcap_snprintf(p, PCAP_ERRBUF_SIZE+1-(p-errbuf), " (%lu)", error);
+       snprintf(p, errbuflen_remaining, "%s (%lu)", win32_errbuf, errnum);
 }
 #endif