Changed how conflicitng first/max TTL works.
[mtr.git] / ui / utils.c
blob5e3a701c18c0d414154a85b535cd279ed0e49776
1 /*
2 mtr -- a network diagnostic tool
3 Copyright (C) 1997,1998 Matt Kimball
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License version 2 as
7 published by the Free Software Foundation.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License along
15 with this program; if not, write to the Free Software Foundation, Inc.,
16 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 #include "config.h"
21 #include <ctype.h>
22 #include <errno.h>
23 #include <limits.h>
24 #include <stdint.h>
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <string.h>
28 #include <time.h>
29 #include <unistd.h>
31 #ifdef HAVE_ERROR_H
32 #include <error.h>
33 #else
34 #include "portability/error.h"
35 #endif
37 #ifdef HAVE_STDIO_EXT_H
38 #include <stdio_ext.h>
39 #endif
41 #include "utils.h"
43 char *trim(
44 char *str,
45 const char c)
47 char *p = str;
48 size_t len;
50 /* left trim */
51 while (*p && (isspace((unsigned char) *p) || (c && *p == c)))
52 p++;
53 if (str < p) {
54 len = strlen(str);
55 memmove(str, p, len + 1);
58 /* right trim */
59 len = strlen(str);
60 while (len) {
61 len--;
62 if (isspace((unsigned char) str[len]) || (c && str[len] == c)) {
63 continue;
65 len++;
66 break;
68 str[len] = '\0';
69 return str;
72 /* Parse string, and return positive signed int. */
73 int strtonum_or_err(
74 const char *str,
75 const char *errmesg,
76 const int type)
78 unsigned long int num;
79 char *end = NULL;
81 if (str != NULL && *str != '\0') {
82 errno = 0;
83 num = strtoul(str, &end, 0);
84 if (errno == 0 && str != end && end != NULL && *end == '\0') {
85 switch (type) {
86 case STRTO_INT:
87 if (num < INT_MAX)
88 return num;
89 break;
90 case STRTO_U32INT:
91 if (num < UINT32_MAX)
92 return num;
93 break;
97 error(EXIT_FAILURE, errno, "%s: '%s'", errmesg, str);
98 return 0;
101 float strtofloat_or_err(
102 const char *str,
103 const char *errmesg)
105 double num;
106 char *end = NULL;
108 if (str != NULL && *str != '\0') {
109 errno = 0;
110 num = strtod(str, &end);
111 if (errno == 0 && str != end && end != NULL && *end == '\0'
112 #ifdef FLT_MAX
113 && num < FLT_MAX
114 #endif
116 return num;
118 error(EXIT_FAILURE, errno, "%s: '%s'", errmesg, str);
119 return 0;
122 void *xmalloc(
123 const size_t size)
125 void *ret = malloc(size);
127 if (!ret && size)
128 error(EXIT_FAILURE, errno, "cannot allocate %zu bytes", size);
129 return ret;
132 char *xstrdup(
133 const char *str)
135 char *ret;
137 if (!str)
138 return NULL;
139 ret = strdup(str);
140 if (!ret)
141 error(EXIT_FAILURE, errno, "cannot duplicate string: %s", str);
142 return ret;
145 #ifndef HAVE___FPENDING
146 static inline int __fpending(
147 FILE * stream __attribute__ ((__unused__)))
149 return 0;
151 #endif
152 static inline int close_stream(
153 FILE * stream)
155 const int some_pending = (__fpending(stream) != 0);
156 const int prev_fail = (ferror(stream) != 0);
157 const int fclose_fail = (fclose(stream) != 0);
159 if (prev_fail || (fclose_fail && (some_pending || errno != EBADF))) {
160 if (!fclose_fail && !(errno == EPIPE))
161 errno = 0;
162 return EOF;
164 return 0;
167 /* Meant to be used atexit(close_stdout); */
168 void close_stdout(
169 void)
171 if (close_stream(stdout) != 0 && !(errno == EPIPE)) {
172 error(0, errno, "write error");
173 _exit(EXIT_FAILURE);
175 if (close_stream(stderr) != 0)
176 _exit(EXIT_FAILURE);
179 /* ctime() replacement that will return ISO-8601 timestamp string such as:
180 * 2016-08-29T19:25:02+01:00 */
181 const char *iso_time(
182 const time_t * t)
184 static char s[32];
185 struct tm *tm;
187 tm = localtime(t);
188 strftime(s, sizeof(s), "%Y-%m-%dT%H:%M:%S%z", tm);
189 return s;