Home | History | Annotate | Download | only in libpcap
      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 /*
     35  * Utilities for message formatting used both by libpcap and rpcapd.
     36  */
     37 
     38 #ifdef HAVE_CONFIG_H
     39 #include <config.h>
     40 #endif
     41 
     42 #include "ftmacros.h"
     43 
     44 #include <stddef.h>
     45 #include <stdarg.h>
     46 #include <stdio.h>
     47 #include <string.h>
     48 #include <errno.h>
     49 
     50 #include <pcap/pcap.h>
     51 
     52 #include "portability.h"
     53 
     54 #include "fmtutils.h"
     55 
     56 /*
     57  * Generate an error message based on a format, arguments, and an
     58  * errno, with a message for the errno after the formatted output.
     59  */
     60 void
     61 pcap_fmt_errmsg_for_errno(char *errbuf, size_t errbuflen, int errnum,
     62     const char *fmt, ...)
     63 {
     64 	va_list ap;
     65 	size_t msglen;
     66 	char *p;
     67 	size_t errbuflen_remaining;
     68 #if defined(HAVE_STRERROR_S)
     69 	errno_t err;
     70 #elif defined(HAVE_STRERROR_R)
     71 	int err;
     72 #endif
     73 
     74 	va_start(ap, fmt);
     75 	pcap_vsnprintf(errbuf, errbuflen, fmt, ap);
     76 	va_end(ap);
     77 	msglen = strlen(errbuf);
     78 
     79 	/*
     80 	 * Do we have enough space to append ": "?
     81 	 * Including the terminating '\0', that's 3 bytes.
     82 	 */
     83 	if (msglen + 3 > errbuflen) {
     84 		/* No - just give them what we've produced. */
     85 		return;
     86 	}
     87 	p = errbuf + msglen;
     88 	errbuflen_remaining = errbuflen - msglen;
     89 	*p++ = ':';
     90 	*p++ = ' ';
     91 	*p = '\0';
     92 	msglen += 2;
     93 	errbuflen_remaining -= 2;
     94 
     95 	/*
     96 	 * Now append the string for the error code.
     97 	 */
     98 #if defined(HAVE_STRERROR_S)
     99 	err = strerror_s(p, errbuflen_remaining, errnum);
    100 	if (err != 0) {
    101 		/*
    102 		 * It doesn't appear to be documented anywhere obvious
    103 		 * what the error returns from strerror_s().
    104 		 */
    105 		pcap_snprintf(p, errbuflen_remaining, "Error %d", errnum);
    106 	}
    107 #elif defined(HAVE_STRERROR_R)
    108 	err = strerror_r(errnum, p, errbuflen_remaining);
    109 	if (err == EINVAL) {
    110 		/*
    111 		 * UNIX 03 says this isn't guaranteed to produce a
    112 		 * fallback error message.
    113 		 */
    114 		pcap_snprintf(p, errbuflen_remaining, "Unknown error: %d",
    115 		    errnum);
    116 	} else if (err == ERANGE) {
    117 		/*
    118 		 * UNIX 03 says this isn't guaranteed to produce a
    119 		 * fallback error message.
    120 		 */
    121 		pcap_snprintf(p, errbuflen_remaining,
    122 		    "Message for error %d is too long", errnum);
    123 	}
    124 #else
    125 	/*
    126 	 * We have neither strerror_s() nor strerror_r(), so we're
    127 	 * stuck with using pcap_strerror().
    128 	 */
    129 	pcap_snprintf(p, errbuflen_remaining, "%s", pcap_strerror(errnum));
    130 #endif
    131 }
    132