OpenSSL options min-version, max-version
[socat.git] / snprinterr.c
blobd994bc18697fd36a93cf80fc89749bc8e16c5ef7
1 /* snprinterr.c */
2 /* Copyright Gerhard Rieger and contributors (see file CHANGES) */
4 /* a function similar to vsnprintf() but it just handles %m */
6 #include "config.h"
8 #include <stddef.h> /* ptrdiff_t */
9 #include <ctype.h> /* isdigit() */
10 #include <stdarg.h>
11 #include <stdlib.h>
12 #include <errno.h>
13 #if HAVE_SYSLOG_H
14 #include <syslog.h>
15 #endif
16 #include <sys/utsname.h>
17 #include <time.h> /* time_t, strftime() */
18 #include <sys/time.h> /* gettimeofday() */
19 #include <stdio.h>
20 #include <string.h>
21 #if HAVE_UNISTD_H
22 #include <unistd.h>
23 #endif
25 #include "snprinterr.h"
27 #define HAVE_STRERROR_R 0
28 /* replace %m in format with actual strerror() message, write result to *str.
29 keep other % formats unchanged!
30 writes at most size chars including the terminating \0 to *str
31 returns the number of bytes in the output without terminating \0
32 result is always \0 terminated except when size==0
34 int snprinterr(char *str, size_t size, const char *format) {
35 char c;
36 int full = 0; /* 1 means: there is no space left in * str for more data or \0 */
37 int count = 0;
38 if (size == 0) return 0;
39 if (count >= size) full = 1;
40 while (c = *format++) {
41 if (c == '%') {
42 c = *format++;
43 switch (c) {
44 case '\0':
45 ++count; if (!full) { (*str++ = '%'); if (count+1 >= size) full = 1; }
46 break;
47 default:
48 ++count; if (!full) { (*str++ = '%'); if (count+1 >= size) full = 1; }
49 ++count; if (!full) { (*str++ = c); if (count+1 >= size) full = 1; }
50 break;
51 case 'm':
53 #if HAVE_STRERROR_R
54 # define BUFLEN 64
55 char buf[BUFLEN] = "";
56 #endif /* HAVE_STRERROR_R */
57 char *bufp;
58 #if !HAVE_STRERROR_R
59 bufp = strerror(errno);
60 #else
61 /* there are two versions floating around... */
62 # if 1 /* GNU version */
63 bufp = strerror_r(errno, buf, BUFLEN);
64 # else /* standard version */
65 strerror_r(errno, buf, BUFLEN);
66 bufp = buf;
67 # endif
68 #endif /* HAVE_STRERROR_R */
69 while ((c = *bufp++) != '\0') {
70 ++count; if (!full) { (*str++ = c); if (count+1 >= size) full = 1; }
73 c = ' '; /* not \0 ! */
74 break;
76 if (c == '\0') break;
77 } else {
78 ++count; if (!full) { (*str++ = c); if (count+1 >= size) full = 1; }
81 *str++ = '\0'; /* always write terminating \0 */
82 return count;
83 #undef BUFLEN