fmtutils.c 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. /*
  2. * Copyright (c) 1993, 1994, 1995, 1996, 1997, 1998
  3. * The Regents of the University of California. All rights reserved.
  4. *
  5. * Redistribution and use in source and binary forms, with or without
  6. * modification, are permitted provided that the following conditions
  7. * are met:
  8. * 1. Redistributions of source code must retain the above copyright
  9. * notice, this list of conditions and the following disclaimer.
  10. * 2. Redistributions in binary form must reproduce the above copyright
  11. * notice, this list of conditions and the following disclaimer in the
  12. * documentation and/or other materials provided with the distribution.
  13. * 3. All advertising materials mentioning features or use of this software
  14. * must display the following acknowledgement:
  15. * This product includes software developed by the Computer Systems
  16. * Engineering Group at Lawrence Berkeley Laboratory.
  17. * 4. Neither the name of the University nor of the Laboratory may be used
  18. * to endorse or promote products derived from this software without
  19. * specific prior written permission.
  20. *
  21. * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  22. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  23. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  24. * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  25. * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  26. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  27. * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  28. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  29. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  30. * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  31. * SUCH DAMAGE.
  32. */
  33. /*
  34. * Utilities for message formatting used both by libpcap and rpcapd.
  35. */
  36. #ifdef HAVE_CONFIG_H
  37. #include <config.h>
  38. #endif
  39. #include "ftmacros.h"
  40. #include <stddef.h>
  41. #include <stdarg.h>
  42. #include <stdio.h>
  43. #include <string.h>
  44. #include <errno.h>
  45. #include <pcap/pcap.h>
  46. #include "portability.h"
  47. #include "fmtutils.h"
  48. /*
  49. * Generate an error message based on a format, arguments, and an
  50. * errno, with a message for the errno after the formatted output.
  51. */
  52. void
  53. pcap_fmt_errmsg_for_errno(char *errbuf, size_t errbuflen, int errnum,
  54. const char *fmt, ...)
  55. {
  56. va_list ap;
  57. size_t msglen;
  58. char *p;
  59. size_t errbuflen_remaining;
  60. #if defined(HAVE_STRERROR_S)
  61. errno_t err;
  62. #elif defined(HAVE_STRERROR_R)
  63. int err;
  64. #endif
  65. va_start(ap, fmt);
  66. pcap_vsnprintf(errbuf, errbuflen, fmt, ap);
  67. va_end(ap);
  68. msglen = strlen(errbuf);
  69. /*
  70. * Do we have enough space to append ": "?
  71. * Including the terminating '\0', that's 3 bytes.
  72. */
  73. if (msglen + 3 > errbuflen) {
  74. /* No - just give them what we've produced. */
  75. return;
  76. }
  77. p = errbuf + msglen;
  78. errbuflen_remaining = errbuflen - msglen;
  79. *p++ = ':';
  80. *p++ = ' ';
  81. *p = '\0';
  82. msglen += 2;
  83. errbuflen_remaining -= 2;
  84. /*
  85. * Now append the string for the error code.
  86. */
  87. #if defined(HAVE_STRERROR_S)
  88. err = strerror_s(p, errbuflen_remaining, errnum);
  89. if (err != 0) {
  90. /*
  91. * It doesn't appear to be documented anywhere obvious
  92. * what the error returns from strerror_s().
  93. */
  94. pcap_snprintf(p, errbuflen_remaining, "Error %d", errnum);
  95. }
  96. #elif defined(HAVE_STRERROR_R)
  97. err = strerror_r(errnum, p, errbuflen_remaining);
  98. if (err == EINVAL) {
  99. /*
  100. * UNIX 03 says this isn't guaranteed to produce a
  101. * fallback error message.
  102. */
  103. pcap_snprintf(p, errbuflen_remaining, "Unknown error: %d",
  104. errnum);
  105. } else if (err == ERANGE) {
  106. /*
  107. * UNIX 03 says this isn't guaranteed to produce a
  108. * fallback error message.
  109. */
  110. pcap_snprintf(p, errbuflen_remaining,
  111. "Message for error %d is too long", errnum);
  112. }
  113. #else
  114. /*
  115. * We have neither strerror_s() nor strerror_r(), so we're
  116. * stuck with using pcap_strerror().
  117. */
  118. pcap_snprintf(p, errbuflen_remaining, "%s", pcap_strerror(errnum));
  119. #endif
  120. }