File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / mtr / ui / utils.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Mon Oct 21 14:25:31 2019 UTC (4 years, 9 months ago) by misho
Branches: mtr, MAIN
CVS tags: v0_92, HEAD
mtr ver 0.92

    1: /*
    2:     mtr  --  a network diagnostic tool
    3:     Copyright (C) 1997,1998  Matt Kimball
    4: 
    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.
    8: 
    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.
   13: 
   14:     You should have received a copy of the GNU General Public License
   15:     along with this program; if not, write to the Free Software
   16:     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
   17: */
   18: 
   19: #include "config.h"
   20: 
   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>
   30: 
   31: #ifdef HAVE_ERROR_H
   32: #include <error.h>
   33: #else
   34: #include "portability/error.h"
   35: #endif
   36: 
   37: #ifdef HAVE_STDIO_EXT_H
   38: #include <stdio_ext.h>
   39: #endif
   40: 
   41: #include "utils.h"
   42: 
   43: char *trim(
   44:     char *str,
   45:     const char c)
   46: {
   47:     char *p = str;
   48:     size_t len;
   49: 
   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);
   56:     }
   57: 
   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;
   64:         }
   65:         len++;
   66:         break;
   67:     }
   68:     str[len] = '\0';
   69:     return str;
   70: }
   71: 
   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)
   77: {
   78:     unsigned long int num;
   79:     char *end = NULL;
   80: 
   81:     if (str != NULL && *str != '\0') {
   82:         errno = 0;
   83:         num = strtoul(str, &end, 10);
   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;
   94:             }
   95:         }
   96:     }
   97:     error(EXIT_FAILURE, errno, "%s: '%s'", errmesg, str);
   98:     return 0;
   99: }
  100: 
  101: float strtofloat_or_err(
  102:     const char *str,
  103:     const char *errmesg)
  104: {
  105:     double num;
  106:     char *end = NULL;
  107: 
  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
  115:             )
  116:             return num;
  117:     }
  118:     error(EXIT_FAILURE, errno, "%s: '%s'", errmesg, str);
  119:     return 0;
  120: }
  121: 
  122: void *xmalloc(
  123:     const size_t size)
  124: {
  125:     void *ret = malloc(size);
  126: 
  127:     if (!ret && size)
  128:         error(EXIT_FAILURE, errno, "cannot allocate %zu bytes", size);
  129:     return ret;
  130: }
  131: 
  132: char *xstrdup(
  133:     const char *str)
  134: {
  135:     char *ret;
  136: 
  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;
  143: }
  144: 
  145: #ifndef HAVE___FPENDING
  146: static inline int __fpending(
  147:     FILE * stream __attribute__ ((__unused__)))
  148: {
  149:     return 0;
  150: }
  151: #endif
  152: static inline int close_stream(
  153:     FILE * stream)
  154: {
  155:     const int some_pending = (__fpending(stream) != 0);
  156:     const int prev_fail = (ferror(stream) != 0);
  157:     const int fclose_fail = (fclose(stream) != 0);
  158: 
  159:     if (prev_fail || (fclose_fail && (some_pending || errno != EBADF))) {
  160:         if (!fclose_fail && !(errno == EPIPE))
  161:             errno = 0;
  162:         return EOF;
  163:     }
  164:     return 0;
  165: }
  166: 
  167: /* Meant to be used atexit(close_stdout); */
  168: void close_stdout(
  169:     void)
  170: {
  171:     if (close_stream(stdout) != 0 && !(errno == EPIPE)) {
  172:         error(0, errno, "write error");
  173:         _exit(EXIT_FAILURE);
  174:     }
  175:     if (close_stream(stderr) != 0)
  176:         _exit(EXIT_FAILURE);
  177: }
  178: 
  179: /* ctime() replacement that will reteturn ISO-8601 timestamp string such as:
  180:  * 2016-08-29T19:25:02+01:00 */
  181: const char *iso_time(
  182:     const time_t * t)
  183: {
  184:     static char s[32];
  185:     struct tm *tm;
  186: 
  187:     tm = localtime(t);
  188:     strftime(s, sizeof(s), "%Y-%m-%dT%H:%M:%S%z", tm);
  189:     return s;
  190: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>